All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 0/4] target/ppc: add hash MMU support for the POWER9 PowerNV machine
@ 2018-03-15 13:33 Cédric Le Goater
  2018-03-15 13:33 ` [Qemu-devel] [PATCH v3 1/4] target/ppc: export external HPT via virtual hypervisor Cédric Le Goater
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Cédric Le Goater @ 2018-03-15 13:33 UTC (permalink / raw)
  To: qemu-ppc, qemu-devel, David Gibson
  Cc: Suraj Jitindar Singh, Cédric Le Goater

Hello,

This adds support for the Hash Page Table MMU mode on POWER9 PowerNV
machines. The Radix Tree mode support for the host is still to be done
but we are getting close. 

Thanks,

C. 

Changes since v2:

 - extended PPCVirtualHypervisor interface to export the external HPT
 - added an assert on MMU model in ppc_store_ptcr()
 - reworked ppc_hash64_hpt_reg() to cover only powernv machines. pseries
   machines being handled with cpu->vhyp at the ppc_hash64_hpt_base()
   level.
 - reworked ppc64_v3_radix() to distinguish pseries machine from
   powernv machines


Changes since v1:

 - introduced ppc64_v3_get_patbe0()
 - renamed ppc64_radix() in ppc64_v3_radix()
 - renamed partition table definitions to match ISA
 - moved definitions under mmu-book3s-v3.h
 
Cédric Le Goater (4):
  target/ppc: export external HPT via virtual hypervisor
  target/ppc: add basic support for PTCR on POWER9
  target/ppc: add hash MMU support on POWER9 for PowerNV only
  target/ppc: generalize check on radix when in HV mode

 hw/ppc/spapr.c              |  8 +++++++
 hw/ppc/spapr_hcall.c        |  5 +++--
 target/ppc/cpu.h            |  3 +++
 target/ppc/helper.h         |  1 +
 target/ppc/misc_helper.c    | 12 +++++++++++
 target/ppc/mmu-book3s-v3.c  | 23 ++++++++++++++++++--
 target/ppc/mmu-book3s-v3.h  | 15 ++++++++++++-
 target/ppc/mmu-hash64.c     | 52 +++++++++++++++++++++++++++++++++++++--------
 target/ppc/mmu-hash64.h     | 39 ++++++++++++++++++++++++++++++++--
 target/ppc/mmu_helper.c     | 33 ++++++++++++++++++++++++++--
 target/ppc/translate.c      |  3 +++
 target/ppc/translate_init.c | 18 ++++++++++++++++
 12 files changed, 194 insertions(+), 18 deletions(-)

-- 
2.13.6

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

* [Qemu-devel] [PATCH v3 1/4] target/ppc: export external HPT via virtual hypervisor
  2018-03-15 13:33 [Qemu-devel] [PATCH v3 0/4] target/ppc: add hash MMU support for the POWER9 PowerNV machine Cédric Le Goater
@ 2018-03-15 13:33 ` Cédric Le Goater
  2018-03-17  4:15   ` David Gibson
  2018-03-15 13:34 ` [Qemu-devel] [PATCH v3 2/4] target/ppc: add basic support for PTCR on POWER9 Cédric Le Goater
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Cédric Le Goater @ 2018-03-15 13:33 UTC (permalink / raw)
  To: qemu-ppc, qemu-devel, David Gibson
  Cc: Suraj Jitindar Singh, Cédric Le Goater

commit e57ca75ce3b2 ("target/ppc: Manage external HPT via virtual
hypervisor") exported a set of methods to manipulate the HPT from the
core hash MMU but the base address of the HPT was not part of them and
SPR_SDR1 is still used under some circumstances, which is incorrect
for the sPAPR machines.

This is not a major change as only the logging should be impacted but
nevertheless, it will help to introduce support for the hash MMU on
POWER9 PowerNV machines.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 hw/ppc/spapr.c          | 8 ++++++++
 target/ppc/cpu.h        | 1 +
 target/ppc/mmu-hash64.h | 5 +++++
 3 files changed, 14 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f1798457bc4d..2329664e0c2c 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1327,6 +1327,13 @@ static hwaddr spapr_hpt_mask(PPCVirtualHypervisor *vhyp)
     return HTAB_SIZE(spapr) / HASH_PTEG_SIZE_64 - 1;
 }
 
+static hwaddr spapr_hpt_base(PPCVirtualHypervisor *vhyp)
+{
+    sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
+
+    return (hwaddr) spapr->htab;
+}
+
 static target_ulong spapr_encode_hpt_for_kvm_pr(PPCVirtualHypervisor *vhyp)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
@@ -4073,6 +4080,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     smc->phb_placement = spapr_phb_placement;
     vhc->hypercall = emulate_spapr_hypercall;
     vhc->hpt_mask = spapr_hpt_mask;
+    vhc->hpt_base = spapr_hpt_base;
     vhc->map_hptes = spapr_map_hptes;
     vhc->unmap_hptes = spapr_unmap_hptes;
     vhc->store_hpte = spapr_store_hpte;
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 7bde1884a142..4de0653a3984 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1258,6 +1258,7 @@ struct PPCVirtualHypervisorClass {
     InterfaceClass parent;
     void (*hypercall)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu);
     hwaddr (*hpt_mask)(PPCVirtualHypervisor *vhyp);
+    hwaddr (*hpt_base)(PPCVirtualHypervisor *vhyp);
     const ppc_hash_pte64_t *(*map_hptes)(PPCVirtualHypervisor *vhyp,
                                          hwaddr ptex, int n);
     void (*unmap_hptes)(PPCVirtualHypervisor *vhyp,
diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
index d297b97d3773..0ade8d15d9e4 100644
--- a/target/ppc/mmu-hash64.h
+++ b/target/ppc/mmu-hash64.h
@@ -100,6 +100,11 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
 
 static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
 {
+    if (cpu->vhyp) {
+        PPCVirtualHypervisorClass *vhc =
+            PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
+        return vhc->hpt_base(cpu->vhyp);
+    }
     return cpu->env.spr[SPR_SDR1] & SDR_64_HTABORG;
 }
 
-- 
2.13.6

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

* [Qemu-devel] [PATCH v3 2/4] target/ppc: add basic support for PTCR on POWER9
  2018-03-15 13:33 [Qemu-devel] [PATCH v3 0/4] target/ppc: add hash MMU support for the POWER9 PowerNV machine Cédric Le Goater
  2018-03-15 13:33 ` [Qemu-devel] [PATCH v3 1/4] target/ppc: export external HPT via virtual hypervisor Cédric Le Goater
@ 2018-03-15 13:34 ` Cédric Le Goater
  2018-03-21  3:19   ` David Gibson
  2018-03-15 13:34 ` [Qemu-devel] [PATCH v3 3/4] target/ppc: add hash MMU support on POWER9 for PowerNV only Cédric Le Goater
  2018-03-15 13:34 ` [Qemu-devel] [PATCH v3 4/4] target/ppc: generalize check on radix when in HV mode Cédric Le Goater
  3 siblings, 1 reply; 12+ messages in thread
From: Cédric Le Goater @ 2018-03-15 13:34 UTC (permalink / raw)
  To: qemu-ppc, qemu-devel, David Gibson
  Cc: Suraj Jitindar Singh, Cédric Le Goater

The Partition Table Control Register (PTCR) is a hypervisor privileged
SPR. It contains the host real address of the Partition Table and its
size.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---

 Changes since v2:

 - added an assert on MMU model in ppc_store_ptcr()
 - renamed s/ptas/patbsize/
 
 Changes since v1:

 - renamed partition table definitions to match ISA
 - moved definitions under mmu-book3s-v3.h

 target/ppc/cpu.h            |  2 ++
 target/ppc/helper.h         |  1 +
 target/ppc/misc_helper.c    | 12 ++++++++++++
 target/ppc/mmu-book3s-v3.h  |  6 ++++++
 target/ppc/mmu_helper.c     | 29 +++++++++++++++++++++++++++++
 target/ppc/translate.c      |  3 +++
 target/ppc/translate_init.c | 18 ++++++++++++++++++
 7 files changed, 71 insertions(+)

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 4de0653a3984..7e900cf86a5f 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1314,6 +1314,7 @@ int ppc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
 
 #if !defined(CONFIG_USER_ONLY)
 void ppc_store_sdr1 (CPUPPCState *env, target_ulong value);
+void ppc_store_ptcr(CPUPPCState *env, target_ulong value);
 #endif /* !defined(CONFIG_USER_ONLY) */
 void ppc_store_msr (CPUPPCState *env, target_ulong value);
 
@@ -1605,6 +1606,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
 #define SPR_BOOKE_GIVOR13     (0x1BC)
 #define SPR_BOOKE_GIVOR14     (0x1BD)
 #define SPR_TIR               (0x1BE)
+#define SPR_PTCR              (0x1D0)
 #define SPR_BOOKE_SPEFSCR     (0x200)
 #define SPR_Exxx_BBEAR        (0x201)
 #define SPR_Exxx_BBTAR        (0x202)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 5b739179b8b5..19453c68138a 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -709,6 +709,7 @@ DEF_HELPER_FLAGS_1(load_601_rtcu, TCG_CALL_NO_RWG, tl, env)
 #if !defined(CONFIG_USER_ONLY)
 #if defined(TARGET_PPC64)
 DEF_HELPER_FLAGS_1(load_purr, TCG_CALL_NO_RWG, tl, env)
+DEF_HELPER_2(store_ptcr, void, env, tl)
 #endif
 DEF_HELPER_2(store_sdr1, void, env, tl)
 DEF_HELPER_2(store_pidr, void, env, tl)
diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c
index 0e4217821b8e..8c8cba5cc6f1 100644
--- a/target/ppc/misc_helper.c
+++ b/target/ppc/misc_helper.c
@@ -88,6 +88,18 @@ void helper_store_sdr1(CPUPPCState *env, target_ulong val)
     }
 }
 
+#if defined(TARGET_PPC64)
+void helper_store_ptcr(CPUPPCState *env, target_ulong val)
+{
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+
+    if (env->spr[SPR_PTCR] != val) {
+        ppc_store_ptcr(env, val);
+        tlb_flush(CPU(cpu));
+    }
+}
+#endif /* defined(TARGET_PPC64) */
+
 void helper_store_pidr(CPUPPCState *env, target_ulong val)
 {
     PowerPCCPU *cpu = ppc_env_get_cpu(env);
diff --git a/target/ppc/mmu-book3s-v3.h b/target/ppc/mmu-book3s-v3.h
index 56095dab522c..fdf80987d7b2 100644
--- a/target/ppc/mmu-book3s-v3.h
+++ b/target/ppc/mmu-book3s-v3.h
@@ -22,6 +22,12 @@
 
 #ifndef CONFIG_USER_ONLY
 
+/*
+ * Partition table definitions
+ */
+#define PTCR_PATB               0x0FFFFFFFFFFFF000ULL /* Partition Table Base */
+#define PTCR_PATS               0x000000000000001FULL /* Partition Table Size */
+
 /* Partition Table Entry Fields */
 #define PATBE1_GR 0x8000000000000000
 
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index 5568d1642b34..03009eee723a 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -2028,6 +2028,35 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
     env->spr[SPR_SDR1] = value;
 }
 
+#if defined(TARGET_PPC64)
+void ppc_store_ptcr(CPUPPCState *env, target_ulong value)
+{
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+    target_ulong ptcr_mask = PTCR_PATB | PTCR_PATS;
+    target_ulong patbsize = value & PTCR_PATS;
+
+    qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value);
+
+    assert(!cpu->vhyp);
+    assert(env->mmu_model & POWERPC_MMU_V3);
+
+    if (value & ~ptcr_mask) {
+        error_report("Invalid bits 0x"TARGET_FMT_lx" set in PTCR",
+                     value & ~ptcr_mask);
+        value &= ptcr_mask;
+    }
+
+    if (patbsize > 24) {
+        error_report("Invalid Partition Table size 0x" TARGET_FMT_lx
+                     " stored in PTCR", patbsize);
+        return;
+    }
+
+    env->spr[SPR_PTCR] = value;
+}
+
+#endif /* defined(TARGET_PPC64) */
+
 /* Segment registers load and store */
 target_ulong helper_load_sr(CPUPPCState *env, target_ulong sr_num)
 {
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 218665b4080b..172fbf35ae53 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -7136,6 +7136,9 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
         if (env->spr_cb[SPR_SDR1].name) { /* SDR1 Exists */
             cpu_fprintf(f, " SDR1 " TARGET_FMT_lx " ", env->spr[SPR_SDR1]);
         }
+        if (env->spr_cb[SPR_PTCR].name) { /* PTCR Exists */
+            cpu_fprintf(f, " PTCR " TARGET_FMT_lx " ", env->spr[SPR_PTCR]);
+        }
         cpu_fprintf(f, "  DAR " TARGET_FMT_lx "  DSISR " TARGET_FMT_lx "\n",
                     env->spr[SPR_DAR], env->spr[SPR_DSISR]);
         break;
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 391b94b97daa..e53cc8dfd188 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -420,6 +420,11 @@ static void spr_write_hior(DisasContext *ctx, int sprn, int gprn)
     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
     tcg_temp_free(t0);
 }
+static void spr_write_ptcr(DisasContext *ctx, int sprn, int gprn)
+{
+    gen_helper_store_ptcr(cpu_env, cpu_gpr[gprn]);
+}
+
 #endif
 #endif
 
@@ -8167,6 +8172,18 @@ static void gen_spr_power8_rpr(CPUPPCState *env)
 #endif
 }
 
+static void gen_spr_power9_mmu(CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+    /* Partition Table Control */
+    spr_register_hv(env, SPR_PTCR, "PTCR",
+                    SPR_NOACCESS, SPR_NOACCESS,
+                    SPR_NOACCESS, SPR_NOACCESS,
+                    &spr_read_generic, &spr_write_ptcr,
+                    0x00000000);
+#endif
+}
+
 static void init_proc_book3s_common(CPUPPCState *env)
 {
     gen_spr_ne_601(env);
@@ -8761,6 +8778,7 @@ static void init_proc_POWER9(CPUPPCState *env)
     gen_spr_power8_ic(env);
     gen_spr_power8_book4(env);
     gen_spr_power8_rpr(env);
+    gen_spr_power9_mmu(env);
 
     /* POWER9 Specific registers */
     spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,
-- 
2.13.6

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

* [Qemu-devel] [PATCH v3 3/4] target/ppc: add hash MMU support on POWER9 for PowerNV only
  2018-03-15 13:33 [Qemu-devel] [PATCH v3 0/4] target/ppc: add hash MMU support for the POWER9 PowerNV machine Cédric Le Goater
  2018-03-15 13:33 ` [Qemu-devel] [PATCH v3 1/4] target/ppc: export external HPT via virtual hypervisor Cédric Le Goater
  2018-03-15 13:34 ` [Qemu-devel] [PATCH v3 2/4] target/ppc: add basic support for PTCR on POWER9 Cédric Le Goater
@ 2018-03-15 13:34 ` Cédric Le Goater
  2018-03-23  8:24   ` David Gibson
  2018-03-15 13:34 ` [Qemu-devel] [PATCH v3 4/4] target/ppc: generalize check on radix when in HV mode Cédric Le Goater
  3 siblings, 1 reply; 12+ messages in thread
From: Cédric Le Goater @ 2018-03-15 13:34 UTC (permalink / raw)
  To: qemu-ppc, qemu-devel, David Gibson
  Cc: Suraj Jitindar Singh, Cédric Le Goater

The HPTE bits definitions are slightly modified in ISA v3.0. Let's add
some helpers to hide the differences in the hash MMU code.

On a POWER9 processor, the Partition Table is composed of a pair of
doublewords per partition. The first doubleword indicates whether the
partition uses HPT or Radix Trees translation and contains the address
of the host's translation table structure and size.

The first doubleword of the PTCR holds the Hash Page Table base
address for the host when the hash MMU is in use. Also add an helper
to retrieve the HPT base address depending on the MMU revision.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---

 Changes since v2:

 - reworked ppc_hash64_hpt_reg() to cover only powernv machines. pseries
   machines being handled with cpu->vhyp at the ppc_hash64_hpt_base()
   level.

 Changes since v1:

 - introduced ppc64_v3_get_patbe0()
 
 hw/ppc/spapr_hcall.c       |  5 +++--
 target/ppc/mmu-book3s-v3.h |  5 +++++
 target/ppc/mmu-hash64.c    | 52 ++++++++++++++++++++++++++++++++++++++--------
 target/ppc/mmu-hash64.h    | 34 ++++++++++++++++++++++++++++--
 4 files changed, 83 insertions(+), 13 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 3215c3b4aec3..b437f8825819 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -94,7 +94,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
         return H_PARAMETER;
     }
 
-    raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << apshift) - 1);
+    raddr = (ptel & ppc_hash64_hpte_r_rpn(cpu)) & ~((1ULL << apshift) - 1);
 
     if (is_ram_address(spapr, raddr)) {
         /* Regular RAM - should have WIMG=0010 */
@@ -586,7 +586,8 @@ static int rehash_hpte(PowerPCCPU *cpu,
 
     base_pg_shift = ppc_hash64_hpte_page_shift_noslb(cpu, pte0, pte1);
     assert(base_pg_shift); /* H_ENTER shouldn't allow a bad encoding */
-    avpn = HPTE64_V_AVPN_VAL(pte0) & ~(((1ULL << base_pg_shift) - 1) >> 23);
+    avpn = ppc_hash64_hpte_v_avpn_val(cpu, pte0) &
+        ~(((1ULL << base_pg_shift) - 1) >> 23);
 
     if (pte0 & HPTE64_V_SECONDARY) {
         pteg = ~pteg;
diff --git a/target/ppc/mmu-book3s-v3.h b/target/ppc/mmu-book3s-v3.h
index fdf80987d7b2..a7ab580c3140 100644
--- a/target/ppc/mmu-book3s-v3.h
+++ b/target/ppc/mmu-book3s-v3.h
@@ -54,6 +54,11 @@ static inline bool ppc64_radix_guest(PowerPCCPU *cpu)
 int ppc64_v3_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
                               int mmu_idx);
 
+static inline hwaddr ppc64_v3_get_patbe0(PowerPCCPU *cpu)
+{
+    return ldq_phys(CPU(cpu)->as, cpu->env.spr[SPR_PTCR] & PTCR_PATB);
+}
+
 #endif /* TARGET_PPC64 */
 
 #endif /* CONFIG_USER_ONLY */
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
index c9b72b742956..c425edd93ebe 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -289,6 +289,26 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb)
     return rt;
 }
 
+hwaddr ppc_hash64_hpt_reg(PowerPCCPU *cpu)
+{
+    CPUPPCState *env = &cpu->env;
+
+    /* We should not reach this routine on sPAPR machines */
+    assert(!cpu->vhyp);
+
+    /* PowerNV machine */
+    if (msr_hv) {
+        if (env->mmu_model & POWERPC_MMU_V3) {
+            return ppc64_v3_get_patbe0(cpu);
+        } else {
+            return cpu->env.spr[SPR_SDR1];
+        }
+    } else {
+        error_report("PowerNV guest support Unimplemented");
+        exit(1);
+    }
+}
+
 /* Check No-Execute or Guarded Storage */
 static inline int ppc_hash64_pte_noexec_guard(PowerPCCPU *cpu,
                                               ppc_hash_pte64_t pte)
@@ -451,8 +471,9 @@ void ppc_hash64_unmap_hptes(PowerPCCPU *cpu, const ppc_hash_pte64_t *hptes,
                         false, n * HASH_PTE_SIZE_64);
 }
 
-static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
-    uint64_t pte0, uint64_t pte1)
+static unsigned hpte_page_shift(PowerPCCPU *cpu,
+                                const struct ppc_one_seg_page_size *sps,
+                                uint64_t pte0, uint64_t pte1)
 {
     int i;
 
@@ -478,7 +499,7 @@ static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
             continue;
         }
 
-        mask = ((1ULL << ps->page_shift) - 1) & HPTE64_R_RPN;
+        mask = ((1ULL << ps->page_shift) - 1) & ppc_hash64_hpte_r_rpn(cpu);
 
         if ((pte1 & mask) == ((uint64_t)ps->pte_enc << HPTE64_R_RPN_SHIFT)) {
             return ps->page_shift;
@@ -488,6 +509,18 @@ static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
     return 0; /* Bad page size encoding */
 }
 
+static bool ppc_hash64_hpte_v_compare(PowerPCCPU *cpu, target_ulong pte0,
+                                      target_ulong ptem)
+{
+    CPUPPCState *env = &cpu->env;
+
+    if (env->mmu_model & POWERPC_MMU_V3) {
+        return HPTE64_V_COMPARE_3_0(pte0, ptem);
+    } else {
+        return HPTE64_V_COMPARE(pte0, ptem);
+    }
+}
+
 static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
                                      const struct ppc_one_seg_page_size *sps,
                                      target_ulong ptem,
@@ -508,8 +541,8 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
         pte1 = ppc_hash64_hpte1(cpu, pteg, i);
 
         /* This compares V, B, H (secondary) and the AVPN */
-        if (HPTE64_V_COMPARE(pte0, ptem)) {
-            *pshift = hpte_page_shift(sps, pte0, pte1);
+        if (ppc_hash64_hpte_v_compare(cpu, pte0, ptem)) {
+            *pshift = hpte_page_shift(cpu, sps, pte0, pte1);
             /*
              * If there is no match, ignore the PTE, it could simply
              * be for a different segment size encoding and the
@@ -569,7 +602,8 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu,
         epn = (eaddr & ~SEGMENT_MASK_256M) & epnmask;
         hash = vsid ^ (epn >> sps->page_shift);
     }
-    ptem = (slb->vsid & SLB_VSID_PTEM) | ((epn >> 16) & HPTE64_V_AVPN);
+    ptem = (slb->vsid & SLB_VSID_PTEM) | ((epn >> 16) &
+                                          ppc_hash64_hpte_v_avpn(cpu));
     ptem |= HPTE64_V_VALID;
 
     /* Page address translation */
@@ -624,7 +658,7 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
             break;
         }
 
-        shift = hpte_page_shift(sps, pte0, pte1);
+        shift = hpte_page_shift(cpu, sps, pte0, pte1);
         if (shift) {
             return shift;
         }
@@ -860,7 +894,7 @@ skip_slb_search:
 
     /* 7. Determine the real address from the PTE */
 
-    raddr = deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, eaddr);
+    raddr = deposit64(pte.pte1 & ppc_hash64_hpte_r_rpn(cpu), 0, apshift, eaddr);
 
     tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
                  prot, mmu_idx, 1ULL << apshift);
@@ -910,7 +944,7 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr)
         return -1;
     }
 
-    return deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, addr)
+    return deposit64(pte.pte1 & ppc_hash64_hpte_r_rpn(cpu), 0, apshift, addr)
         & TARGET_PAGE_MASK;
 }
 
diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
index 0ade8d15d9e4..708f4f6d222a 100644
--- a/target/ppc/mmu-hash64.h
+++ b/target/ppc/mmu-hash64.h
@@ -69,8 +69,12 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
 #define HPTE64_V_SSIZE_SHIFT    62
 #define HPTE64_V_AVPN_SHIFT     7
 #define HPTE64_V_AVPN           0x3fffffffffffff80ULL
+#define HPTE64_V_AVPN_3_0       0x000fffffffffff80ULL
 #define HPTE64_V_AVPN_VAL(x)    (((x) & HPTE64_V_AVPN) >> HPTE64_V_AVPN_SHIFT)
+#define HPTE64_V_AVPN_VAL_3_0(x)                        \
+    (((x) & HPTE64_V_AVPN_3_0) >> HPTE64_V_AVPN_SHIFT)
 #define HPTE64_V_COMPARE(x, y)  (!(((x) ^ (y)) & 0xffffffffffffff83ULL))
+#define HPTE64_V_COMPARE_3_0(x, y)  (!(((x) ^ (y)) & 0x3fffffffffffff83ULL))
 #define HPTE64_V_BOLTED         0x0000000000000010ULL
 #define HPTE64_V_LARGE          0x0000000000000004ULL
 #define HPTE64_V_SECONDARY      0x0000000000000002ULL
@@ -81,6 +85,7 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
 #define HPTE64_R_KEY_HI         0x3000000000000000ULL
 #define HPTE64_R_RPN_SHIFT      12
 #define HPTE64_R_RPN            0x0ffffffffffff000ULL
+#define HPTE64_R_RPN_3_0        0x01fffffffffff000ULL
 #define HPTE64_R_FLAGS          0x00000000000003ffULL
 #define HPTE64_R_PP             0x0000000000000003ULL
 #define HPTE64_R_N              0x0000000000000004ULL
@@ -98,6 +103,31 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
 #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
 #define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
 
+static inline target_ulong ppc_hash64_hpte_r_rpn(PowerPCCPU *cpu)
+{
+    CPUPPCState *env = &cpu->env;
+
+    return env->mmu_model & POWERPC_MMU_V3 ? HPTE64_R_RPN_3_0 : HPTE64_R_RPN;
+}
+
+static inline target_ulong ppc_hash64_hpte_v_avpn(PowerPCCPU *cpu)
+{
+    CPUPPCState *env = &cpu->env;
+
+    return env->mmu_model & POWERPC_MMU_V3 ? HPTE64_V_AVPN_3_0 : HPTE64_V_AVPN;
+}
+
+static inline target_ulong ppc_hash64_hpte_v_avpn_val(PowerPCCPU *cpu,
+                                                      target_ulong pte0)
+{
+    CPUPPCState *env = &cpu->env;
+
+    return env->mmu_model & POWERPC_MMU_V3 ?
+        HPTE64_V_AVPN_VAL_3_0(pte0) : HPTE64_V_AVPN_VAL(pte0);
+}
+
+hwaddr ppc_hash64_hpt_reg(PowerPCCPU *cpu);
+
 static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
 {
     if (cpu->vhyp) {
@@ -105,7 +135,7 @@ static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
             PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
         return vhc->hpt_base(cpu->vhyp);
     }
-    return cpu->env.spr[SPR_SDR1] & SDR_64_HTABORG;
+    return ppc_hash64_hpt_reg(cpu) & SDR_64_HTABORG;
 }
 
 static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cpu)
@@ -115,7 +145,7 @@ static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cpu)
             PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
         return vhc->hpt_mask(cpu->vhyp);
     }
-    return (1ULL << ((cpu->env.spr[SPR_SDR1] & SDR_64_HTABSIZE) + 18 - 7)) - 1;
+    return (1ULL << ((ppc_hash64_hpt_reg(cpu) & SDR_64_HTABSIZE) + 18 - 7)) - 1;
 }
 
 struct ppc_hash_pte64 {
-- 
2.13.6

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

* [Qemu-devel] [PATCH v3 4/4] target/ppc: generalize check on radix when in HV mode
  2018-03-15 13:33 [Qemu-devel] [PATCH v3 0/4] target/ppc: add hash MMU support for the POWER9 PowerNV machine Cédric Le Goater
                   ` (2 preceding siblings ...)
  2018-03-15 13:34 ` [Qemu-devel] [PATCH v3 3/4] target/ppc: add hash MMU support on POWER9 for PowerNV only Cédric Le Goater
@ 2018-03-15 13:34 ` Cédric Le Goater
  2018-04-05  4:37   ` David Gibson
  3 siblings, 1 reply; 12+ messages in thread
From: Cédric Le Goater @ 2018-03-15 13:34 UTC (permalink / raw)
  To: qemu-ppc, qemu-devel, David Gibson
  Cc: Suraj Jitindar Singh, Cédric Le Goater

On a POWER9 processor, the first doubleword of the partition table
entry (as pointed to by the PTCR) indicates whether the host uses HPT
or Radix Tree translation for that partition. Use that bit to check
for radix mode on pseries and powernv QEMU machines.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---

 Changes since v2:

 - reworked ppc64_v3_radix() to distinguish pseries machine from
   powernv machines
 - kept ppc64_radix_guest()

 Changes since v1:

 - fixed commit log
 - introduced ppc64_v3_get_patbe0()
 - renamed ppc64_radix() in ppc64_v3_radix()

 target/ppc/mmu-book3s-v3.c | 23 +++++++++++++++++++++--
 target/ppc/mmu-book3s-v3.h |  4 +++-
 target/ppc/mmu_helper.c    |  4 ++--
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/target/ppc/mmu-book3s-v3.c b/target/ppc/mmu-book3s-v3.c
index b60df4408f3b..89edbb6abc5c 100644
--- a/target/ppc/mmu-book3s-v3.c
+++ b/target/ppc/mmu-book3s-v3.c
@@ -19,16 +19,35 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
+#include "qemu/error-report.h"
 #include "mmu-hash64.h"
 #include "mmu-book3s-v3.h"
 #include "mmu-radix64.h"
 
+bool ppc64_v3_radix(PowerPCCPU *cpu)
+{
+    CPUPPCState *env = &cpu->env;
+
+    /* sPAPR machine */
+    if (cpu->vhyp) {
+        return ppc64_radix_guest(cpu);
+    }
+
+    /* PowerNV machine - only HV mode is supported */
+    if (msr_hv) {
+        return ppc64_v3_get_patbe0(cpu) & PATBE0_HR;
+    } else {
+        error_report("PowerNV guest support Unimplemented");
+        exit(1);
+    }
+}
+
 int ppc64_v3_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
                               int mmu_idx)
 {
-    if (ppc64_radix_guest(cpu)) { /* Guest uses radix */
+    if (ppc64_v3_radix(cpu)) {
         return ppc_radix64_handle_mmu_fault(cpu, eaddr, rwx, mmu_idx);
-    } else { /* Guest uses hash */
+    } else {
         return ppc_hash64_handle_mmu_fault(cpu, eaddr, rwx, mmu_idx);
     }
 }
diff --git a/target/ppc/mmu-book3s-v3.h b/target/ppc/mmu-book3s-v3.h
index a7ab580c3140..9721791d2dd3 100644
--- a/target/ppc/mmu-book3s-v3.h
+++ b/target/ppc/mmu-book3s-v3.h
@@ -29,7 +29,8 @@
 #define PTCR_PATS               0x000000000000001FULL /* Partition Table Size */
 
 /* Partition Table Entry Fields */
-#define PATBE1_GR 0x8000000000000000
+#define PATBE0_HR               PPC_BIT(0)            /* 1:Host Radix  0:HPT  */
+#define PATBE1_GR               PPC_BIT(0)            /* 1:Guest Radix 0:HPT  */
 
 /* Process Table Entry */
 struct prtb_entry {
@@ -50,6 +51,7 @@ static inline bool ppc64_radix_guest(PowerPCCPU *cpu)
 
     return !!(vhc->get_patbe(cpu->vhyp) & PATBE1_GR);
 }
+bool ppc64_v3_radix(PowerPCCPU *cpu);
 
 int ppc64_v3_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
                               int mmu_idx);
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index 03009eee723a..fba203cdef18 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -1285,7 +1285,7 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
         dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
         break;
     case POWERPC_MMU_VER_3_00:
-        if (ppc64_radix_guest(ppc_env_get_cpu(env))) {
+        if (ppc64_v3_radix(ppc_env_get_cpu(env))) {
             /* TODO - Unsupported */
         } else {
             dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
@@ -1431,7 +1431,7 @@ hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
     case POWERPC_MMU_VER_2_07:
         return ppc_hash64_get_phys_page_debug(cpu, addr);
     case POWERPC_MMU_VER_3_00:
-        if (ppc64_radix_guest(ppc_env_get_cpu(env))) {
+        if (ppc64_v3_radix(ppc_env_get_cpu(env))) {
             return ppc_radix64_get_phys_page_debug(cpu, addr);
         } else {
             return ppc_hash64_get_phys_page_debug(cpu, addr);
-- 
2.13.6

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

* Re: [Qemu-devel] [PATCH v3 1/4] target/ppc: export external HPT via virtual hypervisor
  2018-03-15 13:33 ` [Qemu-devel] [PATCH v3 1/4] target/ppc: export external HPT via virtual hypervisor Cédric Le Goater
@ 2018-03-17  4:15   ` David Gibson
  2018-03-17  8:55     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
  0 siblings, 1 reply; 12+ messages in thread
From: David Gibson @ 2018-03-17  4:15 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel, Suraj Jitindar Singh

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

On Thu, Mar 15, 2018 at 01:33:59PM +0000, Cédric Le Goater wrote:
> commit e57ca75ce3b2 ("target/ppc: Manage external HPT via virtual
> hypervisor") exported a set of methods to manipulate the HPT from the
> core hash MMU but the base address of the HPT was not part of them and
> SPR_SDR1 is still used under some circumstances, which is incorrect
> for the sPAPR machines.
> 
> This is not a major change as only the logging should be impacted but
> nevertheless, it will help to introduce support for the hash MMU on
> POWER9 PowerNV machines.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

This doesn't make sense.  The whole point of the "virtual hypervisor"
is that the hash table doesn't live within the guest address space,
and therefore it *has* no meaningful base address.  Basically
ppc_hash64_hpt_base() should never be called if vhyp is set.  If it
is, that's a bug.

> ---
>  hw/ppc/spapr.c          | 8 ++++++++
>  target/ppc/cpu.h        | 1 +
>  target/ppc/mmu-hash64.h | 5 +++++
>  3 files changed, 14 insertions(+)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index f1798457bc4d..2329664e0c2c 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1327,6 +1327,13 @@ static hwaddr spapr_hpt_mask(PPCVirtualHypervisor *vhyp)
>      return HTAB_SIZE(spapr) / HASH_PTEG_SIZE_64 - 1;
>  }
>  
> +static hwaddr spapr_hpt_base(PPCVirtualHypervisor *vhyp)
> +{
> +    sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
> +
> +    return (hwaddr) spapr->htab;
> +}
> +
>  static target_ulong spapr_encode_hpt_for_kvm_pr(PPCVirtualHypervisor *vhyp)
>  {
>      sPAPRMachineState *spapr = SPAPR_MACHINE(vhyp);
> @@ -4073,6 +4080,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
>      smc->phb_placement = spapr_phb_placement;
>      vhc->hypercall = emulate_spapr_hypercall;
>      vhc->hpt_mask = spapr_hpt_mask;
> +    vhc->hpt_base = spapr_hpt_base;
>      vhc->map_hptes = spapr_map_hptes;
>      vhc->unmap_hptes = spapr_unmap_hptes;
>      vhc->store_hpte = spapr_store_hpte;
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 7bde1884a142..4de0653a3984 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -1258,6 +1258,7 @@ struct PPCVirtualHypervisorClass {
>      InterfaceClass parent;
>      void (*hypercall)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu);
>      hwaddr (*hpt_mask)(PPCVirtualHypervisor *vhyp);
> +    hwaddr (*hpt_base)(PPCVirtualHypervisor *vhyp);
>      const ppc_hash_pte64_t *(*map_hptes)(PPCVirtualHypervisor *vhyp,
>                                           hwaddr ptex, int n);
>      void (*unmap_hptes)(PPCVirtualHypervisor *vhyp,
> diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
> index d297b97d3773..0ade8d15d9e4 100644
> --- a/target/ppc/mmu-hash64.h
> +++ b/target/ppc/mmu-hash64.h
> @@ -100,6 +100,11 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
>  
>  static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
>  {
> +    if (cpu->vhyp) {
> +        PPCVirtualHypervisorClass *vhc =
> +            PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
> +        return vhc->hpt_base(cpu->vhyp);
> +    }
>      return cpu->env.spr[SPR_SDR1] & SDR_64_HTABORG;
>  }
>  

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

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

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v3 1/4] target/ppc: export external HPT via virtual hypervisor
  2018-03-17  4:15   ` David Gibson
@ 2018-03-17  8:55     ` Cédric Le Goater
  2018-03-21  3:17       ` David Gibson
  0 siblings, 1 reply; 12+ messages in thread
From: Cédric Le Goater @ 2018-03-17  8:55 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Suraj Jitindar Singh

On 03/17/2018 05:15 AM, David Gibson wrote:
> On Thu, Mar 15, 2018 at 01:33:59PM +0000, Cédric Le Goater wrote:
>> commit e57ca75ce3b2 ("target/ppc: Manage external HPT via virtual
>> hypervisor") exported a set of methods to manipulate the HPT from the
>> core hash MMU but the base address of the HPT was not part of them and
>> SPR_SDR1 is still used under some circumstances, which is incorrect
>> for the sPAPR machines.
>>
>> This is not a major change as only the logging should be impacted but
>> nevertheless, it will help to introduce support for the hash MMU on
>> POWER9 PowerNV machines.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> 
> This doesn't make sense.  The whole point of the "virtual hypervisor"
> is that the hash table doesn't live within the guest address space,
> and therefore it *has* no meaningful base address.  Basically
> ppc_hash64_hpt_base() should never be called if vhyp is set.  If it
> is, that's a bug.


ppc_hash64_hpt_base() is being called in a couple of places but the
returned value is only used if the machines is not a pseries :

  static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cpu)
  {
      if (cpu->vhyp) {
          PPCVirtualHypervisorClass *vhc =
              PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
          return vhc->hpt_mask(cpu->vhyp);
      }
      ....

  const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu,
                                               hwaddr ptex, int n)
  {
      hwaddr pte_offset = ptex * HASH_PTE_SIZE_64;
      hwaddr base = ppc_hash64_hpt_base(cpu);
      hwaddr plen = n * HASH_PTE_SIZE_64;
      const ppc_hash_pte64_t *hptes;
  
      if (cpu->vhyp) {
          PPCVirtualHypervisorClass *vhc =
              PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
          return vhc->map_hptes(cpu->vhyp, ptex, n);
      }  
      ....
  
and also :
  
  void ppc_hash64_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
                             uint64_t pte0, uint64_t pte1)
  {
      hwaddr base = ppc_hash64_hpt_base(cpu);
      hwaddr offset = ptex * HASH_PTE_SIZE_64;
  
      if (cpu->vhyp) {
          PPCVirtualHypervisorClass *vhc =
              PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
          vhc->store_hpte(cpu->vhyp, ptex, pte0, pte1);
          return;
      }
      ....

And, in ppc_hash64_htab_lookup(), the HPT base is logged so we need
some value returned (today, this is SPR_SDR1 which equals zero but 
that's confusing I think).


If you don't agree with the hpt_base() op, we can change it to
something like :

  static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
  {
      if (cpu->vhyp) {
          /* Unused on sPAPR machines */
          return 0;
      }
      return ppc_hash64_hpt_reg(cpu) & SDR_64_HTABORG;
  }

to be consistent with the other routines. I would like to make sure we
don't reach ppc_hash64_hpt_reg() on pseries machines. see patch 3/4.


Thanks,

C.

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

* Re: [Qemu-devel] [Qemu-ppc] [PATCH v3 1/4] target/ppc: export external HPT via virtual hypervisor
  2018-03-17  8:55     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
@ 2018-03-21  3:17       ` David Gibson
  0 siblings, 0 replies; 12+ messages in thread
From: David Gibson @ 2018-03-21  3:17 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel, Suraj Jitindar Singh

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

On Sat, Mar 17, 2018 at 09:55:28AM +0100, Cédric Le Goater wrote:
> On 03/17/2018 05:15 AM, David Gibson wrote:
> > On Thu, Mar 15, 2018 at 01:33:59PM +0000, Cédric Le Goater wrote:
> >> commit e57ca75ce3b2 ("target/ppc: Manage external HPT via virtual
> >> hypervisor") exported a set of methods to manipulate the HPT from the
> >> core hash MMU but the base address of the HPT was not part of them and
> >> SPR_SDR1 is still used under some circumstances, which is incorrect
> >> for the sPAPR machines.
> >>
> >> This is not a major change as only the logging should be impacted but
> >> nevertheless, it will help to introduce support for the hash MMU on
> >> POWER9 PowerNV machines.
> >>
> >> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> > 
> > This doesn't make sense.  The whole point of the "virtual hypervisor"
> > is that the hash table doesn't live within the guest address space,
> > and therefore it *has* no meaningful base address.  Basically
> > ppc_hash64_hpt_base() should never be called if vhyp is set.  If it
> > is, that's a bug.
> 
> 
> ppc_hash64_hpt_base() is being called in a couple of places but the
> returned value is only used if the machines is not a pseries :
> 
>   static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cpu)
>   {
>       if (cpu->vhyp) {
>           PPCVirtualHypervisorClass *vhc =
>               PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
>           return vhc->hpt_mask(cpu->vhyp);
>       }
>       ....
> 
>   const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu,
>                                                hwaddr ptex, int n)
>   {
>       hwaddr pte_offset = ptex * HASH_PTE_SIZE_64;
>       hwaddr base = ppc_hash64_hpt_base(cpu);
>       hwaddr plen = n * HASH_PTE_SIZE_64;
>       const ppc_hash_pte64_t *hptes;
>   
>       if (cpu->vhyp) {
>           PPCVirtualHypervisorClass *vhc =
>               PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
>           return vhc->map_hptes(cpu->vhyp, ptex, n);
>       }  
>       ....
>   
> and also :
>   
>   void ppc_hash64_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
>                              uint64_t pte0, uint64_t pte1)
>   {
>       hwaddr base = ppc_hash64_hpt_base(cpu);
>       hwaddr offset = ptex * HASH_PTE_SIZE_64;
>   
>       if (cpu->vhyp) {
>           PPCVirtualHypervisorClass *vhc =
>               PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
>           vhc->store_hpte(cpu->vhyp, ptex, pte0, pte1);
>           return;
>       }
>       ....

Right.. so called, but not really used.  A little ugly, but we get
away with it for now.

> And, in ppc_hash64_htab_lookup(), the HPT base is logged so we need
> some value returned (today, this is SPR_SDR1 which equals zero but 
> that's confusing I think).
> 
> 
> If you don't agree with the hpt_base() op, we can change it to
> something like :

I certainly don't agree with the definition proposed - that can return
either a guest address or a host userspace address depending on
various factors.  That's definitely not a sensible interface.

>   static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
>   {
>       if (cpu->vhyp) {
>           /* Unused on sPAPR machines */
>           return 0;
>       }
>       return ppc_hash64_hpt_reg(cpu) & SDR_64_HTABORG;
>   }
> 
> to be consistent with the other routines. I would like to make sure we
> don't reach ppc_hash64_hpt_reg() on pseries machines. see patch 3/4.

We could do that, since this routine is basically only used for
logging / debugging, the 0 acts as just a placeholder.

The more strictly correct (but a bit more work) option would be to put
an assert(!cpu->vhyp) in there, and fix the code so that we
really don't call ppc_hash64_hpt_base() in the vhyp cases.

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

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

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

* Re: [Qemu-devel] [PATCH v3 2/4] target/ppc: add basic support for PTCR on POWER9
  2018-03-15 13:34 ` [Qemu-devel] [PATCH v3 2/4] target/ppc: add basic support for PTCR on POWER9 Cédric Le Goater
@ 2018-03-21  3:19   ` David Gibson
  0 siblings, 0 replies; 12+ messages in thread
From: David Gibson @ 2018-03-21  3:19 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel, Suraj Jitindar Singh

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

On Thu, Mar 15, 2018 at 01:34:00PM +0000, Cédric Le Goater wrote:
> The Partition Table Control Register (PTCR) is a hypervisor privileged
> SPR. It contains the host real address of the Partition Table and its
> size.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

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

> ---
> 
>  Changes since v2:
> 
>  - added an assert on MMU model in ppc_store_ptcr()
>  - renamed s/ptas/patbsize/
>  
>  Changes since v1:
> 
>  - renamed partition table definitions to match ISA
>  - moved definitions under mmu-book3s-v3.h
> 
>  target/ppc/cpu.h            |  2 ++
>  target/ppc/helper.h         |  1 +
>  target/ppc/misc_helper.c    | 12 ++++++++++++
>  target/ppc/mmu-book3s-v3.h  |  6 ++++++
>  target/ppc/mmu_helper.c     | 29 +++++++++++++++++++++++++++++
>  target/ppc/translate.c      |  3 +++
>  target/ppc/translate_init.c | 18 ++++++++++++++++++
>  7 files changed, 71 insertions(+)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 4de0653a3984..7e900cf86a5f 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -1314,6 +1314,7 @@ int ppc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
>  
>  #if !defined(CONFIG_USER_ONLY)
>  void ppc_store_sdr1 (CPUPPCState *env, target_ulong value);
> +void ppc_store_ptcr(CPUPPCState *env, target_ulong value);
>  #endif /* !defined(CONFIG_USER_ONLY) */
>  void ppc_store_msr (CPUPPCState *env, target_ulong value);
>  
> @@ -1605,6 +1606,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
>  #define SPR_BOOKE_GIVOR13     (0x1BC)
>  #define SPR_BOOKE_GIVOR14     (0x1BD)
>  #define SPR_TIR               (0x1BE)
> +#define SPR_PTCR              (0x1D0)
>  #define SPR_BOOKE_SPEFSCR     (0x200)
>  #define SPR_Exxx_BBEAR        (0x201)
>  #define SPR_Exxx_BBTAR        (0x202)
> diff --git a/target/ppc/helper.h b/target/ppc/helper.h
> index 5b739179b8b5..19453c68138a 100644
> --- a/target/ppc/helper.h
> +++ b/target/ppc/helper.h
> @@ -709,6 +709,7 @@ DEF_HELPER_FLAGS_1(load_601_rtcu, TCG_CALL_NO_RWG, tl, env)
>  #if !defined(CONFIG_USER_ONLY)
>  #if defined(TARGET_PPC64)
>  DEF_HELPER_FLAGS_1(load_purr, TCG_CALL_NO_RWG, tl, env)
> +DEF_HELPER_2(store_ptcr, void, env, tl)
>  #endif
>  DEF_HELPER_2(store_sdr1, void, env, tl)
>  DEF_HELPER_2(store_pidr, void, env, tl)
> diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c
> index 0e4217821b8e..8c8cba5cc6f1 100644
> --- a/target/ppc/misc_helper.c
> +++ b/target/ppc/misc_helper.c
> @@ -88,6 +88,18 @@ void helper_store_sdr1(CPUPPCState *env, target_ulong val)
>      }
>  }
>  
> +#if defined(TARGET_PPC64)
> +void helper_store_ptcr(CPUPPCState *env, target_ulong val)
> +{
> +    PowerPCCPU *cpu = ppc_env_get_cpu(env);
> +
> +    if (env->spr[SPR_PTCR] != val) {
> +        ppc_store_ptcr(env, val);
> +        tlb_flush(CPU(cpu));
> +    }
> +}
> +#endif /* defined(TARGET_PPC64) */
> +
>  void helper_store_pidr(CPUPPCState *env, target_ulong val)
>  {
>      PowerPCCPU *cpu = ppc_env_get_cpu(env);
> diff --git a/target/ppc/mmu-book3s-v3.h b/target/ppc/mmu-book3s-v3.h
> index 56095dab522c..fdf80987d7b2 100644
> --- a/target/ppc/mmu-book3s-v3.h
> +++ b/target/ppc/mmu-book3s-v3.h
> @@ -22,6 +22,12 @@
>  
>  #ifndef CONFIG_USER_ONLY
>  
> +/*
> + * Partition table definitions
> + */
> +#define PTCR_PATB               0x0FFFFFFFFFFFF000ULL /* Partition Table Base */
> +#define PTCR_PATS               0x000000000000001FULL /* Partition Table Size */
> +
>  /* Partition Table Entry Fields */
>  #define PATBE1_GR 0x8000000000000000
>  
> diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> index 5568d1642b34..03009eee723a 100644
> --- a/target/ppc/mmu_helper.c
> +++ b/target/ppc/mmu_helper.c
> @@ -2028,6 +2028,35 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
>      env->spr[SPR_SDR1] = value;
>  }
>  
> +#if defined(TARGET_PPC64)
> +void ppc_store_ptcr(CPUPPCState *env, target_ulong value)
> +{
> +    PowerPCCPU *cpu = ppc_env_get_cpu(env);
> +    target_ulong ptcr_mask = PTCR_PATB | PTCR_PATS;
> +    target_ulong patbsize = value & PTCR_PATS;
> +
> +    qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value);
> +
> +    assert(!cpu->vhyp);
> +    assert(env->mmu_model & POWERPC_MMU_V3);
> +
> +    if (value & ~ptcr_mask) {
> +        error_report("Invalid bits 0x"TARGET_FMT_lx" set in PTCR",
> +                     value & ~ptcr_mask);
> +        value &= ptcr_mask;
> +    }
> +
> +    if (patbsize > 24) {
> +        error_report("Invalid Partition Table size 0x" TARGET_FMT_lx
> +                     " stored in PTCR", patbsize);
> +        return;
> +    }
> +
> +    env->spr[SPR_PTCR] = value;
> +}
> +
> +#endif /* defined(TARGET_PPC64) */
> +
>  /* Segment registers load and store */
>  target_ulong helper_load_sr(CPUPPCState *env, target_ulong sr_num)
>  {
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 218665b4080b..172fbf35ae53 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -7136,6 +7136,9 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
>          if (env->spr_cb[SPR_SDR1].name) { /* SDR1 Exists */
>              cpu_fprintf(f, " SDR1 " TARGET_FMT_lx " ", env->spr[SPR_SDR1]);
>          }
> +        if (env->spr_cb[SPR_PTCR].name) { /* PTCR Exists */
> +            cpu_fprintf(f, " PTCR " TARGET_FMT_lx " ", env->spr[SPR_PTCR]);
> +        }
>          cpu_fprintf(f, "  DAR " TARGET_FMT_lx "  DSISR " TARGET_FMT_lx "\n",
>                      env->spr[SPR_DAR], env->spr[SPR_DSISR]);
>          break;
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index 391b94b97daa..e53cc8dfd188 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -420,6 +420,11 @@ static void spr_write_hior(DisasContext *ctx, int sprn, int gprn)
>      tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
>      tcg_temp_free(t0);
>  }
> +static void spr_write_ptcr(DisasContext *ctx, int sprn, int gprn)
> +{
> +    gen_helper_store_ptcr(cpu_env, cpu_gpr[gprn]);
> +}
> +
>  #endif
>  #endif
>  
> @@ -8167,6 +8172,18 @@ static void gen_spr_power8_rpr(CPUPPCState *env)
>  #endif
>  }
>  
> +static void gen_spr_power9_mmu(CPUPPCState *env)
> +{
> +#if !defined(CONFIG_USER_ONLY)
> +    /* Partition Table Control */
> +    spr_register_hv(env, SPR_PTCR, "PTCR",
> +                    SPR_NOACCESS, SPR_NOACCESS,
> +                    SPR_NOACCESS, SPR_NOACCESS,
> +                    &spr_read_generic, &spr_write_ptcr,
> +                    0x00000000);
> +#endif
> +}
> +
>  static void init_proc_book3s_common(CPUPPCState *env)
>  {
>      gen_spr_ne_601(env);
> @@ -8761,6 +8778,7 @@ static void init_proc_POWER9(CPUPPCState *env)
>      gen_spr_power8_ic(env);
>      gen_spr_power8_book4(env);
>      gen_spr_power8_rpr(env);
> +    gen_spr_power9_mmu(env);
>  
>      /* POWER9 Specific registers */
>      spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,

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

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

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

* Re: [Qemu-devel] [PATCH v3 3/4] target/ppc: add hash MMU support on POWER9 for PowerNV only
  2018-03-15 13:34 ` [Qemu-devel] [PATCH v3 3/4] target/ppc: add hash MMU support on POWER9 for PowerNV only Cédric Le Goater
@ 2018-03-23  8:24   ` David Gibson
  2018-03-23  8:54     ` Cédric Le Goater
  0 siblings, 1 reply; 12+ messages in thread
From: David Gibson @ 2018-03-23  8:24 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel, Suraj Jitindar Singh

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

I'm not quite sure what the "for PowerNV only" in the subject is
supposed to be indicating.

On Thu, Mar 15, 2018 at 01:34:01PM +0000, Cédric Le Goater wrote:
> The HPTE bits definitions are slightly modified in ISA v3.0. Let's add
> some helpers to hide the differences in the hash MMU code.
> 
> On a POWER9 processor, the Partition Table is composed of a pair of
> doublewords per partition. The first doubleword indicates whether the
> partition uses HPT or Radix Trees translation and contains the address
> of the host's translation table structure and size.
> 
> The first doubleword of the PTCR holds the Hash Page Table base
> address for the host when the hash MMU is in use. Also add an helper
> to retrieve the HPT base address depending on the MMU revision.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
> 
>  Changes since v2:
> 
>  - reworked ppc_hash64_hpt_reg() to cover only powernv machines. pseries
>    machines being handled with cpu->vhyp at the ppc_hash64_hpt_base()
>    level.
> 
>  Changes since v1:
> 
>  - introduced ppc64_v3_get_patbe0()
>  
>  hw/ppc/spapr_hcall.c       |  5 +++--
>  target/ppc/mmu-book3s-v3.h |  5 +++++
>  target/ppc/mmu-hash64.c    | 52 ++++++++++++++++++++++++++++++++++++++--------
>  target/ppc/mmu-hash64.h    | 34 ++++++++++++++++++++++++++++--
>  4 files changed, 83 insertions(+), 13 deletions(-)
> 
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index 3215c3b4aec3..b437f8825819 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -94,7 +94,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>          return H_PARAMETER;
>      }
>  
> -    raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << apshift) - 1);
> +    raddr = (ptel & ppc_hash64_hpte_r_rpn(cpu)) & ~((1ULL << apshift) - 1);

h_enter() will never be used on PowerNV, for example, so why is it
being changed?

>      if (is_ram_address(spapr, raddr)) {
>          /* Regular RAM - should have WIMG=0010 */
> @@ -586,7 +586,8 @@ static int rehash_hpte(PowerPCCPU *cpu,
>  
>      base_pg_shift = ppc_hash64_hpte_page_shift_noslb(cpu, pte0, pte1);
>      assert(base_pg_shift); /* H_ENTER shouldn't allow a bad encoding */
> -    avpn = HPTE64_V_AVPN_VAL(pte0) & ~(((1ULL << base_pg_shift) - 1) >> 23);
> +    avpn = ppc_hash64_hpte_v_avpn_val(cpu, pte0) &
> +        ~(((1ULL << base_pg_shift) - 1) >> 23);
>  
>      if (pte0 & HPTE64_V_SECONDARY) {
>          pteg = ~pteg;
> diff --git a/target/ppc/mmu-book3s-v3.h b/target/ppc/mmu-book3s-v3.h
> index fdf80987d7b2..a7ab580c3140 100644
> --- a/target/ppc/mmu-book3s-v3.h
> +++ b/target/ppc/mmu-book3s-v3.h
> @@ -54,6 +54,11 @@ static inline bool ppc64_radix_guest(PowerPCCPU *cpu)
>  int ppc64_v3_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
>                                int mmu_idx);
>  
> +static inline hwaddr ppc64_v3_get_patbe0(PowerPCCPU *cpu)
> +{
> +    return ldq_phys(CPU(cpu)->as, cpu->env.spr[SPR_PTCR] & PTCR_PATB);
> +}
> +
>  #endif /* TARGET_PPC64 */
>  
>  #endif /* CONFIG_USER_ONLY */
> diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
> index c9b72b742956..c425edd93ebe 100644
> --- a/target/ppc/mmu-hash64.c
> +++ b/target/ppc/mmu-hash64.c
> @@ -289,6 +289,26 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb)
>      return rt;
>  }
>  
> +hwaddr ppc_hash64_hpt_reg(PowerPCCPU *cpu)
> +{
> +    CPUPPCState *env = &cpu->env;
> +
> +    /* We should not reach this routine on sPAPR machines */
> +    assert(!cpu->vhyp);
> +
> +    /* PowerNV machine */
> +    if (msr_hv) {
> +        if (env->mmu_model & POWERPC_MMU_V3) {
> +            return ppc64_v3_get_patbe0(cpu);
> +        } else {
> +            return cpu->env.spr[SPR_SDR1];
> +        }
> +    } else {
> +        error_report("PowerNV guest support Unimplemented");
> +        exit(1);
> +    }
> +}
> +
>  /* Check No-Execute or Guarded Storage */
>  static inline int ppc_hash64_pte_noexec_guard(PowerPCCPU *cpu,
>                                                ppc_hash_pte64_t pte)
> @@ -451,8 +471,9 @@ void ppc_hash64_unmap_hptes(PowerPCCPU *cpu, const ppc_hash_pte64_t *hptes,
>                          false, n * HASH_PTE_SIZE_64);
>  }
>  
> -static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
> -    uint64_t pte0, uint64_t pte1)
> +static unsigned hpte_page_shift(PowerPCCPU *cpu,
> +                                const struct ppc_one_seg_page_size *sps,
> +                                uint64_t pte0, uint64_t pte1)
>  {
>      int i;
>  
> @@ -478,7 +499,7 @@ static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
>              continue;
>          }
>  
> -        mask = ((1ULL << ps->page_shift) - 1) & HPTE64_R_RPN;
> +        mask = ((1ULL << ps->page_shift) - 1) & ppc_hash64_hpte_r_rpn(cpu);
>  
>          if ((pte1 & mask) == ((uint64_t)ps->pte_enc << HPTE64_R_RPN_SHIFT)) {
>              return ps->page_shift;
> @@ -488,6 +509,18 @@ static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
>      return 0; /* Bad page size encoding */
>  }
>  
> +static bool ppc_hash64_hpte_v_compare(PowerPCCPU *cpu, target_ulong pte0,
> +                                      target_ulong ptem)
> +{
> +    CPUPPCState *env = &cpu->env;
> +
> +    if (env->mmu_model & POWERPC_MMU_V3) {
> +        return HPTE64_V_COMPARE_3_0(pte0, ptem);
> +    } else {
> +        return HPTE64_V_COMPARE(pte0, ptem);
> +    }
> +}
> +
>  static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
>                                       const struct ppc_one_seg_page_size *sps,
>                                       target_ulong ptem,
> @@ -508,8 +541,8 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
>          pte1 = ppc_hash64_hpte1(cpu, pteg, i);
>  
>          /* This compares V, B, H (secondary) and the AVPN */
> -        if (HPTE64_V_COMPARE(pte0, ptem)) {
> -            *pshift = hpte_page_shift(sps, pte0, pte1);
> +        if (ppc_hash64_hpte_v_compare(cpu, pte0, ptem)) {
> +            *pshift = hpte_page_shift(cpu, sps, pte0, pte1);
>              /*
>               * If there is no match, ignore the PTE, it could simply
>               * be for a different segment size encoding and the
> @@ -569,7 +602,8 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu,
>          epn = (eaddr & ~SEGMENT_MASK_256M) & epnmask;
>          hash = vsid ^ (epn >> sps->page_shift);
>      }
> -    ptem = (slb->vsid & SLB_VSID_PTEM) | ((epn >> 16) & HPTE64_V_AVPN);
> +    ptem = (slb->vsid & SLB_VSID_PTEM) | ((epn >> 16) &
> +                                          ppc_hash64_hpte_v_avpn(cpu));
>      ptem |= HPTE64_V_VALID;
>  
>      /* Page address translation */
> @@ -624,7 +658,7 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
>              break;
>          }
>  
> -        shift = hpte_page_shift(sps, pte0, pte1);
> +        shift = hpte_page_shift(cpu, sps, pte0, pte1);
>          if (shift) {
>              return shift;
>          }
> @@ -860,7 +894,7 @@ skip_slb_search:
>  
>      /* 7. Determine the real address from the PTE */
>  
> -    raddr = deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, eaddr);
> +    raddr = deposit64(pte.pte1 & ppc_hash64_hpte_r_rpn(cpu), 0, apshift, eaddr);
>  
>      tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
>                   prot, mmu_idx, 1ULL << apshift);
> @@ -910,7 +944,7 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr)
>          return -1;
>      }
>  
> -    return deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, addr)
> +    return deposit64(pte.pte1 & ppc_hash64_hpte_r_rpn(cpu), 0, apshift, addr)
>          & TARGET_PAGE_MASK;
>  }
>  
> diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
> index 0ade8d15d9e4..708f4f6d222a 100644
> --- a/target/ppc/mmu-hash64.h
> +++ b/target/ppc/mmu-hash64.h
> @@ -69,8 +69,12 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
>  #define HPTE64_V_SSIZE_SHIFT    62
>  #define HPTE64_V_AVPN_SHIFT     7
>  #define HPTE64_V_AVPN           0x3fffffffffffff80ULL
> +#define HPTE64_V_AVPN_3_0       0x000fffffffffff80ULL
>  #define HPTE64_V_AVPN_VAL(x)    (((x) & HPTE64_V_AVPN) >> HPTE64_V_AVPN_SHIFT)
> +#define HPTE64_V_AVPN_VAL_3_0(x)                        \
> +    (((x) & HPTE64_V_AVPN_3_0) >> HPTE64_V_AVPN_SHIFT)
>  #define HPTE64_V_COMPARE(x, y)  (!(((x) ^ (y)) & 0xffffffffffffff83ULL))
> +#define HPTE64_V_COMPARE_3_0(x, y)  (!(((x) ^ (y)) & 0x3fffffffffffff83ULL))
>  #define HPTE64_V_BOLTED         0x0000000000000010ULL
>  #define HPTE64_V_LARGE          0x0000000000000004ULL
>  #define HPTE64_V_SECONDARY      0x0000000000000002ULL
> @@ -81,6 +85,7 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
>  #define HPTE64_R_KEY_HI         0x3000000000000000ULL
>  #define HPTE64_R_RPN_SHIFT      12
>  #define HPTE64_R_RPN            0x0ffffffffffff000ULL
> +#define HPTE64_R_RPN_3_0        0x01fffffffffff000ULL
>  #define HPTE64_R_FLAGS          0x00000000000003ffULL
>  #define HPTE64_R_PP             0x0000000000000003ULL
>  #define HPTE64_R_N              0x0000000000000004ULL
> @@ -98,6 +103,31 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
>  #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
>  #define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
>  
> +static inline target_ulong ppc_hash64_hpte_r_rpn(PowerPCCPU *cpu)
> +{
> +    CPUPPCState *env = &cpu->env;
> +
> +    return env->mmu_model & POWERPC_MMU_V3 ? HPTE64_R_RPN_3_0 : HPTE64_R_RPN;
> +}
> +
> +static inline target_ulong ppc_hash64_hpte_v_avpn(PowerPCCPU *cpu)
> +{
> +    CPUPPCState *env = &cpu->env;
> +
> +    return env->mmu_model & POWERPC_MMU_V3 ? HPTE64_V_AVPN_3_0 : HPTE64_V_AVPN;
> +}
> +
> +static inline target_ulong ppc_hash64_hpte_v_avpn_val(PowerPCCPU *cpu,
> +                                                      target_ulong pte0)
> +{
> +    CPUPPCState *env = &cpu->env;
> +
> +    return env->mmu_model & POWERPC_MMU_V3 ?
> +        HPTE64_V_AVPN_VAL_3_0(pte0) : HPTE64_V_AVPN_VAL(pte0);
> +}
> +
> +hwaddr ppc_hash64_hpt_reg(PowerPCCPU *cpu);
> +
>  static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
>  {
>      if (cpu->vhyp) {
> @@ -105,7 +135,7 @@ static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
>              PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
>          return vhc->hpt_base(cpu->vhyp);
>      }
> -    return cpu->env.spr[SPR_SDR1] & SDR_64_HTABORG;
> +    return ppc_hash64_hpt_reg(cpu) & SDR_64_HTABORG;
>  }
>  
>  static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cpu)
> @@ -115,7 +145,7 @@ static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cpu)
>              PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
>          return vhc->hpt_mask(cpu->vhyp);
>      }
> -    return (1ULL << ((cpu->env.spr[SPR_SDR1] & SDR_64_HTABSIZE) + 18 - 7)) - 1;
> +    return (1ULL << ((ppc_hash64_hpt_reg(cpu) & SDR_64_HTABSIZE) + 18 - 7)) - 1;
>  }
>  
>  struct ppc_hash_pte64 {

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

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

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

* Re: [Qemu-devel] [PATCH v3 3/4] target/ppc: add hash MMU support on POWER9 for PowerNV only
  2018-03-23  8:24   ` David Gibson
@ 2018-03-23  8:54     ` Cédric Le Goater
  0 siblings, 0 replies; 12+ messages in thread
From: Cédric Le Goater @ 2018-03-23  8:54 UTC (permalink / raw)
  To: David Gibson; +Cc: qemu-ppc, qemu-devel, Suraj Jitindar Singh

On 03/23/2018 09:24 AM, David Gibson wrote:
> I'm not quite sure what the "for PowerNV only" in the subject is
> supposed to be indicating.

That's the initial subject which didn't evolve with the code, which is 
now changing some sPAPR hcalls. And anyhow, hash MMU is supported on
POWER9 TCG, so there is no reason for the 'only'. KVM is another matter.

I will change the subject and split the patch in two parts, a first 
one for the changes in the HPTE bits definitions introduced by ISA v3.0 
which has some impact on the sPAPR platform. And a second patch to
introduce ppc_hash64_hpt_reg() which adds support for hash MMU to
the PowerNV platform.

Thanks,

C.

 
> On Thu, Mar 15, 2018 at 01:34:01PM +0000, Cédric Le Goater wrote:
>> The HPTE bits definitions are slightly modified in ISA v3.0. Let's add
>> some helpers to hide the differences in the hash MMU code.
>>
>> On a POWER9 processor, the Partition Table is composed of a pair of
>> doublewords per partition. The first doubleword indicates whether the
>> partition uses HPT or Radix Trees translation and contains the address
>> of the host's translation table structure and size.
>>
>> The first doubleword of the PTCR holds the Hash Page Table base
>> address for the host when the hash MMU is in use. Also add an helper
>> to retrieve the HPT base address depending on the MMU revision.
>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>
>>  Changes since v2:
>>
>>  - reworked ppc_hash64_hpt_reg() to cover only powernv machines. pseries
>>    machines being handled with cpu->vhyp at the ppc_hash64_hpt_base()
>>    level.
>>
>>  Changes since v1:
>>
>>  - introduced ppc64_v3_get_patbe0()
>>  
>>  hw/ppc/spapr_hcall.c       |  5 +++--
>>  target/ppc/mmu-book3s-v3.h |  5 +++++
>>  target/ppc/mmu-hash64.c    | 52 ++++++++++++++++++++++++++++++++++++++--------
>>  target/ppc/mmu-hash64.h    | 34 ++++++++++++++++++++++++++++--
>>  4 files changed, 83 insertions(+), 13 deletions(-)
>>
>> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
>> index 3215c3b4aec3..b437f8825819 100644
>> --- a/hw/ppc/spapr_hcall.c
>> +++ b/hw/ppc/spapr_hcall.c
>> @@ -94,7 +94,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,
>>          return H_PARAMETER;
>>      }
>>  
>> -    raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << apshift) - 1);
>> +    raddr = (ptel & ppc_hash64_hpte_r_rpn(cpu)) & ~((1ULL << apshift) - 1);
> 
> h_enter() will never be used on PowerNV, for example, so why is it
> being changed?
> 
>>      if (is_ram_address(spapr, raddr)) {
>>          /* Regular RAM - should have WIMG=0010 */
>> @@ -586,7 +586,8 @@ static int rehash_hpte(PowerPCCPU *cpu,
>>  
>>      base_pg_shift = ppc_hash64_hpte_page_shift_noslb(cpu, pte0, pte1);
>>      assert(base_pg_shift); /* H_ENTER shouldn't allow a bad encoding */
>> -    avpn = HPTE64_V_AVPN_VAL(pte0) & ~(((1ULL << base_pg_shift) - 1) >> 23);
>> +    avpn = ppc_hash64_hpte_v_avpn_val(cpu, pte0) &
>> +        ~(((1ULL << base_pg_shift) - 1) >> 23);
>>  
>>      if (pte0 & HPTE64_V_SECONDARY) {
>>          pteg = ~pteg;
>> diff --git a/target/ppc/mmu-book3s-v3.h b/target/ppc/mmu-book3s-v3.h
>> index fdf80987d7b2..a7ab580c3140 100644
>> --- a/target/ppc/mmu-book3s-v3.h
>> +++ b/target/ppc/mmu-book3s-v3.h
>> @@ -54,6 +54,11 @@ static inline bool ppc64_radix_guest(PowerPCCPU *cpu)
>>  int ppc64_v3_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
>>                                int mmu_idx);
>>  
>> +static inline hwaddr ppc64_v3_get_patbe0(PowerPCCPU *cpu)
>> +{
>> +    return ldq_phys(CPU(cpu)->as, cpu->env.spr[SPR_PTCR] & PTCR_PATB);
>> +}
>> +
>>  #endif /* TARGET_PPC64 */
>>  
>>  #endif /* CONFIG_USER_ONLY */
>> diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
>> index c9b72b742956..c425edd93ebe 100644
>> --- a/target/ppc/mmu-hash64.c
>> +++ b/target/ppc/mmu-hash64.c
>> @@ -289,6 +289,26 @@ target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb)
>>      return rt;
>>  }
>>  
>> +hwaddr ppc_hash64_hpt_reg(PowerPCCPU *cpu)
>> +{
>> +    CPUPPCState *env = &cpu->env;
>> +
>> +    /* We should not reach this routine on sPAPR machines */
>> +    assert(!cpu->vhyp);
>> +
>> +    /* PowerNV machine */
>> +    if (msr_hv) {
>> +        if (env->mmu_model & POWERPC_MMU_V3) {
>> +            return ppc64_v3_get_patbe0(cpu);
>> +        } else {
>> +            return cpu->env.spr[SPR_SDR1];
>> +        }
>> +    } else {
>> +        error_report("PowerNV guest support Unimplemented");
>> +        exit(1);
>> +    }
>> +}
>> +
>>  /* Check No-Execute or Guarded Storage */
>>  static inline int ppc_hash64_pte_noexec_guard(PowerPCCPU *cpu,
>>                                                ppc_hash_pte64_t pte)
>> @@ -451,8 +471,9 @@ void ppc_hash64_unmap_hptes(PowerPCCPU *cpu, const ppc_hash_pte64_t *hptes,
>>                          false, n * HASH_PTE_SIZE_64);
>>  }
>>  
>> -static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
>> -    uint64_t pte0, uint64_t pte1)
>> +static unsigned hpte_page_shift(PowerPCCPU *cpu,
>> +                                const struct ppc_one_seg_page_size *sps,
>> +                                uint64_t pte0, uint64_t pte1)
>>  {
>>      int i;
>>  
>> @@ -478,7 +499,7 @@ static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
>>              continue;
>>          }
>>  
>> -        mask = ((1ULL << ps->page_shift) - 1) & HPTE64_R_RPN;
>> +        mask = ((1ULL << ps->page_shift) - 1) & ppc_hash64_hpte_r_rpn(cpu);
>>  
>>          if ((pte1 & mask) == ((uint64_t)ps->pte_enc << HPTE64_R_RPN_SHIFT)) {
>>              return ps->page_shift;
>> @@ -488,6 +509,18 @@ static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
>>      return 0; /* Bad page size encoding */
>>  }
>>  
>> +static bool ppc_hash64_hpte_v_compare(PowerPCCPU *cpu, target_ulong pte0,
>> +                                      target_ulong ptem)
>> +{
>> +    CPUPPCState *env = &cpu->env;
>> +
>> +    if (env->mmu_model & POWERPC_MMU_V3) {
>> +        return HPTE64_V_COMPARE_3_0(pte0, ptem);
>> +    } else {
>> +        return HPTE64_V_COMPARE(pte0, ptem);
>> +    }
>> +}
>> +
>>  static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
>>                                       const struct ppc_one_seg_page_size *sps,
>>                                       target_ulong ptem,
>> @@ -508,8 +541,8 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
>>          pte1 = ppc_hash64_hpte1(cpu, pteg, i);
>>  
>>          /* This compares V, B, H (secondary) and the AVPN */
>> -        if (HPTE64_V_COMPARE(pte0, ptem)) {
>> -            *pshift = hpte_page_shift(sps, pte0, pte1);
>> +        if (ppc_hash64_hpte_v_compare(cpu, pte0, ptem)) {
>> +            *pshift = hpte_page_shift(cpu, sps, pte0, pte1);
>>              /*
>>               * If there is no match, ignore the PTE, it could simply
>>               * be for a different segment size encoding and the
>> @@ -569,7 +602,8 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu,
>>          epn = (eaddr & ~SEGMENT_MASK_256M) & epnmask;
>>          hash = vsid ^ (epn >> sps->page_shift);
>>      }
>> -    ptem = (slb->vsid & SLB_VSID_PTEM) | ((epn >> 16) & HPTE64_V_AVPN);
>> +    ptem = (slb->vsid & SLB_VSID_PTEM) | ((epn >> 16) &
>> +                                          ppc_hash64_hpte_v_avpn(cpu));
>>      ptem |= HPTE64_V_VALID;
>>  
>>      /* Page address translation */
>> @@ -624,7 +658,7 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
>>              break;
>>          }
>>  
>> -        shift = hpte_page_shift(sps, pte0, pte1);
>> +        shift = hpte_page_shift(cpu, sps, pte0, pte1);
>>          if (shift) {
>>              return shift;
>>          }
>> @@ -860,7 +894,7 @@ skip_slb_search:
>>  
>>      /* 7. Determine the real address from the PTE */
>>  
>> -    raddr = deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, eaddr);
>> +    raddr = deposit64(pte.pte1 & ppc_hash64_hpte_r_rpn(cpu), 0, apshift, eaddr);
>>  
>>      tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
>>                   prot, mmu_idx, 1ULL << apshift);
>> @@ -910,7 +944,7 @@ hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr)
>>          return -1;
>>      }
>>  
>> -    return deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, addr)
>> +    return deposit64(pte.pte1 & ppc_hash64_hpte_r_rpn(cpu), 0, apshift, addr)
>>          & TARGET_PAGE_MASK;
>>  }
>>  
>> diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
>> index 0ade8d15d9e4..708f4f6d222a 100644
>> --- a/target/ppc/mmu-hash64.h
>> +++ b/target/ppc/mmu-hash64.h
>> @@ -69,8 +69,12 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
>>  #define HPTE64_V_SSIZE_SHIFT    62
>>  #define HPTE64_V_AVPN_SHIFT     7
>>  #define HPTE64_V_AVPN           0x3fffffffffffff80ULL
>> +#define HPTE64_V_AVPN_3_0       0x000fffffffffff80ULL
>>  #define HPTE64_V_AVPN_VAL(x)    (((x) & HPTE64_V_AVPN) >> HPTE64_V_AVPN_SHIFT)
>> +#define HPTE64_V_AVPN_VAL_3_0(x)                        \
>> +    (((x) & HPTE64_V_AVPN_3_0) >> HPTE64_V_AVPN_SHIFT)
>>  #define HPTE64_V_COMPARE(x, y)  (!(((x) ^ (y)) & 0xffffffffffffff83ULL))
>> +#define HPTE64_V_COMPARE_3_0(x, y)  (!(((x) ^ (y)) & 0x3fffffffffffff83ULL))
>>  #define HPTE64_V_BOLTED         0x0000000000000010ULL
>>  #define HPTE64_V_LARGE          0x0000000000000004ULL
>>  #define HPTE64_V_SECONDARY      0x0000000000000002ULL
>> @@ -81,6 +85,7 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
>>  #define HPTE64_R_KEY_HI         0x3000000000000000ULL
>>  #define HPTE64_R_RPN_SHIFT      12
>>  #define HPTE64_R_RPN            0x0ffffffffffff000ULL
>> +#define HPTE64_R_RPN_3_0        0x01fffffffffff000ULL
>>  #define HPTE64_R_FLAGS          0x00000000000003ffULL
>>  #define HPTE64_R_PP             0x0000000000000003ULL
>>  #define HPTE64_R_N              0x0000000000000004ULL
>> @@ -98,6 +103,31 @@ void ppc_hash64_update_rmls(CPUPPCState *env);
>>  #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
>>  #define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
>>  
>> +static inline target_ulong ppc_hash64_hpte_r_rpn(PowerPCCPU *cpu)
>> +{
>> +    CPUPPCState *env = &cpu->env;
>> +
>> +    return env->mmu_model & POWERPC_MMU_V3 ? HPTE64_R_RPN_3_0 : HPTE64_R_RPN;
>> +}
>> +
>> +static inline target_ulong ppc_hash64_hpte_v_avpn(PowerPCCPU *cpu)
>> +{
>> +    CPUPPCState *env = &cpu->env;
>> +
>> +    return env->mmu_model & POWERPC_MMU_V3 ? HPTE64_V_AVPN_3_0 : HPTE64_V_AVPN;
>> +}
>> +
>> +static inline target_ulong ppc_hash64_hpte_v_avpn_val(PowerPCCPU *cpu,
>> +                                                      target_ulong pte0)
>> +{
>> +    CPUPPCState *env = &cpu->env;
>> +
>> +    return env->mmu_model & POWERPC_MMU_V3 ?
>> +        HPTE64_V_AVPN_VAL_3_0(pte0) : HPTE64_V_AVPN_VAL(pte0);
>> +}
>> +
>> +hwaddr ppc_hash64_hpt_reg(PowerPCCPU *cpu);
>> +
>>  static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
>>  {
>>      if (cpu->vhyp) {
>> @@ -105,7 +135,7 @@ static inline hwaddr ppc_hash64_hpt_base(PowerPCCPU *cpu)
>>              PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
>>          return vhc->hpt_base(cpu->vhyp);
>>      }
>> -    return cpu->env.spr[SPR_SDR1] & SDR_64_HTABORG;
>> +    return ppc_hash64_hpt_reg(cpu) & SDR_64_HTABORG;
>>  }
>>  
>>  static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cpu)
>> @@ -115,7 +145,7 @@ static inline hwaddr ppc_hash64_hpt_mask(PowerPCCPU *cpu)
>>              PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
>>          return vhc->hpt_mask(cpu->vhyp);
>>      }
>> -    return (1ULL << ((cpu->env.spr[SPR_SDR1] & SDR_64_HTABSIZE) + 18 - 7)) - 1;
>> +    return (1ULL << ((ppc_hash64_hpt_reg(cpu) & SDR_64_HTABSIZE) + 18 - 7)) - 1;
>>  }
>>  
>>  struct ppc_hash_pte64 {
> 

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

* Re: [Qemu-devel] [PATCH v3 4/4] target/ppc: generalize check on radix when in HV mode
  2018-03-15 13:34 ` [Qemu-devel] [PATCH v3 4/4] target/ppc: generalize check on radix when in HV mode Cédric Le Goater
@ 2018-04-05  4:37   ` David Gibson
  0 siblings, 0 replies; 12+ messages in thread
From: David Gibson @ 2018-04-05  4:37 UTC (permalink / raw)
  To: Cédric Le Goater; +Cc: qemu-ppc, qemu-devel, Suraj Jitindar Singh

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

On Thu, Mar 15, 2018 at 01:34:02PM +0000, Cédric Le Goater wrote:
> On a POWER9 processor, the first doubleword of the partition table
> entry (as pointed to by the PTCR) indicates whether the host uses HPT
> or Radix Tree translation for that partition. Use that bit to check
> for radix mode on pseries and powernv QEMU machines.
> 
> Signed-off-by: Cédric Le Goater <clg@kaod.org>

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


> ---
> 
>  Changes since v2:
> 
>  - reworked ppc64_v3_radix() to distinguish pseries machine from
>    powernv machines
>  - kept ppc64_radix_guest()
> 
>  Changes since v1:
> 
>  - fixed commit log
>  - introduced ppc64_v3_get_patbe0()
>  - renamed ppc64_radix() in ppc64_v3_radix()
> 
>  target/ppc/mmu-book3s-v3.c | 23 +++++++++++++++++++++--
>  target/ppc/mmu-book3s-v3.h |  4 +++-
>  target/ppc/mmu_helper.c    |  4 ++--
>  3 files changed, 26 insertions(+), 5 deletions(-)
> 
> diff --git a/target/ppc/mmu-book3s-v3.c b/target/ppc/mmu-book3s-v3.c
> index b60df4408f3b..89edbb6abc5c 100644
> --- a/target/ppc/mmu-book3s-v3.c
> +++ b/target/ppc/mmu-book3s-v3.c
> @@ -19,16 +19,35 @@
>  
>  #include "qemu/osdep.h"
>  #include "cpu.h"
> +#include "qemu/error-report.h"
>  #include "mmu-hash64.h"
>  #include "mmu-book3s-v3.h"
>  #include "mmu-radix64.h"
>  
> +bool ppc64_v3_radix(PowerPCCPU *cpu)
> +{
> +    CPUPPCState *env = &cpu->env;
> +
> +    /* sPAPR machine */
> +    if (cpu->vhyp) {
> +        return ppc64_radix_guest(cpu);
> +    }
> +
> +    /* PowerNV machine - only HV mode is supported */
> +    if (msr_hv) {
> +        return ppc64_v3_get_patbe0(cpu) & PATBE0_HR;
> +    } else {
> +        error_report("PowerNV guest support Unimplemented");
> +        exit(1);
> +    }
> +}
> +
>  int ppc64_v3_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
>                                int mmu_idx)
>  {
> -    if (ppc64_radix_guest(cpu)) { /* Guest uses radix */
> +    if (ppc64_v3_radix(cpu)) {
>          return ppc_radix64_handle_mmu_fault(cpu, eaddr, rwx, mmu_idx);
> -    } else { /* Guest uses hash */
> +    } else {
>          return ppc_hash64_handle_mmu_fault(cpu, eaddr, rwx, mmu_idx);
>      }
>  }
> diff --git a/target/ppc/mmu-book3s-v3.h b/target/ppc/mmu-book3s-v3.h
> index a7ab580c3140..9721791d2dd3 100644
> --- a/target/ppc/mmu-book3s-v3.h
> +++ b/target/ppc/mmu-book3s-v3.h
> @@ -29,7 +29,8 @@
>  #define PTCR_PATS               0x000000000000001FULL /* Partition Table Size */
>  
>  /* Partition Table Entry Fields */
> -#define PATBE1_GR 0x8000000000000000
> +#define PATBE0_HR               PPC_BIT(0)            /* 1:Host Radix  0:HPT  */
> +#define PATBE1_GR               PPC_BIT(0)            /* 1:Guest Radix 0:HPT  */
>  
>  /* Process Table Entry */
>  struct prtb_entry {
> @@ -50,6 +51,7 @@ static inline bool ppc64_radix_guest(PowerPCCPU *cpu)
>  
>      return !!(vhc->get_patbe(cpu->vhyp) & PATBE1_GR);
>  }
> +bool ppc64_v3_radix(PowerPCCPU *cpu);
>  
>  int ppc64_v3_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
>                                int mmu_idx);
> diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> index 03009eee723a..fba203cdef18 100644
> --- a/target/ppc/mmu_helper.c
> +++ b/target/ppc/mmu_helper.c
> @@ -1285,7 +1285,7 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
>          dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
>          break;
>      case POWERPC_MMU_VER_3_00:
> -        if (ppc64_radix_guest(ppc_env_get_cpu(env))) {
> +        if (ppc64_v3_radix(ppc_env_get_cpu(env))) {
>              /* TODO - Unsupported */
>          } else {
>              dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
> @@ -1431,7 +1431,7 @@ hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
>      case POWERPC_MMU_VER_2_07:
>          return ppc_hash64_get_phys_page_debug(cpu, addr);
>      case POWERPC_MMU_VER_3_00:
> -        if (ppc64_radix_guest(ppc_env_get_cpu(env))) {
> +        if (ppc64_v3_radix(ppc_env_get_cpu(env))) {
>              return ppc_radix64_get_phys_page_debug(cpu, addr);
>          } else {
>              return ppc_hash64_get_phys_page_debug(cpu, addr);

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

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

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

end of thread, other threads:[~2018-04-05  4:38 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-15 13:33 [Qemu-devel] [PATCH v3 0/4] target/ppc: add hash MMU support for the POWER9 PowerNV machine Cédric Le Goater
2018-03-15 13:33 ` [Qemu-devel] [PATCH v3 1/4] target/ppc: export external HPT via virtual hypervisor Cédric Le Goater
2018-03-17  4:15   ` David Gibson
2018-03-17  8:55     ` [Qemu-devel] [Qemu-ppc] " Cédric Le Goater
2018-03-21  3:17       ` David Gibson
2018-03-15 13:34 ` [Qemu-devel] [PATCH v3 2/4] target/ppc: add basic support for PTCR on POWER9 Cédric Le Goater
2018-03-21  3:19   ` David Gibson
2018-03-15 13:34 ` [Qemu-devel] [PATCH v3 3/4] target/ppc: add hash MMU support on POWER9 for PowerNV only Cédric Le Goater
2018-03-23  8:24   ` David Gibson
2018-03-23  8:54     ` Cédric Le Goater
2018-03-15 13:34 ` [Qemu-devel] [PATCH v3 4/4] target/ppc: generalize check on radix when in HV mode Cédric Le Goater
2018-04-05  4:37   ` 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.