diff options
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r-- | virt/kvm/kvm_main.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 678e80561b74..8d0b7c16c2f7 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -541,6 +541,26 @@ int kvm_read_guest(struct kvm *kvm, gpa_t gpa, void *data, unsigned long len) | |||
541 | } | 541 | } |
542 | EXPORT_SYMBOL_GPL(kvm_read_guest); | 542 | EXPORT_SYMBOL_GPL(kvm_read_guest); |
543 | 543 | ||
544 | int kvm_read_guest_atomic(struct kvm *kvm, gpa_t gpa, void *data, | ||
545 | unsigned long len) | ||
546 | { | ||
547 | int r; | ||
548 | unsigned long addr; | ||
549 | gfn_t gfn = gpa >> PAGE_SHIFT; | ||
550 | int offset = offset_in_page(gpa); | ||
551 | |||
552 | addr = gfn_to_hva(kvm, gfn); | ||
553 | if (kvm_is_error_hva(addr)) | ||
554 | return -EFAULT; | ||
555 | pagefault_disable(); | ||
556 | r = __copy_from_user_inatomic(data, (void __user *)addr + offset, len); | ||
557 | pagefault_enable(); | ||
558 | if (r) | ||
559 | return -EFAULT; | ||
560 | return 0; | ||
561 | } | ||
562 | EXPORT_SYMBOL(kvm_read_guest_atomic); | ||
563 | |||
544 | int kvm_write_guest_page(struct kvm *kvm, gfn_t gfn, const void *data, | 564 | int kvm_write_guest_page(struct kvm *kvm, gfn_t gfn, const void *data, |
545 | int offset, int len) | 565 | int offset, int len) |
546 | { | 566 | { |