# HG changeset patch # User Tristan Gingold # Date 1180905057 -7200 # Node ID 11fef86dbd31d08e915b36cca37fa8dfaca730ad # Parent e9716dd327fd9c3497c7deb8530541a3b4e1cfa4 Comment priv_rfi and forbid rfi emulation with double un-cover. Signed-off-by: Tristan Gingold diff -r e9716dd327fd -r 11fef86dbd31 xen/arch/ia64/xen/hyperprivop.S --- a/xen/arch/ia64/xen/hyperprivop.S Sat Jun 02 07:56:10 2007 +0200 +++ b/xen/arch/ia64/xen/hyperprivop.S Sun Jun 03 23:10:57 2007 +0200 @@ -1029,8 +1029,22 @@ ENTRY(slow_vcpu_rfi) ld8 r22=[r22];; tbit.z p6,p0=r22,63 (p6) br.spnt.few dispatch_break_fault ;; - // if vips is valid, discard current register frame - // don't need dorfirfi any more + // If vifs.v is set, we have two IFS to consider: + // * the guest IFS + // * the hypervisor IFS (valided by cover) + // Because IFS is copied to CFM and is used to adjust AR.BSP, + // virtualization of rfi is not easy. + // Previously there was a two steps method (a first rfi jumped to + // a stub which performed a new rfi). + // This new method discards the RS before executing the hypervisor + // cover. After cover, IFS.IFM will be zero. This IFS would simply + // clear CFM but not modifying AR.BSP. Therefore the guest IFS can + // be used instead and there is no need of a second rfi. + // Discarding the RS with the following alloc instruction just clears + // CFM, which is safe because rfi will overwrite it. + // There is a drawback: because the RS must be discarded before + // executing C code, emulation of rfi must go through an hyperprivop + // and not through normal instruction decoding. alloc r22=ar.pfs,0,0,0,0 br.spnt.few dispatch_break_fault ;; diff -r e9716dd327fd -r 11fef86dbd31 xen/arch/ia64/xen/privop.c --- a/xen/arch/ia64/xen/privop.c Sat Jun 02 07:56:10 2007 +0200 +++ b/xen/arch/ia64/xen/privop.c Sun Jun 03 23:10:57 2007 +0200 @@ -31,6 +31,15 @@ Privileged operation emulation routines static IA64FAULT priv_rfi(VCPU * vcpu, INST64 inst) { + REGS *regs = vcpu_regs(vcpu); + if (PSCB(vcpu, ifs) > 0x8000000000000000UL + && regs->cr_ifs > 0x8000000000000000UL) { + panic_domain(regs, + "rfi emulation with double uncover is " + "impossible - use hyperprivop\n" + " ip=0x%lx vifs=0x%lx ifs=0x%lx\n", + regs->cr_iip, PSCB(vcpu, ifs), regs->cr_ifs); + } return vcpu_rfi(vcpu); }