[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [IA64] Virtualize ibr/dbr for PV domains.
# HG changeset patch # User Alex Williamson <alex.williamson@xxxxxx> # Date 1183387919 21600 # Node ID 89596982890b78ebceffc4c5803662adc3dddc73 # Parent eb21b7274ab8acd950fdb631e0d1d22345fad76b [IA64] Virtualize ibr/dbr for PV domains. Signed-off-by: Tristan Gingold <tgingold@xxxxxxx> --- xen/arch/ia64/xen/domain.c | 24 +++++++++- xen/arch/ia64/xen/ivt.S | 4 - xen/arch/ia64/xen/vcpu.c | 56 ++++++++++++++++++------- xen/include/asm-ia64/domain.h | 5 ++ xen/include/asm-ia64/linux-xen/asm/processor.h | 4 + 5 files changed, 73 insertions(+), 20 deletions(-) diff -r eb21b7274ab8 -r 89596982890b xen/arch/ia64/xen/domain.c --- a/xen/arch/ia64/xen/domain.c Mon Jul 02 08:38:45 2007 -0600 +++ b/xen/arch/ia64/xen/domain.c Mon Jul 02 08:51:59 2007 -0600 @@ -237,6 +237,14 @@ void context_switch(struct vcpu *prev, s ia64_disable_vhpt_walker(); lazy_fp_switch(prev, current); + if (prev->arch.dbg_used || next->arch.dbg_used) { + /* + * Load debug registers either because they are valid or to clear + * the previous one. + */ + ia64_load_debug_regs(next->arch.dbr); + } + prev = ia64_switch_to(next); /* Note: ia64_switch_to does not return here at vcpu initialization. */ @@ -692,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; @@ -721,7 +737,7 @@ int arch_set_info_guest(struct vcpu *v, struct domain *d = v->domain; int was_initialised = v->is_initialised; unsigned int rbs_size; - int rc; + int rc, i; /* Finish vcpu initialization. */ if (!was_initialised) { @@ -826,8 +842,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 eb21b7274ab8 -r 89596982890b xen/arch/ia64/xen/ivt.S --- a/xen/arch/ia64/xen/ivt.S Mon Jul 02 08:38:45 2007 -0600 +++ b/xen/arch/ia64/xen/ivt.S Mon Jul 02 08:51:59 2007 -0600 @@ -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 eb21b7274ab8 -r 89596982890b xen/arch/ia64/xen/vcpu.c --- a/xen/arch/ia64/xen/vcpu.c Mon Jul 02 08:38:45 2007 -0600 +++ b/xen/arch/ia64/xen/vcpu.c Mon Jul 02 08:51:59 2007 -0600 @@ -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.dbg_used |= (1 << reg); + else + vcpu->arch.dbg_used &= ~(1 << reg); + vcpu->arch.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.dbg_used |= (1 << (reg + IA64_NUM_DBG_REGS)); + else + vcpu->arch.dbg_used &= ~(1 << (reg + IA64_NUM_DBG_REGS)); + vcpu->arch.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.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.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; } diff -r eb21b7274ab8 -r 89596982890b xen/include/asm-ia64/domain.h --- a/xen/include/asm-ia64/domain.h Mon Jul 02 08:38:45 2007 -0600 +++ b/xen/include/asm-ia64/domain.h Mon Jul 02 08:51:59 2007 -0600 @@ -180,6 +180,11 @@ struct arch_vcpu { int starting_rid; /* first RID assigned to domain */ int ending_rid; /* one beyond highest RID assigned to domain */ + /* Bitset for debug register use. */ + unsigned int dbg_used; + u64 dbr[IA64_NUM_DBG_REGS]; + u64 ibr[IA64_NUM_DBG_REGS]; + struct thread_struct _thread; // this must be last thash_cb_t vtlb; diff -r eb21b7274ab8 -r 89596982890b xen/include/asm-ia64/linux-xen/asm/processor.h --- a/xen/include/asm-ia64/linux-xen/asm/processor.h Mon Jul 02 08:38:45 2007 -0600 +++ b/xen/include/asm-ia64/linux-xen/asm/processor.h Mon Jul 02 08:51:59 2007 -0600 @@ -292,11 +292,14 @@ struct thread_struct { #else # define INIT_THREAD_PM #endif +#ifndef XEN __u64 dbr[IA64_NUM_DBG_REGS]; __u64 ibr[IA64_NUM_DBG_REGS]; +#endif struct ia64_fpreg fph[96]; /* saved/loaded on demand */ }; +#ifndef XEN #define INIT_THREAD { \ .flags = 0, \ .on_ustack = 0, \ @@ -333,6 +336,7 @@ struct thread_struct { regs->r1 = 0; regs->r9 = 0; regs->r11 = 0; regs->r13 = 0; regs->r15 = 0; \ } \ } while (0) +#endif /* Forward declarations, a strange C thing... */ struct mm_struct; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |