mirror of https://gitee.com/openkylin/qemu.git
Merge remote-tracking branch 'cohuck/virtio-ccw-upstr' into staging
# By Cornelia Huck (2) and Christian Borntraeger (1) # Via Cornelia Huck * cohuck/virtio-ccw-upstr: virtio-ccw: Wire up guest and host notifies. virtio-ccw: Wire up ioeventfd. s390/virtio-ccw: Fix virtio reset Message-id: 1372177538-9812-1-git-send-email-cornelia.huck@de.ibm.com Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
commit
9e49c8c58c
|
@ -68,7 +68,7 @@ int css_create_css_image(uint8_t cssid, bool default_image)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t css_build_subchannel_id(SubchDev *sch)
|
uint16_t css_build_subchannel_id(SubchDev *sch)
|
||||||
{
|
{
|
||||||
if (channel_subsys->max_cssid > 0) {
|
if (channel_subsys->max_cssid > 0) {
|
||||||
return (sch->cssid << 8) | (1 << 3) | (sch->ssid << 1) | 1;
|
return (sch->cssid << 8) | (1 << 3) | (sch->ssid << 1) | 1;
|
||||||
|
|
|
@ -90,6 +90,7 @@ bool css_devno_used(uint8_t cssid, uint8_t ssid, uint16_t devno);
|
||||||
void css_subch_assign(uint8_t cssid, uint8_t ssid, uint16_t schid,
|
void css_subch_assign(uint8_t cssid, uint8_t ssid, uint16_t schid,
|
||||||
uint16_t devno, SubchDev *sch);
|
uint16_t devno, SubchDev *sch);
|
||||||
void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type);
|
void css_sch_build_virtual_schib(SubchDev *sch, uint8_t chpid, uint8_t type);
|
||||||
|
uint16_t css_build_subchannel_id(SubchDev *sch);
|
||||||
void css_reset(void);
|
void css_reset(void);
|
||||||
void css_reset_sch(SubchDev *sch);
|
void css_reset_sch(SubchDev *sch);
|
||||||
void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, uint16_t rsid);
|
void css_queue_crw(uint8_t rsc, uint8_t erc, int chain, uint16_t rsid);
|
||||||
|
|
|
@ -63,6 +63,91 @@ VirtIODevice *virtio_ccw_get_vdev(SubchDev *sch)
|
||||||
return vdev;
|
return vdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int virtio_ccw_set_guest2host_notifier(VirtioCcwDevice *dev, int n,
|
||||||
|
bool assign, bool set_handler)
|
||||||
|
{
|
||||||
|
VirtQueue *vq = virtio_get_queue(dev->vdev, n);
|
||||||
|
EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
|
||||||
|
int r = 0;
|
||||||
|
SubchDev *sch = dev->sch;
|
||||||
|
uint32_t sch_id = (css_build_subchannel_id(sch) << 16) | sch->schid;
|
||||||
|
|
||||||
|
if (assign) {
|
||||||
|
r = event_notifier_init(notifier, 1);
|
||||||
|
if (r < 0) {
|
||||||
|
error_report("%s: unable to init event notifier: %d", __func__, r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
|
||||||
|
r = s390_assign_subch_ioeventfd(event_notifier_get_fd(notifier), sch_id,
|
||||||
|
n, assign);
|
||||||
|
if (r < 0) {
|
||||||
|
error_report("%s: unable to assign ioeventfd: %d", __func__, r);
|
||||||
|
virtio_queue_set_host_notifier_fd_handler(vq, false, false);
|
||||||
|
event_notifier_cleanup(notifier);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
virtio_queue_set_host_notifier_fd_handler(vq, false, false);
|
||||||
|
s390_assign_subch_ioeventfd(event_notifier_get_fd(notifier), sch_id,
|
||||||
|
n, assign);
|
||||||
|
event_notifier_cleanup(notifier);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void virtio_ccw_start_ioeventfd(VirtioCcwDevice *dev)
|
||||||
|
{
|
||||||
|
int n, r;
|
||||||
|
|
||||||
|
if (!(dev->flags & VIRTIO_CCW_FLAG_USE_IOEVENTFD) ||
|
||||||
|
dev->ioeventfd_disabled ||
|
||||||
|
dev->ioeventfd_started) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
|
||||||
|
if (!virtio_queue_get_num(dev->vdev, n)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
r = virtio_ccw_set_guest2host_notifier(dev, n, true, true);
|
||||||
|
if (r < 0) {
|
||||||
|
goto assign_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dev->ioeventfd_started = true;
|
||||||
|
return;
|
||||||
|
|
||||||
|
assign_error:
|
||||||
|
while (--n >= 0) {
|
||||||
|
if (!virtio_queue_get_num(dev->vdev, n)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
|
||||||
|
assert(r >= 0);
|
||||||
|
}
|
||||||
|
dev->ioeventfd_started = false;
|
||||||
|
/* Disable ioeventfd for this device. */
|
||||||
|
dev->flags &= ~VIRTIO_CCW_FLAG_USE_IOEVENTFD;
|
||||||
|
error_report("%s: failed. Fallback to userspace (slower).", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void virtio_ccw_stop_ioeventfd(VirtioCcwDevice *dev)
|
||||||
|
{
|
||||||
|
int n, r;
|
||||||
|
|
||||||
|
if (!dev->ioeventfd_started) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
|
||||||
|
if (!virtio_queue_get_num(dev->vdev, n)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
r = virtio_ccw_set_guest2host_notifier(dev, n, false, false);
|
||||||
|
assert(r >= 0);
|
||||||
|
}
|
||||||
|
dev->ioeventfd_started = false;
|
||||||
|
}
|
||||||
|
|
||||||
VirtualCssBus *virtual_css_bus_init(void)
|
VirtualCssBus *virtual_css_bus_init(void)
|
||||||
{
|
{
|
||||||
VirtualCssBus *cbus;
|
VirtualCssBus *cbus;
|
||||||
|
@ -187,6 +272,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CCW_CMD_VDEV_RESET:
|
case CCW_CMD_VDEV_RESET:
|
||||||
|
virtio_ccw_stop_ioeventfd(dev);
|
||||||
virtio_reset(dev->vdev);
|
virtio_reset(dev->vdev);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -309,10 +395,16 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
} else {
|
} else {
|
||||||
status = ldub_phys(ccw.cda);
|
status = ldub_phys(ccw.cda);
|
||||||
|
if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
|
||||||
|
virtio_ccw_stop_ioeventfd(dev);
|
||||||
|
}
|
||||||
virtio_set_status(dev->vdev, status);
|
virtio_set_status(dev->vdev, status);
|
||||||
if (dev->vdev->status == 0) {
|
if (dev->vdev->status == 0) {
|
||||||
virtio_reset(dev->vdev);
|
virtio_reset(dev->vdev);
|
||||||
}
|
}
|
||||||
|
if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
|
||||||
|
virtio_ccw_start_ioeventfd(dev);
|
||||||
|
}
|
||||||
sch->curr_status.scsw.count = ccw.count - sizeof(status);
|
sch->curr_status.scsw.count = ccw.count - sizeof(status);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
@ -540,6 +632,7 @@ static int virtio_ccw_exit(VirtioCcwDevice *dev)
|
||||||
{
|
{
|
||||||
SubchDev *sch = dev->sch;
|
SubchDev *sch = dev->sch;
|
||||||
|
|
||||||
|
virtio_ccw_stop_ioeventfd(dev);
|
||||||
if (sch) {
|
if (sch) {
|
||||||
css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
|
css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
|
||||||
g_free(sch);
|
g_free(sch);
|
||||||
|
@ -801,8 +894,106 @@ static void virtio_ccw_reset(DeviceState *d)
|
||||||
{
|
{
|
||||||
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||||
|
|
||||||
|
virtio_ccw_stop_ioeventfd(dev);
|
||||||
virtio_reset(dev->vdev);
|
virtio_reset(dev->vdev);
|
||||||
css_reset_sch(dev->sch);
|
css_reset_sch(dev->sch);
|
||||||
|
dev->indicators = 0;
|
||||||
|
dev->indicators2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void virtio_ccw_vmstate_change(DeviceState *d, bool running)
|
||||||
|
{
|
||||||
|
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||||
|
|
||||||
|
if (running) {
|
||||||
|
virtio_ccw_start_ioeventfd(dev);
|
||||||
|
} else {
|
||||||
|
virtio_ccw_stop_ioeventfd(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool virtio_ccw_query_guest_notifiers(DeviceState *d)
|
||||||
|
{
|
||||||
|
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||||
|
|
||||||
|
return !!(dev->sch->curr_status.pmcw.flags & PMCW_FLAGS_MASK_ENA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virtio_ccw_set_host_notifier(DeviceState *d, int n, bool assign)
|
||||||
|
{
|
||||||
|
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||||
|
|
||||||
|
/* Stop using the generic ioeventfd, we are doing eventfd handling
|
||||||
|
* ourselves below */
|
||||||
|
dev->ioeventfd_disabled = assign;
|
||||||
|
if (assign) {
|
||||||
|
virtio_ccw_stop_ioeventfd(dev);
|
||||||
|
}
|
||||||
|
return virtio_ccw_set_guest2host_notifier(dev, n, assign, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n,
|
||||||
|
bool assign, bool with_irqfd)
|
||||||
|
{
|
||||||
|
VirtQueue *vq = virtio_get_queue(dev->vdev, n);
|
||||||
|
EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
|
||||||
|
VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(dev->vdev);
|
||||||
|
|
||||||
|
if (assign) {
|
||||||
|
int r = event_notifier_init(notifier, 0);
|
||||||
|
|
||||||
|
if (r < 0) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd);
|
||||||
|
/* We do not support irqfd for classic I/O interrupts, because the
|
||||||
|
* classic interrupts are intermixed with the subchannel status, that
|
||||||
|
* is queried with test subchannel. We want to use vhost, though.
|
||||||
|
* Lets make sure to have vhost running and wire up the irq fd to
|
||||||
|
* land in qemu (and only the irq fd) in this code.
|
||||||
|
*/
|
||||||
|
if (k->guest_notifier_mask) {
|
||||||
|
k->guest_notifier_mask(dev->vdev, n, false);
|
||||||
|
}
|
||||||
|
/* get lost events and re-inject */
|
||||||
|
if (k->guest_notifier_pending &&
|
||||||
|
k->guest_notifier_pending(dev->vdev, n)) {
|
||||||
|
event_notifier_set(notifier);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (k->guest_notifier_mask) {
|
||||||
|
k->guest_notifier_mask(dev->vdev, n, true);
|
||||||
|
}
|
||||||
|
virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
|
||||||
|
event_notifier_cleanup(notifier);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virtio_ccw_set_guest_notifiers(DeviceState *d, int nvqs,
|
||||||
|
bool assigned)
|
||||||
|
{
|
||||||
|
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
|
||||||
|
VirtIODevice *vdev = dev->vdev;
|
||||||
|
int r, n;
|
||||||
|
|
||||||
|
for (n = 0; n < nvqs; n++) {
|
||||||
|
if (!virtio_queue_get_num(vdev, n)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* false -> true, as soon as irqfd works */
|
||||||
|
r = virtio_ccw_set_guest_notifier(dev, n, assigned, false);
|
||||||
|
if (r < 0) {
|
||||||
|
goto assign_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
assign_error:
|
||||||
|
while (--n >= 0) {
|
||||||
|
virtio_ccw_set_guest_notifier(dev, n, !assigned, false);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************** Virtio-ccw Bus Device Descriptions *******************/
|
/**************** Virtio-ccw Bus Device Descriptions *******************/
|
||||||
|
@ -812,6 +1003,8 @@ static Property virtio_ccw_net_properties[] = {
|
||||||
DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features[0]),
|
DEFINE_VIRTIO_NET_FEATURES(VirtioCcwDevice, host_features[0]),
|
||||||
DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetCcw, vdev.net_conf),
|
DEFINE_VIRTIO_NET_PROPERTIES(VirtIONetCcw, vdev.net_conf),
|
||||||
DEFINE_NIC_PROPERTIES(VirtIONetCcw, vdev.nic_conf),
|
DEFINE_NIC_PROPERTIES(VirtIONetCcw, vdev.nic_conf),
|
||||||
|
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||||
|
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -838,6 +1031,8 @@ static Property virtio_ccw_blk_properties[] = {
|
||||||
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
||||||
DEFINE_VIRTIO_BLK_FEATURES(VirtioCcwDevice, host_features[0]),
|
DEFINE_VIRTIO_BLK_FEATURES(VirtioCcwDevice, host_features[0]),
|
||||||
DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkCcw, blk),
|
DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkCcw, blk),
|
||||||
|
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||||
|
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -864,6 +1059,8 @@ static Property virtio_ccw_serial_properties[] = {
|
||||||
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
||||||
DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtioSerialCcw, vdev.serial),
|
DEFINE_VIRTIO_SERIAL_PROPERTIES(VirtioSerialCcw, vdev.serial),
|
||||||
DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
|
DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
|
||||||
|
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||||
|
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -889,6 +1086,8 @@ static const TypeInfo virtio_ccw_serial = {
|
||||||
static Property virtio_ccw_balloon_properties[] = {
|
static Property virtio_ccw_balloon_properties[] = {
|
||||||
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
||||||
DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
|
DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
|
||||||
|
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||||
|
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -915,6 +1114,8 @@ static Property virtio_ccw_scsi_properties[] = {
|
||||||
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
||||||
DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
|
DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSICcw, vdev.parent_obj.conf),
|
||||||
DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features[0]),
|
DEFINE_VIRTIO_SCSI_FEATURES(VirtioCcwDevice, host_features[0]),
|
||||||
|
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||||
|
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -978,6 +1179,8 @@ static Property virtio_ccw_rng_properties[] = {
|
||||||
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
DEFINE_PROP_STRING("devno", VirtioCcwDevice, bus_id),
|
||||||
DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
|
DEFINE_VIRTIO_COMMON_FEATURES(VirtioCcwDevice, host_features[0]),
|
||||||
DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGCcw, vdev.conf),
|
DEFINE_VIRTIO_RNG_PROPERTIES(VirtIORNGCcw, vdev.conf),
|
||||||
|
DEFINE_PROP_BIT("ioeventfd", VirtioCcwDevice, flags,
|
||||||
|
VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT, true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1105,6 +1308,10 @@ static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
|
||||||
bus_class->max_dev = 1;
|
bus_class->max_dev = 1;
|
||||||
k->notify = virtio_ccw_notify;
|
k->notify = virtio_ccw_notify;
|
||||||
k->get_features = virtio_ccw_get_features;
|
k->get_features = virtio_ccw_get_features;
|
||||||
|
k->vmstate_change = virtio_ccw_vmstate_change;
|
||||||
|
k->query_guest_notifiers = virtio_ccw_query_guest_notifiers;
|
||||||
|
k->set_host_notifier = virtio_ccw_set_host_notifier;
|
||||||
|
k->set_guest_notifiers = virtio_ccw_set_guest_notifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo virtio_ccw_bus_info = {
|
static const TypeInfo virtio_ccw_bus_info = {
|
||||||
|
|
|
@ -69,6 +69,11 @@ typedef struct VirtIOCCWDeviceClass {
|
||||||
/* Change here if we want to support more feature bits. */
|
/* Change here if we want to support more feature bits. */
|
||||||
#define VIRTIO_CCW_FEATURE_SIZE 1
|
#define VIRTIO_CCW_FEATURE_SIZE 1
|
||||||
|
|
||||||
|
/* Performance improves when virtqueue kick processing is decoupled from the
|
||||||
|
* vcpu thread using ioeventfd for some devices. */
|
||||||
|
#define VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT 1
|
||||||
|
#define VIRTIO_CCW_FLAG_USE_IOEVENTFD (1 << VIRTIO_CCW_FLAG_USE_IOEVENTFD_BIT)
|
||||||
|
|
||||||
struct VirtioCcwDevice {
|
struct VirtioCcwDevice {
|
||||||
DeviceState parent_obj;
|
DeviceState parent_obj;
|
||||||
SubchDev *sch;
|
SubchDev *sch;
|
||||||
|
@ -76,6 +81,9 @@ struct VirtioCcwDevice {
|
||||||
char *bus_id;
|
char *bus_id;
|
||||||
uint32_t host_features[VIRTIO_CCW_FEATURE_SIZE];
|
uint32_t host_features[VIRTIO_CCW_FEATURE_SIZE];
|
||||||
VirtioBusState bus;
|
VirtioBusState bus;
|
||||||
|
bool ioeventfd_started;
|
||||||
|
bool ioeventfd_disabled;
|
||||||
|
uint32_t flags;
|
||||||
/* Guest provided values: */
|
/* Guest provided values: */
|
||||||
hwaddr indicators;
|
hwaddr indicators;
|
||||||
hwaddr indicators2;
|
hwaddr indicators2;
|
||||||
|
|
|
@ -1081,6 +1081,7 @@ void kvm_s390_io_interrupt(S390CPU *cpu, uint16_t subchannel_id,
|
||||||
void kvm_s390_crw_mchk(S390CPU *cpu);
|
void kvm_s390_crw_mchk(S390CPU *cpu);
|
||||||
void kvm_s390_enable_css_support(S390CPU *cpu);
|
void kvm_s390_enable_css_support(S390CPU *cpu);
|
||||||
int kvm_s390_get_registers_partial(CPUState *cpu);
|
int kvm_s390_get_registers_partial(CPUState *cpu);
|
||||||
|
int kvm_s390_assign_subch_ioeventfd(int fd, uint32_t sch, int vq, bool assign);
|
||||||
#else
|
#else
|
||||||
static inline void kvm_s390_io_interrupt(S390CPU *cpu,
|
static inline void kvm_s390_io_interrupt(S390CPU *cpu,
|
||||||
uint16_t subchannel_id,
|
uint16_t subchannel_id,
|
||||||
|
@ -1099,6 +1100,11 @@ static inline int kvm_s390_get_registers_partial(CPUState *cpu)
|
||||||
{
|
{
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
static inline int kvm_s390_assign_subch_ioeventfd(int fd, uint32_t sch, int vq,
|
||||||
|
bool assign)
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void s390_io_interrupt(S390CPU *cpu,
|
static inline void s390_io_interrupt(S390CPU *cpu,
|
||||||
|
@ -1125,4 +1131,14 @@ static inline void s390_crw_mchk(S390CPU *cpu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int s390_assign_subch_ioeventfd(int fd, uint32_t sch_id, int vq,
|
||||||
|
bool assign)
|
||||||
|
{
|
||||||
|
if (kvm_enabled()) {
|
||||||
|
return kvm_s390_assign_subch_ioeventfd(fd, sch_id, vq, assign);
|
||||||
|
} else {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -932,3 +932,22 @@ void kvm_s390_enable_css_support(S390CPU *cpu)
|
||||||
void kvm_arch_init_irq_routing(KVMState *s)
|
void kvm_arch_init_irq_routing(KVMState *s)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int kvm_s390_assign_subch_ioeventfd(int fd, uint32_t sch, int vq, bool assign)
|
||||||
|
{
|
||||||
|
struct kvm_ioeventfd kick = {
|
||||||
|
.flags = KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY |
|
||||||
|
KVM_IOEVENTFD_FLAG_DATAMATCH,
|
||||||
|
.fd = fd,
|
||||||
|
.datamatch = vq,
|
||||||
|
.addr = sch,
|
||||||
|
.len = 8,
|
||||||
|
};
|
||||||
|
if (!kvm_check_extension(kvm_state, KVM_CAP_IOEVENTFD)) {
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
if (!assign) {
|
||||||
|
kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN;
|
||||||
|
}
|
||||||
|
return kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue