mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-04-29 04:04:05 +00:00
hv: enable thermal lvt interrupt
This patch can fetch the thermal lvt irq and propagate it to VM. At this stage we support the case that there is only one VM governing thermal. And we pass the hardware thermal irq to this VM. First, we register the handler for thermal lvt interrupt, its irq vector is THERMAL_VECTOR and the handler is thermal_irq_handler(). Then, when a thermal irq occurs, it flags the SOFTIRQ_THERMAL bit of softirq_pending, This bit triggers the thermal_softirq() function. And this function will inject the virtual thermal irq to VM. Tracked-On: #8595 Signed-off-by: Zhangwei6 <wei6.zhang@intel.com> Reviewed-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
parent
78243c3f49
commit
ddfcb8c3fc
@ -219,6 +219,7 @@ HW_C_SRCS += arch/x86/exception.c
|
||||
HW_C_SRCS += arch/x86/irq.c
|
||||
HW_C_SRCS += arch/x86/tsc.c
|
||||
HW_C_SRCS += arch/x86/tsc_deadline_timer.c
|
||||
HW_C_SRCS += arch/x86/hw_thermal.c
|
||||
HW_C_SRCS += arch/x86/vmx.c
|
||||
HW_C_SRCS += arch/x86/cpu_state_tbl.c
|
||||
HW_C_SRCS += arch/x86/pm.c
|
||||
@ -230,6 +231,7 @@ HW_C_SRCS += arch/x86/sgx.c
|
||||
HW_C_SRCS += common/ticks.c
|
||||
HW_C_SRCS += common/delay.c
|
||||
HW_C_SRCS += common/timer.c
|
||||
HW_C_SRCS += common/thermal.c
|
||||
HW_C_SRCS += common/irq.c
|
||||
HW_C_SRCS += common/softirq.c
|
||||
HW_C_SRCS += common/schedule.c
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <asm/tsc.h>
|
||||
#include <ticks.h>
|
||||
#include <delay.h>
|
||||
#include <thermal.h>
|
||||
|
||||
#define CPU_UP_TIMEOUT 100U /* millisecond */
|
||||
#define CPU_DOWN_TIMEOUT 100U /* millisecond */
|
||||
@ -268,6 +269,7 @@ void init_pcpu_post(uint16_t pcpu_id)
|
||||
init_interrupt(BSP_CPU_ID);
|
||||
|
||||
timer_init();
|
||||
thermal_init();
|
||||
setup_notification();
|
||||
setup_pi_notification();
|
||||
|
||||
@ -309,6 +311,7 @@ void init_pcpu_post(uint16_t pcpu_id)
|
||||
init_interrupt(pcpu_id);
|
||||
|
||||
timer_init();
|
||||
thermal_init();
|
||||
ptdev_init();
|
||||
}
|
||||
|
||||
|
@ -572,6 +572,16 @@ int32_t create_vcpu(uint16_t pcpu_id, struct acrn_vm *vm, struct acrn_vcpu **rtn
|
||||
*/
|
||||
vcpu->arch.vpid = ALLOCATED_MIN_L1_VPID + (vm->vm_id * MAX_VCPUS_PER_VM) + vcpu->vcpu_id;
|
||||
|
||||
/*
|
||||
* There are two locally independent writing operations, namely the
|
||||
* assignment of vcpu->vm and vcpu_array[]. Compilers may optimize
|
||||
* and reorder writing operations while users of vcpu_array[] may
|
||||
* assume the presence of vcpu->vm. A compiler barrier is added here
|
||||
* to prevent compiler reordering, ensuring that assignments to
|
||||
* vcpu->vm precede vcpu_array[].
|
||||
*/
|
||||
cpu_compiler_barrier();
|
||||
|
||||
/*
|
||||
* ACRN uses the following approach to manage VT-d PI notification vectors:
|
||||
* Allocate unique Activation Notification Vectors (ANV) for each vCPU that
|
||||
|
@ -302,6 +302,14 @@ void vcpu_inject_ss(struct acrn_vcpu *vcpu)
|
||||
(void)vcpu_queue_exception(vcpu, IDT_SS, 0);
|
||||
}
|
||||
|
||||
/* Inject thermal sensor interrupt to guest */
|
||||
void vcpu_inject_thermal_interrupt(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
if (is_vtm_configured(vcpu->vm)) {
|
||||
(void)vlapic_set_local_intr(vcpu->vm, vcpu->vcpu_id, APIC_LVT_THERMAL);
|
||||
};
|
||||
}
|
||||
|
||||
int32_t interrupt_window_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
TRACE_2L(TRACE_VMEXIT_INTERRUPT_WINDOW, 0UL, 0UL);
|
||||
|
39
hypervisor/arch/x86/hw_thermal.c
Normal file
39
hypervisor/arch/x86/hw_thermal.c
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <softirq.h>
|
||||
#include <irq.h>
|
||||
#include <logmsg.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/apicreg.h>
|
||||
#include <hw/hw_thermal.h>
|
||||
|
||||
/* run in interrupt context */
|
||||
static void thermal_irq_handler(__unused uint32_t irq, __unused void *data)
|
||||
{
|
||||
fire_softirq(SOFTIRQ_THERMAL);
|
||||
}
|
||||
|
||||
void init_hw_thermal(void)
|
||||
{
|
||||
int32_t retval = 0;
|
||||
|
||||
if (get_pcpu_id() == BSP_CPU_ID) {
|
||||
retval = request_irq(THERMAL_IRQ, thermal_irq_handler, NULL, IRQF_NONE);
|
||||
if (retval < 0) {
|
||||
pr_err("Thermal irq setup failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (retval >= 0) {
|
||||
uint32_t val = THERMAL_VECTOR;
|
||||
|
||||
msr_write(MSR_IA32_EXT_APIC_LVT_THERMAL, val);
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ static struct {
|
||||
uint32_t vector;
|
||||
} irq_static_mappings[NR_STATIC_MAPPINGS] = {
|
||||
{TIMER_IRQ, TIMER_VECTOR},
|
||||
{THERMAL_IRQ, THERMAL_VECTOR},
|
||||
{NOTIFY_VCPU_IRQ, NOTIFY_VCPU_VECTOR},
|
||||
{PMI_IRQ, PMI_VECTOR},
|
||||
|
||||
|
35
hypervisor/common/thermal.c
Normal file
35
hypervisor/common/thermal.c
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include <softirq.h>
|
||||
#include <trace.h>
|
||||
#include <asm/guest/virq.h>
|
||||
#include <hw/hw_thermal.h>
|
||||
|
||||
static void thermal_softirq(uint16_t pcpu_id)
|
||||
{
|
||||
struct acrn_vcpu *vcpu;
|
||||
uint32_t idx;
|
||||
|
||||
for (idx = 0; idx < CONFIG_MAX_VM_NUM; idx++) {
|
||||
vcpu = per_cpu(vcpu_array, pcpu_id)[idx];
|
||||
if (vcpu != NULL) {
|
||||
vcpu_inject_thermal_interrupt(vcpu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void thermal_init(void)
|
||||
{
|
||||
uint16_t pcpu_id = get_pcpu_id();
|
||||
|
||||
if (pcpu_id == BSP_CPU_ID) {
|
||||
register_softirq(SOFTIRQ_THERMAL, thermal_softirq);
|
||||
}
|
||||
|
||||
init_hw_thermal();
|
||||
}
|
@ -589,6 +589,12 @@ static inline void cpu_memory_barrier(void)
|
||||
asm volatile ("mfence\n" : : : "memory");
|
||||
}
|
||||
|
||||
/* Prevents compilers from reordering read/write access across this barrier */
|
||||
static inline void cpu_compiler_barrier(void)
|
||||
{
|
||||
asm volatile ("" : : : "memory");
|
||||
}
|
||||
|
||||
static inline void invlpg(unsigned long addr)
|
||||
{
|
||||
asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
|
||||
|
@ -90,6 +90,17 @@ void vcpu_inject_ud(struct acrn_vcpu *vcpu);
|
||||
* @pre vcpu != NULL
|
||||
*/
|
||||
void vcpu_inject_ss(struct acrn_vcpu *vcpu);
|
||||
|
||||
/**
|
||||
* @brief Inject thermal sensor interrupt to guest.
|
||||
*
|
||||
* @param[in] vcpu Pointer to vCPU.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @pre vcpu != NULL
|
||||
*/
|
||||
void vcpu_inject_thermal_interrupt(struct acrn_vcpu *vcpu);
|
||||
void vcpu_make_request(struct acrn_vcpu *vcpu, uint16_t eventid);
|
||||
|
||||
/*
|
||||
|
@ -22,7 +22,7 @@
|
||||
#define VECTOR_INVALID (NR_MAX_VECTOR + 1U)
|
||||
|
||||
/* # of NR_STATIC_MAPPINGS_1 entries for timer, vcpu notify, and PMI */
|
||||
#define NR_STATIC_MAPPINGS_1 3U
|
||||
#define NR_STATIC_MAPPINGS_1 4U
|
||||
|
||||
/*
|
||||
* The static IRQ/Vector mapping table in irq.c consists of the following entries:
|
||||
@ -53,6 +53,7 @@
|
||||
#define TIMER_VECTOR (VECTOR_FIXED_START)
|
||||
#define NOTIFY_VCPU_VECTOR (VECTOR_FIXED_START + 1U)
|
||||
#define PMI_VECTOR (VECTOR_FIXED_START + 2U)
|
||||
#define THERMAL_VECTOR (VECTOR_FIXED_START + 3U)
|
||||
/*
|
||||
* Starting vector for posted interrupts
|
||||
* # of CONFIG_MAX_VM_NUM (POSTED_INTR_VECTOR ~ (POSTED_INTR_VECTOR + CONFIG_MAX_VM_NUM - 1U))
|
||||
@ -63,6 +64,7 @@
|
||||
#define TIMER_IRQ (NR_IRQS - 1U)
|
||||
#define NOTIFY_VCPU_IRQ (NR_IRQS - 2U)
|
||||
#define PMI_IRQ (NR_IRQS - 3U)
|
||||
#define THERMAL_IRQ (NR_IRQS - 4U)
|
||||
/*
|
||||
* Starting IRQ for posted interrupts
|
||||
* # of CONFIG_MAX_VM_NUM (POSTED_INTR_IRQ ~ (POSTED_INTR_IRQ + CONFIG_MAX_VM_NUM - 1U))
|
||||
|
@ -9,7 +9,8 @@
|
||||
|
||||
#define SOFTIRQ_TIMER 0U
|
||||
#define SOFTIRQ_PTDEV 1U
|
||||
#define NR_SOFTIRQS 2U
|
||||
#define SOFTIRQ_THERMAL 2U
|
||||
#define NR_SOFTIRQS 3U
|
||||
|
||||
typedef void (*softirq_handler)(uint16_t cpu_id);
|
||||
|
||||
|
17
hypervisor/include/common/thermal.h
Normal file
17
hypervisor/include/common/thermal.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation.
|
||||
*-
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef COMMON_THERMAL_H
|
||||
#define COMMON_THERMAL_H
|
||||
|
||||
/**
|
||||
* @brief Initialize thermal.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void thermal_init(void);
|
||||
|
||||
#endif /* COMMON_THERMAL_H */
|
14
hypervisor/include/hw/hw_thermal.h
Normal file
14
hypervisor/include/hw/hw_thermal.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef HW_THERMAL_H
|
||||
#define HW_THERMAL_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
void init_hw_thermal(void);
|
||||
|
||||
#endif /* HW_THERMAL_H */
|
Loading…
Reference in New Issue
Block a user