[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-ia64-devel] PATCH: implements ibr/dbr virtualization for PV
Hi tristan. Is the flag, IA64_THREAD_DBG_VALID, set-only and never-cleared? Can it be cleared when dbr[odd].{r, w} = 0 or ibr[odd].x = 0? thanks, On Tue, Jun 26, 2007 at 04:30:17AM +0200, tgingold@xxxxxxx wrote: > Hi, > > this patch virtualize ibr and dbr for PV. > > Setting an hardware breakpoints now works (at least for domain debugging). > > Tristan. > # HG changeset patch > # User Tristan Gingold <tgingold@xxxxxxx> > # Date 1182824870 -7200 > # Node ID b73d2d95ff151b92ce2796662601ab60b1de63be > # Parent dddbacf2e2f5532a4cf73a03066d13e0b52d36c5 > Implement get/set i/dbr for PV. > > Signed-off-by: Tristan Gingold <tgingold@xxxxxxx> > > diff -r dddbacf2e2f5 -r b73d2d95ff15 xen/arch/ia64/xen/domain.c > --- a/xen/arch/ia64/xen/domain.c Sun Jun 24 05:21:41 2007 +0200 > +++ b/xen/arch/ia64/xen/domain.c Tue Jun 26 04:27:50 2007 +0200 > @@ -237,6 +237,13 @@ void context_switch(struct vcpu *prev, s > ia64_disable_vhpt_walker(); > lazy_fp_switch(prev, current); > > + if ((prev->arch._thread.flags & IA64_THREAD_DBG_VALID) > + || (next->arch._thread.flags & IA64_THREAD_DBG_VALID)) { > + /* Load debug registers either because they are valid or to clear > + the previous one. */ > + ia64_load_debug_regs (next->arch._thread.dbr); > + } > + > prev = ia64_switch_to(next); > > /* Note: ia64_switch_to does not return here at vcpu initialization. */ > @@ -693,6 +700,14 @@ void arch_get_info_guest(struct vcpu *v, > c.nat->privregs_pfn = get_gpfn_from_mfn > (virt_to_maddr(v->arch.privregs) >> PAGE_SHIFT); > > + for (i = 0; i < IA64_NUM_DBG_REGS; i++) { > + vcpu_get_dbr (v, i, &c.nat->regs.dbr[i]); > + vcpu_get_ibr (v, i, &c.nat->regs.ibr[i]); > + } > + > + for (i = 0; i < 7; i++) > + vcpu_get_rr (v, (unsigned long)i << 61, &c.nat->regs.rr[i]); > + > /* Fill extra regs. */ > for (i = 0; i < 8; i++) { > tr->itrs[i].pte = v->arch.itrs[i].pte.val; > @@ -723,6 +738,7 @@ int arch_set_info_guest(struct vcpu *v, > int was_initialised = v->is_initialised; > unsigned int rbs_size; > int rc; > + int i; > > /* Finish vcpu initialization. */ > if (!was_initialised) { > @@ -828,8 +844,12 @@ int arch_set_info_guest(struct vcpu *v, > uregs->ar_rsc |= (2 << 2); /* force PL2/3 */ > } > > + for (i = 0; i < IA64_NUM_DBG_REGS; i++) { > + vcpu_set_dbr (v, i, c.nat->regs.dbr[i]); > + vcpu_set_ibr (v, i, c.nat->regs.ibr[i]); > + } > + > if (c.nat->flags & VGCF_EXTRA_REGS) { > - int i; > struct vcpu_tr_regs *tr = &c.nat->regs.tr; > > for (i = 0; i < 8; i++) { > diff -r dddbacf2e2f5 -r b73d2d95ff15 xen/arch/ia64/xen/ivt.S > --- a/xen/arch/ia64/xen/ivt.S Sun Jun 24 05:21:41 2007 +0200 > +++ b/xen/arch/ia64/xen/ivt.S Tue Jun 26 04:27:50 2007 +0200 > @@ -1183,11 +1183,7 @@ END(speculation_vector) > // 0x5900 Entry 29 (size 16 bundles) Debug (16,28,56) > ENTRY(debug_vector) > DBG_FAULT(29) > -#ifdef XEN > FAULT_OR_REFLECT(29) > -#else > - FAULT(29) > -#endif > END(debug_vector) > > .org ia64_ivt+0x5a00 > diff -r dddbacf2e2f5 -r b73d2d95ff15 xen/arch/ia64/xen/vcpu.c > --- a/xen/arch/ia64/xen/vcpu.c Sun Jun 24 05:21:41 2007 +0200 > +++ b/xen/arch/ia64/xen/vcpu.c Tue Jun 26 04:27:50 2007 +0200 > @@ -1773,33 +1773,61 @@ IA64FAULT vcpu_tak(VCPU * vcpu, u64 vadr > > IA64FAULT vcpu_set_dbr(VCPU * vcpu, u64 reg, u64 val) > { > - // TODO: unimplemented DBRs return a reserved register fault > - // TODO: Should set Logical CPU state, not just physical > - ia64_set_dbr(reg, val); > + if (reg >= IA64_NUM_DBG_REGS) > + return IA64_RSVDREG_FAULT; > + if ((reg & 1) == 0) { > + /* Validate address. */ > + if (val >= HYPERVISOR_VIRT_START && val <= HYPERVISOR_VIRT_END) > + return IA64_ILLOP_FAULT; > + } > + else { > + /* Mask PL0. */ > + val &= ~(1UL << 56); > + } > + if (val != 0) { > + vcpu->arch._thread.flags |= IA64_THREAD_DBG_VALID; > + } > + vcpu->arch._thread.dbr[reg] = val; > + if (vcpu == current) > + ia64_set_dbr(reg, val); > return IA64_NO_FAULT; > } > > IA64FAULT vcpu_set_ibr(VCPU * vcpu, u64 reg, u64 val) > { > - // TODO: unimplemented IBRs return a reserved register fault > - // TODO: Should set Logical CPU state, not just physical > - ia64_set_ibr(reg, val); > + if (reg >= IA64_NUM_DBG_REGS) > + return IA64_RSVDREG_FAULT; > + if ((reg & 1) == 0) { > + /* Validate address. */ > + if (val >= HYPERVISOR_VIRT_START && val <= HYPERVISOR_VIRT_END) > + return IA64_ILLOP_FAULT; > + } > + else { > + /* Mask PL0. */ > + val &= ~(1UL << 56); > + } > + if (val != 0) { > + vcpu->arch._thread.flags |= IA64_THREAD_DBG_VALID; > + } > + vcpu->arch._thread.ibr[reg] = val; > + if (vcpu == current) > + ia64_set_ibr(reg, val); > return IA64_NO_FAULT; > } > > IA64FAULT vcpu_get_dbr(VCPU * vcpu, u64 reg, u64 * pval) > { > - // TODO: unimplemented DBRs return a reserved register fault > - u64 val = ia64_get_dbr(reg); > - *pval = val; > + if (reg >= IA64_NUM_DBG_REGS) > + return IA64_RSVDREG_FAULT; > + *pval = vcpu->arch._thread.dbr[reg]; > return IA64_NO_FAULT; > } > > IA64FAULT vcpu_get_ibr(VCPU * vcpu, u64 reg, u64 * pval) > { > - // TODO: unimplemented IBRs return a reserved register fault > - u64 val = ia64_get_ibr(reg); > - *pval = val; > + if (reg >= IA64_NUM_DBG_REGS) > + return IA64_RSVDREG_FAULT; > + *pval = vcpu->arch._thread.ibr[reg]; > return IA64_NO_FAULT; > } > > @@ -2002,8 +2030,8 @@ IA64FAULT vcpu_set_rr(VCPU * vcpu, u64 r > IA64FAULT vcpu_set_rr(VCPU * vcpu, u64 reg, u64 val) > { > PSCB(vcpu, rrs)[reg >> 61] = val; > - // warning: set_one_rr() does it "live" > - set_one_rr(reg, val); > + if (vcpu == current) > + set_one_rr(reg, val); > return IA64_NO_FAULT; > } > > _______________________________________________ > Xen-ia64-devel mailing list > Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx > http://lists.xensource.com/xen-ia64-devel -- yamahata _______________________________________________ Xen-ia64-devel mailing list Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ia64-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |