All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support
@ 2017-01-13  6:28 Suraj Jitindar Singh
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 01/17] powerpc/cpu-models: rename ISAv3.00 logical PVR definition Suraj Jitindar Singh
                   ` (18 more replies)
  0 siblings, 19 replies; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

This patch set provides the initial implementation of support for the 
POWER9 processor running in tcg mode under the pseries machine type.

To use a POWER9 cpu provide the command line option "-cpu POWER9".

This is the initial work to make the mmu emulation model look like a POWER9

Currently only legacy kernels are supported (hash without segment tables).

This patch set will be followed by two more in the near future to support
the new process table capabilities added in ISAv3.00; hash via segment
tables and radix. Kernels with support for this will currently fail when
they try to register a process table as this isn't yet implemented.

The assumption is that we're running a legacy kernel, in the event the
guest registers a process table (when support exists) we will handle it
accordingly.

The main changes are:
 - Define a new mmu model and fault handler
 - Add new LPCR fields and check them accordingly
 - Add a partition table entry to the machine state
 - Point to the partition table entry in the cpu state
 - Remove SDR1
 - Adapt to new pte format
 - NOOP the cp_abort instruction
 - Small bug fixes

This was intially one huge patch so I've tried to break it up into what I
think are logical chunks, how exactly this should be split up is up for 
debate.

A current upstream kernel with POWER9 support added to the architecture
vector should correctly report a POWER9 cpu under /proc/cpuinfo.

Suraj Jitindar Singh (17):
  powerpc/cpu-models: rename ISAv3.00 logical PVR definition
  hw/ppc/spapr: Add POWER9 to pseries cpu models
  target/ppc: Add pcr_supported to POWER9 cpu class definition
  target/ppc/POWER9: Add ISAv3.00 MMU definition
  target/ppc/POWER9: Adapt LPCR handling for POWER9
  target/ppc/POWER9: Direct all instr and data storage interrupts to the
    hypv
  target/ppc/POWER9: Add partition table pointer to sPAPRMachineState
  target/ppc/POWER9: Add external partition table pointer to cpu state
  target/ppc/POWER9: Remove SDR1 register
  target/ppc/POWER9: Add POWER9 mmu fault handler
  target/ppc/POWER9: Update to new pte format for POWER9 accesses
  target/ppc/POWER9: Add POWER9 pa-features definition
  target/ppc/POWER9: Add cpu_has_work function for POWER9
  target/ppc/debug: Print LPCR register value if register exists
  tcg/POWER9: NOOP the cp_abort instruction
  target/ppc/mmu_hash64: Fix printing unsigned as signed int
  target/ppc/mmu_hash64: Fix incorrect shift value in amr calculation

 hw/ppc/spapr.c              | 56 ++++++++++++++++++++++++---
 hw/ppc/spapr_cpu_core.c     | 15 +++++++-
 hw/ppc/spapr_hcall.c        | 51 +++++++++++++------------
 include/hw/ppc/spapr.h      |  1 +
 target/ppc/cpu-models.h     |  2 +-
 target/ppc/cpu-qom.h        |  5 ++-
 target/ppc/cpu.h            | 24 +++++++++++-
 target/ppc/kvm.c            | 10 ++++-
 target/ppc/mmu-hash64.c     | 68 +++++++++++++++++++++++++++------
 target/ppc/mmu-hash64.h     | 73 +++++++++++++++++++++++++----------
 target/ppc/mmu.h            | 27 +++++++++++++
 target/ppc/mmu_helper.c     | 61 ++++++++++++++++++++++++++++++
 target/ppc/translate.c      | 14 ++++++-
 target/ppc/translate_init.c | 92 +++++++++++++++++++++++++++++++++++++++------
 14 files changed, 418 insertions(+), 81 deletions(-)
 create mode 100644 target/ppc/mmu.h

-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 01/17] powerpc/cpu-models: rename ISAv3.00 logical PVR definition
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-01-16  2:16   ` David Gibson
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 02/17] hw/ppc/spapr: Add POWER9 to pseries cpu models Suraj Jitindar Singh
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

This logical PVR value now corresponds to ISA version 3.00 so rename it
accordingly.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 target/ppc/cpu-models.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/cpu-models.h b/target/ppc/cpu-models.h
index aafbbd7..d587e69 100644
--- a/target/ppc/cpu-models.h
+++ b/target/ppc/cpu-models.h
@@ -601,7 +601,7 @@ enum {
     CPU_POWERPC_LOGICAL_2_06       = 0x0F000003,
     CPU_POWERPC_LOGICAL_2_06_PLUS  = 0x0F100003,
     CPU_POWERPC_LOGICAL_2_07       = 0x0F000004,
-    CPU_POWERPC_LOGICAL_2_08       = 0x0F000005,
+    CPU_POWERPC_LOGICAL_3_00       = 0x0F000005,
 };
 
 /* System version register (used on MPC 8xxx)                                */
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 02/17] hw/ppc/spapr: Add POWER9 to pseries cpu models
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 01/17] powerpc/cpu-models: rename ISAv3.00 logical PVR definition Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-01-16 12:11   ` David Gibson
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 03/17] target/ppc: Add pcr_supported to POWER9 cpu class definition Suraj Jitindar Singh
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

Add POWER9 cpu to list of spapr core models which allows it to be specified
as the cpu model for a pseries guest (e.g. -machine pseries -cpu POWER9).

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 hw/ppc/spapr_cpu_core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index c18632b..8cc7058 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -358,6 +358,9 @@ static const char *spapr_core_models[] = {
 
     /* POWER8NVL */
     "POWER8NVL_v1.0",
+
+    /* POWER9 */
+    "POWER9_v1.0",
 };
 
 void spapr_cpu_core_class_init(ObjectClass *oc, void *data)
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 03/17] target/ppc: Add pcr_supported to POWER9 cpu class definition
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 01/17] powerpc/cpu-models: rename ISAv3.00 logical PVR definition Suraj Jitindar Singh
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 02/17] hw/ppc/spapr: Add POWER9 to pseries cpu models Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-01-16 21:21   ` David Gibson
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 04/17] target/ppc/POWER9: Add ISAv3.00 MMU definition Suraj Jitindar Singh
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

pcr_supported is used to define the supported PCR values for a given
processor. A POWER9 processor can support 3.00, 2.07, 2.06 and 2.05
compatibility modes, thus we set this accordingly.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 target/ppc/cpu.h            | 1 +
 target/ppc/translate_init.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 2a50c43..afb7ddb 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -2250,6 +2250,7 @@ enum {
     PCR_COMPAT_2_05     = 1ull << (63-62),
     PCR_COMPAT_2_06     = 1ull << (63-61),
     PCR_COMPAT_2_07     = 1ull << (63-60),
+    PCR_COMPAT_3_00     = 1ull << (63-59),
     PCR_VEC_DIS         = 1ull << (63-0), /* Vec. disable (bit NA since POWER8) */
     PCR_VSX_DIS         = 1ull << (63-1), /* VSX disable (bit NA since POWER8) */
     PCR_TM_DIS          = 1ull << (63-2), /* Trans. memory disable (POWER8) */
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 626e031..bfc1f24 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -8797,6 +8797,8 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
     dc->props = powerpc_servercpu_properties;
     pcc->pvr_match = ppc_pvr_match_power9;
     pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07;
+    pcc->pcr_supported = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 |
+                         PCR_COMPAT_2_05;
     pcc->init_proc = init_proc_POWER9;
     pcc->check_pow = check_pow_nocheck;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 04/17] target/ppc/POWER9: Add ISAv3.00 MMU definition
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (2 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 03/17] target/ppc: Add pcr_supported to POWER9 cpu class definition Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-01-16 21:36   ` David Gibson
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 05/17] target/ppc/POWER9: Adapt LPCR handling for POWER9 Suraj Jitindar Singh
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

POWER9 processors implement the mmu as defined in version 3.00 of the ISA.

Add a definition for this mmu model and set the POWER9 cpu model to use
this mmu model.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 target/ppc/cpu-qom.h        | 5 ++++-
 target/ppc/mmu_helper.c     | 2 ++
 target/ppc/translate_init.c | 3 +--
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
index d46c31a..1577cc8 100644
--- a/target/ppc/cpu-qom.h
+++ b/target/ppc/cpu-qom.h
@@ -86,10 +86,13 @@ enum powerpc_mmu_t {
     POWERPC_MMU_2_07       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
                              | POWERPC_MMU_64K
                              | POWERPC_MMU_AMR | 0x00000004,
-    /* FIXME Add POWERPC_MMU_3_OO defines */
     /* Architecture 2.07 "degraded" (no 1T segments)           */
     POWERPC_MMU_2_07a      = POWERPC_MMU_64 | POWERPC_MMU_AMR
                              | 0x00000004,
+    /* Architecture 3.00 variant                               */
+    POWERPC_MMU_3_00       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
+                             | POWERPC_MMU_64K
+                             | POWERPC_MMU_AMR | 0x00000005,
 };
 
 /*****************************************************************************/
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index d09fc0a..2ab4562 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -1935,6 +1935,7 @@ void ppc_tlb_invalidate_all(CPUPPCState *env)
     case POWERPC_MMU_2_06a:
     case POWERPC_MMU_2_07:
     case POWERPC_MMU_2_07a:
+    case POWERPC_MMU_3_00:
 #endif /* defined(TARGET_PPC64) */
         env->tlb_need_flush = 0;
         tlb_flush(CPU(cpu), 1);
@@ -1974,6 +1975,7 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
     case POWERPC_MMU_2_06a:
     case POWERPC_MMU_2_07:
     case POWERPC_MMU_2_07a:
+    case POWERPC_MMU_3_00:
         /* tlbie invalidate TLBs for all segments */
         /* XXX: given the fact that there are too many segments to invalidate,
          *      and we still don't have a tlb_flush_mask(env, n, mask) in QEMU,
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index bfc1f24..2402eef 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -8838,8 +8838,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
                     (1ull << MSR_PMM) |
                     (1ull << MSR_RI) |
                     (1ull << MSR_LE);
-    /* Using 2.07 defines until new radix model is added. */
-    pcc->mmu_model = POWERPC_MMU_2_07;
+    pcc->mmu_model = POWERPC_MMU_3_00;
 #if defined(CONFIG_SOFTMMU)
     pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
     /* segment page size remain the same */
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 05/17] target/ppc/POWER9: Adapt LPCR handling for POWER9
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (3 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 04/17] target/ppc/POWER9: Add ISAv3.00 MMU definition Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-01-16 21:40   ` David Gibson
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 06/17] target/ppc/POWER9: Direct all instr and data storage interrupts to the hypv Suraj Jitindar Singh
                   ` (13 subsequent siblings)
  18 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

The logical partitioning control register controls a threads operation
based on the partition it is currently executing. Add new definitions and
update the mask used when writing to the LPCR based on the POWER9 spec.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 target/ppc/cpu.h            | 20 +++++++++++++++++++-
 target/ppc/mmu-hash64.c     |  8 ++++++++
 target/ppc/translate_init.c | 24 ++++++++++++++++++------
 3 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index afb7ddb..0ab49b3 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -379,15 +379,22 @@ struct ppc_slb_t {
 #define LPCR_ISL          (1ull << (63 - 2))
 #define LPCR_KBV          (1ull << (63 - 3))
 #define LPCR_DPFD_SHIFT   (63 - 11)
-#define LPCR_DPFD         (0x3ull << LPCR_DPFD_SHIFT)
+#define LPCR_DPFD         (0x7ull << LPCR_DPFD_SHIFT)
 #define LPCR_VRMASD_SHIFT (63 - 16)
 #define LPCR_VRMASD       (0x1full << LPCR_VRMASD_SHIFT)
+/* P9: Power-saving mode Exit Cause Enable (Upper Section) Mask */
+#define LPCR_PECE_U_SHIFT (63 - 19)
+#define LPCR_PECE_U_MASK  (0x7ull << LPCR_PECE_U_SHIFT)
+#define LPCR_HVEE         (1ull << (63 - 17)) /* Hypervisor Virt Exit Enable */
 #define LPCR_RMLS_SHIFT   (63 - 37)
 #define LPCR_RMLS         (0xfull << LPCR_RMLS_SHIFT)
 #define LPCR_ILE          (1ull << (63 - 38))
 #define LPCR_AIL_SHIFT    (63 - 40)      /* Alternate interrupt location */
 #define LPCR_AIL          (3ull << LPCR_AIL_SHIFT)
+#define LPCR_UPRT         (1ull << (63 - 41)) /* Use Process Table */
+#define LPCR_EVIRT        (1ull << (63 - 42)) /* Enhanced Virtualisation */
 #define LPCR_ONL          (1ull << (63 - 45))
+#define LPCR_LD           (1ull << (63 - 46)) /* Large Decrementer */
 #define LPCR_P7_PECE0     (1ull << (63 - 49))
 #define LPCR_P7_PECE1     (1ull << (63 - 50))
 #define LPCR_P7_PECE2     (1ull << (63 - 51))
@@ -396,11 +403,22 @@ struct ppc_slb_t {
 #define LPCR_P8_PECE2     (1ull << (63 - 49))
 #define LPCR_P8_PECE3     (1ull << (63 - 50))
 #define LPCR_P8_PECE4     (1ull << (63 - 51))
+/* P9: Power-saving mode Exit Cause Enable (Lower Section) Mask */
+#define LPCR_PECE_L_SHIFT (63 - 51)
+#define LPCR_PECE_L_MASK  (0x1full << LPCR_PECE_L_SHIFT)
+#define LPCR_PDEE         (1ull << (63 - 47)) /* Privileged Doorbell Exit EN */
+#define LPCR_HDEE         (1ull << (63 - 48)) /* Hyperv Doorbell Exit Enable */
+#define LPCR_EEE          (1ull << (63 - 49)) /* External Exit Enable        */
+#define LPCR_DEE          (1ull << (63 - 50)) /* Decrementer Exit Enable     */
+#define LPCR_OEE          (1ull << (63 - 51)) /* Other Exit Enable           */
 #define LPCR_MER          (1ull << (63 - 52))
+#define LPCR_GTSE         (1ull << (63 - 53)) /* Guest Translation Shootdown */
 #define LPCR_TC           (1ull << (63 - 54))
+#define LPCR_HEIC         (1ull << (63 - 59)) /* HV Extern Interrupt Control */
 #define LPCR_LPES0        (1ull << (63 - 60))
 #define LPCR_LPES1        (1ull << (63 - 61))
 #define LPCR_RMI          (1ull << (63 - 62))
+#define LPCR_HVICE        (1ull << (63 - 62)) /* HV Virtualisation Int Enable */
 #define LPCR_HDICE        (1ull << (63 - 63))
 
 #define msr_sf   ((env->msr >> MSR_SF)   & 1)
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index fdb7a78..3a2acb8 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -1050,6 +1050,14 @@ void helper_store_lpcr(CPUPPCState *env, target_ulong val)
                       LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 |
                       LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE);
         break;
+    case POWERPC_MMU_3_00: /* P9 */
+        lpcr = val & (LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
+                      (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
+                      LPCR_UPRT | LPCR_EVIRT | LPCR_ONL |
+                      (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
+                      LPCR_DEE | LPCR_OEE)) | LPCR_MER | LPCR_GTSE | LPCR_TC |
+                      LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE);
+        break;
     default:
         ;
     }
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 2402eef..a1994d3 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -8887,12 +8887,24 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)
     lpcr->default_value &= ~LPCR_RMLS;
     lpcr->default_value |= 1ull << LPCR_RMLS_SHIFT;
 
-    /* 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;
+    switch (env->mmu_model) {
+    case POWERPC_MMU_3_00:
+        /* By default we choose legacy mode and switch to new hash or radix
+         * when a register process table hcall is made. So disable process
+         * tables and guest translation shootdown by default
+         */
+        lpcr->default_value &= ~(LPCR_UPRT | LPCR_GTSE);
+        lpcr->default_value |= LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE |
+                               LPCR_OEE;
+        break;
+    default:
+        /* 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.5.5

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

* [Qemu-devel] [RFC PATCH 06/17] target/ppc/POWER9: Direct all instr and data storage interrupts to the hypv
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (4 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 05/17] target/ppc/POWER9: Adapt LPCR handling for POWER9 Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-02-01  0:50   ` David Gibson
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 07/17] target/ppc/POWER9: Add partition table pointer to sPAPRMachineState Suraj Jitindar Singh
                   ` (12 subsequent siblings)
  18 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

The vpm0 bit was removed from the LPCR in POWER9, this bit controlled
whether ISI and DSI interrupts were directed to the hypervisor or the
partition. These interrupts now go to the hypervisor irrespective, thus
it is no longer necessary to check the vmp0 bit in the LPCR.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 target/ppc/mmu-hash64.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index 3a2acb8..fe7da18 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -640,7 +640,15 @@ static void ppc_hash64_set_isi(CPUState *cs, CPUPPCState *env,
     if (msr_ir) {
         vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
     } else {
-        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
+        switch (env->mmu_model) {
+        case POWERPC_MMU_3_00:
+            /* Field deprecated in ISAv3.00 - interrupts always go to hyperv */
+            vpm = true;
+            break;
+        default:
+            vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
+            break;
+        }
     }
     if (vpm && !msr_hv) {
         cs->exception_index = POWERPC_EXCP_HISI;
@@ -658,7 +666,15 @@ static void ppc_hash64_set_dsi(CPUState *cs, CPUPPCState *env, uint64_t dar,
     if (msr_dr) {
         vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
     } else {
-        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
+        switch (env->mmu_model) {
+        case POWERPC_MMU_3_00:
+            /* Field deprecated in ISAv3.00 - interrupts always go to hyperv */
+            vpm = true;
+            break;
+        default:
+            vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
+            break;
+        }
     }
     if (vpm && !msr_hv) {
         cs->exception_index = POWERPC_EXCP_HDSI;
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 07/17] target/ppc/POWER9: Add partition table pointer to sPAPRMachineState
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (5 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 06/17] target/ppc/POWER9: Direct all instr and data storage interrupts to the hypv Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-02-01  4:04   ` David Gibson
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 08/17] target/ppc/POWER9: Add external partition table pointer to cpu state Suraj Jitindar Singh
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

POWER9 uses a partition table to store information relating to how
address translation is performed on a per partition basis.

Add a data area for this to the sPAPRMachineState struct and (re)allocate
it on machine reset.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 hw/ppc/spapr.c         | 38 ++++++++++++++++++++++++++++++++------
 include/hw/ppc/spapr.h |  1 +
 target/ppc/mmu.h       | 13 +++++++++++++
 3 files changed, 46 insertions(+), 6 deletions(-)
 create mode 100644 target/ppc/mmu.h

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 208ef7b..45bd2de 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -41,6 +41,7 @@
 #include "migration/migration.h"
 #include "mmu-hash64.h"
 #include "qom/cpu.h"
+#include "mmu.h"
 
 #include "hw/boards.h"
 #include "hw/ppc/ppc.h"
@@ -1115,6 +1116,26 @@ static void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
     }
 }
 
+static void spapr_reallocate_patb(sPAPRMachineState *spapr, Error **errp)
+{
+    g_free(spapr->patb);
+    spapr->patb = NULL;
+
+    if (!kvm_enabled()) {
+        /* We need to allocate a partition table entry */
+        size_t size = sizeof(struct patb_entry);
+
+        spapr->patb = qemu_memalign(size, size);
+        if (!spapr->patb) {
+            error_setg_errno(errp, errno, "Could not allocate memory for "
+                                          "partition table entry");
+            return;
+        }
+
+        memset(spapr->patb, 0, size);
+    }
+}
+
 static void find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque)
 {
     bool matched = false;
@@ -1134,7 +1155,7 @@ static void ppc_spapr_reset(void)
 {
     MachineState *machine = MACHINE(qdev_get_machine());
     sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
-    PowerPCCPU *first_ppc_cpu;
+    PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
     uint32_t rtas_limit;
     hwaddr rtas_addr, fdt_addr;
     void *fdt;
@@ -1143,10 +1164,16 @@ static void ppc_spapr_reset(void)
     /* Check for unknown sysbus devices */
     foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
 
-    /* Allocate and/or reset the hash page table */
-    spapr_reallocate_hpt(spapr,
-                         spapr_hpt_shift_for_ramsize(machine->maxram_size),
-                         &error_fatal);
+    switch (first_ppc_cpu->env.mmu_model) {
+    case POWERPC_MMU_3_00:
+        /* Allocate the partition table */
+        spapr_reallocate_patb(spapr, &error_fatal);
+    default:
+        /* Allocate and/or reset the hash page table */
+        spapr_reallocate_hpt(spapr,
+                             spapr_hpt_shift_for_ramsize(machine->maxram_size),
+                             &error_fatal);
+    }
 
     /* Update the RMA size if necessary */
     if (spapr->vrma_adjust) {
@@ -1193,7 +1220,6 @@ static void ppc_spapr_reset(void)
     g_free(fdt);
 
     /* Set up the entry state */
-    first_ppc_cpu = POWERPC_CPU(first_cpu);
     first_ppc_cpu->env.gpr[3] = fdt_addr;
     first_ppc_cpu->env.gpr[5] = 0;
     first_cpu->halted = 0;
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index bd5bcf7..b654773 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -63,6 +63,7 @@ struct sPAPRMachineState {
 
     void *htab;
     uint32_t htab_shift;
+    void *patb;
     hwaddr rma_size;
     int vrma_adjust;
     ssize_t rtas_size;
diff --git a/target/ppc/mmu.h b/target/ppc/mmu.h
new file mode 100644
index 0000000..67b9707
--- /dev/null
+++ b/target/ppc/mmu.h
@@ -0,0 +1,13 @@
+#ifndef MMU_H
+#define MMU_H
+
+#ifndef CONFIG_USER_ONLY
+
+/* Partition Table Entry */
+struct patb_entry {
+    uint64_t patbe0, patbe1;
+};
+
+#endif /* CONFIG_USER_ONLY */
+
+#endif /* MMU_H */
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 08/17] target/ppc/POWER9: Add external partition table pointer to cpu state
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (6 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 07/17] target/ppc/POWER9: Add partition table pointer to sPAPRMachineState Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-02-01  4:09   ` David Gibson
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 09/17] target/ppc/POWER9: Remove SDR1 register Suraj Jitindar Singh
                   ` (10 subsequent siblings)
  18 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

Similarly to how we have an external hpt pointer in the cpu state, add
an external partition table pointer and update it to point to the
partition table entry in the machine state struct on cpu reset.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 hw/ppc/spapr_cpu_core.c | 12 ++++++++++--
 target/ppc/cpu.h        |  3 +++
 target/ppc/mmu.h        |  6 ++++++
 target/ppc/mmu_helper.c | 12 ++++++++++++
 4 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 8cc7058..72a7f90 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -17,6 +17,7 @@
 #include "hw/ppc/ppc.h"
 #include "target/ppc/mmu-hash64.h"
 #include "sysemu/numa.h"
+#include "mmu.h"
 
 static void spapr_cpu_reset(void *opaque)
 {
@@ -34,8 +35,15 @@ static void spapr_cpu_reset(void *opaque)
 
     env->spr[SPR_HIOR] = 0;
 
-    ppc_hash64_set_external_hpt(cpu, spapr->htab, spapr->htab_shift,
-                                &error_fatal);
+    switch (env->mmu_model) {
+    case POWERPC_MMU_3_00:
+        ppc64_set_external_patb(cpu, spapr->patb, &error_fatal);
+    default:
+        /* We assume legacy until told otherwise, thus set HPT irrespective */
+        ppc_hash64_set_external_hpt(cpu, spapr->htab, spapr->htab_shift,
+                                    &error_fatal);
+        break;
+    }
 }
 
 static void spapr_cpu_destroy(PowerPCCPU *cpu)
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 0ab49b3..e8b7c06 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -77,6 +77,7 @@
 #include "exec/cpu-defs.h"
 #include "cpu-qom.h"
 #include "fpu/softfloat.h"
+#include "mmu.h"
 
 #if defined (TARGET_PPC64)
 #define PPC_ELF_MACHINE     EM_PPC64
@@ -1009,6 +1010,8 @@ struct CPUPPCState {
     target_ulong sr[32];
     /* externally stored hash table */
     uint8_t *external_htab;
+    /* externally stored partition table entry */
+    struct patb_entry *external_patbe;
     /* BATs */
     uint32_t nb_BATs;
     target_ulong DBAT[2][8];
diff --git a/target/ppc/mmu.h b/target/ppc/mmu.h
index 67b9707..c7967c3 100644
--- a/target/ppc/mmu.h
+++ b/target/ppc/mmu.h
@@ -8,6 +8,12 @@ struct patb_entry {
     uint64_t patbe0, patbe1;
 };
 
+#ifdef TARGET_PPC64
+
+void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error **errp);
+
+#endif /* TARGET_PPC64 */
+
 #endif /* CONFIG_USER_ONLY */
 
 #endif /* MMU_H */
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index 2ab4562..bc6c117 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -28,6 +28,7 @@
 #include "exec/cpu_ldst.h"
 #include "exec/log.h"
 #include "helper_regs.h"
+#include "mmu.h"
 
 //#define DEBUG_MMU
 //#define DEBUG_BATS
@@ -2907,3 +2908,14 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
                                retaddr);
     }
 }
+
+/******************************************************************************/
+
+/* ISA v3.00 (POWER9) Generic MMU Helpers */
+
+void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error **errp)
+{
+    CPUPPCState *env = &cpu->env;
+
+    env->external_patbe = (struct patb_entry *) patb;
+}
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 09/17] target/ppc/POWER9: Remove SDR1 register
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (7 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 08/17] target/ppc/POWER9: Add external partition table pointer to cpu state Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-02-01  4:16   ` David Gibson
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 10/17] target/ppc/POWER9: Add POWER9 mmu fault handler Suraj Jitindar Singh
                   ` (9 subsequent siblings)
  18 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

The SDR1 registers was used to store the location of the hash page table.

This register no longer exists on POWER9 processors, so don't create it.

We now store the hash page table location in the process table entry.

We now check if the SDR1 register exists before printing its value when
displaying register debug info.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 target/ppc/kvm.c            | 10 +++++++++-
 target/ppc/mmu-hash64.c     | 15 ++++++++++++++-
 target/ppc/translate.c      |  6 ++++--
 target/ppc/translate_init.c | 16 +++++++++++++---
 4 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 9c4834c..6016930 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -930,7 +930,15 @@ int kvmppc_put_books_sregs(PowerPCCPU *cpu)
 
     sregs.pvr = env->spr[SPR_PVR];
 
-    sregs.u.s.sdr1 = env->spr[SPR_SDR1];
+    switch (env->mmu_model) {
+    case POWERPC_MMU_3_00:
+        if (env->external_patbe)
+            sregs.u.s.sdr1 = env->external_patbe->patbe0;
+        break;
+    default:
+        sregs.u.s.sdr1 = env->spr[SPR_SDR1];
+        break;
+    }
 
     /* Sync SLB */
 #ifdef TARGET_PPC64
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index fe7da18..b9d4f4e 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -291,7 +291,20 @@ void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong value,
     CPUPPCState *env = &cpu->env;
     target_ulong htabsize = value & SDR_64_HTABSIZE;
 
-    env->spr[SPR_SDR1] = value;
+    switch (env->mmu_model) {
+    case POWERPC_MMU_3_00:
+        /*
+         * Technically P9 doesn't have a SDR1, the hash table address should be
+         * stored in the partition table entry instead.
+         */
+        if (env->external_patbe)
+            env->external_patbe->patbe0 = value;
+        break;
+    default:
+        env->spr[SPR_SDR1] = value;
+        break;
+    }
+
     if (htabsize > 28) {
         error_setg(errp,
                    "Invalid HTABSIZE 0x" TARGET_FMT_lx" stored in SDR1",
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 1212180..521aed3 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -6922,9 +6922,11 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
     case POWERPC_MMU_2_06a:
     case POWERPC_MMU_2_07:
     case POWERPC_MMU_2_07a:
+    case POWERPC_MMU_3_00:
 #endif
-        cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "   DAR " TARGET_FMT_lx
-                       "  DSISR " TARGET_FMT_lx "\n", env->spr[SPR_SDR1],
+        if (env->spr_cb[SPR_SDR1].name)
+            cpu_fprintf(f, " SDR1 " TARGET_FMT_lx " ", env->spr[SPR_SDR1]);
+        cpu_fprintf(f, "  DAR " TARGET_FMT_lx "  DSISR " TARGET_FMT_lx "\n",
                     env->spr[SPR_DAR], env->spr[SPR_DSISR]);
         break;
     case POWERPC_MMU_BOOKE206:
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index a1994d3..c771ba3 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -32,6 +32,7 @@
 #include "qapi/visitor.h"
 #include "hw/qdev-properties.h"
 #include "hw/ppc/ppc.h"
+#include "mmu.h"
 
 //#define PPC_DUMP_CPU
 //#define PPC_DEBUG_SPR
@@ -722,8 +723,8 @@ static void gen_spr_generic (CPUPPCState *env)
                  0x00000000);
 }
 
-/* SPR common to all non-embedded PowerPC, including 601 */
-static void gen_spr_ne_601 (CPUPPCState *env)
+/* SPR common to all non-embedded PowerPC, including POWER9 */
+static void gen_spr_ne_power9 (CPUPPCState *env)
 {
     /* Exception processing */
     spr_register_kvm(env, SPR_DSISR, "DSISR",
@@ -739,6 +740,12 @@ static void gen_spr_ne_601 (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_decr, &spr_write_decr,
                  0x00000000);
+}
+
+/* SPR common to all non-embedded PowerPC, including 601 */
+static void gen_spr_ne_601 (CPUPPCState *env)
+{
+    gen_spr_ne_power9(env);
     /* Memory management */
     spr_register(env, SPR_SDR1, "SDR1",
                  SPR_NOACCESS, SPR_NOACCESS,
@@ -8222,7 +8229,6 @@ static void gen_spr_power8_rpr(CPUPPCState *env)
 
 static void init_proc_book3s_64(CPUPPCState *env, int version)
 {
-    gen_spr_ne_601(env);
     gen_tbl(env);
     gen_spr_book3s_altivec(env);
     gen_spr_book3s_pmu_sup(env);
@@ -8280,6 +8286,10 @@ static void init_proc_book3s_64(CPUPPCState *env, int version)
         gen_spr_power8_book4(env);
         gen_spr_power8_rpr(env);
     }
+    if (version >= BOOK3S_CPU_POWER9)
+        gen_spr_ne_power9(env);
+    else
+        gen_spr_ne_601(env);
     if (version < BOOK3S_CPU_POWER8) {
         gen_spr_book3s_dbg(env);
     } else {
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 10/17] target/ppc/POWER9: Add POWER9 mmu fault handler
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (8 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 09/17] target/ppc/POWER9: Remove SDR1 register Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-02-01  4:23   ` David Gibson
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 11/17] target/ppc/POWER9: Update to new pte format for POWER9 accesses Suraj Jitindar Singh
                   ` (8 subsequent siblings)
  18 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

Add a new mmu fault handler for the POWER9 cpu and add it as the handler
for the POWER9 cpu definition.

This handler checks if the guest is radix or hash based on the value in the
partition table entry and calls the correct fault handler accordingly.

The hash fault handling code has also been updated to check if the
partition is using segment tables.

Currently only legacy hash (no segment tables) is supported.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 target/ppc/mmu-hash64.c     |  8 ++++++++
 target/ppc/mmu.h            |  8 ++++++++
 target/ppc/mmu_helper.c     | 47 +++++++++++++++++++++++++++++++++++++++++++++
 target/ppc/translate_init.c |  2 +-
 4 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index b9d4f4e..b476b3f 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -73,6 +73,14 @@ static ppc_slb_t *slb_lookup(PowerPCCPU *cpu, target_ulong eaddr)
         }
     }
 
+    /* Check if in-memory segment tables are in use */
+    if (ppc64_use_proc_tbl(cpu)) {
+        /* TODO - Unsupported */
+        qemu_log_mask(LOG_UNIMP, "%s: unimplemented - segment table support\n",
+                      __func__);
+        /* Not much we can do here, caller will generate a segment interrupt */
+    }
+
     return NULL;
 }
 
diff --git a/target/ppc/mmu.h b/target/ppc/mmu.h
index c7967c3..e07b128 100644
--- a/target/ppc/mmu.h
+++ b/target/ppc/mmu.h
@@ -3,6 +3,10 @@
 
 #ifndef CONFIG_USER_ONLY
 
+/* Common Partition Table Entry Fields */
+#define PATBE0_HR                0x8000000000000000
+#define PATBE1_GR                0x8000000000000000
+
 /* Partition Table Entry */
 struct patb_entry {
     uint64_t patbe0, patbe1;
@@ -11,6 +15,10 @@ struct patb_entry {
 #ifdef TARGET_PPC64
 
 void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error **errp);
+bool ppc64_use_proc_tbl(PowerPCCPU *cpu);
+bool ppc64_radix_guest(PowerPCCPU *cpu);
+int ppc64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
+                           int mmu_idx);
 
 #endif /* TARGET_PPC64 */
 
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index bc6c117..612f407 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -28,6 +28,7 @@
 #include "exec/cpu_ldst.h"
 #include "exec/log.h"
 #include "helper_regs.h"
+#include "qemu/error-report.h"
 #include "mmu.h"
 
 //#define DEBUG_MMU
@@ -1281,6 +1282,17 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
     case POWERPC_MMU_2_07a:
         dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
         break;
+    case POWERPC_MMU_3_00:
+        if (ppc64_radix_guest(ppc_env_get_cpu(env))) {
+            /* TODO - Unsupported */
+        } else {
+            if (ppc64_use_proc_tbl(ppc_env_get_cpu(env))) {
+                /* TODO - Unsupported */
+            } else {
+                dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
+                break;
+            }
+        }
 #endif
     default:
         qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
@@ -1422,6 +1434,17 @@ hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
     case POWERPC_MMU_2_07:
     case POWERPC_MMU_2_07a:
         return ppc_hash64_get_phys_page_debug(cpu, addr);
+    case POWERPC_MMU_3_00:
+        if (ppc64_radix_guest(ppc_env_get_cpu(env))) {
+            /* TODO - Unsupported */
+        } else {
+            if (ppc64_use_proc_tbl(ppc_env_get_cpu(env))) {
+                /* TODO - Unsupported */
+            } else {
+                return ppc_hash64_get_phys_page_debug(cpu, addr);
+            }
+        }
+        break;
 #endif
 
     case POWERPC_MMU_32B:
@@ -2919,3 +2942,27 @@ void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error **errp)
 
     env->external_patbe = (struct patb_entry *) patb;
 }
+
+inline bool ppc64_use_proc_tbl(PowerPCCPU *cpu)
+{
+    return !!(cpu->env.spr[SPR_LPCR] & LPCR_UPRT);
+}
+
+inline bool ppc64_radix_guest(PowerPCCPU *cpu)
+{
+    struct patb_entry *patbe = cpu->env.external_patbe;
+
+    return patbe && (patbe->patbe1 & PATBE1_GR);
+}
+
+int ppc64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
+                           int mmu_idx)
+{
+    if (ppc64_radix_guest(cpu)) { /* Guest uses radix */
+        /* TODO - Unsupported */
+        error_report("Guest Radix Support Unimplemented\n");
+        abort();
+    } else { /* Guest uses hash */
+        return ppc_hash64_handle_mmu_fault(cpu, eaddr, rwx, mmu_idx);
+    }
+}
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index c771ba3..87297a7 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -8850,7 +8850,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
                     (1ull << MSR_LE);
     pcc->mmu_model = POWERPC_MMU_3_00;
 #if defined(CONFIG_SOFTMMU)
-    pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
+    pcc->handle_mmu_fault = ppc64_handle_mmu_fault;
     /* segment page size remain the same */
     pcc->sps = &POWER7_POWER8_sps;
 #endif
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 11/17] target/ppc/POWER9: Update to new pte format for POWER9 accesses
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (9 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 10/17] target/ppc/POWER9: Add POWER9 mmu fault handler Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-02-01  4:28   ` David Gibson
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 12/17] target/ppc/POWER9: Add POWER9 pa-features definition Suraj Jitindar Singh
                   ` (7 subsequent siblings)
  18 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

The page table entry format was updated for the POWER9 processor.

It was decided that kernels would used the old format irrespective
with the translation occuring at the hypervisor level. Thus we convert
between the old and new format when accessing the ptes. Since we need the
whole pte to perform this conversion, we remove the old functions which
accessed either the first or second doubleword and introduce a new
functions which access the entire pte, returning the entry converted
back to the old format (if required). Update call sites accordingly.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 hw/ppc/spapr_hcall.c    | 51 ++++++++++++++++++-----------------
 target/ppc/mmu-hash64.c | 13 +++++----
 target/ppc/mmu-hash64.h | 71 ++++++++++++++++++++++++++++++++++++-------------
 3 files changed, 86 insertions(+), 49 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 9a9bedf..9f0c20d 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -125,7 +125,8 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
         pte_index &= ~7ULL;
         token = ppc_hash64_start_access(cpu, pte_index);
         for (; index < 8; index++) {
-            if (!(ppc_hash64_load_hpte0(cpu, token, index) & HPTE64_V_VALID)) {
+            ppc_hash_pte64_t pte = ppc_hash64_load_hpte(cpu, token, index);
+            if (!(pte.pte0 & HPTE64_V_VALID)) {
                 break;
             }
         }
@@ -134,8 +135,10 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
             return H_PTEG_FULL;
         }
     } else {
+        ppc_hash_pte64_t pte;
         token = ppc_hash64_start_access(cpu, pte_index);
-        if (ppc_hash64_load_hpte0(cpu, token, 0) & HPTE64_V_VALID) {
+        pte = ppc_hash64_load_hpte(cpu, token, 0);
+        if (pte.pte0 & HPTE64_V_VALID) {
             ppc_hash64_stop_access(cpu, token);
             return H_PTEG_FULL;
         }
@@ -163,26 +166,25 @@ static RemoveResult remove_hpte(PowerPCCPU *cpu, target_ulong ptex,
 {
     CPUPPCState *env = &cpu->env;
     uint64_t token;
-    target_ulong v, r;
+    ppc_hash_pte64_t pte;
 
     if (!valid_pte_index(env, ptex)) {
         return REMOVE_PARM;
     }
 
     token = ppc_hash64_start_access(cpu, ptex);
-    v = ppc_hash64_load_hpte0(cpu, token, 0);
-    r = ppc_hash64_load_hpte1(cpu, token, 0);
+    pte = ppc_hash64_load_hpte(cpu, token, 0);
     ppc_hash64_stop_access(cpu, token);
 
-    if ((v & HPTE64_V_VALID) == 0 ||
-        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) ||
-        ((flags & H_ANDCOND) && (v & avpn) != 0)) {
+    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
+        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn) ||
+        ((flags & H_ANDCOND) && (pte.pte0 & avpn) != 0)) {
         return REMOVE_NOT_FOUND;
     }
-    *vp = v;
-    *rp = r;
+    *vp = pte.pte0;
+    *rp = pte.pte1;
     ppc_hash64_store_hpte(cpu, ptex, HPTE64_V_HPTE_DIRTY, 0);
-    ppc_hash64_tlb_flush_hpte(cpu, ptex, v, r);
+    ppc_hash64_tlb_flush_hpte(cpu, ptex, pte.pte0, pte.pte1);
     return REMOVE_SUCCESS;
 }
 
@@ -293,35 +295,36 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     target_ulong flags = args[0];
     target_ulong pte_index = args[1];
     target_ulong avpn = args[2];
+    ppc_hash_pte64_t pte;
     uint64_t token;
-    target_ulong v, r;
 
     if (!valid_pte_index(env, pte_index)) {
         return H_PARAMETER;
     }
 
     token = ppc_hash64_start_access(cpu, pte_index);
-    v = ppc_hash64_load_hpte0(cpu, token, 0);
-    r = ppc_hash64_load_hpte1(cpu, token, 0);
+    pte = ppc_hash64_load_hpte(cpu, token, 0);
     ppc_hash64_stop_access(cpu, token);
 
-    if ((v & HPTE64_V_VALID) == 0 ||
-        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {
+    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
+        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn)) {
         return H_NOT_FOUND;
     }
 
-    r &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
-           HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
-    r |= (flags << 55) & HPTE64_R_PP0;
-    r |= (flags << 48) & HPTE64_R_KEY_HI;
-    r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
+    pte.pte1 &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
+                  HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
+    pte.pte1 |= (flags << 55) & HPTE64_R_PP0;
+    pte.pte1 |= (flags << 48) & HPTE64_R_KEY_HI;
+    pte.pte1 |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
     ppc_hash64_store_hpte(cpu, pte_index,
-                          (v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY, 0);
-    ppc_hash64_tlb_flush_hpte(cpu, pte_index, v, r);
+                          (pte.pte0 & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY,
+                          0);
+    ppc_hash64_tlb_flush_hpte(cpu, pte_index, pte.pte0, pte.pte1);
     /* Flush the tlb */
     check_tlb_flush(env, true);
     /* Don't need a memory barrier, due to qemu's global lock */
-    ppc_hash64_store_hpte(cpu, pte_index, v | HPTE64_V_HPTE_DIRTY, r);
+    ppc_hash64_store_hpte(cpu, pte_index, pte.pte0 | HPTE64_V_HPTE_DIRTY,
+                          pte.pte1);
     return H_SUCCESS;
 }
 
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index b476b3f..03607d5 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -515,7 +515,6 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
     CPUPPCState *env = &cpu->env;
     int i;
     uint64_t token;
-    target_ulong pte0, pte1;
     target_ulong pte_index;
 
     pte_index = (hash & env->htab_mask) * HPTES_PER_GROUP;
@@ -524,12 +523,11 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
         return -1;
     }
     for (i = 0; i < HPTES_PER_GROUP; i++) {
-        pte0 = ppc_hash64_load_hpte0(cpu, token, i);
-        pte1 = ppc_hash64_load_hpte1(cpu, token, i);
+        ppc_hash_pte64_t entry = ppc_hash64_load_hpte(cpu, token, i);
 
         /* This compares V, B, H (secondary) and the AVPN */
-        if (HPTE64_V_COMPARE(pte0, ptem)) {
-            *pshift = hpte_page_shift(sps, pte0, pte1);
+        if (HPTE64_V_COMPARE(entry.pte0, ptem)) {
+            *pshift = hpte_page_shift(sps, entry.pte0, entry.pte1);
             /*
              * If there is no match, ignore the PTE, it could simply
              * be for a different segment size encoding and the
@@ -543,8 +541,7 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
             /* We don't do anything with pshift yet as qemu TLB only deals
              * with 4K pages anyway
              */
-            pte->pte0 = pte0;
-            pte->pte1 = pte1;
+            *pte = entry;
             ppc_hash64_stop_access(cpu, token);
             return (pte_index + i) * HASH_PTE_SIZE_64;
         }
@@ -924,6 +921,8 @@ void ppc_hash64_store_hpte(PowerPCCPU *cpu,
 {
     CPUPPCState *env = &cpu->env;
 
+    ppc_hash64_hpte_old_to_new(env, &pte0, &pte1);
+
     if (env->external_htab == MMU_HASH64_KVM_MANAGED_HPT) {
         kvmppc_hash64_write_pte(env, pte_index, pte0, pte1);
         return;
diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
index ab5d347..73d7ce4 100644
--- a/target/ppc/mmu-hash64.h
+++ b/target/ppc/mmu-hash64.h
@@ -60,6 +60,7 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
 #define HASH_PTE_SIZE_64        16
 #define HASH_PTEG_SIZE_64       (HASH_PTE_SIZE_64 * HPTES_PER_GROUP)
 
+#define HPTE64_V_3_00_COMMON    0x000fffffffffffffULL
 #define HPTE64_V_SSIZE_SHIFT    62
 #define HPTE64_V_AVPN_SHIFT     7
 #define HPTE64_V_AVPN           0x3fffffffffffff80ULL
@@ -69,9 +70,12 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
 #define HPTE64_V_SECONDARY      0x0000000000000002ULL
 #define HPTE64_V_VALID          0x0000000000000001ULL
 
+#define HPTE64_R_3_00_COMMON    0xf1ffffffffffffffULL
 #define HPTE64_R_PP0            0x8000000000000000ULL
 #define HPTE64_R_TS             0x4000000000000000ULL
 #define HPTE64_R_KEY_HI         0x3000000000000000ULL
+#define HPTE64_R_SSIZE_SHIFT    58
+#define HPTE64_R_SSIZE_MASK     (3ULL << HPTE64_R_SSIZE_SHIFT)
 #define HPTE64_R_RPN_SHIFT      12
 #define HPTE64_R_RPN            0x0ffffffffffff000ULL
 #define HPTE64_R_FLAGS          0x00000000000003ffULL
@@ -91,6 +95,10 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
 #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
 #define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
 
+typedef struct {
+    uint64_t pte0, pte1;
+} ppc_hash_pte64_t;
+
 void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong value,
                          Error **errp);
 void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int shift,
@@ -99,37 +107,64 @@ void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int shift,
 uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, target_ulong pte_index);
 void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t token);
 
-static inline target_ulong ppc_hash64_load_hpte0(PowerPCCPU *cpu,
-                                                 uint64_t token, int index)
+static inline void ppc_hash64_hpte_old_to_new(CPUPPCState *env,
+                                              target_ulong *pte0,
+                                              target_ulong *pte1)
 {
-    CPUPPCState *env = &cpu->env;
-    uint64_t addr;
+    switch (env->mmu_model) {
+    case POWERPC_MMU_3_00:
+        /*
+         * v3.00 of the ISA moved the B field to the second doubleword and
+         * shortened the abbreviated virtual address and abbreviated real page
+         * number fields
+         */
+        *pte1 = (*pte1 & HPTE64_R_3_00_COMMON) |
+                ((*pte0 >> HPTE64_V_SSIZE_SHIFT) << HPTE64_R_SSIZE_SHIFT);
+        *pte0 = *pte0 & HPTE64_V_3_00_COMMON;
+    default:
+        ;
+    }
+}
 
-    addr = token + (index * HASH_PTE_SIZE_64);
-    if (env->external_htab) {
-        return  ldq_p((const void *)(uintptr_t)addr);
-    } else {
-        return ldq_phys(CPU(cpu)->as, addr);
+static inline void ppc_hash64_hpte_new_to_old(CPUPPCState *env,
+                                              target_ulong *pte0,
+                                              target_ulong *pte1)
+{
+    switch (env->mmu_model) {
+    case POWERPC_MMU_3_00:
+        /*
+         * v3.00 of the ISA moved the B field to the second doubleword and
+         * shortened the abbreviated virtual address and abbreviated real page
+         * number fields
+         */
+        *pte0 = (*pte0 & HPTE64_V_3_00_COMMON) | ((*pte1 & HPTE64_R_SSIZE_MASK)
+                << (HPTE64_V_SSIZE_SHIFT - HPTE64_R_SSIZE_SHIFT));
+        *pte1 = *pte1 & HPTE64_R_3_00_COMMON;
+    default:
+        ;
     }
 }
 
-static inline target_ulong ppc_hash64_load_hpte1(PowerPCCPU *cpu,
-                                                 uint64_t token, int index)
+static inline ppc_hash_pte64_t ppc_hash64_load_hpte(PowerPCCPU *cpu,
+                                                    uint64_t token,
+                                                    int index)
 {
     CPUPPCState *env = &cpu->env;
+    ppc_hash_pte64_t pte;
     uint64_t addr;
 
-    addr = token + (index * HASH_PTE_SIZE_64) + HASH_PTE_SIZE_64/2;
+    addr = token + (index * HASH_PTE_SIZE_64);
     if (env->external_htab) {
-        return  ldq_p((const void *)(uintptr_t)addr);
+        pte.pte0 = ldq_p((const void *)(uintptr_t)addr);
+        pte.pte1 = ldq_p((const void *)(uintptr_t)addr + HASH_PTE_SIZE_64/2);
     } else {
-        return ldq_phys(CPU(cpu)->as, addr);
+        pte.pte0 = ldq_phys(CPU(cpu)->as, addr);
+        pte.pte1 = ldq_phys(CPU(cpu)->as, addr + HASH_PTE_SIZE_64/2);
     }
-}
 
-typedef struct {
-    uint64_t pte0, pte1;
-} ppc_hash_pte64_t;
+    ppc_hash64_hpte_new_to_old(env, &pte.pte0, &pte.pte1);
+    return pte;
+}
 
 #endif /* CONFIG_USER_ONLY */
 
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 12/17] target/ppc/POWER9: Add POWER9 pa-features definition
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (10 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 11/17] target/ppc/POWER9: Update to new pte format for POWER9 accesses Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-02-01  4:29   ` David Gibson
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 13/17] target/ppc/POWER9: Add cpu_has_work function for POWER9 Suraj Jitindar Singh
                   ` (6 subsequent siblings)
  18 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

Add a pa-features definition which includes all of the new fields which
have been added, note we don't claim support for any of these new features
at this stage.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 hw/ppc/spapr.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 45bd2de..35799da 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -357,6 +357,20 @@ static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset)
         0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
         0x80, 0x00, 0x80, 0x00, 0x00, 0x00 };
+    /* Currently we don't advertise any of the "new" ISAv3.00 functionality */
+    uint8_t pa_features_300[] = { 64, 0,
+        0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0, /*  0 -  5 */
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /*  6 - 11 */
+        0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
+        0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 24 - 29 */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 35 */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 36 - 41 */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 42 - 47 */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 48 - 53 */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 54 - 59 */
+        0x00, 0x00, 0x00, 0x00           }; /* 60 - 63 */
+
     uint8_t *pa_features;
     size_t pa_size;
 
@@ -371,6 +385,10 @@ static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset)
         pa_features = pa_features_207;
         pa_size = sizeof(pa_features_207);
         break;
+    case POWERPC_MMU_3_00:
+        pa_features = pa_features_300;
+        pa_size = sizeof(pa_features_300);
+        break;
     default:
         return;
     }
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 13/17] target/ppc/POWER9: Add cpu_has_work function for POWER9
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (11 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 12/17] target/ppc/POWER9: Add POWER9 pa-features definition Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-02-01  4:34   ` David Gibson
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 14/17] target/ppc/debug: Print LPCR register value if register exists Suraj Jitindar Singh
                   ` (5 subsequent siblings)
  18 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

The cpu has work function is used to mask interrupts used to determine
if there is work for the cpu based on the LPCR. Add a function to do this
for POWER9 and add it to the POWER9 cpu definition. This is similar to that
for POWER8 except using the LPCR bits as defined for POWER9.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 target/ppc/translate_init.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 87297a7..9db004d 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -8797,10 +8797,54 @@ static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr)
     return false;
 }
 
+static bool cpu_has_work_POWER9(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    if (cs->halted) {
+        if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
+            return false;
+        }
+        /* External Exception */
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
+            (env->spr[SPR_LPCR] & LPCR_EEE)) {
+            return true;
+        }
+        /* Decrementer Exception */
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
+            (env->spr[SPR_LPCR] & LPCR_DEE)) {
+            return true;
+        }
+        /* Machine Check or Hypervisor Maintenance Exception */
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
+            1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
+            return true;
+        }
+        /* Privileged Doorbell Exception */
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
+            (env->spr[SPR_LPCR] & LPCR_PDEE)) {
+            return true;
+        }
+        /* Hypervisor Doorbell Exception */
+        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
+            (env->spr[SPR_LPCR] & LPCR_HDEE)) {
+            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(POWER9)(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
     PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
 
     dc->fw_name = "PowerPC,POWER9";
     dc->desc = "POWER9";
@@ -8811,6 +8855,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
                          PCR_COMPAT_2_05;
     pcc->init_proc = init_proc_POWER9;
     pcc->check_pow = check_pow_nocheck;
+    cc->has_work = cpu_has_work_POWER9;
     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 |
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 14/17] target/ppc/debug: Print LPCR register value if register exists
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (12 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 13/17] target/ppc/POWER9: Add cpu_has_work function for POWER9 Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 15/17] tcg/POWER9: NOOP the cp_abort instruction Suraj Jitindar Singh
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

It can be useful when debugging to print the LPCR value.

Thus we add the LPCR to the "info registers" output if the register had
been defined.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 target/ppc/translate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 521aed3..5d63254 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -6910,6 +6910,9 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
     }
 #endif
 
+    if (env->spr_cb[SPR_LPCR].name)
+        cpu_fprintf(f, " LPCR " TARGET_FMT_lx "\n", env->spr[SPR_LPCR]);
+
     switch (env->mmu_model) {
     case POWERPC_MMU_32B:
     case POWERPC_MMU_601:
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 15/17] tcg/POWER9: NOOP the cp_abort instruction
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (13 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 14/17] target/ppc/debug: Print LPCR register value if register exists Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 16/17] target/ppc/mmu_hash64: Fix printing unsigned as signed int Suraj Jitindar Singh
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

The cp_abort instruction is used to remove the state of an in progress
copy paste sequence. POWER9 compilers add this in various places, such
as context switches which causes illegal instruction signals since we
don't yet implement this instruction.

Given there is no implementation of the copy paste facility and that we
don't claim to support it, we can just noop this instruction.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 target/ppc/translate.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 5d63254..7527bd2 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -6166,6 +6166,10 @@ GEN_TM_NOOP(tabortwci);
 GEN_TM_NOOP(tabortdc);
 GEN_TM_NOOP(tabortdci);
 GEN_TM_NOOP(tsr);
+static inline void gen_cp_abort(DisasContext *ctx)
+{
+    // Do Nothing
+}
 
 static void gen_tcheck(DisasContext *ctx)
 {
@@ -6255,6 +6259,7 @@ GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
 GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
 GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
 GEN_HANDLER_E(cnttzw, 0x1F, 0x1A, 0x10, 0x00000000, PPC_NONE, PPC2_ISA300),
+GEN_HANDLER_E(cp_abort, 0x1F, 0x06, 0x1A, 0x03FFF801, PPC_NONE, PPC2_ISA300),
 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 16/17] target/ppc/mmu_hash64: Fix printing unsigned as signed int
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (14 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 15/17] tcg/POWER9: NOOP the cp_abort instruction Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 17/17] target/ppc/mmu_hash64: Fix incorrect shift value in amr calculation Suraj Jitindar Singh
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

We were printing an unsigned value as a signed value, fix this.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 target/ppc/mmu-hash64.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index 03607d5..08d2393 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -189,8 +189,8 @@ int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot,
     slb->vsid = vsid;
     slb->sps = sps;
 
-    LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
-            " %016" PRIx64 "\n", __func__, slot, esid, vsid,
+    LOG_SLB("%s: " TARGET_FMT_lu " " TARGET_FMT_lx " - " TARGET_FMT_lx
+            " => %016" PRIx64 " %016" PRIx64 "\n", __func__, slot, esid, vsid,
             slb->esid, slb->vsid);
 
     return 0;
-- 
2.5.5

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

* [Qemu-devel] [RFC PATCH 17/17] target/ppc/mmu_hash64: Fix incorrect shift value in amr calculation
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (15 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 16/17] target/ppc/mmu_hash64: Fix printing unsigned as signed int Suraj Jitindar Singh
@ 2017-01-13  6:28 ` Suraj Jitindar Singh
  2017-01-13  6:55 ` [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support no-reply
  2017-02-01  2:16 ` David Gibson
  18 siblings, 0 replies; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-13  6:28 UTC (permalink / raw)
  To: qemu-ppc; +Cc: david, agraf, qemu-devel, Suraj Jitindar Singh

We are calculating the authority mask register key value wrong.

The pte entry contains the key value with the two upper bits and the three
lower bits stored separately. We should use these two portions to get a 5
bit value, not or them together which will only give us a 3 bit value.

Fix this.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 target/ppc/mmu-hash64.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
index 73d7ce4..e8160c3 100644
--- a/target/ppc/mmu-hash64.h
+++ b/target/ppc/mmu-hash64.h
@@ -89,7 +89,7 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
 #define HPTE64_R_C              0x0000000000000080ULL
 #define HPTE64_R_R              0x0000000000000100ULL
 #define HPTE64_R_KEY_LO         0x0000000000000e00ULL
-#define HPTE64_R_KEY(x)         ((((x) & HPTE64_R_KEY_HI) >> 60) | \
+#define HPTE64_R_KEY(x)         ((((x) & HPTE64_R_KEY_HI) >> 57) | \
                                  (((x) & HPTE64_R_KEY_LO) >> 9))
 
 #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
-- 
2.5.5

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

* Re: [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (16 preceding siblings ...)
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 17/17] target/ppc/mmu_hash64: Fix incorrect shift value in amr calculation Suraj Jitindar Singh
@ 2017-01-13  6:55 ` no-reply
  2017-02-01  1:04   ` David Gibson
  2017-02-01  2:16 ` David Gibson
  18 siblings, 1 reply; 53+ messages in thread
From: no-reply @ 2017-01-13  6:55 UTC (permalink / raw)
  To: sjitindarsingh; +Cc: famz, qemu-ppc, qemu-devel, agraf, david

Hi,

Your series seems to have some coding style problems. See output below for
more information:

Message-id: 1484288903-18807-1-git-send-email-sjitindarsingh@gmail.com
Subject: [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/1484288903-18807-1-git-send-email-sjitindarsingh@gmail.com -> patchew/1484288903-18807-1-git-send-email-sjitindarsingh@gmail.com
Switched to a new branch 'test'
fc9a657 target/ppc/mmu_hash64: Fix incorrect shift value in amr calculation
3a6e0b1 target/ppc/mmu_hash64: Fix printing unsigned as signed int
0df1183 tcg/POWER9: NOOP the cp_abort instruction
8b5bf42 target/ppc/debug: Print LPCR register value if register exists
341c7e5 target/ppc/POWER9: Add cpu_has_work function for POWER9
398b7d5 target/ppc/POWER9: Add POWER9 pa-features definition
96a44df target/ppc/POWER9: Update to new pte format for POWER9 accesses
9190833 target/ppc/POWER9: Add POWER9 mmu fault handler
bb7fa61 target/ppc/POWER9: Remove SDR1 register
1191b9a target/ppc/POWER9: Add external partition table pointer to cpu state
8d19919 target/ppc/POWER9: Add partition table pointer to sPAPRMachineState
ffd1d31 target/ppc/POWER9: Direct all instr and data storage interrupts to the hypv
4c92646 target/ppc/POWER9: Adapt LPCR handling for POWER9
e1a9f12 target/ppc/POWER9: Add ISAv3.00 MMU definition
87144e8 target/ppc: Add pcr_supported to POWER9 cpu class definition
b9a19a8 hw/ppc/spapr: Add POWER9 to pseries cpu models
eb1b279 powerpc/cpu-models: rename ISAv3.00 logical PVR definition

=== OUTPUT BEGIN ===
Checking PATCH 1/17: powerpc/cpu-models: rename ISAv3.00 logical PVR definition...
Checking PATCH 2/17: hw/ppc/spapr: Add POWER9 to pseries cpu models...
Checking PATCH 3/17: target/ppc: Add pcr_supported to POWER9 cpu class definition...
ERROR: spaces required around that '-' (ctx:VxV)
#21: FILE: target/ppc/cpu.h:2253:
+    PCR_COMPAT_3_00     = 1ull << (63-59),
                                      ^

total: 1 errors, 0 warnings, 15 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 4/17: target/ppc/POWER9: Add ISAv3.00 MMU definition...
Checking PATCH 5/17: target/ppc/POWER9: Adapt LPCR handling for POWER9...
Checking PATCH 6/17: target/ppc/POWER9: Direct all instr and data storage interrupts to the hypv...
Checking PATCH 7/17: target/ppc/POWER9: Add partition table pointer to sPAPRMachineState...
Checking PATCH 8/17: target/ppc/POWER9: Add external partition table pointer to cpu state...
Checking PATCH 9/17: target/ppc/POWER9: Remove SDR1 register...
ERROR: braces {} are necessary for all arms of this statement
#29: FILE: target/ppc/kvm.c:935:
+        if (env->external_patbe)
[...]

ERROR: braces {} are necessary for all arms of this statement
#54: FILE: target/ppc/mmu-hash64.c:300:
+        if (env->external_patbe)
[...]

ERROR: braces {} are necessary for all arms of this statement
#77: FILE: target/ppc/translate.c:6927:
+        if (env->spr_cb[SPR_SDR1].name)
[...]

ERROR: space prohibited between function name and open parenthesis '('
#102: FILE: target/ppc/translate_init.c:727:
+static void gen_spr_ne_power9 (CPUPPCState *env)

ERROR: space prohibited between function name and open parenthesis '('
#113: FILE: target/ppc/translate_init.c:746:
+static void gen_spr_ne_601 (CPUPPCState *env)

ERROR: braces {} are necessary for all arms of this statement
#131: FILE: target/ppc/translate_init.c:8289:
+    if (version >= BOOK3S_CPU_POWER9)
[...]
+    else
[...]

total: 6 errors, 0 warnings, 96 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 10/17: target/ppc/POWER9: Add POWER9 mmu fault handler...
ERROR: Error messages should not contain newlines
#135: FILE: target/ppc/mmu_helper.c:2963:
+        error_report("Guest Radix Support Unimplemented\n");

total: 1 errors, 0 warnings, 110 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 11/17: target/ppc/POWER9: Update to new pte format for POWER9 accesses...
ERROR: spaces required around that '/' (ctx:VxV)
#280: FILE: target/ppc/mmu-hash64.h:159:
+        pte.pte1 = ldq_p((const void *)(uintptr_t)addr + HASH_PTE_SIZE_64/2);
                                                                          ^

ERROR: spaces required around that '/' (ctx:VxV)
#284: FILE: target/ppc/mmu-hash64.h:162:
+        pte.pte1 = ldq_phys(CPU(cpu)->as, addr + HASH_PTE_SIZE_64/2);
                                                                  ^

total: 2 errors, 0 warnings, 253 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 12/17: target/ppc/POWER9: Add POWER9 pa-features definition...
Checking PATCH 13/17: target/ppc/POWER9: Add cpu_has_work function for POWER9...
Checking PATCH 14/17: target/ppc/debug: Print LPCR register value if register exists...
Checking PATCH 15/17: tcg/POWER9: NOOP the cp_abort instruction...
ERROR: do not use C99 // comments
#27: FILE: target/ppc/translate.c:6171:
+    // Do Nothing

total: 1 errors, 0 warnings, 17 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 16/17: target/ppc/mmu_hash64: Fix printing unsigned as signed int...
Checking PATCH 17/17: target/ppc/mmu_hash64: Fix incorrect shift value in amr calculation...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

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

* Re: [Qemu-devel] [RFC PATCH 01/17] powerpc/cpu-models: rename ISAv3.00 logical PVR definition
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 01/17] powerpc/cpu-models: rename ISAv3.00 logical PVR definition Suraj Jitindar Singh
@ 2017-01-16  2:16   ` David Gibson
  0 siblings, 0 replies; 53+ messages in thread
From: David Gibson @ 2017-01-16  2:16 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:07PM +1100, Suraj Jitindar Singh wrote:
> This logical PVR value now corresponds to ISA version 3.00 so rename it
> accordingly.
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

This one stands on its own, so I've applied it to ppc-for-2.9 already.

> ---
>  target/ppc/cpu-models.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target/ppc/cpu-models.h b/target/ppc/cpu-models.h
> index aafbbd7..d587e69 100644
> --- a/target/ppc/cpu-models.h
> +++ b/target/ppc/cpu-models.h
> @@ -601,7 +601,7 @@ enum {
>      CPU_POWERPC_LOGICAL_2_06       = 0x0F000003,
>      CPU_POWERPC_LOGICAL_2_06_PLUS  = 0x0F100003,
>      CPU_POWERPC_LOGICAL_2_07       = 0x0F000004,
> -    CPU_POWERPC_LOGICAL_2_08       = 0x0F000005,
> +    CPU_POWERPC_LOGICAL_3_00       = 0x0F000005,
>  };
>  
>  /* System version register (used on MPC 8xxx)                                */

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 02/17] hw/ppc/spapr: Add POWER9 to pseries cpu models
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 02/17] hw/ppc/spapr: Add POWER9 to pseries cpu models Suraj Jitindar Singh
@ 2017-01-16 12:11   ` David Gibson
  0 siblings, 0 replies; 53+ messages in thread
From: David Gibson @ 2017-01-16 12:11 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:08PM +1100, Suraj Jitindar Singh wrote:
> Add POWER9 cpu to list of spapr core models which allows it to be specified
> as the cpu model for a pseries guest (e.g. -machine pseries -cpu POWER9).
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

I realize you need this first for development, but for submission,
please move it to the end of the series.  The idea is if you're
bisecting or iterating through commits, then when the POWER9 option
appears, it will actually work.  That won't be the case without the
rest of the patches in the series.

> ---
>  hw/ppc/spapr_cpu_core.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
> index c18632b..8cc7058 100644
> --- a/hw/ppc/spapr_cpu_core.c
> +++ b/hw/ppc/spapr_cpu_core.c
> @@ -358,6 +358,9 @@ static const char *spapr_core_models[] = {
>  
>      /* POWER8NVL */
>      "POWER8NVL_v1.0",
> +
> +    /* POWER9 */
> +    "POWER9_v1.0",
>  };
>  
>  void spapr_cpu_core_class_init(ObjectClass *oc, void *data)

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 03/17] target/ppc: Add pcr_supported to POWER9 cpu class definition
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 03/17] target/ppc: Add pcr_supported to POWER9 cpu class definition Suraj Jitindar Singh
@ 2017-01-16 21:21   ` David Gibson
  0 siblings, 0 replies; 53+ messages in thread
From: David Gibson @ 2017-01-16 21:21 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:09PM +1100, Suraj Jitindar Singh wrote:
> pcr_supported is used to define the supported PCR values for a given
> processor. A POWER9 processor can support 3.00, 2.07, 2.06 and 2.05
> compatibility modes, thus we set this accordingly.
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

This looks fine to go ahead now, so I've merged it to ppc-for-2.9.

> ---
>  target/ppc/cpu.h            | 1 +
>  target/ppc/translate_init.c | 2 ++
>  2 files changed, 3 insertions(+)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 2a50c43..afb7ddb 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -2250,6 +2250,7 @@ enum {
>      PCR_COMPAT_2_05     = 1ull << (63-62),
>      PCR_COMPAT_2_06     = 1ull << (63-61),
>      PCR_COMPAT_2_07     = 1ull << (63-60),
> +    PCR_COMPAT_3_00     = 1ull << (63-59),
>      PCR_VEC_DIS         = 1ull << (63-0), /* Vec. disable (bit NA since POWER8) */
>      PCR_VSX_DIS         = 1ull << (63-1), /* VSX disable (bit NA since POWER8) */
>      PCR_TM_DIS          = 1ull << (63-2), /* Trans. memory disable (POWER8) */
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index 626e031..bfc1f24 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -8797,6 +8797,8 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
>      dc->props = powerpc_servercpu_properties;
>      pcc->pvr_match = ppc_pvr_match_power9;
>      pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07;
> +    pcc->pcr_supported = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 |
> +                         PCR_COMPAT_2_05;
>      pcc->init_proc = init_proc_POWER9;
>      pcc->check_pow = check_pow_nocheck;
>      pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 04/17] target/ppc/POWER9: Add ISAv3.00 MMU definition
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 04/17] target/ppc/POWER9: Add ISAv3.00 MMU definition Suraj Jitindar Singh
@ 2017-01-16 21:36   ` David Gibson
  2017-01-17  0:33     ` Suraj Jitindar Singh
  0 siblings, 1 reply; 53+ messages in thread
From: David Gibson @ 2017-01-16 21:36 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:10PM +1100, Suraj Jitindar Singh wrote:
> POWER9 processors implement the mmu as defined in version 3.00 of the ISA.
> 
> Add a definition for this mmu model and set the POWER9 cpu model to use
> this mmu model.
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> ---
>  target/ppc/cpu-qom.h        | 5 ++++-
>  target/ppc/mmu_helper.c     | 2 ++
>  target/ppc/translate_init.c | 3 +--
>  3 files changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
> index d46c31a..1577cc8 100644
> --- a/target/ppc/cpu-qom.h
> +++ b/target/ppc/cpu-qom.h
> @@ -86,10 +86,13 @@ enum powerpc_mmu_t {
>      POWERPC_MMU_2_07       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
>                               | POWERPC_MMU_64K
>                               | POWERPC_MMU_AMR | 0x00000004,
> -    /* FIXME Add POWERPC_MMU_3_OO defines */
>      /* Architecture 2.07 "degraded" (no 1T segments)           */
>      POWERPC_MMU_2_07a      = POWERPC_MMU_64 | POWERPC_MMU_AMR
>                               | 0x00000004,
> +    /* Architecture 3.00 variant                               */
> +    POWERPC_MMU_3_00       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
> +                             | POWERPC_MMU_64K
> +                             | POWERPC_MMU_AMR | 0x00000005,

Hmm.  I guess it works for now, but I'm not really sure that having
this include POWERPC_MMU_64 is a great idea.  The name is kind of
misleading, but I'm pretty sure a number of places assume that the
POWERPC_MMU_64 bitindicates a 64-bit *hash* MMU, which is no longer
really the case.

>  };
>  
>  /*****************************************************************************/
> diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> index d09fc0a..2ab4562 100644
> --- a/target/ppc/mmu_helper.c
> +++ b/target/ppc/mmu_helper.c
> @@ -1935,6 +1935,7 @@ void ppc_tlb_invalidate_all(CPUPPCState *env)
>      case POWERPC_MMU_2_06a:
>      case POWERPC_MMU_2_07:
>      case POWERPC_MMU_2_07a:
> +    case POWERPC_MMU_3_00:
>  #endif /* defined(TARGET_PPC64) */
>          env->tlb_need_flush = 0;
>          tlb_flush(CPU(cpu), 1);
> @@ -1974,6 +1975,7 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
>      case POWERPC_MMU_2_06a:
>      case POWERPC_MMU_2_07:
>      case POWERPC_MMU_2_07a:
> +    case POWERPC_MMU_3_00:
>          /* tlbie invalidate TLBs for all segments */
>          /* XXX: given the fact that there are too many segments to invalidate,
>           *      and we still don't have a tlb_flush_mask(env, n, mask) in QEMU,
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index bfc1f24..2402eef 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -8838,8 +8838,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
>                      (1ull << MSR_PMM) |
>                      (1ull << MSR_RI) |
>                      (1ull << MSR_LE);
> -    /* Using 2.07 defines until new radix model is added. */
> -    pcc->mmu_model = POWERPC_MMU_2_07;
> +    pcc->mmu_model = POWERPC_MMU_3_00;
>  #if defined(CONFIG_SOFTMMU)
>      pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
>      /* segment page size remain the same */

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 05/17] target/ppc/POWER9: Adapt LPCR handling for POWER9
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 05/17] target/ppc/POWER9: Adapt LPCR handling for POWER9 Suraj Jitindar Singh
@ 2017-01-16 21:40   ` David Gibson
  2017-01-17  0:48     ` Suraj Jitindar Singh
  0 siblings, 1 reply; 53+ messages in thread
From: David Gibson @ 2017-01-16 21:40 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:11PM +1100, Suraj Jitindar Singh wrote:
> The logical partitioning control register controls a threads operation
> based on the partition it is currently executing. Add new definitions and
> update the mask used when writing to the LPCR based on the POWER9 spec.
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> ---
>  target/ppc/cpu.h            | 20 +++++++++++++++++++-
>  target/ppc/mmu-hash64.c     |  8 ++++++++
>  target/ppc/translate_init.c | 24 ++++++++++++++++++------
>  3 files changed, 45 insertions(+), 7 deletions(-)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index afb7ddb..0ab49b3 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -379,15 +379,22 @@ struct ppc_slb_t {
>  #define LPCR_ISL          (1ull << (63 - 2))
>  #define LPCR_KBV          (1ull << (63 - 3))
>  #define LPCR_DPFD_SHIFT   (63 - 11)
> -#define LPCR_DPFD         (0x3ull << LPCR_DPFD_SHIFT)
> +#define LPCR_DPFD         (0x7ull << LPCR_DPFD_SHIFT)

Changing this define effectively changes the valid LPCR mask for
existing POWER8 and POWER7 models, which is not what you want, I think.

>  #define LPCR_VRMASD_SHIFT (63 - 16)
>  #define LPCR_VRMASD       (0x1full << LPCR_VRMASD_SHIFT)
> +/* P9: Power-saving mode Exit Cause Enable (Upper Section) Mask */
> +#define LPCR_PECE_U_SHIFT (63 - 19)
> +#define LPCR_PECE_U_MASK  (0x7ull << LPCR_PECE_U_SHIFT)
> +#define LPCR_HVEE         (1ull << (63 - 17)) /* Hypervisor Virt Exit Enable */
>  #define LPCR_RMLS_SHIFT   (63 - 37)
>  #define LPCR_RMLS         (0xfull << LPCR_RMLS_SHIFT)
>  #define LPCR_ILE          (1ull << (63 - 38))
>  #define LPCR_AIL_SHIFT    (63 - 40)      /* Alternate interrupt location */
>  #define LPCR_AIL          (3ull << LPCR_AIL_SHIFT)
> +#define LPCR_UPRT         (1ull << (63 - 41)) /* Use Process Table */
> +#define LPCR_EVIRT        (1ull << (63 - 42)) /* Enhanced Virtualisation */
>  #define LPCR_ONL          (1ull << (63 - 45))
> +#define LPCR_LD           (1ull << (63 - 46)) /* Large Decrementer */
>  #define LPCR_P7_PECE0     (1ull << (63 - 49))
>  #define LPCR_P7_PECE1     (1ull << (63 - 50))
>  #define LPCR_P7_PECE2     (1ull << (63 - 51))
> @@ -396,11 +403,22 @@ struct ppc_slb_t {
>  #define LPCR_P8_PECE2     (1ull << (63 - 49))
>  #define LPCR_P8_PECE3     (1ull << (63 - 50))
>  #define LPCR_P8_PECE4     (1ull << (63 - 51))
> +/* P9: Power-saving mode Exit Cause Enable (Lower Section) Mask */
> +#define LPCR_PECE_L_SHIFT (63 - 51)
> +#define LPCR_PECE_L_MASK  (0x1full << LPCR_PECE_L_SHIFT)
> +#define LPCR_PDEE         (1ull << (63 - 47)) /* Privileged Doorbell Exit EN */
> +#define LPCR_HDEE         (1ull << (63 - 48)) /* Hyperv Doorbell Exit Enable */
> +#define LPCR_EEE          (1ull << (63 - 49)) /* External Exit Enable        */
> +#define LPCR_DEE          (1ull << (63 - 50)) /* Decrementer Exit Enable     */
> +#define LPCR_OEE          (1ull << (63 - 51)) /* Other Exit Enable           */
>  #define LPCR_MER          (1ull << (63 - 52))
> +#define LPCR_GTSE         (1ull << (63 - 53)) /* Guest Translation Shootdown */
>  #define LPCR_TC           (1ull << (63 - 54))
> +#define LPCR_HEIC         (1ull << (63 - 59)) /* HV Extern Interrupt Control */
>  #define LPCR_LPES0        (1ull << (63 - 60))
>  #define LPCR_LPES1        (1ull << (63 - 61))
>  #define LPCR_RMI          (1ull << (63 - 62))
> +#define LPCR_HVICE        (1ull << (63 - 62)) /* HV Virtualisation Int Enable */
>  #define LPCR_HDICE        (1ull << (63 - 63))
>  
>  #define msr_sf   ((env->msr >> MSR_SF)   & 1)
> diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> index fdb7a78..3a2acb8 100644
> --- a/target/ppc/mmu-hash64.c
> +++ b/target/ppc/mmu-hash64.c
> @@ -1050,6 +1050,14 @@ void helper_store_lpcr(CPUPPCState *env, target_ulong val)
>                        LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 |
>                        LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE);
>          break;
> +    case POWERPC_MMU_3_00: /* P9 */
> +        lpcr = val & (LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
> +                      (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
> +                      LPCR_UPRT | LPCR_EVIRT | LPCR_ONL |
> +                      (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
> +                      LPCR_DEE | LPCR_OEE)) | LPCR_MER | LPCR_GTSE | LPCR_TC |
> +                      LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE);
> +        break;
>      default:
>          ;
>      }
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index 2402eef..a1994d3 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -8887,12 +8887,24 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)
>      lpcr->default_value &= ~LPCR_RMLS;
>      lpcr->default_value |= 1ull << LPCR_RMLS_SHIFT;
>  
> -    /* 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;
> +    switch (env->mmu_model) {

I'm not sure of mmu_model is conceptually the right thing to switch
on, although I guess it will work in practice.

> +    case POWERPC_MMU_3_00:
> +        /* By default we choose legacy mode and switch to new hash or radix
> +         * when a register process table hcall is made. So disable process
> +         * tables and guest translation shootdown by default
> +         */
> +        lpcr->default_value &= ~(LPCR_UPRT | LPCR_GTSE);
> +        lpcr->default_value |= LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE |
> +                               LPCR_OEE;
> +        break;
> +    default:
> +        /* 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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 04/17] target/ppc/POWER9: Add ISAv3.00 MMU definition
  2017-01-16 21:36   ` David Gibson
@ 2017-01-17  0:33     ` Suraj Jitindar Singh
  2017-01-23  5:01       ` Suraj Jitindar Singh
  0 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-17  0:33 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, agraf, qemu-devel

On Tue, 2017-01-17 at 08:36 +1100, David Gibson wrote:
> On Fri, Jan 13, 2017 at 05:28:10PM +1100, Suraj Jitindar Singh wrote:
> > 
> > POWER9 processors implement the mmu as defined in version 3.00 of
> > the ISA.
> > 
> > Add a definition for this mmu model and set the POWER9 cpu model to
> > use
> > this mmu model.
> > 
> > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> > ---
> >  target/ppc/cpu-qom.h        | 5 ++++-
> >  target/ppc/mmu_helper.c     | 2 ++
> >  target/ppc/translate_init.c | 3 +--
> >  3 files changed, 7 insertions(+), 3 deletions(-)
> > 
> > diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
> > index d46c31a..1577cc8 100644
> > --- a/target/ppc/cpu-qom.h
> > +++ b/target/ppc/cpu-qom.h
> > @@ -86,10 +86,13 @@ enum powerpc_mmu_t {
> >      POWERPC_MMU_2_07       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
> >                               | POWERPC_MMU_64K
> >                               | POWERPC_MMU_AMR | 0x00000004,
> > -    /* FIXME Add POWERPC_MMU_3_OO defines */
> >      /* Architecture 2.07 "degraded" (no 1T segments)           */
> >      POWERPC_MMU_2_07a      = POWERPC_MMU_64 | POWERPC_MMU_AMR
> >                               | 0x00000004,
> > +    /* Architecture 3.00 variant                               */
> > +    POWERPC_MMU_3_00       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
> > +                             | POWERPC_MMU_64K
> > +                             | POWERPC_MMU_AMR | 0x00000005,
> Hmm.  I guess it works for now, but I'm not really sure that having
> this include POWERPC_MMU_64 is a great idea.  The name is kind of
> misleading, but I'm pretty sure a number of places assume that the
> POWERPC_MMU_64 bitindicates a 64-bit *hash* MMU, which is no longer
> really the case.
Good catch, I didn't realise this assumption was made in the code.

There are some cases where this bit needs to be set for correct
behaviour but other places where, while it doesn't break anything, it
leads to incorrect code being called.

Time for me to investigate :)
> 
> > 
> >  };
> >  
> >  /*****************************************************************
> > ************/
> > diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> > index d09fc0a..2ab4562 100644
> > --- a/target/ppc/mmu_helper.c
> > +++ b/target/ppc/mmu_helper.c
> > @@ -1935,6 +1935,7 @@ void ppc_tlb_invalidate_all(CPUPPCState *env)
> >      case POWERPC_MMU_2_06a:
> >      case POWERPC_MMU_2_07:
> >      case POWERPC_MMU_2_07a:
> > +    case POWERPC_MMU_3_00:
> >  #endif /* defined(TARGET_PPC64) */
> >          env->tlb_need_flush = 0;
> >          tlb_flush(CPU(cpu), 1);
> > @@ -1974,6 +1975,7 @@ void ppc_tlb_invalidate_one(CPUPPCState *env,
> > target_ulong addr)
> >      case POWERPC_MMU_2_06a:
> >      case POWERPC_MMU_2_07:
> >      case POWERPC_MMU_2_07a:
> > +    case POWERPC_MMU_3_00:
> >          /* tlbie invalidate TLBs for all segments */
> >          /* XXX: given the fact that there are too many segments to
> > invalidate,
> >           *      and we still don't have a tlb_flush_mask(env, n,
> > mask) in QEMU,
> > diff --git a/target/ppc/translate_init.c
> > b/target/ppc/translate_init.c
> > index bfc1f24..2402eef 100644
> > --- a/target/ppc/translate_init.c
> > +++ b/target/ppc/translate_init.c
> > @@ -8838,8 +8838,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void
> > *data)
> >                      (1ull << MSR_PMM) |
> >                      (1ull << MSR_RI) |
> >                      (1ull << MSR_LE);
> > -    /* Using 2.07 defines until new radix model is added. */
> > -    pcc->mmu_model = POWERPC_MMU_2_07;
> > +    pcc->mmu_model = POWERPC_MMU_3_00;
> >  #if defined(CONFIG_SOFTMMU)
> >      pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
> >      /* segment page size remain the same */

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

* Re: [Qemu-devel] [RFC PATCH 05/17] target/ppc/POWER9: Adapt LPCR handling for POWER9
  2017-01-16 21:40   ` David Gibson
@ 2017-01-17  0:48     ` Suraj Jitindar Singh
  2017-01-17  4:37       ` David Gibson
  0 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-17  0:48 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, agraf, qemu-devel

On Tue, 2017-01-17 at 08:40 +1100, David Gibson wrote:
> On Fri, Jan 13, 2017 at 05:28:11PM +1100, Suraj Jitindar Singh wrote:
> > 
> > The logical partitioning control register controls a threads
> > operation
> > based on the partition it is currently executing. Add new
> > definitions and
> > update the mask used when writing to the LPCR based on the POWER9
> > spec.
> > 
> > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> > ---
> >  target/ppc/cpu.h            | 20 +++++++++++++++++++-
> >  target/ppc/mmu-hash64.c     |  8 ++++++++
> >  target/ppc/translate_init.c | 24 ++++++++++++++++++------
> >  3 files changed, 45 insertions(+), 7 deletions(-)
> > 
> > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> > index afb7ddb..0ab49b3 100644
> > --- a/target/ppc/cpu.h
> > +++ b/target/ppc/cpu.h
> > @@ -379,15 +379,22 @@ struct ppc_slb_t {
> >  #define LPCR_ISL          (1ull << (63 - 2))
> >  #define LPCR_KBV          (1ull << (63 - 3))
> >  #define LPCR_DPFD_SHIFT   (63 - 11)
> > -#define LPCR_DPFD         (0x3ull << LPCR_DPFD_SHIFT)
> > +#define LPCR_DPFD         (0x7ull << LPCR_DPFD_SHIFT)
> Changing this define effectively changes the valid LPCR mask for
> existing POWER8 and POWER7 models, which is not what you want, I
> think.
I should have explained this better in the commit message, this has
always been a 3 bit field (at least in POWER7-9) so the mask has just
always been wrong. Afaik fixing this up won't really change anything -
it relates to data stream prefetch depth.

I realise this should probably be a separate patch though, or atleast
mentioned in the commit message.
> 
> > 
> >  #define LPCR_VRMASD_SHIFT (63 - 16)
> >  #define LPCR_VRMASD       (0x1full << LPCR_VRMASD_SHIFT)
> > +/* P9: Power-saving mode Exit Cause Enable (Upper Section) Mask */
> > +#define LPCR_PECE_U_SHIFT (63 - 19)
> > +#define LPCR_PECE_U_MASK  (0x7ull << LPCR_PECE_U_SHIFT)
> > +#define LPCR_HVEE         (1ull << (63 - 17)) /* Hypervisor Virt
> > Exit Enable */
> >  #define LPCR_RMLS_SHIFT   (63 - 37)
> >  #define LPCR_RMLS         (0xfull << LPCR_RMLS_SHIFT)
> >  #define LPCR_ILE          (1ull << (63 - 38))
> >  #define LPCR_AIL_SHIFT    (63 - 40)      /* Alternate interrupt
> > location */
> >  #define LPCR_AIL          (3ull << LPCR_AIL_SHIFT)
> > +#define LPCR_UPRT         (1ull << (63 - 41)) /* Use Process Table
> > */
> > +#define LPCR_EVIRT        (1ull << (63 - 42)) /* Enhanced
> > Virtualisation */
> >  #define LPCR_ONL          (1ull << (63 - 45))
> > +#define LPCR_LD           (1ull << (63 - 46)) /* Large Decrementer
> > */
> >  #define LPCR_P7_PECE0     (1ull << (63 - 49))
> >  #define LPCR_P7_PECE1     (1ull << (63 - 50))
> >  #define LPCR_P7_PECE2     (1ull << (63 - 51))
> > @@ -396,11 +403,22 @@ struct ppc_slb_t {
> >  #define LPCR_P8_PECE2     (1ull << (63 - 49))
> >  #define LPCR_P8_PECE3     (1ull << (63 - 50))
> >  #define LPCR_P8_PECE4     (1ull << (63 - 51))
> > +/* P9: Power-saving mode Exit Cause Enable (Lower Section) Mask */
> > +#define LPCR_PECE_L_SHIFT (63 - 51)
> > +#define LPCR_PECE_L_MASK  (0x1full << LPCR_PECE_L_SHIFT)
> > +#define LPCR_PDEE         (1ull << (63 - 47)) /* Privileged
> > Doorbell Exit EN */
> > +#define LPCR_HDEE         (1ull << (63 - 48)) /* Hyperv Doorbell
> > Exit Enable */
> > +#define LPCR_EEE          (1ull << (63 - 49)) /* External Exit
> > Enable        */
> > +#define LPCR_DEE          (1ull << (63 - 50)) /* Decrementer Exit
> > Enable     */
> > +#define LPCR_OEE          (1ull << (63 - 51)) /* Other Exit
> > Enable           */
> >  #define LPCR_MER          (1ull << (63 - 52))
> > +#define LPCR_GTSE         (1ull << (63 - 53)) /* Guest Translation
> > Shootdown */
> >  #define LPCR_TC           (1ull << (63 - 54))
> > +#define LPCR_HEIC         (1ull << (63 - 59)) /* HV Extern
> > Interrupt Control */
> >  #define LPCR_LPES0        (1ull << (63 - 60))
> >  #define LPCR_LPES1        (1ull << (63 - 61))
> >  #define LPCR_RMI          (1ull << (63 - 62))
> > +#define LPCR_HVICE        (1ull << (63 - 62)) /* HV Virtualisation
> > Int Enable */
> >  #define LPCR_HDICE        (1ull << (63 - 63))
> >  
> >  #define msr_sf   ((env->msr >> MSR_SF)   & 1)
> > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> > index fdb7a78..3a2acb8 100644
> > --- a/target/ppc/mmu-hash64.c
> > +++ b/target/ppc/mmu-hash64.c
> > @@ -1050,6 +1050,14 @@ void helper_store_lpcr(CPUPPCState *env,
> > target_ulong val)
> >                        LPCR_P8_PECE2 | LPCR_P8_PECE3 |
> > LPCR_P8_PECE4 |
> >                        LPCR_MER | LPCR_TC | LPCR_LPES0 |
> > LPCR_HDICE);
> >          break;
> > +    case POWERPC_MMU_3_00: /* P9 */
> > +        lpcr = val & (LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD
> > |
> > +                      (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE |
> > LPCR_AIL |
> > +                      LPCR_UPRT | LPCR_EVIRT | LPCR_ONL |
> > +                      (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE |
> > LPCR_EEE |
> > +                      LPCR_DEE | LPCR_OEE)) | LPCR_MER | LPCR_GTSE
> > | LPCR_TC |
> > +                      LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE |
> > LPCR_HDICE);
> > +        break;
> >      default:
> >          ;
> >      }
> > diff --git a/target/ppc/translate_init.c
> > b/target/ppc/translate_init.c
> > index 2402eef..a1994d3 100644
> > --- a/target/ppc/translate_init.c
> > +++ b/target/ppc/translate_init.c
> > @@ -8887,12 +8887,24 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)
> >      lpcr->default_value &= ~LPCR_RMLS;
> >      lpcr->default_value |= 1ull << LPCR_RMLS_SHIFT;
> >  
> > -    /* 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;
> > +    switch (env->mmu_model) {
> I'm not sure of mmu_model is conceptually the right thing to switch
> on, although I guess it will work in practice.
Well we need something to indicate our default value, which is dictated
by the cpu model, and given that a cpu model correlates to a mmu model
I can't think of a better option.
> 
> > 
> > +    case POWERPC_MMU_3_00:
> > +        /* By default we choose legacy mode and switch to new hash
> > or radix
> > +         * when a register process table hcall is made. So disable
> > process
> > +         * tables and guest translation shootdown by default
> > +         */
> > +        lpcr->default_value &= ~(LPCR_UPRT | LPCR_GTSE);
> > +        lpcr->default_value |= LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
> > LPCR_DEE |
> > +                               LPCR_OEE;
> > +        break;
> > +    default:
> > +        /* 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...

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

* Re: [Qemu-devel] [RFC PATCH 05/17] target/ppc/POWER9: Adapt LPCR handling for POWER9
  2017-01-17  0:48     ` Suraj Jitindar Singh
@ 2017-01-17  4:37       ` David Gibson
  2017-01-23  4:19         ` Suraj Jitindar Singh
  0 siblings, 1 reply; 53+ messages in thread
From: David Gibson @ 2017-01-17  4:37 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Tue, Jan 17, 2017 at 11:48:31AM +1100, Suraj Jitindar Singh wrote:
> On Tue, 2017-01-17 at 08:40 +1100, David Gibson wrote:
> > On Fri, Jan 13, 2017 at 05:28:11PM +1100, Suraj Jitindar Singh wrote:
> > > 
> > > The logical partitioning control register controls a threads
> > > operation
> > > based on the partition it is currently executing. Add new
> > > definitions and
> > > update the mask used when writing to the LPCR based on the POWER9
> > > spec.
> > > 
> > > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> > > ---
> > >  target/ppc/cpu.h            | 20 +++++++++++++++++++-
> > >  target/ppc/mmu-hash64.c     |  8 ++++++++
> > >  target/ppc/translate_init.c | 24 ++++++++++++++++++------
> > >  3 files changed, 45 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> > > index afb7ddb..0ab49b3 100644
> > > --- a/target/ppc/cpu.h
> > > +++ b/target/ppc/cpu.h
> > > @@ -379,15 +379,22 @@ struct ppc_slb_t {
> > >  #define LPCR_ISL          (1ull << (63 - 2))
> > >  #define LPCR_KBV          (1ull << (63 - 3))
> > >  #define LPCR_DPFD_SHIFT   (63 - 11)
> > > -#define LPCR_DPFD         (0x3ull << LPCR_DPFD_SHIFT)
> > > +#define LPCR_DPFD         (0x7ull << LPCR_DPFD_SHIFT)
> > Changing this define effectively changes the valid LPCR mask for
> > existing POWER8 and POWER7 models, which is not what you want, I
> > think.
> I should have explained this better in the commit message, this has
> always been a 3 bit field (at least in POWER7-9) so the mask has just
> always been wrong. Afaik fixing this up won't really change anything -
> it relates to data stream prefetch depth.
> 
> I realise this should probably be a separate patch though, or atleast
> mentioned in the commit message.

Right, yes.  Please make the bugfix a separate patch with the
explanation in the commit message.

> > 
> > > 
> > >  #define LPCR_VRMASD_SHIFT (63 - 16)
> > >  #define LPCR_VRMASD       (0x1full << LPCR_VRMASD_SHIFT)
> > > +/* P9: Power-saving mode Exit Cause Enable (Upper Section) Mask */
> > > +#define LPCR_PECE_U_SHIFT (63 - 19)
> > > +#define LPCR_PECE_U_MASK  (0x7ull << LPCR_PECE_U_SHIFT)
> > > +#define LPCR_HVEE         (1ull << (63 - 17)) /* Hypervisor Virt
> > > Exit Enable */
> > >  #define LPCR_RMLS_SHIFT   (63 - 37)
> > >  #define LPCR_RMLS         (0xfull << LPCR_RMLS_SHIFT)
> > >  #define LPCR_ILE          (1ull << (63 - 38))
> > >  #define LPCR_AIL_SHIFT    (63 - 40)      /* Alternate interrupt
> > > location */
> > >  #define LPCR_AIL          (3ull << LPCR_AIL_SHIFT)
> > > +#define LPCR_UPRT         (1ull << (63 - 41)) /* Use Process Table
> > > */
> > > +#define LPCR_EVIRT        (1ull << (63 - 42)) /* Enhanced
> > > Virtualisation */
> > >  #define LPCR_ONL          (1ull << (63 - 45))
> > > +#define LPCR_LD           (1ull << (63 - 46)) /* Large Decrementer
> > > */
> > >  #define LPCR_P7_PECE0     (1ull << (63 - 49))
> > >  #define LPCR_P7_PECE1     (1ull << (63 - 50))
> > >  #define LPCR_P7_PECE2     (1ull << (63 - 51))
> > > @@ -396,11 +403,22 @@ struct ppc_slb_t {
> > >  #define LPCR_P8_PECE2     (1ull << (63 - 49))
> > >  #define LPCR_P8_PECE3     (1ull << (63 - 50))
> > >  #define LPCR_P8_PECE4     (1ull << (63 - 51))
> > > +/* P9: Power-saving mode Exit Cause Enable (Lower Section) Mask */
> > > +#define LPCR_PECE_L_SHIFT (63 - 51)
> > > +#define LPCR_PECE_L_MASK  (0x1full << LPCR_PECE_L_SHIFT)
> > > +#define LPCR_PDEE         (1ull << (63 - 47)) /* Privileged
> > > Doorbell Exit EN */
> > > +#define LPCR_HDEE         (1ull << (63 - 48)) /* Hyperv Doorbell
> > > Exit Enable */
> > > +#define LPCR_EEE          (1ull << (63 - 49)) /* External Exit
> > > Enable        */
> > > +#define LPCR_DEE          (1ull << (63 - 50)) /* Decrementer Exit
> > > Enable     */
> > > +#define LPCR_OEE          (1ull << (63 - 51)) /* Other Exit
> > > Enable           */
> > >  #define LPCR_MER          (1ull << (63 - 52))
> > > +#define LPCR_GTSE         (1ull << (63 - 53)) /* Guest Translation
> > > Shootdown */
> > >  #define LPCR_TC           (1ull << (63 - 54))
> > > +#define LPCR_HEIC         (1ull << (63 - 59)) /* HV Extern
> > > Interrupt Control */
> > >  #define LPCR_LPES0        (1ull << (63 - 60))
> > >  #define LPCR_LPES1        (1ull << (63 - 61))
> > >  #define LPCR_RMI          (1ull << (63 - 62))
> > > +#define LPCR_HVICE        (1ull << (63 - 62)) /* HV Virtualisation
> > > Int Enable */
> > >  #define LPCR_HDICE        (1ull << (63 - 63))
> > >  
> > >  #define msr_sf   ((env->msr >> MSR_SF)   & 1)
> > > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> > > index fdb7a78..3a2acb8 100644
> > > --- a/target/ppc/mmu-hash64.c
> > > +++ b/target/ppc/mmu-hash64.c
> > > @@ -1050,6 +1050,14 @@ void helper_store_lpcr(CPUPPCState *env,
> > > target_ulong val)
> > >                        LPCR_P8_PECE2 | LPCR_P8_PECE3 |
> > > LPCR_P8_PECE4 |
> > >                        LPCR_MER | LPCR_TC | LPCR_LPES0 |
> > > LPCR_HDICE);
> > >          break;
> > > +    case POWERPC_MMU_3_00: /* P9 */
> > > +        lpcr = val & (LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD
> > > |
> > > +                      (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE |
> > > LPCR_AIL |
> > > +                      LPCR_UPRT | LPCR_EVIRT | LPCR_ONL |
> > > +                      (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE |
> > > LPCR_EEE |
> > > +                      LPCR_DEE | LPCR_OEE)) | LPCR_MER | LPCR_GTSE
> > > | LPCR_TC |
> > > +                      LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE |
> > > LPCR_HDICE);
> > > +        break;
> > >      default:
> > >          ;
> > >      }
> > > diff --git a/target/ppc/translate_init.c
> > > b/target/ppc/translate_init.c
> > > index 2402eef..a1994d3 100644
> > > --- a/target/ppc/translate_init.c
> > > +++ b/target/ppc/translate_init.c
> > > @@ -8887,12 +8887,24 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)
> > >      lpcr->default_value &= ~LPCR_RMLS;
> > >      lpcr->default_value |= 1ull << LPCR_RMLS_SHIFT;
> > >  
> > > -    /* 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;
> > > +    switch (env->mmu_model) {
> > I'm not sure of mmu_model is conceptually the right thing to switch
> > on, although I guess it will work in practice.
> Well we need something to indicate our default value, which is dictated
> by the cpu model, and given that a cpu model correlates to a mmu model
> I can't think of a better option.

Yeah, I guess it's probably reasonable.  We can always change it later
if we need to.

> > 
> > > 
> > > +    case POWERPC_MMU_3_00:
> > > +        /* By default we choose legacy mode and switch to new hash
> > > or radix
> > > +         * when a register process table hcall is made. So disable
> > > process
> > > +         * tables and guest translation shootdown by default
> > > +         */
> > > +        lpcr->default_value &= ~(LPCR_UPRT | LPCR_GTSE);
> > > +        lpcr->default_value |= LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
> > > LPCR_DEE |
> > > +                               LPCR_OEE;
> > > +        break;
> > > +    default:
> > > +        /* 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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 05/17] target/ppc/POWER9: Adapt LPCR handling for POWER9
  2017-01-17  4:37       ` David Gibson
@ 2017-01-23  4:19         ` Suraj Jitindar Singh
  0 siblings, 0 replies; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-23  4:19 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, agraf, qemu-devel

On Tue, 2017-01-17 at 15:37 +1100, David Gibson wrote:
> On Tue, Jan 17, 2017 at 11:48:31AM +1100, Suraj Jitindar Singh wrote:
> > 
> > On Tue, 2017-01-17 at 08:40 +1100, David Gibson wrote:
> > > 
> > > On Fri, Jan 13, 2017 at 05:28:11PM +1100, Suraj Jitindar Singh
> > > wrote:
> > > > 
> > > > 
> > > > The logical partitioning control register controls a threads
> > > > operation
> > > > based on the partition it is currently executing. Add new
> > > > definitions and
> > > > update the mask used when writing to the LPCR based on the
> > > > POWER9
> > > > spec.
> > > > 
> > > > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> > > > ---
> > > >  target/ppc/cpu.h            | 20 +++++++++++++++++++-
> > > >  target/ppc/mmu-hash64.c     |  8 ++++++++
> > > >  target/ppc/translate_init.c | 24 ++++++++++++++++++------
> > > >  3 files changed, 45 insertions(+), 7 deletions(-)
> > > > 
> > > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> > > > index afb7ddb..0ab49b3 100644
> > > > --- a/target/ppc/cpu.h
> > > > +++ b/target/ppc/cpu.h
> > > > @@ -379,15 +379,22 @@ struct ppc_slb_t {
> > > >  #define LPCR_ISL          (1ull << (63 - 2))
> > > >  #define LPCR_KBV          (1ull << (63 - 3))
> > > >  #define LPCR_DPFD_SHIFT   (63 - 11)
> > > > -#define LPCR_DPFD         (0x3ull << LPCR_DPFD_SHIFT)
> > > > +#define LPCR_DPFD         (0x7ull << LPCR_DPFD_SHIFT)
> > > Changing this define effectively changes the valid LPCR mask for
> > > existing POWER8 and POWER7 models, which is not what you want, I
> > > think.
> > I should have explained this better in the commit message, this has
> > always been a 3 bit field (at least in POWER7-9) so the mask has
> > just
> > always been wrong. Afaik fixing this up won't really change
> > anything -
> > it relates to data stream prefetch depth.
> > 
> > I realise this should probably be a separate patch though, or
> > atleast
> > mentioned in the commit message.
> Right, yes.  Please make the bugfix a separate patch with the
> explanation in the commit message.
> 
> > 
> > > 
> > > 
> > > > 
> > > > 
> > > >  #define LPCR_VRMASD_SHIFT (63 - 16)
> > > >  #define LPCR_VRMASD       (0x1full << LPCR_VRMASD_SHIFT)
> > > > +/* P9: Power-saving mode Exit Cause Enable (Upper Section)
> > > > Mask */
> > > > +#define LPCR_PECE_U_SHIFT (63 - 19)
> > > > +#define LPCR_PECE_U_MASK  (0x7ull << LPCR_PECE_U_SHIFT)
> > > > +#define LPCR_HVEE         (1ull << (63 - 17)) /* Hypervisor
> > > > Virt
> > > > Exit Enable */
> > > >  #define LPCR_RMLS_SHIFT   (63 - 37)
> > > >  #define LPCR_RMLS         (0xfull << LPCR_RMLS_SHIFT)
> > > >  #define LPCR_ILE          (1ull << (63 - 38))
> > > >  #define LPCR_AIL_SHIFT    (63 - 40)      /* Alternate
> > > > interrupt
> > > > location */
> > > >  #define LPCR_AIL          (3ull << LPCR_AIL_SHIFT)
> > > > +#define LPCR_UPRT         (1ull << (63 - 41)) /* Use Process
> > > > Table
> > > > */
> > > > +#define LPCR_EVIRT        (1ull << (63 - 42)) /* Enhanced
> > > > Virtualisation */
> > > >  #define LPCR_ONL          (1ull << (63 - 45))
> > > > +#define LPCR_LD           (1ull << (63 - 46)) /* Large
> > > > Decrementer
> > > > */
> > > >  #define LPCR_P7_PECE0     (1ull << (63 - 49))
> > > >  #define LPCR_P7_PECE1     (1ull << (63 - 50))
> > > >  #define LPCR_P7_PECE2     (1ull << (63 - 51))
> > > > @@ -396,11 +403,22 @@ struct ppc_slb_t {
> > > >  #define LPCR_P8_PECE2     (1ull << (63 - 49))
> > > >  #define LPCR_P8_PECE3     (1ull << (63 - 50))
> > > >  #define LPCR_P8_PECE4     (1ull << (63 - 51))
> > > > +/* P9: Power-saving mode Exit Cause Enable (Lower Section)
> > > > Mask */
> > > > +#define LPCR_PECE_L_SHIFT (63 - 51)
> > > > +#define LPCR_PECE_L_MASK  (0x1full << LPCR_PECE_L_SHIFT)
> > > > +#define LPCR_PDEE         (1ull << (63 - 47)) /* Privileged
> > > > Doorbell Exit EN */
> > > > +#define LPCR_HDEE         (1ull << (63 - 48)) /* Hyperv
> > > > Doorbell
> > > > Exit Enable */
> > > > +#define LPCR_EEE          (1ull << (63 - 49)) /* External Exit
> > > > Enable        */
> > > > +#define LPCR_DEE          (1ull << (63 - 50)) /* Decrementer
> > > > Exit
> > > > Enable     */
> > > > +#define LPCR_OEE          (1ull << (63 - 51)) /* Other Exit
> > > > Enable           */
> > > >  #define LPCR_MER          (1ull << (63 - 52))
> > > > +#define LPCR_GTSE         (1ull << (63 - 53)) /* Guest
> > > > Translation
> > > > Shootdown */
> > > >  #define LPCR_TC           (1ull << (63 - 54))
> > > > +#define LPCR_HEIC         (1ull << (63 - 59)) /* HV Extern
> > > > Interrupt Control */
> > > >  #define LPCR_LPES0        (1ull << (63 - 60))
> > > >  #define LPCR_LPES1        (1ull << (63 - 61))
> > > >  #define LPCR_RMI          (1ull << (63 - 62))
> > > > +#define LPCR_HVICE        (1ull << (63 - 62)) /* HV
> > > > Virtualisation
> > > > Int Enable */
> > > >  #define LPCR_HDICE        (1ull << (63 - 63))
> > > >  
> > > >  #define msr_sf   ((env->msr >> MSR_SF)   & 1)
> > > > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> > > > index fdb7a78..3a2acb8 100644
> > > > --- a/target/ppc/mmu-hash64.c
> > > > +++ b/target/ppc/mmu-hash64.c
> > > > @@ -1050,6 +1050,14 @@ void helper_store_lpcr(CPUPPCState *env,
> > > > target_ulong val)
> > > >                        LPCR_P8_PECE2 | LPCR_P8_PECE3 |
> > > > LPCR_P8_PECE4 |
> > > >                        LPCR_MER | LPCR_TC | LPCR_LPES0 |
> > > > LPCR_HDICE);
> > > >          break;
> > > > +    case POWERPC_MMU_3_00: /* P9 */
> > > > +        lpcr = val & (LPCR_VPM1 | LPCR_ISL | LPCR_KBV |
> > > > LPCR_DPFD
> > > > > 
> > > > > 
> > > > +                      (LPCR_PECE_U_MASK & LPCR_HVEE) |
> > > > LPCR_ILE |
> > > > LPCR_AIL |
> > > > +                      LPCR_UPRT | LPCR_EVIRT | LPCR_ONL |
> > > > +                      (LPCR_PECE_L_MASK & (LPCR_PDEE |
> > > > LPCR_HDEE |
> > > > LPCR_EEE |
> > > > +                      LPCR_DEE | LPCR_OEE)) | LPCR_MER |
> > > > LPCR_GTSE
> > > > > 
> > > > > LPCR_TC |
> > > > +                      LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE |
> > > > LPCR_HDICE);
> > > > +        break;
> > > >      default:
> > > >          ;
> > > >      }
> > > > diff --git a/target/ppc/translate_init.c
> > > > b/target/ppc/translate_init.c
> > > > index 2402eef..a1994d3 100644
> > > > --- a/target/ppc/translate_init.c
> > > > +++ b/target/ppc/translate_init.c
> > > > @@ -8887,12 +8887,24 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu)
> > > >      lpcr->default_value &= ~LPCR_RMLS;
> > > >      lpcr->default_value |= 1ull << LPCR_RMLS_SHIFT;
> > > >  
> > > > -    /* 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;
> > > > +    switch (env->mmu_model) {
> > > I'm not sure of mmu_model is conceptually the right thing to
> > > switch
> > > on, although I guess it will work in practice.
> > Well we need something to indicate our default value, which is
> > dictated
> > by the cpu model, and given that a cpu model correlates to a mmu
> > model
> > I can't think of a better option.
> Yeah, I guess it's probably reasonable.  We can always change it
> later
> if we need to.
I mean I can add another mmu flag to indicate that the mmu supports ISA
v3.00 features, POWERPC_MMU_V3 or something. This could be useful in
the likely event that future mmus also support the new features and
want to display support for them.

e.g.

#define POWERPC_MMU_V3 0x00100000

POWERPC_MMU_3_00       = ... | POWERPC_MMU_V3;

if (env->mmu_model & POWERPC_MMU_V3) {
    // ISA v3.00 specific stuffs
}

Not sure if this makes more sense than just checking the mmu_model
directly as I currently am, I guess it'll be necessary eventually for
the next mmu model for us to be able to claim v3.00 support.

Thoughts?
> 
> > 
> > > 
> > > 
> > > > 
> > > > 
> > > > +    case POWERPC_MMU_3_00:
> > > > +        /* By default we choose legacy mode and switch to new
> > > > hash
> > > > or radix
> > > > +         * when a register process table hcall is made. So
> > > > disable
> > > > process
> > > > +         * tables and guest translation shootdown by default
> > > > +         */
> > > > +        lpcr->default_value &= ~(LPCR_UPRT | LPCR_GTSE);
> > > > +        lpcr->default_value |= LPCR_PDEE | LPCR_HDEE |
> > > > LPCR_EEE |
> > > > LPCR_DEE |
> > > > +                               LPCR_OEE;
> > > > +        break;
> > > > +    default:
> > > > +        /* 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...

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

* Re: [Qemu-devel] [RFC PATCH 04/17] target/ppc/POWER9: Add ISAv3.00 MMU definition
  2017-01-17  0:33     ` Suraj Jitindar Singh
@ 2017-01-23  5:01       ` Suraj Jitindar Singh
  0 siblings, 0 replies; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-01-23  5:01 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, agraf, qemu-devel

On Tue, 2017-01-17 at 11:33 +1100, Suraj Jitindar Singh wrote:
> On Tue, 2017-01-17 at 08:36 +1100, David Gibson wrote:
> > 
> > On Fri, Jan 13, 2017 at 05:28:10PM +1100, Suraj Jitindar Singh
> > wrote:
> > > 
> > > 
> > > POWER9 processors implement the mmu as defined in version 3.00 of
> > > the ISA.
> > > 
> > > Add a definition for this mmu model and set the POWER9 cpu model
> > > to
> > > use
> > > this mmu model.
> > > 
> > > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> > > ---
> > >  target/ppc/cpu-qom.h        | 5 ++++-
> > >  target/ppc/mmu_helper.c     | 2 ++
> > >  target/ppc/translate_init.c | 3 +--
> > >  3 files changed, 7 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
> > > index d46c31a..1577cc8 100644
> > > --- a/target/ppc/cpu-qom.h
> > > +++ b/target/ppc/cpu-qom.h
> > > @@ -86,10 +86,13 @@ enum powerpc_mmu_t {
> > >      POWERPC_MMU_2_07       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
> > >                               | POWERPC_MMU_64K
> > >                               | POWERPC_MMU_AMR | 0x00000004,
> > > -    /* FIXME Add POWERPC_MMU_3_OO defines */
> > >      /* Architecture 2.07 "degraded" (no 1T
> > > segments)           */
> > >      POWERPC_MMU_2_07a      = POWERPC_MMU_64 | POWERPC_MMU_AMR
> > >                               | 0x00000004,
> > > +    /* Architecture 3.00
> > > variant                               */
> > > +    POWERPC_MMU_3_00       = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
> > > +                             | POWERPC_MMU_64K
> > > +                             | POWERPC_MMU_AMR | 0x00000005,
> > Hmm.  I guess it works for now, but I'm not really sure that having
> > this include POWERPC_MMU_64 is a great idea.  The name is kind of
> > misleading, but I'm pretty sure a number of places assume that the
> > POWERPC_MMU_64 bitindicates a 64-bit *hash* MMU, which is no longer
> > really the case.
> Good catch, I didn't realise this assumption was made in the code.
> 
> There are some cases where this bit needs to be set for correct
> behaviour but other places where, while it doesn't break anything, it
> leads to incorrect code being called.
> 
> Time for me to investigate :)
Actually, having looked through the code, I think we want this set. As
far as I can tell it doesn't lead to anything we don't want happening.
> > 
> > 
> > > 
> > > 
> > >  };
> > >  
> > >  /***************************************************************
> > > **
> > > ************/
> > > diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> > > index d09fc0a..2ab4562 100644
> > > --- a/target/ppc/mmu_helper.c
> > > +++ b/target/ppc/mmu_helper.c
> > > @@ -1935,6 +1935,7 @@ void ppc_tlb_invalidate_all(CPUPPCState
> > > *env)
> > >      case POWERPC_MMU_2_06a:
> > >      case POWERPC_MMU_2_07:
> > >      case POWERPC_MMU_2_07a:
> > > +    case POWERPC_MMU_3_00:
> > >  #endif /* defined(TARGET_PPC64) */
> > >          env->tlb_need_flush = 0;
> > >          tlb_flush(CPU(cpu), 1);
> > > @@ -1974,6 +1975,7 @@ void ppc_tlb_invalidate_one(CPUPPCState
> > > *env,
> > > target_ulong addr)
> > >      case POWERPC_MMU_2_06a:
> > >      case POWERPC_MMU_2_07:
> > >      case POWERPC_MMU_2_07a:
> > > +    case POWERPC_MMU_3_00:
> > >          /* tlbie invalidate TLBs for all segments */
> > >          /* XXX: given the fact that there are too many segments
> > > to
> > > invalidate,
> > >           *      and we still don't have a tlb_flush_mask(env, n,
> > > mask) in QEMU,
> > > diff --git a/target/ppc/translate_init.c
> > > b/target/ppc/translate_init.c
> > > index bfc1f24..2402eef 100644
> > > --- a/target/ppc/translate_init.c
> > > +++ b/target/ppc/translate_init.c
> > > @@ -8838,8 +8838,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc,
> > > void
> > > *data)
> > >                      (1ull << MSR_PMM) |
> > >                      (1ull << MSR_RI) |
> > >                      (1ull << MSR_LE);
> > > -    /* Using 2.07 defines until new radix model is added. */
> > > -    pcc->mmu_model = POWERPC_MMU_2_07;
> > > +    pcc->mmu_model = POWERPC_MMU_3_00;
> > >  #if defined(CONFIG_SOFTMMU)
> > >      pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
> > >      /* segment page size remain the same */

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

* Re: [Qemu-devel] [RFC PATCH 06/17] target/ppc/POWER9: Direct all instr and data storage interrupts to the hypv
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 06/17] target/ppc/POWER9: Direct all instr and data storage interrupts to the hypv Suraj Jitindar Singh
@ 2017-02-01  0:50   ` David Gibson
  0 siblings, 0 replies; 53+ messages in thread
From: David Gibson @ 2017-02-01  0:50 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:12PM +1100, Suraj Jitindar Singh wrote:
> The vpm0 bit was removed from the LPCR in POWER9, this bit controlled
> whether ISI and DSI interrupts were directed to the hypervisor or the
> partition. These interrupts now go to the hypervisor irrespective, thus
> it is no longer necessary to check the vmp0 bit in the LPCR.
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

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

> ---
>  target/ppc/mmu-hash64.c | 20 ++++++++++++++++++--
>  1 file changed, 18 insertions(+), 2 deletions(-)
> 
> diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> index 3a2acb8..fe7da18 100644
> --- a/target/ppc/mmu-hash64.c
> +++ b/target/ppc/mmu-hash64.c
> @@ -640,7 +640,15 @@ static void ppc_hash64_set_isi(CPUState *cs, CPUPPCState *env,
>      if (msr_ir) {
>          vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
>      } else {
> -        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
> +        switch (env->mmu_model) {
> +        case POWERPC_MMU_3_00:
> +            /* Field deprecated in ISAv3.00 - interrupts always go to hyperv */
> +            vpm = true;
> +            break;
> +        default:
> +            vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
> +            break;
> +        }
>      }
>      if (vpm && !msr_hv) {
>          cs->exception_index = POWERPC_EXCP_HISI;
> @@ -658,7 +666,15 @@ static void ppc_hash64_set_dsi(CPUState *cs, CPUPPCState *env, uint64_t dar,
>      if (msr_dr) {
>          vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
>      } else {
> -        vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
> +        switch (env->mmu_model) {
> +        case POWERPC_MMU_3_00:
> +            /* Field deprecated in ISAv3.00 - interrupts always go to hyperv */
> +            vpm = true;
> +            break;
> +        default:
> +            vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
> +            break;
> +        }
>      }
>      if (vpm && !msr_hv) {
>          cs->exception_index = POWERPC_EXCP_HDSI;

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support
  2017-01-13  6:55 ` [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support no-reply
@ 2017-02-01  1:04   ` David Gibson
  2017-02-09  3:09     ` Suraj Jitindar Singh
  0 siblings, 1 reply; 53+ messages in thread
From: David Gibson @ 2017-02-01  1:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: sjitindarsingh, famz, qemu-ppc, agraf

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

On Thu, Jan 12, 2017 at 10:55:49PM -0800, no-reply@patchew.org wrote:
> Hi,
> 
> Your series seems to have some coding style problems. See output below for
> more information:
> 
> Message-id: 1484288903-18807-1-git-send-email-sjitindarsingh@gmail.com
> Subject: [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support
> Type: series

The style bot does generate a fair few false positives, but AFAICT all
the things below should be addressed.

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support
  2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
                   ` (17 preceding siblings ...)
  2017-01-13  6:55 ` [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support no-reply
@ 2017-02-01  2:16 ` David Gibson
  2017-02-01  2:22   ` David Gibson
  18 siblings, 1 reply; 53+ messages in thread
From: David Gibson @ 2017-02-01  2:16 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:06PM +1100, Suraj Jitindar Singh wrote:
> This patch set provides the initial implementation of support for the 
> POWER9 processor running in tcg mode under the pseries machine type.
> 
> To use a POWER9 cpu provide the command line option "-cpu POWER9".
> 
> This is the initial work to make the mmu emulation model look like a POWER9
> 
> Currently only legacy kernels are supported (hash without segment tables).
> 
> This patch set will be followed by two more in the near future to support
> the new process table capabilities added in ISAv3.00; hash via segment
> tables and radix. Kernels with support for this will currently fail when
> they try to register a process table as this isn't yet implemented.
> 
> The assumption is that we're running a legacy kernel, in the event the
> guest registers a process table (when support exists) we will handle it
> accordingly.
> 
> The main changes are:
>  - Define a new mmu model and fault handler
>  - Add new LPCR fields and check them accordingly
>  - Add a partition table entry to the machine state
>  - Point to the partition table entry in the cpu state
>  - Remove SDR1
>  - Adapt to new pte format
>  - NOOP the cp_abort instruction
>  - Small bug fixes
> 
> This was intially one huge patch so I've tried to break it up into what I
> think are logical chunks, how exactly this should be split up is up for 
> debate.
> 
> A current upstream kernel with POWER9 support added to the architecture
> vector should correctly report a POWER9 cpu under /proc/cpuinfo.

I've merged 14-16/17 since they seem to stand on their own as fixes.

> 
> Suraj Jitindar Singh (17):
>   powerpc/cpu-models: rename ISAv3.00 logical PVR definition
>   hw/ppc/spapr: Add POWER9 to pseries cpu models
>   target/ppc: Add pcr_supported to POWER9 cpu class definition
>   target/ppc/POWER9: Add ISAv3.00 MMU definition
>   target/ppc/POWER9: Adapt LPCR handling for POWER9
>   target/ppc/POWER9: Direct all instr and data storage interrupts to the
>     hypv
>   target/ppc/POWER9: Add partition table pointer to sPAPRMachineState
>   target/ppc/POWER9: Add external partition table pointer to cpu state
>   target/ppc/POWER9: Remove SDR1 register
>   target/ppc/POWER9: Add POWER9 mmu fault handler
>   target/ppc/POWER9: Update to new pte format for POWER9 accesses
>   target/ppc/POWER9: Add POWER9 pa-features definition
>   target/ppc/POWER9: Add cpu_has_work function for POWER9
>   target/ppc/debug: Print LPCR register value if register exists
>   tcg/POWER9: NOOP the cp_abort instruction
>   target/ppc/mmu_hash64: Fix printing unsigned as signed int
>   target/ppc/mmu_hash64: Fix incorrect shift value in amr calculation
> 
>  hw/ppc/spapr.c              | 56 ++++++++++++++++++++++++---
>  hw/ppc/spapr_cpu_core.c     | 15 +++++++-
>  hw/ppc/spapr_hcall.c        | 51 +++++++++++++------------
>  include/hw/ppc/spapr.h      |  1 +
>  target/ppc/cpu-models.h     |  2 +-
>  target/ppc/cpu-qom.h        |  5 ++-
>  target/ppc/cpu.h            | 24 +++++++++++-
>  target/ppc/kvm.c            | 10 ++++-
>  target/ppc/mmu-hash64.c     | 68 +++++++++++++++++++++++++++------
>  target/ppc/mmu-hash64.h     | 73 +++++++++++++++++++++++++----------
>  target/ppc/mmu.h            | 27 +++++++++++++
>  target/ppc/mmu_helper.c     | 61 ++++++++++++++++++++++++++++++
>  target/ppc/translate.c      | 14 ++++++-
>  target/ppc/translate_init.c | 92 +++++++++++++++++++++++++++++++++++++++------
>  14 files changed, 418 insertions(+), 81 deletions(-)
>  create mode 100644 target/ppc/mmu.h
> 

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support
  2017-02-01  2:16 ` David Gibson
@ 2017-02-01  2:22   ` David Gibson
  0 siblings, 0 replies; 53+ messages in thread
From: David Gibson @ 2017-02-01  2:22 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Wed, Feb 01, 2017 at 01:16:00PM +1100, David Gibson wrote:
> On Fri, Jan 13, 2017 at 05:28:06PM +1100, Suraj Jitindar Singh wrote:
> > This patch set provides the initial implementation of support for the 
> > POWER9 processor running in tcg mode under the pseries machine type.
> > 
> > To use a POWER9 cpu provide the command line option "-cpu POWER9".
> > 
> > This is the initial work to make the mmu emulation model look like a POWER9
> > 
> > Currently only legacy kernels are supported (hash without segment tables).
> > 
> > This patch set will be followed by two more in the near future to support
> > the new process table capabilities added in ISAv3.00; hash via segment
> > tables and radix. Kernels with support for this will currently fail when
> > they try to register a process table as this isn't yet implemented.
> > 
> > The assumption is that we're running a legacy kernel, in the event the
> > guest registers a process table (when support exists) we will handle it
> > accordingly.
> > 
> > The main changes are:
> >  - Define a new mmu model and fault handler
> >  - Add new LPCR fields and check them accordingly
> >  - Add a partition table entry to the machine state
> >  - Point to the partition table entry in the cpu state
> >  - Remove SDR1
> >  - Adapt to new pte format
> >  - NOOP the cp_abort instruction
> >  - Small bug fixes
> > 
> > This was intially one huge patch so I've tried to break it up into what I
> > think are logical chunks, how exactly this should be split up is up for 
> > debate.
> > 
> > A current upstream kernel with POWER9 support added to the architecture
> > vector should correctly report a POWER9 cpu under /proc/cpuinfo.
> 
> I've merged 14-16/17 since they seem to stand on their own as fixes.

And 17/17 as well.

> 
> > 
> > Suraj Jitindar Singh (17):
> >   powerpc/cpu-models: rename ISAv3.00 logical PVR definition
> >   hw/ppc/spapr: Add POWER9 to pseries cpu models
> >   target/ppc: Add pcr_supported to POWER9 cpu class definition
> >   target/ppc/POWER9: Add ISAv3.00 MMU definition
> >   target/ppc/POWER9: Adapt LPCR handling for POWER9
> >   target/ppc/POWER9: Direct all instr and data storage interrupts to the
> >     hypv
> >   target/ppc/POWER9: Add partition table pointer to sPAPRMachineState
> >   target/ppc/POWER9: Add external partition table pointer to cpu state
> >   target/ppc/POWER9: Remove SDR1 register
> >   target/ppc/POWER9: Add POWER9 mmu fault handler
> >   target/ppc/POWER9: Update to new pte format for POWER9 accesses
> >   target/ppc/POWER9: Add POWER9 pa-features definition
> >   target/ppc/POWER9: Add cpu_has_work function for POWER9
> >   target/ppc/debug: Print LPCR register value if register exists
> >   tcg/POWER9: NOOP the cp_abort instruction
> >   target/ppc/mmu_hash64: Fix printing unsigned as signed int
> >   target/ppc/mmu_hash64: Fix incorrect shift value in amr calculation
> > 
> >  hw/ppc/spapr.c              | 56 ++++++++++++++++++++++++---
> >  hw/ppc/spapr_cpu_core.c     | 15 +++++++-
> >  hw/ppc/spapr_hcall.c        | 51 +++++++++++++------------
> >  include/hw/ppc/spapr.h      |  1 +
> >  target/ppc/cpu-models.h     |  2 +-
> >  target/ppc/cpu-qom.h        |  5 ++-
> >  target/ppc/cpu.h            | 24 +++++++++++-
> >  target/ppc/kvm.c            | 10 ++++-
> >  target/ppc/mmu-hash64.c     | 68 +++++++++++++++++++++++++++------
> >  target/ppc/mmu-hash64.h     | 73 +++++++++++++++++++++++++----------
> >  target/ppc/mmu.h            | 27 +++++++++++++
> >  target/ppc/mmu_helper.c     | 61 ++++++++++++++++++++++++++++++
> >  target/ppc/translate.c      | 14 ++++++-
> >  target/ppc/translate_init.c | 92 +++++++++++++++++++++++++++++++++++++++------
> >  14 files changed, 418 insertions(+), 81 deletions(-)
> >  create mode 100644 target/ppc/mmu.h
> > 
> 



-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 07/17] target/ppc/POWER9: Add partition table pointer to sPAPRMachineState
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 07/17] target/ppc/POWER9: Add partition table pointer to sPAPRMachineState Suraj Jitindar Singh
@ 2017-02-01  4:04   ` David Gibson
  2017-02-09  2:57     ` Suraj Jitindar Singh
  0 siblings, 1 reply; 53+ messages in thread
From: David Gibson @ 2017-02-01  4:04 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:13PM +1100, Suraj Jitindar Singh wrote:
> POWER9 uses a partition table to store information relating to how
> address translation is performed on a per partition basis.
> 
> Add a data area for this to the sPAPRMachineState struct and (re)allocate
> it on machine reset.
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

Hm.  I'm having trouble understanding this one.

IIUC, for the "pseries" machine type this partition table entry is
essentially a dummy one, since there's actually only one partition.
For KVM the machine would be represented by one of many partition
table entries on the real host - so the entry here isn't really
relevant.  For TCG, I'm not sure what would be looking at it.  We
haven't implemented the partition->host level translation in TCG
anyway, and in any case pseries (rather than powernv) should be
bypassing that - in which case I'd expect it to bypass looking at the
dummy partition table entry as well.

> ---
>  hw/ppc/spapr.c         | 38 ++++++++++++++++++++++++++++++++------
>  include/hw/ppc/spapr.h |  1 +
>  target/ppc/mmu.h       | 13 +++++++++++++
>  3 files changed, 46 insertions(+), 6 deletions(-)
>  create mode 100644 target/ppc/mmu.h
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 208ef7b..45bd2de 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -41,6 +41,7 @@
>  #include "migration/migration.h"
>  #include "mmu-hash64.h"
>  #include "qom/cpu.h"
> +#include "mmu.h"
>  
>  #include "hw/boards.h"
>  #include "hw/ppc/ppc.h"
> @@ -1115,6 +1116,26 @@ static void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
>      }
>  }
>  
> +static void spapr_reallocate_patb(sPAPRMachineState *spapr, Error **errp)
> +{
> +    g_free(spapr->patb);
> +    spapr->patb = NULL;
> +
> +    if (!kvm_enabled()) {
> +        /* We need to allocate a partition table entry */
> +        size_t size = sizeof(struct patb_entry);
> +
> +        spapr->patb = qemu_memalign(size, size);
> +        if (!spapr->patb) {
> +            error_setg_errno(errp, errno, "Could not allocate memory for "
> +                                          "partition table entry");
> +            return;
> +        }
> +
> +        memset(spapr->patb, 0, size);
> +    }
> +}
> +
>  static void find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque)
>  {
>      bool matched = false;
> @@ -1134,7 +1155,7 @@ static void ppc_spapr_reset(void)
>  {
>      MachineState *machine = MACHINE(qdev_get_machine());
>      sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
> -    PowerPCCPU *first_ppc_cpu;
> +    PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
>      uint32_t rtas_limit;
>      hwaddr rtas_addr, fdt_addr;
>      void *fdt;
> @@ -1143,10 +1164,16 @@ static void ppc_spapr_reset(void)
>      /* Check for unknown sysbus devices */
>      foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
>  
> -    /* Allocate and/or reset the hash page table */
> -    spapr_reallocate_hpt(spapr,
> -                         spapr_hpt_shift_for_ramsize(machine->maxram_size),
> -                         &error_fatal);
> +    switch (first_ppc_cpu->env.mmu_model) {
> +    case POWERPC_MMU_3_00:
> +        /* Allocate the partition table */
> +        spapr_reallocate_patb(spapr, &error_fatal);
> +    default:
> +        /* Allocate and/or reset the hash page table */
> +        spapr_reallocate_hpt(spapr,
> +                             spapr_hpt_shift_for_ramsize(machine->maxram_size),
> +                             &error_fatal);
> +    }
>  
>      /* Update the RMA size if necessary */
>      if (spapr->vrma_adjust) {
> @@ -1193,7 +1220,6 @@ static void ppc_spapr_reset(void)
>      g_free(fdt);
>  
>      /* Set up the entry state */
> -    first_ppc_cpu = POWERPC_CPU(first_cpu);
>      first_ppc_cpu->env.gpr[3] = fdt_addr;
>      first_ppc_cpu->env.gpr[5] = 0;
>      first_cpu->halted = 0;
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index bd5bcf7..b654773 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -63,6 +63,7 @@ struct sPAPRMachineState {
>  
>      void *htab;
>      uint32_t htab_shift;
> +    void *patb;
>      hwaddr rma_size;
>      int vrma_adjust;
>      ssize_t rtas_size;
> diff --git a/target/ppc/mmu.h b/target/ppc/mmu.h
> new file mode 100644
> index 0000000..67b9707
> --- /dev/null
> +++ b/target/ppc/mmu.h
> @@ -0,0 +1,13 @@
> +#ifndef MMU_H
> +#define MMU_H
> +
> +#ifndef CONFIG_USER_ONLY
> +
> +/* Partition Table Entry */
> +struct patb_entry {
> +    uint64_t patbe0, patbe1;
> +};
> +
> +#endif /* CONFIG_USER_ONLY */
> +
> +#endif /* MMU_H */

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 08/17] target/ppc/POWER9: Add external partition table pointer to cpu state
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 08/17] target/ppc/POWER9: Add external partition table pointer to cpu state Suraj Jitindar Singh
@ 2017-02-01  4:09   ` David Gibson
  2017-02-09  2:58     ` Suraj Jitindar Singh
  0 siblings, 1 reply; 53+ messages in thread
From: David Gibson @ 2017-02-01  4:09 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:14PM +1100, Suraj Jitindar Singh wrote:
> Similarly to how we have an external hpt pointer in the cpu state, add
> an external partition table pointer and update it to point to the
> partition table entry in the machine state struct on cpu reset.
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

As with the previous patch, I don't quite follow what's going on
here.  It seems to me that if the external HPT is set, that should
make the softmmu logic bypass *both* an HPT set by SDR1 (<= POWER8) or
an HPT set by the partition table (POWER9).  So I'm not sure why we
need the dummy partition table entry.

To look at it another way, the external HPT is special because it lies
outside the guest's address space, but we need its state because the
guest can manipulate it via hypercall.  For the partition table entry,
even if we're minimally modelling the HV parts of the POWER9 MMU,
isn't the partition table entry just fixed at startup?

> ---
>  hw/ppc/spapr_cpu_core.c | 12 ++++++++++--
>  target/ppc/cpu.h        |  3 +++
>  target/ppc/mmu.h        |  6 ++++++
>  target/ppc/mmu_helper.c | 12 ++++++++++++
>  4 files changed, 31 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
> index 8cc7058..72a7f90 100644
> --- a/hw/ppc/spapr_cpu_core.c
> +++ b/hw/ppc/spapr_cpu_core.c
> @@ -17,6 +17,7 @@
>  #include "hw/ppc/ppc.h"
>  #include "target/ppc/mmu-hash64.h"
>  #include "sysemu/numa.h"
> +#include "mmu.h"
>  
>  static void spapr_cpu_reset(void *opaque)
>  {
> @@ -34,8 +35,15 @@ static void spapr_cpu_reset(void *opaque)
>  
>      env->spr[SPR_HIOR] = 0;
>  
> -    ppc_hash64_set_external_hpt(cpu, spapr->htab, spapr->htab_shift,
> -                                &error_fatal);
> +    switch (env->mmu_model) {
> +    case POWERPC_MMU_3_00:
> +        ppc64_set_external_patb(cpu, spapr->patb, &error_fatal);
> +    default:
> +        /* We assume legacy until told otherwise, thus set HPT irrespective */
> +        ppc_hash64_set_external_hpt(cpu, spapr->htab, spapr->htab_shift,
> +                                    &error_fatal);
> +        break;
> +    }
>  }
>  
>  static void spapr_cpu_destroy(PowerPCCPU *cpu)
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 0ab49b3..e8b7c06 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -77,6 +77,7 @@
>  #include "exec/cpu-defs.h"
>  #include "cpu-qom.h"
>  #include "fpu/softfloat.h"
> +#include "mmu.h"
>  
>  #if defined (TARGET_PPC64)
>  #define PPC_ELF_MACHINE     EM_PPC64
> @@ -1009,6 +1010,8 @@ struct CPUPPCState {
>      target_ulong sr[32];
>      /* externally stored hash table */
>      uint8_t *external_htab;
> +    /* externally stored partition table entry */
> +    struct patb_entry *external_patbe;
>      /* BATs */
>      uint32_t nb_BATs;
>      target_ulong DBAT[2][8];
> diff --git a/target/ppc/mmu.h b/target/ppc/mmu.h
> index 67b9707..c7967c3 100644
> --- a/target/ppc/mmu.h
> +++ b/target/ppc/mmu.h
> @@ -8,6 +8,12 @@ struct patb_entry {
>      uint64_t patbe0, patbe1;
>  };
>  
> +#ifdef TARGET_PPC64
> +
> +void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error **errp);
> +
> +#endif /* TARGET_PPC64 */
> +
>  #endif /* CONFIG_USER_ONLY */
>  
>  #endif /* MMU_H */
> diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> index 2ab4562..bc6c117 100644
> --- a/target/ppc/mmu_helper.c
> +++ b/target/ppc/mmu_helper.c
> @@ -28,6 +28,7 @@
>  #include "exec/cpu_ldst.h"
>  #include "exec/log.h"
>  #include "helper_regs.h"
> +#include "mmu.h"
>  
>  //#define DEBUG_MMU
>  //#define DEBUG_BATS
> @@ -2907,3 +2908,14 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
>                                 retaddr);
>      }
>  }
> +
> +/******************************************************************************/
> +
> +/* ISA v3.00 (POWER9) Generic MMU Helpers */
> +
> +void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error **errp)
> +{
> +    CPUPPCState *env = &cpu->env;
> +
> +    env->external_patbe = (struct patb_entry *) patb;
> +}

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 09/17] target/ppc/POWER9: Remove SDR1 register
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 09/17] target/ppc/POWER9: Remove SDR1 register Suraj Jitindar Singh
@ 2017-02-01  4:16   ` David Gibson
  2017-02-09  3:00     ` Suraj Jitindar Singh
  0 siblings, 1 reply; 53+ messages in thread
From: David Gibson @ 2017-02-01  4:16 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:15PM +1100, Suraj Jitindar Singh wrote:
> The SDR1 registers was used to store the location of the hash page table.
> 
> This register no longer exists on POWER9 processors, so don't create it.
> 
> We now store the hash page table location in the process table entry.
> 
> We now check if the SDR1 register exists before printing its value when
> displaying register debug info.
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> ---
>  target/ppc/kvm.c            | 10 +++++++++-
>  target/ppc/mmu-hash64.c     | 15 ++++++++++++++-
>  target/ppc/translate.c      |  6 ++++--
>  target/ppc/translate_init.c | 16 +++++++++++++---
>  4 files changed, 40 insertions(+), 7 deletions(-)
> 
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index 9c4834c..6016930 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -930,7 +930,15 @@ int kvmppc_put_books_sregs(PowerPCCPU *cpu)
>  
>      sregs.pvr = env->spr[SPR_PVR];
>  
> -    sregs.u.s.sdr1 = env->spr[SPR_SDR1];
> +    switch (env->mmu_model) {
> +    case POWERPC_MMU_3_00:
> +        if (env->external_patbe)
> +            sregs.u.s.sdr1 = env->external_patbe->patbe0;

I take it from this that KVM is expecting the address of the guest HPT
in the SDR1 slot of sregs, even on POWER9?  Rather than using a new
ONE_REG entry for the POWER9 data.

Note that this slot was already a hack for PR KVM - we are putting a
userspace address in there, which is clearly not a real SDR1 value.
For HV KVM, I think this value is ignored entirely, since in that case
KVM allocates / controls the guest HPT, not qemu.

> +        break;
> +    default:
> +        sregs.u.s.sdr1 = env->spr[SPR_SDR1];
> +        break;
> +    }

So.. maybe we should take this opportunity to clean this path up and
special case all "external HPT" cases to pass the relevant value to PR
KVM without abusing the env->spr[SPR_SDR1] field.

>  
>      /* Sync SLB */
>  #ifdef TARGET_PPC64
> diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> index fe7da18..b9d4f4e 100644
> --- a/target/ppc/mmu-hash64.c
> +++ b/target/ppc/mmu-hash64.c
> @@ -291,7 +291,20 @@ void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong value,
>      CPUPPCState *env = &cpu->env;
>      target_ulong htabsize = value & SDR_64_HTABSIZE;
>  
> -    env->spr[SPR_SDR1] = value;
> +    switch (env->mmu_model) {
> +    case POWERPC_MMU_3_00:
> +        /*
> +         * Technically P9 doesn't have a SDR1, the hash table address should be
> +         * stored in the partition table entry instead.
> +         */
> +        if (env->external_patbe)
> +            env->external_patbe->patbe0 = value;

This definitely doesn't belong in a function called ..._set_sdr1().
Either rename this function or (probably better), set the partition
table entry from a new function and make the decision in the caller.


> +        break;
> +    default:
> +        env->spr[SPR_SDR1] = value;
> +        break;
> +    }
> +
>      if (htabsize > 28) {
>          error_setg(errp,
>                     "Invalid HTABSIZE 0x" TARGET_FMT_lx" stored in SDR1",
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 1212180..521aed3 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -6922,9 +6922,11 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
>      case POWERPC_MMU_2_06a:
>      case POWERPC_MMU_2_07:
>      case POWERPC_MMU_2_07a:
> +    case POWERPC_MMU_3_00:
>  #endif
> -        cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "   DAR " TARGET_FMT_lx
> -                       "  DSISR " TARGET_FMT_lx "\n", env->spr[SPR_SDR1],
> +        if (env->spr_cb[SPR_SDR1].name)
> +            cpu_fprintf(f, " SDR1 " TARGET_FMT_lx " ", env->spr[SPR_SDR1]);
> +        cpu_fprintf(f, "  DAR " TARGET_FMT_lx "  DSISR " TARGET_FMT_lx "\n",
>                      env->spr[SPR_DAR], env->spr[SPR_DSISR]);
>          break;
>      case POWERPC_MMU_BOOKE206:
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index a1994d3..c771ba3 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -32,6 +32,7 @@
>  #include "qapi/visitor.h"
>  #include "hw/qdev-properties.h"
>  #include "hw/ppc/ppc.h"
> +#include "mmu.h"
>  
>  //#define PPC_DUMP_CPU
>  //#define PPC_DEBUG_SPR
> @@ -722,8 +723,8 @@ static void gen_spr_generic (CPUPPCState *env)
>                   0x00000000);
>  }
>  
> -/* SPR common to all non-embedded PowerPC, including 601 */
> -static void gen_spr_ne_601 (CPUPPCState *env)
> +/* SPR common to all non-embedded PowerPC, including POWER9 */
> +static void gen_spr_ne_power9 (CPUPPCState *env)
>  {
>      /* Exception processing */
>      spr_register_kvm(env, SPR_DSISR, "DSISR",
> @@ -739,6 +740,12 @@ static void gen_spr_ne_601 (CPUPPCState *env)
>                   SPR_NOACCESS, SPR_NOACCESS,
>                   &spr_read_decr, &spr_write_decr,
>                   0x00000000);
> +}
> +
> +/* SPR common to all non-embedded PowerPC, including 601 */
> +static void gen_spr_ne_601 (CPUPPCState *env)
> +{
> +    gen_spr_ne_power9(env);
>      /* Memory management */
>      spr_register(env, SPR_SDR1, "SDR1",
>                   SPR_NOACCESS, SPR_NOACCESS,
> @@ -8222,7 +8229,6 @@ static void gen_spr_power8_rpr(CPUPPCState *env)
>  
>  static void init_proc_book3s_64(CPUPPCState *env, int version)
>  {
> -    gen_spr_ne_601(env);
>      gen_tbl(env);
>      gen_spr_book3s_altivec(env);
>      gen_spr_book3s_pmu_sup(env);
> @@ -8280,6 +8286,10 @@ static void init_proc_book3s_64(CPUPPCState *env, int version)
>          gen_spr_power8_book4(env);
>          gen_spr_power8_rpr(env);
>      }
> +    if (version >= BOOK3S_CPU_POWER9)
> +        gen_spr_ne_power9(env);
> +    else
> +        gen_spr_ne_601(env);
>      if (version < BOOK3S_CPU_POWER8) {
>          gen_spr_book3s_dbg(env);
>      } else {

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 10/17] target/ppc/POWER9: Add POWER9 mmu fault handler
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 10/17] target/ppc/POWER9: Add POWER9 mmu fault handler Suraj Jitindar Singh
@ 2017-02-01  4:23   ` David Gibson
  2017-02-09  3:04     ` Suraj Jitindar Singh
  0 siblings, 1 reply; 53+ messages in thread
From: David Gibson @ 2017-02-01  4:23 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:16PM +1100, Suraj Jitindar Singh wrote:
> Add a new mmu fault handler for the POWER9 cpu and add it as the handler
> for the POWER9 cpu definition.
> 
> This handler checks if the guest is radix or hash based on the value in the
> partition table entry and calls the correct fault handler accordingly.
> 
> The hash fault handling code has also been updated to check if the
> partition is using segment tables.
> 
> Currently only legacy hash (no segment tables) is supported.
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> ---
>  target/ppc/mmu-hash64.c     |  8 ++++++++
>  target/ppc/mmu.h            |  8 ++++++++
>  target/ppc/mmu_helper.c     | 47 +++++++++++++++++++++++++++++++++++++++++++++
>  target/ppc/translate_init.c |  2 +-
>  4 files changed, 64 insertions(+), 1 deletion(-)
> 
> diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> index b9d4f4e..b476b3f 100644
> --- a/target/ppc/mmu-hash64.c
> +++ b/target/ppc/mmu-hash64.c
> @@ -73,6 +73,14 @@ static ppc_slb_t *slb_lookup(PowerPCCPU *cpu, target_ulong eaddr)
>          }
>      }
>  
> +    /* Check if in-memory segment tables are in use */
> +    if (ppc64_use_proc_tbl(cpu)) {
> +        /* TODO - Unsupported */
> +        qemu_log_mask(LOG_UNIMP, "%s: unimplemented - segment table support\n",
> +                      __func__);
> +        /* Not much we can do here, caller will generate a segment interrupt */
> +    }

I think this logic would be better in the fault handler.  For the
fault path in the segment table case, I don't think we want to even
model the SLB (in hardware the SLB is an important optimization, but I
don't think the software SLB will be notably better than just looking
up the seg table directly).  I think the other users of slb_lookup()
are in contexts that only make sense in the context of a software
managed SLB anyway.

>      return NULL;
>  }
>  
> diff --git a/target/ppc/mmu.h b/target/ppc/mmu.h
> index c7967c3..e07b128 100644
> --- a/target/ppc/mmu.h
> +++ b/target/ppc/mmu.h
> @@ -3,6 +3,10 @@
>  
>  #ifndef CONFIG_USER_ONLY
>  
> +/* Common Partition Table Entry Fields */
> +#define PATBE0_HR                0x8000000000000000
> +#define PATBE1_GR                0x8000000000000000
> +
>  /* Partition Table Entry */
>  struct patb_entry {
>      uint64_t patbe0, patbe1;
> @@ -11,6 +15,10 @@ struct patb_entry {
>  #ifdef TARGET_PPC64
>  
>  void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error **errp);
> +bool ppc64_use_proc_tbl(PowerPCCPU *cpu);
> +bool ppc64_radix_guest(PowerPCCPU *cpu);
> +int ppc64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
> +                           int mmu_idx);
>  
>  #endif /* TARGET_PPC64 */
>  
> diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> index bc6c117..612f407 100644
> --- a/target/ppc/mmu_helper.c
> +++ b/target/ppc/mmu_helper.c
> @@ -28,6 +28,7 @@
>  #include "exec/cpu_ldst.h"
>  #include "exec/log.h"
>  #include "helper_regs.h"
> +#include "qemu/error-report.h"
>  #include "mmu.h"
>  
>  //#define DEBUG_MMU
> @@ -1281,6 +1282,17 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
>      case POWERPC_MMU_2_07a:
>          dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
>          break;
> +    case POWERPC_MMU_3_00:
> +        if (ppc64_radix_guest(ppc_env_get_cpu(env))) {
> +            /* TODO - Unsupported */
> +        } else {
> +            if (ppc64_use_proc_tbl(ppc_env_get_cpu(env))) {
> +                /* TODO - Unsupported */
> +            } else {
> +                dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
> +                break;
> +            }
> +        }
>  #endif
>      default:
>          qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
> @@ -1422,6 +1434,17 @@ hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>      case POWERPC_MMU_2_07:
>      case POWERPC_MMU_2_07a:
>          return ppc_hash64_get_phys_page_debug(cpu, addr);
> +    case POWERPC_MMU_3_00:
> +        if (ppc64_radix_guest(ppc_env_get_cpu(env))) {
> +            /* TODO - Unsupported */
> +        } else {
> +            if (ppc64_use_proc_tbl(ppc_env_get_cpu(env))) {
> +                /* TODO - Unsupported */
> +            } else {
> +                return ppc_hash64_get_phys_page_debug(cpu, addr);
> +            }
> +        }
> +        break;
>  #endif
>  
>      case POWERPC_MMU_32B:
> @@ -2919,3 +2942,27 @@ void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error **errp)
>  
>      env->external_patbe = (struct patb_entry *) patb;
>  }
> +
> +inline bool ppc64_use_proc_tbl(PowerPCCPU *cpu)

There's basically no point putting an inline on functions that are in
a .c rather than a .h (it will only be inlined for callers in this .o,
not elsewhere).  These are simple enough that I think they do belong
in the .h instead.

> +{
> +    return !!(cpu->env.spr[SPR_LPCR] & LPCR_UPRT);
> +}
> +
> +inline bool ppc64_radix_guest(PowerPCCPU *cpu)
> +{
> +    struct patb_entry *patbe = cpu->env.external_patbe;
> +
> +    return patbe && (patbe->patbe1 & PATBE1_GR);
> +}
> +
> +int ppc64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
> +                           int mmu_idx)

I think this name is too generic, since it's really only right for
POWER9 / MMU v3.

> +{
> +    if (ppc64_radix_guest(cpu)) { /* Guest uses radix */
> +        /* TODO - Unsupported */
> +        error_report("Guest Radix Support Unimplemented\n");
> +        abort();
> +    } else { /* Guest uses hash */
> +        return ppc_hash64_handle_mmu_fault(cpu, eaddr, rwx, mmu_idx);
> +    }
> +}
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index c771ba3..87297a7 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -8850,7 +8850,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
>                      (1ull << MSR_LE);
>      pcc->mmu_model = POWERPC_MMU_3_00;
>  #if defined(CONFIG_SOFTMMU)
> -    pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
> +    pcc->handle_mmu_fault = ppc64_handle_mmu_fault;
>      /* segment page size remain the same */
>      pcc->sps = &POWER7_POWER8_sps;
>  #endif

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 11/17] target/ppc/POWER9: Update to new pte format for POWER9 accesses
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 11/17] target/ppc/POWER9: Update to new pte format for POWER9 accesses Suraj Jitindar Singh
@ 2017-02-01  4:28   ` David Gibson
  2017-02-09  3:08     ` Suraj Jitindar Singh
  0 siblings, 1 reply; 53+ messages in thread
From: David Gibson @ 2017-02-01  4:28 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:17PM +1100, Suraj Jitindar Singh wrote:
> The page table entry format was updated for the POWER9 processor.
> 
> It was decided that kernels would used the old format irrespective
> with the translation occuring at the hypervisor level. Thus we convert
> between the old and new format when accessing the ptes. Since we need the
> whole pte to perform this conversion, we remove the old functions which
> accessed either the first or second doubleword and introduce a new
> functions which access the entire pte, returning the entry converted
> back to the old format (if required). Update call sites accordingly.
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> ---
>  hw/ppc/spapr_hcall.c    | 51 ++++++++++++++++++-----------------
>  target/ppc/mmu-hash64.c | 13 +++++----
>  target/ppc/mmu-hash64.h | 71 ++++++++++++++++++++++++++++++++++++-------------
>  3 files changed, 86 insertions(+), 49 deletions(-)
> 
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index 9a9bedf..9f0c20d 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -125,7 +125,8 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>          pte_index &= ~7ULL;
>          token = ppc_hash64_start_access(cpu, pte_index);
>          for (; index < 8; index++) {
> -            if (!(ppc_hash64_load_hpte0(cpu, token, index) & HPTE64_V_VALID)) {
> +            ppc_hash_pte64_t pte = ppc_hash64_load_hpte(cpu, token, index);
> +            if (!(pte.pte0 & HPTE64_V_VALID)) {
>                  break;
>              }
>          }
> @@ -134,8 +135,10 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>              return H_PTEG_FULL;
>          }
>      } else {
> +        ppc_hash_pte64_t pte;
>          token = ppc_hash64_start_access(cpu, pte_index);

IIRC the only reason for the clumsy start_access / stop_access stuff
was because we wanted to do the two loads separately (to avoid loading
word1 in cases we don't need it).  Since you're combining both loads
into a single helper, I think you can put the start_access /
stop_access into the same helper.

Or have I missed something.

> -        if (ppc_hash64_load_hpte0(cpu, token, 0) & HPTE64_V_VALID) {
> +        pte = ppc_hash64_load_hpte(cpu, token, 0);
> +        if (pte.pte0 & HPTE64_V_VALID) {
>              ppc_hash64_stop_access(cpu, token);
>              return H_PTEG_FULL;
>          }
> @@ -163,26 +166,25 @@ static RemoveResult remove_hpte(PowerPCCPU *cpu, target_ulong ptex,
>  {
>      CPUPPCState *env = &cpu->env;
>      uint64_t token;
> -    target_ulong v, r;
> +    ppc_hash_pte64_t pte;
>  
>      if (!valid_pte_index(env, ptex)) {
>          return REMOVE_PARM;
>      }
>  
>      token = ppc_hash64_start_access(cpu, ptex);
> -    v = ppc_hash64_load_hpte0(cpu, token, 0);
> -    r = ppc_hash64_load_hpte1(cpu, token, 0);
> +    pte = ppc_hash64_load_hpte(cpu, token, 0);
>      ppc_hash64_stop_access(cpu, token);
>  
> -    if ((v & HPTE64_V_VALID) == 0 ||
> -        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) ||
> -        ((flags & H_ANDCOND) && (v & avpn) != 0)) {
> +    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
> +        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn) ||
> +        ((flags & H_ANDCOND) && (pte.pte0 & avpn) != 0)) {
>          return REMOVE_NOT_FOUND;
>      }
> -    *vp = v;
> -    *rp = r;
> +    *vp = pte.pte0;
> +    *rp = pte.pte1;
>      ppc_hash64_store_hpte(cpu, ptex, HPTE64_V_HPTE_DIRTY, 0);
> -    ppc_hash64_tlb_flush_hpte(cpu, ptex, v, r);
> +    ppc_hash64_tlb_flush_hpte(cpu, ptex, pte.pte0, pte.pte1);
>      return REMOVE_SUCCESS;
>  }
>  
> @@ -293,35 +295,36 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>      target_ulong flags = args[0];
>      target_ulong pte_index = args[1];
>      target_ulong avpn = args[2];
> +    ppc_hash_pte64_t pte;
>      uint64_t token;
> -    target_ulong v, r;
>  
>      if (!valid_pte_index(env, pte_index)) {
>          return H_PARAMETER;
>      }
>  
>      token = ppc_hash64_start_access(cpu, pte_index);
> -    v = ppc_hash64_load_hpte0(cpu, token, 0);
> -    r = ppc_hash64_load_hpte1(cpu, token, 0);
> +    pte = ppc_hash64_load_hpte(cpu, token, 0);
>      ppc_hash64_stop_access(cpu, token);
>  
> -    if ((v & HPTE64_V_VALID) == 0 ||
> -        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {
> +    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
> +        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn)) {
>          return H_NOT_FOUND;
>      }
>  
> -    r &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
> -           HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
> -    r |= (flags << 55) & HPTE64_R_PP0;
> -    r |= (flags << 48) & HPTE64_R_KEY_HI;
> -    r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
> +    pte.pte1 &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
> +                  HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
> +    pte.pte1 |= (flags << 55) & HPTE64_R_PP0;
> +    pte.pte1 |= (flags << 48) & HPTE64_R_KEY_HI;
> +    pte.pte1 |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
>      ppc_hash64_store_hpte(cpu, pte_index,
> -                          (v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY, 0);
> -    ppc_hash64_tlb_flush_hpte(cpu, pte_index, v, r);
> +                          (pte.pte0 & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY,
> +                          0);
> +    ppc_hash64_tlb_flush_hpte(cpu, pte_index, pte.pte0, pte.pte1);
>      /* Flush the tlb */
>      check_tlb_flush(env, true);
>      /* Don't need a memory barrier, due to qemu's global lock */
> -    ppc_hash64_store_hpte(cpu, pte_index, v | HPTE64_V_HPTE_DIRTY, r);
> +    ppc_hash64_store_hpte(cpu, pte_index, pte.pte0 | HPTE64_V_HPTE_DIRTY,
> +                          pte.pte1);
>      return H_SUCCESS;
>  }
>  
> diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> index b476b3f..03607d5 100644
> --- a/target/ppc/mmu-hash64.c
> +++ b/target/ppc/mmu-hash64.c
> @@ -515,7 +515,6 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
>      CPUPPCState *env = &cpu->env;
>      int i;
>      uint64_t token;
> -    target_ulong pte0, pte1;
>      target_ulong pte_index;
>  
>      pte_index = (hash & env->htab_mask) * HPTES_PER_GROUP;
> @@ -524,12 +523,11 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
>          return -1;
>      }
>      for (i = 0; i < HPTES_PER_GROUP; i++) {
> -        pte0 = ppc_hash64_load_hpte0(cpu, token, i);
> -        pte1 = ppc_hash64_load_hpte1(cpu, token, i);
> +        ppc_hash_pte64_t entry = ppc_hash64_load_hpte(cpu, token, i);

Hm.  So the hypercalls using the access helpers which include format
conversion makes sense to me - the hypercalls are defined to use the
old format, even on POWER9 AIUI.

It doesn't really make sense to me here, in what is essentially the
physical implementation of the HPT lookup.  Shouldn't that be using
the new format natively?

Basically it seems odd that you store things in the new format in
memory, but convert to the old format on *all* accesses, not just the
hypercall ones which are defined that way.

>          /* This compares V, B, H (secondary) and the AVPN */
> -        if (HPTE64_V_COMPARE(pte0, ptem)) {
> -            *pshift = hpte_page_shift(sps, pte0, pte1);
> +        if (HPTE64_V_COMPARE(entry.pte0, ptem)) {
> +            *pshift = hpte_page_shift(sps, entry.pte0, entry.pte1);
>              /*
>               * If there is no match, ignore the PTE, it could simply
>               * be for a different segment size encoding and the
> @@ -543,8 +541,7 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
>              /* We don't do anything with pshift yet as qemu TLB only deals
>               * with 4K pages anyway
>               */
> -            pte->pte0 = pte0;
> -            pte->pte1 = pte1;
> +            *pte = entry;
>              ppc_hash64_stop_access(cpu, token);
>              return (pte_index + i) * HASH_PTE_SIZE_64;
>          }
> @@ -924,6 +921,8 @@ void ppc_hash64_store_hpte(PowerPCCPU *cpu,
>  {
>      CPUPPCState *env = &cpu->env;
>  
> +    ppc_hash64_hpte_old_to_new(env, &pte0, &pte1);
> +
>      if (env->external_htab == MMU_HASH64_KVM_MANAGED_HPT) {
>          kvmppc_hash64_write_pte(env, pte_index, pte0, pte1);
>          return;
> diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
> index ab5d347..73d7ce4 100644
> --- a/target/ppc/mmu-hash64.h
> +++ b/target/ppc/mmu-hash64.h
> @@ -60,6 +60,7 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
>  #define HASH_PTE_SIZE_64        16
>  #define HASH_PTEG_SIZE_64       (HASH_PTE_SIZE_64 * HPTES_PER_GROUP)
>  
> +#define HPTE64_V_3_00_COMMON    0x000fffffffffffffULL
>  #define HPTE64_V_SSIZE_SHIFT    62
>  #define HPTE64_V_AVPN_SHIFT     7
>  #define HPTE64_V_AVPN           0x3fffffffffffff80ULL
> @@ -69,9 +70,12 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
>  #define HPTE64_V_SECONDARY      0x0000000000000002ULL
>  #define HPTE64_V_VALID          0x0000000000000001ULL
>  
> +#define HPTE64_R_3_00_COMMON    0xf1ffffffffffffffULL
>  #define HPTE64_R_PP0            0x8000000000000000ULL
>  #define HPTE64_R_TS             0x4000000000000000ULL
>  #define HPTE64_R_KEY_HI         0x3000000000000000ULL
> +#define HPTE64_R_SSIZE_SHIFT    58
> +#define HPTE64_R_SSIZE_MASK     (3ULL << HPTE64_R_SSIZE_SHIFT)
>  #define HPTE64_R_RPN_SHIFT      12
>  #define HPTE64_R_RPN            0x0ffffffffffff000ULL
>  #define HPTE64_R_FLAGS          0x00000000000003ffULL
> @@ -91,6 +95,10 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
>  #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
>  #define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
>  
> +typedef struct {
> +    uint64_t pte0, pte1;
> +} ppc_hash_pte64_t;
> +
>  void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong value,
>                           Error **errp);
>  void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int shift,
> @@ -99,37 +107,64 @@ void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int shift,
>  uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, target_ulong pte_index);
>  void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t token);
>  
> -static inline target_ulong ppc_hash64_load_hpte0(PowerPCCPU *cpu,
> -                                                 uint64_t token, int index)
> +static inline void ppc_hash64_hpte_old_to_new(CPUPPCState *env,
> +                                              target_ulong *pte0,
> +                                              target_ulong *pte1)
>  {
> -    CPUPPCState *env = &cpu->env;
> -    uint64_t addr;
> +    switch (env->mmu_model) {
> +    case POWERPC_MMU_3_00:
> +        /*
> +         * v3.00 of the ISA moved the B field to the second doubleword and
> +         * shortened the abbreviated virtual address and abbreviated real page
> +         * number fields
> +         */
> +        *pte1 = (*pte1 & HPTE64_R_3_00_COMMON) |
> +                ((*pte0 >> HPTE64_V_SSIZE_SHIFT) << HPTE64_R_SSIZE_SHIFT);
> +        *pte0 = *pte0 & HPTE64_V_3_00_COMMON;
> +    default:
> +        ;
> +    }
> +}
>  
> -    addr = token + (index * HASH_PTE_SIZE_64);
> -    if (env->external_htab) {
> -        return  ldq_p((const void *)(uintptr_t)addr);
> -    } else {
> -        return ldq_phys(CPU(cpu)->as, addr);
> +static inline void ppc_hash64_hpte_new_to_old(CPUPPCState *env,
> +                                              target_ulong *pte0,
> +                                              target_ulong *pte1)
> +{
> +    switch (env->mmu_model) {
> +    case POWERPC_MMU_3_00:
> +        /*
> +         * v3.00 of the ISA moved the B field to the second doubleword and
> +         * shortened the abbreviated virtual address and abbreviated real page
> +         * number fields
> +         */
> +        *pte0 = (*pte0 & HPTE64_V_3_00_COMMON) | ((*pte1 & HPTE64_R_SSIZE_MASK)
> +                << (HPTE64_V_SSIZE_SHIFT - HPTE64_R_SSIZE_SHIFT));
> +        *pte1 = *pte1 & HPTE64_R_3_00_COMMON;
> +    default:
> +        ;
>      }
>  }
>  
> -static inline target_ulong ppc_hash64_load_hpte1(PowerPCCPU *cpu,
> -                                                 uint64_t token, int index)
> +static inline ppc_hash_pte64_t ppc_hash64_load_hpte(PowerPCCPU *cpu,
> +                                                    uint64_t token,
> +                                                    int index)
>  {
>      CPUPPCState *env = &cpu->env;
> +    ppc_hash_pte64_t pte;
>      uint64_t addr;
>  
> -    addr = token + (index * HASH_PTE_SIZE_64) + HASH_PTE_SIZE_64/2;
> +    addr = token + (index * HASH_PTE_SIZE_64);
>      if (env->external_htab) {
> -        return  ldq_p((const void *)(uintptr_t)addr);
> +        pte.pte0 = ldq_p((const void *)(uintptr_t)addr);
> +        pte.pte1 = ldq_p((const void *)(uintptr_t)addr + HASH_PTE_SIZE_64/2);
>      } else {
> -        return ldq_phys(CPU(cpu)->as, addr);
> +        pte.pte0 = ldq_phys(CPU(cpu)->as, addr);
> +        pte.pte1 = ldq_phys(CPU(cpu)->as, addr + HASH_PTE_SIZE_64/2);
>      }
> -}
>  
> -typedef struct {
> -    uint64_t pte0, pte1;
> -} ppc_hash_pte64_t;
> +    ppc_hash64_hpte_new_to_old(env, &pte.pte0, &pte.pte1);
> +    return pte;
> +}
>  
>  #endif /* CONFIG_USER_ONLY */
>  

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 12/17] target/ppc/POWER9: Add POWER9 pa-features definition
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 12/17] target/ppc/POWER9: Add POWER9 pa-features definition Suraj Jitindar Singh
@ 2017-02-01  4:29   ` David Gibson
  0 siblings, 0 replies; 53+ messages in thread
From: David Gibson @ 2017-02-01  4:29 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:18PM +1100, Suraj Jitindar Singh wrote:
> Add a pa-features definition which includes all of the new fields which
> have been added, note we don't claim support for any of these new features
> at this stage.
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

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

> ---
>  hw/ppc/spapr.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 45bd2de..35799da 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -357,6 +357,20 @@ static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset)
>          0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
>          0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
>          0x80, 0x00, 0x80, 0x00, 0x00, 0x00 };
> +    /* Currently we don't advertise any of the "new" ISAv3.00 functionality */
> +    uint8_t pa_features_300[] = { 64, 0,
> +        0xf6, 0x1f, 0xc7, 0xc0, 0x80, 0xf0, /*  0 -  5 */
> +        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /*  6 - 11 */
> +        0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 12 - 17 */
> +        0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 18 - 23 */
> +        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 24 - 29 */
> +        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 35 */
> +        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 36 - 41 */
> +        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 42 - 47 */
> +        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 48 - 53 */
> +        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 54 - 59 */
> +        0x00, 0x00, 0x00, 0x00           }; /* 60 - 63 */
> +
>      uint8_t *pa_features;
>      size_t pa_size;
>  
> @@ -371,6 +385,10 @@ static void spapr_populate_pa_features(CPUPPCState *env, void *fdt, int offset)
>          pa_features = pa_features_207;
>          pa_size = sizeof(pa_features_207);
>          break;
> +    case POWERPC_MMU_3_00:
> +        pa_features = pa_features_300;
> +        pa_size = sizeof(pa_features_300);
> +        break;
>      default:
>          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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 13/17] target/ppc/POWER9: Add cpu_has_work function for POWER9
  2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 13/17] target/ppc/POWER9: Add cpu_has_work function for POWER9 Suraj Jitindar Singh
@ 2017-02-01  4:34   ` David Gibson
  0 siblings, 0 replies; 53+ messages in thread
From: David Gibson @ 2017-02-01  4:34 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Jan 13, 2017 at 05:28:19PM +1100, Suraj Jitindar Singh wrote:
> The cpu has work function is used to mask interrupts used to determine
> if there is work for the cpu based on the LPCR. Add a function to do this
> for POWER9 and add it to the POWER9 cpu definition. This is similar to that
> for POWER8 except using the LPCR bits as defined for POWER9.
> 
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>

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

> ---
>  target/ppc/translate_init.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
> 
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index 87297a7..9db004d 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -8797,10 +8797,54 @@ static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr)
>      return false;
>  }
>  
> +static bool cpu_has_work_POWER9(CPUState *cs)
> +{
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);
> +    CPUPPCState *env = &cpu->env;
> +
> +    if (cs->halted) {
> +        if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
> +            return false;
> +        }
> +        /* External Exception */
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
> +            (env->spr[SPR_LPCR] & LPCR_EEE)) {
> +            return true;
> +        }
> +        /* Decrementer Exception */
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
> +            (env->spr[SPR_LPCR] & LPCR_DEE)) {
> +            return true;
> +        }
> +        /* Machine Check or Hypervisor Maintenance Exception */
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
> +            1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
> +            return true;
> +        }
> +        /* Privileged Doorbell Exception */
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
> +            (env->spr[SPR_LPCR] & LPCR_PDEE)) {
> +            return true;
> +        }
> +        /* Hypervisor Doorbell Exception */
> +        if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
> +            (env->spr[SPR_LPCR] & LPCR_HDEE)) {
> +            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(POWER9)(ObjectClass *oc, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(oc);
>      PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
> +    CPUClass *cc = CPU_CLASS(oc);
>  
>      dc->fw_name = "PowerPC,POWER9";
>      dc->desc = "POWER9";
> @@ -8811,6 +8855,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
>                           PCR_COMPAT_2_05;
>      pcc->init_proc = init_proc_POWER9;
>      pcc->check_pow = check_pow_nocheck;
> +    cc->has_work = cpu_has_work_POWER9;
>      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 |

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 07/17] target/ppc/POWER9: Add partition table pointer to sPAPRMachineState
  2017-02-01  4:04   ` David Gibson
@ 2017-02-09  2:57     ` Suraj Jitindar Singh
  2017-02-10  0:11       ` David Gibson
  0 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-02-09  2:57 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, agraf, qemu-devel

On Wed, 2017-02-01 at 15:04 +1100, David Gibson wrote:
> On Fri, Jan 13, 2017 at 05:28:13PM +1100, Suraj Jitindar Singh wrote:
> > 
> > POWER9 uses a partition table to store information relating to how
> > address translation is performed on a per partition basis.
> > 
> > Add a data area for this to the sPAPRMachineState struct and
> > (re)allocate
> > it on machine reset.
> > 
> > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> Hm.  I'm having trouble understanding this one.
> 
> IIUC, for the "pseries" machine type this partition table entry is
> essentially a dummy one, since there's actually only one partition.
> For KVM the machine would be represented by one of many partition
> table entries on the real host - so the entry here isn't really
> relevant.  For TCG, I'm not sure what would be looking at it.  We
> haven't implemented the partition->host level translation in TCG
> anyway, and in any case pseries (rather than powernv) should be
> bypassing that - in which case I'd expect it to bypass looking at the
> dummy partition table entry as well.
As discussed elsewhere it seems having a whole partition table entry is
unnecessary. This will be replaced by a single process table pointer to
be accessed via the vhyp.

In fact this won't be necessary for the legacy case at all and so will
drop this patch from the series in favour of moving it into the radix
enablement series.
> 
> > 
> > ---
> >  hw/ppc/spapr.c         | 38 ++++++++++++++++++++++++++++++++------
> >  include/hw/ppc/spapr.h |  1 +
> >  target/ppc/mmu.h       | 13 +++++++++++++
> >  3 files changed, 46 insertions(+), 6 deletions(-)
> >  create mode 100644 target/ppc/mmu.h
> > 
> > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > index 208ef7b..45bd2de 100644
> > --- a/hw/ppc/spapr.c
> > +++ b/hw/ppc/spapr.c
> > @@ -41,6 +41,7 @@
> >  #include "migration/migration.h"
> >  #include "mmu-hash64.h"
> >  #include "qom/cpu.h"
> > +#include "mmu.h"
> >  
> >  #include "hw/boards.h"
> >  #include "hw/ppc/ppc.h"
> > @@ -1115,6 +1116,26 @@ static void
> > spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
> >      }
> >  }
> >  
> > +static void spapr_reallocate_patb(sPAPRMachineState *spapr, Error
> > **errp)
> > +{
> > +    g_free(spapr->patb);
> > +    spapr->patb = NULL;
> > +
> > +    if (!kvm_enabled()) {
> > +        /* We need to allocate a partition table entry */
> > +        size_t size = sizeof(struct patb_entry);
> > +
> > +        spapr->patb = qemu_memalign(size, size);
> > +        if (!spapr->patb) {
> > +            error_setg_errno(errp, errno, "Could not allocate
> > memory for "
> > +                                          "partition table
> > entry");
> > +            return;
> > +        }
> > +
> > +        memset(spapr->patb, 0, size);
> > +    }
> > +}
> > +
> >  static void find_unknown_sysbus_device(SysBusDevice *sbdev, void
> > *opaque)
> >  {
> >      bool matched = false;
> > @@ -1134,7 +1155,7 @@ static void ppc_spapr_reset(void)
> >  {
> >      MachineState *machine = MACHINE(qdev_get_machine());
> >      sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
> > -    PowerPCCPU *first_ppc_cpu;
> > +    PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
> >      uint32_t rtas_limit;
> >      hwaddr rtas_addr, fdt_addr;
> >      void *fdt;
> > @@ -1143,10 +1164,16 @@ static void ppc_spapr_reset(void)
> >      /* Check for unknown sysbus devices */
> >      foreach_dynamic_sysbus_device(find_unknown_sysbus_device,
> > NULL);
> >  
> > -    /* Allocate and/or reset the hash page table */
> > -    spapr_reallocate_hpt(spapr,
> > -                         spapr_hpt_shift_for_ramsize(machine-
> > >maxram_size),
> > -                         &error_fatal);
> > +    switch (first_ppc_cpu->env.mmu_model) {
> > +    case POWERPC_MMU_3_00:
> > +        /* Allocate the partition table */
> > +        spapr_reallocate_patb(spapr, &error_fatal);
> > +    default:
> > +        /* Allocate and/or reset the hash page table */
> > +        spapr_reallocate_hpt(spapr,
> > +                             spapr_hpt_shift_for_ramsize(machine-
> > >maxram_size),
> > +                             &error_fatal);
> > +    }
> >  
> >      /* Update the RMA size if necessary */
> >      if (spapr->vrma_adjust) {
> > @@ -1193,7 +1220,6 @@ static void ppc_spapr_reset(void)
> >      g_free(fdt);
> >  
> >      /* Set up the entry state */
> > -    first_ppc_cpu = POWERPC_CPU(first_cpu);
> >      first_ppc_cpu->env.gpr[3] = fdt_addr;
> >      first_ppc_cpu->env.gpr[5] = 0;
> >      first_cpu->halted = 0;
> > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> > index bd5bcf7..b654773 100644
> > --- a/include/hw/ppc/spapr.h
> > +++ b/include/hw/ppc/spapr.h
> > @@ -63,6 +63,7 @@ struct sPAPRMachineState {
> >  
> >      void *htab;
> >      uint32_t htab_shift;
> > +    void *patb;
> >      hwaddr rma_size;
> >      int vrma_adjust;
> >      ssize_t rtas_size;
> > diff --git a/target/ppc/mmu.h b/target/ppc/mmu.h
> > new file mode 100644
> > index 0000000..67b9707
> > --- /dev/null
> > +++ b/target/ppc/mmu.h
> > @@ -0,0 +1,13 @@
> > +#ifndef MMU_H
> > +#define MMU_H
> > +
> > +#ifndef CONFIG_USER_ONLY
> > +
> > +/* Partition Table Entry */
> > +struct patb_entry {
> > +    uint64_t patbe0, patbe1;
> > +};
> > +
> > +#endif /* CONFIG_USER_ONLY */
> > +
> > +#endif /* MMU_H */

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

* Re: [Qemu-devel] [RFC PATCH 08/17] target/ppc/POWER9: Add external partition table pointer to cpu state
  2017-02-01  4:09   ` David Gibson
@ 2017-02-09  2:58     ` Suraj Jitindar Singh
  2017-02-10  0:11       ` David Gibson
  0 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-02-09  2:58 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, agraf, qemu-devel

On Wed, 2017-02-01 at 15:09 +1100, David Gibson wrote:
> On Fri, Jan 13, 2017 at 05:28:14PM +1100, Suraj Jitindar Singh wrote:
> > 
> > Similarly to how we have an external hpt pointer in the cpu state,
> > add
> > an external partition table pointer and update it to point to the
> > partition table entry in the machine state struct on cpu reset.
> > 
> > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> As with the previous patch, I don't quite follow what's going on
> here.  It seems to me that if the external HPT is set, that should
> make the softmmu logic bypass *both* an HPT set by SDR1 (<= POWER8)
> or
> an HPT set by the partition table (POWER9).  So I'm not sure why we
> need the dummy partition table entry.
> 
> To look at it another way, the external HPT is special because it
> lies
> outside the guest's address space, but we need its state because the
> guest can manipulate it via hypercall.  For the partition table
> entry,
> even if we're minimally modelling the HV parts of the POWER9 MMU,
> isn't the partition table entry just fixed at startup?
Similarly this patch will be dropped from the series.
> 
> > 
> > ---
> >  hw/ppc/spapr_cpu_core.c | 12 ++++++++++--
> >  target/ppc/cpu.h        |  3 +++
> >  target/ppc/mmu.h        |  6 ++++++
> >  target/ppc/mmu_helper.c | 12 ++++++++++++
> >  4 files changed, 31 insertions(+), 2 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
> > index 8cc7058..72a7f90 100644
> > --- a/hw/ppc/spapr_cpu_core.c
> > +++ b/hw/ppc/spapr_cpu_core.c
> > @@ -17,6 +17,7 @@
> >  #include "hw/ppc/ppc.h"
> >  #include "target/ppc/mmu-hash64.h"
> >  #include "sysemu/numa.h"
> > +#include "mmu.h"
> >  
> >  static void spapr_cpu_reset(void *opaque)
> >  {
> > @@ -34,8 +35,15 @@ static void spapr_cpu_reset(void *opaque)
> >  
> >      env->spr[SPR_HIOR] = 0;
> >  
> > -    ppc_hash64_set_external_hpt(cpu, spapr->htab, spapr-
> > >htab_shift,
> > -                                &error_fatal);
> > +    switch (env->mmu_model) {
> > +    case POWERPC_MMU_3_00:
> > +        ppc64_set_external_patb(cpu, spapr->patb, &error_fatal);
> > +    default:
> > +        /* We assume legacy until told otherwise, thus set HPT
> > irrespective */
> > +        ppc_hash64_set_external_hpt(cpu, spapr->htab, spapr-
> > >htab_shift,
> > +                                    &error_fatal);
> > +        break;
> > +    }
> >  }
> >  
> >  static void spapr_cpu_destroy(PowerPCCPU *cpu)
> > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> > index 0ab49b3..e8b7c06 100644
> > --- a/target/ppc/cpu.h
> > +++ b/target/ppc/cpu.h
> > @@ -77,6 +77,7 @@
> >  #include "exec/cpu-defs.h"
> >  #include "cpu-qom.h"
> >  #include "fpu/softfloat.h"
> > +#include "mmu.h"
> >  
> >  #if defined (TARGET_PPC64)
> >  #define PPC_ELF_MACHINE     EM_PPC64
> > @@ -1009,6 +1010,8 @@ struct CPUPPCState {
> >      target_ulong sr[32];
> >      /* externally stored hash table */
> >      uint8_t *external_htab;
> > +    /* externally stored partition table entry */
> > +    struct patb_entry *external_patbe;
> >      /* BATs */
> >      uint32_t nb_BATs;
> >      target_ulong DBAT[2][8];
> > diff --git a/target/ppc/mmu.h b/target/ppc/mmu.h
> > index 67b9707..c7967c3 100644
> > --- a/target/ppc/mmu.h
> > +++ b/target/ppc/mmu.h
> > @@ -8,6 +8,12 @@ struct patb_entry {
> >      uint64_t patbe0, patbe1;
> >  };
> >  
> > +#ifdef TARGET_PPC64
> > +
> > +void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error
> > **errp);
> > +
> > +#endif /* TARGET_PPC64 */
> > +
> >  #endif /* CONFIG_USER_ONLY */
> >  
> >  #endif /* MMU_H */
> > diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> > index 2ab4562..bc6c117 100644
> > --- a/target/ppc/mmu_helper.c
> > +++ b/target/ppc/mmu_helper.c
> > @@ -28,6 +28,7 @@
> >  #include "exec/cpu_ldst.h"
> >  #include "exec/log.h"
> >  #include "helper_regs.h"
> > +#include "mmu.h"
> >  
> >  //#define DEBUG_MMU
> >  //#define DEBUG_BATS
> > @@ -2907,3 +2908,14 @@ void tlb_fill(CPUState *cs, target_ulong
> > addr, MMUAccessType access_type,
> >                                 retaddr);
> >      }
> >  }
> > +
> > +/*****************************************************************
> > *************/
> > +
> > +/* ISA v3.00 (POWER9) Generic MMU Helpers */
> > +
> > +void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error
> > **errp)
> > +{
> > +    CPUPPCState *env = &cpu->env;
> > +
> > +    env->external_patbe = (struct patb_entry *) patb;
> > +}

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

* Re: [Qemu-devel] [RFC PATCH 09/17] target/ppc/POWER9: Remove SDR1 register
  2017-02-01  4:16   ` David Gibson
@ 2017-02-09  3:00     ` Suraj Jitindar Singh
  0 siblings, 0 replies; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-02-09  3:00 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, agraf, qemu-devel

On Wed, 2017-02-01 at 15:16 +1100, David Gibson wrote:
> On Fri, Jan 13, 2017 at 05:28:15PM +1100, Suraj Jitindar Singh wrote:
> > 
> > The SDR1 registers was used to store the location of the hash page
> > table.
> > 
> > This register no longer exists on POWER9 processors, so don't
> > create it.
> > 
> > We now store the hash page table location in the process table
> > entry.
> > 
> > We now check if the SDR1 register exists before printing its value
> > when
> > displaying register debug info.
> > 
> > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> > ---
> >  target/ppc/kvm.c            | 10 +++++++++-
> >  target/ppc/mmu-hash64.c     | 15 ++++++++++++++-
> >  target/ppc/translate.c      |  6 ++++--
> >  target/ppc/translate_init.c | 16 +++++++++++++---
> >  4 files changed, 40 insertions(+), 7 deletions(-)
> > 
> > diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> > index 9c4834c..6016930 100644
> > --- a/target/ppc/kvm.c
> > +++ b/target/ppc/kvm.c
> > @@ -930,7 +930,15 @@ int kvmppc_put_books_sregs(PowerPCCPU *cpu)
> >  
> >      sregs.pvr = env->spr[SPR_PVR];
> >  
> > -    sregs.u.s.sdr1 = env->spr[SPR_SDR1];
> > +    switch (env->mmu_model) {
> > +    case POWERPC_MMU_3_00:
> > +        if (env->external_patbe)
> > +            sregs.u.s.sdr1 = env->external_patbe->patbe0;
> I take it from this that KVM is expecting the address of the guest
> HPT
> in the SDR1 slot of sregs, even on POWER9?  Rather than using a new
> ONE_REG entry for the POWER9 data.
> 
> Note that this slot was already a hack for PR KVM - we are putting a
> userspace address in there, which is clearly not a real SDR1 value.
> For HV KVM, I think this value is ignored entirely, since in that
> case
> KVM allocates / controls the guest HPT, not qemu.
We don't support KVM_PR or PNV machine type for POWER9 yet. I will
update this patch to remove the idea of a SDR1 which will be fine for
pseries machines. Support for a partition table register will need to
be added to enable PNV for power9 emulation, but that will come later.
> 
> > 
> > +        break;
> > +    default:
> > +        sregs.u.s.sdr1 = env->spr[SPR_SDR1];
> > +        break;
> > +    }
> So.. maybe we should take this opportunity to clean this path up and
> special case all "external HPT" cases to pass the relevant value to
> PR
> KVM without abusing the env->spr[SPR_SDR1] field.
> 
> > 
> >  
> >      /* Sync SLB */
> >  #ifdef TARGET_PPC64
> > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> > index fe7da18..b9d4f4e 100644
> > --- a/target/ppc/mmu-hash64.c
> > +++ b/target/ppc/mmu-hash64.c
> > @@ -291,7 +291,20 @@ void ppc_hash64_set_sdr1(PowerPCCPU *cpu,
> > target_ulong value,
> >      CPUPPCState *env = &cpu->env;
> >      target_ulong htabsize = value & SDR_64_HTABSIZE;
> >  
> > -    env->spr[SPR_SDR1] = value;
> > +    switch (env->mmu_model) {
> > +    case POWERPC_MMU_3_00:
> > +        /*
> > +         * Technically P9 doesn't have a SDR1, the hash table
> > address should be
> > +         * stored in the partition table entry instead.
> > +         */
> > +        if (env->external_patbe)
> > +            env->external_patbe->patbe0 = value;
> This definitely doesn't belong in a function called ..._set_sdr1().
> Either rename this function or (probably better), set the partition
> table entry from a new function and make the decision in the caller.
> 
> 
> > 
> > +        break;
> > +    default:
> > +        env->spr[SPR_SDR1] = value;
> > +        break;
> > +    }
> > +
> >      if (htabsize > 28) {
> >          error_setg(errp,
> >                     "Invalid HTABSIZE 0x" TARGET_FMT_lx" stored in
> > SDR1",
> > diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> > index 1212180..521aed3 100644
> > --- a/target/ppc/translate.c
> > +++ b/target/ppc/translate.c
> > @@ -6922,9 +6922,11 @@ void ppc_cpu_dump_state(CPUState *cs, FILE
> > *f, fprintf_function cpu_fprintf,
> >      case POWERPC_MMU_2_06a:
> >      case POWERPC_MMU_2_07:
> >      case POWERPC_MMU_2_07a:
> > +    case POWERPC_MMU_3_00:
> >  #endif
> > -        cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "   DAR "
> > TARGET_FMT_lx
> > -                       "  DSISR " TARGET_FMT_lx "\n", env-
> > >spr[SPR_SDR1],
> > +        if (env->spr_cb[SPR_SDR1].name)
> > +            cpu_fprintf(f, " SDR1 " TARGET_FMT_lx " ", env-
> > >spr[SPR_SDR1]);
> > +        cpu_fprintf(f, "  DAR " TARGET_FMT_lx "  DSISR "
> > TARGET_FMT_lx "\n",
> >                      env->spr[SPR_DAR], env->spr[SPR_DSISR]);
> >          break;
> >      case POWERPC_MMU_BOOKE206:
> > diff --git a/target/ppc/translate_init.c
> > b/target/ppc/translate_init.c
> > index a1994d3..c771ba3 100644
> > --- a/target/ppc/translate_init.c
> > +++ b/target/ppc/translate_init.c
> > @@ -32,6 +32,7 @@
> >  #include "qapi/visitor.h"
> >  #include "hw/qdev-properties.h"
> >  #include "hw/ppc/ppc.h"
> > +#include "mmu.h"
> >  
> >  //#define PPC_DUMP_CPU
> >  //#define PPC_DEBUG_SPR
> > @@ -722,8 +723,8 @@ static void gen_spr_generic (CPUPPCState *env)
> >                   0x00000000);
> >  }
> >  
> > -/* SPR common to all non-embedded PowerPC, including 601 */
> > -static void gen_spr_ne_601 (CPUPPCState *env)
> > +/* SPR common to all non-embedded PowerPC, including POWER9 */
> > +static void gen_spr_ne_power9 (CPUPPCState *env)
> >  {
> >      /* Exception processing */
> >      spr_register_kvm(env, SPR_DSISR, "DSISR",
> > @@ -739,6 +740,12 @@ static void gen_spr_ne_601 (CPUPPCState *env)
> >                   SPR_NOACCESS, SPR_NOACCESS,
> >                   &spr_read_decr, &spr_write_decr,
> >                   0x00000000);
> > +}
> > +
> > +/* SPR common to all non-embedded PowerPC, including 601 */
> > +static void gen_spr_ne_601 (CPUPPCState *env)
> > +{
> > +    gen_spr_ne_power9(env);
> >      /* Memory management */
> >      spr_register(env, SPR_SDR1, "SDR1",
> >                   SPR_NOACCESS, SPR_NOACCESS,
> > @@ -8222,7 +8229,6 @@ static void gen_spr_power8_rpr(CPUPPCState
> > *env)
> >  
> >  static void init_proc_book3s_64(CPUPPCState *env, int version)
> >  {
> > -    gen_spr_ne_601(env);
> >      gen_tbl(env);
> >      gen_spr_book3s_altivec(env);
> >      gen_spr_book3s_pmu_sup(env);
> > @@ -8280,6 +8286,10 @@ static void init_proc_book3s_64(CPUPPCState
> > *env, int version)
> >          gen_spr_power8_book4(env);
> >          gen_spr_power8_rpr(env);
> >      }
> > +    if (version >= BOOK3S_CPU_POWER9)
> > +        gen_spr_ne_power9(env);
> > +    else
> > +        gen_spr_ne_601(env);
> >      if (version < BOOK3S_CPU_POWER8) {
> >          gen_spr_book3s_dbg(env);
> >      } else {

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

* Re: [Qemu-devel] [RFC PATCH 10/17] target/ppc/POWER9: Add POWER9 mmu fault handler
  2017-02-01  4:23   ` David Gibson
@ 2017-02-09  3:04     ` Suraj Jitindar Singh
  2017-02-10  0:16       ` David Gibson
  0 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-02-09  3:04 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, agraf, qemu-devel

On Wed, 2017-02-01 at 15:23 +1100, David Gibson wrote:
> On Fri, Jan 13, 2017 at 05:28:16PM +1100, Suraj Jitindar Singh wrote:
> > 
> > Add a new mmu fault handler for the POWER9 cpu and add it as the
> > handler
> > for the POWER9 cpu definition.
> > 
> > This handler checks if the guest is radix or hash based on the
> > value in the
> > partition table entry and calls the correct fault handler
> > accordingly.
> > 
> > The hash fault handling code has also been updated to check if the
> > partition is using segment tables.
> > 
> > Currently only legacy hash (no segment tables) is supported.
> > 
> > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> > ---
> >  target/ppc/mmu-hash64.c     |  8 ++++++++
> >  target/ppc/mmu.h            |  8 ++++++++
> >  target/ppc/mmu_helper.c     | 47
> > +++++++++++++++++++++++++++++++++++++++++++++
> >  target/ppc/translate_init.c |  2 +-
> >  4 files changed, 64 insertions(+), 1 deletion(-)
> > 
> > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> > index b9d4f4e..b476b3f 100644
> > --- a/target/ppc/mmu-hash64.c
> > +++ b/target/ppc/mmu-hash64.c
> > @@ -73,6 +73,14 @@ static ppc_slb_t *slb_lookup(PowerPCCPU *cpu,
> > target_ulong eaddr)
> >          }
> >      }
> >  
> > +    /* Check if in-memory segment tables are in use */
> > +    if (ppc64_use_proc_tbl(cpu)) {
> > +        /* TODO - Unsupported */
> > +        qemu_log_mask(LOG_UNIMP, "%s: unimplemented - segment
> > table support\n",
> > +                      __func__);
> > +        /* Not much we can do here, caller will generate a segment
> > interrupt */
> > +    }
> I think this logic would be better in the fault handler.  For the
> fault path in the segment table case, I don't think we want to even
> model the SLB (in hardware the SLB is an important optimization, but
> I
> don't think the software SLB will be notably better than just looking
> up the seg table directly).  I think the other users of slb_lookup()
> are in contexts that only make sense in the context of a software
> managed SLB anyway.
> 
The mmu looks up the slb before it looks in the segment tables, so we
still need to model and search the slb before we search segment tables.
We could call slb lookup and if that fails we can then call a
search_seg_tbl() or something from the fault handler.
> > 
> >      return NULL;
> >  }
> >  
> > diff --git a/target/ppc/mmu.h b/target/ppc/mmu.h
> > index c7967c3..e07b128 100644
> > --- a/target/ppc/mmu.h
> > +++ b/target/ppc/mmu.h
> > @@ -3,6 +3,10 @@
> >  
> >  #ifndef CONFIG_USER_ONLY
> >  
> > +/* Common Partition Table Entry Fields */
> > +#define PATBE0_HR                0x8000000000000000
> > +#define PATBE1_GR                0x8000000000000000
> > +
> >  /* Partition Table Entry */
> >  struct patb_entry {
> >      uint64_t patbe0, patbe1;
> > @@ -11,6 +15,10 @@ struct patb_entry {
> >  #ifdef TARGET_PPC64
> >  
> >  void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error
> > **errp);
> > +bool ppc64_use_proc_tbl(PowerPCCPU *cpu);
> > +bool ppc64_radix_guest(PowerPCCPU *cpu);
> > +int ppc64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
> > +                           int mmu_idx);
> >  
> >  #endif /* TARGET_PPC64 */
> >  
> > diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> > index bc6c117..612f407 100644
> > --- a/target/ppc/mmu_helper.c
> > +++ b/target/ppc/mmu_helper.c
> > @@ -28,6 +28,7 @@
> >  #include "exec/cpu_ldst.h"
> >  #include "exec/log.h"
> >  #include "helper_regs.h"
> > +#include "qemu/error-report.h"
> >  #include "mmu.h"
> >  
> >  //#define DEBUG_MMU
> > @@ -1281,6 +1282,17 @@ void dump_mmu(FILE *f, fprintf_function
> > cpu_fprintf, CPUPPCState *env)
> >      case POWERPC_MMU_2_07a:
> >          dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
> >          break;
> > +    case POWERPC_MMU_3_00:
> > +        if (ppc64_radix_guest(ppc_env_get_cpu(env))) {
> > +            /* TODO - Unsupported */
> > +        } else {
> > +            if (ppc64_use_proc_tbl(ppc_env_get_cpu(env))) {
> > +                /* TODO - Unsupported */
> > +            } else {
> > +                dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
> > +                break;
> > +            }
> > +        }
> >  #endif
> >      default:
> >          qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
> > @@ -1422,6 +1434,17 @@ hwaddr ppc_cpu_get_phys_page_debug(CPUState
> > *cs, vaddr addr)
> >      case POWERPC_MMU_2_07:
> >      case POWERPC_MMU_2_07a:
> >          return ppc_hash64_get_phys_page_debug(cpu, addr);
> > +    case POWERPC_MMU_3_00:
> > +        if (ppc64_radix_guest(ppc_env_get_cpu(env))) {
> > +            /* TODO - Unsupported */
> > +        } else {
> > +            if (ppc64_use_proc_tbl(ppc_env_get_cpu(env))) {
> > +                /* TODO - Unsupported */
> > +            } else {
> > +                return ppc_hash64_get_phys_page_debug(cpu, addr);
> > +            }
> > +        }
> > +        break;
> >  #endif
> >  
> >      case POWERPC_MMU_32B:
> > @@ -2919,3 +2942,27 @@ void ppc64_set_external_patb(PowerPCCPU
> > *cpu, void *patb, Error **errp)
> >  
> >      env->external_patbe = (struct patb_entry *) patb;
> >  }
> > +
> > +inline bool ppc64_use_proc_tbl(PowerPCCPU *cpu)
> There's basically no point putting an inline on functions that are in
> a .c rather than a .h (it will only be inlined for callers in this
> .o,
> not elsewhere).  These are simple enough that I think they do belong
> in the .h instead.
I'll move these into the .h
> 
> > 
> > +{
> > +    return !!(cpu->env.spr[SPR_LPCR] & LPCR_UPRT);
> > +}
> > +
> > +inline bool ppc64_radix_guest(PowerPCCPU *cpu)
> > +{
> > +    struct patb_entry *patbe = cpu->env.external_patbe;
> > +
> > +    return patbe && (patbe->patbe1 & PATBE1_GR);
> > +}
> > +
> > +int ppc64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
> > +                           int mmu_idx)
> I think this name is too generic, since it's really only right for
> POWER9 / MMU v3.
Ok, how about ppc64_v3_handle_mmu_fault?
> 
> > 
> > +{
> > +    if (ppc64_radix_guest(cpu)) { /* Guest uses radix */
> > +        /* TODO - Unsupported */
> > +        error_report("Guest Radix Support Unimplemented\n");
> > +        abort();
> > +    } else { /* Guest uses hash */
> > +        return ppc_hash64_handle_mmu_fault(cpu, eaddr, rwx,
> > mmu_idx);
> > +    }
> > +}
> > diff --git a/target/ppc/translate_init.c
> > b/target/ppc/translate_init.c
> > index c771ba3..87297a7 100644
> > --- a/target/ppc/translate_init.c
> > +++ b/target/ppc/translate_init.c
> > @@ -8850,7 +8850,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void
> > *data)
> >                      (1ull << MSR_LE);
> >      pcc->mmu_model = POWERPC_MMU_3_00;
> >  #if defined(CONFIG_SOFTMMU)
> > -    pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
> > +    pcc->handle_mmu_fault = ppc64_handle_mmu_fault;
> >      /* segment page size remain the same */
> >      pcc->sps = &POWER7_POWER8_sps;
> >  #endif

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

* Re: [Qemu-devel] [RFC PATCH 11/17] target/ppc/POWER9: Update to new pte format for POWER9 accesses
  2017-02-01  4:28   ` David Gibson
@ 2017-02-09  3:08     ` Suraj Jitindar Singh
  2017-02-09 23:47       ` Suraj Jitindar Singh
  0 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-02-09  3:08 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, agraf, qemu-devel

On Wed, 2017-02-01 at 15:28 +1100, David Gibson wrote:
> On Fri, Jan 13, 2017 at 05:28:17PM +1100, Suraj Jitindar Singh wrote:
> > 
> > The page table entry format was updated for the POWER9 processor.
> > 
> > It was decided that kernels would used the old format irrespective
> > with the translation occuring at the hypervisor level. Thus we
> > convert
> > between the old and new format when accessing the ptes. Since we
> > need the
> > whole pte to perform this conversion, we remove the old functions
> > which
> > accessed either the first or second doubleword and introduce a new
> > functions which access the entire pte, returning the entry
> > converted
> > back to the old format (if required). Update call sites
> > accordingly.
> > 
> > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> > ---
> >  hw/ppc/spapr_hcall.c    | 51 ++++++++++++++++++-----------------
> >  target/ppc/mmu-hash64.c | 13 +++++----
> >  target/ppc/mmu-hash64.h | 71 ++++++++++++++++++++++++++++++++++++-
> > ------------
> >  3 files changed, 86 insertions(+), 49 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> > index 9a9bedf..9f0c20d 100644
> > --- a/hw/ppc/spapr_hcall.c
> > +++ b/hw/ppc/spapr_hcall.c
> > @@ -125,7 +125,8 @@ static target_ulong h_enter(PowerPCCPU *cpu,
> > sPAPRMachineState *spapr,
> >          pte_index &= ~7ULL;
> >          token = ppc_hash64_start_access(cpu, pte_index);
> >          for (; index < 8; index++) {
> > -            if (!(ppc_hash64_load_hpte0(cpu, token, index) &
> > HPTE64_V_VALID)) {
> > +            ppc_hash_pte64_t pte = ppc_hash64_load_hpte(cpu,
> > token, index);
> > +            if (!(pte.pte0 & HPTE64_V_VALID)) {
> >                  break;
> >              }
> >          }
> > @@ -134,8 +135,10 @@ static target_ulong h_enter(PowerPCCPU *cpu,
> > sPAPRMachineState *spapr,
> >              return H_PTEG_FULL;
> >          }
> >      } else {
> > +        ppc_hash_pte64_t pte;
> >          token = ppc_hash64_start_access(cpu, pte_index);
> IIRC the only reason for the clumsy start_access / stop_access stuff
> was because we wanted to do the two loads separately (to avoid
> loading
> word1 in cases we don't need it).  Since you're combining both loads
> into a single helper, I think you can put the start_access /
> stop_access into the same helper.
> 
> Or have I missed something.
> 
Yeah these functions can probably be merged together...
> > 
> > -        if (ppc_hash64_load_hpte0(cpu, token, 0) & HPTE64_V_VALID)
> > {
> > +        pte = ppc_hash64_load_hpte(cpu, token, 0);
> > +        if (pte.pte0 & HPTE64_V_VALID) {
> >              ppc_hash64_stop_access(cpu, token);
> >              return H_PTEG_FULL;
> >          }
> > @@ -163,26 +166,25 @@ static RemoveResult remove_hpte(PowerPCCPU
> > *cpu, target_ulong ptex,
> >  {
> >      CPUPPCState *env = &cpu->env;
> >      uint64_t token;
> > -    target_ulong v, r;
> > +    ppc_hash_pte64_t pte;
> >  
> >      if (!valid_pte_index(env, ptex)) {
> >          return REMOVE_PARM;
> >      }
> >  
> >      token = ppc_hash64_start_access(cpu, ptex);
> > -    v = ppc_hash64_load_hpte0(cpu, token, 0);
> > -    r = ppc_hash64_load_hpte1(cpu, token, 0);
> > +    pte = ppc_hash64_load_hpte(cpu, token, 0);
> >      ppc_hash64_stop_access(cpu, token);
> >  
> > -    if ((v & HPTE64_V_VALID) == 0 ||
> > -        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) ||
> > -        ((flags & H_ANDCOND) && (v & avpn) != 0)) {
> > +    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
> > +        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn) ||
> > +        ((flags & H_ANDCOND) && (pte.pte0 & avpn) != 0)) {
> >          return REMOVE_NOT_FOUND;
> >      }
> > -    *vp = v;
> > -    *rp = r;
> > +    *vp = pte.pte0;
> > +    *rp = pte.pte1;
> >      ppc_hash64_store_hpte(cpu, ptex, HPTE64_V_HPTE_DIRTY, 0);
> > -    ppc_hash64_tlb_flush_hpte(cpu, ptex, v, r);
> > +    ppc_hash64_tlb_flush_hpte(cpu, ptex, pte.pte0, pte.pte1);
> >      return REMOVE_SUCCESS;
> >  }
> >  
> > @@ -293,35 +295,36 @@ static target_ulong h_protect(PowerPCCPU
> > *cpu, sPAPRMachineState *spapr,
> >      target_ulong flags = args[0];
> >      target_ulong pte_index = args[1];
> >      target_ulong avpn = args[2];
> > +    ppc_hash_pte64_t pte;
> >      uint64_t token;
> > -    target_ulong v, r;
> >  
> >      if (!valid_pte_index(env, pte_index)) {
> >          return H_PARAMETER;
> >      }
> >  
> >      token = ppc_hash64_start_access(cpu, pte_index);
> > -    v = ppc_hash64_load_hpte0(cpu, token, 0);
> > -    r = ppc_hash64_load_hpte1(cpu, token, 0);
> > +    pte = ppc_hash64_load_hpte(cpu, token, 0);
> >      ppc_hash64_stop_access(cpu, token);
> >  
> > -    if ((v & HPTE64_V_VALID) == 0 ||
> > -        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {
> > +    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
> > +        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn)) {
> >          return H_NOT_FOUND;
> >      }
> >  
> > -    r &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
> > -           HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
> > -    r |= (flags << 55) & HPTE64_R_PP0;
> > -    r |= (flags << 48) & HPTE64_R_KEY_HI;
> > -    r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
> > +    pte.pte1 &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
> > +                  HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
> > +    pte.pte1 |= (flags << 55) & HPTE64_R_PP0;
> > +    pte.pte1 |= (flags << 48) & HPTE64_R_KEY_HI;
> > +    pte.pte1 |= flags & (HPTE64_R_PP | HPTE64_R_N |
> > HPTE64_R_KEY_LO);
> >      ppc_hash64_store_hpte(cpu, pte_index,
> > -                          (v & ~HPTE64_V_VALID) |
> > HPTE64_V_HPTE_DIRTY, 0);
> > -    ppc_hash64_tlb_flush_hpte(cpu, pte_index, v, r);
> > +                          (pte.pte0 & ~HPTE64_V_VALID) |
> > HPTE64_V_HPTE_DIRTY,
> > +                          0);
> > +    ppc_hash64_tlb_flush_hpte(cpu, pte_index, pte.pte0, pte.pte1);
> >      /* Flush the tlb */
> >      check_tlb_flush(env, true);
> >      /* Don't need a memory barrier, due to qemu's global lock */
> > -    ppc_hash64_store_hpte(cpu, pte_index, v | HPTE64_V_HPTE_DIRTY,
> > r);
> > +    ppc_hash64_store_hpte(cpu, pte_index, pte.pte0 |
> > HPTE64_V_HPTE_DIRTY,
> > +                          pte.pte1);
> >      return H_SUCCESS;
> >  }
> >  
> > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> > index b476b3f..03607d5 100644
> > --- a/target/ppc/mmu-hash64.c
> > +++ b/target/ppc/mmu-hash64.c
> > @@ -515,7 +515,6 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU
> > *cpu, hwaddr hash,
> >      CPUPPCState *env = &cpu->env;
> >      int i;
> >      uint64_t token;
> > -    target_ulong pte0, pte1;
> >      target_ulong pte_index;
> >  
> >      pte_index = (hash & env->htab_mask) * HPTES_PER_GROUP;
> > @@ -524,12 +523,11 @@ static hwaddr
> > ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
> >          return -1;
> >      }
> >      for (i = 0; i < HPTES_PER_GROUP; i++) {
> > -        pte0 = ppc_hash64_load_hpte0(cpu, token, i);
> > -        pte1 = ppc_hash64_load_hpte1(cpu, token, i);
> > +        ppc_hash_pte64_t entry = ppc_hash64_load_hpte(cpu, token,
> > i);
> Hm.  So the hypercalls using the access helpers which include format
> conversion makes sense to me - the hypercalls are defined to use the
> old format, even on POWER9 AIUI.
> 
> It doesn't really make sense to me here, in what is essentially the
> physical implementation of the HPT lookup.  Shouldn't that be using
> the new format natively?
> 
> Basically it seems odd that you store things in the new format in
> memory, but convert to the old format on *all* accesses, not just the
> hypercall ones which are defined that way.
> 
It seemed easier to just do the conversion rather than updating the
code in all places. That said since this is modelling the hardware and
should probably use the new format instead of just converting it and
pretenting nothing changed.
> > 
> >          /* This compares V, B, H (secondary) and the AVPN */
> > -        if (HPTE64_V_COMPARE(pte0, ptem)) {
> > -            *pshift = hpte_page_shift(sps, pte0, pte1);
> > +        if (HPTE64_V_COMPARE(entry.pte0, ptem)) {
> > +            *pshift = hpte_page_shift(sps, entry.pte0,
> > entry.pte1);
> >              /*
> >               * If there is no match, ignore the PTE, it could
> > simply
> >               * be for a different segment size encoding and the
> > @@ -543,8 +541,7 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU
> > *cpu, hwaddr hash,
> >              /* We don't do anything with pshift yet as qemu TLB
> > only deals
> >               * with 4K pages anyway
> >               */
> > -            pte->pte0 = pte0;
> > -            pte->pte1 = pte1;
> > +            *pte = entry;
> >              ppc_hash64_stop_access(cpu, token);
> >              return (pte_index + i) * HASH_PTE_SIZE_64;
> >          }
> > @@ -924,6 +921,8 @@ void ppc_hash64_store_hpte(PowerPCCPU *cpu,
> >  {
> >      CPUPPCState *env = &cpu->env;
> >  
> > +    ppc_hash64_hpte_old_to_new(env, &pte0, &pte1);
> > +
> >      if (env->external_htab == MMU_HASH64_KVM_MANAGED_HPT) {
> >          kvmppc_hash64_write_pte(env, pte_index, pte0, pte1);
> >          return;
> > diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
> > index ab5d347..73d7ce4 100644
> > --- a/target/ppc/mmu-hash64.h
> > +++ b/target/ppc/mmu-hash64.h
> > @@ -60,6 +60,7 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
> >  #define HASH_PTE_SIZE_64        16
> >  #define HASH_PTEG_SIZE_64       (HASH_PTE_SIZE_64 *
> > HPTES_PER_GROUP)
> >  
> > +#define HPTE64_V_3_00_COMMON    0x000fffffffffffffULL
> >  #define HPTE64_V_SSIZE_SHIFT    62
> >  #define HPTE64_V_AVPN_SHIFT     7
> >  #define HPTE64_V_AVPN           0x3fffffffffffff80ULL
> > @@ -69,9 +70,12 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
> >  #define HPTE64_V_SECONDARY      0x0000000000000002ULL
> >  #define HPTE64_V_VALID          0x0000000000000001ULL
> >  
> > +#define HPTE64_R_3_00_COMMON    0xf1ffffffffffffffULL
> >  #define HPTE64_R_PP0            0x8000000000000000ULL
> >  #define HPTE64_R_TS             0x4000000000000000ULL
> >  #define HPTE64_R_KEY_HI         0x3000000000000000ULL
> > +#define HPTE64_R_SSIZE_SHIFT    58
> > +#define HPTE64_R_SSIZE_MASK     (3ULL << HPTE64_R_SSIZE_SHIFT)
> >  #define HPTE64_R_RPN_SHIFT      12
> >  #define HPTE64_R_RPN            0x0ffffffffffff000ULL
> >  #define HPTE64_R_FLAGS          0x00000000000003ffULL
> > @@ -91,6 +95,10 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
> >  #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
> >  #define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
> >  
> > +typedef struct {
> > +    uint64_t pte0, pte1;
> > +} ppc_hash_pte64_t;
> > +
> >  void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong value,
> >                           Error **errp);
> >  void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int
> > shift,
> > @@ -99,37 +107,64 @@ void ppc_hash64_set_external_hpt(PowerPCCPU
> > *cpu, void *hpt, int shift,
> >  uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, target_ulong
> > pte_index);
> >  void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t token);
> >  
> > -static inline target_ulong ppc_hash64_load_hpte0(PowerPCCPU *cpu,
> > -                                                 uint64_t token,
> > int index)
> > +static inline void ppc_hash64_hpte_old_to_new(CPUPPCState *env,
> > +                                              target_ulong *pte0,
> > +                                              target_ulong *pte1)
> >  {
> > -    CPUPPCState *env = &cpu->env;
> > -    uint64_t addr;
> > +    switch (env->mmu_model) {
> > +    case POWERPC_MMU_3_00:
> > +        /*
> > +         * v3.00 of the ISA moved the B field to the second
> > doubleword and
> > +         * shortened the abbreviated virtual address and
> > abbreviated real page
> > +         * number fields
> > +         */
> > +        *pte1 = (*pte1 & HPTE64_R_3_00_COMMON) |
> > +                ((*pte0 >> HPTE64_V_SSIZE_SHIFT) <<
> > HPTE64_R_SSIZE_SHIFT);
> > +        *pte0 = *pte0 & HPTE64_V_3_00_COMMON;
> > +    default:
> > +        ;
> > +    }
> > +}
> >  
> > -    addr = token + (index * HASH_PTE_SIZE_64);
> > -    if (env->external_htab) {
> > -        return  ldq_p((const void *)(uintptr_t)addr);
> > -    } else {
> > -        return ldq_phys(CPU(cpu)->as, addr);
> > +static inline void ppc_hash64_hpte_new_to_old(CPUPPCState *env,
> > +                                              target_ulong *pte0,
> > +                                              target_ulong *pte1)
> > +{
> > +    switch (env->mmu_model) {
> > +    case POWERPC_MMU_3_00:
> > +        /*
> > +         * v3.00 of the ISA moved the B field to the second
> > doubleword and
> > +         * shortened the abbreviated virtual address and
> > abbreviated real page
> > +         * number fields
> > +         */
> > +        *pte0 = (*pte0 & HPTE64_V_3_00_COMMON) | ((*pte1 &
> > HPTE64_R_SSIZE_MASK)
> > +                << (HPTE64_V_SSIZE_SHIFT - HPTE64_R_SSIZE_SHIFT));
> > +        *pte1 = *pte1 & HPTE64_R_3_00_COMMON;
> > +    default:
> > +        ;
> >      }
> >  }
> >  
> > -static inline target_ulong ppc_hash64_load_hpte1(PowerPCCPU *cpu,
> > -                                                 uint64_t token,
> > int index)
> > +static inline ppc_hash_pte64_t ppc_hash64_load_hpte(PowerPCCPU
> > *cpu,
> > +                                                    uint64_t
> > token,
> > +                                                    int index)
> >  {
> >      CPUPPCState *env = &cpu->env;
> > +    ppc_hash_pte64_t pte;
> >      uint64_t addr;
> >  
> > -    addr = token + (index * HASH_PTE_SIZE_64) +
> > HASH_PTE_SIZE_64/2;
> > +    addr = token + (index * HASH_PTE_SIZE_64);
> >      if (env->external_htab) {
> > -        return  ldq_p((const void *)(uintptr_t)addr);
> > +        pte.pte0 = ldq_p((const void *)(uintptr_t)addr);
> > +        pte.pte1 = ldq_p((const void *)(uintptr_t)addr +
> > HASH_PTE_SIZE_64/2);
> >      } else {
> > -        return ldq_phys(CPU(cpu)->as, addr);
> > +        pte.pte0 = ldq_phys(CPU(cpu)->as, addr);
> > +        pte.pte1 = ldq_phys(CPU(cpu)->as, addr +
> > HASH_PTE_SIZE_64/2);
> >      }
> > -}
> >  
> > -typedef struct {
> > -    uint64_t pte0, pte1;
> > -} ppc_hash_pte64_t;
> > +    ppc_hash64_hpte_new_to_old(env, &pte.pte0, &pte.pte1);
> > +    return pte;
> > +}
> >  
> >  #endif /* CONFIG_USER_ONLY */
> >  

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

* Re: [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support
  2017-02-01  1:04   ` David Gibson
@ 2017-02-09  3:09     ` Suraj Jitindar Singh
  0 siblings, 0 replies; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-02-09  3:09 UTC (permalink / raw)
  To: David Gibson, qemu-devel; +Cc: famz, qemu-ppc, agraf

On Wed, 2017-02-01 at 12:04 +1100, David Gibson wrote:
> On Thu, Jan 12, 2017 at 10:55:49PM -0800, no-reply@patchew.org wrote:
> > 
> > Hi,
> > 
> > Your series seems to have some coding style problems. See output
> > below for
> > more information:
> > 
> > Message-id: 1484288903-18807-1-git-send-email-sjitindarsingh@gmail.
> > com
> > Subject: [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement
> > POWER9 pseries tcg legacy kernel support
> > Type: series
> The style bot does generate a fair few false positives, but AFAICT
> all
> the things below should be addressed.
> 
I'll fix these up

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

* Re: [Qemu-devel] [RFC PATCH 11/17] target/ppc/POWER9: Update to new pte format for POWER9 accesses
  2017-02-09  3:08     ` Suraj Jitindar Singh
@ 2017-02-09 23:47       ` Suraj Jitindar Singh
  2017-02-10  0:21         ` David Gibson
  0 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-02-09 23:47 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, agraf, qemu-devel

On Thu, 2017-02-09 at 14:08 +1100, Suraj Jitindar Singh wrote:
> On Wed, 2017-02-01 at 15:28 +1100, David Gibson wrote:
> > 
> > On Fri, Jan 13, 2017 at 05:28:17PM +1100, Suraj Jitindar Singh
> > wrote:
> > > 
> > > 
> > > The page table entry format was updated for the POWER9 processor.
> > > 
> > > It was decided that kernels would used the old format
> > > irrespective
> > > with the translation occuring at the hypervisor level. Thus we
> > > convert
> > > between the old and new format when accessing the ptes. Since we
> > > need the
> > > whole pte to perform this conversion, we remove the old functions
> > > which
> > > accessed either the first or second doubleword and introduce a
> > > new
> > > functions which access the entire pte, returning the entry
> > > converted
> > > back to the old format (if required). Update call sites
> > > accordingly.
> > > 
> > > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> > > ---
> > >  hw/ppc/spapr_hcall.c    | 51 ++++++++++++++++++-----------------
> > >  target/ppc/mmu-hash64.c | 13 +++++----
> > >  target/ppc/mmu-hash64.h | 71
> > > ++++++++++++++++++++++++++++++++++++-
> > > ------------
> > >  3 files changed, 86 insertions(+), 49 deletions(-)
> > > 
> > > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> > > index 9a9bedf..9f0c20d 100644
> > > --- a/hw/ppc/spapr_hcall.c
> > > +++ b/hw/ppc/spapr_hcall.c
> > > @@ -125,7 +125,8 @@ static target_ulong h_enter(PowerPCCPU *cpu,
> > > sPAPRMachineState *spapr,
> > >          pte_index &= ~7ULL;
> > >          token = ppc_hash64_start_access(cpu, pte_index);
> > >          for (; index < 8; index++) {
> > > -            if (!(ppc_hash64_load_hpte0(cpu, token, index) &
> > > HPTE64_V_VALID)) {
> > > +            ppc_hash_pte64_t pte = ppc_hash64_load_hpte(cpu,
> > > token, index);
> > > +            if (!(pte.pte0 & HPTE64_V_VALID)) {
> > >                  break;
> > >              }
> > >          }
> > > @@ -134,8 +135,10 @@ static target_ulong h_enter(PowerPCCPU *cpu,
> > > sPAPRMachineState *spapr,
> > >              return H_PTEG_FULL;
> > >          }
> > >      } else {
> > > +        ppc_hash_pte64_t pte;
> > >          token = ppc_hash64_start_access(cpu, pte_index);
> > IIRC the only reason for the clumsy start_access / stop_access
> > stuff
> > was because we wanted to do the two loads separately (to avoid
> > loading
> > word1 in cases we don't need it).  Since you're combining both
> > loads
> > into a single helper, I think you can put the start_access /
> > stop_access into the same helper.
> > 
> > Or have I missed something.
> > 
> Yeah these functions can probably be merged together...
Actually, it looks like we need the start access and stop access stuff
for kvm-hv where we load the pte into a buffer on start access and free
it on stop access. So I think we still need to keep these two functions
separate.
> > 
> > > 
> > > 
> > > -        if (ppc_hash64_load_hpte0(cpu, token, 0) &
> > > HPTE64_V_VALID)
> > > {
> > > +        pte = ppc_hash64_load_hpte(cpu, token, 0);
> > > +        if (pte.pte0 & HPTE64_V_VALID) {
> > >              ppc_hash64_stop_access(cpu, token);
> > >              return H_PTEG_FULL;
> > >          }
> > > @@ -163,26 +166,25 @@ static RemoveResult remove_hpte(PowerPCCPU
> > > *cpu, target_ulong ptex,
> > >  {
> > >      CPUPPCState *env = &cpu->env;
> > >      uint64_t token;
> > > -    target_ulong v, r;
> > > +    ppc_hash_pte64_t pte;
> > >  
> > >      if (!valid_pte_index(env, ptex)) {
> > >          return REMOVE_PARM;
> > >      }
> > >  
> > >      token = ppc_hash64_start_access(cpu, ptex);
> > > -    v = ppc_hash64_load_hpte0(cpu, token, 0);
> > > -    r = ppc_hash64_load_hpte1(cpu, token, 0);
> > > +    pte = ppc_hash64_load_hpte(cpu, token, 0);
> > >      ppc_hash64_stop_access(cpu, token);
> > >  
> > > -    if ((v & HPTE64_V_VALID) == 0 ||
> > > -        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) ||
> > > -        ((flags & H_ANDCOND) && (v & avpn) != 0)) {
> > > +    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
> > > +        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn) ||
> > > +        ((flags & H_ANDCOND) && (pte.pte0 & avpn) != 0)) {
> > >          return REMOVE_NOT_FOUND;
> > >      }
> > > -    *vp = v;
> > > -    *rp = r;
> > > +    *vp = pte.pte0;
> > > +    *rp = pte.pte1;
> > >      ppc_hash64_store_hpte(cpu, ptex, HPTE64_V_HPTE_DIRTY, 0);
> > > -    ppc_hash64_tlb_flush_hpte(cpu, ptex, v, r);
> > > +    ppc_hash64_tlb_flush_hpte(cpu, ptex, pte.pte0, pte.pte1);
> > >      return REMOVE_SUCCESS;
> > >  }
> > >  
> > > @@ -293,35 +295,36 @@ static target_ulong h_protect(PowerPCCPU
> > > *cpu, sPAPRMachineState *spapr,
> > >      target_ulong flags = args[0];
> > >      target_ulong pte_index = args[1];
> > >      target_ulong avpn = args[2];
> > > +    ppc_hash_pte64_t pte;
> > >      uint64_t token;
> > > -    target_ulong v, r;
> > >  
> > >      if (!valid_pte_index(env, pte_index)) {
> > >          return H_PARAMETER;
> > >      }
> > >  
> > >      token = ppc_hash64_start_access(cpu, pte_index);
> > > -    v = ppc_hash64_load_hpte0(cpu, token, 0);
> > > -    r = ppc_hash64_load_hpte1(cpu, token, 0);
> > > +    pte = ppc_hash64_load_hpte(cpu, token, 0);
> > >      ppc_hash64_stop_access(cpu, token);
> > >  
> > > -    if ((v & HPTE64_V_VALID) == 0 ||
> > > -        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {
> > > +    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
> > > +        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn)) {
> > >          return H_NOT_FOUND;
> > >      }
> > >  
> > > -    r &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
> > > -           HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
> > > -    r |= (flags << 55) & HPTE64_R_PP0;
> > > -    r |= (flags << 48) & HPTE64_R_KEY_HI;
> > > -    r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
> > > +    pte.pte1 &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
> > > +                  HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
> > > +    pte.pte1 |= (flags << 55) & HPTE64_R_PP0;
> > > +    pte.pte1 |= (flags << 48) & HPTE64_R_KEY_HI;
> > > +    pte.pte1 |= flags & (HPTE64_R_PP | HPTE64_R_N |
> > > HPTE64_R_KEY_LO);
> > >      ppc_hash64_store_hpte(cpu, pte_index,
> > > -                          (v & ~HPTE64_V_VALID) |
> > > HPTE64_V_HPTE_DIRTY, 0);
> > > -    ppc_hash64_tlb_flush_hpte(cpu, pte_index, v, r);
> > > +                          (pte.pte0 & ~HPTE64_V_VALID) |
> > > HPTE64_V_HPTE_DIRTY,
> > > +                          0);
> > > +    ppc_hash64_tlb_flush_hpte(cpu, pte_index, pte.pte0,
> > > pte.pte1);
> > >      /* Flush the tlb */
> > >      check_tlb_flush(env, true);
> > >      /* Don't need a memory barrier, due to qemu's global lock */
> > > -    ppc_hash64_store_hpte(cpu, pte_index, v |
> > > HPTE64_V_HPTE_DIRTY,
> > > r);
> > > +    ppc_hash64_store_hpte(cpu, pte_index, pte.pte0 |
> > > HPTE64_V_HPTE_DIRTY,
> > > +                          pte.pte1);
> > >      return H_SUCCESS;
> > >  }
> > >  
> > > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> > > index b476b3f..03607d5 100644
> > > --- a/target/ppc/mmu-hash64.c
> > > +++ b/target/ppc/mmu-hash64.c
> > > @@ -515,7 +515,6 @@ static hwaddr
> > > ppc_hash64_pteg_search(PowerPCCPU
> > > *cpu, hwaddr hash,
> > >      CPUPPCState *env = &cpu->env;
> > >      int i;
> > >      uint64_t token;
> > > -    target_ulong pte0, pte1;
> > >      target_ulong pte_index;
> > >  
> > >      pte_index = (hash & env->htab_mask) * HPTES_PER_GROUP;
> > > @@ -524,12 +523,11 @@ static hwaddr
> > > ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
> > >          return -1;
> > >      }
> > >      for (i = 0; i < HPTES_PER_GROUP; i++) {
> > > -        pte0 = ppc_hash64_load_hpte0(cpu, token, i);
> > > -        pte1 = ppc_hash64_load_hpte1(cpu, token, i);
> > > +        ppc_hash_pte64_t entry = ppc_hash64_load_hpte(cpu,
> > > token,
> > > i);
> > Hm.  So the hypercalls using the access helpers which include
> > format
> > conversion makes sense to me - the hypercalls are defined to use
> > the
> > old format, even on POWER9 AIUI.
> > 
> > It doesn't really make sense to me here, in what is essentially the
> > physical implementation of the HPT lookup.  Shouldn't that be using
> > the new format natively?
> > 
> > Basically it seems odd that you store things in the new format in
> > memory, but convert to the old format on *all* accesses, not just
> > the
> > hypercall ones which are defined that way.
> > 
> It seemed easier to just do the conversion rather than updating the
> code in all places. That said since this is modelling the hardware
> and
> should probably use the new format instead of just converting it and
> pretenting nothing changed.
> > 
> > > 
> > > 
> > >          /* This compares V, B, H (secondary) and the AVPN */
> > > -        if (HPTE64_V_COMPARE(pte0, ptem)) {
> > > -            *pshift = hpte_page_shift(sps, pte0, pte1);
> > > +        if (HPTE64_V_COMPARE(entry.pte0, ptem)) {
> > > +            *pshift = hpte_page_shift(sps, entry.pte0,
> > > entry.pte1);
> > >              /*
> > >               * If there is no match, ignore the PTE, it could
> > > simply
> > >               * be for a different segment size encoding and the
> > > @@ -543,8 +541,7 @@ static hwaddr
> > > ppc_hash64_pteg_search(PowerPCCPU
> > > *cpu, hwaddr hash,
> > >              /* We don't do anything with pshift yet as qemu TLB
> > > only deals
> > >               * with 4K pages anyway
> > >               */
> > > -            pte->pte0 = pte0;
> > > -            pte->pte1 = pte1;
> > > +            *pte = entry;
> > >              ppc_hash64_stop_access(cpu, token);
> > >              return (pte_index + i) * HASH_PTE_SIZE_64;
> > >          }
> > > @@ -924,6 +921,8 @@ void ppc_hash64_store_hpte(PowerPCCPU *cpu,
> > >  {
> > >      CPUPPCState *env = &cpu->env;
> > >  
> > > +    ppc_hash64_hpte_old_to_new(env, &pte0, &pte1);
> > > +
> > >      if (env->external_htab == MMU_HASH64_KVM_MANAGED_HPT) {
> > >          kvmppc_hash64_write_pte(env, pte_index, pte0, pte1);
> > >          return;
> > > diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
> > > index ab5d347..73d7ce4 100644
> > > --- a/target/ppc/mmu-hash64.h
> > > +++ b/target/ppc/mmu-hash64.h
> > > @@ -60,6 +60,7 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
> > >  #define HASH_PTE_SIZE_64        16
> > >  #define HASH_PTEG_SIZE_64       (HASH_PTE_SIZE_64 *
> > > HPTES_PER_GROUP)
> > >  
> > > +#define HPTE64_V_3_00_COMMON    0x000fffffffffffffULL
> > >  #define HPTE64_V_SSIZE_SHIFT    62
> > >  #define HPTE64_V_AVPN_SHIFT     7
> > >  #define HPTE64_V_AVPN           0x3fffffffffffff80ULL
> > > @@ -69,9 +70,12 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
> > >  #define HPTE64_V_SECONDARY      0x0000000000000002ULL
> > >  #define HPTE64_V_VALID          0x0000000000000001ULL
> > >  
> > > +#define HPTE64_R_3_00_COMMON    0xf1ffffffffffffffULL
> > >  #define HPTE64_R_PP0            0x8000000000000000ULL
> > >  #define HPTE64_R_TS             0x4000000000000000ULL
> > >  #define HPTE64_R_KEY_HI         0x3000000000000000ULL
> > > +#define HPTE64_R_SSIZE_SHIFT    58
> > > +#define HPTE64_R_SSIZE_MASK     (3ULL << HPTE64_R_SSIZE_SHIFT)
> > >  #define HPTE64_R_RPN_SHIFT      12
> > >  #define HPTE64_R_RPN            0x0ffffffffffff000ULL
> > >  #define HPTE64_R_FLAGS          0x00000000000003ffULL
> > > @@ -91,6 +95,10 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
> > >  #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
> > >  #define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
> > >  
> > > +typedef struct {
> > > +    uint64_t pte0, pte1;
> > > +} ppc_hash_pte64_t;
> > > +
> > >  void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong value,
> > >                           Error **errp);
> > >  void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int
> > > shift,
> > > @@ -99,37 +107,64 @@ void ppc_hash64_set_external_hpt(PowerPCCPU
> > > *cpu, void *hpt, int shift,
> > >  uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, target_ulong
> > > pte_index);
> > >  void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t token);
> > >  
> > > -static inline target_ulong ppc_hash64_load_hpte0(PowerPCCPU
> > > *cpu,
> > > -                                                 uint64_t token,
> > > int index)
> > > +static inline void ppc_hash64_hpte_old_to_new(CPUPPCState *env,
> > > +                                              target_ulong
> > > *pte0,
> > > +                                              target_ulong
> > > *pte1)
> > >  {
> > > -    CPUPPCState *env = &cpu->env;
> > > -    uint64_t addr;
> > > +    switch (env->mmu_model) {
> > > +    case POWERPC_MMU_3_00:
> > > +        /*
> > > +         * v3.00 of the ISA moved the B field to the second
> > > doubleword and
> > > +         * shortened the abbreviated virtual address and
> > > abbreviated real page
> > > +         * number fields
> > > +         */
> > > +        *pte1 = (*pte1 & HPTE64_R_3_00_COMMON) |
> > > +                ((*pte0 >> HPTE64_V_SSIZE_SHIFT) <<
> > > HPTE64_R_SSIZE_SHIFT);
> > > +        *pte0 = *pte0 & HPTE64_V_3_00_COMMON;
> > > +    default:
> > > +        ;
> > > +    }
> > > +}
> > >  
> > > -    addr = token + (index * HASH_PTE_SIZE_64);
> > > -    if (env->external_htab) {
> > > -        return  ldq_p((const void *)(uintptr_t)addr);
> > > -    } else {
> > > -        return ldq_phys(CPU(cpu)->as, addr);
> > > +static inline void ppc_hash64_hpte_new_to_old(CPUPPCState *env,
> > > +                                              target_ulong
> > > *pte0,
> > > +                                              target_ulong
> > > *pte1)
> > > +{
> > > +    switch (env->mmu_model) {
> > > +    case POWERPC_MMU_3_00:
> > > +        /*
> > > +         * v3.00 of the ISA moved the B field to the second
> > > doubleword and
> > > +         * shortened the abbreviated virtual address and
> > > abbreviated real page
> > > +         * number fields
> > > +         */
> > > +        *pte0 = (*pte0 & HPTE64_V_3_00_COMMON) | ((*pte1 &
> > > HPTE64_R_SSIZE_MASK)
> > > +                << (HPTE64_V_SSIZE_SHIFT -
> > > HPTE64_R_SSIZE_SHIFT));
> > > +        *pte1 = *pte1 & HPTE64_R_3_00_COMMON;
> > > +    default:
> > > +        ;
> > >      }
> > >  }
> > >  
> > > -static inline target_ulong ppc_hash64_load_hpte1(PowerPCCPU
> > > *cpu,
> > > -                                                 uint64_t token,
> > > int index)
> > > +static inline ppc_hash_pte64_t ppc_hash64_load_hpte(PowerPCCPU
> > > *cpu,
> > > +                                                    uint64_t
> > > token,
> > > +                                                    int index)
> > >  {
> > >      CPUPPCState *env = &cpu->env;
> > > +    ppc_hash_pte64_t pte;
> > >      uint64_t addr;
> > >  
> > > -    addr = token + (index * HASH_PTE_SIZE_64) +
> > > HASH_PTE_SIZE_64/2;
> > > +    addr = token + (index * HASH_PTE_SIZE_64);
> > >      if (env->external_htab) {
> > > -        return  ldq_p((const void *)(uintptr_t)addr);
> > > +        pte.pte0 = ldq_p((const void *)(uintptr_t)addr);
> > > +        pte.pte1 = ldq_p((const void *)(uintptr_t)addr +
> > > HASH_PTE_SIZE_64/2);
> > >      } else {
> > > -        return ldq_phys(CPU(cpu)->as, addr);
> > > +        pte.pte0 = ldq_phys(CPU(cpu)->as, addr);
> > > +        pte.pte1 = ldq_phys(CPU(cpu)->as, addr +
> > > HASH_PTE_SIZE_64/2);
> > >      }
> > > -}
> > >  
> > > -typedef struct {
> > > -    uint64_t pte0, pte1;
> > > -} ppc_hash_pte64_t;
> > > +    ppc_hash64_hpte_new_to_old(env, &pte.pte0, &pte.pte1);
> > > +    return pte;
> > > +}
> > >  
> > >  #endif /* CONFIG_USER_ONLY */
> > >  

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

* Re: [Qemu-devel] [RFC PATCH 07/17] target/ppc/POWER9: Add partition table pointer to sPAPRMachineState
  2017-02-09  2:57     ` Suraj Jitindar Singh
@ 2017-02-10  0:11       ` David Gibson
  0 siblings, 0 replies; 53+ messages in thread
From: David Gibson @ 2017-02-10  0:11 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Thu, Feb 09, 2017 at 01:57:58PM +1100, Suraj Jitindar Singh wrote:
> On Wed, 2017-02-01 at 15:04 +1100, David Gibson wrote:
> > On Fri, Jan 13, 2017 at 05:28:13PM +1100, Suraj Jitindar Singh wrote:
> > > 
> > > POWER9 uses a partition table to store information relating to how
> > > address translation is performed on a per partition basis.
> > > 
> > > Add a data area for this to the sPAPRMachineState struct and
> > > (re)allocate
> > > it on machine reset.
> > > 
> > > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> > Hm.  I'm having trouble understanding this one.
> > 
> > IIUC, for the "pseries" machine type this partition table entry is
> > essentially a dummy one, since there's actually only one partition.
> > For KVM the machine would be represented by one of many partition
> > table entries on the real host - so the entry here isn't really
> > relevant.  For TCG, I'm not sure what would be looking at it.  We
> > haven't implemented the partition->host level translation in TCG
> > anyway, and in any case pseries (rather than powernv) should be
> > bypassing that - in which case I'd expect it to bypass looking at the
> > dummy partition table entry as well.
> As discussed elsewhere it seems having a whole partition table entry is
> unnecessary. This will be replaced by a single process table pointer to
> be accessed via the vhyp.
> 
> In fact this won't be necessary for the legacy case at all and so will
> drop this patch from the series in favour of moving it into the radix
> enablement series.

Ok, makes sense.

> > 
> > > 
> > > ---
> > >  hw/ppc/spapr.c         | 38 ++++++++++++++++++++++++++++++++------
> > >  include/hw/ppc/spapr.h |  1 +
> > >  target/ppc/mmu.h       | 13 +++++++++++++
> > >  3 files changed, 46 insertions(+), 6 deletions(-)
> > >  create mode 100644 target/ppc/mmu.h
> > > 
> > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > > index 208ef7b..45bd2de 100644
> > > --- a/hw/ppc/spapr.c
> > > +++ b/hw/ppc/spapr.c
> > > @@ -41,6 +41,7 @@
> > >  #include "migration/migration.h"
> > >  #include "mmu-hash64.h"
> > >  #include "qom/cpu.h"
> > > +#include "mmu.h"
> > >  
> > >  #include "hw/boards.h"
> > >  #include "hw/ppc/ppc.h"
> > > @@ -1115,6 +1116,26 @@ static void
> > > spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
> > >      }
> > >  }
> > >  
> > > +static void spapr_reallocate_patb(sPAPRMachineState *spapr, Error
> > > **errp)
> > > +{
> > > +    g_free(spapr->patb);
> > > +    spapr->patb = NULL;
> > > +
> > > +    if (!kvm_enabled()) {
> > > +        /* We need to allocate a partition table entry */
> > > +        size_t size = sizeof(struct patb_entry);
> > > +
> > > +        spapr->patb = qemu_memalign(size, size);
> > > +        if (!spapr->patb) {
> > > +            error_setg_errno(errp, errno, "Could not allocate
> > > memory for "
> > > +                                          "partition table
> > > entry");
> > > +            return;
> > > +        }
> > > +
> > > +        memset(spapr->patb, 0, size);
> > > +    }
> > > +}
> > > +
> > >  static void find_unknown_sysbus_device(SysBusDevice *sbdev, void
> > > *opaque)
> > >  {
> > >      bool matched = false;
> > > @@ -1134,7 +1155,7 @@ static void ppc_spapr_reset(void)
> > >  {
> > >      MachineState *machine = MACHINE(qdev_get_machine());
> > >      sPAPRMachineState *spapr = SPAPR_MACHINE(machine);
> > > -    PowerPCCPU *first_ppc_cpu;
> > > +    PowerPCCPU *first_ppc_cpu = POWERPC_CPU(first_cpu);
> > >      uint32_t rtas_limit;
> > >      hwaddr rtas_addr, fdt_addr;
> > >      void *fdt;
> > > @@ -1143,10 +1164,16 @@ static void ppc_spapr_reset(void)
> > >      /* Check for unknown sysbus devices */
> > >      foreach_dynamic_sysbus_device(find_unknown_sysbus_device,
> > > NULL);
> > >  
> > > -    /* Allocate and/or reset the hash page table */
> > > -    spapr_reallocate_hpt(spapr,
> > > -                         spapr_hpt_shift_for_ramsize(machine-
> > > >maxram_size),
> > > -                         &error_fatal);
> > > +    switch (first_ppc_cpu->env.mmu_model) {
> > > +    case POWERPC_MMU_3_00:
> > > +        /* Allocate the partition table */
> > > +        spapr_reallocate_patb(spapr, &error_fatal);
> > > +    default:
> > > +        /* Allocate and/or reset the hash page table */
> > > +        spapr_reallocate_hpt(spapr,
> > > +                             spapr_hpt_shift_for_ramsize(machine-
> > > >maxram_size),
> > > +                             &error_fatal);
> > > +    }
> > >  
> > >      /* Update the RMA size if necessary */
> > >      if (spapr->vrma_adjust) {
> > > @@ -1193,7 +1220,6 @@ static void ppc_spapr_reset(void)
> > >      g_free(fdt);
> > >  
> > >      /* Set up the entry state */
> > > -    first_ppc_cpu = POWERPC_CPU(first_cpu);
> > >      first_ppc_cpu->env.gpr[3] = fdt_addr;
> > >      first_ppc_cpu->env.gpr[5] = 0;
> > >      first_cpu->halted = 0;
> > > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> > > index bd5bcf7..b654773 100644
> > > --- a/include/hw/ppc/spapr.h
> > > +++ b/include/hw/ppc/spapr.h
> > > @@ -63,6 +63,7 @@ struct sPAPRMachineState {
> > >  
> > >      void *htab;
> > >      uint32_t htab_shift;
> > > +    void *patb;
> > >      hwaddr rma_size;
> > >      int vrma_adjust;
> > >      ssize_t rtas_size;
> > > diff --git a/target/ppc/mmu.h b/target/ppc/mmu.h
> > > new file mode 100644
> > > index 0000000..67b9707
> > > --- /dev/null
> > > +++ b/target/ppc/mmu.h
> > > @@ -0,0 +1,13 @@
> > > +#ifndef MMU_H
> > > +#define MMU_H
> > > +
> > > +#ifndef CONFIG_USER_ONLY
> > > +
> > > +/* Partition Table Entry */
> > > +struct patb_entry {
> > > +    uint64_t patbe0, patbe1;
> > > +};
> > > +
> > > +#endif /* CONFIG_USER_ONLY */
> > > +
> > > +#endif /* MMU_H */
> 

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 08/17] target/ppc/POWER9: Add external partition table pointer to cpu state
  2017-02-09  2:58     ` Suraj Jitindar Singh
@ 2017-02-10  0:11       ` David Gibson
  0 siblings, 0 replies; 53+ messages in thread
From: David Gibson @ 2017-02-10  0:11 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Thu, Feb 09, 2017 at 01:58:28PM +1100, Suraj Jitindar Singh wrote:
> On Wed, 2017-02-01 at 15:09 +1100, David Gibson wrote:
> > On Fri, Jan 13, 2017 at 05:28:14PM +1100, Suraj Jitindar Singh wrote:
> > > 
> > > Similarly to how we have an external hpt pointer in the cpu state,
> > > add
> > > an external partition table pointer and update it to point to the
> > > partition table entry in the machine state struct on cpu reset.
> > > 
> > > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> > As with the previous patch, I don't quite follow what's going on
> > here.  It seems to me that if the external HPT is set, that should
> > make the softmmu logic bypass *both* an HPT set by SDR1 (<= POWER8)
> > or
> > an HPT set by the partition table (POWER9).  So I'm not sure why we
> > need the dummy partition table entry.
> > 
> > To look at it another way, the external HPT is special because it
> > lies
> > outside the guest's address space, but we need its state because the
> > guest can manipulate it via hypercall.  For the partition table
> > entry,
> > even if we're minimally modelling the HV parts of the POWER9 MMU,
> > isn't the partition table entry just fixed at startup?
> Similarly this patch will be dropped from the series.

Ok.

> > 
> > > 
> > > ---
> > >  hw/ppc/spapr_cpu_core.c | 12 ++++++++++--
> > >  target/ppc/cpu.h        |  3 +++
> > >  target/ppc/mmu.h        |  6 ++++++
> > >  target/ppc/mmu_helper.c | 12 ++++++++++++
> > >  4 files changed, 31 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
> > > index 8cc7058..72a7f90 100644
> > > --- a/hw/ppc/spapr_cpu_core.c
> > > +++ b/hw/ppc/spapr_cpu_core.c
> > > @@ -17,6 +17,7 @@
> > >  #include "hw/ppc/ppc.h"
> > >  #include "target/ppc/mmu-hash64.h"
> > >  #include "sysemu/numa.h"
> > > +#include "mmu.h"
> > >  
> > >  static void spapr_cpu_reset(void *opaque)
> > >  {
> > > @@ -34,8 +35,15 @@ static void spapr_cpu_reset(void *opaque)
> > >  
> > >      env->spr[SPR_HIOR] = 0;
> > >  
> > > -    ppc_hash64_set_external_hpt(cpu, spapr->htab, spapr-
> > > >htab_shift,
> > > -                                &error_fatal);
> > > +    switch (env->mmu_model) {
> > > +    case POWERPC_MMU_3_00:
> > > +        ppc64_set_external_patb(cpu, spapr->patb, &error_fatal);
> > > +    default:
> > > +        /* We assume legacy until told otherwise, thus set HPT
> > > irrespective */
> > > +        ppc_hash64_set_external_hpt(cpu, spapr->htab, spapr-
> > > >htab_shift,
> > > +                                    &error_fatal);
> > > +        break;
> > > +    }
> > >  }
> > >  
> > >  static void spapr_cpu_destroy(PowerPCCPU *cpu)
> > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> > > index 0ab49b3..e8b7c06 100644
> > > --- a/target/ppc/cpu.h
> > > +++ b/target/ppc/cpu.h
> > > @@ -77,6 +77,7 @@
> > >  #include "exec/cpu-defs.h"
> > >  #include "cpu-qom.h"
> > >  #include "fpu/softfloat.h"
> > > +#include "mmu.h"
> > >  
> > >  #if defined (TARGET_PPC64)
> > >  #define PPC_ELF_MACHINE     EM_PPC64
> > > @@ -1009,6 +1010,8 @@ struct CPUPPCState {
> > >      target_ulong sr[32];
> > >      /* externally stored hash table */
> > >      uint8_t *external_htab;
> > > +    /* externally stored partition table entry */
> > > +    struct patb_entry *external_patbe;
> > >      /* BATs */
> > >      uint32_t nb_BATs;
> > >      target_ulong DBAT[2][8];
> > > diff --git a/target/ppc/mmu.h b/target/ppc/mmu.h
> > > index 67b9707..c7967c3 100644
> > > --- a/target/ppc/mmu.h
> > > +++ b/target/ppc/mmu.h
> > > @@ -8,6 +8,12 @@ struct patb_entry {
> > >      uint64_t patbe0, patbe1;
> > >  };
> > >  
> > > +#ifdef TARGET_PPC64
> > > +
> > > +void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error
> > > **errp);
> > > +
> > > +#endif /* TARGET_PPC64 */
> > > +
> > >  #endif /* CONFIG_USER_ONLY */
> > >  
> > >  #endif /* MMU_H */
> > > diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> > > index 2ab4562..bc6c117 100644
> > > --- a/target/ppc/mmu_helper.c
> > > +++ b/target/ppc/mmu_helper.c
> > > @@ -28,6 +28,7 @@
> > >  #include "exec/cpu_ldst.h"
> > >  #include "exec/log.h"
> > >  #include "helper_regs.h"
> > > +#include "mmu.h"
> > >  
> > >  //#define DEBUG_MMU
> > >  //#define DEBUG_BATS
> > > @@ -2907,3 +2908,14 @@ void tlb_fill(CPUState *cs, target_ulong
> > > addr, MMUAccessType access_type,
> > >                                 retaddr);
> > >      }
> > >  }
> > > +
> > > +/*****************************************************************
> > > *************/
> > > +
> > > +/* ISA v3.00 (POWER9) Generic MMU Helpers */
> > > +
> > > +void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error
> > > **errp)
> > > +{
> > > +    CPUPPCState *env = &cpu->env;
> > > +
> > > +    env->external_patbe = (struct patb_entry *) patb;
> > > +}
> 

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 10/17] target/ppc/POWER9: Add POWER9 mmu fault handler
  2017-02-09  3:04     ` Suraj Jitindar Singh
@ 2017-02-10  0:16       ` David Gibson
  0 siblings, 0 replies; 53+ messages in thread
From: David Gibson @ 2017-02-10  0:16 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Thu, Feb 09, 2017 at 02:04:52PM +1100, Suraj Jitindar Singh wrote:
> On Wed, 2017-02-01 at 15:23 +1100, David Gibson wrote:
> > On Fri, Jan 13, 2017 at 05:28:16PM +1100, Suraj Jitindar Singh wrote:
> > > 
> > > Add a new mmu fault handler for the POWER9 cpu and add it as the
> > > handler
> > > for the POWER9 cpu definition.
> > > 
> > > This handler checks if the guest is radix or hash based on the
> > > value in the
> > > partition table entry and calls the correct fault handler
> > > accordingly.
> > > 
> > > The hash fault handling code has also been updated to check if the
> > > partition is using segment tables.
> > > 
> > > Currently only legacy hash (no segment tables) is supported.
> > > 
> > > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> > > ---
> > >  target/ppc/mmu-hash64.c     |  8 ++++++++
> > >  target/ppc/mmu.h            |  8 ++++++++
> > >  target/ppc/mmu_helper.c     | 47
> > > +++++++++++++++++++++++++++++++++++++++++++++
> > >  target/ppc/translate_init.c |  2 +-
> > >  4 files changed, 64 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> > > index b9d4f4e..b476b3f 100644
> > > --- a/target/ppc/mmu-hash64.c
> > > +++ b/target/ppc/mmu-hash64.c
> > > @@ -73,6 +73,14 @@ static ppc_slb_t *slb_lookup(PowerPCCPU *cpu,
> > > target_ulong eaddr)
> > >          }
> > >      }
> > >  
> > > +    /* Check if in-memory segment tables are in use */
> > > +    if (ppc64_use_proc_tbl(cpu)) {
> > > +        /* TODO - Unsupported */
> > > +        qemu_log_mask(LOG_UNIMP, "%s: unimplemented - segment
> > > table support\n",
> > > +                      __func__);
> > > +        /* Not much we can do here, caller will generate a segment
> > > interrupt */
> > > +    }
> > I think this logic would be better in the fault handler.  For the
> > fault path in the segment table case, I don't think we want to even
> > model the SLB (in hardware the SLB is an important optimization, but
> > I
> > don't think the software SLB will be notably better than just looking
> > up the seg table directly).  I think the other users of slb_lookup()
> > are in contexts that only make sense in the context of a software
> > managed SLB anyway.
> > 
> The mmu looks up the slb before it looks in the segment tables, so we
> still need to model and search the slb before we search segment tables.

Well, it's not so much the fact that the hardware looks up the slb.
It's that it still permits the guest to software load SLB entries, so
we can have things in the SLB that can't also be discovered from the
segment tables.  I realized this after making the comment.

> We could call slb lookup and if that fails we can then call a
> search_seg_tbl() or something from the fault handler.

Yes, I think doing that in the caller would be clearer than doing the
segment table lookup within slb_lookup().

> > > 
> > >      return NULL;
> > >  }
> > >  
> > > diff --git a/target/ppc/mmu.h b/target/ppc/mmu.h
> > > index c7967c3..e07b128 100644
> > > --- a/target/ppc/mmu.h
> > > +++ b/target/ppc/mmu.h
> > > @@ -3,6 +3,10 @@
> > >  
> > >  #ifndef CONFIG_USER_ONLY
> > >  
> > > +/* Common Partition Table Entry Fields */
> > > +#define PATBE0_HR                0x8000000000000000
> > > +#define PATBE1_GR                0x8000000000000000
> > > +
> > >  /* Partition Table Entry */
> > >  struct patb_entry {
> > >      uint64_t patbe0, patbe1;
> > > @@ -11,6 +15,10 @@ struct patb_entry {
> > >  #ifdef TARGET_PPC64
> > >  
> > >  void ppc64_set_external_patb(PowerPCCPU *cpu, void *patb, Error
> > > **errp);
> > > +bool ppc64_use_proc_tbl(PowerPCCPU *cpu);
> > > +bool ppc64_radix_guest(PowerPCCPU *cpu);
> > > +int ppc64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
> > > +                           int mmu_idx);
> > >  
> > >  #endif /* TARGET_PPC64 */
> > >  
> > > diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> > > index bc6c117..612f407 100644
> > > --- a/target/ppc/mmu_helper.c
> > > +++ b/target/ppc/mmu_helper.c
> > > @@ -28,6 +28,7 @@
> > >  #include "exec/cpu_ldst.h"
> > >  #include "exec/log.h"
> > >  #include "helper_regs.h"
> > > +#include "qemu/error-report.h"
> > >  #include "mmu.h"
> > >  
> > >  //#define DEBUG_MMU
> > > @@ -1281,6 +1282,17 @@ void dump_mmu(FILE *f, fprintf_function
> > > cpu_fprintf, CPUPPCState *env)
> > >      case POWERPC_MMU_2_07a:
> > >          dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
> > >          break;
> > > +    case POWERPC_MMU_3_00:
> > > +        if (ppc64_radix_guest(ppc_env_get_cpu(env))) {
> > > +            /* TODO - Unsupported */
> > > +        } else {
> > > +            if (ppc64_use_proc_tbl(ppc_env_get_cpu(env))) {
> > > +                /* TODO - Unsupported */
> > > +            } else {
> > > +                dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
> > > +                break;
> > > +            }
> > > +        }
> > >  #endif
> > >      default:
> > >          qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
> > > @@ -1422,6 +1434,17 @@ hwaddr ppc_cpu_get_phys_page_debug(CPUState
> > > *cs, vaddr addr)
> > >      case POWERPC_MMU_2_07:
> > >      case POWERPC_MMU_2_07a:
> > >          return ppc_hash64_get_phys_page_debug(cpu, addr);
> > > +    case POWERPC_MMU_3_00:
> > > +        if (ppc64_radix_guest(ppc_env_get_cpu(env))) {
> > > +            /* TODO - Unsupported */
> > > +        } else {
> > > +            if (ppc64_use_proc_tbl(ppc_env_get_cpu(env))) {
> > > +                /* TODO - Unsupported */
> > > +            } else {
> > > +                return ppc_hash64_get_phys_page_debug(cpu, addr);
> > > +            }
> > > +        }
> > > +        break;
> > >  #endif
> > >  
> > >      case POWERPC_MMU_32B:
> > > @@ -2919,3 +2942,27 @@ void ppc64_set_external_patb(PowerPCCPU
> > > *cpu, void *patb, Error **errp)
> > >  
> > >      env->external_patbe = (struct patb_entry *) patb;
> > >  }
> > > +
> > > +inline bool ppc64_use_proc_tbl(PowerPCCPU *cpu)
> > There's basically no point putting an inline on functions that are in
> > a .c rather than a .h (it will only be inlined for callers in this
> > .o,
> > not elsewhere).  These are simple enough that I think they do belong
> > in the .h instead.
> I'll move these into the .h
> > 
> > > 
> > > +{
> > > +    return !!(cpu->env.spr[SPR_LPCR] & LPCR_UPRT);
> > > +}
> > > +
> > > +inline bool ppc64_radix_guest(PowerPCCPU *cpu)
> > > +{
> > > +    struct patb_entry *patbe = cpu->env.external_patbe;
> > > +
> > > +    return patbe && (patbe->patbe1 & PATBE1_GR);
> > > +}
> > > +
> > > +int ppc64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
> > > +                           int mmu_idx)
> > I think this name is too generic, since it's really only right for
> > POWER9 / MMU v3.
> Ok, how about ppc64_v3_handle_mmu_fault?
> > 
> > > 
> > > +{
> > > +    if (ppc64_radix_guest(cpu)) { /* Guest uses radix */
> > > +        /* TODO - Unsupported */
> > > +        error_report("Guest Radix Support Unimplemented\n");
> > > +        abort();
> > > +    } else { /* Guest uses hash */
> > > +        return ppc_hash64_handle_mmu_fault(cpu, eaddr, rwx,
> > > mmu_idx);
> > > +    }
> > > +}
> > > diff --git a/target/ppc/translate_init.c
> > > b/target/ppc/translate_init.c
> > > index c771ba3..87297a7 100644
> > > --- a/target/ppc/translate_init.c
> > > +++ b/target/ppc/translate_init.c
> > > @@ -8850,7 +8850,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void
> > > *data)
> > >                      (1ull << MSR_LE);
> > >      pcc->mmu_model = POWERPC_MMU_3_00;
> > >  #if defined(CONFIG_SOFTMMU)
> > > -    pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
> > > +    pcc->handle_mmu_fault = ppc64_handle_mmu_fault;
> > >      /* segment page size remain the same */
> > >      pcc->sps = &POWER7_POWER8_sps;
> > >  #endif
> 

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 11/17] target/ppc/POWER9: Update to new pte format for POWER9 accesses
  2017-02-09 23:47       ` Suraj Jitindar Singh
@ 2017-02-10  0:21         ` David Gibson
  2017-02-10  1:05           ` Suraj Jitindar Singh
  0 siblings, 1 reply; 53+ messages in thread
From: David Gibson @ 2017-02-10  0:21 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Feb 10, 2017 at 10:47:15AM +1100, Suraj Jitindar Singh wrote:
> On Thu, 2017-02-09 at 14:08 +1100, Suraj Jitindar Singh wrote:
> > On Wed, 2017-02-01 at 15:28 +1100, David Gibson wrote:
> > > 
> > > On Fri, Jan 13, 2017 at 05:28:17PM +1100, Suraj Jitindar Singh
> > > wrote:
> > > > 
> > > > 
> > > > The page table entry format was updated for the POWER9 processor.
> > > > 
> > > > It was decided that kernels would used the old format
> > > > irrespective
> > > > with the translation occuring at the hypervisor level. Thus we
> > > > convert
> > > > between the old and new format when accessing the ptes. Since we
> > > > need the
> > > > whole pte to perform this conversion, we remove the old functions
> > > > which
> > > > accessed either the first or second doubleword and introduce a
> > > > new
> > > > functions which access the entire pte, returning the entry
> > > > converted
> > > > back to the old format (if required). Update call sites
> > > > accordingly.
> > > > 
> > > > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
> > > > ---
> > > >  hw/ppc/spapr_hcall.c    | 51 ++++++++++++++++++-----------------
> > > >  target/ppc/mmu-hash64.c | 13 +++++----
> > > >  target/ppc/mmu-hash64.h | 71
> > > > ++++++++++++++++++++++++++++++++++++-
> > > > ------------
> > > >  3 files changed, 86 insertions(+), 49 deletions(-)
> > > > 
> > > > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> > > > index 9a9bedf..9f0c20d 100644
> > > > --- a/hw/ppc/spapr_hcall.c
> > > > +++ b/hw/ppc/spapr_hcall.c
> > > > @@ -125,7 +125,8 @@ static target_ulong h_enter(PowerPCCPU *cpu,
> > > > sPAPRMachineState *spapr,
> > > >          pte_index &= ~7ULL;
> > > >          token = ppc_hash64_start_access(cpu, pte_index);
> > > >          for (; index < 8; index++) {
> > > > -            if (!(ppc_hash64_load_hpte0(cpu, token, index) &
> > > > HPTE64_V_VALID)) {
> > > > +            ppc_hash_pte64_t pte = ppc_hash64_load_hpte(cpu,
> > > > token, index);
> > > > +            if (!(pte.pte0 & HPTE64_V_VALID)) {
> > > >                  break;
> > > >              }
> > > >          }
> > > > @@ -134,8 +135,10 @@ static target_ulong h_enter(PowerPCCPU *cpu,
> > > > sPAPRMachineState *spapr,
> > > >              return H_PTEG_FULL;
> > > >          }
> > > >      } else {
> > > > +        ppc_hash_pte64_t pte;
> > > >          token = ppc_hash64_start_access(cpu, pte_index);
> > > IIRC the only reason for the clumsy start_access / stop_access
> > > stuff
> > > was because we wanted to do the two loads separately (to avoid
> > > loading
> > > word1 in cases we don't need it).  Since you're combining both
> > > loads
> > > into a single helper, I think you can put the start_access /
> > > stop_access into the same helper.
> > > 
> > > Or have I missed something.
> > > 
> > Yeah these functions can probably be merged together...
> Actually, it looks like we need the start access and stop access stuff
> for kvm-hv where we load the pte into a buffer on start access and free
> it on stop access. So I think we still need to keep these two functions
> separate.

Well, the question is are there any instances where we do more than
just a load word0 + load word1 within the start/stop pair.  I don't
remember off hand.

> > > 
> > > > 
> > > > 
> > > > -        if (ppc_hash64_load_hpte0(cpu, token, 0) &
> > > > HPTE64_V_VALID)
> > > > {
> > > > +        pte = ppc_hash64_load_hpte(cpu, token, 0);
> > > > +        if (pte.pte0 & HPTE64_V_VALID) {
> > > >              ppc_hash64_stop_access(cpu, token);
> > > >              return H_PTEG_FULL;
> > > >          }
> > > > @@ -163,26 +166,25 @@ static RemoveResult remove_hpte(PowerPCCPU
> > > > *cpu, target_ulong ptex,
> > > >  {
> > > >      CPUPPCState *env = &cpu->env;
> > > >      uint64_t token;
> > > > -    target_ulong v, r;
> > > > +    ppc_hash_pte64_t pte;
> > > >  
> > > >      if (!valid_pte_index(env, ptex)) {
> > > >          return REMOVE_PARM;
> > > >      }
> > > >  
> > > >      token = ppc_hash64_start_access(cpu, ptex);
> > > > -    v = ppc_hash64_load_hpte0(cpu, token, 0);
> > > > -    r = ppc_hash64_load_hpte1(cpu, token, 0);
> > > > +    pte = ppc_hash64_load_hpte(cpu, token, 0);
> > > >      ppc_hash64_stop_access(cpu, token);
> > > >  
> > > > -    if ((v & HPTE64_V_VALID) == 0 ||
> > > > -        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) ||
> > > > -        ((flags & H_ANDCOND) && (v & avpn) != 0)) {
> > > > +    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
> > > > +        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn) ||
> > > > +        ((flags & H_ANDCOND) && (pte.pte0 & avpn) != 0)) {
> > > >          return REMOVE_NOT_FOUND;
> > > >      }
> > > > -    *vp = v;
> > > > -    *rp = r;
> > > > +    *vp = pte.pte0;
> > > > +    *rp = pte.pte1;
> > > >      ppc_hash64_store_hpte(cpu, ptex, HPTE64_V_HPTE_DIRTY, 0);
> > > > -    ppc_hash64_tlb_flush_hpte(cpu, ptex, v, r);
> > > > +    ppc_hash64_tlb_flush_hpte(cpu, ptex, pte.pte0, pte.pte1);
> > > >      return REMOVE_SUCCESS;
> > > >  }
> > > >  
> > > > @@ -293,35 +295,36 @@ static target_ulong h_protect(PowerPCCPU
> > > > *cpu, sPAPRMachineState *spapr,
> > > >      target_ulong flags = args[0];
> > > >      target_ulong pte_index = args[1];
> > > >      target_ulong avpn = args[2];
> > > > +    ppc_hash_pte64_t pte;
> > > >      uint64_t token;
> > > > -    target_ulong v, r;
> > > >  
> > > >      if (!valid_pte_index(env, pte_index)) {
> > > >          return H_PARAMETER;
> > > >      }
> > > >  
> > > >      token = ppc_hash64_start_access(cpu, pte_index);
> > > > -    v = ppc_hash64_load_hpte0(cpu, token, 0);
> > > > -    r = ppc_hash64_load_hpte1(cpu, token, 0);
> > > > +    pte = ppc_hash64_load_hpte(cpu, token, 0);
> > > >      ppc_hash64_stop_access(cpu, token);
> > > >  
> > > > -    if ((v & HPTE64_V_VALID) == 0 ||
> > > > -        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {
> > > > +    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
> > > > +        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn)) {
> > > >          return H_NOT_FOUND;
> > > >      }
> > > >  
> > > > -    r &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
> > > > -           HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
> > > > -    r |= (flags << 55) & HPTE64_R_PP0;
> > > > -    r |= (flags << 48) & HPTE64_R_KEY_HI;
> > > > -    r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
> > > > +    pte.pte1 &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
> > > > +                  HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
> > > > +    pte.pte1 |= (flags << 55) & HPTE64_R_PP0;
> > > > +    pte.pte1 |= (flags << 48) & HPTE64_R_KEY_HI;
> > > > +    pte.pte1 |= flags & (HPTE64_R_PP | HPTE64_R_N |
> > > > HPTE64_R_KEY_LO);
> > > >      ppc_hash64_store_hpte(cpu, pte_index,
> > > > -                          (v & ~HPTE64_V_VALID) |
> > > > HPTE64_V_HPTE_DIRTY, 0);
> > > > -    ppc_hash64_tlb_flush_hpte(cpu, pte_index, v, r);
> > > > +                          (pte.pte0 & ~HPTE64_V_VALID) |
> > > > HPTE64_V_HPTE_DIRTY,
> > > > +                          0);
> > > > +    ppc_hash64_tlb_flush_hpte(cpu, pte_index, pte.pte0,
> > > > pte.pte1);
> > > >      /* Flush the tlb */
> > > >      check_tlb_flush(env, true);
> > > >      /* Don't need a memory barrier, due to qemu's global lock */
> > > > -    ppc_hash64_store_hpte(cpu, pte_index, v |
> > > > HPTE64_V_HPTE_DIRTY,
> > > > r);
> > > > +    ppc_hash64_store_hpte(cpu, pte_index, pte.pte0 |
> > > > HPTE64_V_HPTE_DIRTY,
> > > > +                          pte.pte1);
> > > >      return H_SUCCESS;
> > > >  }
> > > >  
> > > > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> > > > index b476b3f..03607d5 100644
> > > > --- a/target/ppc/mmu-hash64.c
> > > > +++ b/target/ppc/mmu-hash64.c
> > > > @@ -515,7 +515,6 @@ static hwaddr
> > > > ppc_hash64_pteg_search(PowerPCCPU
> > > > *cpu, hwaddr hash,
> > > >      CPUPPCState *env = &cpu->env;
> > > >      int i;
> > > >      uint64_t token;
> > > > -    target_ulong pte0, pte1;
> > > >      target_ulong pte_index;
> > > >  
> > > >      pte_index = (hash & env->htab_mask) * HPTES_PER_GROUP;
> > > > @@ -524,12 +523,11 @@ static hwaddr
> > > > ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
> > > >          return -1;
> > > >      }
> > > >      for (i = 0; i < HPTES_PER_GROUP; i++) {
> > > > -        pte0 = ppc_hash64_load_hpte0(cpu, token, i);
> > > > -        pte1 = ppc_hash64_load_hpte1(cpu, token, i);
> > > > +        ppc_hash_pte64_t entry = ppc_hash64_load_hpte(cpu,
> > > > token,
> > > > i);
> > > Hm.  So the hypercalls using the access helpers which include
> > > format
> > > conversion makes sense to me - the hypercalls are defined to use
> > > the
> > > old format, even on POWER9 AIUI.
> > > 
> > > It doesn't really make sense to me here, in what is essentially the
> > > physical implementation of the HPT lookup.  Shouldn't that be using
> > > the new format natively?
> > > 
> > > Basically it seems odd that you store things in the new format in
> > > memory, but convert to the old format on *all* accesses, not just
> > > the
> > > hypercall ones which are defined that way.
> > > 
> > It seemed easier to just do the conversion rather than updating the
> > code in all places. That said since this is modelling the hardware
> > and
> > should probably use the new format instead of just converting it and
> > pretenting nothing changed.
> > > 
> > > > 
> > > > 
> > > >          /* This compares V, B, H (secondary) and the AVPN */
> > > > -        if (HPTE64_V_COMPARE(pte0, ptem)) {
> > > > -            *pshift = hpte_page_shift(sps, pte0, pte1);
> > > > +        if (HPTE64_V_COMPARE(entry.pte0, ptem)) {
> > > > +            *pshift = hpte_page_shift(sps, entry.pte0,
> > > > entry.pte1);
> > > >              /*
> > > >               * If there is no match, ignore the PTE, it could
> > > > simply
> > > >               * be for a different segment size encoding and the
> > > > @@ -543,8 +541,7 @@ static hwaddr
> > > > ppc_hash64_pteg_search(PowerPCCPU
> > > > *cpu, hwaddr hash,
> > > >              /* We don't do anything with pshift yet as qemu TLB
> > > > only deals
> > > >               * with 4K pages anyway
> > > >               */
> > > > -            pte->pte0 = pte0;
> > > > -            pte->pte1 = pte1;
> > > > +            *pte = entry;
> > > >              ppc_hash64_stop_access(cpu, token);
> > > >              return (pte_index + i) * HASH_PTE_SIZE_64;
> > > >          }
> > > > @@ -924,6 +921,8 @@ void ppc_hash64_store_hpte(PowerPCCPU *cpu,
> > > >  {
> > > >      CPUPPCState *env = &cpu->env;
> > > >  
> > > > +    ppc_hash64_hpte_old_to_new(env, &pte0, &pte1);
> > > > +
> > > >      if (env->external_htab == MMU_HASH64_KVM_MANAGED_HPT) {
> > > >          kvmppc_hash64_write_pte(env, pte_index, pte0, pte1);
> > > >          return;
> > > > diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
> > > > index ab5d347..73d7ce4 100644
> > > > --- a/target/ppc/mmu-hash64.h
> > > > +++ b/target/ppc/mmu-hash64.h
> > > > @@ -60,6 +60,7 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
> > > >  #define HASH_PTE_SIZE_64        16
> > > >  #define HASH_PTEG_SIZE_64       (HASH_PTE_SIZE_64 *
> > > > HPTES_PER_GROUP)
> > > >  
> > > > +#define HPTE64_V_3_00_COMMON    0x000fffffffffffffULL
> > > >  #define HPTE64_V_SSIZE_SHIFT    62
> > > >  #define HPTE64_V_AVPN_SHIFT     7
> > > >  #define HPTE64_V_AVPN           0x3fffffffffffff80ULL
> > > > @@ -69,9 +70,12 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
> > > >  #define HPTE64_V_SECONDARY      0x0000000000000002ULL
> > > >  #define HPTE64_V_VALID          0x0000000000000001ULL
> > > >  
> > > > +#define HPTE64_R_3_00_COMMON    0xf1ffffffffffffffULL
> > > >  #define HPTE64_R_PP0            0x8000000000000000ULL
> > > >  #define HPTE64_R_TS             0x4000000000000000ULL
> > > >  #define HPTE64_R_KEY_HI         0x3000000000000000ULL
> > > > +#define HPTE64_R_SSIZE_SHIFT    58
> > > > +#define HPTE64_R_SSIZE_MASK     (3ULL << HPTE64_R_SSIZE_SHIFT)
> > > >  #define HPTE64_R_RPN_SHIFT      12
> > > >  #define HPTE64_R_RPN            0x0ffffffffffff000ULL
> > > >  #define HPTE64_R_FLAGS          0x00000000000003ffULL
> > > > @@ -91,6 +95,10 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
> > > >  #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
> > > >  #define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
> > > >  
> > > > +typedef struct {
> > > > +    uint64_t pte0, pte1;
> > > > +} ppc_hash_pte64_t;
> > > > +
> > > >  void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong value,
> > > >                           Error **errp);
> > > >  void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int
> > > > shift,
> > > > @@ -99,37 +107,64 @@ void ppc_hash64_set_external_hpt(PowerPCCPU
> > > > *cpu, void *hpt, int shift,
> > > >  uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, target_ulong
> > > > pte_index);
> > > >  void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t token);
> > > >  
> > > > -static inline target_ulong ppc_hash64_load_hpte0(PowerPCCPU
> > > > *cpu,
> > > > -                                                 uint64_t token,
> > > > int index)
> > > > +static inline void ppc_hash64_hpte_old_to_new(CPUPPCState *env,
> > > > +                                              target_ulong
> > > > *pte0,
> > > > +                                              target_ulong
> > > > *pte1)
> > > >  {
> > > > -    CPUPPCState *env = &cpu->env;
> > > > -    uint64_t addr;
> > > > +    switch (env->mmu_model) {
> > > > +    case POWERPC_MMU_3_00:
> > > > +        /*
> > > > +         * v3.00 of the ISA moved the B field to the second
> > > > doubleword and
> > > > +         * shortened the abbreviated virtual address and
> > > > abbreviated real page
> > > > +         * number fields
> > > > +         */
> > > > +        *pte1 = (*pte1 & HPTE64_R_3_00_COMMON) |
> > > > +                ((*pte0 >> HPTE64_V_SSIZE_SHIFT) <<
> > > > HPTE64_R_SSIZE_SHIFT);
> > > > +        *pte0 = *pte0 & HPTE64_V_3_00_COMMON;
> > > > +    default:
> > > > +        ;
> > > > +    }
> > > > +}
> > > >  
> > > > -    addr = token + (index * HASH_PTE_SIZE_64);
> > > > -    if (env->external_htab) {
> > > > -        return  ldq_p((const void *)(uintptr_t)addr);
> > > > -    } else {
> > > > -        return ldq_phys(CPU(cpu)->as, addr);
> > > > +static inline void ppc_hash64_hpte_new_to_old(CPUPPCState *env,
> > > > +                                              target_ulong
> > > > *pte0,
> > > > +                                              target_ulong
> > > > *pte1)
> > > > +{
> > > > +    switch (env->mmu_model) {
> > > > +    case POWERPC_MMU_3_00:
> > > > +        /*
> > > > +         * v3.00 of the ISA moved the B field to the second
> > > > doubleword and
> > > > +         * shortened the abbreviated virtual address and
> > > > abbreviated real page
> > > > +         * number fields
> > > > +         */
> > > > +        *pte0 = (*pte0 & HPTE64_V_3_00_COMMON) | ((*pte1 &
> > > > HPTE64_R_SSIZE_MASK)
> > > > +                << (HPTE64_V_SSIZE_SHIFT -
> > > > HPTE64_R_SSIZE_SHIFT));
> > > > +        *pte1 = *pte1 & HPTE64_R_3_00_COMMON;
> > > > +    default:
> > > > +        ;
> > > >      }
> > > >  }
> > > >  
> > > > -static inline target_ulong ppc_hash64_load_hpte1(PowerPCCPU
> > > > *cpu,
> > > > -                                                 uint64_t token,
> > > > int index)
> > > > +static inline ppc_hash_pte64_t ppc_hash64_load_hpte(PowerPCCPU
> > > > *cpu,
> > > > +                                                    uint64_t
> > > > token,
> > > > +                                                    int index)
> > > >  {
> > > >      CPUPPCState *env = &cpu->env;
> > > > +    ppc_hash_pte64_t pte;
> > > >      uint64_t addr;
> > > >  
> > > > -    addr = token + (index * HASH_PTE_SIZE_64) +
> > > > HASH_PTE_SIZE_64/2;
> > > > +    addr = token + (index * HASH_PTE_SIZE_64);
> > > >      if (env->external_htab) {
> > > > -        return  ldq_p((const void *)(uintptr_t)addr);
> > > > +        pte.pte0 = ldq_p((const void *)(uintptr_t)addr);
> > > > +        pte.pte1 = ldq_p((const void *)(uintptr_t)addr +
> > > > HASH_PTE_SIZE_64/2);
> > > >      } else {
> > > > -        return ldq_phys(CPU(cpu)->as, addr);
> > > > +        pte.pte0 = ldq_phys(CPU(cpu)->as, addr);
> > > > +        pte.pte1 = ldq_phys(CPU(cpu)->as, addr +
> > > > HASH_PTE_SIZE_64/2);
> > > >      }
> > > > -}
> > > >  
> > > > -typedef struct {
> > > > -    uint64_t pte0, pte1;
> > > > -} ppc_hash_pte64_t;
> > > > +    ppc_hash64_hpte_new_to_old(env, &pte.pte0, &pte.pte1);
> > > > +    return pte;
> > > > +}
> > > >  
> > > >  #endif /* CONFIG_USER_ONLY */
> > > >  
> 

-- 
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] 53+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 11/17] target/ppc/POWER9: Update to new pte format for POWER9 accesses
  2017-02-10  0:21         ` David Gibson
@ 2017-02-10  1:05           ` Suraj Jitindar Singh
  2017-02-10  2:24             ` David Gibson
  0 siblings, 1 reply; 53+ messages in thread
From: Suraj Jitindar Singh @ 2017-02-10  1:05 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, agraf, qemu-devel

On Fri, 2017-02-10 at 11:21 +1100, David Gibson wrote:
> On Fri, Feb 10, 2017 at 10:47:15AM +1100, Suraj Jitindar Singh wrote:
> > 
> > On Thu, 2017-02-09 at 14:08 +1100, Suraj Jitindar Singh wrote:
> > > 
> > > On Wed, 2017-02-01 at 15:28 +1100, David Gibson wrote:
> > > > 
> > > > 
> > > > On Fri, Jan 13, 2017 at 05:28:17PM +1100, Suraj Jitindar Singh
> > > > wrote:
> > > > > 
> > > > > 
> > > > > 
> > > > > The page table entry format was updated for the POWER9
> > > > > processor.
> > > > > 
> > > > > It was decided that kernels would used the old format
> > > > > irrespective
> > > > > with the translation occuring at the hypervisor level. Thus
> > > > > we
> > > > > convert
> > > > > between the old and new format when accessing the ptes. Since
> > > > > we
> > > > > need the
> > > > > whole pte to perform this conversion, we remove the old
> > > > > functions
> > > > > which
> > > > > accessed either the first or second doubleword and introduce
> > > > > a
> > > > > new
> > > > > functions which access the entire pte, returning the entry
> > > > > converted
> > > > > back to the old format (if required). Update call sites
> > > > > accordingly.
> > > > > 
> > > > > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com
> > > > > >
> > > > > ---
> > > > >  hw/ppc/spapr_hcall.c    | 51 ++++++++++++++++++-------------
> > > > > ----
> > > > >  target/ppc/mmu-hash64.c | 13 +++++----
> > > > >  target/ppc/mmu-hash64.h | 71
> > > > > ++++++++++++++++++++++++++++++++++++-
> > > > > ------------
> > > > >  3 files changed, 86 insertions(+), 49 deletions(-)
> > > > > 
> > > > > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> > > > > index 9a9bedf..9f0c20d 100644
> > > > > --- a/hw/ppc/spapr_hcall.c
> > > > > +++ b/hw/ppc/spapr_hcall.c
> > > > > @@ -125,7 +125,8 @@ static target_ulong h_enter(PowerPCCPU
> > > > > *cpu,
> > > > > sPAPRMachineState *spapr,
> > > > >          pte_index &= ~7ULL;
> > > > >          token = ppc_hash64_start_access(cpu, pte_index);
> > > > >          for (; index < 8; index++) {
> > > > > -            if (!(ppc_hash64_load_hpte0(cpu, token, index) &
> > > > > HPTE64_V_VALID)) {
> > > > > +            ppc_hash_pte64_t pte = ppc_hash64_load_hpte(cpu,
> > > > > token, index);
> > > > > +            if (!(pte.pte0 & HPTE64_V_VALID)) {
> > > > >                  break;
> > > > >              }
> > > > >          }
> > > > > @@ -134,8 +135,10 @@ static target_ulong h_enter(PowerPCCPU
> > > > > *cpu,
> > > > > sPAPRMachineState *spapr,
> > > > >              return H_PTEG_FULL;
> > > > >          }
> > > > >      } else {
> > > > > +        ppc_hash_pte64_t pte;
> > > > >          token = ppc_hash64_start_access(cpu, pte_index);
> > > > IIRC the only reason for the clumsy start_access / stop_access
> > > > stuff
> > > > was because we wanted to do the two loads separately (to avoid
> > > > loading
> > > > word1 in cases we don't need it).  Since you're combining both
> > > > loads
> > > > into a single helper, I think you can put the start_access /
> > > > stop_access into the same helper.
> > > > 
> > > > Or have I missed something.
> > > > 
> > > Yeah these functions can probably be merged together...
> > Actually, it looks like we need the start access and stop access
> > stuff
> > for kvm-hv where we load the pte into a buffer on start access and
> > free
> > it on stop access. So I think we still need to keep these two
> > functions
> > separate.
> Well, the question is are there any instances where we do more than
> just a load word0 + load word1 within the start/stop pair.  I don't
> remember off hand.
> 
Yeah, so the start/stop access gives you a whole page table entry group
and so on KVM this loads the whole pteg into a buffer. We then access
any number of the ptes within that group, meaning we need the
start/stop because otherwise we would be calling into kvm and copying
the ptes 8 times (once per pte in the group) to read a whole group
rather than read it once, access all 8 ptes and then free it.

I can't see a nice way of just having the load without the start/stop
access which doesn't require either multiple calls into kvm to read a
whole group or which requires you to keep a pointer to the group buffer
which is read in on the first access and freed on the last. But this
causes problems when you only access one pte from the group instead of
reading every single one, which does happen, so I think we really need
to leave it as is.
> > 
> > > 
> > > > 
> > > > 
> > > > > 
> > > > > 
> > > > > 
> > > > > -        if (ppc_hash64_load_hpte0(cpu, token, 0) &
> > > > > HPTE64_V_VALID)
> > > > > {
> > > > > +        pte = ppc_hash64_load_hpte(cpu, token, 0);
> > > > > +        if (pte.pte0 & HPTE64_V_VALID) {
> > > > >              ppc_hash64_stop_access(cpu, token);
> > > > >              return H_PTEG_FULL;
> > > > >          }
> > > > > @@ -163,26 +166,25 @@ static RemoveResult
> > > > > remove_hpte(PowerPCCPU
> > > > > *cpu, target_ulong ptex,
> > > > >  {
> > > > >      CPUPPCState *env = &cpu->env;
> > > > >      uint64_t token;
> > > > > -    target_ulong v, r;
> > > > > +    ppc_hash_pte64_t pte;
> > > > >  
> > > > >      if (!valid_pte_index(env, ptex)) {
> > > > >          return REMOVE_PARM;
> > > > >      }
> > > > >  
> > > > >      token = ppc_hash64_start_access(cpu, ptex);
> > > > > -    v = ppc_hash64_load_hpte0(cpu, token, 0);
> > > > > -    r = ppc_hash64_load_hpte1(cpu, token, 0);
> > > > > +    pte = ppc_hash64_load_hpte(cpu, token, 0);
> > > > >      ppc_hash64_stop_access(cpu, token);
> > > > >  
> > > > > -    if ((v & HPTE64_V_VALID) == 0 ||
> > > > > -        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) ||
> > > > > -        ((flags & H_ANDCOND) && (v & avpn) != 0)) {
> > > > > +    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
> > > > > +        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn)
> > > > > ||
> > > > > +        ((flags & H_ANDCOND) && (pte.pte0 & avpn) != 0)) {
> > > > >          return REMOVE_NOT_FOUND;
> > > > >      }
> > > > > -    *vp = v;
> > > > > -    *rp = r;
> > > > > +    *vp = pte.pte0;
> > > > > +    *rp = pte.pte1;
> > > > >      ppc_hash64_store_hpte(cpu, ptex, HPTE64_V_HPTE_DIRTY,
> > > > > 0);
> > > > > -    ppc_hash64_tlb_flush_hpte(cpu, ptex, v, r);
> > > > > +    ppc_hash64_tlb_flush_hpte(cpu, ptex, pte.pte0,
> > > > > pte.pte1);
> > > > >      return REMOVE_SUCCESS;
> > > > >  }
> > > > >  
> > > > > @@ -293,35 +295,36 @@ static target_ulong
> > > > > h_protect(PowerPCCPU
> > > > > *cpu, sPAPRMachineState *spapr,
> > > > >      target_ulong flags = args[0];
> > > > >      target_ulong pte_index = args[1];
> > > > >      target_ulong avpn = args[2];
> > > > > +    ppc_hash_pte64_t pte;
> > > > >      uint64_t token;
> > > > > -    target_ulong v, r;
> > > > >  
> > > > >      if (!valid_pte_index(env, pte_index)) {
> > > > >          return H_PARAMETER;
> > > > >      }
> > > > >  
> > > > >      token = ppc_hash64_start_access(cpu, pte_index);
> > > > > -    v = ppc_hash64_load_hpte0(cpu, token, 0);
> > > > > -    r = ppc_hash64_load_hpte1(cpu, token, 0);
> > > > > +    pte = ppc_hash64_load_hpte(cpu, token, 0);
> > > > >      ppc_hash64_stop_access(cpu, token);
> > > > >  
> > > > > -    if ((v & HPTE64_V_VALID) == 0 ||
> > > > > -        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {
> > > > > +    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
> > > > > +        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn))
> > > > > {
> > > > >          return H_NOT_FOUND;
> > > > >      }
> > > > >  
> > > > > -    r &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
> > > > > -           HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
> > > > > -    r |= (flags << 55) & HPTE64_R_PP0;
> > > > > -    r |= (flags << 48) & HPTE64_R_KEY_HI;
> > > > > -    r |= flags & (HPTE64_R_PP | HPTE64_R_N |
> > > > > HPTE64_R_KEY_LO);
> > > > > +    pte.pte1 &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
> > > > > +                  HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
> > > > > +    pte.pte1 |= (flags << 55) & HPTE64_R_PP0;
> > > > > +    pte.pte1 |= (flags << 48) & HPTE64_R_KEY_HI;
> > > > > +    pte.pte1 |= flags & (HPTE64_R_PP | HPTE64_R_N |
> > > > > HPTE64_R_KEY_LO);
> > > > >      ppc_hash64_store_hpte(cpu, pte_index,
> > > > > -                          (v & ~HPTE64_V_VALID) |
> > > > > HPTE64_V_HPTE_DIRTY, 0);
> > > > > -    ppc_hash64_tlb_flush_hpte(cpu, pte_index, v, r);
> > > > > +                          (pte.pte0 & ~HPTE64_V_VALID) |
> > > > > HPTE64_V_HPTE_DIRTY,
> > > > > +                          0);
> > > > > +    ppc_hash64_tlb_flush_hpte(cpu, pte_index, pte.pte0,
> > > > > pte.pte1);
> > > > >      /* Flush the tlb */
> > > > >      check_tlb_flush(env, true);
> > > > >      /* Don't need a memory barrier, due to qemu's global
> > > > > lock */
> > > > > -    ppc_hash64_store_hpte(cpu, pte_index, v |
> > > > > HPTE64_V_HPTE_DIRTY,
> > > > > r);
> > > > > +    ppc_hash64_store_hpte(cpu, pte_index, pte.pte0 |
> > > > > HPTE64_V_HPTE_DIRTY,
> > > > > +                          pte.pte1);
> > > > >      return H_SUCCESS;
> > > > >  }
> > > > >  
> > > > > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-
> > > > > hash64.c
> > > > > index b476b3f..03607d5 100644
> > > > > --- a/target/ppc/mmu-hash64.c
> > > > > +++ b/target/ppc/mmu-hash64.c
> > > > > @@ -515,7 +515,6 @@ static hwaddr
> > > > > ppc_hash64_pteg_search(PowerPCCPU
> > > > > *cpu, hwaddr hash,
> > > > >      CPUPPCState *env = &cpu->env;
> > > > >      int i;
> > > > >      uint64_t token;
> > > > > -    target_ulong pte0, pte1;
> > > > >      target_ulong pte_index;
> > > > >  
> > > > >      pte_index = (hash & env->htab_mask) * HPTES_PER_GROUP;
> > > > > @@ -524,12 +523,11 @@ static hwaddr
> > > > > ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
> > > > >          return -1;
> > > > >      }
> > > > >      for (i = 0; i < HPTES_PER_GROUP; i++) {
> > > > > -        pte0 = ppc_hash64_load_hpte0(cpu, token, i);
> > > > > -        pte1 = ppc_hash64_load_hpte1(cpu, token, i);
> > > > > +        ppc_hash_pte64_t entry = ppc_hash64_load_hpte(cpu,
> > > > > token,
> > > > > i);
> > > > Hm.  So the hypercalls using the access helpers which include
> > > > format
> > > > conversion makes sense to me - the hypercalls are defined to
> > > > use
> > > > the
> > > > old format, even on POWER9 AIUI.
> > > > 
> > > > It doesn't really make sense to me here, in what is essentially
> > > > the
> > > > physical implementation of the HPT lookup.  Shouldn't that be
> > > > using
> > > > the new format natively?
> > > > 
> > > > Basically it seems odd that you store things in the new format
> > > > in
> > > > memory, but convert to the old format on *all* accesses, not
> > > > just
> > > > the
> > > > hypercall ones which are defined that way.
> > > > 
> > > It seemed easier to just do the conversion rather than updating
> > > the
> > > code in all places. That said since this is modelling the
> > > hardware
> > > and
> > > should probably use the new format instead of just converting it
> > > and
> > > pretenting nothing changed.
> > > > 
> > > > 
> > > > > 
> > > > > 
> > > > > 
> > > > >          /* This compares V, B, H (secondary) and the AVPN */
> > > > > -        if (HPTE64_V_COMPARE(pte0, ptem)) {
> > > > > -            *pshift = hpte_page_shift(sps, pte0, pte1);
> > > > > +        if (HPTE64_V_COMPARE(entry.pte0, ptem)) {
> > > > > +            *pshift = hpte_page_shift(sps, entry.pte0,
> > > > > entry.pte1);
> > > > >              /*
> > > > >               * If there is no match, ignore the PTE, it
> > > > > could
> > > > > simply
> > > > >               * be for a different segment size encoding and
> > > > > the
> > > > > @@ -543,8 +541,7 @@ static hwaddr
> > > > > ppc_hash64_pteg_search(PowerPCCPU
> > > > > *cpu, hwaddr hash,
> > > > >              /* We don't do anything with pshift yet as qemu
> > > > > TLB
> > > > > only deals
> > > > >               * with 4K pages anyway
> > > > >               */
> > > > > -            pte->pte0 = pte0;
> > > > > -            pte->pte1 = pte1;
> > > > > +            *pte = entry;
> > > > >              ppc_hash64_stop_access(cpu, token);
> > > > >              return (pte_index + i) * HASH_PTE_SIZE_64;
> > > > >          }
> > > > > @@ -924,6 +921,8 @@ void ppc_hash64_store_hpte(PowerPCCPU
> > > > > *cpu,
> > > > >  {
> > > > >      CPUPPCState *env = &cpu->env;
> > > > >  
> > > > > +    ppc_hash64_hpte_old_to_new(env, &pte0, &pte1);
> > > > > +
> > > > >      if (env->external_htab == MMU_HASH64_KVM_MANAGED_HPT) {
> > > > >          kvmppc_hash64_write_pte(env, pte_index, pte0, pte1);
> > > > >          return;
> > > > > diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-
> > > > > hash64.h
> > > > > index ab5d347..73d7ce4 100644
> > > > > --- a/target/ppc/mmu-hash64.h
> > > > > +++ b/target/ppc/mmu-hash64.h
> > > > > @@ -60,6 +60,7 @@ void ppc_hash64_update_rmls(CPUPPCState
> > > > > *env);
> > > > >  #define HASH_PTE_SIZE_64        16
> > > > >  #define HASH_PTEG_SIZE_64       (HASH_PTE_SIZE_64 *
> > > > > HPTES_PER_GROUP)
> > > > >  
> > > > > +#define HPTE64_V_3_00_COMMON    0x000fffffffffffffULL
> > > > >  #define HPTE64_V_SSIZE_SHIFT    62
> > > > >  #define HPTE64_V_AVPN_SHIFT     7
> > > > >  #define HPTE64_V_AVPN           0x3fffffffffffff80ULL
> > > > > @@ -69,9 +70,12 @@ void ppc_hash64_update_rmls(CPUPPCState
> > > > > *env);
> > > > >  #define HPTE64_V_SECONDARY      0x0000000000000002ULL
> > > > >  #define HPTE64_V_VALID          0x0000000000000001ULL
> > > > >  
> > > > > +#define HPTE64_R_3_00_COMMON    0xf1ffffffffffffffULL
> > > > >  #define HPTE64_R_PP0            0x8000000000000000ULL
> > > > >  #define HPTE64_R_TS             0x4000000000000000ULL
> > > > >  #define HPTE64_R_KEY_HI         0x3000000000000000ULL
> > > > > +#define HPTE64_R_SSIZE_SHIFT    58
> > > > > +#define HPTE64_R_SSIZE_MASK     (3ULL <<
> > > > > HPTE64_R_SSIZE_SHIFT)
> > > > >  #define HPTE64_R_RPN_SHIFT      12
> > > > >  #define HPTE64_R_RPN            0x0ffffffffffff000ULL
> > > > >  #define HPTE64_R_FLAGS          0x00000000000003ffULL
> > > > > @@ -91,6 +95,10 @@ void ppc_hash64_update_rmls(CPUPPCState
> > > > > *env);
> > > > >  #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
> > > > >  #define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
> > > > >  
> > > > > +typedef struct {
> > > > > +    uint64_t pte0, pte1;
> > > > > +} ppc_hash_pte64_t;
> > > > > +
> > > > >  void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong
> > > > > value,
> > > > >                           Error **errp);
> > > > >  void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt,
> > > > > int
> > > > > shift,
> > > > > @@ -99,37 +107,64 @@ void
> > > > > ppc_hash64_set_external_hpt(PowerPCCPU
> > > > > *cpu, void *hpt, int shift,
> > > > >  uint64_t ppc_hash64_start_access(PowerPCCPU *cpu,
> > > > > target_ulong
> > > > > pte_index);
> > > > >  void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t
> > > > > token);
> > > > >  
> > > > > -static inline target_ulong ppc_hash64_load_hpte0(PowerPCCPU
> > > > > *cpu,
> > > > > -                                                 uint64_t
> > > > > token,
> > > > > int index)
> > > > > +static inline void ppc_hash64_hpte_old_to_new(CPUPPCState
> > > > > *env,
> > > > > +                                              target_ulong
> > > > > *pte0,
> > > > > +                                              target_ulong
> > > > > *pte1)
> > > > >  {
> > > > > -    CPUPPCState *env = &cpu->env;
> > > > > -    uint64_t addr;
> > > > > +    switch (env->mmu_model) {
> > > > > +    case POWERPC_MMU_3_00:
> > > > > +        /*
> > > > > +         * v3.00 of the ISA moved the B field to the second
> > > > > doubleword and
> > > > > +         * shortened the abbreviated virtual address and
> > > > > abbreviated real page
> > > > > +         * number fields
> > > > > +         */
> > > > > +        *pte1 = (*pte1 & HPTE64_R_3_00_COMMON) |
> > > > > +                ((*pte0 >> HPTE64_V_SSIZE_SHIFT) <<
> > > > > HPTE64_R_SSIZE_SHIFT);
> > > > > +        *pte0 = *pte0 & HPTE64_V_3_00_COMMON;
> > > > > +    default:
> > > > > +        ;
> > > > > +    }
> > > > > +}
> > > > >  
> > > > > -    addr = token + (index * HASH_PTE_SIZE_64);
> > > > > -    if (env->external_htab) {
> > > > > -        return  ldq_p((const void *)(uintptr_t)addr);
> > > > > -    } else {
> > > > > -        return ldq_phys(CPU(cpu)->as, addr);
> > > > > +static inline void ppc_hash64_hpte_new_to_old(CPUPPCState
> > > > > *env,
> > > > > +                                              target_ulong
> > > > > *pte0,
> > > > > +                                              target_ulong
> > > > > *pte1)
> > > > > +{
> > > > > +    switch (env->mmu_model) {
> > > > > +    case POWERPC_MMU_3_00:
> > > > > +        /*
> > > > > +         * v3.00 of the ISA moved the B field to the second
> > > > > doubleword and
> > > > > +         * shortened the abbreviated virtual address and
> > > > > abbreviated real page
> > > > > +         * number fields
> > > > > +         */
> > > > > +        *pte0 = (*pte0 & HPTE64_V_3_00_COMMON) | ((*pte1 &
> > > > > HPTE64_R_SSIZE_MASK)
> > > > > +                << (HPTE64_V_SSIZE_SHIFT -
> > > > > HPTE64_R_SSIZE_SHIFT));
> > > > > +        *pte1 = *pte1 & HPTE64_R_3_00_COMMON;
> > > > > +    default:
> > > > > +        ;
> > > > >      }
> > > > >  }
> > > > >  
> > > > > -static inline target_ulong ppc_hash64_load_hpte1(PowerPCCPU
> > > > > *cpu,
> > > > > -                                                 uint64_t
> > > > > token,
> > > > > int index)
> > > > > +static inline ppc_hash_pte64_t
> > > > > ppc_hash64_load_hpte(PowerPCCPU
> > > > > *cpu,
> > > > > +                                                    uint64_t
> > > > > token,
> > > > > +                                                    int
> > > > > index)
> > > > >  {
> > > > >      CPUPPCState *env = &cpu->env;
> > > > > +    ppc_hash_pte64_t pte;
> > > > >      uint64_t addr;
> > > > >  
> > > > > -    addr = token + (index * HASH_PTE_SIZE_64) +
> > > > > HASH_PTE_SIZE_64/2;
> > > > > +    addr = token + (index * HASH_PTE_SIZE_64);
> > > > >      if (env->external_htab) {
> > > > > -        return  ldq_p((const void *)(uintptr_t)addr);
> > > > > +        pte.pte0 = ldq_p((const void *)(uintptr_t)addr);
> > > > > +        pte.pte1 = ldq_p((const void *)(uintptr_t)addr +
> > > > > HASH_PTE_SIZE_64/2);
> > > > >      } else {
> > > > > -        return ldq_phys(CPU(cpu)->as, addr);
> > > > > +        pte.pte0 = ldq_phys(CPU(cpu)->as, addr);
> > > > > +        pte.pte1 = ldq_phys(CPU(cpu)->as, addr +
> > > > > HASH_PTE_SIZE_64/2);
> > > > >      }
> > > > > -}
> > > > >  
> > > > > -typedef struct {
> > > > > -    uint64_t pte0, pte1;
> > > > > -} ppc_hash_pte64_t;
> > > > > +    ppc_hash64_hpte_new_to_old(env, &pte.pte0, &pte.pte1);
> > > > > +    return pte;
> > > > > +}
> > > > >  
> > > > >  #endif /* CONFIG_USER_ONLY */
> > > > >  

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

* Re: [Qemu-devel] [RFC PATCH 11/17] target/ppc/POWER9: Update to new pte format for POWER9 accesses
  2017-02-10  1:05           ` Suraj Jitindar Singh
@ 2017-02-10  2:24             ` David Gibson
  0 siblings, 0 replies; 53+ messages in thread
From: David Gibson @ 2017-02-10  2:24 UTC (permalink / raw)
  To: Suraj Jitindar Singh; +Cc: qemu-ppc, agraf, qemu-devel

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

On Fri, Feb 10, 2017 at 12:05:38PM +1100, Suraj Jitindar Singh wrote:
> On Fri, 2017-02-10 at 11:21 +1100, David Gibson wrote:
> > On Fri, Feb 10, 2017 at 10:47:15AM +1100, Suraj Jitindar Singh wrote:
> > > 
> > > On Thu, 2017-02-09 at 14:08 +1100, Suraj Jitindar Singh wrote:
> > > > 
> > > > On Wed, 2017-02-01 at 15:28 +1100, David Gibson wrote:
> > > > > 
> > > > > 
> > > > > On Fri, Jan 13, 2017 at 05:28:17PM +1100, Suraj Jitindar Singh
> > > > > wrote:
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > > The page table entry format was updated for the POWER9
> > > > > > processor.
> > > > > > 
> > > > > > It was decided that kernels would used the old format
> > > > > > irrespective
> > > > > > with the translation occuring at the hypervisor level. Thus
> > > > > > we
> > > > > > convert
> > > > > > between the old and new format when accessing the ptes. Since
> > > > > > we
> > > > > > need the
> > > > > > whole pte to perform this conversion, we remove the old
> > > > > > functions
> > > > > > which
> > > > > > accessed either the first or second doubleword and introduce
> > > > > > a
> > > > > > new
> > > > > > functions which access the entire pte, returning the entry
> > > > > > converted
> > > > > > back to the old format (if required). Update call sites
> > > > > > accordingly.
> > > > > > 
> > > > > > Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com
> > > > > > >
> > > > > > ---
> > > > > >  hw/ppc/spapr_hcall.c    | 51 ++++++++++++++++++-------------
> > > > > > ----
> > > > > >  target/ppc/mmu-hash64.c | 13 +++++----
> > > > > >  target/ppc/mmu-hash64.h | 71
> > > > > > ++++++++++++++++++++++++++++++++++++-
> > > > > > ------------
> > > > > >  3 files changed, 86 insertions(+), 49 deletions(-)
> > > > > > 
> > > > > > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> > > > > > index 9a9bedf..9f0c20d 100644
> > > > > > --- a/hw/ppc/spapr_hcall.c
> > > > > > +++ b/hw/ppc/spapr_hcall.c
> > > > > > @@ -125,7 +125,8 @@ static target_ulong h_enter(PowerPCCPU
> > > > > > *cpu,
> > > > > > sPAPRMachineState *spapr,
> > > > > >          pte_index &= ~7ULL;
> > > > > >          token = ppc_hash64_start_access(cpu, pte_index);
> > > > > >          for (; index < 8; index++) {
> > > > > > -            if (!(ppc_hash64_load_hpte0(cpu, token, index) &
> > > > > > HPTE64_V_VALID)) {
> > > > > > +            ppc_hash_pte64_t pte = ppc_hash64_load_hpte(cpu,
> > > > > > token, index);
> > > > > > +            if (!(pte.pte0 & HPTE64_V_VALID)) {
> > > > > >                  break;
> > > > > >              }
> > > > > >          }
> > > > > > @@ -134,8 +135,10 @@ static target_ulong h_enter(PowerPCCPU
> > > > > > *cpu,
> > > > > > sPAPRMachineState *spapr,
> > > > > >              return H_PTEG_FULL;
> > > > > >          }
> > > > > >      } else {
> > > > > > +        ppc_hash_pte64_t pte;
> > > > > >          token = ppc_hash64_start_access(cpu, pte_index);
> > > > > IIRC the only reason for the clumsy start_access / stop_access
> > > > > stuff
> > > > > was because we wanted to do the two loads separately (to avoid
> > > > > loading
> > > > > word1 in cases we don't need it).  Since you're combining both
> > > > > loads
> > > > > into a single helper, I think you can put the start_access /
> > > > > stop_access into the same helper.
> > > > > 
> > > > > Or have I missed something.
> > > > > 
> > > > Yeah these functions can probably be merged together...
> > > Actually, it looks like we need the start access and stop access
> > > stuff
> > > for kvm-hv where we load the pte into a buffer on start access and
> > > free
> > > it on stop access. So I think we still need to keep these two
> > > functions
> > > separate.
> > Well, the question is are there any instances where we do more than
> > just a load word0 + load word1 within the start/stop pair.  I don't
> > remember off hand.
> > 
> Yeah, so the start/stop access gives you a whole page table entry group
> and so on KVM this loads the whole pteg into a buffer. We then access
> any number of the ptes within that group, meaning we need the
> start/stop because otherwise we would be calling into kvm and copying
> the ptes 8 times (once per pte in the group) to read a whole group
> rather than read it once, access all 8 ptes and then free it.
> 
> I can't see a nice way of just having the load without the start/stop
> access which doesn't require either multiple calls into kvm to read a
> whole group or which requires you to keep a pointer to the group buffer
> which is read in on the first access and freed on the last. But this
> causes problems when you only access one pte from the group instead of
> reading every single one, which does happen, so I think we really need
> to leave it as is.

Ok, fair enough.

> > > 
> > > > 
> > > > > 
> > > > > 
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > > -        if (ppc_hash64_load_hpte0(cpu, token, 0) &
> > > > > > HPTE64_V_VALID)
> > > > > > {
> > > > > > +        pte = ppc_hash64_load_hpte(cpu, token, 0);
> > > > > > +        if (pte.pte0 & HPTE64_V_VALID) {
> > > > > >              ppc_hash64_stop_access(cpu, token);
> > > > > >              return H_PTEG_FULL;
> > > > > >          }
> > > > > > @@ -163,26 +166,25 @@ static RemoveResult
> > > > > > remove_hpte(PowerPCCPU
> > > > > > *cpu, target_ulong ptex,
> > > > > >  {
> > > > > >      CPUPPCState *env = &cpu->env;
> > > > > >      uint64_t token;
> > > > > > -    target_ulong v, r;
> > > > > > +    ppc_hash_pte64_t pte;
> > > > > >  
> > > > > >      if (!valid_pte_index(env, ptex)) {
> > > > > >          return REMOVE_PARM;
> > > > > >      }
> > > > > >  
> > > > > >      token = ppc_hash64_start_access(cpu, ptex);
> > > > > > -    v = ppc_hash64_load_hpte0(cpu, token, 0);
> > > > > > -    r = ppc_hash64_load_hpte1(cpu, token, 0);
> > > > > > +    pte = ppc_hash64_load_hpte(cpu, token, 0);
> > > > > >      ppc_hash64_stop_access(cpu, token);
> > > > > >  
> > > > > > -    if ((v & HPTE64_V_VALID) == 0 ||
> > > > > > -        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) ||
> > > > > > -        ((flags & H_ANDCOND) && (v & avpn) != 0)) {
> > > > > > +    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
> > > > > > +        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn)
> > > > > > ||
> > > > > > +        ((flags & H_ANDCOND) && (pte.pte0 & avpn) != 0)) {
> > > > > >          return REMOVE_NOT_FOUND;
> > > > > >      }
> > > > > > -    *vp = v;
> > > > > > -    *rp = r;
> > > > > > +    *vp = pte.pte0;
> > > > > > +    *rp = pte.pte1;
> > > > > >      ppc_hash64_store_hpte(cpu, ptex, HPTE64_V_HPTE_DIRTY,
> > > > > > 0);
> > > > > > -    ppc_hash64_tlb_flush_hpte(cpu, ptex, v, r);
> > > > > > +    ppc_hash64_tlb_flush_hpte(cpu, ptex, pte.pte0,
> > > > > > pte.pte1);
> > > > > >      return REMOVE_SUCCESS;
> > > > > >  }
> > > > > >  
> > > > > > @@ -293,35 +295,36 @@ static target_ulong
> > > > > > h_protect(PowerPCCPU
> > > > > > *cpu, sPAPRMachineState *spapr,
> > > > > >      target_ulong flags = args[0];
> > > > > >      target_ulong pte_index = args[1];
> > > > > >      target_ulong avpn = args[2];
> > > > > > +    ppc_hash_pte64_t pte;
> > > > > >      uint64_t token;
> > > > > > -    target_ulong v, r;
> > > > > >  
> > > > > >      if (!valid_pte_index(env, pte_index)) {
> > > > > >          return H_PARAMETER;
> > > > > >      }
> > > > > >  
> > > > > >      token = ppc_hash64_start_access(cpu, pte_index);
> > > > > > -    v = ppc_hash64_load_hpte0(cpu, token, 0);
> > > > > > -    r = ppc_hash64_load_hpte1(cpu, token, 0);
> > > > > > +    pte = ppc_hash64_load_hpte(cpu, token, 0);
> > > > > >      ppc_hash64_stop_access(cpu, token);
> > > > > >  
> > > > > > -    if ((v & HPTE64_V_VALID) == 0 ||
> > > > > > -        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {
> > > > > > +    if ((pte.pte0 & HPTE64_V_VALID) == 0 ||
> > > > > > +        ((flags & H_AVPN) && (pte.pte0 & ~0x7fULL) != avpn))
> > > > > > {
> > > > > >          return H_NOT_FOUND;
> > > > > >      }
> > > > > >  
> > > > > > -    r &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
> > > > > > -           HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
> > > > > > -    r |= (flags << 55) & HPTE64_R_PP0;
> > > > > > -    r |= (flags << 48) & HPTE64_R_KEY_HI;
> > > > > > -    r |= flags & (HPTE64_R_PP | HPTE64_R_N |
> > > > > > HPTE64_R_KEY_LO);
> > > > > > +    pte.pte1 &= ~(HPTE64_R_PP0 | HPTE64_R_PP | HPTE64_R_N |
> > > > > > +                  HPTE64_R_KEY_HI | HPTE64_R_KEY_LO);
> > > > > > +    pte.pte1 |= (flags << 55) & HPTE64_R_PP0;
> > > > > > +    pte.pte1 |= (flags << 48) & HPTE64_R_KEY_HI;
> > > > > > +    pte.pte1 |= flags & (HPTE64_R_PP | HPTE64_R_N |
> > > > > > HPTE64_R_KEY_LO);
> > > > > >      ppc_hash64_store_hpte(cpu, pte_index,
> > > > > > -                          (v & ~HPTE64_V_VALID) |
> > > > > > HPTE64_V_HPTE_DIRTY, 0);
> > > > > > -    ppc_hash64_tlb_flush_hpte(cpu, pte_index, v, r);
> > > > > > +                          (pte.pte0 & ~HPTE64_V_VALID) |
> > > > > > HPTE64_V_HPTE_DIRTY,
> > > > > > +                          0);
> > > > > > +    ppc_hash64_tlb_flush_hpte(cpu, pte_index, pte.pte0,
> > > > > > pte.pte1);
> > > > > >      /* Flush the tlb */
> > > > > >      check_tlb_flush(env, true);
> > > > > >      /* Don't need a memory barrier, due to qemu's global
> > > > > > lock */
> > > > > > -    ppc_hash64_store_hpte(cpu, pte_index, v |
> > > > > > HPTE64_V_HPTE_DIRTY,
> > > > > > r);
> > > > > > +    ppc_hash64_store_hpte(cpu, pte_index, pte.pte0 |
> > > > > > HPTE64_V_HPTE_DIRTY,
> > > > > > +                          pte.pte1);
> > > > > >      return H_SUCCESS;
> > > > > >  }
> > > > > >  
> > > > > > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-
> > > > > > hash64.c
> > > > > > index b476b3f..03607d5 100644
> > > > > > --- a/target/ppc/mmu-hash64.c
> > > > > > +++ b/target/ppc/mmu-hash64.c
> > > > > > @@ -515,7 +515,6 @@ static hwaddr
> > > > > > ppc_hash64_pteg_search(PowerPCCPU
> > > > > > *cpu, hwaddr hash,
> > > > > >      CPUPPCState *env = &cpu->env;
> > > > > >      int i;
> > > > > >      uint64_t token;
> > > > > > -    target_ulong pte0, pte1;
> > > > > >      target_ulong pte_index;
> > > > > >  
> > > > > >      pte_index = (hash & env->htab_mask) * HPTES_PER_GROUP;
> > > > > > @@ -524,12 +523,11 @@ static hwaddr
> > > > > > ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
> > > > > >          return -1;
> > > > > >      }
> > > > > >      for (i = 0; i < HPTES_PER_GROUP; i++) {
> > > > > > -        pte0 = ppc_hash64_load_hpte0(cpu, token, i);
> > > > > > -        pte1 = ppc_hash64_load_hpte1(cpu, token, i);
> > > > > > +        ppc_hash_pte64_t entry = ppc_hash64_load_hpte(cpu,
> > > > > > token,
> > > > > > i);
> > > > > Hm.  So the hypercalls using the access helpers which include
> > > > > format
> > > > > conversion makes sense to me - the hypercalls are defined to
> > > > > use
> > > > > the
> > > > > old format, even on POWER9 AIUI.
> > > > > 
> > > > > It doesn't really make sense to me here, in what is essentially
> > > > > the
> > > > > physical implementation of the HPT lookup.  Shouldn't that be
> > > > > using
> > > > > the new format natively?
> > > > > 
> > > > > Basically it seems odd that you store things in the new format
> > > > > in
> > > > > memory, but convert to the old format on *all* accesses, not
> > > > > just
> > > > > the
> > > > > hypercall ones which are defined that way.
> > > > > 
> > > > It seemed easier to just do the conversion rather than updating
> > > > the
> > > > code in all places. That said since this is modelling the
> > > > hardware
> > > > and
> > > > should probably use the new format instead of just converting it
> > > > and
> > > > pretenting nothing changed.
> > > > > 
> > > > > 
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > >          /* This compares V, B, H (secondary) and the AVPN */
> > > > > > -        if (HPTE64_V_COMPARE(pte0, ptem)) {
> > > > > > -            *pshift = hpte_page_shift(sps, pte0, pte1);
> > > > > > +        if (HPTE64_V_COMPARE(entry.pte0, ptem)) {
> > > > > > +            *pshift = hpte_page_shift(sps, entry.pte0,
> > > > > > entry.pte1);
> > > > > >              /*
> > > > > >               * If there is no match, ignore the PTE, it
> > > > > > could
> > > > > > simply
> > > > > >               * be for a different segment size encoding and
> > > > > > the
> > > > > > @@ -543,8 +541,7 @@ static hwaddr
> > > > > > ppc_hash64_pteg_search(PowerPCCPU
> > > > > > *cpu, hwaddr hash,
> > > > > >              /* We don't do anything with pshift yet as qemu
> > > > > > TLB
> > > > > > only deals
> > > > > >               * with 4K pages anyway
> > > > > >               */
> > > > > > -            pte->pte0 = pte0;
> > > > > > -            pte->pte1 = pte1;
> > > > > > +            *pte = entry;
> > > > > >              ppc_hash64_stop_access(cpu, token);
> > > > > >              return (pte_index + i) * HASH_PTE_SIZE_64;
> > > > > >          }
> > > > > > @@ -924,6 +921,8 @@ void ppc_hash64_store_hpte(PowerPCCPU
> > > > > > *cpu,
> > > > > >  {
> > > > > >      CPUPPCState *env = &cpu->env;
> > > > > >  
> > > > > > +    ppc_hash64_hpte_old_to_new(env, &pte0, &pte1);
> > > > > > +
> > > > > >      if (env->external_htab == MMU_HASH64_KVM_MANAGED_HPT) {
> > > > > >          kvmppc_hash64_write_pte(env, pte_index, pte0, pte1);
> > > > > >          return;
> > > > > > diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-
> > > > > > hash64.h
> > > > > > index ab5d347..73d7ce4 100644
> > > > > > --- a/target/ppc/mmu-hash64.h
> > > > > > +++ b/target/ppc/mmu-hash64.h
> > > > > > @@ -60,6 +60,7 @@ void ppc_hash64_update_rmls(CPUPPCState
> > > > > > *env);
> > > > > >  #define HASH_PTE_SIZE_64        16
> > > > > >  #define HASH_PTEG_SIZE_64       (HASH_PTE_SIZE_64 *
> > > > > > HPTES_PER_GROUP)
> > > > > >  
> > > > > > +#define HPTE64_V_3_00_COMMON    0x000fffffffffffffULL
> > > > > >  #define HPTE64_V_SSIZE_SHIFT    62
> > > > > >  #define HPTE64_V_AVPN_SHIFT     7
> > > > > >  #define HPTE64_V_AVPN           0x3fffffffffffff80ULL
> > > > > > @@ -69,9 +70,12 @@ void ppc_hash64_update_rmls(CPUPPCState
> > > > > > *env);
> > > > > >  #define HPTE64_V_SECONDARY      0x0000000000000002ULL
> > > > > >  #define HPTE64_V_VALID          0x0000000000000001ULL
> > > > > >  
> > > > > > +#define HPTE64_R_3_00_COMMON    0xf1ffffffffffffffULL
> > > > > >  #define HPTE64_R_PP0            0x8000000000000000ULL
> > > > > >  #define HPTE64_R_TS             0x4000000000000000ULL
> > > > > >  #define HPTE64_R_KEY_HI         0x3000000000000000ULL
> > > > > > +#define HPTE64_R_SSIZE_SHIFT    58
> > > > > > +#define HPTE64_R_SSIZE_MASK     (3ULL <<
> > > > > > HPTE64_R_SSIZE_SHIFT)
> > > > > >  #define HPTE64_R_RPN_SHIFT      12
> > > > > >  #define HPTE64_R_RPN            0x0ffffffffffff000ULL
> > > > > >  #define HPTE64_R_FLAGS          0x00000000000003ffULL
> > > > > > @@ -91,6 +95,10 @@ void ppc_hash64_update_rmls(CPUPPCState
> > > > > > *env);
> > > > > >  #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
> > > > > >  #define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
> > > > > >  
> > > > > > +typedef struct {
> > > > > > +    uint64_t pte0, pte1;
> > > > > > +} ppc_hash_pte64_t;
> > > > > > +
> > > > > >  void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong
> > > > > > value,
> > > > > >                           Error **errp);
> > > > > >  void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt,
> > > > > > int
> > > > > > shift,
> > > > > > @@ -99,37 +107,64 @@ void
> > > > > > ppc_hash64_set_external_hpt(PowerPCCPU
> > > > > > *cpu, void *hpt, int shift,
> > > > > >  uint64_t ppc_hash64_start_access(PowerPCCPU *cpu,
> > > > > > target_ulong
> > > > > > pte_index);
> > > > > >  void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t
> > > > > > token);
> > > > > >  
> > > > > > -static inline target_ulong ppc_hash64_load_hpte0(PowerPCCPU
> > > > > > *cpu,
> > > > > > -                                                 uint64_t
> > > > > > token,
> > > > > > int index)
> > > > > > +static inline void ppc_hash64_hpte_old_to_new(CPUPPCState
> > > > > > *env,
> > > > > > +                                              target_ulong
> > > > > > *pte0,
> > > > > > +                                              target_ulong
> > > > > > *pte1)
> > > > > >  {
> > > > > > -    CPUPPCState *env = &cpu->env;
> > > > > > -    uint64_t addr;
> > > > > > +    switch (env->mmu_model) {
> > > > > > +    case POWERPC_MMU_3_00:
> > > > > > +        /*
> > > > > > +         * v3.00 of the ISA moved the B field to the second
> > > > > > doubleword and
> > > > > > +         * shortened the abbreviated virtual address and
> > > > > > abbreviated real page
> > > > > > +         * number fields
> > > > > > +         */
> > > > > > +        *pte1 = (*pte1 & HPTE64_R_3_00_COMMON) |
> > > > > > +                ((*pte0 >> HPTE64_V_SSIZE_SHIFT) <<
> > > > > > HPTE64_R_SSIZE_SHIFT);
> > > > > > +        *pte0 = *pte0 & HPTE64_V_3_00_COMMON;
> > > > > > +    default:
> > > > > > +        ;
> > > > > > +    }
> > > > > > +}
> > > > > >  
> > > > > > -    addr = token + (index * HASH_PTE_SIZE_64);
> > > > > > -    if (env->external_htab) {
> > > > > > -        return  ldq_p((const void *)(uintptr_t)addr);
> > > > > > -    } else {
> > > > > > -        return ldq_phys(CPU(cpu)->as, addr);
> > > > > > +static inline void ppc_hash64_hpte_new_to_old(CPUPPCState
> > > > > > *env,
> > > > > > +                                              target_ulong
> > > > > > *pte0,
> > > > > > +                                              target_ulong
> > > > > > *pte1)
> > > > > > +{
> > > > > > +    switch (env->mmu_model) {
> > > > > > +    case POWERPC_MMU_3_00:
> > > > > > +        /*
> > > > > > +         * v3.00 of the ISA moved the B field to the second
> > > > > > doubleword and
> > > > > > +         * shortened the abbreviated virtual address and
> > > > > > abbreviated real page
> > > > > > +         * number fields
> > > > > > +         */
> > > > > > +        *pte0 = (*pte0 & HPTE64_V_3_00_COMMON) | ((*pte1 &
> > > > > > HPTE64_R_SSIZE_MASK)
> > > > > > +                << (HPTE64_V_SSIZE_SHIFT -
> > > > > > HPTE64_R_SSIZE_SHIFT));
> > > > > > +        *pte1 = *pte1 & HPTE64_R_3_00_COMMON;
> > > > > > +    default:
> > > > > > +        ;
> > > > > >      }
> > > > > >  }
> > > > > >  
> > > > > > -static inline target_ulong ppc_hash64_load_hpte1(PowerPCCPU
> > > > > > *cpu,
> > > > > > -                                                 uint64_t
> > > > > > token,
> > > > > > int index)
> > > > > > +static inline ppc_hash_pte64_t
> > > > > > ppc_hash64_load_hpte(PowerPCCPU
> > > > > > *cpu,
> > > > > > +                                                    uint64_t
> > > > > > token,
> > > > > > +                                                    int
> > > > > > index)
> > > > > >  {
> > > > > >      CPUPPCState *env = &cpu->env;
> > > > > > +    ppc_hash_pte64_t pte;
> > > > > >      uint64_t addr;
> > > > > >  
> > > > > > -    addr = token + (index * HASH_PTE_SIZE_64) +
> > > > > > HASH_PTE_SIZE_64/2;
> > > > > > +    addr = token + (index * HASH_PTE_SIZE_64);
> > > > > >      if (env->external_htab) {
> > > > > > -        return  ldq_p((const void *)(uintptr_t)addr);
> > > > > > +        pte.pte0 = ldq_p((const void *)(uintptr_t)addr);
> > > > > > +        pte.pte1 = ldq_p((const void *)(uintptr_t)addr +
> > > > > > HASH_PTE_SIZE_64/2);
> > > > > >      } else {
> > > > > > -        return ldq_phys(CPU(cpu)->as, addr);
> > > > > > +        pte.pte0 = ldq_phys(CPU(cpu)->as, addr);
> > > > > > +        pte.pte1 = ldq_phys(CPU(cpu)->as, addr +
> > > > > > HASH_PTE_SIZE_64/2);
> > > > > >      }
> > > > > > -}
> > > > > >  
> > > > > > -typedef struct {
> > > > > > -    uint64_t pte0, pte1;
> > > > > > -} ppc_hash_pte64_t;
> > > > > > +    ppc_hash64_hpte_new_to_old(env, &pte.pte0, &pte.pte1);
> > > > > > +    return pte;
> > > > > > +}
> > > > > >  
> > > > > >  #endif /* CONFIG_USER_ONLY */
> > > > > >  
> 

-- 
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] 53+ messages in thread

end of thread, other threads:[~2017-02-10  2:39 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-13  6:28 [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support Suraj Jitindar Singh
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 01/17] powerpc/cpu-models: rename ISAv3.00 logical PVR definition Suraj Jitindar Singh
2017-01-16  2:16   ` David Gibson
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 02/17] hw/ppc/spapr: Add POWER9 to pseries cpu models Suraj Jitindar Singh
2017-01-16 12:11   ` David Gibson
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 03/17] target/ppc: Add pcr_supported to POWER9 cpu class definition Suraj Jitindar Singh
2017-01-16 21:21   ` David Gibson
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 04/17] target/ppc/POWER9: Add ISAv3.00 MMU definition Suraj Jitindar Singh
2017-01-16 21:36   ` David Gibson
2017-01-17  0:33     ` Suraj Jitindar Singh
2017-01-23  5:01       ` Suraj Jitindar Singh
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 05/17] target/ppc/POWER9: Adapt LPCR handling for POWER9 Suraj Jitindar Singh
2017-01-16 21:40   ` David Gibson
2017-01-17  0:48     ` Suraj Jitindar Singh
2017-01-17  4:37       ` David Gibson
2017-01-23  4:19         ` Suraj Jitindar Singh
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 06/17] target/ppc/POWER9: Direct all instr and data storage interrupts to the hypv Suraj Jitindar Singh
2017-02-01  0:50   ` David Gibson
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 07/17] target/ppc/POWER9: Add partition table pointer to sPAPRMachineState Suraj Jitindar Singh
2017-02-01  4:04   ` David Gibson
2017-02-09  2:57     ` Suraj Jitindar Singh
2017-02-10  0:11       ` David Gibson
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 08/17] target/ppc/POWER9: Add external partition table pointer to cpu state Suraj Jitindar Singh
2017-02-01  4:09   ` David Gibson
2017-02-09  2:58     ` Suraj Jitindar Singh
2017-02-10  0:11       ` David Gibson
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 09/17] target/ppc/POWER9: Remove SDR1 register Suraj Jitindar Singh
2017-02-01  4:16   ` David Gibson
2017-02-09  3:00     ` Suraj Jitindar Singh
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 10/17] target/ppc/POWER9: Add POWER9 mmu fault handler Suraj Jitindar Singh
2017-02-01  4:23   ` David Gibson
2017-02-09  3:04     ` Suraj Jitindar Singh
2017-02-10  0:16       ` David Gibson
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 11/17] target/ppc/POWER9: Update to new pte format for POWER9 accesses Suraj Jitindar Singh
2017-02-01  4:28   ` David Gibson
2017-02-09  3:08     ` Suraj Jitindar Singh
2017-02-09 23:47       ` Suraj Jitindar Singh
2017-02-10  0:21         ` David Gibson
2017-02-10  1:05           ` Suraj Jitindar Singh
2017-02-10  2:24             ` David Gibson
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 12/17] target/ppc/POWER9: Add POWER9 pa-features definition Suraj Jitindar Singh
2017-02-01  4:29   ` David Gibson
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 13/17] target/ppc/POWER9: Add cpu_has_work function for POWER9 Suraj Jitindar Singh
2017-02-01  4:34   ` David Gibson
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 14/17] target/ppc/debug: Print LPCR register value if register exists Suraj Jitindar Singh
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 15/17] tcg/POWER9: NOOP the cp_abort instruction Suraj Jitindar Singh
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 16/17] target/ppc/mmu_hash64: Fix printing unsigned as signed int Suraj Jitindar Singh
2017-01-13  6:28 ` [Qemu-devel] [RFC PATCH 17/17] target/ppc/mmu_hash64: Fix incorrect shift value in amr calculation Suraj Jitindar Singh
2017-01-13  6:55 ` [Qemu-devel] [RFC PATCH 00/17] target/ppc: Implement POWER9 pseries tcg legacy kernel support no-reply
2017-02-01  1:04   ` David Gibson
2017-02-09  3:09     ` Suraj Jitindar Singh
2017-02-01  2:16 ` David Gibson
2017-02-01  2:22   ` 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.