hw/vfio/ap: notification handler for AP config changed event

Register an event notifier handler to process AP configuration
change events by queuing the event and generating a CRW to let
the guest know its AP configuration has changed

Signed-off-by: Rorie Reyes <rreyes@linux.ibm.com>
Reviewed-by: Anthony Krowiak <akrowiak@linux.ibm.com>
Link: https://lore.kernel.org/qemu-devel/20250609164418.17585-2-rreyes@linux.ibm.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
This commit is contained in:
Rorie Reyes 2025-06-09 12:44:15 -04:00 committed by Cédric Le Goater
parent 6c4f752ea7
commit 0fb8a62fe4

View file

@ -18,6 +18,7 @@
#include "hw/vfio/vfio-device.h"
#include "system/iommufd.h"
#include "hw/s390x/ap-device.h"
#include "hw/s390x/css.h"
#include "qemu/error-report.h"
#include "qemu/event_notifier.h"
#include "qemu/main-loop.h"
@ -37,6 +38,7 @@ struct VFIOAPDevice {
APDevice apdev;
VFIODevice vdev;
EventNotifier req_notifier;
EventNotifier cfg_notifier;
};
OBJECT_DECLARE_SIMPLE_TYPE(VFIOAPDevice, VFIO_AP_DEVICE)
@ -70,6 +72,18 @@ static void vfio_ap_req_notifier_handler(void *opaque)
}
}
static void vfio_ap_cfg_chg_notifier_handler(void *opaque)
{
VFIOAPDevice *vapdev = opaque;
if (!event_notifier_test_and_clear(&vapdev->cfg_notifier)) {
return;
}
css_generate_css_crws(0);
}
static bool vfio_ap_register_irq_notifier(VFIOAPDevice *vapdev,
unsigned int irq, Error **errp)
{
@ -85,6 +99,10 @@ static bool vfio_ap_register_irq_notifier(VFIOAPDevice *vapdev,
notifier = &vapdev->req_notifier;
fd_read = vfio_ap_req_notifier_handler;
break;
case VFIO_AP_CFG_CHG_IRQ_INDEX:
notifier = &vapdev->cfg_notifier;
fd_read = vfio_ap_cfg_chg_notifier_handler;
break;
default:
error_setg(errp, "vfio: Unsupported device irq(%d)", irq);
return false;
@ -137,6 +155,9 @@ static void vfio_ap_unregister_irq_notifier(VFIOAPDevice *vapdev,
case VFIO_AP_REQ_IRQ_INDEX:
notifier = &vapdev->req_notifier;
break;
case VFIO_AP_CFG_CHG_IRQ_INDEX:
notifier = &vapdev->cfg_notifier;
break;
default:
error_report("vfio: Unsupported device irq(%d)", irq);
return;
@ -176,6 +197,15 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp)
warn_report_err(err);
}
if (!vfio_ap_register_irq_notifier(vapdev, VFIO_AP_CFG_CHG_IRQ_INDEX, &err))
{
/*
* Report this error, but do not make it a failing condition.
* Lack of this IRQ in the host does not prevent normal operation.
*/
warn_report_err(err);
}
return;
error:
@ -188,6 +218,7 @@ static void vfio_ap_unrealize(DeviceState *dev)
VFIOAPDevice *vapdev = VFIO_AP_DEVICE(dev);
vfio_ap_unregister_irq_notifier(vapdev, VFIO_AP_REQ_IRQ_INDEX);
vfio_ap_unregister_irq_notifier(vapdev, VFIO_AP_CFG_CHG_IRQ_INDEX);
vfio_device_detach(&vapdev->vdev);
g_free(vapdev->vdev.name);
}