mirror of
https://github.com/qemu/qemu.git
synced 2024-11-27 22:03:35 +08:00
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:
commit
105b07f1ba
@ -18,8 +18,10 @@ What should go into a stable release?
|
||||
-------------------------------------
|
||||
|
||||
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
|
||||
(or for a distribution picking fixes), it is usually a good candidate
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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(
|
||||
|
@ -305,15 +305,14 @@ static void do_ext_interrupt(CPUS390XState *env)
|
||||
|
||||
if ((env->pending_int & INTERRUPT_EMERGENCY_SIGNAL) &&
|
||||
(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);
|
||||
cpu_addr = find_first_bit(env->emergency_signals, S390_MAX_CPUS);
|
||||
g_assert(cpu_addr < S390_MAX_CPUS);
|
||||
lowcore->cpu_addr = cpu_to_be16(cpu_addr);
|
||||
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)) {
|
||||
env->pending_int &= ~INTERRUPT_EMERGENCY_SIGNAL;
|
||||
}
|
||||
|
@ -365,10 +365,13 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
/*
|
||||
* The migration interface for ais was introduced with kernel 4.13
|
||||
* but the capability itself had been active since 4.12. As migration
|
||||
* support is considered necessary let's disable ais in the 2.10
|
||||
* machine.
|
||||
* support is considered necessary, we only try to enable this for
|
||||
* 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);
|
||||
return 0;
|
||||
|
@ -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 (CPU(dst_cpu)->halted) {
|
||||
si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;
|
||||
} else {
|
||||
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
Loading…
Reference in New Issue
Block a user