s390x changes:

- kvm: re-enable adapter interrupt suppression (AIS)
 - fixes and cleanups
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEEw9DWbcNiT/aowBjO3s9rk8bwL68FAl4u1BQSHGNvaHVja0By
 ZWRoYXQuY29tAAoJEN7Pa5PG8C+vEz4QAJE+uC90wMPMFHcCAU9Fnxtyf7711+yX
 scZlYVU3go4G/pTjUP2he1DohwSU5Rn6C2exTtSgDtDzEqj+CJdnKBLUJzw3i146
 3KMOMuEzzvqp+JjtgXBV1GArRbMlcqt8UIrAa72iuukAFrMlAQmpHyebuP4Llxqg
 3Mf8U8lebHh7h6f+ssrrJaJXx7382pZcyfPi5jG0hYt/IeZgA28nVODq4ShvZz2w
 tBnJ/aQV5Ka6/Lc13U8pTPpJ3u4HI56rEfqlN/DFocR6xgebo1MaHt6yRiImw95g
 3TFiZZWauK4gLVhZVkCcctcIh8qYV1SfTf9Ub3BbPkrfUYnOy/fwy+evbr/8dG/e
 Wp6XhfhUZxhbTi0CeS0SqUzp0I2iS93AUsN06rxpu8j+qbmHLicXQCZSFb7BRs2y
 6O74JT0L+ezU2x75N7zasAcgYOs6RVpulhz6Za04Ch44cDbUOvA3slsqaAl7ExU/
 qkedzgUvPQhYHi1WWCenBV7xthomElXLTf1upyORIcmPO7yPXgbc8TnqZ/eUIXu7
 B1I6nZ7XupsVxxaE3SkfxH1OaOGeVfFxzyXrsUnoFmaJuAuJLnClDUN0fmDlrqmF
 LCeH53ZFeDh7rleyPiyamGK09el9aMQMQKSrIJJ0CSUdR0BfwB9ThXeYEPhz6Nq4
 t0aypQo12OdT
 =Lfdl
 -----END PGP SIGNATURE-----

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

s390x changes:
- kvm: re-enable adapter interrupt suppression (AIS)
- fixes and cleanups

# gpg: Signature made Mon 27 Jan 2020 12:14:12 GMT
# gpg:                using RSA key C3D0D66DC3624FF6A8C018CEDECF6B93C6F02FAF
# gpg:                issuer "cohuck@redhat.com"
# gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>" [marginal]
# gpg:                 aka "Cornelia Huck <huckc@linux.vnet.ibm.com>" [full]
# gpg:                 aka "Cornelia Huck <cornelia.huck@de.ibm.com>" [full]
# gpg:                 aka "Cornelia Huck <cohuck@kernel.org>" [marginal]
# gpg:                 aka "Cornelia Huck <cohuck@redhat.com>" [marginal]
# Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0  18CE DECF 6B93 C6F0 2FAF

* remotes/cohuck/tags/s390x-20200127:
  s390x: sigp: Fix sense running reporting
  hw/s390x: Add a more verbose comment about get_machine_class() and the wrappers
  target/s390x: Remove DisasFields argument from extract_insn
  target/s390x: Move DisasFields into DisasContext
  target/s390x: Pass DisasContext to get_field and have_field
  target/s390x: Remove DisasFields argument from callbacks
  target/s390x: Move struct DisasFields definition earlier
  target/s390x/kvm: Enable adapter interruption suppression again
  docs/devel: fix stable process doc formatting
  target/s390x: Remove duplicated ifdef macro
  s390x/event-facility: fix error propagation
  s390x: adapter routes error handling
  s390x/event-facility.c: remove unneeded labels
  intc/s390_flic_kvm.c: remove unneeded label in kvm_flic_load()
  s390x/sclp.c: remove unneeded label in sclp_service_call()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-01-27 13:02:36 +00:00
commit 105b07f1ba
11 changed files with 874 additions and 872 deletions

View File

@ -18,8 +18,10 @@ What should go into a stable release?
------------------------------------- -------------------------------------
Generally, the following patches are considered stable material: Generally, the following patches are considered stable material:
- Patches that fix severe issues, like fixes for CVEs
- Patches that fix regressions * Patches that fix severe issues, like fixes for CVEs
* Patches that fix regressions
If you think the patch would be important for users of the current release If you think the patch would be important for users of the current release
(or for a distribution picking fixes), it is usually a good candidate (or for a distribution picking fixes), it is usually a good candidate

View File

@ -331,6 +331,10 @@ static int kvm_s390_add_adapter_routes(S390FLICState *fs,
int ret, i; int ret, i;
uint64_t ind_offset = routes->adapter.ind_offset; uint64_t ind_offset = routes->adapter.ind_offset;
if (!kvm_gsi_routing_enabled()) {
return -ENOSYS;
}
for (i = 0; i < routes->num_routes; i++) { for (i = 0; i < routes->num_routes; i++) {
ret = kvm_irqchip_add_adapter_route(kvm_state, &routes->adapter); ret = kvm_irqchip_add_adapter_route(kvm_state, &routes->adapter);
if (ret < 0) { if (ret < 0) {
@ -358,6 +362,10 @@ static void kvm_s390_release_adapter_routes(S390FLICState *fs,
{ {
int i; int i;
if (!kvm_gsi_routing_enabled()) {
return;
}
for (i = 0; i < routes->num_routes; i++) { for (i = 0; i < routes->num_routes; i++) {
if (routes->gsi[i] >= 0) { if (routes->gsi[i] >= 0) {
kvm_irqchip_release_virq(kvm_state, routes->gsi[i]); 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); count = qemu_get_be64(f);
len = count * sizeof(struct kvm_s390_irq); len = count * sizeof(struct kvm_s390_irq);
if (count == FLIC_FAILED) { if (count == FLIC_FAILED) {
r = -EINVAL; return -EINVAL;
goto out;
} }
if (count == 0) { if (count == 0) {
r = 0; return 0;
goto out;
} }
buf = g_try_malloc0(len); buf = g_try_malloc0(len);
if (!buf) { if (!buf) {
r = -ENOMEM; return -ENOMEM;
goto out;
} }
if (qemu_get_buffer(f, (uint8_t *) buf, len) != len) { 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: out_free:
g_free(buf); g_free(buf);
out:
return r; return r;
} }

View File

@ -182,11 +182,11 @@ static void write_event_data(SCLPEventFacility *ef, SCCB *sccb)
{ {
if (sccb->h.function_code != SCLP_FC_NORMAL_WRITE) { if (sccb->h.function_code != SCLP_FC_NORMAL_WRITE) {
sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_FUNCTION); sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_FUNCTION);
goto out; return;
} }
if (be16_to_cpu(sccb->h.length) < 8) { if (be16_to_cpu(sccb->h.length) < 8) {
sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH); sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH);
goto out; return;
} }
/* first do a sanity check of the write events */ /* first do a sanity check of the write events */
sccb->h.response_code = cpu_to_be16(write_event_length_check(sccb)); 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 = sccb->h.response_code =
cpu_to_be16(handle_sccb_write_events(ef, sccb)); cpu_to_be16(handle_sccb_write_events(ef, sccb));
} }
out:
return;
} }
static uint16_t handle_sccb_read_events(SCLPEventFacility *ef, SCCB *sccb, 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) { if (be16_to_cpu(sccb->h.length) != SCCB_SIZE) {
sccb->h.response_code = cpu_to_be16(SCLP_RC_INSUFFICIENT_SCCB_LENGTH); 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) { switch (sccb->h.function_code) {
case SCLP_UNCONDITIONAL_READ: 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; break;
case SCLP_SELECTIVE_READ: 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, copy_mask((uint8_t *)&sclp_active_selection_mask, (uint8_t *)&red->mask,
sizeof(sclp_active_selection_mask), ef->mask_length); sizeof(sclp_active_selection_mask), ef->mask_length);
sclp_active_selection_mask = be64_to_cpu(sclp_active_selection_mask); 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)) { (sclp_active_selection_mask & ~sclp_cp_receive_mask)) {
sccb->h.response_code = sccb->h.response_code =
cpu_to_be16(SCLP_RC_INVALID_SELECTION_MASK); 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; break;
default: default:
sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_FUNCTION); 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) 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) || if (!mask_length || (mask_length > SCLP_EVENT_MASK_LEN_MAX) ||
((mask_length != 4) && !ef->allow_all_mask_sizes)) { ((mask_length != 4) && !ef->allow_all_mask_sizes)) {
sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_MASK_LENGTH); 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); sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);
ef->mask_length = mask_length; ef->mask_length = mask_length;
out:
return;
} }
/* qemu object creation and initialization functions */ /* qemu object creation and initialization functions */
@ -347,7 +338,7 @@ static void sclp_events_bus_realize(BusState *bus, Error **errp)
DeviceState *dev = kid->child; DeviceState *dev = kid->child;
object_property_set_bool(OBJECT(dev), true, "realized", &err); object_property_set_bool(OBJECT(dev), true, "realized", &err);
if (errp) { if (err) {
error_propagate(errp, err); error_propagate(errp, err);
return; return;
} }

View File

@ -505,6 +505,19 @@ static inline void machine_set_dea_key_wrap(Object *obj, bool value,
static S390CcwMachineClass *current_mc; 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) static S390CcwMachineClass *get_machine_class(void)
{ {
if (unlikely(!current_mc)) { if (unlikely(!current_mc)) {
@ -521,19 +534,16 @@ static S390CcwMachineClass *get_machine_class(void)
bool ri_allowed(void) bool ri_allowed(void)
{ {
/* for "none" machine this results in true */
return get_machine_class()->ri_allowed; return get_machine_class()->ri_allowed;
} }
bool cpu_model_allowed(void) bool cpu_model_allowed(void)
{ {
/* for "none" machine this results in true */
return get_machine_class()->cpu_model_allowed; return get_machine_class()->cpu_model_allowed;
} }
bool hpage_1m_allowed(void) bool hpage_1m_allowed(void)
{ {
/* for "none" machine this results in true */
return get_machine_class()->hpage_1m_allowed; return get_machine_class()->hpage_1m_allowed;
} }

View File

@ -197,24 +197,20 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
{ {
SCLPDevice *sclp = get_sclp_device(); SCLPDevice *sclp = get_sclp_device();
SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp); SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
int r = 0;
SCCB work_sccb; SCCB work_sccb;
hwaddr sccb_len = sizeof(SCCB); hwaddr sccb_len = sizeof(SCCB);
/* first some basic checks on program checks */ /* first some basic checks on program checks */
if (env->psw.mask & PSW_MASK_PSTATE) { if (env->psw.mask & PSW_MASK_PSTATE) {
r = -PGM_PRIVILEGED; return -PGM_PRIVILEGED;
goto out;
} }
if (cpu_physical_memory_is_io(sccb)) { if (cpu_physical_memory_is_io(sccb)) {
r = -PGM_ADDRESSING; return -PGM_ADDRESSING;
goto out;
} }
if ((sccb & ~0x1fffUL) == 0 || (sccb & ~0x1fffUL) == env->psa if ((sccb & ~0x1fffUL) == 0 || (sccb & ~0x1fffUL) == env->psa
|| (sccb & ~0x7ffffff8UL) != 0) { || (sccb & ~0x7ffffff8UL) != 0) {
r = -PGM_SPECIFICATION; return -PGM_SPECIFICATION;
goto out;
} }
/* /*
@ -226,8 +222,7 @@ int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
/* Valid sccb sizes */ /* Valid sccb sizes */
if (be16_to_cpu(work_sccb.h.length) < sizeof(SCCBHeader)) { if (be16_to_cpu(work_sccb.h.length) < sizeof(SCCBHeader)) {
r = -PGM_SPECIFICATION; return -PGM_SPECIFICATION;
goto out;
} }
switch (code & SCLP_CMD_CODE_MASK) { switch (code & SCLP_CMD_CODE_MASK) {
@ -257,8 +252,7 @@ out_write:
sclp_c->service_interrupt(sclp, sccb); sclp_c->service_interrupt(sclp, sccb);
out: return 0;
return r;
} }
static void service_interrupt(SCLPDevice *sclp, uint32_t sccb) static void service_interrupt(SCLPDevice *sclp, uint32_t sccb)

View File

@ -697,6 +697,7 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev); CCWDeviceClass *ck = CCW_DEVICE_GET_CLASS(ccw_dev);
SubchDev *sch; SubchDev *sch;
Error *err = NULL; Error *err = NULL;
int i;
sch = css_create_sch(ccw_dev->devno, errp); sch = css_create_sch(ccw_dev->devno, errp);
if (!sch) { if (!sch) {
@ -717,6 +718,9 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
ccw_dev->sch = sch; ccw_dev->sch = sch;
dev->indicators = NULL; dev->indicators = NULL;
dev->revision = -1; 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); css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE);
trace_virtio_ccw_new_device( trace_virtio_ccw_new_device(

View File

@ -305,15 +305,14 @@ static void do_ext_interrupt(CPUS390XState *env)
if ((env->pending_int & INTERRUPT_EMERGENCY_SIGNAL) && if ((env->pending_int & INTERRUPT_EMERGENCY_SIGNAL) &&
(env->cregs[0] & CR0_EMERGENCY_SIGNAL_SC)) { (env->cregs[0] & CR0_EMERGENCY_SIGNAL_SC)) {
MachineState *ms = MACHINE(qdev_get_machine());
unsigned int max_cpus = ms->smp.max_cpus;
lowcore->ext_int_code = cpu_to_be16(EXT_EMERGENCY); lowcore->ext_int_code = cpu_to_be16(EXT_EMERGENCY);
cpu_addr = find_first_bit(env->emergency_signals, S390_MAX_CPUS); cpu_addr = find_first_bit(env->emergency_signals, S390_MAX_CPUS);
g_assert(cpu_addr < S390_MAX_CPUS); g_assert(cpu_addr < S390_MAX_CPUS);
lowcore->cpu_addr = cpu_to_be16(cpu_addr); lowcore->cpu_addr = cpu_to_be16(cpu_addr);
clear_bit(cpu_addr, env->emergency_signals); clear_bit(cpu_addr, env->emergency_signals);
#ifndef CONFIG_USER_ONLY
MachineState *ms = MACHINE(qdev_get_machine());
unsigned int max_cpus = ms->smp.max_cpus;
#endif
if (bitmap_empty(env->emergency_signals, max_cpus)) { if (bitmap_empty(env->emergency_signals, max_cpus)) {
env->pending_int &= ~INTERRUPT_EMERGENCY_SIGNAL; env->pending_int &= ~INTERRUPT_EMERGENCY_SIGNAL;
} }

View File

@ -365,10 +365,13 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
/* /*
* The migration interface for ais was introduced with kernel 4.13 * The migration interface for ais was introduced with kernel 4.13
* but the capability itself had been active since 4.12. As migration * but the capability itself had been active since 4.12. As migration
* support is considered necessary let's disable ais in the 2.10 * support is considered necessary, we only try to enable this for
* machine. * newer machine types if KVM_CAP_S390_AIS_MIGRATION is available.
*/ */
/* kvm_vm_enable_cap(s, KVM_CAP_S390_AIS, 0); */ if (cpu_model_allowed() && kvm_kernel_irqchip_allowed() &&
kvm_check_extension(s, KVM_CAP_S390_AIS_MIGRATION)) {
kvm_vm_enable_cap(s, KVM_CAP_S390_AIS, 0);
}
kvm_set_max_memslot_size(KVM_SLOT_MAX_BYTES); kvm_set_max_memslot_size(KVM_SLOT_MAX_BYTES);
return 0; return 0;

View File

@ -348,9 +348,9 @@ static void sigp_sense_running(S390CPU *dst_cpu, SigpInfo *si)
/* If halted (which includes also STOPPED), it is not running */ /* If halted (which includes also STOPPED), it is not running */
if (CPU(dst_cpu)->halted) { if (CPU(dst_cpu)->halted) {
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
} else {
set_sigp_status(si, SIGP_STAT_NOT_RUNNING); set_sigp_status(si, SIGP_STAT_NOT_RUNNING);
} else {
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff