All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 1/2] powerpc64/dexcr: Compile kernel with privileged hash instructions
@ 2024-03-25  5:06 Benjamin Gray
  2024-03-25  5:06 ` [PATCH v1 2/2] powerpc64/dexcr: Enable PHIE on all CPUs Benjamin Gray
  0 siblings, 1 reply; 3+ messages in thread
From: Benjamin Gray @ 2024-03-25  5:06 UTC (permalink / raw
  To: linuxppc-dev; +Cc: Benjamin Gray

There are dedicated hashstp and hashchkp instructions that
can be inserted into a guest kernel to give it hypervisor
managed ROP protection (the hypervisor sets the secret hash
key and handles hashstp exceptions).

In testing, the kernel appears to handle the compiler generated
hash protection just fine, without any changes. This makes sense,
as any 'weird' stack interactions will normally be done in hand
written assembly. We can expect that a compiler generated function
prologue will be matched with a compiler generated function epilogue
with the stack as expected by the compiler (in some sense, the hash
value stored on the stack is just like any other local variable).

GCC requires ELF ABI v2, and Clang only works with ELF ABI v2
anyway, so add it as a dependency.

GCC will only insert these instructions if the target CPU is
specified to be Power10 (possibly a bug; the documentation says
they are inserted for Power8 or higher).

Signed-off-by: Benjamin Gray <bgray@linux.ibm.com>
---
 arch/powerpc/Makefile                  |  3 +++
 arch/powerpc/platforms/Kconfig.cputype | 12 ++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 65261cbe5bfd..bfaa3c754ae2 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -168,6 +168,9 @@ endif
 CFLAGS-$(CONFIG_TARGET_CPU_BOOL) += -mcpu=$(CONFIG_TARGET_CPU)
 AFLAGS-$(CONFIG_TARGET_CPU_BOOL) += -mcpu=$(CONFIG_TARGET_CPU)
 
+CFLAGS-$(CONFIG_PPC_KERNEL_ROP_PROTECT) += $(call cc-option,-mrop-protect)
+CFLAGS-$(CONFIG_PPC_KERNEL_ROP_PROTECT) += $(call cc-option,-mprivileged)
+
 CFLAGS-y += $(CONFIG_TUNE_CPU)
 
 asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1)
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index b2d8c0da2ad9..a95b11782379 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -517,6 +517,18 @@ config PPC_KUAP_DEBUG
 	  Add extra debugging for Kernel Userspace Access Protection (KUAP)
 	  If you're unsure, say N.
 
+config PPC_KERNEL_ROP_PROTECT
+	bool "Kernel ROP Protection"
+	default y
+	depends on PPC64_ELF_ABI_V2
+	depends on !CC_IS_GCC || TARGET_CPU = "power10"
+	help
+	  This tells the compiler to insert hashstp/hashckp instructions
+	  in the prologue and epilogue of every kernel function. The kernel
+	  also turns on the DEXCR[PHIE] aspect to cause an exception if the
+	  hashchkp does not agree with the hash calculated by the matching
+	  hashstp.
+
 config PPC_PKEY
 	def_bool y
 	depends on PPC_BOOK3S_64
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v1 2/2] powerpc64/dexcr: Enable PHIE on all CPUs
  2024-03-25  5:06 [PATCH v1 1/2] powerpc64/dexcr: Compile kernel with privileged hash instructions Benjamin Gray
@ 2024-03-25  5:06 ` Benjamin Gray
  2024-03-25  5:58   ` Benjamin Gray
  0 siblings, 1 reply; 3+ messages in thread
From: Benjamin Gray @ 2024-03-25  5:06 UTC (permalink / raw
  To: linuxppc-dev; +Cc: Benjamin Gray

While we can now compile the kernel with ROP
protection, it's possible the hash instructions
are acting as NOPs.

Enable the PHIE aspect at an appropriate stage in
boot so as to maximise coverage without requiring
certain functions be compiled without ROP
protection.

For the boot CPU, there are no arch defined functions
that do not return and get called before we start
spawning tasks. Therefore we insert the PHIE enablement
as a feature section after we call early_setup() where
CPU feature detection takes place.

For secondary CPUs, we can enable PHIE in
start_secondary().

Signed-off-by: Benjamin Gray <bgray@linux.ibm.com>

---

This patch is probably incompatible with the
per-task DEXCR tracking in the userspace DEXCR
series, but I'll fix up whichever one lands last.

I tested on a Power10 (TCG and KVM) and Power9.
I also tried enabling ftrace; no apparent issues,
and the trace probes were definitely triggering.

The default config enables ROP protection when
the dependencies are satisfied but perhaps we
might want to phase it in slower by disabling it?

Finally, I've tied together inserting the hash
instructions and enabling the PHIE aspect. It
might be preferable for distros to have the option
to boot without enabling PHIE for performance
comparisons. This would be with a command line
option I guess?
---
 arch/powerpc/include/asm/reg.h |  2 ++
 arch/powerpc/kernel/head_64.S  | 10 ++++++++++
 arch/powerpc/kernel/smp.c      |  6 ++++++
 3 files changed, 18 insertions(+)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index d3d1aea009b4..185807119320 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -392,6 +392,8 @@
 #define   DEXCR_PR_IBRTPD 0x10000000UL /* 3: Indirect Branch Recurrent Target Prediction Disable */
 #define   DEXCR_PR_SRAPD  0x08000000UL /* 4: Subroutine Return Address Prediction Disable */
 #define   DEXCR_PR_NPHIE  0x04000000UL /* 5: Non-Privileged Hash Instruction Enable */
+#define   DEXCR_PR_PHIE   0x02000000UL /* 6: Privileged Hash Instruction Enable */
+#define   DEXCR_PNH_PHIE  (DEXCR_PR_PHIE << 32)
 #define   DEXCR_INIT	DEXCR_PR_NPHIE	/* Fixed DEXCR value to initialise all CPUs with */
 #define SPRN_IC		0x350	/* Virtual Instruction Count */
 #define SPRN_VTB	0x351	/* Virtual Time Base */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 4690c219bfa4..490cd09dc9a4 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1011,6 +1011,16 @@ start_here_multiplatform:
 	mtctr	r12
 	bctrl		/* also sets r13 and SPRG_PACA */
 
+#ifdef CONFIG_PPC_KERNEL_ROP_PROTECT
+BEGIN_FTR_SECTION
+	mfspr	r3,SPRN_DEXCR
+	LOAD_REG_IMMEDIATE(r4,DEXCR_PNH_PHIE)
+	or	r3,r3,r4
+	mtspr	SPRN_DEXCR,r3
+	isync
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_31)
+#endif
+
 	LOAD_REG_ADDR(r3, start_here_common)
 	ld	r4,PACAKMSR(r13)
 	mtspr	SPRN_SRR0,r3
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index a60e4139214b..4a8e9f79aa0c 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -1620,6 +1620,12 @@ void start_secondary(void *unused)
 {
 	unsigned int cpu = raw_smp_processor_id();
 
+	/* Enable hash instructions on this CPU in case not already enabled by the hypervisor */
+	if (IS_ENABLED(CONFIG_PPC_KERNEL_ROP_PROTECT) && cpu_has_feature(CPU_FTR_ARCH_31)) {
+		mtspr(SPRN_DEXCR, mfspr(SPRN_DEXCR) | DEXCR_PNH_PHIE);
+		isync();
+	}
+
 	/* PPC64 calls setup_kup() in early_setup_secondary() */
 	if (IS_ENABLED(CONFIG_PPC32))
 		setup_kup();
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v1 2/2] powerpc64/dexcr: Enable PHIE on all CPUs
  2024-03-25  5:06 ` [PATCH v1 2/2] powerpc64/dexcr: Enable PHIE on all CPUs Benjamin Gray
@ 2024-03-25  5:58   ` Benjamin Gray
  0 siblings, 0 replies; 3+ messages in thread
From: Benjamin Gray @ 2024-03-25  5:58 UTC (permalink / raw
  To: linuxppc-dev

OK, so I compile for corenet64 but not corenet32 apparently. I'll fix
the shift overflow in the next round.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-03-25  5:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-25  5:06 [PATCH v1 1/2] powerpc64/dexcr: Compile kernel with privileged hash instructions Benjamin Gray
2024-03-25  5:06 ` [PATCH v1 2/2] powerpc64/dexcr: Enable PHIE on all CPUs Benjamin Gray
2024-03-25  5:58   ` Benjamin Gray

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.