Message ID | 20190411080004.8690-2-clg@kaod.org |
---|---|
State | New |
Headers | show |
Series | ppc: misc fixes for Radix and Hash | expand |
On Thu, Apr 11, 2019 at 09:59:59AM +0200, Cédric Le Goater wrote: > From: Benjamin Herrenschmidt <benh@kernel.crashing.org> > > 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> Applied to ppc-for-4.1, thanks. > --- > target/ppc/mmu-radix64.c | 16 +++++++++++++--- > 1 file changed, 13 insertions(+), 3 deletions(-) > > diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c > index ca1fb2673f93..cac076ee92d9 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)))) { Hrm.. this looks like a different bug fix. Were we preivously incorrectly handling guest real mode when running powernv? > /* 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=%016lx\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);
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c index ca1fb2673f93..cac076ee92d9 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=%016lx\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);