Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c7d47c3 authored by Alexey Kardashevskiy's avatar Alexey Kardashevskiy Committed by Paul Mackerras
Browse files

KVM: PPC: Book3S PR: Fix WIMG handling under pHyp



Commit 96df2267 ("KVM: PPC: Book3S PR: Preserve storage control bits")
added code to preserve WIMG bits but it missed 2 special cases:
- a magic page in kvmppc_mmu_book3s_64_xlate() and
- guest real mode in kvmppc_handle_pagefault().

For these ptes, WIMG was 0 and pHyp failed on these causing a guest to
stop in the very beginning at NIP=0x100 (due to bd9166ff "KVM: PPC:
Book3S PR: Exit KVM on failed mapping").

According to LoPAPR v1.1 14.5.4.1.2 H_ENTER:

 The hypervisor checks that the WIMG bits within the PTE are appropriate
 for the physical page number else H_Parameter return. (For System Memory
 pages WIMG=0010, or, 1110 if the SAO option is enabled, and for IO pages
 WIMG=01**.)

This hence initializes WIMG to non-zero value HPTE_R_M (0x10), as expected
by pHyp.

[paulus@ozlabs.org - fix compile for 32-bit]

Cc: stable@vger.kernel.org # v4.11+
Fixes: 96df2267 "KVM: PPC: Book3S PR: Preserve storage control bits"
Signed-off-by: default avatarAlexey Kardashevskiy <aik@ozlabs.ru>
Tested-by: default avatarRuediger Oertel <ro@suse.de>
Reviewed-by: default avatarGreg Kurz <groug@kaod.org>
Tested-by: default avatarGreg Kurz <groug@kaod.org>
Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
parent 4ed11aee
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -235,6 +235,7 @@ static int kvmppc_mmu_book3s_64_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
		gpte->may_read = true;
		gpte->may_write = true;
		gpte->page_size = MMU_PAGE_4K;
		gpte->wimg = HPTE_R_M;

		return 0;
	}
+2 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ static void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac);
#define MSR_USER32 MSR_USER
#define MSR_USER64 MSR_USER
#define HW_PAGE_SIZE PAGE_SIZE
#define HPTE_R_M   _PAGE_COHERENT
#endif

static bool kvmppc_is_split_real(struct kvm_vcpu *vcpu)
@@ -557,6 +558,7 @@ int kvmppc_handle_pagefault(struct kvm_run *run, struct kvm_vcpu *vcpu,
		pte.eaddr = eaddr;
		pte.vpage = eaddr >> 12;
		pte.page_size = MMU_PAGE_64K;
		pte.wimg = HPTE_R_M;
	}

	switch (kvmppc_get_msr(vcpu) & (MSR_DR|MSR_IR)) {