mirror of
https://github.com/xen-project/xen.git
synced 2026-10-30 03:00:05 +01:00
[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:
1 parent
67799254d1
commit
afe2dd0bc8
8 files changed
+75
-11
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)){
|
||||
|
||||
@@ -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__);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||