Commit 498c5170 authored by Isaku Yamahata's avatar Isaku Yamahata Committed by Tony Luck

[IA64] pvops: paravirtualize ivt.S

paravirtualize ivt.S which implements fault handler in hand written
assembly code.
They includes sensitive or performance critical privileged instructions.
So they need paravirtualization.

Cc: Keith Owens <kaos@ocs.com.au>
Cc: tgingold@free.fr
Cc: Akio Takebe <takebe_akio@jp.fujitsu.com>
Signed-off-by: default avatarYaozu (Eddie) Dong <eddie.dong@intel.com>
Signed-off-by: default avatarIsaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 02e32e36
...@@ -12,6 +12,14 @@ ...@@ -12,6 +12,14 @@
* *
* 00/08/23 Asit Mallick <asit.k.mallick@intel.com> TLB handling for SMP * 00/08/23 Asit Mallick <asit.k.mallick@intel.com> TLB handling for SMP
* 00/12/20 David Mosberger-Tang <davidm@hpl.hp.com> DTLB/ITLB handler now uses virtual PT. * 00/12/20 David Mosberger-Tang <davidm@hpl.hp.com> DTLB/ITLB handler now uses virtual PT.
*
* Copyright (C) 2005 Hewlett-Packard Co
* Dan Magenheimer <dan.magenheimer@hp.com>
* Xen paravirtualization
* Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
* pv_ops.
* Yaozu (Eddie) Dong <eddie.dong@intel.com>
*/ */
/* /*
* This file defines the interruption vector table used by the CPU. * This file defines the interruption vector table used by the CPU.
...@@ -102,13 +110,13 @@ ENTRY(vhpt_miss) ...@@ -102,13 +110,13 @@ ENTRY(vhpt_miss)
* - the faulting virtual address uses unimplemented address bits * - the faulting virtual address uses unimplemented address bits
* - the faulting virtual address has no valid page table mapping * - the faulting virtual address has no valid page table mapping
*/ */
mov r16=cr.ifa // get address that caused the TLB miss MOV_FROM_IFA(r16) // get address that caused the TLB miss
#ifdef CONFIG_HUGETLB_PAGE #ifdef CONFIG_HUGETLB_PAGE
movl r18=PAGE_SHIFT movl r18=PAGE_SHIFT
mov r25=cr.itir MOV_FROM_ITIR(r25)
#endif #endif
;; ;;
rsm psr.dt // use physical addressing for data RSM_PSR_DT // use physical addressing for data
mov r31=pr // save the predicate registers mov r31=pr // save the predicate registers
mov r19=IA64_KR(PT_BASE) // get page table base address mov r19=IA64_KR(PT_BASE) // get page table base address
shl r21=r16,3 // shift bit 60 into sign bit shl r21=r16,3 // shift bit 60 into sign bit
...@@ -168,21 +176,21 @@ ENTRY(vhpt_miss) ...@@ -168,21 +176,21 @@ ENTRY(vhpt_miss)
dep r21=r19,r20,3,(PAGE_SHIFT-3) // r21=pte_offset(pmd,addr) dep r21=r19,r20,3,(PAGE_SHIFT-3) // r21=pte_offset(pmd,addr)
;; ;;
(p7) ld8 r18=[r21] // read *pte (p7) ld8 r18=[r21] // read *pte
mov r19=cr.isr // cr.isr bit 32 tells us if this is an insn miss MOV_FROM_ISR(r19) // cr.isr bit 32 tells us if this is an insn miss
;; ;;
(p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared? (p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared?
mov r22=cr.iha // get the VHPT address that caused the TLB miss MOV_FROM_IHA(r22) // get the VHPT address that caused the TLB miss
;; // avoid RAW on p7 ;; // avoid RAW on p7
(p7) tbit.nz.unc p10,p11=r19,32 // is it an instruction TLB miss? (p7) tbit.nz.unc p10,p11=r19,32 // is it an instruction TLB miss?
dep r23=0,r20,0,PAGE_SHIFT // clear low bits to get page address dep r23=0,r20,0,PAGE_SHIFT // clear low bits to get page address
;; ;;
(p10) itc.i r18 // insert the instruction TLB entry ITC_I_AND_D(p10, p11, r18, r24) // insert the instruction TLB entry and
(p11) itc.d r18 // insert the data TLB entry // insert the data TLB entry
(p6) br.cond.spnt.many page_fault // handle bad address/page not present (page fault) (p6) br.cond.spnt.many page_fault // handle bad address/page not present (page fault)
mov cr.ifa=r22 MOV_TO_IFA(r22, r24)
#ifdef CONFIG_HUGETLB_PAGE #ifdef CONFIG_HUGETLB_PAGE
(p8) mov cr.itir=r25 // change to default page-size for VHPT MOV_TO_ITIR(p8, r25, r24) // change to default page-size for VHPT
#endif #endif
/* /*
...@@ -192,7 +200,7 @@ ENTRY(vhpt_miss) ...@@ -192,7 +200,7 @@ ENTRY(vhpt_miss)
*/ */
adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23 adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23
;; ;;
(p7) itc.d r24 ITC_D(p7, r24, r25)
;; ;;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* /*
...@@ -234,7 +242,7 @@ ENTRY(vhpt_miss) ...@@ -234,7 +242,7 @@ ENTRY(vhpt_miss)
#endif #endif
mov pr=r31,-1 // restore predicate registers mov pr=r31,-1 // restore predicate registers
rfi RFI
END(vhpt_miss) END(vhpt_miss)
.org ia64_ivt+0x400 .org ia64_ivt+0x400
...@@ -248,11 +256,11 @@ ENTRY(itlb_miss) ...@@ -248,11 +256,11 @@ ENTRY(itlb_miss)
* mode, walk the page table, and then re-execute the PTE read and * mode, walk the page table, and then re-execute the PTE read and
* go on normally after that. * go on normally after that.
*/ */
mov r16=cr.ifa // get virtual address MOV_FROM_IFA(r16) // get virtual address
mov r29=b0 // save b0 mov r29=b0 // save b0
mov r31=pr // save predicates mov r31=pr // save predicates
.itlb_fault: .itlb_fault:
mov r17=cr.iha // get virtual address of PTE MOV_FROM_IHA(r17) // get virtual address of PTE
movl r30=1f // load nested fault continuation point movl r30=1f // load nested fault continuation point
;; ;;
1: ld8 r18=[r17] // read *pte 1: ld8 r18=[r17] // read *pte
...@@ -261,7 +269,7 @@ ENTRY(itlb_miss) ...@@ -261,7 +269,7 @@ ENTRY(itlb_miss)
tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared? tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared?
(p6) br.cond.spnt page_fault (p6) br.cond.spnt page_fault
;; ;;
itc.i r18 ITC_I(p0, r18, r19)
;; ;;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* /*
...@@ -278,7 +286,7 @@ ENTRY(itlb_miss) ...@@ -278,7 +286,7 @@ ENTRY(itlb_miss)
(p7) ptc.l r16,r20 (p7) ptc.l r16,r20
#endif #endif
mov pr=r31,-1 mov pr=r31,-1
rfi RFI
END(itlb_miss) END(itlb_miss)
.org ia64_ivt+0x0800 .org ia64_ivt+0x0800
...@@ -292,11 +300,11 @@ ENTRY(dtlb_miss) ...@@ -292,11 +300,11 @@ ENTRY(dtlb_miss)
* mode, walk the page table, and then re-execute the PTE read and * mode, walk the page table, and then re-execute the PTE read and
* go on normally after that. * go on normally after that.
*/ */
mov r16=cr.ifa // get virtual address MOV_FROM_IFA(r16) // get virtual address
mov r29=b0 // save b0 mov r29=b0 // save b0
mov r31=pr // save predicates mov r31=pr // save predicates
dtlb_fault: dtlb_fault:
mov r17=cr.iha // get virtual address of PTE MOV_FROM_IHA(r17) // get virtual address of PTE
movl r30=1f // load nested fault continuation point movl r30=1f // load nested fault continuation point
;; ;;
1: ld8 r18=[r17] // read *pte 1: ld8 r18=[r17] // read *pte
...@@ -305,7 +313,7 @@ dtlb_fault: ...@@ -305,7 +313,7 @@ dtlb_fault:
tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared? tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared?
(p6) br.cond.spnt page_fault (p6) br.cond.spnt page_fault
;; ;;
itc.d r18 ITC_D(p0, r18, r19)
;; ;;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* /*
...@@ -322,7 +330,7 @@ dtlb_fault: ...@@ -322,7 +330,7 @@ dtlb_fault:
(p7) ptc.l r16,r20 (p7) ptc.l r16,r20
#endif #endif
mov pr=r31,-1 mov pr=r31,-1
rfi RFI
END(dtlb_miss) END(dtlb_miss)
.org ia64_ivt+0x0c00 .org ia64_ivt+0x0c00
...@@ -330,9 +338,9 @@ END(dtlb_miss) ...@@ -330,9 +338,9 @@ END(dtlb_miss)
// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19) // 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
ENTRY(alt_itlb_miss) ENTRY(alt_itlb_miss)
DBG_FAULT(3) DBG_FAULT(3)
mov r16=cr.ifa // get address that caused the TLB miss MOV_FROM_IFA(r16) // get address that caused the TLB miss
movl r17=PAGE_KERNEL movl r17=PAGE_KERNEL
mov r21=cr.ipsr MOV_FROM_IPSR(p0, r21)
movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
mov r31=pr mov r31=pr
;; ;;
...@@ -341,9 +349,9 @@ ENTRY(alt_itlb_miss) ...@@ -341,9 +349,9 @@ ENTRY(alt_itlb_miss)
;; ;;
cmp.gt p8,p0=6,r22 // user mode cmp.gt p8,p0=6,r22 // user mode
;; ;;
(p8) thash r17=r16 THASH(p8, r17, r16, r23)
;; ;;
(p8) mov cr.iha=r17 MOV_TO_IHA(p8, r17, r23)
(p8) mov r29=b0 // save b0 (p8) mov r29=b0 // save b0
(p8) br.cond.dptk .itlb_fault (p8) br.cond.dptk .itlb_fault
#endif #endif
...@@ -358,9 +366,9 @@ ENTRY(alt_itlb_miss) ...@@ -358,9 +366,9 @@ ENTRY(alt_itlb_miss)
or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6 or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6
(p8) br.cond.spnt page_fault (p8) br.cond.spnt page_fault
;; ;;
itc.i r19 // insert the TLB entry ITC_I(p0, r19, r18) // insert the TLB entry
mov pr=r31,-1 mov pr=r31,-1
rfi RFI
END(alt_itlb_miss) END(alt_itlb_miss)
.org ia64_ivt+0x1000 .org ia64_ivt+0x1000
...@@ -368,11 +376,11 @@ END(alt_itlb_miss) ...@@ -368,11 +376,11 @@ END(alt_itlb_miss)
// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46) // 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
ENTRY(alt_dtlb_miss) ENTRY(alt_dtlb_miss)
DBG_FAULT(4) DBG_FAULT(4)
mov r16=cr.ifa // get address that caused the TLB miss MOV_FROM_IFA(r16) // get address that caused the TLB miss
movl r17=PAGE_KERNEL movl r17=PAGE_KERNEL
mov r20=cr.isr MOV_FROM_ISR(r20)
movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
mov r21=cr.ipsr MOV_FROM_IPSR(p0, r21)
mov r31=pr mov r31=pr
mov r24=PERCPU_ADDR mov r24=PERCPU_ADDR
;; ;;
...@@ -381,9 +389,9 @@ ENTRY(alt_dtlb_miss) ...@@ -381,9 +389,9 @@ ENTRY(alt_dtlb_miss)
;; ;;
cmp.gt p8,p0=6,r22 // access to region 0-5 cmp.gt p8,p0=6,r22 // access to region 0-5
;; ;;
(p8) thash r17=r16 THASH(p8, r17, r16, r25)
;; ;;
(p8) mov cr.iha=r17 MOV_TO_IHA(p8, r17, r25)
(p8) mov r29=b0 // save b0 (p8) mov r29=b0 // save b0
(p8) br.cond.dptk dtlb_fault (p8) br.cond.dptk dtlb_fault
#endif #endif
...@@ -402,7 +410,7 @@ ENTRY(alt_dtlb_miss) ...@@ -402,7 +410,7 @@ ENTRY(alt_dtlb_miss)
tbit.nz p9,p0=r20,IA64_ISR_NA_BIT // is non-access bit on? tbit.nz p9,p0=r20,IA64_ISR_NA_BIT // is non-access bit on?
;; ;;
(p10) sub r19=r19,r26 (p10) sub r19=r19,r26
(p10) mov cr.itir=r25 MOV_TO_ITIR(p10, r25, r24)
cmp.ne p8,p0=r0,r23 cmp.ne p8,p0=r0,r23
(p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field (p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field
(p12) dep r17=-1,r17,4,1 // set ma=UC for region 6 addr (p12) dep r17=-1,r17,4,1 // set ma=UC for region 6 addr
...@@ -411,11 +419,11 @@ ENTRY(alt_dtlb_miss) ...@@ -411,11 +419,11 @@ ENTRY(alt_dtlb_miss)
dep r21=-1,r21,IA64_PSR_ED_BIT,1 dep r21=-1,r21,IA64_PSR_ED_BIT,1
;; ;;
or r19=r19,r17 // insert PTE control bits into r19 or r19=r19,r17 // insert PTE control bits into r19
(p6) mov cr.ipsr=r21 MOV_TO_IPSR(p6, r21, r24)
;; ;;
(p7) itc.d r19 // insert the TLB entry ITC_D(p7, r19, r18) // insert the TLB entry
mov pr=r31,-1 mov pr=r31,-1
rfi RFI
END(alt_dtlb_miss) END(alt_dtlb_miss)
.org ia64_ivt+0x1400 .org ia64_ivt+0x1400
...@@ -444,10 +452,10 @@ ENTRY(nested_dtlb_miss) ...@@ -444,10 +452,10 @@ ENTRY(nested_dtlb_miss)
* *
* Clobbered: b0, r18, r19, r21, r22, psr.dt (cleared) * Clobbered: b0, r18, r19, r21, r22, psr.dt (cleared)
*/ */
rsm psr.dt // switch to using physical data addressing RSM_PSR_DT // switch to using physical data addressing
mov r19=IA64_KR(PT_BASE) // get the page table base address mov r19=IA64_KR(PT_BASE) // get the page table base address
shl r21=r16,3 // shift bit 60 into sign bit shl r21=r16,3 // shift bit 60 into sign bit
mov r18=cr.itir MOV_FROM_ITIR(r18)
;; ;;
shr.u r17=r16,61 // get the region number into r17 shr.u r17=r16,61 // get the region number into r17
extr.u r18=r18,2,6 // get the faulting page size extr.u r18=r18,2,6 // get the faulting page size
...@@ -510,21 +518,15 @@ END(ikey_miss) ...@@ -510,21 +518,15 @@ END(ikey_miss)
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
// call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address) // call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address)
ENTRY(page_fault) ENTRY(page_fault)
ssm psr.dt SSM_PSR_DT_AND_SRLZ_I
;;
srlz.i
;; ;;
SAVE_MIN_WITH_COVER SAVE_MIN_WITH_COVER
alloc r15=ar.pfs,0,0,3,0 alloc r15=ar.pfs,0,0,3,0
mov out0=cr.ifa MOV_FROM_IFA(out0)
mov out1=cr.isr MOV_FROM_ISR(out1)
SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r14, r3)
adds r3=8,r2 // set up second base pointer adds r3=8,r2 // set up second base pointer
;; SSM_PSR_I(p15, p15, r14) // restore psr.i
ssm psr.ic | PSR_DEFAULT_BITS
;;
srlz.i // guarantee that interruption collectin is on
;;
(p15) ssm psr.i // restore psr.i
movl r14=ia64_leave_kernel movl r14=ia64_leave_kernel
;; ;;
SAVE_REST SAVE_REST
...@@ -556,10 +558,10 @@ ENTRY(dirty_bit) ...@@ -556,10 +558,10 @@ ENTRY(dirty_bit)
* page table TLB entry isn't present, we take a nested TLB miss hit where we look * page table TLB entry isn't present, we take a nested TLB miss hit where we look
* up the physical address of the L3 PTE and then continue at label 1 below. * up the physical address of the L3 PTE and then continue at label 1 below.
*/ */
mov r16=cr.ifa // get the address that caused the fault MOV_FROM_IFA(r16) // get the address that caused the fault
movl r30=1f // load continuation point in case of nested fault movl r30=1f // load continuation point in case of nested fault
;; ;;
thash r17=r16 // compute virtual address of L3 PTE THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE
mov r29=b0 // save b0 in case of nested fault mov r29=b0 // save b0 in case of nested fault
mov r31=pr // save pr mov r31=pr // save pr
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -576,7 +578,7 @@ ENTRY(dirty_bit) ...@@ -576,7 +578,7 @@ ENTRY(dirty_bit)
;; ;;
(p6) cmp.eq p6,p7=r26,r18 // Only compare if page is present (p6) cmp.eq p6,p7=r26,r18 // Only compare if page is present
;; ;;
(p6) itc.d r25 // install updated PTE ITC_D(p6, r25, r18) // install updated PTE
;; ;;
/* /*
* Tell the assemblers dependency-violation checker that the above "itc" instructions * Tell the assemblers dependency-violation checker that the above "itc" instructions
...@@ -602,7 +604,7 @@ ENTRY(dirty_bit) ...@@ -602,7 +604,7 @@ ENTRY(dirty_bit)
itc.d r18 // install updated PTE itc.d r18 // install updated PTE
#endif #endif
mov pr=r31,-1 // restore pr mov pr=r31,-1 // restore pr
rfi RFI
END(dirty_bit) END(dirty_bit)
.org ia64_ivt+0x2400 .org ia64_ivt+0x2400
...@@ -611,22 +613,22 @@ END(dirty_bit) ...@@ -611,22 +613,22 @@ END(dirty_bit)
ENTRY(iaccess_bit) ENTRY(iaccess_bit)
DBG_FAULT(9) DBG_FAULT(9)
// Like Entry 8, except for instruction access // Like Entry 8, except for instruction access
mov r16=cr.ifa // get the address that caused the fault MOV_FROM_IFA(r16) // get the address that caused the fault
movl r30=1f // load continuation point in case of nested fault movl r30=1f // load continuation point in case of nested fault
mov r31=pr // save predicates mov r31=pr // save predicates
#ifdef CONFIG_ITANIUM #ifdef CONFIG_ITANIUM
/* /*
* Erratum 10 (IFA may contain incorrect address) has "NoFix" status. * Erratum 10 (IFA may contain incorrect address) has "NoFix" status.
*/ */
mov r17=cr.ipsr MOV_FROM_IPSR(p0, r17)
;; ;;
mov r18=cr.iip MOV_FROM_IIP(r18)
tbit.z p6,p0=r17,IA64_PSR_IS_BIT // IA64 instruction set? tbit.z p6,p0=r17,IA64_PSR_IS_BIT // IA64 instruction set?
;; ;;
(p6) mov r16=r18 // if so, use cr.iip instead of cr.ifa (p6) mov r16=r18 // if so, use cr.iip instead of cr.ifa
#endif /* CONFIG_ITANIUM */ #endif /* CONFIG_ITANIUM */
;; ;;
thash r17=r16 // compute virtual address of L3 PTE THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE
mov r29=b0 // save b0 in case of nested fault) mov r29=b0 // save b0 in case of nested fault)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
mov r28=ar.ccv // save ar.ccv mov r28=ar.ccv // save ar.ccv
...@@ -642,7 +644,7 @@ ENTRY(iaccess_bit) ...@@ -642,7 +644,7 @@ ENTRY(iaccess_bit)
;; ;;
(p6) cmp.eq p6,p7=r26,r18 // Only if page present (p6) cmp.eq p6,p7=r26,r18 // Only if page present
;; ;;
(p6) itc.i r25 // install updated PTE ITC_I(p6, r25, r26) // install updated PTE
;; ;;
/* /*
* Tell the assemblers dependency-violation checker that the above "itc" instructions * Tell the assemblers dependency-violation checker that the above "itc" instructions
...@@ -668,7 +670,7 @@ ENTRY(iaccess_bit) ...@@ -668,7 +670,7 @@ ENTRY(iaccess_bit)
itc.i r18 // install updated PTE itc.i r18 // install updated PTE
#endif /* !CONFIG_SMP */ #endif /* !CONFIG_SMP */
mov pr=r31,-1 mov pr=r31,-1
rfi RFI
END(iaccess_bit) END(iaccess_bit)
.org ia64_ivt+0x2800 .org ia64_ivt+0x2800
...@@ -677,10 +679,10 @@ END(iaccess_bit) ...@@ -677,10 +679,10 @@ END(iaccess_bit)
ENTRY(daccess_bit) ENTRY(daccess_bit)
DBG_FAULT(10) DBG_FAULT(10)
// Like Entry 8, except for data access // Like Entry 8, except for data access
mov r16=cr.ifa // get the address that caused the fault MOV_FROM_IFA(r16) // get the address that caused the fault
movl r30=1f // load continuation point in case of nested fault movl r30=1f // load continuation point in case of nested fault
;; ;;
thash r17=r16 // compute virtual address of L3 PTE THASH(p0, r17, r16, r18) // compute virtual address of L3 PTE
mov r31=pr mov r31=pr
mov r29=b0 // save b0 in case of nested fault) mov r29=b0 // save b0 in case of nested fault)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -697,7 +699,7 @@ ENTRY(daccess_bit) ...@@ -697,7 +699,7 @@ ENTRY(daccess_bit)
;; ;;
(p6) cmp.eq p6,p7=r26,r18 // Only if page is present (p6) cmp.eq p6,p7=r26,r18 // Only if page is present
;; ;;
(p6) itc.d r25 // install updated PTE ITC_D(p6, r25, r26) // install updated PTE
/* /*
* Tell the assemblers dependency-violation checker that the above "itc" instructions * Tell the assemblers dependency-violation checker that the above "itc" instructions
* cannot possibly affect the following loads: * cannot possibly affect the following loads:
...@@ -721,7 +723,7 @@ ENTRY(daccess_bit) ...@@ -721,7 +723,7 @@ ENTRY(daccess_bit)
#endif #endif
mov b0=r29 // restore b0 mov b0=r29 // restore b0
mov pr=r31,-1 mov pr=r31,-1
rfi RFI
END(daccess_bit) END(daccess_bit)
.org ia64_ivt+0x2c00 .org ia64_ivt+0x2c00
...@@ -745,10 +747,10 @@ ENTRY(break_fault) ...@@ -745,10 +747,10 @@ ENTRY(break_fault)
*/ */
DBG_FAULT(11) DBG_FAULT(11)
mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc) mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc)
mov r29=cr.ipsr // M2 (12 cyc) MOV_FROM_IPSR(p0, r29) // M2 (12 cyc)
mov r31=pr // I0 (2 cyc) mov r31=pr // I0 (2 cyc)
mov r17=cr.iim // M2 (2 cyc) MOV_FROM_IIM(r17) // M2 (2 cyc)
mov.m r27=ar.rsc // M2 (12 cyc) mov.m r27=ar.rsc // M2 (12 cyc)
mov r18=__IA64_BREAK_SYSCALL // A mov r18=__IA64_BREAK_SYSCALL // A
...@@ -767,7 +769,7 @@ ENTRY(break_fault) ...@@ -767,7 +769,7 @@ ENTRY(break_fault)
nop.m 0 nop.m 0
movl r30=sys_call_table // X movl r30=sys_call_table // X
mov r28=cr.iip // M2 (2 cyc) MOV_FROM_IIP(r28) // M2 (2 cyc)
cmp.eq p0,p7=r18,r17 // I0 is this a system call? cmp.eq p0,p7=r18,r17 // I0 is this a system call?
(p7) br.cond.spnt non_syscall // B no -> (p7) br.cond.spnt non_syscall // B no ->
// //
...@@ -864,18 +866,17 @@ ENTRY(break_fault) ...@@ -864,18 +866,17 @@ ENTRY(break_fault)
#endif #endif
mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0
nop 0 nop 0
bsw.1 // B (6 cyc) regs are saved, switch to bank 1 BSW_1(r2, r14) // B (6 cyc) regs are saved, switch to bank 1
;; ;;
ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r16) // M2 now it's safe to re-enable intr.-collection
// M0 ensure interruption collection is on
movl r3=ia64_ret_from_syscall // X movl r3=ia64_ret_from_syscall // X
;; ;;
srlz.i // M0 ensure interruption collection is on
mov rp=r3 // I0 set the real return addr mov rp=r3 // I0 set the real return addr
(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT (p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT
(p15) ssm psr.i // M2 restore psr.i SSM_PSR_I(p15, p15, r16) // M2 restore psr.i
(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr) (p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr)
br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic
// NOT REACHED // NOT REACHED
...@@ -899,16 +900,15 @@ ENTRY(interrupt) ...@@ -899,16 +900,15 @@ ENTRY(interrupt)
mov r31=pr // prepare to save predicates mov r31=pr // prepare to save predicates
;; ;;
SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3 SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3
ssm psr.ic | PSR_DEFAULT_BITS SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r14)
;; // ensure everybody knows psr.ic is back on
adds r3=8,r2 // set up second base pointer for SAVE_REST adds r3=8,r2 // set up second base pointer for SAVE_REST
srlz.i // ensure everybody knows psr.ic is back on
;; ;;
SAVE_REST SAVE_REST
;; ;;
MCA_RECOVER_RANGE(interrupt) MCA_RECOVER_RANGE(interrupt)
alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
mov out0=cr.ivr // pass cr.ivr as first arg MOV_FROM_IVR(out0, r8) // pass cr.ivr as first arg
add out1=16,sp // pass pointer to pt_regs as second arg add out1=16,sp // pass pointer to pt_regs as second arg
;; ;;
srlz.d // make sure we see the effect of cr.ivr srlz.d // make sure we see the effect of cr.ivr
...@@ -978,6 +978,7 @@ END(interrupt) ...@@ -978,6 +978,7 @@ END(interrupt)
* - ar.fpsr: set to kernel settings * - ar.fpsr: set to kernel settings
* - b6: preserved (same as on entry) * - b6: preserved (same as on entry)
*/ */
#ifdef __IA64_ASM_PARAVIRTUALIZED_NATIVE
GLOBAL_ENTRY(ia64_syscall_setup) GLOBAL_ENTRY(ia64_syscall_setup)
#if PT(B6) != 0 #if PT(B6) != 0
# error This code assumes that b6 is the first field in pt_regs. # error This code assumes that b6 is the first field in pt_regs.
...@@ -1069,6 +1070,7 @@ GLOBAL_ENTRY(ia64_syscall_setup) ...@@ -1069,6 +1070,7 @@ GLOBAL_ENTRY(ia64_syscall_setup)
(p10) mov r8=-EINVAL (p10) mov r8=-EINVAL
br.ret.sptk.many b7 br.ret.sptk.many b7
END(ia64_syscall_setup) END(ia64_syscall_setup)
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
.org ia64_ivt+0x3c00 .org ia64_ivt+0x3c00
///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////
...@@ -1082,7 +1084,7 @@ END(ia64_syscall_setup) ...@@ -1082,7 +1084,7 @@ END(ia64_syscall_setup)
DBG_FAULT(16) DBG_FAULT(16)
FAULT(16) FAULT(16)
#ifdef CONFIG_VIRT_CPU_ACCOUNTING #if defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(__IA64_ASM_PARAVIRTUALIZED_NATIVE)
/* /*
* There is no particular reason for this code to be here, other than * There is no particular reason for this code to be here, other than
* that there happens to be space here that would go unused otherwise. * that there happens to be space here that would go unused otherwise.
...@@ -1092,7 +1094,7 @@ END(ia64_syscall_setup) ...@@ -1092,7 +1094,7 @@ END(ia64_syscall_setup)
* account_sys_enter is called from SAVE_MIN* macros if accounting is * account_sys_enter is called from SAVE_MIN* macros if accounting is
* enabled and if the macro is entered from user mode. * enabled and if the macro is entered from user mode.
*/ */
ENTRY(account_sys_enter) GLOBAL_ENTRY(account_sys_enter)
// mov.m r20=ar.itc is called in advance, and r13 is current // mov.m r20=ar.itc is called in advance, and r13 is current
add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13 add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13
add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13 add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13
...@@ -1134,15 +1136,13 @@ ENTRY(non_syscall) ...@@ -1134,15 +1136,13 @@ ENTRY(non_syscall)
// suitable spot... // suitable spot...
alloc r14=ar.pfs,0,0,2,0 alloc r14=ar.pfs,0,0,2,0
mov out0=cr.iim MOV_FROM_IIM(out0)
add out1=16,sp add out1=16,sp
adds r3=8,r2 // set up second base pointer for SAVE_REST adds r3=8,r2 // set up second base pointer for SAVE_REST
ssm psr.ic | PSR_DEFAULT_BITS SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r15, r24)
;; // guarantee that interruption collection is on
srlz.i // guarantee that interruption collection is on SSM_PSR_I(p15, p15, r15) // restore psr.i
;;
(p15) ssm psr.i // restore psr.i
movl r15=ia64_leave_kernel movl r15=ia64_leave_kernel
;; ;;
SAVE_REST SAVE_REST
...@@ -1168,14 +1168,12 @@ ENTRY(dispatch_unaligned_handler) ...@@ -1168,14 +1168,12 @@ ENTRY(dispatch_unaligned_handler)
SAVE_MIN_WITH_COVER SAVE_MIN_WITH_COVER
;; ;;
alloc r14=ar.pfs,0,0,2,0 // now it's safe (must be first in insn group!) alloc r14=ar.pfs,0,0,2,0 // now it's safe (must be first in insn group!)
mov out0=cr.ifa MOV_FROM_IFA(out0)
adds out1=16,sp adds out1=16,sp
ssm psr.ic | PSR_DEFAULT_BITS SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24)
;; // guarantee that interruption collection is on
srlz.i // guarantee that interruption collection is on SSM_PSR_I(p15, p15, r3) // restore psr.i
;;
(p15) ssm psr.i // restore psr.i
adds r3=8,r2 // set up second base pointer adds r3=8,r2 // set up second base pointer
;; ;;
SAVE_REST SAVE_REST
...@@ -1207,17 +1205,16 @@ ENTRY(dispatch_to_fault_handler) ...@@ -1207,17 +1205,16 @@ ENTRY(dispatch_to_fault_handler)
*/ */
SAVE_MIN_WITH_COVER_R19 SAVE_MIN_WITH_COVER_R19
alloc r14=ar.pfs,0,0,5,0 alloc r14=ar.pfs,0,0,5,0
mov out0=r15 MOV_FROM_ISR(out1)
mov out1=cr.isr MOV_FROM_IFA(out2)
mov out2=cr.ifa MOV_FROM_IIM(out3)
mov out3=cr.iim MOV_FROM_ITIR(out4)
mov out4=cr.itir
;; ;;
ssm psr.ic | PSR_DEFAULT_BITS SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, out0)
;; // guarantee that interruption collection is on
srlz.i // guarantee that interruption collection is on mov out0=r15
;; ;;
(p15) ssm psr.i // restore psr.i SSM_PSR_I(p15, p15, r3) // restore psr.i
adds r3=8,r2 // set up second base pointer for SAVE_REST adds r3=8,r2 // set up second base pointer for SAVE_REST
;; ;;
SAVE_REST SAVE_REST
...@@ -1236,8 +1233,8 @@ END(dispatch_to_fault_handler) ...@@ -1236,8 +1233,8 @@ END(dispatch_to_fault_handler)
// 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49) // 0x5000 Entry 20 (size 16 bundles) Page Not Present (10,22,49)
ENTRY(page_not_present) ENTRY(page_not_present)
DBG_FAULT(20) DBG_FAULT(20)
mov r16=cr.ifa MOV_FROM_IFA(r16)
rsm psr.dt RSM_PSR_DT
/* /*
* The Linux page fault handler doesn't expect non-present pages to be in * The Linux page fault handler doesn't expect non-present pages to be in
* the TLB. Flush the existing entry now, so we meet that expectation. * the TLB. Flush the existing entry now, so we meet that expectation.
...@@ -1256,8 +1253,8 @@ END(page_not_present) ...@@ -1256,8 +1253,8 @@ END(page_not_present)
// 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52) // 0x5100 Entry 21 (size 16 bundles) Key Permission (13,25,52)
ENTRY(key_permission) ENTRY(key_permission)
DBG_FAULT(21) DBG_FAULT(21)
mov r16=cr.ifa MOV_FROM_IFA(r16)
rsm psr.dt RSM_PSR_DT
mov r31=pr mov r31=pr
;; ;;
srlz.d srlz.d
...@@ -1269,8 +1266,8 @@ END(key_permission) ...@@ -1269,8 +1266,8 @@ END(key_permission)
// 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26) // 0x5200 Entry 22 (size 16 bundles) Instruction Access Rights (26)
ENTRY(iaccess_rights) ENTRY(iaccess_rights)
DBG_FAULT(22) DBG_FAULT(22)
mov r16=cr.ifa MOV_FROM_IFA(r16)
rsm psr.dt RSM_PSR_DT
mov r31=pr mov r31=pr
;; ;;
srlz.d srlz.d
...@@ -1282,8 +1279,8 @@ END(iaccess_rights) ...@@ -1282,8 +1279,8 @@ END(iaccess_rights)
// 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53) // 0x5300 Entry 23 (size 16 bundles) Data Access Rights (14,53)
ENTRY(daccess_rights) ENTRY(daccess_rights)
DBG_FAULT(23) DBG_FAULT(23)
mov r16=cr.ifa MOV_FROM_IFA(r16)
rsm psr.dt RSM_PSR_DT
mov r31=pr mov r31=pr
;; ;;
srlz.d srlz.d
...@@ -1295,7 +1292,7 @@ END(daccess_rights) ...@@ -1295,7 +1292,7 @@ END(daccess_rights)
// 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39) // 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
ENTRY(general_exception) ENTRY(general_exception)
DBG_FAULT(24) DBG_FAULT(24)
mov r16=cr.isr MOV_FROM_ISR(r16)
mov r31=pr mov r31=pr
;; ;;
cmp4.eq p6,p0=0,r16 cmp4.eq p6,p0=0,r16
...@@ -1324,8 +1321,8 @@ END(disabled_fp_reg) ...@@ -1324,8 +1321,8 @@ END(disabled_fp_reg)
ENTRY(nat_consumption) ENTRY(nat_consumption)
DBG_FAULT(26) DBG_FAULT(26)
mov r16=cr.ipsr MOV_FROM_IPSR(p0, r16)
mov r17=cr.isr MOV_FROM_ISR(r17)
mov r31=pr // save PR mov r31=pr // save PR
;; ;;
and r18=0xf,r17 // r18 = cr.ipsr.code{3:0} and r18=0xf,r17 // r18 = cr.ipsr.code{3:0}
...@@ -1335,10 +1332,10 @@ ENTRY(nat_consumption) ...@@ -1335,10 +1332,10 @@ ENTRY(nat_consumption)
dep r16=-1,r16,IA64_PSR_ED_BIT,1 dep r16=-1,r16,IA64_PSR_ED_BIT,1
(p6) br.cond.spnt 1f // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH) (p6) br.cond.spnt 1f // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH)
;; ;;
mov cr.ipsr=r16 // set cr.ipsr.na MOV_TO_IPSR(p0, r16, r18)
mov pr=r31,-1 mov pr=r31,-1
;; ;;
rfi RFI
1: mov pr=r31,-1 1: mov pr=r31,-1
;; ;;
...@@ -1360,26 +1357,26 @@ ENTRY(speculation_vector) ...@@ -1360,26 +1357,26 @@ ENTRY(speculation_vector)
* *
* cr.imm contains zero_ext(imm21) * cr.imm contains zero_ext(imm21)
*/ */
mov r18=cr.iim MOV_FROM_IIM(r18)
;; ;;
mov r17=cr.iip MOV_FROM_IIP(r17)
shl r18=r18,43 // put sign bit in position (43=64-21) shl r18=r18,43 // put sign bit in position (43=64-21)
;; ;;
mov r16=cr.ipsr MOV_FROM_IPSR(p0, r16)
shr r18=r18,39 // sign extend (39=43-4) shr r18=r18,39 // sign extend (39=43-4)
;; ;;
add r17=r17,r18 // now add the offset add r17=r17,r18 // now add the offset
;; ;;
mov cr.iip=r17 MOV_FROM_IIP(r17)
dep r16=0,r16,41,2 // clear EI dep r16=0,r16,41,2 // clear EI
;; ;;
mov cr.ipsr=r16 MOV_FROM_IPSR(p0, r16)
;; ;;
rfi // and go back RFI
END(speculation_vector) END(speculation_vector)
.org ia64_ivt+0x5800 .org ia64_ivt+0x5800
...@@ -1517,11 +1514,11 @@ ENTRY(ia32_intercept) ...@@ -1517,11 +1514,11 @@ ENTRY(ia32_intercept)
DBG_FAULT(46) DBG_FAULT(46)
#ifdef CONFIG_IA32_SUPPORT #ifdef CONFIG_IA32_SUPPORT
mov r31=pr mov r31=pr
mov r16=cr.isr MOV_FROM_ISR(r16)
;; ;;
extr.u r17=r16,16,8 // get ISR.code extr.u r17=r16,16,8 // get ISR.code
mov r18=ar.eflag mov r18=ar.eflag
mov r19=cr.iim // old eflag value MOV_FROM_IIM(r19) // old eflag value
;; ;;
cmp.ne p6,p0=2,r17 cmp.ne p6,p0=2,r17
(p6) br.cond.spnt 1f // not a system flag fault (p6) br.cond.spnt 1f // not a system flag fault
...@@ -1533,7 +1530,7 @@ ENTRY(ia32_intercept) ...@@ -1533,7 +1530,7 @@ ENTRY(ia32_intercept)
(p6) br.cond.spnt 1f // eflags.ac bit didn't change (p6) br.cond.spnt 1f // eflags.ac bit didn't change
;; ;;
mov pr=r31,-1 // restore predicate registers mov pr=r31,-1 // restore predicate registers
rfi RFI
1: 1:
#endif // CONFIG_IA32_SUPPORT #endif // CONFIG_IA32_SUPPORT
...@@ -1686,11 +1683,10 @@ ENTRY(dispatch_illegal_op_fault) ...@@ -1686,11 +1683,10 @@ ENTRY(dispatch_illegal_op_fault)
.prologue .prologue
.body .body
SAVE_MIN_WITH_COVER SAVE_MIN_WITH_COVER
ssm psr.ic | PSR_DEFAULT_BITS SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24)
// guarantee that interruption collection is on
;; ;;
srlz.i // guarantee that interruption collection is on SSM_PSR_I(p15, p15, r3) // restore psr.i
;;
(p15) ssm psr.i // restore psr.i
adds r3=8,r2 // set up second base pointer for SAVE_REST adds r3=8,r2 // set up second base pointer for SAVE_REST
;; ;;
alloc r14=ar.pfs,0,0,1,0 // must be first in insn group alloc r14=ar.pfs,0,0,1,0 // must be first in insn group
...@@ -1729,12 +1725,11 @@ END(dispatch_illegal_op_fault) ...@@ -1729,12 +1725,11 @@ END(dispatch_illegal_op_fault)
ENTRY(dispatch_to_ia32_handler) ENTRY(dispatch_to_ia32_handler)
SAVE_MIN SAVE_MIN
;; ;;
mov r14=cr.isr MOV_FROM_ISR(r14)
ssm psr.ic | PSR_DEFAULT_BITS SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(r3, r24)
;; // guarantee that interruption collection is on
srlz.i // guarantee that interruption collection is on
;; ;;
(p15) ssm psr.i SSM_PSR_I(p15, p15, r3)
adds r3=8,r2 // Base pointer for SAVE_REST adds r3=8,r2 // Base pointer for SAVE_REST
;; ;;
SAVE_REST SAVE_REST
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment