[RFC PATCH 1/5] powerpc/64s/hash: convert SLB miss handlers to C

Nicholas Piggin npiggin at gmail.com
Mon Aug 20 20:08:22 AEST 2018


On Mon, 20 Aug 2018 19:41:56 +1000
Nicholas Piggin <npiggin at gmail.com> wrote:


> +long do_slb_fault(struct pt_regs *regs, unsigned long ea)
> +{
> +	unsigned long id = REGION_ID(ea);
> +
> +	/* IRQs are not reconciled here, so can't check irqs_disabled */
> +	VM_WARN_ON(mfmsr() & MSR_EE);
> +
> +	/*
> +	 * SLB kernel faults must be very careful not to touch anything
> +	 * that is not bolted. E.g., PACA and global variables are okay,
> +	 * mm->context stuff is not.
> +	 *
> +	 * SLB user faults can access all of kernel memory, but must be
> +	 * careful not to touch things like IRQ state because it is not
> +	 * "reconciled" here. The difficulty is that we must use
> +	 * fast_exception_return to return from kernel SLB faults without
> +	 * looking at possible non-bolted memory. We could test user vs
> +	 * kernel faults in the interrupt handler asm and do a full fault,
> +	 * reconcile, ret_from_except for user faults which would make them
> +	 * first class kernel code. But for performance it's probably nicer
> +	 * if they go via fast_exception_return too.
> +	 */
> +	if (id >= KERNEL_REGION_ID) {
> +		return slb_allocate_kernel(ea, id);
> +	} else {
> +		struct mm_struct *mm = current->mm;
> +
> +		if (unlikely(!mm))
> +			return -EFAULT;
>  
> -	handle_multi_context_slb_miss(context, ea);
> -	exception_exit(prev_state);
> -	return;
> +		return slb_allocate_user(mm, ea);
> +	}
> +}
>  
> -slb_bad_addr:
> +void do_bad_slb_fault(struct pt_regs *regs, unsigned long ea, long err)
> +{
>  	if (user_mode(regs))
>  		_exception(SIGSEGV, regs, SEGV_BNDERR, ea);
>  	else
>  		bad_page_fault(regs, ea, SIGSEGV);
> -	exception_exit(prev_state);
>  }

I knew I forgot something -- forgot to test MSR[RI] here. That can be
done just by returning a different error from do_slb_fault if RI is
clear, and do_bad_slb_fault will call unrecoverable_exception() if it
sees that code.

Thanks,
Nick


More information about the Linuxppc-dev mailing list