mirror of
https://github.com/xen-project/xen.git
synced 2026-10-30 03:00:05 +01:00
bitkeeper revision 1.1726.1.6 (42bb0675eG3PXvB-XpEs0EYcdos-EA)
ia64: Add fast reflection for most clock ticks Also, some additional debug output for various situations. Signed-off-by: Dan Magenheimer <dan.magenheimer@hp.com>
This commit is contained in:
1 parent
60ca0a2815
commit
862f7b6eb6
7 files changed
+220
-13
No files matched your search
@@ -88,6 +88,7 @@ void foo(void)
|
||||
|
||||
BLANK();
|
||||
DEFINE(IA64_CPUINFO_ITM_NEXT_OFFSET, offsetof (struct cpuinfo_ia64, itm_next));
|
||||
DEFINE(IA64_CPUINFO_PGD_QUICK_OFFSET, offsetof (struct cpuinfo_ia64, pgd_quick));
|
||||
|
||||
//DEFINE(IA64_SIGHAND_SIGLOCK_OFFSET,offsetof (struct sighand_struct, siglock));
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ unsigned long dom0_size = 512*1024*1024; //FIXME: Should be configurable
|
||||
//FIXME: alignment should be 256MB, lest Linux use a 256MB page size
|
||||
unsigned long dom0_align = 256*1024*1024;
|
||||
#else // CONFIG_VTI
|
||||
unsigned long dom0_size = 256*1024*1024; //FIXME: Should be configurable
|
||||
unsigned long dom0_size = 512*1024*1024; //FIXME: Should be configurable
|
||||
//FIXME: alignment should be 256MB, lest Linux use a 256MB page size
|
||||
unsigned long dom0_align = 64*1024*1024;
|
||||
#endif // CONFIG_VTI
|
||||
|
||||
@@ -43,7 +43,8 @@ ia64_hypercall (struct pt_regs *regs)
|
||||
#if 1
|
||||
#define SPURIOUS_VECTOR 15
|
||||
if (vcpu_check_pending_interrupts(v)!=SPURIOUS_VECTOR) {
|
||||
//printf("Domain trying to go idle when interrupt pending!\n");
|
||||
// int pi = vcpu_check_pending_interrupts(v);
|
||||
//printf("idle w/int#%d pending!\n",pi);
|
||||
//this shouldn't happen, but it apparently does quite a bit! so don't
|
||||
//allow it to happen... i.e. if a domain has an interrupt pending and
|
||||
//it tries to halt itself because it thinks it is idle, just return here
|
||||
|
||||
+190
-8
@@ -17,6 +17,10 @@
|
||||
#define FAST_HYPERPRIVOP_CNT
|
||||
#define FAST_REFLECT_CNT
|
||||
|
||||
// FIXME: This is defined in include/asm-ia64/hw_irq.h but this
|
||||
// doesn't appear to be include'able from assembly?
|
||||
#define IA64_TIMER_VECTOR 0xef
|
||||
|
||||
// Should be included from common header file (also in process.c)
|
||||
// NO PSR_CLR IS DIFFERENT! (CPL)
|
||||
#define IA64_PSR_CPL1 (__IA64_UL(1) << IA64_PSR_CPL1_BIT)
|
||||
@@ -241,14 +245,23 @@ ENTRY(hyper_ssm_i)
|
||||
adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18;
|
||||
adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;;
|
||||
bsw.1;;
|
||||
st8 [r2]=r16,16; st8 [r3]=r17,16 ;;
|
||||
st8 [r2]=r18,16; st8 [r3]=r19,16 ;;
|
||||
st8 [r2]=r20,16; st8 [r3]=r21,16 ;;
|
||||
st8 [r2]=r22,16; st8 [r3]=r23,16 ;;
|
||||
st8 [r2]=r24,16; st8 [r3]=r25,16 ;;
|
||||
st8 [r2]=r26,16; st8 [r3]=r27,16 ;;
|
||||
st8 [r2]=r28,16; st8 [r3]=r29,16 ;;
|
||||
st8 [r2]=r30,16; st8 [r3]=r31,16 ;;
|
||||
// FIXME: need to handle ar.unat!
|
||||
.mem.offset 0,0; st8.spill [r2]=r16,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r17,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r18,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r19,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r20,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r21,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r22,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r23,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r24,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r25,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r26,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r27,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r28,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r29,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r30,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r31,16 ;;
|
||||
movl r31=XSI_IPSR;;
|
||||
bsw.0 ;;
|
||||
mov r2=r30; mov r3=r29;;
|
||||
@@ -258,6 +271,175 @@ ENTRY(hyper_ssm_i)
|
||||
rfi
|
||||
;;
|
||||
|
||||
// reflect domain clock interrupt
|
||||
// r31 == pr
|
||||
// r30 == cr.ivr
|
||||
// r29 == rp
|
||||
GLOBAL_ENTRY(fast_tick_reflect)
|
||||
#define FAST_TICK
|
||||
#ifndef FAST_TICK
|
||||
br.cond.sptk.many rp;;
|
||||
#endif
|
||||
mov r28=IA64_TIMER_VECTOR;;
|
||||
cmp.ne p6,p0=r28,r30
|
||||
(p6) br.cond.sptk.many rp;;
|
||||
movl r20=(PERCPU_ADDR)+IA64_CPUINFO_ITM_NEXT_OFFSET;;
|
||||
ld8 r21=[r20];;
|
||||
mov r27=ar.itc;;
|
||||
cmp.ltu p6,p0=r21,r27
|
||||
(p6) br.cond.sptk.many rp;;
|
||||
mov r17=cr.ipsr;;
|
||||
// slow path if: ipsr.be==1, ipsr.pp==1
|
||||
extr.u r21=r17,IA64_PSR_BE_BIT,1 ;;
|
||||
cmp.ne p6,p0=r21,r0
|
||||
(p6) br.cond.sptk.many rp;;
|
||||
extr.u r21=r17,IA64_PSR_PP_BIT,1 ;;
|
||||
cmp.ne p6,p0=r21,r0
|
||||
(p6) br.cond.sptk.many rp;;
|
||||
#ifdef FAST_REFLECT_CNT
|
||||
movl r20=fast_reflect_count+((0x3000>>8)*8);;
|
||||
ld8 r21=[r20];;
|
||||
adds r21=1,r21;;
|
||||
st8 [r20]=r21;;
|
||||
#endif
|
||||
mov cr.eoi=r0;;
|
||||
mov rp=r29;;
|
||||
// vcpu_pend_timer(current)
|
||||
movl r18=XSI_PSR_IC;;
|
||||
adds r20=XSI_ITV_OFS-XSI_PSR_IC_OFS,r18 ;;
|
||||
ld8 r20=[r20];;
|
||||
cmp.eq p6,p0=r20,r0 // if cr.itv==0 done
|
||||
(p6) br.cond.sptk.many fast_tick_reflect_done;;
|
||||
tbit.nz p6,p0=r20,16;; // check itv.m (discard) bit
|
||||
(p6) br.cond.sptk.many fast_tick_reflect_done;;
|
||||
extr.u r27=r20,0,6 // r27 has low 6 bits of itv.vector
|
||||
extr.u r26=r20,6,2;; // r26 has irr index of itv.vector
|
||||
mov r19=IA64_KR(CURRENT);;
|
||||
adds r22=IA64_VCPU_DOMAIN_ITM_LAST_OFFSET,r19
|
||||
adds r23=IA64_VCPU_DOMAIN_ITM_OFFSET,r19;;
|
||||
ld8 r24=[r22];;
|
||||
ld8 r23=[r23];;
|
||||
cmp.eq p6,p0=r23,r24 // skip if this tick already delivered
|
||||
(p6) br.cond.sptk.many fast_tick_reflect_done;;
|
||||
// set irr bit
|
||||
adds r21=IA64_VCPU_IRR0_OFFSET,r19;
|
||||
shl r26=r26,3;;
|
||||
add r21=r21,r26;;
|
||||
mov r25=1;;
|
||||
shl r22=r25,r27;;
|
||||
ld8 r23=[r21];;
|
||||
or r22=r22,r23;;
|
||||
st8 [r21]=r22;;
|
||||
// set PSCB(pending_interruption)!
|
||||
adds r20=XSI_PEND_OFS-XSI_PSR_IC_OFS,r18 ;;
|
||||
st4 [r20]=r25;;
|
||||
|
||||
// if interrupted at pl0, we're done
|
||||
extr.u r16=r17,IA64_PSR_CPL0_BIT,2;;
|
||||
cmp.eq p6,p0=r16,r0;;
|
||||
(p6) br.cond.sptk.many fast_tick_reflect_done;;
|
||||
// now deliver to iva+0x3000
|
||||
// r17 == cr.ipsr
|
||||
// r18 == XSI_PSR_IC
|
||||
// r19 == IA64_KR(CURRENT)
|
||||
// r31 == pr
|
||||
|
||||
// if guest vpsr.i is off, we're done
|
||||
adds r21=XSI_PSR_I_OFS-XSI_PSR_IC_OFS,r18 ;;
|
||||
ld4 r21=[r21];;
|
||||
cmp.eq p6,p0=r21,r0
|
||||
(p6) br.cond.sptk.many fast_tick_reflect_done;;
|
||||
|
||||
// OK, we have a clock tick to deliver to the active domain!
|
||||
mov r16=cr.isr;;
|
||||
mov r29=cr.iip;;
|
||||
adds r21=XSI_IIP_OFS-XSI_PSR_IC_OFS,r18 ;;
|
||||
st8 [r21]=r29 ;;
|
||||
// set shared_mem isr
|
||||
extr.u r16=r16,38,1;; // grab cr.isr.ir bit
|
||||
dep r16=r16,r0,38,1 ;; // insert into cr.isr (rest of bits zero)
|
||||
extr.u r20=r17,41,2 ;; // get ipsr.ri
|
||||
dep r16=r20,r16,41,2 ;; // deposit cr.isr.ei
|
||||
adds r21=XSI_ISR_OFS-XSI_PSR_IC_OFS,r18 ;;
|
||||
st8 [r21]=r16 ;;
|
||||
// set cr.ipsr (make sure cpl==2!)
|
||||
mov r29=r17 ;;
|
||||
movl r28=DELIVER_PSR_SET;;
|
||||
movl r27=~(DELIVER_PSR_CLR|IA64_PSR_CPL0);;
|
||||
or r29=r29,r28;;
|
||||
and r29=r29,r27;;
|
||||
mov cr.ipsr=r29;;
|
||||
// set shared_mem ipsr (from ipsr in r17 with ipsr.ri already set)
|
||||
extr.u r29=r17,IA64_PSR_CPL0_BIT,2;;
|
||||
cmp.eq p6,p7=3,r29;;
|
||||
(p6) dep r17=-1,r17,IA64_PSR_CPL0_BIT,2
|
||||
(p7) dep r17=0,r17,IA64_PSR_CPL0_BIT,2
|
||||
;;
|
||||
movl r28=(IA64_PSR_DT|IA64_PSR_IT|IA64_PSR_RT);;
|
||||
movl r27=~(IA64_PSR_BE|IA64_PSR_PP|IA64_PSR_BN|IA64_PSR_I|IA64_PSR_IC);;
|
||||
dep r21=-1,r21,IA64_PSR_CPL1_BIT,1 ;;
|
||||
or r17=r17,r28;;
|
||||
and r17=r17,r27;;
|
||||
ld4 r16=[r18],4;;
|
||||
cmp.ne p6,p0=r16,r0;;
|
||||
(p6) dep r17=-1,r17,IA64_PSR_IC_BIT,1 ;;
|
||||
ld4 r16=[r18],-4;;
|
||||
cmp.ne p6,p0=r16,r0;;
|
||||
(p6) dep r17=-1,r17,IA64_PSR_I_BIT,1 ;;
|
||||
adds r21=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;;
|
||||
st8 [r21]=r17 ;;
|
||||
// set shared_mem interrupt_delivery_enabled to 0
|
||||
// set shared_mem interrupt_collection_enabled to 0
|
||||
st8 [r18]=r0;;
|
||||
// cover and set shared_mem precover_ifs to cr.ifs
|
||||
// set shared_mem ifs and incomplete_regframe to 0
|
||||
cover ;;
|
||||
mov r20=cr.ifs;;
|
||||
adds r21=XSI_INCOMPL_REG_OFS-XSI_PSR_IC_OFS,r18 ;;
|
||||
st4 [r21]=r0 ;;
|
||||
adds r21=XSI_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
|
||||
st8 [r21]=r0 ;;
|
||||
adds r21=XSI_PRECOVER_IFS_OFS-XSI_PSR_IC_OFS,r18 ;;
|
||||
st8 [r21]=r20 ;;
|
||||
// leave cr.ifs alone for later rfi
|
||||
// set iip to go to domain IVA break instruction vector
|
||||
adds r22=IA64_VCPU_IVA_OFFSET,r19;;
|
||||
ld8 r23=[r22];;
|
||||
movl r24=0x3000;;
|
||||
add r24=r24,r23;;
|
||||
mov cr.iip=r24;;
|
||||
// OK, now all set to go except for switch to virtual bank0
|
||||
mov r30=r2; mov r29=r3;;
|
||||
adds r2=XSI_BANK1_OFS-XSI_PSR_IC_OFS,r18;
|
||||
adds r3=(XSI_BANK1_OFS+8)-XSI_PSR_IC_OFS,r18;;
|
||||
bsw.1;;
|
||||
// FIXME: need to handle ar.unat!
|
||||
.mem.offset 0,0; st8.spill [r2]=r16,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r17,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r18,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r19,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r20,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r21,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r22,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r23,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r24,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r25,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r26,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r27,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r28,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r29,16 ;;
|
||||
.mem.offset 0,0; st8.spill [r2]=r30,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r31,16 ;;
|
||||
movl r31=XSI_IPSR;;
|
||||
bsw.0 ;;
|
||||
mov r2=r30; mov r3=r29;;
|
||||
adds r20=XSI_BANKNUM_OFS-XSI_PSR_IC_OFS,r18 ;;
|
||||
st4 [r20]=r0 ;;
|
||||
fast_tick_reflect_done:
|
||||
mov pr=r31,-1 ;;
|
||||
rfi
|
||||
END(fast_tick_reflect)
|
||||
|
||||
// reflect domain breaks directly to domain
|
||||
// FIXME: DOES NOT WORK YET
|
||||
// r16 == cr.isr
|
||||
|
||||
@@ -919,6 +919,21 @@ ENTRY(interrupt)
|
||||
DBG_FAULT(12)
|
||||
mov r31=pr // prepare to save predicates
|
||||
;;
|
||||
#ifdef XEN
|
||||
mov r30=cr.ivr // pass cr.ivr as first arg
|
||||
// FIXME: this is a hack... use cpuinfo.pgd_quick because its
|
||||
// not used anywhere else and we need a place to stash ivr and
|
||||
// there's no registers available unused by SAVE_MIN/REST
|
||||
movl r29=(PERCPU_ADDR)+IA64_CPUINFO_PGD_QUICK_OFFSET;;
|
||||
st8 [r29]=r30;;
|
||||
movl r28=slow_interrupt;;
|
||||
mov r29=rp;;
|
||||
mov rp=r28;;
|
||||
br.cond.sptk.many fast_tick_reflect
|
||||
;;
|
||||
slow_interrupt:
|
||||
mov rp=r29;;
|
||||
#endif
|
||||
SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3
|
||||
ssm psr.ic | PSR_DEFAULT_BITS
|
||||
;;
|
||||
@@ -928,7 +943,12 @@ ENTRY(interrupt)
|
||||
SAVE_REST
|
||||
;;
|
||||
alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
|
||||
#ifdef XEN
|
||||
movl out0=(PERCPU_ADDR)+IA64_CPUINFO_PGD_QUICK_OFFSET;;
|
||||
ld8 out0=[out0];;
|
||||
#else
|
||||
mov out0=cr.ivr // pass cr.ivr as first arg
|
||||
#endif
|
||||
add out1=16,sp // pass pointer to pt_regs as second arg
|
||||
;;
|
||||
srlz.d // make sure we see the effect of cr.ivr
|
||||
|
||||
@@ -781,6 +781,7 @@ ia64_hyperprivop(unsigned long iim, REGS *regs)
|
||||
// FIXME: Handle faults appropriately for these
|
||||
if (!iim || iim > HYPERPRIVOP_MAX) {
|
||||
printf("bad hyperprivop; ignored\n");
|
||||
printf("iim=%d, iip=%p\n",iim,regs->cr_iip);
|
||||
return 1;
|
||||
}
|
||||
slow_hyperpriv_cnt[iim]++;
|
||||
|
||||
@@ -191,8 +191,8 @@ void reflect_interruption(unsigned long ifa, unsigned long isr, unsigned long it
|
||||
if (vector != IA64_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(v,iip));
|
||||
panic_domain(regs,"psr.ic off, delivering fault=%lx,ipsr=%p,iip=%p,ifa=%p,isr=%p,PSCB.iip=%p\n",
|
||||
vector,regs->cr_ipsr,regs->cr_iip,ifa,isr,PSCB(v,iip));
|
||||
|
||||
}
|
||||
//printf("Delivering NESTED DATA TLB fault\n");
|
||||
@@ -754,7 +754,8 @@ if (!running_on_sim) { printf("SSC_OPEN, not implemented on hardware. (ignoring
|
||||
vcpu_set_gr(current,8,-1L);
|
||||
break;
|
||||
default:
|
||||
printf("ia64_handle_break: bad ssc code %lx, iip=%p, b0=%p\n",ssc,regs->cr_iip,regs->b0);
|
||||
printf("ia64_handle_break: bad ssc code %lx, iip=%p, b0=%p... spinning\n",ssc,regs->cr_iip,regs->b0);
|
||||
while(1);
|
||||
break;
|
||||
}
|
||||
vcpu_increment_iip(current);
|
||||
@@ -845,6 +846,7 @@ ia64_handle_reflection (unsigned long ifa, struct pt_regs *regs, unsigned long i
|
||||
break;
|
||||
case 26:
|
||||
printf("*** NaT fault... attempting to handle as privop\n");
|
||||
printf("isr=%p, ifa=%p,iip=%p,ipsr=%p\n",isr,ifa,regs->cr_iip,psr);
|
||||
vector = priv_emulate(v,regs,isr);
|
||||
if (vector == IA64_NO_FAULT) {
|
||||
printf("*** Handled privop masquerading as NaT fault\n");
|
||||
|
||||