add CCW indirect data access support
v3 cover add CCW indirect data access support
Abstract
--------
The objective of this series is introducing CCW IDA (indirect data access) support to our virtual channel subsystem implementation. Briefly CCW IDA can be thought of as a kind of a scatter gather support for a single CCW. If certain flags are set, the cda is to be interpreted as an address to a list which in turn holds further addresses designating the actual data. Thus the scheme which we are currently using for accessing CCW payload does not work in general case. Currently there is no immediate need for proper IDA handling (no use case), but since it IDA is a non-optional part of the architecture, the only way towards AR compliance is actually implementing IDA.
Testing
-------
On request the things meant for testing from v1 were factored out into a separate series (requested by Connie). Please look for the series 'tests for CCW IDA' (see [1]) or use the stuff form v1.
[1] https://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg03489.html
Changelog
---------
v2 --> v3:
* added maximum data address checking (see patch #4) (Dong Jia) To not mix converting to the new infrastructure and changing behavior, this is done after the conversion. For IDA the same (on both IDAL and data level) is now a part of the respective patch (was missing in v2).
* even less nits, and improved aesthetics (mostly Dong Jia) v1 --> v2:
* factored out the stuff added only for testing
* use g_assert instead of assert
* fixed a lot's of typos
* removed some TODOs addressed by another series of mine
* refactored ccw_dstream_rw_ida (structured programming)
* done some rewording of commit message #3
Halil Pasic (5):
s390x/css: introduce css data stream s390x/css: use ccw data stream
virtio-ccw: use ccw data stream
390x/css: introduce maximum data address checking s390x/css: support ccw IDA
hw/s390x/css.c | 189 +++++++++++++++++++++++++++++++++++++++++++++++-- hw/s390x/virtio-ccw.c | 157 ++++++++++++---------------------------- include/hw/s390x/css.h | 68 ++++++++++++++++++ 3 files changed, 299 insertions(+), 115 deletions(-)
Signature · 1 line
2.13.5
PATCH v3 1/5 s390x/css: introduce css data stream
This is a preparation for introducing handling for indirect data addressing and modified indirect data addressing (CCW). Here we introduce an interface which should make the addressing scheme transparent for the client code. Here we implement only the basic scheme (no IDA or MIDA).
--- hw/s390x/css.c | 55 +++++++++++++++++++++++++++++++++++++++++ include/hw/s390x/css.h | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+)
hw/s390x/css.c +55 -0
@@ -783,6 +783,61 @@ static CCW1 copy_ccw_from_guest(hwaddr addr, bool fmt1) }return ret; } +/** +* If out of bounds marks the stream broken. If broken returns -EINVAL, +* otherwise the requested length (may be zero) +*/ +static inline int cds_check_len (CcwDataStream *cds,int len) +{ +if (cds->at_byte + len > cds->count) { + cds->flags |=CDS_F_STREAM_BROKEN ; + } +return cds->flags &CDS_F_STREAM_BROKEN ? -EINVAL : len; +} + +static int ccw_dstream_rw_noflags (CcwDataStream *cds,void *buff,int len, +CcwDataStreamOp op) +{ +int ret; + + ret =cds_check_len (cds, len); +if (ret <=0 ) { +return ret; + } +if (op ==CDS_OP_A ) { + goto incr; + } + ret =address_space_rw (&address_space_memory, cds->cda, +MEMTXATTRS_UNSPECIFIED , buff, len, op); +if (ret !=MEMTX_OK ) { + cds->flags |=CDS_F_STREAM_BROKEN ; +return -EINVAL ; + } +incr: + cds->at_byte += len; + cds->cda += len; +return 0 ; +} + +void ccw_dstream_init (CcwDataStream *cds,CCW1 const *ccw,ORB const *orb) +{ +/* +* We don't support MIDA (an optional facility) yet and we +* catch this earlier. Just for expressing the precondition. +*/ +g_assert (!(orb->ctrl1 &ORB_CTRL1_MASK_MIDAW )); + cds->flags = (orb->ctrl0 &ORB_CTRL0_MASK_I2K ?CDS_F_I2K :0 ) | + (orb->ctrl0 &ORB_CTRL0_MASK_C64 ?CDS_F_C64 :0 ) | + (ccw->flags &CCW_FLAG_IDA ?CDS_F_IDA :0 ); + cds->count = ccw->count; + cds->cda_orig = ccw->cda; +ccw_dstream_rewind (cds); +if (!(cds->flags &CDS_F_IDA )) { + cds->op_handler = ccw_dstream_rw_noflags; + }else { +assert (false); + } +}static int css_interpret_ccw (SubchDev *sch,hwaddr ccw_addr,bool suspend_allowed)
include/hw/s390x/css.h +67 -0
83 lines not on this page · raw message
Signature · 1 line
2.13.5
Re: [Qemu-devel] [PATCH v3 1/5] s390x/css: introduce css data stream
* Halil Pasic <[email protected]> [2017-09-19 20:27:41 +0200]:
[...]
include/hw/s390x/css.h typedef struct CMBE { · line 81
Quoted 12 lines
include/hw/s390x/css.h +4
-0@@ -75,6 +75,29 @@ typedef struct CMBE {uint32_t reserved[7 ]; }QEMU_PACKED CMBE ; +typedef enum CcwDataStreamOp { + CDS_OP_R = 0, /* read, false when used as is_write */ + CDS_OP_W = 1, /* write, true when used as is_write */ + CDS_OP_A = 2 /* advance, should not be used as is_write */
Looks good to me.
Quoted 3 lines
include/hw/s390x/css.h +2
-0+} CcwDataStreamOp; +
[...]
Signature · 1 line
Dong Jia Shi
PATCH v3 2/5 s390x/css: use ccw data stream
In reply to Halil PasicReplace direct access which implicitly assumes no IDA or MIDA with the new ccw data stream interface which should cope with these transparently in the future.
--- hw/s390x/css.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
hw/s390x/css.c +5 -4
@@ -890,6 +890,7 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr, }/* Look at the command. */ +ccw_dstream_init (&sch->cds, &ccw, &(sch->orb));switch (ccw.cmd_code) {case CCW_CMD_NOOP :/* Nothing to do. */
@@ -903,8 +904,8 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr, } } len =MIN (ccw.count,sizeof (sch->sense_data)); -cpu_physical_memory_write (ccw.cda, sch->sense_data, len); - sch->curr_status.scsw.count = ccw.count - len; +ccw_dstream_write_buf (&sch->cds, sch->sense_data, len); + sch->curr_status.scsw.count =ccw_dstream_residual_count (&sch->cds);memset (sch->sense_data,0 ,sizeof (sch->sense_data)); ret =0 ;break ;
@@ -930,8 +931,8 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr, }else { sense_id.reserved =0 ; } -cpu_physical_memory_write (ccw.cda, &sense_id, len); - sch->curr_status.scsw.count = ccw.count - len; +ccw_dstream_write_buf (&sch->cds, &sense_id, len); + sch->curr_status.scsw.count =ccw_dstream_residual_count (&sch->cds); ret =0 ;break ; }
Signature · 1 line
2.13.5
Re: [Qemu-devel] [PATCH v3 2/5] s390x/css: use ccw data stream
Quoted 24 lines · Halil Pasic
Replace direct access which implicitly assumes no IDA or MIDA with the new ccw data stream interface which should cope with these transparently in the future.
Signed-off-by Halil Pasic <[email protected]>Reviewed-by Dong Jia Shi <[email protected]>Reviewed-by Pierre Morel<[email protected]>--- hw/s390x/css.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)hw/s390x/css.c +1
-0@@ -890,6 +890,7 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr, }/* Look at the command. */ +ccw_dstream_init (&sch->cds, &ccw, &(sch->orb));switch (ccw.cmd_code) {case CCW_CMD_NOOP :/* Nothing to do. */
hw/s390x/css.c static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr, · line 907
Quoted 6 lines
hw/s390x/css.c +1
-2@@ -903,8 +904,8 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr, } } len =MIN (ccw.count,sizeof (sch->sense_data)); -cpu_physical_memory_write (ccw.cda, sch->sense_data, len); - sch->curr_status.scsw.count = ccw.count - len; +ccw_dstream_write_buf (&sch->cds, sch->sense_data, len);
Well, I oversaw this when I reviewed:
I think you should test the return value of ccw_dstream_write_buf here.
hw/s390x/css.c static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr, · line 934
Quoted 11 lines
hw/s390x/css.c +2
-2+ sch->curr_status.scsw.count =ccw_dstream_residual_count (&sch->cds);memset (sch->sense_data,0 ,sizeof (sch->sense_data)); ret =0 ;break ;@@ -930,8 +931,8 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr, }else { sense_id.reserved =0 ; } -cpu_physical_memory_write (ccw.cda, &sense_id, len); - sch->curr_status.scsw.count = ccw.count - len; +ccw_dstream_write_buf (&sch->cds, &sense_id, len);
and here
Quoted 5 lines
hw/s390x/css.c +1
-0+ sch->curr_status.scsw.count =ccw_dstream_residual_count (&sch->cds); ret =0 ;break ; }
Signature · 2 lines
Pierre Morel Linux/KVM/QEMU in Böblingen - Germany
PATCH v3 3/5 virtio-ccw: use ccw data stream
In reply to Halil PasicReplace direct access which implicitly assumes no IDA or MIDA with the new ccw data stream interface which should cope with these transparently in the future.
--- hw/s390x/virtio-ccw.c | 157 +++++++++++++++----------------------------------- 1 file changed, 46 insertions(+), 111 deletions(-)
hw/s390x/virtio-ccw.c +46 -111
@@ -287,49 +287,19 @@ static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len,return -EFAULT ; }if (is_legacy) { - linfo.queue =address_space_ldq_be (&address_space_memory, ccw.cda, -MEMTXATTRS_UNSPECIFIED ,NULL ); - linfo.align =address_space_ldl_be (&address_space_memory, - ccw.cda +sizeof (linfo.queue), -MEMTXATTRS_UNSPECIFIED , -NULL ); - linfo.index =address_space_lduw_be (&address_space_memory, - ccw.cda +sizeof (linfo.queue) - +sizeof (linfo.align), -MEMTXATTRS_UNSPECIFIED , -NULL ); - linfo.num =address_space_lduw_be (&address_space_memory, - ccw.cda +sizeof (linfo.queue) - +sizeof (linfo.align) - +sizeof (linfo.index), -MEMTXATTRS_UNSPECIFIED , -NULL ); +ccw_dstream_read (&sch->cds, linfo); +be64_to_cpus (&linfo.queue); +be32_to_cpus (&linfo.align); +be16_to_cpus (&linfo.index); +be16_to_cpus (&linfo.num); ret =virtio_ccw_set_vqs (sch,NULL , &linfo); }else { - info.desc =address_space_ldq_be (&address_space_memory, ccw.cda, -MEMTXATTRS_UNSPECIFIED ,NULL ); - info.index =address_space_lduw_be (&address_space_memory, - ccw.cda +sizeof (info.desc) - +sizeof (info.res0), -MEMTXATTRS_UNSPECIFIED ,NULL ); - info.num =address_space_lduw_be (&address_space_memory, - ccw.cda +sizeof (info.desc) - +sizeof (info.res0) - +sizeof (info.index), -MEMTXATTRS_UNSPECIFIED ,NULL ); - info.avail =address_space_ldq_be (&address_space_memory, - ccw.cda +sizeof (info.desc) - +sizeof (info.res0) - +sizeof (info.index) - +sizeof (info.num), -MEMTXATTRS_UNSPECIFIED ,NULL ); - info.used =address_space_ldq_be (&address_space_memory, - ccw.cda +sizeof (info.desc) - +sizeof (info.res0) - +sizeof (info.index) - +sizeof (info.num) - +sizeof (info.avail), -MEMTXATTRS_UNSPECIFIED ,NULL ); +ccw_dstream_read (&sch->cds, info); +be64_to_cpus (&info.desc); +be16_to_cpus (&info.index); +be16_to_cpus (&info.num); +be64_to_cpus (&info.avail); +be64_to_cpus (&info.used); ret =virtio_ccw_set_vqs (sch, &info,NULL ); } sch->curr_status.scsw.count =0 ;
@@ -342,15 +312,13 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)VirtioRevInfo revinfo;uint8_t status;VirtioFeatDesc features; -void *config;hwaddr indicators;VqConfigBlock vq_config;VirtioCcwDevice *dev = sch->driver_data;VirtIODevice *vdev =virtio_ccw_get_vdev (sch);bool check_len;int len; -hwaddr hw_len; -VirtioThinintInfo *thinint; +VirtioThinintInfo thinint;if (!dev) {return -EINVAL ;
@@ -394,11 +362,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) }else {VirtioDeviceClass *vdc =VIRTIO_DEVICE_GET_CLASS (vdev); - features.index =address_space_ldub (&address_space_memory, - ccw.cda - +sizeof (features.features), -MEMTXATTRS_UNSPECIFIED , -NULL ); +ccw_dstream_advance (&sch->cds,sizeof (features.features)); +ccw_dstream_read (&sch->cds, features.index);if (features.index ==0 ) {if (dev->revision >=1 ) {/* Don't offer legacy features for modern devices. */
@@ -417,9 +382,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)/* Return zeroes if the guest supports more feature bits. */ features.features =0 ; } -address_space_stl_le (&address_space_memory, ccw.cda, - features.features,MEMTXATTRS_UNSPECIFIED , -NULL ); +ccw_dstream_rewind (&sch->cds); +cpu_to_le32s (&features.features); +ccw_dstream_write (&sch->cds, features.features); sch->curr_status.scsw.count = ccw.count -sizeof (features); ret =0 ; }
@@ -438,15 +403,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)if (!ccw.cda) { ret = -EFAULT ; }else { - features.index =address_space_ldub (&address_space_memory, - ccw.cda - +sizeof (features.features), -MEMTXATTRS_UNSPECIFIED , -NULL ); - features.features =address_space_ldl_le (&address_space_memory, - ccw.cda, -MEMTXATTRS_UNSPECIFIED , -NULL ); +ccw_dstream_read (&sch->cds, features); +le32_to_cpus (&features.features);if (features.index ==0 ) { virtio_set_features(vdev, (vdev->guest_features & 0xffffffff00000000ULL) |
@@ -487,8 +445,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) ret = -EFAULT ; }else {virtio_bus_get_vdev_config (&dev->bus, vdev->config); -/* XXX config space endianness */ -cpu_physical_memory_write (ccw.cda, vdev->config, len); +ccw_dstream_write_buf (&sch->cds, vdev->config, len); sch->curr_status.scsw.count = ccw.count - len; ret =0 ; }
@@ -501,21 +458,13 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) } } len =MIN (ccw.count, vdev->config_len); - hw_len = len;if (!ccw.cda) { ret = -EFAULT ; }else { - config =cpu_physical_memory_map (ccw.cda, &hw_len,0 ); -if (!config) { - ret = -EFAULT ; - }else { - len = hw_len; -/* XXX config space endianness */ -memcpy (vdev->config, config, len); -cpu_physical_memory_unmap (config, hw_len,0 , hw_len); + ret =ccw_dstream_read_buf (&sch->cds, vdev->config, len); +if (!ret) {virtio_bus_set_vdev_config (&dev->bus, vdev->config); sch->curr_status.scsw.count = ccw.count - len; - ret =0 ; } }break ;
@@ -553,8 +502,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)if (!ccw.cda) { ret = -EFAULT ; }else { - status =address_space_ldub (&address_space_memory, ccw.cda, -MEMTXATTRS_UNSPECIFIED ,NULL ); +ccw_dstream_read (&sch->cds, status);if (!(status &VIRTIO_CONFIG_S_DRIVER_OK )) {virtio_ccw_stop_ioeventfd (dev); }
@@ -597,8 +545,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)if (!ccw.cda) { ret = -EFAULT ; }else { - indicators =address_space_ldq_be (&address_space_memory, ccw.cda, -MEMTXATTRS_UNSPECIFIED ,NULL ); +ccw_dstream_read (&sch->cds, indicators); +be64_to_cpus (&indicators); dev->indicators =get_indicator (indicators,sizeof (uint64_t )); sch->curr_status.scsw.count = ccw.count -sizeof (indicators); ret =0 ;
@@ -618,8 +566,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)if (!ccw.cda) { ret = -EFAULT ; }else { - indicators =address_space_ldq_be (&address_space_memory, ccw.cda, -MEMTXATTRS_UNSPECIFIED ,NULL ); +ccw_dstream_read (&sch->cds, indicators); +be64_to_cpus (&indicators); dev->indicators2 =get_indicator (indicators,sizeof (uint64_t )); sch->curr_status.scsw.count = ccw.count -sizeof (indicators); ret =0 ;
@@ -639,67 +587,58 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)if (!ccw.cda) { ret = -EFAULT ; }else { - vq_config.index =address_space_lduw_be (&address_space_memory, - ccw.cda, -MEMTXATTRS_UNSPECIFIED , -NULL ); +ccw_dstream_read (&sch->cds, vq_config.index); +be16_to_cpus (&vq_config.index);if (vq_config.index >=VIRTIO_QUEUE_MAX ) { ret = -EINVAL ;break ; } vq_config.num_max =virtio_queue_get_num (vdev, vq_config.index); -address_space_stw_be (&address_space_memory, - ccw.cda +sizeof (vq_config.index), - vq_config.num_max, -MEMTXATTRS_UNSPECIFIED , -NULL ); +cpu_to_be16s (&vq_config.num_max); +ccw_dstream_write (&sch->cds, vq_config.num_max); sch->curr_status.scsw.count = ccw.count -sizeof (vq_config); ret =0 ; }break ;case CCW_CMD_SET_IND_ADAPTER :if (check_len) { -if (ccw.count !=sizeof (*thinint)) { +if (ccw.count !=sizeof (thinint)) { ret = -EINVAL ;break ; } - }else if (ccw.count <sizeof (*thinint)) { + }else if (ccw.count <sizeof (thinint)) {/* Can't execute command. */ ret = -EINVAL ;break ; } - len =sizeof (*thinint); - hw_len = len;if (!ccw.cda) { ret = -EFAULT ; }else if (dev->indicators && !sch->thinint_active) {/* Trigger a command reject. */ ret = -ENOSYS ; }else { - thinint =cpu_physical_memory_map (ccw.cda, &hw_len,0 ); -if (!thinint) { +if (ccw_dstream_read (&sch->cds, thinint)) { ret = -EFAULT ; }else { -uint64_t ind_bit =ldq_be_p (&thinint->ind_bit); +be64_to_cpus (&thinint.ind_bit); +be64_to_cpus (&thinint.summary_indicator); +be64_to_cpus (&thinint.device_indicator); - len = hw_len; dev->summary_indicator = -get_indicator (ldq_be_p (&thinint->summary_indicator), -sizeof (uint8_t )); +get_indicator (thinint.summary_indicator,sizeof (uint8_t )); dev->indicators = -get_indicator (ldq_be_p (&thinint->device_indicator), - ind_bit /8 +1 ); - dev->thinint_isc = thinint->isc; - dev->routes.adapter.ind_offset = ind_bit; +get_indicator (thinint.device_indicator, + thinint.ind_bit /8 +1 ); + dev->thinint_isc = thinint.isc; + dev->routes.adapter.ind_offset = thinint.ind_bit; dev->routes.adapter.summary_offset =7 ; -cpu_physical_memory_unmap (thinint, hw_len,0 , hw_len); dev->routes.adapter.adapter_id =css_get_adapter_id (CSS_IO_ADAPTER_VIRTIO , dev->thinint_isc); sch->thinint_active = ((dev->indicators !=NULL ) && (dev->summary_indicator !=NULL )); - sch->curr_status.scsw.count = ccw.count - len; + sch->curr_status.scsw.count = ccw.count -sizeof (thinint); ret =0 ; } }
@@ -714,13 +653,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) ret = -EFAULT ;break ; } - revinfo.revision = -address_space_lduw_be (&address_space_memory, ccw.cda, -MEMTXATTRS_UNSPECIFIED ,NULL ); - revinfo.length = -address_space_lduw_be (&address_space_memory, - ccw.cda +sizeof (revinfo.revision), -MEMTXATTRS_UNSPECIFIED ,NULL ); +ccw_dstream_read_buf (&sch->cds, &revinfo,4 ); +be16_to_cpus (&revinfo.revision); +be16_to_cpus (&revinfo.length);if (ccw.count < len + revinfo.length || (check_len && ccw.count > len + revinfo.length)) { ret = -EINVAL ;
Signature · 1 line
2.13.5
Re: [Qemu-devel] [PATCH v3 3/5] virtio-ccw: use ccw data stream
Quoted 10 lines · Halil Pasic
Replace direct access which implicitly assumes no IDA or MIDA with the new ccw data stream interface which should cope with these transparently in the future.
Signed-off-by Halil Pasic <[email protected]>Reviewed-by Pierre Morel<[email protected]>--- hw/s390x/virtio-ccw.c | 157 +++++++++++++++----------------------------------- 1 file changed, 46 insertions(+), 111 deletions(-)
[...]
Signature · 1 line
Dong Jia Shi
Re: [Qemu-devel] [PATCH v3 3/5] virtio-ccw: use ccw data stream
In reply to Halil PasicQuoted 12 lines · On Tue, 19 Sep 2017 20:27:43 +0200 Halil Pasic <[email protected]> wrote:
Replace direct access which implicitly assumes no IDA or MIDA with the new ccw data stream interface which should cope with these transparently in the future.
Signed-off-by Halil Pasic <[email protected]>Reviewed-by Pierre Morel<[email protected]>--- hw/s390x/virtio-ccw.c | 157 +++++++++++++++----------------------------------- 1 file changed, 46 insertions(+), 111 deletions(-)
hw/s390x/virtio-ccw.c static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) · line 388
Quoted 10 lines
hw/s390x/virtio-ccw.c +3
-3@@ -417,9 +382,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)/* Return zeroes if the guest supports more feature bits. */ features.features =0 ; } -address_space_stl_le (&address_space_memory, ccw.cda, - features.features,MEMTXATTRS_UNSPECIFIED , -NULL ); +ccw_dstream_rewind (&sch->cds); +cpu_to_le32s (&features.features); +ccw_dstream_write (&sch->cds, features.features); sch->curr_status.scsw.count = ccw.count -sizeof (features);
Hm, didn't you want to convert these as well? Or do you plan to do it as an add-on patch?
Quoted 2 lines
(quoted diff) +0
-0ret = 0; }
Re: [Qemu-devel] [PATCH v3 3/5] virtio-ccw: use ccw data stream
Quoted 14 lines · Cornelia Huck
Quoted 10 lines · On Tue, 19 Sep 2017 20:27:43 +0200 Halil Pasic <[email protected]> wrote:
Replace direct access which implicitly assumes no IDA or MIDA with the new ccw data stream interface which should cope with these transparently in the future.
Signed-off-by Halil Pasic <[email protected]>Reviewed-by Pierre Morel<[email protected]>--- hw/s390x/virtio-ccw.c | 157 +++++++++++++++----------------------------------- 1 file changed, 46 insertions(+), 111 deletions(-)
Quoted 15 lines
hw/s390x/virtio-ccw.c static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) · line 388
Quoted 11 lines
hw/s390x/virtio-ccw.c +3
-3@@ -417,9 +382,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)/* Return zeroes if the guest supports more feature bits. */ features.features =0 ; } -address_space_stl_le (&address_space_memory, ccw.cda, - features.features,MEMTXATTRS_UNSPECIFIED , -NULL ); +ccw_dstream_rewind (&sch->cds); +cpu_to_le32s (&features.features); +ccw_dstream_write (&sch->cds, features.features); sch->curr_status.scsw.count = ccw.count -sizeof (features);Hm, didn't you want to convert these as well? Or do you plan to do it as an add-on patch?
I plan to do it as an add on patch.
Quoted 3 lines
Quoted 2 lines
(quoted diff) +0
-0ret = 0; }
Re: [Qemu-devel] [PATCH v3 3/5] virtio-ccw: use ccw data stream
Quoted 31 lines · On Wed, 20 Sep 2017 12:56:16 +0200 Halil Pasic <[email protected]> wrote:
Quoted 14 lines · Cornelia Huck
Quoted 10 lines · On Tue, 19 Sep 2017 20:27:43 +0200 Halil Pasic <[email protected]> wrote:
Replace direct access which implicitly assumes no IDA or MIDA with the new ccw data stream interface which should cope with these transparently in the future.
Signed-off-by Halil Pasic <[email protected]>Reviewed-by Pierre Morel<[email protected]>--- hw/s390x/virtio-ccw.c | 157 +++++++++++++++----------------------------------- 1 file changed, 46 insertions(+), 111 deletions(-)Quoted 15 lines
hw/s390x/virtio-ccw.c static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) · line 388
Quoted 11 lines
hw/s390x/virtio-ccw.c +3
-3@@ -417,9 +382,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)/* Return zeroes if the guest supports more feature bits. */ features.features =0 ; } -address_space_stl_le (&address_space_memory, ccw.cda, - features.features,MEMTXATTRS_UNSPECIFIED , -NULL ); +ccw_dstream_rewind (&sch->cds); +cpu_to_le32s (&features.features); +ccw_dstream_write (&sch->cds, features.features); sch->curr_status.scsw.count = ccw.count -sizeof (features);Hm, didn't you want to convert these as well? Or do you plan to do it as an add-on patch?
Quoted 1 line
I plan to do it as an add on patch.
OK, fine with me as well.
Re: [Qemu-devel] [PATCH v3 3/5] virtio-ccw: use ccw data stream
In reply to Halil PasicQuoted 25 lines · Halil Pasic
Replace direct access which implicitly assumes no IDA or MIDA with the new ccw data stream interface which should cope with these transparently in the future.
Signed-off-by Halil Pasic <[email protected]>Reviewed-by Pierre Morel<[email protected]>--- hw/s390x/virtio-ccw.c | 157 +++++++++++++++----------------------------------- 1 file changed, 46 insertions(+), 111 deletions(-)hw/s390x/virtio-ccw.c +0
-7@@ -287,49 +287,19 @@ static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len,return -EFAULT ; }if (is_legacy) { - linfo.queue =address_space_ldq_be (&address_space_memory, ccw.cda, -MEMTXATTRS_UNSPECIFIED ,NULL ); - linfo.align =address_space_ldl_be (&address_space_memory, - ccw.cda +sizeof (linfo.queue), -MEMTXATTRS_UNSPECIFIED , -NULL ); - linfo.index = address_space_lduw_be(&address_space_memory,
hw/s390x/virtio-ccw.c static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len, · line 306
Quoted 10 lines
hw/s390x/virtio-ccw.c +0
-10- ccw.cda +sizeof (linfo.queue) - +sizeof (linfo.align), -MEMTXATTRS_UNSPECIFIED , - NULL); - linfo.num =address_space_lduw_be (&address_space_memory, - ccw.cda +sizeof (linfo.queue) - +sizeof (linfo.align) - +sizeof (linfo.index), -MEMTXATTRS_UNSPECIFIED , -NULL );
Here again, I oversaw this.
Sorry.
hw/s390x/virtio-ccw.c static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len, · line 290
Quoted 1 line
hw/s390x/virtio-ccw.c +1
-0+ccw_dstream_read (&sch->cds, linfo);
Same as for patch 2/5:
Shouldn't you test the return value here?
Quoted 21 lines
hw/s390x/virtio-ccw.c +4
-15+be64_to_cpus (&linfo.queue); +be32_to_cpus (&linfo.align); +be16_to_cpus (&linfo.index); +be16_to_cpus (&linfo.num); ret =virtio_ccw_set_vqs (sch,NULL , &linfo); }else { - info.desc =address_space_ldq_be (&address_space_memory, ccw.cda, -MEMTXATTRS_UNSPECIFIED ,NULL ); - info.index =address_space_lduw_be (&address_space_memory, - ccw.cda +sizeof (info.desc) - +sizeof (info.res0), -MEMTXATTRS_UNSPECIFIED ,NULL ); - info.num =address_space_lduw_be (&address_space_memory, - ccw.cda +sizeof (info.desc) - +sizeof (info.res0) - +sizeof (info.index), -MEMTXATTRS_UNSPECIFIED ,NULL ); - info.avail =address_space_ldq_be (&address_space_memory, - ccw.cda +sizeof (info.desc) - +sizeof (info.res0) - + sizeof(info.index)
hw/s390x/virtio-ccw.c static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len, · line 297
Quoted 10 lines
hw/s390x/virtio-ccw.c +1
-9- +sizeof (info.num), - MEMTXATTRS_UNSPECIFIED, NULL); - info.used =address_space_ldq_be (&address_space_memory, - ccw.cda +sizeof (info.desc) - +sizeof (info.res0) - +sizeof (info.index) - +sizeof (info.num) - +sizeof (info.avail), -MEMTXATTRS_UNSPECIFIED ,NULL ); +ccw_dstream_read (&sch->cds, info);
and here
Quoted 26 lines
hw/s390x/virtio-ccw.c +6
-3+be64_to_cpus (&info.desc); +be16_to_cpus (&info.index); +be16_to_cpus (&info.num); +be64_to_cpus (&info.avail); +be64_to_cpus (&info.used); ret =virtio_ccw_set_vqs (sch, &info,NULL ); } sch->curr_status.scsw.count =0 ;@@ -342,15 +312,13 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)VirtioRevInfo revinfo;uint8_t status;VirtioFeatDesc features; -void *config;hwaddr indicators;VqConfigBlock vq_config;VirtioCcwDevice *dev = sch->driver_data;VirtIODevice *vdev =virtio_ccw_get_vdev (sch);bool check_len;int len; -hwaddr hw_len; -VirtioThinintInfo *thinint; +VirtioThinintInfo thinint;if (!dev) {return -EINVAL ;
hw/s390x/virtio-ccw.c static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) · line 366
Quoted 10 lines
hw/s390x/virtio-ccw.c +2
-5@@ -394,11 +362,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) }else {VirtioDeviceClass *vdc =VIRTIO_DEVICE_GET_CLASS (vdev); - features.index =address_space_ldub (&address_space_memory, - ccw.cda - +sizeof (features.features), -MEMTXATTRS_UNSPECIFIED , -NULL ); +ccw_dstream_advance (&sch->cds,sizeof (features.features)); +ccw_dstream_read (&sch->cds, features.index);
here again
Quoted 20 lines
hw/s390x/virtio-ccw.c +3
-3if (features.index ==0 ) {if (dev->revision >=1 ) {/* Don't offer legacy features for modern devices. */ @@ -417,9 +382,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)/* Return zeroes if the guest supports more feature bits. */ features.features =0 ; } -address_space_stl_le (&address_space_memory, ccw.cda, - features.features,MEMTXATTRS_UNSPECIFIED , -NULL ); +ccw_dstream_rewind (&sch->cds); +cpu_to_le32s (&features.features); +ccw_dstream_write (&sch->cds, features.features); sch->curr_status.scsw.count = ccw.count -sizeof (features); ret =0 ; }@@ -438,15 +403,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)if (!ccw.cda) { ret = -EFAULT ; }else {
hw/s390x/virtio-ccw.c static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) · line 406
Quoted 10 lines
hw/s390x/virtio-ccw.c +1
-9- features.index =address_space_ldub (&address_space_memory, - ccw.cda - +sizeof (features.features), -MEMTXATTRS_UNSPECIFIED , -NULL ); - features.features =address_space_ldl_le (&address_space_memory, - ccw.cda, -MEMTXATTRS_UNSPECIFIED , -NULL ); +ccw_dstream_read (&sch->cds, features);
... and everywhere where you use the IDA stream...
Pierre
Quoted 172 lines
hw/s390x/virtio-ccw.c +28
-50+le32_to_cpus (&features.features);if (features.index ==0 ) { virtio_set_features(vdev, (vdev->guest_features & 0xffffffff00000000ULL) |@@ -487,8 +445,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) ret = -EFAULT ; }else {virtio_bus_get_vdev_config (&dev->bus, vdev->config); -/* XXX config space endianness */ -cpu_physical_memory_write (ccw.cda, vdev->config, len); +ccw_dstream_write_buf (&sch->cds, vdev->config, len); sch->curr_status.scsw.count = ccw.count - len; ret =0 ; }@@ -501,21 +458,13 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) } } len =MIN (ccw.count, vdev->config_len); - hw_len = len;if (!ccw.cda) { ret = -EFAULT ; }else { - config =cpu_physical_memory_map (ccw.cda, &hw_len,0 ); -if (!config) { - ret = -EFAULT ; - }else { - len = hw_len; -/* XXX config space endianness */ -memcpy (vdev->config, config, len); -cpu_physical_memory_unmap (config, hw_len,0 , hw_len); + ret =ccw_dstream_read_buf (&sch->cds, vdev->config, len); +if (!ret) {virtio_bus_set_vdev_config (&dev->bus, vdev->config); sch->curr_status.scsw.count = ccw.count - len; - ret =0 ; } }break ;@@ -553,8 +502,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)if (!ccw.cda) { ret = -EFAULT ; }else { - status =address_space_ldub (&address_space_memory, ccw.cda, -MEMTXATTRS_UNSPECIFIED ,NULL ); +ccw_dstream_read (&sch->cds, status);if (!(status &VIRTIO_CONFIG_S_DRIVER_OK )) {virtio_ccw_stop_ioeventfd (dev); }@@ -597,8 +545,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)if (!ccw.cda) { ret = -EFAULT ; }else { - indicators =address_space_ldq_be (&address_space_memory, ccw.cda, -MEMTXATTRS_UNSPECIFIED ,NULL ); +ccw_dstream_read (&sch->cds, indicators); +be64_to_cpus (&indicators); dev->indicators =get_indicator (indicators,sizeof (uint64_t )); sch->curr_status.scsw.count = ccw.count -sizeof (indicators); ret =0 ;@@ -618,8 +566,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)if (!ccw.cda) { ret = -EFAULT ; }else { - indicators =address_space_ldq_be (&address_space_memory, ccw.cda, -MEMTXATTRS_UNSPECIFIED ,NULL ); +ccw_dstream_read (&sch->cds, indicators); +be64_to_cpus (&indicators); dev->indicators2 =get_indicator (indicators,sizeof (uint64_t )); sch->curr_status.scsw.count = ccw.count -sizeof (indicators); ret =0 ;@@ -639,67 +587,58 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)if (!ccw.cda) { ret = -EFAULT ; }else { - vq_config.index =address_space_lduw_be (&address_space_memory, - ccw.cda, -MEMTXATTRS_UNSPECIFIED , -NULL ); +ccw_dstream_read (&sch->cds, vq_config.index); +be16_to_cpus (&vq_config.index);if (vq_config.index >=VIRTIO_QUEUE_MAX ) { ret = -EINVAL ;break ; } vq_config.num_max =virtio_queue_get_num (vdev, vq_config.index); -address_space_stw_be (&address_space_memory, - ccw.cda +sizeof (vq_config.index), - vq_config.num_max, -MEMTXATTRS_UNSPECIFIED , -NULL ); +cpu_to_be16s (&vq_config.num_max); +ccw_dstream_write (&sch->cds, vq_config.num_max); sch->curr_status.scsw.count = ccw.count -sizeof (vq_config); ret =0 ; }break ;case CCW_CMD_SET_IND_ADAPTER :if (check_len) { -if (ccw.count !=sizeof (*thinint)) { +if (ccw.count !=sizeof (thinint)) { ret = -EINVAL ;break ; } - }else if (ccw.count <sizeof (*thinint)) { + }else if (ccw.count <sizeof (thinint)) {/* Can't execute command. */ ret = -EINVAL ;break ; } - len =sizeof (*thinint); - hw_len = len;if (!ccw.cda) { ret = -EFAULT ; }else if (dev->indicators && !sch->thinint_active) {/* Trigger a command reject. */ ret = -ENOSYS ; }else { - thinint =cpu_physical_memory_map (ccw.cda, &hw_len,0 ); -if (!thinint) { +if (ccw_dstream_read (&sch->cds, thinint)) { ret = -EFAULT ; }else { -uint64_t ind_bit =ldq_be_p (&thinint->ind_bit); +be64_to_cpus (&thinint.ind_bit); +be64_to_cpus (&thinint.summary_indicator); +be64_to_cpus (&thinint.device_indicator); - len = hw_len; dev->summary_indicator = -get_indicator (ldq_be_p (&thinint->summary_indicator), -sizeof (uint8_t )); +get_indicator (thinint.summary_indicator,sizeof (uint8_t )); dev->indicators = -get_indicator (ldq_be_p (&thinint->device_indicator), - ind_bit /8 +1 ); - dev->thinint_isc = thinint->isc; - dev->routes.adapter.ind_offset = ind_bit; +get_indicator (thinint.device_indicator, + thinint.ind_bit /8 +1 ); + dev->thinint_isc = thinint.isc; + dev->routes.adapter.ind_offset = thinint.ind_bit; dev->routes.adapter.summary_offset =7 ; -cpu_physical_memory_unmap (thinint, hw_len,0 , hw_len); dev->routes.adapter.adapter_id =css_get_adapter_id (CSS_IO_ADAPTER_VIRTIO , dev->thinint_isc); sch->thinint_active = ((dev->indicators !=NULL ) && (dev->summary_indicator !=NULL )); - sch->curr_status.scsw.count = ccw.count - len; + sch->curr_status.scsw.count = ccw.count -sizeof (thinint); ret =0 ; } }@@ -714,13 +653,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) ret = -EFAULT ;break ; } - revinfo.revision = -address_space_lduw_be (&address_space_memory, ccw.cda, -MEMTXATTRS_UNSPECIFIED ,NULL ); - revinfo.length = -address_space_lduw_be (&address_space_memory, - ccw.cda +sizeof (revinfo.revision), -MEMTXATTRS_UNSPECIFIED ,NULL ); +ccw_dstream_read_buf (&sch->cds, &revinfo,4 ); +be16_to_cpus (&revinfo.revision); +be16_to_cpus (&revinfo.length);if (ccw.count < len + revinfo.length || (check_len && ccw.count > len + revinfo.length)) { ret = -EINVAL ;
Signature · 2 lines
Pierre Morel Linux/KVM/QEMU in Böblingen - Germany
Re: [Qemu-devel] [PATCH v3 3/5] virtio-ccw: use ccw data stream
Quoted 40 lines · Pierre Morel
Quoted 25 lines · Halil Pasic
Replace direct access which implicitly assumes no IDA or MIDA with the new ccw data stream interface which should cope with these transparently in the future.
Signed-off-by Halil Pasic <[email protected]>Reviewed-by Pierre Morel<[email protected]>---
hw/s390x/virtio-ccw.c| 157 +++++++++++++++-----------------------------------1 file changed, 46 insertions(+), 111 deletions(-)hw/s390x/virtio-ccw.c +0
-7@@ -287,49 +287,19 @@ static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len, return -EFAULT; } if (is_legacy) { - linfo.queue = address_space_ldq_be(&address_space_memory, ccw.cda, - MEMTXATTRS_UNSPECIFIED, NULL); - linfo.align = address_space_ldl_be(&address_space_memory, - ccw.cda + sizeof(linfo.queue), - MEMTXATTRS_UNSPECIFIED, - NULL); - linfo.index = address_space_lduw_be(&address_space_memory,hw/s390x/virtio-ccw.c static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len, · line 306
Quoted 10 lines
hw/s390x/virtio-ccw.c +0
-10- ccw.cda + sizeof(linfo.queue) - + sizeof(linfo.align), - MEMTXATTRS_UNSPECIFIED, - NULL); - linfo.num = address_space_lduw_be(&address_space_memory, - ccw.cda + sizeof(linfo.queue) - + sizeof(linfo.align) - + sizeof(linfo.index), - MEMTXATTRS_UNSPECIFIED, - NULL);Here again, I oversaw this.
Sorry.
Quoted 5 lines
hw/s390x/virtio-ccw.c static int virtio_ccw_handle_set_vq(SubchDev *sch, CCW1 ccw, bool check_len, · line 290
Quoted 1 line
hw/s390x/virtio-ccw.c +1
-0+ ccw_dstream_read(&sch->cds, linfo);Same as for patch 2/5:
Shouldn't you test the return value here?
It's keep the change minimal policy. Later we can discuss tightening the checks. For now I don't want to introduce any new ones.
Halil
PATCH v3 4/5 390x/css: introduce maximum data address checking
In reply to Halil PasicThe architecture mandates the addresses to be accessed on the first indirection level (that is, the data addresses without IDA, and the (M)IDAW addresses with (M)IDA) to be checked against an CCW format dependent limit maximum address. If a violation is detected, the storage access is not to be performed and a channel program check needs to be generated. As of today, we fail to do this check.
Let us stick even closer to the architecture specification.
--- hw/s390x/css.c | 10 ++++++++++ include/hw/s390x/css.h | 1 + 2 files changed, 11 insertions(+)
hw/s390x/css.c +10 -0
@@ -795,6 +795,11 @@ static inline int cds_check_len(CcwDataStream *cds, int len)return cds->flags &CDS_F_STREAM_BROKEN ? -EINVAL : len; } +static inline bool cds_ccw_addrs_ok (hwaddr addr,int len,bool ccw_fmt1) +{ +return (addr + len) < (ccw_fmt1 ? (1UL <<31 ) : (1UL <<24 )); +} +static int ccw_dstream_rw_noflags (CcwDataStream *cds,void *buff,int len,CcwDataStreamOp op) {
@@ -804,6 +809,9 @@ static int ccw_dstream_rw_noflags(CcwDataStream *cds, void *buff, int len,if (ret <=0 ) {return ret; } +if (!cds_ccw_addrs_ok (cds->cda, len, cds->flags &CDS_F_FMT )) { +return -EINVAL ;/* channel program check */ + }if (op ==CDS_OP_A ) { goto incr; }
@@ -828,7 +836,9 @@ void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb)g_assert (!(orb->ctrl1 &ORB_CTRL1_MASK_MIDAW )); cds->flags = (orb->ctrl0 &ORB_CTRL0_MASK_I2K ?CDS_F_I2K :0 ) | (orb->ctrl0 &ORB_CTRL0_MASK_C64 ?CDS_F_C64 :0 ) | + (orb->ctrl0 &ORB_CTRL0_MASK_FMT ?CDS_F_FMT :0 ) | (ccw->flags &CCW_FLAG_IDA ?CDS_F_IDA :0 ); + cds->count = ccw->count; cds->cda_orig = ccw->cda;ccw_dstream_rewind (cds);
include/hw/s390x/css.h +1 -0
@@ -87,6 +87,7 @@ typedef struct CcwDataStream {#define CDS_F_MIDA 0x02#define CDS_F_I2K 0x04#define CDS_F_C64 0x08 +#define CDS_F_FMT 0x10/* CCW format-1 */ #define CDS_F_STREAM_BROKEN 0x80uint8_t flags;uint8_t at_idaw;
Signature · 1 line
2.13.5
Re: [Qemu-devel] [PATCH v3 4/5] 390x/css: introduce maximum data address checking
Quoted 42 lines · Halil Pasic
The architecture mandates the addresses to be accessed on the first indirection level (that is, the data addresses without IDA, and the (M)IDAW addresses with (M)IDA) to be checked against an CCW format dependent limit maximum address. If a violation is detected, the storage access is not to be performed and a channel program check needs to be generated. As of today, we fail to do this check.
Let us stick even closer to the architecture specification.
Signed-off-by Halil Pasic <[email protected]>--- hw/s390x/css.c | 10 ++++++++++ include/hw/s390x/css.h | 1 + 2 files changed, 11 insertions(+)hw/s390x/css.c +8
-0@@ -795,6 +795,11 @@ static inline int cds_check_len(CcwDataStream *cds, int len)return cds->flags &CDS_F_STREAM_BROKEN ? -EINVAL : len; } +static inline bool cds_ccw_addrs_ok (hwaddr addr,int len,bool ccw_fmt1) +{ +return (addr + len) < (ccw_fmt1 ? (1UL <<31 ) : (1UL <<24 )); +} +static int ccw_dstream_rw_noflags (CcwDataStream *cds,void *buff,int len,CcwDataStreamOp op) {@@ -804,6 +809,9 @@ static int ccw_dstream_rw_noflags(CcwDataStream *cds, void *buff, int len,if (ret <=0 ) {return ret; } +if (!cds_ccw_addrs_ok (cds->cda, len, cds->flags &CDS_F_FMT )) { +return -EINVAL ;/* channel program check */ + }if (op ==CDS_OP_A ) { goto incr; }
hw/s390x/css.c void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb) · line 839
Quoted 4 lines
hw/s390x/css.c +1
-0@@ -828,7 +836,9 @@ void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb)g_assert (!(orb->ctrl1 &ORB_CTRL1_MASK_MIDAW )); cds->flags = (orb->ctrl0 &ORB_CTRL0_MASK_I2K ?CDS_F_I2K :0 ) | (orb->ctrl0 &ORB_CTRL0_MASK_C64 ?CDS_F_C64 :0 ) | + (orb->ctrl0 & ORB_CTRL0_MASK_FMT ? CDS_F_FMT : 0) |
This reminds me one more question:
Calling ccw_dsteram_init() after copy_ccw_from_guest() may lead to a fmt-1 @ccw with an @orb that designates fmt-0 ccw. This sounds insane.
Quoted 20 lines
hw/s390x/css.c +1
-0(ccw->flags &CCW_FLAG_IDA ?CDS_F_IDA :0 ); + cds->count = ccw->count; cds->cda_orig = ccw->cda;ccw_dstream_rewind (cds);include/hw/s390x/css.h +1
-0@@ -87,6 +87,7 @@ typedef struct CcwDataStream {#define CDS_F_MIDA 0x02#define CDS_F_I2K 0x04#define CDS_F_C64 0x08 +#define CDS_F_FMT 0x10/* CCW format-1 */ #define CDS_F_STREAM_BROKEN 0x80uint8_t flags;uint8_t at_idaw;Signature · 1 line
2.13.5
Signature · 1 line
Dong Jia Shi
Re: [Qemu-devel] [PATCH v3 4/5] 390x/css: introduce maximum data address checking
Quoted 10 lines · On Wed, 20 Sep 2017 15:47:51 +0800 Dong Jia Shi <[email protected]>…
hw/s390x/css.c void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb) · line 839
Quoted 5 lines · Halil Pasic
hw/s390x/css.c +1
-0@@ -828,7 +836,9 @@ void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb)g_assert (!(orb->ctrl1 &ORB_CTRL1_MASK_MIDAW )); cds->flags = (orb->ctrl0 &ORB_CTRL0_MASK_I2K ?CDS_F_I2K :0 ) | (orb->ctrl0 &ORB_CTRL0_MASK_C64 ?CDS_F_C64 :0 ) | + (orb->ctrl0 & ORB_CTRL0_MASK_FMT ? CDS_F_FMT : 0) |This reminds me one more question:
Callingccw_dsteram_init()aftercopy_ccw_from_guest()may lead to a fmt-1 @ccw with an @orb that designates fmt-0 ccw. This sounds insane.
That's just a consequence of us translating everything to format-1 ccws. A bit confusing, but no problem if we pay attention to the format bit everywhere it makes a difference.
Re: [Qemu-devel] [PATCH v3 4/5] 390x/css: introduce maximum data address checking
Quoted 14 lines · Cornelia Huck
Quoted 10 lines · On Wed, 20 Sep 2017 15:47:51 +0800 Dong Jia Shi <[email protected]>…
hw/s390x/css.c void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb) · line 839
Quoted 5 lines · Halil Pasic
hw/s390x/css.c +1
-0@@ -828,7 +836,9 @@ void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb)g_assert (!(orb->ctrl1 &ORB_CTRL1_MASK_MIDAW )); cds->flags = (orb->ctrl0 &ORB_CTRL0_MASK_I2K ?CDS_F_I2K :0 ) | (orb->ctrl0 &ORB_CTRL0_MASK_C64 ?CDS_F_C64 :0 ) | + (orb->ctrl0 & ORB_CTRL0_MASK_FMT ? CDS_F_FMT : 0) |This reminds me one more question:
Callingccw_dsteram_init()aftercopy_ccw_from_guest()may lead to a fmt-1 @ccw with an @orb that designates fmt-0 ccw. This sounds insane.
Quoted 4 lines
That's just a consequence of us translating everything to format-1 ccws. A bit confusing, but no problem if we pay attention to the format bit everywhere it makes a difference.
Agree.
Halil
Re: [Qemu-devel] [PATCH v3 4/5] 390x/css: introduce maximum data address checking
Quoted 17 lines · Halil Pasic
Quoted 14 lines · Cornelia Huck
Quoted 10 lines · On Wed, 20 Sep 2017 15:47:51 +0800 Dong Jia Shi <[email protected]>…
hw/s390x/css.c void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb) · line 839
Quoted 5 lines · Halil Pasic
hw/s390x/css.c +1
-0@@ -828,7 +836,9 @@ void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb)g_assert (!(orb->ctrl1 &ORB_CTRL1_MASK_MIDAW )); cds->flags = (orb->ctrl0 &ORB_CTRL0_MASK_I2K ?CDS_F_I2K :0 ) | (orb->ctrl0 &ORB_CTRL0_MASK_C64 ?CDS_F_C64 :0 ) | + (orb->ctrl0 & ORB_CTRL0_MASK_FMT ? CDS_F_FMT : 0) |This reminds me one more question:
Callingccw_dsteram_init()aftercopy_ccw_from_guest()may lead to a fmt-1 @ccw with an @orb that designates fmt-0 ccw. This sounds insane.
Quoted 6 lines
Quoted 4 lines
That's just a consequence of us translating everything to format-1 ccws. A bit confusing, but no problem if we pay attention to the format bit everywhere it makes a difference.
Agree.
Ok. I'm fine with this.
Quoted 2 lines
Halil
Signature · 1 line
Dong Jia Shi
Re: [Qemu-devel] [PATCH v3 4/5] 390x/css: introduce maximum data address checking
In reply to Halil PasicQuoted 20 lines · On Tue, 19 Sep 2017 20:27:44 +0200 Halil Pasic <[email protected]> wrote:
The architecture mandates the addresses to be accessed on the first indirection level (that is, the data addresses without IDA, and the (M)IDAW addresses with (M)IDA) to be checked against an CCW format dependent limit maximum address. If a violation is detected, the storage access is not to be performed and a channel program check needs to be generated. As of today, we fail to do this check.
Let us stick even closer to the architecture specification.
Signed-off-by Halil Pasic <[email protected]>--- hw/s390x/css.c | 10 ++++++++++ include/hw/s390x/css.h | 1 + 2 files changed, 11 insertions(+)hw/s390x/css.c +0
-0
hw/s390x/css.c static inline int cds_check_len(CcwDataStream *cds, int len) · line 798
Quoted 4 lines
hw/s390x/css.c +1
-0@@ -795,6 +795,11 @@ static inline int cds_check_len(CcwDataStream *cds, int len)return cds->flags &CDS_F_STREAM_BROKEN ? -EINVAL : len; } +static inline bool cds_ccw_addrs_ok (hwaddr addr,int len,bool ccw_fmt1)
cds_cda_limit_ok?
hw/s390x/css.c static inline int cds_check_len(CcwDataStream *cds, int len) · line 805
Quoted 7 lines
hw/s390x/css.c +4
-0+{ +return (addr + len) < (ccw_fmt1 ? (1UL <<31 ) : (1UL <<24 )); +} +static int ccw_dstream_rw_noflags (CcwDataStream *cds,void *buff,int len,CcwDataStreamOp op) {
Looks good.
Re: [Qemu-devel] [PATCH v3 4/5] 390x/css: introduce maximum data address checking
Quoted 26 lines · Cornelia Huck
Quoted 23 lines · On Tue, 19 Sep 2017 20:27:44 +0200 Halil Pasic <[email protected]> wrote:
The architecture mandates the addresses to be accessed on the first indirection level (that is, the data addresses without IDA, and the (M)IDAW addresses with (M)IDA) to be checked against an CCW format dependent limit maximum address. If a violation is detected, the storage access is not to be performed and a channel program check needs to be generated. As of today, we fail to do this check.
Let us stick even closer to the architecture specification.
Signed-off-by Halil Pasic <[email protected]>--- hw/s390x/css.c | 10 ++++++++++ include/hw/s390x/css.h | 1 + 2 files changed, 11 insertions(+)hw/s390x/css.c +0
-0@@ -795,6 +795,11 @@ static inline int cds_check_len(CcwDataStream *cds, int len)return cds->flags &CDS_F_STREAM_BROKEN ? -EINVAL : len; }
Quoted 4 lines
hw/s390x/css.c static inline int cds_check_len(CcwDataStream *cds, int len) · line 798
Quoted 1 line
hw/s390x/css.c +1
-0+static inline bool cds_ccw_addrs_ok (hwaddr addr,int len,bool ccw_fmt1)
cds_cda_limit_ok?
I use cda to point to the 2 level in case of IDA. This is about level 1 (addressed by the ccw directly). That's why I used ccw_addrs but if you think cds_cda_limit_ok is better I can live with that.
We could also think about renaming cds->cda. Btw what does cda stand for (channel data address is my guess)?
Regards,
Halil
Quoted 10 lines
hw/s390x/css.c static inline int cds_check_len(CcwDataStream *cds, int len) · line 805
Quoted 7 lines
hw/s390x/css.c +4
-0+{ +return (addr + len) < (ccw_fmt1 ? (1UL <<31 ) : (1UL <<24 )); +} +static int ccw_dstream_rw_noflags (CcwDataStream *cds,void *buff,int len,CcwDataStreamOp op) {Looks good.
Re: [Qemu-devel] [PATCH v3 4/5] 390x/css: introduce maximum data address checking
Quoted 27 lines · On Wed, 20 Sep 2017 13:34:21 +0200 Halil Pasic <[email protected]> wrote:
Quoted 26 lines · Cornelia Huck
Quoted 23 lines · On Tue, 19 Sep 2017 20:27:44 +0200 Halil Pasic <[email protected]> wrote:
The architecture mandates the addresses to be accessed on the first indirection level (that is, the data addresses without IDA, and the (M)IDAW addresses with (M)IDA) to be checked against an CCW format dependent limit maximum address. If a violation is detected, the storage access is not to be performed and a channel program check needs to be generated. As of today, we fail to do this check.
Let us stick even closer to the architecture specification.
Signed-off-by Halil Pasic <[email protected]>--- hw/s390x/css.c | 10 ++++++++++ include/hw/s390x/css.h | 1 + 2 files changed, 11 insertions(+)hw/s390x/css.c +0
-0@@ -795,6 +795,11 @@ static inline int cds_check_len(CcwDataStream *cds, int len)return cds->flags &CDS_F_STREAM_BROKEN ? -EINVAL : len; }
Quoted 8 lines
Quoted 4 lines
hw/s390x/css.c static inline int cds_check_len(CcwDataStream *cds, int len) · line 798
Quoted 1 line
hw/s390x/css.c +1
-0+static inline bool cds_ccw_addrs_ok (hwaddr addr,int len,bool ccw_fmt1)
cds_cda_limit_ok?I use cda to point to the 2 level in case of IDA. This is about level 1 (addressed by the ccw directly). That's why I used
ccw_addrsbut if you thinkcds_cda_limit_okis better I can live with that.
I don't care that much, tbh.
Quoted 3 lines
We could also think about renaming
cds->cda. Btw what does cda stand for (channel data address is my guess)?
Yes, cda should stand for 'channel data address'. Its usage in cds->cda is probably the source of this minor confusion.
But, as said, I don't really care that much; so unless one of the other folks has a strong opinion, feel free to leave as-is.
PATCH v3 5/5 s390x/css: support ccw IDA
In reply to Halil PasicLet's add indirect data addressing support for our virtual channel subsystem. This implementation does not bother with any kind of prefetching. We simply step through the IDAL on demand.
--- hw/s390x/css.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-)
hw/s390x/css.c +116 -1
@@ -827,6 +827,121 @@ incr:return 0 ; } +/* returns values between 1 and bsz, where bsz is a power of 2 */ +static inline uint16_t ida_continuous_left (hwaddr cda,uint64_t bsz) +{ +return bsz - (cda & (bsz -1 )); +} + +static inline uint64_t ccw_ida_block_size (uint8_t flags) +{ +if ((flags &CDS_F_C64 ) && !(flags &CDS_F_I2K )) { +return 1ULL <<12 ; + } +return 1ULL <<11 ; +} + +static inline int ida_read_next_idaw (CcwDataStream *cds,bool ccw_fmt1, +bool idaw_fmt_2) +{ +union {uint64_t fmt2;uint32_t fmt1; } idaw; +int ret; +hwaddr idaw_addr; + +if (idaw_fmt_2) { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt2) * cds->at_idaw; +if (idaw_addr &0x07 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret =address_space_rw (&address_space_memory, idaw_addr, +MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt2, +sizeof (idaw.fmt2), false); + cds->cda =be64_to_cpu (idaw.fmt2); + }else { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt1) * cds->at_idaw; +if (idaw_addr &0x03 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret =address_space_rw (&address_space_memory, idaw_addr, +MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt1, +sizeof (idaw.fmt1), false); + cds->cda =be64_to_cpu (idaw.fmt1); + } + ++(cds->at_idaw); +if (ret !=MEMTX_OK ) { +/* assume inaccessible address */ +return -EINVAL ;/* channel program check */ + + } +return 0 ; +} + +static int ccw_dstream_rw_ida (CcwDataStream *cds,void *buff,int len, +CcwDataStreamOp op) +{ +uint64_t bsz =ccw_ida_block_size (cds->flags); +int ret =0 ; +uint16_t cont_left, iter_len; +const bool idaw_fmt2 = cds->flags &CDS_F_C64 ; +bool ccw_fmt1 = cds->flags &CDS_F_FMT ; + + ret =cds_check_len (cds, len); +if (ret <=0 ) { +return ret; + } +if (!cds->at_idaw) { +/* read first idaw */ + ret =ida_read_next_idaw (cds, ccw_fmt1, idaw_fmt2); +if (ret) { + goto err; + } + cont_left =ida_continuous_left (cds->cda, bsz); + }else { + cont_left =ida_continuous_left (cds->cda, bsz); +if (cont_left == bsz) { + ret =ida_read_next_idaw (cds, ccw_fmt1, idaw_fmt2); +if (ret) { + goto err; + } +if (cds->cda & (bsz -1 )) { + ret = -EINVAL ;/* channel program check */ + goto err; + } + } + } +do { + iter_len =MIN (len, cont_left); +if (!idaw_fmt2 && (cds->cda + iter_len) >= (1ULL <<31 )) { + ret = -EINVAL ;/* channel program check */ + goto err; + } +if (op !=CDS_OP_A ) { + ret =address_space_rw (&address_space_memory, cds->cda, +MEMTXATTRS_UNSPECIFIED , buff, iter_len, op); +if (ret !=MEMTX_OK ) { +/* assume inaccessible address */ + ret = -EINVAL ;/* channel program check */ + goto err; + } + } + cds->at_byte += iter_len; + cds->cda += iter_len; + len -= iter_len; +if (!len) { +break ; + } + ret =ida_read_next_idaw (cds, ccw_fmt1, idaw_fmt2); +if (ret) { + goto err; + } + cont_left = bsz; + }while (true); +return ret; +err: + cds->flags |=CDS_F_STREAM_BROKEN ; +return ret; +} +void ccw_dstream_init (CcwDataStream *cds,CCW1 const *ccw,ORB const *orb) {/*
@@ -845,7 +960,7 @@ void ccw_dstream_init(CcwDataStream *cds, CCW1 const *ccw, ORB const *orb)if (!(cds->flags &CDS_F_IDA )) { cds->op_handler = ccw_dstream_rw_noflags; }else { -assert (false); + cds->op_handler = ccw_dstream_rw_ida; } }
Signature · 1 line
2.13.5
Re: [Qemu-devel] [PATCH v3 5/5] s390x/css: support ccw IDA
Quoted 35 lines · Halil Pasic
Let's add indirect data addressing support for our virtual channel subsystem. This implementation does not bother with any kind of prefetching. We simply step through the IDAL on demand.
Signed-off-by Halil Pasic <[email protected]>Signed-off-by Cornelia Huck <[email protected]>--- hw/s390x/css.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-)hw/s390x/css.c +17
-0@@ -827,6 +827,121 @@ incr:return 0 ; } +/* returns values between 1 and bsz, where bsz is a power of 2 */ +static inline uint16_t ida_continuous_left (hwaddr cda,uint64_t bsz) +{ +return bsz - (cda & (bsz -1 )); +} + +static inline uint64_t ccw_ida_block_size (uint8_t flags) +{ +if ((flags &CDS_F_C64 ) && !(flags &CDS_F_I2K )) { +return 1ULL <<12 ; + } +return 1ULL <<11 ; +} + +static inline int ida_read_next_idaw (CcwDataStream *cds,bool ccw_fmt1, +bool idaw_fmt_2) +{
hw/s390x/css.c incr: · line 856
Quoted 10 lines
hw/s390x/css.c +10
-0+union {uint64_t fmt2;uint32_t fmt1; } idaw; +int ret; +hwaddr idaw_addr; + +if (idaw_fmt_2) { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt2) * cds->at_idaw; +if (idaw_addr &0x07 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret = address_space_rw(&address_space_memory, idaw_addr,
Ahh, just got one question here:
Do we need to considerate endianess for idaw_addr?
hw/s390x/css.c incr: · line 868
Quoted 12 lines
hw/s390x/css.c +12
-0+MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt2, + sizeof(idaw.fmt2), false); + cds->cda =be64_to_cpu (idaw.fmt2); + }else { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt1) * cds->at_idaw; +if (idaw_addr &0x03 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret =address_space_rw (&address_space_memory, idaw_addr, +MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt1, +sizeof (idaw.fmt1), false); + cds->cda =be64_to_cpu (idaw.fmt1);
Still need to check bit 0x80000000 here I think.
hw/s390x/css.c incr: · line 874
Quoted 6 lines
hw/s390x/css.c +6
-0+ } + ++(cds->at_idaw); +if (ret !=MEMTX_OK ) { +/* assume inaccessible address */ +return -EINVAL ;/* channel program check */ +
Extra line.
hw/s390x/css.c incr: · line 886
Quoted 12 lines
hw/s390x/css.c +12
-0+ } +return 0 ; +} + +static int ccw_dstream_rw_ida (CcwDataStream *cds,void *buff,int len, +CcwDataStreamOp op) +{ +uint64_t bsz =ccw_ida_block_size (cds->flags); +int ret =0 ; +uint16_t cont_left, iter_len; +const bool idaw_fmt2 = cds->flags &CDS_F_C64 ; +bool ccw_fmt1 = cds->flags &CDS_F_FMT ;
Use 'const bool' either? Although I doubt the value of using const here. ;)
Quoted 5 lines
hw/s390x/css.c +5
-0+ + ret =cds_check_len (cds, len); +if (ret <=0 ) { +return ret; + }
[...]
Signature · 1 line
Dong Jia Shi
Re: [Qemu-devel] [PATCH v3 5/5] s390x/css: support ccw IDA
Quoted 41 lines · On Wed, 20 Sep 2017 15:42:38 +0800 Dong Jia Shi <[email protected]>…
Quoted 39 lines · Halil Pasic
Let's add indirect data addressing support for our virtual channel subsystem. This implementation does not bother with any kind of prefetching. We simply step through the IDAL on demand.
Signed-off-by Halil Pasic <[email protected]>Signed-off-by Cornelia Huck <[email protected]>--- hw/s390x/css.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-)hw/s390x/css.c +21
-0@@ -827,6 +827,121 @@ incr:return 0 ; } +/* returns values between 1 and bsz, where bsz is a power of 2 */ +static inline uint16_t ida_continuous_left (hwaddr cda,uint64_t bsz) +{ +return bsz - (cda & (bsz -1 )); +} + +static inline uint64_t ccw_ida_block_size (uint8_t flags) +{ +if ((flags &CDS_F_C64 ) && !(flags &CDS_F_I2K )) { +return 1ULL <<12 ; + } +return 1ULL <<11 ; +} + +static inline int ida_read_next_idaw (CcwDataStream *cds,bool ccw_fmt1, +bool idaw_fmt_2) +{ +union {uint64_t fmt2;uint32_t fmt1; } idaw; +int ret; +hwaddr idaw_addr; +
Quoted 8 lines
hw/s390x/css.c incr: · line 856
Quoted 6 lines
hw/s390x/css.c +6
-0+if (idaw_fmt_2) { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt2) * cds->at_idaw; +if (idaw_addr &0x07 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret = address_space_rw(&address_space_memory, idaw_addr,Ahh, just got one question here:
Do we need to considerate endianess foridaw_addr?
That is taken care of below.
And the previous version worked on my laptop via tcg ;)
Quoted 13 lines
hw/s390x/css.c incr: · line 868
Quoted 13 lines
hw/s390x/css.c +12
-0+MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt2, + sizeof(idaw.fmt2), false); + cds->cda =be64_to_cpu (idaw.fmt2); + }else { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt1) * cds->at_idaw; +if (idaw_addr &0x03 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret =address_space_rw (&address_space_memory, idaw_addr, +MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt1, +sizeof (idaw.fmt1), false); + cds->cda =be64_to_cpu (idaw.fmt1);
Quoted 1 line
Still need to check bit
0x80000000here I think.
Yes, I think this is 'must be zero' for format-1 idaws, and not covered by the ccw-format specific checks above. (Although the PoP can be a bit confusing with many similar terms...)
Quoted 9 lines
hw/s390x/css.c incr: · line 874
Quoted 7 lines
hw/s390x/css.c +6
-0+ } + ++(cds->at_idaw); +if (ret !=MEMTX_OK ) { +/* assume inaccessible address */ +return -EINVAL ;/* channel program check */ +Extra line.
Quoted 14 lines
hw/s390x/css.c incr: · line 886
Quoted 12 lines
hw/s390x/css.c +12
-0+ } +return 0 ; +} + +static int ccw_dstream_rw_ida (CcwDataStream *cds,void *buff,int len, +CcwDataStreamOp op) +{ +uint64_t bsz =ccw_ida_block_size (cds->flags); +int ret =0 ; +uint16_t cont_left, iter_len; +const bool idaw_fmt2 = cds->flags &CDS_F_C64 ; +bool ccw_fmt1 = cds->flags &CDS_F_FMT ;Use 'const bool' either? Although I doubt the value of using const here. ;)
Both being the same is still a good idea.
Quoted 9 lines
Quoted 6 lines
hw/s390x/css.c +5
-0+ + ret =cds_check_len (cds, len); +if (ret <=0 ) { +return ret; + }[...]
Re: [Qemu-devel] [PATCH v3 5/5] s390x/css: support ccw IDA
Quoted 53 lines · Cornelia Huck
Quoted 41 lines · On Wed, 20 Sep 2017 15:42:38 +0800 Dong Jia Shi <[email protected]>…
Quoted 39 lines · Halil Pasic
Let's add indirect data addressing support for our virtual channel subsystem. This implementation does not bother with any kind of prefetching. We simply step through the IDAL on demand.
Signed-off-by Halil Pasic <[email protected]>Signed-off-by Cornelia Huck <[email protected]>--- hw/s390x/css.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-)hw/s390x/css.c +21
-0@@ -827,6 +827,121 @@ incr:return 0 ; } +/* returns values between 1 and bsz, where bsz is a power of 2 */ +static inline uint16_t ida_continuous_left (hwaddr cda,uint64_t bsz) +{ +return bsz - (cda & (bsz -1 )); +} + +static inline uint64_t ccw_ida_block_size (uint8_t flags) +{ +if ((flags &CDS_F_C64 ) && !(flags &CDS_F_I2K )) { +return 1ULL <<12 ; + } +return 1ULL <<11 ; +} + +static inline int ida_read_next_idaw (CcwDataStream *cds,bool ccw_fmt1, +bool idaw_fmt_2) +{ +union {uint64_t fmt2;uint32_t fmt1; } idaw; +int ret; +hwaddr idaw_addr; +Quoted 8 lines
hw/s390x/css.c incr: · line 856
Quoted 6 lines
hw/s390x/css.c +6
-0+if (idaw_fmt_2) { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt2) * cds->at_idaw; +if (idaw_addr &0x07 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret = address_space_rw(&address_space_memory, idaw_addr,Ahh, just got one question here:
Do we need to considerate endianess foridaw_addr?
Quoted 3 lines
That is taken care of below.
And the previous version worked on my laptop via tcg ;)
Nod.
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
hw/s390x/css.c +12
-0+MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt2, + sizeof(idaw.fmt2), false); + cds->cda =be64_to_cpu (idaw.fmt2); + }else { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt1) * cds->at_idaw; +if (idaw_addr &0x03 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret =address_space_rw (&address_space_memory, idaw_addr, +MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt1, +sizeof (idaw.fmt1), false); + cds->cda =be64_to_cpu (idaw.fmt1);
Quoted 6 lines
Quoted 1 line
Still need to check bit
0x80000000here I think.Yes, I think this is 'must be zero' for format-1 idaws, and not covered by the ccw-format specific checks above. (Although the PoP can be a bit confusing with many similar terms...)
It's taken care of in ccw_dstream_rw_ida before the actual access happens. Code looks like this:
+ if (!idaw_fmt2 && (cds->cda + iter_len) >= (1ULL << 31)) {
+ ret = -EINVAL; /* channel program check */
+ goto err;
+ }
The idea was to have it similar to the non-indirect case.
Quoted 24 lines
Quoted 9 lines
hw/s390x/css.c incr: · line 874
Quoted 7 lines
hw/s390x/css.c +6
-0+ } + ++(cds->at_idaw); +if (ret !=MEMTX_OK ) { +/* assume inaccessible address */ +return -EINVAL ;/* channel program check */ +Extra line.
Quoted 14 lines
hw/s390x/css.c incr: · line 886
Quoted 12 lines
hw/s390x/css.c +12
-0+ } +return 0 ; +} + +static int ccw_dstream_rw_ida (CcwDataStream *cds,void *buff,int len, +CcwDataStreamOp op) +{ +uint64_t bsz =ccw_ida_block_size (cds->flags); +int ret =0 ; +uint16_t cont_left, iter_len; +const bool idaw_fmt2 = cds->flags &CDS_F_C64 ; +bool ccw_fmt1 = cds->flags &CDS_F_FMT ;Use 'const bool' either? Although I doubt the value of using const here. ;)
Quoted 2 lines
Both being the same is still a good idea.
Yeah. For which one should I go (with const or without)?
Quoted 10 lines
Quoted 9 lines
Quoted 6 lines
hw/s390x/css.c +5
-0+ + ret =cds_check_len (cds, len); +if (ret <=0 ) { +return ret; + }[...]
Re: [Qemu-devel] [PATCH v3 5/5] s390x/css: support ccw IDA
Quoted 32 lines · On Wed, 20 Sep 2017 13:13:01 +0200 Halil Pasic <[email protected]> wrote:
Quoted 17 lines · Cornelia Huck
Quoted 14 lines · On Wed, 20 Sep 2017 15:42:38 +0800 Dong Jia Shi <[email protected]>…
Quoted 12 lines · Halil Pasic
hw/s390x/css.c +12
-0+MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt2, + sizeof(idaw.fmt2), false); + cds->cda =be64_to_cpu (idaw.fmt2); + }else { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt1) * cds->at_idaw; +if (idaw_addr &0x03 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret =address_space_rw (&address_space_memory, idaw_addr, +MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt1, +sizeof (idaw.fmt1), false); + cds->cda =be64_to_cpu (idaw.fmt1);Quoted 6 lines
Quoted 1 line
Still need to check bit
0x80000000here I think.Yes, I think this is 'must be zero' for format-1 idaws, and not covered by the ccw-format specific checks above. (Although the PoP can be a bit confusing with many similar terms...)
It's taken care of in
ccw_dstream_rw_idabefore the actual access happens. Code looks like this:hw/s390x/css.c +4
-0+if (!idaw_fmt2 && (cds->cda + iter_len) >= (1ULL <<31 )) { + ret = -EINVAL ;/* channel program check */ + goto err; + }
Quoted 1 line
The idea was to have it similar to the non-indirect case.
<looks at patch again>
Ah, I was simply looking for the wrong pattern. Looks correct.
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
hw/s390x/css.c incr: · line 886
Quoted 8 lines
hw/s390x/css.c +8
-0+static int ccw_dstream_rw_ida (CcwDataStream *cds,void *buff,int len, +CcwDataStreamOp op) +{ +uint64_t bsz =ccw_ida_block_size (cds->flags); +int ret =0 ; +uint16_t cont_left, iter_len; +const bool idaw_fmt2 = cds->flags &CDS_F_C64 ; +bool ccw_fmt1 = cds->flags &CDS_F_FMT ;Use 'const bool' either? Although I doubt the value of using const here. ;)
Quoted 4 lines
Quoted 2 lines
Both being the same is still a good idea.
Yeah. For which one should I go (with const or without)?
For the one you prefer :) (I'm not sure if the const adds value here.)
Re: [Qemu-devel] [PATCH v3 5/5] s390x/css: support ccw IDA
Quoted 35 lines · Cornelia Huck
Quoted 32 lines · On Wed, 20 Sep 2017 13:13:01 +0200 Halil Pasic <[email protected]> wrote:
Quoted 17 lines · Cornelia Huck
Quoted 14 lines · On Wed, 20 Sep 2017 15:42:38 +0800 Dong Jia Shi <[email protected]>…
Quoted 12 lines · Halil Pasic
hw/s390x/css.c +12
-0+MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt2, + sizeof(idaw.fmt2), false); + cds->cda =be64_to_cpu (idaw.fmt2); + }else { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt1) * cds->at_idaw; +if (idaw_addr &0x03 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret =address_space_rw (&address_space_memory, idaw_addr, +MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt1, +sizeof (idaw.fmt1), false); + cds->cda =be64_to_cpu (idaw.fmt1);Quoted 6 lines
Quoted 1 line
Still need to check bit
0x80000000here I think.Yes, I think this is 'must be zero' for format-1 idaws, and not covered by the ccw-format specific checks above. (Although the PoP can be a bit confusing with many similar terms...)
It's taken care of in
ccw_dstream_rw_idabefore the actual access happens. Code looks like this:hw/s390x/css.c +4
-0+if (!idaw_fmt2 && (cds->cda + iter_len) >= (1ULL <<31 )) { + ret = -EINVAL ;/* channel program check */ + goto err; + }
Quoted 7 lines
Quoted 1 line
The idea was to have it similar to the non-indirect case.
<looks at patch again>
Ah, I was simply looking for the wrong pattern. Looks correct.
Thinking about this some more. Since in case of IDA we are guaranteed to never cross a block boundary with a single IDAW we won't ever cross block boundary. So we can do the check in ida_read_next_idaw by checking bit 0x80000000 on the ccw->cda. So we could keep idaw_fmt2 and ccw_fmt1 local to ida_read_next_idaw and save one goto err. I think that would look a bit nicer than what I have here in v3. Agree?
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
hw/s390x/css.c incr: · line 886
Quoted 8 lines
hw/s390x/css.c +8
-0+static int ccw_dstream_rw_ida (CcwDataStream *cds,void *buff,int len, +CcwDataStreamOp op) +{ +uint64_t bsz =ccw_ida_block_size (cds->flags); +int ret =0 ; +uint16_t cont_left, iter_len; +const bool idaw_fmt2 = cds->flags &CDS_F_C64 ; +bool ccw_fmt1 = cds->flags &CDS_F_FMT ;Use 'const bool' either? Although I doubt the value of using const here. ;)
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Both being the same is still a good idea.
Yeah. For which one should I go (with const or without)?
For the one you prefer :) (I'm not sure if the const adds value here.)
I think we generally don't care about const-ness in such situations, so I think I won't use consts.
I intend to fix the issues we have found and do a v4 tomorrow, unless somebody screams -- could do it today but I would like to give Dong Jia an opportunity to react. On the other hand waiting more that that will IMHO do us no favor either (I think of our storage/memory hierarchy).
Regards,
Halil
Re: [Qemu-devel] [PATCH v3 5/5] s390x/css: support ccw IDA
Quoted 46 lines · Halil Pasic
Quoted 35 lines · Cornelia Huck
Quoted 32 lines · On Wed, 20 Sep 2017 13:13:01 +0200 Halil Pasic <[email protected]> wrote:
Quoted 17 lines · Cornelia Huck
Quoted 14 lines · On Wed, 20 Sep 2017 15:42:38 +0800 Dong Jia Shi <[email protected]>…
Quoted 12 lines · Halil Pasic
hw/s390x/css.c +12
-0+MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt2, + sizeof(idaw.fmt2), false); + cds->cda =be64_to_cpu (idaw.fmt2); + }else { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt1) * cds->at_idaw; +if (idaw_addr &0x03 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret =address_space_rw (&address_space_memory, idaw_addr, +MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt1, +sizeof (idaw.fmt1), false); + cds->cda =be64_to_cpu (idaw.fmt1);Quoted 6 lines
Quoted 1 line
Still need to check bit
0x80000000here I think.Yes, I think this is 'must be zero' for format-1 idaws, and not covered by the ccw-format specific checks above. (Although the PoP can be a bit confusing with many similar terms...)
It's taken care of in
ccw_dstream_rw_idabefore the actual access happens. Code looks like this:hw/s390x/css.c +4
-0+if (!idaw_fmt2 && (cds->cda + iter_len) >= (1ULL <<31 )) { + ret = -EINVAL ;/* channel program check */ + goto err; + }Quoted 7 lines
Quoted 1 line
The idea was to have it similar to the non-indirect case.
<looks at patch again>
Ah, I was simply looking for the wrong pattern. Looks correct.
Quoted 6 lines
Thinking about this some more. Since in case of IDA we are guaranteed to never cross a block boundary with a single IDAW we won't ever cross block boundary. So we can do the check in
ida_read_next_idawby checking bit0x80000000on theccw->cda. So we could keepidaw_fmt2andccw_fmt1local toida_read_next_idawand save one goto err. I think that would look a bit nicer than what I have here in v3. Agree?
Agree. That would also do the check in the first place. Sounds better.
Quoted 20 lines
Quoted 12 lines
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
hw/s390x/css.c incr: · line 886
Quoted 9 lines
hw/s390x/css.c +8
-0+static int ccw_dstream_rw_ida (CcwDataStream *cds,void *buff,int len, +CcwDataStreamOp op) +{ +uint64_t bsz =ccw_ida_block_size (cds->flags); +int ret =0 ; +uint16_t cont_left, iter_len; +const bool idaw_fmt2 = cds->flags &CDS_F_C64 ; +bool ccw_fmt1 = cds->flags &CDS_F_FMT ;Use 'const bool' either? Although I doubt the value of using const here. ;)
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines
Both being the same is still a good idea.
Yeah. For which one should I go (with const or without)?
For the one you prefer :) (I'm not sure if the const adds value here.)
Quoted 6 lines
I think we generally don't care about const-ness in such situations, so I think I won't use consts.
I intend to fix the issues we have found and do a v4 tomorrow, unless somebody screams -- could do it today but I would like to give Dong Jia an opportunity to react.
Thanks. I'm coming. :)
Quoted 5 lines
On the other hand waiting more that that will IMHO do us no favor either (I think of our storage/memory hierarchy).
Regards,
Halil
Signature · 1 line
Dong Jia Shi
Re: [Qemu-devel] [PATCH v3 5/5] s390x/css: support ccw IDA
Quoted 9 lines · On Thu, 21 Sep 2017 08:50:36 +0800 Dong Jia Shi <[email protected]>…
Quoted 6 lines · Halil Pasic
Thinking about this some more. Since in case of IDA we are guaranteed to never cross a block boundary with a single IDAW we won't ever cross block boundary. So we can do the check in
ida_read_next_idawby checking bit0x80000000on theccw->cda. So we could keepidaw_fmt2andccw_fmt1local toida_read_next_idawand save one goto err. I think that would look a bit nicer than what I have here in v3. Agree?Agree. That would also do the check in the first place. Sounds better.
Can't argue with nicer code, either :) Looking forward to the next version.
Re: [Qemu-devel] [PATCH v3 5/5] s390x/css: support ccw IDA
In reply to Halil PasicQuoted 56 lines · Halil Pasic
Quoted 53 lines · Cornelia Huck
Quoted 49 lines · On Wed, 20 Sep 2017 15:42:38 +0800 Dong Jia Shi <[email protected]>…
Quoted 35 lines · Halil Pasic
Let's add indirect data addressing support for our virtual channel subsystem. This implementation does not bother with any kind of prefetching. We simply step through the IDAL on demand.
Signed-off-by Halil Pasic <[email protected]>Signed-off-by Cornelia Huck <[email protected]>--- hw/s390x/css.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-)hw/s390x/css.c +17
-0@@ -827,6 +827,121 @@ incr:return 0 ; } +/* returns values between 1 and bsz, where bsz is a power of 2 */ +static inline uint16_t ida_continuous_left (hwaddr cda,uint64_t bsz) +{ +return bsz - (cda & (bsz -1 )); +} + +static inline uint64_t ccw_ida_block_size (uint8_t flags) +{ +if ((flags &CDS_F_C64 ) && !(flags &CDS_F_I2K )) { +return 1ULL <<12 ; + } +return 1ULL <<11 ; +} + +static inline int ida_read_next_idaw (CcwDataStream *cds,bool ccw_fmt1, +bool idaw_fmt_2) +{hw/s390x/css.c incr: · line 856
Quoted 10 lines
hw/s390x/css.c +10
-0+union {uint64_t fmt2;uint32_t fmt1; } idaw; +int ret; +hwaddr idaw_addr; + +if (idaw_fmt_2) { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt2) * cds->at_idaw; +if (idaw_addr &0x07 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret = address_space_rw(&address_space_memory, idaw_addr,Ahh, just got one question here:
Do we need to considerate endianess foridaw_addr?
Quoted 5 lines
Quoted 3 lines
That is taken care of below.
And the previous version worked on my laptop via tcg ;)
Nod.
My fault!
I was thinking of the idaw_addr itself, not the content of it. Now I realized that, since we already converted (cds->cda_orig) in copy_ccw_from_guest(), there is no need to convert (idaw_addr + idaw_size * idaw_index) anymore.
Please ingnore my noise. ;P
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
Quoted 15 lines
hw/s390x/css.c +12
-0+MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt2, + sizeof(idaw.fmt2), false); + cds->cda =be64_to_cpu (idaw.fmt2); + }else { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt1) * cds->at_idaw; +if (idaw_addr &0x03 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret =address_space_rw (&address_space_memory, idaw_addr, +MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt1, +sizeof (idaw.fmt1), false); + cds->cda =be64_to_cpu (idaw.fmt1);
[...]
Signature · 1 line
Dong Jia Shi
Re: [Qemu-devel] [PATCH v3 5/5] s390x/css: support ccw IDA
In reply to Halil PasicQuoted 6 lines · On Tue, 19 Sep 2017 20:27:45 +0200 Halil Pasic <[email protected]> wrote:
Let's add indirect data addressing support for our virtual channel subsystem. This implementation does not bother with any kind of prefetching. We simply step through the IDAL on demand.
Signed-off-by Halil Pasic <[email protected]>Signed-off-by Cornelia Huck <[email protected]>
My s-o-b is a bit preliminary ;)
Quoted 26 lines
--- hw/s390x/css.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-)hw/s390x/css.c +14
-0@@ -827,6 +827,121 @@ incr:return 0 ; } +/* returns values between 1 and bsz, where bsz is a power of 2 */ +static inline uint16_t ida_continuous_left (hwaddr cda,uint64_t bsz) +{ +return bsz - (cda & (bsz -1 )); +} + +static inline uint64_t ccw_ida_block_size (uint8_t flags) +{ +if ((flags &CDS_F_C64 ) && !(flags &CDS_F_I2K )) { +return 1ULL <<12 ; + } +return 1ULL <<11 ; +} +
hw/s390x/css.c incr: · line 853
Quoted 10 lines
hw/s390x/css.c +10
-0+static inline int ida_read_next_idaw (CcwDataStream *cds,bool ccw_fmt1, +bool idaw_fmt_2) +{ +union {uint64_t fmt2;uint32_t fmt1; } idaw; +int ret; +hwaddr idaw_addr; + +if (idaw_fmt_2) { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt2) * cds->at_idaw; +if (idaw_addr &0x07 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) {
So, what is supposed to happen if the idaw_addr is not aligned correctly _and_ is violating the limits?
Quoted 24 lines
hw/s390x/css.c +24
-0+return -EINVAL ;/* channel program check */ + } + ret =address_space_rw (&address_space_memory, idaw_addr, +MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt2, +sizeof (idaw.fmt2), false); + cds->cda =be64_to_cpu (idaw.fmt2); + }else { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt1) * cds->at_idaw; +if (idaw_addr &0x03 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) { +return -EINVAL ;/* channel program check */ + } + ret =address_space_rw (&address_space_memory, idaw_addr, +MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt1, +sizeof (idaw.fmt1), false); + cds->cda =be64_to_cpu (idaw.fmt1); + } + ++(cds->at_idaw); +if (ret !=MEMTX_OK ) { +/* assume inaccessible address */ +return -EINVAL ;/* channel program check */ + + } +return 0 ; +}
Re: [Qemu-devel] [PATCH v3 5/5] s390x/css: support ccw IDA
Quoted 43 lines · Cornelia Huck
Quoted 6 lines · On Tue, 19 Sep 2017 20:27:45 +0200 Halil Pasic <[email protected]> wrote:
Let's add indirect data addressing support for our virtual channel subsystem. This implementation does not bother with any kind of prefetching. We simply step through the IDAL on demand.
Signed-off-by Halil Pasic <[email protected]>Signed-off-by Cornelia Huck <[email protected]>My s-o-b is a bit preliminary ;)
Quoted 31 lines
--- hw/s390x/css.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-)hw/s390x/css.c +19
-0@@ -827,6 +827,121 @@ incr:return 0 ; } +/* returns values between 1 and bsz, where bsz is a power of 2 */ +static inline uint16_t ida_continuous_left (hwaddr cda,uint64_t bsz) +{ +return bsz - (cda & (bsz -1 )); +} + +static inline uint64_t ccw_ida_block_size (uint8_t flags) +{ +if ((flags &CDS_F_C64 ) && !(flags &CDS_F_I2K )) { +return 1ULL <<12 ; + } +return 1ULL <<11 ; +} + +static inline int ida_read_next_idaw (CcwDataStream *cds,bool ccw_fmt1, +bool idaw_fmt_2) +{ +union {uint64_t fmt2;uint32_t fmt1; } idaw; +int ret;
Quoted 8 lines
hw/s390x/css.c incr: · line 853
Quoted 5 lines
hw/s390x/css.c +5
-0+hwaddr idaw_addr; + +if (idaw_fmt_2) { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt2) * cds->at_idaw; +if (idaw_addr &0x07 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) {So, what is supposed to happen if the
idaw_addris not aligned correctly _and_ is violating the limits?
You are right this is obviously wrong.
Should have been
if (idaw_addr & 0x07 || !cds_ccw_addrs_ok(idaw_addr, 0, ccw_fmt1)) {
Quoted 10 lines
hw/s390x/css.c incr: · line 862
Quoted 10 lines
hw/s390x/css.c +9
-0+return -EINVAL ;/* channel program check */ + } + ret =address_space_rw (&address_space_memory, idaw_addr, +MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt2, +sizeof (idaw.fmt2), false); + cds->cda =be64_to_cpu (idaw.fmt2); + }else { + idaw_addr = cds->cda_orig +sizeof (idaw.fmt1) * cds->at_idaw; +if (idaw_addr &0x03 &&cds_ccw_addrs_ok (idaw_addr,0 , ccw_fmt1)) {
Same here.
Quoted 16 lines
Quoted 15 lines
hw/s390x/css.c +15
-0+return -EINVAL ;/* channel program check */ + } + ret =address_space_rw (&address_space_memory, idaw_addr, +MEMTXATTRS_UNSPECIFIED , (void *) &idaw.fmt1, +sizeof (idaw.fmt1), false); + cds->cda =be64_to_cpu (idaw.fmt1); + } + ++(cds->at_idaw); +if (ret !=MEMTX_OK ) { +/* assume inaccessible address */ +return -EINVAL ;/* channel program check */ + + } +return 0 ; +}