All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/2] target/ppc: Improve syscall exception logging
@ 2020-03-17  5:49 Nicholas Piggin
  2020-03-17  5:49 ` [PATCH v3 2/2] target/ppc: Add support for scv and rfscv instructions Nicholas Piggin
  2020-03-19  6:22 ` [PATCH v3 1/2] target/ppc: Improve syscall exception logging David Gibson
  0 siblings, 2 replies; 4+ messages in thread
From: Nicholas Piggin @ 2020-03-17  5:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: qemu-devel, Nicholas Piggin, David Gibson

system calls (at least in Linux) use registers r3-r8 for inputs, so
include those registers in the dump.

This also adds a mode for PAPR hcalls, which have a different calling
convention.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
Since v2:
- Rebased on top of FWNMI series

 target/ppc/excp_helper.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 08bc885ca6..81ee19ebae 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -57,12 +57,29 @@ static void ppc_hw_interrupt(CPUPPCState *env)
 #else /* defined(CONFIG_USER_ONLY) */
 static inline void dump_syscall(CPUPPCState *env)
 {
-    qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 " r3=%016" PRIx64
-                  " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
+    qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
+                  " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64
+                  " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64
                   " nip=" TARGET_FMT_lx "\n",
                   ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
                   ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
-                  ppc_dump_gpr(env, 6), env->nip);
+                  ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
+                  ppc_dump_gpr(env, 8), env->nip);
+}
+
+static inline void dump_hcall(CPUPPCState *env)
+{
+    qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64
+		  " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
+		  " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64
+		  " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64
+                  " nip=" TARGET_FMT_lx "\n",
+                  ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4),
+		  ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6),
+		  ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8),
+		  ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10),
+		  ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12),
+		  env->nip);
 }
 
 static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp,
@@ -379,9 +396,14 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
         break;
     case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
-        dump_syscall(env);
         lev = env->error_code;
 
+        if ((lev == 1) && cpu->vhyp) {
+            dump_hcall(env);
+        } else {
+            dump_syscall(env);
+        }
+
         /*
          * We need to correct the NIP which in this case is supposed
          * to point to the next instruction
-- 
2.23.0



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

* [PATCH v3 2/2] target/ppc: Add support for scv and rfscv instructions
  2020-03-17  5:49 [PATCH v3 1/2] target/ppc: Improve syscall exception logging Nicholas Piggin
@ 2020-03-17  5:49 ` Nicholas Piggin
  2020-03-19  6:22   ` David Gibson
  2020-03-19  6:22 ` [PATCH v3 1/2] target/ppc: Improve syscall exception logging David Gibson
  1 sibling, 1 reply; 4+ messages in thread
From: Nicholas Piggin @ 2020-03-17  5:49 UTC (permalink / raw)
  To: qemu-ppc; +Cc: qemu-devel, Nicholas Piggin, David Gibson

POWER9 adds scv and rfscv instructions and the system call vectored
interrupt. Linux does not support this instruction yet but it has
been tested with a modified kernel that runs on real hardware.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
Since v2:
- Rebased on top of FWNMI series

 linux-user/ppc/cpu_loop.c       |  1 +
 target/ppc/cpu.h                |  7 ++-
 target/ppc/excp_helper.c        | 98 ++++++++++++++++++++++++---------
 target/ppc/helper.h             |  1 +
 target/ppc/translate.c          | 46 +++++++++++++++-
 target/ppc/translate_init.inc.c |  3 +-
 6 files changed, 126 insertions(+), 30 deletions(-)

diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c
index 5b27f8603e..df71e15a25 100644
--- a/linux-user/ppc/cpu_loop.c
+++ b/linux-user/ppc/cpu_loop.c
@@ -267,6 +267,7 @@ void cpu_loop(CPUPPCState *env)
             queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
             break;
         case POWERPC_EXCP_SYSCALL:  /* System call exception                 */
+        case POWERPC_EXCP_SYSCALL_VECTORED:
             cpu_abort(cs, "Syscall exception while in user mode. "
                       "Aborting\n");
             break;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index ed8d2015bd..992f0a49e8 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -127,8 +127,9 @@ enum {
     POWERPC_EXCP_SDOOR_HV = 100,
     /* ISA 3.00 additions */
     POWERPC_EXCP_HVIRT    = 101,
+    POWERPC_EXCP_SYSCALL_VECTORED = 102, /* scv exception                     */
     /* EOL                                                                   */
-    POWERPC_EXCP_NB       = 102,
+    POWERPC_EXCP_NB       = 103,
     /* QEMU exceptions: used internally during code translation              */
     POWERPC_EXCP_STOP         = 0x200, /* stop translation                   */
     POWERPC_EXCP_BRANCH       = 0x201, /* branch instruction                 */
@@ -475,6 +476,7 @@ typedef struct ppc_v3_pate_t {
 /* Facility Status and Control (FSCR) bits */
 #define FSCR_EBB        (63 - 56) /* Event-Based Branch Facility */
 #define FSCR_TAR        (63 - 55) /* Target Address Register */
+#define FSCR_SCV        (63 - 51) /* System call vectored */
 /* Interrupt cause mask and position in FSCR. HFSCR has the same format */
 #define FSCR_IC_MASK    (0xFFULL)
 #define FSCR_IC_POS     (63 - 7)
@@ -484,6 +486,7 @@ typedef struct ppc_v3_pate_t {
 #define FSCR_IC_TM          5
 #define FSCR_IC_EBB         7
 #define FSCR_IC_TAR         8
+#define FSCR_IC_SCV        12
 
 /* Exception state register bits definition                                  */
 #define ESR_PIL   PPC_BIT(36) /* Illegal Instruction                    */
@@ -551,6 +554,8 @@ enum {
     POWERPC_FLAG_VSX      = 0x00080000,
     /* Has Transaction Memory (ISA 2.07)                                     */
     POWERPC_FLAG_TM       = 0x00100000,
+    /* Has SCV (ISA 3.00)                                                    */
+    POWERPC_FLAG_SCV      = 0x00200000,
 };
 
 /*****************************************************************************/
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 81ee19ebae..73b5c28d03 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -67,6 +67,18 @@ static inline void dump_syscall(CPUPPCState *env)
                   ppc_dump_gpr(env, 8), env->nip);
 }
 
+static inline void dump_syscall_vectored(CPUPPCState *env)
+{
+    qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
+                  " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64
+                  " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64
+                  " nip=" TARGET_FMT_lx "\n",
+                  ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
+                  ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
+                  ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
+                  ppc_dump_gpr(env, 8), env->nip);
+}
+
 static inline void dump_hcall(CPUPPCState *env)
 {
     qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64
@@ -185,7 +197,7 @@ 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, lev, ail;
+    int srr0, srr1, asrr0, asrr1, lev = -1, ail;
     bool lpes0;
 
     qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
@@ -421,6 +433,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             new_msr |= (target_ulong)MSR_HVB;
         }
         break;
+    case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception                     */
+        lev = env->error_code;
+        dump_syscall_vectored(env);
+        env->nip += 4;
+        new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
+        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
+        break;
     case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
     case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
     case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
@@ -723,12 +742,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         break;
     }
 
-    /* Save PC */
-    env->spr[srr0] = env->nip;
-
-    /* Save MSR */
-    env->spr[srr1] = msr;
-
     /* Sanity check */
     if (!(env->msr_mask & MSR_HVB)) {
         if (new_msr & MSR_HVB) {
@@ -741,14 +754,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         }
     }
 
-    /* If any alternate SRR register are defined, duplicate saved values */
-    if (asrr0 != -1) {
-        env->spr[asrr0] = env->spr[srr0];
-    }
-    if (asrr1 != -1) {
-        env->spr[asrr1] = env->spr[srr1];
-    }
-
     /*
      * Sort out endianness of interrupt, this differs depending on the
      * CPU, the HV mode, etc...
@@ -783,14 +788,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     }
 #endif
 
-    /* Jump to handler */
-    vector = env->excp_vectors[excp];
-    if (vector == (target_ulong)-1ULL) {
-        cpu_abort(cs, "Raised an exception without defined vector %d\n",
-                  excp);
-    }
-    vector |= env->excp_prefix;
-
     /*
      * AIL only works if there is no HV transition and we are running
      * with translations enabled
@@ -799,10 +796,21 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         ((new_msr & MSR_HVB) && !(msr & MSR_HVB))) {
         ail = 0;
     }
-    /* Handle AIL */
-    if (ail) {
-        new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
-        vector |= ppc_excp_vector_offset(cs, ail);
+
+    vector = env->excp_vectors[excp];
+    if (vector == (target_ulong)-1ULL) {
+        cpu_abort(cs, "Raised an exception without defined vector %d\n",
+                  excp);
+    }
+
+    vector |= env->excp_prefix;
+
+    /* If any alternate SRR register are defined, duplicate saved values */
+    if (asrr0 != -1) {
+        env->spr[asrr0] = env->nip;
+    }
+    if (asrr1 != -1) {
+        env->spr[asrr1] = msr;
     }
 
 #if defined(TARGET_PPC64)
@@ -822,6 +830,37 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     }
 #endif
 
+    if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
+        /* Save PC */
+        env->spr[srr0] = env->nip;
+
+        /* Save MSR */
+        env->spr[srr1] = msr;
+
+        /* Handle AIL */
+        if (ail) {
+            new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
+            vector |= ppc_excp_vector_offset(cs, ail);
+        }
+
+#if defined(TARGET_PPC64)
+    } else {
+        /* scv AIL is a little different */
+        if (ail) {
+            new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
+        }
+        if (ail == AIL_C000_0000_0000_4000) {
+            vector |= 0xc000000000003000ull;
+        } else {
+            vector |= 0x0000000000017000ull;
+        }
+        vector += lev * 0x20;
+
+        env->lr = env->nip;
+        env->ctr = msr;
+#endif
+    }
+
     powerpc_set_excp_state(cpu, vector, new_msr);
 }
 
@@ -1162,6 +1201,11 @@ void helper_rfid(CPUPPCState *env)
     do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
 }
 
+void helper_rfscv(CPUPPCState *env)
+{
+    do_rfi(env, env->lr, env->ctr);
+}
+
 void helper_hrfid(CPUPPCState *env)
 {
     do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index cfb4c07085..ee1498050d 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -15,6 +15,7 @@ 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(rfscv, void, env)
 DEF_HELPER_1(hrfid, void, env)
 DEF_HELPER_2(store_lpcr, void, env, tl)
 DEF_HELPER_2(store_pcr, void, env, tl)
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 127c82a24e..eb0ddba850 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -173,6 +173,7 @@ struct DisasContext {
     bool vsx_enabled;
     bool spe_enabled;
     bool tm_enabled;
+    bool scv_enabled;
     bool gtse;
     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
     int singlestep_enabled;
@@ -4012,6 +4013,22 @@ static void gen_rfid(DisasContext *ctx)
 #endif
 }
 
+static void gen_rfscv(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+    GEN_PRIV;
+#else
+    /* Restore CPU state */
+    CHK_SV;
+    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+        gen_io_start();
+    }
+    gen_update_cfar(ctx, ctx->base.pc_next - 4);
+    gen_helper_rfscv(cpu_env);
+    gen_sync_exception(ctx);
+#endif
+}
+
 static void gen_hrfid(DisasContext *ctx)
 {
 #if defined(CONFIG_USER_ONLY)
@@ -4030,6 +4047,7 @@ static void gen_hrfid(DisasContext *ctx)
 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
 #else
 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
+#define POWERPC_SYSCALL_VECTORED POWERPC_EXCP_SYSCALL_VECTORED
 #endif
 static void gen_sc(DisasContext *ctx)
 {
@@ -4039,6 +4057,21 @@ static void gen_sc(DisasContext *ctx)
     gen_exception_err(ctx, POWERPC_SYSCALL, lev);
 }
 
+#if defined(TARGET_PPC64)
+static void gen_scv(DisasContext *ctx)
+{
+    uint32_t lev;
+
+    if (unlikely(!ctx->scv_enabled)) {
+        gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_SCV);
+        return;
+    }
+
+    lev = (ctx->opcode >> 5) & 0x7F;
+    gen_exception_err(ctx, POWERPC_SYSCALL_VECTORED, lev);
+}
+#endif
+
 /***                                Trap                                   ***/
 
 /* Check for unconditional traps (always or never) */
@@ -7019,6 +7052,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),
+/* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */
+GEN_HANDLER_E(scv, 0x11, 0x10, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
+GEN_HANDLER_E(scv, 0x11, 0x00, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
+GEN_HANDLER_E(rfscv, 0x13, 0x12, 0x02, 0x03FF8001, PPC_NONE, PPC2_ISA300),
 GEN_HANDLER_E(stop, 0x13, 0x12, 0x0b, 0x03FFF801, PPC_NONE, PPC2_ISA300),
 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),
@@ -7026,7 +7063,9 @@ 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),
+/* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */
+GEN_HANDLER(sc, 0x11, 0x11, 0xFF, 0x03FFF01D, PPC_FLOW),
+GEN_HANDLER(sc, 0x11, 0x01, 0xFF, 0x03FFF01D, PPC_FLOW),
 GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
 #if defined(TARGET_PPC64)
@@ -7805,6 +7844,11 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     } else {
         ctx->vsx_enabled = false;
     }
+    if ((env->flags & POWERPC_FLAG_SCV) && (env->spr[SPR_FSCR] & (1ull << FSCR_SCV))) {
+        ctx->scv_enabled = true;
+    } else {
+        ctx->scv_enabled = false;
+    }
 #if defined(TARGET_PPC64)
     if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
         ctx->tm_enabled = !!msr_tm;
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 0ae145e18d..15025cd5ea 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -3382,6 +3382,7 @@ static void init_excp_POWER9(CPUPPCState *env)
 
 #if !defined(CONFIG_USER_ONLY)
     env->excp_vectors[POWERPC_EXCP_HVIRT]    = 0x00000EA0;
+    env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00000000;
 #endif
 }
 
@@ -9030,7 +9031,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
     pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
                  POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
                  POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
-                 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
+                 POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV;
     pcc->l1_dcache_size = 0x8000;
     pcc->l1_icache_size = 0x8000;
     pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
-- 
2.23.0



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

* Re: [PATCH v3 1/2] target/ppc: Improve syscall exception logging
  2020-03-17  5:49 [PATCH v3 1/2] target/ppc: Improve syscall exception logging Nicholas Piggin
  2020-03-17  5:49 ` [PATCH v3 2/2] target/ppc: Add support for scv and rfscv instructions Nicholas Piggin
@ 2020-03-19  6:22 ` David Gibson
  1 sibling, 0 replies; 4+ messages in thread
From: David Gibson @ 2020-03-19  6:22 UTC (permalink / raw)
  To: Nicholas Piggin; +Cc: qemu-ppc, qemu-devel

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

On Tue, Mar 17, 2020 at 03:49:17PM +1000, Nicholas Piggin wrote:
> system calls (at least in Linux) use registers r3-r8 for inputs, so
> include those registers in the dump.
> 
> This also adds a mode for PAPR hcalls, which have a different calling
> convention.
> 
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>

Applied to a newly created ppc-for-5.1 branch.

> ---
> Since v2:
> - Rebased on top of FWNMI series
> 
>  target/ppc/excp_helper.c | 30 ++++++++++++++++++++++++++----
>  1 file changed, 26 insertions(+), 4 deletions(-)
> 
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 08bc885ca6..81ee19ebae 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -57,12 +57,29 @@ static void ppc_hw_interrupt(CPUPPCState *env)
>  #else /* defined(CONFIG_USER_ONLY) */
>  static inline void dump_syscall(CPUPPCState *env)
>  {
> -    qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 " r3=%016" PRIx64
> -                  " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
> +    qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
> +                  " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64
> +                  " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64
>                    " nip=" TARGET_FMT_lx "\n",
>                    ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
>                    ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
> -                  ppc_dump_gpr(env, 6), env->nip);
> +                  ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
> +                  ppc_dump_gpr(env, 8), env->nip);
> +}
> +
> +static inline void dump_hcall(CPUPPCState *env)
> +{
> +    qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64
> +		  " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
> +		  " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64
> +		  " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64
> +                  " nip=" TARGET_FMT_lx "\n",
> +                  ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4),
> +		  ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6),
> +		  ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8),
> +		  ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10),
> +		  ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12),
> +		  env->nip);
>  }
>  
>  static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp,
> @@ -379,9 +396,14 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          }
>          break;
>      case POWERPC_EXCP_SYSCALL:   /* System call exception                    */
> -        dump_syscall(env);
>          lev = env->error_code;
>  
> +        if ((lev == 1) && cpu->vhyp) {
> +            dump_hcall(env);
> +        } else {
> +            dump_syscall(env);
> +        }
> +
>          /*
>           * We need to correct the NIP which in this case is supposed
>           * to point to the next instruction

-- 
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: 833 bytes --]

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

* Re: [PATCH v3 2/2] target/ppc: Add support for scv and rfscv instructions
  2020-03-17  5:49 ` [PATCH v3 2/2] target/ppc: Add support for scv and rfscv instructions Nicholas Piggin
@ 2020-03-19  6:22   ` David Gibson
  0 siblings, 0 replies; 4+ messages in thread
From: David Gibson @ 2020-03-19  6:22 UTC (permalink / raw)
  To: Nicholas Piggin; +Cc: qemu-ppc, qemu-devel

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

On Tue, Mar 17, 2020 at 03:49:18PM +1000, Nicholas Piggin wrote:
> POWER9 adds scv and rfscv instructions and the system call vectored
> interrupt. Linux does not support this instruction yet but it has
> been tested with a modified kernel that runs on real hardware.
> 
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>

Applied to ppc-for-5.1.

> ---
> Since v2:
> - Rebased on top of FWNMI series
> 
>  linux-user/ppc/cpu_loop.c       |  1 +
>  target/ppc/cpu.h                |  7 ++-
>  target/ppc/excp_helper.c        | 98 ++++++++++++++++++++++++---------
>  target/ppc/helper.h             |  1 +
>  target/ppc/translate.c          | 46 +++++++++++++++-
>  target/ppc/translate_init.inc.c |  3 +-
>  6 files changed, 126 insertions(+), 30 deletions(-)
> 
> diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c
> index 5b27f8603e..df71e15a25 100644
> --- a/linux-user/ppc/cpu_loop.c
> +++ b/linux-user/ppc/cpu_loop.c
> @@ -267,6 +267,7 @@ void cpu_loop(CPUPPCState *env)
>              queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
>              break;
>          case POWERPC_EXCP_SYSCALL:  /* System call exception                 */
> +        case POWERPC_EXCP_SYSCALL_VECTORED:
>              cpu_abort(cs, "Syscall exception while in user mode. "
>                        "Aborting\n");
>              break;
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index ed8d2015bd..992f0a49e8 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -127,8 +127,9 @@ enum {
>      POWERPC_EXCP_SDOOR_HV = 100,
>      /* ISA 3.00 additions */
>      POWERPC_EXCP_HVIRT    = 101,
> +    POWERPC_EXCP_SYSCALL_VECTORED = 102, /* scv exception                     */
>      /* EOL                                                                   */
> -    POWERPC_EXCP_NB       = 102,
> +    POWERPC_EXCP_NB       = 103,
>      /* QEMU exceptions: used internally during code translation              */
>      POWERPC_EXCP_STOP         = 0x200, /* stop translation                   */
>      POWERPC_EXCP_BRANCH       = 0x201, /* branch instruction                 */
> @@ -475,6 +476,7 @@ typedef struct ppc_v3_pate_t {
>  /* Facility Status and Control (FSCR) bits */
>  #define FSCR_EBB        (63 - 56) /* Event-Based Branch Facility */
>  #define FSCR_TAR        (63 - 55) /* Target Address Register */
> +#define FSCR_SCV        (63 - 51) /* System call vectored */
>  /* Interrupt cause mask and position in FSCR. HFSCR has the same format */
>  #define FSCR_IC_MASK    (0xFFULL)
>  #define FSCR_IC_POS     (63 - 7)
> @@ -484,6 +486,7 @@ typedef struct ppc_v3_pate_t {
>  #define FSCR_IC_TM          5
>  #define FSCR_IC_EBB         7
>  #define FSCR_IC_TAR         8
> +#define FSCR_IC_SCV        12
>  
>  /* Exception state register bits definition                                  */
>  #define ESR_PIL   PPC_BIT(36) /* Illegal Instruction                    */
> @@ -551,6 +554,8 @@ enum {
>      POWERPC_FLAG_VSX      = 0x00080000,
>      /* Has Transaction Memory (ISA 2.07)                                     */
>      POWERPC_FLAG_TM       = 0x00100000,
> +    /* Has SCV (ISA 3.00)                                                    */
> +    POWERPC_FLAG_SCV      = 0x00200000,
>  };
>  
>  /*****************************************************************************/
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 81ee19ebae..73b5c28d03 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -67,6 +67,18 @@ static inline void dump_syscall(CPUPPCState *env)
>                    ppc_dump_gpr(env, 8), env->nip);
>  }
>  
> +static inline void dump_syscall_vectored(CPUPPCState *env)
> +{
> +    qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
> +                  " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64
> +                  " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64
> +                  " nip=" TARGET_FMT_lx "\n",
> +                  ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
> +                  ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
> +                  ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7),
> +                  ppc_dump_gpr(env, 8), env->nip);
> +}
> +
>  static inline void dump_hcall(CPUPPCState *env)
>  {
>      qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64
> @@ -185,7 +197,7 @@ 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, lev, ail;
> +    int srr0, srr1, asrr0, asrr1, lev = -1, ail;
>      bool lpes0;
>  
>      qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
> @@ -421,6 +433,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>              new_msr |= (target_ulong)MSR_HVB;
>          }
>          break;
> +    case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception                     */
> +        lev = env->error_code;
> +        dump_syscall_vectored(env);
> +        env->nip += 4;
> +        new_msr |= env->msr & ((target_ulong)1 << MSR_EE);
> +        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
> +        break;
>      case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */
>      case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */
>      case POWERPC_EXCP_DECR:      /* Decrementer exception                    */
> @@ -723,12 +742,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          break;
>      }
>  
> -    /* Save PC */
> -    env->spr[srr0] = env->nip;
> -
> -    /* Save MSR */
> -    env->spr[srr1] = msr;
> -
>      /* Sanity check */
>      if (!(env->msr_mask & MSR_HVB)) {
>          if (new_msr & MSR_HVB) {
> @@ -741,14 +754,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          }
>      }
>  
> -    /* If any alternate SRR register are defined, duplicate saved values */
> -    if (asrr0 != -1) {
> -        env->spr[asrr0] = env->spr[srr0];
> -    }
> -    if (asrr1 != -1) {
> -        env->spr[asrr1] = env->spr[srr1];
> -    }
> -
>      /*
>       * Sort out endianness of interrupt, this differs depending on the
>       * CPU, the HV mode, etc...
> @@ -783,14 +788,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      }
>  #endif
>  
> -    /* Jump to handler */
> -    vector = env->excp_vectors[excp];
> -    if (vector == (target_ulong)-1ULL) {
> -        cpu_abort(cs, "Raised an exception without defined vector %d\n",
> -                  excp);
> -    }
> -    vector |= env->excp_prefix;
> -
>      /*
>       * AIL only works if there is no HV transition and we are running
>       * with translations enabled
> @@ -799,10 +796,21 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>          ((new_msr & MSR_HVB) && !(msr & MSR_HVB))) {
>          ail = 0;
>      }
> -    /* Handle AIL */
> -    if (ail) {
> -        new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
> -        vector |= ppc_excp_vector_offset(cs, ail);
> +
> +    vector = env->excp_vectors[excp];
> +    if (vector == (target_ulong)-1ULL) {
> +        cpu_abort(cs, "Raised an exception without defined vector %d\n",
> +                  excp);
> +    }
> +
> +    vector |= env->excp_prefix;
> +
> +    /* If any alternate SRR register are defined, duplicate saved values */
> +    if (asrr0 != -1) {
> +        env->spr[asrr0] = env->nip;
> +    }
> +    if (asrr1 != -1) {
> +        env->spr[asrr1] = msr;
>      }
>  
>  #if defined(TARGET_PPC64)
> @@ -822,6 +830,37 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
>      }
>  #endif
>  
> +    if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
> +        /* Save PC */
> +        env->spr[srr0] = env->nip;
> +
> +        /* Save MSR */
> +        env->spr[srr1] = msr;
> +
> +        /* Handle AIL */
> +        if (ail) {
> +            new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
> +            vector |= ppc_excp_vector_offset(cs, ail);
> +        }
> +
> +#if defined(TARGET_PPC64)
> +    } else {
> +        /* scv AIL is a little different */
> +        if (ail) {
> +            new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
> +        }
> +        if (ail == AIL_C000_0000_0000_4000) {
> +            vector |= 0xc000000000003000ull;
> +        } else {
> +            vector |= 0x0000000000017000ull;
> +        }
> +        vector += lev * 0x20;
> +
> +        env->lr = env->nip;
> +        env->ctr = msr;
> +#endif
> +    }
> +
>      powerpc_set_excp_state(cpu, vector, new_msr);
>  }
>  
> @@ -1162,6 +1201,11 @@ void helper_rfid(CPUPPCState *env)
>      do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
>  }
>  
> +void helper_rfscv(CPUPPCState *env)
> +{
> +    do_rfi(env, env->lr, env->ctr);
> +}
> +
>  void helper_hrfid(CPUPPCState *env)
>  {
>      do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
> diff --git a/target/ppc/helper.h b/target/ppc/helper.h
> index cfb4c07085..ee1498050d 100644
> --- a/target/ppc/helper.h
> +++ b/target/ppc/helper.h
> @@ -15,6 +15,7 @@ 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(rfscv, void, env)
>  DEF_HELPER_1(hrfid, void, env)
>  DEF_HELPER_2(store_lpcr, void, env, tl)
>  DEF_HELPER_2(store_pcr, void, env, tl)
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 127c82a24e..eb0ddba850 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -173,6 +173,7 @@ struct DisasContext {
>      bool vsx_enabled;
>      bool spe_enabled;
>      bool tm_enabled;
> +    bool scv_enabled;
>      bool gtse;
>      ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
>      int singlestep_enabled;
> @@ -4012,6 +4013,22 @@ static void gen_rfid(DisasContext *ctx)
>  #endif
>  }
>  
> +static void gen_rfscv(DisasContext *ctx)
> +{
> +#if defined(CONFIG_USER_ONLY)
> +    GEN_PRIV;
> +#else
> +    /* Restore CPU state */
> +    CHK_SV;
> +    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> +        gen_io_start();
> +    }
> +    gen_update_cfar(ctx, ctx->base.pc_next - 4);
> +    gen_helper_rfscv(cpu_env);
> +    gen_sync_exception(ctx);
> +#endif
> +}
> +
>  static void gen_hrfid(DisasContext *ctx)
>  {
>  #if defined(CONFIG_USER_ONLY)
> @@ -4030,6 +4047,7 @@ static void gen_hrfid(DisasContext *ctx)
>  #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
>  #else
>  #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
> +#define POWERPC_SYSCALL_VECTORED POWERPC_EXCP_SYSCALL_VECTORED
>  #endif
>  static void gen_sc(DisasContext *ctx)
>  {
> @@ -4039,6 +4057,21 @@ static void gen_sc(DisasContext *ctx)
>      gen_exception_err(ctx, POWERPC_SYSCALL, lev);
>  }
>  
> +#if defined(TARGET_PPC64)
> +static void gen_scv(DisasContext *ctx)
> +{
> +    uint32_t lev;
> +
> +    if (unlikely(!ctx->scv_enabled)) {
> +        gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_SCV);
> +        return;
> +    }
> +
> +    lev = (ctx->opcode >> 5) & 0x7F;
> +    gen_exception_err(ctx, POWERPC_SYSCALL_VECTORED, lev);
> +}
> +#endif
> +
>  /***                                Trap                                   ***/
>  
>  /* Check for unconditional traps (always or never) */
> @@ -7019,6 +7052,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),
> +/* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */
> +GEN_HANDLER_E(scv, 0x11, 0x10, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
> +GEN_HANDLER_E(scv, 0x11, 0x00, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
> +GEN_HANDLER_E(rfscv, 0x13, 0x12, 0x02, 0x03FF8001, PPC_NONE, PPC2_ISA300),
>  GEN_HANDLER_E(stop, 0x13, 0x12, 0x0b, 0x03FFF801, PPC_NONE, PPC2_ISA300),
>  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),
> @@ -7026,7 +7063,9 @@ 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),
> +/* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */
> +GEN_HANDLER(sc, 0x11, 0x11, 0xFF, 0x03FFF01D, PPC_FLOW),
> +GEN_HANDLER(sc, 0x11, 0x01, 0xFF, 0x03FFF01D, PPC_FLOW),
>  GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
>  GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
>  #if defined(TARGET_PPC64)
> @@ -7805,6 +7844,11 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>      } else {
>          ctx->vsx_enabled = false;
>      }
> +    if ((env->flags & POWERPC_FLAG_SCV) && (env->spr[SPR_FSCR] & (1ull << FSCR_SCV))) {
> +        ctx->scv_enabled = true;
> +    } else {
> +        ctx->scv_enabled = false;
> +    }
>  #if defined(TARGET_PPC64)
>      if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
>          ctx->tm_enabled = !!msr_tm;
> diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
> index 0ae145e18d..15025cd5ea 100644
> --- a/target/ppc/translate_init.inc.c
> +++ b/target/ppc/translate_init.inc.c
> @@ -3382,6 +3382,7 @@ static void init_excp_POWER9(CPUPPCState *env)
>  
>  #if !defined(CONFIG_USER_ONLY)
>      env->excp_vectors[POWERPC_EXCP_HVIRT]    = 0x00000EA0;
> +    env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00000000;
>  #endif
>  }
>  
> @@ -9030,7 +9031,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
>      pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
>                   POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
>                   POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
> -                 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
> +                 POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV;
>      pcc->l1_dcache_size = 0x8000;
>      pcc->l1_icache_size = 0x8000;
>      pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;

-- 
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: 833 bytes --]

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

end of thread, other threads:[~2020-03-19  6:24 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-03-17  5:49 [PATCH v3 1/2] target/ppc: Improve syscall exception logging Nicholas Piggin
2020-03-17  5:49 ` [PATCH v3 2/2] target/ppc: Add support for scv and rfscv instructions Nicholas Piggin
2020-03-19  6:22   ` David Gibson
2020-03-19  6:22 ` [PATCH v3 1/2] target/ppc: Improve syscall exception logging 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.