Hi Simon,

   This series seems to work ok for me, at least as far as existing
functionality, I haven't tested kexec.  This patch has some commented
out code (a couple lines in the asm, then a chunk later).  Can this be
cleaned out, or should it at least be better commented about why it
remains?  There's also a rather obvious FIXME in this patch, has this
been resolved to your satisfaction, or can someone else on list familiar
with unwind statements comment?  Thanks,

        Alex

On Thu, 2008-04-24 at 09:04 +1000, Simon Horman wrote:
> A cut down version of set_one_rr (and ia64_new_rr7) for
> use when switching to the EFI RID for SAL, PAL and EFI calls.
> 
> There seems to be no need to repin: palcode, mapped_regs or vhpt in this
> case. If it turns they do need to be repinned then special care needs to
> betaken to track the correct value to repin.  That is generally the values
> that were most recently pinned by ia64_new_rr7.
> 
> ia64_new_rr7_efi can probably be merged with ia64_new_rr7,
> as they are quite similar, but for testing purposes it seems
> easier to keep them separate.
> 
> Cc: Isaku Yamahata <[EMAIL PROTECTED]>
> Cc: Alex Williamson <[EMAIL PROTECTED]>
> Cc: Aron Griffis <[EMAIL PROTECTED]>
> Signed-off-by: Simon Horman <[EMAIL PROTECTED]>
> 
> --- 
> 
> Wed, 23 Apr 2008 10:09:03 +1000
> * Repin VPD (privregs) if they have been pinned
>   - A separate patch handles unpinning on kexec
> 
> Thu, 24 Apr 2008 08:35:03 +1000
> * Move percpu_set declaration from xen/include/xen/cpumask.h
>   (symlink, generic code) to  xen/include/asm-ia64/regionreg.h
>   (file, architecture-specific code)
> 
> Index: xen-unstable.hg/xen/arch/ia64/xen/regionreg.c
> ===================================================================
> --- xen-unstable.hg.orig/xen/arch/ia64/xen/regionreg.c        2008-04-24 
> 08:31:32.000000000 +1000
> +++ xen-unstable.hg/xen/arch/ia64/xen/regionreg.c     2008-04-24 
> 08:33:36.000000000 +1000
> @@ -11,6 +11,7 @@
>  #include <linux/config.h>
>  #include <linux/types.h>
>  #include <linux/sched.h>
> +#include <linux/percpu.h>
>  #include <asm/page.h>
>  #include <asm/regionreg.h>
>  #include <asm/vhpt.h>
> @@ -20,6 +21,8 @@
>  
>  /* Defined in xemasm.S  */
>  extern void ia64_new_rr7(unsigned long rid, void *shared_info, void 
> *shared_arch_info, unsigned long shared_info_va, unsigned long va_vhpt);
> +extern void ia64_new_rr7_efi(unsigned long rid, unsigned long percpu_pte,
> +                          unsigned long privregs);
>  
>  /* RID virtualization mechanism is really simple:  domains have less rid bits
>     than the host and the host rid space is shared among the domains.  (Values
> @@ -233,6 +236,7 @@ set_rr(unsigned long rr, unsigned long r
>  DEFINE_PER_CPU(unsigned long, inserted_vhpt);
>  #endif
>  DEFINE_PER_CPU(unsigned long, inserted_shared_info);
> +DEFINE_PER_CPU(unsigned long, inserted_privregs);
>  
>  // validates and changes a single region register
>  // in the currently executing domain
> @@ -281,6 +285,29 @@ int set_one_rr(unsigned long rr, unsigne
>       return 1;
>  }
>  
> +int set_one_rr_efi(unsigned long rr, unsigned long val)
> +{
> +     unsigned long rreg = REGION_NUMBER(rr);
> +     struct vcpu *v = current;
> +     int percpu_set_f;
> +     unsigned long privregs = 0UL;
> +
> +     BUG_ON(rreg != 6 && rreg != 7);
> +
> +     if (rreg == 6) {
> +             ia64_set_rr(rr, val);
> +             ia64_srlz_d();
> +     }
> +     else {
> +             percpu_set_f = cpu_isset(smp_processor_id(), percpu_set);
> +             if (percpu_set_f)
> +                     privregs = __get_cpu_var(inserted_privregs);
> +             ia64_new_rr7_efi(val, percpu_set_f, privregs);
> +     }
> +
> +     return 1;
> +}
> +
>  void set_virtual_rr0(void)
>  {
>       struct vcpu *v = current;
> Index: xen-unstable.hg/xen/arch/ia64/xen/xenasm.S
> ===================================================================
> --- xen-unstable.hg.orig/xen/arch/ia64/xen/xenasm.S   2008-04-23 
> 12:30:32.000000000 +1000
> +++ xen-unstable.hg/xen/arch/ia64/xen/xenasm.S        2008-04-24 
> 08:33:36.000000000 +1000
> @@ -195,6 +195,193 @@ GLOBAL_ENTRY(ia64_new_rr7)
>       br.ret.sptk.many rp
>  END(ia64_new_rr7)
>  
> +
> + /* ia64_new_rr7_efi:
> +  *   in0 = rid
> +  *   in1 = repin_percpu
> +  *   in2 = vpd vaddr
> +  *
> +  * There seems to be no need to repin: palcode, mapped_regs
> +  * or vhpt. If they do need to be repinned then special care
> +  * needs to betaken to track the correct value to repin.
> +  * That is generally the values that were most recently pinned by
> +  * ia64_new_rr7.
> +  *
> +  * This code function could probably be merged with ia64_new_rr7
> +  * as it is just a trimmed down version of that function.
> +  * However, current can change without repinning occuring,
> +  * so simply getting the values from current does not work correctly.
> +  */
> +
> +GLOBAL_ENTRY(ia64_new_rr7_efi)
> +     // FIXME? not sure this unwind statement is correct...
> +     .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(1)
> +     alloc loc1 = ar.pfs, 3, 9, 0, 0
> +     movl loc2=PERCPU_ADDR
> +1:   {
> +       mov loc3 = psr                // save psr
> +       mov loc0 = rp                 // save rp
> +       mov r8   = ip                 // save ip to compute branch
> +     };;
> +     .body
> +     tpa loc2=loc2                   // grab this BEFORE changing rr7
> +     adds r8 = 1f-1b,r8              // calculate return address for call
> +     ;;
> +     movl r17=PSR_BITS_TO_SET
> +     mov loc4=ar.rsc                 // save RSE configuration
> +     movl r16=PSR_BITS_TO_CLEAR
> +     ;;
> +     tpa r8=r8                       // convert rp to physical
> +     mov ar.rsc=0                    // put RSE in enforced lazy, LE mode
> +     or loc3=loc3,r17                // add in psr the bits to set
> +     ;;
> +        movl loc5=pal_vaddr             // get pal_vaddr
> +     ;;
> +     ld8 loc5=[loc5]                 // read pal_vaddr
> +     ;;
> +     dep loc7 = 0,in2,60,4           // get physical address of privregs
> +     ;;
> +     dep loc7 = 0,loc7,0,IA64_GRANULE_SHIFT
> +                                     // mask granule shift
> +     ;;
> +     andcm r16=loc3,r16              // removes bits to clear from psr
> +     dep loc6=0,r8,0,KERNEL_TR_PAGE_SHIFT // Xen code paddr
> +     br.call.sptk.many rp=ia64_switch_mode_phys
> +//1:
> +     movl    r26=PAGE_KERNEL
> +     // now in physical mode with psr.i/ic off so do rr7 switch
> +     dep r16=-1,r0,61,3
> +     ;;
> +     mov     loc8=rr[r16]
> +     ;;
> +     mov     rr[r16]=in0
> +     //mov   rr[r16]=loc8
> +     ;;
> +     srlz.d
> +
> +     // re-pin mappings for kernel text and data
> +     mov r24=KERNEL_TR_PAGE_SHIFT<<2
> +     movl r17=KERNEL_START
> +     ;;
> +     ptr.i   r17,r24
> +     ;;
> +     ptr.d   r17,r24
> +     ;;
> +     srlz.i
> +     ;;
> +     srlz.d
> +     ;;
> +     mov r16=IA64_TR_KERNEL
> +     mov cr.itir=r24
> +     mov cr.ifa=r17
> +     or r18=loc6,r26
> +     ;;
> +     itr.i itr[r16]=r18
> +     ;;
> +     itr.d dtr[r16]=r18
> +     ;;
> +     srlz.i
> +     ;;
> +     srlz.d
> +     ;;
> +
> +     // re-pin mappings for stack (current)
> +
> +     // unless overlaps with KERNEL_TR
> +     dep r18=0,r13,0,KERNEL_TR_PAGE_SHIFT
> +     ;;
> +     cmp.eq p7,p0=r17,r18
> +(p7) br.cond.sptk ia64_new_rr7_efi_stack_overlaps
> +     mov r25=IA64_GRANULE_SHIFT<<2
> +     dep r21=0,r13,60,4              // physical address of "current"
> +     ;;
> +     ptr.d   r13,r25
> +     ;;
> +     srlz.d
> +     ;;
> +     or r23=r21,r26                  // construct PA | page properties
> +     mov cr.itir=r25
> +     mov cr.ifa=r13                  // VA of next task...
> +     mov r21=IA64_TR_CURRENT_STACK
> +     ;;
> +     itr.d dtr[r21]=r23              // wire in new mapping...
> +     ;;
> +     srlz.d
> +     ;;
> +ia64_new_rr7_efi_stack_overlaps:
> +
> +     //  Per-cpu
> +     cmp.eq p7,p0=r0,in1
> +(p7) br.cond.sptk ia64_new_rr7_efi_percpu_not_mapped
> +     mov r24=PERCPU_PAGE_SHIFT<<2
> +     movl r22=PERCPU_ADDR
> +     ;;
> +     ptr.d   r22,r24
> +     ;;
> +     srlz.d
> +     ;;
> +     or r23=loc2,r26
> +     mov cr.itir=r24
> +     mov cr.ifa=r22
> +     mov r25=IA64_TR_PERCPU_DATA
> +     ;;
> +     itr.d dtr[r25]=r23              // wire in new mapping...
> +     ;;
> +     srlz.d
> +     ;;
> +ia64_new_rr7_efi_percpu_not_mapped:
> +
> +#if 0
> +     // Purge/insert PAL TR
> +     mov r24=IA64_TR_PALCODE
> +     mov r23=IA64_GRANULE_SHIFT<<2
> +     dep r25=0,loc5,60,4             // convert pal vaddr to paddr
> +     ;;
> +     dep r25 = 0,r25,0,IA64_GRANULE_SHIFT
> +                                     // mask granule shift
> +     ;;
> +     ptr.i   loc5,r23
> +     or r25=r25,r26                  // construct PA | page properties
> +     mov cr.itir=r23
> +     mov cr.ifa=loc5
> +     ;;
> +     itr.i itr[r24]=r25
> +#endif
> +
> +     //  privregs / mapped_regs
> +     cmp.eq p7,p0=r0,in2
> +(p7) br.cond.sptk ia64_new_rr7_efi_privregs_not_mapped
> +     or loc7 = r26,loc7              // construct PA | page properties
> +     mov r22=IA64_TR_VPD
> +     mov r24=IA64_TR_MAPPED_REGS
> +     mov r23=IA64_GRANULE_SHIFT<<2
> +     ;;
> +     ptr.i   in2,r23
> +     ;;
> +     srlz.i
> +     ;;
> +     mov cr.itir=r23
> +     mov cr.ifa=in2
> +     ;;
> +     itr.i itr[r22]=loc7
> +     ;;
> +     srlz.i
> +ia64_new_rr7_efi_privregs_not_mapped:
> +
> +     // done, switch back to virtual and return
> +     mov r16=loc3                    // r16= original psr
> +     br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
> +     mov psr.l = loc3                // restore init PSR
> +     ;;
> +
> +     mov ar.pfs = loc1
> +     mov rp = loc0
> +     ;;
> +     mov ar.rsc=loc4                 // restore RSE configuration
> +     srlz.d                          // seralize restoration of psr.l
> +     br.ret.sptk.many rp
> +END(ia64_new_rr7_efi)
> +
>  #if 0 /* Not used */
>  #include "minstate.h"
>  
> Index: xen-unstable.hg/xen/include/asm-ia64/regionreg.h
> ===================================================================
> --- xen-unstable.hg.orig/xen/include/asm-ia64/regionreg.h     2008-04-24 
> 08:31:25.000000000 +1000
> +++ xen-unstable.hg/xen/include/asm-ia64/regionreg.h  2008-04-24 
> 08:38:08.000000000 +1000
> @@ -37,8 +37,12 @@ typedef union ia64_rr {
>  #define RR_RID_MASK     0x00000000ffffff00L
>  
>  DECLARE_PER_CPU(unsigned long, inserted_vhpt);
> +DECLARE_PER_CPU(unsigned long, inserted_privregs);
> +
> +extern cpumask_t percpu_set;
>  
>  int set_one_rr(unsigned long rr, unsigned long val);
> +int set_one_rr_efi(unsigned long rr, unsigned long val);
>  
>  // This function is purely for performance... apparently scrambling
>  //  bits in the region id makes for better hashing, which means better
> Index: xen-unstable.hg/xen/arch/ia64/xen/mm_init.c
> ===================================================================
> --- xen-unstable.hg.orig/xen/arch/ia64/xen/mm_init.c  2008-04-23 
> 12:30:32.000000000 +1000
> +++ xen-unstable.hg/xen/arch/ia64/xen/mm_init.c       2008-04-24 
> 08:33:36.000000000 +1000
> @@ -18,12 +18,16 @@ struct ia64_mca_tlb_info ia64_mca_tlb_li
>  
>  extern void ia64_tlb_init (void);
>  
> +#ifdef XEN
> +cpumask_t percpu_set;
> +#endif
> +
>  void __devinit
>  ia64_mmu_init (void *my_cpu_data)
>  {
>       unsigned long psr, impl_va_bits;
>       extern void __devinit tlb_init (void);
> -     int cpu;
> +     int cpu = smp_processor_id();
>  
>       /* Pin mapping for percpu area into TLB */
>       psr = ia64_clear_ic();
> @@ -33,6 +37,9 @@ ia64_mmu_init (void *my_cpu_data)
>  
>       ia64_set_psr(psr);
>       ia64_srlz_i();
> +#ifdef XEN
> +     cpu_set(cpu, percpu_set);
> +#endif
>  
>       /*
>        * Check if the virtually mapped linear page table (VMLPT) overlaps 
> with a mapped
> @@ -72,8 +79,6 @@ ia64_mmu_init (void *my_cpu_data)
>       ia64_srlz_d();
>  #endif
>  
> -     cpu = smp_processor_id();
> -
>       /* mca handler uses cr.lid as key to pick the right entry */
>       ia64_mca_tlb_list[cpu].cr_lid = ia64_getreg(_IA64_REG_CR_LID);
>  
> Index: xen-unstable.hg/xen/arch/ia64/vmx/vmx_phy_mode.c
> ===================================================================
> --- xen-unstable.hg.orig/xen/arch/ia64/vmx/vmx_phy_mode.c     2008-04-24 
> 08:31:25.000000000 +1000
> +++ xen-unstable.hg/xen/arch/ia64/vmx/vmx_phy_mode.c  2008-04-24 
> 08:33:36.000000000 +1000
> @@ -174,6 +174,7 @@ vmx_load_all_rr(VCPU *vcpu)
>  #if VHPT_ENABLED
>          __get_cpu_var(inserted_vhpt) = __va_ul(vcpu_vhpt_maddr(v));
>  #endif
> +     __get_cpu_var(inserted_privregs) = vcpu->arch.privregs;
>       vmx_switch_rr7(vrrtomrr(vcpu,VMX(vcpu, vrr[VRN7])),
>                        (void *)vcpu->arch.vhpt.hash,
>                      pal_vaddr, vcpu->arch.privregs);
> Index: xen-unstable.hg/xen/arch/ia64/vmx/vmx_vcpu.c
> ===================================================================
> --- xen-unstable.hg.orig/xen/arch/ia64/vmx/vmx_vcpu.c 2008-04-24 
> 08:31:25.000000000 +1000
> +++ xen-unstable.hg/xen/arch/ia64/vmx/vmx_vcpu.c      2008-04-24 
> 08:33:36.000000000 +1000
> @@ -184,6 +184,7 @@ IA64FAULT vmx_vcpu_set_rr(VCPU *vcpu, u6
>  #if VHPT_ENABLED
>              __get_cpu_var(inserted_vhpt) = __va_ul(vcpu_vhpt_maddr(v));
>  #endif
> +            __get_cpu_var(inserted_privregs) = vcpu->arch.privregs;
>              vmx_switch_rr7(vrrtomrr(vcpu,val), (void *)vcpu->arch.vhpt.hash,
>                             pal_vaddr, vcpu->arch.privregs);
>          }
> 
-- 
Alex Williamson                             HP Open Source & Linux Org.


_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@lists.xensource.com
http://lists.xensource.com/xen-ia64-devel

Reply via email to