@@ -39,7 +39,7 @@ typedef struct SCLPEventsBus {
struct SCLPEventFacility {
SysBusDevice parent_obj;
SCLPEventsBus sbus;
- SCLPEvent quiesce, cpu_hotplug;
+ SCLPEvent quiesce, cpu_hotplug, cpi;
/* guest's receive mask */
union {
uint32_t receive_mask_pieces[2];
@@ -436,6 +436,10 @@ static void init_event_facility(Object *obj)
object_initialize_child(obj, TYPE_SCLP_CPU_HOTPLUG,
&event_facility->cpu_hotplug,
TYPE_SCLP_CPU_HOTPLUG);
+
+ object_initialize_child(obj, TYPE_SCLP_CPI,
+ &event_facility->cpi,
+ TYPE_SCLP_CPI);
}
static void realize_event_facility(DeviceState *dev, Error **errp)
@@ -451,6 +455,12 @@ static void realize_event_facility(DeviceState *dev, Error **errp)
qdev_unrealize(DEVICE(&event_facility->quiesce));
return;
}
+ if (!qdev_realize(DEVICE(&event_facility->cpi),
+ BUS(&event_facility->sbus), errp)) {
+ qdev_unrealize(DEVICE(&event_facility->quiesce));
+ qdev_unrealize(DEVICE(&event_facility->cpu_hotplug));
+ return;
+ }
}
static void reset_event_facility(DeviceState *dev)
@@ -13,6 +13,7 @@ s390x_ss.add(files(
's390-skeys.c',
's390-stattrib.c',
'sclp.c',
+ 'sclpcpi.c',
'sclpcpu.c',
'sclpquiesce.c',
'tod.c',
new file mode 100644
@@ -0,0 +1,94 @@
+/*
+ * SCLP event type 11 - Control-Program Identification(CPI):
+ * CPI is used to send program identifiers from control-program to the SCLP.
+ * The program identifiers provide data about Linux instance. It is not sent
+ * by the SCLP.
+ *
+ * The program identifiers are system type, system name, sysplex name and
+ * system level. The system type, system name, and sysplex name use EBCDIC
+ * ucharacters from this set: capital A-Z, 0-9, $, @, #, and blank. The
+ * system level is hex value.
+ *
+ * Copyright IBM, Corp. 2024
+ *
+ * Authors:
+ * Shalini Chellathurai Saroja <shalini@linux.ibm.com>
+ *
+ * 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 "qemu/osdep.h"
+#include "hw/s390x/sclp.h"
+#include "hw/s390x/event-facility.h"
+
+typedef struct Data {
+ uint8_t id_format;
+ uint8_t reserved0;
+ uint8_t system_type[8];
+ uint64_t reserved1;
+ uint8_t system_name[8];
+ uint64_t reserved2;
+ uint64_t system_level;
+ uint64_t reserved3;
+ uint8_t sysplex_name[8];
+ uint8_t reserved4[16];
+} QEMU_PACKED Data;
+
+typedef struct CPI {
+ EventBufferHeader ebh;
+ Data data;
+} QEMU_PACKED CPI;
+
+static bool can_handle_event(uint8_t type)
+{
+ return type == SCLP_EVENT_CPI;
+}
+
+static sccb_mask_t send_mask(void)
+{
+ return 0;
+}
+
+/* Enable SCLP to accept buffers of event type CPI from the control-program. */
+static sccb_mask_t receive_mask(void)
+{
+ return SCLP_EVENT_MASK_CPI;
+}
+
+static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
+{
+ CPI *cpi = container_of(evt_buf_hdr, CPI, ebh);
+
+ cpi->ebh.flags = SCLP_EVENT_BUFFER_ACCEPTED;
+ return SCLP_RC_NORMAL_COMPLETION;
+}
+
+static void cpi_class_init(ObjectClass *klass, void *data)
+{
+ SCLPEventClass *sclp_cpi = SCLP_EVENT_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ sclp_cpi->can_handle_event = can_handle_event;
+ sclp_cpi->get_send_mask = send_mask;
+ sclp_cpi->get_receive_mask = receive_mask;
+ sclp_cpi->write_event_data = write_event_data;
+ dc->user_creatable = false;
+}
+
+static const TypeInfo sclp_cpi_info = {
+ .name = TYPE_SCLP_CPI,
+ .parent = TYPE_SCLP_EVENT,
+ .instance_size = sizeof(SCLPEvent),
+ .class_init = cpi_class_init,
+ .class_size = sizeof(SCLPEventClass),
+};
+
+static void sclp_cpi_register_types(void)
+{
+ type_register_static(&sclp_cpi_info);
+}
+
+type_init(sclp_cpi_register_types)
+
@@ -25,6 +25,7 @@
#define SCLP_EVENT_MESSAGE 0x02
#define SCLP_EVENT_CONFIG_MGT_DATA 0x04
#define SCLP_EVENT_PMSGCMD 0x09
+#define SCLP_EVENT_CPI 0x0b
#define SCLP_EVENT_ASCII_CONSOLE_DATA 0x1a
#define SCLP_EVENT_SIGNAL_QUIESCE 0x1d
@@ -35,6 +36,7 @@
#define SCLP_EVENT_MASK_MSG SCLP_EVMASK(SCLP_EVENT_MESSAGE)
#define SCLP_EVENT_MASK_CONFIG_MGT_DATA SCLP_EVMASK(SCLP_EVENT_CONFIG_MGT_DATA)
#define SCLP_EVENT_MASK_PMSGCMD SCLP_EVMASK(SCLP_EVENT_PMSGCMD)
+#define SCLP_EVENT_MASK_CPI SCLP_EVMASK(SCLP_EVENT_CPI)
#define SCLP_EVENT_MASK_MSG_ASCII SCLP_EVMASK(SCLP_EVENT_ASCII_CONSOLE_DATA)
#define SCLP_EVENT_MASK_SIGNAL_QUIESCE SCLP_EVMASK(SCLP_EVENT_SIGNAL_QUIESCE)
@@ -46,6 +48,7 @@ OBJECT_DECLARE_TYPE(SCLPEvent, SCLPEventClass,
SCLP_EVENT)
#define TYPE_SCLP_CPU_HOTPLUG "sclp-cpu-hotplug"
+#define TYPE_SCLP_CPI "sclpcpi"
#define TYPE_SCLP_QUIESCE "sclpquiesce"
#define SCLP_EVENT_MASK_LEN_MAX 1021
This commit implements the SCLP event type Control-Program Identification in QEMU. Control-program is an IBM term for operating system. This event is used to send firmware program identifiers from KVM guest to SCLP. The program identifiers provide data about the guest OS. The program identifiers are system type, system name, system level and sysplex name. System type provides the OS type of the guest. System name provides the name of the guest. System level provides the distribution and kernel version of the guest OS. Sysplex name provides sysplex name of the guest. Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> --- hw/s390x/event-facility.c | 12 +++- hw/s390x/meson.build | 1 + hw/s390x/sclpcpi.c | 94 +++++++++++++++++++++++++++++++ include/hw/s390x/event-facility.h | 3 + 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 hw/s390x/sclpcpi.c