# HG changeset patch # User Tristan Gingold # Date 1178512173 -7200 # Node ID 56913057a5b0df0d5dc7473afef322d314750842 # Parent 4b3218254746cdf69b00d3df53f2e1f9ace38a30 Small cleanup: vcpu_get_psr now returns the virtual psr. vcpu_set_psr_interrupt sets psr for interrupt delivering. vcpu_get_psr_masked returns psr for mov from psr. Signed-off-by: Tristan Gingold diff -r 4b3218254746 -r 56913057a5b0 xen/arch/ia64/xen/faults.c --- a/xen/arch/ia64/xen/faults.c Sun May 06 06:39:56 2007 +0200 +++ b/xen/arch/ia64/xen/faults.c Mon May 07 06:29:33 2007 +0200 @@ -38,19 +38,6 @@ extern int ia64_hyperprivop(unsigned lon extern int ia64_hyperprivop(unsigned long, REGS *); extern IA64FAULT ia64_hypercall(struct pt_regs *regs); -#define IA64_PSR_CPL1 (__IA64_UL(1) << IA64_PSR_CPL1_BIT) -// note IA64_PSR_PK removed from following, why is this necessary? -#define DELIVER_PSR_SET (IA64_PSR_IC | IA64_PSR_I | \ - IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_CPL1 | \ - IA64_PSR_IT | IA64_PSR_BN) - -#define DELIVER_PSR_CLR (IA64_PSR_AC | IA64_PSR_DFL | IA64_PSR_DFH | \ - IA64_PSR_SP | IA64_PSR_DI | IA64_PSR_SI | \ - IA64_PSR_DB | IA64_PSR_LP | IA64_PSR_TB | \ - IA64_PSR_CPL| IA64_PSR_MC | IA64_PSR_IS | \ - IA64_PSR_ID | IA64_PSR_DA | IA64_PSR_DD | \ - IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | IA64_PSR_IA) - extern void do_ssc(unsigned long ssc, struct pt_regs *regs); // should never panic domain... if it does, stack may have been overrun @@ -83,22 +70,14 @@ void reflect_interruption(unsigned long check_bad_nested_interruption(isr, regs, vector); PSCB(v, unat) = regs->ar_unat; // not sure if this is really needed? PSCB(v, precover_ifs) = regs->cr_ifs; - PSCB(v, ipsr) = vcpu_get_ipsr_int_state(v, regs->cr_ipsr); + PSCB(v, ipsr) = vcpu_get_psr(v); vcpu_bsw0(v); PSCB(v, isr) = isr; PSCB(v, iip) = regs->cr_iip; PSCB(v, ifs) = 0; regs->cr_iip = ((unsigned long)PSCBX(v, iva) + vector) & ~0xffUL; - regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET; - if (PSCB(v, dcr) & IA64_DCR_BE) - regs->cr_ipsr |= IA64_PSR_BE; - - if (PSCB(v, hpsr_dfh)) - regs->cr_ipsr |= IA64_PSR_DFH; - PSCB(v, vpsr_dfh) = 0; - v->vcpu_info->evtchn_upcall_mask = 1; - PSCB(v, interrupt_collection_enabled) = 0; + vcpu_set_psr_interrupt (v); perfc_incra(slow_reflect, vector >> 8); } @@ -148,22 +127,14 @@ void reflect_event(void) regs->cr_ipsr, regs->cr_iip, isr, PSCB(v, iip)); PSCB(v, unat) = regs->ar_unat; // not sure if this is really needed? PSCB(v, precover_ifs) = regs->cr_ifs; - PSCB(v, ipsr) = vcpu_get_ipsr_int_state(v, regs->cr_ipsr); + PSCB(v, ipsr) = vcpu_get_psr(v); vcpu_bsw0(v); PSCB(v, isr) = isr; PSCB(v, iip) = regs->cr_iip; PSCB(v, ifs) = 0; regs->cr_iip = v->arch.event_callback_ip; - regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET; - if (PSCB(v, dcr) & IA64_DCR_BE) - regs->cr_ipsr |= IA64_PSR_BE; - - if (PSCB(v, hpsr_dfh)) - regs->cr_ipsr |= IA64_PSR_DFH; - PSCB(v, vpsr_dfh) = 0; - v->vcpu_info->evtchn_upcall_mask = 1; - PSCB(v, interrupt_collection_enabled) = 0; + vcpu_set_psr_interrupt (v); } // ONLY gets called from ia64_leave_kernel @@ -269,12 +240,7 @@ void ia64_do_page_fault(unsigned long ad fault = IA64_DATA_NESTED_TLB_VECTOR; regs->cr_iip = ((unsigned long)PSCBX(current, iva) + fault) & ~0xffUL; - regs->cr_ipsr = - (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET; - - if (PSCB(current, hpsr_dfh)) - regs->cr_ipsr |= IA64_PSR_DFH; - PSCB(current, vpsr_dfh) = 0; + vcpu_set_psr_interrupt (current); perfc_incra(slow_reflect, fault >> 8); return; } diff -r 4b3218254746 -r 56913057a5b0 xen/arch/ia64/xen/privop.c --- a/xen/arch/ia64/xen/privop.c Sun May 06 06:39:56 2007 +0200 +++ b/xen/arch/ia64/xen/privop.c Mon May 07 06:29:33 2007 +0200 @@ -524,7 +524,7 @@ static IA64FAULT priv_mov_from_psr(VCPU u64 val; IA64FAULT fault; - fault = vcpu_get_psr(vcpu, &val); + fault = vcpu_get_psr_masked(vcpu, &val); if (fault == IA64_NO_FAULT) return vcpu_set_gr(vcpu, tgt, val, 0); else @@ -883,7 +883,7 @@ int ia64_hyperprivop(unsigned long iim, vcpu_reset_psr_sm(v, IA64_PSR_BE); return 1; case HYPERPRIVOP_GET_PSR: - vcpu_get_psr(v, &val); + vcpu_get_psr_masked(v, &val); regs->r8 = val; return 1; } diff -r 4b3218254746 -r 56913057a5b0 xen/arch/ia64/xen/vcpu.c --- a/xen/arch/ia64/xen/vcpu.c Sun May 06 06:39:56 2007 +0200 +++ b/xen/arch/ia64/xen/vcpu.c Mon May 07 06:29:33 2007 +0200 @@ -51,6 +51,21 @@ typedef union { #define IA64_PTA_BASE_BIT 15 #define IA64_PTA_LFMT (1UL << IA64_PTA_VF_BIT) #define IA64_PTA_SZ(x) (x##UL << IA64_PTA_SZ_BIT) + +#define IA64_PSR_CPL1 (__IA64_UL(1) << IA64_PSR_CPL1_BIT) +// note IA64_PSR_PK removed from following, why is this necessary? +#define DELIVER_PSR_SET (IA64_PSR_IC | IA64_PSR_I | \ + IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_CPL1 | \ + IA64_PSR_IT | IA64_PSR_BN) + +#define DELIVER_PSR_CLR (IA64_PSR_AC | IA64_PSR_BE | \ + IA64_PSR_DFL | IA64_PSR_DFH | \ + IA64_PSR_SP | IA64_PSR_PP | \ + IA64_PSR_DI | IA64_PSR_SI | \ + IA64_PSR_DB | IA64_PSR_LP | IA64_PSR_TB | \ + IA64_PSR_CPL| IA64_PSR_MC | IA64_PSR_IS | \ + IA64_PSR_ID | IA64_PSR_DA | IA64_PSR_DD | \ + IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | IA64_PSR_IA) unsigned long vcpu_verbose = 0; @@ -331,9 +346,9 @@ IA64FAULT vcpu_set_psr_sm(VCPU * vcpu, u imm = *(struct ia64_psr *)&imm24; ipsr = (struct ia64_psr *)®s->cr_ipsr; // just handle psr.sp,pp and psr.i,ic (and user mask) for now - mask = - IA64_PSR_PP | IA64_PSR_SP | IA64_PSR_I | IA64_PSR_IC | IA64_PSR_UM | - IA64_PSR_DT | IA64_PSR_DFL | IA64_PSR_DFH | IA64_PSR_BE; + mask = (IA64_PSR_PP | IA64_PSR_SP | IA64_PSR_I | IA64_PSR_IC | + IA64_PSR_UM | IA64_PSR_DT | IA64_PSR_DFL | IA64_PSR_DFH | + IA64_PSR_BE); if (imm24 & ~mask) return IA64_ILLOP_FAULT; if (imm.dfh) { @@ -447,32 +462,51 @@ IA64FAULT vcpu_set_psr_l(VCPU * vcpu, u6 return IA64_NO_FAULT; } -IA64FAULT vcpu_get_psr(VCPU * vcpu, u64 * pval) +u64 vcpu_get_psr(VCPU * vcpu) { REGS *regs = vcpu_regs(vcpu); - struct ia64_psr newpsr; - - newpsr = *(struct ia64_psr *)®s->cr_ipsr; - if (!vcpu->vcpu_info->evtchn_upcall_mask) - newpsr.i = 1; - else - newpsr.i = 0; - if (PSCB(vcpu, interrupt_collection_enabled)) - newpsr.ic = 1; - else - newpsr.ic = 0; - if (PSCB(vcpu, metaphysical_mode)) - newpsr.dt = 0; - else - newpsr.dt = 1; - if (PSCB(vcpu, vpsr_pp)) - newpsr.pp = 1; - else - newpsr.pp = 0; - newpsr.dfh = PSCB(vcpu, vpsr_dfh); - - *pval = *(unsigned long *)&newpsr; - *pval &= (MASK(0, 32) | MASK(35, 2)); + PSR newpsr; + PSR ipsr; + unsigned int not_metaphysical; + + ipsr.i64 = regs->cr_ipsr; + + /* Copy user mask (not virtualized). */ + newpsr.i64 = ipsr.i64 & (IA64_PSR_BE | IA64_PSR_UP | IA64_PSR_AC + | IA64_PSR_MFL | IA64_PSR_MFH); + + /* System mask. */ + newpsr.ia64_psr.ic = !!PSCB(vcpu, interrupt_collection_enabled); + newpsr.ia64_psr.i = !vcpu->vcpu_info->evtchn_upcall_mask; + newpsr.ia64_psr.pk = ipsr.ia64_psr.pk; /* Should be 0. */ + + not_metaphysical = !PSCB(vcpu, metaphysical_mode); + newpsr.ia64_psr.dt = not_metaphysical; + newpsr.ia64_psr.dfl = ipsr.ia64_psr.dfl; + newpsr.ia64_psr.dfh = !!PSCB(vcpu, vpsr_dfh); + newpsr.ia64_psr.sp = ipsr.ia64_psr.sp; + newpsr.ia64_psr.pp = !!PSCB(vcpu, vpsr_pp); + newpsr.ia64_psr.di = 1; /* Ia32 not supported. */ + newpsr.ia64_psr.si = 0; + + newpsr.i64 |= ipsr.i64 & (IA64_PSR_DB | IA64_PSR_LP | IA64_PSR_TB); + newpsr.ia64_psr.rt = not_metaphysical; + newpsr.ia64_psr.is = 0; /* Ia32 not supported. */ + newpsr.ia64_psr.mc = 1; + newpsr.ia64_psr.it = not_metaphysical; + newpsr.ia64_psr.cpl = ipsr.ia64_psr.cpl < 3 ? 0 : 3; /* Fool domain. */ + newpsr.i64 |= ipsr.i64 & (IA64_PSR_ID | IA64_PSR_DA | IA64_PSR_DD + | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED + | IA64_PSR_IA); + newpsr.ia64_psr.bn = PSCB(vcpu, banknum); + + return newpsr.i64; +} + +IA64FAULT vcpu_get_psr_masked(VCPU * vcpu, u64 * pval) +{ + u64 psr = vcpu_get_psr(vcpu); + *pval = psr & (MASK(0, 32) | MASK(35, 2)); return IA64_NO_FAULT; } @@ -486,28 +520,25 @@ BOOLEAN vcpu_get_psr_i(VCPU * vcpu) return !vcpu->vcpu_info->evtchn_upcall_mask; } -u64 vcpu_get_ipsr_int_state(VCPU * vcpu, u64 prevpsr) +void vcpu_set_psr_interrupt(VCPU * vcpu) { u64 dcr = PSCB(vcpu, dcr); - PSR psr; - - //printk("*** vcpu_get_ipsr_int_state (0x%016lx)...\n",prevpsr); - psr.i64 = prevpsr; - psr.ia64_psr.pp = 0; + REGS *regs = vcpu_regs(vcpu); + + /* Set cr_ipsr for delivering an interrupt. */ + regs->cr_ipsr = (regs->cr_ipsr & ~DELIVER_PSR_CLR) | DELIVER_PSR_SET; + if (dcr & IA64_DCR_BE) + regs->cr_ipsr |= IA64_PSR_BE; if (dcr & IA64_DCR_PP) - psr.ia64_psr.pp = 1; - psr.ia64_psr.ic = PSCB(vcpu, interrupt_collection_enabled); - psr.ia64_psr.i = !vcpu->vcpu_info->evtchn_upcall_mask; - psr.ia64_psr.bn = PSCB(vcpu, banknum); - psr.ia64_psr.dfh = PSCB(vcpu, vpsr_dfh); - psr.ia64_psr.dt = 1; - psr.ia64_psr.it = 1; - psr.ia64_psr.rt = 1; - if (psr.ia64_psr.cpl == 2) - psr.ia64_psr.cpl = 0; // !!!! fool domain - // psr.pk = 1; - //printk("returns 0x%016lx...\n",psr.i64); - return psr.i64; + regs->cr_ipsr |= IA64_PSR_PP; + + if (PSCB(vcpu, hpsr_dfh)) + regs->cr_ipsr |= IA64_PSR_DFH; + PSCB(vcpu, vpsr_dfh) = 0; + + /* i = 0, ic = 0. */ + vcpu->vcpu_info->evtchn_upcall_mask = 1; + PSCB(vcpu, interrupt_collection_enabled) = 0; } /************************************************************************** @@ -1359,17 +1390,16 @@ IA64FAULT vcpu_rfi(VCPU * vcpu) psr.ia64_psr.rt = 1; psr.ia64_psr.it = 1; psr.ia64_psr.bn = 1; - //psr.pk = 1; // checking pkeys shouldn't be a problem but seems broken + //psr.pk = 1; // pkeys shouldn't be a problem but seems broken + PSCB(vcpu, interrupt_collection_enabled) = 1; + vcpu_bsw1(vcpu); + vcpu->vcpu_info->evtchn_upcall_mask = !int_enable; + regs->cr_ipsr = psr.i64; ifs = PSCB(vcpu, ifs); if (ifs & 0x8000000000000000UL) regs->cr_ifs = ifs; - - regs->cr_ipsr = psr.i64; regs->cr_iip = PSCB(vcpu, iip); - PSCB(vcpu, interrupt_collection_enabled) = 1; - vcpu_bsw1(vcpu); - vcpu->vcpu_info->evtchn_upcall_mask = !int_enable; return IA64_NO_FAULT; } diff -r 4b3218254746 -r 56913057a5b0 xen/include/asm-ia64/vcpu.h --- a/xen/include/asm-ia64/vcpu.h Sun May 06 06:39:56 2007 +0200 +++ b/xen/include/asm-ia64/vcpu.h Mon May 07 06:29:33 2007 +0200 @@ -41,8 +41,9 @@ extern IA64FAULT vcpu_get_ar(VCPU * vcpu extern IA64FAULT vcpu_get_ar(VCPU * vcpu, u64 reg, u64 * val); /* psr */ extern BOOLEAN vcpu_get_psr_ic(VCPU * vcpu); -extern u64 vcpu_get_ipsr_int_state(VCPU * vcpu, u64 prevpsr); -extern IA64FAULT vcpu_get_psr(VCPU * vcpu, u64 * pval); +extern void vcpu_set_psr_interrupt(VCPU * vcpu); +extern u64 vcpu_get_psr(VCPU * vcpu); +extern IA64FAULT vcpu_get_psr_masked(VCPU * vcpu, u64 * pval); extern IA64FAULT vcpu_reset_psr_sm(VCPU * vcpu, u64 imm); extern IA64FAULT vcpu_set_psr_sm(VCPU * vcpu, u64 imm); extern IA64FAULT vcpu_set_psr_l(VCPU * vcpu, u64 val);