Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6c2a479 authored by Ram Pai's avatar Ram Pai Committed by Michael Ellerman
Browse files

powerpc: Handle exceptions caused by pkey violation



Handle Data and  Instruction exceptions caused by memory
protection-key.

The CPU will detect the key fault if the HPTE is already
programmed with the key.

However if the HPTE is not  hashed, a key fault will not
be detected by the hardware. The software will detect
pkey violation in such a case.

Signed-off-by: default avatarRam Pai <linuxram@us.ibm.com>
Signed-off-by: default avatarThiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 1137573a
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -312,7 +312,6 @@
				 DSISR_BAD_EXT_CTRL)
#define	  DSISR_BAD_FAULT_64S	(DSISR_BAD_FAULT_32S	| \
				 DSISR_ATTR_CONFLICT	| \
				 DSISR_KEYFAULT		| \
				 DSISR_UNSUPP_MMU	| \
				 DSISR_PRTABLE_FAULT	| \
				 DSISR_ICSWX_NO_CT	| \
+1 −1
Original line number Diff line number Diff line
@@ -1527,7 +1527,7 @@ USE_TEXT_SECTION()
	.balign	IFETCH_ALIGN_BYTES
do_hash_page:
#ifdef CONFIG_PPC_BOOK3S_64
	lis	r0,(DSISR_BAD_FAULT_64S|DSISR_DABRMATCH)@h
	lis	r0,(DSISR_BAD_FAULT_64S | DSISR_DABRMATCH | DSISR_KEYFAULT)@h
	ori	r0,r0,DSISR_BAD_FAULT_64S@l
	and.	r0,r4,r0		/* weird error? */
	bne-	handle_page_fault	/* if not, try to insert a HPTE */
+22 −0
Original line number Diff line number Diff line
@@ -427,6 +427,11 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,

	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);

	if (error_code & DSISR_KEYFAULT) {
		_exception(SIGSEGV, regs, SEGV_PKUERR, address);
		return 0;
	}

	/*
	 * We want to do this outside mmap_sem, because reading code around nip
	 * can result in fault, which will cause a deadlock when called with
@@ -498,6 +503,23 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
	 * the fault.
	 */
	fault = handle_mm_fault(vma, address, flags);

#ifdef CONFIG_PPC_MEM_KEYS
	/*
	 * if the HPTE is not hashed, hardware will not detect
	 * a key fault. Lets check if we failed because of a
	 * software detected key fault.
	 */
	if (unlikely(fault & VM_FAULT_SIGSEGV) &&
		!arch_vma_access_permitted(vma, flags & FAULT_FLAG_WRITE,
			is_exec, 0)) {
		int pkey = vma_pkey(vma);

		if (likely(pkey))
			return __bad_area(regs, address, SEGV_PKUERR);
	}
#endif /* CONFIG_PPC_MEM_KEYS */

	major |= fault & VM_FAULT_MAJOR;

	/*