Re: [RFC PATCH] powerpc/pseries/svm: capture instruction faulting on MMIO access, in sprg0 register
From: Nicholas Piggin <npiggin@gmail.com>
Date: 2020-07-21 15:08:52
Excerpts from Ram Pai's message of July 16, 2020 6:32 pm:
An instruction accessing a mmio address, generates a HDSI fault. This fault is appropriately handled by the Hypervisor. However in the case of secureVMs, the fault is delivered to the ultravisor.
Why not a ucall if you're paraultravizing it anyway?
quoted hunk ↗ jump to hunk
Unfortunately the Ultravisor has no correct-way to fetch the faulting instruction. The PEF architecture does not allow Ultravisor to enable MMU translation. Walking the two level page table to read the instruction can race with other vcpus modifying the SVM's process scoped page table. This problem can be correctly solved with some help from the kernel. Capture the faulting instruction in SPRG0 register, before executing the faulting instruction. This enables the ultravisor to easily procure the faulting instruction and emulate it. Signed-off-by: Ram Pai <redacted> --- arch/powerpc/include/asm/io.h | 85 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 10 deletions(-)diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index 635969b..7ef663d 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h@@ -35,6 +35,7 @@ #include <asm/mmu.h> #include <asm/ppc_asm.h> #include <asm/pgtable.h> +#include <asm/svm.h> #define SIO_CONFIG_RA 0x398 #define SIO_CONFIG_RD 0x399@@ -105,34 +106,98 @@ static inline u##size name(const volatile u##size __iomem *addr) \ { \ u##size ret; \ - __asm__ __volatile__("sync;"#insn" %0,%y1;twi 0,%0,0;isync" \ - : "=r" (ret) : "Z" (*addr) : "memory"); \ + if (is_secure_guest()) { \ + __asm__ __volatile__("mfsprg0 %3;" \ + "lnia %2;" \ + "ld %2,12(%2);" \ + "mtsprg0 %2;" \ + "sync;" \ + #insn" %0,%y1;" \ + "twi 0,%0,0;" \ + "isync;" \ + "mtsprg0 %3" \
We prefer to use mtspr in new code, and the nia offset should be calculated with a label I think "(1f - .)(%2)" should work. SPRG usage is documented in arch/powerpc/include/asm/reg.h if this goes past RFC stage. Looks like SPRG0 probably could be used for this. Thanks, Nick