|
@@ -1421,66 +1421,6 @@ static void nested_svm_unmap(void *addr, enum km_type idx)
|
|
|
kvm_release_page_dirty(page);
|
|
|
}
|
|
|
|
|
|
-static struct page *nested_svm_get_page(struct vcpu_svm *svm, u64 gpa)
|
|
|
-{
|
|
|
- struct page *page;
|
|
|
-
|
|
|
- down_read(¤t->mm->mmap_sem);
|
|
|
- page = gfn_to_page(svm->vcpu.kvm, gpa >> PAGE_SHIFT);
|
|
|
- up_read(¤t->mm->mmap_sem);
|
|
|
-
|
|
|
- if (is_error_page(page)) {
|
|
|
- printk(KERN_INFO "%s: could not find page at 0x%llx\n",
|
|
|
- __func__, gpa);
|
|
|
- kvm_release_page_clean(page);
|
|
|
- kvm_inject_gp(&svm->vcpu, 0);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- return page;
|
|
|
-}
|
|
|
-
|
|
|
-static int nested_svm_do(struct vcpu_svm *svm,
|
|
|
- u64 arg1_gpa, u64 arg2_gpa, void *opaque,
|
|
|
- int (*handler)(struct vcpu_svm *svm,
|
|
|
- void *arg1,
|
|
|
- void *arg2,
|
|
|
- void *opaque))
|
|
|
-{
|
|
|
- struct page *arg1_page;
|
|
|
- struct page *arg2_page = NULL;
|
|
|
- void *arg1;
|
|
|
- void *arg2 = NULL;
|
|
|
- int retval;
|
|
|
-
|
|
|
- arg1_page = nested_svm_get_page(svm, arg1_gpa);
|
|
|
- if(arg1_page == NULL)
|
|
|
- return 1;
|
|
|
-
|
|
|
- if (arg2_gpa) {
|
|
|
- arg2_page = nested_svm_get_page(svm, arg2_gpa);
|
|
|
- if(arg2_page == NULL) {
|
|
|
- kvm_release_page_clean(arg1_page);
|
|
|
- return 1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- arg1 = kmap_atomic(arg1_page, KM_USER0);
|
|
|
- if (arg2_gpa)
|
|
|
- arg2 = kmap_atomic(arg2_page, KM_USER1);
|
|
|
-
|
|
|
- retval = handler(svm, arg1, arg2, opaque);
|
|
|
-
|
|
|
- kunmap_atomic(arg1, KM_USER0);
|
|
|
- if (arg2_gpa)
|
|
|
- kunmap_atomic(arg2, KM_USER1);
|
|
|
-
|
|
|
- kvm_release_page_dirty(arg1_page);
|
|
|
- if (arg2_gpa)
|
|
|
- kvm_release_page_dirty(arg2_page);
|
|
|
-
|
|
|
- return retval;
|
|
|
-}
|
|
|
-
|
|
|
static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm)
|
|
|
{
|
|
|
u32 param = svm->vmcb->control.exit_info_1 & 1;
|