# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID ea306829506c657565937916d0922aeab211f494
# Parent 602f5965e217ba986c22659c04b379e74be90c22
[IA64] fix ptc.ga virtualization
fix ptc.ga virtualization. Uninitialized vcpu doesn't need tlb flush.
ptc_ga_remote_func() calls vmx_vcpu_ptc_l() in IPI context.
I.e. vcpu may not equal to current. On the other hand vmx_vcpu_ptc_l()
assumes vcpu = current. remove the assumption.
Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
---
xen/arch/ia64/vmx/vmmu.c | 3 ++
xen/arch/ia64/vmx/vmx_phy_mode.c | 21 ++++++++++++++++++-
xen/arch/ia64/vmx/vtlb.c | 38 ++++++++++++++++++++++++++----------
xen/arch/ia64/xen/regionreg.c | 13 ++++++++++++
xen/arch/ia64/xen/vhpt.c | 12 ++++++++++-
xen/include/asm-ia64/regionreg.h | 1
xen/include/asm-ia64/vmx.h | 1
xen/include/asm-ia64/vmx_phy_mode.h | 1
8 files changed, 77 insertions(+), 13 deletions(-)
diff -r 602f5965e217 -r ea306829506c xen/arch/ia64/vmx/vmmu.c
--- a/xen/arch/ia64/vmx/vmmu.c Mon Jun 19 13:42:34 2006 -0600
+++ b/xen/arch/ia64/vmx/vmmu.c Mon Jun 19 13:45:42 2006 -0600
@@ -544,6 +544,9 @@ IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu,UIN
vcpu_get_rr(vcpu, va, &args.rid);
args.ps = ps;
for_each_vcpu (d, v) {
+ if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+ continue;
+
args.vcpu = v;
if (v->processor != vcpu->processor) {
int proc;
diff -r 602f5965e217 -r ea306829506c xen/arch/ia64/vmx/vmx_phy_mode.c
--- a/xen/arch/ia64/vmx/vmx_phy_mode.c Mon Jun 19 13:42:34 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_phy_mode.c Mon Jun 19 13:45:42 2006 -0600
@@ -137,13 +137,14 @@ vmx_init_all_rr(VCPU *vcpu)
#endif
}
+extern void * pal_vaddr;
+
void
vmx_load_all_rr(VCPU *vcpu)
{
unsigned long psr;
ia64_rr phy_rr;
- extern void * pal_vaddr;
local_irq_save(psr);
@@ -204,6 +205,24 @@ vmx_load_all_rr(VCPU *vcpu)
}
void
+vmx_load_rr7_and_pta(VCPU *vcpu)
+{
+ unsigned long psr;
+
+ local_irq_save(psr);
+
+ vmx_switch_rr7(vrrtomrr(vcpu,VMX(vcpu, vrr[VRN7])),
+ (void *)vcpu->domain->shared_info,
+ (void *)vcpu->arch.privregs,
+ (void *)vcpu->arch.vhpt.hash, pal_vaddr );
+ ia64_set_pta(vcpu->arch.arch_vmx.mpta);
+
+ ia64_srlz_d();
+ local_irq_restore(psr);
+ ia64_srlz_i();
+}
+
+void
switch_to_physical_rid(VCPU *vcpu)
{
UINT64 psr;
diff -r 602f5965e217 -r ea306829506c xen/arch/ia64/vmx/vtlb.c
--- a/xen/arch/ia64/vmx/vtlb.c Mon Jun 19 13:42:34 2006 -0600
+++ b/xen/arch/ia64/vmx/vtlb.c Mon Jun 19 13:45:42 2006 -0600
@@ -28,8 +28,10 @@
#include <asm/gcc_intrin.h>
#include <linux/interrupt.h>
#include <asm/vmx_vcpu.h>
+#include <asm/vmx_phy_mode.h>
#include <asm/vmmu.h>
#include <asm/tlbflush.h>
+#include <asm/regionreg.h>
#define MAX_CCH_LENGTH 40
thash_data_t *__alloc_chain(thash_cb_t *);
@@ -229,12 +231,13 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
* purge software guest tlb
*/
-static void vtlb_purge(thash_cb_t *hcb, u64 va, u64 ps)
-{
+static void vtlb_purge(VCPU *v, u64 va, u64 ps)
+{
+ thash_cb_t *hcb = &v->arch.vtlb;
thash_data_t *hash_table, *prev, *next;
u64 start, end, size, tag, rid, def_size;
ia64_rr vrr;
- vcpu_get_rr(current, va, &vrr.rrval);
+ vcpu_get_rr(v, va, &vrr.rrval);
rid = vrr.rid;
size = PSIZE(ps);
start = va & (-size);
@@ -263,16 +266,29 @@ static void vtlb_purge(thash_cb_t *hcb,
}
// machine_tlb_purge(va, ps);
}
+
+static void
+switch_rr7_and_pta(VCPU* v)
+{
+ if (VMX_DOMAIN(v))
+ vmx_load_rr7_and_pta(v);
+ else
+ load_region_reg7_and_pta(v);
+}
+
/*
* purge VHPT and machine TLB
*/
-static void vhpt_purge(thash_cb_t *hcb, u64 va, u64 ps)
-{
+static void vhpt_purge(VCPU *v, u64 va, u64 ps)
+{
+ //thash_cb_t *hcb = &v->arch.vhpt;
thash_data_t *hash_table, *prev, *next;
u64 start, end, size, tag;
size = PSIZE(ps);
start = va & (-size);
end = start + size;
+ if (current != v)
+ switch_rr7_and_pta(v);
while(start < end){
hash_table = (thash_data_t *)ia64_thash(start);
tag = ia64_ttag(start);
@@ -294,6 +310,8 @@ static void vhpt_purge(thash_cb_t *hcb,
start += PAGE_SIZE;
}
machine_tlb_purge(va, ps);
+ if (current != v)
+ switch_rr7_and_pta(current);
}
/*
@@ -413,8 +431,8 @@ void thash_purge_entries(VCPU *v, u64 va
void thash_purge_entries(VCPU *v, u64 va, u64 ps)
{
if(vcpu_quick_region_check(v->arch.tc_regions,va))
- vtlb_purge(&v->arch.vtlb, va, ps);
- vhpt_purge(&v->arch.vhpt, va, ps);
+ vtlb_purge(v, va, ps);
+ vhpt_purge(v, va, ps);
}
u64 translate_phy_pte(VCPU *v, u64 *pte, u64 itir, u64 va)
@@ -456,17 +474,17 @@ void thash_purge_and_insert(VCPU *v, u64
phy_pte = translate_phy_pte(v, &pte, itir, ifa);
if(ps==PAGE_SHIFT){
if(!(pte&VTLB_PTE_IO)){
- vhpt_purge(&v->arch.vhpt, ifa, ps);
+ vhpt_purge(v, ifa, ps);
vmx_vhpt_insert(&v->arch.vhpt, phy_pte, itir, ifa);
}
else{
- vhpt_purge(&v->arch.vhpt, ifa, ps);
+ vhpt_purge(v, ifa, ps);
vtlb_insert(&v->arch.vtlb, pte, itir, ifa);
vcpu_quick_region_set(PSCBX(v,tc_regions),ifa);
}
}
else{
- vhpt_purge(&v->arch.vhpt, ifa, ps);
+ vhpt_purge(v, ifa, ps);
vtlb_insert(&v->arch.vtlb, pte, itir, ifa);
vcpu_quick_region_set(PSCBX(v,tc_regions),ifa);
if(!(pte&VTLB_PTE_IO)){
diff -r 602f5965e217 -r ea306829506c xen/arch/ia64/xen/regionreg.c
--- a/xen/arch/ia64/xen/regionreg.c Mon Jun 19 13:42:34 2006 -0600
+++ b/xen/arch/ia64/xen/regionreg.c Mon Jun 19 13:45:42 2006 -0600
@@ -342,3 +342,16 @@ void load_region_regs(struct vcpu *v)
panic_domain(0,"load_region_regs: can't set! bad=%lx\n",bad);
}
}
+
+void load_region_reg7_and_pta(struct vcpu *v)
+{
+ unsigned long rr7;
+
+ ia64_set_pta(VHPT_ADDR | (1 << 8) | (VHPT_SIZE_LOG2 << 2) |
+ VHPT_ENABLED);
+
+ // TODO: These probably should be validated
+ rr7 = VCPU(v,rrs[7]);
+ if (!set_one_rr(0xe000000000000000L, rr7))
+ panic_domain(0, "%s: can't set!\n", __func__);
+}
diff -r 602f5965e217 -r ea306829506c xen/arch/ia64/xen/vhpt.c
--- a/xen/arch/ia64/xen/vhpt.c Mon Jun 19 13:42:34 2006 -0600
+++ b/xen/arch/ia64/xen/vhpt.c Mon Jun 19 13:45:42 2006 -0600
@@ -153,7 +153,10 @@ void domain_flush_vtlb_all (void)
int cpu = smp_processor_id ();
struct vcpu *v;
- for_each_vcpu (current->domain, v)
+ for_each_vcpu (current->domain, v) {
+ if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+ continue;
+
if (v->processor == cpu)
vcpu_flush_vtlb_all ();
else
@@ -161,6 +164,7 @@ void domain_flush_vtlb_all (void)
(v->processor,
(void(*)(void *))vcpu_flush_vtlb_all,
NULL,1,1);
+ }
}
static void cpu_flush_vhpt_range (int cpu, u64 vadr, u64 addr_range)
@@ -198,6 +202,9 @@ void domain_flush_vtlb_range (struct dom
#endif
for_each_vcpu (d, v) {
+ if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+ continue;
+
/* Purge TC entries.
FIXME: clear only if match. */
vcpu_purge_tr_entry(&PSCBX(v,dtlb));
@@ -206,6 +213,9 @@ void domain_flush_vtlb_range (struct dom
smp_mb();
for_each_vcpu (d, v) {
+ if (!test_bit(_VCPUF_initialised, &v->vcpu_flags))
+ continue;
+
/* Invalidate VHPT entries. */
cpu_flush_vhpt_range (v->processor, vadr, addr_range);
}
diff -r 602f5965e217 -r ea306829506c xen/include/asm-ia64/regionreg.h
--- a/xen/include/asm-ia64/regionreg.h Mon Jun 19 13:42:34 2006 -0600
+++ b/xen/include/asm-ia64/regionreg.h Mon Jun 19 13:45:42 2006 -0600
@@ -79,5 +79,6 @@ extern int set_metaphysical_rr0(void);
extern int set_metaphysical_rr0(void);
extern void load_region_regs(struct vcpu *v);
+extern void load_region_reg7_and_pta(struct vcpu *v);
#endif /* !_REGIONREG_H_ */
diff -r 602f5965e217 -r ea306829506c xen/include/asm-ia64/vmx.h
--- a/xen/include/asm-ia64/vmx.h Mon Jun 19 13:42:34 2006 -0600
+++ b/xen/include/asm-ia64/vmx.h Mon Jun 19 13:45:42 2006 -0600
@@ -37,7 +37,6 @@ extern void vmx_setup_platform(struct do
extern void vmx_setup_platform(struct domain *d, struct vcpu_guest_context *c);
extern void vmx_wait_io(void);
extern void vmx_io_assist(struct vcpu *v);
-extern void vmx_load_all_rr(struct vcpu *vcpu);
extern void panic_domain(struct pt_regs *regs, const char *fmt, ...);
extern int ia64_hypercall (struct pt_regs *regs);
extern void vmx_save_state(struct vcpu *v);
diff -r 602f5965e217 -r ea306829506c xen/include/asm-ia64/vmx_phy_mode.h
--- a/xen/include/asm-ia64/vmx_phy_mode.h Mon Jun 19 13:42:34 2006 -0600
+++ b/xen/include/asm-ia64/vmx_phy_mode.h Mon Jun 19 13:45:42 2006 -0600
@@ -96,6 +96,7 @@ extern void recover_if_physical_mode(VCP
extern void recover_if_physical_mode(VCPU *vcpu);
extern void vmx_init_all_rr(VCPU *vcpu);
extern void vmx_load_all_rr(VCPU *vcpu);
+extern void vmx_load_rr7_and_pta(VCPU *vcpu);
extern void physical_tlb_miss(VCPU *vcpu, u64 vadr);
/*
* No sanity check here, since all psr changes have been
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|