From 5c9456462b30cd0721bf806297b0247dd2dbc33a Mon Sep 17 00:00:00 2001 From: Yifan Liu Date: Wed, 8 Dec 2021 07:46:35 +0000 Subject: [PATCH] hv && config-tool: Add compilation option to disable all interrupts in HV This patch adds an option CONFIG_KEEP_IRQ_DISABLED to hv (default n) and config-tool so that when this option is 'y', all interrupts in hv root mode will be permanently disabled. With this option to be 'y', all interrupts received in root mode will be handled in external interrupt vmexit after next VM entry. The postpone latency is negligible. This new configuration is a requirement from x86 TEE's secure/non-secure interrupt flow support. Many race conditions can be avoided when keeping IRQ off. v5: Rename CONFIG_ACRN_KEEP_IRQ_DISABLED to CONFIG_KEEP_IRQ_DISABLED v4: Change CPU_IRQ_ENABLE/DISABLE to CPU_IRQ_ENABLE_ON_CONFIG/DISABLE_ON_CONFIG and guard them using CONFIG_ACRN_KEEP_IRQ_DISABLED v3: CONFIG_ACRN_DISABLE_INTERRUPT -> CONFIG_ACRN_KEEP_IRQ_DISABLED Add more comment in commit message Tracked-On: #6571 Signed-off-by: Yifan Liu Reviewed-by: Wang, Yu1 Acked-by: Anthony Xu --- hypervisor/arch/x86/guest/vmexit.c | 4 ++-- hypervisor/arch/x86/pm.c | 4 ++-- hypervisor/common/hv_main.c | 8 ++++---- hypervisor/common/irq.c | 2 +- hypervisor/common/softirq.c | 4 ++-- hypervisor/include/arch/x86/asm/cpu.h | 22 ++++++++++++++++++---- misc/config_tools/schema/config.xsd | 5 +++++ misc/config_tools/xforms/config_common.xsl | 4 ++++ 8 files changed, 38 insertions(+), 15 deletions(-) diff --git a/hypervisor/arch/x86/guest/vmexit.c b/hypervisor/arch/x86/guest/vmexit.c index 01ec718f4..305daec83 100644 --- a/hypervisor/arch/x86/guest/vmexit.c +++ b/hypervisor/arch/x86/guest/vmexit.c @@ -279,13 +279,13 @@ int32_t vmexit_handler(struct acrn_vcpu *vcpu) if (basic_exit_reason == VMX_EXIT_REASON_EXTERNAL_INTERRUPT) { /* Handling external_interrupt should disable intr */ if (!is_lapic_pt_enabled(vcpu)) { - CPU_IRQ_DISABLE(); + CPU_IRQ_DISABLE_ON_CONFIG(); } ret = dispatch->handler(vcpu); if (!is_lapic_pt_enabled(vcpu)) { - CPU_IRQ_ENABLE(); + CPU_IRQ_ENABLE_ON_CONFIG(); } } else { ret = dispatch->handler(vcpu); diff --git a/hypervisor/arch/x86/pm.c b/hypervisor/arch/x86/pm.c index 756e6ede4..923912637 100644 --- a/hypervisor/arch/x86/pm.c +++ b/hypervisor/arch/x86/pm.c @@ -201,7 +201,7 @@ void host_enter_s3(const struct pm_s_state_data *sstate_data, uint32_t pm1a_cnt_ write_trampoline_sym(main_entry, (uint64_t)restore_s3_context); clac(); - CPU_IRQ_DISABLE(); + CPU_IRQ_DISABLE_ON_CONFIG(); vmx_off(); suspend_console(); @@ -216,7 +216,7 @@ void host_enter_s3(const struct pm_s_state_data *sstate_data, uint32_t pm1a_cnt_ resume_ioapic(); vmx_on(); - CPU_IRQ_ENABLE(); + CPU_IRQ_ENABLE_ON_CONFIG(); /* restore the default main entry */ stac(); diff --git a/hypervisor/common/hv_main.c b/hypervisor/common/hv_main.c index 08e7daf77..226d43516 100644 --- a/hypervisor/common/hv_main.c +++ b/hypervisor/common/hv_main.c @@ -22,7 +22,7 @@ void vcpu_thread(struct thread_object *obj) do { if (!is_lapic_pt_enabled(vcpu)) { - CPU_IRQ_DISABLE(); + CPU_IRQ_DISABLE_ON_CONFIG(); } /* Don't open interrupt window between here and vmentry */ @@ -59,7 +59,7 @@ void vcpu_thread(struct thread_object *obj) profiling_pre_vmexit_handler(vcpu); if (!is_lapic_pt_enabled(vcpu)) { - CPU_IRQ_ENABLE(); + CPU_IRQ_ENABLE_ON_CONFIG(); } /* Dispatch handler */ ret = vmexit_handler(vcpu); @@ -86,9 +86,9 @@ void default_idle(__unused struct thread_object *obj) } else if (need_shutdown_vm(pcpu_id)) { shutdown_vm_from_idle(pcpu_id); } else { - CPU_IRQ_ENABLE(); + CPU_IRQ_ENABLE_ON_CONFIG(); cpu_do_idle(); - CPU_IRQ_DISABLE(); + CPU_IRQ_DISABLE_ON_CONFIG(); } } } diff --git a/hypervisor/common/irq.c b/hypervisor/common/irq.c index 2a43b1534..0caac13aa 100644 --- a/hypervisor/common/irq.c +++ b/hypervisor/common/irq.c @@ -227,5 +227,5 @@ void init_interrupt(uint16_t pcpu_id) init_softirq(); } - CPU_IRQ_ENABLE(); + CPU_IRQ_ENABLE_ON_CONFIG(); } diff --git a/hypervisor/common/softirq.c b/hypervisor/common/softirq.c index 8a56f1b30..2fef825a3 100644 --- a/hypervisor/common/softirq.c +++ b/hypervisor/common/softirq.c @@ -55,9 +55,9 @@ void do_softirq(void) if (per_cpu(softirq_servicing, cpu_id) == 0U) { per_cpu(softirq_servicing, cpu_id) = 1U; - CPU_IRQ_ENABLE(); + CPU_IRQ_ENABLE_ON_CONFIG(); do_softirq_internal(cpu_id); - CPU_IRQ_DISABLE(); + CPU_IRQ_DISABLE_ON_CONFIG(); do_softirq_internal(cpu_id); per_cpu(softirq_servicing, cpu_id) = 0U; diff --git a/hypervisor/include/arch/x86/asm/cpu.h b/hypervisor/include/arch/x86/asm/cpu.h index 13c05cec2..e92216327 100644 --- a/hypervisor/include/arch/x86/asm/cpu.h +++ b/hypervisor/include/arch/x86/asm/cpu.h @@ -522,16 +522,30 @@ static inline void asm_hlt(void) } /* Disables interrupts on the current CPU */ -#define CPU_IRQ_DISABLE() \ +#ifdef CONFIG_KEEP_IRQ_DISABLED +#define CPU_IRQ_DISABLE_ON_CONFIG() do { } while (0) +#else +#define CPU_IRQ_DISABLE_ON_CONFIG() \ { \ asm volatile ("cli\n" : : : "cc"); \ } +#endif -/* Enables interrupts on the current CPU */ -#define CPU_IRQ_ENABLE() \ +/* Enables interrupts on the current CPU + * If CONFIG_KEEP_IRQ_DISABLED is 'y', all interrupts + * received in root mode will be handled in external interrupt + * vmexit after next VM entry. The postpone latency is negligible. + * Permanently turning off interrupts in root mode can be useful in + * many scenarios (e.g., x86_tee). + */ +#ifdef CONFIG_KEEP_IRQ_DISABLED +#define CPU_IRQ_ENABLE_ON_CONFIG() do { } while (0) +#else +#define CPU_IRQ_ENABLE_ON_CONFIG() \ { \ asm volatile ("sti\n" : : : "cc"); \ } +#endif /* This macro writes the stack pointer. */ static inline void cpu_sp_write(uint64_t *stack_ptr) @@ -617,7 +631,7 @@ cpu_rdtscp_execute(uint64_t *timestamp_ptr, uint32_t *cpu_id_ptr) #define CPU_INT_ALL_DISABLE(p_rflags) \ { \ CPU_RFLAGS_SAVE(p_rflags); \ - CPU_IRQ_DISABLE(); \ + CPU_IRQ_DISABLE_ON_CONFIG(); \ } /* This macro restores the architecture status / state register used to lockout diff --git a/misc/config_tools/schema/config.xsd b/misc/config_tools/schema/config.xsd index b46d778f6..74d381437 100644 --- a/misc/config_tools/schema/config.xsd +++ b/misc/config_tools/schema/config.xsd @@ -102,6 +102,11 @@ developer only. Security VM, setting this option to ``n`` + + + If ``y``, permanently disables all interrupts in HV root mode. + + Enable the Intel Resource Director Technology (RDT) diff --git a/misc/config_tools/xforms/config_common.xsl b/misc/config_tools/xforms/config_common.xsl index 5a5bd4bd8..22fe7d88b 100644 --- a/misc/config_tools/xforms/config_common.xsl +++ b/misc/config_tools/xforms/config_common.xsl @@ -81,6 +81,10 @@ + + + +