summaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2019-04-11 09:59:59 +0200
committerDavid Gibson <david@gibson.dropbear.id.au>2019-04-26 11:37:57 +1000
commit24b5e0a5ce36975c24d1870832ad3a97876f460a (patch)
tree1814e790615a7d0c37485761b9616c70f5265ec7 /target
parent8d83cbf1015f547cd9336881e6b62ae2ca293849 (diff)
target/ppc: Don't check UPRT in radix mode when in HV real mode
It appears that during kexec, we run for a while in hypervisor real mode with LPCR:HR set and LPCR:UPRT clear, which trips the assertion in ppc_radix64_handle_mmu_fault(). First this shouldn't be an assertion, it's a guest error. Then we shouldn't be checking these things in hypervisor real mode (or in virtual hypervisor guest real mode which is similar) as the real HW won't use those LPCR bits in those cases anyway, so technically it's ok to have this discrepancy. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20190411080004.8690-2-clg@kaod.org> [dwg: Fix for 32-bit builds] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target')
-rw-r--r--target/ppc/mmu-radix64.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index ca1fb2673f..066e324464 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -228,10 +228,10 @@ int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
ppc_v3_pate_t pate;
assert((rwx == 0) || (rwx == 1) || (rwx == 2));
- assert(ppc64_use_proc_tbl(cpu));
- /* Real Mode Access */
- if (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0))) {
+ /* HV or virtual hypervisor Real Mode Access */
+ if ((msr_hv || cpu->vhyp) &&
+ (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0)))) {
/* In real mode top 4 effective addr bits (mostly) ignored */
raddr = eaddr & 0x0FFFFFFFFFFFFFFFULL;
@@ -241,6 +241,16 @@ int ppc_radix64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
return 0;
}
+ /*
+ * Check UPRT (we avoid the check in real mode to deal with
+ * transitional states during kexec.
+ */
+ if (!ppc64_use_proc_tbl(cpu)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "LPCR:UPRT not set in radix mode ! LPCR="
+ TARGET_FMT_lx "\n", env->spr[SPR_LPCR]);
+ }
+
/* Virtual Mode Access - get the fully qualified address */
if (!ppc_radix64_get_fully_qualified_addr(env, eaddr, &lpid, &pid)) {
ppc_radix64_raise_segi(cpu, rwx, eaddr);