From ee25f50eebc290f5255aa73cf9207a8331ea8639 Mon Sep 17 00:00:00 2001
From: Miao Wang <shankerwangmiao@gmail.com>
Date: Fri, 5 Jun 2026 04:48:09 +0800
Subject: [PATCH] pvscsi: translate data endianness

---
 hw/scsi/vmw_pvscsi.c | 54 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 11ae6b9b74..124a59da3f 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -35,6 +35,7 @@
 #include "hw/pci/msi.h"
 #include "hw/core/qdev-properties.h"
 #include "exec/cpu-common.h"
+#include "exec/tswap.h"
 #include "vmw_pvscsi.h"
 #include "trace.h"
 #include "qom/object.h"
@@ -395,6 +396,14 @@ pvscsi_cmp_ring_put(PVSCSIState *s, struct PVSCSIRingCmpDesc *cmp_desc)
 
     cmp_descr_pa = pvscsi_ring_pop_cmp_descr(&s->rings);
     trace_pvscsi_cmp_ring_put(cmp_descr_pa);
+    struct PVSCSIRingCmpDesc cmp_desc_conv = {
+        .context = tswap64(cmp_desc->context),
+        .dataLen = tswap64(cmp_desc->dataLen),
+        .senseLen = tswap32(cmp_desc->senseLen),
+        .hostStatus = tswap16(cmp_desc->hostStatus),
+        .scsiStatus = tswap16(cmp_desc->scsiStatus),
+    };
+    cmp_desc = &cmp_desc_conv;
     cpu_physical_memory_write(cmp_descr_pa, cmp_desc, sizeof(*cmp_desc));
 }
 
@@ -405,6 +414,13 @@ pvscsi_msg_ring_put(PVSCSIState *s, struct PVSCSIRingMsgDesc *msg_desc)
 
     msg_descr_pa = pvscsi_ring_pop_msg_descr(&s->rings);
     trace_pvscsi_msg_ring_put(msg_descr_pa);
+    struct PVSCSIRingMsgDesc msg_desc_conv = {
+        .type = tswap32(msg_desc->type),
+    };
+    for (int i = 0; i < sizeof(msg_desc->args) / sizeof(msg_desc->args[0]); i++) {
+        msg_desc_conv.args[i] = tswap32(msg_desc->args[i]);
+    }
+    msg_desc = &msg_desc_conv;
     cpu_physical_memory_write(msg_descr_pa, msg_desc, sizeof(*msg_desc));
 }
 
@@ -481,6 +497,9 @@ pvscsi_get_next_sg_elem(PVSCSISGState *sg)
     struct PVSCSISGElement elem;
 
     cpu_physical_memory_read(sg->elemAddr, &elem, sizeof(elem));
+    elem.addr = tswap64(elem.addr);
+    elem.length = tswap32(elem.length);
+    elem.flags = tswap32(elem.flags);
     if ((elem.flags & ~PVSCSI_KNOWN_FLAGS) != 0) {
         /*
             * There is PVSCSI_SGE_FLAG_CHAIN_ELEMENT flag described in
@@ -759,6 +778,12 @@ pvscsi_process_io(PVSCSIState *s)
 
         trace_pvscsi_process_io(next_descr_pa);
         cpu_physical_memory_read(next_descr_pa, &descr, sizeof(descr));
+        descr.context = tswap64(descr.context);
+        descr.dataAddr = tswap64(descr.dataAddr);
+        descr.dataLen = tswap64(descr.dataLen);
+        descr.senseAddr = tswap64(descr.senseAddr);
+        descr.senseLen = tswap32(descr.senseLen);
+        descr.flags = tswap32(descr.flags);
         pvscsi_process_request_descriptor(s, &descr);
     }
 
@@ -809,6 +834,16 @@ pvscsi_on_cmd_setup_rings(PVSCSIState *s)
     PVSCSICmdDescSetupRings *rc =
         (PVSCSICmdDescSetupRings *) s->curr_cmd_data;
 
+    PVSCSICmdDescSetupRings translated;
+    translated.reqRingNumPages = tswap32(rc->reqRingNumPages);
+    translated.cmpRingNumPages = tswap32(rc->cmpRingNumPages);
+    translated.ringsStatePPN = tswap64(rc->ringsStatePPN);
+    for (int i = 0; i < PVSCSI_SETUP_RINGS_MAX_NUM_PAGES; i++) {
+        translated.reqRingPPNs[i] = tswap64(rc->reqRingPPNs[i]);
+        translated.cmpRingPPNs[i] = tswap64(rc->cmpRingPPNs[i]);
+    }
+    rc = &translated;
+
     trace_pvscsi_on_cmd_arrived("PVSCSI_CMD_SETUP_RINGS");
 
     if (!rc->reqRingNumPages
@@ -831,6 +866,11 @@ pvscsi_on_cmd_abort(PVSCSIState *s)
     PVSCSICmdDescAbortCmd *cmd = (PVSCSICmdDescAbortCmd *) s->curr_cmd_data;
     PVSCSIRequest *r, *next;
 
+    PVSCSICmdDescAbortCmd translated = *cmd;
+    translated.context = tswap32(cmd->context);
+    translated.target = tswap32(cmd->target);
+    cmd = &translated;
+
     trace_pvscsi_on_cmd_abort(cmd->context, cmd->target);
 
     QTAILQ_FOREACH_SAFE(r, &s->pending_queue, next, next) {
@@ -862,6 +902,10 @@ pvscsi_on_cmd_reset_device(PVSCSIState *s)
         (struct PVSCSICmdDescResetDevice *) s->curr_cmd_data;
     SCSIDevice *sdev;
 
+    PVSCSICmdDescResetDevice translated = *cmd;
+    translated.target = tswap32(cmd->target);
+    cmd = &translated;
+
     sdev = pvscsi_device_find(s, 0, cmd->target, cmd->lun, &target_lun);
 
     trace_pvscsi_on_cmd_reset_dev(cmd->target, (int) target_lun, sdev);
@@ -893,6 +937,14 @@ pvscsi_on_cmd_setup_msg_ring(PVSCSIState *s)
     PVSCSICmdDescSetupMsgRing *rc =
         (PVSCSICmdDescSetupMsgRing *) s->curr_cmd_data;
 
+    PVSCSICmdDescSetupMsgRing translated = *rc;
+
+    translated.numPages = tswap32(rc->numPages);
+    for (int i = 0; i < PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES; i++) {
+        translated.ringPPNs[i] = tswap64(rc->ringPPNs[i]);
+    }
+    rc = &translated;
+
     trace_pvscsi_on_cmd_arrived("PVSCSI_CMD_SETUP_MSG_RING");
 
     if (!s->use_msg) {
@@ -994,7 +1046,7 @@ pvscsi_on_command_data(PVSCSIState *s, uint32_t value)
     size_t bytes_arrived = s->curr_cmd_data_cntr * sizeof(uint32_t);
 
     assert(bytes_arrived < sizeof(s->curr_cmd_data));
-    s->curr_cmd_data[s->curr_cmd_data_cntr++] = value;
+    s->curr_cmd_data[s->curr_cmd_data_cntr++] = tswap32(value);
 
     pvscsi_do_command_processing(s);
 }
-- 
2.47.3

