Re: [PATCH v4 4/4] target/ppc: Add support for Radix partition-scoped translation

2020-04-08 Thread Cédric Le Goater
>>> -*raddr = g_raddr;
>>> +/*
>>> + * Perform partition-scoped translation if !HV or HV access to
>>> + * quadrants 1 or 2. Translates a guest real address to a host
>>> + * real address.
>>> + */
>>> +if ((lpid != 0) || (!cpu->vhyp && !msr_hv)) {
>>
>> This check is too complex for my taste. Also it doesn't seem right
>> to look at lpid if the machine is pseries, even if it would happen
>> to work because pseries cannot have lpid != 0. I think we should
>> have distinct paths for powernv and pseries.
>>
>> A bit like with the following squashed in:
>>
>> ===
>> --- a/target/ppc/mmu-radix64.c
>> +++ b/target/ppc/mmu-radix64.c
>> @@ -489,22 +489,28 @@ static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr 
>> eaddr, int rwx,
>>  g_raddr = eaddr & R_EADDR_MASK;
>>  }
>>  
>> -/*
>> - * Perform partition-scoped translation if !HV or HV access to
>> - * quadrants 1 or 2. Translates a guest real address to a host
>> - * real address.
>> - */
>> -if ((lpid != 0) || (!cpu->vhyp && !msr_hv)) {
>> -int ret = ppc_radix64_partition_scoped_xlate(cpu, rwx, eaddr, 
>> g_raddr,
>> +if (cpu->vhyp) {
>> +*raddr = g_raddr;
>> +} else {
>> +/*
>> + * Perform partition-scoped translation if !HV or HV access to
>> + * quadrants 1 or 2. Translates a guest real address to a host
>> + * real address.
>> + */
>> +if (lpid || !msr_hv) {
>> +int ret;
>> +
>> +ret = ppc_radix64_partition_scoped_xlate(cpu, rwx, eaddr, 
>> g_raddr,
>>   pate, raddr, , 
>> ,
>>   0, cause_excp);
>> -if (ret) {
>> -return ret;
>> +if (ret) {
>> +return ret;
>> +}
>> +*psizep = MIN(*psizep, psize);
>> +*protp &= prot;
>> +} else {
>> +*raddr = g_raddr;
>>  }
>> -*psizep = MIN(*psizep, psize);
>> -*protp &= prot;
>> -} else {
>> -*raddr = g_raddr;
>>  }
>>  
>>  return 0;
>> ===
>>
>> David,
>>
>> If my comment makes sense to you, can you squash the above fix into
>> Cedric's patch ?
> 
> Yes.  I also think we shouldn't be looking at lpid for the vhyp case.
> I've applied the rest of the series to ppc-for-5.1, and folded in this
> correction as suggested.


I explored a solution with two ppc_radix64_xlate() routines, one simple 
for pseries, a second more complex for powernv but it didn't look very
good. May be it will be easier now that the first patches are merged. 

Thanks,

C. 





Re: [PATCH v4 4/4] target/ppc: Add support for Radix partition-scoped translation

2020-04-07 Thread David Gibson
On Fri, Apr 03, 2020 at 05:11:29PM +0200, Greg Kurz wrote:
> On Fri,  3 Apr 2020 16:00:56 +0200
> Cédric Le Goater  wrote:
> 
> > The Radix tree translation model currently supports process-scoped
> > translation for the PowerNV machine (Hypervisor mode) and for the
> > pSeries machine (Guest mode). Guests running under an emulated
> > Hypervisor (PowerNV machine) require a new type of Radix translation,
> > called partition-scoped, which is missing today.
> > 
> > The Radix tree translation is a 2 steps process. The first step,
> > process-scoped translation, converts an effective Address to a guest
> > real address, and the second step, partition-scoped translation,
> > converts a guest real address to a host real address.
> > 
> > There are difference cases to covers :
> > 
> > * Hypervisor real mode access: no Radix translation.
> > 
> > * Hypervisor or host application access (quadrant 0 and 3) with
> >   relocation on: process-scoped translation.
> > 
> > * Guest OS real mode access: only partition-scoped translation.
> > 
> > * Guest OS real or guest application access (quadrant 0 and 3) with
> >   relocation on: both process-scoped translation and partition-scoped
> >   translations.
> > 
> > * Hypervisor access in quadrant 1 and 2 with relocation on: both
> >   process-scoped translation and partition-scoped translations.
> > 
> > The radix tree partition-scoped translation is performed using tables
> > pointed to by the first double-word of the Partition Table Entries and
> > process-scoped translation uses tables pointed to by the Process Table
> > Entries (second double-word of the Partition Table Entries).
> > 
> > Both partition-scoped and process-scoped translations process are
> > identical and thus the radix tree traversing code is largely reused.
> > However, errors in partition-scoped translations generate hypervisor
> > exceptions.
> > 
> > Signed-off-by: Suraj Jitindar Singh 
> > Signed-off-by: Greg Kurz 
> > Signed-off-by: Cédric Le Goater 
> > ---
> >  target/ppc/cpu.h |   3 +
> >  target/ppc/excp_helper.c |   3 +-
> >  target/ppc/mmu-radix64.c | 188 +++
> >  3 files changed, 175 insertions(+), 19 deletions(-)
> > 
> > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> > index f4a5304d4356..6b6dd7e483f1 100644
> > --- a/target/ppc/cpu.h
> > +++ b/target/ppc/cpu.h
> > @@ -463,6 +463,9 @@ typedef struct ppc_v3_pate_t {
> >  #define DSISR_AMR0x0020
> >  /* Unsupported Radix Tree Configuration */
> >  #define DSISR_R_BADCONFIG0x0008
> > +#define DSISR_ATOMIC_RC  0x0004
> > +/* Unable to translate address of (guest) pde or process/page table entry 
> > */
> > +#define DSISR_PRTABLE_FAULT  0x0002
> >  
> >  /* SRR1 error code fields */
> >  
> > diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> > index 1acc3786de0e..f05297966472 100644
> > --- a/target/ppc/excp_helper.c
> > +++ b/target/ppc/excp_helper.c
> > @@ -506,9 +506,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
> > excp_model, int excp)
> >  case POWERPC_EXCP_ISEG:  /* Instruction segment exception  
> >   */
> >  case POWERPC_EXCP_TRACE: /* Trace exception
> >   */
> >  break;
> > +case POWERPC_EXCP_HISI:  /* Hypervisor instruction storage 
> > exception */
> > +msr |= env->error_code;
> >  case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception   
> >   */
> >  case POWERPC_EXCP_HDSI:  /* Hypervisor data storage exception  
> >   */
> > -case POWERPC_EXCP_HISI:  /* Hypervisor instruction storage 
> > exception */
> >  case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception  
> >   */
> >  case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment 
> > exception */
> >  case POWERPC_EXCP_SDOOR_HV:  /* Hypervisor Doorbell interrupt  
> >   */
> > diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
> > index 2400da41e06c..d473dc742e11 100644
> > --- a/target/ppc/mmu-radix64.c
> > +++ b/target/ppc/mmu-radix64.c
> > @@ -103,6 +103,27 @@ static void ppc_radix64_raise_si(PowerPCCPU *cpu, int 
> > rwx, vaddr eaddr,
> >  }
> >  }
> >  
> > +static void ppc_radix64_raise_hsi(PowerPCCPU *cpu, int rwx, vaddr eaddr,
> > +  hwaddr g_raddr, uint32_t cause)
> > +{
> > +CPUState *cs = CPU(cpu);
> > +CPUPPCState *env = >env;
> > +
> > +if (rwx == 2) { /* H Instruction Storage Interrupt */
> > +cs->exception_index = POWERPC_EXCP_HISI;
> > +env->spr[SPR_ASDR] = g_raddr;
> > +env->error_code = cause;
> > +} else { /* H Data Storage Interrupt */
> > +cs->exception_index = POWERPC_EXCP_HDSI;
> > +if (rwx == 1) { /* Write -> Store */
> > +cause |= DSISR_ISSTORE;
> > +}
> > +env->spr[SPR_HDSISR] = cause;
> > +env->spr[SPR_HDAR] = eaddr;
> > +  

Re: [PATCH v4 4/4] target/ppc: Add support for Radix partition-scoped translation

2020-04-03 Thread Greg Kurz
On Fri,  3 Apr 2020 16:00:56 +0200
Cédric Le Goater  wrote:

> The Radix tree translation model currently supports process-scoped
> translation for the PowerNV machine (Hypervisor mode) and for the
> pSeries machine (Guest mode). Guests running under an emulated
> Hypervisor (PowerNV machine) require a new type of Radix translation,
> called partition-scoped, which is missing today.
> 
> The Radix tree translation is a 2 steps process. The first step,
> process-scoped translation, converts an effective Address to a guest
> real address, and the second step, partition-scoped translation,
> converts a guest real address to a host real address.
> 
> There are difference cases to covers :
> 
> * Hypervisor real mode access: no Radix translation.
> 
> * Hypervisor or host application access (quadrant 0 and 3) with
>   relocation on: process-scoped translation.
> 
> * Guest OS real mode access: only partition-scoped translation.
> 
> * Guest OS real or guest application access (quadrant 0 and 3) with
>   relocation on: both process-scoped translation and partition-scoped
>   translations.
> 
> * Hypervisor access in quadrant 1 and 2 with relocation on: both
>   process-scoped translation and partition-scoped translations.
> 
> The radix tree partition-scoped translation is performed using tables
> pointed to by the first double-word of the Partition Table Entries and
> process-scoped translation uses tables pointed to by the Process Table
> Entries (second double-word of the Partition Table Entries).
> 
> Both partition-scoped and process-scoped translations process are
> identical and thus the radix tree traversing code is largely reused.
> However, errors in partition-scoped translations generate hypervisor
> exceptions.
> 
> Signed-off-by: Suraj Jitindar Singh 
> Signed-off-by: Greg Kurz 
> Signed-off-by: Cédric Le Goater 
> ---
>  target/ppc/cpu.h |   3 +
>  target/ppc/excp_helper.c |   3 +-
>  target/ppc/mmu-radix64.c | 188 +++
>  3 files changed, 175 insertions(+), 19 deletions(-)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index f4a5304d4356..6b6dd7e483f1 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -463,6 +463,9 @@ typedef struct ppc_v3_pate_t {
>  #define DSISR_AMR0x0020
>  /* Unsupported Radix Tree Configuration */
>  #define DSISR_R_BADCONFIG0x0008
> +#define DSISR_ATOMIC_RC  0x0004
> +/* Unable to translate address of (guest) pde or process/page table entry */
> +#define DSISR_PRTABLE_FAULT  0x0002
>  
>  /* SRR1 error code fields */
>  
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 1acc3786de0e..f05297966472 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -506,9 +506,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
> excp_model, int excp)
>  case POWERPC_EXCP_ISEG:  /* Instruction segment exception
> */
>  case POWERPC_EXCP_TRACE: /* Trace exception  
> */
>  break;
> +case POWERPC_EXCP_HISI:  /* Hypervisor instruction storage exception 
> */
> +msr |= env->error_code;
>  case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception 
> */
>  case POWERPC_EXCP_HDSI:  /* Hypervisor data storage exception
> */
> -case POWERPC_EXCP_HISI:  /* Hypervisor instruction storage exception 
> */
>  case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception
> */
>  case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception 
> */
>  case POWERPC_EXCP_SDOOR_HV:  /* Hypervisor Doorbell interrupt
> */
> diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
> index 2400da41e06c..d473dc742e11 100644
> --- a/target/ppc/mmu-radix64.c
> +++ b/target/ppc/mmu-radix64.c
> @@ -103,6 +103,27 @@ static void ppc_radix64_raise_si(PowerPCCPU *cpu, int 
> rwx, vaddr eaddr,
>  }
>  }
>  
> +static void ppc_radix64_raise_hsi(PowerPCCPU *cpu, int rwx, vaddr eaddr,
> +  hwaddr g_raddr, uint32_t cause)
> +{
> +CPUState *cs = CPU(cpu);
> +CPUPPCState *env = >env;
> +
> +if (rwx == 2) { /* H Instruction Storage Interrupt */
> +cs->exception_index = POWERPC_EXCP_HISI;
> +env->spr[SPR_ASDR] = g_raddr;
> +env->error_code = cause;
> +} else { /* H Data Storage Interrupt */
> +cs->exception_index = POWERPC_EXCP_HDSI;
> +if (rwx == 1) { /* Write -> Store */
> +cause |= DSISR_ISSTORE;
> +}
> +env->spr[SPR_HDSISR] = cause;
> +env->spr[SPR_HDAR] = eaddr;
> +env->spr[SPR_ASDR] = g_raddr;
> +env->error_code = 0;
> +}
> +}
>  
>  static bool ppc_radix64_check_prot(PowerPCCPU *cpu, int rwx, uint64_t pte,
> int *fault_cause, int *prot,
> @@ -243,6 +264,37 @@ static bool validate_pate(PowerPCCPU *cpu,