ia64/xen-unstable

changeset 15414:89596982890b

[IA64] Virtualize ibr/dbr for PV domains.

Signed-off-by: Tristan Gingold <tgingold@free.fr>
author Alex Williamson <alex.williamson@hp.com>
date Mon Jul 02 08:51:59 2007 -0600 (2007-07-02)
parents eb21b7274ab8
children 38d061886873
files xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/ivt.S xen/arch/ia64/xen/vcpu.c xen/include/asm-ia64/domain.h xen/include/asm-ia64/linux-xen/asm/processor.h
line diff
     1.1 --- a/xen/arch/ia64/xen/domain.c	Mon Jul 02 08:38:45 2007 -0600
     1.2 +++ b/xen/arch/ia64/xen/domain.c	Mon Jul 02 08:51:59 2007 -0600
     1.3 @@ -237,6 +237,14 @@ void context_switch(struct vcpu *prev, s
     1.4      ia64_disable_vhpt_walker();
     1.5      lazy_fp_switch(prev, current);
     1.6  
     1.7 +    if (prev->arch.dbg_used || next->arch.dbg_used) {
     1.8 +        /*
     1.9 +         * Load debug registers either because they are valid or to clear
    1.10 +         * the previous one.
    1.11 +         */
    1.12 +        ia64_load_debug_regs(next->arch.dbr);
    1.13 +    }
    1.14 +    
    1.15      prev = ia64_switch_to(next);
    1.16  
    1.17      /* Note: ia64_switch_to does not return here at vcpu initialization.  */
    1.18 @@ -692,6 +700,14 @@ void arch_get_info_guest(struct vcpu *v,
    1.19   	c.nat->privregs_pfn = get_gpfn_from_mfn
    1.20  		(virt_to_maddr(v->arch.privregs) >> PAGE_SHIFT);
    1.21  
    1.22 +	for (i = 0; i < IA64_NUM_DBG_REGS; i++) {
    1.23 +		vcpu_get_dbr(v, i, &c.nat->regs.dbr[i]);
    1.24 +		vcpu_get_ibr(v, i, &c.nat->regs.ibr[i]);
    1.25 +	}
    1.26 +
    1.27 +	for (i = 0; i < 7; i++)
    1.28 +		vcpu_get_rr(v, (unsigned long)i << 61, &c.nat->regs.rr[i]);
    1.29 +
    1.30  	/* Fill extra regs.  */
    1.31  	for (i = 0; i < 8; i++) {
    1.32  		tr->itrs[i].pte = v->arch.itrs[i].pte.val;
    1.33 @@ -721,7 +737,7 @@ int arch_set_info_guest(struct vcpu *v, 
    1.34  	struct domain *d = v->domain;
    1.35  	int was_initialised = v->is_initialised;
    1.36  	unsigned int rbs_size;
    1.37 -	int rc;
    1.38 +	int rc, i;
    1.39  
    1.40  	/* Finish vcpu initialization.  */
    1.41  	if (!was_initialised) {
    1.42 @@ -826,8 +842,12 @@ int arch_set_info_guest(struct vcpu *v, 
    1.43   		uregs->ar_rsc |= (2 << 2); /* force PL2/3 */
    1.44   	}
    1.45  
    1.46 +	for (i = 0; i < IA64_NUM_DBG_REGS; i++) {
    1.47 +		vcpu_set_dbr(v, i, c.nat->regs.dbr[i]);
    1.48 +		vcpu_set_ibr(v, i, c.nat->regs.ibr[i]);
    1.49 +	}
    1.50 +
    1.51  	if (c.nat->flags & VGCF_EXTRA_REGS) {
    1.52 -		int i;
    1.53  		struct vcpu_tr_regs *tr = &c.nat->regs.tr;
    1.54  
    1.55  		for (i = 0; i < 8; i++) {
     2.1 --- a/xen/arch/ia64/xen/ivt.S	Mon Jul 02 08:38:45 2007 -0600
     2.2 +++ b/xen/arch/ia64/xen/ivt.S	Mon Jul 02 08:51:59 2007 -0600
     2.3 @@ -1183,11 +1183,7 @@ END(speculation_vector)
     2.4  // 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56)
     2.5  ENTRY(debug_vector)
     2.6  	DBG_FAULT(29)
     2.7 -#ifdef XEN
     2.8  	FAULT_OR_REFLECT(29)
     2.9 -#else
    2.10 -	FAULT(29)
    2.11 -#endif
    2.12  END(debug_vector)
    2.13  
    2.14  	.org ia64_ivt+0x5a00
     3.1 --- a/xen/arch/ia64/xen/vcpu.c	Mon Jul 02 08:38:45 2007 -0600
     3.2 +++ b/xen/arch/ia64/xen/vcpu.c	Mon Jul 02 08:51:59 2007 -0600
     3.3 @@ -1773,33 +1773,61 @@ IA64FAULT vcpu_tak(VCPU * vcpu, u64 vadr
     3.4  
     3.5  IA64FAULT vcpu_set_dbr(VCPU * vcpu, u64 reg, u64 val)
     3.6  {
     3.7 -	// TODO: unimplemented DBRs return a reserved register fault
     3.8 -	// TODO: Should set Logical CPU state, not just physical
     3.9 -	ia64_set_dbr(reg, val);
    3.10 +	if (reg >= IA64_NUM_DBG_REGS)
    3.11 +		return IA64_RSVDREG_FAULT;
    3.12 +	if ((reg & 1) == 0) {
    3.13 +		/* Validate address. */
    3.14 +		if (val >= HYPERVISOR_VIRT_START && val <= HYPERVISOR_VIRT_END)
    3.15 +			return IA64_ILLOP_FAULT;
    3.16 +	} else {
    3.17 +		/* Mask PL0.  */
    3.18 +		val &= ~(1UL << 56);
    3.19 +	}
    3.20 +	if (val != 0)
    3.21 +		vcpu->arch.dbg_used |= (1 << reg);
    3.22 +	else
    3.23 +		vcpu->arch.dbg_used &= ~(1 << reg);
    3.24 +	vcpu->arch.dbr[reg] = val;
    3.25 +	if (vcpu == current)
    3.26 +		ia64_set_dbr(reg, val);
    3.27  	return IA64_NO_FAULT;
    3.28  }
    3.29  
    3.30  IA64FAULT vcpu_set_ibr(VCPU * vcpu, u64 reg, u64 val)
    3.31  {
    3.32 -	// TODO: unimplemented IBRs return a reserved register fault
    3.33 -	// TODO: Should set Logical CPU state, not just physical
    3.34 -	ia64_set_ibr(reg, val);
    3.35 +	if (reg >= IA64_NUM_DBG_REGS)
    3.36 +		return IA64_RSVDREG_FAULT;
    3.37 +	if ((reg & 1) == 0) {
    3.38 +		/* Validate address. */
    3.39 +		if (val >= HYPERVISOR_VIRT_START && val <= HYPERVISOR_VIRT_END)
    3.40 +			return IA64_ILLOP_FAULT;
    3.41 +	} else {
    3.42 +		/* Mask PL0.  */
    3.43 +		val &= ~(1UL << 56);
    3.44 +	}
    3.45 +	if (val != 0)
    3.46 +		vcpu->arch.dbg_used |= (1 << (reg + IA64_NUM_DBG_REGS));
    3.47 +	else
    3.48 +		vcpu->arch.dbg_used &= ~(1 << (reg + IA64_NUM_DBG_REGS));
    3.49 +	vcpu->arch.ibr[reg] = val;
    3.50 +	if (vcpu == current)
    3.51 +		ia64_set_ibr(reg, val);
    3.52  	return IA64_NO_FAULT;
    3.53  }
    3.54  
    3.55  IA64FAULT vcpu_get_dbr(VCPU * vcpu, u64 reg, u64 * pval)
    3.56  {
    3.57 -	// TODO: unimplemented DBRs return a reserved register fault
    3.58 -	u64 val = ia64_get_dbr(reg);
    3.59 -	*pval = val;
    3.60 +	if (reg >= IA64_NUM_DBG_REGS)
    3.61 +		return IA64_RSVDREG_FAULT;
    3.62 +	*pval = vcpu->arch.dbr[reg];
    3.63  	return IA64_NO_FAULT;
    3.64  }
    3.65  
    3.66  IA64FAULT vcpu_get_ibr(VCPU * vcpu, u64 reg, u64 * pval)
    3.67  {
    3.68 -	// TODO: unimplemented IBRs return a reserved register fault
    3.69 -	u64 val = ia64_get_ibr(reg);
    3.70 -	*pval = val;
    3.71 +	if (reg >= IA64_NUM_DBG_REGS)
    3.72 +		return IA64_RSVDREG_FAULT;
    3.73 +	*pval = vcpu->arch.ibr[reg];
    3.74  	return IA64_NO_FAULT;
    3.75  }
    3.76  
    3.77 @@ -2002,8 +2030,8 @@ unsigned long vcpu_get_rr_ve(VCPU * vcpu
    3.78  IA64FAULT vcpu_set_rr(VCPU * vcpu, u64 reg, u64 val)
    3.79  {
    3.80  	PSCB(vcpu, rrs)[reg >> 61] = val;
    3.81 -	// warning: set_one_rr() does it "live"
    3.82 -	set_one_rr(reg, val);
    3.83 +	if (vcpu == current)
    3.84 +		set_one_rr(reg, val);
    3.85  	return IA64_NO_FAULT;
    3.86  }
    3.87  
     4.1 --- a/xen/include/asm-ia64/domain.h	Mon Jul 02 08:38:45 2007 -0600
     4.2 +++ b/xen/include/asm-ia64/domain.h	Mon Jul 02 08:51:59 2007 -0600
     4.3 @@ -180,6 +180,11 @@ struct arch_vcpu {
     4.4      int starting_rid;		/* first RID assigned to domain */
     4.5      int ending_rid;		/* one beyond highest RID assigned to domain */
     4.6  
     4.7 +    /* Bitset for debug register use.  */
     4.8 +    unsigned int dbg_used;
     4.9 +    u64 dbr[IA64_NUM_DBG_REGS];
    4.10 +    u64 ibr[IA64_NUM_DBG_REGS];
    4.11 +
    4.12      struct thread_struct _thread;	// this must be last
    4.13  
    4.14      thash_cb_t vtlb;
     5.1 --- a/xen/include/asm-ia64/linux-xen/asm/processor.h	Mon Jul 02 08:38:45 2007 -0600
     5.2 +++ b/xen/include/asm-ia64/linux-xen/asm/processor.h	Mon Jul 02 08:51:59 2007 -0600
     5.3 @@ -292,11 +292,14 @@ struct thread_struct {
     5.4  #else
     5.5  # define INIT_THREAD_PM
     5.6  #endif
     5.7 +#ifndef XEN
     5.8  	__u64 dbr[IA64_NUM_DBG_REGS];
     5.9  	__u64 ibr[IA64_NUM_DBG_REGS];
    5.10 +#endif
    5.11  	struct ia64_fpreg fph[96];	/* saved/loaded on demand */
    5.12  };
    5.13  
    5.14 +#ifndef XEN
    5.15  #define INIT_THREAD {						\
    5.16  	.flags =	0,					\
    5.17  	.on_ustack =	0,					\
    5.18 @@ -333,6 +336,7 @@ struct thread_struct {
    5.19  		regs->r1 = 0; regs->r9  = 0; regs->r11 = 0; regs->r13 = 0; regs->r15 = 0;	\
    5.20  	}											\
    5.21  } while (0)
    5.22 +#endif
    5.23  
    5.24  /* Forward declarations, a strange C thing... */
    5.25  struct mm_struct;