mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 18:39:59 +00:00
KVM: s390: Fixes for 4.4
1. disallow changing the SIMD mode when CPUs have been created. it allowed userspace to corrupt kernel memory 2. Fix vCPU lookup. Until now the vCPU number equals the vCPU id. Some kernel code places relied on that. This might a: cause guest failures b: allow userspace to corrupt kernel memory 3. Fencing of the PFMF instruction should use the guest facilities and not the host facilities. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) iQIcBAABAgAGBQJWTdM4AAoJEBF7vIC1phx8ROUQALQsGOZD2VLANXjTnjMqZjhD WVCdS+XReHtAdTdTa6XrC1yZ/U7I0GvOXwa2Tn4Gezp+JJlyfRB/Werwj/Q363Tc ONKkGA3F11MIzUqK0NdoYxJBQEJKaeZrUaWv9vEA2b8dHRn/V7P9gxFcChxTe9Q6 PEfzCQRVGqJ3zYEO787IDsRudRJCYsmwFHBap1RunGYLngAJ0XJf8XtITJNcJrg6 imORMF6dEYRPJM/QaPE3CeeZrSxdooVzAEA/4VYSc4j28WUc14cTQlqO7bAEL0GQ 9KjCN8ymTD0HhY23891YhyhJu6bEXNi98l8dKtpdhQ0niNLgkwhwUKmSlvF+msPp MreW40Yl7KML+fy7UpQpngcNKoRUHKqpBY9dm/scjh7K6rIiZqPi4rGdMxVrF85y /KhMAMboTkvddnu80VViOY1G1PTmeNzcy1wFT3QxiTWwO0UfyT9VMKyTKw0AEts1 4xJ4FC+C8f4ZJ1wuBkope1Sa3GJntaOmRU1PpS8cj0CBZHEbk0lBuHCsvpv8StYH L8dUZ3ddIrs4qxEhGbWaEaDQc4nCfkcBpLcx2ijw0u8VEr5dgxaD/00InN74tQq9 dLwnXbg3DCmLacahWSLYU+zEepmfvj+AkeVYLRuAFZz5rLkyMeeSMO7FuMGgtLI/ xjoKu7NozfO8Z3cV42HK =ZiXK -----END PGP SIGNATURE----- Merge tag 'kvm-s390-master-4.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into kvm-master KVM: s390: Fixes for 4.4 1. disallow changing the SIMD mode when CPUs have been created. it allowed userspace to corrupt kernel memory 2. Fix vCPU lookup. Until now the vCPU number equals the vCPU id. Some kernel code places relied on that. This might a: cause guest failures b: allow userspace to corrupt kernel memory 3. Fencing of the PFMF instruction should use the guest facilities and not the host facilities.
This commit is contained in:
commit
d792abacaf
5 changed files with 24 additions and 10 deletions
|
@ -1030,8 +1030,7 @@ static int __inject_extcall(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
|
|||
src_id, 0);
|
||||
|
||||
/* sending vcpu invalid */
|
||||
if (src_id >= KVM_MAX_VCPUS ||
|
||||
kvm_get_vcpu(vcpu->kvm, src_id) == NULL)
|
||||
if (kvm_get_vcpu_by_id(vcpu->kvm, src_id) == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (sclp.has_sigpif)
|
||||
|
@ -1110,6 +1109,10 @@ static int __inject_sigp_emergency(struct kvm_vcpu *vcpu,
|
|||
trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY,
|
||||
irq->u.emerg.code, 0);
|
||||
|
||||
/* sending vcpu invalid */
|
||||
if (kvm_get_vcpu_by_id(vcpu->kvm, irq->u.emerg.code) == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
set_bit(irq->u.emerg.code, li->sigp_emerg_pending);
|
||||
set_bit(IRQ_PEND_EXT_EMERGENCY, &li->pending_irqs);
|
||||
atomic_or(CPUSTAT_EXT_INT, li->cpuflags);
|
||||
|
|
|
@ -342,12 +342,16 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
|
|||
r = 0;
|
||||
break;
|
||||
case KVM_CAP_S390_VECTOR_REGISTERS:
|
||||
if (MACHINE_HAS_VX) {
|
||||
mutex_lock(&kvm->lock);
|
||||
if (atomic_read(&kvm->online_vcpus)) {
|
||||
r = -EBUSY;
|
||||
} else if (MACHINE_HAS_VX) {
|
||||
set_kvm_facility(kvm->arch.model.fac->mask, 129);
|
||||
set_kvm_facility(kvm->arch.model.fac->list, 129);
|
||||
r = 0;
|
||||
} else
|
||||
r = -EINVAL;
|
||||
mutex_unlock(&kvm->lock);
|
||||
VM_EVENT(kvm, 3, "ENABLE: CAP_S390_VECTOR_REGISTERS %s",
|
||||
r ? "(not available)" : "(success)");
|
||||
break;
|
||||
|
|
|
@ -660,7 +660,7 @@ static int handle_pfmf(struct kvm_vcpu *vcpu)
|
|||
|
||||
kvm_s390_get_regs_rre(vcpu, ®1, ®2);
|
||||
|
||||
if (!MACHINE_HAS_PFMF)
|
||||
if (!test_kvm_facility(vcpu->kvm, 8))
|
||||
return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
|
||||
|
||||
if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
|
||||
|
|
|
@ -291,12 +291,8 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code,
|
|||
u16 cpu_addr, u32 parameter, u64 *status_reg)
|
||||
{
|
||||
int rc;
|
||||
struct kvm_vcpu *dst_vcpu;
|
||||
struct kvm_vcpu *dst_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr);
|
||||
|
||||
if (cpu_addr >= KVM_MAX_VCPUS)
|
||||
return SIGP_CC_NOT_OPERATIONAL;
|
||||
|
||||
dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
|
||||
if (!dst_vcpu)
|
||||
return SIGP_CC_NOT_OPERATIONAL;
|
||||
|
||||
|
@ -478,7 +474,7 @@ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu)
|
|||
trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr);
|
||||
|
||||
if (order_code == SIGP_EXTERNAL_CALL) {
|
||||
dest_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
|
||||
dest_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr);
|
||||
BUG_ON(dest_vcpu == NULL);
|
||||
|
||||
kvm_s390_vcpu_wakeup(dest_vcpu);
|
||||
|
|
|
@ -460,6 +460,17 @@ static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
|
|||
(vcpup = kvm_get_vcpu(kvm, idx)) != NULL; \
|
||||
idx++)
|
||||
|
||||
static inline struct kvm_vcpu *kvm_get_vcpu_by_id(struct kvm *kvm, int id)
|
||||
{
|
||||
struct kvm_vcpu *vcpu;
|
||||
int i;
|
||||
|
||||
kvm_for_each_vcpu(i, vcpu, kvm)
|
||||
if (vcpu->vcpu_id == id)
|
||||
return vcpu;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define kvm_for_each_memslot(memslot, slots) \
|
||||
for (memslot = &slots->memslots[0]; \
|
||||
memslot < slots->memslots + KVM_MEM_SLOTS_NUM && memslot->npages;\
|
||||
|
|
Loading…
Reference in a new issue