# HG changeset patch
# User djm@xxxxxxxxxxxxxxx
# Node ID 4e4f1db8ea94e57bbf0f318153b44942ace8a1f5
# Parent b7276814008c9c924fceecf6fd9f67ccddaadcb2
More updating to linux 2.6.13 sources
diff -r b7276814008c -r 4e4f1db8ea94 xen/arch/ia64/Makefile
--- a/xen/arch/ia64/Makefile Wed Aug 31 20:32:27 2005
+++ b/xen/arch/ia64/Makefile Wed Aug 31 22:55:04 2005
@@ -23,7 +23,8 @@
ifeq ($(CONFIG_VTI),y)
OBJS += vmx_virt.o vmx_vcpu.o vmx_process.o vmx_vsa.o vmx_ivt.o\
vmx_phy_mode.o vmx_utility.o vmx_interrupt.o vmx_entry.o vmmu.o \
- vtlb.o mmio.o vlsapic.o vmx_hypercall.o mm.o vmx_support.o pal_emul.o
+ vtlb.o mmio.o vlsapic.o vmx_hypercall.o mm.o vmx_support.o \
+ pal_emul.o vmx_irq_ia64.o
endif
# files from xen/arch/ia64/linux/lib (linux/arch/ia64/lib)
diff -r b7276814008c -r 4e4f1db8ea94 xen/arch/ia64/linux-xen/efi.c
--- a/xen/arch/ia64/linux-xen/efi.c Wed Aug 31 20:32:27 2005
+++ b/xen/arch/ia64/linux-xen/efi.c Wed Aug 31 22:55:04 2005
@@ -418,6 +418,38 @@
(*callback)(start, end, arg);
}
}
+
+/*
+ * Walk the EFI memory map to pull out leftover pages in the lower
+ * memory regions which do not end up in the regular memory map and
+ * stick them into the uncached allocator
+ *
+ * The regular walk function is significantly more complex than the
+ * uncached walk which means it really doesn't make sense to try and
+ * marge the two.
+ */
+void __init
+efi_memmap_walk_uc (efi_freemem_callback_t callback)
+{
+ void *efi_map_start, *efi_map_end, *p;
+ efi_memory_desc_t *md;
+ u64 efi_desc_size, start, end;
+
+ efi_map_start = __va(ia64_boot_param->efi_memmap);
+ efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
+ efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+ for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+ md = p;
+ if (md->attribute == EFI_MEMORY_UC) {
+ start = PAGE_ALIGN(md->phys_addr);
+ end = PAGE_ALIGN((md->phys_addr+(md->num_pages <<
EFI_PAGE_SHIFT)) & PAGE_MASK);
+ if ((*callback)(start, end, NULL) < 0)
+ return;
+ }
+ }
+}
+
/*
* Look for the PAL_CODE region reported by EFI and maps it using an
diff -r b7276814008c -r 4e4f1db8ea94 xen/arch/ia64/linux-xen/entry.S
--- a/xen/arch/ia64/linux-xen/entry.S Wed Aug 31 20:32:27 2005
+++ b/xen/arch/ia64/linux-xen/entry.S Wed Aug 31 22:55:04 2005
@@ -175,7 +175,7 @@
mov rp=loc0
br.ret.sptk.many rp
END(sys_clone)
-#endif /* !XEN */
+#endif
/*
* prev_task <- ia64_switch_to(struct task_struct *next)
@@ -191,12 +191,14 @@
adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13
movl r25=init_task
+#ifdef XEN
movl r27=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_STACK_OFFSET;;
ld8 r27=[r27]
adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0
-#ifdef XEN
dep r20=0,in0,60,4 // physical address of "next"
#else
+ mov r27=IA64_KR(CURRENT_STACK)
+ adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0
dep r20=0,in0,61,3 // physical address of "next"
#endif
;;
@@ -215,8 +217,12 @@
;;
(p6) srlz.d
ld8 sp=[r21] // load kernel stack pointer of new task
+#ifdef XEN
movl r8=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
st8 [r8]=in0
+#else
+ mov IA64_KR(CURRENT)=in0 // update "current" application register
+#endif
mov r8=r13 // return pointer to previously running
task
mov r13=in0 // set "current" pointer
;;
@@ -250,8 +256,14 @@
mov cr.ifa=in0 // VA of next task...
;;
mov r25=IA64_TR_CURRENT_STACK
+#ifdef XEN
movl r8=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_STACK_OFFSET;;
st8 [r8]=r26
+
+#else
+ mov IA64_KR(CURRENT_STACK)=r26 // remember last page we mapped...
+#endif
+ ;;
itr.d dtr[r25]=r23 // wire in new mapping...
br.cond.sptk .done
END(ia64_switch_to)
@@ -494,18 +506,6 @@
END(load_switch_stack)
#ifndef XEN
-GLOBAL_ENTRY(__ia64_syscall)
- .regstk 6,0,0,0
- mov r15=in5 // put syscall number in place
- break __BREAK_SYSCALL
- movl r2=errno
- cmp.eq p6,p7=-1,r10
- ;;
-(p6) st4 [r2]=r8
-(p6) mov r8=-1
- br.ret.sptk.many rp
-END(__ia64_syscall)
-
GLOBAL_ENTRY(execve)
mov r15=__NR_execve // put syscall number in place
break __BREAK_SYSCALL
@@ -672,7 +672,7 @@
* r8-r11: restored (syscall return value(s))
* r12: restored (user-level stack pointer)
* r13: restored (user-level thread pointer)
- * r14: cleared
+ * r14: set to __kernel_syscall_via_epc
* r15: restored (syscall #)
* r16-r17: cleared
* r18: user-level b6
@@ -693,7 +693,7 @@
* pr: restored (user-level pr)
* b0: restored (user-level rp)
* b6: restored
- * b7: cleared
+ * b7: set to __kernel_syscall_via_epc
* ar.unat: restored (user-level ar.unat)
* ar.pfs: restored (user-level ar.pfs)
* ar.rsc: restored (user-level ar.rsc)
@@ -743,15 +743,15 @@
(p6) ld4 r31=[r18] // load
current_thread_info()->flags
#endif
ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for
"loadrs"
- mov b7=r0 // clear b7
- ;;
- ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be
garbage)
+ nop.i 0
+ ;;
+ mov r16=ar.bsp // M2 get existing backing
store pointer
ld8 r18=[r2],PT(R9)-PT(B6) // load b6
#ifndef XEN
(p6) and r15=TIF_WORK_MASK,r31 // any work other than
TIF_SYSCALL_TRACE?
#endif
;;
- mov r16=ar.bsp // M2 get existing backing
store pointer
+ ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be
garbage)
#ifndef XEN
(p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending?
(p6) br.cond.spnt .work_pending_syscall
@@ -760,63 +760,74 @@
// start restoring the state saved on the kernel stack (struct pt_regs):
ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
ld8 r11=[r3],PT(CR_IIP)-PT(R11)
- mov f6=f0 // clear f6
+(pNonSys) break 0 // bug check: we shouldn't be here if
pNonSys is TRUE!
;;
invala // M0|1 invalidate ALAT
- rsm psr.i | psr.ic // M2 initiate turning off of interrupt and
interruption collection
- mov f9=f0 // clear f9
-
- ld8 r29=[r2],16 // load cr.ipsr
- ld8 r28=[r3],16 // load cr.iip
- mov f8=f0 // clear f8
+ rsm psr.i | psr.ic // M2 turn off interrupts and interruption
collection
+ cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should
restore cr.ifs
+
+ ld8 r29=[r2],16 // M0|1 load cr.ipsr
+ ld8 r28=[r3],16 // M0|1 load cr.iip
+ mov r22=r0 // A clear r22
;;
ld8 r30=[r2],16 // M0|1 load cr.ifs
- mov.m ar.ssd=r0 // M2 clear ar.ssd
- cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore
cr.ifs
- ;;
ld8 r25=[r3],16 // M0|1 load ar.unat
- mov.m ar.csd=r0 // M2 clear ar.csd
- mov r22=r0 // clear r22
+(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
;;
ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs
-(pKStk) mov r22=psr // M2 read PSR now that interrupts are
disabled
- mov f10=f0 // clear f10
- ;;
- ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0
- ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc
- mov f11=f0 // clear f11
- ;;
- ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // load ar.rnat (may be garbage)
- ld8 r31=[r3],PT(R1)-PT(PR) // load predicates
-(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
- ;;
- ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr
- ld8.fill r1=[r3],16 // load r1
-(pUStk) mov r17=1
- ;;
- srlz.d // M0 ensure interruption collection is off
- ld8.fill r13=[r3],16
- mov f7=f0 // clear f7
- ;;
- ld8.fill r12=[r2] // restore r12 (sp)
- ld8.fill r15=[r3] // restore r15
+(pKStk) mov r22=psr // M2 read PSR now that
interrupts are disabled
+ nop 0
+ ;;
+ ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
+ ld8 r27=[r3],PT(PR)-PT(AR_RSC) // M0|1 load ar.rsc
+ mov f6=f0 // F clear f6
+ ;;
+ ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // M0|1 load ar.rnat (may be
garbage)
+ ld8 r31=[r3],PT(R1)-PT(PR) // M0|1 load predicates
+ mov f7=f0 // F clear f7
+ ;;
+ ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // M0|1 load ar.fpsr
+ ld8.fill r1=[r3],16 // M0|1 load r1
+(pUStk) mov r17=1 // A
+ ;;
+(pUStk) st1 [r14]=r17 // M2|3
+ ld8.fill r13=[r3],16 // M0|1
+ mov f8=f0 // F clear f8
+ ;;
+ ld8.fill r12=[r2] // M0|1 restore r12 (sp)
+ ld8.fill r15=[r3] // M0|1 restore r15
+ mov b6=r18 // I0 restore b6
+
#ifdef XEN
- movl r3=THIS_CPU(ia64_phys_stacked_size_p8)
+ movl r17=THIS_CPU(ia64_phys_stacked_size_p8) // A
#else
- addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0
-#endif
- ;;
-(pUStk) ld4 r3=[r3] // r3 = cpu_data->phys_stacked_size_p8
-(pUStk) st1 [r14]=r17
- mov b6=r18 // I0 restore b6
- ;;
- mov r14=r0 // clear r14
- shr.u r18=r19,16 // I0|1 get byte size of existing "dirty"
partition
-(pKStk) br.cond.dpnt.many skip_rbs_switch
-
- mov.m ar.ccv=r0 // clear ar.ccv
-(pNonSys) br.cond.dpnt.many dont_preserve_current_frame
- br.cond.sptk.many rbs_switch
+ addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A
+#endif
+ mov f9=f0 // F clear f9
+(pKStk) br.cond.dpnt.many skip_rbs_switch // B
+
+ srlz.d // M0 ensure interruption collection
is off (for cover)
+ shr.u r18=r19,16 // I0|1 get byte size of existing
"dirty" partition
+ cover // B add current frame into dirty
partition & set cr.ifs
+ ;;
+(pUStk) ld4 r17=[r17] // M0|1 r17 =
cpu_data->phys_stacked_size_p8
+ mov r19=ar.bsp // M2 get new backing store pointer
+ mov f10=f0 // F clear f10
+
+ nop.m 0
+#ifdef XEN
+ mov r14=r0
+#else
+ movl r14=__kernel_syscall_via_epc // X
+#endif
+ ;;
+ mov.m ar.csd=r0 // M2 clear ar.csd
+ mov.m ar.ccv=r0 // M2 clear ar.ccv
+ mov b7=r14 // I0 clear b7 (hint with
__kernel_syscall_via_epc)
+
+ mov.m ar.ssd=r0 // M2 clear ar.ssd
+ mov f11=f0 // F clear f11
+ br.cond.sptk.many rbs_switch // B
END(ia64_leave_syscall)
#ifdef CONFIG_IA32_SUPPORT
@@ -829,7 +840,7 @@
st8.spill [r2]=r8 // store return value in slot for r8 and set
unat bit
.mem.offset 8,0
st8.spill [r3]=r0 // clear error indication in slot for r10 and
set unat bit
-END(ia64_ret_from_ia32_execve_syscall)
+END(ia64_ret_from_ia32_execve)
// fall through
#endif /* CONFIG_IA32_SUPPORT */
GLOBAL_ENTRY(ia64_leave_kernel)
@@ -884,11 +895,15 @@
ld8 r28=[r2],8 // load b6
adds r29=PT(R24)+16,r12
+#ifdef XEN
ld8.fill r16=[r3]
+ adds r3=PT(AR_CSD)-PT(R16),r3
+#else
+ ld8.fill r16=[r3],PT(AR_CSD)-PT(R16)
+#endif
adds r30=PT(AR_CCV)+16,r12
(p6) and r19=TIF_WORK_MASK,r31 // any work other than
TIF_SYSCALL_TRACE?
;;
- adds r3=PT(AR_CSD)-PT(R16),r3
ld8.fill r24=[r29]
ld8 r15=[r30] // load ar.ccv
(p6) cmp4.ne.unc p6,p0=r19, r0 // any special work pending?
@@ -944,14 +959,18 @@
ldf.fill f7=[r2],PT(F11)-PT(F7)
ldf.fill f8=[r3],32
;;
- srlz.i // ensure interruption collection is off
+ srlz.d // ensure that inter. collection is off (VHPT is don't care,
since text is pinned)
mov ar.ccv=r15
;;
ldf.fill f11=[r2]
bsw.0 // switch back to bank 0 (no stop bit required
beforehand...)
;;
+#ifdef XEN
(pUStk) movl r18=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
(pUStk) ld8 r18=[r18]
+#else
+(pUStk) mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency)
+#endif
adds r16=PT(CR_IPSR)+16,r12
adds r17=PT(CR_IIP)+16,r12
@@ -1009,11 +1028,10 @@
* NOTE: alloc, loadrs, and cover can't be predicated.
*/
(pNonSys) br.cond.dpnt dont_preserve_current_frame
-
+ cover // add current frame into dirty
partition and set cr.ifs
+ ;;
+ mov r19=ar.bsp // get new backing store pointer
rbs_switch:
- cover // add current frame into dirty
partition and set cr.ifs
- ;;
- mov r19=ar.bsp // get new backing store pointer
sub r16=r16,r18 // krbs = old bsp - size of dirty
partition
cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs
;;
@@ -1088,14 +1106,14 @@
mov loc5=0
mov loc6=0
mov loc7=0
-(pRecurse) br.call.sptk.few b0=rse_clear_invalid
+(pRecurse) br.call.dptk.few b0=rse_clear_invalid
;;
mov loc8=0
mov loc9=0
cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to
do a br.ret
mov loc10=0
mov loc11=0
-(pReturn) br.ret.sptk.many b0
+(pReturn) br.ret.dptk.many b0
#endif /* !CONFIG_ITANIUM */
# undef pRecurse
# undef pReturn
@@ -1249,7 +1267,7 @@
;;
(pNonSys) mov out2=0 // out2==0 => not a syscall
.fframe 16
- .spillpsp ar.unat, 16 // (note that offset is
relative to psp+0x10!)
+ .spillsp ar.unat, 16
st8 [sp]=r9,-16 // allocate space for ar.unat
and save it
st8 [out1]=loc1,-8 // save ar.pfs, out1=&sigscratch
.body
@@ -1275,7 +1293,7 @@
adds out2=8,sp // out2=&sigscratch->ar_pfs
;;
.fframe 16
- .spillpsp ar.unat, 16 // (note that offset is
relative to psp+0x10!)
+ .spillsp ar.unat, 16
st8 [sp]=r9,-16 // allocate space for ar.unat
and save it
st8 [out2]=loc1,-8 // save ar.pfs, out2=&sigscratch
.body
@@ -1322,7 +1340,7 @@
stf.spill [r17]=f11
adds out0=16,sp // out0 = &sigscratch
br.call.sptk.many rp=ia64_rt_sigreturn
-.ret19: .restore sp 0
+.ret19: .restore sp,0
adds sp=16,sp
;;
ld8 r9=[sp] // load new ar.unat
@@ -1486,7 +1504,7 @@
data8 sys_msgrcv
data8 sys_msgctl
data8 sys_shmget
- data8 ia64_shmat
+ data8 sys_shmat
data8 sys_shmdt // 1115
data8 sys_shmctl
data8 sys_syslog
@@ -1646,12 +1664,12 @@
data8 sys_add_key
data8 sys_request_key
data8 sys_keyctl
+ data8 sys_ioprio_set
+ data8 sys_ioprio_get // 1275
data8 sys_ni_syscall
- data8 sys_ni_syscall // 1275
- data8 sys_ni_syscall
- data8 sys_ni_syscall
- data8 sys_ni_syscall
- data8 sys_ni_syscall
+ data8 sys_inotify_init
+ data8 sys_inotify_add_watch
+ data8 sys_inotify_rm_watch
.org sys_call_table + 8*NR_syscalls // guard against failures to
increase NR_syscalls
#endif
diff -r b7276814008c -r 4e4f1db8ea94 xen/arch/ia64/linux-xen/entry.h
--- a/xen/arch/ia64/linux-xen/entry.h Wed Aug 31 20:32:27 2005
+++ b/xen/arch/ia64/linux-xen/entry.h Wed Aug 31 22:55:04 2005
@@ -7,12 +7,6 @@
#define PRED_LEAVE_SYSCALL 1 /* TRUE iff leave from syscall */
#define PRED_KERNEL_STACK 2 /* returning to kernel-stacks? */
#define PRED_USER_STACK 3 /* returning to user-stacks? */
-#ifdef CONFIG_VTI
-#define PRED_EMUL 2 /* Need to save r4-r7 for inst emulation */
-#define PRED_NON_EMUL 3 /* No need to save r4-r7 for normal path */
-#define PRED_BN0 6 /* Guest is in bank 0 */
-#define PRED_BN1 7 /* Guest is in bank 1 */
-#endif // CONFIG_VTI
#define PRED_SYSCALL 4 /* inside a system call? */
#define PRED_NON_SYSCALL 5 /* complement of PRED_SYSCALL */
@@ -23,21 +17,26 @@
# define pLvSys PASTE(p,PRED_LEAVE_SYSCALL)
# define pKStk PASTE(p,PRED_KERNEL_STACK)
# define pUStk PASTE(p,PRED_USER_STACK)
-#ifdef CONFIG_VTI
-# define pEml PASTE(p,PRED_EMUL)
-# define pNonEml PASTE(p,PRED_NON_EMUL)
-# define pBN0 PASTE(p,PRED_BN0)
-# define pBN1 PASTE(p,PRED_BN1)
-#endif // CONFIG_VTI
# define pSys PASTE(p,PRED_SYSCALL)
# define pNonSys PASTE(p,PRED_NON_SYSCALL)
#endif
#define PT(f) (IA64_PT_REGS_##f##_OFFSET)
#define SW(f) (IA64_SWITCH_STACK_##f##_OFFSET)
+
+#ifdef XEN
#ifdef CONFIG_VTI
+#define PRED_EMUL 2 /* Need to save r4-r7 for inst emulation */
+#define PRED_NON_EMUL 3 /* No need to save r4-r7 for normal path */
+#define PRED_BN0 6 /* Guest is in bank 0 */
+#define PRED_BN1 7 /* Guest is in bank 1 */
+# define pEml PASTE(p,PRED_EMUL)
+# define pNonEml PASTE(p,PRED_NON_EMUL)
+# define pBN0 PASTE(p,PRED_BN0)
+# define pBN1 PASTE(p,PRED_BN1)
#define VPD(f) (VPD_##f##_START_OFFSET)
#endif // CONFIG_VTI
+#endif
#define PT_REGS_SAVES(off) \
.unwabi 3, 'i'; \
@@ -75,7 +74,7 @@
.spillsp @priunat,SW(AR_UNAT)+16+(off);
\
.spillsp ar.rnat,SW(AR_RNAT)+16+(off);
\
.spillsp ar.bspstore,SW(AR_BSPSTORE)+16+(off);
\
- .spillsp pr,SW(PR)+16+(off))
+ .spillsp pr,SW(PR)+16+(off)
#define DO_SAVE_SWITCH_STACK \
movl r28=1f; \
diff -r b7276814008c -r 4e4f1db8ea94 xen/arch/ia64/linux-xen/head.S
--- a/xen/arch/ia64/linux-xen/head.S Wed Aug 31 20:32:27 2005
+++ b/xen/arch/ia64/linux-xen/head.S Wed Aug 31 22:55:04 2005
@@ -15,6 +15,8 @@
* Copyright (C) 1999 Don Dugger <Don.Dugger@xxxxxxxxx>
* Copyright (C) 2002 Fenghua Yu <fenghua.yu@xxxxxxxxx>
* -Optimize __ia64_save_fpu() and __ia64_load_fpu() for Itanium 2.
+ * Copyright (C) 2004 Ashok Raj <ashok.raj@xxxxxxxxx>
+ * Support for CPU Hotplug
*/
#include <linux/config.h>
@@ -29,6 +31,146 @@
#include <asm/processor.h>
#include <asm/ptrace.h>
#include <asm/system.h>
+#include <asm/mca_asm.h>
+
+#ifdef CONFIG_HOTPLUG_CPU
+#define SAL_PSR_BITS_TO_SET \
+ (IA64_PSR_AC | IA64_PSR_BN | IA64_PSR_MFH | IA64_PSR_MFL)
+
+#define SAVE_FROM_REG(src, ptr, dest) \
+ mov dest=src;; \
+ st8 [ptr]=dest,0x08
+
+#define RESTORE_REG(reg, ptr, _tmp) \
+ ld8 _tmp=[ptr],0x08;; \
+ mov reg=_tmp
+
+#define SAVE_BREAK_REGS(ptr, _idx, _breg, _dest)\
+ mov ar.lc=IA64_NUM_DBG_REGS-1;; \
+ mov _idx=0;;
\
+1:
\
+ SAVE_FROM_REG(_breg[_idx], ptr, _dest);; \
+ add _idx=1,_idx;;
\
+ br.cloop.sptk.many 1b
+
+#define RESTORE_BREAK_REGS(ptr, _idx, _breg, _tmp, _lbl)\
+ mov ar.lc=IA64_NUM_DBG_REGS-1;; \
+ mov _idx=0;; \
+_lbl: RESTORE_REG(_breg[_idx], ptr, _tmp);; \
+ add _idx=1, _idx;; \
+ br.cloop.sptk.many _lbl
+
+#define SAVE_ONE_RR(num, _reg, _tmp) \
+ movl _tmp=(num<<61);; \
+ mov _reg=rr[_tmp]
+
+#define SAVE_REGION_REGS(_tmp, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) \
+ SAVE_ONE_RR(0,_r0, _tmp);; \
+ SAVE_ONE_RR(1,_r1, _tmp);; \
+ SAVE_ONE_RR(2,_r2, _tmp);; \
+ SAVE_ONE_RR(3,_r3, _tmp);; \
+ SAVE_ONE_RR(4,_r4, _tmp);; \
+ SAVE_ONE_RR(5,_r5, _tmp);; \
+ SAVE_ONE_RR(6,_r6, _tmp);; \
+ SAVE_ONE_RR(7,_r7, _tmp);;
+
+#define STORE_REGION_REGS(ptr, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) \
+ st8 [ptr]=_r0, 8;; \
+ st8 [ptr]=_r1, 8;; \
+ st8 [ptr]=_r2, 8;; \
+ st8 [ptr]=_r3, 8;; \
+ st8 [ptr]=_r4, 8;; \
+ st8 [ptr]=_r5, 8;; \
+ st8 [ptr]=_r6, 8;; \
+ st8 [ptr]=_r7, 8;;
+
+#define RESTORE_REGION_REGS(ptr, _idx1, _idx2, _tmp) \
+ mov ar.lc=0x08-1;;
\
+ movl _idx1=0x00;; \
+RestRR:
\
+ dep.z _idx2=_idx1,61,3;; \
+ ld8 _tmp=[ptr],8;;
\
+ mov rr[_idx2]=_tmp;;
\
+ srlz.d;;
\
+ add _idx1=1,_idx1;;
\
+ br.cloop.sptk.few RestRR
+
+#define SET_AREA_FOR_BOOTING_CPU(reg1, reg2) \
+ movl reg1=sal_state_for_booting_cpu;; \
+ ld8 reg2=[reg1];;
+
+/*
+ * Adjust region registers saved before starting to save
+ * break regs and rest of the states that need to be preserved.
+ */
+#define SAL_TO_OS_BOOT_HANDOFF_STATE_SAVE(_reg1,_reg2,_pred) \
+ SAVE_FROM_REG(b0,_reg1,_reg2);;
\
+ SAVE_FROM_REG(b1,_reg1,_reg2);;
\
+ SAVE_FROM_REG(b2,_reg1,_reg2);;
\
+ SAVE_FROM_REG(b3,_reg1,_reg2);;
\
+ SAVE_FROM_REG(b4,_reg1,_reg2);;
\
+ SAVE_FROM_REG(b5,_reg1,_reg2);;
\
+ st8 [_reg1]=r1,0x08;;
\
+ st8 [_reg1]=r12,0x08;;
\
+ st8 [_reg1]=r13,0x08;;
\
+ SAVE_FROM_REG(ar.fpsr,_reg1,_reg2);; \
+ SAVE_FROM_REG(ar.pfs,_reg1,_reg2);;
\
+ SAVE_FROM_REG(ar.rnat,_reg1,_reg2);; \
+ SAVE_FROM_REG(ar.unat,_reg1,_reg2);; \
+ SAVE_FROM_REG(ar.bspstore,_reg1,_reg2);; \
+ SAVE_FROM_REG(cr.dcr,_reg1,_reg2);;
\
+ SAVE_FROM_REG(cr.iva,_reg1,_reg2);;
\
+ SAVE_FROM_REG(cr.pta,_reg1,_reg2);;
\
+ SAVE_FROM_REG(cr.itv,_reg1,_reg2);;
\
+ SAVE_FROM_REG(cr.pmv,_reg1,_reg2);;
\
+ SAVE_FROM_REG(cr.cmcv,_reg1,_reg2);; \
+ SAVE_FROM_REG(cr.lrr0,_reg1,_reg2);; \
+ SAVE_FROM_REG(cr.lrr1,_reg1,_reg2);; \
+ st8 [_reg1]=r4,0x08;;
\
+ st8 [_reg1]=r5,0x08;;
\
+ st8 [_reg1]=r6,0x08;;
\
+ st8 [_reg1]=r7,0x08;;
\
+ st8 [_reg1]=_pred,0x08;;
\
+ SAVE_FROM_REG(ar.lc, _reg1, _reg2);; \
+ stf.spill.nta [_reg1]=f2,16;;
\
+ stf.spill.nta [_reg1]=f3,16;;
\
+ stf.spill.nta [_reg1]=f4,16;;
\
+ stf.spill.nta [_reg1]=f5,16;;
\
+ stf.spill.nta [_reg1]=f16,16;;
\
+ stf.spill.nta [_reg1]=f17,16;;
\
+ stf.spill.nta [_reg1]=f18,16;;
\
+ stf.spill.nta [_reg1]=f19,16;;
\
+ stf.spill.nta [_reg1]=f20,16;;
\
+ stf.spill.nta [_reg1]=f21,16;;
\
+ stf.spill.nta [_reg1]=f22,16;;
\
+ stf.spill.nta [_reg1]=f23,16;;
\
+ stf.spill.nta [_reg1]=f24,16;;
\
+ stf.spill.nta [_reg1]=f25,16;;
\
+ stf.spill.nta [_reg1]=f26,16;;
\
+ stf.spill.nta [_reg1]=f27,16;;
\
+ stf.spill.nta [_reg1]=f28,16;;
\
+ stf.spill.nta [_reg1]=f29,16;;
\
+ stf.spill.nta [_reg1]=f30,16;;
\
+ stf.spill.nta [_reg1]=f31,16;;
+
+#else
+#define SET_AREA_FOR_BOOTING_CPU(a1, a2)
+#define SAL_TO_OS_BOOT_HANDOFF_STATE_SAVE(a1,a2, a3)
+#define SAVE_REGION_REGS(_tmp, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7)
+#define STORE_REGION_REGS(ptr, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7)
+#endif
+
+#ifdef XEN
+#define SET_ONE_RR(num, pgsize, _tmp1, _tmp2, vhpt) \
+ movl _tmp1=(num << 61);; \
+ movl _tmp2=((ia64_rid(IA64_REGION_ID_KERNEL, (num<<61)) << 8) | (pgsize
<< 2) | vhpt);; \
+ mov rr[_tmp1]=_tmp2
+#else
+#define SET_ONE_RR(num, pgsize, _tmp1, _tmp2, vhpt) \
+ movl _tmp1=(num << 61);; \
+ mov _tmp2=((ia64_rid(IA64_REGION_ID_KERNEL, (num<<61)) << 8) | (pgsize
<< 2) | vhpt);; \
+ mov rr[_tmp1]=_tmp2
+#endif
.section __special_page_section,"ax"
@@ -63,6 +205,12 @@
;;
srlz.i
;;
+ /*
+ * Save the region registers, predicate before they get clobbered
+ */
+ SAVE_REGION_REGS(r2, r8,r9,r10,r11,r12,r13,r14,r15);
+ mov r25=pr;;
+
/*
* Initialize kernel region registers:
* rr[0]: VHPT enabled, page size = PAGE_SHIFT
@@ -76,32 +224,14 @@
* We initialize all of them to prevent inadvertently assuming
* something about the state of address translation early in boot.
*/
- movl r6=((ia64_rid(IA64_REGION_ID_KERNEL, (0<<61)) << 8) | (PAGE_SHIFT
<< 2) | 1)
- movl r7=(0<<61)
- movl r8=((ia64_rid(IA64_REGION_ID_KERNEL, (1<<61)) << 8) | (PAGE_SHIFT
<< 2) | 1)
- movl r9=(1<<61)
- movl r10=((ia64_rid(IA64_REGION_ID_KERNEL, (2<<61)) << 8) | (PAGE_SHIFT
<< 2) | 1)
- movl r11=(2<<61)
- movl r12=((ia64_rid(IA64_REGION_ID_KERNEL, (3<<61)) << 8) | (PAGE_SHIFT
<< 2) | 1)
- movl r13=(3<<61)
- movl r14=((ia64_rid(IA64_REGION_ID_KERNEL, (4<<61)) << 8) | (PAGE_SHIFT
<< 2) | 1)
- movl r15=(4<<61)
- movl r16=((ia64_rid(IA64_REGION_ID_KERNEL, (5<<61)) << 8) | (PAGE_SHIFT
<< 2) | 1)
- movl r17=(5<<61)
- movl r18=((ia64_rid(IA64_REGION_ID_KERNEL, (6<<61)) << 8) |
(IA64_GRANULE_SHIFT << 2))
- movl r19=(6<<61)
- movl r20=((ia64_rid(IA64_REGION_ID_KERNEL, (7<<61)) << 8) |
(IA64_GRANULE_SHIFT << 2))
- movl r21=(7<<61)
- ;;
- mov rr[r7]=r6
- mov rr[r9]=r8
- mov rr[r11]=r10
- mov rr[r13]=r12
- mov rr[r15]=r14
- mov rr[r17]=r16
- mov rr[r19]=r18
- mov rr[r21]=r20
- ;;
+ SET_ONE_RR(0, PAGE_SHIFT, r2, r16, 1);;
+ SET_ONE_RR(1, PAGE_SHIFT, r2, r16, 1);;
+ SET_ONE_RR(2, PAGE_SHIFT, r2, r16, 1);;
+ SET_ONE_RR(3, PAGE_SHIFT, r2, r16, 1);;
+ SET_ONE_RR(4, PAGE_SHIFT, r2, r16, 1);;
+ SET_ONE_RR(5, PAGE_SHIFT, r2, r16, 1);;
+ SET_ONE_RR(6, IA64_GRANULE_SHIFT, r2, r16, 0);;
+ SET_ONE_RR(7, IA64_GRANULE_SHIFT, r2, r16, 0);;
/*
* Now pin mappings into the TLB for kernel text and data
*/
@@ -129,13 +259,13 @@
/*
* Switch into virtual mode:
*/
-#ifdef CONFIG_VTI
- movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH \
+#if defined(XEN) && defined(CONFIG_VTI)
+ movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH\
|IA64_PSR_DI)
-#else // CONFIG_VTI
+#else
movl
r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \
|IA64_PSR_DI)
-#endif // CONFIG_VTI
+#endif
;;
mov cr.ipsr=r16
movl r17=1f
@@ -147,12 +277,18 @@
;;
1: // now we are in virtual mode
+ SET_AREA_FOR_BOOTING_CPU(r2, r16);
+
+ STORE_REGION_REGS(r16, r8,r9,r10,r11,r12,r13,r14,r15);
+ SAL_TO_OS_BOOT_HANDOFF_STATE_SAVE(r16,r17,r25)
+ ;;
+
// set IVT entry point---can't access I/O ports without it
-#ifdef CONFIG_VTI
- movl r3=vmx_ia64_ivt
-#else // CONFIG_VTI
+#if defined(XEN) && defined(CONFIG_VTI)
+ movl r3=vmx_ia64_ivt
+#else
movl r3=ia64_ivt
-#endif // CONFIG_VTI
+#endif
;;
mov cr.iva=r3
movl r2=FPSR_DEFAULT
@@ -220,23 +356,24 @@
.load_current:
// load the "current" pointer (r13) and ar.k6 with the current task
-#ifdef CONFIG_VTI
- mov r21=r2 // virtual address
+#if defined(XEN) && defined(CONFIG_VTI)
+ mov r21=r2
;;
bsw.1
;;
-#else // CONFIG_VTI
- mov IA64_KR(CURRENT)=r2
+#else
+ mov IA64_KR(CURRENT)=r2 // virtual address
mov IA64_KR(CURRENT_STACK)=r16
-#endif // CONFIG_VTI
+#endif
mov r13=r2
/*
- * Reserve space at the top of the stack for "struct pt_regs". Kernel
threads
- * don't store interesting values in that structure, but the space
still needs
- * to be there because time-critical stuff such as the context
switching can
- * be implemented more efficiently (for example, __switch_to()
+ * Reserve space at the top of the stack for "struct pt_regs". Kernel
+ * threads don't store interesting values in that structure, but the
space
+ * still needs to be there because time-critical stuff such as the
context
+ * switching can be implemented more efficiently (for example,
__switch_to()
* always sets the psr.dfh bit of the task it is switching to).
*/
+
addl r12=IA64_STK_OFFSET-IA64_PT_REGS_SIZE-16,r2
addl r2=IA64_RBS_OFFSET,r2 // initialize the RSE
mov ar.rsc=0 // place RSE in enforced lazy mode
@@ -278,9 +415,13 @@
br.call.sptk.many b0=console_print
self: hint @pause
+#ifdef XEN
;;
br.sptk.many self // endless loop
;;
+#else
+ br.sptk.many self // endless loop
+#endif
END(_start)
GLOBAL_ENTRY(ia64_save_debug_regs)
@@ -1023,4 +1164,98 @@
#endif
+#ifdef CONFIG_HOTPLUG_CPU
+GLOBAL_ENTRY(ia64_jump_to_sal)
+ alloc r16=ar.pfs,1,0,0,0;;
+ rsm psr.i | psr.ic
+{
+ flushrs
+ srlz.i
+}
+ tpa r25=in0
+ movl r18=tlb_purge_done;;
+ DATA_VA_TO_PA(r18);;
+ mov b1=r18 // Return location
+ movl r18=ia64_do_tlb_purge;;
+ DATA_VA_TO_PA(r18);;
+ mov b2=r18 // doing tlb_flush work
+ mov ar.rsc=0 // Put RSE in enforced lazy, LE mode
+ movl r17=1f;;
+ DATA_VA_TO_PA(r17);;
+ mov cr.iip=r17
+ movl r16=SAL_PSR_BITS_TO_SET;;
+ mov cr.ipsr=r16
+ mov cr.ifs=r0;;
+ rfi;;
+1:
+ /*
+ * Invalidate all TLB data/inst
+ */
+ br.sptk.many b2;; // jump to tlb purge code
+
+tlb_purge_done:
+ RESTORE_REGION_REGS(r25, r17,r18,r19);;
+ RESTORE_REG(b0, r25, r17);;
+ RESTORE_REG(b1, r25, r17);;
+ RESTORE_REG(b2, r25, r17);;
+ RESTORE_REG(b3, r25, r17);;
+ RESTORE_REG(b4, r25, r17);;
+ RESTORE_REG(b5, r25, r17);;
+ ld8 r1=[r25],0x08;;
+ ld8 r12=[r25],0x08;;
+ ld8 r13=[r25],0x08;;
+ RESTORE_REG(ar.fpsr, r25, r17);;
+ RESTORE_REG(ar.pfs, r25, r17);;
+ RESTORE_REG(ar.rnat, r25, r17);;
+ RESTORE_REG(ar.unat, r25, r17);;
+ RESTORE_REG(ar.bspstore, r25, r17);;
+ RESTORE_REG(cr.dcr, r25, r17);;
+ RESTORE_REG(cr.iva, r25, r17);;
+ RESTORE_REG(cr.pta, r25, r17);;
+ RESTORE_REG(cr.itv, r25, r17);;
+ RESTORE_REG(cr.pmv, r25, r17);;
+ RESTORE_REG(cr.cmcv, r25, r17);;
+ RESTORE_REG(cr.lrr0, r25, r17);;
+ RESTORE_REG(cr.lrr1, r25, r17);;
+ ld8 r4=[r25],0x08;;
+ ld8 r5=[r25],0x08;;
+ ld8 r6=[r25],0x08;;
+ ld8 r7=[r25],0x08;;
+ ld8 r17=[r25],0x08;;
+ mov pr=r17,-1;;
+ RESTORE_REG(ar.lc, r25, r17);;
+ /*
+ * Now Restore floating point regs
+ */
+ ldf.fill.nta f2=[r25],16;;
+ ldf.fill.nta f3=[r25],16;;
+ ldf.fill.nta f4=[r25],16;;
+ ldf.fill.nta f5=[r25],16;;
+ ldf.fill.nta f16=[r25],16;;
+ ldf.fill.nta f17=[r25],16;;
+ ldf.fill.nta f18=[r25],16;;
+ ldf.fill.nta f19=[r25],16;;
+ ldf.fill.nta f20=[r25],16;;
+ ldf.fill.nta f21=[r25],16;;
+ ldf.fill.nta f22=[r25],16;;
+ ldf.fill.nta f23=[r25],16;;
+ ldf.fill.nta f24=[r25],16;;
+ ldf.fill.nta f25=[r25],16;;
+ ldf.fill.nta f26=[r25],16;;
+ ldf.fill.nta f27=[r25],16;;
+ ldf.fill.nta f28=[r25],16;;
+ ldf.fill.nta f29=[r25],16;;
+ ldf.fill.nta f30=[r25],16;;
+ ldf.fill.nta f31=[r25],16;;
+
+ /*
+ * Now that we have done all the register restores
+ * we are now ready for the big DIVE to SAL Land
+ */
+ ssm psr.ic;;
+ srlz.d;;
+ br.ret.sptk.many b0;;
+END(ia64_jump_to_sal)
+#endif /* CONFIG_HOTPLUG_CPU */
+
#endif /* CONFIG_SMP */
diff -r b7276814008c -r 4e4f1db8ea94 xen/arch/ia64/linux-xen/irq_ia64.c
--- a/xen/arch/ia64/linux-xen/irq_ia64.c Wed Aug 31 20:32:27 2005
+++ b/xen/arch/ia64/linux-xen/irq_ia64.c Wed Aug 31 22:55:04 2005
@@ -70,8 +70,7 @@
pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS);
vector = IA64_FIRST_DEVICE_VECTOR + pos;
if (vector > IA64_LAST_DEVICE_VECTOR)
- /* XXX could look for sharable vectors instead of panic'ing...
*/
- panic("assign_irq_vector: out of interrupt vectors!");
+ return -ENOSPC;
if (test_and_set_bit(pos, ia64_vector_mask))
goto again;
return vector;
@@ -173,103 +172,6 @@
irq_exit();
}
-#ifdef CONFIG_VTI
-#define vmx_irq_enter() \
- add_preempt_count(HARDIRQ_OFFSET);
-
-/* Now softirq will be checked when leaving hypervisor, or else
- * scheduler irq will be executed too early.
- */
-#define vmx_irq_exit(void) \
- sub_preempt_count(HARDIRQ_OFFSET);
-/*
- * That's where the IVT branches when we get an external
- * interrupt. This branches to the correct hardware IRQ handler via
- * function ptr.
- */
-void
-vmx_ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
-{
- unsigned long saved_tpr;
- int wake_dom0 = 0;
-
-
-#if IRQ_DEBUG
- {
- unsigned long bsp, sp;
-
- /*
- * Note: if the interrupt happened while executing in
- * the context switch routine (ia64_switch_to), we may
- * get a spurious stack overflow here. This is
- * because the register and the memory stack are not
- * switched atomically.
- */
- bsp = ia64_getreg(_IA64_REG_AR_BSP);
- sp = ia64_getreg(_IA64_REG_AR_SP);
-
- if ((sp - bsp) < 1024) {
- static unsigned char count;
- static long last_time;
-
- if (jiffies - last_time > 5*HZ)
- count = 0;
- if (++count < 5) {
- last_time = jiffies;
- printk("ia64_handle_irq: DANGER: less than "
- "1KB of free stack space!!\n"
- "(bsp=0x%lx, sp=%lx)\n", bsp, sp);
- }
- }
- }
-#endif /* IRQ_DEBUG */
-
- /*
- * Always set TPR to limit maximum interrupt nesting depth to
- * 16 (without this, it would be ~240, which could easily lead
- * to kernel stack overflows).
- */
- vmx_irq_enter();
- saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
- ia64_srlz_d();
- while (vector != IA64_SPURIOUS_INT_VECTOR) {
- if (!IS_RESCHEDULE(vector)) {
- ia64_setreg(_IA64_REG_CR_TPR, vector);
- ia64_srlz_d();
-
- if (vector != IA64_TIMER_VECTOR) {
- /* FIXME: Leave IRQ re-route later */
- vmx_vcpu_pend_interrupt(dom0->vcpu[0],vector);
- wake_dom0 = 1;
- }
- else { // FIXME: Handle Timer only now
- __do_IRQ(local_vector_to_irq(vector), regs);
- }
-
- /*
- * Disable interrupts and send EOI:
- */
- local_irq_disable();
- ia64_setreg(_IA64_REG_CR_TPR, saved_tpr);
- }
- else {
- printf("Oops: RESCHEDULE IPI absorbed by HV\n");
- }
- ia64_eoi();
- vector = ia64_get_ivr();
- }
- /*
- * This must be done *after* the ia64_eoi(). For example, the keyboard
softirq
- * handler needs to be able to wait for further keyboard interrupts,
which can't
- * come through until ia64_eoi() has been done.
- */
- vmx_irq_exit();
- if ( wake_dom0 && current != dom0 )
- vcpu_wake(dom0->vcpu[0]);
-}
-#endif
-
-
#ifdef CONFIG_HOTPLUG_CPU
/*
* This function emulates a interrupt processing when a cpu is about to be
diff -r b7276814008c -r 4e4f1db8ea94 xen/arch/ia64/linux-xen/minstate.h
--- a/xen/arch/ia64/linux-xen/minstate.h Wed Aug 31 20:32:27 2005
+++ b/xen/arch/ia64/linux-xen/minstate.h Wed Aug 31 22:55:04 2005
@@ -26,7 +26,7 @@
(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode,
use sp (r12) */ \
;;
\
(pUStk) mov r18=ar.bsp;
\
-(pUStk) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian,
loadrs=0 */ \
+(pUStk) mov ar.rsc=0x3; /* set eager mode, pl 0, little-endian,
loadrs=0 */
#define MINSTATE_END_SAVE_MIN_VIRT
\
bsw.1; /* switch back to bank 1 (must be last in insn
group) */ \
@@ -41,7 +41,7 @@
(pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;;
\
(pKStk) ld8 r3 = [r3];;
\
(pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;;
\
-(pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3;
\
+(pKStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3;
\
(pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0,
little-endian, loadrs=0 */ \
(pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of
register backing store */ \
;;
\
@@ -50,7 +50,6 @@
(pUStk) mov r23=ar.bspstore; /* save
ar.bspstore */ \
(pUStk) dep r22=-1,r22,61,3; /* compute kernel
virtual addr of RBS */ \
;;
\
-(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp
(r12) */ \
(pUStk) mov ar.bspstore=r22; /* switch to kernel RBS
*/ \
;;
\
(pUStk) mov r18=ar.bsp;
\
@@ -61,9 +60,13 @@
;;
#ifdef MINSTATE_VIRT
-# define MINSTATE_GET_CURRENT(reg) \
- movl reg=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;\
- ld8 reg=[reg]
+#ifdef XEN
+# define MINSTATE_GET_CURRENT(reg) \
+ movl reg=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; \
+ ld8 reg=[reg]
+#else
+# define MINSTATE_GET_CURRENT(reg) mov reg=IA64_KR(CURRENT)
+#endif
# define MINSTATE_START_SAVE_MIN MINSTATE_START_SAVE_MIN_VIRT
# define MINSTATE_END_SAVE_MIN MINSTATE_END_SAVE_MIN_VIRT
#endif
@@ -172,8 +175,8 @@
;;
\
.mem.offset 0,0; st8.spill [r16]=r13,16;
\
.mem.offset 8,0; st8.spill [r17]=r21,16; /* save ar.fpsr */
\
- movl r13=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;;
\
- ld8 r13=[r13]; /* establish 'current' */
\
+ /* XEN mov r13=IA64_KR(CURRENT); /* establish `current' */
\
+ MINSTATE_GET_CURRENT(r13); /* XEN establish `current' */
\
;;
\
.mem.offset 0,0; st8.spill [r16]=r15,16;
\
.mem.offset 8,0; st8.spill [r17]=r14,16;
\
diff -r b7276814008c -r 4e4f1db8ea94 xen/arch/ia64/linux-xen/mm_contig.c
--- a/xen/arch/ia64/linux-xen/mm_contig.c Wed Aug 31 20:32:27 2005
+++ b/xen/arch/ia64/linux-xen/mm_contig.c Wed Aug 31 22:55:04 2005
@@ -62,7 +62,8 @@
printk("%d reserved pages\n", reserved);
printk("%d pages shared\n", shared);
printk("%d pages swap cached\n", cached);
- printk("%ld pages in page table cache\n", pgtable_cache_size);
+ printk("%ld pages in page table cache\n",
+ pgtable_quicklist_total_size());
}
#endif
@@ -290,7 +291,7 @@
vmem_map = (struct page *) vmalloc_end;
efi_memmap_walk(create_mem_map_page_table, NULL);
- mem_map = contig_page_data.node_mem_map = vmem_map;
+ NODE_DATA(0)->node_mem_map = vmem_map;
free_area_init_node(0, &contig_page_data, zones_size,
0, zholes_size);
@@ -307,4 +308,4 @@
#endif /* !CONFIG_VIRTUAL_MEM_MAP */
zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
}
-#endif /* !CONFIG_XEN */
+#endif
diff -r b7276814008c -r 4e4f1db8ea94 xen/arch/ia64/linux-xen/unaligned.c
--- a/xen/arch/ia64/linux-xen/unaligned.c Wed Aug 31 20:32:27 2005
+++ b/xen/arch/ia64/linux-xen/unaligned.c Wed Aug 31 22:55:04 2005
@@ -201,7 +201,7 @@
RPT(r1), RPT(r2), RPT(r3),
-#ifdef CONFIG_VTI
+#if defined(XEN) && defined(CONFIG_VTI)
RPT(r4), RPT(r5), RPT(r6), RPT(r7),
#else //CONFIG_VTI
RSW(r4), RSW(r5), RSW(r6), RSW(r7),
@@ -295,7 +295,7 @@
return reg;
}
-#ifdef CONFIG_VTI
+#if defined(XEN) && defined(CONFIG_VTI)
static void
set_rse_reg (struct pt_regs *regs, unsigned long r1, unsigned long val,
unsigned long nat)
{
@@ -359,56 +359,6 @@
}
ia64_set_rsc(old_rsc);
}
-
-
-static void
-get_rse_reg (struct pt_regs *regs, unsigned long r1, unsigned long *val,
unsigned long *nat)
-{
- struct switch_stack *sw = (struct switch_stack *) regs - 1;
- unsigned long *bsp, *addr, *rnat_addr, *ubs_end, *bspstore;
- unsigned long *kbs = (void *) current + IA64_RBS_OFFSET;
- unsigned long rnats, nat_mask;
- unsigned long on_kbs;
- unsigned long old_rsc, new_rsc;
- long sof = (regs->cr_ifs) & 0x7f;
- long sor = 8 * ((regs->cr_ifs >> 14) & 0xf);
- long rrb_gr = (regs->cr_ifs >> 18) & 0x7f;
- long ridx = r1 - 32;
-
- if (ridx >= sof) {
- /* read of out-of-frame register returns an undefined value; 0
in our case. */
- DPRINT("ignoring read from r%lu; only %lu registers are
allocated!\n", r1, sof);
- panic("wrong stack register number");
- }
-
- if (ridx < sor)
- ridx = rotate_reg(sor, rrb_gr, ridx);
-
- old_rsc=ia64_get_rsc();
- new_rsc=old_rsc&(~(0x3));
- ia64_set_rsc(new_rsc);
-
- bspstore = ia64_get_bspstore();
- bsp =kbs + (regs->loadrs >> 19); //16+3;
-
- addr = ia64_rse_skip_regs(bsp, -sof + ridx);
- nat_mask = 1UL << ia64_rse_slot_num(addr);
- rnat_addr = ia64_rse_rnat_addr(addr);
-
- if(addr >= bspstore){
-
- ia64_flushrs ();
- ia64_mf ();
- bspstore = ia64_get_bspstore();
- }
- *val=*addr;
- if(bspstore < rnat_addr){
- *nat=!!(ia64_get_rnat()&nat_mask);
- }else{
- *nat = !!((*rnat_addr)&nat_mask);
- }
- ia64_set_rsc(old_rsc);
-}
#else // CONFIG_VTI
static void
set_rse_reg (struct pt_regs *regs, unsigned long r1, unsigned long val, int
nat)
@@ -590,7 +540,7 @@
unat = &sw->ar_unat;
} else {
addr = (unsigned long)regs;
-#ifdef CONFIG_VTI
+#if defined(XEN) && defined(CONFIG_VTI)
unat = ®s->eml_unat;
#else //CONFIG_VTI
unat = &sw->caller_unat;
@@ -780,7 +730,7 @@
unat = &sw->ar_unat;
} else {
addr = (unsigned long)regs;
-#ifdef CONFIG_VTI
+#if defined(XEN) && defined(CONFIG_VTI)
unat = ®s->eml_unat;;
#else //CONFIG_VTI
unat = &sw->caller_unat;
@@ -1527,6 +1477,10 @@
* - ldX.spill
* - stX.spill
* Reason: RNATs are based on addresses
+ * - ld16
+ * - st16
+ * Reason: ld16 and st16 are supposed to occur in a single
+ * memory op
*
* synchronization:
* - cmpxchg
@@ -1548,6 +1502,10 @@
switch (opcode) {
case LDS_OP:
case LDSA_OP:
+ if (u.insn.x)
+ /* oops, really a semaphore op (cmpxchg, etc) */
+ goto failure;
+ /* no break */
case LDS_IMM_OP:
case LDSA_IMM_OP:
case LDFS_OP:
@@ -1572,6 +1530,10 @@
case LDCCLR_OP:
case LDCNC_OP:
case LDCCLRACQ_OP:
+ if (u.insn.x)
+ /* oops, really a semaphore op (cmpxchg, etc) */
+ goto failure;
+ /* no break */
case LD_IMM_OP:
case LDA_IMM_OP:
case LDBIAS_IMM_OP:
@@ -1584,6 +1546,10 @@
case ST_OP:
case STREL_OP:
+ if (u.insn.x)
+ /* oops, really a semaphore op (cmpxchg, etc) */
+ goto failure;
+ /* no break */
case ST_IMM_OP:
case STREL_IMM_OP:
ret = emulate_store_int(ifa, u.insn, regs);
diff -r b7276814008c -r 4e4f1db8ea94 xen/arch/ia64/linux/README.origin
--- a/xen/arch/ia64/linux/README.origin Wed Aug 31 20:32:27 2005
+++ b/xen/arch/ia64/linux/README.origin Wed Aug 31 22:55:04 2005
@@ -1,4 +1,8 @@
Source files in this directory are identical copies of linux-2.6.13 files:
+
+NOTE: DO NOT commit changes to these files! If a file
+needs to be changed, move it to ../linux-xen and follow
+the instructions in the README there.
cmdline.c -> linux/lib/cmdline.c
efi_stub.S -> linux/arch/ia64/efi_stub.S
diff -r b7276814008c -r 4e4f1db8ea94 xen/arch/ia64/linux-xen/README.origin
--- /dev/null Wed Aug 31 20:32:27 2005
+++ b/xen/arch/ia64/linux-xen/README.origin Wed Aug 31 22:55:04 2005
@@ -0,0 +1,21 @@
+Source files in this directory are near-identical copies of linux-2.6.13 files:
+
+NOTE: ALL changes to these files should be clearly marked (e.g. with
+#ifdef XEN or XEN in a comment) so that they can be easily updated
+to future versions of the corresponding Linux files.
+
+efi.c -> linux/arch/ia64/kernel/efi.c
+entry.h -> linux/arch/ia64/kernel/entry.h
+entry.S -> linux/arch/ia64/kernel/entry.S
+irq_ia64.c -> linux/arch/ia64/kernel/irq_ia64.c
+minstate.h -> linux/arch/ia64/kernel/minstate.h
+mm_contig.c -> linux/arch/ia64/mm/contig.c
+pal.S -> linux/arch/ia64/kernel/pal.S
+sal.c -> linux/arch/ia64/kernel/sal.c
+setup.c -> linux/arch/ia64/kernel/setup.c
+smp.c -> linux/arch/ia64/kernel/smp.c
+smpboot.c -> linux/arch/ia64/kernel/smpboot.c
+sort.c -> linux/lib/sort.c
+time.c -> linux/arch/ia64/kernel/time.c
+tlb.c -> linux/arch/ia64/mm/tlb.c
+unaligned.c -> linux/arch/ia64/kernel/unaligned.c
diff -r b7276814008c -r 4e4f1db8ea94 xen/arch/ia64/vmx_irq_ia64.c
--- /dev/null Wed Aug 31 20:32:27 2005
+++ b/xen/arch/ia64/vmx_irq_ia64.c Wed Aug 31 22:55:04 2005
@@ -0,0 +1,127 @@
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/jiffies.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/kernel_stat.h>
+#include <linux/slab.h>
+#include <linux/ptrace.h>
+#include <linux/random.h> /* for rand_initialize_irq() */
+#include <linux/signal.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/threads.h>
+#include <linux/bitops.h>
+
+#include <asm/delay.h>
+#include <asm/intrinsics.h>
+#include <asm/io.h>
+#include <asm/hw_irq.h>
+#include <asm/machvec.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_PERFMON
+# include <asm/perfmon.h>
+#endif
+
+#define IRQ_DEBUG 0
+
+#ifdef CONFIG_VTI
+#define vmx_irq_enter() \
+ add_preempt_count(HARDIRQ_OFFSET);
+
+/* Now softirq will be checked when leaving hypervisor, or else
+ * scheduler irq will be executed too early.
+ */
+#define vmx_irq_exit(void) \
+ sub_preempt_count(HARDIRQ_OFFSET);
+/*
+ * That's where the IVT branches when we get an external
+ * interrupt. This branches to the correct hardware IRQ handler via
+ * function ptr.
+ */
+void
+vmx_ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
+{
+ unsigned long saved_tpr;
+ int wake_dom0 = 0;
+
+
+#if IRQ_DEBUG
+ {
+ unsigned long bsp, sp;
+
+ /*
+ * Note: if the interrupt happened while executing in
+ * the context switch routine (ia64_switch_to), we may
+ * get a spurious stack overflow here. This is
+ * because the register and the memory stack are not
+ * switched atomically.
+ */
+ bsp = ia64_getreg(_IA64_REG_AR_BSP);
+ sp = ia64_getreg(_IA64_REG_AR_SP);
+
+ if ((sp - bsp) < 1024) {
+ static unsigned char count;
+ static long last_time;
+
+ if (jiffies - last_time > 5*HZ)
+ count = 0;
+ if (++count < 5) {
+ last_time = jiffies;
+ printk("ia64_handle_irq: DANGER: less than "
+ "1KB of free stack space!!\n"
+ "(bsp=0x%lx, sp=%lx)\n", bsp, sp);
+ }
+ }
+ }
+#endif /* IRQ_DEBUG */
+
+ /*
+ * Always set TPR to limit maximum interrupt nesting depth to
+ * 16 (without this, it would be ~240, which could easily lead
+ * to kernel stack overflows).
+ */
+ vmx_irq_enter();
+ saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
+ ia64_srlz_d();
+ while (vector != IA64_SPURIOUS_INT_VECTOR) {
+ if (!IS_RESCHEDULE(vector)) {
+ ia64_setreg(_IA64_REG_CR_TPR, vector);
+ ia64_srlz_d();
+
+ if (vector != IA64_TIMER_VECTOR) {
+ /* FIXME: Leave IRQ re-route later */
+ vmx_vcpu_pend_interrupt(dom0->vcpu[0],vector);
+ wake_dom0 = 1;
+ }
+ else { // FIXME: Handle Timer only now
+ __do_IRQ(local_vector_to_irq(vector), regs);
+ }
+
+ /*
+ * Disable interrupts and send EOI:
+ */
+ local_irq_disable();
+ ia64_setreg(_IA64_REG_CR_TPR, saved_tpr);
+ }
+ else {
+ printf("Oops: RESCHEDULE IPI absorbed by HV\n");
+ }
+ ia64_eoi();
+ vector = ia64_get_ivr();
+ }
+ /*
+ * This must be done *after* the ia64_eoi(). For example, the keyboard
softirq
+ * handler needs to be able to wait for further keyboard interrupts,
which can't
+ * come through until ia64_eoi() has been done.
+ */
+ vmx_irq_exit();
+ if ( wake_dom0 && current != dom0 )
+ vcpu_wake(dom0->vcpu[0]);
+}
+#endif
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|