direct-io.hg

changeset 10598:f8310e19fcaf

[IA64] check address clash with Xen for itc/ptc/itr/ptr

Panic domain if the address is within the Xen virtual space.

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author awilliam@lappy
date Tue Jun 20 16:29:59 2006 -0600 (2006-06-20)
parents 668a225a1df8
children 8314141cfe54
files xen/arch/ia64/xen/vcpu.c
line diff
     1.1 --- a/xen/arch/ia64/xen/vcpu.c	Tue Jun 20 16:21:13 2006 -0600
     1.2 +++ b/xen/arch/ia64/xen/vcpu.c	Tue Jun 20 16:29:59 2006 -0600
     1.3 @@ -174,7 +174,7 @@ void vcpu_init_regs (struct vcpu *v)
     1.4  		VCPU(v, banknum) = 1;
     1.5  		VCPU(v, metaphysical_mode) = 1;
     1.6  		VCPU(v, interrupt_mask_addr) =
     1.7 -		    (uint64_t)SHAREDINFO_ADDR + INT_ENABLE_OFFSET(v);
     1.8 +		    v->domain->arch.shared_info_va + INT_ENABLE_OFFSET(v);
     1.9  		VCPU(v, itv) = (1 << 16); /* timer vector masked */
    1.10  	}
    1.11  
    1.12 @@ -1344,6 +1344,21 @@ static inline int range_overlap (u64 b1,
    1.13  	return (b1 <= e2) && (e1 >= b2);
    1.14  }
    1.15  
    1.16 +/* Crash domain if [base, base + page_size] and Xen virtual space overlaps.
    1.17 +   Note: LSBs of base inside page_size are ignored.  */
    1.18 +static inline void
    1.19 +check_xen_space_overlap (const char *func, u64 base, u64 page_size)
    1.20 +{
    1.21 +	/* Mask LSBs of base.  */
    1.22 +	base &= ~(page_size - 1);
    1.23 +
    1.24 +	/* FIXME: ideally an MCA should be generated...  */
    1.25 +	if (range_overlap (XEN_VIRT_SPACE_LOW, XEN_VIRT_SPACE_HIGH,
    1.26 +			   base, base + page_size))
    1.27 +		panic_domain (NULL, "%s on Xen virtual space (%lx)\n",
    1.28 +			      func, base);
    1.29 +}
    1.30 +
    1.31  // FIXME: also need to check && (!trp->key || vcpu_pkr_match(trp->key))
    1.32  static inline int vcpu_match_tr_entry_no_p(TR_ENTRY *trp, UINT64 ifa, UINT64 rid)
    1.33  {
    1.34 @@ -1472,7 +1487,7 @@ again:
    1.35  			(gip & ((1 << tr.ps) - 1));
    1.36  	}
    1.37  	
    1.38 -	vaddr = domain_mpa_to_imva(vcpu->domain, gpip);
    1.39 +	vaddr = (unsigned long)domain_mpa_to_imva(vcpu->domain, gpip);
    1.40  	page = virt_to_page(vaddr);
    1.41  	if (get_page(page, vcpu->domain) == 0) {
    1.42  		if (page_get_owner(page) != vcpu->domain) {
    1.43 @@ -1950,13 +1965,13 @@ void vcpu_itc_no_srlz(VCPU *vcpu, UINT64
    1.44  	unsigned long psr;
    1.45  	unsigned long ps = (vcpu->domain==dom0) ? logps : PAGE_SHIFT;
    1.46  
    1.47 -	// FIXME: validate ifa here (not in Xen space), COULD MACHINE CHECK!
    1.48 +	check_xen_space_overlap ("itc", vaddr, 1UL << logps);
    1.49 +
    1.50  	// FIXME, must be inlined or potential for nested fault here!
    1.51 -	if ((vcpu->domain==dom0) && (logps < PAGE_SHIFT)) {
    1.52 -		printf("vcpu_itc_no_srlz: domain0 use of smaller page size!\n");
    1.53 -		//FIXME: kill domain here
    1.54 -		while(1);
    1.55 -	}
    1.56 +	if ((vcpu->domain==dom0) && (logps < PAGE_SHIFT))
    1.57 +		panic_domain (NULL, "vcpu_itc_no_srlz: domain trying to use "
    1.58 + 			      "smaller page size!\n");
    1.59 +
    1.60  #ifdef CONFIG_XEN_IA64_DOM0_VP
    1.61  	BUG_ON(logps > PAGE_SHIFT);
    1.62  #endif
    1.63 @@ -1993,11 +2008,10 @@ IA64FAULT vcpu_itc_d(VCPU *vcpu, UINT64 
    1.64  	BOOLEAN swap_rr0 = (!(ifa>>61) && PSCB(vcpu,metaphysical_mode));
    1.65  	struct p2m_entry entry;
    1.66  
    1.67 -	if (logps < PAGE_SHIFT) {
    1.68 -		printf("vcpu_itc_d: domain trying to use smaller page size!\n");
    1.69 -		//FIXME: kill domain here
    1.70 -		while(1);
    1.71 -	}
    1.72 +	if (logps < PAGE_SHIFT)
    1.73 +		panic_domain (NULL, "vcpu_itc_d: domain trying to use "
    1.74 + 			      "smaller page size!\n");
    1.75 +
    1.76  again:
    1.77  	//itir = (itir & ~0xfc) | (PAGE_SHIFT<<2); // ignore domain's pagesize
    1.78  	pteval = translate_domain_pte(pte, ifa, itir, &logps, &entry);
    1.79 @@ -2018,16 +2032,12 @@ IA64FAULT vcpu_itc_i(VCPU *vcpu, UINT64 
    1.80  	BOOLEAN swap_rr0 = (!(ifa>>61) && PSCB(vcpu,metaphysical_mode));
    1.81  	struct p2m_entry entry;
    1.82  
    1.83 -	// FIXME: validate ifa here (not in Xen space), COULD MACHINE CHECK!
    1.84 -	if (logps < PAGE_SHIFT) {
    1.85 -		printf("vcpu_itc_i: domain trying to use smaller page size!\n");
    1.86 -		//FIXME: kill domain here
    1.87 -		while(1);
    1.88 -	}
    1.89 +	if (logps < PAGE_SHIFT)
    1.90 +		panic_domain (NULL, "vcpu_itc_i: domain trying to use "
    1.91 + 			      "smaller page size!\n");
    1.92  again:
    1.93  	//itir = (itir & ~0xfc) | (PAGE_SHIFT<<2); // ignore domain's pagesize
    1.94  	pteval = translate_domain_pte(pte, ifa, itir, &logps, &entry);
    1.95 -	// FIXME: what to do if bad physical address? (machine check?)
    1.96  	if (!pteval) return IA64_ILLOP_FAULT;
    1.97  	if (swap_rr0) set_one_rr(0x0,PSCB(vcpu,rrs[0]));
    1.98  	vcpu_itc_no_srlz(vcpu, 1,ifa,pteval,pte,logps);
    1.99 @@ -2043,6 +2053,8 @@ IA64FAULT vcpu_ptc_l(VCPU *vcpu, UINT64 
   1.100  {
   1.101  	BUG_ON(vcpu != current);
   1.102  
   1.103 +	check_xen_space_overlap ("ptc_l", vadr, 1UL << log_range);
   1.104 +
   1.105  	/* Purge TC  */
   1.106  	vcpu_purge_tr_entry(&PSCBX(vcpu,dtlb));
   1.107  	vcpu_purge_tr_entry(&PSCBX(vcpu,itlb));
   1.108 @@ -2101,6 +2113,8 @@ IA64FAULT vcpu_ptc_ga(VCPU *vcpu,UINT64 
   1.109  	// FIXME: ??breaks if domain PAGE_SIZE < Xen PAGE_SIZE
   1.110  //printf("######## vcpu_ptc_ga(%p,%p) ##############\n",vadr,addr_range);
   1.111  
   1.112 +	check_xen_space_overlap ("ptc_ga", vadr, addr_range);
   1.113 +
   1.114  	domain_flush_vtlb_range (vcpu->domain, vadr, addr_range);
   1.115  
   1.116  	return IA64_NO_FAULT;
   1.117 @@ -2113,7 +2127,9 @@ IA64FAULT vcpu_ptr_d(VCPU *vcpu,UINT64 v
   1.118  	unsigned long rid, rr;
   1.119  	int i;
   1.120  	TR_ENTRY *trp;
   1.121 +
   1.122  	BUG_ON(vcpu != current);
   1.123 +	check_xen_space_overlap ("ptr_d", vadr, 1UL << log_range);
   1.124  
   1.125  	rr = PSCB(vcpu,rrs)[region];
   1.126  	rid = rr & RR_RID_MASK;
   1.127 @@ -2142,7 +2158,9 @@ IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 v
   1.128  	unsigned long rid, rr;
   1.129  	int i;
   1.130  	TR_ENTRY *trp;
   1.131 +
   1.132  	BUG_ON(vcpu != current);
   1.133 +	check_xen_space_overlap ("ptr_i", vadr, 1UL << log_range);
   1.134  
   1.135  	rr = PSCB(vcpu,rrs)[region];
   1.136  	rid = rr & RR_RID_MASK;