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>
This commit is contained in:
commit
9fa673c3e3
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 = {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
|
@ -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
2
numa.c
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user