[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PULL 13/23] ppc: Fix 64K pages support in full emulation
From: |
David Gibson |
Subject: |
[Qemu-ppc] [PULL 13/23] ppc: Fix 64K pages support in full emulation |
Date: |
Fri, 1 Jul 2016 16:41:49 +1000 |
From: Benjamin Herrenschmidt <address@hidden>
We were always advertising only 4K & 16M. Additionally the code wasn't
properly matching the page size with the PTE content, which meant we
could potentially hit an incorrect PTE if the guest used multiple sizes.
Finally, honor the CPU capabilities when decoding the size from the SLB
so we don't try to use 64K pages on 970.
This still doesn't add support for MPSS (Multiple Page Sizes per Segment)
Signed-off-by: Benjamin Herrenschmidt <address@hidden>
[clg: fixed checkpatch.pl errors
commits 61a36c9b5a12 and 1114e712c998 reworked the hpte code
doing insertion/removal in hw/ppc/spapr_hcall.c. The hunks
modifying these areas were removed. ]
Signed-off-by: Cédric Le Goater <address@hidden>
Signed-off-by: David Gibson <address@hidden>
---
target-ppc/cpu-qom.h | 3 +++
target-ppc/mmu-hash64.c | 39 +++++++++++++++++++++++++++++++++++----
target-ppc/translate_init.c | 22 +++++++++++++++++++---
3 files changed, 57 insertions(+), 7 deletions(-)
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 0fad2de..2864105 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -70,18 +70,21 @@ enum powerpc_mmu_t {
#define POWERPC_MMU_64 0x00010000
#define POWERPC_MMU_1TSEG 0x00020000
#define POWERPC_MMU_AMR 0x00040000
+#define POWERPC_MMU_64K 0x00080000
/* 64 bits PowerPC MMU */
POWERPC_MMU_64B = POWERPC_MMU_64 | 0x00000001,
/* Architecture 2.03 and later (has LPCR) */
POWERPC_MMU_2_03 = POWERPC_MMU_64 | 0x00000002,
/* Architecture 2.06 variant */
POWERPC_MMU_2_06 = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
+ | POWERPC_MMU_64K
| POWERPC_MMU_AMR | 0x00000003,
/* Architecture 2.06 "degraded" (no 1T segments) */
POWERPC_MMU_2_06a = POWERPC_MMU_64 | POWERPC_MMU_AMR
| 0x00000003,
/* Architecture 2.07 variant */
POWERPC_MMU_2_07 = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
+ | POWERPC_MMU_64K
| POWERPC_MMU_AMR | 0x00000004,
/* Architecture 2.07 "degraded" (no 1T segments) */
POWERPC_MMU_2_07a = POWERPC_MMU_64 | POWERPC_MMU_AMR
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 6d6f26c..3b1357a 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -450,9 +450,31 @@ void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t
token)
}
}
+/* Returns the effective page shift or 0. MPSS isn't supported yet so
+ * this will always be the slb_pshift or 0
+ */
+static uint32_t ppc_hash64_pte_size_decode(uint64_t pte1, uint32_t slb_pshift)
+{
+ switch (slb_pshift) {
+ case 12:
+ return 12;
+ case 16:
+ if ((pte1 & 0xf000) == 0x1000) {
+ return 16;
+ }
+ return 0;
+ case 24:
+ if ((pte1 & 0xff000) == 0) {
+ return 24;
+ }
+ return 0;
+ }
+ return 0;
+}
+
static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
- bool secondary, target_ulong ptem,
- ppc_hash_pte64_t *pte)
+ uint32_t slb_pshift, bool secondary,
+ target_ulong ptem, ppc_hash_pte64_t *pte)
{
CPUPPCState *env = &cpu->env;
int i;
@@ -472,6 +494,13 @@ static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu,
hwaddr hash,
if ((pte0 & HPTE64_V_VALID)
&& (secondary == !!(pte0 & HPTE64_V_SECONDARY))
&& HPTE64_V_COMPARE(pte0, ptem)) {
+ uint32_t pshift = ppc_hash64_pte_size_decode(pte1, slb_pshift);
+ if (pshift == 0) {
+ continue;
+ }
+ /* We don't do anything with pshift yet as qemu TLB only deals
+ * with 4K pages anyway
+ */
pte->pte0 = pte0;
pte->pte1 = pte1;
ppc_hash64_stop_access(cpu, token);
@@ -525,7 +554,8 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu,
" vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
" hash=" TARGET_FMT_plx "\n",
env->htab_base, env->htab_mask, vsid, ptem, hash);
- pte_offset = ppc_hash64_pteg_search(cpu, hash, 0, ptem, pte);
+ pte_offset = ppc_hash64_pteg_search(cpu, hash, slb->sps->page_shift,
+ 0, ptem, pte);
if (pte_offset == -1) {
/* Secondary PTEG lookup */
@@ -535,7 +565,8 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu,
" hash=" TARGET_FMT_plx "\n", env->htab_base,
env->htab_mask, vsid, ptem, ~hash);
- pte_offset = ppc_hash64_pteg_search(cpu, ~hash, 1, ptem, pte);
+ pte_offset = ppc_hash64_pteg_search(cpu, ~hash, slb->sps->page_shift,
1,
+ ptem, pte);
}
return pte_offset;
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 55d1bfa..843f19b 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -10293,8 +10293,8 @@ static void ppc_cpu_initfn(Object *obj)
if (pcc->sps) {
env->sps = *pcc->sps;
} else if (env->mmu_model & POWERPC_MMU_64) {
- /* Use default sets of page sizes */
- static const struct ppc_segment_page_sizes defsps = {
+ /* Use default sets of page sizes. We don't support MPSS */
+ static const struct ppc_segment_page_sizes defsps_4k = {
.sps = {
{ .page_shift = 12, /* 4K */
.slb_enc = 0,
@@ -10306,7 +10306,23 @@ static void ppc_cpu_initfn(Object *obj)
},
},
};
- env->sps = defsps;
+ static const struct ppc_segment_page_sizes defsps_64k = {
+ .sps = {
+ { .page_shift = 12, /* 4K */
+ .slb_enc = 0,
+ .enc = { { .page_shift = 12, .pte_enc = 0 } }
+ },
+ { .page_shift = 16, /* 64K */
+ .slb_enc = 0x110,
+ .enc = { { .page_shift = 16, .pte_enc = 1 } }
+ },
+ { .page_shift = 24, /* 16M */
+ .slb_enc = 0x100,
+ .enc = { { .page_shift = 24, .pte_enc = 0 } }
+ },
+ },
+ };
+ env->sps = (env->mmu_model & POWERPC_MMU_64K) ? defsps_64k : defsps_4k;
}
#endif /* defined(TARGET_PPC64) */
--
2.7.4
- Re: [Qemu-ppc] [Qemu-devel] [PULL 05/23] ppc: Enforce setting MSR:EE, IR and DR when MSR:PR is set, (continued)
- Re: [Qemu-ppc] [Qemu-devel] [PULL 05/23] ppc: Enforce setting MSR:EE, IR and DR when MSR:PR is set, Mark Cave-Ayland, 2016/07/09
- Re: [Qemu-ppc] [PULL 05/23] ppc: Enforce setting MSR:EE, IR and DR when MSR:PR is set, Cédric Le Goater, 2016/07/09
- Re: [Qemu-ppc] [PULL 05/23] ppc: Enforce setting MSR:EE, IR and DR when MSR:PR is set, Benjamin Herrenschmidt, 2016/07/09
- Re: [Qemu-ppc] [Qemu-devel] [PULL 05/23] ppc: Enforce setting MSR:EE, IR and DR when MSR:PR is set, Cédric Le Goater, 2016/07/09
[Qemu-ppc] [PULL 03/23] ppc: Use a helper to filter writes to LPCR, David Gibson, 2016/07/01
[Qemu-ppc] [PULL 02/23] ppc: Update LPCR definitions, David Gibson, 2016/07/01
[Qemu-ppc] [PULL 21/23] spapr: do proper error propagation in spapr_cpu_core_realize_child(), David Gibson, 2016/07/01
[Qemu-ppc] [PULL 19/23] spapr: Restore support for 970MP and POWER8NVL CPU cores, David Gibson, 2016/07/01
[Qemu-ppc] [PULL 12/23] target-ppc: Eliminate redundant and incorrect function booke206_page_size_to_tlb, David Gibson, 2016/07/01
[Qemu-ppc] [PULL 01/23] ppc: Add a bunch of hypervisor SPRs to Book3s, David Gibson, 2016/07/01
[Qemu-ppc] [PULL 13/23] ppc: Fix 64K pages support in full emulation,
David Gibson <=
[Qemu-ppc] [PULL 08/23] ppc: Print HSRR0/HSRR1 in "info registers", David Gibson, 2016/07/01
[Qemu-ppc] [PULL 18/23] target-ppc: gen_pause for instructions: yield, mdoio, mdoom, miso, David Gibson, 2016/07/01
[Qemu-ppc] [PULL 09/23] hw/ppc/spapr: Add some missing hcall function set strings, David Gibson, 2016/07/01
[Qemu-ppc] [PULL 22/23] spapr: drop duplicate variable in spapr_core_release(), David Gibson, 2016/07/01
[Qemu-ppc] [PULL 23/23] qmp: fix spapr example of query-hotpluggable-cpus, David Gibson, 2016/07/01
[Qemu-ppc] [PULL 07/23] ppc: LPCR is a HV resource, David Gibson, 2016/07/01
[Qemu-ppc] [PULL 20/23] spapr: drop reference on child object during core realization, David Gibson, 2016/07/01
[Qemu-ppc] [PULL 04/23] ppc: Fix conditions for delivering external interrupts to a guest, David Gibson, 2016/07/01
[Qemu-ppc] [PULL 11/23] spapr: Restore support for older PowerPC CPU cores, David Gibson, 2016/07/01
[Qemu-ppc] [PULL 06/23] ppc: Initial HDEC support, David Gibson, 2016/07/01