aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/intc/s390_flic_kvm.c18
-rw-r--r--hw/s390x/event-facility.c35
-rw-r--r--hw/s390x/s390-virtio-ccw.c16
-rw-r--r--hw/s390x/sclp.c16
-rw-r--r--hw/s390x/virtio-ccw.c4
5 files changed, 46 insertions, 43 deletions
diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c
index dddd33ea61..a306b26faa 100644
--- a/hw/intc/s390_flic_kvm.c
+++ b/hw/intc/s390_flic_kvm.c
@@ -331,6 +331,10 @@ static int kvm_s390_add_adapter_routes(S390FLICState *fs,
int ret, i;
uint64_t ind_offset = routes->adapter.ind_offset;
+ if (!kvm_gsi_routing_enabled()) {
+ return -ENOSYS;
+ }
+
for (i = 0; i < routes->num_routes; i++) {
ret = kvm_irqchip_add_adapter_route(kvm_state, &routes->adapter);
if (ret < 0) {
@@ -358,6 +362,10 @@ static void kvm_s390_release_adapter_routes(S390FLICState *fs,
{
int i;
+ if (!kvm_gsi_routing_enabled()) {
+ return;
+ }
+
for (i = 0; i < routes->num_routes; i++) {
if (routes->gsi[i] >= 0) {
kvm_irqchip_release_virq(kvm_state, routes->gsi[i]);
@@ -439,17 +447,14 @@ static int kvm_flic_load(QEMUFile *f, void *opaque, size_t size,
count = qemu_get_be64(f);
len = count * sizeof(struct kvm_s390_irq);
if (count == FLIC_FAILED) {
- r = -EINVAL;
- goto out;
+ return -EINVAL;
}
if (count == 0) {
- r = 0;
- goto out;
+ return 0;
}
buf = g_try_malloc0(len);
if (!buf) {
- r = -ENOMEM;
- goto out;
+ return -ENOMEM;
}
if (qemu_get_buffer(f, (uint8_t *) buf, len) != len) {
@@ -460,7 +465,6 @@ static int kvm_flic_load(QEMUFile *f, void *opaque, size_t size,
out_free:
g_free(buf);
-out:
return r;
}
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
index 6afe278cad..9d6972afa8 100644
--- a/hw/s390x/event-facility.c
+++ b/hw/s390x/event-facility.c
@@ -182,11 +182,11 @@ static void write_event_data(SCLPEventFacility *ef, SCCB *sccb)
{
if (sccb->h.function_code != SCLP_FC_NORMAL_WRITE) {
sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_FUNCTION);
- goto out;
+ return;
}
if (be16_to_cpu(sccb->h.length) < 8) {
sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
- goto out;
+ return;
}
/* first do a sanity check of the write events */
sccb->h.response_code = cpu_to_be16(write_event_length_check(sccb));
@@ -196,9 +196,6 @@ static void write_event_data(SCLPEventFacility *ef, SCCB *sccb)
sccb->h.response_code =
cpu_to_be16(handle_sccb_write_events(ef, sccb));
}
-
-out:
- return;
}
static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb,
@@ -262,17 +259,18 @@ static void read_event_data(SCLPEventFacility *ef, SCCB *sccb)
if (be16_to_cpu(sccb->h.length) != SCCB_SIZE) {
sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
- goto out;
+ return;
}
- sclp_cp_receive_mask = ef->receive_mask;
-
- /* get active selection mask */
switch (sccb->h.function_code) {
case SCLP_UNCONDITIONAL_READ:
- sclp_active_selection_mask = sclp_cp_receive_mask;
+ sccb->h.response_code = cpu_to_be16(
+ handle_sccb_read_events(ef, sccb, ef->receive_mask));
break;
case SCLP_SELECTIVE_READ:
+ /* get active selection mask */
+ sclp_cp_receive_mask = ef->receive_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 = be64_to_cpu(sclp_active_selection_mask);
@@ -280,18 +278,14 @@ static void read_event_data(SCLPEventFacility *ef, SCCB *sccb)
(sclp_active_selection_mask & ~sclp_cp_receive_mask)) {
sccb->h.response_code =
cpu_to_be16(SCLP_RC_INVALID_SELECTION_MASK);
- goto out;
+ } else {
+ sccb->h.response_code = cpu_to_be16(
+ handle_sccb_read_events(ef, sccb, sclp_active_selection_mask));
}
break;
default:
sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_FUNCTION);
- goto out;
}
- sccb->h.response_code = cpu_to_be16(
- handle_sccb_read_events(ef, sccb, sclp_active_selection_mask));
-
-out:
- return;
}
static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb)
@@ -303,7 +297,7 @@ static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb)
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;
+ return;
}
/*
@@ -328,9 +322,6 @@ static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb)
sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);
ef->mask_length = mask_length;
-
-out:
- return;
}
/* qemu object creation and initialization functions */
@@ -347,7 +338,7 @@ static void sclp_events_bus_realize(BusState *bus, Error **errp)
DeviceState *dev = kid->child;
object_property_set_bool(OBJECT(dev), true, "realized", &err);
- if (errp) {
+ if (err) {
error_propagate(errp, err);
return;
}
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index e0e28139a2..e759eb5f83 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -505,6 +505,19 @@ static inline void machine_set_dea_key_wrap(Object *obj, bool value,
static S390CcwMachineClass *current_mc;
+/*
+ * Get the class of the s390-ccw-virtio machine that is currently in use.
+ * Note: libvirt is using the "none" machine to probe for the features of the
+ * host CPU, so in case this is called with the "none" machine, the function
+ * returns the TYPE_S390_CCW_MACHINE base class. In this base class, all the
+ * various "*_allowed" variables are enabled, so that the *_allowed() wrappers
+ * below return the correct default value for the "none" machine.
+ *
+ * Attention! Do *not* add additional new wrappers for CPU features (e.g. like
+ * the ri_allowed() wrapper) via this mechanism anymore. CPU features should
+ * be handled via the CPU models, i.e. checking with cpu_model_allowed() during
+ * CPU initialization and s390_has_feat() later should be sufficient.
+ */
static S390CcwMachineClass *get_machine_class(void)
{
if (unlikely(!current_mc)) {
@@ -521,19 +534,16 @@ static S390CcwMachineClass *get_machine_class(void)
bool ri_allowed(void)
{
- /* for "none" machine this results in true */
return get_machine_class()->ri_allowed;
}
bool cpu_model_allowed(void)
{
- /* for "none" machine this results in true */
return get_machine_class()->cpu_model_allowed;
}
bool hpage_1m_allowed(void)
{
- /* for "none" machine this results in true */
return get_machine_class()->hpage_1m_allowed;
}
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index f57ce7b739..af0bfbc2ec 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -197,24 +197,20 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
{
SCLPDevice *sclp = get_sclp_device();
SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
- int r = 0;
SCCB work_sccb;
hwaddr sccb_len = sizeof(SCCB);
/* first some basic checks on program checks */
if (env->psw.mask & PSW_MASK_PSTATE) {
- r = -PGM_PRIVILEGED;
- goto out;
+ return -PGM_PRIVILEGED;
}
if (cpu_physical_memory_is_io(sccb)) {
- r = -PGM_ADDRESSING;
- goto out;
+ return -PGM_ADDRESSING;
}
if ((sccb & ~0x1fffUL) == 0 || (sccb & ~0x1fffUL) == env->psa
|| (sccb & ~0x7ffffff8UL) != 0) {
- r = -PGM_SPECIFICATION;
- goto out;
+ return -PGM_SPECIFICATION;
}
/*
@@ -226,8 +222,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
/* Valid sccb sizes */
if (be16_to_cpu(work_sccb.h.length) < sizeof(SCCBHeader)) {
- r = -PGM_SPECIFICATION;
- goto out;
+ return -PGM_SPECIFICATION;
}
switch (code & SCLP_CMD_CODE_MASK) {
@@ -257,8 +252,7 @@ out_write:
sclp_c->service_interrupt(sclp, sccb);
-out:
- return r;
+ return 0;
}
static void service_interrupt(SCLPDevice *sclp, uint32_t sccb)
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 6580ce5907..13f57e7b67 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -697,6 +697,7 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
SubchDev *sch;
Error *err = NULL;
+ int i;
sch = css_create_sch(ccw_dev->devno, errp);
if (!sch) {
@@ -717,6 +718,9 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
ccw_dev->sch = sch;
dev->indicators = NULL;
dev->revision = -1;
+ for (i = 0; i < ADAPTER_ROUTES_MAX_GSI; i++) {
+ dev->routes.gsi[i] = -1;
+ }
css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
trace_virtio_ccw_new_device(