* [PATCH v2 07/37] KVM: PPC: Book3S 64: Move GUEST_MODE_SKIP test into KVM
From: Nicholas Piggin @ 2021-02-25 13:46 UTC (permalink / raw)
To: kvm-ppc; +Cc: linuxppc-dev, Nicholas Piggin, Fabiano Rosas
In-Reply-To: <20210225134652.2127648-1-npiggin@gmail.com>
Move the GUEST_MODE_SKIP logic into KVM code. This is quite a KVM
internal detail that has no real need to be in common handlers.
Also add a comment explaining why this thing exists.
Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 60 ----------------------------
arch/powerpc/kvm/book3s_64_entry.S | 51 ++++++++++++++++++++++-
2 files changed, 50 insertions(+), 61 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index ba13d749d203..d956dd9ed61f 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -133,7 +133,6 @@ name:
#define IBRANCH_TO_COMMON .L_IBRANCH_TO_COMMON_\name\() /* ENTRY branch to common */
#define IREALMODE_COMMON .L_IREALMODE_COMMON_\name\() /* Common runs in realmode */
#define IMASK .L_IMASK_\name\() /* IRQ soft-mask bit */
-#define IKVM_SKIP .L_IKVM_SKIP_\name\() /* Generate KVM skip handler */
#define IKVM_REAL .L_IKVM_REAL_\name\() /* Real entry tests KVM */
#define __IKVM_REAL(name) .L_IKVM_REAL_ ## name
#define IKVM_VIRT .L_IKVM_VIRT_\name\() /* Virt entry tests KVM */
@@ -190,9 +189,6 @@ do_define_int n
.ifndef IMASK
IMASK=0
.endif
- .ifndef IKVM_SKIP
- IKVM_SKIP=0
- .endif
.ifndef IKVM_REAL
IKVM_REAL=0
.endif
@@ -250,15 +246,10 @@ do_define_int n
.balign IFETCH_ALIGN_BYTES
\name\()_kvm:
- .if IKVM_SKIP
- cmpwi r10,KVM_GUEST_MODE_SKIP
- beq 89f
- .else
BEGIN_FTR_SECTION
ld r10,IAREA+EX_CFAR(r13)
std r10,HSTATE_CFAR(r13)
END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
- .endif
ld r10,IAREA+EX_CTR(r13)
mtctr r10
@@ -285,27 +276,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
ori r12,r12,(IVEC)
.endif
b kvmppc_interrupt
-
- .if IKVM_SKIP
-89: mtocrf 0x80,r9
- ld r10,IAREA+EX_CTR(r13)
- mtctr r10
- ld r9,IAREA+EX_R9(r13)
- ld r10,IAREA+EX_R10(r13)
- ld r11,IAREA+EX_R11(r13)
- ld r12,IAREA+EX_R12(r13)
- .if IHSRR_IF_HVMODE
- BEGIN_FTR_SECTION
- b kvmppc_skip_Hinterrupt
- FTR_SECTION_ELSE
- b kvmppc_skip_interrupt
- ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
- .elseif IHSRR
- b kvmppc_skip_Hinterrupt
- .else
- b kvmppc_skip_interrupt
- .endif
- .endif
.endm
#else
@@ -1083,7 +1053,6 @@ INT_DEFINE_BEGIN(machine_check)
ISET_RI=0
IDAR=1
IDSISR=1
- IKVM_SKIP=1
IKVM_REAL=1
INT_DEFINE_END(machine_check)
@@ -1356,7 +1325,6 @@ INT_DEFINE_BEGIN(data_access)
IVEC=0x300
IDAR=1
IDSISR=1
- IKVM_SKIP=1
IKVM_REAL=1
INT_DEFINE_END(data_access)
@@ -1410,7 +1378,6 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
INT_DEFINE_BEGIN(data_access_slb)
IVEC=0x380
IDAR=1
- IKVM_SKIP=1
IKVM_REAL=1
INT_DEFINE_END(data_access_slb)
@@ -2080,7 +2047,6 @@ INT_DEFINE_BEGIN(h_data_storage)
IHSRR=1
IDAR=1
IDSISR=1
- IKVM_SKIP=1
IKVM_REAL=1
IKVM_VIRT=1
INT_DEFINE_END(h_data_storage)
@@ -3024,32 +2990,6 @@ EXPORT_SYMBOL(do_uaccess_flush)
MASKED_INTERRUPT
MASKED_INTERRUPT hsrr=1
-#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
-kvmppc_skip_interrupt:
- /*
- * Here all GPRs are unchanged from when the interrupt happened
- * except for r13, which is saved in SPRG_SCRATCH0.
- */
- mfspr r13, SPRN_SRR0
- addi r13, r13, 4
- mtspr SPRN_SRR0, r13
- GET_SCRATCH0(r13)
- RFI_TO_KERNEL
- b .
-
-kvmppc_skip_Hinterrupt:
- /*
- * Here all GPRs are unchanged from when the interrupt happened
- * except for r13, which is saved in SPRG_SCRATCH0.
- */
- mfspr r13, SPRN_HSRR0
- addi r13, r13, 4
- mtspr SPRN_HSRR0, r13
- GET_SCRATCH0(r13)
- HRFI_TO_KERNEL
- b .
-#endif
-
/*
* Relocation-on interrupts: A subset of the interrupts can be delivered
* with IR=1/DR=1, if AIL==2 and MSR.HV won't be changed by delivering
diff --git a/arch/powerpc/kvm/book3s_64_entry.S b/arch/powerpc/kvm/book3s_64_entry.S
index e9a6a8fbb164..c1276f616af4 100644
--- a/arch/powerpc/kvm/book3s_64_entry.S
+++ b/arch/powerpc/kvm/book3s_64_entry.S
@@ -1,5 +1,6 @@
#include <asm/asm-offsets.h>
#include <asm/cache.h>
+#include <asm/exception-64s.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_book3s_asm.h>
#include <asm/ppc_asm.h>
@@ -19,9 +20,12 @@ kvmppc_interrupt:
* guest R12 saved in shadow VCPU SCRATCH0
* guest R13 saved in SPRN_SCRATCH0
*/
-#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
std r9,HSTATE_SCRATCH2(r13)
lbz r9,HSTATE_IN_GUEST(r13)
+ cmpwi r9,KVM_GUEST_MODE_SKIP
+ beq- .Lmaybe_skip
+.Lno_skip:
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
cmpwi r9,KVM_GUEST_MODE_HOST_HV
beq kvmppc_bad_host_intr
#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
@@ -33,3 +37,48 @@ kvmppc_interrupt:
#else
b kvmppc_interrupt_pr
#endif
+
+/*
+ * KVM uses a trick where it is running in MSR[HV]=1 mode in real-mode with the
+ * guest MMU context loaded, and it sets KVM_GUEST_MODE_SKIP and enables
+ * MSR[DR]=1 while leaving MSR[IR]=0, so it continues to fetch HV instructions
+ * but loads and stores will access the guest context. This is used to load
+ * the faulting instruction without walking page tables.
+ *
+ * However the guest context may not be able to translate, or it may cause a
+ * machine check or other issue, which will result in a fault in the host
+ * (even with KVM-HV).
+ *
+ * These faults are caught here and if the fault was (or was likely) due to
+ * that load, then we just return with the PC advanced +4 and skip the load,
+ * which then goes via the slow path.
+ */
+.Lmaybe_skip:
+ cmpwi r12,BOOK3S_INTERRUPT_MACHINE_CHECK
+ beq 1f
+ cmpwi r12,BOOK3S_INTERRUPT_DATA_STORAGE
+ beq 1f
+ cmpwi r12,BOOK3S_INTERRUPT_DATA_SEGMENT
+ beq 1f
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+ /* HSRR interrupts have 2 added to trap vector */
+ cmpwi r12,BOOK3S_INTERRUPT_H_DATA_STORAGE | 0x2
+ beq 2f
+#endif
+ b .Lno_skip
+1: mfspr r9,SPRN_SRR0
+ addi r9,r9,4
+ mtspr SPRN_SRR0,r9
+ ld r12,HSTATE_SCRATCH0(r13)
+ ld r9,HSTATE_SCRATCH2(r13)
+ GET_SCRATCH0(r13)
+ RFI_TO_KERNEL
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+2: mfspr r9,SPRN_HSRR0
+ addi r9,r9,4
+ mtspr SPRN_HSRR0,r9
+ ld r12,HSTATE_SCRATCH0(r13)
+ ld r9,HSTATE_SCRATCH2(r13)
+ GET_SCRATCH0(r13)
+ HRFI_TO_KERNEL
+#endif
--
2.23.0
^ permalink raw reply related
* [PATCH v2 06/37] KVM: PPC: Book3S 64: move KVM interrupt entry to a common entry point
From: Nicholas Piggin @ 2021-02-25 13:46 UTC (permalink / raw)
To: kvm-ppc; +Cc: linuxppc-dev, Nicholas Piggin, Fabiano Rosas
In-Reply-To: <20210225134652.2127648-1-npiggin@gmail.com>
Rather than bifurcate the call depending on whether or not HV is
possible, and have the HV entry test for PR, just make a single
common point which does the demultiplexing. This makes it simpler
to add another type of exit handler.
Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 8 +-----
arch/powerpc/kvm/Makefile | 3 +++
arch/powerpc/kvm/book3s_64_entry.S | 35 +++++++++++++++++++++++++
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 11 ++------
4 files changed, 41 insertions(+), 16 deletions(-)
create mode 100644 arch/powerpc/kvm/book3s_64_entry.S
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 0097e0676ed7..ba13d749d203 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -208,7 +208,6 @@ do_define_int n
.endm
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
-#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
/*
* All interrupts which set HSRR registers, as well as SRESET and MCE and
* syscall when invoked with "sc 1" switch to MSR[HV]=1 (HVMODE) to be taken,
@@ -238,13 +237,8 @@ do_define_int n
/*
* If an interrupt is taken while a guest is running, it is immediately routed
- * to KVM to handle. If both HV and PR KVM arepossible, KVM interrupts go first
- * to kvmppc_interrupt_hv, which handles the PR guest case.
+ * to KVM to handle.
*/
-#define kvmppc_interrupt kvmppc_interrupt_hv
-#else
-#define kvmppc_interrupt kvmppc_interrupt_pr
-#endif
.macro KVMTEST name
lbz r10,HSTATE_IN_GUEST(r13)
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 2bfeaa13befb..cdd119028f64 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -59,6 +59,9 @@ kvm-pr-y := \
kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) += \
tm.o
+kvm-book3s_64-builtin-objs-y += \
+ book3s_64_entry.o
+
ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) += \
book3s_rmhandlers.o
diff --git a/arch/powerpc/kvm/book3s_64_entry.S b/arch/powerpc/kvm/book3s_64_entry.S
new file mode 100644
index 000000000000..e9a6a8fbb164
--- /dev/null
+++ b/arch/powerpc/kvm/book3s_64_entry.S
@@ -0,0 +1,35 @@
+#include <asm/asm-offsets.h>
+#include <asm/cache.h>
+#include <asm/kvm_asm.h>
+#include <asm/kvm_book3s_asm.h>
+#include <asm/ppc_asm.h>
+#include <asm/reg.h>
+
+/*
+ * This is branched to from interrupt handlers in exception-64s.S which set
+ * IKVM_REAL or IKVM_VIRT, if HSTATE_IN_GUEST was found to be non-zero.
+ */
+.global kvmppc_interrupt
+.balign IFETCH_ALIGN_BYTES
+kvmppc_interrupt:
+ /*
+ * Register contents:
+ * R12 = (guest CR << 32) | interrupt vector
+ * R13 = PACA
+ * guest R12 saved in shadow VCPU SCRATCH0
+ * guest R13 saved in SPRN_SCRATCH0
+ */
+#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+ std r9,HSTATE_SCRATCH2(r13)
+ lbz r9,HSTATE_IN_GUEST(r13)
+ cmpwi r9,KVM_GUEST_MODE_HOST_HV
+ beq kvmppc_bad_host_intr
+#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
+ cmpwi r9,KVM_GUEST_MODE_GUEST
+ ld r9,HSTATE_SCRATCH2(r13)
+ beq kvmppc_interrupt_pr
+#endif
+ b kvmppc_interrupt_hv
+#else
+ b kvmppc_interrupt_pr
+#endif
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 5e634db4809b..f976efb7e4a9 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1269,16 +1269,8 @@ kvmppc_interrupt_hv:
* R13 = PACA
* guest R12 saved in shadow VCPU SCRATCH0
* guest R13 saved in SPRN_SCRATCH0
+ * guest R9 saved in HSTATE_SCRATCH2
*/
- std r9, HSTATE_SCRATCH2(r13)
- lbz r9, HSTATE_IN_GUEST(r13)
- cmpwi r9, KVM_GUEST_MODE_HOST_HV
- beq kvmppc_bad_host_intr
-#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
- cmpwi r9, KVM_GUEST_MODE_GUEST
- ld r9, HSTATE_SCRATCH2(r13)
- beq kvmppc_interrupt_pr
-#endif
/* We're now back in the host but in guest MMU context */
li r9, KVM_GUEST_MODE_HOST_HV
stb r9, HSTATE_IN_GUEST(r13)
@@ -3280,6 +3272,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_P9_TM_HV_ASSIST)
* cfar is saved in HSTATE_CFAR(r13)
* ppr is saved in HSTATE_PPR(r13)
*/
+.global kvmppc_bad_host_intr
kvmppc_bad_host_intr:
/*
* Switch to the emergency stack, but start half-way down in
--
2.23.0
^ permalink raw reply related
* [PATCH v2 05/37] KVM: PPC: Book3S HV: Ensure MSR[ME] is always set in guest MSR
From: Nicholas Piggin @ 2021-02-25 13:46 UTC (permalink / raw)
To: kvm-ppc; +Cc: linuxppc-dev, Nicholas Piggin, Fabiano Rosas
In-Reply-To: <20210225134652.2127648-1-npiggin@gmail.com>
Rather than add the ME bit to the MSR when the guest is entered, make
it clear that the hypervisor does not allow the guest to clear the bit.
The ME addition is kept in the code for now, but a future patch will
warn if it's not present.
Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kvm/book3s_hv_builtin.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c
index 158d309b42a3..1ca484160636 100644
--- a/arch/powerpc/kvm/book3s_hv_builtin.c
+++ b/arch/powerpc/kvm/book3s_hv_builtin.c
@@ -662,6 +662,13 @@ static void kvmppc_end_cede(struct kvm_vcpu *vcpu)
void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr)
{
+ /*
+ * Guest must always run with machine check interrupt
+ * enabled.
+ */
+ if (!(msr & MSR_ME))
+ msr |= MSR_ME;
+
/*
* Check for illegal transactional state bit combination
* and if we find it, force the TS field to a safe state.
--
2.23.0
^ permalink raw reply related
* [PATCH v2 04/37] powerpc/64s: remove KVM SKIP test from instruction breakpoint handler
From: Nicholas Piggin @ 2021-02-25 13:46 UTC (permalink / raw)
To: kvm-ppc; +Cc: linuxppc-dev, Nicholas Piggin, Fabiano Rosas
In-Reply-To: <20210225134652.2127648-1-npiggin@gmail.com>
The code being executed in KVM_GUEST_MODE_SKIP is hypervisor code with
MSR[IR]=0, so the faults of concern are the d-side ones caused by access
to guest context by the hypervisor.
Instruction breakpoint interrupts are not a concern here. It's unlikely
any good would come of causing breaks in this code, but skipping the
instruction that caused it won't help matters (e.g., skip the mtmsr that
sets MSR[DR]=0 or clears KVM_GUEST_MODE_SKIP).
Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index a027600beeb1..0097e0676ed7 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -2553,7 +2553,6 @@ EXC_VIRT_NONE(0x5200, 0x100)
INT_DEFINE_BEGIN(instruction_breakpoint)
IVEC=0x1300
#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE
- IKVM_SKIP=1
IKVM_REAL=1
#endif
INT_DEFINE_END(instruction_breakpoint)
--
2.23.0
^ permalink raw reply related
* [PATCH v2 03/37] powerpc/64s: Remove KVM handler support from CBE_RAS interrupts
From: Nicholas Piggin @ 2021-02-25 13:46 UTC (permalink / raw)
To: kvm-ppc; +Cc: linuxppc-dev, Nicholas Piggin, Fabiano Rosas
In-Reply-To: <20210225134652.2127648-1-npiggin@gmail.com>
Cell does not support KVM.
Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 6 ------
1 file changed, 6 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 60d3051a8bc8..a027600beeb1 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -2530,8 +2530,6 @@ EXC_VIRT_NONE(0x5100, 0x100)
INT_DEFINE_BEGIN(cbe_system_error)
IVEC=0x1200
IHSRR=1
- IKVM_SKIP=1
- IKVM_REAL=1
INT_DEFINE_END(cbe_system_error)
EXC_REAL_BEGIN(cbe_system_error, 0x1200, 0x100)
@@ -2701,8 +2699,6 @@ EXC_COMMON_BEGIN(denorm_exception_common)
INT_DEFINE_BEGIN(cbe_maintenance)
IVEC=0x1600
IHSRR=1
- IKVM_SKIP=1
- IKVM_REAL=1
INT_DEFINE_END(cbe_maintenance)
EXC_REAL_BEGIN(cbe_maintenance, 0x1600, 0x100)
@@ -2754,8 +2750,6 @@ EXC_COMMON_BEGIN(altivec_assist_common)
INT_DEFINE_BEGIN(cbe_thermal)
IVEC=0x1800
IHSRR=1
- IKVM_SKIP=1
- IKVM_REAL=1
INT_DEFINE_END(cbe_thermal)
EXC_REAL_BEGIN(cbe_thermal, 0x1800, 0x100)
--
2.23.0
^ permalink raw reply related
* [PATCH v2 02/37] KVM: PPC: Book3S HV: Fix CONFIG_SPAPR_TCE_IOMMU=n default hcalls
From: Nicholas Piggin @ 2021-02-25 13:46 UTC (permalink / raw)
To: kvm-ppc; +Cc: linuxppc-dev, Nicholas Piggin
In-Reply-To: <20210225134652.2127648-1-npiggin@gmail.com>
This config option causes the warning in init_default_hcalls to fire
because the TCE handlers are in the default hcall list but not
implemented.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kvm/book3s_hv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 13bad6bf4c95..895090636295 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -5369,8 +5369,10 @@ static unsigned int default_hcall_list[] = {
H_READ,
H_PROTECT,
H_BULK_REMOVE,
+#ifdef CONFIG_SPAPR_TCE_IOMMU
H_GET_TCE,
H_PUT_TCE,
+#endif
H_SET_DABR,
H_SET_XDABR,
H_CEDE,
--
2.23.0
^ permalink raw reply related
* [PATCH v2 01/37] KVM: PPC: Book3S 64: remove unused kvmppc_h_protect argument
From: Nicholas Piggin @ 2021-02-25 13:46 UTC (permalink / raw)
To: kvm-ppc; +Cc: linuxppc-dev, Nicholas Piggin
In-Reply-To: <20210225134652.2127648-1-npiggin@gmail.com>
The va argument is not used in the function or set by its asm caller,
so remove it to be safe.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/include/asm/kvm_ppc.h | 3 +--
arch/powerpc/kvm/book3s_hv_rm_mmu.c | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 8aacd76bb702..9531b1c1b190 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -767,8 +767,7 @@ long kvmppc_h_remove(struct kvm_vcpu *vcpu, unsigned long flags,
unsigned long pte_index, unsigned long avpn);
long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu);
long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
- unsigned long pte_index, unsigned long avpn,
- unsigned long va);
+ unsigned long pte_index, unsigned long avpn);
long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags,
unsigned long pte_index);
long kvmppc_h_clear_ref(struct kvm_vcpu *vcpu, unsigned long flags,
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index 88da2764c1bb..7af7c70f1468 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -673,8 +673,7 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu)
}
long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
- unsigned long pte_index, unsigned long avpn,
- unsigned long va)
+ unsigned long pte_index, unsigned long avpn)
{
struct kvm *kvm = vcpu->kvm;
__be64 *hpte;
--
2.23.0
^ permalink raw reply related
* [PATCH v2 00/37] KVM: PPC: Book3S: C-ify the P9 entry/exit code
From: Nicholas Piggin @ 2021-02-25 13:46 UTC (permalink / raw)
To: kvm-ppc; +Cc: linuxppc-dev, Nicholas Piggin
Since last posting, fixed a bunch of bugs, tidied things up, and
ironed out a few issues with XIVE.
I also got HPT guest and also host working on the new P9 path, which
allows major simplifications to the old path and moving P9 off it
completely, so I think that is really worth posting (I thought it
would be much more difficult).
Thanks,
Nick
Nicholas Piggin (37):
KVM: PPC: Book3S 64: remove unused kvmppc_h_protect argument
KVM: PPC: Book3S HV: Fix CONFIG_SPAPR_TCE_IOMMU=n default hcalls
powerpc/64s: Remove KVM handler support from CBE_RAS interrupts
powerpc/64s: remove KVM SKIP test from instruction breakpoint handler
KVM: PPC: Book3S HV: Ensure MSR[ME] is always set in guest MSR
KVM: PPC: Book3S 64: move KVM interrupt entry to a common entry point
KVM: PPC: Book3S 64: Move GUEST_MODE_SKIP test into KVM
KVM: PPC: Book3S 64: add hcall interrupt handler
KVM: PPC: Book3S 64: Move hcall early register setup to KVM
KVM: PPC: Book3S 64: Move interrupt early register setup to KVM
KVM: PPC: Book3S 64: move bad_host_intr check to HV handler
KVM: PPC: Book3S 64: Minimise hcall handler calling convention
differences
KVM: PPC: Book3S HV P9: Move radix MMU switching instructions together
KVM: PPC: Book3S HV P9: implement kvmppc_xive_pull_vcpu in C
KVM: PPC: Book3S HV P9: Move xive vcpu context management into
kvmhv_p9_guest_entry
KVM: PPC: Book3S HV P9: Stop handling hcalls in real-mode in the P9
path
KVM: PPC: Book3S HV P9: Move setting HDEC after switching to guest
LPCR
KVM: PPC: Book3S HV P9: Use large decrementer for HDEC
KVM: PPC: Book3S HV P9: Use host timer accounting to avoid decrementer
read
KVM: PPC: Book3S HV P9: Reduce mftb per guest entry/exit
powerpc: add set_dec_or_work API for safely updating decrementer
KVM: PPC: Book3S HV P9: Reduce irq_work vs guest decrementer races
KVM: PPC: Book3S HV P9: Implement the rest of the P9 path in C
KVM: PPC: Book3S HV P9: inline kvmhv_load_hv_regs_and_go into
__kvmhv_vcpu_entry_p9
KVM: PPC: Book3S HV P9: Read machine check registers while MSR[RI] is
0
KVM: PPC: Book3S HV P9: Improve exit timing accounting coverage
KVM: PPC: Book3S HV P9: Move SPR loading after expiry time check
KVM: PPC: Book3S HV P9: Add helpers for OS SPR handling
KVM: PPC: Book3S HV P9: Switch to guest MMU context as late as
possible
KVM: PPC: Book3S HV: Implement radix prefetch workaround by disabling
MMU
KVM: PPC: Book3S HV: Remove support for dependent threads mode on P9
KVM: PPC: Book3S HV: Remove radix guest support from P7/8 path
KVM: PPC: Book3S HV: small pseries_do_hcall cleanup
KVM: PPC: Book3S HV: add virtual mode handlers for HPT hcalls and page
faults
KVM: PPC: Book3S HV P9: implement hash guest support
KVM: PPC: Book3S HV P9: implement hash host / hash guest support
KVM: PPC: Book3S HV: remove POWER9 support from P7/8 paths
arch/powerpc/include/asm/asm-prototypes.h | 3 +-
arch/powerpc/include/asm/exception-64s.h | 13 +
arch/powerpc/include/asm/kvm_asm.h | 3 +-
arch/powerpc/include/asm/kvm_book3s_64.h | 8 +
arch/powerpc/include/asm/kvm_host.h | 1 -
arch/powerpc/include/asm/kvm_ppc.h | 10 +-
arch/powerpc/include/asm/mmu_context.h | 6 -
arch/powerpc/include/asm/paca.h | 1 +
arch/powerpc/include/asm/time.h | 16 +
arch/powerpc/kernel/exceptions-64s.S | 257 ++-------
arch/powerpc/kernel/security.c | 5 +-
arch/powerpc/kernel/time.c | 20 +-
arch/powerpc/kvm/Makefile | 6 +
arch/powerpc/kvm/book3s_64_entry.S | 297 ++++++++++
arch/powerpc/kvm/book3s_hv.c | 590 ++++++++++----------
arch/powerpc/kvm/book3s_hv_builtin.c | 7 +
arch/powerpc/kvm/book3s_hv_interrupt.c | 493 +++++++++++++++++
arch/powerpc/kvm/book3s_hv_interrupts.S | 9 +-
arch/powerpc/kvm/book3s_hv_nested.c | 1 +
arch/powerpc/kvm/book3s_hv_ras.c | 5 +
arch/powerpc/kvm/book3s_hv_rm_mmu.c | 7 +-
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 625 +---------------------
arch/powerpc/kvm/book3s_segment.S | 7 +
arch/powerpc/kvm/book3s_xive.c | 93 ++++
arch/powerpc/mm/book3s64/radix_pgtable.c | 27 +-
arch/powerpc/mm/book3s64/radix_tlb.c | 46 --
arch/powerpc/mm/mmu_context.c | 4 +-
arch/powerpc/platforms/powernv/idle.c | 52 +-
28 files changed, 1342 insertions(+), 1270 deletions(-)
create mode 100644 arch/powerpc/kvm/book3s_64_entry.S
create mode 100644 arch/powerpc/kvm/book3s_hv_interrupt.c
--
2.23.0
^ permalink raw reply
* Re: [PATCH] crypto/nx: add missing call to of_node_put()
From: kernel test robot @ 2021-02-25 12:59 UTC (permalink / raw)
To: Yang Li, herbert
Cc: kbuild-all, linux-kernel, paulus, linux-crypto, Yang Li,
linuxppc-dev, davem
In-Reply-To: <1614243417-48556-1-git-send-email-yang.lee@linux.alibaba.com>
[-- Attachment #1: Type: text/plain, Size: 7066 bytes --]
Hi Yang,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on powerpc/next]
[also build test WARNING on cryptodev/master crypto/master v5.11 next-20210225]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Yang-Li/crypto-nx-add-missing-call-to-of_node_put/20210225-165847
base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-ppc64_defconfig (attached as .config)
compiler: powerpc64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/828d2f2854283776f81eabbdb8d2c93441206421
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Yang-Li/crypto-nx-add-missing-call-to-of_node_put/20210225-165847
git checkout 828d2f2854283776f81eabbdb8d2c93441206421
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
drivers/crypto/nx/nx-common-powernv.c: In function 'nx_powernv_probe_vas':
>> drivers/crypto/nx/nx-common-powernv.c:935:3: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
935 | if (ret)
| ^~
drivers/crypto/nx/nx-common-powernv.c:937:4: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
937 | return ret;
| ^~~~~~
vim +/if +935 drivers/crypto/nx/nx-common-powernv.c
4aebf3ce26ca212 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 908
4aebf3ce26ca212 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 909 static int __init nx_powernv_probe_vas(struct device_node *pn)
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 910 {
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 911 int chip_id, vasid, ret = 0;
1af11ae225350a9 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 912 int ct_842 = 0, ct_gzip = 0;
4aebf3ce26ca212 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 913 struct device_node *dn;
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 914
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 915 chip_id = of_get_ibm_chip_id(pn);
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 916 if (chip_id < 0) {
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 917 pr_err("ibm,chip-id missing\n");
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 918 return -EINVAL;
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 919 }
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 920
d4ef61b5e8955fb drivers/crypto/nx/nx-842-powernv.c Sukadev Bhattiprolu 2017-11-07 921 vasid = chip_to_vas_id(chip_id);
d4ef61b5e8955fb drivers/crypto/nx/nx-842-powernv.c Sukadev Bhattiprolu 2017-11-07 922 if (vasid < 0) {
d4ef61b5e8955fb drivers/crypto/nx/nx-842-powernv.c Sukadev Bhattiprolu 2017-11-07 923 pr_err("Unable to map chip_id %d to vasid\n", chip_id);
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 924 return -EINVAL;
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 925 }
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 926
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 927 for_each_child_of_node(pn, dn) {
4aebf3ce26ca212 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 928 ret = find_nx_device_tree(dn, chip_id, vasid, NX_CT_842,
4aebf3ce26ca212 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 929 "ibm,p9-nx-842", &ct_842);
1af11ae225350a9 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 930
1af11ae225350a9 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 931 if (!ret)
1af11ae225350a9 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 932 ret = find_nx_device_tree(dn, chip_id, vasid,
1af11ae225350a9 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 933 NX_CT_GZIP, "ibm,p9-nx-gzip", &ct_gzip);
1af11ae225350a9 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 934
4aebf3ce26ca212 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 @935 if (ret)
828d2f285428377 drivers/crypto/nx/nx-common-powernv.c Yang Li 2021-02-25 936 of_node_put(dn);
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 937 return ret;
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 938 }
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 939
1af11ae225350a9 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 940 if (!ct_842 || !ct_gzip) {
1af11ae225350a9 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 941 pr_err("NX FIFO nodes are missing\n");
656ecc16e8fc2ab drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2018-06-13 942 return -EINVAL;
656ecc16e8fc2ab drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2018-06-13 943 }
656ecc16e8fc2ab drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2018-06-13 944
656ecc16e8fc2ab drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2018-06-13 945 /*
656ecc16e8fc2ab drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2018-06-13 946 * Initialize NX instance for both high and normal priority FIFOs.
656ecc16e8fc2ab drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2018-06-13 947 */
1af11ae225350a9 drivers/crypto/nx/nx-common-powernv.c Haren Myneni 2020-04-17 948 ret = nx_coproc_init(chip_id, ct_842, ct_gzip);
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 949
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 950 return ret;
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 951 }
b0d6c9bab5e41d0 drivers/crypto/nx/nx-842-powernv.c Haren Myneni 2017-08-31 952
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 26604 bytes --]
^ permalink raw reply
* Re: [PATCH v2] vio: make remove callback return void
From: Michael Ellerman @ 2021-02-25 11:49 UTC (permalink / raw)
To: Uwe Kleine-König, Benjamin Herrenschmidt, Paul Mackerras,
David S. Miller, Jens Axboe, Matt Mackall, Herbert Xu,
Peter Huewe, Jarkko Sakkinen, Jason Gunthorpe, Haren Myneni,
Breno Leitão, Nayna Jain, Paulo Flabiano Smorigo,
Steven Royer, Arnd Bergmann, Greg Kroah-Hartman, Cristobal Forno,
Jakub Kicinski, Dany Madden, Lijun Pan, Sukadev Bhattiprolu,
Tyrel Datwyler, James E.J. Bottomley, Martin K. Petersen,
Michael Cyr, Jiri Slaby
Cc: linux-scsi, netdev, linux-kernel, linux-block, target-devel,
linux-crypto, sparclinux, linux-integrity, linuxppc-dev
In-Reply-To: <20210224072516.74696-1-uwe@kleine-koenig.org>
Uwe Kleine-König <uwe@kleine-koenig.org> writes:
> The driver core ignores the return value of struct bus_type::remove()
> because there is only little that can be done. To simplify the quest to
> make this function return void, let struct vio_driver::remove() return
> void, too. All users already unconditionally return 0, this commit makes
> it obvious that returning an error code is a bad idea and makes it
> obvious for future driver authors that returning an error code isn't
> intended.
>
> Note there are two nominally different implementations for a vio bus:
> one in arch/sparc/kernel/vio.c and the other in
> arch/powerpc/platforms/pseries/vio.c. I didn't care to check which
> driver is using which of these busses (or if even some of them can be
> used with both) and simply adapt all drivers and the two bus codes in
> one go.
I'm 99% sure there's no connection between the two implementations,
other than the name.
So splitting the patch by arch would make it easier to merge. I'm
reluctant to merge changes to sparc code.
The list of powerpc specific drivers is:
drivers/char/hw_random/pseries-rng.c
drivers/char/tpm/tpm_ibmvtpm.c
drivers/crypto/nx/nx-842-pseries.c
drivers/crypto/nx/nx.c
drivers/misc/ibmvmc.c
drivers/net/ethernet/ibm/ibmveth.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
drivers/tty/hvc/hvcs.c
cheers
^ permalink raw reply
* Re: [PATCH] crypto/nx: add missing call to of_node_put()
From: Michael Ellerman @ 2021-02-25 11:15 UTC (permalink / raw)
To: Yang Li, herbert
Cc: linux-kernel, paulus, linux-crypto, Yang Li, linuxppc-dev, davem
In-Reply-To: <1614243417-48556-1-git-send-email-yang.lee@linux.alibaba.com>
Yang Li <yang.lee@linux.alibaba.com> writes:
> In one of the error paths of the for_each_child_of_node() loop,
> add missing call to of_node_put().
>
> Fix the following coccicheck warning:
> ./drivers/crypto/nx/nx-common-powernv.c:927:1-23: WARNING: Function
> "for_each_child_of_node" should have of_node_put() before return around
> line 936.
>
> Reported-by: Abaci Robot <abaci@linux.alibaba.com>
> Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
> ---
> drivers/crypto/nx/nx-common-powernv.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/crypto/nx/nx-common-powernv.c b/drivers/crypto/nx/nx-common-powernv.c
> index 13c65de..b43c457 100644
> --- a/drivers/crypto/nx/nx-common-powernv.c
> +++ b/drivers/crypto/nx/nx-common-powernv.c
> @@ -933,6 +933,7 @@ static int __init nx_powernv_probe_vas(struct device_node *pn)
> NX_CT_GZIP, "ibm,p9-nx-gzip", &ct_gzip);
>
> if (ret)
> + of_node_put(dn);
> return ret;
Sorry this is wrong, the if needs braces.
cheers
^ permalink raw reply
* Re: [PATCH 12/13] KVM: PPC: Book3S HV: Move radix MMU switching together in the P9 path
From: Nicholas Piggin @ 2021-02-25 10:59 UTC (permalink / raw)
To: Fabiano Rosas, kvm-ppc; +Cc: linuxppc-dev
In-Reply-To: <878s7dxkxr.fsf@linux.ibm.com>
Excerpts from Fabiano Rosas's message of February 25, 2021 6:36 am:
> Nicholas Piggin <npiggin@gmail.com> writes:
>
>> Switching the MMU from radix<->radix mode is tricky particularly as the
>> MMU can remain enabled and requires a certain sequence of SPR updates.
>> Move these together into their own functions.
>>
>> This also includes the radix TLB check / flush because it's tied in to
>> MMU switching due to tlbiel getting LPID from LPIDR.
>>
>> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
>> ---
>
> <snip>
>
>> @@ -4117,7 +4138,7 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
>> {
>> struct kvm_run *run = vcpu->run;
>> int trap, r, pcpu;
>> - int srcu_idx, lpid;
>> + int srcu_idx;
>> struct kvmppc_vcore *vc;
>> struct kvm *kvm = vcpu->kvm;
>> struct kvm_nested_guest *nested = vcpu->arch.nested;
>> @@ -4191,13 +4212,6 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit,
>> vc->vcore_state = VCORE_RUNNING;
>> trace_kvmppc_run_core(vc, 0);
>>
>> - if (cpu_has_feature(CPU_FTR_HVMODE)) {
>> - lpid = nested ? nested->shadow_lpid : kvm->arch.lpid;
>> - mtspr(SPRN_LPID, lpid);
>> - isync();
>> - kvmppc_check_need_tlb_flush(kvm, pcpu, nested);
>> - }
>> -
>
> What about the counterpart to this^ down below?
>
> if (cpu_has_feature(CPU_FTR_HVMODE)) {
> mtspr(SPRN_LPID, kvm->arch.host_lpid);
> isync();
> }
Good catch, you're right that can be removed too.
Thanks,
Nick
^ permalink raw reply
* Re: Is unrecoverable_exception() really an interrupt handler ?
From: Nicholas Piggin @ 2021-02-25 10:54 UTC (permalink / raw)
To: Christophe Leroy, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <2b89ac7e-e971-7de6-e6af-4bd86b699eab@csgroup.eu>
Excerpts from Christophe Leroy's message of February 24, 2021 6:15 pm:
> Hi Nick,
>
> You defined unrecoverable_exeption() as an interrupt handler in interrupt.h
>
> I think there are several issues around that:
>
> - do_bad_slb_fault() which is also an interrupt handler calls unrecoverable_exeption()
> - in exception-64s.S, unrecoverable_exeption() is called after machine_check_exception()
> - interrupt_exit_kernel_prepare() calls unrecoverable_exception()
>
> So in those cases, interrupt_enter_prepare() gets called twice, so things like for instance
> account_cpu_user_entry() gets called twice.
Hi Christophe,
You are right of course.
I would say we can revert it back to a regular function. I would just
remove it completely from machine_check_exception too.
Thanks,
Nick
^ permalink raw reply
* Re: [PATCH] powerpc/syscall: Force inlining of __prep_irq_for_enabled_exit()
From: Nicholas Piggin @ 2021-02-25 10:52 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Christophe Leroy, Michael Ellerman,
Paul Mackerras
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <53f3a1f719441761000c41154602bf097d4350b5.1614148356.git.christophe.leroy@csgroup.eu>
Excerpts from Christophe Leroy's message of February 24, 2021 4:34 pm:
> As reported by kernel test robot, a randconfig with high amount of
> debuging options can lead to build failure for undefined reference
> to replay_soft_interrupts() on ppc32.
>
> This is due to gcc not seeing that __prep_irq_for_enabled_exit()
> always returns true on ppc32 because it doesn't inline it for
> some reason.
>
> Force inlining of __prep_irq_for_enabled_exit() to fix the build.
>
> Reported-by: kernel test robot <lkp@intel.com>
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Acked-by: Nicholas Piggin <npiggin@gmail.com>
> Fixes: 344bb20b159d ("powerpc/syscall: Make interrupt.c buildable on PPC32")
> ---
> arch/powerpc/kernel/interrupt.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
> index 398cd86b6ada..2ef3c4051bb9 100644
> --- a/arch/powerpc/kernel/interrupt.c
> +++ b/arch/powerpc/kernel/interrupt.c
> @@ -149,7 +149,7 @@ notrace long system_call_exception(long r3, long r4, long r5,
> * enabled when the interrupt handler returns (indicating a process-context /
> * synchronous interrupt) then irqs_enabled should be true.
> */
> -static notrace inline bool __prep_irq_for_enabled_exit(bool clear_ri)
> +static notrace __always_inline bool __prep_irq_for_enabled_exit(bool clear_ri)
> {
> /* This must be done with RI=1 because tracing may touch vmaps */
> trace_hardirqs_on();
> --
> 2.25.0
>
>
^ permalink raw reply
* [PATCH V2] powerpc/perf: Fix handling of privilege level checks in perf interrupt context
From: Athira Rajeev @ 2021-02-25 10:10 UTC (permalink / raw)
To: mpe; +Cc: maddy, peterz, omosnace, acme, jolsa, linuxppc-dev, kan.liang
Running "perf mem record" in powerpc platforms with selinux enabled
resulted in soft lockup's. Below call-trace was seen in the logs:
CPU: 58 PID: 3751 Comm: sssd_nss Not tainted 5.11.0-rc7+ #2
NIP: c000000000dff3d4 LR: c000000000dff3d0 CTR: 0000000000000000
REGS: c000007fffab7d60 TRAP: 0100 Not tainted (5.11.0-rc7+)
<<>>
NIP [c000000000dff3d4] _raw_spin_lock_irqsave+0x94/0x120
LR [c000000000dff3d0] _raw_spin_lock_irqsave+0x90/0x120
Call Trace:
[c00000000fd471a0] [c00000000fd47260] 0xc00000000fd47260 (unreliable)
[c00000000fd471e0] [c000000000b5fbbc] skb_queue_tail+0x3c/0x90
[c00000000fd47220] [c000000000296edc] audit_log_end+0x6c/0x180
[c00000000fd47260] [c0000000006a3f20] common_lsm_audit+0xb0/0xe0
[c00000000fd472a0] [c00000000066c664] slow_avc_audit+0xa4/0x110
[c00000000fd47320] [c00000000066cff4] avc_has_perm+0x1c4/0x260
[c00000000fd47430] [c00000000066e064] selinux_perf_event_open+0x74/0xd0
[c00000000fd47450] [c000000000669888] security_perf_event_open+0x68/0xc0
[c00000000fd47490] [c00000000013d788] record_and_restart+0x6e8/0x7f0
[c00000000fd476c0] [c00000000013dabc] perf_event_interrupt+0x22c/0x560
[c00000000fd477d0] [c00000000002d0fc] performance_monitor_exception0x4c/0x60
[c00000000fd477f0] [c00000000000b378] performance_monitor_common_virt+0x1c8/0x1d0
interrupt: f00 at _raw_spin_lock_irqsave+0x38/0x120
NIP: c000000000dff378 LR: c000000000b5fbbc CTR: c0000000007d47f0
REGS: c00000000fd47860 TRAP: 0f00 Not tainted (5.11.0-rc7+)
<<>>
NIP [c000000000dff378] _raw_spin_lock_irqsave+0x38/0x120
LR [c000000000b5fbbc] skb_queue_tail+0x3c/0x90
interrupt: f00
[c00000000fd47b00] [0000000000000038] 0x38 (unreliable)
[c00000000fd47b40] [c00000000aae6200] 0xc00000000aae6200
[c00000000fd47b80] [c000000000296edc] audit_log_end+0x6c/0x180
[c00000000fd47bc0] [c00000000029f494] audit_log_exit+0x344/0xf80
[c00000000fd47d10] [c0000000002a2b00] __audit_syscall_exit+0x2c0/0x320
[c00000000fd47d60] [c000000000032878] do_syscall_trace_leave+0x148/0x200
[c00000000fd47da0] [c00000000003d5b4] syscall_exit_prepare+0x324/0x390
[c00000000fd47e10] [c00000000000d76c] system_call_common+0xfc/0x27c
The above trace shows that while the CPU was handling a performance
monitor exception, there was a call to "security_perf_event_open"
function. In powerpc core-book3s, this function is called from
'perf_allow_kernel' check during recording of data address in the sample
via perf_get_data_addr().
Commit da97e18458fb ("perf_event: Add support for LSM and SELinux checks")
introduced security enhancements to perf. As part of this commit, the new
security hook for perf_event_open was added in all places where perf
paranoid check was previously used. In powerpc core-book3s code, originally
had paranoid checks in 'perf_get_data_addr' and 'power_pmu_bhrb_read'. So
'perf_paranoid_kernel' checks were replaced with 'perf_allow_kernel' in
these pmu helper functions as well.
The intention of paranoid checks in core-book3s was to verify privilege
access before capturing some of the sample data. Along with paranoid
checks, 'perf_allow_kernel' also does a 'security_perf_event_open'. Since
these functions are accessed while recording sample, we end up in calling
selinux_perf_event_open in PMI context. Some of the security functions
use spinlock like sidtab_sid2str_put(). If a perf interrupt hits under
a spin lock and if we end up in calling selinux hook functions in PMI
handler, this could cause a dead lock.
Since the purpose of this security hook is to control access to
perf_event_open, it is not right to call this in interrupt context.
The paranoid checks in powerpc core-book3s were done at interrupt
time which is also not correct.
Reference commits:
Commit cd1231d7035f ("powerpc/perf: Prevent kernel address leak via
perf_get_data_addr()")
Commit bb19af816025 ("powerpc/perf: Prevent kernel address leak to
userspace via BHRB buffer")
We only allow creation of events that has already passed the privilege
checks in perf_event_open. So these paranoid checks are not needed at
event time. As a fix, patch uses 'event->attr.exclude_kernel' check
to prevent exposing kernel address for userspace only sampling.
Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
---
Changes in v2:
- Addressed review comments from Ondrej Mosnacek and Peter Zijlstra.
Changed the approach to use 'event->attr.exclude_kernel'
check to prevent exposing kernel address for userspace only
sampling as suggested by Ondrej Mosnacek.
arch/powerpc/perf/core-book3s.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 4b4319d8..c8be44c 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -222,7 +222,7 @@ static inline void perf_get_data_addr(struct perf_event *event, struct pt_regs *
if (!(mmcra & MMCRA_SAMPLE_ENABLE) || sdar_valid)
*addrp = mfspr(SPRN_SDAR);
- if (is_kernel_addr(mfspr(SPRN_SDAR)) && perf_allow_kernel(&event->attr) != 0)
+ if (is_kernel_addr(mfspr(SPRN_SDAR)) && event->attr.exclude_kernel)
*addrp = 0;
}
@@ -507,7 +507,7 @@ static void power_pmu_bhrb_read(struct perf_event *event, struct cpu_hw_events *
* addresses, hence include a check before filtering code
*/
if (!(ppmu->flags & PPMU_ARCH_31) &&
- is_kernel_addr(addr) && perf_allow_kernel(&event->attr) != 0)
+ is_kernel_addr(addr) && event->attr.exclude_kernel)
continue;
/* Branches are read most recent first (ie. mfbhrb 0 is
--
1.8.3.1
^ permalink raw reply related
* [PATCH] powerpc: Replace DEFINE_SIMPLE_ATTRIBUTE with DEFINE_DEBUGFS_ATTRIBUTE
From: Yang Li @ 2021-02-25 9:12 UTC (permalink / raw)
To: mpe; +Cc: Yang Li, paulus, linuxppc-dev, linux-kernel
Fix the following coccicheck warning:
./arch/powerpc/kernel/setup_64.c:1143:0-23: WARNING: fops_rfi_flush
should be defined with DEFINE_DEBUGFS_ATTRIBUTE
./arch/powerpc/kernel/setup_64.c:1169:0-23: WARNING: fops_entry_flush
should be defined with DEFINE_DEBUGFS_ATTRIBUTE
./arch/powerpc/kernel/setup_64.c:1195:0-23: WARNING: fops_uaccess_flush
should be defined with DEFINE_DEBUGFS_ATTRIBUTE
./arch/powerpc/platforms/powernv/memtrace.c:311:0-23: WARNING:
memtrace_init_fops should be defined with DEFINE_DEBUGFS_ATTRIBUTE
./arch/powerpc/xmon/xmon.c:3997:0-23: WARNING: xmon_dbgfs_ops should be
defined with DEFINE_DEBUGFS_ATTRIBUTE
Reported-by: Abaci Robot <abaci@linux.alibaba.com>
Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
---
arch/powerpc/kernel/setup_64.c | 6 +++---
arch/powerpc/platforms/powernv/memtrace.c | 4 ++--
arch/powerpc/xmon/xmon.c | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 560ed8b..6a030b0 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -1140,7 +1140,7 @@ static int rfi_flush_get(void *data, u64 *val)
return 0;
}
-DEFINE_SIMPLE_ATTRIBUTE(fops_rfi_flush, rfi_flush_get, rfi_flush_set, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(fops_rfi_flush, rfi_flush_get, rfi_flush_set, "%llu\n");
static int entry_flush_set(void *data, u64 val)
{
@@ -1166,7 +1166,7 @@ static int entry_flush_get(void *data, u64 *val)
return 0;
}
-DEFINE_SIMPLE_ATTRIBUTE(fops_entry_flush, entry_flush_get, entry_flush_set, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(fops_entry_flush, entry_flush_get, entry_flush_set, "%llu\n");
static int uaccess_flush_set(void *data, u64 val)
{
@@ -1192,7 +1192,7 @@ static int uaccess_flush_get(void *data, u64 *val)
return 0;
}
-DEFINE_SIMPLE_ATTRIBUTE(fops_uaccess_flush, uaccess_flush_get, uaccess_flush_set, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(fops_uaccess_flush, uaccess_flush_get, uaccess_flush_set, "%llu\n");
static __init int rfi_flush_debugfs_init(void)
{
diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c
index 019669e..731be02 100644
--- a/arch/powerpc/platforms/powernv/memtrace.c
+++ b/arch/powerpc/platforms/powernv/memtrace.c
@@ -308,8 +308,8 @@ static int memtrace_enable_get(void *data, u64 *val)
return 0;
}
-DEFINE_SIMPLE_ATTRIBUTE(memtrace_init_fops, memtrace_enable_get,
- memtrace_enable_set, "0x%016llx\n");
+DEFINE_DEBUGFS_ATTRIBUTE(memtrace_init_fops, memtrace_enable_get,
+ memtrace_enable_set, "0x%016llx\n");
static int memtrace_init(void)
{
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 3fe3749..6d54767 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -3994,7 +3994,7 @@ static int xmon_dbgfs_get(void *data, u64 *val)
return 0;
}
-DEFINE_SIMPLE_ATTRIBUTE(xmon_dbgfs_ops, xmon_dbgfs_get,
+DEFINE_DEBUGFS_ATTRIBUTE(xmon_dbgfs_ops, xmon_dbgfs_get,
xmon_dbgfs_set, "%llu\n");
static int __init setup_xmon_dbgfs(void)
--
1.8.3.1
^ permalink raw reply related
* [PATCH] crypto/nx: add missing call to of_node_put()
From: Yang Li @ 2021-02-25 8:56 UTC (permalink / raw)
To: herbert; +Cc: linux-kernel, paulus, linux-crypto, Yang Li, linuxppc-dev, davem
In one of the error paths of the for_each_child_of_node() loop,
add missing call to of_node_put().
Fix the following coccicheck warning:
./drivers/crypto/nx/nx-common-powernv.c:927:1-23: WARNING: Function
"for_each_child_of_node" should have of_node_put() before return around
line 936.
Reported-by: Abaci Robot <abaci@linux.alibaba.com>
Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
---
drivers/crypto/nx/nx-common-powernv.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/crypto/nx/nx-common-powernv.c b/drivers/crypto/nx/nx-common-powernv.c
index 13c65de..b43c457 100644
--- a/drivers/crypto/nx/nx-common-powernv.c
+++ b/drivers/crypto/nx/nx-common-powernv.c
@@ -933,6 +933,7 @@ static int __init nx_powernv_probe_vas(struct device_node *pn)
NX_CT_GZIP, "ibm,p9-nx-gzip", &ct_gzip);
if (ret)
+ of_node_put(dn);
return ret;
}
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH 1/2] powerpc/perf: Infrastructure to support checking of attr.config*
From: Madhavan Srinivasan @ 2021-02-25 6:39 UTC (permalink / raw)
To: Paul A. Clarke; +Cc: Alexey Kardashevskiy, linuxppc-dev
In-Reply-To: <20210224144758.GA566251@li-24c3614c-2adc-11b2-a85c-85f334518bdb.ibm.com>
On 2/24/21 8:17 PM, Paul A. Clarke wrote:
> On Wed, Feb 24, 2021 at 07:58:39PM +0530, Madhavan Srinivasan wrote:
>> Introduce code to support the checking of attr.config* for
>> values which are reserved for a given platform.
>> Performance Monitoring Unit (PMU) configuration registers
>> have fileds that are reserved and specific values to bit fields
> s/fileds/fields/
>
>> as reserved. Writing a none zero values in these fields
> Should the previous sentences say something like "required values
> for specific bit fields" or "specific bit fields that are reserved"?
>
> s/none zero/non-zero/
>
>> or writing invalid value to bit fields will have unknown
>> behaviours.
>>
>> Patch here add a generic call-back function "check_attr_config"
> s/add/adds/ or "This patch adds ..." or just "Add ...".
Thanks for the review. Will fix it.
>
>> in "struct power_pmu", to be called in event_init to
>> check for attr.config* values for a given platform.
>> "check_attr_config" is valid only for raw event type.
>>
>> Suggested-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
>> ---
>> arch/powerpc/include/asm/perf_event_server.h | 6 ++++++
>> arch/powerpc/perf/core-book3s.c | 12 ++++++++++++
>> 2 files changed, 18 insertions(+)
>>
>> diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
>> index 00e7e671bb4b..dde97d7d9253 100644
>> --- a/arch/powerpc/include/asm/perf_event_server.h
>> +++ b/arch/powerpc/include/asm/perf_event_server.h
>> @@ -67,6 +67,12 @@ struct power_pmu {
>> * the pmu supports extended perf regs capability
>> */
>> int capabilities;
>> + /*
>> + * Function to check event code for values which are
>> + * reserved. Function takes struct perf_event as input,
>> + * since event code could be spread in attr.config*
>> + */
>> + int (*check_attr_config)(struct perf_event *ev);
>> };
>>
>> /*
>> diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
>> index 6817331e22ff..679d67506299 100644
>> --- a/arch/powerpc/perf/core-book3s.c
>> +++ b/arch/powerpc/perf/core-book3s.c
>> @@ -1958,6 +1958,18 @@ static int power_pmu_event_init(struct perf_event *event)
>>
>> if (ppmu->blacklist_ev && is_event_blacklisted(ev))
>> return -EINVAL;
>> + /*
>> + * PMU config registers have fileds that are
>> + * reserved and spacific values to bit fileds be reserved.
> s/spacific/specific/
> s/fileds/fields/
> Same comment about "specific values to bit fields be reserved", and
> rewording that to be more clear.
>
>> + * This call-back will check the event code for same.
>> + *
>> + * Event type hardware and hw_cache will not value
>> + * invalid values in the event code which is not true
>> + * for raw event type.
> I confess I don't understand what this means. (But it could be just me!)
My bad. What I wanted to say was, this check is needed only
for raw event type, since tools like fuzzer use it to provide
randomized event code values for test. Will fix the comment
Thanks for the review comments.
>
>> + */
>> + if (ppmu->check_attr_config &&
>> + ppmu->check_attr_config(event))
>> + return -EINVAL;
>> break;
>> default:
>> return -ENOENT;
>> --
> PC
^ permalink raw reply
* [PATCH] selftests/powerpc: Add uaccess flush test
From: Daniel Axtens @ 2021-02-25 6:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Thadeu Lima de Souza Cascardo, Daniel Axtens
From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Also based on the RFI and entry flush tests, it counts the L1D misses
by doing a syscall that does user access: uname, in this case.
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
[dja: forward port, rename function]
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
This applies on top of Russell's change to use better constants:
https://patchwork.ozlabs.org/project/linuxppc-dev/patch/20210223070227.2916871-1-ruscur@russell.cc/
It's possible that we could share some more code between the tests, but
it hardly seems worth it.
---
.../selftests/powerpc/security/Makefile | 3 +-
.../selftests/powerpc/security/flush_utils.c | 13 ++
.../selftests/powerpc/security/flush_utils.h | 3 +
.../powerpc/security/uaccess_flush.c | 158 ++++++++++++++++++
4 files changed, 176 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/security/uaccess_flush.c
diff --git a/tools/testing/selftests/powerpc/security/Makefile b/tools/testing/selftests/powerpc/security/Makefile
index f25e854fe370..844d18cd5f93 100644
--- a/tools/testing/selftests/powerpc/security/Makefile
+++ b/tools/testing/selftests/powerpc/security/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+
-TEST_GEN_PROGS := rfi_flush entry_flush spectre_v2
+TEST_GEN_PROGS := rfi_flush entry_flush uaccess_flush spectre_v2
top_srcdir = ../../../../..
CFLAGS += -I../../../../../usr/include
@@ -13,3 +13,4 @@ $(OUTPUT)/spectre_v2: CFLAGS += -m64
$(OUTPUT)/spectre_v2: ../pmu/event.c branch_loops.S
$(OUTPUT)/rfi_flush: flush_utils.c
$(OUTPUT)/entry_flush: flush_utils.c
+$(OUTPUT)/uaccess_flush: flush_utils.c
diff --git a/tools/testing/selftests/powerpc/security/flush_utils.c b/tools/testing/selftests/powerpc/security/flush_utils.c
index 0c3c4c40c7fb..4d95965cb751 100644
--- a/tools/testing/selftests/powerpc/security/flush_utils.c
+++ b/tools/testing/selftests/powerpc/security/flush_utils.c
@@ -13,6 +13,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <sys/utsname.h>
#include "utils.h"
#include "flush_utils.h"
@@ -35,6 +36,18 @@ void syscall_loop(char *p, unsigned long iterations,
}
}
+void syscall_loop_uaccess(char *p, unsigned long iterations,
+ unsigned long zero_size)
+{
+ struct utsname utsname;
+
+ for (unsigned long i = 0; i < iterations; i++) {
+ for (unsigned long j = 0; j < zero_size; j += CACHELINE_SIZE)
+ load(p + j);
+ uname(&utsname);
+ }
+}
+
static void sigill_handler(int signr, siginfo_t *info, void *unused)
{
static int warned;
diff --git a/tools/testing/selftests/powerpc/security/flush_utils.h b/tools/testing/selftests/powerpc/security/flush_utils.h
index 7a3d60292916..e1e68281f7ac 100644
--- a/tools/testing/selftests/powerpc/security/flush_utils.h
+++ b/tools/testing/selftests/powerpc/security/flush_utils.h
@@ -16,6 +16,9 @@
void syscall_loop(char *p, unsigned long iterations,
unsigned long zero_size);
+void syscall_loop_uaccess(char *p, unsigned long iterations,
+ unsigned long zero_size);
+
void set_dscr(unsigned long val);
#endif /* _SELFTESTS_POWERPC_SECURITY_FLUSH_UTILS_H */
diff --git a/tools/testing/selftests/powerpc/security/uaccess_flush.c b/tools/testing/selftests/powerpc/security/uaccess_flush.c
new file mode 100644
index 000000000000..cf80f960e38a
--- /dev/null
+++ b/tools/testing/selftests/powerpc/security/uaccess_flush.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright 2018 IBM Corporation.
+ * Copyright 2020 Canonical Ltd.
+ */
+
+#define __SANE_USERSPACE_TYPES__
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "utils.h"
+#include "flush_utils.h"
+
+int uaccess_flush_test(void)
+{
+ char *p;
+ int repetitions = 10;
+ int fd, passes = 0, iter, rc = 0;
+ struct perf_event_read v;
+ __u64 l1d_misses_total = 0;
+ unsigned long iterations = 100000, zero_size = 24 * 1024;
+ unsigned long l1d_misses_expected;
+ int rfi_flush_orig;
+ int entry_flush_orig;
+ int uaccess_flush, uaccess_flush_orig;
+
+ SKIP_IF(geteuid() != 0);
+
+ // The PMU event we use only works on Power7 or later
+ SKIP_IF(!have_hwcap(PPC_FEATURE_ARCH_2_06));
+
+ if (read_debugfs_file("powerpc/rfi_flush", &rfi_flush_orig) < 0) {
+ perror("Unable to read powerpc/rfi_flush debugfs file");
+ SKIP_IF(1);
+ }
+
+ if (read_debugfs_file("powerpc/entry_flush", &entry_flush_orig) < 0) {
+ perror("Unable to read powerpc/entry_flush debugfs file");
+ SKIP_IF(1);
+ }
+
+ if (read_debugfs_file("powerpc/uaccess_flush", &uaccess_flush_orig) < 0) {
+ perror("Unable to read powerpc/entry_flush debugfs file");
+ SKIP_IF(1);
+ }
+
+ if (rfi_flush_orig != 0) {
+ if (write_debugfs_file("powerpc/rfi_flush", 0) < 0) {
+ perror("error writing to powerpc/rfi_flush debugfs file");
+ FAIL_IF(1);
+ }
+ }
+
+ if (entry_flush_orig != 0) {
+ if (write_debugfs_file("powerpc/entry_flush", 0) < 0) {
+ perror("error writing to powerpc/entry_flush debugfs file");
+ FAIL_IF(1);
+ }
+ }
+
+ uaccess_flush = uaccess_flush_orig;
+
+ fd = perf_event_open_counter(PERF_TYPE_HW_CACHE, PERF_L1D_READ_MISS_CONFIG, -1);
+ FAIL_IF(fd < 0);
+
+ p = (char *)memalign(zero_size, CACHELINE_SIZE);
+
+ FAIL_IF(perf_event_enable(fd));
+
+ // disable L1 prefetching
+ set_dscr(1);
+
+ iter = repetitions;
+
+ /*
+ * We expect to see l1d miss for each cacheline access when entry_flush
+ * is set. Allow a small variation on this.
+ */
+ l1d_misses_expected = iterations * (zero_size / CACHELINE_SIZE - 2);
+
+again:
+ FAIL_IF(perf_event_reset(fd));
+
+ syscall_loop_uaccess(p, iterations, zero_size);
+
+ FAIL_IF(read(fd, &v, sizeof(v)) != sizeof(v));
+
+ if (uaccess_flush && v.l1d_misses >= l1d_misses_expected)
+ passes++;
+ else if (!uaccess_flush && v.l1d_misses < (l1d_misses_expected / 2))
+ passes++;
+
+ l1d_misses_total += v.l1d_misses;
+
+ while (--iter)
+ goto again;
+
+ if (passes < repetitions) {
+ printf("FAIL (L1D misses with uaccess_flush=%d: %llu %c %lu) [%d/%d failures]\n",
+ uaccess_flush, l1d_misses_total, uaccess_flush ? '<' : '>',
+ uaccess_flush ? repetitions * l1d_misses_expected :
+ repetitions * l1d_misses_expected / 2,
+ repetitions - passes, repetitions);
+ rc = 1;
+ } else {
+ printf("PASS (L1D misses with uaccess_flush=%d: %llu %c %lu) [%d/%d pass]\n",
+ uaccess_flush, l1d_misses_total, uaccess_flush ? '>' : '<',
+ uaccess_flush ? repetitions * l1d_misses_expected :
+ repetitions * l1d_misses_expected / 2,
+ passes, repetitions);
+ }
+
+ if (uaccess_flush == uaccess_flush_orig) {
+ uaccess_flush = !uaccess_flush_orig;
+ if (write_debugfs_file("powerpc/uaccess_flush", uaccess_flush) < 0) {
+ perror("error writing to powerpc/uaccess_flush debugfs file");
+ return 1;
+ }
+ iter = repetitions;
+ l1d_misses_total = 0;
+ passes = 0;
+ goto again;
+ }
+
+ perf_event_disable(fd);
+ close(fd);
+
+ set_dscr(0);
+
+ if (write_debugfs_file("powerpc/rfi_flush", rfi_flush_orig) < 0) {
+ perror("unable to restore original value of powerpc/rfi_flush debugfs file");
+ return 1;
+ }
+
+ if (write_debugfs_file("powerpc/entry_flush", entry_flush_orig) < 0) {
+ perror("unable to restore original value of powerpc/entry_flush debugfs file");
+ return 1;
+ }
+
+ if (write_debugfs_file("powerpc/uaccess_flush", uaccess_flush_orig) < 0) {
+ perror("unable to restore original value of powerpc/uaccess_flush debugfs file");
+ return 1;
+ }
+
+ return rc;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_harness(uaccess_flush_test, "uaccess_flush_test");
+}
--
2.27.0
^ permalink raw reply related
* [PATCH] docs: powerpc: Fix tables in syscall64-abi.rst
From: Andrew Donnellan @ 2021-02-25 6:08 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mchehab+huawei, corbet, linux-doc
Commit 209b44c804c ("docs: powerpc: syscall64-abi.rst: fix a malformed
table") attempted to fix the formatting of tables in syscall64-abi.rst, but
inadvertently changed some register names.
Redo the tables with the correct register names, and while we're here,
clean things up to separate the registers into different rows and add
headings.
Fixes: 209b44c804c ("docs: powerpc: syscall64-abi.rst: fix a malformed table")
Signed-off-by: Andrew Donnellan <ajd@linux.ibm.com>
---
Documentation/powerpc/syscall64-abi.rst | 51 ++++++++++++++++---------
1 file changed, 32 insertions(+), 19 deletions(-)
diff --git a/Documentation/powerpc/syscall64-abi.rst b/Documentation/powerpc/syscall64-abi.rst
index cf9b2857c72a..dabee3729e5a 100644
--- a/Documentation/powerpc/syscall64-abi.rst
+++ b/Documentation/powerpc/syscall64-abi.rst
@@ -46,25 +46,38 @@ stack frame LR and CR save fields are not used.
Register preservation rules
---------------------------
-Register preservation rules match the ELF ABI calling sequence with the
-following differences:
-
-+------------------------------------------------------------------------+
-| For the sc instruction, differences with the ELF ABI |
-+--------------+--------------+------------------------------------------+
-| r0 | Volatile | (System call number.) |
-| rr3 | Volatile | (Parameter 1, and return value.) |
-| rr4-r8 | Volatile | (Parameters 2-6.) |
-| rcr0 | Volatile | (cr0.SO is the return error condition.) |
-| rcr1, cr5-7 | Nonvolatile | |
-| rlr | Nonvolatile | |
-+--------------+--------------+------------------------------------------+
-| For the scv 0 instruction, differences with the ELF ABI |
-+--------------+--------------+------------------------------------------+
-| r0 | Volatile | (System call number.) |
-| r3 | Volatile | (Parameter 1, and return value.) |
-| r4-r8 | Volatile | (Parameters 2-6.) |
-+--------------+--------------+------------------------------------------+
+Register preservation rules match the ELF ABI calling sequence with some
+differences.
+
+For the sc instruction, the differences from the ELF ABI are as follows:
+
++--------------+--------------------+-----------------------------------------+
+| Register | Preservation Rules | Purpose |
++==============+====================+=========================================+
+| r0 | Volatile | (System call number.) |
++--------------+--------------------+-----------------------------------------+
+| r3 | Volatile | (Parameter 1, and return value.) |
++--------------+--------------------+-----------------------------------------+
+| r4-r8 | Volatile | (Parameters 2-6.) |
++--------------+--------------------+-----------------------------------------+
+| cr0 | Volatile | (cr0.SO is the return error condition.) |
++--------------+--------------------+-----------------------------------------+
+| cr1, cr5-7 | Nonvolatile | |
++--------------+--------------------+-----------------------------------------+
+| lr | Nonvolatile | |
++--------------+--------------------+-----------------------------------------+
+
+For the scv 0 instruction, the differences from the ELF ABI are as follows:
+
++--------------+--------------------+-----------------------------------------+
+| Register | Preservation Rules | Purpose |
++==============+====================+=========================================+
+| r0 | Volatile | (System call number.) |
++--------------+--------------------+-----------------------------------------+
+| r3 | Volatile | (Parameter 1, and return value.) |
++--------------+--------------------+-----------------------------------------+
+| r4-r8 | Volatile | (Parameters 2-6.) |
++--------------+--------------------+-----------------------------------------+
All floating point and vector data registers as well as control and status
registers are nonvolatile.
--
2.20.1
^ permalink raw reply related
* Re: [PATCH v6 07/10] powerpc/signal64: Replace restore_sigcontext() w/ unsafe_restore_sigcontext()
From: Christopher M. Riedl @ 2021-02-25 3:54 UTC (permalink / raw)
To: Christophe Leroy, linuxppc-dev
In-Reply-To: <67afcec9-6335-2bd5-938b-687ecb61bf3d@csgroup.eu>
On Tue Feb 23, 2021 at 11:36 AM CST, Christophe Leroy wrote:
>
>
> Le 21/02/2021 à 02:23, Christopher M. Riedl a écrit :
> > Previously restore_sigcontext() performed a costly KUAP switch on every
> > uaccess operation. These repeated uaccess switches cause a significant
> > drop in signal handling performance.
> >
> > Rewrite restore_sigcontext() to assume that a userspace read access
> > window is open by replacing all uaccess functions with their 'unsafe'
> > versions. Modify the callers to first open, call
> > unsafe_restore_sigcontext(), and then close the uaccess window.
> >
> > Signed-off-by: Christopher M. Riedl <cmr@codefail.de>
> > ---
> > arch/powerpc/kernel/signal_64.c | 68 ++++++++++++++++++++-------------
> > 1 file changed, 41 insertions(+), 27 deletions(-)
> >
> > diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
> > index 3faaa736ed62..76b525261f61 100644
> > --- a/arch/powerpc/kernel/signal_64.c
> > +++ b/arch/powerpc/kernel/signal_64.c
> > @@ -326,14 +326,14 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc,
> > /*
> > * Restore the sigcontext from the signal frame.
> > */
> > -
> > -static long restore_sigcontext(struct task_struct *tsk, sigset_t *set, int sig,
> > - struct sigcontext __user *sc)
> > +#define unsafe_restore_sigcontext(tsk, set, sig, sc, e) \
> > + unsafe_op_wrap(__unsafe_restore_sigcontext(tsk, set, sig, sc), e)
>
> unsafe_op_wrap() was not initially meant to be used outside of uaccess.h
>
> In the begining, it has been copied from include/linux/uaccess.h and was
> used
> for unsafe_put_user(), unsafe_get_user() and unsafe_copy_to_user().
> After other changes, only
> unsafe_get_user() is still using it and I'm going to drop
> unsafe_op_wrap() soon.
>
> I'd prefer if you can do the same as unsafe_save_general_regs() and
> others in signal_32.c
Sounds good, will change this in the next version (and also the wrapper
around unsafe_setup_sigcontext()).
>
> > +static long notrace __unsafe_restore_sigcontext(struct task_struct *tsk, sigset_t *set,
> > + int sig, struct sigcontext __user *sc)
> > {
> > #ifdef CONFIG_ALTIVEC
> > elf_vrreg_t __user *v_regs;
> > #endif
> > - unsigned long err = 0;
> > unsigned long save_r13 = 0;
> > unsigned long msr;
> > struct pt_regs *regs = tsk->thread.regs;
> > @@ -348,27 +348,28 @@ static long restore_sigcontext(struct task_struct *tsk, sigset_t *set, int sig,
> > save_r13 = regs->gpr[13];
> >
> > /* copy the GPRs */
> > - err |= __copy_from_user(regs->gpr, sc->gp_regs, sizeof(regs->gpr));
> > - err |= __get_user(regs->nip, &sc->gp_regs[PT_NIP]);
> > + unsafe_copy_from_user(regs->gpr, sc->gp_regs, sizeof(regs->gpr),
> > + efault_out);
>
> I think it would be better to keep the above on a single line for
> readability.
> Nowadays we tolerate 100 chars lines for cases like this one.
Ok, changed this (and the line you mention further below) in the next
version.
>
> > + unsafe_get_user(regs->nip, &sc->gp_regs[PT_NIP], efault_out);
> > /* get MSR separately, transfer the LE bit if doing signal return */
> > - err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
> > + unsafe_get_user(msr, &sc->gp_regs[PT_MSR], efault_out);
> > if (sig)
> > regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
> > - err |= __get_user(regs->orig_gpr3, &sc->gp_regs[PT_ORIG_R3]);
> > - err |= __get_user(regs->ctr, &sc->gp_regs[PT_CTR]);
> > - err |= __get_user(regs->link, &sc->gp_regs[PT_LNK]);
> > - err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]);
> > - err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]);
> > + unsafe_get_user(regs->orig_gpr3, &sc->gp_regs[PT_ORIG_R3], efault_out);
> > + unsafe_get_user(regs->ctr, &sc->gp_regs[PT_CTR], efault_out);
> > + unsafe_get_user(regs->link, &sc->gp_regs[PT_LNK], efault_out);
> > + unsafe_get_user(regs->xer, &sc->gp_regs[PT_XER], efault_out);
> > + unsafe_get_user(regs->ccr, &sc->gp_regs[PT_CCR], efault_out);
> > /* Don't allow userspace to set SOFTE */
> > set_trap_norestart(regs);
> > - err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]);
> > - err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]);
> > - err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]);
> > + unsafe_get_user(regs->dar, &sc->gp_regs[PT_DAR], efault_out);
> > + unsafe_get_user(regs->dsisr, &sc->gp_regs[PT_DSISR], efault_out);
> > + unsafe_get_user(regs->result, &sc->gp_regs[PT_RESULT], efault_out);
> >
> > if (!sig)
> > regs->gpr[13] = save_r13;
> > if (set != NULL)
> > - err |= __get_user(set->sig[0], &sc->oldmask);
> > + unsafe_get_user(set->sig[0], &sc->oldmask, efault_out);
> >
> > /*
> > * Force reload of FP/VEC.
> > @@ -378,29 +379,28 @@ static long restore_sigcontext(struct task_struct *tsk, sigset_t *set, int sig,
> > regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC | MSR_VSX);
> >
> > #ifdef CONFIG_ALTIVEC
> > - err |= __get_user(v_regs, &sc->v_regs);
> > - if (err)
> > - return err;
> > + unsafe_get_user(v_regs, &sc->v_regs, efault_out);
> > if (v_regs && !access_ok(v_regs, 34 * sizeof(vector128)))
> > return -EFAULT;
> > /* Copy 33 vec registers (vr0..31 and vscr) from the stack */
> > if (v_regs != NULL && (msr & MSR_VEC) != 0) {
> > - err |= __copy_from_user(&tsk->thread.vr_state, v_regs,
> > - 33 * sizeof(vector128));
> > + unsafe_copy_from_user(&tsk->thread.vr_state, v_regs,
> > + 33 * sizeof(vector128), efault_out);
> > tsk->thread.used_vr = true;
> > } else if (tsk->thread.used_vr) {
> > memset(&tsk->thread.vr_state, 0, 33 * sizeof(vector128));
> > }
> > /* Always get VRSAVE back */
> > if (v_regs != NULL)
> > - err |= __get_user(tsk->thread.vrsave, (u32 __user *)&v_regs[33]);
> > + unsafe_get_user(tsk->thread.vrsave, (u32 __user *)&v_regs[33],
> > + efault_out);
>
> Same, would be better on a single line I think.
>
> > else
> > tsk->thread.vrsave = 0;
> > if (cpu_has_feature(CPU_FTR_ALTIVEC))
> > mtspr(SPRN_VRSAVE, tsk->thread.vrsave);
> > #endif /* CONFIG_ALTIVEC */
> > /* restore floating point */
> > - err |= copy_fpr_from_user(tsk, &sc->fp_regs);
> > + unsafe_copy_fpr_from_user(tsk, &sc->fp_regs, efault_out);
> > #ifdef CONFIG_VSX
> > /*
> > * Get additional VSX data. Update v_regs to point after the
> > @@ -409,14 +409,17 @@ static long restore_sigcontext(struct task_struct *tsk, sigset_t *set, int sig,
> > */
> > v_regs += ELF_NVRREG;
> > if ((msr & MSR_VSX) != 0) {
> > - err |= copy_vsx_from_user(tsk, v_regs);
> > + unsafe_copy_vsx_from_user(tsk, v_regs, efault_out);
> > tsk->thread.used_vsr = true;
> > } else {
> > for (i = 0; i < 32 ; i++)
> > tsk->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
> > }
> > #endif
> > - return err;
> > + return 0;
> > +
> > +efault_out:
> > + return -EFAULT;
> > }
> >
> > #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
> > @@ -707,8 +710,14 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx,
> > if (__copy_from_user(&set, &new_ctx->uc_sigmask, sizeof(set)))
> > do_exit(SIGSEGV);
> > set_current_blocked(&set);
> > - if (restore_sigcontext(current, NULL, 0, &new_ctx->uc_mcontext))
> > +
> > + if (!user_read_access_begin(new_ctx, ctx_size))
> > + return -EFAULT;
> > + if (__unsafe_restore_sigcontext(current, NULL, 0, &new_ctx->uc_mcontext)) {
> > + user_read_access_end();
> > do_exit(SIGSEGV);
> > + }
> > + user_read_access_end();
> >
> > /* This returns like rt_sigreturn */
> > set_thread_flag(TIF_RESTOREALL);
> > @@ -811,8 +820,13 @@ SYSCALL_DEFINE0(rt_sigreturn)
> > * causing a TM bad thing.
> > */
> > current->thread.regs->msr &= ~MSR_TS_MASK;
> > - if (restore_sigcontext(current, NULL, 1, &uc->uc_mcontext))
> > + if (!user_read_access_begin(&uc->uc_mcontext, sizeof(uc->uc_mcontext)))
> > + return -EFAULT;
> > + if (__unsafe_restore_sigcontext(current, NULL, 1, &uc->uc_mcontext)) {
> > + user_read_access_end();
> > goto badframe;
> > + }
> > + user_read_access_end();
> > }
> >
> > if (restore_altstack(&uc->uc_stack))
> >
^ permalink raw reply
* [PATCH 3/3] powerpc/sstep: Always test lmw and stmw
From: Jordan Niethe @ 2021-02-25 3:21 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Jordan Niethe
In-Reply-To: <20210225032108.1458352-1-jniethe5@gmail.com>
Load Multiple Word (lmw) and Store Multiple Word (stmw) will raise an
Alignment Exception:
- Little Endian mode: always
- Big Endian mode: address not word aligned
These conditions do not depend on cache inhibited memory. Test the
alignment handler emulation of these instructions regardless of if there
is cache inhibited memory available or not.
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
.../powerpc/alignment/alignment_handler.c | 96 ++++++++++++++++++-
1 file changed, 94 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/powerpc/alignment/alignment_handler.c b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
index f5eb5b85a2cf..c3003f95e043 100644
--- a/tools/testing/selftests/powerpc/alignment/alignment_handler.c
+++ b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
@@ -45,6 +45,7 @@
#include <getopt.h>
#include <setjmp.h>
#include <signal.h>
+#include <errno.h>
#include "utils.h"
#include "instructions.h"
@@ -434,7 +435,6 @@ int test_alignment_handler_integer(void)
LOAD_DFORM_TEST(ldu);
LOAD_XFORM_TEST(ldx);
LOAD_XFORM_TEST(ldux);
- LOAD_DFORM_TEST(lmw);
STORE_DFORM_TEST(stb);
STORE_XFORM_TEST(stbx);
STORE_DFORM_TEST(stbu);
@@ -453,7 +453,6 @@ int test_alignment_handler_integer(void)
STORE_XFORM_TEST(stdx);
STORE_DFORM_TEST(stdu);
STORE_XFORM_TEST(stdux);
- STORE_DFORM_TEST(stmw);
return rc;
}
@@ -599,6 +598,97 @@ int test_alignment_handler_fp_prefix(void)
return rc;
}
+int test_alignment_handler_multiple(void)
+{
+ int offset, width, r, rc = 0;
+ void *src1, *dst1, *src2, *dst2;
+
+ rc = posix_memalign(&src1, bufsize, bufsize);
+ if (rc) {
+ printf("\n");
+ return rc;
+ }
+
+ rc = posix_memalign(&dst1, bufsize, bufsize);
+ if (rc) {
+ printf("\n");
+ free(src1);
+ return rc;
+ }
+
+ src2 = malloc(bufsize);
+ if (!src2) {
+ printf("\n");
+ free(src1);
+ free(dst1);
+ return -ENOMEM;
+ }
+
+ dst2 = malloc(bufsize);
+ if (!dst2) {
+ printf("\n");
+ free(src1);
+ free(dst1);
+ free(src2);
+ return -ENOMEM;
+ }
+
+ /* lmw */
+ width = 4;
+ printf("\tDoing lmw:\t");
+ for (offset = 0; offset < width; offset++) {
+ preload_data(src1, offset, width);
+ preload_data(src2, offset, width);
+
+ asm volatile("lmw 31, 0(%0) ; std 31, 0(%1)"
+ :: "r"(src1 + offset), "r"(dst1 + offset), "r"(0)
+ : "memory", "r31");
+
+ memcpy(dst2 + offset, src1 + offset, width);
+
+ r = test_memcmp(dst1, dst2, width, offset, "test_lmw");
+ if (r && !debug) {
+ printf("FAILED: Wrong Data\n");
+ break;
+ }
+ }
+
+ if (!r)
+ printf("PASSED\n");
+ else
+ rc |= 1;
+
+ /* stmw */
+ width = 4;
+ printf("\tDoing stmw:\t");
+ for (offset = 0; offset < width; offset++) {
+ preload_data(src1, offset, width);
+ preload_data(src2, offset, width);
+
+ asm volatile("ld 31, 0(%0) ; stmw 31, 0(%1)"
+ :: "r"(src1 + offset), "r"(dst1 + offset), "r"(0)
+ : "memory", "r31");
+
+ memcpy(dst2 + offset, src1 + offset, width);
+
+ r = test_memcmp(dst1, dst2, width, offset, "test_stmw");
+ if (r && !debug) {
+ printf("FAILED: Wrong Data\n");
+ break;
+ }
+ }
+ if (!r)
+ printf("PASSED\n");
+ else
+ rc |= 1;
+
+ free(src1);
+ free(src2);
+ free(dst1);
+ free(dst2);
+ return rc;
+}
+
void usage(char *prog)
{
printf("Usage: %s [options] [path [offset]]\n", prog);
@@ -673,5 +763,7 @@ int main(int argc, char *argv[])
"test_alignment_handler_fp_206");
rc |= test_harness(test_alignment_handler_fp_prefix,
"test_alignment_handler_fp_prefix");
+ rc |= test_harness(test_alignment_handler_multiple,
+ "test_alignment_handler_multiple");
return rc;
}
--
2.25.1
^ permalink raw reply related
* [PATCH 2/3] selftests/powerpc: Suggest memtrace instead of /dev/mem for ci memory
From: Jordan Niethe @ 2021-02-25 3:21 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Jordan Niethe
In-Reply-To: <20210225032108.1458352-1-jniethe5@gmail.com>
The suggested alternative for getting cache-inhibited memory with 'mem='
and /dev/mem is pretty hacky. Also, PAPR guests do not allow system
memory to be mapped cache-inhibited so despite /dev/mem being available
this will not work which can cause confusion. Instead recommend using
the memtrace buffers. memtrace is only available on powernv so there
will not be any chance of trying to do this in a guest.
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
.../selftests/powerpc/alignment/alignment_handler.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/tools/testing/selftests/powerpc/alignment/alignment_handler.c b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
index cb53a8b777e6..f5eb5b85a2cf 100644
--- a/tools/testing/selftests/powerpc/alignment/alignment_handler.c
+++ b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
@@ -10,16 +10,7 @@
*
* We create two sets of source and destination buffers, one in regular memory,
* the other cache-inhibited (by default we use /dev/fb0 for this, but an
- * alterative path for cache-inhibited memory may be provided).
- *
- * One way to get cache-inhibited memory is to use the "mem" kernel parameter
- * to limit the kernel to less memory than actually exists. Addresses above
- * the limit may still be accessed but will be treated as cache-inhibited. For
- * example, if there is actually 4GB of memory and the parameter "mem=3GB" is
- * used, memory from address 0xC0000000 onwards is treated as cache-inhibited.
- * To access this region /dev/mem is used. The kernel should be configured
- * without CONFIG_STRICT_DEVMEM. In this case use:
- * ./alignment_handler /dev/mem 0xc0000000
+ * alterative path for cache-inhibited memory may be provided, e.g. memtrace).
*
* We initialise the source buffers, then use whichever set of load/store
* instructions is under test to copy bytes from the source buffers to the
--
2.25.1
^ permalink raw reply related
* [PATCH 1/3] powernv/memtrace: Allow mmaping trace buffers
From: Jordan Niethe @ 2021-02-25 3:21 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Jordan Niethe
Let the memory removed from the linear mapping to be used for the trace
buffers be mmaped. This is a useful way of providing cache-inhibited
memory for the alignment_handler selftest.
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
arch/powerpc/platforms/powernv/memtrace.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c
index 5fc9408bb0b3..8a1df39305e9 100644
--- a/arch/powerpc/platforms/powernv/memtrace.c
+++ b/arch/powerpc/platforms/powernv/memtrace.c
@@ -45,10 +45,26 @@ static ssize_t memtrace_read(struct file *filp, char __user *ubuf,
return simple_read_from_buffer(ubuf, count, ppos, ent->mem, ent->size);
}
+int memtrace_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct memtrace_entry *ent = filp->private_data;
+
+ if (ent->size < vma->vm_end - vma->vm_start)
+ return -EINVAL;
+
+ if (vma->vm_pgoff << PAGE_SHIFT >= ent->size)
+ return -EINVAL;
+
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return remap_pfn_range(vma, vma->vm_start, PHYS_PFN(ent->start) + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot);
+}
+
static const struct file_operations memtrace_fops = {
.llseek = default_llseek,
.read = memtrace_read,
.open = simple_open,
+ .mmap = memtrace_mmap,
};
static void memtrace_clear_range(unsigned long start_pfn,
@@ -158,7 +174,7 @@ static int memtrace_init_debugfs(void)
dir = debugfs_create_dir(ent->name, memtrace_debugfs_dir);
ent->dir = dir;
- debugfs_create_file("trace", 0400, dir, ent, &memtrace_fops);
+ debugfs_create_file_unsafe("trace", 0600, dir, ent, &memtrace_fops);
debugfs_create_x64("start", 0400, dir, &ent->start);
debugfs_create_x64("size", 0400, dir, &ent->size);
}
--
2.25.1
^ permalink raw reply related
* [PATCH] powerpc/sstep: Fix VSX instruction emulation
From: Jordan Niethe @ 2021-02-25 3:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: ravi.bangoria, Jordan Niethe, bala24
Commit af99da74333b ("powerpc/sstep: Support VSX vector paired storage
access instructions") added loading and storing 32 word long data into
adjacent VSRs. However the calculation used to determine if two VSRs
needed to be loaded/stored inadvertently prevented the load/storing
taking place for instructions with a data length less than 16 words.
This causes the emulation to not function correctly, which can be seen
by the alignment_handler selftest:
$ ./alignment_handler
[snip]
test: test_alignment_handler_vsx_207
tags: git_version:powerpc-5.12-1-0-g82d2c16b350f
VSX: 2.07B
Doing lxsspx: PASSED
Doing lxsiwax: FAILED: Wrong Data
Doing lxsiwzx: PASSED
Doing stxsspx: PASSED
Doing stxsiwx: PASSED
failure: test_alignment_handler_vsx_207
test: test_alignment_handler_vsx_300
tags: git_version:powerpc-5.12-1-0-g82d2c16b350f
VSX: 3.00B
Doing lxsd: PASSED
Doing lxsibzx: PASSED
Doing lxsihzx: PASSED
Doing lxssp: FAILED: Wrong Data
Doing lxv: PASSED
Doing lxvb16x: PASSED
Doing lxvh8x: PASSED
Doing lxvx: PASSED
Doing lxvwsx: FAILED: Wrong Data
Doing lxvl: PASSED
Doing lxvll: PASSED
Doing stxsd: PASSED
Doing stxsibx: PASSED
Doing stxsihx: PASSED
Doing stxssp: PASSED
Doing stxv: PASSED
Doing stxvb16x: PASSED
Doing stxvh8x: PASSED
Doing stxvx: PASSED
Doing stxvl: PASSED
Doing stxvll: PASSED
failure: test_alignment_handler_vsx_300
[snip]
Fix this by making sure all VSX instruction emulation correctly
load/store from the VSRs.
Fixes: af99da74333b ("powerpc/sstep: Support VSX vector paired storage access instructions")
Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
arch/powerpc/lib/sstep.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 683f7c20f74b..3953e63bbba5 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -902,7 +902,7 @@ static nokprobe_inline int do_vsx_load(struct instruction_op *op,
if (!address_ok(regs, ea, size) || copy_mem_in(mem, ea, size, regs))
return -EFAULT;
- nr_vsx_regs = size / sizeof(__vector128);
+ nr_vsx_regs = max(1ul, size / sizeof(__vector128));
emulate_vsx_load(op, buf, mem, cross_endian);
preempt_disable();
if (reg < 32) {
@@ -949,7 +949,7 @@ static nokprobe_inline int do_vsx_store(struct instruction_op *op,
if (!address_ok(regs, ea, size))
return -EFAULT;
- nr_vsx_regs = size / sizeof(__vector128);
+ nr_vsx_regs = max(1ul, size / sizeof(__vector128));
preempt_disable();
if (reg < 32) {
/* FP regs + extensions */
--
2.25.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox