ping....

在 2022年6月13日星期一,Dongjiu Geng <[email protected]> 写道:

> Jan Kiszka <[email protected]> 于2022年6月10日周五 13:20写道:
> >
> > On 09.06.22 17:27, Dongjiu Geng wrote:
> > > ping,sorry for the noise
> > >
> >
> > No need to be sorry, I unfortunately didn't find the time to fully
> > understand this.
>
> Thanks for your time.
>
> >
> > >
> > > Dongjiu Geng <[email protected]> 于2022年6月3日周五 21:11写道:
> > >>
> > >> The HPFAR can be invalid if the stage 2 fault did not happen during a
> > >> stage 1 page table walk (the ESR_EL2.S1PTW bit is clear) and one of
> the
> > >> two following cases are true:
> > >>   1). The fault was due to a permission fault
> > >>   2). The processor carries errata 834220
> > >>
> > >> Therefore, for all non S1PTW faults where we either have a permission
> > >> fault or the errata workaround is enabled, we resolve the IPA using
> the
> > >> AT instruction.
> > >>
> > >> Signed-off-by: Dongjiu Geng <[email protected]>
> > >> ---
> > >>  hypervisor/arch/arm64/include/asm/paging.h  |  8 ++
> > >>  hypervisor/arch/arm64/include/asm/sysregs.h |  8 ++
> > >>  hypervisor/arch/arm64/include/asm/traps.h   |  2 +
> > >>  hypervisor/arch/arm64/mmio.c                |  7 +-
> > >>  hypervisor/arch/arm64/traps.c               | 89
> +++++++++++++++++++--
> > >>  5 files changed, 105 insertions(+), 9 deletions(-)
> > >>
> > >> diff --git a/hypervisor/arch/arm64/include/asm/paging.h
> b/hypervisor/arch/arm64/include/asm/paging.h
> > >> index e600cf58..4f0cb81c 100644
> > >> --- a/hypervisor/arch/arm64/include/asm/paging.h
> > >> +++ b/hypervisor/arch/arm64/include/asm/paging.h
> > >> @@ -198,6 +198,14 @@ unsigned int get_cpu_parange(void);
> > >>                                 | (cpu_parange_encoded <<
> TCR_PS_SHIFT) \
> > >>                                 | VTCR_RES1)
> > >>
> > >> +/* Flags for get fault ipa from gva */
> > >> +#define GV2M_READ              (0u<<0)
> > >> +#define GV2M_WRITE             (1u<<0)
> > >> +
> > >> +/* Indicates address translation aborted */
> > >> +#define PAR_F                  (1UL)
> > >> +#define PADDR_MASK             ((1UL << 48) - 1UL)
> > >> +
> > >>  int arm_paging_cell_init(struct cell *cell);
> > >>  void arm_paging_cell_destroy(struct cell *cell);
> > >>
> > >> diff --git a/hypervisor/arch/arm64/include/asm/sysregs.h
> b/hypervisor/arch/arm64/include/asm/sysregs.h
> > >> index 868ef887..2c683832 100644
> > >> --- a/hypervisor/arch/arm64/include/asm/sysregs.h
> > >> +++ b/hypervisor/arch/arm64/include/asm/sysregs.h
> > >> @@ -117,6 +117,14 @@
> > >>  #define ESR_IL(esr)            GET_FIELD((esr), 25, 25)
> > >>  /* Instruction specific syndrome */
> > >>  #define ESR_ISS(esr)           GET_FIELD((esr), 24, 0)
> > >> +
> > >> +/* Fault status code of instruction specific syndrome */
> > >> +#define ESR_ISS_FSC(esr)       GET_FIELD((esr), 5, 0)
> > >> +
> > >> +/* Shared ISS fault status code(IFSC/DFSC) for Data/Instruction
> aborts */
> > >> +#define ESR_ISS_FSC_TYPE       (0x3C)
> > >> +#define ESR_ISS_FSC_PERM       (0x0C)
> > >> +
> > >>  /* Exception classes values */
> > >>  #define ESR_EC_UNKNOWN         0x00
> > >>  #define ESR_EC_WFx             0x01
> > >> diff --git a/hypervisor/arch/arm64/include/asm/traps.h
> b/hypervisor/arch/arm64/include/asm/traps.h
> > >> index a7c07624..0efedef1 100644
> > >> --- a/hypervisor/arch/arm64/include/asm/traps.h
> > >> +++ b/hypervisor/arch/arm64/include/asm/traps.h
> > >> @@ -25,6 +25,8 @@ struct trap_context {
> > >>
> > >>  void arch_handle_trap(union registers *guest_regs);
> > >>  void arch_el2_abt(union registers *regs);
> > >> +bool arch_get_fault_ipa(struct trap_context *ctx, unsigned long *ipa,
> > >> +                                unsigned int flag);
> > >>
> > >>  /* now include from arm-common */
> > >>  #include_next <asm/traps.h>
> > >> diff --git a/hypervisor/arch/arm64/mmio.c
> b/hypervisor/arch/arm64/mmio.c
> > >> index 7fbfef75..70301ab3 100644
> > >> --- a/hypervisor/arch/arm64/mmio.c
> > >> +++ b/hypervisor/arch/arm64/mmio.c
> > >> @@ -43,7 +43,6 @@ enum trap_return arch_handle_dabt(struct
> trap_context *ctx)
> > >>  {
> > >>         enum mmio_result mmio_result;
> > >>         struct mmio_access mmio;
> > >> -       unsigned long hpfar;
> > >>         unsigned long hdfar;
> > >>         /* Decode the syndrome fields */
> > >>         u32 iss         = ESR_ISS(ctx->esr);
> > >> @@ -57,10 +56,10 @@ enum trap_return arch_handle_dabt(struct
> trap_context *ctx)
> > >>         u32 is_write    = iss >> 6 & 0x1;
> > >>         u32 size        = 1 << sas;
> > >>
> > >> -       arm_read_sysreg(HPFAR_EL2, hpfar);
> > >>         arm_read_sysreg(FAR_EL2, hdfar);
> > >> -       mmio.address = hpfar << 8;
> > >> -       mmio.address |= hdfar & 0xfff;
> > >> +
> > >> +       if (!arch_get_fault_ipa(ctx, &mmio.address, GV2M_READ))
> > >> +               return TRAP_HANDLED; /* Try again */
> >
> > So, this means we need to make the guest trap again, and then HPFAR is
> > valid??
>
> Maybe this invalidation is due to someone playing with the Stage-2
> page table of the domain,  and can not get the right IPA, so we try
> again.
>
>
> >
> > >>
> > >>         this_cpu_public()->stats[JAILHOUSE_CPU_STAT_VMEXITS_MMIO]++;
> > >>
> > >> diff --git a/hypervisor/arch/arm64/traps.c
> b/hypervisor/arch/arm64/traps.c
> > >> index 488dd7f8..10441b4b 100644
> > >> --- a/hypervisor/arch/arm64/traps.c
> > >> +++ b/hypervisor/arch/arm64/traps.c
> > >> @@ -33,6 +33,85 @@ void arch_skip_instruction(struct trap_context
> *ctx)
> > >>         arm_write_sysreg(ELR_EL2, pc);
> > >>  }
> > >>
> > >> +static bool check_workaround_834220(void)
> > >> +{
> > >> +        unsigned long midr;
> > >> +       unsigned int variant, revision, part;
> > >> +
> > >> +       arm_read_sysreg(MIDR_EL1, midr);
> > >> +
> > >> +       variant = (midr >> 20) & 0xf;
> > >> +       revision = midr & 0xf;
> > >> +       part = (midr >> 4) & 0xfff;
> > >> +
> > >> +       /* Cortex-A57 r0p0 - r1p2 */
> > >> +       if (part == 0xD07 && variant <= 1 && revision <= 2)
> > >> +               return true;
> > >> +
> > >> +       return false;
> > >> +}
> > >> +
> > >> +static bool hpfar_is_not_valid(bool s1ptw, u8 fsc)
> > >> +{
> > >> +       /*
> > >> +        * The HPFAR can be invalid if the stage 2 fault did not
> > >> +        * happen during a stage 1 page table walk (the ESR_EL2.S1PTW
> > >> +        * bit is clear) and one of the two following cases are true:
> > >> +        *   1. The fault was due to a permission fault
> > >> +        *   2. The processor carries errata 834220
> > >> +        *
> > >> +        */
> > >> +       return (s1ptw == 0U) && (((fsc & ESR_ISS_FSC_TYPE) ==
> ESR_ISS_FSC_PERM) || check_workaround_834220());
> > >> +}
> > >> +
> > >> +bool arch_get_fault_ipa(struct trap_context *ctx, unsigned long
> *ipa, unsigned int flags)
> > >> +{
> > >> +       unsigned long hpfar, hdfar, par, tmp;
> > >> +
> > >> +       u32 s1ptw = ESR_ISS(ctx->esr) >> 7 & 0x1;
> > >> +       u8 fsc = ESR_ISS_FSC(ctx->esr);
> > >> +
> > >> +       arm_read_sysreg(FAR_EL2, hdfar);
> > >> +
> > >> +       if (hpfar_is_not_valid(s1ptw, fsc)) {
> > >> +
> > >> +               /* Save current PAR_EL1 */
> > >> +               arm_read_sysreg(PAR_EL1, tmp);
> > >> +
> > >> +               /*
> > >> +                *  Performs stage 1 address translation, with
> permissions as if
> > >> +                *  writing to or reading from the given virtual
> address from EL1
> > >> +                */
> > >> +                if ( (flags & GV2M_WRITE) == GV2M_WRITE ) {
> > >> +                        asm volatile ("at s1e1w, %0;" : : "r"
> (hdfar));
> > >> +                } else {
> > >> +                        asm volatile ("at s1e1r, %0;" : : "r"
> (hdfar));
> > >> +                }
> > >> +
> > >> +               isb();
> > >> +
> > >> +               /* The resulting address can be read from the PAR_EL1
> */
> > >> +               arm_read_sysreg(PAR_EL1, par);
> > >> +
> > >> +               /* Recover current PAR_EL1 */
> > >> +               arm_write_sysreg(PAR_EL1, tmp);
> > >> +
> > >> +               /* If PAR_EL1.F = 1, address translation aborted */
> > >> +               if ((par & PAR_F) == PAR_F) {
> > >> +                       printk("Failed to ipa!\n");
> > >> +                       return false;
> > >> +               } else {
> > >> +                       *ipa = (par & PADDR_MASK & PAGE_MASK) |
> (hdfar & (~PAGE_MASK));
> > >> +               }
> > >> +       } else {
> > >> +               arm_read_sysreg(HPFAR_EL2, hpfar);
> > >> +               *ipa = hpfar << 8;
> > >> +               *ipa |= hdfar & 0xfff;
> > >> +       }
> > >> +
> > >> +       return true;
> > >> +}
> > >> +
> > >>  static enum trap_return handle_hvc(struct trap_context *ctx)
> > >>  {
> > >>         unsigned long *regs = ctx->regs;
> > >> @@ -71,7 +150,7 @@ static enum trap_return handle_sysreg(struct
> trap_context *ctx)
> > >>
> > >>  static enum trap_return handle_iabt(struct trap_context *ctx)
> > >>  {
> > >> -       unsigned long hpfar, hdfar;
> > >> +       unsigned long hpfar;
> > >>
> > >>         if (this_cpu_data()->sdei_event) {
> > >>                 this_cpu_data()->sdei_event = false;
> > >> @@ -83,11 +162,11 @@ static enum trap_return handle_iabt(struct
> trap_context *ctx)
> > >>                 return TRAP_HANDLED;
> > >>         }
> > >>
> > >> -       arm_read_sysreg(HPFAR_EL2, hpfar);
> > >> -       arm_read_sysreg(FAR_EL2, hdfar);
> > >> +       if (arch_get_fault_ipa(ctx, &hpfar, GV2M_READ))
> > >> +               panic_printk("FATAL: instruction abort at 0x%lx\n",
> hpfar);
> > >> +       else
> > >> +               panic_printk("FATAL: instruction abort and can not
> get ipa\n");
> > >>
> > >> -       panic_printk("FATAL: instruction abort at 0x%lx\n",
> > >> -                    (hpfar << 8) | (hdfar & 0xfff));
> > >>         return TRAP_FORBIDDEN;
> > >>  }
> > >>
> > >> --
> > >> 2.25.1
> > >>
> >
> > How common is this erratum? Is it already affecting real boards? Just to
> > get a feeling for the urgency.
>
> Yes,  it can affect the real boards.
> For example,  if we configure a buffer's  stage2 page table to readonly
> for VM,
> this VM's process writes this buffer, then it will trigger stage2
> permission fault.
> In this case, we can not get the right IPA without this patch.
>
>
> >
> > Thanks,
> > Jan
> >
> > --
> > Siemens AG, Technology
> > Competence Center Embedded Linux
>

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/CABSBigQTreqdPXV6y3hH%2BAerOK5hr3Y6C2bq1T9CdVeC27z6uQ%40mail.gmail.com.

Reply via email to