arm: consolidate stage 1 translation function use

This commit introduces `addressTranslateS1` to be used on Arm platforms
with hypervisor enabled for stage 1 (vaddr to IPA) translation. On
AArch32 this is a rename from `addressTranslateS1CPR`, and on AArch64 it
wraps `ats1e1r`. This changes the ABI on AArch64 to report faulting
address as IPA.

Reasoning:

With hypervisor enabled, AArch64 defined `addressTranslateS1CPR` to do
nothing, while AArch32 defined it to do stage 1 translation. This
delivered VM faults to the user with the faulting address being either
an IPA or a vaddr depending on mode. This inconsistency is undesireable.

This commit proposes adjusting the inconsistency to match AArch32
behaviour, as it is one of the verified platforms.

Signed-off-by: Rafal Kolanski <rafal.kolanski@proofcraft.systems>
This commit is contained in:
Rafal Kolanski 2022-02-03 14:05:54 +11:00 committed by Rafal Kolanski
parent 3179add042
commit fce5cece4d
6 changed files with 16 additions and 13 deletions

View file

@ -118,7 +118,7 @@ static inline void invalidateHypTLB(void)
isb();
}
static inline paddr_t PURE addressTranslateS1CPR(vptr_t vaddr)
static inline paddr_t PURE addressTranslateS1(vptr_t vaddr)
{
uint32_t ipa0, ipa1;
asm volatile("mcr p15, 0, %0, c7, c8, 0" :: "r"(vaddr));
@ -192,7 +192,7 @@ static inline word_t readHTPIDR(void)
{
return 0;
}
static inline paddr_t addressTranslateS1CPR(vptr_t vaddr)
static inline paddr_t addressTranslateS1(vptr_t vaddr)
{
return vaddr;
}

View file

@ -375,4 +375,12 @@ static inline word_t ats2e0r(word_t va)
void arch_clean_invalidate_caches(void);
void arch_clean_invalidate_L1_caches(word_t type);
static inline paddr_t addressTranslateS1(vptr_t vaddr)
{
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
return ats1e1r(vaddr);
#else
/* shouldn't be called on non-hyp, added for consistency with AArch32 */
return vaddr;
#endif
}

View file

@ -35,8 +35,3 @@ static inline void setCurrentPDPL2(paddr_t pa) {}
static inline void invalidateHypTLB(void) {}
static inline void writeContextIDPL2(word_t pd_val) {}
static inline void writeContextIDAndPD(word_t id, word_t pd_val) {}
static inline paddr_t addressTranslateS1CPR(vptr_t vaddr)
{
return vaddr;
}

View file

@ -1213,7 +1213,7 @@ exception_t handleVMFault(tcb_t *thread, vm_fault_type_t vm_faultType)
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
addr = getHDFAR();
addr = (addressTranslateS1CPR(addr) & ~MASK(PAGE_BITS)) | (addr & MASK(PAGE_BITS));
addr = (addressTranslateS1(addr) & ~MASK(PAGE_BITS)) | (addr & MASK(PAGE_BITS));
/* MSBs tell us that this was a DataAbort */
fault = getHSR() & 0x3ffffff;
#else
@ -1244,7 +1244,7 @@ exception_t handleVMFault(tcb_t *thread, vm_fault_type_t vm_faultType)
pc = getRestartPC(thread);
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
pc = (addressTranslateS1CPR(pc) & ~MASK(PAGE_BITS)) | (pc & MASK(PAGE_BITS));
pc = (addressTranslateS1(pc) & ~MASK(PAGE_BITS)) | (pc & MASK(PAGE_BITS));
/* MSBs tell us that this was a PrefetchAbort */
fault = getHSR() & 0x3ffffff;
#else

View file

@ -955,7 +955,7 @@ exception_t handleVMFault(tcb_t *thread, vm_fault_type_t vm_faultType)
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
/* use the IPA */
if (ARCH_NODE_STATE(armHSVCPUActive)) {
addr = GET_PAR_ADDR(ats1e1r(addr)) | (addr & MASK(PAGE_BITS));
addr = GET_PAR_ADDR(addressTranslateS1(addr)) | (addr & MASK(PAGE_BITS));
}
#endif
current_fault = seL4_Fault_VMFault_new(addr, fault, false);
@ -970,7 +970,7 @@ exception_t handleVMFault(tcb_t *thread, vm_fault_type_t vm_faultType)
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
if (ARCH_NODE_STATE(armHSVCPUActive)) {
pc = GET_PAR_ADDR(ats1e1r(pc)) | (pc & MASK(PAGE_BITS));
pc = GET_PAR_ADDR(addressTranslateS1(pc)) | (pc & MASK(PAGE_BITS));
}
#endif
current_fault = seL4_Fault_VMFault_new(pc, fault, true);

View file

@ -37,7 +37,7 @@ word_t Arch_setMRs_fault(tcb_t *sender, tcb_t *receiver, word_t *receiveIPCBuffe
if (config_set(CONFIG_ARM_HYPERVISOR_SUPPORT)) {
word_t ipa, va;
va = getRestartPC(sender);
ipa = (addressTranslateS1CPR(va) & ~MASK(PAGE_BITS)) | (va & MASK(PAGE_BITS));
ipa = (addressTranslateS1(va) & ~MASK(PAGE_BITS)) | (va & MASK(PAGE_BITS));
setMR(receiver, receiveIPCBuffer, seL4_VMFault_IP, ipa);
} else {
setMR(receiver, receiveIPCBuffer, seL4_VMFault_IP, getRestartPC(sender));