diff mbox series

[v4,4/5] target/ppc: add hash MMU support for PowerNV POWER9 machines

Message ID 20180424113045.25687-5-clg@kaod.org
State New
Headers show
Series target/ppc: add hash MMU support for the POWER9 PowerNV machine | expand

Commit Message

Cédric Le Goater April 24, 2018, 11:30 a.m. UTC
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. Add an helper to
retrieve the HPT base address depending on the MMU revision.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 target/ppc/mmu-book3s-v3.h |  5 +++++
 target/ppc/mmu-hash64.c    | 20 ++++++++++++++++++++
 target/ppc/mmu-hash64.h    |  6 ++++--
 3 files changed, 29 insertions(+), 2 deletions(-)

Comments

Cédric Le Goater April 24, 2018, 12:03 p.m. UTC | #1
> +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_3_00) {
> +            return ppc64_v3_get_patbe0(cpu);
> +        } else {
> +            return cpu->env.spr[SPR_SDR1];
> +        }
> +    } else {
> +        error_report("PowerNV guest support Unimplemented");
> +        exit(1);

I just noticed that this breaks 970 CPUs ...

C.


> +    }
> +}
Cédric Le Goater April 24, 2018, 12:41 p.m. UTC | #2
On 04/24/2018 02:03 PM, Cédric Le Goater wrote:
>> +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_3_00) {
>> +            return ppc64_v3_get_patbe0(cpu);
>> +        } else {
>> +            return cpu->env.spr[SPR_SDR1];
>> +        }
>> +    } else {
>> +        error_report("PowerNV guest support Unimplemented");
>> +        exit(1);
> 
> I just noticed that this breaks 970 CPUs ...

How about ?

    if (env->mmu_model < POWERPC_MMU_2_07) {
        return cpu->env.spr[SPR_SDR1];
    }

    /* P8/P9 PowerNV machine */
    if (msr_hv) {
        if (env->mmu_model == POWERPC_MMU_3_00) {
            return ppc64_v3_get_patbe0(cpu);
        } else {
            return cpu->env.spr[SPR_SDR1];
        }
    } else {
        error_report("PowerNV guest support Unimplemented");
        exit(1);
    }

and I have to fix all the :

	env->mmu_model & POWERPC_MMU_3_00

by :

	env->mmu_model == POWERPC_MMU_3_00

I tripped over with the recent changes
 
C.
David Gibson May 3, 2018, 12:58 a.m. UTC | #3
On Tue, Apr 24, 2018 at 02:41:47PM +0200, Cédric Le Goater wrote:
> On 04/24/2018 02:03 PM, Cédric Le Goater wrote:
> >> +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_3_00) {
> >> +            return ppc64_v3_get_patbe0(cpu);
> >> +        } else {
> >> +            return cpu->env.spr[SPR_SDR1];
> >> +        }
> >> +    } else {
> >> +        error_report("PowerNV guest support Unimplemented");
> >> +        exit(1);
> > 
> > I just noticed that this breaks 970 CPUs ...
> 
> How about ?

Hmm.. I'm not actually seeing why it breaks 970.

I really want to ditch 970 support, but we have to go through the
deprecation process first.

> 
>     if (env->mmu_model < POWERPC_MMU_2_07) {
>         return cpu->env.spr[SPR_SDR1];
>     }
> 
>     /* P8/P9 PowerNV machine */
>     if (msr_hv) {
>         if (env->mmu_model == POWERPC_MMU_3_00) {
>             return ppc64_v3_get_patbe0(cpu);
>         } else {
>             return cpu->env.spr[SPR_SDR1];
>         }
>     } else {
>         error_report("PowerNV guest support Unimplemented");
>         exit(1);
>     }
> 
> and I have to fix all the :
> 
> 	env->mmu_model & POWERPC_MMU_3_00
> 
> by :
> 
> 	env->mmu_model == POWERPC_MMU_3_00
> 
> I tripped over with the recent changes

Right.. eventually I actually want this to be something more like
	if (cpu->radix64_opts)
but I'm not sure on the details yet.
Cédric Le Goater May 3, 2018, 5:52 a.m. UTC | #4
On 05/03/2018 02:58 AM, David Gibson wrote:
> On Tue, Apr 24, 2018 at 02:41:47PM +0200, Cédric Le Goater wrote:
>> On 04/24/2018 02:03 PM, Cédric Le Goater wrote:
>>>> +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_3_00) {
>>>> +            return ppc64_v3_get_patbe0(cpu);
>>>> +        } else {
>>>> +            return cpu->env.spr[SPR_SDR1];
>>>> +        }
>>>> +    } else {
>>>> +        error_report("PowerNV guest support Unimplemented");
>>>> +        exit(1);
>>>
>>> I just noticed that this breaks 970 CPUs ...
>>
>> How about ?
> 
> Hmm.. I'm not actually seeing why it breaks 970.

it does not have MSR_SHV bit.

> I really want to ditch 970 support, but we have to go through the
> deprecation process first.

Is it causing a lot of maintenance issues ? 

>>
>>     if (env->mmu_model < POWERPC_MMU_2_07) {
>>         return cpu->env.spr[SPR_SDR1];
>>     }
>>
>>     /* P8/P9 PowerNV machine */
>>     if (msr_hv) {
>>         if (env->mmu_model == POWERPC_MMU_3_00) {
>>             return ppc64_v3_get_patbe0(cpu);
>>         } else {
>>             return cpu->env.spr[SPR_SDR1];
>>         }
>>     } else {
>>         error_report("PowerNV guest support Unimplemented");
>>         exit(1);
>>     }
>>
>> and I have to fix all the :
>>
>> 	env->mmu_model & POWERPC_MMU_3_00
>>
>> by :
>>
>> 	env->mmu_model == POWERPC_MMU_3_00
>>
>> I tripped over with the recent changes
> 
> Right.. eventually I actually want this to be something more like
> 	if (cpu->radix64_opts)
> but I'm not sure on the details yet.

OK.

C.
David Gibson May 3, 2018, 6:36 a.m. UTC | #5
On Thu, May 03, 2018 at 07:52:32AM +0200, Cédric Le Goater wrote:
> On 05/03/2018 02:58 AM, David Gibson wrote:
> > On Tue, Apr 24, 2018 at 02:41:47PM +0200, Cédric Le Goater wrote:
> >> On 04/24/2018 02:03 PM, Cédric Le Goater wrote:
> >>>> +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_3_00) {
> >>>> +            return ppc64_v3_get_patbe0(cpu);
> >>>> +        } else {
> >>>> +            return cpu->env.spr[SPR_SDR1];
> >>>> +        }
> >>>> +    } else {
> >>>> +        error_report("PowerNV guest support Unimplemented");
> >>>> +        exit(1);
> >>>
> >>> I just noticed that this breaks 970 CPUs ...
> >>
> >> How about ?
> > 
> > Hmm.. I'm not actually seeing why it breaks 970.
> 
> it does not have MSR_SHV bit.

It does, actually.  At least, as long as it's not strapped into "Apple
mode".

> > I really want to ditch 970 support, but we have to go through the
> > deprecation process first.
> 
> Is it causing a lot of maintenance issues ?

Enough.  The explicit RMA allocation stuff is a particular pain.
Cédric Le Goater May 3, 2018, 8:05 a.m. UTC | #6
On 05/03/2018 08:36 AM, David Gibson wrote:
> On Thu, May 03, 2018 at 07:52:32AM +0200, Cédric Le Goater wrote:
>> On 05/03/2018 02:58 AM, David Gibson wrote:
>>> On Tue, Apr 24, 2018 at 02:41:47PM +0200, Cédric Le Goater wrote:
>>>> On 04/24/2018 02:03 PM, Cédric Le Goater wrote:
>>>>>> +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_3_00) {
>>>>>> +            return ppc64_v3_get_patbe0(cpu);
>>>>>> +        } else {
>>>>>> +            return cpu->env.spr[SPR_SDR1];
>>>>>> +        }
>>>>>> +    } else {
>>>>>> +        error_report("PowerNV guest support Unimplemented");
>>>>>> +        exit(1);
>>>>>
>>>>> I just noticed that this breaks 970 CPUs ...
>>>>
>>>> How about ?
>>>
>>> Hmm.. I'm not actually seeing why it breaks 970.
>>
>> it does not have MSR_SHV bit.
> 
> It does, actually.  At least, as long as it's not strapped into "Apple
> mode".

ah. this is why the tests are failing then : 

tests/boot-serial-test.c:    { "ppc64", "mac99", "", "PowerPC,970FX" },

C.

> 
>>> I really want to ditch 970 support, but we have to go through the
>>> deprecation process first.
>>
>> Is it causing a lot of maintenance issues ?
> 
> Enough.  The explicit RMA allocation stuff is a particular pain.
>
diff mbox series

Patch

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 ecea2ae04dd3..fae164d30706 100644
--- a/target/ppc/mmu-hash64.c
+++ b/target/ppc/mmu-hash64.c
@@ -290,6 +290,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_3_00) {
+            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)
diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h
index a3a0de452b94..daf3ba27e2cc 100644
--- a/target/ppc/mmu-hash64.h
+++ b/target/ppc/mmu-hash64.h
@@ -129,12 +129,14 @@  static inline target_ulong ppc_hash64_hpte_v_avpn_val(PowerPCCPU *cpu,
         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) {
         return 0;
     }
-    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)
@@ -144,7 +146,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 {