On Tue, Oct 17, 2017 at 06:44:28PM +0100, James Morse wrote:
> The Software Delegated Exception Interface (SDEI) is an ARM standard
> for registering callbacks from the platform firmware into the OS.
> This is typically used to implement RAS notifications.
> 
> Such notifications enter the kernel at the registered entry-point
> with the register values of the interrupted CPU context. Because this
> is not a CPU exception, it cannot reuse the existing entry code.
> (crucially we don't implicitly know which exception level we interrupted),
> 
> Add an sdei-entry.S asm file to set us up for calling into C code. If
> the event interrupted code that had interrupts masked, we always return
> to that location. Otherwise we pretend this was an IRQ, and use SDEI's
> complete_and_resume call to return to vbar_el1 + offset.
> 
> This allows the kernel to deliver signals to user space processes. For
> KVM this triggers the world switch, a quick spin round vcpu_run, then
> back into the guest, unless there are pending signals.
> 
> Add sdei_mask_local_cpu() calls to the smp_send_stop() code, this covers
> the panic() code-path, which doesn't invoke cpuhotplug notifiers.
> 
> Because we can interrupt entry-from/exit-to another EL, we can't trust the
> value in sp_el0 or x29, even if we interrupted the kernel, in this case
> the code in entry.S will save/restore sp_el0 and use the value in
> __entry_task.
> 
> When we have VMAP stacks we can interrupt the stack-overflow test, which
> stirs x0 into sp, meaning we have to have our own VMAP stack.
> 
> Signed-off-by: James Morse <[email protected]>

Reviewed-by: Catalin Marinas <[email protected]>

> +static __kprobes unsigned long _sdei_handler(struct pt_regs *regs,
> +                                          struct sdei_registered_event *arg)
> +{
> +     u32 mode;
> +     int i, err = 0;
> +     const int clobbered_registers = 4;
> +     u64 elr = read_sysreg(elr_el1);
> +     u32 kernel_mode = read_sysreg(CurrentEL) | 1;   /* +SPSel */
> +     unsigned long vbar = read_sysreg(vbar_el1);
> +
> +     /* Retrieve the missing registers values */
> +     for (i = 0; i < clobbered_registers; i++) {
> +             /* from within the handler, this call always succeeds */
> +             sdei_api_event_context(i, &regs->regs[i]);
> +     }
> +
> +     /*
> +      * We didn't take an exception to get here, set PAN. UAO will be cleared
> +      * by sdei_event_handler()s set_fs(USER_DS) call.
> +      */
> +     asm(ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN,
> +                     CONFIG_ARM64_PAN));

We have a similar asm in __cpu_suspend_exit(), so there's precedent. As
a separate patch (not part of this series), we should move them into
a macro, e.g. __uaccess_disable_hw_pan() (enabling as well for
consistency).

-- 
Catalin
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to