* [PATCH 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use @ 2020-03-04 15:33 Philippe Mathieu-Daudé 2020-03-04 15:33 ` [PATCH 1/5] hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include Philippe Mathieu-Daudé ` (4 more replies) 0 siblings, 5 replies; 14+ messages in thread From: Philippe Mathieu-Daudé @ 2020-03-04 15:33 UTC (permalink / raw) To: qemu-devel Cc: Fam Zheng, qemu-ppc, Paolo Bonzini, Philippe Mathieu-Daudé, David Gibson This series fixes a dangerous zero-length array use. Simples patches first to clean the issue in the last patch: dissociate the buffer holding DMA requests with pointer to SRP Information Unit packets. Philippe Mathieu-Daudé (5): hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include hw/scsi/spapr_vscsi: Use SRP_MAX_IU_LEN instead of sizeof flexible array hw/scsi/spapr_vscsi: Simplify a bit hw/scsi/spapr_vscsi: Introduce req_ui() helper hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size hw/scsi/viosrp.h | 4 ++- hw/scsi/spapr_vscsi.c | 60 ++++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 27 deletions(-) -- 2.21.1 ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/5] hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include 2020-03-04 15:33 [PATCH 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Philippe Mathieu-Daudé @ 2020-03-04 15:33 ` Philippe Mathieu-Daudé 2020-03-05 0:39 ` David Gibson 2020-03-04 15:33 ` [PATCH 2/5] hw/scsi/spapr_vscsi: Use SRP_MAX_IU_LEN instead of sizeof flexible array Philippe Mathieu-Daudé ` (3 subsequent siblings) 4 siblings, 1 reply; 14+ messages in thread From: Philippe Mathieu-Daudé @ 2020-03-04 15:33 UTC (permalink / raw) To: qemu-devel Cc: Fam Zheng, qemu-ppc, Paolo Bonzini, Philippe Mathieu-Daudé, David Gibson This header use the srp_* structures declared in "hw/scsi/srp.h". Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> --- hw/scsi/viosrp.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/scsi/viosrp.h b/hw/scsi/viosrp.h index d8e365db1e..25676c2383 100644 --- a/hw/scsi/viosrp.h +++ b/hw/scsi/viosrp.h @@ -34,6 +34,8 @@ #ifndef PPC_VIOSRP_H #define PPC_VIOSRP_H +#include "hw/scsi/srp.h" + #define SRP_VERSION "16.a" #define SRP_MAX_IU_LEN 256 #define SRP_MAX_LOC_LEN 32 -- 2.21.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/5] hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include 2020-03-04 15:33 ` [PATCH 1/5] hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include Philippe Mathieu-Daudé @ 2020-03-05 0:39 ` David Gibson 0 siblings, 0 replies; 14+ messages in thread From: David Gibson @ 2020-03-05 0:39 UTC (permalink / raw) To: Philippe Mathieu-Daudé Cc: Fam Zheng, qemu-ppc, qemu-devel, Paolo Bonzini [-- Attachment #1: Type: text/plain, Size: 856 bytes --] On Wed, Mar 04, 2020 at 04:33:07PM +0100, Philippe Mathieu-Daudé wrote: > This header use the srp_* structures declared in "hw/scsi/srp.h". > > Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> Applied to ppc-for-5.0. > --- > hw/scsi/viosrp.h | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/hw/scsi/viosrp.h b/hw/scsi/viosrp.h > index d8e365db1e..25676c2383 100644 > --- a/hw/scsi/viosrp.h > +++ b/hw/scsi/viosrp.h > @@ -34,6 +34,8 @@ > #ifndef PPC_VIOSRP_H > #define PPC_VIOSRP_H > > +#include "hw/scsi/srp.h" > + > #define SRP_VERSION "16.a" > #define SRP_MAX_IU_LEN 256 > #define SRP_MAX_LOC_LEN 32 -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/5] hw/scsi/spapr_vscsi: Use SRP_MAX_IU_LEN instead of sizeof flexible array 2020-03-04 15:33 [PATCH 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Philippe Mathieu-Daudé 2020-03-04 15:33 ` [PATCH 1/5] hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include Philippe Mathieu-Daudé @ 2020-03-04 15:33 ` Philippe Mathieu-Daudé 2020-03-05 0:40 ` David Gibson 2020-03-04 15:33 ` [PATCH 3/5] hw/scsi/spapr_vscsi: Simplify a bit Philippe Mathieu-Daudé ` (2 subsequent siblings) 4 siblings, 1 reply; 14+ messages in thread From: Philippe Mathieu-Daudé @ 2020-03-04 15:33 UTC (permalink / raw) To: qemu-devel Cc: Fam Zheng, qemu-ppc, Paolo Bonzini, Philippe Mathieu-Daudé, David Gibson Replace sizeof() flexible arrays union srp_iu/viosrp_iu by the SRP_MAX_IU_LEN definition, which is what this code actually meant to use. Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> --- hw/scsi/spapr_vscsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 7d584e7732..7e397ed797 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -671,8 +671,8 @@ static void vscsi_process_login(VSCSIState *s, vscsi_req *req) */ rsp->req_lim_delta = cpu_to_be32(VSCSI_REQ_LIMIT-2); rsp->tag = tag; - rsp->max_it_iu_len = cpu_to_be32(sizeof(union srp_iu)); - rsp->max_ti_iu_len = cpu_to_be32(sizeof(union srp_iu)); + rsp->max_it_iu_len = cpu_to_be32(SRP_MAX_IU_LEN); + rsp->max_ti_iu_len = cpu_to_be32(SRP_MAX_IU_LEN); /* direct and indirect */ rsp->buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT); @@ -1088,7 +1088,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq) * in our 256 bytes IUs. If not we'll have to increase the size * of the structure. */ - if (crq->s.IU_length > sizeof(union viosrp_iu)) { + if (crq->s.IU_length > SRP_MAX_IU_LEN) { fprintf(stderr, "VSCSI: SRP IU too long (%d bytes) !\n", crq->s.IU_length); vscsi_put_req(req); -- 2.21.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 2/5] hw/scsi/spapr_vscsi: Use SRP_MAX_IU_LEN instead of sizeof flexible array 2020-03-04 15:33 ` [PATCH 2/5] hw/scsi/spapr_vscsi: Use SRP_MAX_IU_LEN instead of sizeof flexible array Philippe Mathieu-Daudé @ 2020-03-05 0:40 ` David Gibson 0 siblings, 0 replies; 14+ messages in thread From: David Gibson @ 2020-03-05 0:40 UTC (permalink / raw) To: Philippe Mathieu-Daudé Cc: Fam Zheng, qemu-ppc, qemu-devel, Paolo Bonzini [-- Attachment #1: Type: text/plain, Size: 1768 bytes --] On Wed, Mar 04, 2020 at 04:33:08PM +0100, Philippe Mathieu-Daudé wrote: > Replace sizeof() flexible arrays union srp_iu/viosrp_iu by the > SRP_MAX_IU_LEN definition, which is what this code actually meant > to use. > > Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> Applied to ppc-for-5.0 > --- > hw/scsi/spapr_vscsi.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c > index 7d584e7732..7e397ed797 100644 > --- a/hw/scsi/spapr_vscsi.c > +++ b/hw/scsi/spapr_vscsi.c > @@ -671,8 +671,8 @@ static void vscsi_process_login(VSCSIState *s, vscsi_req *req) > */ > rsp->req_lim_delta = cpu_to_be32(VSCSI_REQ_LIMIT-2); > rsp->tag = tag; > - rsp->max_it_iu_len = cpu_to_be32(sizeof(union srp_iu)); > - rsp->max_ti_iu_len = cpu_to_be32(sizeof(union srp_iu)); > + rsp->max_it_iu_len = cpu_to_be32(SRP_MAX_IU_LEN); > + rsp->max_ti_iu_len = cpu_to_be32(SRP_MAX_IU_LEN); > /* direct and indirect */ > rsp->buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT); > > @@ -1088,7 +1088,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq) > * in our 256 bytes IUs. If not we'll have to increase the size > * of the structure. > */ > - if (crq->s.IU_length > sizeof(union viosrp_iu)) { > + if (crq->s.IU_length > SRP_MAX_IU_LEN) { > fprintf(stderr, "VSCSI: SRP IU too long (%d bytes) !\n", > crq->s.IU_length); > vscsi_put_req(req); -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/5] hw/scsi/spapr_vscsi: Simplify a bit 2020-03-04 15:33 [PATCH 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Philippe Mathieu-Daudé 2020-03-04 15:33 ` [PATCH 1/5] hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include Philippe Mathieu-Daudé 2020-03-04 15:33 ` [PATCH 2/5] hw/scsi/spapr_vscsi: Use SRP_MAX_IU_LEN instead of sizeof flexible array Philippe Mathieu-Daudé @ 2020-03-04 15:33 ` Philippe Mathieu-Daudé 2020-03-05 0:40 ` David Gibson 2020-03-05 10:21 ` Greg Kurz 2020-03-04 15:33 ` [PATCH 4/5] hw/scsi/spapr_vscsi: Introduce req_ui() helper Philippe Mathieu-Daudé 2020-03-04 15:33 ` [PATCH 5/5] hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size Philippe Mathieu-Daudé 4 siblings, 2 replies; 14+ messages in thread From: Philippe Mathieu-Daudé @ 2020-03-04 15:33 UTC (permalink / raw) To: qemu-devel Cc: Fam Zheng, qemu-ppc, Paolo Bonzini, Philippe Mathieu-Daudé, David Gibson We already have a ui pointer, use it (to simplify the next commit). Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> --- hw/scsi/spapr_vscsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 7e397ed797..3cb5a38181 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -261,9 +261,9 @@ static int vscsi_send_rsp(VSCSIState *s, vscsi_req *req, if (status) { iu->srp.rsp.sol_not = (sol_not & 0x04) >> 2; if (req->senselen) { - req->iu.srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID; - req->iu.srp.rsp.sense_data_len = cpu_to_be32(req->senselen); - memcpy(req->iu.srp.rsp.data, req->sense, req->senselen); + iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID; + iu->srp.rsp.sense_data_len = cpu_to_be32(req->senselen); + memcpy(iu->srp.rsp.data, req->sense, req->senselen); total_len += req->senselen; } } else { -- 2.21.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 3/5] hw/scsi/spapr_vscsi: Simplify a bit 2020-03-04 15:33 ` [PATCH 3/5] hw/scsi/spapr_vscsi: Simplify a bit Philippe Mathieu-Daudé @ 2020-03-05 0:40 ` David Gibson 2020-03-05 10:21 ` Greg Kurz 1 sibling, 0 replies; 14+ messages in thread From: David Gibson @ 2020-03-05 0:40 UTC (permalink / raw) To: Philippe Mathieu-Daudé Cc: Fam Zheng, qemu-ppc, qemu-devel, Paolo Bonzini [-- Attachment #1: Type: text/plain, Size: 1380 bytes --] On Wed, Mar 04, 2020 at 04:33:09PM +0100, Philippe Mathieu-Daudé wrote: > We already have a ui pointer, use it (to simplify the next commit). > > Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> Applied to ppc-for-5.0. > --- > hw/scsi/spapr_vscsi.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c > index 7e397ed797..3cb5a38181 100644 > --- a/hw/scsi/spapr_vscsi.c > +++ b/hw/scsi/spapr_vscsi.c > @@ -261,9 +261,9 @@ static int vscsi_send_rsp(VSCSIState *s, vscsi_req *req, > if (status) { > iu->srp.rsp.sol_not = (sol_not & 0x04) >> 2; > if (req->senselen) { > - req->iu.srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID; > - req->iu.srp.rsp.sense_data_len = cpu_to_be32(req->senselen); > - memcpy(req->iu.srp.rsp.data, req->sense, req->senselen); > + iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID; > + iu->srp.rsp.sense_data_len = cpu_to_be32(req->senselen); > + memcpy(iu->srp.rsp.data, req->sense, req->senselen); > total_len += req->senselen; > } > } else { -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/5] hw/scsi/spapr_vscsi: Simplify a bit 2020-03-04 15:33 ` [PATCH 3/5] hw/scsi/spapr_vscsi: Simplify a bit Philippe Mathieu-Daudé 2020-03-05 0:40 ` David Gibson @ 2020-03-05 10:21 ` Greg Kurz 1 sibling, 0 replies; 14+ messages in thread From: Greg Kurz @ 2020-03-05 10:21 UTC (permalink / raw) To: Philippe Mathieu-Daudé Cc: Fam Zheng, Paolo Bonzini, qemu-ppc, qemu-devel, David Gibson On Wed, 4 Mar 2020 16:33:09 +0100 Philippe Mathieu-Daudé <philmd@redhat.com> wrote: > We already have a ui pointer, use it (to simplify the next commit). > Small typo, s/ui/iu > Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> > --- > hw/scsi/spapr_vscsi.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c > index 7e397ed797..3cb5a38181 100644 > --- a/hw/scsi/spapr_vscsi.c > +++ b/hw/scsi/spapr_vscsi.c > @@ -261,9 +261,9 @@ static int vscsi_send_rsp(VSCSIState *s, vscsi_req *req, > if (status) { > iu->srp.rsp.sol_not = (sol_not & 0x04) >> 2; > if (req->senselen) { > - req->iu.srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID; > - req->iu.srp.rsp.sense_data_len = cpu_to_be32(req->senselen); > - memcpy(req->iu.srp.rsp.data, req->sense, req->senselen); > + iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID; > + iu->srp.rsp.sense_data_len = cpu_to_be32(req->senselen); > + memcpy(iu->srp.rsp.data, req->sense, req->senselen); > total_len += req->senselen; > } > } else { ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 4/5] hw/scsi/spapr_vscsi: Introduce req_ui() helper 2020-03-04 15:33 [PATCH 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Philippe Mathieu-Daudé ` (2 preceding siblings ...) 2020-03-04 15:33 ` [PATCH 3/5] hw/scsi/spapr_vscsi: Simplify a bit Philippe Mathieu-Daudé @ 2020-03-04 15:33 ` Philippe Mathieu-Daudé 2020-03-05 0:41 ` David Gibson 2020-03-04 15:33 ` [PATCH 5/5] hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size Philippe Mathieu-Daudé 4 siblings, 1 reply; 14+ messages in thread From: Philippe Mathieu-Daudé @ 2020-03-04 15:33 UTC (permalink / raw) To: qemu-devel Cc: Fam Zheng, qemu-ppc, Paolo Bonzini, Philippe Mathieu-Daudé, David Gibson Introduce the req_ui() helper which returns a pointer to the viosrp_iu union held in the vscsi_req structure. This simplifies the next patch. Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> --- hw/scsi/spapr_vscsi.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 3cb5a38181..f1a0bbdc31 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -97,6 +97,12 @@ typedef struct { vscsi_req reqs[VSCSI_REQ_LIMIT]; } VSCSIState; +static union viosrp_iu *req_iu(vscsi_req *req) +{ + return (union viosrp_iu *)req->iu.srp.reserved; +} + + static struct vscsi_req *vscsi_get_req(VSCSIState *s) { vscsi_req *req; @@ -121,7 +127,7 @@ static struct vscsi_req *vscsi_find_req(VSCSIState *s, uint64_t srp_tag) for (i = 0; i < VSCSI_REQ_LIMIT; i++) { req = &s->reqs[i]; - if (req->iu.srp.cmd.tag == srp_tag) { + if (req_iu(req)->srp.cmd.tag == srp_tag) { return req; } } @@ -188,7 +194,7 @@ static int vscsi_send_iu(VSCSIState *s, vscsi_req *req, req->crq.s.reserved = 0x00; req->crq.s.timeout = cpu_to_be16(0x0000); req->crq.s.IU_length = cpu_to_be16(length); - req->crq.s.IU_data_ptr = req->iu.srp.rsp.tag; /* right byte order */ + req->crq.s.IU_data_ptr = req_iu(req)->srp.rsp.tag; /* right byte order */ if (rc == 0) { req->crq.s.status = VIOSRP_OK; @@ -224,7 +230,7 @@ static void vscsi_makeup_sense(VSCSIState *s, vscsi_req *req, static int vscsi_send_rsp(VSCSIState *s, vscsi_req *req, uint8_t status, int32_t res_in, int32_t res_out) { - union viosrp_iu *iu = &req->iu; + union viosrp_iu *iu = req_iu(req); uint64_t tag = iu->srp.rsp.tag; int total_len = sizeof(iu->srp.rsp); uint8_t sol_not = iu->srp.cmd.sol_not; @@ -285,7 +291,7 @@ static int vscsi_fetch_desc(VSCSIState *s, struct vscsi_req *req, unsigned n, unsigned buf_offset, struct srp_direct_buf *ret) { - struct srp_cmd *cmd = &req->iu.srp.cmd; + struct srp_cmd *cmd = &req_iu(req)->srp.cmd; switch (req->dma_fmt) { case SRP_NO_DATA_DESC: { @@ -473,7 +479,7 @@ static int data_out_desc_size(struct srp_cmd *cmd) static int vscsi_preprocess_desc(vscsi_req *req) { - struct srp_cmd *cmd = &req->iu.srp.cmd; + struct srp_cmd *cmd = &req_iu(req)->srp.cmd; req->cdb_offset = cmd->add_cdb_len & ~3; @@ -655,7 +661,7 @@ static void *vscsi_load_request(QEMUFile *f, SCSIRequest *sreq) static void vscsi_process_login(VSCSIState *s, vscsi_req *req) { - union viosrp_iu *iu = &req->iu; + union viosrp_iu *iu = req_iu(req); struct srp_login_rsp *rsp = &iu->srp.login_rsp; uint64_t tag = iu->srp.rsp.tag; @@ -681,7 +687,7 @@ static void vscsi_process_login(VSCSIState *s, vscsi_req *req) static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req) { - uint8_t *cdb = req->iu.srp.cmd.cdb; + uint8_t *cdb = req_iu(req)->srp.cmd.cdb; uint8_t resp_data[36]; int rc, len, alen; @@ -770,7 +776,7 @@ static void vscsi_report_luns(VSCSIState *s, vscsi_req *req) static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req) { - union srp_iu *srp = &req->iu.srp; + union srp_iu *srp = &req_iu(req)->srp; SCSIDevice *sdev; int n, lun; @@ -821,7 +827,7 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req) static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) { - union viosrp_iu *iu = &req->iu; + union viosrp_iu *iu = req_iu(req); vscsi_req *tmpreq; int i, lun = 0, resp = SRP_TSK_MGMT_COMPLETE; SCSIDevice *d; @@ -831,7 +837,8 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) fprintf(stderr, "vscsi_process_tsk_mgmt %02x\n", iu->srp.tsk_mgmt.tsk_mgmt_func); - d = vscsi_device_find(&s->bus, be64_to_cpu(req->iu.srp.tsk_mgmt.lun), &lun); + d = vscsi_device_find(&s->bus, + be64_to_cpu(req_iu(req)->srp.tsk_mgmt.lun), &lun); if (!d) { resp = SRP_TSK_MGMT_FIELDS_INVALID; } else { @@ -842,7 +849,7 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) break; } - tmpreq = vscsi_find_req(s, req->iu.srp.tsk_mgmt.task_tag); + tmpreq = vscsi_find_req(s, req_iu(req)->srp.tsk_mgmt.task_tag); if (tmpreq && tmpreq->sreq) { assert(tmpreq->sreq->hba_private); scsi_req_cancel(tmpreq->sreq); @@ -867,7 +874,8 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) for (i = 0; i < VSCSI_REQ_LIMIT; i++) { tmpreq = &s->reqs[i]; - if (tmpreq->iu.srp.cmd.lun != req->iu.srp.tsk_mgmt.lun) { + if (req_iu(tmpreq)->srp.cmd.lun + != req_iu(req)->srp.tsk_mgmt.lun) { continue; } if (!tmpreq->active || !tmpreq->sreq) { @@ -911,7 +919,7 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) static int vscsi_handle_srp_req(VSCSIState *s, vscsi_req *req) { - union srp_iu *srp = &req->iu.srp; + union srp_iu *srp = &req_iu(req)->srp; int done = 1; uint8_t opcode = srp->rsp.opcode; @@ -948,7 +956,7 @@ static int vscsi_send_adapter_info(VSCSIState *s, vscsi_req *req) struct mad_adapter_info_data info; int rc; - sinfo = &req->iu.mad.adapter_info; + sinfo = &req_iu(req)->mad.adapter_info; #if 0 /* What for ? */ rc = spapr_vio_dma_read(&s->vdev, be64_to_cpu(sinfo->buffer), @@ -984,7 +992,7 @@ static int vscsi_send_capabilities(VSCSIState *s, vscsi_req *req) uint64_t buffer; int rc; - vcap = &req->iu.mad.capabilities; + vcap = &req_iu(req)->mad.capabilities; req_len = len = be16_to_cpu(vcap->common.length); buffer = be64_to_cpu(vcap->buffer); if (len > sizeof(cap)) { @@ -1029,7 +1037,7 @@ static int vscsi_send_capabilities(VSCSIState *s, vscsi_req *req) static int vscsi_handle_mad_req(VSCSIState *s, vscsi_req *req) { - union mad_iu *mad = &req->iu.mad; + union mad_iu *mad = &req_iu(req)->mad; bool request_handled = false; uint64_t retlen = 0; -- 2.21.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 4/5] hw/scsi/spapr_vscsi: Introduce req_ui() helper 2020-03-04 15:33 ` [PATCH 4/5] hw/scsi/spapr_vscsi: Introduce req_ui() helper Philippe Mathieu-Daudé @ 2020-03-05 0:41 ` David Gibson 2020-03-05 0:42 ` David Gibson 0 siblings, 1 reply; 14+ messages in thread From: David Gibson @ 2020-03-05 0:41 UTC (permalink / raw) To: Philippe Mathieu-Daudé Cc: Fam Zheng, qemu-ppc, qemu-devel, Paolo Bonzini [-- Attachment #1: Type: text/plain, Size: 7279 bytes --] On Wed, Mar 04, 2020 at 04:33:10PM +0100, Philippe Mathieu-Daudé wrote: > Introduce the req_ui() helper which returns a pointer to > the viosrp_iu union held in the vscsi_req structure. > This simplifies the next patch. > > Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> > --- > hw/scsi/spapr_vscsi.c | 40 ++++++++++++++++++++++++---------------- > 1 file changed, 24 insertions(+), 16 deletions(-) > > diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c > index 3cb5a38181..f1a0bbdc31 100644 > --- a/hw/scsi/spapr_vscsi.c > +++ b/hw/scsi/spapr_vscsi.c > @@ -97,6 +97,12 @@ typedef struct { > vscsi_req reqs[VSCSI_REQ_LIMIT]; > } VSCSIState; > > +static union viosrp_iu *req_iu(vscsi_req *req) > +{ > + return (union viosrp_iu *)req->iu.srp.reserved; I guess it doesn't really matter since you remove it in the next patch, but this seems a really weird way of expressing return &req->iu; > +} > + > + > static struct vscsi_req *vscsi_get_req(VSCSIState *s) > { > vscsi_req *req; > @@ -121,7 +127,7 @@ static struct vscsi_req *vscsi_find_req(VSCSIState *s, uint64_t srp_tag) > > for (i = 0; i < VSCSI_REQ_LIMIT; i++) { > req = &s->reqs[i]; > - if (req->iu.srp.cmd.tag == srp_tag) { > + if (req_iu(req)->srp.cmd.tag == srp_tag) { > return req; > } > } > @@ -188,7 +194,7 @@ static int vscsi_send_iu(VSCSIState *s, vscsi_req *req, > req->crq.s.reserved = 0x00; > req->crq.s.timeout = cpu_to_be16(0x0000); > req->crq.s.IU_length = cpu_to_be16(length); > - req->crq.s.IU_data_ptr = req->iu.srp.rsp.tag; /* right byte order */ > + req->crq.s.IU_data_ptr = req_iu(req)->srp.rsp.tag; /* right byte order */ > > if (rc == 0) { > req->crq.s.status = VIOSRP_OK; > @@ -224,7 +230,7 @@ static void vscsi_makeup_sense(VSCSIState *s, vscsi_req *req, > static int vscsi_send_rsp(VSCSIState *s, vscsi_req *req, > uint8_t status, int32_t res_in, int32_t res_out) > { > - union viosrp_iu *iu = &req->iu; > + union viosrp_iu *iu = req_iu(req); > uint64_t tag = iu->srp.rsp.tag; > int total_len = sizeof(iu->srp.rsp); > uint8_t sol_not = iu->srp.cmd.sol_not; > @@ -285,7 +291,7 @@ static int vscsi_fetch_desc(VSCSIState *s, struct vscsi_req *req, > unsigned n, unsigned buf_offset, > struct srp_direct_buf *ret) > { > - struct srp_cmd *cmd = &req->iu.srp.cmd; > + struct srp_cmd *cmd = &req_iu(req)->srp.cmd; > > switch (req->dma_fmt) { > case SRP_NO_DATA_DESC: { > @@ -473,7 +479,7 @@ static int data_out_desc_size(struct srp_cmd *cmd) > > static int vscsi_preprocess_desc(vscsi_req *req) > { > - struct srp_cmd *cmd = &req->iu.srp.cmd; > + struct srp_cmd *cmd = &req_iu(req)->srp.cmd; > > req->cdb_offset = cmd->add_cdb_len & ~3; > > @@ -655,7 +661,7 @@ static void *vscsi_load_request(QEMUFile *f, SCSIRequest *sreq) > > static void vscsi_process_login(VSCSIState *s, vscsi_req *req) > { > - union viosrp_iu *iu = &req->iu; > + union viosrp_iu *iu = req_iu(req); > struct srp_login_rsp *rsp = &iu->srp.login_rsp; > uint64_t tag = iu->srp.rsp.tag; > > @@ -681,7 +687,7 @@ static void vscsi_process_login(VSCSIState *s, vscsi_req *req) > > static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req) > { > - uint8_t *cdb = req->iu.srp.cmd.cdb; > + uint8_t *cdb = req_iu(req)->srp.cmd.cdb; > uint8_t resp_data[36]; > int rc, len, alen; > > @@ -770,7 +776,7 @@ static void vscsi_report_luns(VSCSIState *s, vscsi_req *req) > > static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req) > { > - union srp_iu *srp = &req->iu.srp; > + union srp_iu *srp = &req_iu(req)->srp; > SCSIDevice *sdev; > int n, lun; > > @@ -821,7 +827,7 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req) > > static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) > { > - union viosrp_iu *iu = &req->iu; > + union viosrp_iu *iu = req_iu(req); > vscsi_req *tmpreq; > int i, lun = 0, resp = SRP_TSK_MGMT_COMPLETE; > SCSIDevice *d; > @@ -831,7 +837,8 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) > fprintf(stderr, "vscsi_process_tsk_mgmt %02x\n", > iu->srp.tsk_mgmt.tsk_mgmt_func); > > - d = vscsi_device_find(&s->bus, be64_to_cpu(req->iu.srp.tsk_mgmt.lun), &lun); > + d = vscsi_device_find(&s->bus, > + be64_to_cpu(req_iu(req)->srp.tsk_mgmt.lun), &lun); > if (!d) { > resp = SRP_TSK_MGMT_FIELDS_INVALID; > } else { > @@ -842,7 +849,7 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) > break; > } > > - tmpreq = vscsi_find_req(s, req->iu.srp.tsk_mgmt.task_tag); > + tmpreq = vscsi_find_req(s, req_iu(req)->srp.tsk_mgmt.task_tag); > if (tmpreq && tmpreq->sreq) { > assert(tmpreq->sreq->hba_private); > scsi_req_cancel(tmpreq->sreq); > @@ -867,7 +874,8 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) > > for (i = 0; i < VSCSI_REQ_LIMIT; i++) { > tmpreq = &s->reqs[i]; > - if (tmpreq->iu.srp.cmd.lun != req->iu.srp.tsk_mgmt.lun) { > + if (req_iu(tmpreq)->srp.cmd.lun > + != req_iu(req)->srp.tsk_mgmt.lun) { > continue; > } > if (!tmpreq->active || !tmpreq->sreq) { > @@ -911,7 +919,7 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) > > static int vscsi_handle_srp_req(VSCSIState *s, vscsi_req *req) > { > - union srp_iu *srp = &req->iu.srp; > + union srp_iu *srp = &req_iu(req)->srp; > int done = 1; > uint8_t opcode = srp->rsp.opcode; > > @@ -948,7 +956,7 @@ static int vscsi_send_adapter_info(VSCSIState *s, vscsi_req *req) > struct mad_adapter_info_data info; > int rc; > > - sinfo = &req->iu.mad.adapter_info; > + sinfo = &req_iu(req)->mad.adapter_info; > > #if 0 /* What for ? */ > rc = spapr_vio_dma_read(&s->vdev, be64_to_cpu(sinfo->buffer), > @@ -984,7 +992,7 @@ static int vscsi_send_capabilities(VSCSIState *s, vscsi_req *req) > uint64_t buffer; > int rc; > > - vcap = &req->iu.mad.capabilities; > + vcap = &req_iu(req)->mad.capabilities; > req_len = len = be16_to_cpu(vcap->common.length); > buffer = be64_to_cpu(vcap->buffer); > if (len > sizeof(cap)) { > @@ -1029,7 +1037,7 @@ static int vscsi_send_capabilities(VSCSIState *s, vscsi_req *req) > > static int vscsi_handle_mad_req(VSCSIState *s, vscsi_req *req) > { > - union mad_iu *mad = &req->iu.mad; > + union mad_iu *mad = &req_iu(req)->mad; > bool request_handled = false; > uint64_t retlen = 0; > -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/5] hw/scsi/spapr_vscsi: Introduce req_ui() helper 2020-03-05 0:41 ` David Gibson @ 2020-03-05 0:42 ` David Gibson 0 siblings, 0 replies; 14+ messages in thread From: David Gibson @ 2020-03-05 0:42 UTC (permalink / raw) To: Philippe Mathieu-Daudé Cc: Fam Zheng, qemu-ppc, qemu-devel, Paolo Bonzini [-- Attachment #1: Type: text/plain, Size: 7761 bytes --] On Thu, Mar 05, 2020 at 11:41:37AM +1100, David Gibson wrote: > On Wed, Mar 04, 2020 at 04:33:10PM +0100, Philippe Mathieu-Daudé wrote: > > Introduce the req_ui() helper which returns a pointer to > > the viosrp_iu union held in the vscsi_req structure. > > This simplifies the next patch. > > > > Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> > > --- > > hw/scsi/spapr_vscsi.c | 40 ++++++++++++++++++++++++---------------- > > 1 file changed, 24 insertions(+), 16 deletions(-) > > > > diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c > > index 3cb5a38181..f1a0bbdc31 100644 > > --- a/hw/scsi/spapr_vscsi.c > > +++ b/hw/scsi/spapr_vscsi.c > > @@ -97,6 +97,12 @@ typedef struct { > > vscsi_req reqs[VSCSI_REQ_LIMIT]; > > } VSCSIState; > > > > +static union viosrp_iu *req_iu(vscsi_req *req) > > +{ > > + return (union viosrp_iu *)req->iu.srp.reserved; > > I guess it doesn't really matter since you remove it in the next > patch, but this seems a really weird way of expressing > return &req->iu; Oh, also s/req_ui/req_iu/g in the commit message. > > > +} > > + > > + > > static struct vscsi_req *vscsi_get_req(VSCSIState *s) > > { > > vscsi_req *req; > > @@ -121,7 +127,7 @@ static struct vscsi_req *vscsi_find_req(VSCSIState *s, uint64_t srp_tag) > > > > for (i = 0; i < VSCSI_REQ_LIMIT; i++) { > > req = &s->reqs[i]; > > - if (req->iu.srp.cmd.tag == srp_tag) { > > + if (req_iu(req)->srp.cmd.tag == srp_tag) { > > return req; > > } > > } > > @@ -188,7 +194,7 @@ static int vscsi_send_iu(VSCSIState *s, vscsi_req *req, > > req->crq.s.reserved = 0x00; > > req->crq.s.timeout = cpu_to_be16(0x0000); > > req->crq.s.IU_length = cpu_to_be16(length); > > - req->crq.s.IU_data_ptr = req->iu.srp.rsp.tag; /* right byte order */ > > + req->crq.s.IU_data_ptr = req_iu(req)->srp.rsp.tag; /* right byte order */ > > > > if (rc == 0) { > > req->crq.s.status = VIOSRP_OK; > > @@ -224,7 +230,7 @@ static void vscsi_makeup_sense(VSCSIState *s, vscsi_req *req, > > static int vscsi_send_rsp(VSCSIState *s, vscsi_req *req, > > uint8_t status, int32_t res_in, int32_t res_out) > > { > > - union viosrp_iu *iu = &req->iu; > > + union viosrp_iu *iu = req_iu(req); > > uint64_t tag = iu->srp.rsp.tag; > > int total_len = sizeof(iu->srp.rsp); > > uint8_t sol_not = iu->srp.cmd.sol_not; > > @@ -285,7 +291,7 @@ static int vscsi_fetch_desc(VSCSIState *s, struct vscsi_req *req, > > unsigned n, unsigned buf_offset, > > struct srp_direct_buf *ret) > > { > > - struct srp_cmd *cmd = &req->iu.srp.cmd; > > + struct srp_cmd *cmd = &req_iu(req)->srp.cmd; > > > > switch (req->dma_fmt) { > > case SRP_NO_DATA_DESC: { > > @@ -473,7 +479,7 @@ static int data_out_desc_size(struct srp_cmd *cmd) > > > > static int vscsi_preprocess_desc(vscsi_req *req) > > { > > - struct srp_cmd *cmd = &req->iu.srp.cmd; > > + struct srp_cmd *cmd = &req_iu(req)->srp.cmd; > > > > req->cdb_offset = cmd->add_cdb_len & ~3; > > > > @@ -655,7 +661,7 @@ static void *vscsi_load_request(QEMUFile *f, SCSIRequest *sreq) > > > > static void vscsi_process_login(VSCSIState *s, vscsi_req *req) > > { > > - union viosrp_iu *iu = &req->iu; > > + union viosrp_iu *iu = req_iu(req); > > struct srp_login_rsp *rsp = &iu->srp.login_rsp; > > uint64_t tag = iu->srp.rsp.tag; > > > > @@ -681,7 +687,7 @@ static void vscsi_process_login(VSCSIState *s, vscsi_req *req) > > > > static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req) > > { > > - uint8_t *cdb = req->iu.srp.cmd.cdb; > > + uint8_t *cdb = req_iu(req)->srp.cmd.cdb; > > uint8_t resp_data[36]; > > int rc, len, alen; > > > > @@ -770,7 +776,7 @@ static void vscsi_report_luns(VSCSIState *s, vscsi_req *req) > > > > static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req) > > { > > - union srp_iu *srp = &req->iu.srp; > > + union srp_iu *srp = &req_iu(req)->srp; > > SCSIDevice *sdev; > > int n, lun; > > > > @@ -821,7 +827,7 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req) > > > > static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) > > { > > - union viosrp_iu *iu = &req->iu; > > + union viosrp_iu *iu = req_iu(req); > > vscsi_req *tmpreq; > > int i, lun = 0, resp = SRP_TSK_MGMT_COMPLETE; > > SCSIDevice *d; > > @@ -831,7 +837,8 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) > > fprintf(stderr, "vscsi_process_tsk_mgmt %02x\n", > > iu->srp.tsk_mgmt.tsk_mgmt_func); > > > > - d = vscsi_device_find(&s->bus, be64_to_cpu(req->iu.srp.tsk_mgmt.lun), &lun); > > + d = vscsi_device_find(&s->bus, > > + be64_to_cpu(req_iu(req)->srp.tsk_mgmt.lun), &lun); > > if (!d) { > > resp = SRP_TSK_MGMT_FIELDS_INVALID; > > } else { > > @@ -842,7 +849,7 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) > > break; > > } > > > > - tmpreq = vscsi_find_req(s, req->iu.srp.tsk_mgmt.task_tag); > > + tmpreq = vscsi_find_req(s, req_iu(req)->srp.tsk_mgmt.task_tag); > > if (tmpreq && tmpreq->sreq) { > > assert(tmpreq->sreq->hba_private); > > scsi_req_cancel(tmpreq->sreq); > > @@ -867,7 +874,8 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) > > > > for (i = 0; i < VSCSI_REQ_LIMIT; i++) { > > tmpreq = &s->reqs[i]; > > - if (tmpreq->iu.srp.cmd.lun != req->iu.srp.tsk_mgmt.lun) { > > + if (req_iu(tmpreq)->srp.cmd.lun > > + != req_iu(req)->srp.tsk_mgmt.lun) { > > continue; > > } > > if (!tmpreq->active || !tmpreq->sreq) { > > @@ -911,7 +919,7 @@ static int vscsi_process_tsk_mgmt(VSCSIState *s, vscsi_req *req) > > > > static int vscsi_handle_srp_req(VSCSIState *s, vscsi_req *req) > > { > > - union srp_iu *srp = &req->iu.srp; > > + union srp_iu *srp = &req_iu(req)->srp; > > int done = 1; > > uint8_t opcode = srp->rsp.opcode; > > > > @@ -948,7 +956,7 @@ static int vscsi_send_adapter_info(VSCSIState *s, vscsi_req *req) > > struct mad_adapter_info_data info; > > int rc; > > > > - sinfo = &req->iu.mad.adapter_info; > > + sinfo = &req_iu(req)->mad.adapter_info; > > > > #if 0 /* What for ? */ > > rc = spapr_vio_dma_read(&s->vdev, be64_to_cpu(sinfo->buffer), > > @@ -984,7 +992,7 @@ static int vscsi_send_capabilities(VSCSIState *s, vscsi_req *req) > > uint64_t buffer; > > int rc; > > > > - vcap = &req->iu.mad.capabilities; > > + vcap = &req_iu(req)->mad.capabilities; > > req_len = len = be16_to_cpu(vcap->common.length); > > buffer = be64_to_cpu(vcap->buffer); > > if (len > sizeof(cap)) { > > @@ -1029,7 +1037,7 @@ static int vscsi_send_capabilities(VSCSIState *s, vscsi_req *req) > > > > static int vscsi_handle_mad_req(VSCSIState *s, vscsi_req *req) > > { > > - union mad_iu *mad = &req->iu.mad; > > + union mad_iu *mad = &req_iu(req)->mad; > > bool request_handled = false; > > uint64_t retlen = 0; > > > -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 5/5] hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size 2020-03-04 15:33 [PATCH 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Philippe Mathieu-Daudé ` (3 preceding siblings ...) 2020-03-04 15:33 ` [PATCH 4/5] hw/scsi/spapr_vscsi: Introduce req_ui() helper Philippe Mathieu-Daudé @ 2020-03-04 15:33 ` Philippe Mathieu-Daudé 2020-03-05 0:43 ` David Gibson 4 siblings, 1 reply; 14+ messages in thread From: Philippe Mathieu-Daudé @ 2020-03-04 15:33 UTC (permalink / raw) To: qemu-devel Cc: Fam Zheng, qemu-ppc, Paolo Bonzini, Philippe Mathieu-Daudé, David Gibson The 'union srp_iu' is meant as a pointer to any SRP Information Unit type, it is not related to the size of a VIO DMA buffer. Use a plain buffer for the VIO DMA read/write calls. We can remove the reserved buffer from the 'union srp_iu'. This issue was noticed when replacing the zero-length arrays from hw/scsi/srp.h with flexible array member, 'clang -fsanitize=undefined' reported: hw/scsi/spapr_vscsi.c:69:29: error: field 'iu' with variable sized type 'union viosrp_iu' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end] union viosrp_iu iu; ^ Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> --- hw/scsi/viosrp.h | 2 +- hw/scsi/spapr_vscsi.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/scsi/viosrp.h b/hw/scsi/viosrp.h index 25676c2383..aba3203028 100644 --- a/hw/scsi/viosrp.h +++ b/hw/scsi/viosrp.h @@ -49,8 +49,8 @@ union srp_iu { struct srp_tsk_mgmt tsk_mgmt; struct srp_cmd cmd; struct srp_rsp rsp; - uint8_t reserved[SRP_MAX_IU_LEN]; }; +_Static_assert(sizeof(union srp_iu) <= SRP_MAX_IU_LEN, "srp_iu size incorrect"); enum viosrp_crq_formats { VIOSRP_SRP_FORMAT = 0x01, diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index f1a0bbdc31..f9be68e44e 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -66,7 +66,7 @@ typedef union vscsi_crq { typedef struct vscsi_req { vscsi_crq crq; - union viosrp_iu iu; + uint8_t viosrp_iu_buf[SRP_MAX_IU_LEN]; /* SCSI request tracking */ SCSIRequest *sreq; @@ -99,7 +99,7 @@ typedef struct { static union viosrp_iu *req_iu(vscsi_req *req) { - return (union viosrp_iu *)req->iu.srp.reserved; + return (union viosrp_iu *)req->viosrp_iu_buf; } @@ -184,7 +184,7 @@ static int vscsi_send_iu(VSCSIState *s, vscsi_req *req, /* First copy the SRP */ rc = spapr_vio_dma_write(&s->vdev, req->crq.s.IU_data_ptr, - &req->iu, length); + &req->viosrp_iu_buf, length); if (rc) { fprintf(stderr, "vscsi_send_iu: DMA write failure !\n"); } @@ -603,7 +603,7 @@ static const VMStateDescription vmstate_spapr_vscsi_req = { .minimum_version_id = 1, .fields = (VMStateField[]) { VMSTATE_BUFFER(crq.raw, vscsi_req), - VMSTATE_BUFFER(iu.srp.reserved, vscsi_req), + VMSTATE_BUFFER(viosrp_iu_buf, vscsi_req), VMSTATE_UINT32(qtag, vscsi_req), VMSTATE_BOOL(active, vscsi_req), VMSTATE_UINT32(data_len, vscsi_req), @@ -1104,7 +1104,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq) } /* XXX Handle failure differently ? */ - if (spapr_vio_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->iu, + if (spapr_vio_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->viosrp_iu_buf, crq->s.IU_length)) { fprintf(stderr, "vscsi_got_payload: DMA read failure !\n"); vscsi_put_req(req); -- 2.21.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 5/5] hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size 2020-03-04 15:33 ` [PATCH 5/5] hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size Philippe Mathieu-Daudé @ 2020-03-05 0:43 ` David Gibson 2020-03-05 6:47 ` Philippe Mathieu-Daudé 0 siblings, 1 reply; 14+ messages in thread From: David Gibson @ 2020-03-05 0:43 UTC (permalink / raw) To: Philippe Mathieu-Daudé Cc: Fam Zheng, qemu-ppc, qemu-devel, Paolo Bonzini [-- Attachment #1: Type: text/plain, Size: 3769 bytes --] On Wed, Mar 04, 2020 at 04:33:11PM +0100, Philippe Mathieu-Daudé wrote: > The 'union srp_iu' is meant as a pointer to any SRP Information > Unit type, it is not related to the size of a VIO DMA buffer. > > Use a plain buffer for the VIO DMA read/write calls. > We can remove the reserved buffer from the 'union srp_iu'. > > This issue was noticed when replacing the zero-length arrays > from hw/scsi/srp.h with flexible array member, > 'clang -fsanitize=undefined' reported: > > hw/scsi/spapr_vscsi.c:69:29: error: field 'iu' with variable sized type 'union viosrp_iu' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end] > union viosrp_iu iu; > ^ > > Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> > --- > hw/scsi/viosrp.h | 2 +- > hw/scsi/spapr_vscsi.c | 10 +++++----- > 2 files changed, 6 insertions(+), 6 deletions(-) > > diff --git a/hw/scsi/viosrp.h b/hw/scsi/viosrp.h > index 25676c2383..aba3203028 100644 > --- a/hw/scsi/viosrp.h > +++ b/hw/scsi/viosrp.h > @@ -49,8 +49,8 @@ union srp_iu { > struct srp_tsk_mgmt tsk_mgmt; > struct srp_cmd cmd; > struct srp_rsp rsp; > - uint8_t reserved[SRP_MAX_IU_LEN]; > }; > +_Static_assert(sizeof(union srp_iu) <= SRP_MAX_IU_LEN, "srp_iu size incorrect"); Hrm. Given that srp_iu will be a variably sized type, is this assertion actually testing anything meaningful? Otherwise, LGTM. > > enum viosrp_crq_formats { > VIOSRP_SRP_FORMAT = 0x01, > diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c > index f1a0bbdc31..f9be68e44e 100644 > --- a/hw/scsi/spapr_vscsi.c > +++ b/hw/scsi/spapr_vscsi.c > @@ -66,7 +66,7 @@ typedef union vscsi_crq { > > typedef struct vscsi_req { > vscsi_crq crq; > - union viosrp_iu iu; > + uint8_t viosrp_iu_buf[SRP_MAX_IU_LEN]; > > /* SCSI request tracking */ > SCSIRequest *sreq; > @@ -99,7 +99,7 @@ typedef struct { > > static union viosrp_iu *req_iu(vscsi_req *req) > { > - return (union viosrp_iu *)req->iu.srp.reserved; > + return (union viosrp_iu *)req->viosrp_iu_buf; > } > > > @@ -184,7 +184,7 @@ static int vscsi_send_iu(VSCSIState *s, vscsi_req *req, > > /* First copy the SRP */ > rc = spapr_vio_dma_write(&s->vdev, req->crq.s.IU_data_ptr, > - &req->iu, length); > + &req->viosrp_iu_buf, length); > if (rc) { > fprintf(stderr, "vscsi_send_iu: DMA write failure !\n"); > } > @@ -603,7 +603,7 @@ static const VMStateDescription vmstate_spapr_vscsi_req = { > .minimum_version_id = 1, > .fields = (VMStateField[]) { > VMSTATE_BUFFER(crq.raw, vscsi_req), > - VMSTATE_BUFFER(iu.srp.reserved, vscsi_req), > + VMSTATE_BUFFER(viosrp_iu_buf, vscsi_req), > VMSTATE_UINT32(qtag, vscsi_req), > VMSTATE_BOOL(active, vscsi_req), > VMSTATE_UINT32(data_len, vscsi_req), > @@ -1104,7 +1104,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq) > } > > /* XXX Handle failure differently ? */ > - if (spapr_vio_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->iu, > + if (spapr_vio_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->viosrp_iu_buf, > crq->s.IU_length)) { > fprintf(stderr, "vscsi_got_payload: DMA read failure !\n"); > vscsi_put_req(req); -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 5/5] hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size 2020-03-05 0:43 ` David Gibson @ 2020-03-05 6:47 ` Philippe Mathieu-Daudé 0 siblings, 0 replies; 14+ messages in thread From: Philippe Mathieu-Daudé @ 2020-03-05 6:47 UTC (permalink / raw) To: David Gibson; +Cc: Fam Zheng, qemu-ppc, qemu-devel, Paolo Bonzini On 3/5/20 1:43 AM, David Gibson wrote: > On Wed, Mar 04, 2020 at 04:33:11PM +0100, Philippe Mathieu-Daudé wrote: >> The 'union srp_iu' is meant as a pointer to any SRP Information >> Unit type, it is not related to the size of a VIO DMA buffer. >> >> Use a plain buffer for the VIO DMA read/write calls. >> We can remove the reserved buffer from the 'union srp_iu'. >> >> This issue was noticed when replacing the zero-length arrays >> from hw/scsi/srp.h with flexible array member, >> 'clang -fsanitize=undefined' reported: >> >> hw/scsi/spapr_vscsi.c:69:29: error: field 'iu' with variable sized type 'union viosrp_iu' not at the end of a struct or class is a GNU extension [-Werror,-Wgnu-variable-sized-type-not-at-end] >> union viosrp_iu iu; >> ^ >> >> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> >> --- >> hw/scsi/viosrp.h | 2 +- >> hw/scsi/spapr_vscsi.c | 10 +++++----- >> 2 files changed, 6 insertions(+), 6 deletions(-) >> >> diff --git a/hw/scsi/viosrp.h b/hw/scsi/viosrp.h >> index 25676c2383..aba3203028 100644 >> --- a/hw/scsi/viosrp.h >> +++ b/hw/scsi/viosrp.h >> @@ -49,8 +49,8 @@ union srp_iu { >> struct srp_tsk_mgmt tsk_mgmt; >> struct srp_cmd cmd; >> struct srp_rsp rsp; >> - uint8_t reserved[SRP_MAX_IU_LEN]; >> }; >> +_Static_assert(sizeof(union srp_iu) <= SRP_MAX_IU_LEN, "srp_iu size incorrect"); > > Hrm. Given that srp_iu will be a variably sized type, is this > assertion actually testing anything meaningful? I wanted to assert that if another SRP IU is added, the DMA buffer will be big enough to hold it. I'll simply remove the check. > Otherwise, LGTM. Thanks for reviewing the series, Phil. > >> >> enum viosrp_crq_formats { >> VIOSRP_SRP_FORMAT = 0x01, >> diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c >> index f1a0bbdc31..f9be68e44e 100644 >> --- a/hw/scsi/spapr_vscsi.c >> +++ b/hw/scsi/spapr_vscsi.c >> @@ -66,7 +66,7 @@ typedef union vscsi_crq { >> >> typedef struct vscsi_req { >> vscsi_crq crq; >> - union viosrp_iu iu; >> + uint8_t viosrp_iu_buf[SRP_MAX_IU_LEN]; >> >> /* SCSI request tracking */ >> SCSIRequest *sreq; >> @@ -99,7 +99,7 @@ typedef struct { >> >> static union viosrp_iu *req_iu(vscsi_req *req) >> { >> - return (union viosrp_iu *)req->iu.srp.reserved; >> + return (union viosrp_iu *)req->viosrp_iu_buf; >> } >> >> >> @@ -184,7 +184,7 @@ static int vscsi_send_iu(VSCSIState *s, vscsi_req *req, >> >> /* First copy the SRP */ >> rc = spapr_vio_dma_write(&s->vdev, req->crq.s.IU_data_ptr, >> - &req->iu, length); >> + &req->viosrp_iu_buf, length); >> if (rc) { >> fprintf(stderr, "vscsi_send_iu: DMA write failure !\n"); >> } >> @@ -603,7 +603,7 @@ static const VMStateDescription vmstate_spapr_vscsi_req = { >> .minimum_version_id = 1, >> .fields = (VMStateField[]) { >> VMSTATE_BUFFER(crq.raw, vscsi_req), >> - VMSTATE_BUFFER(iu.srp.reserved, vscsi_req), >> + VMSTATE_BUFFER(viosrp_iu_buf, vscsi_req), >> VMSTATE_UINT32(qtag, vscsi_req), >> VMSTATE_BOOL(active, vscsi_req), >> VMSTATE_UINT32(data_len, vscsi_req), >> @@ -1104,7 +1104,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq) >> } >> >> /* XXX Handle failure differently ? */ >> - if (spapr_vio_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->iu, >> + if (spapr_vio_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->viosrp_iu_buf, >> crq->s.IU_length)) { >> fprintf(stderr, "vscsi_got_payload: DMA read failure !\n"); >> vscsi_put_req(req); > ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2020-03-05 10:22 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-03-04 15:33 [PATCH 0/5] hw/scsi/spapr_vscsi: Fix time bomb zero-length array use Philippe Mathieu-Daudé 2020-03-04 15:33 ` [PATCH 1/5] hw/scsi/viosrp: Add missing 'hw/scsi/srp.h' include Philippe Mathieu-Daudé 2020-03-05 0:39 ` David Gibson 2020-03-04 15:33 ` [PATCH 2/5] hw/scsi/spapr_vscsi: Use SRP_MAX_IU_LEN instead of sizeof flexible array Philippe Mathieu-Daudé 2020-03-05 0:40 ` David Gibson 2020-03-04 15:33 ` [PATCH 3/5] hw/scsi/spapr_vscsi: Simplify a bit Philippe Mathieu-Daudé 2020-03-05 0:40 ` David Gibson 2020-03-05 10:21 ` Greg Kurz 2020-03-04 15:33 ` [PATCH 4/5] hw/scsi/spapr_vscsi: Introduce req_ui() helper Philippe Mathieu-Daudé 2020-03-05 0:41 ` David Gibson 2020-03-05 0:42 ` David Gibson 2020-03-04 15:33 ` [PATCH 5/5] hw/scsi/spapr_vscsi: Do not mix SRP IU size with DMA buffer size Philippe Mathieu-Daudé 2020-03-05 0:43 ` David Gibson 2020-03-05 6:47 ` Philippe Mathieu-Daudé
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).