diff mbox series

[1/6] target/ppc: Don't check UPRT in radix mode when in HV real mode

Message ID 20190411080004.8690-2-clg@kaod.org
State New
Headers show
Series ppc: misc fixes for Radix and Hash | expand

Commit Message

Cédric Le Goater April 11, 2019, 7:59 a.m. UTC
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>
---
 target/ppc/mmu-radix64.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

Comments

David Gibson April 12, 2019, 6:10 a.m. UTC | #1
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 mbox series

Patch

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);