diff mbox series

[v2,6/7] x86/power: Sprinkle some noinstr

Message ID 20230116143645.888786209@infradead.org (mailing list archive)
State New, archived
Headers show
Series x86: retbleed=stuff fixes | expand

Commit Message

Peter Zijlstra Jan. 16, 2023, 2:25 p.m. UTC
Ensure no compiler instrumentation sneaks in while restoring the CPU
state. Specifically we can't handle CALL/RET until GS is restored.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 arch/x86/power/cpu.c |   13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

Comments

Ingo Molnar Jan. 17, 2023, 9:31 a.m. UTC | #1
* Peter Zijlstra <peterz@infradead.org> wrote:

> +	/*
> +	 * Definitely wrong, but at this point we should have at least enough
> +	 * to do CALL/RET (consider SKL callthunks) and this avoids having
> +	 * to deal with the noinstr explosion for now :/
> +	 */
> +	instrumentation_begin();

BTW., readability side note: instrumentation_begin()/end() are the 
misnomers of the century - they don't signal the start/end of instrumented 
code areas like the name falsely & naively suggests, but the exact 
opposite: start/end of *non-*instrumented code areas.

As such they should probably be something like:

	noinstr_begin();
	...
	noinstr_end();

... to reuse the nomenclature of the 'noinstr' attribute?

Thanks,

	Ingo
Peter Zijlstra Jan. 17, 2023, 11:29 a.m. UTC | #2
On Tue, Jan 17, 2023 at 10:31:05AM +0100, Ingo Molnar wrote:
> 
> * Peter Zijlstra <peterz@infradead.org> wrote:
> 
> > +	/*
> > +	 * Definitely wrong, but at this point we should have at least enough
> > +	 * to do CALL/RET (consider SKL callthunks) and this avoids having
> > +	 * to deal with the noinstr explosion for now :/
> > +	 */
> > +	instrumentation_begin();
> 
> BTW., readability side note: instrumentation_begin()/end() are the 
> misnomers of the century - they don't signal the start/end of instrumented 
> code areas like the name falsely & naively suggests, but the exact 
> opposite: start/end of *non-*instrumented code areas.

Nope, they do as they say on the tin.

noinstr void foo(void)
{
}

declares the whole function as non-instrumented.

Within such functions, we demark regions where instrumentation is
allowed by:

noinstr void foo(void)
{
	instrumentation_begin();
	/* code that calls non-noinstr functions goes here */
	instrumentation_end();
}

(note the double negative in the comment)
Ingo Molnar Jan. 17, 2023, 11:54 a.m. UTC | #3
* Peter Zijlstra <peterz@infradead.org> wrote:

> Nope, they do as they say on the tin.
> 
> noinstr void foo(void)
> {
> }
> 
> declares the whole function as non-instrumented.
> 
> Within such functions, we demark regions where instrumentation is
> allowed by:
> 
> noinstr void foo(void)
> {
> 	instrumentation_begin();
> 	/* code that calls non-noinstr functions goes here */
> 	instrumentation_end();

Indeed, you are right - I should have gotten more of my morning tea ... :-/

Thanks,

	Ingo
diff mbox series

Patch

--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -192,7 +192,7 @@  static void fix_processor_context(void)
  * The asm code that gets us here will have restored a usable GDT, although
  * it will be pointing to the wrong alias.
  */
-static void notrace __restore_processor_state(struct saved_context *ctxt)
+static __always_inline void __restore_processor_state(struct saved_context *ctxt)
 {
 	struct cpuinfo_x86 *c;
 
@@ -235,6 +235,13 @@  static void notrace __restore_processor_
 	loadsegment(fs, __KERNEL_PERCPU);
 #endif
 
+	/*
+	 * Definitely wrong, but at this point we should have at least enough
+	 * to do CALL/RET (consider SKL callthunks) and this avoids having
+	 * to deal with the noinstr explosion for now :/
+	 */
+	instrumentation_begin();
+
 	/* Restore the TSS, RO GDT, LDT, and usermode-relevant MSRs. */
 	fix_processor_context();
 
@@ -276,10 +283,12 @@  static void notrace __restore_processor_
 	 * because some of the MSRs are "emulated" in microcode.
 	 */
 	msr_restore_context(ctxt);
+
+	instrumentation_end();
 }
 
 /* Needed by apm.c */
-void notrace restore_processor_state(void)
+void noinstr restore_processor_state(void)
 {
 	__restore_processor_state(&saved_context);
 }