[v5,05/34] x86/traps: export external_interrupt() for VMX IRQ reinjection

Message ID 20230307023946.14516-6-xin3.li@intel.com
State New
Headers
Series x86: enable FRED for x86-64 |

Commit Message

Li, Xin3 March 7, 2023, 2:39 a.m. UTC
  To eliminate dispatching IRQ through the IDT, export external_interrupt()
for VMX IRQ reinjection.

Tested-by: Shan Kang <shan.kang@intel.com>
Signed-off-by: Xin Li <xin3.li@intel.com>
---
 arch/x86/include/asm/traps.h |  2 ++
 arch/x86/kernel/traps.c      | 14 ++++++++++++++
 2 files changed, 16 insertions(+)
  

Comments

Sean Christopherson March 22, 2023, 5:52 p.m. UTC | #1
On Mon, Mar 06, 2023, Xin Li wrote:
> To eliminate dispatching IRQ through the IDT, export external_interrupt()
> for VMX IRQ reinjection.
> 
> Tested-by: Shan Kang <shan.kang@intel.com>
> Signed-off-by: Xin Li <xin3.li@intel.com>
> ---
>  arch/x86/include/asm/traps.h |  2 ++
>  arch/x86/kernel/traps.c      | 14 ++++++++++++++
>  2 files changed, 16 insertions(+)
> 
> diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
> index 46f5e4e2a346..da4c21ed68b4 100644
> --- a/arch/x86/include/asm/traps.h
> +++ b/arch/x86/include/asm/traps.h
> @@ -56,4 +56,6 @@ void __noreturn handle_stack_overflow(struct pt_regs *regs,
>  	void f (struct pt_regs *regs)
>  typedef DECLARE_SYSTEM_INTERRUPT_HANDLER((*system_interrupt_handler));
>  
> +int external_interrupt(struct pt_regs *regs, unsigned int vector);
> +
>  #endif /* _ASM_X86_TRAPS_H */
> diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
> index 31ad645be2fb..cebba1f49e19 100644
> --- a/arch/x86/kernel/traps.c
> +++ b/arch/x86/kernel/traps.c
> @@ -1540,6 +1540,20 @@ int external_interrupt(struct pt_regs *regs, unsigned int vector)
>  	return 0;
>  }
>  
> +#if IS_ENABLED(CONFIG_KVM_INTEL)
> +/*
> + * KVM VMX reinjects IRQ on its current stack, it's a sync call
> + * thus the values in the pt_regs structure are not used in
> + * executing IRQ handlers, except cs.RPL and flags.IF, which
> + * are both always 0 in the VMX IRQ reinjection context.
> + *
> + * However, the pt_regs structure is sometimes used in stack
> + * dump, e.g., show_regs(). So let the caller, i.e., KVM VMX
> + * decide how to initialize the input pt_regs structure.
> + */
> +EXPORT_SYMBOL_GPL(external_interrupt);
> +#endif

If the x86 maintainers don't object, I would prefer this to be squashed with the
actual KVM usage, that way discussions on exactly what the exported API should be
can be contained in a single thread.
  
Li, Xin3 March 22, 2023, 10:38 p.m. UTC | #2
> > +#if IS_ENABLED(CONFIG_KVM_INTEL)
> > +/*
> > + * KVM VMX reinjects IRQ on its current stack, it's a sync call
> > + * thus the values in the pt_regs structure are not used in
> > + * executing IRQ handlers, except cs.RPL and flags.IF, which
> > + * are both always 0 in the VMX IRQ reinjection context.
> > + *
> > + * However, the pt_regs structure is sometimes used in stack
> > + * dump, e.g., show_regs(). So let the caller, i.e., KVM VMX
> > + * decide how to initialize the input pt_regs structure.
> > + */
> > +EXPORT_SYMBOL_GPL(external_interrupt);
> > +#endif
> 
> If the x86 maintainers don't object, I would prefer this to be squashed with the
> actual KVM usage, that way discussions on exactly what the exported API should be
> can be contained in a single thread.

The KVM usage is the only one now, thus it does make sense to squash into one.

I'm working on v6 and will merge this patch into the corresponding KVM patch.
BTW, I will stop using "reinject" as asked.
  

Patch

diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index 46f5e4e2a346..da4c21ed68b4 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -56,4 +56,6 @@  void __noreturn handle_stack_overflow(struct pt_regs *regs,
 	void f (struct pt_regs *regs)
 typedef DECLARE_SYSTEM_INTERRUPT_HANDLER((*system_interrupt_handler));
 
+int external_interrupt(struct pt_regs *regs, unsigned int vector);
+
 #endif /* _ASM_X86_TRAPS_H */
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 31ad645be2fb..cebba1f49e19 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -1540,6 +1540,20 @@  int external_interrupt(struct pt_regs *regs, unsigned int vector)
 	return 0;
 }
 
+#if IS_ENABLED(CONFIG_KVM_INTEL)
+/*
+ * KVM VMX reinjects IRQ on its current stack, it's a sync call
+ * thus the values in the pt_regs structure are not used in
+ * executing IRQ handlers, except cs.RPL and flags.IF, which
+ * are both always 0 in the VMX IRQ reinjection context.
+ *
+ * However, the pt_regs structure is sometimes used in stack
+ * dump, e.g., show_regs(). So let the caller, i.e., KVM VMX
+ * decide how to initialize the input pt_regs structure.
+ */
+EXPORT_SYMBOL_GPL(external_interrupt);
+#endif
+
 void __init trap_init(void)
 {
 	/* Init cpu_entry_area before IST entries are set up */