mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-09-03 15:32:26 -06:00
hw/s390x: add SCLP event type CPI
Implement the Service-Call Logical Processor (SCLP) event type Control-Program Identification (CPI) in QEMU. This event is used to send CPI identifiers from the guest to the host. The CPI identifiers are: system type, system name, system level and sysplex name. System type: operating system of the guest (e.g. "LINUX "). System name: user configurable name of the guest (e.g. "TESTVM "). System level: distribution and kernel version, if the system type is Linux (e.g. 74872343805430528). Sysplex name: name of the cluster which the guest belongs to (if any) (e.g. "PLEX"). The SCLP event CPI is supported only from "s390-ccw-virtio-10.1" machine and higher. Signed-off-by: Shalini Chellathurai Saroja <shalini@linux.ibm.com> Reviewed-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Message-ID: <20250616140107.990538-2-shalini@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
920f067347
commit
435c758da1
6 changed files with 161 additions and 0 deletions
|
@ -4,6 +4,7 @@
|
|||
* handles SCLP event types
|
||||
* - Signal Quiesce - system power down
|
||||
* - ASCII Console Data - VT220 read and write
|
||||
* - Control-Program Identification - Send OS data from guest to host
|
||||
*
|
||||
* Copyright IBM, Corp. 2012
|
||||
*
|
||||
|
@ -40,6 +41,7 @@ struct SCLPEventFacility {
|
|||
SysBusDevice parent_obj;
|
||||
SCLPEventsBus sbus;
|
||||
SCLPEvent quiesce, cpu_hotplug;
|
||||
SCLPEventCPI cpi;
|
||||
/* guest's receive mask */
|
||||
union {
|
||||
uint32_t receive_mask_pieces[2];
|
||||
|
|
|
@ -13,6 +13,7 @@ s390x_ss.add(files(
|
|||
's390-skeys.c',
|
||||
's390-stattrib.c',
|
||||
'sclp.c',
|
||||
'sclpcpi.c',
|
||||
'sclpcpu.c',
|
||||
'sclpquiesce.c',
|
||||
'tod.c',
|
||||
|
|
|
@ -260,9 +260,21 @@ static void s390_create_sclpconsole(SCLPDevice *sclp,
|
|||
qdev_realize_and_unref(dev, ev_fac_bus, &error_fatal);
|
||||
}
|
||||
|
||||
static void s390_create_sclpcpi(SCLPDevice *sclp)
|
||||
{
|
||||
SCLPEventFacility *ef = sclp->event_facility;
|
||||
BusState *ev_fac_bus = sclp_get_event_facility_bus(ef);
|
||||
DeviceState *dev;
|
||||
|
||||
dev = qdev_new(TYPE_SCLP_EVENT_CPI);
|
||||
object_property_add_child(OBJECT(ef), "sclpcpi", OBJECT(dev));
|
||||
qdev_realize_and_unref(dev, ev_fac_bus, &error_fatal);
|
||||
}
|
||||
|
||||
static void ccw_init(MachineState *machine)
|
||||
{
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
|
||||
S390CcwMachineState *ms = S390_CCW_MACHINE(machine);
|
||||
int ret;
|
||||
VirtualCssBus *css_bus;
|
||||
|
@ -323,6 +335,12 @@ static void ccw_init(MachineState *machine)
|
|||
|
||||
/* init the TOD clock */
|
||||
s390_init_tod();
|
||||
|
||||
/* init SCLP event Control-Program Identification */
|
||||
if (s390mc->use_cpi) {
|
||||
s390_create_sclpcpi(ms->sclp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void s390_cpu_plug(HotplugHandler *hotplug_dev,
|
||||
|
@ -783,6 +801,7 @@ static void ccw_machine_class_init(ObjectClass *oc, const void *data)
|
|||
DumpSKeysInterface *dsi = DUMP_SKEYS_INTERFACE_CLASS(oc);
|
||||
|
||||
s390mc->max_threads = 1;
|
||||
s390mc->use_cpi = true;
|
||||
mc->reset = s390_machine_reset;
|
||||
mc->block_default_type = IF_VIRTIO;
|
||||
mc->no_cdrom = 1;
|
||||
|
@ -908,6 +927,9 @@ static void ccw_machine_10_0_instance_options(MachineState *machine)
|
|||
|
||||
static void ccw_machine_10_0_class_options(MachineClass *mc)
|
||||
{
|
||||
S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc);
|
||||
s390mc->use_cpi = false;
|
||||
|
||||
ccw_machine_10_1_class_options(mc);
|
||||
compat_props_add(mc->compat_props, hw_compat_10_0, hw_compat_10_0_len);
|
||||
}
|
||||
|
|
123
hw/s390x/sclpcpi.c
Normal file
123
hw/s390x/sclpcpi.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
* SCLP event type 11 - Control-Program Identification (CPI):
|
||||
* CPI is used to send program identifiers from the guest to the
|
||||
* Service-Call Logical Processor (SCLP). It is not sent by the SCLP.
|
||||
*
|
||||
* 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 a 4-bit digit, 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.
|
||||
*
|
||||
* The CPI feature is supported since 10.1.
|
||||
*
|
||||
* Copyright IBM, Corp. 2024
|
||||
*
|
||||
* Authors:
|
||||
* Shalini Chellathurai Saroja <shalini@linux.ibm.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.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 ControlProgramIdMsg {
|
||||
EventBufferHeader ebh;
|
||||
Data data;
|
||||
} QEMU_PACKED ControlProgramIdMsg;
|
||||
|
||||
static bool can_handle_event(uint8_t type)
|
||||
{
|
||||
return type == SCLP_EVENT_CTRL_PGM_ID;
|
||||
}
|
||||
|
||||
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_CTRL_PGM_ID;
|
||||
}
|
||||
|
||||
static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
|
||||
{
|
||||
ControlProgramIdMsg *cpim = container_of(evt_buf_hdr, ControlProgramIdMsg,
|
||||
ebh);
|
||||
|
||||
cpim->ebh.flags = SCLP_EVENT_BUFFER_ACCEPTED;
|
||||
return SCLP_RC_NORMAL_COMPLETION;
|
||||
}
|
||||
|
||||
static void cpi_class_init(ObjectClass *klass, const void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SCLPEventClass *k = SCLP_EVENT_CLASS(klass);
|
||||
|
||||
dc->user_creatable = false;
|
||||
|
||||
k->can_handle_event = can_handle_event;
|
||||
k->get_send_mask = send_mask;
|
||||
k->get_receive_mask = receive_mask;
|
||||
k->write_event_data = write_event_data;
|
||||
}
|
||||
|
||||
static const TypeInfo sclp_cpi_info = {
|
||||
.name = TYPE_SCLP_EVENT_CPI,
|
||||
.parent = TYPE_SCLP_EVENT,
|
||||
.instance_size = sizeof(SCLPEventCPI),
|
||||
.class_init = cpi_class_init,
|
||||
};
|
||||
|
||||
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_CTRL_PGM_ID 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_CTRL_PGM_ID SCLP_EVMASK(SCLP_EVENT_CTRL_PGM_ID)
|
||||
#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)
|
||||
|
||||
|
@ -191,6 +193,16 @@ struct SCLPEventClass {
|
|||
bool (*can_handle_event)(uint8_t type);
|
||||
};
|
||||
|
||||
#define TYPE_SCLP_EVENT_CPI "sclpcpi"
|
||||
typedef struct SCLPEventCPIClass SCLPEventCPIClass;
|
||||
typedef struct SCLPEventCPI SCLPEventCPI;
|
||||
OBJECT_DECLARE_TYPE(SCLPEventCPI, SCLPEventCPIClass,
|
||||
SCLP_EVENT_CPI)
|
||||
|
||||
struct SCLPEventCPI {
|
||||
SCLPEvent event;
|
||||
};
|
||||
|
||||
#define TYPE_SCLP_EVENT_FACILITY "s390-sclp-event-facility"
|
||||
typedef struct SCLPEventFacility SCLPEventFacility;
|
||||
typedef struct SCLPEventFacilityClass SCLPEventFacilityClass;
|
||||
|
|
|
@ -54,6 +54,7 @@ struct S390CcwMachineClass {
|
|||
|
||||
/*< public >*/
|
||||
int max_threads;
|
||||
bool use_cpi;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue