Add Control-Program Identification (CPI) data to the QEMU Object Model (QOM), along with the timestamp in which the data was received as shown below.
virsh # qemu-monitor-command vm --pretty '{"execute":"qom-list", "arguments":{"path":"/machine/sclp/s390-sclp-event-facility/sclpcpi"}}' { "return": [ [...] { "name": "system_level", "type": "uint64" }, { "name": "system_name", "type": "string" }, { "name": "system_type", "type": "string" }, { "name": "timestamp", "type": "uint64" }, { "name": "sysplex_name", "type": "string" } ], "id": "libvirt-14" } Example CPI data: virsh # qemu-monitor-command vm --pretty '{"execute":"qom-get", "arguments":{"path":"/machine/sclp/s390-sclp-event-facility/sclpcpi", "property":"system_type"}}' { "return": "LINUX ", "id": "libvirt-18" } virsh # qemu-monitor-command vm --pretty '{"execute":"qom-get", "arguments":{"path":"/machine/sclp/s390-sclp-event-facility/sclpcpi", "property":"system_name"}}' { "return": "TESTVM ", "id": "libvirt-19" } virsh # qemu-monitor-command vm --pretty '{"execute":"qom-get", "arguments":{"path":"/machine/sclp/s390-sclp-event-facility/sclpcpi", "property":"sysplex_name"}}' { "return": "PLEX ", "id": "libvirt-20" } virsh # qemu-monitor-command vm --pretty '{"execute":"qom-get", "arguments":{"path":"/machine/sclp/s390-sclp-event-facility/sclpcpi", "property":"system_level"}}' { "return": 74872343805430528, "id": "libvirt-21" } virsh # qemu-monitor-command vm --pretty '{"execute":"qom-get", "arguments":{"path":"/machine/sclp/s390-sclp-event-facility/sclpcpi", "property":"timestamp"}}' { "return": 1748866753433923000, "id": "libvirt-22" } Signed-off-by: Shalini Chellathurai Saroja <shal...@linux.ibm.com> --- hw/s390x/sclpcpi.c | 47 +++++++++++++++++++++++++ include/hw/s390x/event-facility.h | 5 +++ qapi/machine.json | 58 +++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) diff --git a/hw/s390x/sclpcpi.c b/hw/s390x/sclpcpi.c index 935fa87acd..ec711e2291 100644 --- a/hw/s390x/sclpcpi.c +++ b/hw/s390x/sclpcpi.c @@ -15,7 +15,9 @@ */ #include "qemu/osdep.h" +#include "qemu/timer.h" #include "hw/s390x/event-facility.h" +#include "hw/s390x/ebcdic.h" typedef struct Data { uint8_t id_format; @@ -55,11 +57,42 @@ static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr) { ControlProgramIdMsg *cpim = container_of(evt_buf_hdr, ControlProgramIdMsg, ebh); + SCLPEventCPI *e = SCLP_EVENT_CPI(event); + + ascii_put(e->system_type, (char *)cpim->data.system_type, + sizeof(cpim->data.system_type)); + ascii_put(e->system_name, (char *)cpim->data.system_name, + sizeof(cpim->data.system_name)); + ascii_put(e->sysplex_name, (char *)cpim->data.sysplex_name, + sizeof(cpim->data.sysplex_name)); + e->system_level = ldq_be_p(&cpim->data.system_level); + e->timestamp = qemu_clock_get_ns(QEMU_CLOCK_HOST); cpim->ebh.flags = SCLP_EVENT_BUFFER_ACCEPTED; return SCLP_RC_NORMAL_COMPLETION; } +static char *get_system_type(Object *obj, Error **errp) +{ + SCLPEventCPI *e = SCLP_EVENT_CPI(obj); + + return g_strndup((char *) e->system_type, sizeof(e->system_type)); +} + +static char *get_system_name(Object *obj, Error **errp) +{ + SCLPEventCPI *e = SCLP_EVENT_CPI(obj); + + return g_strndup((char *) e->system_name, sizeof(e->system_name)); +} + +static char *get_sysplex_name(Object *obj, Error **errp) +{ + SCLPEventCPI *e = SCLP_EVENT_CPI(obj); + + return g_strndup((char *) e->sysplex_name, sizeof(e->sysplex_name)); +} + static void cpi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -73,10 +106,24 @@ static void cpi_class_init(ObjectClass *klass, const void *data) k->write_event_data = write_event_data; } +static void cpi_init(Object *obj) +{ + SCLPEventCPI *e = SCLP_EVENT_CPI(obj); + + object_property_add_str(obj, "system_type", get_system_type, NULL); + object_property_add_str(obj, "system_name", get_system_name, NULL); + object_property_add_str(obj, "sysplex_name", get_sysplex_name, NULL); + object_property_add_uint64_ptr(obj, "system_level", &(e->system_level), + OBJ_PROP_FLAG_READ); + object_property_add_uint64_ptr(obj, "timestamp", &(e->timestamp), + OBJ_PROP_FLAG_READ); +} + static const TypeInfo sclp_cpi_info = { .name = TYPE_SCLP_EVENT_CPI, .parent = TYPE_SCLP_EVENT, .instance_size = sizeof(SCLPEventCPI), + .instance_init = cpi_init, .class_init = cpi_class_init, }; diff --git a/include/hw/s390x/event-facility.h b/include/hw/s390x/event-facility.h index e81bc80498..eac7a51100 100644 --- a/include/hw/s390x/event-facility.h +++ b/include/hw/s390x/event-facility.h @@ -201,6 +201,11 @@ OBJECT_DECLARE_TYPE(SCLPEventCPI, SCLPEventCPIClass, struct SCLPEventCPI { SCLPEvent event; + uint8_t system_type[8]; + uint8_t system_name[8]; + uint64_t system_level; + uint8_t sysplex_name[8]; + uint64_t timestamp; }; #define TYPE_SCLP_EVENT_FACILITY "s390-sclp-event-facility" diff --git a/qapi/machine.json b/qapi/machine.json index 5373e1368c..1f2db68032 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -2279,3 +2279,61 @@ # Since: 1.2 ## { 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] } + +## +# @S390ControlProgramId: +# +# Control-program identifiers provide data about the guest operating system. +# The control-program identifiers are: system type, system name, system level +# and sysplex name. +# +# In Linux, all the control-program identifiers are user configurable. The +# system type, system name, and sysplex name use EBCDIC characters from +# this set: capital A-Z, 0-9, $, @, #, and blank. In Linux, the system type, +# system name and sysplex name are arbitrary free-form texts. +# +# In Linux, the 8-byte hexadecimal system-level has the format +# 0x<a><b><cc><dd><eeee><ff><gg><hh>, where: +# <a>: is one hexadecimal byte, its most significant bit indicates hypervisor +# use +# <b>: is one digit that represents Linux distributions as follows +# 0: generic Linux +# 1: Red Hat Enterprise Linux +# 2: SUSE Linux Enterprise Server +# 3: Canonical Ubuntu +# 4: Fedora +# 5: openSUSE Leap +# 6: Debian GNU/Linux +# 7: Red Hat Enterprise Linux CoreOS +# <cc>: are two digits for a distribution-specific encoding of the major version +# of the distribution +# <dd>: are two digits for a distribution-specific encoding of the minor version +# of the distribution +# <eeee>: are four digits for the patch level of the distribution +# <ff>: are two digits for the major version of the kernel +# <gg>: are two digits for the minor version of the kernel +# <hh>: are two digits for the stable version of the kernel +# (e.g. 74872343805430528, when converted to hex is 0x010a000000060b00). On +# machines prior to z16, some of the values are not available to display. +# +# Sysplex refers to a cluster of logical partitions that communicates and +# co-operates with each other. +# +# @system-type: operating system (e.g. "LINUX ") +# +# @system-name: user configurable name of the VM (e.g. "TESTVM ") +# +# @system-level: distribution and kernel version in Linux +# +# @sysplex-name: sysplex which the VM belongs to, if any (e.g. "PLEX ") +# +# @timestamp: latest update of CPI data in nanoseconds since the UNIX EPOCH +# +# Since: 10.1 +## +{ 'struct': 'S390ControlProgramId', 'data': { + 'system-type': 'str', + 'system-name': 'str', + 'system-level': 'uint64', + 'sysplex-name': 'str', + 'timestamp': 'uint64' } } -- 2.49.0