Commit e0d8e991 authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Michael Ellerman
Browse files

powerpc/book3s64/kuap: Move UAMOR setup to key init function



UAMOR values are not application-specific. The kernel initializes
its value based on different reserved keys. Remove the thread-specific
UAMOR value and don't switch the UAMOR on context switch.

Move UAMOR initialization to key initialization code and remove
thread_struct.uamor because it is not used anymore.

Before commit: 4a4a5e5d ("powerpc/pkeys: key allocation/deallocation must not change pkey registers")
we used to update uamor based on key allocation and free.

Signed-off-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200709032946.881753-20-aneesh.kumar@linux.ibm.com
parent 000a42b3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -5,6 +5,8 @@

#include <asm/book3s/64/hash-pkey.h>

extern u64 __ro_after_init default_uamor;

static inline u64 vmflag_to_pte_pkey_bits(u64 vm_flags)
{
	if (!mmu_has_feature(MMU_FTR_PKEY))
+0 −1
Original line number Diff line number Diff line
@@ -237,7 +237,6 @@ struct thread_struct {
#ifdef CONFIG_PPC_MEM_KEYS
	unsigned long	amr;
	unsigned long	iamr;
	unsigned long	uamor;
#endif
#ifdef CONFIG_KVM_BOOK3S_32_HANDLER
	void*		kvm_shadow_vcpu; /* KVM internal data */
+21 −6
Original line number Diff line number Diff line
@@ -488,14 +488,21 @@ static int pkey_active(struct task_struct *target, const struct user_regset *reg
static int pkey_get(struct task_struct *target, const struct user_regset *regset,
		    unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
{
	int ret;

	BUILD_BUG_ON(TSO(amr) + sizeof(unsigned long) != TSO(iamr));
	BUILD_BUG_ON(TSO(iamr) + sizeof(unsigned long) != TSO(uamor));

	if (!arch_pkeys_enabled())
		return -ENODEV;

	return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.amr,
				   0, ELF_NPKEY * sizeof(unsigned long));
	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.amr,
				  0, 2 * sizeof(unsigned long));
	if (ret)
		return ret;

	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &default_uamor,
				  2 * sizeof(unsigned long), 3 * sizeof(unsigned long));
	return ret;
}

static int pkey_set(struct task_struct *target, const struct user_regset *regset,
@@ -517,9 +524,17 @@ static int pkey_set(struct task_struct *target, const struct user_regset *regset
	if (ret)
		return ret;

	/* UAMOR determines which bits of the AMR can be set from userspace. */
	target->thread.amr = (new_amr & target->thread.uamor) |
			     (target->thread.amr & ~target->thread.uamor);
	/*
	 * UAMOR determines which bits of the AMR can be set from userspace.
	 * UAMOR value 0b11 indicates that the AMR value can be modified
	 * from userspace. If the kernel is using a specific key, we avoid
	 * userspace modifying the AMR value for that key by masking them
	 * via UAMOR 0b00.
	 *
	 * Pick the AMR values for the keys that kernel is using. This
	 * will be indicated by the ~default_uamor bits.
	 */
	target->thread.amr = (new_amr & default_uamor) | (target->thread.amr & ~default_uamor);

	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@
#include <asm/asm-prototypes.h>
#include <asm/cpu_has_feature.h>
#include <asm/ftrace.h>
#include <asm/kup.h>

#ifdef DEBUG
#include <asm/udbg.h>
+4 −0
Original line number Diff line number Diff line
@@ -1110,6 +1110,10 @@ void hash__early_init_mmu_secondary(void)
	if (cpu_has_feature(CPU_FTR_ARCH_206)
			&& cpu_has_feature(CPU_FTR_HVMODE))
		tlbiel_all();

#ifdef CONFIG_PPC_MEM_KEYS
	mtspr(SPRN_UAMOR, default_uamor);
#endif
}
#endif /* CONFIG_SMP */

Loading