Index: xen-3.0.4-testing/xen/arch/x86/domain.c =================================================================== --- xen-3.0.4-testing.orig/xen/arch/x86/domain.c +++ xen-3.0.4-testing/xen/arch/x86/domain.c @@ -41,6 +41,7 @@ #include #include #include +#include #ifdef CONFIG_COMPAT #include #endif @@ -334,6 +335,8 @@ int vcpu_initialise(struct vcpu *v) pae_l3_cache_init(&v->arch.pae_l3_cache); + hap_vcpu_init(v); + /* This should move to arch_domain_create(). */ if ( !is_idle_domain(d) && (v->vcpu_id == 0) ) pit_init(v, cpu_khz); @@ -470,6 +473,9 @@ void arch_domain_destroy(struct domain * hvm_domain_destroy(d); } + for_each_vcpu ( d, v ) + hap_vcpu_destroy(v); + shadow_final_teardown(d); free_xenheap_pages( Index: xen-3.0.4-testing/xen/arch/x86/hvm/hvm.c =================================================================== --- xen-3.0.4-testing.orig/xen/arch/x86/hvm/hvm.c +++ xen-3.0.4-testing/xen/arch/x86/hvm/hvm.c @@ -49,6 +49,7 @@ #include #include #include +#include int hvm_enabled = 0; @@ -339,7 +340,7 @@ static int __hvm_copy(void *buf, paddr_t count = min_t(int, PAGE_SIZE - (addr & ~PAGE_MASK), todo); if ( virt ) - mfn = get_mfn_from_gpfn(shadow_gva_to_gfn(current, addr)); + mfn = get_mfn_from_gpfn(hap_gva_to_gfn(current, addr)); else mfn = get_mfn_from_gpfn(addr >> PAGE_SHIFT); Index: xen-3.0.4-testing/xen/arch/x86/hvm/platform.c =================================================================== --- xen-3.0.4-testing.orig/xen/arch/x86/hvm/platform.c +++ xen-3.0.4-testing/xen/arch/x86/hvm/platform.c @@ -37,6 +37,7 @@ #include #include #include +#include #define DECODE_success 1 #define DECODE_failure 0 @@ -793,7 +794,7 @@ void send_pio_req(unsigned long port, un if ( value_is_ptr ) /* get physical address of data */ { if ( hvm_paging_enabled(current) ) - p->data = shadow_gva_to_gpa(current, value); + p->data = hap_gva_to_gpa(current, value); else p->data = value; /* guest VA == guest PA */ } @@ -849,7 +850,7 @@ static void send_mmio_req(unsigned char if ( value_is_ptr ) { if ( hvm_paging_enabled(v) ) - p->data = shadow_gva_to_gpa(v, value); + p->data = hap_gva_to_gpa(v, value); else p->data = value; /* guest VA == guest PA */ } @@ -965,7 +966,7 @@ void handle_mmio(unsigned long gpa) if ( ad_size == WORD ) addr &= 0xFFFF; addr += hvm_get_segment_base(v, x86_seg_es); - if ( shadow_gva_to_gpa(v, addr) == gpa ) + if ( hap_gva_to_gpa(v, addr) == gpa ) { enum x86_segment seg; Index: xen-3.0.4-testing/xen/arch/x86/mm/hap/hap.c =================================================================== --- xen-3.0.4-testing.orig/xen/arch/x86/mm/hap/hap.c +++ xen-3.0.4-testing/xen/arch/x86/mm/hap/hap.c @@ -18,7 +18,21 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* initialize hardware assisted paging. It checks whether hap option is enabled * in Xen boot option. @@ -26,6 +40,20 @@ int opt_hap_enabled = 0; boolean_param("hap", opt_hap_enabled); +/*************************************************/ +/* hap functions */ +/*************************************************/ +void hap_vcpu_init(struct vcpu *v) +{ + v->arch.hap_activated = 0; /* not activated at the beginning */ +} + +void hap_vcpu_destroy(struct vcpu *v) +{ + /* nothing to do */ +} + + /* * Local variables: * mode: C Index: xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/npt.c =================================================================== --- xen-3.0.4-testing.orig/xen/arch/x86/mm/hap/npt/npt.c +++ xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/npt.c @@ -34,6 +34,49 @@ #include "page-guest32.h" extern int opt_hap_enabled; + +/* Forward Declaration */ +static paddr_t npt_gva_to_gpa_real_mode(struct vcpu *v, unsigned long gva); +static paddr_t npt_gva_to_gpa_protected_mode(struct vcpu *v, + unsigned long gva); +static paddr_t npt_gva_to_gpa_pae_mode(struct vcpu *v, unsigned long gva); +static paddr_t npt_gva_to_gpa_long_mode(struct vcpu *v, unsigned long gva); +static unsigned long npt_gva_to_gfn_real_mode(struct vcpu *v, + unsigned long gva); +static unsigned long npt_gva_to_gfn_protected_mode(struct vcpu *v, + unsigned long gva); +static unsigned long npt_gva_to_gfn_pae_mode(struct vcpu *v, + unsigned long gva); +static unsigned long npt_gva_to_gfn_long_mode(struct vcpu *v, + unsigned long gva); + +/*******************************************/ +/* global variables */ +/*******************************************/ +struct hap_vcpu NPT_REAL_MODE_HANDLER = { + .guest_page_level = 1, + .gva_to_gfn = npt_gva_to_gfn_real_mode, + .gva_to_gpa = npt_gva_to_gpa_real_mode +}; + +struct hap_vcpu NPT_PROTECTED_MODE_HANDLER = { + .guest_page_level = 2, + .gva_to_gfn = npt_gva_to_gfn_protected_mode, + .gva_to_gpa = npt_gva_to_gpa_protected_mode +}; + +struct hap_vcpu NPT_PAE_MODE_HANDLER = { + .guest_page_level = 3, + .gva_to_gfn = npt_gva_to_gfn_pae_mode, + .gva_to_gpa = npt_gva_to_gpa_pae_mode +}; + +struct hap_vcpu NPT_LONG_MODE_HANDLER = { + .guest_page_level = 4, + .gva_to_gfn = npt_gva_to_gfn_long_mode, + .gva_to_gpa = npt_gva_to_gpa_long_mode +}; + /*******************************************/ /* Platform Specific Functions */ /*******************************************/ @@ -350,7 +393,9 @@ void npt_detect(void) /* check CPUID for nested paging support */ cpuid(0x8000000A, &eax, &ebx, &ecx, &edx); - if ( !(edx & 0x01) && opt_hap_enabled ) { + if ( edx & 0x01 ) { + } + else if ( opt_hap_enabled ) { printk(" nested paging is not supported by this CPU.\n"); opt_hap_enabled = 0; /* no nested paging, we disable op_hap_enabled */ } @@ -366,23 +411,19 @@ void npt_set_guest_paging_levels(struct switch(levels) { case 1: NPT_PRINTK("Install real mode guest with ID = %d\n", v->vcpu_id); - v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_real_mode; - v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_real_mode; + v->arch.hap_mode = &NPT_REAL_MODE_HANDLER; break; case 2: NPT_PRINTK("Install 32-bit non-PAE guest with ID = %d\n", v->vcpu_id); - v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_protected_mode; - v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_protected_mode; + v->arch.hap_mode = &NPT_PROTECTED_MODE_HANDLER; break; case 3: NPT_PRINTK("Install 32-bit PAE guest with ID = %d\n", v->vcpu_id); - v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_pae_mode; - v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_pae_mode; + v->arch.hap_mode = &NPT_PAE_MODE_HANDLER; break; case 4: NPT_PRINTK("Install 64-bit guest with ID = %d\n", v->vcpu_id); - v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_long_mode; - v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_long_mode; + v->arch.hap_mode = &NPT_LONG_MODE_HANDLER; break; default: printk("Un-supported guest paging level: %d\n", levels); Index: xen-3.0.4-testing/xen/include/asm-x86/domain.h =================================================================== --- xen-3.0.4-testing.orig/xen/include/asm-x86/domain.h +++ xen-3.0.4-testing/xen/include/asm-x86/domain.h @@ -208,8 +208,8 @@ struct arch_vcpu unsigned long shadow_ldt_mapcnt; struct shadow_vcpu shadow; - - unsigned int hap_activated:1; /* hardware assisted paging */ + struct hap_vcpu *hap_mode; /* hardware assisted paging support */ + unsigned int hap_activated:1; } __cacheline_aligned; /* shorthands to improve code legibility */ Index: xen-3.0.4-testing/xen/include/asm-x86/hap.h =================================================================== --- xen-3.0.4-testing.orig/xen/include/asm-x86/hap.h +++ xen-3.0.4-testing/xen/include/asm-x86/hap.h @@ -26,6 +26,25 @@ #include #include +/************************************************/ +/* HAP data structure */ +/************************************************/ +struct hap_vcpu { + int guest_page_level; + + /* function pointers */ + int (*host_pgfault )(struct vcpu *v, unsigned long va, + struct cpu_user_regs *regs); + unsigned long (*gva_to_gfn )(struct vcpu *v, unsigned long gva); + paddr_t (*gva_to_gpa )(struct vcpu *v, unsigned long gva); +}; + +/************************************************/ +/* HAP interface to Xen */ +/************************************************/ +void hap_vcpu_init(struct vcpu *v); +void hap_vcpu_destroy(struct vcpu *v); + static inline unsigned int hap_is_activated(struct vcpu *v) { return v->arch.hap_activated; @@ -41,6 +60,24 @@ static inline void hap_deactivate(struct v->arch.hap_activated = 0; } +static inline paddr_t hap_gva_to_gpa(struct vcpu *v, unsigned long gva) +{ + if ( v->arch.hap_activated ) + return v->arch.hap_mode->gva_to_gpa(v, gva); + else + return shadow_gva_to_gpa(v, gva); +} + +static inline unsigned long hap_gva_to_gfn(struct vcpu *v, unsigned long gva) +{ + if ( v->arch.hap_activated ) + return v->arch.hap_mode->gva_to_gfn(v, gva); + else + return shadow_gva_to_gfn(v, gva); +} +/************************************************/ +/* nested paging interface */ +/************************************************/ void npt_update_guest_paging_mode(struct vcpu *v); void npt_detect(void); #endif