ia64/xen-unstable

changeset 7727:d7bcc7bbf981

Fix region0 virtual accesses
Signed-off by: Dan Magenheimer <dan.magenheimer@hp.com>
author djm@kirby.fc.hp.com
date Fri Nov 11 12:51:08 2005 -0600 (2005-11-11)
parents 2f98977d9f85
children 12d4d2dc06a2
files xen/arch/ia64/xen/regionreg.c xen/arch/ia64/xen/vcpu.c
line diff
     1.1 --- a/xen/arch/ia64/xen/regionreg.c	Thu Nov 10 15:24:29 2005 -0600
     1.2 +++ b/xen/arch/ia64/xen/regionreg.c	Fri Nov 11 12:51:08 2005 -0600
     1.3 @@ -190,12 +190,6 @@ set_rr(unsigned long rr, unsigned long r
     1.4  	ia64_srlz_d();
     1.5  }
     1.6  
     1.7 -unsigned long
     1.8 -get_rr(unsigned long rr)
     1.9 -{
    1.10 -	return vmUnmangleRID(ia64_get_rr(rr));
    1.11 -}
    1.12 -
    1.13  static inline int validate_page_size(unsigned long ps)
    1.14  {
    1.15  	switch(ps) {
     2.1 --- a/xen/arch/ia64/xen/vcpu.c	Thu Nov 10 15:24:29 2005 -0600
     2.2 +++ b/xen/arch/ia64/xen/vcpu.c	Fri Nov 11 12:51:08 2005 -0600
     2.3 @@ -1256,7 +1256,6 @@ IA64FAULT vcpu_thash(VCPU *vcpu, UINT64 
     2.4  	UINT64 Mask = (1L << pta_sz) - 1;
     2.5  	UINT64 Mask_60_15 = (Mask >> 15) & 0x3fffffffffff;
     2.6  	UINT64 compMask_60_15 = ~Mask_60_15;
     2.7 -	//UINT64 rr_ps = RR_TO_PS(get_rr(vadr));
     2.8  	UINT64 rr_ps = vcpu_get_rr_ps(vcpu,vadr);
     2.9  	UINT64 VHPT_offset = (vadr >> rr_ps) << 3;
    2.10  	UINT64 VHPT_addr1 = vadr & 0xe000000000000000L;
    2.11 @@ -1287,27 +1286,37 @@ unsigned long fast_vhpt_translate_count 
    2.12  unsigned long recover_to_page_fault_count = 0;
    2.13  unsigned long recover_to_break_fault_count = 0;
    2.14  
    2.15 +int warn_region0_address = 0; // FIXME later: tie to a boot parameter?
    2.16 +
    2.17  IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pteval, UINT64 *itir, UINT64 *iha)
    2.18  {
    2.19  	unsigned long pta, pte, rid, rr;
    2.20  	int i;
    2.21  	TR_ENTRY *trp;
    2.22  
    2.23 -	if (!(address >> 61)) {
    2.24 -		if (!PSCB(vcpu,metaphysical_mode)) {
    2.25 -			REGS *regs = vcpu_regs(vcpu);
    2.26 -			unsigned long viip = PSCB(vcpu,iip);
    2.27 -			unsigned long vipsr = PSCB(vcpu,ipsr);
    2.28 -			unsigned long iip = regs->cr_iip;
    2.29 -			unsigned long ipsr = regs->cr_ipsr;
    2.30 -			printk("vcpu_translate: bad address %p, viip=%p, vipsr=%p, iip=%p, ipsr=%p continuing\n", address, viip, vipsr, iip, ipsr);
    2.31 +	if (PSCB(vcpu,metaphysical_mode)) {
    2.32 +		unsigned long region = address >> 61;
    2.33 +		// dom0 may generate an uncacheable physical address (msb=1)
    2.34 +		if (region && ((region != 4) || (vcpu->domain != dom0))) {
    2.35 +// FIXME: This seems to happen even though it shouldn't.  Need to track
    2.36 +// this down, but since it has been apparently harmless, just flag it for now
    2.37 +//			panic_domain(vcpu_regs(vcpu),
    2.38 +			printk(
    2.39 +			 "vcpu_translate: bad physical address: %p\n",address);
    2.40  		}
    2.41 -
    2.42  		*pteval = (address & _PAGE_PPN_MASK) | __DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX;
    2.43  		*itir = PAGE_SHIFT << 2;
    2.44  		phys_translate_count++;
    2.45  		return IA64_NO_FAULT;
    2.46  	}
    2.47 +	else if (!(address >> 61) && warn_region0_address) {
    2.48 +		REGS *regs = vcpu_regs(vcpu);
    2.49 +		unsigned long viip = PSCB(vcpu,iip);
    2.50 +		unsigned long vipsr = PSCB(vcpu,ipsr);
    2.51 +		unsigned long iip = regs->cr_iip;
    2.52 +		unsigned long ipsr = regs->cr_ipsr;
    2.53 +		printk("vcpu_translate: bad address %p, viip=%p, vipsr=%p, iip=%p, ipsr=%p continuing\n", address, viip, vipsr, iip, ipsr);
    2.54 +	}
    2.55  
    2.56  	rr = PSCB(vcpu,rrs)[address>>61];
    2.57  	rid = rr & RR_RID_MASK;
    2.58 @@ -1685,7 +1694,7 @@ static void vcpu_set_tr_entry(TR_ENTRY *
    2.59  	UINT64 ps;
    2.60  
    2.61  	trp->itir = itir;
    2.62 -	trp->rid = virtualize_rid(current, get_rr(ifa) & RR_RID_MASK);
    2.63 +	trp->rid = VCPU(current,rrs[ifa>>61]) & RR_RID_MASK;
    2.64  	trp->p = 1;
    2.65  	ps = trp->ps;
    2.66  	trp->page_flags = pte;
    2.67 @@ -1760,7 +1769,8 @@ void vcpu_itc_no_srlz(VCPU *vcpu, UINT64
    2.68  	// PAGE_SIZE mapping in the vhpt for now, else purging is complicated
    2.69  	else vhpt_insert(vaddr,pte,PAGE_SHIFT<<2);
    2.70  #endif
    2.71 -	if ((mp_pte == -1UL) || (IorD & 0x4)) return;  // don't place in 1-entry TLB
    2.72 +	if ((mp_pte == -1UL) || (IorD & 0x4)) // don't place in 1-entry TLB
    2.73 +		return;
    2.74  	if (IorD & 0x1) {
    2.75  		vcpu_set_tr_entry(&PSCBX(vcpu,itlb),pte,ps<<2,vaddr);
    2.76  		PSCBX(vcpu,itlb_pte) = mp_pte;
    2.77 @@ -1775,6 +1785,7 @@ IA64FAULT vcpu_itc_d(VCPU *vcpu, UINT64 
    2.78  {
    2.79  	unsigned long pteval, logps = (itir >> 2) & 0x3f;
    2.80  	unsigned long translate_domain_pte(UINT64,UINT64,UINT64);
    2.81 +	BOOLEAN swap_rr0 = (!(ifa>>61) && PSCB(vcpu,metaphysical_mode));
    2.82  
    2.83  	if (logps < PAGE_SHIFT) {
    2.84  		printf("vcpu_itc_d: domain trying to use smaller page size!\n");
    2.85 @@ -1784,7 +1795,9 @@ IA64FAULT vcpu_itc_d(VCPU *vcpu, UINT64 
    2.86  	//itir = (itir & ~0xfc) | (PAGE_SHIFT<<2); // ignore domain's pagesize
    2.87  	pteval = translate_domain_pte(pte,ifa,itir);
    2.88  	if (!pteval) return IA64_ILLOP_FAULT;
    2.89 +	if (swap_rr0) set_one_rr(0x0,PSCB(vcpu,rrs[0]));
    2.90  	vcpu_itc_no_srlz(vcpu,2,ifa,pteval,pte,logps);
    2.91 +	if (swap_rr0) set_metaphysical_rr0();
    2.92  	return IA64_NO_FAULT;
    2.93  }
    2.94  
    2.95 @@ -1792,6 +1805,7 @@ IA64FAULT vcpu_itc_i(VCPU *vcpu, UINT64 
    2.96  {
    2.97  	unsigned long pteval, logps = (itir >> 2) & 0x3f;
    2.98  	unsigned long translate_domain_pte(UINT64,UINT64,UINT64);
    2.99 +	BOOLEAN swap_rr0 = (!(ifa>>61) && PSCB(vcpu,metaphysical_mode));
   2.100  
   2.101  	// FIXME: validate ifa here (not in Xen space), COULD MACHINE CHECK!
   2.102  	if (logps < PAGE_SHIFT) {
   2.103 @@ -1803,7 +1817,9 @@ IA64FAULT vcpu_itc_i(VCPU *vcpu, UINT64 
   2.104  	pteval = translate_domain_pte(pte,ifa,itir);
   2.105  	// FIXME: what to do if bad physical address? (machine check?)
   2.106  	if (!pteval) return IA64_ILLOP_FAULT;
   2.107 +	if (swap_rr0) set_one_rr(0x0,PSCB(vcpu,rrs[0]));
   2.108  	vcpu_itc_no_srlz(vcpu, 1,ifa,pteval,pte,logps);
   2.109 +	if (swap_rr0) set_metaphysical_rr0();
   2.110  	return IA64_NO_FAULT;
   2.111  }
   2.112