Fixes and cleanups for the 2.12 softfreeze.

-----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEEw9DWbcNiT/aowBjO3s9rk8bwL68FAlqheIoSHGNvaHVja0By
 ZWRoYXQuY29tAAoJEN7Pa5PG8C+v4ngP/1aVUAIyM+dJGwdECfAXwoFQxJ2MDyQR
 Shq+GlpXwXxQy9NEXfqxHRyYrfnAz0QDg8IZMjKRG+izkeFeDSZrxPNCyhOcM5oM
 OM9oECc6sh4Mo3JpxFmzTx2759f4lyaZs+i22+vu7jqhLJWCHpOVf79sz81fp3SR
 a51b9yWBEAvdMHjWy8EaKGpUbGFOAajtX2jXIyk00jzntwYmPoO+dak8RAFLGVRo
 HLt4q9T8vMN6BLDESXhAG0y5ewRaa1Wh0445I3uRpfQy+Itt/rh1BSHU1hn3hlBA
 4g7BXxXf1DiaQQgy2LiPFtkrKG0kawMZwl0lCqoR4gWzB8YrfMJoOBDBaadOoOam
 O8OetkrEB0YBK7D0XDILY92kBKTqZOpRsQcf31575QTojGpSxZgpFYV+CQ6bgvu1
 fQjo3yjoVJmaaQT6uL0uYAbM9qCD2wwOy/vMDOINkjge72kBNwlD7P3uiy9hUt2z
 NTzjtalHXC/VFCz6KHE5yp03rftAYUgCUOXF8q/X3ajEVxn0z5t1ldIwyafzV1nL
 l55Nm+d91WtPhbmCS8iy/440zsG9V5/axuaIXyCmM8lYZaHNFM9SVJiGYX5PlMHs
 H01wHM2sqPssZ/U10fcV7y0AwmHkxGBpfR5BJyxsZux4UYX0BmjiyfyJU52yAZOx
 ch8Jgpo86vrN
 =zdfF
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20180308' into staging

Fixes and cleanups for the 2.12 softfreeze.

# gpg: Signature made Thu 08 Mar 2018 17:53:14 GMT
# gpg:                using RSA key DECF6B93C6F02FAF
# gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>"
# gpg:                 aka "Cornelia Huck <huckc@linux.vnet.ibm.com>"
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>"
# gpg:                 aka "Cornelia Huck <cohuck@kernel.org>"
# gpg:                 aka "Cornelia Huck <cohuck@redhat.com>"
# Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0  18CE DECF 6B93 C6F0 2FAF

* remotes/cohuck/tags/s390x-20180308:
  s390x/virtio: Convert virtio-ccw from *_exit to *_unrealize
  pc-bios/s390-ccw: Move string arrays from bootmap header to .c file
  s390x/sclp: clean up sclp masks
  s390x/sclp: proper support of larger send and receive masks
  vfio-ccw: license text should indicate GPL v2 or later
  s390x/sclpconsole: Remove dead code - remove exit handlers
  numa: we don't implement NUMA for s390x
  hw/s390x: Add the possibility to specify the netboot image on the command line
  target/s390x: Remove leading underscores from #defines
  s390/ipl: only print boot menu error if -boot menu=on was specified
  hw/s390x/ipl: Bail out if the network bootloader can not be found

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
master
Peter Maydell 2018-03-08 18:30:16 +00:00
commit 9fa673c3e3
17 changed files with 230 additions and 184 deletions

View File

@ -102,12 +102,12 @@ static bool can_handle_event(uint8_t type)
return type == SCLP_EVENT_MESSAGE || type == SCLP_EVENT_PMSGCMD;
}
static unsigned int send_mask(void)
static sccb_mask_t send_mask(void)
{
return SCLP_EVENT_MASK_OP_CMD | SCLP_EVENT_MASK_PMSGCMD;
}
static unsigned int receive_mask(void)
static sccb_mask_t receive_mask(void)
{
return SCLP_EVENT_MASK_MSG | SCLP_EVENT_MASK_PMSGCMD;
}
@ -318,11 +318,6 @@ static int console_init(SCLPEvent *event)
return 0;
}
static int console_exit(SCLPEvent *event)
{
return 0;
}
static void console_reset(DeviceState *dev)
{
SCLPEvent *event = SCLP_EVENT(dev);
@ -349,7 +344,6 @@ static void console_class_init(ObjectClass *klass, void *data)
dc->reset = console_reset;
dc->vmsd = &vmstate_sclplmconsole;
ec->init = console_init;
ec->exit = console_exit;
ec->get_send_mask = send_mask;
ec->get_receive_mask = receive_mask;
ec->can_handle_event = can_handle_event;

View File

@ -83,12 +83,12 @@ static bool can_handle_event(uint8_t type)
return type == SCLP_EVENT_ASCII_CONSOLE_DATA;
}
static unsigned int send_mask(void)
static sccb_mask_t send_mask(void)
{
return SCLP_EVENT_MASK_MSG_ASCII;
}
static unsigned int receive_mask(void)
static sccb_mask_t receive_mask(void)
{
return SCLP_EVENT_MASK_MSG_ASCII;
}
@ -246,11 +246,6 @@ static void console_reset(DeviceState *dev)
scon->notify = false;
}
static int console_exit(SCLPEvent *event)
{
return 0;
}
static Property console_properties[] = {
DEFINE_PROP_CHR("chardev", SCLPConsole, chr),
DEFINE_PROP_END_OF_LIST(),
@ -265,7 +260,6 @@ static void console_class_init(ObjectClass *klass, void *data)
dc->reset = console_reset;
dc->vmsd = &vmstate_sclpconsole;
ec->init = console_init;
ec->exit = console_exit;
ec->get_send_mask = send_mask;
ec->get_receive_mask = receive_mask;
ec->can_handle_event = can_handle_event;

View File

@ -29,8 +29,17 @@ typedef struct SCLPEventsBus {
struct SCLPEventFacility {
SysBusDevice parent_obj;
SCLPEventsBus sbus;
/* guest' receive mask */
unsigned int receive_mask;
/* guest's receive mask */
sccb_mask_t receive_mask;
/*
* when false, we keep the same broken, backwards compatible behaviour as
* before, allowing only masks of size exactly 4; when true, we implement
* the architecture correctly, allowing all valid mask sizes. Needed for
* migration toward older versions.
*/
bool allow_all_mask_sizes;
/* length of the receive mask */
uint16_t mask_length;
};
/* return true if any child has event pending set */
@ -52,9 +61,9 @@ static bool event_pending(SCLPEventFacility *ef)
return false;
}
static unsigned int get_host_send_mask(SCLPEventFacility *ef)
static sccb_mask_t get_host_send_mask(SCLPEventFacility *ef)
{
unsigned int mask;
sccb_mask_t mask;
BusChild *kid;
SCLPEventClass *child;
@ -68,9 +77,9 @@ static unsigned int get_host_send_mask(SCLPEventFacility *ef)
return mask;
}
static unsigned int get_host_receive_mask(SCLPEventFacility *ef)
static sccb_mask_t get_host_receive_mask(SCLPEventFacility *ef)
{
unsigned int mask;
sccb_mask_t mask;
BusChild *kid;
SCLPEventClass *child;
@ -180,7 +189,7 @@ out:
}
static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb,
unsigned int mask)
sccb_mask_t mask)
{
uint16_t rc;
int slen;
@ -220,10 +229,21 @@ static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb,
return rc;
}
/* copy up to src_len bytes and fill the rest of dst with zeroes */
static void copy_mask(uint8_t *dst, uint8_t *src, uint16_t dst_len,
uint16_t src_len)
{
int i;
for (i = 0; i < dst_len; i++) {
dst[i] = i < src_len ? src[i] : 0;
}
}
static void read_event_data(SCLPEventFacility *ef, SCCB *sccb)
{
unsigned int sclp_active_selection_mask;
unsigned int sclp_cp_receive_mask;
sccb_mask_t sclp_active_selection_mask;
sccb_mask_t sclp_cp_receive_mask;
ReadEventData *red = (ReadEventData *) sccb;
@ -240,7 +260,9 @@ static void read_event_data(SCLPEventFacility *ef, SCCB *sccb)
sclp_active_selection_mask = sclp_cp_receive_mask;
break;
case SCLP_SELECTIVE_READ:
sclp_active_selection_mask = be32_to_cpu(red->mask);
copy_mask((uint8_t *)&sclp_active_selection_mask, (uint8_t *)&red->mask,
sizeof(sclp_active_selection_mask), ef->mask_length);
sclp_active_selection_mask = be32_to_cpu(sclp_active_selection_mask);
if (!sclp_cp_receive_mask ||
(sclp_active_selection_mask & ~sclp_cp_receive_mask)) {
sccb->h.response_code =
@ -259,24 +281,14 @@ out:
return;
}
/* copy up to dst_len bytes and fill the rest of dst with zeroes */
static void copy_mask(uint8_t *dst, uint8_t *src, uint16_t dst_len,
uint16_t src_len)
{
int i;
for (i = 0; i < dst_len; i++) {
dst[i] = i < src_len ? src[i] : 0;
}
}
static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb)
{
WriteEventMask *we_mask = (WriteEventMask *) sccb;
uint16_t mask_length = be16_to_cpu(we_mask->mask_length);
uint32_t tmp_mask;
sccb_mask_t tmp_mask;
if (!mask_length || (mask_length > SCLP_EVENT_MASK_LEN_MAX)) {
if (!mask_length || (mask_length > SCLP_EVENT_MASK_LEN_MAX) ||
((mask_length != 4) && !ef->allow_all_mask_sizes)) {
sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_MASK_LENGTH);
goto out;
}
@ -301,6 +313,7 @@ static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb)
mask_length, sizeof(tmp_mask));
sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);
ef->mask_length = mask_length;
out:
return;
@ -356,6 +369,24 @@ static void command_handler(SCLPEventFacility *ef, SCCB *sccb, uint64_t code)
}
}
static bool vmstate_event_facility_mask_length_needed(void *opaque)
{
SCLPEventFacility *ef = opaque;
return ef->allow_all_mask_sizes;
}
static const VMStateDescription vmstate_event_facility_mask_length = {
.name = "vmstate-event-facility/mask_length",
.version_id = 0,
.minimum_version_id = 0,
.needed = vmstate_event_facility_mask_length_needed,
.fields = (VMStateField[]) {
VMSTATE_UINT16(mask_length, SCLPEventFacility),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_event_facility = {
.name = "vmstate-event-facility",
.version_id = 0,
@ -363,15 +394,39 @@ static const VMStateDescription vmstate_event_facility = {
.fields = (VMStateField[]) {
VMSTATE_UINT32(receive_mask, SCLPEventFacility),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription * []) {
&vmstate_event_facility_mask_length,
NULL
}
};
static void sclp_event_set_allow_all_mask_sizes(Object *obj, bool value,
Error **errp)
{
SCLPEventFacility *ef = (SCLPEventFacility *)obj;
ef->allow_all_mask_sizes = value;
}
static bool sclp_event_get_allow_all_mask_sizes(Object *obj, Error **e)
{
SCLPEventFacility *ef = (SCLPEventFacility *)obj;
return ef->allow_all_mask_sizes;
}
static void init_event_facility(Object *obj)
{
SCLPEventFacility *event_facility = EVENT_FACILITY(obj);
DeviceState *sdev = DEVICE(obj);
Object *new;
event_facility->mask_length = 4;
event_facility->allow_all_mask_sizes = true;
object_property_add_bool(obj, "allow_all_mask_sizes",
sclp_event_get_allow_all_mask_sizes,
sclp_event_set_allow_all_mask_sizes, NULL);
/* Spawn a new bus for SCLP events */
qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus),
TYPE_SCLP_EVENTS_BUS, sdev, NULL);
@ -431,26 +486,12 @@ static void event_realize(DeviceState *qdev, Error **errp)
}
}
static void event_unrealize(DeviceState *qdev, Error **errp)
{
SCLPEvent *event = SCLP_EVENT(qdev);
SCLPEventClass *child = SCLP_EVENT_GET_CLASS(event);
if (child->exit) {
int rc = child->exit(event);
if (rc < 0) {
error_setg(errp, "SCLP event exit failed.");
return;
}
}
}
static void event_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->bus_type = TYPE_SCLP_EVENTS_BUS;
dc->realize = event_realize;
dc->unrealize = event_unrealize;
}
static const TypeInfo sclp_event_type_info = {

View File

@ -234,7 +234,7 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
if (!get_boot_device(0)) {
if (boot_menu) {
error_report("boot menu requires a bootindex to be specified for "
"the IPL device.");
"the IPL device");
}
return;
}
@ -250,7 +250,9 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
case S390_IPL_TYPE_QEMU_SCSI:
break;
default:
error_report("boot menu is not supported for this device type.");
if (boot_menu) {
error_report("boot menu is not supported for this device type");
}
return;
}
@ -263,13 +265,13 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
tmp = qemu_opt_get(opts, "splash-time");
if (tmp && qemu_strtoul(tmp, NULL, 10, &splash_time)) {
error_report("splash-time is invalid, forcing it to 0.");
error_report("splash-time is invalid, forcing it to 0");
*timeout = 0;
return;
}
if (splash_time > 0xffffffff) {
error_report("splash-time is too large, forcing it to max value.");
error_report("splash-time is too large, forcing it to max value");
*timeout = 0xffffffff;
return;
}
@ -380,7 +382,8 @@ static int load_netboot_image(Error **errp)
netboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, ipl->netboot_fw);
if (netboot_filename == NULL) {
error_setg(errp, "Could not find network bootloader");
error_setg(errp, "Could not find network bootloader '%s'",
ipl->netboot_fw);
goto unref_mr;
}
@ -489,7 +492,7 @@ void s390_ipl_prepare_cpu(S390CPU *cpu)
if (ipl->netboot) {
if (load_netboot_image(&err) < 0) {
error_report_err(err);
vm_stop(RUN_STATE_INTERNAL_ERROR);
exit(1);
}
ipl->qipl.netboot_start_addr = cpu_to_be64(ipl->start_addr);
}

View File

@ -27,6 +27,7 @@
#include "s390-pci-bus.h"
#include "hw/s390x/storage-keys.h"
#include "hw/s390x/storage-attributes.h"
#include "hw/s390x/event-facility.h"
#include "hw/compat.h"
#include "ipl.h"
#include "hw/s390x/s390-virtio-ccw.h"
@ -254,8 +255,10 @@ static void s390_init_ipl_dev(const char *kernel_filename,
}
qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
qdev_prop_set_string(dev, "firmware", firmware);
qdev_prop_set_string(dev, "netboot_fw", netboot_fw);
qdev_prop_set_bit(dev, "enforce_bios", enforce_bios);
if (!strlen(object_property_get_str(new, "netboot_fw", &error_abort))) {
qdev_prop_set_string(dev, "netboot_fw", netboot_fw);
}
object_property_add_child(qdev_get_machine(), TYPE_S390_IPL,
new, NULL);
object_unref(new);
@ -388,12 +391,14 @@ static void s390_machine_device_unplug_request(HotplugHandler *hotplug_dev,
}
}
static CpuInstanceProperties s390_cpu_index_to_props(MachineState *machine,
static CpuInstanceProperties s390_cpu_index_to_props(MachineState *ms,
unsigned cpu_index)
{
g_assert(machine->possible_cpus && cpu_index < machine->possible_cpus->len);
MachineClass *mc = MACHINE_GET_CLASS(ms);
const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
return machine->possible_cpus->cpus[cpu_index].props;
assert(cpu_index < possible_cpus->len);
return possible_cpus->cpus[cpu_index].props;
}
static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms)
@ -664,7 +669,12 @@ bool css_migration_enabled(void)
type_init(ccw_machine_register_##suffix)
#define CCW_COMPAT_2_11 \
HW_COMPAT_2_11
HW_COMPAT_2_11 \
{\
.driver = TYPE_SCLP_EVENT_FACILITY,\
.property = "allow_all_mask_sizes",\
.value = "off",\
},
#define CCW_COMPAT_2_10 \
HW_COMPAT_2_10

View File

@ -37,12 +37,12 @@ void raise_irq_cpu_hotplug(void)
sclp_service_interrupt(0);
}
static unsigned int send_mask(void)
static sccb_mask_t send_mask(void)
{
return SCLP_EVENT_MASK_CONFIG_MGT_DATA;
}
static unsigned int receive_mask(void)
static sccb_mask_t receive_mask(void)
{
return 0;
}

View File

@ -28,12 +28,12 @@ static bool can_handle_event(uint8_t type)
return type == SCLP_EVENT_SIGNAL_QUIESCE;
}
static unsigned int send_mask(void)
static sccb_mask_t send_mask(void)
{
return SCLP_EVENT_MASK_SIGNAL_QUIESCE;
}
static unsigned int receive_mask(void)
static sccb_mask_t receive_mask(void)
{
return 0;
}

View File

@ -752,7 +752,7 @@ out_err:
g_free(sch);
}
static int virtio_ccw_exit(VirtioCcwDevice *dev)
static void virtio_ccw_unrealize(VirtioCcwDevice *dev, Error **errp)
{
CcwDevice *ccw_dev = CCW_DEVICE(dev);
SubchDev *sch = ccw_dev->sch;
@ -760,12 +760,12 @@ static int virtio_ccw_exit(VirtioCcwDevice *dev)
if (sch) {
css_subch_assign(sch->cssid, sch->ssid, sch->schid, sch->devno, NULL);
g_free(sch);
ccw_dev->sch = NULL;
}
if (dev->indicators) {
release_indicator(&dev->routes.adapter, dev->indicators);
dev->indicators = NULL;
}
return 0;
}
static void virtio_ccw_net_realize(VirtioCcwDevice *ccw_dev, Error **errp)
@ -1344,7 +1344,7 @@ static void virtio_ccw_net_class_init(ObjectClass *klass, void *data)
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
k->realize = virtio_ccw_net_realize;
k->exit = virtio_ccw_exit;
k->unrealize = virtio_ccw_unrealize;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_net_properties;
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
@ -1372,7 +1372,7 @@ static void virtio_ccw_blk_class_init(ObjectClass *klass, void *data)
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
k->realize = virtio_ccw_blk_realize;
k->exit = virtio_ccw_exit;
k->unrealize = virtio_ccw_unrealize;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_blk_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
@ -1400,7 +1400,7 @@ static void virtio_ccw_serial_class_init(ObjectClass *klass, void *data)
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
k->realize = virtio_ccw_serial_realize;
k->exit = virtio_ccw_exit;
k->unrealize = virtio_ccw_unrealize;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_serial_properties;
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
@ -1428,7 +1428,7 @@ static void virtio_ccw_balloon_class_init(ObjectClass *klass, void *data)
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
k->realize = virtio_ccw_balloon_realize;
k->exit = virtio_ccw_exit;
k->unrealize = virtio_ccw_unrealize;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_balloon_properties;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
@ -1456,7 +1456,7 @@ static void virtio_ccw_scsi_class_init(ObjectClass *klass, void *data)
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
k->realize = virtio_ccw_scsi_realize;
k->exit = virtio_ccw_exit;
k->unrealize = virtio_ccw_unrealize;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_scsi_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
@ -1483,7 +1483,7 @@ static void vhost_ccw_scsi_class_init(ObjectClass *klass, void *data)
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
k->realize = vhost_ccw_scsi_realize;
k->exit = virtio_ccw_exit;
k->unrealize = virtio_ccw_unrealize;
dc->reset = virtio_ccw_reset;
dc->props = vhost_ccw_scsi_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
@ -1520,7 +1520,7 @@ static void virtio_ccw_rng_class_init(ObjectClass *klass, void *data)
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
k->realize = virtio_ccw_rng_realize;
k->exit = virtio_ccw_exit;
k->unrealize = virtio_ccw_unrealize;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_rng_properties;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
@ -1558,7 +1558,7 @@ static void virtio_ccw_crypto_class_init(ObjectClass *klass, void *data)
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
k->realize = virtio_ccw_crypto_realize;
k->exit = virtio_ccw_exit;
k->unrealize = virtio_ccw_unrealize;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_crypto_properties;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
@ -1596,7 +1596,7 @@ static void virtio_ccw_gpu_class_init(ObjectClass *klass, void *data)
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
k->realize = virtio_ccw_gpu_realize;
k->exit = virtio_ccw_exit;
k->unrealize = virtio_ccw_unrealize;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_gpu_properties;
dc->hotpluggable = false;
@ -1625,7 +1625,7 @@ static void virtio_ccw_input_class_init(ObjectClass *klass, void *data)
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
k->realize = virtio_ccw_input_realize;
k->exit = virtio_ccw_exit;
k->unrealize = virtio_ccw_unrealize;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_input_properties;
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
@ -1705,12 +1705,12 @@ static void virtio_ccw_busdev_realize(DeviceState *dev, Error **errp)
virtio_ccw_device_realize(_dev, errp);
}
static int virtio_ccw_busdev_exit(DeviceState *dev)
static void virtio_ccw_busdev_unrealize(DeviceState *dev, Error **errp)
{
VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
return _info->exit(_dev);
_info->unrealize(_dev, errp);
}
static void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev,
@ -1728,7 +1728,7 @@ static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
k->unplug = virtio_ccw_busdev_unplug;
dc->realize = virtio_ccw_busdev_realize;
dc->exit = virtio_ccw_busdev_exit;
dc->unrealize = virtio_ccw_busdev_unrealize;
dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
}
@ -1804,7 +1804,7 @@ static void virtio_ccw_9p_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
k->exit = virtio_ccw_exit;
k->unrealize = virtio_ccw_unrealize;
k->realize = virtio_ccw_9p_realize;
dc->reset = virtio_ccw_reset;
dc->props = virtio_ccw_9p_properties;
@ -1853,7 +1853,7 @@ static void vhost_vsock_ccw_class_init(ObjectClass *klass, void *data)
VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass);
k->realize = vhost_vsock_ccw_realize;
k->exit = virtio_ccw_exit;
k->unrealize = virtio_ccw_unrealize;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
dc->props = vhost_vsock_ccw_properties;
dc->reset = virtio_ccw_reset;

View File

@ -76,7 +76,7 @@ typedef struct VirtioCcwDevice VirtioCcwDevice;
typedef struct VirtIOCCWDeviceClass {
CCWDeviceClass parent_class;
void (*realize)(VirtioCcwDevice *dev, Error **errp);
int (*exit)(VirtioCcwDevice *dev);
void (*unrealize)(VirtioCcwDevice *dev, Error **errp);
} VirtIOCCWDeviceClass;
/* Performance improves when virtqueue kick processing is decoupled from the

View File

@ -6,8 +6,8 @@
* Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
* Pierre Morel <pmorel@linux.vnet.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or(at
* your option) any version. See the COPYING file in the top-level
* 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.
*/

View File

@ -28,12 +28,14 @@
#define SCLP_EVENT_SIGNAL_QUIESCE 0x1d
/* SCLP event masks */
#define SCLP_EVENT_MASK_SIGNAL_QUIESCE 0x00000008
#define SCLP_EVENT_MASK_MSG_ASCII 0x00000040
#define SCLP_EVENT_MASK_CONFIG_MGT_DATA 0x10000000
#define SCLP_EVENT_MASK_OP_CMD 0x80000000
#define SCLP_EVENT_MASK_MSG 0x40000000
#define SCLP_EVENT_MASK_PMSGCMD 0x00800000
#define SCLP_EVMASK(T) (1ULL << (sizeof(sccb_mask_t) * 8 - (T)))
#define SCLP_EVENT_MASK_OP_CMD SCLP_EVMASK(SCLP_EVENT_OPRTNS_COMMAND)
#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_MSG_ASCII SCLP_EVMASK(SCLP_EVENT_ASCII_CONSOLE_DATA)
#define SCLP_EVENT_MASK_SIGNAL_QUIESCE SCLP_EVMASK(SCLP_EVENT_SIGNAL_QUIESCE)
#define SCLP_UNCONDITIONAL_READ 0x00
#define SCLP_SELECTIVE_READ 0x01
@ -71,6 +73,8 @@ typedef struct WriteEventMask {
#define WEM_RECEIVE_MASK(wem, mask_len) ((wem)->masks + 2 * (mask_len))
#define WEM_SEND_MASK(wem, mask_len) ((wem)->masks + 3 * (mask_len))
typedef uint32_t sccb_mask_t;
typedef struct EventBufferHeader {
uint16_t length;
uint8_t type;
@ -160,7 +164,7 @@ typedef struct WriteEventData {
typedef struct ReadEventData {
SCCBHeader h;
union {
uint32_t mask;
sccb_mask_t mask;
EventBufferHeader ebh;
};
} QEMU_PACKED ReadEventData;
@ -174,13 +178,12 @@ typedef struct SCLPEvent {
typedef struct SCLPEventClass {
DeviceClass parent_class;
int (*init)(SCLPEvent *event);
int (*exit)(SCLPEvent *event);
/* get SCLP's send mask */
unsigned int (*get_send_mask)(void);
sccb_mask_t (*get_send_mask)(void);
/* get SCLP's receive mask */
unsigned int (*get_receive_mask)(void);
sccb_mask_t (*get_receive_mask)(void);
int (*read_event_data)(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
int *slen);

2
numa.c
View File

@ -80,7 +80,7 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
return;
}
if (!mc->cpu_index_to_instance_props) {
if (!mc->cpu_index_to_instance_props || !mc->get_default_cpu_node_id) {
error_report("NUMA is not supported by this machine-type");
exit(1);
}

View File

@ -37,6 +37,26 @@ typedef struct ResetInfo {
static ResetInfo save;
const uint8_t el_torito_magic[] = "EL TORITO SPECIFICATION"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
/*
* Match two CCWs located after PSW and eight filler bytes.
* From libmagic and arch/s390/kernel/head.S.
*/
const uint8_t linux_s390_magic[] = "\x02\x00\x00\x18\x60\x00\x00\x50\x02\x00"
"\x00\x68\x60\x00\x00\x50\x40\x40\x40\x40"
"\x40\x40\x40\x40";
static inline bool is_iso_vd_valid(IsoVolDesc *vd)
{
const uint8_t vol_desc_magic[] = "CD001";
return !memcmp(&vd->ident[0], vol_desc_magic, 5) &&
vd->version == 0x1 &&
vd->type <= VOL_DESC_TYPE_PARTITION;
}
static void jump_to_IPL_2(void)
{
ResetInfo *current = 0;

View File

@ -375,9 +375,6 @@ static inline void read_iso_boot_image(uint32_t block_offset, void *load_addr,
"Failed to read boot image!");
}
const uint8_t el_torito_magic[] = "EL TORITO SPECIFICATION"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
#define ISO9660_MAX_DIR_DEPTH 8
typedef struct IsoDirHdr {
@ -430,20 +427,12 @@ typedef struct IsoVolDesc {
} vd;
} __attribute__((packed)) IsoVolDesc;
const uint8_t vol_desc_magic[] = "CD001";
#define VOL_DESC_TYPE_BOOT 0
#define VOL_DESC_TYPE_PRIMARY 1
#define VOL_DESC_TYPE_SUPPLEMENT 2
#define VOL_DESC_TYPE_PARTITION 3
#define VOL_DESC_TERMINATOR 255
static inline bool is_iso_vd_valid(IsoVolDesc *vd)
{
return !memcmp(&vd->ident[0], vol_desc_magic, 5) &&
vd->version == 0x1 &&
vd->type <= VOL_DESC_TYPE_PARTITION;
}
typedef struct IsoBcValid {
uint8_t platform_id;
uint16_t reserved;
@ -468,14 +457,6 @@ typedef struct IsoBcHdr {
uint8_t id[28];
} __attribute__((packed)) IsoBcHdr;
/*
* Match two CCWs located after PSW and eight filler bytes.
* From libmagic and arch/s390/kernel/head.S.
*/
const uint8_t linux_s390_magic[] = "\x02\x00\x00\x18\x60\x00\x00\x50\x02\x00"
"\x00\x68\x60\x00\x00\x50\x40\x40\x40\x40"
"\x40\x40\x40\x40";
typedef struct IsoBcEntry {
uint8_t id;
union {

View File

@ -538,39 +538,39 @@ typedef union SysIB {
QEMU_BUILD_BUG_ON(sizeof(SysIB) != 4096);
/* MMU defines */
#define _ASCE_ORIGIN ~0xfffULL /* segment table origin */
#define _ASCE_SUBSPACE 0x200 /* subspace group control */
#define _ASCE_PRIVATE_SPACE 0x100 /* private space control */
#define _ASCE_ALT_EVENT 0x80 /* storage alteration event control */
#define _ASCE_SPACE_SWITCH 0x40 /* space switch event */
#define _ASCE_REAL_SPACE 0x20 /* real space control */
#define _ASCE_TYPE_MASK 0x0c /* asce table type mask */
#define _ASCE_TYPE_REGION1 0x0c /* region first table type */
#define _ASCE_TYPE_REGION2 0x08 /* region second table type */
#define _ASCE_TYPE_REGION3 0x04 /* region third table type */
#define _ASCE_TYPE_SEGMENT 0x00 /* segment table type */
#define _ASCE_TABLE_LENGTH 0x03 /* region table length */
#define ASCE_ORIGIN (~0xfffULL) /* segment table origin */
#define ASCE_SUBSPACE 0x200 /* subspace group control */
#define ASCE_PRIVATE_SPACE 0x100 /* private space control */
#define ASCE_ALT_EVENT 0x80 /* storage alteration event control */
#define ASCE_SPACE_SWITCH 0x40 /* space switch event */
#define ASCE_REAL_SPACE 0x20 /* real space control */
#define ASCE_TYPE_MASK 0x0c /* asce table type mask */
#define ASCE_TYPE_REGION1 0x0c /* region first table type */
#define ASCE_TYPE_REGION2 0x08 /* region second table type */
#define ASCE_TYPE_REGION3 0x04 /* region third table type */
#define ASCE_TYPE_SEGMENT 0x00 /* segment table type */
#define ASCE_TABLE_LENGTH 0x03 /* region table length */
#define _REGION_ENTRY_ORIGIN ~0xfffULL /* region/segment table origin */
#define _REGION_ENTRY_RO 0x200 /* region/segment protection bit */
#define _REGION_ENTRY_TF 0xc0 /* region/segment table offset */
#define _REGION_ENTRY_INV 0x20 /* invalid region table entry */
#define _REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */
#define _REGION_ENTRY_TYPE_R1 0x0c /* region first table type */
#define _REGION_ENTRY_TYPE_R2 0x08 /* region second table type */
#define _REGION_ENTRY_TYPE_R3 0x04 /* region third table type */
#define _REGION_ENTRY_LENGTH 0x03 /* region third length */
#define REGION_ENTRY_ORIGIN (~0xfffULL) /* region/segment table origin */
#define REGION_ENTRY_RO 0x200 /* region/segment protection bit */
#define REGION_ENTRY_TF 0xc0 /* region/segment table offset */
#define REGION_ENTRY_INV 0x20 /* invalid region table entry */
#define REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */
#define REGION_ENTRY_TYPE_R1 0x0c /* region first table type */
#define REGION_ENTRY_TYPE_R2 0x08 /* region second table type */
#define REGION_ENTRY_TYPE_R3 0x04 /* region third table type */
#define REGION_ENTRY_LENGTH 0x03 /* region third length */
#define _SEGMENT_ENTRY_ORIGIN ~0x7ffULL /* segment table origin */
#define _SEGMENT_ENTRY_FC 0x400 /* format control */
#define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */
#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */
#define SEGMENT_ENTRY_ORIGIN (~0x7ffULL) /* segment table origin */
#define SEGMENT_ENTRY_FC 0x400 /* format control */
#define SEGMENT_ENTRY_RO 0x200 /* page protection bit */
#define SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */
#define VADDR_PX 0xff000 /* page index bits */
#define VADDR_PX 0xff000 /* page index bits */
#define _PAGE_RO 0x200 /* HW read-only bit */
#define _PAGE_INVALID 0x400 /* HW invalid bit */
#define _PAGE_RES0 0x800 /* bit must be zero */
#define PAGE_RO 0x200 /* HW read-only bit */
#define PAGE_INVALID 0x400 /* HW invalid bit */
#define PAGE_RES0 0x800 /* bit must be zero */
#define SK_C (0x1 << 1)
#define SK_R (0x1 << 2)

View File

@ -1924,20 +1924,20 @@ void HELPER(idte)(CPUS390XState *env, uint64_t r1, uint64_t r2, uint32_t m4)
if (!(r2 & 0x800)) {
/* invalidation-and-clearing operation */
table = r1 & _ASCE_ORIGIN;
table = r1 & ASCE_ORIGIN;
entries = (r2 & 0x7ff) + 1;
switch (r1 & _ASCE_TYPE_MASK) {
case _ASCE_TYPE_REGION1:
switch (r1 & ASCE_TYPE_MASK) {
case ASCE_TYPE_REGION1:
index = (r2 >> 53) & 0x7ff;
break;
case _ASCE_TYPE_REGION2:
case ASCE_TYPE_REGION2:
index = (r2 >> 42) & 0x7ff;
break;
case _ASCE_TYPE_REGION3:
case ASCE_TYPE_REGION3:
index = (r2 >> 31) & 0x7ff;
break;
case _ASCE_TYPE_SEGMENT:
case ASCE_TYPE_SEGMENT:
index = (r2 >> 20) & 0x7ff;
break;
}
@ -1945,9 +1945,9 @@ void HELPER(idte)(CPUS390XState *env, uint64_t r1, uint64_t r2, uint32_t m4)
/* addresses are not wrapped in 24/31bit mode but table index is */
raddr = table + ((index + i) & 0x7ff) * sizeof(entry);
entry = cpu_ldq_real_ra(env, raddr, ra);
if (!(entry & _REGION_ENTRY_INV)) {
if (!(entry & REGION_ENTRY_INV)) {
/* we are allowed to not store if already invalid */
entry |= _REGION_ENTRY_INV;
entry |= REGION_ENTRY_INV;
cpu_stq_real_ra(env, raddr, entry, ra);
}
}
@ -1971,12 +1971,12 @@ void HELPER(ipte)(CPUS390XState *env, uint64_t pto, uint64_t vaddr,
uint64_t pte_addr, pte;
/* Compute the page table entry address */
pte_addr = (pto & _SEGMENT_ENTRY_ORIGIN);
pte_addr = (pto & SEGMENT_ENTRY_ORIGIN);
pte_addr += (vaddr & VADDR_PX) >> 9;
/* Mark the page table entry as invalid */
pte = cpu_ldq_real_ra(env, pte_addr, ra);
pte |= _PAGE_INVALID;
pte |= PAGE_INVALID;
cpu_stq_real_ra(env, pte_addr, pte, ra);
/* XXX we exploit the fact that Linux passes the exact virtual

View File

@ -128,11 +128,11 @@ static bool lowprot_enabled(const CPUS390XState *env, uint64_t asc)
/* Check the private-space control bit */
switch (asc) {
case PSW_ASC_PRIMARY:
return !(env->cregs[1] & _ASCE_PRIVATE_SPACE);
return !(env->cregs[1] & ASCE_PRIVATE_SPACE);
case PSW_ASC_SECONDARY:
return !(env->cregs[7] & _ASCE_PRIVATE_SPACE);
return !(env->cregs[7] & ASCE_PRIVATE_SPACE);
case PSW_ASC_HOME:
return !(env->cregs[13] & _ASCE_PRIVATE_SPACE);
return !(env->cregs[13] & ASCE_PRIVATE_SPACE);
default:
/* We don't support access register mode */
error_report("unsupported addressing mode");
@ -159,20 +159,20 @@ static int mmu_translate_pte(CPUS390XState *env, target_ulong vaddr,
uint64_t asc, uint64_t pt_entry,
target_ulong *raddr, int *flags, int rw, bool exc)
{
if (pt_entry & _PAGE_INVALID) {
if (pt_entry & PAGE_INVALID) {
DPRINTF("%s: PTE=0x%" PRIx64 " invalid\n", __func__, pt_entry);
trigger_page_fault(env, vaddr, PGM_PAGE_TRANS, asc, rw, exc);
return -1;
}
if (pt_entry & _PAGE_RES0) {
if (pt_entry & PAGE_RES0) {
trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw, exc);
return -1;
}
if (pt_entry & _PAGE_RO) {
if (pt_entry & PAGE_RO) {
*flags &= ~PAGE_WRITE;
}
*raddr = pt_entry & _ASCE_ORIGIN;
*raddr = pt_entry & ASCE_ORIGIN;
PTE_DPRINTF("%s: PTE=0x%" PRIx64 "\n", __func__, pt_entry);
@ -188,11 +188,11 @@ static int mmu_translate_segment(CPUS390XState *env, target_ulong vaddr,
CPUState *cs = CPU(s390_env_get_cpu(env));
uint64_t origin, offs, pt_entry;
if (st_entry & _SEGMENT_ENTRY_RO) {
if (st_entry & SEGMENT_ENTRY_RO) {
*flags &= ~PAGE_WRITE;
}
if ((st_entry & _SEGMENT_ENTRY_FC) && (env->cregs[0] & CR0_EDAT)) {
if ((st_entry & SEGMENT_ENTRY_FC) && (env->cregs[0] & CR0_EDAT)) {
/* Decode EDAT1 segment frame absolute address (1MB page) */
*raddr = (st_entry & 0xfffffffffff00000ULL) | (vaddr & 0xfffff);
PTE_DPRINTF("%s: SEG=0x%" PRIx64 "\n", __func__, st_entry);
@ -200,7 +200,7 @@ static int mmu_translate_segment(CPUS390XState *env, target_ulong vaddr,
}
/* Look up 4KB page entry */
origin = st_entry & _SEGMENT_ENTRY_ORIGIN;
origin = st_entry & SEGMENT_ENTRY_ORIGIN;
offs = (vaddr & VADDR_PX) >> 9;
pt_entry = ldq_phys(cs->as, origin + offs);
PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n",
@ -223,39 +223,39 @@ static int mmu_translate_region(CPUS390XState *env, target_ulong vaddr,
PTE_DPRINTF("%s: 0x%" PRIx64 "\n", __func__, entry);
origin = entry & _REGION_ENTRY_ORIGIN;
origin = entry & REGION_ENTRY_ORIGIN;
offs = (vaddr >> (17 + 11 * level / 4)) & 0x3ff8;
new_entry = ldq_phys(cs->as, origin + offs);
PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n",
__func__, origin, offs, new_entry);
if ((new_entry & _REGION_ENTRY_INV) != 0) {
if ((new_entry & REGION_ENTRY_INV) != 0) {
DPRINTF("%s: invalid region\n", __func__);
trigger_page_fault(env, vaddr, pchks[level / 4], asc, rw, exc);
return -1;
}
if ((new_entry & _REGION_ENTRY_TYPE_MASK) != level) {
if ((new_entry & REGION_ENTRY_TYPE_MASK) != level) {
trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw, exc);
return -1;
}
if (level == _ASCE_TYPE_SEGMENT) {
if (level == ASCE_TYPE_SEGMENT) {
return mmu_translate_segment(env, vaddr, asc, new_entry, raddr, flags,
rw, exc);
}
/* Check region table offset and length */
offs = (vaddr >> (28 + 11 * (level - 4) / 4)) & 3;
if (offs < ((new_entry & _REGION_ENTRY_TF) >> 6)
|| offs > (new_entry & _REGION_ENTRY_LENGTH)) {
if (offs < ((new_entry & REGION_ENTRY_TF) >> 6)
|| offs > (new_entry & REGION_ENTRY_LENGTH)) {
DPRINTF("%s: invalid offset or len (%lx)\n", __func__, new_entry);
trigger_page_fault(env, vaddr, pchks[level / 4 - 1], asc, rw, exc);
return -1;
}
if ((env->cregs[0] & CR0_EDAT) && (new_entry & _REGION_ENTRY_RO)) {
if ((env->cregs[0] & CR0_EDAT) && (new_entry & REGION_ENTRY_RO)) {
*flags &= ~PAGE_WRITE;
}
@ -271,52 +271,52 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr,
int level;
int r;
if (asce & _ASCE_REAL_SPACE) {
if (asce & ASCE_REAL_SPACE) {
/* direct mapping */
*raddr = vaddr;
return 0;
}
level = asce & _ASCE_TYPE_MASK;
level = asce & ASCE_TYPE_MASK;
switch (level) {
case _ASCE_TYPE_REGION1:
if ((vaddr >> 62) > (asce & _ASCE_TABLE_LENGTH)) {
case ASCE_TYPE_REGION1:
if ((vaddr >> 62) > (asce & ASCE_TABLE_LENGTH)) {
trigger_page_fault(env, vaddr, PGM_REG_FIRST_TRANS, asc, rw, exc);
return -1;
}
break;
case _ASCE_TYPE_REGION2:
case ASCE_TYPE_REGION2:
if (vaddr & 0xffe0000000000000ULL) {
DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64
" 0xffe0000000000000ULL\n", __func__, vaddr);
trigger_page_fault(env, vaddr, PGM_ASCE_TYPE, asc, rw, exc);
return -1;
}
if ((vaddr >> 51 & 3) > (asce & _ASCE_TABLE_LENGTH)) {
if ((vaddr >> 51 & 3) > (asce & ASCE_TABLE_LENGTH)) {
trigger_page_fault(env, vaddr, PGM_REG_SEC_TRANS, asc, rw, exc);
return -1;
}
break;
case _ASCE_TYPE_REGION3:
case ASCE_TYPE_REGION3:
if (vaddr & 0xfffffc0000000000ULL) {
DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64
" 0xfffffc0000000000ULL\n", __func__, vaddr);
trigger_page_fault(env, vaddr, PGM_ASCE_TYPE, asc, rw, exc);
return -1;
}
if ((vaddr >> 40 & 3) > (asce & _ASCE_TABLE_LENGTH)) {
if ((vaddr >> 40 & 3) > (asce & ASCE_TABLE_LENGTH)) {
trigger_page_fault(env, vaddr, PGM_REG_THIRD_TRANS, asc, rw, exc);
return -1;
}
break;
case _ASCE_TYPE_SEGMENT:
case ASCE_TYPE_SEGMENT:
if (vaddr & 0xffffffff80000000ULL) {
DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64
" 0xffffffff80000000ULL\n", __func__, vaddr);
trigger_page_fault(env, vaddr, PGM_ASCE_TYPE, asc, rw, exc);
return -1;
}
if ((vaddr >> 29 & 3) > (asce & _ASCE_TABLE_LENGTH)) {
if ((vaddr >> 29 & 3) > (asce & ASCE_TABLE_LENGTH)) {
trigger_page_fault(env, vaddr, PGM_SEGMENT_TRANS, asc, rw, exc);
return -1;
}