Commit eed52e43 authored by Sean Christopherson's avatar Sean Christopherson Committed by Paolo Bonzini
Browse files

KVM: Allow arch code to track number of memslot address spaces per VM



Let x86 track the number of address spaces on a per-VM basis so that KVM
can disallow SMM memslots for confidential VMs.  Confidentials VMs are
fundamentally incompatible with emulating SMM, which as the name suggests
requires being able to read and write guest memory and register state.

Disallowing SMM will simplify support for guest private memory, as KVM
will not need to worry about tracking memory attributes for multiple
address spaces (SMM is the only "non-default" address space across all
architectures).

Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Reviewed-by: default avatarFuad Tabba <tabba@google.com>
Tested-by: default avatarFuad Tabba <tabba@google.com>
Message-Id: <20231027182217.3615211-23-seanjc@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 2333afa1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6084,7 +6084,7 @@ static int kvmhv_svm_off(struct kvm *kvm)
	}

	srcu_idx = srcu_read_lock(&kvm->srcu);
	for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
	for (i = 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) {
		struct kvm_memory_slot *memslot;
		struct kvm_memslots *slots = __kvm_memslots(kvm, i);
		int bkt;
+7 −1
Original line number Diff line number Diff line
@@ -2136,9 +2136,15 @@ enum {
#define HF_SMM_MASK		(1 << 1)
#define HF_SMM_INSIDE_NMI_MASK	(1 << 2)

# define KVM_ADDRESS_SPACE_NUM 2
# define KVM_MAX_NR_ADDRESS_SPACES	2
# define kvm_arch_vcpu_memslots_id(vcpu) ((vcpu)->arch.hflags & HF_SMM_MASK ? 1 : 0)
# define kvm_memslots_for_spte_role(kvm, role) __kvm_memslots(kvm, (role).smm)

static inline int kvm_arch_nr_memslot_as_ids(struct kvm *kvm)
{
	return KVM_MAX_NR_ADDRESS_SPACES;
}

#else
# define kvm_memslots_for_spte_role(kvm, role) __kvm_memslots(kvm, 0)
#endif
+1 −1
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ static int kvm_mmu_rmaps_stat_show(struct seq_file *m, void *v)
	mutex_lock(&kvm->slots_lock);
	write_lock(&kvm->mmu_lock);

	for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
	for (i = 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) {
		int bkt;

		slots = __kvm_memslots(kvm, i);
+3 −3
Original line number Diff line number Diff line
@@ -3763,7 +3763,7 @@ static int mmu_first_shadow_root_alloc(struct kvm *kvm)
	    kvm_page_track_write_tracking_enabled(kvm))
		goto out_success;

	for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
	for (i = 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) {
		slots = __kvm_memslots(kvm, i);
		kvm_for_each_memslot(slot, bkt, slots) {
			/*
@@ -6309,7 +6309,7 @@ static bool kvm_rmap_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_e
	if (!kvm_memslots_have_rmaps(kvm))
		return flush;

	for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
	for (i = 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) {
		slots = __kvm_memslots(kvm, i);

		kvm_for_each_memslot_in_gfn_range(&iter, slots, gfn_start, gfn_end) {
@@ -6806,7 +6806,7 @@ void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm, u64 gen)
	 * modifier prior to checking for a wrap of the MMIO generation so
	 * that a wrap in any address space is detected.
	 */
	gen &= ~((u64)KVM_ADDRESS_SPACE_NUM - 1);
	gen &= ~((u64)kvm_arch_nr_memslot_as_ids(kvm) - 1);

	/*
	 * The very rare case: if the MMIO generation number has wrapped,
+1 −1
Original line number Diff line number Diff line
@@ -12577,7 +12577,7 @@ void __user * __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa,
		hva = slot->userspace_addr;
	}

	for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) {
	for (i = 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) {
		struct kvm_userspace_memory_region2 m;

		m.slot = id | (i << 16);
Loading