Commit 73232603 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge branch 'kvm-coco-hooks' into HEAD

Common patches for the target-independent functionality and hooks
that are needed by SEV-SNP and TDX.
parents 7d41e24d f32fb328
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -139,6 +139,9 @@ KVM_X86_OP(vcpu_deliver_sipi_vector)
KVM_X86_OP_OPTIONAL_RET0(vcpu_get_apicv_inhibit_reasons);
KVM_X86_OP_OPTIONAL(get_untagged_addr)
KVM_X86_OP_OPTIONAL(alloc_apic_backing_page)
KVM_X86_OP_OPTIONAL_RET0(gmem_prepare)
KVM_X86_OP_OPTIONAL_RET0(private_max_mapping_level)
KVM_X86_OP_OPTIONAL(gmem_invalidate)

#undef KVM_X86_OP
#undef KVM_X86_OP_OPTIONAL
+3 −0
Original line number Diff line number Diff line
@@ -1812,6 +1812,9 @@ struct kvm_x86_ops {

	gva_t (*get_untagged_addr)(struct kvm_vcpu *vcpu, gva_t gva, unsigned int flags);
	void *(*alloc_apic_backing_page)(struct kvm_vcpu *vcpu);
	int (*gmem_prepare)(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order);
	void (*gmem_invalidate)(kvm_pfn_t start, kvm_pfn_t end);
	int (*private_max_mapping_level)(struct kvm *kvm, kvm_pfn_t pfn);
};

struct kvm_x86_nested_ops {
+21 −2
Original line number Diff line number Diff line
@@ -4280,6 +4280,25 @@ static inline u8 kvm_max_level_for_order(int order)
	return PG_LEVEL_4K;
}

static u8 kvm_max_private_mapping_level(struct kvm *kvm, kvm_pfn_t pfn,
					u8 max_level, int gmem_order)
{
	u8 req_max_level;

	if (max_level == PG_LEVEL_4K)
		return PG_LEVEL_4K;

	max_level = min(kvm_max_level_for_order(gmem_order), max_level);
	if (max_level == PG_LEVEL_4K)
		return PG_LEVEL_4K;

	req_max_level = static_call(kvm_x86_private_max_mapping_level)(kvm, pfn);
	if (req_max_level)
		max_level = min(max_level, req_max_level);

	return req_max_level;
}

static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu,
				   struct kvm_page_fault *fault)
{
@@ -4297,9 +4316,9 @@ static int kvm_faultin_pfn_private(struct kvm_vcpu *vcpu,
		return r;
	}

	fault->max_level = min(kvm_max_level_for_order(max_order),
			       fault->max_level);
	fault->map_writable = !(fault->slot->flags & KVM_MEM_READONLY);
	fault->max_level = kvm_max_private_mapping_level(vcpu->kvm, fault->pfn,
							 fault->max_level, max_order);

	return RET_PF_CONTINUE;
}
+13 −0
Original line number Diff line number Diff line
@@ -13599,6 +13599,19 @@ bool kvm_arch_no_poll(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_GPL(kvm_arch_no_poll);

#ifdef CONFIG_HAVE_KVM_GMEM_PREPARE
int kvm_arch_gmem_prepare(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, int max_order)
{
	return static_call(kvm_x86_gmem_prepare)(kvm, pfn, gfn, max_order);
}
#endif

#ifdef CONFIG_HAVE_KVM_GMEM_INVALIDATE
void kvm_arch_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end)
{
	static_call_cond(kvm_x86_gmem_invalidate)(start, end);
}
#endif

int kvm_spec_ctrl_test_value(u64 value)
{
+36 −0
Original line number Diff line number Diff line
@@ -2441,4 +2441,40 @@ static inline int kvm_gmem_get_pfn(struct kvm *kvm,
}
#endif /* CONFIG_KVM_PRIVATE_MEM */

#ifdef CONFIG_HAVE_KVM_GMEM_PREPARE
int kvm_arch_gmem_prepare(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, int max_order);
bool kvm_arch_gmem_prepare_needed(struct kvm *kvm);
#endif

/**
 * kvm_gmem_populate() - Populate/prepare a GPA range with guest data
 *
 * @kvm: KVM instance
 * @gfn: starting GFN to be populated
 * @src: userspace-provided buffer containing data to copy into GFN range
 *       (passed to @post_populate, and incremented on each iteration
 *       if not NULL)
 * @npages: number of pages to copy from userspace-buffer
 * @post_populate: callback to issue for each gmem page that backs the GPA
 *                 range
 * @opaque: opaque data to pass to @post_populate callback
 *
 * This is primarily intended for cases where a gmem-backed GPA range needs
 * to be initialized with userspace-provided data prior to being mapped into
 * the guest as a private page. This should be called with the slots->lock
 * held so that caller-enforced invariants regarding the expected memory
 * attributes of the GPA range do not race with KVM_SET_MEMORY_ATTRIBUTES.
 *
 * Returns the number of pages that were populated.
 */
typedef int (*kvm_gmem_populate_cb)(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn,
				    void __user *src, int order, void *opaque);

long kvm_gmem_populate(struct kvm *kvm, gfn_t gfn, void __user *src, long npages,
		       kvm_gmem_populate_cb post_populate, void *opaque);

#ifdef CONFIG_HAVE_KVM_GMEM_INVALIDATE
void kvm_arch_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end);
#endif

#endif
Loading