Commit 2b12164b authored by Linus Torvalds's avatar Linus Torvalds

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
parents 56c22854 02a68d05
...@@ -93,6 +93,8 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run) ...@@ -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: ...@@ -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) ...@@ -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: ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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 |
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment