Message ID | 20250310153552.32987-5-rreyes@linux.ibm.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Report vfio-ap configuration changes | expand |
On 3/10/25 11:35 AM, Rorie Reyes wrote: > These functions can be invoked by the function that handles interception > of the CHSC SEI instruction for requests indicating the accessibility of > one or more adjunct processors has changed. > > Signed-off-by: Rorie Reyes <rreyes@linux.ibm.com> > --- > hw/vfio/ap.c | 38 ++++++++++++++++++++++++++++++++++++ > include/hw/s390x/ap-bridge.h | 22 +++++++++++++++++++++ > 2 files changed, 60 insertions(+) > > diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c > index ddab764ab4..a152a90ca8 100644 > --- a/hw/vfio/ap.c > +++ b/hw/vfio/ap.c > @@ -94,6 +94,44 @@ static void vfio_ap_cfg_chg_notifier_handler(void *opaque) > > } > > +int ap_chsc_sei_nt0_get_event(void *res) > +{ > + APConfigChgEvent *cfg_chg_event = QTAILQ_FIRST(&cfg_chg_events); You're assuming that the queue has elements in it. Shouldn't you check first? > + ChscSeiNt0Res *nt0_res = (ChscSeiNt0Res *)res; > + > + memset(nt0_res, 0, sizeof(*nt0_res)); > + > + if (!cfg_chg_event) { Okay, so I see you are checking whether the QTAILQ_FIRST() call above returned anything. Why not call the ap_chsc_sei_nt0_have_event() function here instead, then follow that with the call to QTAILQ_FIRST() if there are any elements in the queue. Also, maybe forego the memset() call above until you verify that there are elements in the queue; if not, then the memset() call is unnecessary. > + return 1; > + } > + > + QTAILQ_REMOVE(&cfg_chg_events, cfg_chg_event, next); > + g_free(cfg_chg_event); > + > + /* > + * If there are any AP configuration change events in the queue, > + * indicate to the caller that there is pending event info in > + * the response block > + */ > + if (ap_chsc_sei_nt0_have_event()) { > + nt0_res->flags |= PENDING_EVENT_INFO_BITMASK; > + } > + > + nt0_res->length = sizeof(ChscSeiNt0Res); > + nt0_res->code = NT0_RES_RESPONSE_CODE; > + nt0_res->nt = NT0_RES_NT_DEFAULT; > + nt0_res->rs = NT0_RES_RS_AP_CHANGE; > + nt0_res->cc = NT0_RES_CC_AP_CHANGE; > + > + return 0; > + > +} > + > +int ap_chsc_sei_nt0_have_event(void) > +{ > + return !QTAILQ_EMPTY(&cfg_chg_events); > +} > + > static bool vfio_ap_register_irq_notifier(VFIOAPDevice *vapdev, > unsigned int irq, Error **errp) > { > diff --git a/include/hw/s390x/ap-bridge.h b/include/hw/s390x/ap-bridge.h > index 470e439a98..f4d838bf99 100644 > --- a/include/hw/s390x/ap-bridge.h > +++ b/include/hw/s390x/ap-bridge.h > @@ -16,4 +16,26 @@ > > void s390_init_ap(void); > > +typedef struct ChscSeiNt0Res { > + uint16_t length; > + uint16_t code; > + uint8_t reserved1; > + uint16_t reserved2; > + uint8_t nt; > +#define PENDING_EVENT_INFO_BITMASK 0x80; > + uint8_t flags; > + uint8_t reserved3; > + uint8_t rs; > + uint8_t cc; > +} QEMU_PACKED ChscSeiNt0Res; > + > +#define NT0_RES_RESPONSE_CODE 1; > +#define NT0_RES_NT_DEFAULT 0; > +#define NT0_RES_RS_AP_CHANGE 5; > +#define NT0_RES_CC_AP_CHANGE 3; > + > +int ap_chsc_sei_nt0_get_event(void *res); > + > +int ap_chsc_sei_nt0_have_event(void); > + > #endif
diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c index ddab764ab4..a152a90ca8 100644 --- a/hw/vfio/ap.c +++ b/hw/vfio/ap.c @@ -94,6 +94,44 @@ static void vfio_ap_cfg_chg_notifier_handler(void *opaque) } +int ap_chsc_sei_nt0_get_event(void *res) +{ + APConfigChgEvent *cfg_chg_event = QTAILQ_FIRST(&cfg_chg_events); + ChscSeiNt0Res *nt0_res = (ChscSeiNt0Res *)res; + + memset(nt0_res, 0, sizeof(*nt0_res)); + + if (!cfg_chg_event) { + return 1; + } + + QTAILQ_REMOVE(&cfg_chg_events, cfg_chg_event, next); + g_free(cfg_chg_event); + + /* + * If there are any AP configuration change events in the queue, + * indicate to the caller that there is pending event info in + * the response block + */ + if (ap_chsc_sei_nt0_have_event()) { + nt0_res->flags |= PENDING_EVENT_INFO_BITMASK; + } + + nt0_res->length = sizeof(ChscSeiNt0Res); + nt0_res->code = NT0_RES_RESPONSE_CODE; + nt0_res->nt = NT0_RES_NT_DEFAULT; + nt0_res->rs = NT0_RES_RS_AP_CHANGE; + nt0_res->cc = NT0_RES_CC_AP_CHANGE; + + return 0; + +} + +int ap_chsc_sei_nt0_have_event(void) +{ + return !QTAILQ_EMPTY(&cfg_chg_events); +} + static bool vfio_ap_register_irq_notifier(VFIOAPDevice *vapdev, unsigned int irq, Error **errp) { diff --git a/include/hw/s390x/ap-bridge.h b/include/hw/s390x/ap-bridge.h index 470e439a98..f4d838bf99 100644 --- a/include/hw/s390x/ap-bridge.h +++ b/include/hw/s390x/ap-bridge.h @@ -16,4 +16,26 @@ void s390_init_ap(void); +typedef struct ChscSeiNt0Res { + uint16_t length; + uint16_t code; + uint8_t reserved1; + uint16_t reserved2; + uint8_t nt; +#define PENDING_EVENT_INFO_BITMASK 0x80; + uint8_t flags; + uint8_t reserved3; + uint8_t rs; + uint8_t cc; +} QEMU_PACKED ChscSeiNt0Res; + +#define NT0_RES_RESPONSE_CODE 1; +#define NT0_RES_NT_DEFAULT 0; +#define NT0_RES_RS_AP_CHANGE 5; +#define NT0_RES_CC_AP_CHANGE 3; + +int ap_chsc_sei_nt0_get_event(void *res); + +int ap_chsc_sei_nt0_have_event(void); + #endif
These functions can be invoked by the function that handles interception of the CHSC SEI instruction for requests indicating the accessibility of one or more adjunct processors has changed. Signed-off-by: Rorie Reyes <rreyes@linux.ibm.com> --- hw/vfio/ap.c | 38 ++++++++++++++++++++++++++++++++++++ include/hw/s390x/ap-bridge.h | 22 +++++++++++++++++++++ 2 files changed, 60 insertions(+)