On 05.06.2026 16:27, Miao Wang via B4 Relay wrote:
From: Miao Wang <[email protected]>

This patch improves the implementation of the pvscsi device by
translating the endianness of the data sent or received from the guest.
This ensures pvscsi can work on big-endian hosts with little-endian
guests.

Hi!

Can we pick this one up for 11.1 please?
I know right to nothing about s390x internals so can't really review
the change.  But the fix seems to work, and it should be picked up for
the stable qemu series too, it loks like.

Thanks,

/mjt

Signed-off-by: Miao Wang <[email protected]>
---
  hw/scsi/vmw_pvscsi.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 
11ae6b9b7474b9bc87621137eb7911361b5fd721..883dfe9b6b5dc687737de356da02fe5f68aea7ad
 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"
@@ -392,9 +393,18 @@ static void
  pvscsi_cmp_ring_put(PVSCSIState *s, struct PVSCSIRingCmpDesc *cmp_desc)
  {
      hwaddr cmp_descr_pa;
+    struct PVSCSIRingCmpDesc cmp_desc_conv;
cmp_descr_pa = pvscsi_ring_pop_cmp_descr(&s->rings);
      trace_pvscsi_cmp_ring_put(cmp_descr_pa);
+    cmp_desc_conv = (struct PVSCSIRingCmpDesc) {
+        .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));
  }
@@ -402,9 +412,18 @@ static void
  pvscsi_msg_ring_put(PVSCSIState *s, struct PVSCSIRingMsgDesc *msg_desc)
  {
      hwaddr msg_descr_pa;
+    struct PVSCSIRingMsgDesc msg_desc_conv;
+    int i;
msg_descr_pa = pvscsi_ring_pop_msg_descr(&s->rings);
      trace_pvscsi_msg_ring_put(msg_descr_pa);
+    msg_desc_conv = (struct PVSCSIRingMsgDesc) {
+        .type = tswap32(msg_desc->type),
+    };
+    for (i = 0; i < ARRAY_SIZE(msg_desc->args); 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 +500,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 +781,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);
      }
@@ -808,6 +836,17 @@ pvscsi_on_cmd_setup_rings(PVSCSIState *s)
  {
      PVSCSICmdDescSetupRings *rc =
          (PVSCSICmdDescSetupRings *) s->curr_cmd_data;
+    PVSCSICmdDescSetupRings translated;
+    int i;
+
+    translated.reqRingNumPages = tswap32(rc->reqRingNumPages);
+    translated.cmpRingNumPages = tswap32(rc->cmpRingNumPages);
+    translated.ringsStatePPN = tswap64(rc->ringsStatePPN);
+    for (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"); @@ -831,6 +870,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 +906,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);
@@ -892,6 +940,14 @@ pvscsi_on_cmd_setup_msg_ring(PVSCSIState *s)
  {
      PVSCSICmdDescSetupMsgRing *rc =
          (PVSCSICmdDescSetupMsgRing *) s->curr_cmd_data;
+    PVSCSICmdDescSetupMsgRing translated = *rc;
+    int i;
+
+    translated.numPages = tswap32(rc->numPages);
+    for (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"); @@ -994,7 +1050,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);
  }

---
base-commit: 29c042c6e9d4a09d4a0ac3fa54aeb7ee08ce0bdc
change-id: 20260605-pvscsi-endianness-c0d389d8274e

Best regards,


Reply via email to