diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2013-01-17 04:23:46 +0000 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2013-01-18 19:07:47 +0100 |
commit | 28e942f86d46ccd46bf1f4836389abb3ff706dff (patch) | |
tree | 7febe9c29172fa7ff2ee3a61a2be26e941c4b2ff /hw/s390-virtio.c | |
parent | d5627ce8a4fd8dd6d7afd3d4d1ff7e9f1fb86d45 (diff) |
s390: Add a hypercall registration interface.
Allow virtio machines to register for different diag500 function
codes and convert s390-virtio to use it.
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'hw/s390-virtio.c')
-rw-r--r-- | hw/s390-virtio.c | 90 |
1 files changed, 48 insertions, 42 deletions
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c index 3cfb97e2dc..5edaabb7c4 100644 --- a/hw/s390-virtio.c +++ b/hw/s390-virtio.c @@ -36,6 +36,7 @@ #include "hw/s390-virtio-bus.h" #include "hw/s390x/sclp.h" +#include "hw/s390-virtio.h" //#define DEBUG_S390 @@ -47,10 +48,6 @@ do { } while (0) #endif -#define KVM_S390_VIRTIO_NOTIFY 0 -#define KVM_S390_VIRTIO_RESET 1 -#define KVM_S390_VIRTIO_SET_STATUS 2 - #define MAX_BLK_DEVS 10 static VirtIOS390Bus *s390_bus; @@ -65,56 +62,63 @@ S390CPU *s390_cpu_addr2state(uint16_t cpu_addr) return ipi_states[cpu_addr]; } -int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t hypercall) +static int s390_virtio_hcall_notify(const uint64_t *args) { + uint64_t mem = args[0]; int r = 0, i; - dprintf("KVM hypercall: %ld\n", hypercall); - switch (hypercall) { - case KVM_S390_VIRTIO_NOTIFY: - if (mem > ram_size) { - VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus, - mem, &i); - if (dev) { - virtio_queue_notify(dev->vdev, i); - } else { - r = -EINVAL; - } - } else { - /* Early printk */ - } - break; - case KVM_S390_VIRTIO_RESET: - { - VirtIOS390Device *dev; - - dev = s390_virtio_bus_find_mem(s390_bus, mem); - virtio_reset(dev->vdev); - stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0); - s390_virtio_device_sync(dev); - s390_virtio_reset_idx(dev); - break; - } - case KVM_S390_VIRTIO_SET_STATUS: - { - VirtIOS390Device *dev; - - dev = s390_virtio_bus_find_mem(s390_bus, mem); + if (mem > ram_size) { + VirtIOS390Device *dev = s390_virtio_bus_find_vring(s390_bus, mem, &i); if (dev) { - s390_virtio_device_update_status(dev); + virtio_queue_notify(dev->vdev, i); } else { r = -EINVAL; } - break; + } else { + /* Early printk */ } - default: + return r; +} + +static int s390_virtio_hcall_reset(const uint64_t *args) +{ + uint64_t mem = args[0]; + VirtIOS390Device *dev; + + dev = s390_virtio_bus_find_mem(s390_bus, mem); + virtio_reset(dev->vdev); + stb_phys(dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0); + s390_virtio_device_sync(dev); + s390_virtio_reset_idx(dev); + + return 0; +} + +static int s390_virtio_hcall_set_status(const uint64_t *args) +{ + uint64_t mem = args[0]; + int r = 0; + VirtIOS390Device *dev; + + dev = s390_virtio_bus_find_mem(s390_bus, mem); + if (dev) { + s390_virtio_device_update_status(dev); + } else { r = -EINVAL; - break; } - return r; } +static void s390_virtio_register_hcalls(void) +{ + s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY, + s390_virtio_hcall_notify); + s390_register_virtio_hypercall(KVM_S390_VIRTIO_RESET, + s390_virtio_hcall_reset); + s390_register_virtio_hypercall(KVM_S390_VIRTIO_SET_STATUS, + s390_virtio_hcall_set_status); +} + /* * The number of running CPUs. On s390 a shutdown is the state of all CPUs * being either stopped or disabled (for interrupts) waiting. We have to @@ -182,6 +186,9 @@ static void s390_init(QEMUMachineInitArgs *args) qdev_prop_set_string(dev, "cmdline", args->kernel_cmdline); qdev_init_nofail(dev); + /* register hypercalls */ + s390_virtio_register_hcalls(); + /* allocate RAM */ memory_region_init_ram(ram, "s390.ram", my_ram_size); vmstate_register_ram_global(ram); @@ -265,4 +272,3 @@ static void s390_machine_init(void) } machine_init(s390_machine_init); - |