Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: "A smattering of bug fixes across most architectures" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: powerpc/kvm/cma: Fix panic introduces by signed shift operation KVM: s390/mm: Fix guest storage key corruption in ptep_set_access_flags KVM: s390/mm: Fix storage key corruption during swapping arm/arm64: KVM: Complete WFI/WFE instructions ARM/ARM64: KVM: Nuke Hyp-mode tlbs before enabling MMU KVM: s390/mm: try a cow on read only pages for key ops KVM: s390: Fix user triggerable bug in dead code
This commit is contained in:
@@ -93,6 +93,8 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|||||||
else
|
else
|
||||||
kvm_vcpu_block(vcpu);
|
kvm_vcpu_block(vcpu);
|
||||||
|
|
||||||
|
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -99,6 +99,10 @@ __do_hyp_init:
|
|||||||
mrc p15, 0, r0, c10, c2, 1
|
mrc p15, 0, r0, c10, c2, 1
|
||||||
mcr p15, 4, r0, c10, c2, 1
|
mcr p15, 4, r0, c10, c2, 1
|
||||||
|
|
||||||
|
@ Invalidate the stale TLBs from Bootloader
|
||||||
|
mcr p15, 4, r0, c8, c7, 0 @ TLBIALLH
|
||||||
|
dsb ish
|
||||||
|
|
||||||
@ Set the HSCTLR to:
|
@ Set the HSCTLR to:
|
||||||
@ - ARM/THUMB exceptions: Kernel config (Thumb-2 kernel)
|
@ - ARM/THUMB exceptions: Kernel config (Thumb-2 kernel)
|
||||||
@ - Endianness: Kernel config
|
@ - Endianness: Kernel config
|
||||||
|
@@ -66,6 +66,8 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|||||||
else
|
else
|
||||||
kvm_vcpu_block(vcpu);
|
kvm_vcpu_block(vcpu);
|
||||||
|
|
||||||
|
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -80,6 +80,10 @@ __do_hyp_init:
|
|||||||
msr mair_el2, x4
|
msr mair_el2, x4
|
||||||
isb
|
isb
|
||||||
|
|
||||||
|
/* Invalidate the stale TLBs from Bootloader */
|
||||||
|
tlbi alle2
|
||||||
|
dsb sy
|
||||||
|
|
||||||
mrs x4, sctlr_el2
|
mrs x4, sctlr_el2
|
||||||
and x4, x4, #SCTLR_EL2_EE // preserve endianness of EL2
|
and x4, x4, #SCTLR_EL2_EE // preserve endianness of EL2
|
||||||
ldr x5, =SCTLR_EL2_FLAGS
|
ldr x5, =SCTLR_EL2_FLAGS
|
||||||
|
@@ -62,10 +62,10 @@ long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
kvm->arch.hpt_cma_alloc = 0;
|
kvm->arch.hpt_cma_alloc = 0;
|
||||||
page = kvm_alloc_hpt(1 << (order - PAGE_SHIFT));
|
page = kvm_alloc_hpt(1ul << (order - PAGE_SHIFT));
|
||||||
if (page) {
|
if (page) {
|
||||||
hpt = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
|
hpt = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
|
||||||
memset((void *)hpt, 0, (1 << order));
|
memset((void *)hpt, 0, (1ul << order));
|
||||||
kvm->arch.hpt_cma_alloc = 1;
|
kvm->arch.hpt_cma_alloc = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1127,7 +1127,7 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
|
|||||||
unsigned long addr, pte_t *ptep)
|
unsigned long addr, pte_t *ptep)
|
||||||
{
|
{
|
||||||
pgste_t pgste;
|
pgste_t pgste;
|
||||||
pte_t pte;
|
pte_t pte, oldpte;
|
||||||
int young;
|
int young;
|
||||||
|
|
||||||
if (mm_has_pgste(vma->vm_mm)) {
|
if (mm_has_pgste(vma->vm_mm)) {
|
||||||
@@ -1135,12 +1135,13 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
|
|||||||
pgste = pgste_ipte_notify(vma->vm_mm, ptep, pgste);
|
pgste = pgste_ipte_notify(vma->vm_mm, ptep, pgste);
|
||||||
}
|
}
|
||||||
|
|
||||||
pte = *ptep;
|
oldpte = pte = *ptep;
|
||||||
ptep_flush_direct(vma->vm_mm, addr, ptep);
|
ptep_flush_direct(vma->vm_mm, addr, ptep);
|
||||||
young = pte_young(pte);
|
young = pte_young(pte);
|
||||||
pte = pte_mkold(pte);
|
pte = pte_mkold(pte);
|
||||||
|
|
||||||
if (mm_has_pgste(vma->vm_mm)) {
|
if (mm_has_pgste(vma->vm_mm)) {
|
||||||
|
pgste = pgste_update_all(&oldpte, pgste, vma->vm_mm);
|
||||||
pgste = pgste_set_pte(ptep, pgste, pte);
|
pgste = pgste_set_pte(ptep, pgste, pte);
|
||||||
pgste_set_unlock(ptep, pgste);
|
pgste_set_unlock(ptep, pgste);
|
||||||
} else
|
} else
|
||||||
@@ -1330,6 +1331,7 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
|
|||||||
ptep_flush_direct(vma->vm_mm, address, ptep);
|
ptep_flush_direct(vma->vm_mm, address, ptep);
|
||||||
|
|
||||||
if (mm_has_pgste(vma->vm_mm)) {
|
if (mm_has_pgste(vma->vm_mm)) {
|
||||||
|
pgste_set_key(ptep, pgste, entry, vma->vm_mm);
|
||||||
pgste = pgste_set_pte(ptep, pgste, entry);
|
pgste = pgste_set_pte(ptep, pgste, entry);
|
||||||
pgste_set_unlock(ptep, pgste);
|
pgste_set_unlock(ptep, pgste);
|
||||||
} else
|
} else
|
||||||
|
@@ -1317,19 +1317,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (kvm_run->exit_reason) {
|
|
||||||
case KVM_EXIT_S390_SIEIC:
|
|
||||||
case KVM_EXIT_UNKNOWN:
|
|
||||||
case KVM_EXIT_INTR:
|
|
||||||
case KVM_EXIT_S390_RESET:
|
|
||||||
case KVM_EXIT_S390_UCONTROL:
|
|
||||||
case KVM_EXIT_S390_TSCH:
|
|
||||||
case KVM_EXIT_DEBUG:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
|
|
||||||
vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
|
vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask;
|
||||||
vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
|
vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr;
|
||||||
if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) {
|
if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) {
|
||||||
|
@@ -986,11 +986,21 @@ int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
|
|||||||
pte_t *ptep;
|
pte_t *ptep;
|
||||||
|
|
||||||
down_read(&mm->mmap_sem);
|
down_read(&mm->mmap_sem);
|
||||||
|
retry:
|
||||||
ptep = get_locked_pte(current->mm, addr, &ptl);
|
ptep = get_locked_pte(current->mm, addr, &ptl);
|
||||||
if (unlikely(!ptep)) {
|
if (unlikely(!ptep)) {
|
||||||
up_read(&mm->mmap_sem);
|
up_read(&mm->mmap_sem);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
if (!(pte_val(*ptep) & _PAGE_INVALID) &&
|
||||||
|
(pte_val(*ptep) & _PAGE_PROTECT)) {
|
||||||
|
pte_unmap_unlock(*ptep, ptl);
|
||||||
|
if (fixup_user_fault(current, mm, addr, FAULT_FLAG_WRITE)) {
|
||||||
|
up_read(&mm->mmap_sem);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
|
||||||
new = old = pgste_get_lock(ptep);
|
new = old = pgste_get_lock(ptep);
|
||||||
pgste_val(new) &= ~(PGSTE_GR_BIT | PGSTE_GC_BIT |
|
pgste_val(new) &= ~(PGSTE_GR_BIT | PGSTE_GC_BIT |
|
||||||
|
Reference in New Issue
Block a user