# HG changeset patch
# User awilliam@xxxxxxxxxxxx
# Date 1174404744 21600
# Node ID c07b1dc6dc6d3b8ee2836090510dcbdf3be4ad74
# Parent 2dbee4f1ee633a69483290fb68e9f482f4ce4214
[IA64] fix access rights in VHPT when itr.ar!=dtr.ar
This is a workaround patch for Windows 2003 Server.
Windows (vcpu>=2) set itr[1].ar=3(RWX) but dtr[1].ar=2(RW).
It causes an impossible INST_ACCESS_RIGHTS interruption via VHPT
which is used for emulating TR.
Surprisingly, windows ordinarily accepts this interruption.
But windows sometimes crashes with the message 'PANIC_STACK_SWITCH'
owing to this interruption.
Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>
---
xen/arch/ia64/vmx/vmx_process.c | 5 +++++
xen/arch/ia64/vmx/vtlb.c | 31 +++++++++++++++++++++++++++++++
xen/include/asm-ia64/vmmu.h | 2 ++
3 files changed, 38 insertions(+)
diff -r 2dbee4f1ee63 -r c07b1dc6dc6d xen/arch/ia64/vmx/vmx_process.c
--- a/xen/arch/ia64/vmx/vmx_process.c Tue Mar 20 09:24:02 2007 -0600
+++ b/xen/arch/ia64/vmx/vmx_process.c Tue Mar 20 09:32:24 2007 -0600
@@ -92,6 +92,11 @@ void vmx_reflect_interruption(u64 ifa, u
switch (vec) {
+ case 22: // IA64_INST_ACCESS_RIGHTS_VECTOR
+ if (vhpt_access_rights_fixup(vcpu, ifa, 0))
+ return;
+ break;
+
case 25: // IA64_DISABLED_FPREG_VECTOR
if (FP_PSR(vcpu) & IA64_PSR_DFH) {
diff -r 2dbee4f1ee63 -r c07b1dc6dc6d xen/arch/ia64/vmx/vtlb.c
--- a/xen/arch/ia64/vmx/vtlb.c Tue Mar 20 09:24:02 2007 -0600
+++ b/xen/arch/ia64/vmx/vtlb.c Tue Mar 20 09:32:24 2007 -0600
@@ -196,6 +196,37 @@ void thash_vhpt_insert(VCPU *v, u64 pte,
ia64_srlz_i();
}
}
+
+int vhpt_access_rights_fixup(VCPU *v, u64 ifa, int is_data)
+{
+ thash_data_t *trp, *data;
+ u64 ps, tag, mask;
+
+ trp = __vtr_lookup(v, ifa, is_data);
+ if (trp) {
+ ps = _REGION_PAGE_SIZE(ia64_get_rr(ifa));
+ if (trp->ps < ps)
+ return 0;
+ ifa = PAGEALIGN(ifa, ps);
+ data = (thash_data_t *)ia64_thash(ifa);
+ tag = ia64_ttag(ifa);
+ do {
+ if (data->etag == tag) {
+ mask = trp->page_flags & PAGE_FLAGS_AR_PL_MASK;
+ if (mask != (data->page_flags & PAGE_FLAGS_AR_PL_MASK)) {
+ data->page_flags &= ~PAGE_FLAGS_AR_PL_MASK;
+ data->page_flags |= mask;
+ machine_tlb_purge(ifa, ps);
+ return 1;
+ }
+ return 0;
+ }
+ data = data->next;
+ } while(data);
+ }
+ return 0;
+}
+
/*
* vhpt lookup
*/
diff -r 2dbee4f1ee63 -r c07b1dc6dc6d xen/include/asm-ia64/vmmu.h
--- a/xen/include/asm-ia64/vmmu.h Tue Mar 20 09:24:02 2007 -0600
+++ b/xen/include/asm-ia64/vmmu.h Tue Mar 20 09:32:24 2007 -0600
@@ -291,6 +291,7 @@ extern int thash_lock_tc(thash_cb_t *hcb
#define ITIR_RV_MASK (((1UL<<32)-1)<<32 | 0x3)
#define PAGE_FLAGS_RV_MASK (0x2 | (0x3UL<<50)|(((1UL<<11)-1)<<53))
+#define PAGE_FLAGS_AR_PL_MASK ((0x7UL<<9)|(0x3UL<<7))
extern u64 machine_ttag(PTA pta, u64 va);
extern u64 machine_thash(PTA pta, u64 va);
extern void purge_machine_tc_by_domid(domid_t domid);
@@ -309,6 +310,7 @@ extern void thash_vhpt_insert(struct vcp
extern void thash_vhpt_insert(struct vcpu *v, u64 pte, u64 itir, u64 ifa,
int type);
extern u64 guest_vhpt_lookup(u64 iha, u64 *pte);
+extern int vhpt_access_rights_fixup(struct vcpu *v, u64 ifa, int is_data);
static inline void vmx_vcpu_set_tr (thash_data_t *trp, u64 pte, u64 itir, u64
va, u64 rid)
{
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|