From mboxrd@z Thu Jan 1 00:00:00 1970 From: Izik Eidus Subject: [PATCH 2/4] Swapping Date: Sat, 13 Oct 2007 04:08:42 +0200 Message-ID: <471028AA.1010603@qumranet.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------010604070506040801010000" To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Return-path: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Errors-To: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org List-Id: kvm.vger.kernel.org This is a multi-part message in MIME format. --------------010604070506040801010000 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit this patch make gfn_to_page always safe function (return bad_page in case there is no such page in the guest) --------------010604070506040801010000 Content-Type: text/x-patch; name="0002-change-gfn_to_page-to-be-safe-always-function.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename*0="0002-change-gfn_to_page-to-be-safe-always-function.patch" >>From 51a8851a2805f5b61d3fbe506ab317ecb677c3da Mon Sep 17 00:00:00 2001 From: Izik Eidus Date: Sat, 13 Oct 2007 02:01:54 +0200 Subject: [PATCH] change gfn_to_page to be safe always function. Signed-off-by: Izik Eidus --- drivers/kvm/kvm.h | 3 ++- drivers/kvm/kvm_main.c | 26 ++++++++++++++------------ drivers/kvm/mmu.c | 16 +++++----------- drivers/kvm/paging_tmpl.h | 11 +++-------- 4 files changed, 24 insertions(+), 32 deletions(-) diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index 4a52d6e..a155c2b 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h @@ -565,8 +565,9 @@ static inline int is_error_hpa(hpa_t hpa) { return hpa >> HPA_MSB; } hpa_t gva_to_hpa(struct kvm_vcpu *vcpu, gva_t gva); struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva); -extern hpa_t bad_page_address; +extern struct page *bad_page; +int is_error_page(struct page *page); gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn); struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn); int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset, diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index a0f8366..bfa201c 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -1012,6 +1012,12 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip) return r; } +int is_error_page(struct page *page) +{ + return page == bad_page; +} +EXPORT_SYMBOL_GPL(is_error_page); + gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) { int i; @@ -1053,7 +1059,7 @@ struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn) gfn = unalias_gfn(kvm, gfn); slot = __gfn_to_memslot(kvm, gfn); if (!slot) - return NULL; + return bad_page; return slot->phys_mem[gfn - slot->base_gfn]; } EXPORT_SYMBOL_GPL(gfn_to_page); @@ -1073,7 +1079,7 @@ int kvm_read_guest_page(struct kvm *kvm, gfn_t gfn, void *data, int offset, struct page *page; page = gfn_to_page(kvm, gfn); - if (!page) + if (is_error_page(page)) return -EFAULT; page_virt = kmap_atomic(page, KM_USER0); @@ -1111,7 +1117,7 @@ int kvm_write_guest_page(struct kvm *kvm, gfn_t gfn, const void *data, struct page *page; page = gfn_to_page(kvm, gfn); - if (!page) + if (is_error_page(page)) return -EFAULT; page_virt = kmap_atomic(page, KM_USER0); @@ -1149,7 +1155,7 @@ int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len) struct page *page; page = gfn_to_page(kvm, gfn); - if (!page) + if (is_error_page(page)) return -EFAULT; page_virt = kmap_atomic(page, KM_USER0); @@ -3075,7 +3081,7 @@ static struct page *kvm_vm_nopage(struct vm_area_struct *vma, pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; page = gfn_to_page(kvm, pgoff); - if (!page) + if (is_error_page(page)) return NOPAGE_SIGBUS; get_page(page); if (type != NULL) @@ -3390,7 +3396,7 @@ static struct sys_device kvm_sysdev = { .cls = &kvm_sysdev_class, }; -hpa_t bad_page_address; +struct page *bad_page; static inline struct kvm_vcpu *preempt_notifier_to_vcpu(struct preempt_notifier *pn) @@ -3519,7 +3525,6 @@ EXPORT_SYMBOL_GPL(kvm_exit_x86); static __init int kvm_init(void) { - static struct page *bad_page; int r; r = kvm_mmu_module_init(); @@ -3530,16 +3535,13 @@ static __init int kvm_init(void) kvm_arch_init(); - bad_page = alloc_page(GFP_KERNEL); + bad_page = alloc_page(GFP_KERNEL | __GFP_ZERO); if (bad_page == NULL) { r = -ENOMEM; goto out; } - bad_page_address = page_to_pfn(bad_page) << PAGE_SHIFT; - memset(__va(bad_page_address), 0, PAGE_SIZE); - return 0; out: @@ -3552,7 +3554,7 @@ out4: static __exit void kvm_exit(void) { kvm_exit_debug(); - __free_page(pfn_to_page(bad_page_address >> PAGE_SHIFT)); + __free_page(bad_page); kvm_mmu_module_exit(); } diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c index cfbeec8..e6a9b4a 100644 --- a/drivers/kvm/mmu.c +++ b/drivers/kvm/mmu.c @@ -850,23 +850,17 @@ static void page_header_update_slot(struct kvm *kvm, void *pte, gpa_t gpa) __set_bit(slot, &page_head->slot_bitmap); } -hpa_t safe_gpa_to_hpa(struct kvm *kvm, gpa_t gpa) -{ - hpa_t hpa = gpa_to_hpa(kvm, gpa); - - return is_error_hpa(hpa) ? bad_page_address | (gpa & ~PAGE_MASK): hpa; -} - hpa_t gpa_to_hpa(struct kvm *kvm, gpa_t gpa) { struct page *page; + hpa_t hpa; ASSERT((gpa & HPA_ERR_MASK) == 0); page = gfn_to_page(kvm, gpa >> PAGE_SHIFT); - if (!page) - return gpa | HPA_ERR_MASK; - return ((hpa_t)page_to_pfn(page) << PAGE_SHIFT) - | (gpa & (PAGE_SIZE-1)); + hpa = ((hpa_t)page_to_pfn(page) << PAGE_SHIFT) | (gpa & (PAGE_SIZE-1)); + if (is_error_page(page)) + return hpa | HPA_ERR_MASK; + return hpa; } hpa_t gva_to_hpa(struct kvm_vcpu *vcpu, gva_t gva) diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h index a9e687b..58fd35a 100644 --- a/drivers/kvm/paging_tmpl.h +++ b/drivers/kvm/paging_tmpl.h @@ -92,8 +92,6 @@ static int FNAME(walk_addr)(struct guest_walker *walker, struct kvm_vcpu *vcpu, gva_t addr, int write_fault, int user_fault, int fetch_fault) { - hpa_t hpa; - struct kvm_memory_slot *slot; pt_element_t *ptep; pt_element_t root; gfn_t table_gfn; @@ -118,9 +116,8 @@ static int FNAME(walk_addr)(struct guest_walker *walker, walker->table_gfn[walker->level - 1] = table_gfn; pgprintk("%s: table_gfn[%d] %lx\n", __FUNCTION__, walker->level - 1, table_gfn); - slot = gfn_to_memslot(vcpu->kvm, table_gfn); - hpa = safe_gpa_to_hpa(vcpu->kvm, root & PT64_BASE_ADDR_MASK); - walker->page = pfn_to_page(hpa >> PAGE_SHIFT); + walker->page = gfn_to_page(vcpu->kvm, (root & PT64_BASE_ADDR_MASK) + >> PAGE_SHIFT); walker->table = kmap_atomic(walker->page, KM_USER0); ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) || @@ -130,7 +127,6 @@ static int FNAME(walk_addr)(struct guest_walker *walker, for (;;) { int index = PT_INDEX(addr, walker->level); - hpa_t paddr; ptep = &walker->table[index]; walker->index = index; @@ -179,8 +175,7 @@ static int FNAME(walk_addr)(struct guest_walker *walker, walker->inherited_ar &= walker->table[index]; table_gfn = (*ptep & PT_BASE_ADDR_MASK) >> PAGE_SHIFT; kunmap_atomic(walker->table, KM_USER0); - paddr = safe_gpa_to_hpa(vcpu->kvm, table_gfn << PAGE_SHIFT); - walker->page = pfn_to_page(paddr >> PAGE_SHIFT); + walker->page = gfn_to_page(vcpu->kvm, table_gfn); walker->table = kmap_atomic(walker->page, KM_USER0); --walker->level; walker->table_gfn[walker->level - 1] = table_gfn; -- 1.5.2.4 --------------010604070506040801010000 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ --------------010604070506040801010000 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ kvm-devel mailing list kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/kvm-devel --------------010604070506040801010000--