mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	kvm: Introduce kvm_write_guest_offset_cached()
It allows us to update some status or field of a structure partially. We can also save a kvm_read_guest_cached() call if we just update one fild of the struct regardless of its current value. Signed-off-by: Pan Xinhui <xinhui.pan@linux.vnet.ibm.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Paolo Bonzini <pbonzini@redhat.com> Cc: David.Laight@ACULAB.COM Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: benh@kernel.crashing.org Cc: boqun.feng@gmail.com Cc: borntraeger@de.ibm.com Cc: bsingharora@gmail.com Cc: dave@stgolabs.net Cc: jgross@suse.com Cc: kernellwp@gmail.com Cc: konrad.wilk@oracle.com Cc: linuxppc-dev@lists.ozlabs.org Cc: mpe@ellerman.id.au Cc: paulmck@linux.vnet.ibm.com Cc: paulus@samba.org Cc: rkrcmar@redhat.com Cc: virtualization@lists.linux-foundation.org Cc: will.deacon@arm.com Cc: xen-devel-request@lists.xenproject.org Cc: xen-devel@lists.xenproject.org Link: http://lkml.kernel.org/r/1478077718-37424-8-git-send-email-xinhui.pan@linux.vnet.ibm.com [ Typo fixes. ] Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
		
							parent
							
								
									446f3dc8cc
								
							
						
					
					
						commit
						4ec6e86362
					
				
					 2 changed files with 16 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -645,6 +645,8 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data,
 | 
			
		|||
		    unsigned long len);
 | 
			
		||||
int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
 | 
			
		||||
			   void *data, unsigned long len);
 | 
			
		||||
int kvm_write_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
 | 
			
		||||
			   void *data, int offset, 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);
 | 
			
		||||
int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1972,30 +1972,38 @@ int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
 | 
			
		|||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(kvm_gfn_to_hva_cache_init);
 | 
			
		||||
 | 
			
		||||
int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
 | 
			
		||||
			   void *data, unsigned long len)
 | 
			
		||||
int kvm_write_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
 | 
			
		||||
			   void *data, int offset, unsigned long len)
 | 
			
		||||
{
 | 
			
		||||
	struct kvm_memslots *slots = kvm_memslots(kvm);
 | 
			
		||||
	int r;
 | 
			
		||||
	gpa_t gpa = ghc->gpa + offset;
 | 
			
		||||
 | 
			
		||||
	BUG_ON(len > ghc->len);
 | 
			
		||||
	BUG_ON(len + offset > ghc->len);
 | 
			
		||||
 | 
			
		||||
	if (slots->generation != ghc->generation)
 | 
			
		||||
		kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len);
 | 
			
		||||
 | 
			
		||||
	if (unlikely(!ghc->memslot))
 | 
			
		||||
		return kvm_write_guest(kvm, ghc->gpa, data, len);
 | 
			
		||||
		return kvm_write_guest(kvm, gpa, data, len);
 | 
			
		||||
 | 
			
		||||
	if (kvm_is_error_hva(ghc->hva))
 | 
			
		||||
		return -EFAULT;
 | 
			
		||||
 | 
			
		||||
	r = __copy_to_user((void __user *)ghc->hva, data, len);
 | 
			
		||||
	r = __copy_to_user((void __user *)ghc->hva + offset, data, len);
 | 
			
		||||
	if (r)
 | 
			
		||||
		return -EFAULT;
 | 
			
		||||
	mark_page_dirty_in_slot(ghc->memslot, ghc->gpa >> PAGE_SHIFT);
 | 
			
		||||
	mark_page_dirty_in_slot(ghc->memslot, gpa >> PAGE_SHIFT);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(kvm_write_guest_offset_cached);
 | 
			
		||||
 | 
			
		||||
int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
 | 
			
		||||
			   void *data, unsigned long len)
 | 
			
		||||
{
 | 
			
		||||
	return kvm_write_guest_offset_cached(kvm, ghc, data, 0, len);
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(kvm_write_guest_cached);
 | 
			
		||||
 | 
			
		||||
int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue