xen/npt-windows-bug.patch

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