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:
Binbin Wu 2020-08-04 10:42:37 +08:00 committed by wenlingz
parent 77775c9297
commit 547428021a
9 changed files with 60 additions and 6 deletions

View File

@ -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:

View File

@ -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

View File

@ -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.
*/ */
if (!is_pmu_pt_configured(vcpu->vm)) {
value32 |= VMX_PROCBASED_CTLS_RDPMC; 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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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 " \

View File

@ -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 " \