[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@valinux.co.jp>
This commit is contained in:
awilliam@xenbuild.aw committed 2006-06-19 13:45:42 -06:00
1 parent 67799254d1
commit afe2dd0bc8
8 files changed
+75 -11

No files matched your search

+3
View File
@@ -544,6 +544,9 @@ IA64FAULT vmx_vcpu_ptc_ga(VCPU *vcpu,UINT64 va,UINT64 ps)
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;
+20 -1
View File
@@ -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);
@@ -203,6 +204,24 @@ vmx_load_all_rr(VCPU *vcpu)
ia64_srlz_i();
}
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)
{
+26 -8
View File
@@ -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, u64 va, u64 ps)
}
// 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, u64 va, u64 ps)
start += PAGE_SIZE;
}
machine_tlb_purge(va, ps);
if (current != v)
switch_rr7_and_pta(current);
}
/*
@@ -413,8 +431,8 @@ int vtr_find_overlap(VCPU *vcpu, u64 va, u64 ps, int is_data)
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 pte, u64 itir, u64 ifa)
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)){
+13
View File
@@ -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__);
}
+11 -1
View File
@@ -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 domain *d, u64 vadr, u64 addr_range)
#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 domain *d, u64 vadr, u64 addr_range)
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);
}
+1
View File
@@ -79,5 +79,6 @@ extern void init_all_rr(struct vcpu *v);
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_ */
-1
View File
@@ -37,7 +37,6 @@ extern void vmx_load_state(struct vcpu *v);
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);
+1
View File
@@ -96,6 +96,7 @@ extern void prepare_if_physical_mode(VCPU *vcpu);
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
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.