Commit cac0f1b7 authored by Steven Price's avatar Steven Price Committed by Marc Zyngier
Browse files

KVM: Implement kvm_put_guest()



kvm_put_guest() is analogous to put_user() - it writes a single value to
the guest physical address. The implementation is built upon put_user()
and so it has the same single copy atomic properties.

Signed-off-by: default avatarSteven Price <steven.price@arm.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent b48c1a45
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -746,6 +746,28 @@ int kvm_write_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
				  unsigned long len);
int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
			      gpa_t gpa, unsigned long len);

#define __kvm_put_guest(kvm, gfn, offset, value, type)			\
({									\
	unsigned long __addr = gfn_to_hva(kvm, gfn);			\
	type __user *__uaddr = (type __user *)(__addr + offset);	\
	int __ret = -EFAULT;						\
									\
	if (!kvm_is_error_hva(__addr))					\
		__ret = put_user(value, __uaddr);			\
	if (!__ret)							\
		mark_page_dirty(kvm, gfn);				\
	__ret;								\
})

#define kvm_put_guest(kvm, gpa, value, type)				\
({									\
	gpa_t __gpa = gpa;						\
	struct kvm *__kvm = kvm;					\
	__kvm_put_guest(__kvm, __gpa >> PAGE_SHIFT,			\
			offset_in_page(__gpa), (value), type);		\
})

int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len);
int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len);
struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn);