Re: [Xen-ia64-devel] [patch 06/12] ia64: kexec: Repining for EFI RID
On Thu, Mar 20, 2008 at 05:52:54PM +1100, Simon Horman wrote: Index: xen-unstable.hg/xen/arch/ia64/xen/xenasm.S === --- xen-unstable.hg.orig/xen/arch/ia64/xen/xenasm.S 2008-04-22 11:24:46.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/xenasm.S2008-04-22 16:56:00.0 +1000 @@ -195,6 +195,193 @@ GLOBAL_ENTRY(ia64_new_rr7) ... +GLOBAL_ENTRY(ia64_new_rr7_efi) ... + // 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_SHIFT2 + ;; + 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: VPD must be pinned not only by itr[], but also dtr[] too. SDM 2.2 vol2 says that VPD must be pinned down by both ITR and DTR. See the pal call section, PAL_VP_REGISTER, PAL_VP_RESTORE, PAL_VP_SAVE, PAL_VPS_RESTORE, PAL_VPS_SAVE. It's very unintuitive to pin down by ITR. And I think ia64_do_tlb_purge() have to purge not only dtr[], but also itr[IA64_TR_VPD]. -- yamahata ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel
Re: [Xen-ia64-devel] [patch 06/12] ia64: kexec: Repining for EFI RID
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) Fri, 25 Apr 2008 11:28:58 +1000 * Remove commented out code from ia64_new_rr7_efi() as it was only there for debugging purposes. Tue, 29 Apr 2008 06:04:02 +1000 * There is no need to check that the stack (current) overlaps with the kernel in ia64_new_rr7_efi since KERNEL_START was recently moved to 0xa001. This reflects similar a made to ia64_new_rr7(). Thanks to Yamahata-san for pointing this out. Index: xen-unstable.hg/xen/arch/ia64/xen/regionreg.c === --- xen-unstable.hg.orig/xen/arch/ia64/xen/regionreg.c 2008-04-28 10:14:43.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/regionreg.c 2008-04-28 10:15:16.0 +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 @@ -283,6 +287,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-28 10:03:31.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/xenasm.S 2008-04-28 10:20:50.0 +1000 @@ -195,6 +195,168 @@ 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 + };; +
Re: [Xen-ia64-devel] [patch 06/12] ia64: kexec: Repining for EFI RID
On Fri, Apr 25, 2008 at 11:30:57AM +1000, Simon Horman wrote: Index: xen-unstable.hg/xen/arch/ia64/xen/xenasm.S === --- xen-unstable.hg.orig/xen/arch/ia64/xen/xenasm.S 2008-04-25 11:17:22.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/xenasm.S2008-04-25 11:18:36.0 +1000 @@ -195,6 +195,175 @@ GLOBAL_ENTRY(ia64_new_rr7) ... +GLOBAL_ENTRY(ia64_new_rr7_efi) ... + // re-pin mappings for kernel text and data + mov r24=KERNEL_TR_PAGE_SHIFT2 + 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_SHIFT2 + 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: Now the text area starts at KERNEL_START = 0xa001 which is out of the xen identity mapping area. The above overlapping check always fails so that the check is unnecessary. Please check the current ia64_new_rr7() which was chenged rather recently. -- yamahata ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel
Re: [Xen-ia64-devel] [patch 06/12] ia64: kexec: Repining for EFI RID
On Fri, Apr 25, 2008 at 03:36:53PM +0900, Isaku Yamahata wrote: On Fri, Apr 25, 2008 at 11:30:57AM +1000, Simon Horman wrote: Index: xen-unstable.hg/xen/arch/ia64/xen/xenasm.S === --- xen-unstable.hg.orig/xen/arch/ia64/xen/xenasm.S 2008-04-25 11:17:22.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/xenasm.S 2008-04-25 11:18:36.0 +1000 @@ -195,6 +195,175 @@ GLOBAL_ENTRY(ia64_new_rr7) ... +GLOBAL_ENTRY(ia64_new_rr7_efi) ... + // re-pin mappings for kernel text and data + mov r24=KERNEL_TR_PAGE_SHIFT2 + 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_SHIFT2 + 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: Now the text area starts at KERNEL_START = 0xa001 which is out of the xen identity mapping area. The above overlapping check always fails so that the check is unnecessary. Please check the current ia64_new_rr7() which was chenged rather recently. Thanks, I missed that change. ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel
Re: [Xen-ia64-devel] [patch 06/12] ia64: kexec: Repining for EFI RID
On Thu, Apr 24, 2008 at 03:55:15AM +0200, Tristan Gingold wrote: On Thu, Apr 24, 2008 at 09:04:01AM +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. Hi, is it for efficienty or fonctionnaly required ? The reason that it is cut down is just for functionality. The functionlity could be merged into the existing code. But I thought that would be best to get it right first. This is particularly true of the asm code, which I think could become very messy. As for the reason for switching the RID in the first place. This is to protect the memory from HVM domains. 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 Humm, even PAL ? Yes, surprisingly so. Though it does seem to be harmless to repin it. -- Horms ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel
Re: [Xen-ia64-devel] [patch 06/12] ia64: kexec: Repining for EFI RID
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.c2008-04-24 08:31:32.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/regionreg.c 2008-04-24 08:33:36.0 +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.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/xenasm.S2008-04-24 08:33:36.0 +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
Re: [Xen-ia64-devel] [patch 06/12] ia64: kexec: Repining for EFI RID
On Thu, Apr 24, 2008 at 01:46:48PM -0600, Alex Williamson wrote: 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, I will remove the commented out section of asm, it is code that doesn' seem to be needed and can always be readed later if it turns out to be neccessary. The commented out lines are also artifacts of debugging, I'll clean them up - sorry I didn't do that before posting. With regards to the FIXME, this is a cut and paste from ia64_new_rr7(), which is the basis for ia64_new_rr7_efi(). I would be very happy for someone more familiar with unwind statements to help out. 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.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/regionreg.c 2008-04-24 08:33:36.0 +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.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/xenasm.S 2008-04-24 08:33:36.0 +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
Re: [Xen-ia64-devel] [patch 06/12] ia64: kexec: Repining for EFI RID
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) Fri, 25 Apr 2008 11:28:58 +1000 * Remove commented out code from ia64_new_rr7_efi() as it was only there for debugging purposes. Index: xen-unstable.hg/xen/arch/ia64/xen/regionreg.c === --- xen-unstable.hg.orig/xen/arch/ia64/xen/regionreg.c 2008-04-25 11:17:28.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/regionreg.c 2008-04-25 11:17:29.0 +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-25 11:17:22.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/xenasm.S 2008-04-25 11:18:36.0 +1000 @@ -195,6 +195,175 @@ 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
Re: [Xen-ia64-devel] [patch 06/12] ia64: kexec: Repining for EFI RID
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.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/regionreg.c 2008-04-24 08:33:36.0 +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.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/xenasm.S 2008-04-24 08:33:36.0 +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//
Re: [Xen-ia64-devel] [patch 06/12] ia64: kexec: Repining for EFI RID
On Thu, Apr 24, 2008 at 09:04:01AM +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. Hi, is it for efficienty or fonctionnaly required ? 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 Humm, even PAL ? Tristan. ___ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel
[Xen-ia64-devel] [patch 06/12] ia64: kexec: Repining for EFI RID
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 Index: xen-unstable.hg/xen/arch/ia64/xen/regionreg.c === --- xen-unstable.hg.orig/xen/arch/ia64/xen/regionreg.c 2008-04-22 11:26:03.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/regionreg.c 2008-04-22 16:56:11.0 +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 +287,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-22 11:24:46.0 +1000 +++ xen-unstable.hg/xen/arch/ia64/xen/xenasm.S 2008-04-22 16:56:00.0 +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 + ;; +