ia64/xen-unstable

changeset 15611:45b97e0f2dc8

hap: Merge the guest-walking functions into one.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Jul 17 14:09:45 2007 +0100 (2007-07-17)
parents ee7a5ddc1847
children 4721e9d836dd
files xen/arch/x86/mm/hap/Makefile xen/arch/x86/mm/hap/guest_walk.c xen/arch/x86/mm/hap/hap.c xen/arch/x86/mm/hap/private.h xen/arch/x86/mm/hap/support.c
line diff
     1.1 --- a/xen/arch/x86/mm/hap/Makefile	Tue Jul 17 10:36:33 2007 +0100
     1.2 +++ b/xen/arch/x86/mm/hap/Makefile	Tue Jul 17 14:09:45 2007 +0100
     1.3 @@ -1,2 +1,10 @@
     1.4  obj-y += hap.o
     1.5 -obj-y += support.o
     1.6 +obj-y += guest_walk_2level.o
     1.7 +obj-y += guest_walk_3level.o
     1.8 +obj-y += guest_walk_4level.o
     1.9 +
    1.10 +guest_levels  = $(subst level,,$(filter %level,$(subst ., ,$(subst _, ,$(1)))))
    1.11 +guest_walk_defns = -DGUEST_PAGING_LEVELS=$(call guest_levels,$(1))
    1.12 +
    1.13 +guest_walk_%level.o: guest_walk.c $(HDRS) Makefile
    1.14 +	$(CC) $(CFLAGS) $(call guest_walk_defns,$(@F)) -c $< -o $@
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xen/arch/x86/mm/hap/guest_walk.c	Tue Jul 17 14:09:45 2007 +0100
     2.3 @@ -0,0 +1,181 @@
     2.4 +/*
     2.5 + * arch/x86/mm/hap/guest_walk.c
     2.6 + *
     2.7 + * Guest page table walker
     2.8 + * Copyright (c) 2007, AMD Corporation (Wei Huang)
     2.9 + * Copyright (c) 2007, XenSource Inc.
    2.10 + *
    2.11 + * This program is free software; you can redistribute it and/or modify it
    2.12 + * under the terms and conditions of the GNU General Public License,
    2.13 + * version 2, as published by the Free Software Foundation.
    2.14 + *
    2.15 + * This program is distributed in the hope it will be useful, but WITHOUT
    2.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.17 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    2.18 + * more details.
    2.19 + *
    2.20 + * You should have received a copy of the GNU General Public License along with
    2.21 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    2.22 + * Place - Suite 330, Boston, MA 02111-1307 USA.
    2.23 + */
    2.24 +
    2.25 +#include <xen/config.h>
    2.26 +#include <xen/types.h>
    2.27 +#include <xen/mm.h>
    2.28 +#include <xen/domain_page.h>
    2.29 +#include <asm/page.h>
    2.30 +#include <xen/event.h>
    2.31 +#include <xen/sched.h>
    2.32 +#include <asm/hvm/svm/vmcb.h>
    2.33 +#include <asm/domain.h>
    2.34 +#include <asm/shadow.h>
    2.35 +#include <asm/hap.h>
    2.36 +
    2.37 +#include "private.h"
    2.38 +
    2.39 +#define _hap_gva_to_gfn(levels) hap_gva_to_gfn_##levels##level
    2.40 +#define hap_gva_to_gfn(levels) _hap_gva_to_gfn(levels)
    2.41 +
    2.42 +#if GUEST_PAGING_LEVELS > CONFIG_PAGING_LEVELS
    2.43 +
    2.44 +unsigned long hap_gva_to_gfn(GUEST_PAGING_LEVELS)(
    2.45 +    struct vcpu *v, unsigned long gva)
    2.46 +{
    2.47 +    gdprintk(XENLOG_ERR,
    2.48 +             "Guest paging level is greater than host paging level!\n");
    2.49 +    domain_crash(v->domain);
    2.50 +    return INVALID_GFN;
    2.51 +}
    2.52 +
    2.53 +#else
    2.54 +
    2.55 +#if GUEST_PAGING_LEVELS == 2
    2.56 +#include "../page-guest32.h"
    2.57 +#define l1_pgentry_t l1_pgentry_32_t
    2.58 +#define l2_pgentry_t l2_pgentry_32_t
    2.59 +#undef l2e_get_flags
    2.60 +#define l2e_get_flags(x) l2e_get_flags_32(x)
    2.61 +#undef l1e_get_flags
    2.62 +#define l1e_get_flags(x) l1e_get_flags_32(x)
    2.63 +#endif
    2.64 +
    2.65 +unsigned long hap_gva_to_gfn(GUEST_PAGING_LEVELS)(
    2.66 +    struct vcpu *v, unsigned long gva)
    2.67 +{
    2.68 +    unsigned long gcr3 = hvm_get_guest_ctrl_reg(v, 3);
    2.69 +    int mode = GUEST_PAGING_LEVELS;
    2.70 +    int lev, index;
    2.71 +    paddr_t gpa = 0;
    2.72 +    unsigned long gpfn, mfn;
    2.73 +    int success = 1;
    2.74 +
    2.75 +    l1_pgentry_t *l1e;
    2.76 +    l2_pgentry_t *l2e;
    2.77 +#if GUEST_PAGING_LEVELS >= 3
    2.78 +    l3_pgentry_t *l3e;
    2.79 +#endif
    2.80 +#if GUEST_PAGING_LEVELS >= 4
    2.81 +    l4_pgentry_t *l4e;
    2.82 +#endif
    2.83 +
    2.84 +    gpfn = (gcr3 >> PAGE_SHIFT);
    2.85 +    for ( lev = mode; lev >= 1; lev-- )
    2.86 +    {
    2.87 +        mfn = get_mfn_from_gpfn(gpfn);
    2.88 +        if ( mfn == INVALID_MFN )
    2.89 +        {
    2.90 +            HAP_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva, 
    2.91 +                       lev);
    2.92 +            success = 0;
    2.93 +            break;
    2.94 +        }
    2.95 +        index = (gva >> PT_SHIFT[mode][lev]) & (PT_ENTRIES[mode][lev]-1);
    2.96 +
    2.97 +#if GUEST_PAGING_LEVELS >= 4
    2.98 +        if ( lev == 4 )
    2.99 +        {
   2.100 +            l4e = map_domain_page(mfn);
   2.101 +            if ( !(l4e_get_flags(l4e[index]) & _PAGE_PRESENT) )
   2.102 +            {
   2.103 +                HAP_PRINTK("Level 4 entry not present at index = %d\n", index);
   2.104 +                success = 0;
   2.105 +            }
   2.106 +            gpfn = l4e_get_pfn(l4e[index]);
   2.107 +            unmap_domain_page(l4e);
   2.108 +        }
   2.109 +#endif
   2.110 +
   2.111 +#if GUEST_PAGING_LEVELS >= 3
   2.112 +        if ( lev == 3 )
   2.113 +        {
   2.114 +            l3e = map_domain_page(mfn);
   2.115 +#if GUEST_PAGING_LEVELS == 3
   2.116 +            index += ((gcr3 >> 5) & 127) * 4;
   2.117 +#endif
   2.118 +            if ( !(l3e_get_flags(l3e[index]) & _PAGE_PRESENT) )
   2.119 +            {
   2.120 +                HAP_PRINTK("Level 3 entry not present at index = %d\n", index);
   2.121 +                success = 0;
   2.122 +            }
   2.123 +            gpfn = l3e_get_pfn(l3e[index]);
   2.124 +            unmap_domain_page(l3e);
   2.125 +        }
   2.126 +#endif
   2.127 +
   2.128 +        if ( lev == 2 )
   2.129 +        {
   2.130 +            l2e = map_domain_page(mfn);
   2.131 +            if ( !(l2e_get_flags(l2e[index]) & _PAGE_PRESENT) )
   2.132 +            {
   2.133 +                HAP_PRINTK("Level 2 entry not present at index = %d\n", index);
   2.134 +                success = 0;
   2.135 +            }
   2.136 +
   2.137 +            if ( l2e_get_flags(l2e[index]) & _PAGE_PSE )
   2.138 +            {
   2.139 +                paddr_t mask = ((paddr_t)1 << PT_SHIFT[mode][2]) - 1;
   2.140 +                HAP_PRINTK("guest page table is PSE\n");
   2.141 +                gpa = (l2e_get_intpte(l2e[index]) & ~mask) + (gva & mask);
   2.142 +                unmap_domain_page(l2e);
   2.143 +                break; /* last level page table, jump out from here */
   2.144 +            }
   2.145 +
   2.146 +            gpfn = l2e_get_pfn(l2e[index]);
   2.147 +            unmap_domain_page(l2e);
   2.148 +        }
   2.149 +
   2.150 +        if ( lev == 1 )
   2.151 +        {
   2.152 +            l1e = map_domain_page(mfn);
   2.153 +            if ( !(l1e_get_flags(l1e[index]) & _PAGE_PRESENT) )
   2.154 +            {
   2.155 +                HAP_PRINTK("Level 1 entry not present at index = %d\n", index);
   2.156 +                success = 0;
   2.157 +            }
   2.158 +            gpfn = l1e_get_pfn(l1e[index]);
   2.159 +            gpa = (l1e_get_intpte(l1e[index]) & PAGE_MASK) + (gva &~PAGE_MASK);
   2.160 +            unmap_domain_page(l1e);
   2.161 +        }
   2.162 +
   2.163 +        if ( success != 1 ) /* error happened, jump out */
   2.164 +            break;
   2.165 +    }
   2.166 +
   2.167 +    gpa &= PADDR_MASK;
   2.168 +    HAP_PRINTK("success = %d, gva = %lx, gpa = %lx\n", success, gva, gpa);
   2.169 +
   2.170 +    return (!success ? INVALID_GFN : ((paddr_t)gpa >> PAGE_SHIFT));
   2.171 +}
   2.172 +
   2.173 +#endif
   2.174 +
   2.175 +/*
   2.176 + * Local variables:
   2.177 + * mode: C
   2.178 + * c-set-style: "BSD"
   2.179 + * c-basic-offset: 4
   2.180 + * tab-width: 4
   2.181 + * indent-tabs-mode: nil
   2.182 + * End:
   2.183 + */
   2.184 +
     3.1 --- a/xen/arch/x86/mm/hap/hap.c	Tue Jul 17 10:36:33 2007 +0100
     3.2 +++ b/xen/arch/x86/mm/hap/hap.c	Tue Jul 17 14:09:45 2007 +0100
     3.3 @@ -290,8 +290,8 @@ void hap_install_xen_entries_in_l2h(stru
     3.4              l2e_from_pfn(
     3.5                  mfn_x(page_to_mfn(virt_to_page(d->arch.mm_perdomain_pt) + i)),
     3.6                  __PAGE_HYPERVISOR);
     3.7 -    
     3.8 -    for ( i = 0; i < HAP_L3_PAGETABLE_ENTRIES; i++ )
     3.9 +
    3.10 +    for ( i = 0; i < 4; i++ )
    3.11          sl2e[l2_table_offset(LINEAR_PT_VIRT_START) + i] =
    3.12              l2e_empty();
    3.13  
    3.14 @@ -564,6 +564,7 @@ void hap_vcpu_init(struct vcpu *v)
    3.15  {
    3.16      v->arch.paging.mode = &hap_paging_real_mode;
    3.17  }
    3.18 +
    3.19  /************************************************/
    3.20  /*          HAP PAGING MODE FUNCTIONS           */
    3.21  /************************************************/
    3.22 @@ -571,8 +572,8 @@ void hap_vcpu_init(struct vcpu *v)
    3.23   * HAP guests can handle page faults (in the guest page tables) without
    3.24   * needing any action from Xen, so we should not be intercepting them.
    3.25   */
    3.26 -int hap_page_fault(struct vcpu *v, unsigned long va, 
    3.27 -                   struct cpu_user_regs *regs)
    3.28 +static int hap_page_fault(struct vcpu *v, unsigned long va, 
    3.29 +                          struct cpu_user_regs *regs)
    3.30  {
    3.31      HAP_ERROR("Intercepted a guest #PF (%u:%u) with HAP enabled.\n",
    3.32                v->domain->domain_id, v->vcpu_id);
    3.33 @@ -584,7 +585,7 @@ int hap_page_fault(struct vcpu *v, unsig
    3.34   * HAP guests can handle invlpg without needing any action from Xen, so
    3.35   * should not be intercepting it. 
    3.36   */
    3.37 -int hap_invlpg(struct vcpu *v, unsigned long va)
    3.38 +static int hap_invlpg(struct vcpu *v, unsigned long va)
    3.39  {
    3.40      HAP_ERROR("Intercepted a guest INVLPG (%u:%u) with HAP enabled.\n",
    3.41                v->domain->domain_id, v->vcpu_id);
    3.42 @@ -596,11 +597,11 @@ int hap_invlpg(struct vcpu *v, unsigned 
    3.43   * HAP guests do not need to take any action on CR3 writes (they are still
    3.44   * intercepted, so that Xen's copy of the guest's CR3 can be kept in sync.)
    3.45   */
    3.46 -void hap_update_cr3(struct vcpu *v, int do_locking)
    3.47 +static void hap_update_cr3(struct vcpu *v, int do_locking)
    3.48  {
    3.49  }
    3.50  
    3.51 -void hap_update_paging_modes(struct vcpu *v)
    3.52 +static void hap_update_paging_modes(struct vcpu *v)
    3.53  {
    3.54      struct domain *d;
    3.55  
    3.56 @@ -678,7 +679,7 @@ static void p2m_install_entry_in_monitor
    3.57  }
    3.58  #endif
    3.59  
    3.60 -void 
    3.61 +static void 
    3.62  hap_write_p2m_entry(struct vcpu *v, unsigned long gfn, l1_pgentry_t *p,
    3.63                      mfn_t table_mfn, l1_pgentry_t new, unsigned int level)
    3.64  {
    3.65 @@ -696,6 +697,12 @@ hap_write_p2m_entry(struct vcpu *v, unsi
    3.66      hap_unlock(v->domain);
    3.67  }
    3.68  
    3.69 +static unsigned long hap_gva_to_gfn_real_mode(
    3.70 +    struct vcpu *v, unsigned long gva)
    3.71 +{
    3.72 +    return ((paddr_t)gva >> PAGE_SHIFT);
    3.73 +}
    3.74 +
    3.75  /* Entry points into this mode of the hap code. */
    3.76  struct paging_mode hap_paging_real_mode = {
    3.77      .page_fault             = hap_page_fault, 
    3.78 @@ -710,7 +717,7 @@ struct paging_mode hap_paging_real_mode 
    3.79  struct paging_mode hap_paging_protected_mode = {
    3.80      .page_fault             = hap_page_fault, 
    3.81      .invlpg                 = hap_invlpg,
    3.82 -    .gva_to_gfn             = hap_gva_to_gfn_protected_mode,
    3.83 +    .gva_to_gfn             = hap_gva_to_gfn_2level,
    3.84      .update_cr3             = hap_update_cr3,
    3.85      .update_paging_modes    = hap_update_paging_modes,
    3.86      .write_p2m_entry        = hap_write_p2m_entry,
    3.87 @@ -720,7 +727,7 @@ struct paging_mode hap_paging_protected_
    3.88  struct paging_mode hap_paging_pae_mode = {
    3.89      .page_fault             = hap_page_fault, 
    3.90      .invlpg                 = hap_invlpg,
    3.91 -    .gva_to_gfn             = hap_gva_to_gfn_pae_mode,
    3.92 +    .gva_to_gfn             = hap_gva_to_gfn_3level,
    3.93      .update_cr3             = hap_update_cr3,
    3.94      .update_paging_modes    = hap_update_paging_modes,
    3.95      .write_p2m_entry        = hap_write_p2m_entry,
    3.96 @@ -730,7 +737,7 @@ struct paging_mode hap_paging_pae_mode =
    3.97  struct paging_mode hap_paging_long_mode = {
    3.98      .page_fault             = hap_page_fault, 
    3.99      .invlpg                 = hap_invlpg,
   3.100 -    .gva_to_gfn             = hap_gva_to_gfn_long_mode,
   3.101 +    .gva_to_gfn             = hap_gva_to_gfn_4level,
   3.102      .update_cr3             = hap_update_cr3,
   3.103      .update_paging_modes    = hap_update_paging_modes,
   3.104      .write_p2m_entry        = hap_write_p2m_entry,
     4.1 --- a/xen/arch/x86/mm/hap/private.h	Tue Jul 17 10:36:33 2007 +0100
     4.2 +++ b/xen/arch/x86/mm/hap/private.h	Tue Jul 17 14:09:45 2007 +0100
     4.3 @@ -26,10 +26,10 @@
     4.4  /********************************************/
     4.5  /*          GUEST TRANSLATION FUNCS         */
     4.6  /********************************************/
     4.7 -unsigned long hap_gva_to_gfn_real_mode(struct vcpu *v, unsigned long gva);
     4.8 -unsigned long hap_gva_to_gfn_protected_mode(struct vcpu *v, unsigned long gva);
     4.9 -unsigned long hap_gva_to_gfn_pae_mode(struct vcpu *v, unsigned long gva);
    4.10 -unsigned long hap_gva_to_gfn_long_mode(struct vcpu *v, unsigned long gva);
    4.11 +unsigned long hap_gva_to_gfn_2level(struct vcpu *v, unsigned long gva);
    4.12 +unsigned long hap_gva_to_gfn_3level(struct vcpu *v, unsigned long gva);
    4.13 +unsigned long hap_gva_to_gfn_4level(struct vcpu *v, unsigned long gva);
    4.14 +
    4.15  /********************************************/
    4.16  /*            MISC DEFINITIONS              */
    4.17  /********************************************/
    4.18 @@ -62,51 +62,4 @@ static const int PT_ENTRIES[][5] =
    4.19      {    0,  512,  512,  512,  512}    /* 4  */
    4.20    };
    4.21  
    4.22 -/********************************************/
    4.23 -/*       PAGING DEFINITION FOR GUEST        */
    4.24 -/********************************************/
    4.25 -#define PHYSICAL_PAGE_4K_SIZE (1UL << 12)
    4.26 -#define PHYSICAL_PAGE_2M_SIZE (1UL << 21)
    4.27 -#define PHYSICAL_PAGE_4M_SIZE (1UL << 22)
    4.28 -#define PHYSICAL_PAGE_4K_MASK ( ~(PHYSICAL_PAGE_4K_SIZE - 1) )
    4.29 -#define PHYSICAL_PAGE_2M_MASK ( ~(PHYSICAL_PAGE_2M_SIZE - 1) )
    4.30 -#define PHYSICAL_PAGE_4M_MASK ( ~(PHYSICAL_PAGE_4M_SIZE - 1) )
    4.31 -
    4.32 -/* long mode physical address mask */
    4.33 -#define PHYSICAL_ADDR_BITS_LM    52
    4.34 -#define PHYSICAL_ADDR_MASK_LM    ((1UL << PHYSICAL_ADDR_BITS_LM)-1)
    4.35 -#define PHYSICAL_ADDR_2M_MASK_LM (PHYSICAL_PAGE_2M_MASK & PHYSICAL_ADDR_MASK_LM)
    4.36 -#define PHYSICAL_ADDR_4K_MASK_LM (PHYSICAL_PAGE_4K_MASK & PHYSICAL_ADDR_MASK_LM)
    4.37 -
    4.38 -#define PAGE_NX_BIT      (1ULL << 63)
    4.39 -/************************************************/
    4.40 -/*        PAGETABLE RELATED VARIABLES           */
    4.41 -/************************************************/
    4.42 -#if CONFIG_PAGING_LEVELS == 2
    4.43 -#define HAP_L1_PAGETABLE_ENTRIES    1024
    4.44 -#define HAP_L2_PAGETABLE_ENTRIES    1024
    4.45 -#define HAP_L1_PAGETABLE_SHIFT        12
    4.46 -#define HAP_L2_PAGETABLE_SHIFT        22
    4.47 -#endif
    4.48 -
    4.49 -#if CONFIG_PAGING_LEVELS == 3
    4.50 -#define HAP_L1_PAGETABLE_ENTRIES     512
    4.51 -#define HAP_L2_PAGETABLE_ENTRIES     512
    4.52 -#define HAP_L3_PAGETABLE_ENTRIES       4
    4.53 -#define HAP_L1_PAGETABLE_SHIFT        12
    4.54 -#define HAP_L2_PAGETABLE_SHIFT        21
    4.55 -#define HAP_L3_PAGETABLE_SHIFT        30
    4.56 -#endif
    4.57 -
    4.58 -#if CONFIG_PAGING_LEVELS == 4
    4.59 -#define HAP_L1_PAGETABLE_ENTRIES     512
    4.60 -#define HAP_L2_PAGETABLE_ENTRIES     512
    4.61 -#define HAP_L3_PAGETABLE_ENTRIES     512
    4.62 -#define HAP_L4_PAGETABLE_ENTRIES     512
    4.63 -#define HAP_L1_PAGETABLE_SHIFT        12
    4.64 -#define HAP_L2_PAGETABLE_SHIFT        21
    4.65 -#define HAP_L3_PAGETABLE_SHIFT        30
    4.66 -#define HAP_L4_PAGETABLE_SHIFT        39
    4.67 -#endif
    4.68 -
    4.69  #endif /* __SVM_NPT_H__ */
     5.1 --- a/xen/arch/x86/mm/hap/support.c	Tue Jul 17 10:36:33 2007 +0100
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,340 +0,0 @@
     5.4 -/*
     5.5 - * arch/x86/mm/hap/support.c
     5.6 - * 
     5.7 - * guest page table walker
     5.8 - * Copyright (c) 2007, AMD Corporation (Wei Huang)
     5.9 - *
    5.10 - * This program is free software; you can redistribute it and/or modify it
    5.11 - * under the terms and conditions of the GNU General Public License,
    5.12 - * version 2, as published by the Free Software Foundation.
    5.13 - *
    5.14 - * This program is distributed in the hope it will be useful, but WITHOUT
    5.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    5.17 - * more details.
    5.18 - *
    5.19 - * You should have received a copy of the GNU General Public License along with
    5.20 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    5.21 - * Place - Suite 330, Boston, MA 02111-1307 USA.
    5.22 - *
    5.23 - */
    5.24 -
    5.25 -#include <xen/config.h>
    5.26 -#include <xen/types.h>
    5.27 -#include <xen/mm.h>
    5.28 -#include <xen/domain_page.h>
    5.29 -#include <asm/page.h>
    5.30 -#include <xen/event.h>
    5.31 -#include <xen/sched.h>
    5.32 -#include <asm/hvm/svm/vmcb.h>
    5.33 -#include <asm/domain.h>
    5.34 -#include <asm/shadow.h>
    5.35 -#include <asm/hap.h>
    5.36 -
    5.37 -#include "private.h"
    5.38 -#include "../page-guest32.h"
    5.39 -
    5.40 -/*******************************************/
    5.41 -/*      Platform Specific Functions        */
    5.42 -/*******************************************/
    5.43 -
    5.44 -/* Translate guest virtual address to guest physical address. Specifically
    5.45 - * for real mode guest. 
    5.46 - */
    5.47 -unsigned long hap_gva_to_gfn_real_mode(struct vcpu *v, unsigned long gva)
    5.48 -{
    5.49 -    return ((paddr_t)gva >> PAGE_SHIFT);
    5.50 -}
    5.51 -
    5.52 -/* Translate guest virtual address to guest physical address. Specifically
    5.53 - * for protected guest. 
    5.54 - */
    5.55 -unsigned long hap_gva_to_gfn_protected_mode(struct vcpu *v, unsigned long gva)
    5.56 -{
    5.57 -    unsigned long gcr3 = hvm_get_guest_ctrl_reg(v, 3);
    5.58 -    int mode = 2; /* two-level guest */
    5.59 -    int lev, index;
    5.60 -    paddr_t gpa = 0;
    5.61 -    unsigned long gpfn, mfn;
    5.62 -    int success = 1;
    5.63 -    l2_pgentry_32_t *l2e; /* guest page entry size is 32-bit */
    5.64 -    l1_pgentry_32_t *l1e;
    5.65 -
    5.66 -    gpfn = (gcr3 >> PAGE_SHIFT);
    5.67 -    for ( lev = mode; lev >= 1; lev-- )
    5.68 -    {
    5.69 -        mfn = get_mfn_from_gpfn(gpfn);
    5.70 -        if ( mfn == INVALID_MFN )
    5.71 -        {
    5.72 -            HAP_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva, 
    5.73 -                       lev);
    5.74 -            success = 0;
    5.75 -            break;
    5.76 -        }
    5.77 -        index = (gva >> PT_SHIFT[mode][lev]) & (PT_ENTRIES[mode][lev]-1);
    5.78 -
    5.79 -        if ( lev == 2 )
    5.80 -        {
    5.81 -            l2e = map_domain_page(mfn);
    5.82 -            HAP_PRINTK("l2 page table entry is %ulx at index = %d\n", 
    5.83 -                       l2e[index].l2, index);
    5.84 -            if ( !(l2e_get_flags_32(l2e[index]) & _PAGE_PRESENT) )
    5.85 -            {
    5.86 -                HAP_PRINTK("Level 2 entry not present at index = %d\n", index);
    5.87 -                success = 0;
    5.88 -            }
    5.89 -
    5.90 -            if ( l2e_get_flags_32(l2e[index]) & _PAGE_PSE )
    5.91 -            {
    5.92 -                HAP_PRINTK("guest page table is PSE\n");
    5.93 -                if ( l2e_get_intpte(l2e[index]) & 0x001FE000UL ) /*[13:20] */
    5.94 -                {
    5.95 -                    printk("guest physical memory size is too large!\n");
    5.96 -                    domain_crash(v->domain);
    5.97 -                }
    5.98 -                gpa = (l2e_get_intpte(l2e[index]) & PHYSICAL_PAGE_4M_MASK) + 
    5.99 -                    (gva & ~PHYSICAL_PAGE_4M_MASK);
   5.100 -                unmap_domain_page(l2e);
   5.101 -                break; /* last level page table, return from here */
   5.102 -            }
   5.103 -
   5.104 -            gpfn = l2e_get_pfn(l2e[index]);
   5.105 -            unmap_domain_page(l2e);
   5.106 -        }
   5.107 -
   5.108 -        if ( lev == 1 )
   5.109 -        {
   5.110 -            l1e = map_domain_page(mfn);
   5.111 -            HAP_PRINTK("l1 page table entry is %ulx at index = %d\n", 
   5.112 -                       l1e[index].l1, index);
   5.113 -            if ( !(l1e_get_flags_32(l1e[index]) & _PAGE_PRESENT) )
   5.114 -            {
   5.115 -                HAP_PRINTK("Level 1 entry not present at index = %d\n", index);
   5.116 -                success = 0;
   5.117 -            }
   5.118 -            gpfn = l1e_get_pfn(l1e[index]);
   5.119 -            gpa = (l1e_get_intpte(l1e[index]) & PHYSICAL_PAGE_4K_MASK) + 
   5.120 -                (gva & ~PHYSICAL_PAGE_4K_MASK);    
   5.121 -            unmap_domain_page(l1e);
   5.122 -        }
   5.123 -
   5.124 -        if ( !success ) /* error happened, jump out */
   5.125 -            break;
   5.126 -    }
   5.127 -
   5.128 -    HAP_PRINTK("success = %d, gva = %lx, gpa = %lx\n", success, gva, gpa);
   5.129 -
   5.130 -    return (!success ? INVALID_GFN : ((paddr_t)gpa >> PAGE_SHIFT));
   5.131 -}
   5.132 -
   5.133 -
   5.134 -
   5.135 -/* Translate guest virtual address to guest physical address. Specifically
   5.136 - * for PAE mode guest. 
   5.137 - */
   5.138 -unsigned long hap_gva_to_gfn_pae_mode(struct vcpu *v, unsigned long gva)
   5.139 -{
   5.140 -#if CONFIG_PAGING_LEVELS >= 3
   5.141 -    unsigned long gcr3 = hvm_get_guest_ctrl_reg(v, 3);
   5.142 -    int mode = 3; /* three-level guest */
   5.143 -    int lev, index;
   5.144 -    paddr_t gpa = 0;
   5.145 -    unsigned long gpfn, mfn;
   5.146 -    int success = 1;
   5.147 -    l1_pgentry_t *l1e;
   5.148 -    l2_pgentry_t *l2e;
   5.149 -    l3_pgentry_t *l3e;
   5.150 -    
   5.151 -    gpfn = (gcr3 >> PAGE_SHIFT);
   5.152 -    for ( lev = mode; lev >= 1; lev-- )
   5.153 -    {
   5.154 -        mfn = get_mfn_from_gpfn(gpfn);
   5.155 -        if ( mfn == INVALID_MFN )
   5.156 -        {
   5.157 -            HAP_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva, 
   5.158 -                       lev);
   5.159 -            success = 0;
   5.160 -            break;
   5.161 -        }
   5.162 -        index = (gva >> PT_SHIFT[mode][lev]) & (PT_ENTRIES[mode][lev]-1);
   5.163 -
   5.164 -        if ( lev == 3 )
   5.165 -        {
   5.166 -            l3e = map_domain_page(mfn);
   5.167 -            index += ((gcr3 >> 5) & 127) * 4;
   5.168 -            if ( !(l3e_get_flags(l3e[index]) & _PAGE_PRESENT) )
   5.169 -            {
   5.170 -                HAP_PRINTK("Level 3 entry not present at index = %d\n", index);
   5.171 -                success = 0;
   5.172 -            }
   5.173 -            gpfn = l3e_get_pfn(l3e[index]);
   5.174 -            unmap_domain_page(l3e);
   5.175 -        }
   5.176 -
   5.177 -        if ( lev == 2 )
   5.178 -        {
   5.179 -            l2e = map_domain_page(mfn);
   5.180 -            if ( !(l2e_get_flags(l2e[index]) & _PAGE_PRESENT) )
   5.181 -            {
   5.182 -                HAP_PRINTK("Level 2 entry not present at index = %d\n", index);
   5.183 -                success = 0;
   5.184 -            }
   5.185 -
   5.186 -            if ( l2e_get_flags(l2e[index]) & _PAGE_PSE )
   5.187 -            {
   5.188 -                HAP_PRINTK("guest page table is PSE\n");
   5.189 -                gpa = (l2e_get_intpte(l2e[index]) & PHYSICAL_PAGE_2M_MASK) + 
   5.190 -                    (gva & ~PHYSICAL_PAGE_2M_MASK);
   5.191 -                unmap_domain_page(l2e);
   5.192 -                break; /* last level page table, jump out from here */
   5.193 -            }
   5.194 -
   5.195 -            gpfn = l2e_get_pfn(l2e[index]);
   5.196 -            unmap_domain_page(l2e);
   5.197 -        }
   5.198 -
   5.199 -        if ( lev == 1 )
   5.200 -        {
   5.201 -            l1e = map_domain_page(mfn);
   5.202 -            if ( !(l1e_get_flags(l1e[index]) & _PAGE_PRESENT) )
   5.203 -            {
   5.204 -                HAP_PRINTK("Level 1 entry not present at index = %d\n", index);
   5.205 -                success = 0;
   5.206 -            }
   5.207 -            gpfn = l1e_get_pfn(l1e[index]);
   5.208 -            gpa = (l1e_get_intpte(l1e[index]) & PHYSICAL_PAGE_4K_MASK) + 
   5.209 -                (gva & ~PHYSICAL_PAGE_4K_MASK);
   5.210 -            unmap_domain_page(l1e);
   5.211 -        }
   5.212 -
   5.213 -        if ( success != 1 ) /* error happened, jump out */
   5.214 -            break;
   5.215 -    }
   5.216 -
   5.217 -    gpa &= ~PAGE_NX_BIT; /* clear NX bit of guest physical address */
   5.218 -    HAP_PRINTK("success = %d, gva = %lx, gpa = %lx\n", success, gva, gpa);
   5.219 -
   5.220 -    return (!success ? INVALID_GFN : ((paddr_t)gpa >> PAGE_SHIFT));
   5.221 -#else
   5.222 -    printk("guest paging level (3) is greater than host paging level!\n");
   5.223 -    domain_crash(v->domain);
   5.224 -    return INVALID_GFN;
   5.225 -#endif
   5.226 -}
   5.227 -
   5.228 -
   5.229 -/* Translate guest virtual address to guest physical address. Specifically
   5.230 - * for long mode guest. 
   5.231 - */
   5.232 -unsigned long hap_gva_to_gfn_long_mode(struct vcpu *v, unsigned long gva)
   5.233 -{
   5.234 -#if CONFIG_PAGING_LEVELS == 4
   5.235 -    unsigned long gcr3 = hvm_get_guest_ctrl_reg(v, 3);
   5.236 -    int mode = 4; /* four-level guest */
   5.237 -    int lev, index;
   5.238 -    paddr_t gpa = 0;
   5.239 -    unsigned long gpfn, mfn;
   5.240 -    int success = 1;
   5.241 -    l4_pgentry_t *l4e;
   5.242 -    l3_pgentry_t *l3e;
   5.243 -    l2_pgentry_t *l2e;
   5.244 -    l1_pgentry_t *l1e;
   5.245 -
   5.246 -    gpfn = (gcr3 >> PAGE_SHIFT);
   5.247 -    for ( lev = mode; lev >= 1; lev-- )
   5.248 -    {
   5.249 -        mfn = get_mfn_from_gpfn(gpfn);
   5.250 -        if ( mfn == INVALID_MFN )
   5.251 -        {
   5.252 -            HAP_PRINTK("bad pfn=0x%lx from gva=0x%lx at lev%d\n", gpfn, gva, 
   5.253 -                       lev);
   5.254 -            success = 0;
   5.255 -            break;
   5.256 -        }
   5.257 -        index = (gva >> PT_SHIFT[mode][lev]) & (PT_ENTRIES[mode][lev]-1);
   5.258 -
   5.259 -        if ( lev == 4 )
   5.260 -        {
   5.261 -            l4e = map_domain_page(mfn);
   5.262 -            if ( !(l4e_get_flags(l4e[index]) & _PAGE_PRESENT) )
   5.263 -            {
   5.264 -                HAP_PRINTK("Level 4 entry not present at index = %d\n", index);
   5.265 -                success = 0;
   5.266 -            }
   5.267 -            gpfn = l4e_get_pfn(l4e[index]);
   5.268 -            unmap_domain_page(l4e);
   5.269 -        }
   5.270 -
   5.271 -        if ( lev == 3 )
   5.272 -        {
   5.273 -            l3e = map_domain_page(mfn);
   5.274 -            if ( !(l3e_get_flags(l3e[index]) & _PAGE_PRESENT) )
   5.275 -            {
   5.276 -                HAP_PRINTK("Level 3 entry not present at index = %d\n", index);
   5.277 -                success = 0;
   5.278 -            }
   5.279 -            gpfn = l3e_get_pfn(l3e[index]);
   5.280 -            unmap_domain_page(l3e);
   5.281 -        }
   5.282 -
   5.283 -        if ( lev == 2 )
   5.284 -        {
   5.285 -            l2e = map_domain_page(mfn);
   5.286 -            if ( !(l2e_get_flags(l2e[index]) & _PAGE_PRESENT) )
   5.287 -            {
   5.288 -                HAP_PRINTK("Level 2 entry not present at index = %d\n", index);
   5.289 -                success = 0;
   5.290 -            }
   5.291 -
   5.292 -            if ( l2e_get_flags(l2e[index]) & _PAGE_PSE )
   5.293 -            {
   5.294 -                HAP_PRINTK("guest page table is PSE\n");
   5.295 -                gpa = (l2e_get_intpte(l2e[index]) & PHYSICAL_ADDR_2M_MASK_LM) 
   5.296 -                    + (gva & ~PHYSICAL_PAGE_2M_MASK);
   5.297 -                unmap_domain_page(l2e);
   5.298 -                break; /* last level page table, jump out from here */
   5.299 -            }
   5.300 -
   5.301 -            gpfn = l2e_get_pfn(l2e[index]);
   5.302 -            unmap_domain_page(l2e);
   5.303 -        }
   5.304 -
   5.305 -        if ( lev == 1 )
   5.306 -        {
   5.307 -            l1e = map_domain_page(mfn);
   5.308 -            if ( !(l1e_get_flags(l1e[index]) & _PAGE_PRESENT) )
   5.309 -            {
   5.310 -                HAP_PRINTK("Level 1 entry not present at index = %d\n", index);
   5.311 -                success = 0;
   5.312 -            }
   5.313 -            gpfn = l1e_get_pfn(l1e[index]);
   5.314 -            gpa = (l1e_get_intpte(l1e[index]) & PHYSICAL_ADDR_4K_MASK_LM) + 
   5.315 -                (gva & ~PHYSICAL_PAGE_4K_MASK);
   5.316 -            unmap_domain_page(l1e);
   5.317 -        }
   5.318 -
   5.319 -        if ( success != 1 ) /* error happened, jump out */
   5.320 -            break;
   5.321 -    }
   5.322 -
   5.323 -    gpa &= ~PAGE_NX_BIT; /* clear NX bit of guest physical address */
   5.324 -    HAP_PRINTK("success = %d, gva = %lx, gpa = %lx\n", success, gva, gpa);
   5.325 -
   5.326 -    return (!success ? INVALID_GFN : ((paddr_t)gpa >> PAGE_SHIFT));
   5.327 -#else
   5.328 -    printk("guest paging level (4) is greater than host paging level!\n");
   5.329 -    domain_crash(v->domain);
   5.330 -    return INVALID_GFN;
   5.331 -#endif
   5.332 -}
   5.333 -
   5.334 -/*
   5.335 - * Local variables:
   5.336 - * mode: C
   5.337 - * c-set-style: "BSD"
   5.338 - * c-basic-offset: 4
   5.339 - * tab-width: 4
   5.340 - * indent-tabs-mode: nil
   5.341 - * End:
   5.342 - */
   5.343 -