mirror of
https://github.com/torvalds/linux
synced 2024-10-04 18:33:42 +00:00
KVM VMX changes for 6.9:
- Fix a bug where KVM would report stale/bogus exit qualification information when exiting to userspace due to an unexpected VM-Exit while the CPU was vectoring an exception. - Add a VMX flag in /proc/cpuinfo to report 5-level EPT support. - Clean up the logic for massaging the passthrough MSR bitmaps when userspace changes its MSR filter. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEKTobbabEP7vbhhN9OlYIJqCjN/0FAmXrUh4ACgkQOlYIJqCj N/2CRA//VKa4KE8zgF3xM6Btyt2NegPgmGYVyhmMHTvARyHDIl5nURy++uXseb4f UXQLGcoGS+CIiaMohQFhCOjoNvv/2LR9P72qVV2WjQjFxVGBchybz8bjrqIDSSvY TuiPJApIfZtLryFFcowo8jLEBQv3JKgfgn9r2hBwVDcYP13wSz0Z4AWntHIqBxNa DW75wo7wnBFzy2RfUdtAgucpbmEihqSoKA+YjUT+0GRLBI7rWbFxdEKqe3BIM/7n 4NoJXbOmw7mlhTNumZYsF5sKiyOihBOdtUL1TDgKWjJScgmwG+KCSvrp5Ko4PZpo uyWWcIbskQ+cTO6dHDoIJTVPsCDxo3PgVJKG1T60CV68NavwxXCUGri1n1ZNyYH/ bXxEW7dTGHX0TDSt3dcyVOYdZFHbaIbqpu1EXlrzBm1hnruQ1C1uBQGHZ/X+Yo86 0qdq9SgXJ48tykr8BDruIHMy0Q8jbXxl67oXR0CdRjJGM+H9f+7RefnRN9wPYFhy n6Hl3kbezwCZb+8RO34Hq2CpKzNlKRHlJDhUq1ypd2vXPw8FDq1aQYKih0jAzyJQ yCdUueBJgo8OJtSL4HGEHvgkLHR4/XERgbCOxpSYNbqIjahAwNtbfHryUnJRWRb5 V3QczG/TtGfEpVblbRzn3Atbft4rM5a9Z3+s0siB6C2w8wyPmZg= =oJso -----END PGP SIGNATURE----- Merge tag 'kvm-x86-vmx-6.9' of https://github.com/kvm-x86/linux into HEAD KVM VMX changes for 6.9: - Fix a bug where KVM would report stale/bogus exit qualification information when exiting to userspace due to an unexpected VM-Exit while the CPU was vectoring an exception. - Add a VMX flag in /proc/cpuinfo to report 5-level EPT support. - Clean up the logic for massaging the passthrough MSR bitmaps when userspace changes its MSR filter.
This commit is contained in:
commit
b00471a552
|
@ -25,6 +25,7 @@
|
|||
#define VMX_FEATURE_EPT_EXECUTE_ONLY ( 0*32+ 17) /* "ept_x_only" EPT entries can be execute only */
|
||||
#define VMX_FEATURE_EPT_AD ( 0*32+ 18) /* EPT Accessed/Dirty bits */
|
||||
#define VMX_FEATURE_EPT_1GB ( 0*32+ 19) /* 1GB EPT pages */
|
||||
#define VMX_FEATURE_EPT_5LEVEL ( 0*32+ 20) /* 5-level EPT paging */
|
||||
|
||||
/* Aggregated APIC features 24-27 */
|
||||
#define VMX_FEATURE_FLEXPRIORITY ( 0*32+ 24) /* TPR shadow + virt APIC */
|
||||
|
|
|
@ -72,6 +72,8 @@ static void init_vmx_capabilities(struct cpuinfo_x86 *c)
|
|||
c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_AD);
|
||||
if (ept & VMX_EPT_1GB_PAGE_BIT)
|
||||
c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_1GB);
|
||||
if (ept & VMX_EPT_PAGE_WALK_5_BIT)
|
||||
c->vmx_capability[MISC_FEATURES] |= VMX_F(EPT_5LEVEL);
|
||||
|
||||
/* Synthetic APIC features that are aggregates of multiple features. */
|
||||
if ((c->vmx_capability[PRIMARY_CTLS] & VMX_F(VIRTUAL_TPR)) &&
|
||||
|
|
|
@ -161,7 +161,7 @@ module_param(allow_smaller_maxphyaddr, bool, S_IRUGO);
|
|||
|
||||
/*
|
||||
* List of MSRs that can be directly passed to the guest.
|
||||
* In addition to these x2apic and PT MSRs are handled specially.
|
||||
* In addition to these x2apic, PT and LBR MSRs are handled specially.
|
||||
*/
|
||||
static u32 vmx_possible_passthrough_msrs[MAX_POSSIBLE_PASSTHROUGH_MSRS] = {
|
||||
MSR_IA32_SPEC_CTRL,
|
||||
|
@ -669,25 +669,14 @@ static inline bool cpu_need_virtualize_apic_accesses(struct kvm_vcpu *vcpu)
|
|||
return flexpriority_enabled && lapic_in_kernel(vcpu);
|
||||
}
|
||||
|
||||
static int possible_passthrough_msr_slot(u32 msr)
|
||||
static int vmx_get_passthrough_msr_slot(u32 msr)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(vmx_possible_passthrough_msrs); i++)
|
||||
if (vmx_possible_passthrough_msrs[i] == msr)
|
||||
return i;
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static bool is_valid_passthrough_msr(u32 msr)
|
||||
{
|
||||
bool r;
|
||||
int i;
|
||||
|
||||
switch (msr) {
|
||||
case 0x800 ... 0x8ff:
|
||||
/* x2APIC MSRs. These are handled in vmx_update_msr_bitmap_x2apic() */
|
||||
return true;
|
||||
return -ENOENT;
|
||||
case MSR_IA32_RTIT_STATUS:
|
||||
case MSR_IA32_RTIT_OUTPUT_BASE:
|
||||
case MSR_IA32_RTIT_OUTPUT_MASK:
|
||||
|
@ -702,14 +691,16 @@ static bool is_valid_passthrough_msr(u32 msr)
|
|||
case MSR_LBR_CORE_FROM ... MSR_LBR_CORE_FROM + 8:
|
||||
case MSR_LBR_CORE_TO ... MSR_LBR_CORE_TO + 8:
|
||||
/* LBR MSRs. These are handled in vmx_update_intercept_for_lbr_msrs() */
|
||||
return true;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
r = possible_passthrough_msr_slot(msr) != -ENOENT;
|
||||
for (i = 0; i < ARRAY_SIZE(vmx_possible_passthrough_msrs); i++) {
|
||||
if (vmx_possible_passthrough_msrs[i] == msr)
|
||||
return i;
|
||||
}
|
||||
|
||||
WARN(!r, "Invalid MSR %x, please adapt vmx_possible_passthrough_msrs[]", msr);
|
||||
|
||||
return r;
|
||||
WARN(1, "Invalid MSR %x, please adapt vmx_possible_passthrough_msrs[]", msr);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
struct vmx_uret_msr *vmx_find_uret_msr(struct vcpu_vmx *vmx, u32 msr)
|
||||
|
@ -3963,6 +3954,7 @@ void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type)
|
|||
{
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
unsigned long *msr_bitmap = vmx->vmcs01.msr_bitmap;
|
||||
int idx;
|
||||
|
||||
if (!cpu_has_vmx_msr_bitmap())
|
||||
return;
|
||||
|
@ -3972,16 +3964,13 @@ void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type)
|
|||
/*
|
||||
* Mark the desired intercept state in shadow bitmap, this is needed
|
||||
* for resync when the MSR filters change.
|
||||
*/
|
||||
if (is_valid_passthrough_msr(msr)) {
|
||||
int idx = possible_passthrough_msr_slot(msr);
|
||||
|
||||
if (idx != -ENOENT) {
|
||||
if (type & MSR_TYPE_R)
|
||||
clear_bit(idx, vmx->shadow_msr_intercept.read);
|
||||
if (type & MSR_TYPE_W)
|
||||
clear_bit(idx, vmx->shadow_msr_intercept.write);
|
||||
}
|
||||
*/
|
||||
idx = vmx_get_passthrough_msr_slot(msr);
|
||||
if (idx >= 0) {
|
||||
if (type & MSR_TYPE_R)
|
||||
clear_bit(idx, vmx->shadow_msr_intercept.read);
|
||||
if (type & MSR_TYPE_W)
|
||||
clear_bit(idx, vmx->shadow_msr_intercept.write);
|
||||
}
|
||||
|
||||
if ((type & MSR_TYPE_R) &&
|
||||
|
@ -4007,6 +3996,7 @@ void vmx_enable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type)
|
|||
{
|
||||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
unsigned long *msr_bitmap = vmx->vmcs01.msr_bitmap;
|
||||
int idx;
|
||||
|
||||
if (!cpu_has_vmx_msr_bitmap())
|
||||
return;
|
||||
|
@ -4016,16 +4006,13 @@ void vmx_enable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type)
|
|||
/*
|
||||
* Mark the desired intercept state in shadow bitmap, this is needed
|
||||
* for resync when the MSR filter changes.
|
||||
*/
|
||||
if (is_valid_passthrough_msr(msr)) {
|
||||
int idx = possible_passthrough_msr_slot(msr);
|
||||
|
||||
if (idx != -ENOENT) {
|
||||
if (type & MSR_TYPE_R)
|
||||
set_bit(idx, vmx->shadow_msr_intercept.read);
|
||||
if (type & MSR_TYPE_W)
|
||||
set_bit(idx, vmx->shadow_msr_intercept.write);
|
||||
}
|
||||
*/
|
||||
idx = vmx_get_passthrough_msr_slot(msr);
|
||||
if (idx >= 0) {
|
||||
if (type & MSR_TYPE_R)
|
||||
set_bit(idx, vmx->shadow_msr_intercept.read);
|
||||
if (type & MSR_TYPE_W)
|
||||
set_bit(idx, vmx->shadow_msr_intercept.write);
|
||||
}
|
||||
|
||||
if (type & MSR_TYPE_R)
|
||||
|
@ -4136,6 +4123,9 @@ static void vmx_msr_filter_changed(struct kvm_vcpu *vcpu)
|
|||
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||
u32 i;
|
||||
|
||||
if (!cpu_has_vmx_msr_bitmap())
|
||||
return;
|
||||
|
||||
/*
|
||||
* Redo intercept permissions for MSRs that KVM is passing through to
|
||||
* the guest. Disabling interception will check the new MSR filter and
|
||||
|
@ -6539,7 +6529,7 @@ static int __vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
|
|||
vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_DELIVERY_EV;
|
||||
vcpu->run->internal.data[0] = vectoring_info;
|
||||
vcpu->run->internal.data[1] = exit_reason.full;
|
||||
vcpu->run->internal.data[2] = vcpu->arch.exit_qualification;
|
||||
vcpu->run->internal.data[2] = vmx_get_exit_qual(vcpu);
|
||||
if (exit_reason.basic == EXIT_REASON_EPT_MISCONFIG) {
|
||||
vcpu->run->internal.data[ndata++] =
|
||||
vmcs_read64(GUEST_PHYSICAL_ADDRESS);
|
||||
|
|
Loading…
Reference in a new issue