From 60118a94125f2d1dc55017779d8582645710d106 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Mon, 23 May 2005 23:05:04 +0000 Subject: [PATCH 1/5] bitkeeper revision 1.1509.1.2 (429261a0Qv1Wip4lt2f2ekcSvhVyxA) Fix multi-domain scheduling bug Signed-off by: Dan Magenheimer --- xen/arch/ia64/Makefile | 3 +++ xen/arch/ia64/domain.c | 1 + xen/arch/ia64/hypercall.c | 4 ++++ xen/arch/ia64/patch/linux-2.6.11/entry.S | 30 +++++++++++++----------- xen/arch/ia64/tools/mkbuildtree | 1 - xen/arch/ia64/vcpu.c | 29 +++++++++++++++++++++-- xen/arch/ia64/xenmisc.c | 9 ++++--- 7 files changed, 57 insertions(+), 20 deletions(-) diff --git a/xen/arch/ia64/Makefile b/xen/arch/ia64/Makefile index fdb9fbe1b9..bfe11cb49c 100644 --- a/xen/arch/ia64/Makefile +++ b/xen/arch/ia64/Makefile @@ -29,6 +29,9 @@ default: $(OBJS) head.o ia64lib.o xen.lds.s $(LD) $(LDFLAGS) -T $(BASEDIR)/arch/$(TARGET_ARCH)/xen.lds.s -N \ -Map map.out head.o $(ALL_OBJS) -o $(TARGET)-syms $(OBJCOPY) -R .note -R .comment -S $(TARGET)-syms $(TARGET) + $(NM) -n $(TARGET)-syms | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)'\ + > $(BASEDIR)/System.map + asm-offsets.s: asm-offsets.c $(BASEDIR)/include/asm-ia64/.offsets.h.stamp $(CC) $(CFLAGS) -S -o $@ $< diff --git a/xen/arch/ia64/domain.c b/xen/arch/ia64/domain.c index 8f12179c5d..66559c2931 100644 --- a/xen/arch/ia64/domain.c +++ b/xen/arch/ia64/domain.c @@ -116,6 +116,7 @@ void continue_cpu_idle_loop(void) #endif while ( !softirq_pending(cpu) ) default_idle(); + raise_softirq(SCHEDULE_SOFTIRQ); do_softirq(); } } diff --git a/xen/arch/ia64/hypercall.c b/xen/arch/ia64/hypercall.c index 3eeff6fe2b..adaf7d3b44 100644 --- a/xen/arch/ia64/hypercall.c +++ b/xen/arch/ia64/hypercall.c @@ -41,6 +41,10 @@ ia64_hypercall (struct pt_regs *regs) ed->vcpu_info->arch.pending_interruption = 1; #endif x = pal_emulator_static(regs->r28); + if (regs->r28 == PAL_HALT_LIGHT) { + do_sched_op(SCHEDOP_yield); + //break; + } regs->r8 = x.status; regs->r9 = x.v0; regs->r10 = x.v1; regs->r11 = x.v2; break; diff --git a/xen/arch/ia64/patch/linux-2.6.11/entry.S b/xen/arch/ia64/patch/linux-2.6.11/entry.S index 9f860edc4f..2b7f690aa8 100644 --- a/xen/arch/ia64/patch/linux-2.6.11/entry.S +++ b/xen/arch/ia64/patch/linux-2.6.11/entry.S @@ -1,5 +1,5 @@ ---- /home/adsharma/disk2/xen-ia64/xeno-unstable-rebase.bk/xen/../../linux-2.6.11/arch/ia64/kernel/entry.S 2005-03-01 23:37:50.000000000 -0800 -+++ /home/adsharma/disk2/xen-ia64/xeno-unstable-rebase.bk/xen/arch/ia64/entry.S 2005-05-18 12:40:51.000000000 -0700 +--- ../../linux-2.6.11/arch/ia64/kernel/entry.S 2005-03-02 00:37:50.000000000 -0700 ++++ arch/ia64/entry.S 2005-05-23 16:49:23.000000000 -0600 @@ -46,6 +46,7 @@ #include "minstate.h" @@ -97,11 +97,13 @@ ;; // added stop bits to prevent r8 dependency END(ia64_ret_from_clone) // fall through -@@ -700,19 +732,25 @@ +@@ -700,19 +732,27 @@ .work_processed_syscall: adds r2=PT(LOADRS)+16,r12 adds r3=PT(AR_BSPSTORE)+16,r12 -+#ifndef XEN ++#ifdef XEN ++ ;; ++#else adds r18=TI_FLAGS+IA64_TASK_SIZE,r13 ;; (p6) ld4 r31=[r18] // load current_thread_info()->flags @@ -123,7 +125,7 @@ ;; // start restoring the state saved on the kernel stack (struct pt_regs): ld8 r9=[r2],PT(CR_IPSR)-PT(R9) -@@ -757,7 +795,11 @@ +@@ -757,7 +797,11 @@ ;; ld8.fill r12=[r2] // restore r12 (sp) ld8.fill r15=[r3] // restore r15 @@ -135,7 +137,7 @@ ;; (pUStk) ld4 r3=[r3] // r3 = cpu_data->phys_stacked_size_p8 (pUStk) st1 [r14]=r17 -@@ -814,9 +856,18 @@ +@@ -814,9 +858,18 @@ (pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk #endif .work_processed_kernel: @@ -154,7 +156,7 @@ adds r21=PT(PR)+16,r12 ;; -@@ -828,17 +879,20 @@ +@@ -828,17 +881,20 @@ ld8 r28=[r2],8 // load b6 adds r29=PT(R24)+16,r12 @@ -176,7 +178,7 @@ ;; ld8 r31=[r2],16 // load ar.ssd ld8.fill r8=[r3],16 -@@ -934,7 +988,11 @@ +@@ -934,7 +990,11 @@ shr.u r18=r19,16 // get byte size of existing "dirty" partition ;; mov r16=ar.bsp // get existing backing store pointer @@ -188,7 +190,7 @@ ;; ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 (pKStk) br.cond.dpnt skip_rbs_switch -@@ -1069,6 +1127,7 @@ +@@ -1069,6 +1129,7 @@ mov pr=r31,-1 // I0 rfi // B @@ -196,7 +198,7 @@ /* * On entry: * r20 = ¤t->thread_info->pre_count (if CONFIG_PREEMPT) -@@ -1130,6 +1189,7 @@ +@@ -1130,6 +1191,7 @@ ld8 r8=[r2] ld8 r10=[r3] br.cond.sptk.many .work_processed_syscall // re-check @@ -204,7 +206,7 @@ END(ia64_leave_kernel) -@@ -1166,6 +1226,7 @@ +@@ -1166,6 +1228,7 @@ br.ret.sptk.many rp END(ia64_invoke_schedule_tail) @@ -212,7 +214,7 @@ /* * Setup stack and call do_notify_resume_user(). Note that pSys and pNonSys need to * be set up by the caller. We declare 8 input registers so the system call -@@ -1264,6 +1325,7 @@ +@@ -1264,6 +1327,7 @@ mov ar.unat=r9 br.many b7 END(sys_rt_sigreturn) @@ -220,7 +222,7 @@ GLOBAL_ENTRY(ia64_prepare_handle_unaligned) .prologue -@@ -1278,6 +1340,7 @@ +@@ -1278,6 +1342,7 @@ br.cond.sptk.many rp // goes to ia64_leave_kernel END(ia64_prepare_handle_unaligned) @@ -228,7 +230,7 @@ // // unw_init_running(void (*callback)(info, arg), void *arg) // -@@ -1585,3 +1648,4 @@ +@@ -1585,3 +1650,4 @@ data8 sys_ni_syscall .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls diff --git a/xen/arch/ia64/tools/mkbuildtree b/xen/arch/ia64/tools/mkbuildtree index f9b58527dd..15a6d937ca 100644 --- a/xen/arch/ia64/tools/mkbuildtree +++ b/xen/arch/ia64/tools/mkbuildtree @@ -307,7 +307,6 @@ softlink include/linux/timex.h include/asm-ia64/linux/timex.h softlink include/linux/topology.h include/asm-ia64/linux/topology.h softlink include/linux/seqlock.h include/asm-ia64/linux/seqlock.h softlink include/linux/jiffies.h include/asm-ia64/linux/jiffies.h -softlink include/linux/jiffies.h include/asm-ia64/linux/jiffies.h null include/asm-ia64/linux/file.h null include/asm-ia64/linux/module.h diff --git a/xen/arch/ia64/vcpu.c b/xen/arch/ia64/vcpu.c index 863c99beb3..61f369e401 100644 --- a/xen/arch/ia64/vcpu.c +++ b/xen/arch/ia64/vcpu.c @@ -638,7 +638,15 @@ IA64FAULT vcpu_get_ivr(VCPU *vcpu, UINT64 *pval) { int i; UINT64 vector, mask; -#if 1 + +#define HEARTBEAT_FREQ 16 // period in seconds +#ifdef HEARTBEAT_FREQ +#define N_DOMS 16 // period in seconds + static long count[N_DOMS] = { 0 }; + REGS *regs = vcpu_regs(vcpu); + unsigned domid = vcpu->domain->domain_id; +#endif +#ifdef IRQ_DEBUG static char firstivr = 1; static char firsttime[256]; if (firstivr) { @@ -654,9 +662,21 @@ IA64FAULT vcpu_get_ivr(VCPU *vcpu, UINT64 *pval) *pval = vector; return IA64_NO_FAULT; } +#ifdef HEARTBEAT_FREQ + if (domid >= N_DOMS) domid = N_DOMS-1; + if (vector == (PSCB(vcpu,itv) & 0xff) && + !(++count[domid] & ((HEARTBEAT_FREQ*1024)-1))) { + printf("Dom%d heartbeat... iip=%p,psr.i=%d,pend=%d\n", + domid, regs->cr_iip, + current->vcpu_info->arch.interrupt_delivery_enabled, + current->vcpu_info->arch.pending_interruption); + count[domid] = 0; + dump_runq(); + } +#endif // now have an unmasked, pending, deliverable vector! // getting ivr has "side effects" -#if 0 +#ifdef IRQ_DEBUG if (firsttime[vector]) { printf("*** First get_ivr on vector=%d,itc=%lx\n", vector,ia64_get_itc()); @@ -989,6 +1009,10 @@ IA64FAULT vcpu_set_itc(VCPU *vcpu, UINT64 val) UINT64 newnow = val, min_delta; +#define DISALLOW_SETTING_ITC_FOR_NOW +#ifdef DISALLOW_SETTING_ITC_FOR_NOW +printf("vcpu_set_itc: Setting ar.itc is currently disabled\n"); +#else local_irq_disable(); if (olditm) { printf("**** vcpu_set_itc(%lx): vitm changed to %lx\n",val,newnow+d); @@ -1008,6 +1032,7 @@ printf("**** vcpu_set_itc(%lx): vitm changed to %lx\n",val,newnow+d); //using_xen_as_itm++; } local_irq_enable(); +#endif return (IA64_NO_FAULT); } diff --git a/xen/arch/ia64/xenmisc.c b/xen/arch/ia64/xenmisc.c index 142cbfcb26..c4630bd7fd 100644 --- a/xen/arch/ia64/xenmisc.c +++ b/xen/arch/ia64/xenmisc.c @@ -262,8 +262,8 @@ void context_switch(struct exec_domain *prev, struct exec_domain *next) static long cnt[16] = { 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50}; static int i = 100; int id = ((struct exec_domain *)current)->domain->domain_id & 0xf; -if (!cnt[id]--) { printk("%x",id); cnt[id] = 50; } -if (!i--) { printk("+",id); cnt[id] = 100; } +if (!cnt[id]--) { printk("%x",id); cnt[id] = 500; } +if (!i--) { printk("+",id); cnt[id] = 1000; } } clear_bit(_VCPUF_running, &prev->vcpu_flags); //if (!is_idle_task(next->domain) ) @@ -273,7 +273,10 @@ if (!i--) { printk("+",id); cnt[id] = 100; } vmx_load_all_rr(current); return; #else // CONFIG_VTI - load_region_regs(current); + if (!is_idle_task(current->domain)) { + load_region_regs(current); + if (vcpu_timer_expired(current)) vcpu_pend_timer(current); + } if (vcpu_timer_expired(current)) vcpu_pend_timer(current); #endif // CONFIG_VTI } From 247a787cb98c243a2c96cf679b40f1638b13c68f Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Tue, 24 May 2005 21:40:01 +0000 Subject: [PATCH 2/5] bitkeeper revision 1.1509.1.3 (42939f31KzK-SwtLziu7eM9buqA-bg) Fix xen/xenlinux to work with CONFIG_DISABLE_VHPT off and CONFIG_VIRTUAL_MEM_MAP=y Signed-off-by: Matthew Chapman Signed-off by: Dan Magenheimer --- xen/arch/ia64/ivt.S | 6 +++++- xen/arch/ia64/privop.c | 24 ++---------------------- xen/arch/ia64/process.c | 20 +++++++++----------- xen/arch/ia64/tools/README.xenia64 | 4 +--- xen/arch/ia64/tools/README.xenia64linux | 4 ++-- xen/arch/ia64/vcpu.c | 6 +++--- 6 files changed, 22 insertions(+), 42 deletions(-) diff --git a/xen/arch/ia64/ivt.S b/xen/arch/ia64/ivt.S index a44f5eb8a9..449306c61b 100644 --- a/xen/arch/ia64/ivt.S +++ b/xen/arch/ia64/ivt.S @@ -785,14 +785,18 @@ ENTRY(break_fault) cmp.eq p7,p0=r0,r17 // is this a psuedo-cover? (p7) br.sptk.many dispatch_privop_fault ;; - cmp.ne p7,p0=r0,r19 + cmp4.ne p7,p0=r0,r19 (p7) br.sptk.many dispatch_break_fault // If we get to here, we have a hyperprivop // For now, hyperprivops are handled through the break mechanism // Later, they will be fast hand-coded assembly with psr.ic off // which means no calls, no use of r1-r15 and no memory accesses // except to pinned addresses! +#ifdef FAST_HYPERPRIVOPS + br.sptk.many fast_hyperprivop +#else br.sptk.many dispatch_break_fault +#endif ;; #endif mov r16=IA64_KR(CURRENT) // r16 = current task; 12 cycle read lat. diff --git a/xen/arch/ia64/privop.c b/xen/arch/ia64/privop.c index aec763f80d..ad2044e909 100644 --- a/xen/arch/ia64/privop.c +++ b/xen/arch/ia64/privop.c @@ -569,7 +569,7 @@ priv_handle_op(VCPU *vcpu, REGS *regs, int privlvl) #endif { //printf("*** priv_handle_op: privop bundle @%p not mapped, retrying\n",iip); - return IA64_RETRY; + return vcpu_force_data_miss(vcpu,regs->cr_iip); } #if 0 if (iip==0xa000000100001820) { @@ -732,30 +732,10 @@ priv_emulate(VCPU *vcpu, REGS *regs, UINT64 isr) privlvl = (ipsr & IA64_PSR_CPL) >> IA64_PSR_CPL0_BIT; // its OK for a privified-cover to be executed in user-land fault = priv_handle_op(vcpu,regs,privlvl); - if (fault == IA64_NO_FAULT) { // success!! + if ((fault == IA64_NO_FAULT) || (fault == IA64_EXTINT_VECTOR)) { // success!! // update iip/ipsr to point to the next instruction (void)vcpu_increment_iip(vcpu); } - else if (fault == IA64_EXTINT_VECTOR) { - // update iip/ipsr before delivering interrupt - (void)vcpu_increment_iip(vcpu); - } - else if (fault == IA64_RFI_IN_PROGRESS) return fault; - // success but don't update to next instruction - else if (fault == IA64_RETRY) { - //printf("Priv emulate gets IA64_RETRY\n"); - //printf("priv_emulate: returning RETRY, not implemented!\n"); - //while (1); - // don't update iip/ipsr, deliver - - vcpu_force_data_miss(vcpu,regs->cr_iip); - return IA64_RETRY; - } - else if (priv_verbose) printf("unhandled operation from handle_op\n"); -// if (fault == IA64_ILLOP_FAULT) { -// printf("priv_emulate: returning ILLOP, not implemented!\n"); -// while (1); -// } return fault; } diff --git a/xen/arch/ia64/process.c b/xen/arch/ia64/process.c index f99cfc225d..50534abdbf 100644 --- a/xen/arch/ia64/process.c +++ b/xen/arch/ia64/process.c @@ -170,16 +170,11 @@ panic_domain(regs,"psr.ic off, delivering fault=%lx,iip=%p,ifa=%p,isr=%p,PSCB.ii if ((vector & 0xf) != IA64_FORCED_IFA) PSCB(ed,ifa) = ifa; else ifa = PSCB(ed,ifa); vector &= ~0xf; -// always deliver on ALT vector (for now?) because no VHPT -// if (!vcpu_get_rr_ve(ed,ifa)) { - if (vector == IA64_DATA_TLB_VECTOR) - vector = IA64_ALT_DATA_TLB_VECTOR; - else if (vector == IA64_INST_TLB_VECTOR) - vector = IA64_ALT_INST_TLB_VECTOR; -// } - if (vector == IA64_ALT_DATA_TLB_VECTOR || - vector == IA64_ALT_INST_TLB_VECTOR) { - vcpu_thash(ed,ifa,&PSCB(ed,iha)); + if (vector == IA64_DATA_TLB_VECTOR + || vector == IA64_ALT_DATA_TLB_VECTOR + || vector == IA64_INST_TLB_VECTOR + || vector == IA64_ALT_INST_TLB_VECTOR) { + vcpu_thash(ed,ifa,&PSCB(current,iha)); } PSCB(ed,unat) = regs->ar_unat; // not sure if this is really needed? PSCB(ed,precover_ifs) = regs->cr_ifs; @@ -367,7 +362,7 @@ void ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_reg vcpu_itc_no_srlz(current,is_data?2:1,address,pteval,-1UL,(trp->itir>>2)&0x3f); return; } - vector = is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR; + if (handle_lazy_cover(current, isr, regs)) return; if (!(address>>61)) { panic_domain(0,"ia64_do_page_fault: @%p???, iip=%p, itc=%p (spinning...)\n",address,iip,ia64_get_itc()); @@ -383,6 +378,9 @@ panic_domain(0,"ia64_do_page_fault: @%p???, iip=%p, itc=%p (spinning...)\n",addr ia64_psr(regs)->ed = 1; return; } + vector = vcpu_get_rr_ve(current, address) ? + (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR) + : (is_data ? IA64_ALT_DATA_TLB_VECTOR : IA64_ALT_INST_TLB_VECTOR); reflect_interruption(address, isr, itir, regs, vector); } diff --git a/xen/arch/ia64/tools/README.xenia64 b/xen/arch/ia64/tools/README.xenia64 index f099e5c929..f0f8d8ff4e 100644 --- a/xen/arch/ia64/tools/README.xenia64 +++ b/xen/arch/ia64/tools/README.xenia64 @@ -6,18 +6,16 @@ # unpack linux-2.6.11 in the xenXXX.bk/.. directory tar xzf linux-2.6.11.tar.gz -cd linux-2.6.11 # go back to the xen subdirectory of xenXXX.bk cd xenXXX.bk/xen # create and patch the linux/ia64 files -bash arch/ia64/tools/mkbuildtree # this should print out many patch messages but no errors bash arch/ia64/tools/mkbuildtree # build xen/ia64 # if using cross-compiler -make TARGET_ARCH=ia64 +make XEN_TARGET_ARCH=ia64 # else if native make diff --git a/xen/arch/ia64/tools/README.xenia64linux b/xen/arch/ia64/tools/README.xenia64linux index ab694423b5..5c1555ebdf 100644 --- a/xen/arch/ia64/tools/README.xenia64linux +++ b/xen/arch/ia64/tools/README.xenia64linux @@ -6,7 +6,6 @@ INSTRUCTIONS FOR BUILDING XENLINUX/IA64 unset CONFIG_IA32_SUPPORT unset CONFIG_IDE [for now, need to fix later] unset CONFIG_VIRTUAL_MEM_MAP [for now, need to fix later] - set CONFIG_DISABLE_VHPT 3) if running on ski, it is useful to make the following change: a) at the beginning of drivers/acpi/motherboard.c:acpi_reserve_resources() add the line: @@ -46,5 +45,6 @@ INSTRUCTIONS FOR BUILDING XENLINUX/IA64 (It may be necessary also to un-inline the routine, not sure.) c) It can be useful to modify linux/init/main.c to add a printf before or after a lot of the init calls -6) NOTE: mca currently has a problem with binary translation, +6) Start Xen from elilo, passing the Linux kernel as an initrd. + NOTE: mca currently has a problem with binary translation, must run with "nomca" as a kernel argument diff --git a/xen/arch/ia64/vcpu.c b/xen/arch/ia64/vcpu.c index 61f369e401..f8e4a3867c 100644 --- a/xen/arch/ia64/vcpu.c +++ b/xen/arch/ia64/vcpu.c @@ -1118,7 +1118,7 @@ Privileged operation emulation routines IA64FAULT vcpu_force_data_miss(VCPU *vcpu, UINT64 ifa) { PSCB(vcpu,ifa) = ifa; // privop traps don't set ifa so do it here - return (IA64_DATA_TLB_VECTOR | IA64_FORCED_IFA); + return (vcpu_get_rr_ve(vcpu,ifa) ? IA64_DATA_TLB_VECTOR : IA64_ALT_DATA_TLB_VECTOR) | IA64_FORCED_IFA; } @@ -1617,7 +1617,7 @@ IA64FAULT vcpu_itc_d(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa) unsigned long pteval, logps = (itir >> 2) & 0x3f; unsigned long translate_domain_pte(UINT64,UINT64,UINT64); - if (((itir & 0xfcL) >> 2) < PAGE_SHIFT) { + if (logps < PAGE_SHIFT) { printf("vcpu_itc_d: domain trying to use smaller page size!\n"); //FIXME: kill domain here while(1); @@ -1635,7 +1635,7 @@ IA64FAULT vcpu_itc_i(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa) unsigned long translate_domain_pte(UINT64,UINT64,UINT64); // FIXME: validate ifa here (not in Xen space), COULD MACHINE CHECK! - if (((itir & 0xfcL) >> 2) < PAGE_SHIFT) { + if (logps < PAGE_SHIFT) { printf("vcpu_itc_i: domain trying to use smaller page size!\n"); //FIXME: kill domain here while(1); From 3db90e1075f88dc20f90e1ff1bd710d067ba4723 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Wed, 25 May 2005 20:19:09 +0000 Subject: [PATCH 3/5] bitkeeper revision 1.1509.1.4 (4294ddbdS0zXLWNl7GY3vmRtzKddcQ) Implement virtual short format VHPT walker Signed-off-by: Matthew Chapman Signed-off by: Dan Magenheimer --- xen/arch/ia64/patch/linux-2.6.11/kregs.h | 4 +- xen/arch/ia64/process.c | 62 ++++++++++++++++-------- xen/arch/ia64/vcpu.c | 4 +- 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/xen/arch/ia64/patch/linux-2.6.11/kregs.h b/xen/arch/ia64/patch/linux-2.6.11/kregs.h index dab91c8b07..1268171987 100644 --- a/xen/arch/ia64/patch/linux-2.6.11/kregs.h +++ b/xen/arch/ia64/patch/linux-2.6.11/kregs.h @@ -45,7 +45,7 @@ #define IA64_ISR_CODE_LFETCH 4 #define IA64_ISR_CODE_PROBEF 5 -+#ifdef CONFIG_VTI ++#ifdef XEN +/* Interruption Function State */ +#define IA64_IFS_V_BIT 63 +#define IA64_IFS_V (__IA64_UL(1) << IA64_IFS_V_BIT) @@ -60,6 +60,6 @@ +#define IA64_PTA_SIZE (__IA64_UL(0x3f) << IA64_PTA_SIZE_BIT) +#define IA64_PTA_VF (__IA64_UL(1) << IA64_PTA_VF_BIT) +#define IA64_PTA_BASE (__IA64_UL(0) - ((__IA64_UL(1) << IA64_PTA_BASE_BIT))) -+#endif // CONFIG_VTI ++#endif + #endif /* _ASM_IA64_kREGS_H */ diff --git a/xen/arch/ia64/process.c b/xen/arch/ia64/process.c index 50534abdbf..60a2f30f76 100644 --- a/xen/arch/ia64/process.c +++ b/xen/arch/ia64/process.c @@ -153,7 +153,8 @@ void reflect_interruption(unsigned long ifa, unsigned long isr, unsigned long it } vector &= ~0xf; if (vector != IA64_DATA_TLB_VECTOR && - vector != IA64_ALT_DATA_TLB_VECTOR) { + vector != IA64_ALT_DATA_TLB_VECTOR && + vector != IA64_VHPT_TRANS_VECTOR) { panic_domain(regs,"psr.ic off, delivering fault=%lx,iip=%p,ifa=%p,isr=%p,PSCB.iip=%p\n", vector,regs->cr_iip,ifa,isr,PSCB(ed,iip)); @@ -167,15 +168,12 @@ panic_domain(regs,"psr.ic off, delivering fault=%lx,iip=%p,ifa=%p,isr=%p,PSCB.ii return; } - if ((vector & 0xf) != IA64_FORCED_IFA) PSCB(ed,ifa) = ifa; - else ifa = PSCB(ed,ifa); + if ((vector & 0xf) == IA64_FORCED_IFA) + ifa = PSCB(ed,tmp[0]); vector &= ~0xf; - if (vector == IA64_DATA_TLB_VECTOR - || vector == IA64_ALT_DATA_TLB_VECTOR - || vector == IA64_INST_TLB_VECTOR - || vector == IA64_ALT_INST_TLB_VECTOR) { + PSCB(ed,ifa) = ifa; + if (vector < IA64_DATA_NESTED_TLB_VECTOR) /* VHPT miss, TLB miss, Alt TLB miss */ vcpu_thash(ed,ifa,&PSCB(current,iha)); - } PSCB(ed,unat) = regs->ar_unat; // not sure if this is really needed? PSCB(ed,precover_ifs) = regs->cr_ifs; vcpu_bsw0(ed); @@ -320,7 +318,7 @@ void ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_reg unsigned long psr = regs->cr_ipsr, mask, flags; unsigned long iip = regs->cr_iip; // FIXME should validate address here - unsigned long pteval, mpaddr; + unsigned long iha, pteval, mpaddr; unsigned long lookup_domain_mpa(struct domain *,unsigned long); unsigned long is_data = !((isr >> IA64_ISR_X_BIT) & 1UL); unsigned long vector; @@ -346,8 +344,8 @@ void ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_reg // FIXME should validate mpaddr here if (d == dom0) { if (address < dom0_start || address >= dom0_start + dom0_size) { - //printk("ia64_do_page_fault: out-of-bounds dom0 mpaddr %p, iip=%p! continuing...\n",address,iip); - //printk("ia64_do_page_fault: out-of-bounds dom0 mpaddr %p, old iip=%p!\n",address,current->vcpu_info->arch.iip); + printk("ia64_do_page_fault: out-of-bounds dom0 mpaddr %p, iip=%p! continuing...\n",address,iip); + printk("ia64_do_page_fault: out-of-bounds dom0 mpaddr %p, old iip=%p!\n",address,current->vcpu_info->arch.iip); tdpfoo(); } } @@ -365,7 +363,7 @@ void ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_reg if (handle_lazy_cover(current, isr, regs)) return; if (!(address>>61)) { -panic_domain(0,"ia64_do_page_fault: @%p???, iip=%p, itc=%p (spinning...)\n",address,iip,ia64_get_itc()); +panic_domain(0,"ia64_do_page_fault: @%p???, iip=%p, b0=%p, itc=%p (spinning...)\n",address,iip,regs->b0,ia64_get_itc()); } if ((isr & IA64_ISR_SP) || ((isr & IA64_ISR_NA) && (isr & IA64_ISR_CODE_MASK) == IA64_ISR_CODE_LFETCH)) @@ -378,9 +376,37 @@ panic_domain(0,"ia64_do_page_fault: @%p???, iip=%p, itc=%p (spinning...)\n",addr ia64_psr(regs)->ed = 1; return; } - vector = vcpu_get_rr_ve(current, address) ? - (is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR) - : (is_data ? IA64_ALT_DATA_TLB_VECTOR : IA64_ALT_INST_TLB_VECTOR); + + if (vcpu_get_rr_ve(current, address) && (PSCB(current,pta) & IA64_PTA_VE)) + { + if (PSCB(current,pta) & IA64_PTA_VF) + { + /* long format VHPT - not implemented */ + vector = is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR; + } + else + { + /* short format VHPT */ + vcpu_thash(current, address, &iha); + if (__copy_from_user(&pteval, iha, sizeof(pteval)) == 0) + { + /* + * Optimisation: this VHPT walker aborts on not-present pages + * instead of inserting a not-present translation, this allows + * vectoring directly to the miss handler. + \ */ + if (pteval & _PAGE_P) + { + pteval = translate_domain_pte(pteval,address,itir); + vcpu_itc_no_srlz(current,is_data?2:1,address,pteval,-1UL,(itir>>2)&0x3f); + return; + } + else vector = is_data ? IA64_DATA_TLB_VECTOR : IA64_INST_TLB_VECTOR; + } + else vector = IA64_VHPT_TRANS_VECTOR; + } + } + else vector = is_data ? IA64_ALT_DATA_TLB_VECTOR : IA64_ALT_INST_TLB_VECTOR; reflect_interruption(address, isr, itir, regs, vector); } @@ -744,11 +770,7 @@ ia64_handle_privop (unsigned long ifa, struct pt_regs *regs, unsigned long isr, // AND ACTUALLY reflect_interruption doesn't use it anyway! itir = vcpu_get_itir_on_fault(ed,ifa); vector = priv_emulate(current,regs,isr); - if (vector == IA64_RETRY) { - reflect_interruption(ifa,isr,itir,regs, - IA64_ALT_DATA_TLB_VECTOR | IA64_FORCED_IFA); - } - else if (vector != IA64_NO_FAULT && vector != IA64_RFI_IN_PROGRESS) { + if (vector != IA64_NO_FAULT && vector != IA64_RFI_IN_PROGRESS) { reflect_interruption(ifa,isr,itir,regs,vector); } } diff --git a/xen/arch/ia64/vcpu.c b/xen/arch/ia64/vcpu.c index f8e4a3867c..fb9db8a35f 100644 --- a/xen/arch/ia64/vcpu.c +++ b/xen/arch/ia64/vcpu.c @@ -1117,7 +1117,7 @@ Privileged operation emulation routines IA64FAULT vcpu_force_data_miss(VCPU *vcpu, UINT64 ifa) { - PSCB(vcpu,ifa) = ifa; // privop traps don't set ifa so do it here + PSCB(vcpu,tmp[0]) = ifa; // save ifa in vcpu structure, then specify IA64_FORCED_IFA return (vcpu_get_rr_ve(vcpu,ifa) ? IA64_DATA_TLB_VECTOR : IA64_ALT_DATA_TLB_VECTOR) | IA64_FORCED_IFA; } @@ -1206,7 +1206,7 @@ IA64FAULT vcpu_thash(VCPU *vcpu, UINT64 vadr, UINT64 *pval) ((pta_base >> 15) & 0x3fffffffffff) & compMask_60_15; UINT64 VHPT_addr2b = ((VHPT_offset >> 15) & 0x3fffffffffff) & Mask_60_15;; - UINT64 VHPT_addr3 = VHPT_offset & 0x3fff; + UINT64 VHPT_addr3 = VHPT_offset & 0x7fff; UINT64 VHPT_addr = VHPT_addr1 | ((VHPT_addr2a | VHPT_addr2b) << 15) | VHPT_addr3; From 5de3fef23a8ce028c409531f786085d98a12025a Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Thu, 26 May 2005 15:43:04 +0000 Subject: [PATCH 4/5] bitkeeper revision 1.1509.1.5 (4295ee88HY2abQVcdhSuV8au7cjYDA) First fast hyperprivop support (hyper_rfi) Signed-off by: Dan Magenheimer --- .rootkeys | 1 + xen/arch/ia64/Makefile | 2 +- xen/arch/ia64/asm-offsets.c | 7 +++ xen/arch/ia64/hyperprivop.S | 103 +++++++++++++++++++++++++++++++ xen/arch/ia64/ivt.S | 13 +++- xen/arch/ia64/privop.c | 2 +- xen/include/asm-ia64/xensystem.h | 2 +- xen/include/public/arch-ia64.h | 7 +++ 8 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 xen/arch/ia64/hyperprivop.S diff --git a/.rootkeys b/.rootkeys index 01bf481c2c..1bac1bc7f3 100644 --- a/.rootkeys +++ b/.rootkeys @@ -1063,6 +1063,7 @@ 421098b2O7jsNfzQXA1v3rbAc1QhpA xen/arch/ia64/dom_fw.c 421098b2ZlaBcyiuuPr3WpzaSDwg6Q xen/arch/ia64/domain.c 4239e98a_HX-FCIcXtVqY0BbrDqVug xen/arch/ia64/hypercall.c +4295e18f42gf1T-8W97A3KSlBaY1tA xen/arch/ia64/hyperprivop.S 421098b3LYAS8xJkQiGP7tiTlyBt0Q xen/arch/ia64/idle0_task.c 421098b3ys5GAr4z6_H1jD33oem82g xen/arch/ia64/irq.c 4272a8e4lavI6DrTvqaIhXeR5RuKBw xen/arch/ia64/ivt.S diff --git a/xen/arch/ia64/Makefile b/xen/arch/ia64/Makefile index bfe11cb49c..568cbe5957 100644 --- a/xen/arch/ia64/Makefile +++ b/xen/arch/ia64/Makefile @@ -9,7 +9,7 @@ OBJS = xensetup.o setup.o time.o irq.o ia64_ksyms.o process.o smp.o \ xenmem.o sal.o cmdline.o mm_init.o tlb.o smpboot.o \ extable.o linuxextable.o xenirq.o xentime.o \ regionreg.o entry.o unaligned.o privop.o vcpu.o \ - irq_ia64.o irq_lsapic.o vhpt.o xenasm.o dom_fw.o + irq_ia64.o irq_lsapic.o vhpt.o xenasm.o hyperprivop.o dom_fw.o ifeq ($(CONFIG_VTI),y) OBJS += vmx_init.o vmx_virt.o vmx_vcpu.o vmx_process.o vmx_vsa.o vmx_ivt.o \ diff --git a/xen/arch/ia64/asm-offsets.c b/xen/arch/ia64/asm-offsets.c index a45bb76b88..45990de15e 100644 --- a/xen/arch/ia64/asm-offsets.c +++ b/xen/arch/ia64/asm-offsets.c @@ -44,6 +44,13 @@ void foo(void) DEFINE(XSI_PSR_IC_OFS, offsetof(vcpu_info_t, arch.interrupt_collection_enabled)); DEFINE(XSI_PSR_IC, (SHAREDINFO_ADDR+offsetof(vcpu_info_t, arch.interrupt_collection_enabled))); DEFINE(XSI_PSR_I_OFS, offsetof(vcpu_info_t, arch.interrupt_delivery_enabled)); + DEFINE(XSI_IIP_OFS, offsetof(vcpu_info_t, arch.iip)); + DEFINE(XSI_IPSR_OFS, offsetof(vcpu_info_t, arch.ipsr)); + DEFINE(XSI_IFS_OFS, offsetof(vcpu_info_t, arch.ifs)); + DEFINE(XSI_BANKNUM_OFS, offsetof(vcpu_info_t, arch.banknum)); + DEFINE(XSI_METAPHYS_OFS, offsetof(vcpu_info_t, arch.metaphysical_mode)); + DEFINE(XSI_INCOMPL_REG_OFS, offsetof(vcpu_info_t, arch.incomplete_regframe)); + DEFINE(XSI_PEND_OFS, offsetof(vcpu_info_t, arch.pending_interruption)); //DEFINE(IA64_TASK_BLOCKED_OFFSET,offsetof (struct task_struct, blocked)); //DEFINE(IA64_TASK_CLEAR_CHILD_TID_OFFSET,offsetof (struct task_struct, clear_child_tid)); //DEFINE(IA64_TASK_GROUP_LEADER_OFFSET, offsetof (struct task_struct, group_leader)); diff --git a/xen/arch/ia64/hyperprivop.S b/xen/arch/ia64/hyperprivop.S new file mode 100644 index 0000000000..4c8ebb09fc --- /dev/null +++ b/xen/arch/ia64/hyperprivop.S @@ -0,0 +1,103 @@ +/* + * arch/ia64/kernel/hyperprivop.S + * + * Copyright (C) 2005 Hewlett-Packard Co + * Dan Magenheimer + */ + +#include + +#include +#include +#include +#include +#include +#include + +// Note: not hand-scheduled for now +// Registers at entry +// r16 == cr.isr +// r17 == cr.iim +// r18 == XSI_PSR_IC_OFS +// r19 == vpsr.ic (low 32 bits) | vpsr.i (high 32 bits) +// r31 == pr +GLOBAL_ENTRY(fast_hyperprivop) + //cover;; + // if domain interrupts pending, give up for now and do it the slow way + adds r20=XSI_PEND_OFS-XSI_PSR_IC_OFS,r18 ;; + ld8 r20=[r20] ;; + cmp.ne p7,p0=r0,r20 +(p7) br.sptk.many dispatch_break_fault ;; + + // HYPERPRIVOP_RFI? + cmp.eq p7,p6=XEN_HYPER_RFI,r17 +(p7) br.sptk.many hyper_rfi;; + // if not rfi, give up for now and do it the slow way + br.sptk.many dispatch_break_fault ;; + +// ensure that, if giving up, registers at entry to fast_hyperprivop unchanged +ENTRY(hyper_rfi) + adds r20=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;; + ld8 r21=[r20];; // r21 = vcr.ipsr + extr.u r22=r21,IA64_PSR_BE_BIT,1 ;; + // if turning on psr.be, give up for now and do it the slow way + cmp.ne p7,p0=r22,r0 +(p7) br.sptk.many dispatch_break_fault ;; + // if (!(vpsr.dt && vpsr.rt && vpsr.it)), do it the slow way + movl r20=(IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_IT);; + and r22=r20,r21 + ;; + cmp.ne p7,p0=r22,r20 +(p7) br.sptk.many dispatch_break_fault ;; + // if was in metaphys mode, do it the slow way (FIXME later?) + adds r20=XSI_METAPHYS_OFS-XSI_PSR_IC_OFS,r18 ;; + ld4 r20=[r20];; + cmp.ne p7,p0=r20,r0 +(p7) br.sptk.many dispatch_break_fault ;; + // if domain hasn't already done virtual bank switch + // do it the slow way (FIXME later?) + adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;; + ld4 r20=[r20];; + cmp.eq p7,p0=r20,r0 +(p7) br.sptk.many dispatch_break_fault ;; + // validate vcr.iip, if in Xen range, do it the slow way + adds r20=XSI_IIP_OFS-XSI_PSR_IC_OFS,r18 ;; + ld8 r22=[r20];; + movl r23=XEN_VIRT_SPACE_LOW + movl r24=XEN_VIRT_SPACE_HIGH ;; + cmp.ltu p0,p7=r22,r23 ;; // if !(iip=high) +(p7) br.sptk.many dispatch_break_fault ;; + + // OK now, let's do an rfi. + // r18=&vpsr.i|vpsr.ic, r21==vpsr, r20==&vcr.iip, r22=vcr.iip + mov cr.iip=r22;; + adds r20=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;; + st4 [r20]=r0 ;; + adds r20=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;; + ld8 r20=[r20];; + dep r20=0,r20,38,25;; // ensure ifs has no reserved bits set + mov cr.ifs=r20 ;; +// TODO: increment a counter so we can count how many rfi's go the fast way +// but where? counter must be pinned + // ipsr.cpl == (vcr.ipsr.cpl == 0) 2 : 3; + dep r21=-1,r21,IA64_PSR_CPL1_BIT,1 ;; + // vpsr.i = vcr.ipsr.i; vpsr.ic = vcr.ipsr.ic + mov r19=r0 ;; + extr.u r22=r21,IA64_PSR_I_BIT,1 ;; + cmp.ne p7,p6=r22,r0 ;; +(p7) dep r19=-1,r19,32,1 + extr.u r22=r21,IA64_PSR_IC_BIT,1 ;; + cmp.ne p7,p6=r22,r0 ;; +(p7) dep r19=-1,r19,0,1 ;; + st8 [r18]=r19 ;; + // force on psr.ic, i, dt, rt, it, bn + movl r20=(IA64_PSR_I|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_IT|IA64_PSR_BN) + ;; + or r21=r21,r20 + ;; + mov cr.ipsr=r21 + mov pr=r31,-1 + ;; + rfi + ;; diff --git a/xen/arch/ia64/ivt.S b/xen/arch/ia64/ivt.S index 449306c61b..0938f6075e 100644 --- a/xen/arch/ia64/ivt.S +++ b/xen/arch/ia64/ivt.S @@ -792,6 +792,7 @@ ENTRY(break_fault) // Later, they will be fast hand-coded assembly with psr.ic off // which means no calls, no use of r1-r15 and no memory accesses // except to pinned addresses! +#define FAST_HYPERPRIVOPS #ifdef FAST_HYPERPRIVOPS br.sptk.many fast_hyperprivop #else @@ -917,9 +918,10 @@ END(interrupt) // fault ever gets "unreserved", simply moved the following code to a more // suitable spot... -ENTRY(dispatch_break_fault) +GLOBAL_ENTRY(dispatch_break_fault) SAVE_MIN_WITH_COVER ;; +dispatch_break_fault_post_save: alloc r14=ar.pfs,0,0,4,0 // now it's safe (must be first in insn group!) mov out0=cr.ifa adds out1=16,sp @@ -1796,6 +1798,15 @@ ENTRY(dispatch_reflection) mov rp=r14 br.sptk.many ia64_prepare_handle_reflection END(dispatch_reflection) + +#define SAVE_MIN_COVER_DONE DO_SAVE_MIN(,mov r30=cr.ifs,) + +// same as dispatch_break_fault except cover has already been done +GLOBAL_ENTRY(dispatch_slow_hyperprivop) + SAVE_MIN_COVER_DONE + ;; + br.sptk.many dispatch_break_fault_post_save +END(dispatch_slow_hyperprivop) #endif #ifdef CONFIG_IA32_SUPPORT diff --git a/xen/arch/ia64/privop.c b/xen/arch/ia64/privop.c index ad2044e909..0fba1d502f 100644 --- a/xen/arch/ia64/privop.c +++ b/xen/arch/ia64/privop.c @@ -981,7 +981,7 @@ int dump_hyperprivop_counts(char *buf) { int i; char *s = buf; - s += sprintf(s,"Hyperprivops:\n"); + s += sprintf(s,"Slow hyperprivops:\n"); for (i = 1; i <= HYPERPRIVOP_MAX; i++) if (hyperpriv_cnt[i]) s += sprintf(s,"%10d %s\n", diff --git a/xen/include/asm-ia64/xensystem.h b/xen/include/asm-ia64/xensystem.h index 55209d874c..7c63a738b0 100644 --- a/xen/include/asm-ia64/xensystem.h +++ b/xen/include/asm-ia64/xensystem.h @@ -14,10 +14,10 @@ #include /* Define HV space hierarchy */ -#ifdef CONFIG_VTI #define XEN_VIRT_SPACE_LOW 0xe800000000000000 #define XEN_VIRT_SPACE_HIGH 0xf800000000000000 /* This is address to mapping rr7 switch stub, in region 5 */ +#ifdef CONFIG_VTI #define XEN_RR7_SWITCH_STUB 0xb700000000000000 #endif // CONFIG_VTI diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h index 8c785d65d6..ebae4b89c3 100644 --- a/xen/include/public/arch-ia64.h +++ b/xen/include/public/arch-ia64.h @@ -81,4 +81,11 @@ typedef struct vcpu_guest_context { #endif /* !__ASSEMBLY__ */ +#define XEN_HYPER_RFI 1 +#define XEN_HYPER_RSM_PSR_DT 2 +#define XEN_HYPER_SSM_PSR_DT 3 +#define XEN_HYPER_COVER 4 +#define XEN_HYPER_ITC_D 5 +#define XEN_HYPER_ITC_I 6 + #endif /* __HYPERVISOR_IF_IA64_H__ */ From 294f78094890bed79582ebdf5bc3160aaba29da9 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Thu, 26 May 2005 16:02:35 +0000 Subject: [PATCH 5/5] bitkeeper revision 1.1564.1.3 (4295f31bXXSt2FVu5PG4ForW7oosIw) One-liner to resolve link error due to recent core changes to idle --- xen/arch/ia64/domain.c | 1 - 1 file changed, 1 deletion(-) diff --git a/xen/arch/ia64/domain.c b/xen/arch/ia64/domain.c index 54a3b68e50..772b4bd99d 100644 --- a/xen/arch/ia64/domain.c +++ b/xen/arch/ia64/domain.c @@ -133,7 +133,6 @@ void startup_cpu_idle_loop(void) * Therefore memory barrier to ensure state is visible. */ smp_mb(); - init_idle(); #if 0 //do we have to ensure the idle task has a shared page so that, for example, //region registers can be loaded from it. Apparently not...