All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/10] rework exception model to support the HV mode
@ 2016-06-13  5:24 Cédric Le Goater
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation Cédric Le Goater
                   ` (9 more replies)
  0 siblings, 10 replies; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-13  5:24 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt, Cedric Le Goater

Hello,

Here is a new set bringing more changes required for the powernv
platform. The major one is the rework of the exception model to
support the HV mode.

It was tested with a pseries guest, KVM and TCG, and with a mac99
guest !

The next serie will cover a rework of XICS to support native mode and
it should be the last one before the first powernv core patches.

Cheers,

C.

Benjamin Herrenschmidt (10):
  ppc: Fix rfi/rfid/hrfi/... emulation
  ppc: Create cpu_ppc_set_papr() helper (for LPCR)
  ppc: Rework POWER7 & POWER8 exception model (part 2)
  ppc: Fix POWER7 and POWER8 exception definitions
  ppc: Fix generation if ISI/DSI vs. HV mode
  ppc: Rework generation of priv and inval interrupts
  ppc: Add real mode CI load/store instructions for P7 and P8
  ppc: Turn a bunch of booleans from int to bool
  ppc: Move exception generation code out of line
  ppc: Add P7/P8 Power Management instructions

 linux-user/main.c           |   1 +
 target-ppc/cpu-qom.h        |   9 +
 target-ppc/cpu.h            |  32 +-
 target-ppc/excp_helper.c    | 263 ++++++++------
 target-ppc/helper.h         |   1 +
 target-ppc/mmu-hash64.c     |  69 +++-
 target-ppc/translate.c      | 866 ++++++++++++++++++++++----------------------
 target-ppc/translate_init.c | 139 ++++++-
 8 files changed, 797 insertions(+), 583 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-13  5:24 [Qemu-devel] [PATCH 00/10] rework exception model to support the HV mode Cédric Le Goater
@ 2016-06-13  5:24 ` Cédric Le Goater
  2016-06-16  1:07   ` David Gibson
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 02/10] ppc: Create cpu_ppc_set_papr() helper (for LPCR) Cédric Le Goater
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-13  5:24 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt, Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

This reworks emulation of the various "rfi" variants. I removed
some masking bits that I couldn't make sense of, the only bit that
I am aware we should mask here is POW, the CPU's MSR mask should
take care of the rest.

This also fixes some problems when running 32-bit userspace under
a 64-bit kernel.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 target-ppc/excp_helper.c | 51 +++++++++++++++++++-----------------------------
 target-ppc/translate.c   |  7 +++++++
 2 files changed, 27 insertions(+), 31 deletions(-)

diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 30e960e30b63..aa0b63f4b0de 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -922,25 +922,20 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
     }
 }
 
-static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
-                          target_ulong msrm, int keep_msrh)
+static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
 {
     CPUState *cs = CPU(ppc_env_get_cpu(env));
 
+    /* MSR:POW cannot be set by any form of rfi */
+    msr &= ~(1ULL << MSR_POW);
+
 #if defined(TARGET_PPC64)
-    if (msr_is_64bit(env, msr)) {
-        nip = (uint64_t)nip;
-        msr &= (uint64_t)msrm;
-    } else {
+    /* Switching to 32-bit ? Crop the nip */
+    if (!msr_is_64bit(env, msr)) {
         nip = (uint32_t)nip;
-        msr = (uint32_t)(msr & msrm);
-        if (keep_msrh) {
-            msr |= env->msr & ~((uint64_t)0xFFFFFFFF);
-        }
     }
 #else
     nip = (uint32_t)nip;
-    msr &= (uint32_t)msrm;
 #endif
     /* XXX: beware: this is false if VLE is supported */
     env->nip = nip & ~((target_ulong)0x00000003);
@@ -959,26 +954,24 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
 
 void helper_rfi(CPUPPCState *env)
 {
-    if (env->excp_model == POWERPC_EXCP_BOOKE) {
-        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
-               ~((target_ulong)0), 0);
-    } else {
-        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
-               ~((target_ulong)0x783F0000), 1);
-    }
+    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
 }
 
+#define MSR_BOOK3S_MASK
 #if defined(TARGET_PPC64)
 void helper_rfid(CPUPPCState *env)
 {
-    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
-           ~((target_ulong)0x783F0000), 0);
+    /* The architeture defines a number of rules for which bits
+     * can change but in practice, we handle this in hreg_store_msr()
+     * which will be called by do_rfi(), so there is no need to filter
+     * here
+     */
+    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
 }
 
 void helper_hrfid(CPUPPCState *env)
 {
-    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
-           ~((target_ulong)0x783F0000), 0);
+    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
 }
 #endif
 
@@ -986,28 +979,24 @@ void helper_hrfid(CPUPPCState *env)
 /* Embedded PowerPC specific helpers */
 void helper_40x_rfci(CPUPPCState *env)
 {
-    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3],
-           ~((target_ulong)0xFFFF0000), 0);
+    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
 }
 
 void helper_rfci(CPUPPCState *env)
 {
-    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
-           ~((target_ulong)0), 0);
+    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
 }
 
 void helper_rfdi(CPUPPCState *env)
 {
     /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
-    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1],
-           ~((target_ulong)0), 0);
+    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
 }
 
 void helper_rfmci(CPUPPCState *env)
 {
     /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
-    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1],
-           ~((target_ulong)0), 0);
+    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
 }
 #endif
 
@@ -1045,7 +1034,7 @@ void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
 
 void helper_rfsvc(CPUPPCState *env)
 {
-    do_rfi(env, env->lr, env->ctr, 0x0000FFFF, 0);
+    do_rfi(env, env->lr, env->ctr & 0x0000FFFF);
 }
 
 /* Embedded.Processor Control */
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index b6894751e8df..a02ddf52bfe6 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -4087,6 +4087,13 @@ static void gen_rfi(DisasContext *ctx)
 #if defined(CONFIG_USER_ONLY)
     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
 #else
+    /* This instruction doesn't exist anymore on 64-bit server
+     * processors compliant with arch 2.x
+     */
+    if (ctx->insns_flags & PPC_SEGMENT_64B) {
+        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
+        return;
+    }
     /* Restore CPU state */
     if (unlikely(ctx->pr)) {
         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 02/10] ppc: Create cpu_ppc_set_papr() helper (for LPCR)
  2016-06-13  5:24 [Qemu-devel] [PATCH 00/10] rework exception model to support the HV mode Cédric Le Goater
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation Cédric Le Goater
@ 2016-06-13  5:24 ` Cédric Le Goater
  2016-06-14  6:15   ` David Gibson
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 03/10] ppc: Rework POWER7 & POWER8 exception model (part 2) Cédric Le Goater
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-13  5:24 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt, Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

And move the code adjusting the MSR mask and calling kvmppc_set_papr()
to it. This allows us to add a few more things such as disabling setting
of MSR:HV and appropriate LPCR bits which will be used when fixing
the exception model.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
[clg: previous commit 26a7f1291bb5 did not include the LPCR setting as
      it was not needed at the time ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target-ppc/translate_init.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index ca894ff4af45..edfd91a85425 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8509,6 +8509,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
 void cpu_ppc_set_papr(PowerPCCPU *cpu)
 {
     CPUPPCState *env = &cpu->env;
+    ppc_spr_t *lpcr = &env->spr_cb[SPR_LPCR];
     ppc_spr_t *amor = &env->spr_cb[SPR_AMOR];
 
     /* PAPR always has exception vectors in RAM not ROM. To ensure this,
@@ -8518,6 +8519,19 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)
      */
     env->msr_mask &= ~((1ull << MSR_EP) | MSR_HVB);
 
+    /* Set emulated LPCR to not send interrupts to hypervisor. Note that
+     * under KVM, the actual HW LPCR will be set differently by KVM itself,
+     * the settings below ensure proper operations with TCG in absence of
+     * a real hypervisor
+     */
+    lpcr->default_value &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV);
+    lpcr->default_value |= LPCR_LPES0 | LPCR_LPES1;
+
+    /* We should be followed by a CPU reset but update the active value
+     * just in case...
+     */
+    env->spr[SPR_LPCR] = lpcr->default_value;
+
     /* Set a full AMOR so guest can use the AMR as it sees fit */
     env->spr[SPR_AMOR] = amor->default_value = 0xffffffffffffffffull;
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 03/10] ppc: Rework POWER7 & POWER8 exception model (part 2)
  2016-06-13  5:24 [Qemu-devel] [PATCH 00/10] rework exception model to support the HV mode Cédric Le Goater
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation Cédric Le Goater
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 02/10] ppc: Create cpu_ppc_set_papr() helper (for LPCR) Cédric Le Goater
@ 2016-06-13  5:24 ` Cédric Le Goater
  2016-06-14  6:25   ` David Gibson
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 04/10] ppc: Fix POWER7 and POWER8 exception definitions Cédric Le Goater
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-13  5:24 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt, Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Properly implement LPES0/1 handling for HV vs. !HV mode.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[clg: AIL implementation was fixed in commit 5c94b2a5e5ef
      fixed checkpatch.pl errors ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target-ppc/excp_helper.c | 134 ++++++++++++++++-------------------------------
 1 file changed, 45 insertions(+), 89 deletions(-)

diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index aa0b63f4b0de..7c44c102db39 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -77,18 +77,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
     target_ulong msr, new_msr, vector;
-    int srr0, srr1, asrr0, asrr1;
-    int lpes0, lpes1, lev, ail;
-
-    if (0) {
-        /* XXX: find a suitable condition to enable the hypervisor mode */
-        lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;
-        lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;
-    } else {
-        /* Those values ensure we won't enter the hypervisor mode */
-        lpes0 = 0;
-        lpes1 = 1;
-    }
+    int srr0, srr1, asrr0, asrr1, lev, ail;
+    bool lpes0;
 
     qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
                   " => %08x (%02x)\n", env->nip, excp, env->error_code);
@@ -100,8 +90,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         msr = env->msr & ~0x783f0000ULL;
     }
 
-    /* new interrupt handler msr */
-    new_msr = env->msr & ((target_ulong)1 << MSR_ME);
+    /* new interrupt handler msr preserves existing HV and ME unless
+     * explicitly overriden
+     */
+    new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
 
     /* target registers */
     srr0 = SPR_SRR0;
@@ -111,12 +103,19 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
 
     /* Exception targetting modifiers
      *
+     * LPES0 is supported on POWER7/8
+     * LPES1 is not supported (old iSeries mode)
+     *
+     * On anything else, we behave as if LPES0 is 1
+     * (externals don't alter MSR:HV)
+     *
      * AIL is initialized here but can be cleared by
      * selected exceptions
      */
 #if defined(TARGET_PPC64)
     if (excp_model == POWERPC_EXCP_POWER7 ||
         excp_model == POWERPC_EXCP_POWER8) {
+        lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
         if (excp_model == POWERPC_EXCP_POWER8) {
             ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
         } else {
@@ -125,6 +124,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     } else
 #endif /* defined(TARGET_PPC64) */
     {
+        lpes0 = true;
         ail = 0;
     }
 
@@ -162,10 +162,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             cs->halted = 1;
             cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
         }
-        if (0) {
-            /* XXX: find a suitable condition to enable the hypervisor mode */
-            new_msr |= (target_ulong)MSR_HVB;
-        }
+        new_msr |= (target_ulong)MSR_HVB;
         ail = 0;
 
         /* machine check exceptions don't have ME set */
@@ -191,23 +188,20 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     case POWERPC_EXCP_DSI:       /* Data storage exception                   */
         LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
                  "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_next;
     case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
         LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
                  "\n", msr, env->nip);
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         msr |= env->error_code;
         goto store_next;
     case POWERPC_EXCP_EXTERNAL:  /* External input                           */
         cs = CPU(cpu);
 
-        if (lpes0 == 1) {
+        if (!lpes0) {
             new_msr |= (target_ulong)MSR_HVB;
+            new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
+            srr0 = SPR_HSRR0;
+            srr1 = SPR_HSRR1;
         }
         if (env->mpic_proxy) {
             /* IACK the IRQ on delivery */
@@ -215,9 +209,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
         goto store_next;
     case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         /* XXX: this is false */
         /* Get rS/rD and rA from faulting opcode */
         env->spr[SPR_DSISR] |= (cpu_ldl_code(env, (env->nip - 4))
@@ -232,9 +223,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
                 env->error_code = 0;
                 return;
             }
-            if (lpes1 == 0) {
-                new_msr |= (target_ulong)MSR_HVB;
-            }
             msr |= 0x00100000;
             if (msr_fe0 == msr_fe1) {
                 goto store_next;
@@ -243,23 +231,14 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             break;
         case POWERPC_EXCP_INVAL:
             LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
-            if (lpes1 == 0) {
-                new_msr |= (target_ulong)MSR_HVB;
-            }
             msr |= 0x00080000;
             env->spr[SPR_BOOKE_ESR] = ESR_PIL;
             break;
         case POWERPC_EXCP_PRIV:
-            if (lpes1 == 0) {
-                new_msr |= (target_ulong)MSR_HVB;
-            }
             msr |= 0x00040000;
             env->spr[SPR_BOOKE_ESR] = ESR_PPR;
             break;
         case POWERPC_EXCP_TRAP:
-            if (lpes1 == 0) {
-                new_msr |= (target_ulong)MSR_HVB;
-            }
             msr |= 0x00020000;
             env->spr[SPR_BOOKE_ESR] = ESR_PTR;
             break;
@@ -271,27 +250,23 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
         goto store_current;
     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_current;
     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
         dump_syscall(env);
         lev = env->error_code;
+
+        /* "PAPR mode" built-in hypercall emulation */
         if ((lev == 1) && cpu_ppc_hypercall) {
             cpu_ppc_hypercall(cpu);
             return;
         }
-        if (lev == 1 || (lpes0 == 0 && lpes1 == 0)) {
+        if (lev == 1) {
             new_msr |= (target_ulong)MSR_HVB;
         }
         goto store_next;
     case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
         goto store_current;
     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_next;
     case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
         /* FIT on 4xx */
@@ -361,21 +336,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             new_msr &= ~((target_ulong)1 << MSR_ME);
         }
 
-        if (0) {
-            /* XXX: find a suitable condition to enable the hypervisor mode */
-            new_msr |= (target_ulong)MSR_HVB;
-        }
+        new_msr |= (target_ulong)MSR_HVB;
         ail = 0;
         goto store_next;
     case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_next;
     case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_next;
     case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
         srr0 = SPR_HSRR0;
@@ -384,9 +350,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
         goto store_next;
     case POWERPC_EXCP_TRACE:     /* Trace exception                          */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_next;
     case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
         srr0 = SPR_HSRR0;
@@ -413,19 +376,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
         goto store_next;
     case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_current;
     case POWERPC_EXCP_VSXU:       /* VSX unavailable exception               */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_current;
     case POWERPC_EXCP_FU:         /* Facility unavailable exception          */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         goto store_current;
     case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
         LOG_EXCP("PIT exception\n");
@@ -444,9 +398,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
                   "is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
-        if (lpes1 == 0) { /* XXX: check this */
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         switch (excp_model) {
         case POWERPC_EXCP_602:
         case POWERPC_EXCP_603:
@@ -463,9 +414,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
         break;
     case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
-        if (lpes1 == 0) { /* XXX: check this */
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         switch (excp_model) {
         case POWERPC_EXCP_602:
         case POWERPC_EXCP_603:
@@ -482,9 +430,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
         break;
     case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
-        if (lpes1 == 0) { /* XXX: check this */
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         switch (excp_model) {
         case POWERPC_EXCP_602:
         case POWERPC_EXCP_603:
@@ -590,9 +535,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
                   "is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
-        if (lpes1 == 0) {
-            new_msr |= (target_ulong)MSR_HVB;
-        }
         /* XXX: TODO */
         cpu_abort(cs,
                   "Performance counter exception is not implemented yet !\n");
@@ -636,6 +578,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     }
     /* Save MSR */
     env->spr[srr1] = msr;
+
+    /* Sanity check */
+    if (!(env->msr_mask & MSR_HVB) && (srr0 == SPR_HSRR0)) {
+        cpu_abort(cs, "Trying to deliver HV exception %d with "
+                  "no HV support\n", excp);
+    }
+
     /* If any alternate SRR register are defined, duplicate saved values */
     if (asrr0 != -1) {
         env->spr[asrr0] = env->spr[srr0];
@@ -644,14 +593,20 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         env->spr[asrr1] = env->spr[srr1];
     }
 
-    if (env->spr[SPR_LPCR] & LPCR_AIL) {
-        new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
-    }
-
+    /* Sort out endianness of interrupt, this differs depending on the
+     * CPU, the HV mode, etc...
+     */
 #ifdef TARGET_PPC64
-    if (excp_model == POWERPC_EXCP_POWER7 ||
-        excp_model == POWERPC_EXCP_POWER8) {
-        if (env->spr[SPR_LPCR] & LPCR_ILE) {
+    if (excp_model == POWERPC_EXCP_POWER7) {
+        if (!(new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) {
+            new_msr |= (target_ulong)1 << MSR_LE;
+        }
+    } else if (excp_model == POWERPC_EXCP_POWER8) {
+        if (new_msr & MSR_HVB) {
+            if (env->spr[SPR_HID0] & HID0_HILE) {
+                new_msr |= (target_ulong)1 << MSR_LE;
+            }
+        } else if (env->spr[SPR_LPCR] & LPCR_ILE) {
             new_msr |= (target_ulong)1 << MSR_LE;
         }
     } else if (msr_ile) {
@@ -674,7 +629,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     /* AIL only works if there is no HV transition and we are running with
      * translations enabled
      */
-    if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1)) {
+    if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1) ||
+        ((new_msr & MSR_HVB) && !(msr & MSR_HVB))) {
         ail = 0;
     }
     /* Handle AIL */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 04/10] ppc: Fix POWER7 and POWER8 exception definitions
  2016-06-13  5:24 [Qemu-devel] [PATCH 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (2 preceding siblings ...)
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 03/10] ppc: Rework POWER7 & POWER8 exception model (part 2) Cédric Le Goater
@ 2016-06-13  5:24 ` Cédric Le Goater
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 05/10] ppc: Fix generation if ISI/DSI vs. HV mode Cédric Le Goater
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-13  5:24 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt, Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

We were initializing unused ones and missing some

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
[clg: fixed checkpatch.pl errors ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target-ppc/cpu.h            | 11 ++++++++++-
 target-ppc/translate_init.c | 27 +++++++++++++++++++++------
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 93c2dd5a65a1..f005549c352e 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -116,6 +116,9 @@ enum {
     POWERPC_EXCP_HYPPRIV  = 41, /* Embedded hypervisor priv instruction      */
     /* Vectors 42 to 63 are reserved                                         */
     /* Exceptions defined in the PowerPC server specification                */
+    /* Server doorbell variants */
+#define POWERPC_EXCP_SDOOR      POWERPC_EXCP_GDOORI
+#define POWERPC_EXCP_SDOOR_HV   POWERPC_EXCP_DOORI
     POWERPC_EXCP_RESET    = 64, /* System reset exception                    */
     POWERPC_EXCP_DSEG     = 65, /* Data segment exception                    */
     POWERPC_EXCP_ISEG     = 66, /* Instruction segment exception             */
@@ -158,8 +161,12 @@ enum {
     /* VSX Unavailable (Power ISA 2.06 and later)                            */
     POWERPC_EXCP_VSXU     = 94, /* VSX Unavailable                           */
     POWERPC_EXCP_FU       = 95, /* Facility Unavailable                      */
+    /* Additional ISA 2.06 and later server exceptions                       */
+    POWERPC_EXCP_HV_EMU   = 96, /* HV emulation assistance                   */
+    POWERPC_EXCP_HV_MAINT = 97, /* HMI                                       */
+    POWERPC_EXCP_HV_FU    = 98, /* Hypervisor Facility unavailable           */
     /* EOL                                                                   */
-    POWERPC_EXCP_NB       = 96,
+    POWERPC_EXCP_NB       = 99,
     /* QEMU exceptions: used internally during code translation              */
     POWERPC_EXCP_STOP         = 0x200, /* stop translation                   */
     POWERPC_EXCP_BRANCH       = 0x201, /* branch instruction                 */
@@ -2196,6 +2203,8 @@ enum {
     PPC_INTERRUPT_CDOORBELL,      /* Critical doorbell interrupt          */
     PPC_INTERRUPT_DOORBELL,       /* Doorbell interrupt                   */
     PPC_INTERRUPT_PERFM,          /* Performance monitor interrupt        */
+    PPC_INTERRUPT_HMI,            /* Hypervisor Maintainance interrupt    */
+    PPC_INTERRUPT_HDOORBELL,      /* Hypervisor Doorbell interrupt        */
 };
 
 /* Processor Compatibility mask (PCR) */
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index edfd91a85425..3b4234b325d1 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -3171,18 +3171,30 @@ static void init_excp_POWER7 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_HDECR]    = 0x00000980;
     env->excp_vectors[POWERPC_EXCP_SYSCALL]  = 0x00000C00;
     env->excp_vectors[POWERPC_EXCP_TRACE]    = 0x00000D00;
+    env->excp_vectors[POWERPC_EXCP_HDSI]     = 0x00000E00;
+    env->excp_vectors[POWERPC_EXCP_HISI]     = 0x00000E20;
+    env->excp_vectors[POWERPC_EXCP_HV_EMU]   = 0x00000E40;
+    env->excp_vectors[POWERPC_EXCP_HV_MAINT] = 0x00000E60;
     env->excp_vectors[POWERPC_EXCP_PERFM]    = 0x00000F00;
     env->excp_vectors[POWERPC_EXCP_VPU]      = 0x00000F20;
     env->excp_vectors[POWERPC_EXCP_VSXU]     = 0x00000F40;
-    env->excp_vectors[POWERPC_EXCP_FU]       = 0x00000F60;
-    env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
-    env->excp_vectors[POWERPC_EXCP_MAINT]    = 0x00001600;
-    env->excp_vectors[POWERPC_EXCP_VPUA]     = 0x00001700;
-    env->excp_vectors[POWERPC_EXCP_THERM]    = 0x00001800;
     /* Hardware reset vector */
     env->hreset_vector = 0x0000000000000100ULL;
 #endif
 }
+
+static void init_excp_POWER8(CPUPPCState *env)
+{
+    init_excp_POWER7(env);
+
+#if !defined(CONFIG_USER_ONLY)
+    env->excp_vectors[POWERPC_EXCP_SDOOR]    = 0x00000A00;
+    env->excp_vectors[POWERPC_EXCP_FU]       = 0x00000F60;
+    env->excp_vectors[POWERPC_EXCP_HV_FU]    = 0x00000F80;
+    env->excp_vectors[POWERPC_EXCP_SDOOR_HV] = 0x00000E80;
+#endif
+}
+
 #endif
 
 /*****************************************************************************/
@@ -8123,10 +8135,13 @@ static void init_proc_book3s_64(CPUPPCState *env, int version)
         ppc970_irq_init(ppc_env_get_cpu(env));
         break;
     case BOOK3S_CPU_POWER7:
-    case BOOK3S_CPU_POWER8:
         init_excp_POWER7(env);
         ppcPOWER7_irq_init(ppc_env_get_cpu(env));
         break;
+    case BOOK3S_CPU_POWER8:
+        init_excp_POWER8(env);
+        ppcPOWER7_irq_init(ppc_env_get_cpu(env));
+        break;
     default:
         g_assert_not_reached();
     }
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 05/10] ppc: Fix generation if ISI/DSI vs. HV mode
  2016-06-13  5:24 [Qemu-devel] [PATCH 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (3 preceding siblings ...)
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 04/10] ppc: Fix POWER7 and POWER8 exception definitions Cédric Le Goater
@ 2016-06-13  5:24 ` Cédric Le Goater
  2016-06-14  6:34   ` David Gibson
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 06/10] ppc: Rework generation of priv and inval interrupts Cédric Le Goater
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-13  5:24 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt, Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Under some circumstances, we need to direct ISI and DSI interrupts
at the hypervisor, turning them into HISI/HDSI, and using different
SPRs (HDSISR and HDAR) depending on the combination of MSR_DR and
the corresponding VPM bits in LPCR.

This moves part of the code into helpers that are fixed to select
the right exception type and registers. On pre-P7 processors, LPCR
is 0 which provides the old behaviour of directing the interrupts
at the supervisor.

Thanks to Andrei Warkentin for finding a bug when HV=1

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 target-ppc/mmu-hash64.c | 69 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 50 insertions(+), 19 deletions(-)

diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 668da5e22653..072a952c8bd5 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -613,6 +613,47 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
     return 0;
 }
 
+static void ppc_hash64_set_isi(CPUState *cs, CPUPPCState *env,
+                               uint64_t error_code)
+{
+    bool vpm;
+
+    if (msr_ir) {
+        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
+    } else {
+        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
+    }
+    if (vpm && !msr_hv) {
+        cs->exception_index = POWERPC_EXCP_HISI;
+    } else {
+        cs->exception_index = POWERPC_EXCP_ISI;
+    }
+    env->error_code = error_code;
+}
+
+static void ppc_hash64_set_dsi(CPUState *cs, CPUPPCState *env, uint64_t dar,
+                               uint64_t dsisr)
+{
+    bool vpm;
+
+    if (msr_dr) {
+        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
+    } else {
+        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
+    }
+    if (vpm && msr_hv) {
+        cs->exception_index = POWERPC_EXCP_HDSI;
+        env->spr[SPR_HDAR] = dar;
+        env->spr[SPR_HDSISR] = dsisr;
+    } else {
+        cs->exception_index = POWERPC_EXCP_DSI;
+        env->spr[SPR_DAR] = dar;
+        env->spr[SPR_DSISR] = dsisr;
+   }
+    env->error_code = 0;
+}
+
+
 int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
                                 int rwx, int mmu_idx)
 {
@@ -623,7 +664,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
     hwaddr pte_offset;
     ppc_hash_pte64_t pte;
     int pp_prot, amr_prot, prot;
-    uint64_t new_pte1;
+    uint64_t new_pte1, dsisr;
     const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
     hwaddr raddr;
 
@@ -657,26 +698,21 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
 
     /* 3. Check for segment level no-execute violation */
     if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
-        cs->exception_index = POWERPC_EXCP_ISI;
-        env->error_code = 0x10000000;
+        ppc_hash64_set_isi(cs, env, 0x10000000);
         return 1;
     }
 
     /* 4. Locate the PTE in the hash table */
     pte_offset = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte);
     if (pte_offset == -1) {
+        dsisr = 0x40000000;
         if (rwx == 2) {
-            cs->exception_index = POWERPC_EXCP_ISI;
-            env->error_code = 0x40000000;
+            ppc_hash64_set_isi(cs, env, dsisr);
         } else {
-            cs->exception_index = POWERPC_EXCP_DSI;
-            env->error_code = 0;
-            env->spr[SPR_DAR] = eaddr;
             if (rwx == 1) {
-                env->spr[SPR_DSISR] = 0x42000000;
-            } else {
-                env->spr[SPR_DSISR] = 0x40000000;
+                dsisr |= 0x02000000;
             }
+            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
         }
         return 1;
     }
@@ -705,14 +741,9 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
         /* Access right violation */
         qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
         if (rwx == 2) {
-            cs->exception_index = POWERPC_EXCP_ISI;
-            env->error_code = 0x08000000;
+            ppc_hash64_set_isi(cs, env, 0x08000000);
         } else {
-            target_ulong dsisr = 0;
-
-            cs->exception_index = POWERPC_EXCP_DSI;
-            env->error_code = 0;
-            env->spr[SPR_DAR] = eaddr;
+            dsisr = 0;
             if (need_prot[rwx] & ~pp_prot) {
                 dsisr |= 0x08000000;
             }
@@ -722,7 +753,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
             if (need_prot[rwx] & ~amr_prot) {
                 dsisr |= 0x00200000;
             }
-            env->spr[SPR_DSISR] = dsisr;
+            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
         }
         return 1;
     }
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 06/10] ppc: Rework generation of priv and inval interrupts
  2016-06-13  5:24 [Qemu-devel] [PATCH 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (4 preceding siblings ...)
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 05/10] ppc: Fix generation if ISI/DSI vs. HV mode Cédric Le Goater
@ 2016-06-13  5:24 ` Cédric Le Goater
  2016-06-15  1:19   ` David Gibson
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 07/10] ppc: Add real mode CI load/store instructions for P7 and P8 Cédric Le Goater
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-13  5:24 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt, Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Recent server processors use the Hypervisor Emulation Assistance
interrupt for illegal instructions and *some* type of SPR accesses.

Also the code was always generating inval instructions even for priv
violations due to setting the wrong flags

Finally, the checking for PR/HV was open coded everywhere.

This reworks it all, using little helper macros for checking, and
adding the HV interrupt (which gets converted back to program check
in the slow path of excp_helper.c on CPUs that don't want it).

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[clg: fixed checkpatch.pl errors ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 linux-user/main.c        |   1 +
 target-ppc/excp_helper.c |  19 ++
 target-ppc/translate.c   | 690 ++++++++++++++++++++---------------------------
 3 files changed, 311 insertions(+), 399 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index f8a8764ae97a..9e9b88b458c4 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1721,6 +1721,7 @@ void cpu_loop(CPUPPCState *env)
             queue_signal(env, info.si_signo, &info);
             break;
         case POWERPC_EXCP_PROGRAM:  /* Program exception                     */
+        case POWERPC_EXCP_HV_EMU:   /* HV emulation                          */
             /* XXX: check this */
             switch (env->error_code & ~0xF) {
             case POWERPC_EXCP_FP:
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 7c44c102db39..054c12de3bff 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -128,6 +128,19 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         ail = 0;
     }
 
+    /* Hypervisor emulation assistance interrupt only exists on server
+     * arch 2.05 server or later. We also don't want to generate it if
+     * we don't have HVB in msr_mask (PAPR mode).
+     */
+    if (excp == POWERPC_EXCP_HV_EMU
+#if defined(TARGET_PPC64)
+        && !((env->mmu_model & POWERPC_MMU_64) && (env->msr_mask & MSR_HVB))
+#endif /* defined(TARGET_PPC64) */
+
+    ) {
+        excp = POWERPC_EXCP_PROGRAM;
+    }
+
     switch (excp) {
     case POWERPC_EXCP_NONE:
         /* Should never happen */
@@ -249,6 +262,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             break;
         }
         goto store_current;
+    case POWERPC_EXCP_HV_EMU:
+        srr0 = SPR_HSRR0;
+        srr1 = SPR_HSRR1;
+        new_msr |= (target_ulong)MSR_HVB;
+        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
+        goto store_current;
     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
         goto store_current;
     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index a02ddf52bfe6..2ec858063ecc 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -325,7 +325,19 @@ static inline void gen_debug_exception(DisasContext *ctx)
 
 static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
 {
-    gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
+    /* Will be converted to program check if needed */
+    gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_INVAL | error);
+}
+
+static inline void gen_priv_exception(DisasContext *ctx, uint32_t error)
+{
+    gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_PRIV | error);
+}
+
+static inline void gen_hvpriv_exception(DisasContext *ctx, uint32_t error)
+{
+    /* Will be converted to program check if needed */
+    gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_PRIV | error);
 }
 
 /* Stop translation */
@@ -366,6 +378,33 @@ typedef struct opcode_t {
     const char *oname;
 } opcode_t;
 
+/* Helpers for priv. check */
+#define GEN_PRIV                                                \
+    do {                                                        \
+        gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; \
+    } while (0)
+
+#if defined(CONFIG_USER_ONLY)
+#define CHK_HV GEN_PRIV
+#define CHK_SV GEN_PRIV
+#else
+#define CHK_HV                                                          \
+    do {                                                                \
+        if (unlikely(ctx->pr || !ctx->hv)) {                            \
+            GEN_PRIV;                                                   \
+        }                                                               \
+    } while (0)
+#define CHK_SV                   \
+    do {                         \
+        if (unlikely(ctx->pr)) { \
+            GEN_PRIV;            \
+        }                        \
+    } while (0)
+#endif
+
+#define CHK_NONE
+
+
 /*****************************************************************************/
 /***                           Instruction decoding                        ***/
 #define EXTRACT_HELPER(name, shift, nb)                                       \
@@ -2929,7 +2968,7 @@ static void gen_lq(DisasContext *ctx)
     bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
 
     if (!legal_in_user_mode && ctx->pr) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
         return;
     }
 
@@ -3055,7 +3094,7 @@ static void gen_std(DisasContext *ctx)
         }
 
         if (!legal_in_user_mode && ctx->pr) {
-            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
             return;
         }
 
@@ -4085,7 +4124,7 @@ static void gen_mcrf(DisasContext *ctx)
 static void gen_rfi(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     /* This instruction doesn't exist anymore on 64-bit server
      * processors compliant with arch 2.x
@@ -4095,10 +4134,7 @@ static void gen_rfi(DisasContext *ctx)
         return;
     }
     /* Restore CPU state */
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_update_cfar(ctx, ctx->nip);
     gen_helper_rfi(cpu_env);
     gen_sync_exception(ctx);
@@ -4109,13 +4145,10 @@ static void gen_rfi(DisasContext *ctx)
 static void gen_rfid(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     /* Restore CPU state */
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_update_cfar(ctx, ctx->nip);
     gen_helper_rfid(cpu_env);
     gen_sync_exception(ctx);
@@ -4125,13 +4158,10 @@ static void gen_rfid(DisasContext *ctx)
 static void gen_hrfid(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     /* Restore CPU state */
-    if (unlikely(ctx->pr || !ctx->hv)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_HV;
     gen_helper_hrfid(cpu_env);
     gen_sync_exception(ctx);
 #endif
@@ -4294,15 +4324,8 @@ static void gen_mfcr(DisasContext *ctx)
 /* mfmsr */
 static void gen_mfmsr(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-#else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
-#endif
 }
 
 static void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
@@ -4348,9 +4371,15 @@ static inline void gen_op_mfspr(DisasContext *ctx)
                              TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
                 }
             }
-            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
         }
     } else {
+        /* ISA 2.07 defines these as no-ops */
+        if ((ctx->insns_flags2 & PPC2_ISA207S) &&
+            (sprn >= 808 && sprn <= 811)) {
+            /* This is a nop */
+            return;
+        }
         /* Not defined */
         fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at "
                 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
@@ -4358,9 +4387,18 @@ static inline void gen_op_mfspr(DisasContext *ctx)
             qemu_log("Trying to read invalid spr %d (0x%03x) at "
                      TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
         }
-        /* Only generate an exception in user space, otherwise this is a nop */
-        if (ctx->pr) {
-            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+
+        /* The behaviour depends on MSR:PR and SPR# bit 0x10,
+         * it can generate a priv, a hv emu or a no-op
+         */
+        if (sprn & 0x10) {
+            if (ctx->pr) {
+                gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+            }
+        } else {
+            if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) {
+                gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+            }
         }
     }
 }
@@ -4408,13 +4446,9 @@ static void gen_mtcrf(DisasContext *ctx)
 #if defined(TARGET_PPC64)
 static void gen_mtmsrd(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-#else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
+
+#if !defined(CONFIG_USER_ONLY)
     if (ctx->opcode & 0x00010000) {
         /* Special form that does not need any synchronisation */
         TCGv t0 = tcg_temp_new();
@@ -4433,20 +4467,16 @@ static void gen_mtmsrd(DisasContext *ctx)
         /* Note that mtmsr is not always defined as context-synchronizing */
         gen_stop_exception(ctx);
     }
-#endif
+#endif /* !defined(CONFIG_USER_ONLY) */
 }
-#endif
+#endif /* defined(TARGET_PPC64) */
 
 static void gen_mtmsr(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-#else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
-    if (ctx->opcode & 0x00010000) {
+    CHK_SV;
+
+#if !defined(CONFIG_USER_ONLY)
+   if (ctx->opcode & 0x00010000) {
         /* Special form that does not need any synchronisation */
         TCGv t0 = tcg_temp_new();
         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
@@ -4503,9 +4533,16 @@ static void gen_mtspr(DisasContext *ctx)
                 qemu_log("Trying to write privileged spr %d (0x%03x) at "
                          TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
             }
-            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
         }
     } else {
+        /* ISA 2.07 defines these as no-ops */
+        if ((ctx->insns_flags2 & PPC2_ISA207S) &&
+            (sprn >= 808 && sprn <= 811)) {
+            /* This is a nop */
+            return;
+        }
+
         /* Not defined */
         if (qemu_log_separate()) {
             qemu_log("Trying to write invalid spr %d (0x%03x) at "
@@ -4514,9 +4551,18 @@ static void gen_mtspr(DisasContext *ctx)
         fprintf(stderr, "Trying to write invalid spr %d (0x%03x) at "
                 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
 
-        /* Only generate an exception in user space, otherwise this is a nop */
-        if (ctx->pr) {
-            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+
+        /* The behaviour depends on MSR:PR and SPR# bit 0x10,
+         * it can generate a priv, a hv emu or a no-op
+         */
+        if (sprn & 0x10) {
+            if (ctx->pr) {
+                gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+            }
+        } else {
+            if (ctx->pr || sprn == 0) {
+                gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
+            }
         }
     }
 }
@@ -4539,13 +4585,11 @@ static void gen_dcbf(DisasContext *ctx)
 static void gen_dcbi(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv EA, val;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     EA = tcg_temp_new();
     gen_set_access_type(ctx, ACCESS_CACHE);
     gen_addr_reg_index(ctx, EA);
@@ -4555,7 +4599,7 @@ static void gen_dcbi(DisasContext *ctx)
     gen_qemu_st8(ctx, val, EA);
     tcg_temp_free(val);
     tcg_temp_free(EA);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* dcdst */
@@ -4676,72 +4720,64 @@ static void gen_dcba(DisasContext *ctx)
 static void gen_mfsr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_const_tl(SR(ctx->opcode));
     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mfsrin */
 static void gen_mfsrin(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mtsr */
 static void gen_mtsr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_const_tl(SR(ctx->opcode));
     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mtsrin */
 static void gen_mtsrin(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
+
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rD(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 #if defined(TARGET_PPC64)
@@ -4751,115 +4787,101 @@ static void gen_mtsrin(DisasContext *ctx)
 static void gen_mfsr_64b(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_const_tl(SR(ctx->opcode));
     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mfsrin */
 static void gen_mfsrin_64b(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mtsr */
 static void gen_mtsr_64b(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_const_tl(SR(ctx->opcode));
     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mtsrin */
 static void gen_mtsrin_64b(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* slbmte */
 static void gen_slbmte(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)],
                          cpu_gpr[rS(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_slbmfee(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,
                              cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_slbmfev(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
                              cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_slbfee_(DisasContext *ctx)
@@ -4895,40 +4917,34 @@ static void gen_slbfee_(DisasContext *ctx)
 static void gen_tlbia(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr || !ctx->hv)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_HV;
+
     gen_helper_tlbia(cpu_env);
-#endif
+#endif  /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbiel */
 static void gen_tlbiel(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbie */
 static void gen_tlbie(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr || !ctx->hv)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_HV;
+
     if (NARROW_MODE(ctx)) {
         TCGv t0 = tcg_temp_new();
         tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
@@ -4937,25 +4953,23 @@ static void gen_tlbie(DisasContext *ctx)
     } else {
         gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbsync */
 static void gen_tlbsync(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr || !ctx->hv)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_HV;
+
     /* tlbsync is a nop for server, ptesync handles delayed tlb flush,
      * embedded however needs to deal with tlbsync. We don't try to be
      * fancy and swallow the overhead of checking for both.
      */
     gen_check_tlb_flush(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 #if defined(TARGET_PPC64)
@@ -4963,30 +4977,26 @@ static void gen_tlbsync(DisasContext *ctx)
 static void gen_slbia(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_slbia(cpu_env);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* slbie */
 static void gen_slbie(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
-#endif
+#endif  /* defined(TARGET_PPC64) */
 
 /***                              External control                         ***/
 /* Optional: */
@@ -5685,14 +5695,11 @@ static void gen_esa(DisasContext *ctx)
 static void gen_mfrom(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* 602 - 603 - G2 TLB management */
@@ -5701,28 +5708,22 @@ static void gen_mfrom(DisasContext *ctx)
 static void gen_tlbld_6xx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbli */
 static void gen_tlbli_6xx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* 74xx TLB management */
@@ -5731,28 +5732,22 @@ static void gen_tlbli_6xx(DisasContext *ctx)
 static void gen_tlbld_74xx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_helper_74xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbli */
 static void gen_tlbli_74xx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_helper_74xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* POWER instructions not in PowerPC 601 */
@@ -5766,15 +5761,12 @@ static void gen_clf(DisasContext *ctx)
 /* cli */
 static void gen_cli(DisasContext *ctx)
 {
-    /* Cache line invalidate: privileged and treated as no-op */
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
-#endif
+    /* Cache line invalidate: privileged and treated as no-op */
+    CHK_SV;
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* dclst */
@@ -5786,15 +5778,13 @@ static void gen_dclst(DisasContext *ctx)
 static void gen_mfsri(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     int ra = rA(ctx->opcode);
     int rd = rD(ctx->opcode);
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     tcg_gen_shri_tl(t0, t0, 28);
@@ -5803,38 +5793,34 @@ static void gen_mfsri(DisasContext *ctx)
     tcg_temp_free(t0);
     if (ra != 0 && ra != rd)
         tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_rac(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     gen_helper_rac(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_rfsvc(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
+
     gen_helper_rfsvc(cpu_env);
     gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* svc is not implemented for now */
@@ -5987,18 +5973,16 @@ static void gen_mfapidi(DisasContext *ctx)
 static void gen_tlbiva(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* All 405 MAC instructions are translated here */
@@ -6220,38 +6204,34 @@ GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
 static void gen_mfdcr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv dcrn;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     dcrn = tcg_const_tl(SPR(ctx->opcode));
     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn);
     tcg_temp_free(dcrn);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mtdcr */
 static void gen_mtdcr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
     TCGv dcrn;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+
+    CHK_SV;
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     dcrn = tcg_const_tl(SPR(ctx->opcode));
     gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(dcrn);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mfdcrx */
@@ -6259,18 +6239,15 @@ static void gen_mtdcr(DisasContext *ctx)
 static void gen_mfdcrx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
                         cpu_gpr[rA(ctx->opcode)]);
     /* Note: Rc update flag set leads to undefined state of Rc0 */
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mtdcrx */
@@ -6278,18 +6255,15 @@ static void gen_mfdcrx(DisasContext *ctx)
 static void gen_mtdcrx(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-        return;
-    }
+    CHK_SV;
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
                          cpu_gpr[rS(ctx->opcode)]);
     /* Note: Rc update flag set leads to undefined state of Rc0 */
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* mfdcrux (PPC 460) : user-mode access to DCR */
@@ -6315,28 +6289,19 @@ static void gen_mtdcrux(DisasContext *ctx)
 /* dccci */
 static void gen_dccci(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-#else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* interpreted as no-op */
-#endif
 }
 
 /* dcread */
 static void gen_dcread(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv EA, val;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     gen_set_access_type(ctx, ACCESS_CACHE);
     EA = tcg_temp_new();
     gen_addr_reg_index(ctx, EA);
@@ -6345,7 +6310,7 @@ static void gen_dcread(DisasContext *ctx)
     tcg_temp_free(val);
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
     tcg_temp_free(EA);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* icbt */
@@ -6360,60 +6325,40 @@ static void gen_icbt_40x(DisasContext *ctx)
 /* iccci */
 static void gen_iccci(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-#else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* interpreted as no-op */
-#endif
 }
 
 /* icread */
 static void gen_icread(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-#else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* interpreted as no-op */
-#endif
 }
 
 /* rfci (supervisor only) */
 static void gen_rfci_40x(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* Restore CPU state */
     gen_helper_40x_rfci(cpu_env);
     gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_rfci(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* Restore CPU state */
     gen_helper_rfci(cpu_env);
     gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* BookE specific */
@@ -6422,32 +6367,26 @@ static void gen_rfci(DisasContext *ctx)
 static void gen_rfdi(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* Restore CPU state */
     gen_helper_rfdi(cpu_env);
     gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* XXX: not implemented on 440 ? */
 static void gen_rfmci(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     /* Restore CPU state */
     gen_helper_rfmci(cpu_env);
     gen_sync_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* TLB management - PowerPC 405 implementation */
@@ -6456,12 +6395,9 @@ static void gen_rfmci(DisasContext *ctx)
 static void gen_tlbre_40x(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     switch (rB(ctx->opcode)) {
     case 0:
         gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env,
@@ -6475,20 +6411,18 @@ static void gen_tlbre_40x(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         break;
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbsx - tlbsx. */
 static void gen_tlbsx_40x(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
@@ -6500,19 +6434,17 @@ static void gen_tlbsx_40x(DisasContext *ctx)
         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
         gen_set_label(l1);
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbwe */
 static void gen_tlbwe_40x(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
+
     switch (rB(ctx->opcode)) {
     case 0:
         gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)],
@@ -6526,7 +6458,7 @@ static void gen_tlbwe_40x(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         break;
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* TLB management - PowerPC 440 implementation */
@@ -6535,12 +6467,10 @@ static void gen_tlbwe_40x(DisasContext *ctx)
 static void gen_tlbre_440(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
+
     switch (rB(ctx->opcode)) {
     case 0:
     case 1:
@@ -6556,20 +6486,18 @@ static void gen_tlbre_440(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         break;
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbsx - tlbsx. */
 static void gen_tlbsx_440(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
     gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
@@ -6581,19 +6509,16 @@ static void gen_tlbsx_440(DisasContext *ctx)
         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
         gen_set_label(l1);
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbwe */
 static void gen_tlbwe_440(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     switch (rB(ctx->opcode)) {
     case 0:
     case 1:
@@ -6609,7 +6534,7 @@ static void gen_tlbwe_440(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         break;
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* TLB management - PowerPC BookE 2.06 implementation */
@@ -6617,30 +6542,23 @@ static void gen_tlbwe_440(DisasContext *ctx)
 /* tlbre */
 static void gen_tlbre_booke206(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+ #if defined(CONFIG_USER_ONLY)
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
-
+   CHK_SV;
     gen_helper_booke206_tlbre(cpu_env);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbsx - tlbsx. */
 static void gen_tlbsx_booke206(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
 
+    CHK_SV;
     if (rA(ctx->opcode)) {
         t0 = tcg_temp_new();
         tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
@@ -6651,54 +6569,44 @@ static void gen_tlbsx_booke206(DisasContext *ctx)
     tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
     gen_helper_booke206_tlbsx(cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* tlbwe */
 static void gen_tlbwe_booke206(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     gen_update_nip(ctx, ctx->nip - 4);
     gen_helper_booke206_tlbwe(cpu_env);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_tlbivax_booke206(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
 
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
-
     gen_helper_booke206_tlbivax(cpu_env, t0);
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_tlbilx_booke206(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
 
+    CHK_SV;
     t0 = tcg_temp_new();
     gen_addr_reg_index(ctx, t0);
 
@@ -6718,7 +6626,7 @@ static void gen_tlbilx_booke206(DisasContext *ctx)
     }
 
     tcg_temp_free(t0);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 
@@ -6726,13 +6634,11 @@ static void gen_tlbilx_booke206(DisasContext *ctx)
 static void gen_wrtee(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
     TCGv t0;
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+
+    CHK_SV;
     t0 = tcg_temp_new();
     tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
     tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
@@ -6742,19 +6648,16 @@ static void gen_wrtee(DisasContext *ctx)
      * if we just set msr_ee to 1
      */
     gen_stop_exception(ctx);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* wrteei */
 static void gen_wrteei(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
+    CHK_SV;
     if (ctx->opcode & 0x00008000) {
         tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
         /* Stop translation to have a chance to raise an exception */
@@ -6762,7 +6665,7 @@ static void gen_wrteei(DisasContext *ctx)
     } else {
         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
     }
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /* PowerPC 440 specific instructions */
@@ -6802,29 +6705,21 @@ static void gen_icbt_440(DisasContext *ctx)
 static void gen_msgclr(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
-
+    CHK_SV;
     gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 static void gen_msgsnd(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    GEN_PRIV;
 #else
-    if (unlikely(ctx->pr)) {
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-        return;
-    }
-
+    CHK_SV;
     gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
-#endif
+#endif /* defined(CONFIG_USER_ONLY) */
 }
 
 /***                      Altivec vector extension                         ***/
@@ -9826,7 +9721,7 @@ static void gen_tcheck(DisasContext *ctx)
 #define GEN_TM_PRIV_NOOP(name)                                 \
 static inline void gen_##name(DisasContext *ctx)               \
 {                                                              \
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);           \
+    gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);           \
 }
 
 #else
@@ -9834,10 +9729,7 @@ static inline void gen_##name(DisasContext *ctx)               \
 #define GEN_TM_PRIV_NOOP(name)                                 \
 static inline void gen_##name(DisasContext *ctx)               \
 {                                                              \
-    if (unlikely(ctx->pr)) {                                   \
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);       \
-        return;                                                \
-    }                                                          \
+    CHK_SV;                                                    \
     if (unlikely(!ctx->tm_enabled)) {                          \
         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);   \
         return;                                                \
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 07/10] ppc: Add real mode CI load/store instructions for P7 and P8
  2016-06-13  5:24 [Qemu-devel] [PATCH 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (5 preceding siblings ...)
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 06/10] ppc: Rework generation of priv and inval interrupts Cédric Le Goater
@ 2016-06-13  5:24 ` Cédric Le Goater
  2016-06-15  3:46   ` David Gibson
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 08/10] ppc: Turn a bunch of booleans from int to bool Cédric Le Goater
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-13  5:24 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt, Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Those instructions are only available in hypervisor real mode and
allow cache inhibited garded access to devices in that mode.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[clg: fixed checkpatch.pl errors ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---

This patch still has a couple of checkpatch issues which I did not
know quite understand:

ERROR: Macros with complex values should be enclosed in parenthesis
#176: FILE: target-ppc/translate.c:10238:
+#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),

ERROR: Macros with complex values should be enclosed in parenthesis
#200: FILE: target-ppc/translate.c:10277:
+#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),

total: 2 errors, 0 warnings, 196 lines checked


 target-ppc/cpu.h            |  4 ++-
 target-ppc/translate.c      | 59 ++++++++++++++++++++++++++++++++++++---------
 target-ppc/translate_init.c |  6 +++--
 3 files changed, 55 insertions(+), 14 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index f005549c352e..61a24b19ffce 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1912,6 +1912,8 @@ enum {
     PPC_POPCNTB        = 0x0000000000001000ULL,
     /*   string load / store                                                 */
     PPC_STRING         = 0x0000000000002000ULL,
+    /*   real mode cache inhibited load / store                              */
+    PPC_CILDST         = 0x0000000000004000ULL,
 
     /* Floating-point unit extensions                                        */
     /*   Optional floating point instructions                                */
@@ -2026,7 +2028,7 @@ enum {
                         | PPC_MFAPIDI | PPC_TLBIVA | PPC_TLBIVAX \
                         | PPC_4xx_COMMON | PPC_40x_ICBT | PPC_RFMCI \
                         | PPC_RFDI | PPC_DCR | PPC_DCRX | PPC_DCRUX \
-                        | PPC_POPCNTWD)
+                        | PPC_POPCNTWD | PPC_CILDST)
 
     /* extended type values */
 
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 2ec858063ecc..b594b18399f7 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -192,7 +192,7 @@ struct DisasContext {
     uint32_t opcode;
     uint32_t exception;
     /* Routine used to access memory */
-    bool pr, hv;
+    bool pr, hv, dr;
     bool lazy_tlb_flush;
     int mem_idx;
     int access_type;
@@ -387,6 +387,7 @@ typedef struct opcode_t {
 #if defined(CONFIG_USER_ONLY)
 #define CHK_HV GEN_PRIV
 #define CHK_SV GEN_PRIV
+#define CHK_HVRM GEN_PRIV
 #else
 #define CHK_HV                                                          \
     do {                                                                \
@@ -400,6 +401,12 @@ typedef struct opcode_t {
             GEN_PRIV;            \
         }                        \
     } while (0)
+#define CHK_HVRM                                            \
+    do {                                                    \
+        if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) {     \
+            GEN_PRIV;                                       \
+        }                                                   \
+    } while (0)
 #endif
 
 #define CHK_NONE
@@ -2895,18 +2902,23 @@ static void glue(gen_, name##ux)(DisasContext *ctx)
     tcg_temp_free(EA);                                                        \
 }
 
-#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
+#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
 static void glue(gen_, name##x)(DisasContext *ctx)                            \
 {                                                                             \
     TCGv EA;                                                                  \
+    chk;                                                                      \
     gen_set_access_type(ctx, ACCESS_INT);                                     \
     EA = tcg_temp_new();                                                      \
     gen_addr_reg_index(ctx, EA);                                              \
     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
     tcg_temp_free(EA);                                                        \
 }
+
 #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
-    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE)
+    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_NONE)
+
+#define GEN_LDX_HVRM(name, ldop, opc2, opc3, type)                            \
+    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
 
 #define GEN_LDS(name, ldop, op, type)                                         \
 GEN_LD(name, ldop, op | 0x20, type);                                          \
@@ -2932,6 +2944,12 @@ GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B);
 /* ldx */
 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
 
+/* CI load/store variants */
+GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST)
+GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST)
+GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
+GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
+
 static void gen_ld(DisasContext *ctx)
 {
     TCGv EA;
@@ -3050,10 +3068,11 @@ static void glue(gen_, name##ux)(DisasContext *ctx)
     tcg_temp_free(EA);                                                        \
 }
 
-#define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
+#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
 static void glue(gen_, name##x)(DisasContext *ctx)                            \
 {                                                                             \
     TCGv EA;                                                                  \
+    chk;                                                                      \
     gen_set_access_type(ctx, ACCESS_INT);                                     \
     EA = tcg_temp_new();                                                      \
     gen_addr_reg_index(ctx, EA);                                              \
@@ -3061,7 +3080,10 @@ static void glue(gen_, name##x)(DisasContext *ctx)                            \
     tcg_temp_free(EA);                                                        \
 }
 #define GEN_STX(name, stop, opc2, opc3, type)                                 \
-    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE)
+    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_NONE)
+
+#define GEN_STX_HVRM(name, stop, opc2, opc3, type)                            \
+    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
 
 #define GEN_STS(name, stop, op, type)                                         \
 GEN_ST(name, stop, op | 0x20, type);                                          \
@@ -3078,6 +3100,10 @@ GEN_STS(stw, st32, 0x04, PPC_INTEGER);
 #if defined(TARGET_PPC64)
 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
 GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
+GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST)
+GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
+GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
+GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
 
 static void gen_std(DisasContext *ctx)
 {
@@ -3166,7 +3192,7 @@ static inline void gen_qemu_ld64ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
     TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
     tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, op);
 }
-GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX);
+GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE);
 #endif  /* TARGET_PPC64 */
 
 /* sthbrx */
@@ -3192,7 +3218,7 @@ static inline void gen_qemu_st64r(DisasContext *ctx, TCGv arg1, TCGv arg2)
     TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
     tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, op);
 }
-GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX);
+GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE);
 #endif  /* TARGET_PPC64 */
 
 /***                    Integer load and store multiple                    ***/
@@ -10209,7 +10235,7 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
 #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
-#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
+#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
 #define GEN_LDS(name, ldop, op, type)                                         \
 GEN_LD(name, ldop, op | 0x20, type)                                           \
@@ -10226,7 +10252,13 @@ GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
 GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
-GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX)
+GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE)
+
+/* HV/P7 and later only */
+GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST)
+GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x18, PPC_CILDST)
+GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
+GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
 #endif
 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
@@ -10242,7 +10274,7 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
 GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
 #define GEN_STUX(name, stop, opc2, opc3, type)                                \
 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
-#define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
+#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
 #define GEN_STS(name, stop, op, type)                                         \
 GEN_ST(name, stop, op | 0x20, type)                                           \
@@ -10256,7 +10288,11 @@ GEN_STS(stw, st32, 0x04, PPC_INTEGER)
 #if defined(TARGET_PPC64)
 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
 GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
-GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX)
+GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE)
+GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST)
+GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
+GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
+GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
 #endif
 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
@@ -11424,6 +11460,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
     ctx.spr_cb = env->spr_cb;
     ctx.pr = msr_pr;
     ctx.mem_idx = env->dmmu_idx;
+    ctx.dr = msr_dr;
 #if !defined(CONFIG_USER_ONLY)
     ctx.hv = msr_hv || !env->has_hv_mode;
 #endif
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 3b4234b325d1..6f2f760728bb 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8395,7 +8395,8 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
-                       PPC_POPCNTB | PPC_POPCNTWD;
+                       PPC_POPCNTB | PPC_POPCNTWD |
+                       PPC_CILDST;
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
                         PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
@@ -8476,7 +8477,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
-                       PPC_POPCNTB | PPC_POPCNTWD;
+                       PPC_POPCNTB | PPC_POPCNTWD |
+                       PPC_CILDST;
     pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
                         PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 08/10] ppc: Turn a bunch of booleans from int to bool
  2016-06-13  5:24 [Qemu-devel] [PATCH 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (6 preceding siblings ...)
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 07/10] ppc: Add real mode CI load/store instructions for P7 and P8 Cédric Le Goater
@ 2016-06-13  5:24 ` Cédric Le Goater
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 09/10] ppc: Move exception generation code out of line Cédric Le Goater
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 10/10] ppc: Add P7/P8 Power Management instructions Cédric Le Goater
  9 siblings, 0 replies; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-13  5:24 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt, Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 target-ppc/translate.c | 37 ++++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index b594b18399f7..f211d175c09c 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -192,22 +192,21 @@ struct DisasContext {
     uint32_t opcode;
     uint32_t exception;
     /* Routine used to access memory */
-    bool pr, hv, dr;
+    bool pr, hv, dr, le_mode;
     bool lazy_tlb_flush;
     int mem_idx;
     int access_type;
     /* Translation flags */
-    int le_mode;
     TCGMemOp default_tcg_memop_mask;
 #if defined(TARGET_PPC64)
-    int sf_mode;
-    int has_cfar;
+    bool sf_mode;
+    bool has_cfar;
 #endif
-    int fpu_enabled;
-    int altivec_enabled;
-    int vsx_enabled;
-    int spe_enabled;
-    int tm_enabled;
+    bool fpu_enabled;
+    bool altivec_enabled;
+    bool vsx_enabled;
+    bool spe_enabled;
+    bool tm_enabled;
     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
     int singlestep_enabled;
     uint64_t insns_flags;
@@ -11467,7 +11466,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
     ctx.insns_flags = env->insns_flags;
     ctx.insns_flags2 = env->insns_flags2;
     ctx.access_type = -1;
-    ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
+    ctx.le_mode = !!(env->hflags & (1 << MSR_LE));
     ctx.default_tcg_memop_mask = ctx.le_mode ? MO_LE : MO_BE;
 #if defined(TARGET_PPC64)
     ctx.sf_mode = msr_is_64bit(env, env->msr);
@@ -11478,25 +11477,25 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
         (env->mmu_model & POWERPC_MMU_64B))
             ctx.lazy_tlb_flush = true;
 
-    ctx.fpu_enabled = msr_fp;
+    ctx.fpu_enabled = !!msr_fp;
     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
-        ctx.spe_enabled = msr_spe;
+        ctx.spe_enabled = !!msr_spe;
     else
-        ctx.spe_enabled = 0;
+        ctx.spe_enabled = false;
     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
-        ctx.altivec_enabled = msr_vr;
+        ctx.altivec_enabled = !!msr_vr;
     else
-        ctx.altivec_enabled = 0;
+        ctx.altivec_enabled = false;
     if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) {
-        ctx.vsx_enabled = msr_vsx;
+        ctx.vsx_enabled = !!msr_vsx;
     } else {
-        ctx.vsx_enabled = 0;
+        ctx.vsx_enabled = false;
     }
 #if defined(TARGET_PPC64)
     if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
-        ctx.tm_enabled = msr_tm;
+        ctx.tm_enabled = !!msr_tm;
     } else {
-        ctx.tm_enabled = 0;
+        ctx.tm_enabled = false;
     }
 #endif
     if ((env->flags & POWERPC_FLAG_SE) && msr_se)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 09/10] ppc: Move exception generation code out of line
  2016-06-13  5:24 [Qemu-devel] [PATCH 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (7 preceding siblings ...)
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 08/10] ppc: Turn a bunch of booleans from int to bool Cédric Le Goater
@ 2016-06-13  5:24 ` Cédric Le Goater
  2016-06-13  7:44   ` Thomas Huth
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 10/10] ppc: Add P7/P8 Power Management instructions Cédric Le Goater
  9 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-13  5:24 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt, Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

There's no point inlining this, if you hit the exception case you exit
anyway, and not inlining saves about 100K of code size (and cache
footprint).

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 target-ppc/translate.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index f211d175c09c..600d5db2bb9a 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -283,7 +283,8 @@ void gen_update_current_nip(void *opaque)
     tcg_gen_movi_tl(cpu_nip, ctx->nip);
 }
 
-static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
+static void __attribute__((noinline))
+gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
 {
     TCGv_i32 t0, t1;
     if (ctx->exception == POWERPC_EXCP_NONE) {
@@ -297,7 +298,8 @@ static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t
     ctx->exception = (excp);
 }
 
-static inline void gen_exception(DisasContext *ctx, uint32_t excp)
+static void __attribute__((noinline))
+gen_exception(DisasContext *ctx, uint32_t excp)
 {
     TCGv_i32 t0;
     if (ctx->exception == POWERPC_EXCP_NONE) {
@@ -309,7 +311,8 @@ static inline void gen_exception(DisasContext *ctx, uint32_t excp)
     ctx->exception = (excp);
 }
 
-static inline void gen_debug_exception(DisasContext *ctx)
+static void __attribute__((noinline))
+gen_debug_exception(DisasContext *ctx)
 {
     TCGv_i32 t0;
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [Qemu-devel] [PATCH 10/10] ppc: Add P7/P8 Power Management instructions
  2016-06-13  5:24 [Qemu-devel] [PATCH 00/10] rework exception model to support the HV mode Cédric Le Goater
                   ` (8 preceding siblings ...)
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 09/10] ppc: Move exception generation code out of line Cédric Le Goater
@ 2016-06-13  5:24 ` Cédric Le Goater
  2016-06-15  1:56   ` David Gibson
  9 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-13  5:24 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt, Cedric Le Goater

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

This adds the ISA 2.06 and later power management instructions
(doze, nap, sleep and rvwinkle) and associated wakeup cause testing
in LPCR

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[clg: fixed checkpatch.pl errors ]
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target-ppc/cpu-qom.h        |  9 +++++
 target-ppc/cpu.h            | 17 ++++++++-
 target-ppc/excp_helper.c    | 59 +++++++++++++++++++++++++++++
 target-ppc/helper.h         |  1 +
 target-ppc/translate.c      | 66 ++++++++++++++++++++++++++++++++
 target-ppc/translate_init.c | 92 ++++++++++++++++++++++++++++++++++++++++++++-
 6 files changed, 241 insertions(+), 3 deletions(-)

diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 969ecdfbd40a..0fad2def0a94 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -126,6 +126,15 @@ enum powerpc_excp_t {
 };
 
 /*****************************************************************************/
+/* PM instructions */
+typedef enum {
+    PPC_PM_DOZE,
+    PPC_PM_NAP,
+    PPC_PM_SLEEP,
+    PPC_PM_RVWINKLE,
+} powerpc_pm_insn_t;
+
+/*****************************************************************************/
 /* Input pins model                                                          */
 typedef enum powerpc_input_t powerpc_input_t;
 enum powerpc_input_t {
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 61a24b19ffce..b1354a4791db 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -383,6 +383,14 @@ struct ppc_slb_t {
 #define LPCR_LPES1        (1ull << (63 - 61))
 #define LPCR_AIL_SHIFT    (63 - 40)      /* Alternate interrupt location */
 #define LPCR_AIL          (3ull << LPCR_AIL_SHIFT)
+#define LPCR_P7_PECE0     (1ull << (63 - 49))
+#define LPCR_P7_PECE1     (1ull << (63 - 50))
+#define LPCR_P7_PECE2     (1ull << (63 - 51))
+#define LPCR_P8_PECE0     (1ull << (63 - 47))
+#define LPCR_P8_PECE1     (1ull << (63 - 48))
+#define LPCR_P8_PECE2     (1ull << (63 - 49))
+#define LPCR_P8_PECE3     (1ull << (63 - 50))
+#define LPCR_P8_PECE4     (1ull << (63 - 51))
 
 #define msr_sf   ((env->msr >> MSR_SF)   & 1)
 #define msr_isf  ((env->msr >> MSR_ISF)  & 1)
@@ -1059,6 +1067,11 @@ struct CPUPPCState {
      * instructions and SPRs are diallowed if MSR:HV is 0
      */
     bool has_hv_mode;
+    /* On P7/P8, set when in PM state, we need to handle resume
+     * in a special way (such as routing some resume causes to
+     * 0x100), so flag this here.
+     */
+    bool in_pm_state;
 #endif
 
     /* Those resources are used only during code translation */
@@ -2068,6 +2081,8 @@ enum {
     PPC2_FP_CVT_S64    = 0x0000000000010000ULL,
     /* Transactional Memory (ISA 2.07, Book II)                              */
     PPC2_TM            = 0x0000000000020000ULL,
+    /* Server PM instructgions (ISA 2.06, Book III)                          */
+    PPC2_PM_ISA206     = 0x0000000000040000ULL,
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
                         PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
@@ -2075,7 +2090,7 @@ enum {
                         PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | \
                         PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | \
                         PPC2_ALTIVEC_207 | PPC2_ISA207S | PPC2_DFP | \
-                        PPC2_FP_CVT_S64 | PPC2_TM)
+                        PPC2_FP_CVT_S64 | PPC2_TM | PPC2_PM_ISA206)
 };
 
 /*****************************************************************************/
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 054c12de3bff..533866b87b60 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -101,6 +101,44 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     asrr0 = -1;
     asrr1 = -1;
 
+    /* check for special resume at 0x100 from doze/nap/sleep/winkle on P7/P8 */
+    if (env->in_pm_state) {
+        env->in_pm_state = false;
+
+        /* Pretend to be returning from doze always as we don't lose state */
+        msr |= (0x1ull << (63 - 47));
+
+        /* Non-machine check are routed to 0x100 with a wakeup cause
+         * encoded in SRR1
+         */
+        if (excp != POWERPC_EXCP_MCHECK) {
+            switch (excp) {
+            case POWERPC_EXCP_RESET:
+                msr |= 0x4ull << (63 - 45);
+                break;
+            case POWERPC_EXCP_EXTERNAL:
+                msr |= 0x8ull << (63 - 45);
+                break;
+            case POWERPC_EXCP_DECR:
+                msr |= 0x6ull << (63 - 45);
+                break;
+            case POWERPC_EXCP_SDOOR:
+                msr |= 0x5ull << (63 - 45);
+                break;
+            case POWERPC_EXCP_SDOOR_HV:
+                msr |= 0x3ull << (63 - 45);
+                break;
+            case POWERPC_EXCP_HV_MAINT:
+                msr |= 0xaull << (63 - 45);
+                break;
+            default:
+                cpu_abort(cs, "Unsupported exception %d in Power Save mode\n",
+                          excp);
+            }
+            excp = POWERPC_EXCP_RESET;
+        }
+    }
+
     /* Exception targetting modifiers
      *
      * LPES0 is supported on POWER7/8
@@ -897,6 +935,27 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
     }
 }
 
+#if defined(TARGET_PPC64)
+void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn)
+{
+    CPUState *cs;
+
+    cs = CPU(ppc_env_get_cpu(env));
+    cs->halted = 1;
+    env->in_pm_state = true;
+
+    /* Technically, nap doesn't set EE, but if we don't set it
+     * then ppc_hw_interrupt() won't deliver. We could add some
+     * other tests there based on LPCR but it's simpler to just
+     * whack EE in. It will be cleared by the 0x100 at wakeup
+     * anyway. It will still be observable by the guest in SRR1
+     * but this doesn't seem to be a problem.
+     */
+    env->msr |= (1ull << MSR_EE);
+    helper_raise_exception(env, EXCP_HLT);
+}
+#endif /* defined(TARGET_PPC64) */
+
 static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
 {
     CPUState *cs = CPU(ppc_env_get_cpu(env));
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index f4410a836954..ab9592926f7b 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -13,6 +13,7 @@ DEF_HELPER_1(rfci, void, env)
 DEF_HELPER_1(rfdi, void, env)
 DEF_HELPER_1(rfmci, void, env)
 #if defined(TARGET_PPC64)
+DEF_HELPER_2(pminsn, void, env, i32)
 DEF_HELPER_1(rfid, void, env)
 DEF_HELPER_1(hrfid, void, env)
 #endif
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 600d5db2bb9a..2dd74c3244ed 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3574,6 +3574,68 @@ static void gen_wait(DisasContext *ctx)
     gen_exception_err(ctx, EXCP_HLT, 1);
 }
 
+#if defined(TARGET_PPC64)
+static void gen_doze(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+    GEN_PRIV;
+#else
+    TCGv_i32 t;
+
+    CHK_HV;
+    t = tcg_const_i32(PPC_PM_DOZE);
+    gen_helper_pminsn(cpu_env, t);
+    tcg_temp_free_i32(t);
+    gen_stop_exception(ctx);
+#endif /* defined(CONFIG_USER_ONLY) */
+}
+
+static void gen_nap(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+    GEN_PRIV;
+#else
+    TCGv_i32 t;
+
+    CHK_HV;
+    t = tcg_const_i32(PPC_PM_NAP);
+    gen_helper_pminsn(cpu_env, t);
+    tcg_temp_free_i32(t);
+    gen_stop_exception(ctx);
+#endif /* defined(CONFIG_USER_ONLY) */
+}
+
+static void gen_sleep(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+    GEN_PRIV;
+#else
+    TCGv_i32 t;
+
+    CHK_HV;
+    t = tcg_const_i32(PPC_PM_SLEEP);
+    gen_helper_pminsn(cpu_env, t);
+    tcg_temp_free_i32(t);
+    gen_stop_exception(ctx);
+#endif /* defined(CONFIG_USER_ONLY) */
+}
+
+static void gen_rvwinkle(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+    GEN_PRIV;
+#else
+    TCGv_i32 t;
+
+    CHK_HV;
+    t = tcg_const_i32(PPC_PM_RVWINKLE);
+    gen_helper_pminsn(cpu_env, t);
+    tcg_temp_free_i32(t);
+    gen_stop_exception(ctx);
+#endif /* defined(CONFIG_USER_ONLY) */
+}
+#endif /* #if defined(TARGET_PPC64) */
+
 /***                         Floating-point load                           ***/
 #define GEN_LDF(name, ldop, opc, type)                                        \
 static void glue(gen_, name)(DisasContext *ctx)                                       \
@@ -9885,6 +9947,10 @@ GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
 #if defined(TARGET_PPC64)
 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
+GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
+GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
+GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
+GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
 GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
 #endif
 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 6f2f760728bb..0b39a088458d 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8371,10 +8371,45 @@ static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)
     return false;
 }
 
+static bool cpu_has_work_POWER7(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    if (cs->halted) {
+        if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
+            return false;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
+            (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
+            (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
+            (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
+            (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
+            return true;
+        }
+        if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
+            return true;
+        }
+        return false;
+    } else {
+        return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
+    }
+}
+
 POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
     PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
 
     dc->fw_name = "PowerPC,POWER7";
     dc->desc = "POWER7";
@@ -8384,6 +8419,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
     pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
     pcc->init_proc = init_proc_POWER7;
     pcc->check_pow = check_pow_nocheck;
+    cc->has_work = cpu_has_work_POWER7;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -8400,7 +8436,8 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
                         PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
-                        PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64;
+                        PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 |
+                        PPC2_PM_ISA206;
     pcc->msr_mask = (1ull << MSR_SF) |
                     (1ull << MSR_VR) |
                     (1ull << MSR_VSX) |
@@ -8453,10 +8490,53 @@ static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)
     return false;
 }
 
+static bool cpu_has_work_POWER8(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    if (cs->halted) {
+        if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
+            return false;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
+            (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
+            (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
+            (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
+            (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
+            (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
+            return true;
+        }
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
+            (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
+            return true;
+        }
+        if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
+            return true;
+        }
+        return false;
+    } else {
+        return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
+    }
+}
+
 POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
     PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
 
     dc->fw_name = "PowerPC,POWER8";
     dc->desc = "POWER8";
@@ -8466,6 +8546,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
     pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
     pcc->init_proc = init_proc_POWER8;
     pcc->check_pow = check_pow_nocheck;
+    cc->has_work = cpu_has_work_POWER8;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
@@ -8485,7 +8566,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                         PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
                         PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
                         PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
-                        PPC2_TM;
+                        PPC2_TM | PPC2_PM_ISA206;
     pcc->msr_mask = (1ull << MSR_SF) |
                     (1ull << MSR_SHV) |
                     (1ull << MSR_TM) |
@@ -8544,6 +8625,13 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)
     lpcr->default_value &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV);
     lpcr->default_value |= LPCR_LPES0 | LPCR_LPES1;
 
+    /* P7 and P8 has slightly different PECE bits, mostly because P8 adds
+     * bit 47 and 48 which are reserved on P7. Here we set them all, which
+     * will work as expected for both implementations
+     */
+    lpcr->default_value |= LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 |
+                           LPCR_P8_PECE3 | LPCR_P8_PECE4;
+
     /* We should be followed by a CPU reset but update the active value
      * just in case...
      */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 09/10] ppc: Move exception generation code out of line
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 09/10] ppc: Move exception generation code out of line Cédric Le Goater
@ 2016-06-13  7:44   ` Thomas Huth
  2016-06-13  8:36     ` Cédric Le Goater
  0 siblings, 1 reply; 68+ messages in thread
From: Thomas Huth @ 2016-06-13  7:44 UTC (permalink / raw)
  To: Cédric Le Goater, David Gibson; +Cc: qemu-ppc, qemu-devel

On 13.06.2016 07:24, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> There's no point inlining this, if you hit the exception case you exit
> anyway, and not inlining saves about 100K of code size (and cache
> footprint).
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>  target-ppc/translate.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index f211d175c09c..600d5db2bb9a 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -283,7 +283,8 @@ void gen_update_current_nip(void *opaque)
>      tcg_gen_movi_tl(cpu_nip, ctx->nip);
>  }
>  
> -static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
> +static void __attribute__((noinline))
> +gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
>  {
>      TCGv_i32 t0, t1;
>      if (ctx->exception == POWERPC_EXCP_NONE) {
> @@ -297,7 +298,8 @@ static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t
>      ctx->exception = (excp);
>  }
>  
> -static inline void gen_exception(DisasContext *ctx, uint32_t excp)
> +static void __attribute__((noinline))
> +gen_exception(DisasContext *ctx, uint32_t excp)
>  {
>      TCGv_i32 t0;
>      if (ctx->exception == POWERPC_EXCP_NONE) {
> @@ -309,7 +311,8 @@ static inline void gen_exception(DisasContext *ctx, uint32_t excp)
>      ctx->exception = (excp);
>  }
>  
> -static inline void gen_debug_exception(DisasContext *ctx)
> +static void __attribute__((noinline))
> +gen_debug_exception(DisasContext *ctx)
>  {
>      TCGv_i32 t0;

Do you get the same results if you just remove the "inline" keyword,
without adding the "__attribute__((noinline))" ? If yes, I'd suggest to
do this patch without the "__attribute__((noinline))" - that's easier to
read, and the compiler can still decide to inline something in case it's
better one a certain architecture.

 Thomas

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 09/10] ppc: Move exception generation code out of line
  2016-06-13  7:44   ` Thomas Huth
@ 2016-06-13  8:36     ` Cédric Le Goater
  2016-06-15  1:57       ` David Gibson
  0 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-13  8:36 UTC (permalink / raw)
  To: Thomas Huth, David Gibson; +Cc: qemu-ppc, qemu-devel

On 06/13/2016 09:44 AM, Thomas Huth wrote:
> On 13.06.2016 07:24, Cédric Le Goater wrote:
>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>
>> There's no point inlining this, if you hit the exception case you exit
>> anyway, and not inlining saves about 100K of code size (and cache
>> footprint).
>>
>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>> ---
>>  target-ppc/translate.c | 9 ++++++---
>>  1 file changed, 6 insertions(+), 3 deletions(-)
>>
>> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
>> index f211d175c09c..600d5db2bb9a 100644
>> --- a/target-ppc/translate.c
>> +++ b/target-ppc/translate.c
>> @@ -283,7 +283,8 @@ void gen_update_current_nip(void *opaque)
>>      tcg_gen_movi_tl(cpu_nip, ctx->nip);
>>  }
>>  
>> -static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
>> +static void __attribute__((noinline))
>> +gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
>>  {
>>      TCGv_i32 t0, t1;
>>      if (ctx->exception == POWERPC_EXCP_NONE) {
>> @@ -297,7 +298,8 @@ static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t
>>      ctx->exception = (excp);
>>  }
>>  
>> -static inline void gen_exception(DisasContext *ctx, uint32_t excp)
>> +static void __attribute__((noinline))
>> +gen_exception(DisasContext *ctx, uint32_t excp)
>>  {
>>      TCGv_i32 t0;
>>      if (ctx->exception == POWERPC_EXCP_NONE) {
>> @@ -309,7 +311,8 @@ static inline void gen_exception(DisasContext *ctx, uint32_t excp)
>>      ctx->exception = (excp);
>>  }
>>  
>> -static inline void gen_debug_exception(DisasContext *ctx)
>> +static void __attribute__((noinline))
>> +gen_debug_exception(DisasContext *ctx)
>>  {
>>      TCGv_i32 t0;
> 
> Do you get the same results if you just remove the "inline" keyword,
> without adding the "__attribute__((noinline))" ? If yes, I'd suggest to
> do this patch without the "__attribute__((noinline))" - that's easier to
> read, and the compiler can still decide to inline something in case it's
> better one a certain architecture.

Yes. They are no differences. 

The interesting part though is that the .text is about the same size. 
There is even a slight increase of ~2K with gcc 4.9.2 (intel host) and 
a slight decrease of ~1K with gcc 5.3.1 (ppc64le host).

I guess we can just drop that patch. It does not seem to bring much.

Thanks,

C.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 02/10] ppc: Create cpu_ppc_set_papr() helper (for LPCR)
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 02/10] ppc: Create cpu_ppc_set_papr() helper (for LPCR) Cédric Le Goater
@ 2016-06-14  6:15   ` David Gibson
  2016-06-14  6:52     ` Cédric Le Goater
  0 siblings, 1 reply; 68+ messages in thread
From: David Gibson @ 2016-06-14  6:15 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt

[-- Attachment #1: Type: text/plain, Size: 2508 bytes --]

On Mon, Jun 13, 2016 at 07:24:48AM +0200, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> And move the code adjusting the MSR mask and calling kvmppc_set_papr()
> to it. This allows us to add a few more things such as disabling setting
> of MSR:HV and appropriate LPCR bits which will be used when fixing
> the exception model.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> [clg: previous commit 26a7f1291bb5 did not include the LPCR setting as
>       it was not needed at the time ]

I see how this came about, but it means the commit message (both long
and short) is confusingly mismatched from the code now.

> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  target-ppc/translate_init.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index ca894ff4af45..edfd91a85425 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -8509,6 +8509,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
>  void cpu_ppc_set_papr(PowerPCCPU *cpu)
>  {
>      CPUPPCState *env = &cpu->env;
> +    ppc_spr_t *lpcr = &env->spr_cb[SPR_LPCR];
>      ppc_spr_t *amor = &env->spr_cb[SPR_AMOR];
>  
>      /* PAPR always has exception vectors in RAM not ROM. To ensure this,
> @@ -8518,6 +8519,19 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)
>       */
>      env->msr_mask &= ~((1ull << MSR_EP) | MSR_HVB);
>  
> +    /* Set emulated LPCR to not send interrupts to hypervisor. Note that
> +     * under KVM, the actual HW LPCR will be set differently by KVM itself,
> +     * the settings below ensure proper operations with TCG in absence of
> +     * a real hypervisor
> +     */
> +    lpcr->default_value &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV);
> +    lpcr->default_value |= LPCR_LPES0 | LPCR_LPES1;
> +
> +    /* We should be followed by a CPU reset but update the active value
> +     * just in case...
> +     */
> +    env->spr[SPR_LPCR] = lpcr->default_value;
> +
>      /* Set a full AMOR so guest can use the AMR as it sees fit */
>      env->spr[SPR_AMOR] = amor->default_value = 0xffffffffffffffffull;
>  

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 03/10] ppc: Rework POWER7 & POWER8 exception model (part 2)
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 03/10] ppc: Rework POWER7 & POWER8 exception model (part 2) Cédric Le Goater
@ 2016-06-14  6:25   ` David Gibson
  2016-06-14 21:19     ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 68+ messages in thread
From: David Gibson @ 2016-06-14  6:25 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt

[-- Attachment #1: Type: text/plain, Size: 14816 bytes --]

On Mon, Jun 13, 2016 at 07:24:49AM +0200, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> Properly implement LPES0/1 handling for HV vs. !HV mode.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> [clg: AIL implementation was fixed in commit 5c94b2a5e5ef
>       fixed checkpatch.pl errors ]

Code looks ok, but the short description really needs an update, since
this has been taken out of its original series context.

> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  target-ppc/excp_helper.c | 134 ++++++++++++++++-------------------------------
>  1 file changed, 45 insertions(+), 89 deletions(-)
> 
> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> index aa0b63f4b0de..7c44c102db39 100644
> --- a/target-ppc/excp_helper.c
> +++ b/target-ppc/excp_helper.c
> @@ -77,18 +77,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      CPUState *cs = CPU(cpu);
>      CPUPPCState *env = &cpu->env;
>      target_ulong msr, new_msr, vector;
> -    int srr0, srr1, asrr0, asrr1;
> -    int lpes0, lpes1, lev, ail;
> -
> -    if (0) {
> -        /* XXX: find a suitable condition to enable the hypervisor mode */
> -        lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;
> -        lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;
> -    } else {
> -        /* Those values ensure we won't enter the hypervisor mode */
> -        lpes0 = 0;
> -        lpes1 = 1;
> -    }
> +    int srr0, srr1, asrr0, asrr1, lev, ail;
> +    bool lpes0;
>  
>      qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
>                    " => %08x (%02x)\n", env->nip, excp, env->error_code);
> @@ -100,8 +90,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          msr = env->msr & ~0x783f0000ULL;
>      }
>  
> -    /* new interrupt handler msr */
> -    new_msr = env->msr & ((target_ulong)1 << MSR_ME);
> +    /* new interrupt handler msr preserves existing HV and ME unless
> +     * explicitly overriden
> +     */
> +    new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
>  
>      /* target registers */
>      srr0 = SPR_SRR0;
> @@ -111,12 +103,19 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>  
>      /* Exception targetting modifiers
>       *
> +     * LPES0 is supported on POWER7/8
> +     * LPES1 is not supported (old iSeries mode)
> +     *
> +     * On anything else, we behave as if LPES0 is 1
> +     * (externals don't alter MSR:HV)
> +     *
>       * AIL is initialized here but can be cleared by
>       * selected exceptions
>       */
>  #if defined(TARGET_PPC64)
>      if (excp_model == POWERPC_EXCP_POWER7 ||
>          excp_model == POWERPC_EXCP_POWER8) {
> +        lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
>          if (excp_model == POWERPC_EXCP_POWER8) {
>              ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
>          } else {
> @@ -125,6 +124,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      } else
>  #endif /* defined(TARGET_PPC64) */
>      {
> +        lpes0 = true;
>          ail = 0;
>      }
>  
> @@ -162,10 +162,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>              cs->halted = 1;
>              cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
>          }
> -        if (0) {
> -            /* XXX: find a suitable condition to enable the hypervisor mode */
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
> +        new_msr |= (target_ulong)MSR_HVB;
>          ail = 0;
>  
>          /* machine check exceptions don't have ME set */
> @@ -191,23 +188,20 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      case POWERPC_EXCP_DSI:       /* Data storage exception                   */
>          LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
>                   "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_next;
>      case POWERPC_EXCP_ISI:       /* Instruction storage exception            */
>          LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
>                   "\n", msr, env->nip);
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          msr |= env->error_code;
>          goto store_next;
>      case POWERPC_EXCP_EXTERNAL:  /* External input                           */
>          cs = CPU(cpu);
>  
> -        if (lpes0 == 1) {
> +        if (!lpes0) {
>              new_msr |= (target_ulong)MSR_HVB;
> +            new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
> +            srr0 = SPR_HSRR0;
> +            srr1 = SPR_HSRR1;
>          }
>          if (env->mpic_proxy) {
>              /* IACK the IRQ on delivery */
> @@ -215,9 +209,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          }
>          goto store_next;
>      case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          /* XXX: this is false */
>          /* Get rS/rD and rA from faulting opcode */
>          env->spr[SPR_DSISR] |= (cpu_ldl_code(env, (env->nip - 4))
> @@ -232,9 +223,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>                  env->error_code = 0;
>                  return;
>              }
> -            if (lpes1 == 0) {
> -                new_msr |= (target_ulong)MSR_HVB;
> -            }
>              msr |= 0x00100000;
>              if (msr_fe0 == msr_fe1) {
>                  goto store_next;
> @@ -243,23 +231,14 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>              break;
>          case POWERPC_EXCP_INVAL:
>              LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
> -            if (lpes1 == 0) {
> -                new_msr |= (target_ulong)MSR_HVB;
> -            }
>              msr |= 0x00080000;
>              env->spr[SPR_BOOKE_ESR] = ESR_PIL;
>              break;
>          case POWERPC_EXCP_PRIV:
> -            if (lpes1 == 0) {
> -                new_msr |= (target_ulong)MSR_HVB;
> -            }
>              msr |= 0x00040000;
>              env->spr[SPR_BOOKE_ESR] = ESR_PPR;
>              break;
>          case POWERPC_EXCP_TRAP:
> -            if (lpes1 == 0) {
> -                new_msr |= (target_ulong)MSR_HVB;
> -            }
>              msr |= 0x00020000;
>              env->spr[SPR_BOOKE_ESR] = ESR_PTR;
>              break;
> @@ -271,27 +250,23 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          }
>          goto store_current;
>      case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_current;
>      case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
>          dump_syscall(env);
>          lev = env->error_code;
> +
> +        /* "PAPR mode" built-in hypercall emulation */
>          if ((lev == 1) && cpu_ppc_hypercall) {
>              cpu_ppc_hypercall(cpu);
>              return;
>          }
> -        if (lev == 1 || (lpes0 == 0 && lpes1 == 0)) {
> +        if (lev == 1) {
>              new_msr |= (target_ulong)MSR_HVB;
>          }
>          goto store_next;
>      case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
>          goto store_current;
>      case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_next;
>      case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */
>          /* FIT on 4xx */
> @@ -361,21 +336,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>              new_msr &= ~((target_ulong)1 << MSR_ME);
>          }
>  
> -        if (0) {
> -            /* XXX: find a suitable condition to enable the hypervisor mode */
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
> +        new_msr |= (target_ulong)MSR_HVB;
>          ail = 0;
>          goto store_next;
>      case POWERPC_EXCP_DSEG:      /* Data segment exception                   */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_next;
>      case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_next;
>      case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */
>          srr0 = SPR_HSRR0;
> @@ -384,9 +350,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
>          goto store_next;
>      case POWERPC_EXCP_TRACE:     /* Trace exception                          */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_next;
>      case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */
>          srr0 = SPR_HSRR0;
> @@ -413,19 +376,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
>          goto store_next;
>      case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_current;
>      case POWERPC_EXCP_VSXU:       /* VSX unavailable exception               */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_current;
>      case POWERPC_EXCP_FU:         /* Facility unavailable exception          */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          goto store_current;
>      case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */
>          LOG_EXCP("PIT exception\n");
> @@ -444,9 +398,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>                    "is not implemented yet !\n");
>          goto store_next;
>      case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
> -        if (lpes1 == 0) { /* XXX: check this */
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          switch (excp_model) {
>          case POWERPC_EXCP_602:
>          case POWERPC_EXCP_603:
> @@ -463,9 +414,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          }
>          break;
>      case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */
> -        if (lpes1 == 0) { /* XXX: check this */
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          switch (excp_model) {
>          case POWERPC_EXCP_602:
>          case POWERPC_EXCP_603:
> @@ -482,9 +430,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          }
>          break;
>      case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */
> -        if (lpes1 == 0) { /* XXX: check this */
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          switch (excp_model) {
>          case POWERPC_EXCP_602:
>          case POWERPC_EXCP_603:
> @@ -590,9 +535,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>                    "is not implemented yet !\n");
>          goto store_next;
>      case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
> -        if (lpes1 == 0) {
> -            new_msr |= (target_ulong)MSR_HVB;
> -        }
>          /* XXX: TODO */
>          cpu_abort(cs,
>                    "Performance counter exception is not implemented yet !\n");
> @@ -636,6 +578,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      }
>      /* Save MSR */
>      env->spr[srr1] = msr;
> +
> +    /* Sanity check */
> +    if (!(env->msr_mask & MSR_HVB) && (srr0 == SPR_HSRR0)) {
> +        cpu_abort(cs, "Trying to deliver HV exception %d with "
> +                  "no HV support\n", excp);
> +    }
> +
>      /* If any alternate SRR register are defined, duplicate saved values */
>      if (asrr0 != -1) {
>          env->spr[asrr0] = env->spr[srr0];
> @@ -644,14 +593,20 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          env->spr[asrr1] = env->spr[srr1];
>      }
>  
> -    if (env->spr[SPR_LPCR] & LPCR_AIL) {
> -        new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
> -    }
> -
> +    /* Sort out endianness of interrupt, this differs depending on the
> +     * CPU, the HV mode, etc...
> +     */
>  #ifdef TARGET_PPC64
> -    if (excp_model == POWERPC_EXCP_POWER7 ||
> -        excp_model == POWERPC_EXCP_POWER8) {
> -        if (env->spr[SPR_LPCR] & LPCR_ILE) {
> +    if (excp_model == POWERPC_EXCP_POWER7) {
> +        if (!(new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) {
> +            new_msr |= (target_ulong)1 << MSR_LE;
> +        }
> +    } else if (excp_model == POWERPC_EXCP_POWER8) {
> +        if (new_msr & MSR_HVB) {
> +            if (env->spr[SPR_HID0] & HID0_HILE) {
> +                new_msr |= (target_ulong)1 << MSR_LE;
> +            }
> +        } else if (env->spr[SPR_LPCR] & LPCR_ILE) {
>              new_msr |= (target_ulong)1 << MSR_LE;
>          }
>      } else if (msr_ile) {
> @@ -674,7 +629,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      /* AIL only works if there is no HV transition and we are running with
>       * translations enabled
>       */
> -    if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1)) {
> +    if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1) ||
> +        ((new_msr & MSR_HVB) && !(msr & MSR_HVB))) {
>          ail = 0;
>      }
>      /* Handle AIL */

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 05/10] ppc: Fix generation if ISI/DSI vs. HV mode
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 05/10] ppc: Fix generation if ISI/DSI vs. HV mode Cédric Le Goater
@ 2016-06-14  6:34   ` David Gibson
  2016-06-14  6:42     ` Cédric Le Goater
  0 siblings, 1 reply; 68+ messages in thread
From: David Gibson @ 2016-06-14  6:34 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt

[-- Attachment #1: Type: text/plain, Size: 5527 bytes --]

On Mon, Jun 13, 2016 at 07:24:51AM +0200, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> Under some circumstances, we need to direct ISI and DSI interrupts
> at the hypervisor, turning them into HISI/HDSI, and using different
> SPRs (HDSISR and HDAR) depending on the combination of MSR_DR and
> the corresponding VPM bits in LPCR.
> 
> This moves part of the code into helpers that are fixed to select
> the right exception type and registers. On pre-P7 processors, LPCR
> is 0 which provides the old behaviour of directing the interrupts
> at the supervisor.
> 
> Thanks to Andrei Warkentin for finding a bug when HV=1
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  target-ppc/mmu-hash64.c | 69 +++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 50 insertions(+), 19 deletions(-)
> 
> diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
> index 668da5e22653..072a952c8bd5 100644
> --- a/target-ppc/mmu-hash64.c
> +++ b/target-ppc/mmu-hash64.c
> @@ -613,6 +613,47 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
>      return 0;
>  }
>  
> +static void ppc_hash64_set_isi(CPUState *cs, CPUPPCState *env,
> +                               uint64_t error_code)
> +{
> +    bool vpm;
> +
> +    if (msr_ir) {
> +        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
> +    } else {
> +        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
> +    }
> +    if (vpm && !msr_hv) {
> +        cs->exception_index = POWERPC_EXCP_HISI;

In the ISI case, you use HISI if !msr_hv..

> +    } else {
> +        cs->exception_index = POWERPC_EXCP_ISI;
> +    }
> +    env->error_code = error_code;
> +}
> +
> +static void ppc_hash64_set_dsi(CPUState *cs, CPUPPCState *env, uint64_t dar,
> +                               uint64_t dsisr)
> +{
> +    bool vpm;
> +
> +    if (msr_dr) {
> +        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
> +    } else {
> +        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
> +    }
> +    if (vpm && msr_hv) {
> +        cs->exception_index = POWERPC_EXCP_HDSI;

..but in the DSI case you use HDSI if msr_hv.  Is that really right?

> +        env->spr[SPR_HDAR] = dar;
> +        env->spr[SPR_HDSISR] = dsisr;
> +    } else {
> +        cs->exception_index = POWERPC_EXCP_DSI;
> +        env->spr[SPR_DAR] = dar;
> +        env->spr[SPR_DSISR] = dsisr;
> +   }
> +    env->error_code = 0;
> +}
> +
> +
>  int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
>                                  int rwx, int mmu_idx)
>  {
> @@ -623,7 +664,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
>      hwaddr pte_offset;
>      ppc_hash_pte64_t pte;
>      int pp_prot, amr_prot, prot;
> -    uint64_t new_pte1;
> +    uint64_t new_pte1, dsisr;
>      const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
>      hwaddr raddr;
>  
> @@ -657,26 +698,21 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
>  
>      /* 3. Check for segment level no-execute violation */
>      if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
> -        cs->exception_index = POWERPC_EXCP_ISI;
> -        env->error_code = 0x10000000;
> +        ppc_hash64_set_isi(cs, env, 0x10000000);
>          return 1;
>      }
>  
>      /* 4. Locate the PTE in the hash table */
>      pte_offset = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte);
>      if (pte_offset == -1) {
> +        dsisr = 0x40000000;
>          if (rwx == 2) {
> -            cs->exception_index = POWERPC_EXCP_ISI;
> -            env->error_code = 0x40000000;
> +            ppc_hash64_set_isi(cs, env, dsisr);
>          } else {
> -            cs->exception_index = POWERPC_EXCP_DSI;
> -            env->error_code = 0;
> -            env->spr[SPR_DAR] = eaddr;
>              if (rwx == 1) {
> -                env->spr[SPR_DSISR] = 0x42000000;
> -            } else {
> -                env->spr[SPR_DSISR] = 0x40000000;
> +                dsisr |= 0x02000000;
>              }
> +            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
>          }
>          return 1;
>      }
> @@ -705,14 +741,9 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
>          /* Access right violation */
>          qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
>          if (rwx == 2) {
> -            cs->exception_index = POWERPC_EXCP_ISI;
> -            env->error_code = 0x08000000;
> +            ppc_hash64_set_isi(cs, env, 0x08000000);
>          } else {
> -            target_ulong dsisr = 0;
> -
> -            cs->exception_index = POWERPC_EXCP_DSI;
> -            env->error_code = 0;
> -            env->spr[SPR_DAR] = eaddr;
> +            dsisr = 0;
>              if (need_prot[rwx] & ~pp_prot) {
>                  dsisr |= 0x08000000;
>              }
> @@ -722,7 +753,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
>              if (need_prot[rwx] & ~amr_prot) {
>                  dsisr |= 0x00200000;
>              }
> -            env->spr[SPR_DSISR] = dsisr;
> +            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
>          }
>          return 1;
>      }

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 05/10] ppc: Fix generation if ISI/DSI vs. HV mode
  2016-06-14  6:34   ` David Gibson
@ 2016-06-14  6:42     ` Cédric Le Goater
  2016-06-15  1:09       ` David Gibson
  0 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-14  6:42 UTC (permalink / raw)
  To: David Gibson
  Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt, Andrei Warkentin

On 06/14/2016 08:34 AM, David Gibson wrote:
> On Mon, Jun 13, 2016 at 07:24:51AM +0200, Cédric Le Goater wrote:
>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>
>> Under some circumstances, we need to direct ISI and DSI interrupts
>> at the hypervisor, turning them into HISI/HDSI, and using different
>> SPRs (HDSISR and HDAR) depending on the combination of MSR_DR and
>> the corresponding VPM bits in LPCR.
>>
>> This moves part of the code into helpers that are fixed to select
>> the right exception type and registers. On pre-P7 processors, LPCR
>> is 0 which provides the old behaviour of directing the interrupts
>> at the supervisor.
>>
>> Thanks to Andrei Warkentin for finding a bug when HV=1
>>
>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>> ---
>>  target-ppc/mmu-hash64.c | 69 +++++++++++++++++++++++++++++++++++--------------
>>  1 file changed, 50 insertions(+), 19 deletions(-)
>>
>> diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
>> index 668da5e22653..072a952c8bd5 100644
>> --- a/target-ppc/mmu-hash64.c
>> +++ b/target-ppc/mmu-hash64.c
>> @@ -613,6 +613,47 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
>>      return 0;
>>  }
>>  
>> +static void ppc_hash64_set_isi(CPUState *cs, CPUPPCState *env,
>> +                               uint64_t error_code)
>> +{
>> +    bool vpm;
>> +
>> +    if (msr_ir) {
>> +        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
>> +    } else {
>> +        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
>> +    }
>> +    if (vpm && !msr_hv) {
>> +        cs->exception_index = POWERPC_EXCP_HISI;
> 
> In the ISI case, you use HISI if !msr_hv..
> 
>> +    } else {
>> +        cs->exception_index = POWERPC_EXCP_ISI;
>> +    }
>> +    env->error_code = error_code;
>> +}
>> +
>> +static void ppc_hash64_set_dsi(CPUState *cs, CPUPPCState *env, uint64_t dar,
>> +                               uint64_t dsisr)
>> +{
>> +    bool vpm;
>> +
>> +    if (msr_dr) {
>> +        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
>> +    } else {
>> +        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
>> +    }
>> +    if (vpm && msr_hv) {
>> +        cs->exception_index = POWERPC_EXCP_HDSI;
> 
> ..but in the DSI case you use HDSI if msr_hv.  Is that really right?

No. I forgot to add this patch from Andrei :

	https://github.com/legoater/qemu/commit/e218fd3ba945bb0f483f5f12bedbb74d897cd5b9

I will send it as a fix.

C.  

>> +        env->spr[SPR_HDAR] = dar;
>> +        env->spr[SPR_HDSISR] = dsisr;
>> +    } else {
>> +        cs->exception_index = POWERPC_EXCP_DSI;
>> +        env->spr[SPR_DAR] = dar;
>> +        env->spr[SPR_DSISR] = dsisr;
>> +   }
>> +    env->error_code = 0;
>> +}
>> +
>> +
>>  int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
>>                                  int rwx, int mmu_idx)
>>  {
>> @@ -623,7 +664,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
>>      hwaddr pte_offset;
>>      ppc_hash_pte64_t pte;
>>      int pp_prot, amr_prot, prot;
>> -    uint64_t new_pte1;
>> +    uint64_t new_pte1, dsisr;
>>      const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
>>      hwaddr raddr;
>>  
>> @@ -657,26 +698,21 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
>>  
>>      /* 3. Check for segment level no-execute violation */
>>      if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
>> -        cs->exception_index = POWERPC_EXCP_ISI;
>> -        env->error_code = 0x10000000;
>> +        ppc_hash64_set_isi(cs, env, 0x10000000);
>>          return 1;
>>      }
>>  
>>      /* 4. Locate the PTE in the hash table */
>>      pte_offset = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte);
>>      if (pte_offset == -1) {
>> +        dsisr = 0x40000000;
>>          if (rwx == 2) {
>> -            cs->exception_index = POWERPC_EXCP_ISI;
>> -            env->error_code = 0x40000000;
>> +            ppc_hash64_set_isi(cs, env, dsisr);
>>          } else {
>> -            cs->exception_index = POWERPC_EXCP_DSI;
>> -            env->error_code = 0;
>> -            env->spr[SPR_DAR] = eaddr;
>>              if (rwx == 1) {
>> -                env->spr[SPR_DSISR] = 0x42000000;
>> -            } else {
>> -                env->spr[SPR_DSISR] = 0x40000000;
>> +                dsisr |= 0x02000000;
>>              }
>> +            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
>>          }
>>          return 1;
>>      }
>> @@ -705,14 +741,9 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
>>          /* Access right violation */
>>          qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
>>          if (rwx == 2) {
>> -            cs->exception_index = POWERPC_EXCP_ISI;
>> -            env->error_code = 0x08000000;
>> +            ppc_hash64_set_isi(cs, env, 0x08000000);
>>          } else {
>> -            target_ulong dsisr = 0;
>> -
>> -            cs->exception_index = POWERPC_EXCP_DSI;
>> -            env->error_code = 0;
>> -            env->spr[SPR_DAR] = eaddr;
>> +            dsisr = 0;
>>              if (need_prot[rwx] & ~pp_prot) {
>>                  dsisr |= 0x08000000;
>>              }
>> @@ -722,7 +753,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
>>              if (need_prot[rwx] & ~amr_prot) {
>>                  dsisr |= 0x00200000;
>>              }
>> -            env->spr[SPR_DSISR] = dsisr;
>> +            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
>>          }
>>          return 1;
>>      }
> 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 02/10] ppc: Create cpu_ppc_set_papr() helper (for LPCR)
  2016-06-14  6:15   ` David Gibson
@ 2016-06-14  6:52     ` Cédric Le Goater
  2016-06-15  1:01       ` David Gibson
  0 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-14  6:52 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt

On 06/14/2016 08:15 AM, David Gibson wrote:
> On Mon, Jun 13, 2016 at 07:24:48AM +0200, Cédric Le Goater wrote:
>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>
>> And move the code adjusting the MSR mask and calling kvmppc_set_papr()
>> to it. This allows us to add a few more things such as disabling setting
>> of MSR:HV and appropriate LPCR bits which will be used when fixing
>> the exception model.
>>
>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>> [clg: previous commit 26a7f1291bb5 did not include the LPCR setting as
>>       it was not needed at the time ]
> 
> I see how this came about, but it means the commit message (both long
> and short) is confusingly mismatched from the code now.

OK. I will work on it.

For my education, how much can we change the initial changelog of a patch ?
Is it considered as part of the code ? 

Thanks,

C. 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 03/10] ppc: Rework POWER7 & POWER8 exception model (part 2)
  2016-06-14  6:25   ` David Gibson
@ 2016-06-14 21:19     ` Benjamin Herrenschmidt
  2016-06-15  1:00       ` David Gibson
  0 siblings, 1 reply; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-14 21:19 UTC (permalink / raw)
  To: David Gibson, Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

On Tue, 2016-06-14 at 16:25 +1000, David Gibson wrote:
> > Properly implement LPES0/1 handling for HV vs. !HV mode.
> > 
> > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > [clg: AIL implementation was fixed in commit 5c94b2a5e5ef
> >       fixed checkpatch.pl errors ]
> 
> Code looks ok, but the short description really needs an update,
> since
> this has been taken out of its original series context.

This is still what this does. It properly implements support for LPCR0
(LPCR1 isn't supported). It also fixes how the HV bit is handled when
taking interrupts and which set of SRR's are used in some cases.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 03/10] ppc: Rework POWER7 & POWER8 exception model (part 2)
  2016-06-14 21:19     ` Benjamin Herrenschmidt
@ 2016-06-15  1:00       ` David Gibson
  0 siblings, 0 replies; 68+ messages in thread
From: David Gibson @ 2016-06-15  1:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Cédric Le Goater, qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1034 bytes --]

On Wed, Jun 15, 2016 at 07:19:39AM +1000, Benjamin Herrenschmidt wrote:
> On Tue, 2016-06-14 at 16:25 +1000, David Gibson wrote:
> > > Properly implement LPES0/1 handling for HV vs. !HV mode.
> > > 
> > > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > [clg: AIL implementation was fixed in commit 5c94b2a5e5ef
> > >       fixed checkpatch.pl errors ]
> > 
> > Code looks ok, but the short description really needs an update,
> > since
> > this has been taken out of its original series context.
> 
> This is still what this does. It properly implements support for LPCR0
> (LPCR1 isn't supported). It also fixes how the HV bit is handled when
> taking interrupts and which set of SRR's are used in some cases.

It's the "Rework POWER7 & POWER8 exception model (part 2)" bit which
is the problem.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 02/10] ppc: Create cpu_ppc_set_papr() helper (for LPCR)
  2016-06-14  6:52     ` Cédric Le Goater
@ 2016-06-15  1:01       ` David Gibson
  0 siblings, 0 replies; 68+ messages in thread
From: David Gibson @ 2016-06-15  1:01 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt

[-- Attachment #1: Type: text/plain, Size: 1424 bytes --]

On Tue, Jun 14, 2016 at 08:52:12AM +0200, Cédric Le Goater wrote:
> On 06/14/2016 08:15 AM, David Gibson wrote:
> > On Mon, Jun 13, 2016 at 07:24:48AM +0200, Cédric Le Goater wrote:
> >> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> >>
> >> And move the code adjusting the MSR mask and calling kvmppc_set_papr()
> >> to it. This allows us to add a few more things such as disabling setting
> >> of MSR:HV and appropriate LPCR bits which will be used when fixing
> >> the exception model.
> >>
> >> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> >> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> >> [clg: previous commit 26a7f1291bb5 did not include the LPCR setting as
> >>       it was not needed at the time ]
> > 
> > I see how this came about, but it means the commit message (both long
> > and short) is confusingly mismatched from the code now.
> 
> OK. I will work on it.
> 
> For my education, how much can we change the initial changelog of a patch ?
> Is it considered as part of the code ? 

I'm not entirely sure I follow the question, but AFAIK it's entirely
ok to reword and clarify a commit message as it moves through the
signed-off-by chain.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 05/10] ppc: Fix generation if ISI/DSI vs. HV mode
  2016-06-14  6:42     ` Cédric Le Goater
@ 2016-06-15  1:09       ` David Gibson
  0 siblings, 0 replies; 68+ messages in thread
From: David Gibson @ 2016-06-15  1:09 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt, Andrei Warkentin

[-- Attachment #1: Type: text/plain, Size: 6403 bytes --]

On Tue, Jun 14, 2016 at 08:42:26AM +0200, Cédric Le Goater wrote:
> On 06/14/2016 08:34 AM, David Gibson wrote:
> > On Mon, Jun 13, 2016 at 07:24:51AM +0200, Cédric Le Goater wrote:
> >> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> >>
> >> Under some circumstances, we need to direct ISI and DSI interrupts
> >> at the hypervisor, turning them into HISI/HDSI, and using different
> >> SPRs (HDSISR and HDAR) depending on the combination of MSR_DR and
> >> the corresponding VPM bits in LPCR.
> >>
> >> This moves part of the code into helpers that are fixed to select
> >> the right exception type and registers. On pre-P7 processors, LPCR
> >> is 0 which provides the old behaviour of directing the interrupts
> >> at the supervisor.
> >>
> >> Thanks to Andrei Warkentin for finding a bug when HV=1
> >>
> >> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> >> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> >> ---
> >>  target-ppc/mmu-hash64.c | 69 +++++++++++++++++++++++++++++++++++--------------
> >>  1 file changed, 50 insertions(+), 19 deletions(-)
> >>
> >> diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
> >> index 668da5e22653..072a952c8bd5 100644
> >> --- a/target-ppc/mmu-hash64.c
> >> +++ b/target-ppc/mmu-hash64.c
> >> @@ -613,6 +613,47 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
> >>      return 0;
> >>  }
> >>  
> >> +static void ppc_hash64_set_isi(CPUState *cs, CPUPPCState *env,
> >> +                               uint64_t error_code)
> >> +{
> >> +    bool vpm;
> >> +
> >> +    if (msr_ir) {
> >> +        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
> >> +    } else {
> >> +        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
> >> +    }
> >> +    if (vpm && !msr_hv) {
> >> +        cs->exception_index = POWERPC_EXCP_HISI;
> > 
> > In the ISI case, you use HISI if !msr_hv..
> > 
> >> +    } else {
> >> +        cs->exception_index = POWERPC_EXCP_ISI;
> >> +    }
> >> +    env->error_code = error_code;
> >> +}
> >> +
> >> +static void ppc_hash64_set_dsi(CPUState *cs, CPUPPCState *env, uint64_t dar,
> >> +                               uint64_t dsisr)
> >> +{
> >> +    bool vpm;
> >> +
> >> +    if (msr_dr) {
> >> +        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
> >> +    } else {
> >> +        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
> >> +    }
> >> +    if (vpm && msr_hv) {
> >> +        cs->exception_index = POWERPC_EXCP_HDSI;
> > 
> > ..but in the DSI case you use HDSI if msr_hv.  Is that really right?
> 
> No. I forgot to add this patch from Andrei :
> 
> 	https://github.com/legoater/qemu/commit/e218fd3ba945bb0f483f5f12bedbb74d897cd5b9
> 
> I will send it as a fix.

Given that there are a number of tweaks this series needs, I'd prefer
to see it folded in rather than as a separate patch.

> 
> C.  
> 
> >> +        env->spr[SPR_HDAR] = dar;
> >> +        env->spr[SPR_HDSISR] = dsisr;
> >> +    } else {
> >> +        cs->exception_index = POWERPC_EXCP_DSI;
> >> +        env->spr[SPR_DAR] = dar;
> >> +        env->spr[SPR_DSISR] = dsisr;
> >> +   }
> >> +    env->error_code = 0;
> >> +}
> >> +
> >> +
> >>  int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
> >>                                  int rwx, int mmu_idx)
> >>  {
> >> @@ -623,7 +664,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
> >>      hwaddr pte_offset;
> >>      ppc_hash_pte64_t pte;
> >>      int pp_prot, amr_prot, prot;
> >> -    uint64_t new_pte1;
> >> +    uint64_t new_pte1, dsisr;
> >>      const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
> >>      hwaddr raddr;
> >>  
> >> @@ -657,26 +698,21 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
> >>  
> >>      /* 3. Check for segment level no-execute violation */
> >>      if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
> >> -        cs->exception_index = POWERPC_EXCP_ISI;
> >> -        env->error_code = 0x10000000;
> >> +        ppc_hash64_set_isi(cs, env, 0x10000000);
> >>          return 1;
> >>      }
> >>  
> >>      /* 4. Locate the PTE in the hash table */
> >>      pte_offset = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte);
> >>      if (pte_offset == -1) {
> >> +        dsisr = 0x40000000;
> >>          if (rwx == 2) {
> >> -            cs->exception_index = POWERPC_EXCP_ISI;
> >> -            env->error_code = 0x40000000;
> >> +            ppc_hash64_set_isi(cs, env, dsisr);
> >>          } else {
> >> -            cs->exception_index = POWERPC_EXCP_DSI;
> >> -            env->error_code = 0;
> >> -            env->spr[SPR_DAR] = eaddr;
> >>              if (rwx == 1) {
> >> -                env->spr[SPR_DSISR] = 0x42000000;
> >> -            } else {
> >> -                env->spr[SPR_DSISR] = 0x40000000;
> >> +                dsisr |= 0x02000000;
> >>              }
> >> +            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
> >>          }
> >>          return 1;
> >>      }
> >> @@ -705,14 +741,9 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
> >>          /* Access right violation */
> >>          qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
> >>          if (rwx == 2) {
> >> -            cs->exception_index = POWERPC_EXCP_ISI;
> >> -            env->error_code = 0x08000000;
> >> +            ppc_hash64_set_isi(cs, env, 0x08000000);
> >>          } else {
> >> -            target_ulong dsisr = 0;
> >> -
> >> -            cs->exception_index = POWERPC_EXCP_DSI;
> >> -            env->error_code = 0;
> >> -            env->spr[SPR_DAR] = eaddr;
> >> +            dsisr = 0;
> >>              if (need_prot[rwx] & ~pp_prot) {
> >>                  dsisr |= 0x08000000;
> >>              }
> >> @@ -722,7 +753,7 @@ int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
> >>              if (need_prot[rwx] & ~amr_prot) {
> >>                  dsisr |= 0x00200000;
> >>              }
> >> -            env->spr[SPR_DSISR] = dsisr;
> >> +            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
> >>          }
> >>          return 1;
> >>      }
> > 
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 06/10] ppc: Rework generation of priv and inval interrupts
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 06/10] ppc: Rework generation of priv and inval interrupts Cédric Le Goater
@ 2016-06-15  1:19   ` David Gibson
  2016-06-15  4:31     ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 68+ messages in thread
From: David Gibson @ 2016-06-15  1:19 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt

[-- Attachment #1: Type: text/plain, Size: 48321 bytes --]

On Mon, Jun 13, 2016 at 07:24:52AM +0200, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> Recent server processors use the Hypervisor Emulation Assistance
> interrupt for illegal instructions and *some* type of SPR accesses.
> 
> Also the code was always generating inval instructions even for priv
> violations due to setting the wrong flags
> 
> Finally, the checking for PR/HV was open coded everywhere.
> 
> This reworks it all, using little helper macros for checking, and
> adding the HV interrupt (which gets converted back to program check
> in the slow path of excp_helper.c on CPUs that don't want it).
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> [clg: fixed checkpatch.pl errors ]
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  linux-user/main.c        |   1 +
>  target-ppc/excp_helper.c |  19 ++
>  target-ppc/translate.c   | 690 ++++++++++++++++++++---------------------------
>  3 files changed, 311 insertions(+), 399 deletions(-)
> 
> diff --git a/linux-user/main.c b/linux-user/main.c
> index f8a8764ae97a..9e9b88b458c4 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -1721,6 +1721,7 @@ void cpu_loop(CPUPPCState *env)
>              queue_signal(env, info.si_signo, &info);
>              break;
>          case POWERPC_EXCP_PROGRAM:  /* Program exception                     */
> +        case POWERPC_EXCP_HV_EMU:   /* HV emulation                          */
>              /* XXX: check this */
>              switch (env->error_code & ~0xF) {
>              case POWERPC_EXCP_FP:
> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> index 7c44c102db39..054c12de3bff 100644
> --- a/target-ppc/excp_helper.c
> +++ b/target-ppc/excp_helper.c
> @@ -128,6 +128,19 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          ail = 0;
>      }
>  
> +    /* Hypervisor emulation assistance interrupt only exists on server
> +     * arch 2.05 server or later. We also don't want to generate it if
> +     * we don't have HVB in msr_mask (PAPR mode).
> +     */
> +    if (excp == POWERPC_EXCP_HV_EMU
> +#if defined(TARGET_PPC64)
> +        && !((env->mmu_model & POWERPC_MMU_64) && (env->msr_mask & MSR_HVB))
> +#endif /* defined(TARGET_PPC64) */
> +
> +    ) {
> +        excp = POWERPC_EXCP_PROGRAM;
> +    }
> +
>      switch (excp) {
>      case POWERPC_EXCP_NONE:
>          /* Should never happen */
> @@ -249,6 +262,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>              break;
>          }
>          goto store_current;
> +    case POWERPC_EXCP_HV_EMU:
> +        srr0 = SPR_HSRR0;
> +        srr1 = SPR_HSRR1;
> +        new_msr |= (target_ulong)MSR_HVB;
> +        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
> +        goto store_current;
>      case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
>          goto store_current;
>      case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index a02ddf52bfe6..2ec858063ecc 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -325,7 +325,19 @@ static inline void gen_debug_exception(DisasContext *ctx)
>  
>  static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
>  {
> -    gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
> +    /* Will be converted to program check if needed */
> +    gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_INVAL | error);
> +}
> +
> +static inline void gen_priv_exception(DisasContext *ctx, uint32_t error)
> +{
> +    gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_PRIV | error);
> +}
> +
> +static inline void gen_hvpriv_exception(DisasContext *ctx, uint32_t error)
> +{
> +    /* Will be converted to program check if needed */
> +    gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_PRIV | error);
>  }
>  
>  /* Stop translation */
> @@ -366,6 +378,33 @@ typedef struct opcode_t {
>      const char *oname;
>  } opcode_t;
>  
> +/* Helpers for priv. check */
> +#define GEN_PRIV                                                \
> +    do {                                                        \
> +        gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; \
> +    } while (0)
> +
> +#if defined(CONFIG_USER_ONLY)
> +#define CHK_HV GEN_PRIV
> +#define CHK_SV GEN_PRIV
> +#else
> +#define CHK_HV                                                          \
> +    do {                                                                \
> +        if (unlikely(ctx->pr || !ctx->hv)) {                            \
> +            GEN_PRIV;                                                   \
> +        }                                                               \
> +    } while (0)
> +#define CHK_SV                   \
> +    do {                         \
> +        if (unlikely(ctx->pr)) { \
> +            GEN_PRIV;            \
> +        }                        \
> +    } while (0)
> +#endif
> +
> +#define CHK_NONE
> +
> +
>  /*****************************************************************************/
>  /***                           Instruction decoding                        ***/
>  #define EXTRACT_HELPER(name, shift, nb)                                       \
> @@ -2929,7 +2968,7 @@ static void gen_lq(DisasContext *ctx)
>      bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
>  
>      if (!legal_in_user_mode && ctx->pr) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +        gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
>          return;
>      }
>  
> @@ -3055,7 +3094,7 @@ static void gen_std(DisasContext *ctx)
>          }
>  
>          if (!legal_in_user_mode && ctx->pr) {
> -            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
>              return;
>          }
>  
> @@ -4085,7 +4124,7 @@ static void gen_mcrf(DisasContext *ctx)
>  static void gen_rfi(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      /* This instruction doesn't exist anymore on 64-bit server
>       * processors compliant with arch 2.x
> @@ -4095,10 +4134,7 @@ static void gen_rfi(DisasContext *ctx)
>          return;
>      }
>      /* Restore CPU state */
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      gen_update_cfar(ctx, ctx->nip);
>      gen_helper_rfi(cpu_env);
>      gen_sync_exception(ctx);
> @@ -4109,13 +4145,10 @@ static void gen_rfi(DisasContext *ctx)
>  static void gen_rfid(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      /* Restore CPU state */
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      gen_update_cfar(ctx, ctx->nip);
>      gen_helper_rfid(cpu_env);
>      gen_sync_exception(ctx);
> @@ -4125,13 +4158,10 @@ static void gen_rfid(DisasContext *ctx)
>  static void gen_hrfid(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      /* Restore CPU state */
> -    if (unlikely(ctx->pr || !ctx->hv)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_HV;
>      gen_helper_hrfid(cpu_env);
>      gen_sync_exception(ctx);
>  #endif
> @@ -4294,15 +4324,8 @@ static void gen_mfcr(DisasContext *ctx)
>  /* mfmsr */
>  static void gen_mfmsr(DisasContext *ctx)
>  {
> -#if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -#else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +    CHK_SV;
>      tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
> -#endif
>  }
>  
>  static void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
> @@ -4348,9 +4371,15 @@ static inline void gen_op_mfspr(DisasContext *ctx)
>                               TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
>                  }
>              }
> -            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
>          }
>      } else {
> +        /* ISA 2.07 defines these as no-ops */
> +        if ((ctx->insns_flags2 & PPC2_ISA207S) &&
> +            (sprn >= 808 && sprn <= 811)) {
> +            /* This is a nop */
> +            return;
> +        }
>          /* Not defined */
>          fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at "
>                  TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
> @@ -4358,9 +4387,18 @@ static inline void gen_op_mfspr(DisasContext *ctx)
>              qemu_log("Trying to read invalid spr %d (0x%03x) at "
>                       TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
>          }
> -        /* Only generate an exception in user space, otherwise this is a nop */
> -        if (ctx->pr) {
> -            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
> +
> +        /* The behaviour depends on MSR:PR and SPR# bit 0x10,
> +         * it can generate a priv, a hv emu or a no-op
> +         */
> +        if (sprn & 0x10) {
> +            if (ctx->pr) {
> +                gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
> +            }
> +        } else {
> +            if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) {
> +                gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);

Just double checking this logic.  So in this case we get an exception
to the hypervisor if executed in guest user mode, but a no-op if
executed in guest supervisor mode.  That seems.. odd.

> +            }
>          }
>      }
>  }
> @@ -4408,13 +4446,9 @@ static void gen_mtcrf(DisasContext *ctx)
>  #if defined(TARGET_PPC64)
>  static void gen_mtmsrd(DisasContext *ctx)
>  {
> -#if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -#else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +    CHK_SV;
> +
> +#if !defined(CONFIG_USER_ONLY)
>      if (ctx->opcode & 0x00010000) {
>          /* Special form that does not need any synchronisation */
>          TCGv t0 = tcg_temp_new();
> @@ -4433,20 +4467,16 @@ static void gen_mtmsrd(DisasContext *ctx)
>          /* Note that mtmsr is not always defined as context-synchronizing */
>          gen_stop_exception(ctx);
>      }
> -#endif
> +#endif /* !defined(CONFIG_USER_ONLY) */
>  }
> -#endif
> +#endif /* defined(TARGET_PPC64) */
>  
>  static void gen_mtmsr(DisasContext *ctx)
>  {
> -#if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -#else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> -    if (ctx->opcode & 0x00010000) {
> +    CHK_SV;
> +
> +#if !defined(CONFIG_USER_ONLY)
> +   if (ctx->opcode & 0x00010000) {
>          /* Special form that does not need any synchronisation */
>          TCGv t0 = tcg_temp_new();
>          tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
> @@ -4503,9 +4533,16 @@ static void gen_mtspr(DisasContext *ctx)
>                  qemu_log("Trying to write privileged spr %d (0x%03x) at "
>                           TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
>              }
> -            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
>          }
>      } else {
> +        /* ISA 2.07 defines these as no-ops */
> +        if ((ctx->insns_flags2 & PPC2_ISA207S) &&
> +            (sprn >= 808 && sprn <= 811)) {
> +            /* This is a nop */
> +            return;
> +        }
> +
>          /* Not defined */
>          if (qemu_log_separate()) {
>              qemu_log("Trying to write invalid spr %d (0x%03x) at "
> @@ -4514,9 +4551,18 @@ static void gen_mtspr(DisasContext *ctx)
>          fprintf(stderr, "Trying to write invalid spr %d (0x%03x) at "
>                  TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
>  
> -        /* Only generate an exception in user space, otherwise this is a nop */
> -        if (ctx->pr) {
> -            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
> +
> +        /* The behaviour depends on MSR:PR and SPR# bit 0x10,
> +         * it can generate a priv, a hv emu or a no-op
> +         */
> +        if (sprn & 0x10) {
> +            if (ctx->pr) {
> +                gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
> +            }
> +        } else {
> +            if (ctx->pr || sprn == 0) {
> +                gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
> +            }
>          }
>      }
>  }
> @@ -4539,13 +4585,11 @@ static void gen_dcbf(DisasContext *ctx)
>  static void gen_dcbi(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      TCGv EA, val;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +
> +    CHK_SV;
>      EA = tcg_temp_new();
>      gen_set_access_type(ctx, ACCESS_CACHE);
>      gen_addr_reg_index(ctx, EA);
> @@ -4555,7 +4599,7 @@ static void gen_dcbi(DisasContext *ctx)
>      gen_qemu_st8(ctx, val, EA);
>      tcg_temp_free(val);
>      tcg_temp_free(EA);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* dcdst */
> @@ -4676,72 +4720,64 @@ static void gen_dcba(DisasContext *ctx)
>  static void gen_mfsr(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +
> +    CHK_SV;
>      t0 = tcg_const_tl(SR(ctx->opcode));
>      gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
>      tcg_temp_free(t0);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* mfsrin */
>  static void gen_mfsrin(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +
> +    CHK_SV;
>      t0 = tcg_temp_new();
>      tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
>      tcg_gen_andi_tl(t0, t0, 0xF);
>      gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
>      tcg_temp_free(t0);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* mtsr */
>  static void gen_mtsr(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +
> +    CHK_SV;
>      t0 = tcg_const_tl(SR(ctx->opcode));
>      gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
>      tcg_temp_free(t0);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* mtsrin */
>  static void gen_mtsrin(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +    CHK_SV;
> +
>      t0 = tcg_temp_new();
>      tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
>      tcg_gen_andi_tl(t0, t0, 0xF);
>      gen_helper_store_sr(cpu_env, t0, cpu_gpr[rD(ctx->opcode)]);
>      tcg_temp_free(t0);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  #if defined(TARGET_PPC64)
> @@ -4751,115 +4787,101 @@ static void gen_mtsrin(DisasContext *ctx)
>  static void gen_mfsr_64b(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +
> +    CHK_SV;
>      t0 = tcg_const_tl(SR(ctx->opcode));
>      gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
>      tcg_temp_free(t0);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* mfsrin */
>  static void gen_mfsrin_64b(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +
> +    CHK_SV;
>      t0 = tcg_temp_new();
>      tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
>      tcg_gen_andi_tl(t0, t0, 0xF);
>      gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
>      tcg_temp_free(t0);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* mtsr */
>  static void gen_mtsr_64b(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +
> +    CHK_SV;
>      t0 = tcg_const_tl(SR(ctx->opcode));
>      gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
>      tcg_temp_free(t0);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* mtsrin */
>  static void gen_mtsrin_64b(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +
> +    CHK_SV;
>      t0 = tcg_temp_new();
>      tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
>      tcg_gen_andi_tl(t0, t0, 0xF);
>      gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
>      tcg_temp_free(t0);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* slbmte */
>  static void gen_slbmte(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +    CHK_SV;
> +
>      gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)],
>                           cpu_gpr[rS(ctx->opcode)]);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  static void gen_slbmfee(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +    CHK_SV;
> +
>      gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,
>                               cpu_gpr[rB(ctx->opcode)]);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  static void gen_slbmfev(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +    CHK_SV;
> +
>      gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
>                               cpu_gpr[rB(ctx->opcode)]);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  static void gen_slbfee_(DisasContext *ctx)
> @@ -4895,40 +4917,34 @@ static void gen_slbfee_(DisasContext *ctx)
>  static void gen_tlbia(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr || !ctx->hv)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_HV;
> +
>      gen_helper_tlbia(cpu_env);
> -#endif
> +#endif  /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* tlbiel */
>  static void gen_tlbiel(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
> +
>      gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* tlbie */
>  static void gen_tlbie(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr || !ctx->hv)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_HV;
> +
>      if (NARROW_MODE(ctx)) {
>          TCGv t0 = tcg_temp_new();
>          tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
> @@ -4937,25 +4953,23 @@ static void gen_tlbie(DisasContext *ctx)
>      } else {
>          gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
>      }
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* tlbsync */
>  static void gen_tlbsync(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr || !ctx->hv)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_HV;
> +
>      /* tlbsync is a nop for server, ptesync handles delayed tlb flush,
>       * embedded however needs to deal with tlbsync. We don't try to be
>       * fancy and swallow the overhead of checking for both.
>       */
>      gen_check_tlb_flush(ctx);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  #if defined(TARGET_PPC64)
> @@ -4963,30 +4977,26 @@ static void gen_tlbsync(DisasContext *ctx)
>  static void gen_slbia(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
> +
>      gen_helper_slbia(cpu_env);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* slbie */
>  static void gen_slbie(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
> +
>      gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
> -#endif
> +#endif  /* defined(TARGET_PPC64) */
>  
>  /***                              External control                         ***/
>  /* Optional: */
> @@ -5685,14 +5695,11 @@ static void gen_esa(DisasContext *ctx)
>  static void gen_mfrom(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* 602 - 603 - G2 TLB management */
> @@ -5701,28 +5708,22 @@ static void gen_mfrom(DisasContext *ctx)
>  static void gen_tlbld_6xx(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* tlbli */
>  static void gen_tlbli_6xx(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* 74xx TLB management */
> @@ -5731,28 +5732,22 @@ static void gen_tlbli_6xx(DisasContext *ctx)
>  static void gen_tlbld_74xx(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      gen_helper_74xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* tlbli */
>  static void gen_tlbli_74xx(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      gen_helper_74xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* POWER instructions not in PowerPC 601 */
> @@ -5766,15 +5761,12 @@ static void gen_clf(DisasContext *ctx)
>  /* cli */
>  static void gen_cli(DisasContext *ctx)
>  {
> -    /* Cache line invalidate: privileged and treated as no-op */
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> -#endif
> +    /* Cache line invalidate: privileged and treated as no-op */
> +    CHK_SV;
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* dclst */
> @@ -5786,15 +5778,13 @@ static void gen_dclst(DisasContext *ctx)
>  static void gen_mfsri(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      int ra = rA(ctx->opcode);
>      int rd = rD(ctx->opcode);
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +
> +    CHK_SV;
>      t0 = tcg_temp_new();
>      gen_addr_reg_index(ctx, t0);
>      tcg_gen_shri_tl(t0, t0, 28);
> @@ -5803,38 +5793,34 @@ static void gen_mfsri(DisasContext *ctx)
>      tcg_temp_free(t0);
>      if (ra != 0 && ra != rd)
>          tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  static void gen_rac(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +
> +    CHK_SV;
>      t0 = tcg_temp_new();
>      gen_addr_reg_index(ctx, t0);
>      gen_helper_rac(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
>      tcg_temp_free(t0);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  static void gen_rfsvc(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
> +
>      gen_helper_rfsvc(cpu_env);
>      gen_sync_exception(ctx);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* svc is not implemented for now */
> @@ -5987,18 +5973,16 @@ static void gen_mfapidi(DisasContext *ctx)
>  static void gen_tlbiva(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +
> +    CHK_SV;
>      t0 = tcg_temp_new();
>      gen_addr_reg_index(ctx, t0);
>      gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]);
>      tcg_temp_free(t0);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* All 405 MAC instructions are translated here */
> @@ -6220,38 +6204,34 @@ GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
>  static void gen_mfdcr(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
>      TCGv dcrn;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +
> +    CHK_SV;
>      /* NIP cannot be restored if the memory exception comes from an helper */
>      gen_update_nip(ctx, ctx->nip - 4);
>      dcrn = tcg_const_tl(SPR(ctx->opcode));
>      gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn);
>      tcg_temp_free(dcrn);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* mtdcr */
>  static void gen_mtdcr(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
>      TCGv dcrn;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +
> +    CHK_SV;
>      /* NIP cannot be restored if the memory exception comes from an helper */
>      gen_update_nip(ctx, ctx->nip - 4);
>      dcrn = tcg_const_tl(SPR(ctx->opcode));
>      gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
>      tcg_temp_free(dcrn);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* mfdcrx */
> @@ -6259,18 +6239,15 @@ static void gen_mtdcr(DisasContext *ctx)
>  static void gen_mfdcrx(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +    CHK_SV;
>      /* NIP cannot be restored if the memory exception comes from an helper */
>      gen_update_nip(ctx, ctx->nip - 4);
>      gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
>                          cpu_gpr[rA(ctx->opcode)]);
>      /* Note: Rc update flag set leads to undefined state of Rc0 */
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* mtdcrx */
> @@ -6278,18 +6255,15 @@ static void gen_mfdcrx(DisasContext *ctx)
>  static void gen_mtdcrx(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> -        return;
> -    }
> +    CHK_SV;
>      /* NIP cannot be restored if the memory exception comes from an helper */
>      gen_update_nip(ctx, ctx->nip - 4);
>      gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
>                           cpu_gpr[rS(ctx->opcode)]);
>      /* Note: Rc update flag set leads to undefined state of Rc0 */
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* mfdcrux (PPC 460) : user-mode access to DCR */
> @@ -6315,28 +6289,19 @@ static void gen_mtdcrux(DisasContext *ctx)
>  /* dccci */
>  static void gen_dccci(DisasContext *ctx)
>  {
> -#if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -#else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      /* interpreted as no-op */
> -#endif
>  }
>  
>  /* dcread */
>  static void gen_dcread(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      TCGv EA, val;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +
> +    CHK_SV;
>      gen_set_access_type(ctx, ACCESS_CACHE);
>      EA = tcg_temp_new();
>      gen_addr_reg_index(ctx, EA);
> @@ -6345,7 +6310,7 @@ static void gen_dcread(DisasContext *ctx)
>      tcg_temp_free(val);
>      tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
>      tcg_temp_free(EA);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* icbt */
> @@ -6360,60 +6325,40 @@ static void gen_icbt_40x(DisasContext *ctx)
>  /* iccci */
>  static void gen_iccci(DisasContext *ctx)
>  {
> -#if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -#else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      /* interpreted as no-op */
> -#endif
>  }
>  
>  /* icread */
>  static void gen_icread(DisasContext *ctx)
>  {
> -#if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -#else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      /* interpreted as no-op */
> -#endif
>  }
>  
>  /* rfci (supervisor only) */
>  static void gen_rfci_40x(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      /* Restore CPU state */
>      gen_helper_40x_rfci(cpu_env);
>      gen_sync_exception(ctx);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  static void gen_rfci(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      /* Restore CPU state */
>      gen_helper_rfci(cpu_env);
>      gen_sync_exception(ctx);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* BookE specific */
> @@ -6422,32 +6367,26 @@ static void gen_rfci(DisasContext *ctx)
>  static void gen_rfdi(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      /* Restore CPU state */
>      gen_helper_rfdi(cpu_env);
>      gen_sync_exception(ctx);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* XXX: not implemented on 440 ? */
>  static void gen_rfmci(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      /* Restore CPU state */
>      gen_helper_rfmci(cpu_env);
>      gen_sync_exception(ctx);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* TLB management - PowerPC 405 implementation */
> @@ -6456,12 +6395,9 @@ static void gen_rfmci(DisasContext *ctx)
>  static void gen_tlbre_40x(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      switch (rB(ctx->opcode)) {
>      case 0:
>          gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env,
> @@ -6475,20 +6411,18 @@ static void gen_tlbre_40x(DisasContext *ctx)
>          gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
>          break;
>      }
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* tlbsx - tlbsx. */
>  static void gen_tlbsx_40x(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +
> +    CHK_SV;
>      t0 = tcg_temp_new();
>      gen_addr_reg_index(ctx, t0);
>      gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
> @@ -6500,19 +6434,17 @@ static void gen_tlbsx_40x(DisasContext *ctx)
>          tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
>          gen_set_label(l1);
>      }
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* tlbwe */
>  static void gen_tlbwe_40x(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
> +
>      switch (rB(ctx->opcode)) {
>      case 0:
>          gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)],
> @@ -6526,7 +6458,7 @@ static void gen_tlbwe_40x(DisasContext *ctx)
>          gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
>          break;
>      }
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* TLB management - PowerPC 440 implementation */
> @@ -6535,12 +6467,10 @@ static void gen_tlbwe_40x(DisasContext *ctx)
>  static void gen_tlbre_440(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
> +
>      switch (rB(ctx->opcode)) {
>      case 0:
>      case 1:
> @@ -6556,20 +6486,18 @@ static void gen_tlbre_440(DisasContext *ctx)
>          gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
>          break;
>      }
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* tlbsx - tlbsx. */
>  static void gen_tlbsx_440(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +
> +    CHK_SV;
>      t0 = tcg_temp_new();
>      gen_addr_reg_index(ctx, t0);
>      gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
> @@ -6581,19 +6509,16 @@ static void gen_tlbsx_440(DisasContext *ctx)
>          tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
>          gen_set_label(l1);
>      }
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* tlbwe */
>  static void gen_tlbwe_440(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      switch (rB(ctx->opcode)) {
>      case 0:
>      case 1:
> @@ -6609,7 +6534,7 @@ static void gen_tlbwe_440(DisasContext *ctx)
>          gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
>          break;
>      }
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* TLB management - PowerPC BookE 2.06 implementation */
> @@ -6617,30 +6542,23 @@ static void gen_tlbwe_440(DisasContext *ctx)
>  /* tlbre */
>  static void gen_tlbre_booke206(DisasContext *ctx)
>  {
> -#if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> + #if defined(CONFIG_USER_ONLY)
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> -
> +   CHK_SV;
>      gen_helper_booke206_tlbre(cpu_env);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* tlbsx - tlbsx. */
>  static void gen_tlbsx_booke206(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
>  
> +    CHK_SV;
>      if (rA(ctx->opcode)) {
>          t0 = tcg_temp_new();
>          tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
> @@ -6651,54 +6569,44 @@ static void gen_tlbsx_booke206(DisasContext *ctx)
>      tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
>      gen_helper_booke206_tlbsx(cpu_env, t0);
>      tcg_temp_free(t0);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* tlbwe */
>  static void gen_tlbwe_booke206(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      gen_update_nip(ctx, ctx->nip - 4);
>      gen_helper_booke206_tlbwe(cpu_env);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  static void gen_tlbivax_booke206(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
>  
> +    CHK_SV;
>      t0 = tcg_temp_new();
>      gen_addr_reg_index(ctx, t0);
> -
>      gen_helper_booke206_tlbivax(cpu_env, t0);
>      tcg_temp_free(t0);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  static void gen_tlbilx_booke206(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
>  
> +    CHK_SV;
>      t0 = tcg_temp_new();
>      gen_addr_reg_index(ctx, t0);
>  
> @@ -6718,7 +6626,7 @@ static void gen_tlbilx_booke206(DisasContext *ctx)
>      }
>  
>      tcg_temp_free(t0);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  
> @@ -6726,13 +6634,11 @@ static void gen_tlbilx_booke206(DisasContext *ctx)
>  static void gen_wrtee(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
>      TCGv t0;
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +
> +    CHK_SV;
>      t0 = tcg_temp_new();
>      tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
>      tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
> @@ -6742,19 +6648,16 @@ static void gen_wrtee(DisasContext *ctx)
>       * if we just set msr_ee to 1
>       */
>      gen_stop_exception(ctx);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* wrteei */
>  static void gen_wrteei(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> +    CHK_SV;
>      if (ctx->opcode & 0x00008000) {
>          tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
>          /* Stop translation to have a chance to raise an exception */
> @@ -6762,7 +6665,7 @@ static void gen_wrteei(DisasContext *ctx)
>      } else {
>          tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
>      }
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /* PowerPC 440 specific instructions */
> @@ -6802,29 +6705,21 @@ static void gen_icbt_440(DisasContext *ctx)
>  static void gen_msgclr(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> -
> +    CHK_SV;
>      gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  static void gen_msgsnd(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    GEN_PRIV;
>  #else
> -    if (unlikely(ctx->pr)) {
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> -        return;
> -    }
> -
> +    CHK_SV;
>      gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
> -#endif
> +#endif /* defined(CONFIG_USER_ONLY) */
>  }
>  
>  /***                      Altivec vector extension                         ***/
> @@ -9826,7 +9721,7 @@ static void gen_tcheck(DisasContext *ctx)
>  #define GEN_TM_PRIV_NOOP(name)                                 \
>  static inline void gen_##name(DisasContext *ctx)               \
>  {                                                              \
> -    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);           \
> +    gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);           \
>  }
>  
>  #else
> @@ -9834,10 +9729,7 @@ static inline void gen_##name(DisasContext *ctx)               \
>  #define GEN_TM_PRIV_NOOP(name)                                 \
>  static inline void gen_##name(DisasContext *ctx)               \
>  {                                                              \
> -    if (unlikely(ctx->pr)) {                                   \
> -        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);       \
> -        return;                                                \
> -    }                                                          \
> +    CHK_SV;                                                    \
>      if (unlikely(!ctx->tm_enabled)) {                          \
>          gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);   \
>          return;                                                \

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 10/10] ppc: Add P7/P8 Power Management instructions
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 10/10] ppc: Add P7/P8 Power Management instructions Cédric Le Goater
@ 2016-06-15  1:56   ` David Gibson
  0 siblings, 0 replies; 68+ messages in thread
From: David Gibson @ 2016-06-15  1:56 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt

[-- Attachment #1: Type: text/plain, Size: 16734 bytes --]

On Mon, Jun 13, 2016 at 07:24:56AM +0200, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> This adds the ISA 2.06 and later power management instructions
> (doze, nap, sleep and rvwinkle) and associated wakeup cause testing
> in LPCR
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> [clg: fixed checkpatch.pl errors ]
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  target-ppc/cpu-qom.h        |  9 +++++
>  target-ppc/cpu.h            | 17 ++++++++-
>  target-ppc/excp_helper.c    | 59 +++++++++++++++++++++++++++++
>  target-ppc/helper.h         |  1 +
>  target-ppc/translate.c      | 66 ++++++++++++++++++++++++++++++++
>  target-ppc/translate_init.c | 92 ++++++++++++++++++++++++++++++++++++++++++++-
>  6 files changed, 241 insertions(+), 3 deletions(-)
> 
> diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
> index 969ecdfbd40a..0fad2def0a94 100644
> --- a/target-ppc/cpu-qom.h
> +++ b/target-ppc/cpu-qom.h
> @@ -126,6 +126,15 @@ enum powerpc_excp_t {
>  };
>  
>  /*****************************************************************************/
> +/* PM instructions */
> +typedef enum {
> +    PPC_PM_DOZE,
> +    PPC_PM_NAP,
> +    PPC_PM_SLEEP,
> +    PPC_PM_RVWINKLE,
> +} powerpc_pm_insn_t;
> +
> +/*****************************************************************************/
>  /* Input pins model                                                          */
>  typedef enum powerpc_input_t powerpc_input_t;
>  enum powerpc_input_t {
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index 61a24b19ffce..b1354a4791db 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -383,6 +383,14 @@ struct ppc_slb_t {
>  #define LPCR_LPES1        (1ull << (63 - 61))
>  #define LPCR_AIL_SHIFT    (63 - 40)      /* Alternate interrupt location */
>  #define LPCR_AIL          (3ull << LPCR_AIL_SHIFT)
> +#define LPCR_P7_PECE0     (1ull << (63 - 49))
> +#define LPCR_P7_PECE1     (1ull << (63 - 50))
> +#define LPCR_P7_PECE2     (1ull << (63 - 51))
> +#define LPCR_P8_PECE0     (1ull << (63 - 47))
> +#define LPCR_P8_PECE1     (1ull << (63 - 48))
> +#define LPCR_P8_PECE2     (1ull << (63 - 49))
> +#define LPCR_P8_PECE3     (1ull << (63 - 50))
> +#define LPCR_P8_PECE4     (1ull << (63 - 51))
>  
>  #define msr_sf   ((env->msr >> MSR_SF)   & 1)
>  #define msr_isf  ((env->msr >> MSR_ISF)  & 1)
> @@ -1059,6 +1067,11 @@ struct CPUPPCState {
>       * instructions and SPRs are diallowed if MSR:HV is 0
>       */
>      bool has_hv_mode;
> +    /* On P7/P8, set when in PM state, we need to handle resume
> +     * in a special way (such as routing some resume causes to
> +     * 0x100), so flag this here.
> +     */
> +    bool in_pm_state;
>  #endif
>  
>      /* Those resources are used only during code translation */
> @@ -2068,6 +2081,8 @@ enum {
>      PPC2_FP_CVT_S64    = 0x0000000000010000ULL,
>      /* Transactional Memory (ISA 2.07, Book II)                              */
>      PPC2_TM            = 0x0000000000020000ULL,
> +    /* Server PM instructgions (ISA 2.06, Book III)                          */
> +    PPC2_PM_ISA206     = 0x0000000000040000ULL,
>  
>  #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
>                          PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
> @@ -2075,7 +2090,7 @@ enum {
>                          PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | \
>                          PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | \
>                          PPC2_ALTIVEC_207 | PPC2_ISA207S | PPC2_DFP | \
> -                        PPC2_FP_CVT_S64 | PPC2_TM)
> +                        PPC2_FP_CVT_S64 | PPC2_TM | PPC2_PM_ISA206)
>  };
>  
>  /*****************************************************************************/
> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> index 054c12de3bff..533866b87b60 100644
> --- a/target-ppc/excp_helper.c
> +++ b/target-ppc/excp_helper.c
> @@ -101,6 +101,44 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      asrr0 = -1;
>      asrr1 = -1;
>  
> +    /* check for special resume at 0x100 from doze/nap/sleep/winkle on P7/P8 */
> +    if (env->in_pm_state) {
> +        env->in_pm_state = false;
> +
> +        /* Pretend to be returning from doze always as we don't lose state */
> +        msr |= (0x1ull << (63 - 47));
> +
> +        /* Non-machine check are routed to 0x100 with a wakeup cause
> +         * encoded in SRR1
> +         */
> +        if (excp != POWERPC_EXCP_MCHECK) {
> +            switch (excp) {
> +            case POWERPC_EXCP_RESET:
> +                msr |= 0x4ull << (63 - 45);
> +                break;
> +            case POWERPC_EXCP_EXTERNAL:
> +                msr |= 0x8ull << (63 - 45);
> +                break;
> +            case POWERPC_EXCP_DECR:
> +                msr |= 0x6ull << (63 - 45);
> +                break;
> +            case POWERPC_EXCP_SDOOR:
> +                msr |= 0x5ull << (63 - 45);
> +                break;
> +            case POWERPC_EXCP_SDOOR_HV:
> +                msr |= 0x3ull << (63 - 45);
> +                break;
> +            case POWERPC_EXCP_HV_MAINT:
> +                msr |= 0xaull << (63 - 45);
> +                break;
> +            default:
> +                cpu_abort(cs, "Unsupported exception %d in Power Save mode\n",
> +                          excp);
> +            }
> +            excp = POWERPC_EXCP_RESET;
> +        }
> +    }
> +
>      /* Exception targetting modifiers
>       *
>       * LPES0 is supported on POWER7/8
> @@ -897,6 +935,27 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
>      }
>  }
>  
> +#if defined(TARGET_PPC64)
> +void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn)
> +{
> +    CPUState *cs;
> +
> +    cs = CPU(ppc_env_get_cpu(env));
> +    cs->halted = 1;
> +    env->in_pm_state = true;
> +
> +    /* Technically, nap doesn't set EE, but if we don't set it
> +     * then ppc_hw_interrupt() won't deliver. We could add some
> +     * other tests there based on LPCR but it's simpler to just
> +     * whack EE in. It will be cleared by the 0x100 at wakeup
> +     * anyway. It will still be observable by the guest in SRR1
> +     * but this doesn't seem to be a problem.
> +     */
> +    env->msr |= (1ull << MSR_EE);
> +    helper_raise_exception(env, EXCP_HLT);
> +}
> +#endif /* defined(TARGET_PPC64) */
> +
>  static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
>  {
>      CPUState *cs = CPU(ppc_env_get_cpu(env));
> diff --git a/target-ppc/helper.h b/target-ppc/helper.h
> index f4410a836954..ab9592926f7b 100644
> --- a/target-ppc/helper.h
> +++ b/target-ppc/helper.h
> @@ -13,6 +13,7 @@ DEF_HELPER_1(rfci, void, env)
>  DEF_HELPER_1(rfdi, void, env)
>  DEF_HELPER_1(rfmci, void, env)
>  #if defined(TARGET_PPC64)
> +DEF_HELPER_2(pminsn, void, env, i32)
>  DEF_HELPER_1(rfid, void, env)
>  DEF_HELPER_1(hrfid, void, env)
>  #endif
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index 600d5db2bb9a..2dd74c3244ed 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -3574,6 +3574,68 @@ static void gen_wait(DisasContext *ctx)
>      gen_exception_err(ctx, EXCP_HLT, 1);
>  }
>  
> +#if defined(TARGET_PPC64)
> +static void gen_doze(DisasContext *ctx)
> +{
> +#if defined(CONFIG_USER_ONLY)
> +    GEN_PRIV;
> +#else
> +    TCGv_i32 t;
> +
> +    CHK_HV;
> +    t = tcg_const_i32(PPC_PM_DOZE);
> +    gen_helper_pminsn(cpu_env, t);
> +    tcg_temp_free_i32(t);
> +    gen_stop_exception(ctx);
> +#endif /* defined(CONFIG_USER_ONLY) */
> +}
> +
> +static void gen_nap(DisasContext *ctx)
> +{
> +#if defined(CONFIG_USER_ONLY)
> +    GEN_PRIV;
> +#else
> +    TCGv_i32 t;
> +
> +    CHK_HV;
> +    t = tcg_const_i32(PPC_PM_NAP);
> +    gen_helper_pminsn(cpu_env, t);
> +    tcg_temp_free_i32(t);
> +    gen_stop_exception(ctx);
> +#endif /* defined(CONFIG_USER_ONLY) */
> +}
> +
> +static void gen_sleep(DisasContext *ctx)
> +{
> +#if defined(CONFIG_USER_ONLY)
> +    GEN_PRIV;
> +#else
> +    TCGv_i32 t;
> +
> +    CHK_HV;
> +    t = tcg_const_i32(PPC_PM_SLEEP);
> +    gen_helper_pminsn(cpu_env, t);
> +    tcg_temp_free_i32(t);
> +    gen_stop_exception(ctx);
> +#endif /* defined(CONFIG_USER_ONLY) */
> +}
> +
> +static void gen_rvwinkle(DisasContext *ctx)
> +{
> +#if defined(CONFIG_USER_ONLY)
> +    GEN_PRIV;
> +#else
> +    TCGv_i32 t;
> +
> +    CHK_HV;
> +    t = tcg_const_i32(PPC_PM_RVWINKLE);
> +    gen_helper_pminsn(cpu_env, t);
> +    tcg_temp_free_i32(t);
> +    gen_stop_exception(ctx);
> +#endif /* defined(CONFIG_USER_ONLY) */
> +}
> +#endif /* #if defined(TARGET_PPC64) */
> +
>  /***                         Floating-point load                           ***/
>  #define GEN_LDF(name, ldop, opc, type)                                        \
>  static void glue(gen_, name)(DisasContext *ctx)                                       \
> @@ -9885,6 +9947,10 @@ GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
>  GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
>  #if defined(TARGET_PPC64)
>  GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
> +GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
> +GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
> +GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
> +GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
>  GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
>  #endif
>  GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index 6f2f760728bb..0b39a088458d 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -8371,10 +8371,45 @@ static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)
>      return false;
>  }
>  
> +static bool cpu_has_work_POWER7(CPUState *cs)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    CPUPPCState *env = &cpu->env;
> +
> +    if (cs->halted) {
> +        if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
> +            return false;
> +        }
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
> +            (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
> +            return true;
> +        }
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
> +            (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
> +            return true;
> +        }
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
> +            (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
> +            return true;
> +        }
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
> +            (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
> +            return true;
> +        }
> +        if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
> +            return true;
> +        }
> +        return false;
> +    } else {
> +        return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
> +    }
> +}
> +
>  POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(oc);
>      PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
> +    CPUClass *cc = CPU_CLASS(oc);
>  
>      dc->fw_name = "PowerPC,POWER7";
>      dc->desc = "POWER7";
> @@ -8384,6 +8419,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
>      pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
>      pcc->init_proc = init_proc_POWER7;
>      pcc->check_pow = check_pow_nocheck;
> +    cc->has_work = cpu_has_work_POWER7;
>      pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
>                         PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
>                         PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
> @@ -8400,7 +8436,8 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
>      pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
>                          PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
>                          PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
> -                        PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64;
> +                        PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 |
> +                        PPC2_PM_ISA206;
>      pcc->msr_mask = (1ull << MSR_SF) |
>                      (1ull << MSR_VR) |
>                      (1ull << MSR_VSX) |
> @@ -8453,10 +8490,53 @@ static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)
>      return false;
>  }
>  
> +static bool cpu_has_work_POWER8(CPUState *cs)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    CPUPPCState *env = &cpu->env;
> +
> +    if (cs->halted) {
> +        if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
> +            return false;
> +        }
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
> +            (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
> +            return true;
> +        }
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
> +            (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
> +            return true;
> +        }
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
> +            (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
> +            return true;
> +        }
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
> +            (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
> +            return true;
> +        }
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
> +            (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
> +            return true;
> +        }
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
> +            (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
> +            return true;
> +        }
> +        if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
> +            return true;
> +        }
> +        return false;
> +    } else {
> +        return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
> +    }
> +}
> +
>  POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(oc);
>      PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
> +    CPUClass *cc = CPU_CLASS(oc);
>  
>      dc->fw_name = "PowerPC,POWER8";
>      dc->desc = "POWER8";
> @@ -8466,6 +8546,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
>      pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
>      pcc->init_proc = init_proc_POWER8;
>      pcc->check_pow = check_pow_nocheck;
> +    cc->has_work = cpu_has_work_POWER8;
>      pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
>                         PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
>                         PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
> @@ -8485,7 +8566,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
>                          PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
>                          PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
>                          PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
> -                        PPC2_TM;
> +                        PPC2_TM | PPC2_PM_ISA206;
>      pcc->msr_mask = (1ull << MSR_SF) |
>                      (1ull << MSR_SHV) |
>                      (1ull << MSR_TM) |
> @@ -8544,6 +8625,13 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)
>      lpcr->default_value &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV);
>      lpcr->default_value |= LPCR_LPES0 | LPCR_LPES1;
>  
> +    /* P7 and P8 has slightly different PECE bits, mostly because P8 adds
> +     * bit 47 and 48 which are reserved on P7. Here we set them all, which
> +     * will work as expected for both implementations
> +     */
> +    lpcr->default_value |= LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 |
> +                           LPCR_P8_PECE3 | LPCR_P8_PECE4;
> +
>      /* We should be followed by a CPU reset but update the active value
>       * just in case...
>       */

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 09/10] ppc: Move exception generation code out of line
  2016-06-13  8:36     ` Cédric Le Goater
@ 2016-06-15  1:57       ` David Gibson
  0 siblings, 0 replies; 68+ messages in thread
From: David Gibson @ 2016-06-15  1:57 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: Thomas Huth, qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 3051 bytes --]

On Mon, Jun 13, 2016 at 10:36:24AM +0200, Cédric Le Goater wrote:
> On 06/13/2016 09:44 AM, Thomas Huth wrote:
> > On 13.06.2016 07:24, Cédric Le Goater wrote:
> >> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> >>
> >> There's no point inlining this, if you hit the exception case you exit
> >> anyway, and not inlining saves about 100K of code size (and cache
> >> footprint).
> >>
> >> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> >> ---
> >>  target-ppc/translate.c | 9 ++++++---
> >>  1 file changed, 6 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> >> index f211d175c09c..600d5db2bb9a 100644
> >> --- a/target-ppc/translate.c
> >> +++ b/target-ppc/translate.c
> >> @@ -283,7 +283,8 @@ void gen_update_current_nip(void *opaque)
> >>      tcg_gen_movi_tl(cpu_nip, ctx->nip);
> >>  }
> >>  
> >> -static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
> >> +static void __attribute__((noinline))
> >> +gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
> >>  {
> >>      TCGv_i32 t0, t1;
> >>      if (ctx->exception == POWERPC_EXCP_NONE) {
> >> @@ -297,7 +298,8 @@ static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t
> >>      ctx->exception = (excp);
> >>  }
> >>  
> >> -static inline void gen_exception(DisasContext *ctx, uint32_t excp)
> >> +static void __attribute__((noinline))
> >> +gen_exception(DisasContext *ctx, uint32_t excp)
> >>  {
> >>      TCGv_i32 t0;
> >>      if (ctx->exception == POWERPC_EXCP_NONE) {
> >> @@ -309,7 +311,8 @@ static inline void gen_exception(DisasContext *ctx, uint32_t excp)
> >>      ctx->exception = (excp);
> >>  }
> >>  
> >> -static inline void gen_debug_exception(DisasContext *ctx)
> >> +static void __attribute__((noinline))
> >> +gen_debug_exception(DisasContext *ctx)
> >>  {
> >>      TCGv_i32 t0;
> > 
> > Do you get the same results if you just remove the "inline" keyword,
> > without adding the "__attribute__((noinline))" ? If yes, I'd suggest to
> > do this patch without the "__attribute__((noinline))" - that's easier to
> > read, and the compiler can still decide to inline something in case it's
> > better one a certain architecture.
> 
> Yes. They are no differences. 
> 
> The interesting part though is that the .text is about the same size. 
> There is even a slight increase of ~2K with gcc 4.9.2 (intel host) and 
> a slight decrease of ~1K with gcc 5.3.1 (ppc64le host).
> 
> I guess we can just drop that patch. It does not seem to bring much.

I would prefer to see the inline keyword removed.  Except in the case
of tiny header functions, it's very rarely a good idea - usually the
compiler will have better information on whether to inline or not.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 07/10] ppc: Add real mode CI load/store instructions for P7 and P8
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 07/10] ppc: Add real mode CI load/store instructions for P7 and P8 Cédric Le Goater
@ 2016-06-15  3:46   ` David Gibson
  0 siblings, 0 replies; 68+ messages in thread
From: David Gibson @ 2016-06-15  3:46 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt

[-- Attachment #1: Type: text/plain, Size: 14151 bytes --]

On Mon, Jun 13, 2016 at 07:24:53AM +0200, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> Those instructions are only available in hypervisor real mode and
> allow cache inhibited garded access to devices in that mode.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> [clg: fixed checkpatch.pl errors ]
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
> 
> This patch still has a couple of checkpatch issues which I did not
> know quite understand:
> 
> ERROR: Macros with complex values should be enclosed in parenthesis
> #176: FILE: target-ppc/translate.c:10238:
> +#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
>  GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
> 
> ERROR: Macros with complex values should be enclosed in parenthesis
> #200: FILE: target-ppc/translate.c:10277:
> +#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
>  GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),

I believe that's because of the trailing comma in those expansions - I
think those are making checkpatch think the macro expands to an
expression, which should be parenthesised, but isn't.

That expansion is kinda weird, and quite possibly a bad idea, but it
wasn't actually changed by this patch - this just changes the macro
arguments.  So, I don't think it's within the scope of this patch to
fix it, i.e. I believe you can ignore the checkpatch warnings in this
case.

> total: 2 errors, 0 warnings, 196 lines checked
> 
> 
>  target-ppc/cpu.h            |  4 ++-
>  target-ppc/translate.c      | 59 ++++++++++++++++++++++++++++++++++++---------
>  target-ppc/translate_init.c |  6 +++--
>  3 files changed, 55 insertions(+), 14 deletions(-)
> 
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index f005549c352e..61a24b19ffce 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -1912,6 +1912,8 @@ enum {
>      PPC_POPCNTB        = 0x0000000000001000ULL,
>      /*   string load / store                                                 */
>      PPC_STRING         = 0x0000000000002000ULL,
> +    /*   real mode cache inhibited load / store                              */
> +    PPC_CILDST         = 0x0000000000004000ULL,
>  
>      /* Floating-point unit extensions                                        */
>      /*   Optional floating point instructions                                */
> @@ -2026,7 +2028,7 @@ enum {
>                          | PPC_MFAPIDI | PPC_TLBIVA | PPC_TLBIVAX \
>                          | PPC_4xx_COMMON | PPC_40x_ICBT | PPC_RFMCI \
>                          | PPC_RFDI | PPC_DCR | PPC_DCRX | PPC_DCRUX \
> -                        | PPC_POPCNTWD)
> +                        | PPC_POPCNTWD | PPC_CILDST)
>  
>      /* extended type values */
>  
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index 2ec858063ecc..b594b18399f7 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -192,7 +192,7 @@ struct DisasContext {
>      uint32_t opcode;
>      uint32_t exception;
>      /* Routine used to access memory */
> -    bool pr, hv;
> +    bool pr, hv, dr;
>      bool lazy_tlb_flush;
>      int mem_idx;
>      int access_type;
> @@ -387,6 +387,7 @@ typedef struct opcode_t {
>  #if defined(CONFIG_USER_ONLY)
>  #define CHK_HV GEN_PRIV
>  #define CHK_SV GEN_PRIV
> +#define CHK_HVRM GEN_PRIV
>  #else
>  #define CHK_HV                                                          \
>      do {                                                                \
> @@ -400,6 +401,12 @@ typedef struct opcode_t {
>              GEN_PRIV;            \
>          }                        \
>      } while (0)
> +#define CHK_HVRM                                            \
> +    do {                                                    \
> +        if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) {     \
> +            GEN_PRIV;                                       \
> +        }                                                   \
> +    } while (0)
>  #endif
>  
>  #define CHK_NONE
> @@ -2895,18 +2902,23 @@ static void glue(gen_, name##ux)(DisasContext *ctx)
>      tcg_temp_free(EA);                                                        \
>  }
>  
> -#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
> +#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
>  static void glue(gen_, name##x)(DisasContext *ctx)                            \
>  {                                                                             \
>      TCGv EA;                                                                  \
> +    chk;                                                                      \
>      gen_set_access_type(ctx, ACCESS_INT);                                     \
>      EA = tcg_temp_new();                                                      \
>      gen_addr_reg_index(ctx, EA);                                              \
>      gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
>      tcg_temp_free(EA);                                                        \
>  }
> +
>  #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
> -    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE)
> +    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_NONE)
> +
> +#define GEN_LDX_HVRM(name, ldop, opc2, opc3, type)                            \
> +    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
>  
>  #define GEN_LDS(name, ldop, op, type)                                         \
>  GEN_LD(name, ldop, op | 0x20, type);                                          \
> @@ -2932,6 +2944,12 @@ GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B);
>  /* ldx */
>  GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
>  
> +/* CI load/store variants */
> +GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST)
> +GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST)
> +GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
> +GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
> +
>  static void gen_ld(DisasContext *ctx)
>  {
>      TCGv EA;
> @@ -3050,10 +3068,11 @@ static void glue(gen_, name##ux)(DisasContext *ctx)
>      tcg_temp_free(EA);                                                        \
>  }
>  
> -#define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
> +#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
>  static void glue(gen_, name##x)(DisasContext *ctx)                            \
>  {                                                                             \
>      TCGv EA;                                                                  \
> +    chk;                                                                      \
>      gen_set_access_type(ctx, ACCESS_INT);                                     \
>      EA = tcg_temp_new();                                                      \
>      gen_addr_reg_index(ctx, EA);                                              \
> @@ -3061,7 +3080,10 @@ static void glue(gen_, name##x)(DisasContext *ctx)                            \
>      tcg_temp_free(EA);                                                        \
>  }
>  #define GEN_STX(name, stop, opc2, opc3, type)                                 \
> -    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE)
> +    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_NONE)
> +
> +#define GEN_STX_HVRM(name, stop, opc2, opc3, type)                            \
> +    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
>  
>  #define GEN_STS(name, stop, op, type)                                         \
>  GEN_ST(name, stop, op | 0x20, type);                                          \
> @@ -3078,6 +3100,10 @@ GEN_STS(stw, st32, 0x04, PPC_INTEGER);
>  #if defined(TARGET_PPC64)
>  GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
>  GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
> +GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST)
> +GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
> +GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
> +GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
>  
>  static void gen_std(DisasContext *ctx)
>  {
> @@ -3166,7 +3192,7 @@ static inline void gen_qemu_ld64ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
>      TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
>      tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, op);
>  }
> -GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX);
> +GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE);
>  #endif  /* TARGET_PPC64 */
>  
>  /* sthbrx */
> @@ -3192,7 +3218,7 @@ static inline void gen_qemu_st64r(DisasContext *ctx, TCGv arg1, TCGv arg2)
>      TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
>      tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, op);
>  }
> -GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX);
> +GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE);
>  #endif  /* TARGET_PPC64 */
>  
>  /***                    Integer load and store multiple                    ***/
> @@ -10209,7 +10235,7 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
>  GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
>  #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
>  GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
> -#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
> +#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
>  GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
>  #define GEN_LDS(name, ldop, op, type)                                         \
>  GEN_LD(name, ldop, op | 0x20, type)                                           \
> @@ -10226,7 +10252,13 @@ GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
>  GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
>  GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
>  GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
> -GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX)
> +GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE)
> +
> +/* HV/P7 and later only */
> +GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST)
> +GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x18, PPC_CILDST)
> +GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
> +GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
>  #endif
>  GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
>  GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
> @@ -10242,7 +10274,7 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
>  GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
>  #define GEN_STUX(name, stop, opc2, opc3, type)                                \
>  GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
> -#define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
> +#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
>  GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
>  #define GEN_STS(name, stop, op, type)                                         \
>  GEN_ST(name, stop, op | 0x20, type)                                           \
> @@ -10256,7 +10288,11 @@ GEN_STS(stw, st32, 0x04, PPC_INTEGER)
>  #if defined(TARGET_PPC64)
>  GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
>  GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
> -GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX)
> +GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE)
> +GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST)
> +GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
> +GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
> +GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
>  #endif
>  GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
>  GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
> @@ -11424,6 +11460,7 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
>      ctx.spr_cb = env->spr_cb;
>      ctx.pr = msr_pr;
>      ctx.mem_idx = env->dmmu_idx;
> +    ctx.dr = msr_dr;
>  #if !defined(CONFIG_USER_ONLY)
>      ctx.hv = msr_hv || !env->has_hv_mode;
>  #endif
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index 3b4234b325d1..6f2f760728bb 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -8395,7 +8395,8 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
>                         PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
>                         PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
>                         PPC_SEGMENT_64B | PPC_SLBI |
> -                       PPC_POPCNTB | PPC_POPCNTWD;
> +                       PPC_POPCNTB | PPC_POPCNTWD |
> +                       PPC_CILDST;
>      pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
>                          PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
>                          PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
> @@ -8476,7 +8477,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
>                         PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
>                         PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
>                         PPC_SEGMENT_64B | PPC_SLBI |
> -                       PPC_POPCNTB | PPC_POPCNTWD;
> +                       PPC_POPCNTB | PPC_POPCNTWD |
> +                       PPC_CILDST;
>      pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
>                          PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
>                          PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
> -- 
> 2.1.4
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 06/10] ppc: Rework generation of priv and inval interrupts
  2016-06-15  1:19   ` David Gibson
@ 2016-06-15  4:31     ` Benjamin Herrenschmidt
  2016-06-15  5:06       ` David Gibson
  0 siblings, 1 reply; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-15  4:31 UTC (permalink / raw)
  To: David Gibson, Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

On Wed, 2016-06-15 at 11:19 +1000, David Gibson wrote:
> 
> >  static void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
> > @@ -4348,9 +4371,15 @@ static inline void gen_op_mfspr(DisasContext *ctx)
> >                               TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
> >                  }
> >              }
> > -            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> > +            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
> >          }
> >      } else {
> > +        /* ISA 2.07 defines these as no-ops */
> > +        if ((ctx->insns_flags2 & PPC2_ISA207S) &&
> > +            (sprn >= 808 && sprn <= 811)) {
> > +            /* This is a nop */
> > +            return;
> > +        }
> >          /* Not defined */
> >          fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at "
> >                  TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
> > @@ -4358,9 +4387,18 @@ static inline void gen_op_mfspr(DisasContext *ctx)
> >              qemu_log("Trying to read invalid spr %d (0x%03x) at "
> >                       TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
> >          }
> > -        /* Only generate an exception in user space, otherwise this is a nop */
> > -        if (ctx->pr) {
> > -            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
> > +
> > +        /* The behaviour depends on MSR:PR and SPR# bit 0x10,
> > +         * it can generate a priv, a hv emu or a no-op
> > +         */
> > +        if (sprn & 0x10) {
> > +            if (ctx->pr) {
> > +                gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
> > +            }
> > +        } else {
> > +            if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) {
> > +                gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
> 
> Just double checking this logic.  So in this case we get an exception
> to the hypervisor if executed in guest user mode, but a no-op if
> 
> executed in guest supervisor mode.  That seems.. odd.

From the architecture:

* if spr 0 =0:
  - if MSR PR =1: Hypervisor Emulation Assistance
    interrupt
  - if MSR PR =0: Hypervisor Emulation Assistance
    interrupt for SPRs 0, 4, 5, and 6 and no opera-
    tion (i.e. the instruction is treated as a no-op)
    for all other SPRs
„
* if spr 0 =1:
  - if MSR PR =1: Privileged Instruction type Pro-
    gram interrupt
  - if MSR PR =0: no operation (i.e. the instruction
    is treated as a no-op)

IE. SPRs with 0x10 are supervisor priv, so PR access will trap to
the OS, whether they are implemented or not.

Otherwise, you get the "system illegal isntruction" handler which
is turned into an HVPRIV on all recent processors (the exception code
will turn that back into a 0x700 if the processor doesn't support
HVPRIV).

It was done this way so that an OS (guest) can context switch a bunch
of supervisor SPRs without having to test if they individually exist
on a given processor.

Cheers,
Ben.

> 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 06/10] ppc: Rework generation of priv and inval interrupts
  2016-06-15  4:31     ` Benjamin Herrenschmidt
@ 2016-06-15  5:06       ` David Gibson
  0 siblings, 0 replies; 68+ messages in thread
From: David Gibson @ 2016-06-15  5:06 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Cédric Le Goater, qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 3439 bytes --]

On Wed, Jun 15, 2016 at 02:31:56PM +1000, Benjamin Herrenschmidt wrote:
> On Wed, 2016-06-15 at 11:19 +1000, David Gibson wrote:
> > 
> > >  static void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
> > > @@ -4348,9 +4371,15 @@ static inline void gen_op_mfspr(DisasContext *ctx)
> > >                               TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
> > >                  }
> > >              }
> > > -            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
> > > +            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
> > >          }
> > >      } else {
> > > +        /* ISA 2.07 defines these as no-ops */
> > > +        if ((ctx->insns_flags2 & PPC2_ISA207S) &&
> > > +            (sprn >= 808 && sprn <= 811)) {
> > > +            /* This is a nop */
> > > +            return;
> > > +        }
> > >          /* Not defined */
> > >          fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at "
> > >                  TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
> > > @@ -4358,9 +4387,18 @@ static inline void gen_op_mfspr(DisasContext *ctx)
> > >              qemu_log("Trying to read invalid spr %d (0x%03x) at "
> > >                       TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
> > >          }
> > > -        /* Only generate an exception in user space, otherwise this is a nop */
> > > -        if (ctx->pr) {
> > > -            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
> > > +
> > > +        /* The behaviour depends on MSR:PR and SPR# bit 0x10,
> > > +         * it can generate a priv, a hv emu or a no-op
> > > +         */
> > > +        if (sprn & 0x10) {
> > > +            if (ctx->pr) {
> > > +                gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
> > > +            }
> > > +        } else {
> > > +            if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) {
> > > +                gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
> > 
> > Just double checking this logic.  So in this case we get an exception
> > to the hypervisor if executed in guest user mode, but a no-op if
> > 
> > executed in guest supervisor mode.  That seems.. odd.
> 
> >From the architecture:
> 
> * if spr 0 =0:
>   - if MSR PR =1: Hypervisor Emulation Assistance
>     interrupt
>   - if MSR PR =0: Hypervisor Emulation Assistance
>     interrupt for SPRs 0, 4, 5, and 6 and no opera-
>     tion (i.e. the instruction is treated as a no-op)
>     for all other SPRs
> „
> * if spr 0 =1:
>   - if MSR PR =1: Privileged Instruction type Pro-
>     gram interrupt
>   - if MSR PR =0: no operation (i.e. the instruction
>     is treated as a no-op)
> 
> IE. SPRs with 0x10 are supervisor priv, so PR access will trap to
> the OS, whether they are implemented or not.
> 
> Otherwise, you get the "system illegal isntruction" handler which
> is turned into an HVPRIV on all recent processors (the exception code
> will turn that back into a 0x700 if the processor doesn't support
> HVPRIV).
> 
> It was done this way so that an OS (guest) can context switch a bunch
> of supervisor SPRs without having to test if they individually exist
> on a given processor.

Huh.  Alright then.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-13  5:24 ` [Qemu-devel] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation Cédric Le Goater
@ 2016-06-16  1:07   ` David Gibson
  2016-06-17  2:27     ` [Qemu-devel] [Qemu-ppc] " David Gibson
  2016-06-17  6:19     ` [Qemu-devel] " Cédric Le Goater
  0 siblings, 2 replies; 68+ messages in thread
From: David Gibson @ 2016-06-16  1:07 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt

[-- Attachment #1: Type: text/plain, Size: 5989 bytes --]

On Mon, Jun 13, 2016 at 07:24:47AM +0200, Cédric Le Goater wrote:
> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> 
> This reworks emulation of the various "rfi" variants. I removed
> some masking bits that I couldn't make sense of, the only bit that
> I am aware we should mask here is POW, the CPU's MSR mask should
> take care of the rest.
> 
> This also fixes some problems when running 32-bit userspace under
> a 64-bit kernel.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

I've merged this patch to ppc-for-2.7.

The reset of the series I'd like to see a respin for, even if it's
just to clean up the commit messages.

> ---
>  target-ppc/excp_helper.c | 51 +++++++++++++++++++-----------------------------
>  target-ppc/translate.c   |  7 +++++++
>  2 files changed, 27 insertions(+), 31 deletions(-)
> 
> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> index 30e960e30b63..aa0b63f4b0de 100644
> --- a/target-ppc/excp_helper.c
> +++ b/target-ppc/excp_helper.c
> @@ -922,25 +922,20 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
>      }
>  }
>  
> -static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
> -                          target_ulong msrm, int keep_msrh)
> +static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
>  {
>      CPUState *cs = CPU(ppc_env_get_cpu(env));
>  
> +    /* MSR:POW cannot be set by any form of rfi */
> +    msr &= ~(1ULL << MSR_POW);
> +
>  #if defined(TARGET_PPC64)
> -    if (msr_is_64bit(env, msr)) {
> -        nip = (uint64_t)nip;
> -        msr &= (uint64_t)msrm;
> -    } else {
> +    /* Switching to 32-bit ? Crop the nip */
> +    if (!msr_is_64bit(env, msr)) {
>          nip = (uint32_t)nip;
> -        msr = (uint32_t)(msr & msrm);
> -        if (keep_msrh) {
> -            msr |= env->msr & ~((uint64_t)0xFFFFFFFF);
> -        }
>      }
>  #else
>      nip = (uint32_t)nip;
> -    msr &= (uint32_t)msrm;
>  #endif
>      /* XXX: beware: this is false if VLE is supported */
>      env->nip = nip & ~((target_ulong)0x00000003);
> @@ -959,26 +954,24 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
>  
>  void helper_rfi(CPUPPCState *env)
>  {
> -    if (env->excp_model == POWERPC_EXCP_BOOKE) {
> -        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
> -               ~((target_ulong)0), 0);
> -    } else {
> -        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
> -               ~((target_ulong)0x783F0000), 1);
> -    }
> +    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
>  }
>  
> +#define MSR_BOOK3S_MASK
>  #if defined(TARGET_PPC64)
>  void helper_rfid(CPUPPCState *env)
>  {
> -    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
> -           ~((target_ulong)0x783F0000), 0);
> +    /* The architeture defines a number of rules for which bits
> +     * can change but in practice, we handle this in hreg_store_msr()
> +     * which will be called by do_rfi(), so there is no need to filter
> +     * here
> +     */
> +    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
>  }
>  
>  void helper_hrfid(CPUPPCState *env)
>  {
> -    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
> -           ~((target_ulong)0x783F0000), 0);
> +    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
>  }
>  #endif
>  
> @@ -986,28 +979,24 @@ void helper_hrfid(CPUPPCState *env)
>  /* Embedded PowerPC specific helpers */
>  void helper_40x_rfci(CPUPPCState *env)
>  {
> -    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3],
> -           ~((target_ulong)0xFFFF0000), 0);
> +    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
>  }
>  
>  void helper_rfci(CPUPPCState *env)
>  {
> -    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
> -           ~((target_ulong)0), 0);
> +    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
>  }
>  
>  void helper_rfdi(CPUPPCState *env)
>  {
>      /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
> -    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1],
> -           ~((target_ulong)0), 0);
> +    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
>  }
>  
>  void helper_rfmci(CPUPPCState *env)
>  {
>      /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
> -    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1],
> -           ~((target_ulong)0), 0);
> +    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
>  }
>  #endif
>  
> @@ -1045,7 +1034,7 @@ void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
>  
>  void helper_rfsvc(CPUPPCState *env)
>  {
> -    do_rfi(env, env->lr, env->ctr, 0x0000FFFF, 0);
> +    do_rfi(env, env->lr, env->ctr & 0x0000FFFF);
>  }
>  
>  /* Embedded.Processor Control */
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index b6894751e8df..a02ddf52bfe6 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -4087,6 +4087,13 @@ static void gen_rfi(DisasContext *ctx)
>  #if defined(CONFIG_USER_ONLY)
>      gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
>  #else
> +    /* This instruction doesn't exist anymore on 64-bit server
> +     * processors compliant with arch 2.x
> +     */
> +    if (ctx->insns_flags & PPC_SEGMENT_64B) {
> +        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
> +        return;
> +    }
>      /* Restore CPU state */
>      if (unlikely(ctx->pr)) {
>          gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-16  1:07   ` David Gibson
@ 2016-06-17  2:27     ` David Gibson
  2016-06-17  5:54       ` Cédric Le Goater
  2016-06-17  6:19     ` [Qemu-devel] " Cédric Le Goater
  1 sibling, 1 reply; 68+ messages in thread
From: David Gibson @ 2016-06-17  2:27 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 6559 bytes --]

On Thu, Jun 16, 2016 at 11:07:02AM +1000, David Gibson wrote:
> On Mon, Jun 13, 2016 at 07:24:47AM +0200, Cédric Le Goater wrote:
> > From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > 
> > This reworks emulation of the various "rfi" variants. I removed
> > some masking bits that I couldn't make sense of, the only bit that
> > I am aware we should mask here is POW, the CPU's MSR mask should
> > take care of the rest.
> > 
> > This also fixes some problems when running 32-bit userspace under
> > a 64-bit kernel.
> > 
> > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> 
> I've merged this patch to ppc-for-2.7.

..and now I've removed it again.  It seems that this breaks Thomas'
new test that OpenBIOS runs on the mac machine types.  Not sure why,
but we need to figure that out before I apply.

> The reset of the series I'd like to see a respin for, even if it's
> just to clean up the commit messages.
> 
> > ---
> >  target-ppc/excp_helper.c | 51 +++++++++++++++++++-----------------------------
> >  target-ppc/translate.c   |  7 +++++++
> >  2 files changed, 27 insertions(+), 31 deletions(-)
> > 
> > diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> > index 30e960e30b63..aa0b63f4b0de 100644
> > --- a/target-ppc/excp_helper.c
> > +++ b/target-ppc/excp_helper.c
> > @@ -922,25 +922,20 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
> >      }
> >  }
> >  
> > -static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
> > -                          target_ulong msrm, int keep_msrh)
> > +static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
> >  {
> >      CPUState *cs = CPU(ppc_env_get_cpu(env));
> >  
> > +    /* MSR:POW cannot be set by any form of rfi */
> > +    msr &= ~(1ULL << MSR_POW);
> > +
> >  #if defined(TARGET_PPC64)
> > -    if (msr_is_64bit(env, msr)) {
> > -        nip = (uint64_t)nip;
> > -        msr &= (uint64_t)msrm;
> > -    } else {
> > +    /* Switching to 32-bit ? Crop the nip */
> > +    if (!msr_is_64bit(env, msr)) {
> >          nip = (uint32_t)nip;
> > -        msr = (uint32_t)(msr & msrm);
> > -        if (keep_msrh) {
> > -            msr |= env->msr & ~((uint64_t)0xFFFFFFFF);
> > -        }
> >      }
> >  #else
> >      nip = (uint32_t)nip;
> > -    msr &= (uint32_t)msrm;
> >  #endif
> >      /* XXX: beware: this is false if VLE is supported */
> >      env->nip = nip & ~((target_ulong)0x00000003);
> > @@ -959,26 +954,24 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
> >  
> >  void helper_rfi(CPUPPCState *env)
> >  {
> > -    if (env->excp_model == POWERPC_EXCP_BOOKE) {
> > -        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
> > -               ~((target_ulong)0), 0);
> > -    } else {
> > -        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
> > -               ~((target_ulong)0x783F0000), 1);
> > -    }
> > +    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
> >  }
> >  
> > +#define MSR_BOOK3S_MASK
> >  #if defined(TARGET_PPC64)
> >  void helper_rfid(CPUPPCState *env)
> >  {
> > -    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
> > -           ~((target_ulong)0x783F0000), 0);
> > +    /* The architeture defines a number of rules for which bits
> > +     * can change but in practice, we handle this in hreg_store_msr()
> > +     * which will be called by do_rfi(), so there is no need to filter
> > +     * here
> > +     */
> > +    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
> >  }
> >  
> >  void helper_hrfid(CPUPPCState *env)
> >  {
> > -    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
> > -           ~((target_ulong)0x783F0000), 0);
> > +    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
> >  }
> >  #endif
> >  
> > @@ -986,28 +979,24 @@ void helper_hrfid(CPUPPCState *env)
> >  /* Embedded PowerPC specific helpers */
> >  void helper_40x_rfci(CPUPPCState *env)
> >  {
> > -    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3],
> > -           ~((target_ulong)0xFFFF0000), 0);
> > +    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
> >  }
> >  
> >  void helper_rfci(CPUPPCState *env)
> >  {
> > -    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
> > -           ~((target_ulong)0), 0);
> > +    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
> >  }
> >  
> >  void helper_rfdi(CPUPPCState *env)
> >  {
> >      /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
> > -    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1],
> > -           ~((target_ulong)0), 0);
> > +    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
> >  }
> >  
> >  void helper_rfmci(CPUPPCState *env)
> >  {
> >      /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
> > -    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1],
> > -           ~((target_ulong)0), 0);
> > +    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
> >  }
> >  #endif
> >  
> > @@ -1045,7 +1034,7 @@ void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
> >  
> >  void helper_rfsvc(CPUPPCState *env)
> >  {
> > -    do_rfi(env, env->lr, env->ctr, 0x0000FFFF, 0);
> > +    do_rfi(env, env->lr, env->ctr & 0x0000FFFF);
> >  }
> >  
> >  /* Embedded.Processor Control */
> > diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> > index b6894751e8df..a02ddf52bfe6 100644
> > --- a/target-ppc/translate.c
> > +++ b/target-ppc/translate.c
> > @@ -4087,6 +4087,13 @@ static void gen_rfi(DisasContext *ctx)
> >  #if defined(CONFIG_USER_ONLY)
> >      gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> >  #else
> > +    /* This instruction doesn't exist anymore on 64-bit server
> > +     * processors compliant with arch 2.x
> > +     */
> > +    if (ctx->insns_flags & PPC_SEGMENT_64B) {
> > +        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
> > +        return;
> > +    }
> >      /* Restore CPU state */
> >      if (unlikely(ctx->pr)) {
> >          gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> 



-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-17  2:27     ` [Qemu-devel] [Qemu-ppc] " David Gibson
@ 2016-06-17  5:54       ` Cédric Le Goater
  2016-06-17  6:03         ` Cédric Le Goater
  0 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-17  5:54 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 06/17/2016 04:27 AM, David Gibson wrote:
> On Thu, Jun 16, 2016 at 11:07:02AM +1000, David Gibson wrote:
>> On Mon, Jun 13, 2016 at 07:24:47AM +0200, Cédric Le Goater wrote:
>>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>
>>> This reworks emulation of the various "rfi" variants. I removed
>>> some masking bits that I couldn't make sense of, the only bit that
>>> I am aware we should mask here is POW, the CPU's MSR mask should
>>> take care of the rest.
>>>
>>> This also fixes some problems when running 32-bit userspace under
>>> a 64-bit kernel.
>>>
>>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>>
>> I've merged this patch to ppc-for-2.7.
> 
> ..and now I've removed it again.  It seems that this breaks Thomas'
> new test that OpenBIOS runs on the mac machine types.  Not sure why,
> but we need to figure that out before I apply.

Just this patch ? I booted a macosx image with it. but maybe just a mac99.
I will check today.

C. 

>> The reset of the series I'd like to see a respin for, even if it's
>> just to clean up the commit messages.
>>
>>> ---
>>>  target-ppc/excp_helper.c | 51 +++++++++++++++++++-----------------------------
>>>  target-ppc/translate.c   |  7 +++++++
>>>  2 files changed, 27 insertions(+), 31 deletions(-)
>>>
>>> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
>>> index 30e960e30b63..aa0b63f4b0de 100644
>>> --- a/target-ppc/excp_helper.c
>>> +++ b/target-ppc/excp_helper.c
>>> @@ -922,25 +922,20 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
>>>      }
>>>  }
>>>  
>>> -static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
>>> -                          target_ulong msrm, int keep_msrh)
>>> +static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
>>>  {
>>>      CPUState *cs = CPU(ppc_env_get_cpu(env));
>>>  
>>> +    /* MSR:POW cannot be set by any form of rfi */
>>> +    msr &= ~(1ULL << MSR_POW);
>>> +
>>>  #if defined(TARGET_PPC64)
>>> -    if (msr_is_64bit(env, msr)) {
>>> -        nip = (uint64_t)nip;
>>> -        msr &= (uint64_t)msrm;
>>> -    } else {
>>> +    /* Switching to 32-bit ? Crop the nip */
>>> +    if (!msr_is_64bit(env, msr)) {
>>>          nip = (uint32_t)nip;
>>> -        msr = (uint32_t)(msr & msrm);
>>> -        if (keep_msrh) {
>>> -            msr |= env->msr & ~((uint64_t)0xFFFFFFFF);
>>> -        }
>>>      }
>>>  #else
>>>      nip = (uint32_t)nip;
>>> -    msr &= (uint32_t)msrm;
>>>  #endif
>>>      /* XXX: beware: this is false if VLE is supported */
>>>      env->nip = nip & ~((target_ulong)0x00000003);
>>> @@ -959,26 +954,24 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
>>>  
>>>  void helper_rfi(CPUPPCState *env)
>>>  {
>>> -    if (env->excp_model == POWERPC_EXCP_BOOKE) {
>>> -        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
>>> -               ~((target_ulong)0), 0);
>>> -    } else {
>>> -        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
>>> -               ~((target_ulong)0x783F0000), 1);
>>> -    }
>>> +    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
>>>  }
>>>  
>>> +#define MSR_BOOK3S_MASK
>>>  #if defined(TARGET_PPC64)
>>>  void helper_rfid(CPUPPCState *env)
>>>  {
>>> -    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
>>> -           ~((target_ulong)0x783F0000), 0);
>>> +    /* The architeture defines a number of rules for which bits
>>> +     * can change but in practice, we handle this in hreg_store_msr()
>>> +     * which will be called by do_rfi(), so there is no need to filter
>>> +     * here
>>> +     */
>>> +    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
>>>  }
>>>  
>>>  void helper_hrfid(CPUPPCState *env)
>>>  {
>>> -    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
>>> -           ~((target_ulong)0x783F0000), 0);
>>> +    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
>>>  }
>>>  #endif
>>>  
>>> @@ -986,28 +979,24 @@ void helper_hrfid(CPUPPCState *env)
>>>  /* Embedded PowerPC specific helpers */
>>>  void helper_40x_rfci(CPUPPCState *env)
>>>  {
>>> -    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3],
>>> -           ~((target_ulong)0xFFFF0000), 0);
>>> +    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
>>>  }
>>>  
>>>  void helper_rfci(CPUPPCState *env)
>>>  {
>>> -    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
>>> -           ~((target_ulong)0), 0);
>>> +    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
>>>  }
>>>  
>>>  void helper_rfdi(CPUPPCState *env)
>>>  {
>>>      /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
>>> -    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1],
>>> -           ~((target_ulong)0), 0);
>>> +    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
>>>  }
>>>  
>>>  void helper_rfmci(CPUPPCState *env)
>>>  {
>>>      /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
>>> -    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1],
>>> -           ~((target_ulong)0), 0);
>>> +    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
>>>  }
>>>  #endif
>>>  
>>> @@ -1045,7 +1034,7 @@ void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
>>>  
>>>  void helper_rfsvc(CPUPPCState *env)
>>>  {
>>> -    do_rfi(env, env->lr, env->ctr, 0x0000FFFF, 0);
>>> +    do_rfi(env, env->lr, env->ctr & 0x0000FFFF);
>>>  }
>>>  
>>>  /* Embedded.Processor Control */
>>> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
>>> index b6894751e8df..a02ddf52bfe6 100644
>>> --- a/target-ppc/translate.c
>>> +++ b/target-ppc/translate.c
>>> @@ -4087,6 +4087,13 @@ static void gen_rfi(DisasContext *ctx)
>>>  #if defined(CONFIG_USER_ONLY)
>>>      gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
>>>  #else
>>> +    /* This instruction doesn't exist anymore on 64-bit server
>>> +     * processors compliant with arch 2.x
>>> +     */
>>> +    if (ctx->insns_flags & PPC_SEGMENT_64B) {
>>> +        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
>>> +        return;
>>> +    }
>>>      /* Restore CPU state */
>>>      if (unlikely(ctx->pr)) {
>>>          gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
>>
> 
> 
> 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-17  5:54       ` Cédric Le Goater
@ 2016-06-17  6:03         ` Cédric Le Goater
  2016-06-17  6:28           ` David Gibson
  2016-06-17  7:10           ` Thomas Huth
  0 siblings, 2 replies; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-17  6:03 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 06/17/2016 07:54 AM, Cédric Le Goater wrote:
> On 06/17/2016 04:27 AM, David Gibson wrote:
>> On Thu, Jun 16, 2016 at 11:07:02AM +1000, David Gibson wrote:
>>> On Mon, Jun 13, 2016 at 07:24:47AM +0200, Cédric Le Goater wrote:
>>>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>
>>>> This reworks emulation of the various "rfi" variants. I removed
>>>> some masking bits that I couldn't make sense of, the only bit that
>>>> I am aware we should mask here is POW, the CPU's MSR mask should
>>>> take care of the rest.
>>>>
>>>> This also fixes some problems when running 32-bit userspace under
>>>> a 64-bit kernel.
>>>>
>>>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>>>
>>> I've merged this patch to ppc-for-2.7.
>>
>> ..and now I've removed it again.  It seems that this breaks Thomas'
>> new test that OpenBIOS runs on the mac machine types.  Not sure why,
>> but we need to figure that out before I apply.
> 
> Just this patch ? I booted a macosx image with it. but maybe just a mac99.
> I will check today.

With your branch ppc-for-2.7 (at commit aba2e6258d86) + the 
"ppc: Fix rfi/rfid/hrfi/... emulation" patch, these guests : 

	qemu-system-ppc -cdrom ./darwinppc-602.cdr -boot d 
	qemu-system-ppc -M mac99 -cdrom ./darwinppc-602.cdr -boot d 

reach the installer macosx installer.

C.

>>> The reset of the series I'd like to see a respin for, even if it's
>>> just to clean up the commit messages.
>>>
>>>> ---
>>>>  target-ppc/excp_helper.c | 51 +++++++++++++++++++-----------------------------
>>>>  target-ppc/translate.c   |  7 +++++++
>>>>  2 files changed, 27 insertions(+), 31 deletions(-)
>>>>
>>>> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
>>>> index 30e960e30b63..aa0b63f4b0de 100644
>>>> --- a/target-ppc/excp_helper.c
>>>> +++ b/target-ppc/excp_helper.c
>>>> @@ -922,25 +922,20 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
>>>>      }
>>>>  }
>>>>  
>>>> -static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
>>>> -                          target_ulong msrm, int keep_msrh)
>>>> +static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
>>>>  {
>>>>      CPUState *cs = CPU(ppc_env_get_cpu(env));
>>>>  
>>>> +    /* MSR:POW cannot be set by any form of rfi */
>>>> +    msr &= ~(1ULL << MSR_POW);
>>>> +
>>>>  #if defined(TARGET_PPC64)
>>>> -    if (msr_is_64bit(env, msr)) {
>>>> -        nip = (uint64_t)nip;
>>>> -        msr &= (uint64_t)msrm;
>>>> -    } else {
>>>> +    /* Switching to 32-bit ? Crop the nip */
>>>> +    if (!msr_is_64bit(env, msr)) {
>>>>          nip = (uint32_t)nip;
>>>> -        msr = (uint32_t)(msr & msrm);
>>>> -        if (keep_msrh) {
>>>> -            msr |= env->msr & ~((uint64_t)0xFFFFFFFF);
>>>> -        }
>>>>      }
>>>>  #else
>>>>      nip = (uint32_t)nip;
>>>> -    msr &= (uint32_t)msrm;
>>>>  #endif
>>>>      /* XXX: beware: this is false if VLE is supported */
>>>>      env->nip = nip & ~((target_ulong)0x00000003);
>>>> @@ -959,26 +954,24 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
>>>>  
>>>>  void helper_rfi(CPUPPCState *env)
>>>>  {
>>>> -    if (env->excp_model == POWERPC_EXCP_BOOKE) {
>>>> -        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
>>>> -               ~((target_ulong)0), 0);
>>>> -    } else {
>>>> -        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
>>>> -               ~((target_ulong)0x783F0000), 1);
>>>> -    }
>>>> +    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
>>>>  }
>>>>  
>>>> +#define MSR_BOOK3S_MASK
>>>>  #if defined(TARGET_PPC64)
>>>>  void helper_rfid(CPUPPCState *env)
>>>>  {
>>>> -    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
>>>> -           ~((target_ulong)0x783F0000), 0);
>>>> +    /* The architeture defines a number of rules for which bits
>>>> +     * can change but in practice, we handle this in hreg_store_msr()
>>>> +     * which will be called by do_rfi(), so there is no need to filter
>>>> +     * here
>>>> +     */
>>>> +    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
>>>>  }
>>>>  
>>>>  void helper_hrfid(CPUPPCState *env)
>>>>  {
>>>> -    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
>>>> -           ~((target_ulong)0x783F0000), 0);
>>>> +    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
>>>>  }
>>>>  #endif
>>>>  
>>>> @@ -986,28 +979,24 @@ void helper_hrfid(CPUPPCState *env)
>>>>  /* Embedded PowerPC specific helpers */
>>>>  void helper_40x_rfci(CPUPPCState *env)
>>>>  {
>>>> -    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3],
>>>> -           ~((target_ulong)0xFFFF0000), 0);
>>>> +    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
>>>>  }
>>>>  
>>>>  void helper_rfci(CPUPPCState *env)
>>>>  {
>>>> -    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
>>>> -           ~((target_ulong)0), 0);
>>>> +    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
>>>>  }
>>>>  
>>>>  void helper_rfdi(CPUPPCState *env)
>>>>  {
>>>>      /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
>>>> -    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1],
>>>> -           ~((target_ulong)0), 0);
>>>> +    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
>>>>  }
>>>>  
>>>>  void helper_rfmci(CPUPPCState *env)
>>>>  {
>>>>      /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
>>>> -    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1],
>>>> -           ~((target_ulong)0), 0);
>>>> +    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
>>>>  }
>>>>  #endif
>>>>  
>>>> @@ -1045,7 +1034,7 @@ void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
>>>>  
>>>>  void helper_rfsvc(CPUPPCState *env)
>>>>  {
>>>> -    do_rfi(env, env->lr, env->ctr, 0x0000FFFF, 0);
>>>> +    do_rfi(env, env->lr, env->ctr & 0x0000FFFF);
>>>>  }
>>>>  
>>>>  /* Embedded.Processor Control */
>>>> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
>>>> index b6894751e8df..a02ddf52bfe6 100644
>>>> --- a/target-ppc/translate.c
>>>> +++ b/target-ppc/translate.c
>>>> @@ -4087,6 +4087,13 @@ static void gen_rfi(DisasContext *ctx)
>>>>  #if defined(CONFIG_USER_ONLY)
>>>>      gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
>>>>  #else
>>>> +    /* This instruction doesn't exist anymore on 64-bit server
>>>> +     * processors compliant with arch 2.x
>>>> +     */
>>>> +    if (ctx->insns_flags & PPC_SEGMENT_64B) {
>>>> +        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
>>>> +        return;
>>>> +    }
>>>>      /* Restore CPU state */
>>>>      if (unlikely(ctx->pr)) {
>>>>          gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
>>>
>>
>>
>>
> 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-16  1:07   ` David Gibson
  2016-06-17  2:27     ` [Qemu-devel] [Qemu-ppc] " David Gibson
@ 2016-06-17  6:19     ` Cédric Le Goater
  1 sibling, 0 replies; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-17  6:19 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Benjamin Herrenschmidt

On 06/16/2016 03:07 AM, David Gibson wrote:
> On Mon, Jun 13, 2016 at 07:24:47AM +0200, Cédric Le Goater wrote:
>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>
>> This reworks emulation of the various "rfi" variants. I removed
>> some masking bits that I couldn't make sense of, the only bit that
>> I am aware we should mask here is POW, the CPU's MSR mask should
>> take care of the rest.
>>
>> This also fixes some problems when running 32-bit userspace under
>> a 64-bit kernel.
>>
>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> 
> I've merged this patch to ppc-for-2.7.
> 
> The reset of the series I'd like to see a respin for, even if it's
> just to clean up the commit messages.

Yes. I noted a couple of commit messages to rephrase, the "inline"
removal patch to keep and a merge of Andrei patches for HV {I,D}SI.

I will get that going once I have a better idea on a block I/O
issue I see with another patchset. I am really pulling my hair 
on this one. Spent the week on it :/ The good thing is that it
made me write a unit test !


Cheers,

C.

>> ---
>>  target-ppc/excp_helper.c | 51 +++++++++++++++++++-----------------------------
>>  target-ppc/translate.c   |  7 +++++++
>>  2 files changed, 27 insertions(+), 31 deletions(-)
>>
>> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
>> index 30e960e30b63..aa0b63f4b0de 100644
>> --- a/target-ppc/excp_helper.c
>> +++ b/target-ppc/excp_helper.c
>> @@ -922,25 +922,20 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
>>      }
>>  }
>>  
>> -static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
>> -                          target_ulong msrm, int keep_msrh)
>> +static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
>>  {
>>      CPUState *cs = CPU(ppc_env_get_cpu(env));
>>  
>> +    /* MSR:POW cannot be set by any form of rfi */
>> +    msr &= ~(1ULL << MSR_POW);
>> +
>>  #if defined(TARGET_PPC64)
>> -    if (msr_is_64bit(env, msr)) {
>> -        nip = (uint64_t)nip;
>> -        msr &= (uint64_t)msrm;
>> -    } else {
>> +    /* Switching to 32-bit ? Crop the nip */
>> +    if (!msr_is_64bit(env, msr)) {
>>          nip = (uint32_t)nip;
>> -        msr = (uint32_t)(msr & msrm);
>> -        if (keep_msrh) {
>> -            msr |= env->msr & ~((uint64_t)0xFFFFFFFF);
>> -        }
>>      }
>>  #else
>>      nip = (uint32_t)nip;
>> -    msr &= (uint32_t)msrm;
>>  #endif
>>      /* XXX: beware: this is false if VLE is supported */
>>      env->nip = nip & ~((target_ulong)0x00000003);
>> @@ -959,26 +954,24 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
>>  
>>  void helper_rfi(CPUPPCState *env)
>>  {
>> -    if (env->excp_model == POWERPC_EXCP_BOOKE) {
>> -        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
>> -               ~((target_ulong)0), 0);
>> -    } else {
>> -        do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
>> -               ~((target_ulong)0x783F0000), 1);
>> -    }
>> +    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
>>  }
>>  
>> +#define MSR_BOOK3S_MASK
>>  #if defined(TARGET_PPC64)
>>  void helper_rfid(CPUPPCState *env)
>>  {
>> -    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
>> -           ~((target_ulong)0x783F0000), 0);
>> +    /* The architeture defines a number of rules for which bits
>> +     * can change but in practice, we handle this in hreg_store_msr()
>> +     * which will be called by do_rfi(), so there is no need to filter
>> +     * here
>> +     */
>> +    do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
>>  }
>>  
>>  void helper_hrfid(CPUPPCState *env)
>>  {
>> -    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
>> -           ~((target_ulong)0x783F0000), 0);
>> +    do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
>>  }
>>  #endif
>>  
>> @@ -986,28 +979,24 @@ void helper_hrfid(CPUPPCState *env)
>>  /* Embedded PowerPC specific helpers */
>>  void helper_40x_rfci(CPUPPCState *env)
>>  {
>> -    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3],
>> -           ~((target_ulong)0xFFFF0000), 0);
>> +    do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
>>  }
>>  
>>  void helper_rfci(CPUPPCState *env)
>>  {
>> -    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
>> -           ~((target_ulong)0), 0);
>> +    do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
>>  }
>>  
>>  void helper_rfdi(CPUPPCState *env)
>>  {
>>      /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
>> -    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1],
>> -           ~((target_ulong)0), 0);
>> +    do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
>>  }
>>  
>>  void helper_rfmci(CPUPPCState *env)
>>  {
>>      /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
>> -    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1],
>> -           ~((target_ulong)0), 0);
>> +    do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
>>  }
>>  #endif
>>  
>> @@ -1045,7 +1034,7 @@ void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
>>  
>>  void helper_rfsvc(CPUPPCState *env)
>>  {
>> -    do_rfi(env, env->lr, env->ctr, 0x0000FFFF, 0);
>> +    do_rfi(env, env->lr, env->ctr & 0x0000FFFF);
>>  }
>>  
>>  /* Embedded.Processor Control */
>> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
>> index b6894751e8df..a02ddf52bfe6 100644
>> --- a/target-ppc/translate.c
>> +++ b/target-ppc/translate.c
>> @@ -4087,6 +4087,13 @@ static void gen_rfi(DisasContext *ctx)
>>  #if defined(CONFIG_USER_ONLY)
>>      gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
>>  #else
>> +    /* This instruction doesn't exist anymore on 64-bit server
>> +     * processors compliant with arch 2.x
>> +     */
>> +    if (ctx->insns_flags & PPC_SEGMENT_64B) {
>> +        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
>> +        return;
>> +    }
>>      /* Restore CPU state */
>>      if (unlikely(ctx->pr)) {
>>          gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-17  6:03         ` Cédric Le Goater
@ 2016-06-17  6:28           ` David Gibson
  2016-06-17  6:39             ` Cédric Le Goater
  2016-06-17  7:10           ` Thomas Huth
  1 sibling, 1 reply; 68+ messages in thread
From: David Gibson @ 2016-06-17  6:28 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1805 bytes --]

On Fri, Jun 17, 2016 at 08:03:29AM +0200, Cédric Le Goater wrote:
> On 06/17/2016 07:54 AM, Cédric Le Goater wrote:
> > On 06/17/2016 04:27 AM, David Gibson wrote:
> >> On Thu, Jun 16, 2016 at 11:07:02AM +1000, David Gibson wrote:
> >>> On Mon, Jun 13, 2016 at 07:24:47AM +0200, Cédric Le Goater wrote:
> >>>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> >>>>
> >>>> This reworks emulation of the various "rfi" variants. I removed
> >>>> some masking bits that I couldn't make sense of, the only bit that
> >>>> I am aware we should mask here is POW, the CPU's MSR mask should
> >>>> take care of the rest.
> >>>>
> >>>> This also fixes some problems when running 32-bit userspace under
> >>>> a 64-bit kernel.
> >>>>
> >>>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> >>>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> >>>
> >>> I've merged this patch to ppc-for-2.7.
> >>
> >> ..and now I've removed it again.  It seems that this breaks Thomas'
> >> new test that OpenBIOS runs on the mac machine types.  Not sure why,
> >> but we need to figure that out before I apply.
> > 
> > Just this patch ? I booted a macosx image with it. but maybe just a mac99.
> > I will check today.
> 
> With your branch ppc-for-2.7 (at commit aba2e6258d86) + the 
> "ppc: Fix rfi/rfid/hrfi/... emulation" patch, these guests : 
> 
> 	qemu-system-ppc -cdrom ./darwinppc-602.cdr -boot d 
> 	qemu-system-ppc -M mac99 -cdrom ./darwinppc-602.cdr -boot d 
> 
> reach the installer macosx installer.

But the prom-env-test from make check fails :(.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-17  6:28           ` David Gibson
@ 2016-06-17  6:39             ` Cédric Le Goater
  0 siblings, 0 replies; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-17  6:39 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel

On 06/17/2016 08:28 AM, David Gibson wrote:
> On Fri, Jun 17, 2016 at 08:03:29AM +0200, Cédric Le Goater wrote:
>> On 06/17/2016 07:54 AM, Cédric Le Goater wrote:
>>> On 06/17/2016 04:27 AM, David Gibson wrote:
>>>> On Thu, Jun 16, 2016 at 11:07:02AM +1000, David Gibson wrote:
>>>>> On Mon, Jun 13, 2016 at 07:24:47AM +0200, Cédric Le Goater wrote:
>>>>>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>>
>>>>>> This reworks emulation of the various "rfi" variants. I removed
>>>>>> some masking bits that I couldn't make sense of, the only bit that
>>>>>> I am aware we should mask here is POW, the CPU's MSR mask should
>>>>>> take care of the rest.
>>>>>>
>>>>>> This also fixes some problems when running 32-bit userspace under
>>>>>> a 64-bit kernel.
>>>>>>
>>>>>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>>>>>
>>>>> I've merged this patch to ppc-for-2.7.
>>>>
>>>> ..and now I've removed it again.  It seems that this breaks Thomas'
>>>> new test that OpenBIOS runs on the mac machine types.  Not sure why,
>>>> but we need to figure that out before I apply.
>>>
>>> Just this patch ? I booted a macosx image with it. but maybe just a mac99.
>>> I will check today.
>>
>> With your branch ppc-for-2.7 (at commit aba2e6258d86) + the 
>> "ppc: Fix rfi/rfid/hrfi/... emulation" patch, these guests : 
>>
>> 	qemu-system-ppc -cdrom ./darwinppc-602.cdr -boot d 
>> 	qemu-system-ppc -M mac99 -cdrom ./darwinppc-602.cdr -boot d 
>>
>> reach the installer macosx installer.
> 
> But the prom-env-test from make check fails :(.
> 

I do not see the issue on ppc-for-2.7 (commit aba2e6258d86) + the 
"ppc: Fix rfi/rfid/hrfi/... emulation" patch. 

I will update during the day and let you know.

Cheers,

C.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-17  6:03         ` Cédric Le Goater
  2016-06-17  6:28           ` David Gibson
@ 2016-06-17  7:10           ` Thomas Huth
  2016-06-17  7:17             ` Cédric Le Goater
  2016-06-17 10:41             ` Cédric Le Goater
  1 sibling, 2 replies; 68+ messages in thread
From: Thomas Huth @ 2016-06-17  7:10 UTC (permalink / raw)
  To: Cédric Le Goater, David Gibson; +Cc: qemu-ppc, qemu-devel

On 17.06.2016 08:03, Cédric Le Goater wrote:
> On 06/17/2016 07:54 AM, Cédric Le Goater wrote:
>> On 06/17/2016 04:27 AM, David Gibson wrote:
>>> On Thu, Jun 16, 2016 at 11:07:02AM +1000, David Gibson wrote:
>>>> On Mon, Jun 13, 2016 at 07:24:47AM +0200, Cédric Le Goater wrote:
>>>>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>
>>>>> This reworks emulation of the various "rfi" variants. I removed
>>>>> some masking bits that I couldn't make sense of, the only bit that
>>>>> I am aware we should mask here is POW, the CPU's MSR mask should
>>>>> take care of the rest.
>>>>>
>>>>> This also fixes some problems when running 32-bit userspace under
>>>>> a 64-bit kernel.
>>>>>
>>>>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>>>>
>>>> I've merged this patch to ppc-for-2.7.
>>>
>>> ..and now I've removed it again.  It seems that this breaks Thomas'
>>> new test that OpenBIOS runs on the mac machine types.  Not sure why,
>>> but we need to figure that out before I apply.
>>
>> Just this patch ? I booted a macosx image with it. but maybe just a mac99.
>> I will check today.
> 
> With your branch ppc-for-2.7 (at commit aba2e6258d86) + the 
> "ppc: Fix rfi/rfid/hrfi/... emulation" patch, these guests : 
> 
> 	qemu-system-ppc -cdrom ./darwinppc-602.cdr -boot d 
> 	qemu-system-ppc -M mac99 -cdrom ./darwinppc-602.cdr -boot d 
                       ^
                       |
You're missing the "64" here ;-)

> reach the installer macosx installer.

It seems to be only failing for the 64-bit builds - and there only for
the PPC970 CPU (which is the default for the mac99 machine in 64-bit
builds):

qemu-system-ppc64 -nographic -cpu 750 -M mac99 ==> works fine

qemu-system-ppc64 -nographic -cpu 970 -M mac99 ==> hangs

 Thomas

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-17  7:10           ` Thomas Huth
@ 2016-06-17  7:17             ` Cédric Le Goater
  2016-06-17 10:41             ` Cédric Le Goater
  1 sibling, 0 replies; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-17  7:17 UTC (permalink / raw)
  To: Thomas Huth, David Gibson; +Cc: qemu-ppc, qemu-devel

On 06/17/2016 09:10 AM, Thomas Huth wrote:
> On 17.06.2016 08:03, Cédric Le Goater wrote:
>> On 06/17/2016 07:54 AM, Cédric Le Goater wrote:
>>> On 06/17/2016 04:27 AM, David Gibson wrote:
>>>> On Thu, Jun 16, 2016 at 11:07:02AM +1000, David Gibson wrote:
>>>>> On Mon, Jun 13, 2016 at 07:24:47AM +0200, Cédric Le Goater wrote:
>>>>>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>>
>>>>>> This reworks emulation of the various "rfi" variants. I removed
>>>>>> some masking bits that I couldn't make sense of, the only bit that
>>>>>> I am aware we should mask here is POW, the CPU's MSR mask should
>>>>>> take care of the rest.
>>>>>>
>>>>>> This also fixes some problems when running 32-bit userspace under
>>>>>> a 64-bit kernel.
>>>>>>
>>>>>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>>>>>
>>>>> I've merged this patch to ppc-for-2.7.
>>>>
>>>> ..and now I've removed it again.  It seems that this breaks Thomas'
>>>> new test that OpenBIOS runs on the mac machine types.  Not sure why,
>>>> but we need to figure that out before I apply.
>>>
>>> Just this patch ? I booted a macosx image with it. but maybe just a mac99.
>>> I will check today.
>>
>> With your branch ppc-for-2.7 (at commit aba2e6258d86) + the 
>> "ppc: Fix rfi/rfid/hrfi/... emulation" patch, these guests : 
>>
>> 	qemu-system-ppc -cdrom ./darwinppc-602.cdr -boot d 
>> 	qemu-system-ppc -M mac99 -cdrom ./darwinppc-602.cdr -boot d 
>                        ^
>                        |
> You're missing the "64" here ;-)

ah ! I never use the 64 bit version for these but I should. I will give
a try.

Thanks,

C.

>> reach the installer macosx installer.
> 
> It seems to be only failing for the 64-bit builds - and there only for
> the PPC970 CPU (which is the default for the mac99 machine in 64-bit
> builds):
> 
> qemu-system-ppc64 -nographic -cpu 750 -M mac99 ==> works fine
> 
> qemu-system-ppc64 -nographic -cpu 970 -M mac99 ==> hangs
> 
>  Thomas
> 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-17  7:10           ` Thomas Huth
  2016-06-17  7:17             ` Cédric Le Goater
@ 2016-06-17 10:41             ` Cédric Le Goater
  2016-06-17 11:02               ` Thomas Huth
  2016-06-18 23:29               ` Benjamin Herrenschmidt
  1 sibling, 2 replies; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-17 10:41 UTC (permalink / raw)
  To: Thomas Huth, David Gibson; +Cc: qemu-ppc, qemu-devel

On 06/17/2016 09:10 AM, Thomas Huth wrote:
> On 17.06.2016 08:03, Cédric Le Goater wrote:
>> On 06/17/2016 07:54 AM, Cédric Le Goater wrote:
>>> On 06/17/2016 04:27 AM, David Gibson wrote:
>>>> On Thu, Jun 16, 2016 at 11:07:02AM +1000, David Gibson wrote:
>>>>> On Mon, Jun 13, 2016 at 07:24:47AM +0200, Cédric Le Goater wrote:
>>>>>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>>
>>>>>> This reworks emulation of the various "rfi" variants. I removed
>>>>>> some masking bits that I couldn't make sense of, the only bit that
>>>>>> I am aware we should mask here is POW, the CPU's MSR mask should
>>>>>> take care of the rest.
>>>>>>
>>>>>> This also fixes some problems when running 32-bit userspace under
>>>>>> a 64-bit kernel.

he.

>>>>>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>>>>>
>>>>> I've merged this patch to ppc-for-2.7.
>>>>
>>>> ..and now I've removed it again.  It seems that this breaks Thomas'
>>>> new test that OpenBIOS runs on the mac machine types.  Not sure why,
>>>> but we need to figure that out before I apply.
>>>
>>> Just this patch ? I booted a macosx image with it. but maybe just a mac99.
>>> I will check today.
>>
>> With your branch ppc-for-2.7 (at commit aba2e6258d86) + the 
>> "ppc: Fix rfi/rfid/hrfi/... emulation" patch, these guests : 
>>
>> 	qemu-system-ppc -cdrom ./darwinppc-602.cdr -boot d 
>> 	qemu-system-ppc -M mac99 -cdrom ./darwinppc-602.cdr -boot d 
>                        ^
>                        |
> You're missing the "64" here ;-)
> 
>> reach the installer macosx installer.
> 
> It seems to be only failing for the 64-bit builds - and there only for
> the PPC970 CPU (which is the default for the mac99 machine in 64-bit
> builds):
> 
> qemu-system-ppc64 -nographic -cpu 750 -M mac99 ==> works fine
> 
> qemu-system-ppc64 -nographic -cpu 970 -M mac99 ==> hangs


This is too brutal :

+    /* This instruction doesn't exist anymore on 64-bit server
+     * processors compliant with arch 2.x
+     */
+    if (ctx->insns_flags & PPC_SEGMENT_64B) {
+        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
+        return;
+    }
	

There are a couple of instructions which have been deleted from 
ISA 2.x. rfi is one of them. Could we use a insn_flag to filter
them  ? 

Thanks,

C.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-17 10:41             ` Cédric Le Goater
@ 2016-06-17 11:02               ` Thomas Huth
  2016-06-17 11:11                 ` Alexander Graf
                                   ` (2 more replies)
  2016-06-18 23:29               ` Benjamin Herrenschmidt
  1 sibling, 3 replies; 68+ messages in thread
From: Thomas Huth @ 2016-06-17 11:02 UTC (permalink / raw)
  To: Cédric Le Goater, David Gibson
  Cc: qemu-ppc, qemu-devel, Mark Cave-Ayland

On 17.06.2016 12:41, Cédric Le Goater wrote:
> On 06/17/2016 09:10 AM, Thomas Huth wrote:
>> On 17.06.2016 08:03, Cédric Le Goater wrote:
>>> On 06/17/2016 07:54 AM, Cédric Le Goater wrote:
>>>> On 06/17/2016 04:27 AM, David Gibson wrote:
>>>>> On Thu, Jun 16, 2016 at 11:07:02AM +1000, David Gibson wrote:
>>>>>> On Mon, Jun 13, 2016 at 07:24:47AM +0200, Cédric Le Goater wrote:
>>>>>>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>>>
>>>>>>> This reworks emulation of the various "rfi" variants. I removed
>>>>>>> some masking bits that I couldn't make sense of, the only bit that
>>>>>>> I am aware we should mask here is POW, the CPU's MSR mask should
>>>>>>> take care of the rest.
>>>>>>>
>>>>>>> This also fixes some problems when running 32-bit userspace under
>>>>>>> a 64-bit kernel.
> 
> he.
> 
>>>>>>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>>>>>>
>>>>>> I've merged this patch to ppc-for-2.7.
>>>>>
>>>>> ..and now I've removed it again.  It seems that this breaks Thomas'
>>>>> new test that OpenBIOS runs on the mac machine types.  Not sure why,
>>>>> but we need to figure that out before I apply.
>>>>
>>>> Just this patch ? I booted a macosx image with it. but maybe just a mac99.
>>>> I will check today.
>>>
>>> With your branch ppc-for-2.7 (at commit aba2e6258d86) + the 
>>> "ppc: Fix rfi/rfid/hrfi/... emulation" patch, these guests : 
>>>
>>> 	qemu-system-ppc -cdrom ./darwinppc-602.cdr -boot d 
>>> 	qemu-system-ppc -M mac99 -cdrom ./darwinppc-602.cdr -boot d 
>>                        ^
>>                        |
>> You're missing the "64" here ;-)
>>
>>> reach the installer macosx installer.
>>
>> It seems to be only failing for the 64-bit builds - and there only for
>> the PPC970 CPU (which is the default for the mac99 machine in 64-bit
>> builds):
>>
>> qemu-system-ppc64 -nographic -cpu 750 -M mac99 ==> works fine
>>
>> qemu-system-ppc64 -nographic -cpu 970 -M mac99 ==> hangs
> 
> 
> This is too brutal :
> 
> +    /* This instruction doesn't exist anymore on 64-bit server
> +     * processors compliant with arch 2.x
> +     */
> +    if (ctx->insns_flags & PPC_SEGMENT_64B) {
> +        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
> +        return;
> +    }
> 
> There are a couple of instructions which have been deleted from 
> ISA 2.x. rfi is one of them. Could we use a insn_flag to filter
> them  ? 

According to the PPC970FX user manual that I have:

"The 970FX does not provide support for the following optional or
 obsolete instructions (or instruction forms).
 Attempted use of these will result in an illegal instruction type
 program interrupt.
  [...]
  · rfi - Return from interrupt (obsolete) "

So if OpenBIOS is using this instruction in 970 mode, it's maybe
OpenBIOS that should be fixed instead?

 Thomas

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-17 11:02               ` Thomas Huth
@ 2016-06-17 11:11                 ` Alexander Graf
  2016-06-17 14:32                 ` Cédric Le Goater
  2016-06-18 23:30                 ` Benjamin Herrenschmidt
  2 siblings, 0 replies; 68+ messages in thread
From: Alexander Graf @ 2016-06-17 11:11 UTC (permalink / raw)
  To: Thomas Huth, Cédric Le Goater, David Gibson; +Cc: qemu-ppc, qemu-devel



On 17.06.16 13:02, Thomas Huth wrote:
> On 17.06.2016 12:41, Cédric Le Goater wrote:
>> On 06/17/2016 09:10 AM, Thomas Huth wrote:
>>> On 17.06.2016 08:03, Cédric Le Goater wrote:
>>>> On 06/17/2016 07:54 AM, Cédric Le Goater wrote:
>>>>> On 06/17/2016 04:27 AM, David Gibson wrote:
>>>>>> On Thu, Jun 16, 2016 at 11:07:02AM +1000, David Gibson wrote:
>>>>>>> On Mon, Jun 13, 2016 at 07:24:47AM +0200, Cédric Le Goater wrote:
>>>>>>>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>>>>
>>>>>>>> This reworks emulation of the various "rfi" variants. I removed
>>>>>>>> some masking bits that I couldn't make sense of, the only bit that
>>>>>>>> I am aware we should mask here is POW, the CPU's MSR mask should
>>>>>>>> take care of the rest.
>>>>>>>>
>>>>>>>> This also fixes some problems when running 32-bit userspace under
>>>>>>>> a 64-bit kernel.
>>
>> he.
>>
>>>>>>>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>>>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>>>>>>>
>>>>>>> I've merged this patch to ppc-for-2.7.
>>>>>>
>>>>>> ..and now I've removed it again.  It seems that this breaks Thomas'
>>>>>> new test that OpenBIOS runs on the mac machine types.  Not sure why,
>>>>>> but we need to figure that out before I apply.
>>>>>
>>>>> Just this patch ? I booted a macosx image with it. but maybe just a mac99.
>>>>> I will check today.
>>>>
>>>> With your branch ppc-for-2.7 (at commit aba2e6258d86) + the 
>>>> "ppc: Fix rfi/rfid/hrfi/... emulation" patch, these guests : 
>>>>
>>>> 	qemu-system-ppc -cdrom ./darwinppc-602.cdr -boot d 
>>>> 	qemu-system-ppc -M mac99 -cdrom ./darwinppc-602.cdr -boot d 
>>>                        ^
>>>                        |
>>> You're missing the "64" here ;-)
>>>
>>>> reach the installer macosx installer.
>>>
>>> It seems to be only failing for the 64-bit builds - and there only for
>>> the PPC970 CPU (which is the default for the mac99 machine in 64-bit
>>> builds):
>>>
>>> qemu-system-ppc64 -nographic -cpu 750 -M mac99 ==> works fine
>>>
>>> qemu-system-ppc64 -nographic -cpu 970 -M mac99 ==> hangs
>>
>>
>> This is too brutal :
>>
>> +    /* This instruction doesn't exist anymore on 64-bit server
>> +     * processors compliant with arch 2.x
>> +     */
>> +    if (ctx->insns_flags & PPC_SEGMENT_64B) {
>> +        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
>> +        return;
>> +    }
>>
>> There are a couple of instructions which have been deleted from 
>> ISA 2.x. rfi is one of them. Could we use a insn_flag to filter
>> them  ? 
> 
> According to the PPC970FX user manual that I have:
> 
> "The 970FX does not provide support for the following optional or
>  obsolete instructions (or instruction forms).
>  Attempted use of these will result in an illegal instruction type
>  program interrupt.
>   [...]
>   · rfi - Return from interrupt (obsolete) "
> 
> So if OpenBIOS is using this instruction in 970 mode, it's maybe
> OpenBIOS that should be fixed instead?

If 970 doesn't implement rfi, OpenBIOS shouldn't use it, yes :).


Alex

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-17 11:02               ` Thomas Huth
  2016-06-17 11:11                 ` Alexander Graf
@ 2016-06-17 14:32                 ` Cédric Le Goater
  2016-06-18 23:35                   ` Benjamin Herrenschmidt
  2016-06-18 23:30                 ` Benjamin Herrenschmidt
  2 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-17 14:32 UTC (permalink / raw)
  To: Thomas Huth, David Gibson; +Cc: qemu-ppc, qemu-devel, Mark Cave-Ayland

On 06/17/2016 01:02 PM, Thomas Huth wrote:
> On 17.06.2016 12:41, Cédric Le Goater wrote:
>> On 06/17/2016 09:10 AM, Thomas Huth wrote:
>>> On 17.06.2016 08:03, Cédric Le Goater wrote:
>>>> On 06/17/2016 07:54 AM, Cédric Le Goater wrote:
>>>>> On 06/17/2016 04:27 AM, David Gibson wrote:
>>>>>> On Thu, Jun 16, 2016 at 11:07:02AM +1000, David Gibson wrote:
>>>>>>> On Mon, Jun 13, 2016 at 07:24:47AM +0200, Cédric Le Goater wrote:
>>>>>>>> From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>>>>
>>>>>>>> This reworks emulation of the various "rfi" variants. I removed
>>>>>>>> some masking bits that I couldn't make sense of, the only bit that
>>>>>>>> I am aware we should mask here is POW, the CPU's MSR mask should
>>>>>>>> take care of the rest.
>>>>>>>>
>>>>>>>> This also fixes some problems when running 32-bit userspace under
>>>>>>>> a 64-bit kernel.
>>
>> he.
>>
>>>>>>>> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>>>>>>>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>>>>>>>
>>>>>>> I've merged this patch to ppc-for-2.7.
>>>>>>
>>>>>> ..and now I've removed it again.  It seems that this breaks Thomas'
>>>>>> new test that OpenBIOS runs on the mac machine types.  Not sure why,
>>>>>> but we need to figure that out before I apply.
>>>>>
>>>>> Just this patch ? I booted a macosx image with it. but maybe just a mac99.
>>>>> I will check today.
>>>>
>>>> With your branch ppc-for-2.7 (at commit aba2e6258d86) + the 
>>>> "ppc: Fix rfi/rfid/hrfi/... emulation" patch, these guests : 
>>>>
>>>> 	qemu-system-ppc -cdrom ./darwinppc-602.cdr -boot d 
>>>> 	qemu-system-ppc -M mac99 -cdrom ./darwinppc-602.cdr -boot d 
>>>                        ^
>>>                        |
>>> You're missing the "64" here ;-)
>>>
>>>> reach the installer macosx installer.
>>>
>>> It seems to be only failing for the 64-bit builds - and there only for
>>> the PPC970 CPU (which is the default for the mac99 machine in 64-bit
>>> builds):
>>>
>>> qemu-system-ppc64 -nographic -cpu 750 -M mac99 ==> works fine
>>>
>>> qemu-system-ppc64 -nographic -cpu 970 -M mac99 ==> hangs
>>
>>
>> This is too brutal :
>>
>> +    /* This instruction doesn't exist anymore on 64-bit server
>> +     * processors compliant with arch 2.x
>> +     */
>> +    if (ctx->insns_flags & PPC_SEGMENT_64B) {
>> +        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
>> +        return;
>> +    }
>>
>> There are a couple of instructions which have been deleted from 
>> ISA 2.x. rfi is one of them. Could we use a insn_flag to filter
>> them  ? 
> 
> According to the PPC970FX user manual that I have:
> 
> "The 970FX does not provide support for the following optional or
>  obsolete instructions (or instruction forms).
>  Attempted use of these will result in an illegal instruction type
>  program interrupt.
>   [...]
>   · rfi - Return from interrupt (obsolete) "
> 
> So if OpenBIOS is using this instruction in 970 mode, it's maybe
> OpenBIOS that should be fixed instead?

Both, then :) rfi is considered implemented for all cpu. But it should 
not. 

The instruction set PPC_POWER_BR contains nearly all the deleted 
instructions from isa2. rfi is not part of it and should. Also, only 
the cpus "PowerPC 601*" make a use of it in their insns_flags.

So, we would want this set to be in all the "PowerPC {6,7}*" cpus. 
Are there more ? 

Thanks,

C. 

    dc->desc = "PowerPC 401";
    dc->desc = "PowerPC 401x2";
    dc->desc = "PowerPC 401x3";
    dc->desc = "IOP480";
    dc->desc = "PowerPC 403";
    dc->desc = "PowerPC 403 GCX";
    dc->desc = "PowerPC 405";
    dc->desc = "PowerPC 440 EP";
    dc->desc = "PowerPC 440 GP";
    dc->desc = "PowerPC 440x4";
    dc->desc = "PowerPC 440x5";
    dc->desc = "PowerPC 440x5 with double precision FPU";
    dc->desc = "PowerPC 460 (guessed)";
    dc->desc = "PowerPC 460F (guessed)";
    dc->desc = "Freescale 5xx cores (aka RCPU)";
    dc->desc = "Freescale 8xx cores (aka PowerQUICC)";
    dc->desc = "PowerPC G2";
    dc->desc = "PowerPC G2LE";
    dc->desc = "e200 core";
    dc->desc = "e300 core";
    dc->desc = "e500v1 core";
    dc->desc = "e500v2 core";
    dc->desc = "e500mc core";
    dc->desc = "e5500 core";
    dc->desc = "POWER";
    dc->desc = "PowerPC 601";
    pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
    dc->desc = "PowerPC 601v";
    pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
    dc->desc = "PowerPC 602";
    dc->desc = "PowerPC 603";
    dc->desc = "PowerPC 603e";
    dc->desc = "PowerPC 604";
    dc->desc = "PowerPC 604E";
    dc->desc = "PowerPC 740";
    dc->desc = "PowerPC 750";
    dc->desc = "PowerPC 750 CL";
    dc->desc = "PowerPC 750CX";
    dc->desc = "PowerPC 750FX";
    dc->desc = "PowerPC 750GX";
    dc->desc = "PowerPC 745";
    dc->desc = "PowerPC 755";
    dc->desc = "PowerPC 7400 (aka G4)";
    dc->desc = "PowerPC 7410 (aka G4)";
    dc->desc = "PowerPC 7440 (aka G4)";
    dc->desc = "PowerPC 7450 (aka G4)";
    dc->desc = "PowerPC 7445 (aka G4)";
    dc->desc = "PowerPC 7455 (aka G4)";
    dc->desc = "PowerPC 7457 (aka G4)";
    dc->desc = "PowerPC e600";
    dc->desc = "PowerPC 970";
    dc->desc = "POWER5+";
    dc->desc = "POWER7";
    dc->desc = "POWER8";

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-17 10:41             ` Cédric Le Goater
  2016-06-17 11:02               ` Thomas Huth
@ 2016-06-18 23:29               ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-18 23:29 UTC (permalink / raw)
  To: Cédric Le Goater, Thomas Huth, David Gibson; +Cc: qemu-ppc, qemu-devel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1080 bytes --]

	
	<1465795496-15071-2-git-send-email-clg@kaod.org>
	
	
	<20160616010702.GI28087@voom.fritz.box>
	
	
	<20160617022731.GA19581@voom.fritz.box> <57639095.5010305@kaod.org>
	
	
	<576392B1.6030204@kaod.org> <5763A258.2010408@redhat.com>
	 <5763D3EF.6060305@kaod.org>
Organization: IBM Australia
Content-Type: text/plain; charset="UTF-8"
X-Mailer: Evolution 3.20.3 (3.20.3-1.fc24) 
Mime-Version: 1.0
Content-Transfer-Encoding: 8bit

On Fri, 2016-06-17 at 12:41 +0200, Cédric Le Goater wrote:
> 
> This is too brutal :
> 
> +    /* This instruction doesn't exist anymore on 64-bit server
> +     * processors compliant with arch 2.x
> +     */
> +    if (ctx->insns_flags & PPC_SEGMENT_64B) {
> +        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
> +        return;
> +    }
>         
> 
> There are a couple of instructions which have been deleted from 
> ISA 2.x. rfi is one of them. Could we use a insn_flag to filter
> them  ? 

Why is it too brutal ? We don't really support pre-arch 2.0 64-bit
processors do we ?

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-17 11:02               ` Thomas Huth
  2016-06-17 11:11                 ` Alexander Graf
  2016-06-17 14:32                 ` Cédric Le Goater
@ 2016-06-18 23:30                 ` Benjamin Herrenschmidt
  2 siblings, 0 replies; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-18 23:30 UTC (permalink / raw)
  To: Thomas Huth, Cédric Le Goater, David Gibson; +Cc: qemu-ppc, qemu-devel

On Fri, 2016-06-17 at 13:02 +0200, Thomas Huth wrote:
> According to the PPC970FX user manual that I have:
> 
> "The 970FX does not provide support for the following optional or
>  obsolete instructions (or instruction forms).
>  Attempted use of these will result in an illegal instruction type
>  program interrupt.
>   [...]
>   · rfi - Return from interrupt (obsolete) "
> 
> So if OpenBIOS is using this instruction in 970 mode, it's maybe
> OpenBIOS that should be fixed instead?

Right, I was about to say that ... This instruction *might* have
existed on POWER3 which we don't emulate, but definitely not on
POWER4 and later.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-17 14:32                 ` Cédric Le Goater
@ 2016-06-18 23:35                   ` Benjamin Herrenschmidt
  2016-06-19 12:49                     ` Cédric Le Goater
  0 siblings, 1 reply; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-18 23:35 UTC (permalink / raw)
  To: Cédric Le Goater, Thomas Huth, David Gibson; +Cc: qemu-ppc, qemu-devel

On Fri, 2016-06-17 at 16:32 +0200, Cédric Le Goater wrote:
> The instruction set PPC_POWER_BR contains nearly all the deleted 
> instructions from isa2. rfi is not part of it and should. Also, only 
> the cpus "PowerPC 601*" make a use of it in their insns_flags.

Are you sure those arent the old POWER instructions as in pre-powerPC
architecture that 601 (and only 601) supports ?

> So, we would want this set to be in all the "PowerPC {6,7}*" cpus. 
> Are there more ? 

All 32-bit hash based CPUs are arch 1.x and support rfi

All 64-bit hash based CPUs we support (ie, POWER4 and later) are
architecture 2.x and later.

So my test is correct in the context of what we emulate today.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-18 23:35                   ` Benjamin Herrenschmidt
@ 2016-06-19 12:49                     ` Cédric Le Goater
  2016-06-19 13:00                       ` Alexander Graf
  2016-06-19 14:08                       ` Benjamin Herrenschmidt
  0 siblings, 2 replies; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-19 12:49 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Huth, David Gibson; +Cc: qemu-ppc, qemu-devel

On 06/19/2016 01:35 AM, Benjamin Herrenschmidt wrote:
> On Fri, 2016-06-17 at 16:32 +0200, Cédric Le Goater wrote:
>> The instruction set PPC_POWER_BR contains nearly all the deleted 
>> instructions from isa2. rfi is not part of it and should. Also, only 
>> the cpus "PowerPC 601*" make a use of it in their insns_flags.
> 
> Are you sure those arent the old POWER instructions as in pre-powerPC
> architecture that 601 (and only 601) supports ?

OK. I get it now.  

All the deleted instructions from POWER are/should be under the set 
PPC_POWER.

All the deleted instructions from POWER2 are under the set PPC_POWER2.

None of these sets are in use.


For the  "PowerPC 601*" cpus, we moved a couple from set PPC_POWER to 
subset PPC_POWER_BR.

rfi is special. it is under PPC_FLOW and all CPUs can use it

>> So, we would want this set to be in all the "PowerPC {6,7}*" cpus. 
>> Are there more ? 
> 
> All 32-bit hash based CPUs are arch 1.x and support rfi
> 
> All 64-bit hash based CPUs we support (ie, POWER4 and later) are
> architecture 2.x and later.
> 
> So my test is correct in the context of what we emulate today.

OK. so this is an openbios issue when run under a ppc64. shouldn't we 
be using an openbios-ppc64 in that case ?  


We could be more strict with the rfi instruction. 


C.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-19 12:49                     ` Cédric Le Goater
@ 2016-06-19 13:00                       ` Alexander Graf
  2016-06-19 17:21                         ` Cédric Le Goater
  2016-06-19 14:08                       ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 68+ messages in thread
From: Alexander Graf @ 2016-06-19 13:00 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: Benjamin Herrenschmidt, Thomas Huth, David Gibson, qemu-ppc, qemu-devel



> Am 19.06.2016 um 14:49 schrieb Cédric Le Goater <clg@kaod.org>:
> 
>> On 06/19/2016 01:35 AM, Benjamin Herrenschmidt wrote:
>>> On Fri, 2016-06-17 at 16:32 +0200, Cédric Le Goater wrote:
>>> The instruction set PPC_POWER_BR contains nearly all the deleted 
>>> instructions from isa2. rfi is not part of it and should. Also, only 
>>> the cpus "PowerPC 601*" make a use of it in their insns_flags.
>> 
>> Are you sure those arent the old POWER instructions as in pre-powerPC
>> architecture that 601 (and only 601) supports ?
> 
> OK. I get it now.  
> 
> All the deleted instructions from POWER are/should be under the set 
> PPC_POWER.
> 
> All the deleted instructions from POWER2 are under the set PPC_POWER2.
> 
> None of these sets are in use.
> 
> 
> For the  "PowerPC 601*" cpus, we moved a couple from set PPC_POWER to 
> subset PPC_POWER_BR.
> 
> rfi is special. it is under PPC_FLOW and all CPUs can use it
> 
>>> So, we would want this set to be in all the "PowerPC {6,7}*" cpus. 
>>> Are there more ?
>> 
>> All 32-bit hash based CPUs are arch 1.x and support rfi
>> 
>> All 64-bit hash based CPUs we support (ie, POWER4 and later) are
>> architecture 2.x and later.
>> 
>> So my test is correct in the context of what we emulate today.
> 
> OK. so this is an openbios issue when run under a ppc64. shouldn't we 
> be using an openbios-ppc64 in that case ?  

No, openbios can run on both. Just add a runtime check in openbios for rfi/rfid.

Alex

> 
> 
> We could be more strict with the rfi instruction. 
> 
> 
> C.
> 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-19 12:49                     ` Cédric Le Goater
  2016-06-19 13:00                       ` Alexander Graf
@ 2016-06-19 14:08                       ` Benjamin Herrenschmidt
  2016-06-19 17:23                         ` Cédric Le Goater
  1 sibling, 1 reply; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-19 14:08 UTC (permalink / raw)
  To: Cédric Le Goater, Thomas Huth, David Gibson; +Cc: qemu-ppc, qemu-devel

On Sun, 2016-06-19 at 14:49 +0200, Cédric Le Goater wrote:
> > So my test is correct in the context of what we emulate today.
> 
> OK. so this is an openbios issue when run under a ppc64. shouldn't we 
> be using an openbios-ppc64 in that case ?  
> 
> 
> We could be more strict with the rfi instruction. 

Well, ppc64 isn't backward compatible with ppc32 at the supervisor
level, at least not on server chips (it is on bookE chips). So yes it's
an OpenBIOS problem but that doesn't mean we have to use openbios-ppc64 
:-) 

You can run a 32-bit OS or firmware on ppc64, but it needs to know that
it's running on a 64-bit chip and do a few things differently.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-19 13:00                       ` Alexander Graf
@ 2016-06-19 17:21                         ` Cédric Le Goater
  2016-06-19 22:15                           ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-19 17:21 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Benjamin Herrenschmidt, Thomas Huth, David Gibson, qemu-ppc, qemu-devel

On 06/19/2016 03:00 PM, Alexander Graf wrote:
> 
> 
>> Am 19.06.2016 um 14:49 schrieb Cédric Le Goater <clg@kaod.org>:
>>
>>> On 06/19/2016 01:35 AM, Benjamin Herrenschmidt wrote:
>>>> On Fri, 2016-06-17 at 16:32 +0200, Cédric Le Goater wrote:
>>>> The instruction set PPC_POWER_BR contains nearly all the deleted 
>>>> instructions from isa2. rfi is not part of it and should. Also, only 
>>>> the cpus "PowerPC 601*" make a use of it in their insns_flags.
>>>
>>> Are you sure those arent the old POWER instructions as in pre-powerPC
>>> architecture that 601 (and only 601) supports ?
>>
>> OK. I get it now.  
>>
>> All the deleted instructions from POWER are/should be under the set 
>> PPC_POWER.
>>
>> All the deleted instructions from POWER2 are under the set PPC_POWER2.
>>
>> None of these sets are in use.
>>
>>
>> For the  "PowerPC 601*" cpus, we moved a couple from set PPC_POWER to 
>> subset PPC_POWER_BR.
>>
>> rfi is special. it is under PPC_FLOW and all CPUs can use it
>>
>>>> So, we would want this set to be in all the "PowerPC {6,7}*" cpus. 
>>>> Are there more ?
>>>
>>> All 32-bit hash based CPUs are arch 1.x and support rfi
>>>
>>> All 64-bit hash based CPUs we support (ie, POWER4 and later) are
>>> architecture 2.x and later.
>>>
>>> So my test is correct in the context of what we emulate today.
>>
>> OK. so this is an openbios issue when run under a ppc64. shouldn't we 
>> be using an openbios-ppc64 in that case ?  
> 
> No, openbios can run on both. Just add a runtime check in openbios for rfi/rfid.


OK. 

How's that for a start ? Seems to work. 

But, I could not boot  ./darwinppc-602.cdr with on a 970. That might
be another issue.

Thanks,

C.

From: Cédric Le Goater <clg@kaod.org>
Subject: [PATCH] ppc: use rfid when running under a CPU from the 970 family.
Date: Sun, 19 Jun 2016 15:48:41 +0200
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 arch/ppc/qemu/start.S |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

Index: openbios.git/arch/ppc/qemu/start.S
===================================================================
--- openbios.git.orig/arch/ppc/qemu/start.S
+++ openbios.git/arch/ppc/qemu/start.S
@@ -148,7 +148,20 @@
 	ll	r31,(35 * ULONG_SIZE)(r1) ; \
 .endif ; \
 	ll	r1,(1 * ULONG_SIZE)(r1) ;	/* restore stack at last */ \
-	rfi
+	mtsprg1	r3 ; \
+	mfpvr r3 ; \
+	rlwinm	r3,r3,16,16,31 ; \
+	cmplwi	cr1,r3,0x0039 ; 	/* 970 CPUs */ \
+	beq- cr1,0f ; \
+	cmplwi	cr1,r3,0x003C ; 	/* 970fx CPUs */ \
+	beq- cr1,0f ; \
+	cmplwi	cr1,r3,0x0044 ; 	/* 970mp CPUs */ \
+	beq- cr1,0f ; \
+	mfsprg1	r3 ; \
+	rfi ; \
+0:	    ; \
+	mfsprg1	r3 ; \
+	rfid
 
 // PPC32
 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-19 14:08                       ` Benjamin Herrenschmidt
@ 2016-06-19 17:23                         ` Cédric Le Goater
  2016-06-19 21:12                           ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-19 17:23 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Huth, David Gibson; +Cc: qemu-ppc, qemu-devel

On 06/19/2016 04:08 PM, Benjamin Herrenschmidt wrote:
> On Sun, 2016-06-19 at 14:49 +0200, Cédric Le Goater wrote:
>>> So my test is correct in the context of what we emulate today.
>>
>> OK. so this is an openbios issue when run under a ppc64. shouldn't we 
>> be using an openbios-ppc64 in that case ?  
>>
>>
>> We could be more strict with the rfi instruction. 
> 
> Well, ppc64 isn't backward compatible with ppc32 at the supervisor
> level, at least not on server chips (it is on bookE chips). So yes it's
> an OpenBIOS problem but that doesn't mean we have to use openbios-ppc64 
> :-) 
> 
> You can run a 32-bit OS or firmware on ppc64, but it needs to know that
> it's running on a 64-bit chip and do a few things differently.

yes sure but qemu would still allow rfi under 64bit CPUs, that is what 
I was concerned about. Is that ok ? 

C.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-19 17:23                         ` Cédric Le Goater
@ 2016-06-19 21:12                           ` Benjamin Herrenschmidt
  2016-06-20  2:19                             ` David Gibson
  2016-06-20  6:10                             ` Cédric Le Goater
  0 siblings, 2 replies; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-19 21:12 UTC (permalink / raw)
  To: Cédric Le Goater, Thomas Huth, David Gibson; +Cc: qemu-ppc, qemu-devel

On Sun, 2016-06-19 at 19:23 +0200, Cédric Le Goater wrote:
> > You can run a 32-bit OS or firmware on ppc64, but it needs to know that
> > it's running on a 64-bit chip and do a few things differently.
> 
> yes sure but qemu would still allow rfi under 64bit CPUs, that is what 
> I was concerned about. Is that ok ? 

Why ? A real CPU won't allow it, why should we ?

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-19 17:21                         ` Cédric Le Goater
@ 2016-06-19 22:15                           ` Benjamin Herrenschmidt
  2016-06-19 22:35                             ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-19 22:15 UTC (permalink / raw)
  To: Cédric Le Goater, Alexander Graf
  Cc: Thomas Huth, David Gibson, qemu-ppc, qemu-devel

On Sun, 2016-06-19 at 19:21 +0200, Cédric Le Goater wrote:
> But, I could not boot  ./darwinppc-602.cdr with on a 970. That might
> be another issue.

Right, the issue is that the kernel in Darwin 6.0.2 doesn't support the
970 :-)

I think the first MacOS X to support 970 was some special build of
10.2.8 or something along those lines, which is slightly after Darwin
6.0.2 was released.

Now that being said, Darwin 8.0.1 is also not booting in 970 and that
is possible a real issue, but I don't think it's realted to those
patches since that happens with current upstream7

I can look into it later (they both boot fine with a 7400).

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-19 22:15                           ` Benjamin Herrenschmidt
@ 2016-06-19 22:35                             ` Benjamin Herrenschmidt
  2016-06-20  7:08                               ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-19 22:35 UTC (permalink / raw)
  To: Cédric Le Goater, Alexander Graf
  Cc: Thomas Huth, David Gibson, qemu-ppc, qemu-devel

On Mon, 2016-06-20 at 08:15 +1000, Benjamin Herrenschmidt wrote:
> On Sun, 2016-06-19 at 19:21 +0200, Cédric Le Goater wrote:
> > But, I could not boot  ./darwinppc-602.cdr with on a 970. That
> > might
> > be another issue.
> 
> Right, the issue is that the kernel in Darwin 6.0.2 doesn't support
> the
> 970 :-)
> 
> I think the first MacOS X to support 970 was some special build of
> 10.2.8 or something along those lines, which is slightly after Darwin
> 6.0.2 was released.
> 
> Now that being said, Darwin 8.0.1 is also not booting in 970 and that
> is possible a real issue, but I don't think it's realted to those
> patches since that happens with current upstream7
> 
> I can look into it later (they both boot fine with a 7400).

Ok so Darwin uses some of the HSPRG etc... that we don't emulate on the
970 so I suspect it never worked. I've added them but something else
breaks, I'll dig, I have the kernel source so it shouldn't be too hard
;-)

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-19 21:12                           ` Benjamin Herrenschmidt
@ 2016-06-20  2:19                             ` David Gibson
  2016-06-20  6:17                               ` Cédric Le Goater
  2016-06-20  6:10                             ` Cédric Le Goater
  1 sibling, 1 reply; 68+ messages in thread
From: David Gibson @ 2016-06-20  2:19 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Cédric Le Goater, Thomas Huth, qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1044 bytes --]

On Mon, Jun 20, 2016 at 07:12:38AM +1000, Benjamin Herrenschmidt wrote:
> On Sun, 2016-06-19 at 19:23 +0200, Cédric Le Goater wrote:
> > > You can run a 32-bit OS or firmware on ppc64, but it needs to know that
> > > it's running on a 64-bit chip and do a few things differently.
> > 
> > yes sure but qemu would still allow rfi under 64bit CPUs, that is what 
> > I was concerned about. Is that ok ? 
> 
> Why ? A real CPU won't allow it, why should we ?

We shouldn't.  However, I'm inclined to in for now, until we have an
OpenBIOS fix actually committed.  I'd prefer to keep the existing
setup sorta-working when the current situation is unlikely to break
working code, even though it's definitely wrong.

BenH or Cédric, if you want to resend the hrfi fix patch with the
64-bit rfi support left in for no, that would be good.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-19 21:12                           ` Benjamin Herrenschmidt
  2016-06-20  2:19                             ` David Gibson
@ 2016-06-20  6:10                             ` Cédric Le Goater
  2016-06-20  8:18                               ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-20  6:10 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Huth, David Gibson; +Cc: qemu-ppc, qemu-devel

On 06/19/2016 11:12 PM, Benjamin Herrenschmidt wrote:
> On Sun, 2016-06-19 at 19:23 +0200, Cédric Le Goater wrote:
>>> You can run a 32-bit OS or firmware on ppc64, but it needs to know that
>>> it's running on a 64-bit chip and do a few things differently.
>>
>> yes sure but qemu would still allow rfi under 64bit CPUs, that is what 
>> I was concerned about. Is that ok ? 
> 
> Why ? A real CPU won't allow it, why should we ?

That is how I feel also. So, why don't we just remove the op code in the 
instruction sets from the 32bit CPUs instead of leaving it and testing 
for PPC_SEGMENT_64B ? or is there some reasons we want to keep it around ? 

Cheers,

C.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-20  2:19                             ` David Gibson
@ 2016-06-20  6:17                               ` Cédric Le Goater
  2016-06-20  7:47                                 ` Thomas Huth
  2016-06-20  8:18                                 ` Benjamin Herrenschmidt
  0 siblings, 2 replies; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-20  6:17 UTC (permalink / raw)
  To: David Gibson, Benjamin Herrenschmidt; +Cc: Thomas Huth, qemu-ppc, qemu-devel

On 06/20/2016 04:19 AM, David Gibson wrote:
> On Mon, Jun 20, 2016 at 07:12:38AM +1000, Benjamin Herrenschmidt wrote:
>> On Sun, 2016-06-19 at 19:23 +0200, Cédric Le Goater wrote:
>>>> You can run a 32-bit OS or firmware on ppc64, but it needs to know that
>>>> it's running on a 64-bit chip and do a few things differently.
>>>
>>> yes sure but qemu would still allow rfi under 64bit CPUs, that is what 
>>> I was concerned about. Is that ok ? 
>>
>> Why ? A real CPU won't allow it, why should we ?
> 
> We shouldn't.  However, I'm inclined to in for now, until we have an
> OpenBIOS fix actually committed.  I'd prefer to keep the existing
> setup sorta-working when the current situation is unlikely to break
> working code, even though it's definitely wrong.
>
> BenH or Cédric, if you want to resend the hrfi fix patch with the
> 64-bit rfi support left in for no, that would be good.

The current patch does not need fixing. I will send the OpenBIOS patch 
shortly after I have looked at the FPU exception.

Linux ppc behaves the same on a 970. So we will need to fix the 'rfi's
there also. 

C.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-19 22:35                             ` Benjamin Herrenschmidt
@ 2016-06-20  7:08                               ` Benjamin Herrenschmidt
  2016-06-20  7:11                                 ` Alexander Graf
  2016-06-20  8:02                                 ` Benjamin Herrenschmidt
  0 siblings, 2 replies; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-20  7:08 UTC (permalink / raw)
  To: Cédric Le Goater, Alexander Graf
  Cc: Thomas Huth, David Gibson, qemu-ppc, qemu-devel

On Mon, 2016-06-20 at 08:35 +1000, Benjamin Herrenschmidt wrote:
> ,
> Ok so Darwin uses some of the HSPRG etc... that we don't emulate on
> the 970 so I suspect it never worked. I've added them but something
> else breaks, I'll dig, I have the kernel source so it shouldn't be
> too hard
> ;-)

Well, it ended up being harder than I thought. In fact I'm not there
yet ! So the Darwin VM layer dies early because HID5 isn't set
properly, thus dcbz is doing 128 bytes clear instead of 32, clobbering
things.

It looks like Apple's kernel doesn't set the right default in HID5, so
we have to either do it in openbios or in qemu. Alex, what did you find
out back in the day ? Or you never bothered running a 64-bit MacOS
under PR KVM ?

That fixed, it dies elsewhere in something related to page faults,
still digging.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-20  7:08                               ` Benjamin Herrenschmidt
@ 2016-06-20  7:11                                 ` Alexander Graf
  2016-06-20  8:02                                 ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 68+ messages in thread
From: Alexander Graf @ 2016-06-20  7:11 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Cédric Le Goater
  Cc: Thomas Huth, David Gibson, qemu-ppc, qemu-devel



On 20.06.16 09:08, Benjamin Herrenschmidt wrote:
> On Mon, 2016-06-20 at 08:35 +1000, Benjamin Herrenschmidt wrote:
>>  ,
>> Ok so Darwin uses some of the HSPRG etc... that we don't emulate on
>> the 970 so I suspect it never worked. I've added them but something
>> else breaks, I'll dig, I have the kernel source so it shouldn't be
>> too hard
>> ;-)
> 
> Well, it ended up being harder than I thought. In fact I'm not there
> yet ! So the Darwin VM layer dies early because HID5 isn't set
> properly, thus dcbz is doing 128 bytes clear instead of 32, clobbering
> things.
> 
> It looks like Apple's kernel doesn't set the right default in HID5, so
> we have to either do it in openbios or in qemu. Alex, what did you find

Uh, I'm fairy sure XNU sets HID5.

> out back in the day ? Or you never bothered running a 64-bit MacOS
> under PR KVM ?

I don't think I ever had 64bit Mac OS X working in TCG or KVM :).


Alex

> That fixed, it dies elsewhere in something related to page faults,
> still digging.
> 
> Cheers,
> Ben.
> 

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-20  6:17                               ` Cédric Le Goater
@ 2016-06-20  7:47                                 ` Thomas Huth
  2016-06-20  8:21                                   ` Benjamin Herrenschmidt
  2016-06-20  8:46                                   ` Cédric Le Goater
  2016-06-20  8:18                                 ` Benjamin Herrenschmidt
  1 sibling, 2 replies; 68+ messages in thread
From: Thomas Huth @ 2016-06-20  7:47 UTC (permalink / raw)
  To: Cédric Le Goater, David Gibson, Benjamin Herrenschmidt
  Cc: qemu-ppc, qemu-devel

On 20.06.2016 08:17, Cédric Le Goater wrote:
> On 06/20/2016 04:19 AM, David Gibson wrote:
>> On Mon, Jun 20, 2016 at 07:12:38AM +1000, Benjamin Herrenschmidt wrote:
>>> On Sun, 2016-06-19 at 19:23 +0200, Cédric Le Goater wrote:
>>>>> You can run a 32-bit OS or firmware on ppc64, but it needs to know that
>>>>> it's running on a 64-bit chip and do a few things differently.
>>>>
>>>> yes sure but qemu would still allow rfi under 64bit CPUs, that is what 
>>>> I was concerned about. Is that ok ? 
>>>
>>> Why ? A real CPU won't allow it, why should we ?
>>
>> We shouldn't.  However, I'm inclined to in for now, until we have an
>> OpenBIOS fix actually committed.  I'd prefer to keep the existing
>> setup sorta-working when the current situation is unlikely to break
>> working code, even though it's definitely wrong.
>>
>> BenH or Cédric, if you want to resend the hrfi fix patch with the
>> 64-bit rfi support left in for no, that would be good.
> 
> The current patch does not need fixing. I will send the OpenBIOS patch 
> shortly after I have looked at the FPU exception.
> 
> Linux ppc behaves the same on a 970. So we will need to fix the 'rfi's
> there also. 

Really? Wow, that surprises me. That OpenBIOS code likely never ran on a
real 970 hardware, so that's not too much surprising that the "rfi"
sneaked in there, but the Linux kernel certainly ran on a real 970 once,
so I wonder why it's not properly using rfid for the 970 yet?

 Thomas

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-20  7:08                               ` Benjamin Herrenschmidt
  2016-06-20  7:11                                 ` Alexander Graf
@ 2016-06-20  8:02                                 ` Benjamin Herrenschmidt
  2016-06-20  9:32                                   ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-20  8:02 UTC (permalink / raw)
  To: Cédric Le Goater, Alexander Graf
  Cc: Thomas Huth, David Gibson, qemu-ppc, qemu-devel

On Mon, 2016-06-20 at 17:08 +1000, Benjamin Herrenschmidt wrote:
> 
> That fixed, it dies elsewhere in something related to page faults,
> still digging.
> 
Next problem: Darwin kernel assumes DSISR is 0 on a 0x380 exception !

qemu was leaving it to whatever value it had before. Kaboom.

Now it crashes a bit further :-)

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-20  6:10                             ` Cédric Le Goater
@ 2016-06-20  8:18                               ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-20  8:18 UTC (permalink / raw)
  To: Cédric Le Goater, Thomas Huth, David Gibson; +Cc: qemu-ppc, qemu-devel

On Mon, 2016-06-20 at 08:10 +0200, Cédric Le Goater wrote:
> That is how I feel also. So, why don't we just remove the op code in the 
> instruction sets from the 32bit CPUs instead of leaving it and testing 
> for PPC_SEGMENT_64B ? or is there some reasons we want to keep it around ? 

Ah no

Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-20  6:17                               ` Cédric Le Goater
  2016-06-20  7:47                                 ` Thomas Huth
@ 2016-06-20  8:18                                 ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-20  8:18 UTC (permalink / raw)
  To: Cédric Le Goater, David Gibson; +Cc: Thomas Huth, qemu-ppc, qemu-devel

On Mon, 2016-06-20 at 08:17 +0200, Cédric Le Goater wrote:
> 
> The current patch does not need fixing. I will send the OpenBIOS
> patch 
> shortly after I have looked at the FPU exception.
> 
> Linux ppc behaves the same on a 970. So we will need to fix the
> 'rfi's there also. 

What do you mean ? where ?

Linux should be only using rfid on 970...

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-20  7:47                                 ` Thomas Huth
@ 2016-06-20  8:21                                   ` Benjamin Herrenschmidt
  2016-06-20  8:46                                   ` Cédric Le Goater
  1 sibling, 0 replies; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-20  8:21 UTC (permalink / raw)
  To: Thomas Huth, Cédric Le Goater, David Gibson; +Cc: qemu-ppc, qemu-devel

On Mon, 2016-06-20 at 09:47 +0200, Thomas Huth wrote:
> > Linux ppc behaves the same on a 970. So we will need to fix the 'rfi's
> > there also. 
> 
> Really? Wow, that surprises me. That OpenBIOS code likely never ran on a
> real 970 hardware, so that's not too much surprising that the "rfi"
> sneaked in there, but the Linux kernel certainly ran on a real 970 once,
> so I wonder why it's not properly using rfid for the 970 yet?

It's working, Cedric was looking at the 32-bit kernel :-)

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-20  7:47                                 ` Thomas Huth
  2016-06-20  8:21                                   ` Benjamin Herrenschmidt
@ 2016-06-20  8:46                                   ` Cédric Le Goater
  1 sibling, 0 replies; 68+ messages in thread
From: Cédric Le Goater @ 2016-06-20  8:46 UTC (permalink / raw)
  To: Thomas Huth, David Gibson, Benjamin Herrenschmidt; +Cc: qemu-ppc, qemu-devel

On 06/20/2016 09:47 AM, Thomas Huth wrote:
> On 20.06.2016 08:17, Cédric Le Goater wrote:
>> On 06/20/2016 04:19 AM, David Gibson wrote:
>>> On Mon, Jun 20, 2016 at 07:12:38AM +1000, Benjamin Herrenschmidt wrote:
>>>> On Sun, 2016-06-19 at 19:23 +0200, Cédric Le Goater wrote:
>>>>>> You can run a 32-bit OS or firmware on ppc64, but it needs to know that
>>>>>> it's running on a 64-bit chip and do a few things differently.
>>>>>
>>>>> yes sure but qemu would still allow rfi under 64bit CPUs, that is what 
>>>>> I was concerned about. Is that ok ? 
>>>>
>>>> Why ? A real CPU won't allow it, why should we ?
>>>
>>> We shouldn't.  However, I'm inclined to in for now, until we have an
>>> OpenBIOS fix actually committed.  I'd prefer to keep the existing
>>> setup sorta-working when the current situation is unlikely to break
>>> working code, even though it's definitely wrong.
>>>
>>> BenH or Cédric, if you want to resend the hrfi fix patch with the
>>> 64-bit rfi support left in for no, that would be good.
>>
>> The current patch does not need fixing. I will send the OpenBIOS patch 
>> shortly after I have looked at the FPU exception.
>>
>> Linux ppc behaves the same on a 970. So we will need to fix the 'rfi's
>> there also. 
> 
> Really? Wow, that surprises me. That OpenBIOS code likely never ran on a
> real 970 hardware, so that's not too much surprising that the "rfi"
> sneaked in there, but the Linux kernel certainly ran on a real 970 once,
> so I wonder why it's not properly using rfid for the 970 yet?

I just learned that the support for 970 was removed from the 32bit kernel
long time ago. False alarm, my bad.

C.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-20  8:02                                 ` Benjamin Herrenschmidt
@ 2016-06-20  9:32                                   ` Benjamin Herrenschmidt
  2016-06-20 13:55                                     ` Alexander Graf
  2016-06-21  8:21                                     ` Mark Cave-Ayland
  0 siblings, 2 replies; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-20  9:32 UTC (permalink / raw)
  To: Cédric Le Goater, Alexander Graf
  Cc: Thomas Huth, David Gibson, qemu-ppc, qemu-devel

On Mon, 2016-06-20 at 18:02 +1000, Benjamin Herrenschmidt wrote:
> On Mon, 2016-06-20 at 17:08 +1000, Benjamin Herrenschmidt wrote:
> >  
> > That fixed, it dies elsewhere in something related to page faults,
> > still digging.
> >  
> Next problem: Darwin kernel assumes DSISR is 0 on a 0x380 exception !
> 
> qemu was leaving it to whatever value it had before. Kaboom.
> 
> Now it crashes a bit further :-)

Right so it tries to load a MacRISC2 PE because we don't really emulate
a MacRISC4 with U3 etc... and that isn't going to do it any good,
really..

I'm not *actually* sure where MacOS gets itself into a spin, it seems
to be poking at something at 0xf280_0000 which is somewhat odd as this
would be the IO space and we have nothing there afaik, but I am not
enough of a MacOS expert to figure out quite how to track down which
kext it gets into etc...

In any case, the machine we give it is definitely nowhere near a real
G5 and that might be the main reason. More work needed.

I'll still cleanup & submit my current crop of fixes in case somebody
wants to have a look.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-20  9:32                                   ` Benjamin Herrenschmidt
@ 2016-06-20 13:55                                     ` Alexander Graf
  2016-06-21  8:21                                     ` Mark Cave-Ayland
  1 sibling, 0 replies; 68+ messages in thread
From: Alexander Graf @ 2016-06-20 13:55 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Cédric Le Goater
  Cc: Thomas Huth, David Gibson, qemu-ppc, qemu-devel

On 06/20/2016 11:32 AM, Benjamin Herrenschmidt wrote:
> On Mon, 2016-06-20 at 18:02 +1000, Benjamin Herrenschmidt wrote:
>> On Mon, 2016-06-20 at 17:08 +1000, Benjamin Herrenschmidt wrote:
>>>   
>>> That fixed, it dies elsewhere in something related to page faults,
>>> still digging.
>>>   
>> Next problem: Darwin kernel assumes DSISR is 0 on a 0x380 exception !
>>
>> qemu was leaving it to whatever value it had before. Kaboom.
>>
>> Now it crashes a bit further :-)
> Right so it tries to load a MacRISC2 PE because we don't really emulate
> a MacRISC4 with U3 etc... and that isn't going to do it any good,
> really..
>
> I'm not *actually* sure where MacOS gets itself into a spin, it seems
> to be poking at something at 0xf280_0000 which is somewhat odd as this
> would be the IO space and we have nothing there afaik, but I am not
> enough of a MacOS expert to figure out quite how to track down which
> kext it gets into etc...
>
> In any case, the machine we give it is definitely nowhere near a real
> G5 and that might be the main reason. More work needed.
>
> I'll still cleanup & submit my current crop of fixes in case somebody
> wants to have a look.

Since the patches do get you further along and get us closer to an 
actual 970, I guess it's a good idea to actually push them into the tree.

Alex

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-20  9:32                                   ` Benjamin Herrenschmidt
  2016-06-20 13:55                                     ` Alexander Graf
@ 2016-06-21  8:21                                     ` Mark Cave-Ayland
  2016-06-21  9:33                                       ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 68+ messages in thread
From: Mark Cave-Ayland @ 2016-06-21  8:21 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Cédric Le Goater, Alexander Graf
  Cc: Thomas Huth, qemu-ppc, qemu-devel, David Gibson

On 20/06/16 10:32, Benjamin Herrenschmidt wrote:

> On Mon, 2016-06-20 at 18:02 +1000, Benjamin Herrenschmidt wrote:
>> On Mon, 2016-06-20 at 17:08 +1000, Benjamin Herrenschmidt wrote:
>>>  
>>> That fixed, it dies elsewhere in something related to page faults,
>>> still digging.
>>>  
>> Next problem: Darwin kernel assumes DSISR is 0 on a 0x380 exception !
>>
>> qemu was leaving it to whatever value it had before. Kaboom.
>>
>> Now it crashes a bit further :-)
> 
> Right so it tries to load a MacRISC2 PE because we don't really emulate
> a MacRISC4 with U3 etc... and that isn't going to do it any good,
> really..
> 
> I'm not *actually* sure where MacOS gets itself into a spin, it seems
> to be poking at something at 0xf280_0000 which is somewhat odd as this
> would be the IO space and we have nothing there afaik, but I am not
> enough of a MacOS expert to figure out quite how to track down which
> kext it gets into etc...
> 
> In any case, the machine we give it is definitely nowhere near a real
> G5 and that might be the main reason. More work needed.

A quick check with "info mtree" shows that this area of memory is PCI
configuration space. There was a patch added to uninorth in order to
suppress some PCI warnings on Darwin boot found by going over the source
to the Darwin MacRISC driver which resulted in the patch at
http://git.qemu.org/?p=qemu.git;a=commitdiff;h=98ae3b27d57b59c6dc9a74e6351e339523c16def.
Maybe it could be related to that?

> I'll still cleanup & submit my current crop of fixes in case somebody
> wants to have a look.

Not sure I can help much here, however I can give everything a good test
and make sure that it doesn't break :)


ATB,

Mark.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-21  8:21                                     ` Mark Cave-Ayland
@ 2016-06-21  9:33                                       ` Benjamin Herrenschmidt
  2016-06-21  9:37                                         ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-21  9:33 UTC (permalink / raw)
  To: Mark Cave-Ayland, Cédric Le Goater, Alexander Graf
  Cc: Thomas Huth, qemu-ppc, qemu-devel, David Gibson

On Tue, 2016-06-21 at 09:21 +0100, Mark Cave-Ayland wrote:
> A quick check with "info mtree" shows that this area of memory is PCI
> configuration space. There was a patch added to uninorth in order to
> suppress some PCI warnings on Darwin boot found by going over the source
> to the Darwin MacRISC driver which resulted in the patch at
> http://git.qemu.org/?p=qemu.git;a=commitdiff;h=98ae3b27d57b59c6dc9a74e6351e339523c16def.
> Maybe it could be related to that?
> 
> > I'll still cleanup & submit my current crop of fixes in case somebody
> > wants to have a look.
> 
> Not sure I can help much here, however I can give everything a good test
> and make sure that it doesn't break :)

I'll double check, I used to know that HW well and might even have
access to some docs internally but that specific f280_0000 doesn't look
like something that would mean anything on a machine with macio at
8000_0000.... 

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [Qemu-devel] [Qemu-ppc] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation
  2016-06-21  9:33                                       ` Benjamin Herrenschmidt
@ 2016-06-21  9:37                                         ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 68+ messages in thread
From: Benjamin Herrenschmidt @ 2016-06-21  9:37 UTC (permalink / raw)
  To: Mark Cave-Ayland, Cédric Le Goater, Alexander Graf
  Cc: Thomas Huth, qemu-ppc, qemu-devel, David Gibson

On Tue, 2016-06-21 at 19:33 +1000, Benjamin Herrenschmidt wrote:
> On Tue, 2016-06-21 at 09:21 +0100, Mark Cave-Ayland wrote:
> > A quick check with "info mtree" shows that this area of memory is
> > PCI
> > configuration space. There was a patch added to uninorth in order
> > to
> > suppress some PCI warnings on Darwin boot found by going over the
> > source
> > to the Darwin MacRISC driver which resulted in the patch at
> > http://git.qemu.org/?p=qemu.git;a=commitdiff;h=98ae3b27d57b59c6dc9a
> > 74e6351e339523c16def.
> > Maybe it could be related to that?
> > 
> > > I'll still cleanup & submit my current crop of fixes in case
> > > somebody
> > > wants to have a look.
> > 
> > Not sure I can help much here, however I can give everything a good
> > test
> > and make sure that it doesn't break :)
> 
> I'll double check, I used to know that HW well and might even have
> access to some docs internally but that specific f280_0000 doesn't
> look
> like something that would mean anything on a machine with macio at
> 8000_0000.... 
> 
You are right, it's PCI1 config space. I'll dig more later.

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 68+ messages in thread

end of thread, other threads:[~2016-06-21  9:38 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-13  5:24 [Qemu-devel] [PATCH 00/10] rework exception model to support the HV mode Cédric Le Goater
2016-06-13  5:24 ` [Qemu-devel] [PATCH 01/10] ppc: Fix rfi/rfid/hrfi/... emulation Cédric Le Goater
2016-06-16  1:07   ` David Gibson
2016-06-17  2:27     ` [Qemu-devel] [Qemu-ppc] " David Gibson
2016-06-17  5:54       ` Cédric Le Goater
2016-06-17  6:03         ` Cédric Le Goater
2016-06-17  6:28           ` David Gibson
2016-06-17  6:39             ` Cédric Le Goater
2016-06-17  7:10           ` Thomas Huth
2016-06-17  7:17             ` Cédric Le Goater
2016-06-17 10:41             ` Cédric Le Goater
2016-06-17 11:02               ` Thomas Huth
2016-06-17 11:11                 ` Alexander Graf
2016-06-17 14:32                 ` Cédric Le Goater
2016-06-18 23:35                   ` Benjamin Herrenschmidt
2016-06-19 12:49                     ` Cédric Le Goater
2016-06-19 13:00                       ` Alexander Graf
2016-06-19 17:21                         ` Cédric Le Goater
2016-06-19 22:15                           ` Benjamin Herrenschmidt
2016-06-19 22:35                             ` Benjamin Herrenschmidt
2016-06-20  7:08                               ` Benjamin Herrenschmidt
2016-06-20  7:11                                 ` Alexander Graf
2016-06-20  8:02                                 ` Benjamin Herrenschmidt
2016-06-20  9:32                                   ` Benjamin Herrenschmidt
2016-06-20 13:55                                     ` Alexander Graf
2016-06-21  8:21                                     ` Mark Cave-Ayland
2016-06-21  9:33                                       ` Benjamin Herrenschmidt
2016-06-21  9:37                                         ` Benjamin Herrenschmidt
2016-06-19 14:08                       ` Benjamin Herrenschmidt
2016-06-19 17:23                         ` Cédric Le Goater
2016-06-19 21:12                           ` Benjamin Herrenschmidt
2016-06-20  2:19                             ` David Gibson
2016-06-20  6:17                               ` Cédric Le Goater
2016-06-20  7:47                                 ` Thomas Huth
2016-06-20  8:21                                   ` Benjamin Herrenschmidt
2016-06-20  8:46                                   ` Cédric Le Goater
2016-06-20  8:18                                 ` Benjamin Herrenschmidt
2016-06-20  6:10                             ` Cédric Le Goater
2016-06-20  8:18                               ` Benjamin Herrenschmidt
2016-06-18 23:30                 ` Benjamin Herrenschmidt
2016-06-18 23:29               ` Benjamin Herrenschmidt
2016-06-17  6:19     ` [Qemu-devel] " Cédric Le Goater
2016-06-13  5:24 ` [Qemu-devel] [PATCH 02/10] ppc: Create cpu_ppc_set_papr() helper (for LPCR) Cédric Le Goater
2016-06-14  6:15   ` David Gibson
2016-06-14  6:52     ` Cédric Le Goater
2016-06-15  1:01       ` David Gibson
2016-06-13  5:24 ` [Qemu-devel] [PATCH 03/10] ppc: Rework POWER7 & POWER8 exception model (part 2) Cédric Le Goater
2016-06-14  6:25   ` David Gibson
2016-06-14 21:19     ` Benjamin Herrenschmidt
2016-06-15  1:00       ` David Gibson
2016-06-13  5:24 ` [Qemu-devel] [PATCH 04/10] ppc: Fix POWER7 and POWER8 exception definitions Cédric Le Goater
2016-06-13  5:24 ` [Qemu-devel] [PATCH 05/10] ppc: Fix generation if ISI/DSI vs. HV mode Cédric Le Goater
2016-06-14  6:34   ` David Gibson
2016-06-14  6:42     ` Cédric Le Goater
2016-06-15  1:09       ` David Gibson
2016-06-13  5:24 ` [Qemu-devel] [PATCH 06/10] ppc: Rework generation of priv and inval interrupts Cédric Le Goater
2016-06-15  1:19   ` David Gibson
2016-06-15  4:31     ` Benjamin Herrenschmidt
2016-06-15  5:06       ` David Gibson
2016-06-13  5:24 ` [Qemu-devel] [PATCH 07/10] ppc: Add real mode CI load/store instructions for P7 and P8 Cédric Le Goater
2016-06-15  3:46   ` David Gibson
2016-06-13  5:24 ` [Qemu-devel] [PATCH 08/10] ppc: Turn a bunch of booleans from int to bool Cédric Le Goater
2016-06-13  5:24 ` [Qemu-devel] [PATCH 09/10] ppc: Move exception generation code out of line Cédric Le Goater
2016-06-13  7:44   ` Thomas Huth
2016-06-13  8:36     ` Cédric Le Goater
2016-06-15  1:57       ` David Gibson
2016-06-13  5:24 ` [Qemu-devel] [PATCH 10/10] ppc: Add P7/P8 Power Management instructions Cédric Le Goater
2016-06-15  1:56   ` David Gibson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.