From: Ekaterina Tumanova <tumanova@xxxxxxxxxxxxxxxxxx> The following patch adds Qemu CONFIG device, which interacts with kvm CONFIG device by calling KVM_CREATE_DEVICE (to create the device in kernel), KVM_GET_DEVICE_ATTR and KVM_SET_DEVICE_ATTR (to get and set the particular attributes of KVM CONFIG device respectively). This patch uses the Qemu CONFIG device to copy the qemu_name (if specified) into the kvm CONFIG device. Signed-off-by: Ekaterina Tumanova <tumanova@xxxxxxxxxxxxxxxxxx> Signed-off-by: Christian Borntraeger <borntraeger@xxxxxxxxxx> Signed-off-by: Michael Mueller <mimu@xxxxxxxxxxxxxxxxxx> Signed-off-by: Jens Freimann <jfrei@xxxxxxxxxxxxxxxxxx> --- default-configs/s390x-softmmu.mak | 1 + hw/s390x/Makefile.objs | 1 + hw/s390x/config.c | 113 ++++++++++++++++++++++++++++++++++++++ hw/s390x/s390-virtio-ccw.c | 6 ++ hw/s390x/s390-virtio.c | 24 ++++++++ hw/s390x/s390-virtio.h | 1 + include/hw/s390x/config.h | 51 +++++++++++++++++ linux-headers/asm-s390/kvm.h | 11 ++++ linux-headers/linux/kvm.h | 1 + trace-events | 4 ++ 10 files changed, 213 insertions(+) create mode 100644 hw/s390x/config.c create mode 100644 include/hw/s390x/config.h diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak index d843dc0..a07697d 100644 --- a/default-configs/s390x-softmmu.mak +++ b/default-configs/s390x-softmmu.mak @@ -1,3 +1,4 @@ CONFIG_VIRTIO=y CONFIG_SCLPCONSOLE=y CONFIG_S390_FLIC=$(CONFIG_KVM) +CONFIG_S390_CONFIG=$(CONFIG_KVM) diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs index 1ba6c3a..dc03e1d 100644 --- a/hw/s390x/Makefile.objs +++ b/hw/s390x/Makefile.objs @@ -8,3 +8,4 @@ obj-y += ipl.o obj-y += css.o obj-y += s390-virtio-ccw.o obj-y += virtio-ccw.o +obj-$(CONFIG_S390_CONFIG) += config.o diff --git a/hw/s390x/config.c b/hw/s390x/config.c new file mode 100644 index 0000000..f70e880 --- /dev/null +++ b/hw/s390x/config.c @@ -0,0 +1,113 @@ +/* + * S390 configuration and control device + * + * Copyright 2014 IBM Corp. + * Author(s): Ekaterina Tumanova <tumanova@xxxxxxxxxxxxxxxxxx> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include <sys/ioctl.h> +#include "hw/s390x/config.h" +#include "trace.h" + +S390ConfigState *get_config_state(void) +{ + return S390_CONFIG(object_resolve_path("/machine/s390-config", NULL)); +} + +static int config_set(S390ConfigState *config, struct kvm_device_attr *attr) +{ + int rc; + + rc = ioctl(config->fd, KVM_SET_DEVICE_ATTR, attr); + return rc < 0 ? -errno : rc; +} + +/* +static int config_get(S390ConfigState *config, struct kvm_device_attr *attr) +{ + int rc; + + rc = ioctl(config->fd, KVM_GET_DEVICE_ATTR, attr); + return rc < 0 ? -errno : rc; +} +*/ + +static int config_set_name(S390ConfigState *config, char *name) +{ + struct kvm_device_attr attr = { + .group = KVM_DEV_CONFIG_GROUP, + .attr = KVM_DEV_CONFIG_NAME, + .addr = (uint64_t)name, + }; + + if (!name || + (qemu_strnlen(name, S390_MACHINE_NAME_SIZE) + >= S390_MACHINE_NAME_SIZE)) { + return -EINVAL; + } + + return config_set(config, &attr); +} + +static void s390_config_realize(DeviceState *dev, Error **errp) +{ + S390ConfigState *cfg = S390_CONFIG(dev); + struct kvm_create_device cd = {0}; + int ret; + + if (!kvm_check_extension(kvm_state, KVM_CAP_DEVICE_CTRL)) { + trace_config_no_device_api(errno); + return; + } + + cd.type = KVM_DEV_TYPE_S390_CONFIG; + ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd); + if (ret < 0) { + trace_config_create_device(errno); + return; + } + cfg->fd = cd.fd; +} + +void s390_config_dev_init(void) +{ + DeviceState *dev; + + if (kvm_enabled()) { + dev = qdev_create(NULL, TYPE_S390_CONFIG); + + object_property_add_child(qdev_get_machine(), + TYPE_S390_CONFIG, + OBJECT(dev), NULL); + qdev_init_nofail(dev); + } +} + +static void s390_config_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + S390ConfigClass *scc = S390_CONFIG_CLASS(oc); + + dc->realize = s390_config_realize; + scc->set_name = config_set_name; +} + +static const TypeInfo s390_config_info = { + .name = TYPE_S390_CONFIG, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(S390ConfigState), + .class_init = s390_config_class_init, + .class_size = sizeof(S390ConfigClass), +}; + + +static void s390_config_register_types(void) +{ + type_register_static(&s390_config_info); +} + +type_init(s390_config_register_types) diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 0d4f6ae..1e4b9ad 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -14,9 +14,11 @@ #include "s390-virtio.h" #include "hw/s390x/sclp.h" #include "hw/s390x/s390_flic.h" +#include "hw/s390x/config.h" #include "ioinst.h" #include "css.h" #include "virtio-ccw.h" +#include "qemu/error-report.h" void io_subsystem_reset(void) { @@ -106,6 +108,10 @@ static void ccw_init(QEMUMachineInitArgs *args) args->initrd_filename, "s390-ccw.img"); s390_flic_init(); + s390_config_dev_init(); + + s390_set_vm_name(); + /* register hypercalls */ virtio_ccw_register_hcalls(); diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c index aef2003..7a296fd 100644 --- a/hw/s390x/s390-virtio.c +++ b/hw/s390x/s390-virtio.c @@ -39,6 +39,8 @@ #include "hw/s390x/s390_flic.h" #include "hw/s390x/s390-virtio.h" +#include "hw/s390x/config.h" + //#define DEBUG_S390 #ifdef DEBUG_S390 @@ -223,6 +225,24 @@ void s390_create_virtio_net(BusState *bus, const char *name) } } +void s390_set_vm_name(void) +{ + S390ConfigState *config = get_config_state(); + char machine_name[S390_MACHINE_NAME_SIZE]; + S390ConfigClass *scc; + + if (!config || !qemu_name) { + return; + } + strncpy(machine_name, qemu_name, sizeof(machine_name)); + + scc = S390_CONFIG_GET_CLASS(config); + + if (scc->set_name(config, machine_name)) { + error_report("Setting machine name failed: %m"); + } +} + /* PC hardware initialisation */ static void s390_init(QEMUMachineInitArgs *args) { @@ -252,6 +272,10 @@ static void s390_init(QEMUMachineInitArgs *args) args->initrd_filename, ZIPL_FILENAME); s390_flic_init(); + s390_config_dev_init(); + + s390_set_vm_name(); + /* register hypercalls */ s390_virtio_register_hcalls(); diff --git a/hw/s390x/s390-virtio.h b/hw/s390x/s390-virtio.h index 5c405e7..deca18e 100644 --- a/hw/s390x/s390-virtio.h +++ b/hw/s390x/s390-virtio.h @@ -26,4 +26,5 @@ void s390_init_ipl_dev(const char *kernel_filename, const char *initrd_filename, const char *firmware); void s390_create_virtio_net(BusState *bus, const char *name); +void s390_set_vm_name(void); #endif diff --git a/include/hw/s390x/config.h b/include/hw/s390x/config.h new file mode 100644 index 0000000..14d9b02 --- /dev/null +++ b/include/hw/s390x/config.h @@ -0,0 +1,51 @@ +/* + * S390 configuration and control device + * + * Copyright 2014 IBM Corp. + * Author(s): Ekaterina Tumanova <tumanova@xxxxxxxxxxxxxxxxxx> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#ifndef __KVM_S390_CONFIG_H +#define __KVM_S390_CONFIG_H + +#include "hw/sysbus.h" +#include "migration/qemu-file.h" + +#define TYPE_S390_CONFIG "s390-config" +#define S390_CONFIG(obj) \ + OBJECT_CHECK(S390ConfigState, (obj), TYPE_S390_CONFIG) +#define S390_CONFIG_CLASS(class) \ + OBJECT_CLASS_CHECK(S390ConfigClass, (class), TYPE_S390_CONFIG) +#define S390_CONFIG_GET_CLASS(obj) \ + OBJECT_GET_CLASS(S390ConfigClass, (obj), TYPE_S390_CONFIG) + +typedef struct S390ConfigState { + SysBusDevice parent_obj; + uint32_t fd; +} S390ConfigState; + +typedef struct S390ConfigClass { + /*< private >*/ + SysBusDeviceClass parent_class; + /*< public >*/ + int (*set_name)(S390ConfigState *config, char *name); +} S390ConfigClass; + +#ifdef CONFIG_KVM +void s390_config_dev_init(void); +S390ConfigState *get_config_state(void); +#define S390_MACHINE_NAME_SIZE sizeof(struct kvm_s390_attr_name) +#else +static inline void s390_config_dev_init(void) { } +static inline S390ConfigState *get_config_state(void) +{ + return NULL; +} +#define S390_MACHINE_NAME_SIZE 128 +#endif + +#endif /* __KVM_S390_CONFIG_H */ diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h index cb4c1eb..432ffa5 100644 --- a/linux-headers/asm-s390/kvm.h +++ b/linux-headers/asm-s390/kvm.h @@ -57,6 +57,17 @@ struct kvm_debug_exit_arch { struct kvm_guest_debug_arch { }; + + +/* config device specific GROUPS */ + +#define KVM_DEV_CONFIG_GROUP 0 +#define KVM_DEV_CONFIG_NAME 0 + +struct kvm_s390_attr_name { + char name[128]; +}; + #define KVM_SYNC_PREFIX (1UL << 0) #define KVM_SYNC_GPRS (1UL << 1) #define KVM_SYNC_ACRS (1UL << 2) diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index e27a4b3..59d1ec3 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -921,6 +921,7 @@ struct kvm_device_attr { #define KVM_DEV_VFIO_GROUP_DEL 2 #define KVM_DEV_TYPE_ARM_VGIC_V2 5 #define KVM_DEV_TYPE_FLIC 6 +#define KVM_DEV_TYPE_S390_CONFIG 7 /* * ioctls for VM fds diff --git a/trace-events b/trace-events index 3df3f32..6ccd619 100644 --- a/trace-events +++ b/trace-events @@ -1185,6 +1185,10 @@ css_adapter_interrupt(uint8_t isc) "CSS: adapter I/O interrupt (isc %x)" virtio_ccw_interpret_ccw(int cssid, int ssid, int schid, int cmd_code) "VIRTIO-CCW: %x.%x.%04x: interpret command %x" virtio_ccw_new_device(int cssid, int ssid, int schid, int devno, const char *devno_mode) "VIRTIO-CCW: add subchannel %x.%x.%04x, devno %04x (%s)" +# hw/s390x/config.c +config_no_device_api(int err) "config_dev: no Device Control API support %d" +config_create_device(int err) "config_dev: create device failed %d" + # hw/intc/s390_flic.c flic_create_device(int err) "flic: create device failed %d" flic_no_device_api(int err) "flic: no Device Contral API support %d" -- 1.8.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-s390" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html