* [PATCH 1/3] KVM: x86: add config for non-kvm users of page tracking
2021-09-21 8:10 [PATCH 0/3] KVM: x86: skip gfn_track allocation when possible David Stevens
@ 2021-09-21 8:10 ` David Stevens
2021-09-21 8:10 ` [PATCH 2/3] KVM: x86/mmu: skip page tracking when possible David Stevens
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: David Stevens @ 2021-09-21 8:10 UTC (permalink / raw)
To: kvm
Cc: Paolo Bonzini, Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li,
Jim Mattson, Joerg Roedel, David Stevens
From: David Stevens <stevensd@chromium.org>
Add a config option that allows kvm to determine whether or not there
are any external users of page tracking.
Signed-off-by: David Stevens <stevensd@chromium.org>
---
arch/x86/kvm/Kconfig | 3 +++
drivers/gpu/drm/i915/Kconfig | 1 +
2 files changed, 4 insertions(+)
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index ac69894eab88..619186138176 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -129,4 +129,7 @@ config KVM_MMU_AUDIT
This option adds a R/W kVM module parameter 'mmu_audit', which allows
auditing of KVM MMU events at runtime.
+config KVM_EXTERNAL_WRITE_TRACKING
+ bool
+
endif # VIRTUALIZATION
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index f960f5d7664e..107762427648 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -126,6 +126,7 @@ config DRM_I915_GVT_KVMGT
depends on DRM_I915_GVT
depends on KVM
depends on VFIO_MDEV
+ select KVM_EXTERNAL_WRITE_TRACKING
default n
help
Choose this option if you want to enable KVMGT support for
--
2.33.0.464.g1972c5931b-goog
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 2/3] KVM: x86/mmu: skip page tracking when possible
2021-09-21 8:10 [PATCH 0/3] KVM: x86: skip gfn_track allocation when possible David Stevens
2021-09-21 8:10 ` [PATCH 1/3] KVM: x86: add config for non-kvm users of page tracking David Stevens
@ 2021-09-21 8:10 ` David Stevens
2021-09-21 8:10 ` [PATCH 3/3] KVM: VMX: skip page tracking based on cpuid David Stevens
2021-09-21 10:27 ` [PATCH 0/3] KVM: x86: skip gfn_track allocation when possible Paolo Bonzini
3 siblings, 0 replies; 5+ messages in thread
From: David Stevens @ 2021-09-21 8:10 UTC (permalink / raw)
To: kvm
Cc: Paolo Bonzini, Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li,
Jim Mattson, Joerg Roedel, David Stevens
From: David Stevens <stevensd@chromium.org>
Skip allocating gfn_track arrays if nothing will use them, to save 2
bytes per 4kb of guest memory. This can be done when there are no
external users of page tracking (i.e. GVT-g is disabled), KVM is using
tdp, and the guest doesn't support nested virtualization.
Signed-off-by: David Stevens <stevensd@chromium.org>
---
arch/x86/include/asm/kvm-x86-ops.h | 1 +
arch/x86/include/asm/kvm_host.h | 2 ++
arch/x86/include/asm/kvm_page_track.h | 5 +++--
arch/x86/kvm/mmu/page_track.c | 25 +++++++++++++++++++++----
arch/x86/kvm/svm/svm.c | 6 ++++++
arch/x86/kvm/vmx/vmx.c | 6 ++++++
arch/x86/kvm/x86.c | 5 +++--
7 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h
index cefe1d81e2e8..99b0254305ea 100644
--- a/arch/x86/include/asm/kvm-x86-ops.h
+++ b/arch/x86/include/asm/kvm-x86-ops.h
@@ -18,6 +18,7 @@ KVM_X86_OP_NULL(hardware_unsetup)
KVM_X86_OP_NULL(cpu_has_accelerated_tpr)
KVM_X86_OP(has_emulated_msr)
KVM_X86_OP(vcpu_after_set_cpuid)
+KVM_X86_OP(nested_enabled)
KVM_X86_OP(vm_init)
KVM_X86_OP_NULL(vm_destroy)
KVM_X86_OP(vcpu_create)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index f8f48a7ec577..ba29f64d16d3 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1049,6 +1049,7 @@ struct kvm_arch {
struct list_head lpage_disallowed_mmu_pages;
struct kvm_page_track_notifier_node mmu_sp_tracker;
struct kvm_page_track_notifier_head track_notifier_head;
+ bool mmu_uses_page_tracking;
/*
* Protects marking pages unsync during page faults, as TDP MMU page
* faults only take mmu_lock for read. For simplicity, the unsync
@@ -1302,6 +1303,7 @@ struct kvm_x86_ops {
bool (*cpu_has_accelerated_tpr)(void);
bool (*has_emulated_msr)(struct kvm *kvm, u32 index);
void (*vcpu_after_set_cpuid)(struct kvm_vcpu *vcpu);
+ bool (*nested_enabled)(void);
unsigned int vm_size;
int (*vm_init)(struct kvm *kvm);
diff --git a/arch/x86/include/asm/kvm_page_track.h b/arch/x86/include/asm/kvm_page_track.h
index 87bd6025d91d..92e9e2c74219 100644
--- a/arch/x86/include/asm/kvm_page_track.h
+++ b/arch/x86/include/asm/kvm_page_track.h
@@ -46,11 +46,12 @@ struct kvm_page_track_notifier_node {
struct kvm_page_track_notifier_node *node);
};
-void kvm_page_track_init(struct kvm *kvm);
+void kvm_page_track_init(struct kvm *kvm, bool mmu_uses_page_tracking);
void kvm_page_track_cleanup(struct kvm *kvm);
void kvm_page_track_free_memslot(struct kvm_memory_slot *slot);
-int kvm_page_track_create_memslot(struct kvm_memory_slot *slot,
+int kvm_page_track_create_memslot(struct kvm *kvm,
+ struct kvm_memory_slot *slot,
unsigned long npages);
void kvm_slot_page_track_add_page(struct kvm *kvm,
diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c
index 269f11f92fd0..c553bc09d50a 100644
--- a/arch/x86/kvm/mmu/page_track.c
+++ b/arch/x86/kvm/mmu/page_track.c
@@ -29,11 +29,16 @@ void kvm_page_track_free_memslot(struct kvm_memory_slot *slot)
}
}
-int kvm_page_track_create_memslot(struct kvm_memory_slot *slot,
+int kvm_page_track_create_memslot(struct kvm *kvm,
+ struct kvm_memory_slot *slot,
unsigned long npages)
{
int i;
+ if (!IS_ENABLED(CONFIG_KVM_EXTERNAL_WRITE_TRACKING) &&
+ !kvm->arch.mmu_uses_page_tracking)
+ return 0;
+
for (i = 0; i < KVM_PAGE_TRACK_MAX; i++) {
slot->arch.gfn_track[i] =
kvcalloc(npages, sizeof(*slot->arch.gfn_track[i]),
@@ -61,10 +66,15 @@ static void update_gfn_track(struct kvm_memory_slot *slot, gfn_t gfn,
enum kvm_page_track_mode mode, short count)
{
int index, val;
+ unsigned short *arr;
+
+ arr = slot->arch.gfn_track[mode];
+ if (WARN_ON(!arr))
+ return;
index = gfn_to_index(gfn, slot->base_gfn, PG_LEVEL_4K);
- val = slot->arch.gfn_track[mode][index];
+ val = arr[index];
if (WARN_ON(val + count < 0 || val + count > USHRT_MAX))
return;
@@ -143,6 +153,7 @@ bool kvm_page_track_is_active(struct kvm_vcpu *vcpu, gfn_t gfn,
enum kvm_page_track_mode mode)
{
struct kvm_memory_slot *slot;
+ unsigned short *arr;
int index;
if (WARN_ON(!page_track_mode_is_valid(mode)))
@@ -152,8 +163,12 @@ bool kvm_page_track_is_active(struct kvm_vcpu *vcpu, gfn_t gfn,
if (!slot)
return false;
+ arr = slot->arch.gfn_track[mode];
+ if (!arr)
+ return false;
+
index = gfn_to_index(gfn, slot->base_gfn, PG_LEVEL_4K);
- return !!READ_ONCE(slot->arch.gfn_track[mode][index]);
+ return !!READ_ONCE(arr[index]);
}
void kvm_page_track_cleanup(struct kvm *kvm)
@@ -164,13 +179,15 @@ void kvm_page_track_cleanup(struct kvm *kvm)
cleanup_srcu_struct(&head->track_srcu);
}
-void kvm_page_track_init(struct kvm *kvm)
+void kvm_page_track_init(struct kvm *kvm, bool mmu_uses_page_tracking)
{
struct kvm_page_track_notifier_head *head;
head = &kvm->arch.track_notifier_head;
init_srcu_struct(&head->track_srcu);
INIT_HLIST_HEAD(&head->track_notifier_list);
+
+ kvm->arch.mmu_uses_page_tracking = mmu_uses_page_tracking;
}
/*
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 1a70e11f0487..bcc8f887d3bd 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -4049,6 +4049,11 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
}
}
+static bool svm_nested_enabled(void)
+{
+ return nested;
+}
+
static bool svm_has_wbinvd_exit(void)
{
return true;
@@ -4590,6 +4595,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = {
.get_exit_info = svm_get_exit_info,
.vcpu_after_set_cpuid = svm_vcpu_after_set_cpuid,
+ .nested_enabled = svm_nested_enabled,
.has_wbinvd_exit = svm_has_wbinvd_exit,
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 0c2c0d5ae873..1b21ed01e837 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7225,6 +7225,11 @@ static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
vmx_update_exception_bitmap(vcpu);
}
+static bool vmx_nested_enabled(void)
+{
+ return nested;
+}
+
static __init void vmx_set_cpu_caps(void)
{
kvm_set_cpu_caps();
@@ -7637,6 +7642,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
.get_exit_info = vmx_get_exit_info,
.vcpu_after_set_cpuid = vmx_vcpu_after_set_cpuid,
+ .nested_enabled = vmx_nested_enabled,
.has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 28ef14155726..cc47571a148a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -11174,7 +11174,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
kvm_apicv_init(kvm);
kvm_hv_init_vm(kvm);
- kvm_page_track_init(kvm);
+ kvm_page_track_init(kvm, !tdp_enabled ||
+ static_call(kvm_x86_nested_enabled));
kvm_mmu_init_vm(kvm);
kvm_xen_init_vm(kvm);
@@ -11474,7 +11475,7 @@ static int kvm_alloc_memslot_metadata(struct kvm *kvm,
}
}
- if (kvm_page_track_create_memslot(slot, npages))
+ if (kvm_page_track_create_memslot(kvm, slot, npages))
goto out_free;
return 0;
--
2.33.0.464.g1972c5931b-goog
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 3/3] KVM: VMX: skip page tracking based on cpuid
2021-09-21 8:10 [PATCH 0/3] KVM: x86: skip gfn_track allocation when possible David Stevens
2021-09-21 8:10 ` [PATCH 1/3] KVM: x86: add config for non-kvm users of page tracking David Stevens
2021-09-21 8:10 ` [PATCH 2/3] KVM: x86/mmu: skip page tracking when possible David Stevens
@ 2021-09-21 8:10 ` David Stevens
2021-09-21 10:27 ` [PATCH 0/3] KVM: x86: skip gfn_track allocation when possible Paolo Bonzini
3 siblings, 0 replies; 5+ messages in thread
From: David Stevens @ 2021-09-21 8:10 UTC (permalink / raw)
To: kvm
Cc: Paolo Bonzini, Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li,
Jim Mattson, Joerg Roedel, David Stevens
From: David Stevens <stevensd@chromium.org>
Consider X86_FEATURE_VMX when determining whether or not page tracking
is necessary, since that flag can be used to control whether or not a
particular guest supports nested virtualization. When the flag is
toggled, it is necessary to free/allocate gfn_track arrays for any
already existing slots.
If cpuid is heterogeneous or is modified after KVM_RUN, page tracking
may not work properly. This may cause guest instability, as per the
caveat on KVM_SET_CPUID{,2}. Host stability should not be affected.
Signed-off-by: David Stevens <stevensd@chromium.org>
---
arch/x86/include/asm/kvm_host.h | 2 +-
arch/x86/include/asm/kvm_page_track.h | 2 +
arch/x86/kvm/cpuid.c | 55 +++++++++++++++++++++------
arch/x86/kvm/mmu/page_track.c | 49 ++++++++++++++++++++++++
arch/x86/kvm/svm/svm.c | 4 +-
arch/x86/kvm/vmx/vmx.c | 7 +++-
6 files changed, 104 insertions(+), 15 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index ba29f64d16d3..dc732ac0eb56 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1302,7 +1302,7 @@ struct kvm_x86_ops {
void (*hardware_unsetup)(void);
bool (*cpu_has_accelerated_tpr)(void);
bool (*has_emulated_msr)(struct kvm *kvm, u32 index);
- void (*vcpu_after_set_cpuid)(struct kvm_vcpu *vcpu);
+ int (*vcpu_after_set_cpuid)(struct kvm_vcpu *vcpu);
bool (*nested_enabled)(void);
unsigned int vm_size;
diff --git a/arch/x86/include/asm/kvm_page_track.h b/arch/x86/include/asm/kvm_page_track.h
index 92e9e2c74219..f917cea1b4b1 100644
--- a/arch/x86/include/asm/kvm_page_track.h
+++ b/arch/x86/include/asm/kvm_page_track.h
@@ -49,6 +49,8 @@ struct kvm_page_track_notifier_node {
void kvm_page_track_init(struct kvm *kvm, bool mmu_uses_page_tracking);
void kvm_page_track_cleanup(struct kvm *kvm);
+int kvm_page_tracking_mmu_enable(struct kvm *kvm, bool enable);
+
void kvm_page_track_free_memslot(struct kvm_memory_slot *slot);
int kvm_page_track_create_memslot(struct kvm *kvm,
struct kvm_memory_slot *slot,
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 739be5da3bca..fb011b0e76e6 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -150,10 +150,11 @@ void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_GPL(kvm_update_cpuid_runtime);
-static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
+static int kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
{
struct kvm_lapic *apic = vcpu->arch.apic;
struct kvm_cpuid_entry2 *best;
+ int ret;
best = kvm_find_cpuid_entry(vcpu, 1, 0);
if (best && apic) {
@@ -198,14 +199,20 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
kvm_hv_set_cpuid(vcpu);
- /* Invoke the vendor callback only after the above state is updated. */
- static_call(kvm_x86_vcpu_after_set_cpuid)(vcpu);
+ /*
+ * Invoke the vendor callback only after the above state is updated. If
+ * it fails, continue the function and let the caller roll back to the
+ * previous cpuid.
+ */
+ ret = static_call(kvm_x86_vcpu_after_set_cpuid)(vcpu);
/*
* Except for the MMU, which needs to do its thing any vendor specific
* adjustments to the reserved GPA bits.
*/
kvm_mmu_after_set_cpuid(vcpu);
+
+ return ret;
}
static int is_efer_nx(void)
@@ -261,9 +268,9 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
struct kvm_cpuid *cpuid,
struct kvm_cpuid_entry __user *entries)
{
- int r, i;
+ int r, i, orig_nent;
struct kvm_cpuid_entry *e = NULL;
- struct kvm_cpuid_entry2 *e2 = NULL;
+ struct kvm_cpuid_entry2 *e2 = NULL, *orig_e2;
if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
return -E2BIG;
@@ -298,13 +305,25 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
goto out_free_cpuid;
}
- kvfree(vcpu->arch.cpuid_entries);
+ orig_e2 = vcpu->arch.cpuid_entries;
+ orig_nent = vcpu->arch.cpuid_nent;
+
vcpu->arch.cpuid_entries = e2;
vcpu->arch.cpuid_nent = cpuid->nent;
cpuid_fix_nx_cap(vcpu);
kvm_update_cpuid_runtime(vcpu);
- kvm_vcpu_after_set_cpuid(vcpu);
+ r = kvm_vcpu_after_set_cpuid(vcpu);
+
+ if (!r) {
+ kvfree(orig_e2);
+ } else {
+ kvfree(e2);
+ vcpu->arch.cpuid_entries = orig_e2;
+ vcpu->arch.cpuid_nent = orig_nent;
+ kvm_update_cpuid_runtime(vcpu);
+ kvm_vcpu_after_set_cpuid(vcpu);
+ }
out_free_cpuid:
kvfree(e);
@@ -316,8 +335,8 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
struct kvm_cpuid2 *cpuid,
struct kvm_cpuid_entry2 __user *entries)
{
- struct kvm_cpuid_entry2 *e2 = NULL;
- int r;
+ struct kvm_cpuid_entry2 *e2 = NULL, *orig_e2;
+ int r, orig_nent;
if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
return -E2BIG;
@@ -334,14 +353,26 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
return r;
}
- kvfree(vcpu->arch.cpuid_entries);
+ orig_e2 = vcpu->arch.cpuid_entries;
+ orig_nent = vcpu->arch.cpuid_nent;
+
vcpu->arch.cpuid_entries = e2;
vcpu->arch.cpuid_nent = cpuid->nent;
kvm_update_cpuid_runtime(vcpu);
- kvm_vcpu_after_set_cpuid(vcpu);
+ r = kvm_vcpu_after_set_cpuid(vcpu);
- return 0;
+ if (!r) {
+ kvfree(orig_e2);
+ } else {
+ kvfree(e2);
+ vcpu->arch.cpuid_entries = orig_e2;
+ vcpu->arch.cpuid_nent = orig_nent;
+ kvm_update_cpuid_runtime(vcpu);
+ kvm_vcpu_after_set_cpuid(vcpu);
+ }
+
+ return r;
}
int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c
index c553bc09d50a..e4d0e6ad2178 100644
--- a/arch/x86/kvm/mmu/page_track.c
+++ b/arch/x86/kvm/mmu/page_track.c
@@ -19,6 +19,55 @@
#include "mmu.h"
#include "mmu_internal.h"
+int kvm_page_tracking_mmu_enable(struct kvm *kvm, bool enable)
+{
+ struct kvm_memslots *slots;
+ struct kvm_memory_slot *s;
+ unsigned short **gfn_track, *buf;
+ int i, ret = 0;
+
+ if (IS_ENABLED(CONFIG_KVM_EXTERNAL_WRITE_TRACKING))
+ return 0;
+
+ mutex_lock(&kvm->slots_lock);
+
+ if (enable == kvm->arch.mmu_uses_page_tracking) {
+ mutex_unlock(&kvm->slots_lock);
+ return 0;
+ }
+
+ for (i = 0; enable && i < KVM_ADDRESS_SPACE_NUM && !ret; i++) {
+ slots = __kvm_memslots(kvm, i);
+ kvm_for_each_memslot(s, slots) {
+ gfn_track = s->arch.gfn_track + KVM_PAGE_TRACK_WRITE;
+ *gfn_track = kvcalloc(s->npages, sizeof(*gfn_track),
+ GFP_KERNEL_ACCOUNT);
+ if (!*gfn_track) {
+ ret = -ENOMEM;
+ break;
+ }
+ }
+ }
+
+ for (i = 0; (!enable || !ret) && i < KVM_ADDRESS_SPACE_NUM; i++) {
+ slots = __kvm_memslots(kvm, i);
+ kvm_for_each_memslot(s, slots) {
+ gfn_track = s->arch.gfn_track + KVM_PAGE_TRACK_WRITE;
+ buf = *gfn_track;
+ *gfn_track = NULL;
+ synchronize_srcu(&kvm->srcu);
+ kvfree(buf);
+ }
+ }
+
+ if (!ret)
+ kvm->arch.mmu_uses_page_tracking = enable;
+
+ mutex_unlock(&kvm->slots_lock);
+
+ return ret;
+}
+
void kvm_page_track_free_memslot(struct kvm_memory_slot *slot)
{
int i;
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index bcc8f887d3bd..af904e9f4be9 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -3981,7 +3981,7 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
return 0;
}
-static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
+static int svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
struct kvm_cpuid_entry2 *best;
@@ -4047,6 +4047,8 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
set_msr_interception(vcpu, svm->msrpm, MSR_IA32_SYSENTER_EIP, 1, 1);
set_msr_interception(vcpu, svm->msrpm, MSR_IA32_SYSENTER_ESP, 1, 1);
}
+
+ return 0;
}
static bool svm_nested_enabled(void)
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 1b21ed01e837..6455759907d1 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7166,7 +7166,7 @@ static void update_intel_pt_cfg(struct kvm_vcpu *vcpu)
vmx->pt_desc.ctl_bitmask &= ~(0xfULL << (32 + i * 4));
}
-static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
+static int vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -7223,6 +7223,11 @@ static void vmx_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
/* Refresh #PF interception to account for MAXPHYADDR changes. */
vmx_update_exception_bitmap(vcpu);
+
+ if (tdp_enabled)
+ return kvm_page_tracking_mmu_enable(vcpu->kvm,
+ nested_vmx_allowed(vcpu));
+ return 0;
}
static bool vmx_nested_enabled(void)
--
2.33.0.464.g1972c5931b-goog
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH 0/3] KVM: x86: skip gfn_track allocation when possible
2021-09-21 8:10 [PATCH 0/3] KVM: x86: skip gfn_track allocation when possible David Stevens
` (2 preceding siblings ...)
2021-09-21 8:10 ` [PATCH 3/3] KVM: VMX: skip page tracking based on cpuid David Stevens
@ 2021-09-21 10:27 ` Paolo Bonzini
3 siblings, 0 replies; 5+ messages in thread
From: Paolo Bonzini @ 2021-09-21 10:27 UTC (permalink / raw)
To: David Stevens, kvm
Cc: Sean Christopherson, Vitaly Kuznetsov, Wanpeng Li, Jim Mattson,
Joerg Roedel
On 21/09/21 10:10, David Stevens wrote:
> This straightforward approach has the downside that for VMs where nested
> virtualization is enabled but never used, gfn_track arrays are still
> allocated. Instead of going so far as to try to initialize things on
> demand, key off of whether or not X86_FEATURE_VMX is set in the guest's
> cpuid to support per-VM configuration instead of system wide
> configuration based on the nested module param.
Can you allocate it lazily like we do for the rmap?
Paolo
^ permalink raw reply [flat|nested] 5+ messages in thread