mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-21 05:02:24 +00:00
hv: pmu: passthrough pmu to vm when GUEST_FLAG_PMU_PASSTHROUGH set
Add a new guest_flag GUEST_FLAG_PMU_PASSTHROUGH to indicate whether to passthrough Performance Monitor Unit (PMU) to a VM or not. If GUEST_FLAG_PMU_PASSTHROUGH is set for a VM, passthrough PMU. Currently, PEBS is not supported. Tracked-On: #5132 Signed-off-by: Binbin Wu <binbin.wu@intel.com>
This commit is contained in:
parent
77775c9297
commit
547428021a
@ -360,9 +360,12 @@ int32_t set_vcpuid_entries(struct acrn_vm *vm)
|
|||||||
case 0x12U:
|
case 0x12U:
|
||||||
result = set_vcpuid_sgx(vm);
|
result = set_vcpuid_sgx(vm);
|
||||||
break;
|
break;
|
||||||
/* These features are disabled */
|
|
||||||
/* PMU is not supported */
|
|
||||||
case 0x0aU:
|
case 0x0aU:
|
||||||
|
if (is_pmu_pt_configured(vm)) {
|
||||||
|
init_vcpuid_entry(i, 0U, 0U, &entry);
|
||||||
|
result = set_vcpuid_entry(vm, &entry);
|
||||||
|
}
|
||||||
|
break;
|
||||||
/* Intel RDT */
|
/* Intel RDT */
|
||||||
case 0x0fU:
|
case 0x0fU:
|
||||||
case 0x10U:
|
case 0x10U:
|
||||||
|
@ -124,6 +124,13 @@ bool is_rt_vm(const struct acrn_vm *vm)
|
|||||||
return ((vm_config->guest_flags & GUEST_FLAG_RT) != 0U);
|
return ((vm_config->guest_flags & GUEST_FLAG_RT) != 0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_pmu_pt_configured(const struct acrn_vm *vm)
|
||||||
|
{
|
||||||
|
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
|
||||||
|
|
||||||
|
return ((vm_config->guest_flags & GUEST_FLAG_PMU_PASSTHROUGH) != 0U);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief VT-d PI posted mode can possibly be used for PTDEVs assigned
|
* @brief VT-d PI posted mode can possibly be used for PTDEVs assigned
|
||||||
* to this VM if platform supports VT-d PI AND lapic passthru is not configured
|
* to this VM if platform supports VT-d PI AND lapic passthru is not configured
|
||||||
|
@ -286,7 +286,9 @@ static void init_exec_ctrl(struct acrn_vcpu *vcpu)
|
|||||||
/*
|
/*
|
||||||
* Enable VM_EXIT for rdpmc execution.
|
* Enable VM_EXIT for rdpmc execution.
|
||||||
*/
|
*/
|
||||||
value32 |= VMX_PROCBASED_CTLS_RDPMC;
|
if (!is_pmu_pt_configured(vcpu->vm)) {
|
||||||
|
value32 |= VMX_PROCBASED_CTLS_RDPMC;
|
||||||
|
}
|
||||||
|
|
||||||
exec_vmwrite32(VMX_PROC_VM_EXEC_CONTROLS, value32);
|
exec_vmwrite32(VMX_PROC_VM_EXEC_CONTROLS, value32);
|
||||||
pr_dbg("VMX_PROC_VM_EXEC_CONTROLS: 0x%x ", value32);
|
pr_dbg("VMX_PROC_VM_EXEC_CONTROLS: 0x%x ", value32);
|
||||||
|
@ -347,6 +347,43 @@ void init_msr_emulation(struct acrn_vcpu *vcpu)
|
|||||||
/* don't need to intercept rdmsr for these MSRs */
|
/* don't need to intercept rdmsr for these MSRs */
|
||||||
enable_msr_interception(msr_bitmap, MSR_IA32_TIME_STAMP_COUNTER, INTERCEPT_WRITE);
|
enable_msr_interception(msr_bitmap, MSR_IA32_TIME_STAMP_COUNTER, INTERCEPT_WRITE);
|
||||||
|
|
||||||
|
|
||||||
|
if (is_pmu_pt_configured(vcpu->vm)) {
|
||||||
|
/* Passthru PMU related MSRs to guest */
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_FIXED_CTR_CTL, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PERF_GLOBAL_CTRL, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PERF_GLOBAL_STATUS, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PERF_GLOBAL_OVF_CTRL, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PERF_GLOBAL_STATUS_SET, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PERF_GLOBAL_INUSE, INTERCEPT_DISABLE);
|
||||||
|
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_FIXED_CTR0, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_FIXED_CTR1, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_FIXED_CTR2, INTERCEPT_DISABLE);
|
||||||
|
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PMC0, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PMC1, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PMC2, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PMC3, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PMC4, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PMC5, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PMC6, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PMC7, INTERCEPT_DISABLE);
|
||||||
|
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_A_PMC0, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_A_PMC1, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_A_PMC2, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_A_PMC3, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_A_PMC4, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_A_PMC5, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_A_PMC6, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_A_PMC7, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PERFEVTSEL0, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PERFEVTSEL1, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PERFEVTSEL2, INTERCEPT_DISABLE);
|
||||||
|
enable_msr_interception(msr_bitmap, MSR_IA32_PERFEVTSEL3, INTERCEPT_DISABLE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup MSR bitmap - Intel SDM Vol3 24.6.9 */
|
/* Setup MSR bitmap - Intel SDM Vol3 24.6.9 */
|
||||||
value64 = hva2hpa(vcpu->arch.msr_bitmap);
|
value64 = hva2hpa(vcpu->arch.msr_bitmap);
|
||||||
exec_vmwrite64(VMX_MSR_BITMAP_FULL, value64);
|
exec_vmwrite64(VMX_MSR_BITMAP_FULL, value64);
|
||||||
|
@ -241,6 +241,7 @@ void vrtc_init(struct acrn_vm *vm);
|
|||||||
bool is_lapic_pt_configured(const struct acrn_vm *vm);
|
bool is_lapic_pt_configured(const struct acrn_vm *vm);
|
||||||
bool is_rt_vm(const struct acrn_vm *vm);
|
bool is_rt_vm(const struct acrn_vm *vm);
|
||||||
bool is_pi_capable(const struct acrn_vm *vm);
|
bool is_pi_capable(const struct acrn_vm *vm);
|
||||||
|
bool is_pmu_pt_configured(const struct acrn_vm *vm);
|
||||||
bool has_rt_vm(void);
|
bool has_rt_vm(void);
|
||||||
struct acrn_vm *get_highest_severity_vm(bool runtime);
|
struct acrn_vm *get_highest_severity_vm(bool runtime);
|
||||||
bool vm_hide_mtrr(const struct acrn_vm *vm);
|
bool vm_hide_mtrr(const struct acrn_vm *vm);
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#define GUEST_FLAG_IO_COMPLETION_POLLING (1UL << 2U) /* Whether need hypervisor poll IO completion */
|
#define GUEST_FLAG_IO_COMPLETION_POLLING (1UL << 2U) /* Whether need hypervisor poll IO completion */
|
||||||
#define GUEST_FLAG_HIDE_MTRR (1UL << 3U) /* Whether hide MTRR from VM */
|
#define GUEST_FLAG_HIDE_MTRR (1UL << 3U) /* Whether hide MTRR from VM */
|
||||||
#define GUEST_FLAG_RT (1UL << 4U) /* Whether the vm is RT-VM */
|
#define GUEST_FLAG_RT (1UL << 4U) /* Whether the vm is RT-VM */
|
||||||
|
#define GUEST_FLAG_PMU_PASSTHROUGH (1UL << 5U) /* Whether passthrough PMU to the VM */
|
||||||
|
|
||||||
/* TODO: We may need to get this addr from guest ACPI instead of hardcode here */
|
/* TODO: We may need to get this addr from guest ACPI instead of hardcode here */
|
||||||
#define VIRTUAL_PM1A_CNT_ADDR 0x404U
|
#define VIRTUAL_PM1A_CNT_ADDR 0x404U
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
|
|
||||||
/* Bits mask of guest flags that can be programmed by device model. Other bits are set by hypervisor only */
|
/* Bits mask of guest flags that can be programmed by device model. Other bits are set by hypervisor only */
|
||||||
#define DM_OWNED_GUEST_FLAG_MASK (GUEST_FLAG_SECURE_WORLD_ENABLED | GUEST_FLAG_LAPIC_PASSTHROUGH | \
|
#define DM_OWNED_GUEST_FLAG_MASK (GUEST_FLAG_SECURE_WORLD_ENABLED | GUEST_FLAG_LAPIC_PASSTHROUGH | \
|
||||||
GUEST_FLAG_RT | GUEST_FLAG_IO_COMPLETION_POLLING)
|
GUEST_FLAG_RT | GUEST_FLAG_IO_COMPLETION_POLLING | \
|
||||||
|
GUEST_FLAG_PMU_PASSTHROUGH)
|
||||||
|
|
||||||
/* SOS_VM_NUM can only be 0U or 1U;
|
/* SOS_VM_NUM can only be 0U or 1U;
|
||||||
* When SOS_VM_NUM is 0U, MAX_POST_VM_NUM must be 0U too;
|
* When SOS_VM_NUM is 0U, MAX_POST_VM_NUM must be 0U too;
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
|
|
||||||
/* Bits mask of guest flags that can be programmed by device model. Other bits are set by hypervisor only */
|
/* Bits mask of guest flags that can be programmed by device model. Other bits are set by hypervisor only */
|
||||||
#define DM_OWNED_GUEST_FLAG_MASK (GUEST_FLAG_SECURE_WORLD_ENABLED | GUEST_FLAG_LAPIC_PASSTHROUGH | \
|
#define DM_OWNED_GUEST_FLAG_MASK (GUEST_FLAG_SECURE_WORLD_ENABLED | GUEST_FLAG_LAPIC_PASSTHROUGH | \
|
||||||
GUEST_FLAG_RT | GUEST_FLAG_IO_COMPLETION_POLLING)
|
GUEST_FLAG_RT | GUEST_FLAG_IO_COMPLETION_POLLING | \
|
||||||
|
GUEST_FLAG_PMU_PASSTHROUGH)
|
||||||
|
|
||||||
#define SOS_VM_BOOTARGS SOS_ROOTFS \
|
#define SOS_VM_BOOTARGS SOS_ROOTFS \
|
||||||
"rw rootwait " \
|
"rw rootwait " \
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
|
|
||||||
/* Bits mask of guest flags that can be programmed by device model. Other bits are set by hypervisor only */
|
/* Bits mask of guest flags that can be programmed by device model. Other bits are set by hypervisor only */
|
||||||
#define DM_OWNED_GUEST_FLAG_MASK (GUEST_FLAG_SECURE_WORLD_ENABLED | GUEST_FLAG_LAPIC_PASSTHROUGH | \
|
#define DM_OWNED_GUEST_FLAG_MASK (GUEST_FLAG_SECURE_WORLD_ENABLED | GUEST_FLAG_LAPIC_PASSTHROUGH | \
|
||||||
GUEST_FLAG_RT | GUEST_FLAG_IO_COMPLETION_POLLING)
|
GUEST_FLAG_RT | GUEST_FLAG_IO_COMPLETION_POLLING | \
|
||||||
|
GUEST_FLAG_PMU_PASSTHROUGH)
|
||||||
|
|
||||||
#define SOS_VM_BOOTARGS SOS_ROOTFS \
|
#define SOS_VM_BOOTARGS SOS_ROOTFS \
|
||||||
"rw rootwait " \
|
"rw rootwait " \
|
||||||
|
Loading…
Reference in New Issue
Block a user