303 lines
11 KiB
Diff
303 lines
11 KiB
Diff
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 <asm/hvm/hvm.h>
|
|
#include <asm/hvm/support.h>
|
|
#include <asm/msr.h>
|
|
+#include <asm/hap.h>
|
|
#ifdef CONFIG_COMPAT
|
|
#include <compat/vcpu.h>
|
|
#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 <public/hvm/ioreq.h>
|
|
#include <public/version.h>
|
|
#include <public/memory.h>
|
|
+#include <asm/hap.h>
|
|
|
|
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 <xen/lib.h>
|
|
#include <xen/sched.h>
|
|
#include <asm/current.h>
|
|
+#include <asm/hap.h>
|
|
|
|
#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 <xen/init.h>
|
|
+#include <xen/config.h>
|
|
+#include <xen/types.h>
|
|
+#include <xen/mm.h>
|
|
+#include <xen/trace.h>
|
|
+#include <xen/sched.h>
|
|
+#include <xen/perfc.h>
|
|
+#include <xen/irq.h>
|
|
+#include <xen/domain_page.h>
|
|
+#include <xen/guest_access.h>
|
|
+#include <xen/keyhandler.h>
|
|
+#include <asm/event.h>
|
|
+#include <asm/page.h>
|
|
+#include <asm/current.h>
|
|
+#include <asm/flushtlb.h>
|
|
+#include <asm/hap.h>
|
|
|
|
/* 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 <xen/domain_page.h>
|
|
#include <asm/flushtlb.h>
|
|
|
|
+/************************************************/
|
|
+/* 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
|