qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH RFC v2] s390/css: handle CCW_FLAG_SKIP


From: Eric Farman
Subject: Re: [Qemu-devel] [PATCH RFC v2] s390/css: handle CCW_FLAG_SKIP
Date: Tue, 7 May 2019 11:31:16 -0400
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1



On 5/7/19 5:08 AM, Pierre Morel wrote:
On 07/05/2019 10:12, Cornelia Huck wrote:
If a ccw has CCW_FLAG_SKIP set, and the command is of type
read, read backwards, or sense, no data should be written
to the guest for that command.

Signed-off-by: Cornelia Huck <address@hidden>
---

v1 -> v2: fixed checks for command type [Eric]

Still only lightly tested (it boots); I don't think I have a tool
generating channel programs with the skip flag handy.

FWIW, my test program hits this code once (read of a single page, with SLI and SKIP flags set) before getting into the passthrough codepath.


---
  hw/s390x/css.c         | 22 ++++++++++++++++++----
  include/hw/s390x/css.h |  1 +
  2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 8fc9e35ba5d3..080ac7e5bc0b 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -830,8 +830,12 @@ static int ccw_dstream_rw_noflags(CcwDataStream *cds, void *buff, int len,
      if (op == CDS_OP_A) {
          goto incr;
      }
-    ret = address_space_rw(&address_space_memory, cds->cda,
-                           MEMTXATTRS_UNSPECIFIED, buff, len, op);
+    if (!cds->do_skip) {
+        ret = address_space_rw(&address_space_memory, cds->cda,
+                               MEMTXATTRS_UNSPECIFIED, buff, len, op);
+    } else {
+        ret = 0;
+    }
      if (ret != MEMTX_OK) {
          cds->flags |= CDS_F_STREAM_BROKEN;
          return -EINVAL;
@@ -928,8 +932,13 @@ static int ccw_dstream_rw_ida(CcwDataStream *cds, void *buff, int len,
      do {
          iter_len = MIN(len, cont_left);
          if (op != CDS_OP_A) {
-            ret = address_space_rw(&address_space_memory, cds->cda,
-                                   MEMTXATTRS_UNSPECIFIED, buff, iter_len, op);
+            if (!cds->do_skip) {
+                ret = address_space_rw(&address_space_memory, cds->cda,
+                                       MEMTXATTRS_UNSPECIFIED, buff, iter_len,
+                                       op);
+            } else {
+                ret = 0;
+            }
              if (ret != MEMTX_OK) {
                  /* assume inaccessible address */
                  ret = -EINVAL; /* channel program check */
@@ -968,6 +977,11 @@ void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb)
      cds->count = ccw->count;
      cds->cda_orig = ccw->cda;
+    /* skip is only effective for read, read backwards, or sense commands */
+    cds->do_skip = (ccw->flags & CCW_FLAG_SKIP) &&
+        ((ccw->cmd_code & CCW_CMD_BASIC_SENSE) == CCW_CMD_BASIC_SENSE ||
+         (ccw->cmd_code & 0x02) == 0x02 /* read */ ||
+         (ccw->cmd_code & 0x0c) == 0x0c /* read backwards */);

I think you should use masks like
((code & 0x3) == 2) => READ
((code & 0xf) == 0xc) => READ BACKWARD
((code & 0xf) == 0x4) => SENSE

I think Pierre is right. In the v2 code, a control CCW (like NOP) would still be flagged as a READ.


Regards,
Pierre




      ccw_dstream_rewind(cds);
      if (!(cds->flags & CDS_F_IDA)) {
          cds->op_handler = ccw_dstream_rw_noflags;
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index aae19c427229..7cc183ef4366 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -97,6 +97,7 @@ typedef struct CcwDataStream {
      int (*op_handler)(struct CcwDataStream *cds, void *buff, int len,
                        CcwDataStreamOp op);
      hwaddr cda;
+    bool do_skip;
  } CcwDataStream;
  /*





reply via email to

[Prev in Thread] Current Thread [Next in Thread]