Message ID | 20210323203946.2159693-12-samitolvanen@google.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Add support for Clang CFI | expand |
On Tue, Mar 23, 2021 at 01:39:40PM -0700, Sami Tolvanen wrote: > With CONFIG_CFI_CLANG, the compiler replaces function pointers with > jump table addresses, which results in __pa_symbol returning the > physical address of the jump table entry. As the jump table contains > an immediate jump to an EL1 virtual address, this typically won't > work as intended. Use __pa_function instead to get the address to > cpu_resume. > > Signed-off-by: Sami Tolvanen <samitolvanen@google.com> > Reviewed-by: Kees Cook <keescook@chromium.org> > --- > drivers/firmware/psci/psci.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c > index f5fc429cae3f..facd3cce3244 100644 > --- a/drivers/firmware/psci/psci.c > +++ b/drivers/firmware/psci/psci.c > @@ -326,7 +326,7 @@ static int psci_suspend_finisher(unsigned long state) > { > u32 power_state = state; > > - return psci_ops.cpu_suspend(power_state, __pa_symbol(cpu_resume)); > + return psci_ops.cpu_suspend(power_state, __pa_function(cpu_resume)); As mentioned on the patch adding __pa_function(), I'd prefer to keep the whatever->phys conversion separate from the CFI removal, since we have a number of distinct virtual address ranges with differing conversions to phys, and I don't think it's clear that __pa_function() only works for kernel symbols (rather than module addresses, linear map addresses, etc). Other than that, I'm happy in principle with wrapping this. I suspect that for clarity we should add an intermediate variable, e.g. | phys_addr_t pa_cpu_resume = pa_symbol(function_nocfi(cpu_resume)); | return psci_ops.cpu_suspend(power_state, pa_cpu_resume) Thanks, Mark. > } > > int psci_cpu_suspend_enter(u32 state) > @@ -345,7 +345,7 @@ int psci_cpu_suspend_enter(u32 state) > static int psci_system_suspend(unsigned long unused) > { > return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), > - __pa_symbol(cpu_resume), 0, 0); > + __pa_function(cpu_resume), 0, 0); > } > > static int psci_system_suspend_enter(suspend_state_t state) > -- > 2.31.0.291.g576ba9dcdaf-goog >
diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c index f5fc429cae3f..facd3cce3244 100644 --- a/drivers/firmware/psci/psci.c +++ b/drivers/firmware/psci/psci.c @@ -326,7 +326,7 @@ static int psci_suspend_finisher(unsigned long state) { u32 power_state = state; - return psci_ops.cpu_suspend(power_state, __pa_symbol(cpu_resume)); + return psci_ops.cpu_suspend(power_state, __pa_function(cpu_resume)); } int psci_cpu_suspend_enter(u32 state) @@ -345,7 +345,7 @@ int psci_cpu_suspend_enter(u32 state) static int psci_system_suspend(unsigned long unused) { return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), - __pa_symbol(cpu_resume), 0, 0); + __pa_function(cpu_resume), 0, 0); } static int psci_system_suspend_enter(suspend_state_t state)