From: David Mosberger <davidm@hpl.hp.com>
To: linux-ia64@vger.kernel.org
Subject: [Linux-ia64] [PATCH] kernel updated (relative to 2.3.99pre6)
Date: Fri, 26 May 2000 07:49:50 +0000 [thread overview]
Message-ID: <marc-linux-ia64-105590678205108@msgid-missing> (raw)
Attached below is the long overdue kernel update. The diff below is
relative to the previous IA-64 kernel. A full diff relative to
Linus's 2.3.99pre6 is at:
ftp://ftp.kernel.org/pub/linux/kernel/ports/ia64/
in file "linux-2.3.99-pre6-ia64-000525.diff.gz". Note: this kernel
hasn't been tested in a lot of configurations so I'd not recommend to
use it in a distribution (not without further testing at least). In
particular, I haven't had time to test SMP. UP works fine on Big Sur
and the HP simulator. The reason I'm making the patch available now
is that we need to sync up with Linus's tree so if this patch happens
not to work on some systems, not much is lost as I plan to put out a
patch soon that brings us to 2.4-test1.
An updated kdb patch is available at:
ftp://ftp.hpl.hp.com/pub/linux-ia64/kdb-2.3.99-pre6-000525.diff.gz
The kdb patch is known not to work with SMP (it crashes in the boot
with a "CPU already initialized" error; looks like it's a stupid
problem, but I haven't had time to fix it; if someone could make this
work again, it would be great).
Summary of changes:
o The big change this time is lots of new code to support full stack
unwinding. This is fairly intricate stuff and the code is not 100%
complete yet. For example, more debugging needs to be done, the
memory/cache management is stupid, and SMP locking is
missing. Having said that, I'm quite happy with how things are
shaping up so far. It looks like we should be able to unwind both
reliably and efficiently. the "backtrace" command in kdb works
better than it ever did and there is complete support for all
unwind directives (modulo bugs that is... ;-). The new unwind
support is enabled only if CONFIG_IA64_NEW_UNWIND is turned on. Do
NOT turn this on right now unless you have a toolchain that has all
the unwind fixes applied (goes for gcc and gas). Without those
fixes, the unwind info will be incorrect and things won't work
properly.
As a consequence of this, I added unwind directives for all
assembly files (I think I missed mca_asm.S though). Please be sure
to keep this info in sync with the assembly code. For a
description of the unwind directives, see the Assembly Reference
Guide (available at http://developer.intel.com/design/ia64)
o Workaround for the global tlb flush hw erratum (Asit).
o Kernel module support (Stephen Zeisset).
o SIGFPE now passes ISR in the si_isr field of siginfo to permit
user-level fp emulation/testing etc. (Goutham).
o Fixes to the emu10k1 sound driver (Bill, I think).
o New kernel option: if you have a CPU that has an A2 or later
stepping, you can turn off CONFIG_ITANIUM_A1_SPECIFIC and enjoy
reduced interrupt latency etc.
o Increased number of PCI busses to scan to 255 (the fix necessary to
make this work come from Asit).
o Changes required for the AzusA platform (kouchi). Please note that
I did not include the azusa_vectors table nor did I change the
isa_irq_to_vector_map. For the former, please hack (or better
still: fix) the bootloader. For the latter, I think we need a
better solution. Either we can find an ISA vector map that will
work on all platforms or, if that's not possible, we'll need to
assign the ISA vectors dynamically. Anyone want to take a stab at
a clean solution for this?
o Timer-management related updated by Walt. I chose to use a different
approach to handling "race conditions" with the itm. Basically, the
new code turns off interrupts while checking if the itc is past
the itm and additionally allows for a slack of 1000 cycles. Haven't
done much experimenting with it, but I do think this should be the
good way to reduce the number of spurious lost tick messages.
o IA-32 updates by Don and myself. Don, note that the IA-32
state-switching is now in ia32_support.c. I rearranged that code a
little. I think it should be much faster now, but I haven't
measured it.
o New header file <asm/asmmacro.h> defines a couple of convenience
macros to assist in assembly programming.
o Remove support for old compilers that didn't know how to return
things in r9, r10, and r11.
o ptrace updates in preparation for the new unwind code. Kevin, note
that PT_PRI_UNAT now exists but it does NOT yet return the correct
NaT bits. This will be one of the next things I'll work on.
o Fix execve() code so that running gdb on vmlinux and typing "run"
no longer freezes the system. ;-)
That should be it. Please give it a spin and let me know how it
works.
If someone is looking for a small but potentially interesting project:
in the SMP case, we currently do not implement a fine-grained
gettimeofday(). This is easy to do if you're willing to do an IPI to
the bootstrap processor on every gettimeofday(), but it seems to me we
should be able to do better than that (a lot better, actually). Would
be great if someone could come up with a great way of solving this
issue (to get started, take a look at
arch/ia64/kernel/time.c:gettimeoffset()).
Enjoy,
--david
diff -urN linux-davidm/arch/ia64/Makefile linux-2.3.99-pre6-lia/arch/ia64/Makefile
--- linux-davidm/arch/ia64/Makefile Thu May 25 23:22:10 2000
+++ linux-2.3.99-pre6-lia/arch/ia64/Makefile Thu May 25 22:52:30 2000
@@ -12,16 +12,11 @@
AWK := awk
LINKFLAGS = -static -T arch/$(ARCH)/vmlinux.lds
-# next line is for HP compiler backend:
-#AFLAGS += -DGCC_RETVAL_POINTER_IN_R8
-# The next line is needed when compiling with the July snapshot of the Cygnus compiler:
-#EXTRA = -D__GCC_DOESNT_KNOW_IN_REGS__
-# next two lines are for the September snapshot of the Cygnus compiler:
-AFLAGS += -D__GCC_MULTIREG_RETVALS__ -Wa,-x
-EXTRA = -D__GCC_MULTIREG_RETVALS__
+AFLAGS += -Wa,-x
+EXTRA
-#CFLAGS := $(CFLAGS) -pipe -mconstant-gp $(EXTRA) -Wa,-x -ffixed-r13 -mfixed-rangeñ0-f15,f32-f127
-CFLAGS := $(CFLAGS) -pipe $(EXTRA) -Wa,-x -ffixed-r13 -mfixed-rangeñ0-f15,f32-f127
+CFLAGS := $(CFLAGS) -pipe $(EXTRA) -Wa,-x -ffixed-r13 -mfixed-rangeñ0-f15,f32-f127 \
+ -mconstant-gp -funwind-tables
ifdef CONFIG_IA64_GENERIC
CORE_FILES := arch/$(ARCH)/hp/hp.a \
diff -urN linux-davidm/arch/ia64/boot/Makefile linux-2.3.99-pre6-lia/arch/ia64/boot/Makefile
--- linux-davidm/arch/ia64/boot/Makefile Thu Mar 30 16:56:04 2000
+++ linux-2.3.99-pre6-lia/arch/ia64/boot/Makefile Thu May 25 22:53:10 2000
@@ -25,7 +25,8 @@
all: $(TARGETS)
bootloader: $(OBJECTS)
- $(LD) $(LINKFLAGS) $(OBJECTS) $(LIBS) -o bootloader
+ $(LD) $(LINKFLAGS) $(OBJECTS) $(TOPDIR)/lib/lib.a $(TOPDIR)/arch/$(ARCH)/lib/lib.a \
+ -o bootloader
clean:
rm -f $(TARGETS)
diff -urN linux-davidm/arch/ia64/config.in linux-2.3.99-pre6-lia/arch/ia64/config.in
--- linux-davidm/arch/ia64/config.in Thu May 25 23:22:10 2000
+++ linux-2.3.99-pre6-lia/arch/ia64/config.in Thu May 25 22:54:04 2000
@@ -24,9 +24,9 @@
if [ "$CONFIG_IA64_DIG" = "y" ]; then
bool ' Enable Itanium A-step specific code' CONFIG_ITANIUM_ASTEP_SPECIFIC
bool ' Enable Itanium A1-step specific code' CONFIG_ITANIUM_A1_SPECIFIC
+ bool ' Enable use of global TLB purge instruction (ptc.g)' CONFIG_ITANIUM_PTCG
bool ' Enable SoftSDV hacks' CONFIG_IA64_SOFTSDV_HACKS
- bool ' Enable BigSur hacks' CONFIG_IA64_BIGSUR_HACKS
- bool ' Enable Lion hacks' CONFIG_IA64_LION_HACKS
+ bool ' Enable AzusA hacks' CONFIG_IA64_AZUSA_HACKS
bool ' Emulate PAL/SAL/EFI firmware' CONFIG_IA64_FW_EMU
bool ' Enable IA64 Machine Check Abort' CONFIG_IA64_MCA
fi
@@ -188,5 +188,6 @@
bool 'Turn on compare-and-exchange bug checking (slow!)' CONFIG_IA64_DEBUG_CMPXCHG
bool 'Turn on irq debug checks (slow!)' CONFIG_IA64_DEBUG_IRQ
bool 'Print possible IA64 hazards to console' CONFIG_IA64_PRINT_HAZARDS
+bool 'Enable new unwind support' CONFIG_IA64_NEW_UNWIND
endmenu
diff -urN linux-davidm/arch/ia64/dig/iosapic.c linux-2.3.99-pre6-lia/arch/ia64/dig/iosapic.c
--- linux-davidm/arch/ia64/dig/iosapic.c Thu May 25 23:22:10 2000
+++ linux-2.3.99-pre6-lia/arch/ia64/dig/iosapic.c Thu May 25 22:54:40 2000
@@ -67,6 +67,12 @@
(delivery << IO_SAPIC_DELIVERY_SHIFT) |
vector);
+#ifdef CONFIG_IA64_AZUSA_HACKS
+ /* set Flush Disable bit */
+ if (iosapic_addr != 0xc0000000fec00000)
+ low32 |= (1 << 17);
+#endif
+
/* dest contains both id and eid */
high32 = (dest << IO_SAPIC_DEST_SHIFT);
@@ -216,29 +222,31 @@
}
void
-iosapic_init (unsigned long address)
+iosapic_init (unsigned long address, int irqbase)
{
struct hw_interrupt_type *irq_type;
struct pci_vector_struct *vectors;
int i, irq;
- /*
- * Map the legacy ISA devices into the IOSAPIC data. Some of
- * these may get reprogrammed later on with data from the ACPI
- * Interrupt Source Override table.
- */
- for (i = 0; i < 16; i++) {
- irq = isa_irq_to_vector(i);
- iosapic_pin(irq) = i;
- iosapic_bus(irq) = BUS_ISA;
- iosapic_busdata(irq) = 0;
- iosapic_dmode(irq) = IO_SAPIC_LOWEST_PRIORITY;
- iosapic_trigger(irq) = IO_SAPIC_EDGE;
- iosapic_polarity(irq) = IO_SAPIC_POL_HIGH;
+ if (irqbase = 0)
+ /*
+ * Map the legacy ISA devices into the IOSAPIC data.
+ * Some of these may get reprogrammed later on with
+ * data from the ACPI Interrupt Source Override table.
+ */
+ for (i = 0; i < 16; i++) {
+ irq = isa_irq_to_vector(i);
+ iosapic_pin(irq) = i;
+ iosapic_bus(irq) = BUS_ISA;
+ iosapic_busdata(irq) = 0;
+ iosapic_dmode(irq) = IO_SAPIC_LOWEST_PRIORITY;
+ iosapic_trigger(irq) = IO_SAPIC_EDGE;
+ iosapic_polarity(irq) = IO_SAPIC_POL_HIGH;
#ifdef DEBUG_IRQ_ROUTING
- printk("ISA: IRQ %02x -> Vector %02x IOSAPIC Pin %d\n", i, irq, iosapic_pin(irq));
+ printk("ISA: IRQ %02x -> Vector %02x IOSAPIC Pin %d\n",
+ i, irq, iosapic_pin(irq));
#endif
- }
+ }
#ifndef CONFIG_IA64_SOFTSDV_HACKS
/*
@@ -251,6 +259,8 @@
irq = vectors[i].irq;
if (irq < 16)
irq = isa_irq_to_vector(irq);
+ if (iosapic_baseirq(irq) != irqbase)
+ continue;
iosapic_bustype(irq) = BUS_PCI;
iosapic_pin(irq) = irq - iosapic_baseirq(irq);
@@ -274,6 +284,9 @@
#endif /* CONFIG_IA64_SOFTSDV_HACKS */
for (i = 0; i < NR_IRQS; ++i) {
+ if (iosapic_baseirq(i) != irqbase)
+ continue;
+
if (iosapic_pin(i) != -1) {
if (iosapic_trigger(i) = IO_SAPIC_LEVEL)
irq_type = &irq_type_iosapic_level;
diff -urN linux-davidm/arch/ia64/ia32/ia32_entry.S linux-2.3.99-pre6-lia/arch/ia64/ia32/ia32_entry.S
--- linux-davidm/arch/ia64/ia32/ia32_entry.S Fri Apr 21 15:21:23 2000
+++ linux-2.3.99-pre6-lia/arch/ia64/ia32/ia32_entry.S Thu May 25 22:55:27 2000
@@ -1,14 +1,15 @@
+#include <asm/asmmacro.h>
#include <asm/offsets.h>
#include <asm/signal.h>
+#include "../kernel/entry.h"
+
//
// Get possibly unaligned sigmask argument into an aligned
// kernel buffer
.text
- .proc ia32_rt_sigsuspend
- .global ia32_rt_sigsuspend
-ia32_rt_sigsuspend:
+GLOBAL_ENTRY(ia32_rt_sigsuspend)
// We'll cheat and not do an alloc here since we are ultimately
// going to do a simple branch to the IA64 sys_rt_sigsuspend.
// r32 is still the first argument which is the signal mask.
@@ -32,24 +33,22 @@
st4 [r32]=r2
st4 [r10]=r3
br.cond.sptk.many sys_rt_sigsuspend
+END(ia32_rt_sigsuspend)
.section __ex_table,"a"
data4 @gprel(1b)
data4 (2b-1b)|1
.previous
+GLOBAL_ENTRY(ia32_ret_from_syscall)
+ PT_REGS_UNWIND_INFO
- .endp ia32_rt_sigsuspend
-
- .global ia32_ret_from_syscall
- .proc ia32_ret_from_syscall
-ia32_ret_from_syscall:
cmp.ge p6,p7=r8,r0 // syscall executed successfully?
adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8
;;
st8 [r2]=r8 // store return value in slot for r8
br.cond.sptk.few ia64_leave_kernel
- .endp ia32_ret_from_syscall
+END(ia32_ret_from_syscall)
//
// Invoke a system call, but do some tracing before and after the call.
@@ -61,9 +60,8 @@
// r15 = syscall number
// b6 = syscall entry point
//
- .global ia32_trace_syscall
- .proc ia32_trace_syscall
-ia32_trace_syscall:
+GLOBAL_ENTRY(ia32_trace_syscall)
+ PT_REGS_UNWIND_INFO
br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch syscall args
.Lret4: br.call.sptk.few rp¶ // do the syscall
.Lret5: cmp.lt p6,p0=r8,r0 // syscall failed?
@@ -72,42 +70,38 @@
st8.spill [r2]=r8 // store return value in slot for r8
br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch return value
.Lret6: br.cond.sptk.many ia64_leave_kernel // rp MUST be != ia64_leave_kernel!
+END(ia32_trace_syscall)
- .endp ia32_trace_syscall
-
- .align 16
- .global sys32_vfork
- .proc sys32_vfork
-sys32_vfork:
+GLOBAL_ENTRY(sys32_vfork)
alloc r16=ar.pfs,2,2,3,0;;
mov out0=IA64_CLONE_VFORK|IA64_CLONE_VM|SIGCHLD // out0 = clone_flags
br.cond.sptk.few .fork1 // do the work
- .endp sys32_vfork
+END(sys32_vfork)
- .align 16
- .global sys32_fork
- .proc sys32_fork
-sys32_fork:
- alloc r16=ar.pfs,2,2,3,0;;
+GLOBAL_ENTRY(sys32_fork)
+ UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2))
+ alloc r16=ar.pfs,2,2,3,0
mov out0=SIGCHLD // out0 = clone_flags
+ ;;
.fork1:
- movl r28\x1f
- mov loc1=rp
- br.cond.sptk.many save_switch_stack
-1:
- mov loc0=r16 // save ar.pfs across do_fork
+ mov loc0=rp
+ mov loc1=r16 // save ar.pfs across do_fork
+ DO_SAVE_SWITCH_STACK
+
+ UNW(.body)
+
adds out2=IA64_SWITCH_STACK_SIZE+16,sp
adds r2=IA64_SWITCH_STACK_SIZE+IA64_PT_REGS_R12_OFFSET+16,sp
;;
ld8 out1=[r2] // fetch usp from pt_regs.r12
br.call.sptk.few rp=do_fork
.ret1:
- mov ar.pfs=loc0
+ mov ar.pfs=loc1
+ UNW(.restore sp)
adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
- mov rp=loc1
- ;;
+ mov rp=loc0
br.ret.sptk.many rp
- .endp sys32_fork
+END(sys32_fork)
.rodata
.align 8
@@ -304,3 +298,8 @@
data8 sys_ni_syscall /* streams1 */
data8 sys_ni_syscall /* streams2 */
data8 sys32_vfork /* 190 */
+ /*
+ * CAUTION: If any system calls are added beyond this point
+ * then the check in `arch/ia64/kernel/ivt.S' will have
+ * to be modified also. You've been warned.
+ */
diff -urN linux-davidm/arch/ia64/ia32/ia32_signal.c linux-2.3.99-pre6-lia/arch/ia64/ia32/ia32_signal.c
--- linux-davidm/arch/ia64/ia32/ia32_signal.c Fri Apr 21 15:21:23 2000
+++ linux-2.3.99-pre6-lia/arch/ia64/ia32/ia32_signal.c Wed May 10 13:50:50 2000
@@ -226,7 +226,7 @@
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
- err |= __put_user(frame->retcode, &frame->pretcode);
+ err |= __put_user((long)frame->retcode, &frame->pretcode);
/* This is popl %eax ; movl $,%eax ; int $0x80 */
err |= __put_user(0xb858, (short *)(frame->retcode+0));
#define __IA32_NR_sigreturn 119
@@ -281,8 +281,8 @@
? current->exec_domain->signal_invmap[sig]
: sig),
&frame->sig);
- err |= __put_user(&frame->info, &frame->pinfo);
- err |= __put_user(&frame->uc, &frame->puc);
+ err |= __put_user((long)&frame->info, &frame->pinfo);
+ err |= __put_user((long)&frame->uc, &frame->puc);
err |= __copy_to_user(&frame->info, info, sizeof(*info));
/* Create the ucontext. */
@@ -296,7 +296,7 @@
regs, set->sig[0]);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
- err |= __put_user(frame->retcode, &frame->pretcode);
+ err |= __put_user((long)frame->retcode, &frame->pretcode);
/* This is movl $,%eax ; int $0x80 */
err |= __put_user(0xb8, (char *)(frame->retcode+0));
#define __IA32_NR_rt_sigreturn 173
diff -urN linux-davidm/arch/ia64/ia32/ia32_support.c linux-2.3.99-pre6-lia/arch/ia64/ia32/ia32_support.c
--- linux-davidm/arch/ia64/ia32/ia32_support.c Tue Feb 8 12:01:59 2000
+++ linux-2.3.99-pre6-lia/arch/ia64/ia32/ia32_support.c Mon May 22 18:03:20 2000
@@ -16,6 +16,43 @@
extern void die_if_kernel (char *str, struct pt_regs *regs, long err);
+void
+ia32_save_state (struct thread_struct *thread)
+{
+ unsigned long eflag, fsr, fcr, fir, fdr;
+
+ asm ("mov %0=ar.eflag;"
+ "mov %1=ar.fsr;"
+ "mov %2=ar.fcr;"
+ "mov %3=ar.fir;"
+ "mov %4=ar.fdr"
+ : "=r"(eflag), "=r"(fsr), "=r"(fcr), "=r"(fir), "=r"(fdr));
+ thread->eflag = eflag;
+ thread->fsr = fsr;
+ thread->fcr = fcr;
+ thread->fir = fir;
+ thread->fdr = fdr;
+}
+
+void
+ia32_load_state (struct thread_struct *thread)
+{
+ unsigned long eflag, fsr, fcr, fir, fdr;
+
+ eflag = thread->eflag;
+ fsr = thread->fsr;
+ fcr = thread->fcr;
+ fir = thread->fir;
+ fdr = thread->fdr;
+
+ asm volatile ("mov ar.eflag=%0;"
+ "mov ar.fsr=%1;"
+ "mov ar.fcr=%2;"
+ "mov ar.fir=%3;"
+ "mov ar.fdr=%4"
+ :: "r"(eflag), "r"(fsr), "r"(fcr), "r"(fir), "r"(fdr));
+}
+
/*
* Setup IA32 GDT and TSS
*/
diff -urN linux-davidm/arch/ia64/ia32/sys_ia32.c linux-2.3.99-pre6-lia/arch/ia64/ia32/sys_ia32.c
--- linux-davidm/arch/ia64/ia32/sys_ia32.c Thu May 25 23:22:10 2000
+++ linux-2.3.99-pre6-lia/arch/ia64/ia32/sys_ia32.c Thu May 25 22:55:38 2000
@@ -7,6 +7,8 @@
* Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2000 Hewlett-Packard Co.
+ * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
*
* These routines maintain argument size conversion between 32bit and 64bit
* environment.
@@ -55,24 +57,29 @@
#include <net/sock.h>
#include <asm/ia32.h>
-#define A(__x) ((unsigned long)(__x))
-#define AA(__x) ((unsigned long)(__x))
+#define A(__x) ((unsigned long)(__x))
+#define AA(__x) ((unsigned long)(__x))
+#define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
+#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
+
+extern asmlinkage long sys_execve (char *, char **, char **, struct pt_regs *);
+extern asmlinkage long sys_munmap (unsigned long, size_t len);
+extern asmlinkage long sys_mprotect (unsigned long, size_t, unsigned long);
static int
nargs(unsigned int arg, char **ap)
{
- char *ptr;
- int n, err;
+ int n, err, addr;
n = 0;
do {
- if (err = get_user(ptr, (int *)arg))
+ if ((err = get_user(addr, (int *)A(arg))) != 0)
return(err);
if (ap)
- *ap++ = ptr;
+ *ap++ = (char *)A(addr);
arg += sizeof(unsigned int);
n++;
- } while (ptr);
+ } while (addr);
return(n - 1);
}
@@ -106,14 +113,14 @@
down(¤t->mm->mmap_sem);
lock_kernel();
- av = do_mmap_pgoff(0, NULL, len,
- PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0);
+ av = (char **) do_mmap_pgoff(0, 0UL, len, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0);
unlock_kernel();
up(¤t->mm->mmap_sem);
if (IS_ERR(av))
- return(av);
+ return (long)av;
ae = av + na + 1;
av[na] = (char *)0;
ae[ne] = (char *)0;
@@ -121,7 +128,7 @@
(void)nargs(envp, ae);
r = sys_execve(filename, av, ae, regs);
if (IS_ERR(r))
- sys_munmap(av, len);
+ sys_munmap((unsigned long) av, len);
return(r);
}
@@ -146,9 +153,9 @@
return err;
}
-extern asmlinkage int sys_newstat(char * filename, struct stat * statbuf);
+extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
-asmlinkage int
+asmlinkage long
sys32_newstat(char * filename, struct stat32 *statbuf)
{
int ret;
@@ -163,9 +170,9 @@
return ret;
}
-extern asmlinkage int sys_newlstat(char * filename, struct stat * statbuf);
+extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
-asmlinkage int
+asmlinkage long
sys32_newlstat(char * filename, struct stat32 *statbuf)
{
int ret;
@@ -180,9 +187,9 @@
return ret;
}
-extern asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf);
+extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
-asmlinkage int
+asmlinkage long
sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
{
int ret;
@@ -223,14 +230,14 @@
}
if (addr && ((addr + len) & ~PAGE_MASK) && get_user(c, (char *)(addr + len)) = 0) {
back = kmalloc(PAGE_SIZE - ((addr + len) & ~PAGE_MASK), GFP_KERNEL);
- memcpy(back, addr + len, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
+ memcpy(back, (char *)addr + len, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
}
if ((r = do_mmap(0, baddr, len + (addr - baddr), prot, flags | MAP_ANONYMOUS, 0)) < 0)
return(r);
if (addr = 0)
addr = r;
if (back) {
- memcpy(addr + len, back, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
+ memcpy((char *)addr + len, back, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
kfree(back);
}
if (front) {
@@ -238,7 +245,7 @@
kfree(front);
}
if (flags & MAP_ANONYMOUS) {
- memset(addr, 0, len);
+ memset((char *)addr, 0, len);
return(addr);
}
if (!file)
@@ -272,7 +279,7 @@
unsigned int offset;
};
-asmlinkage int
+asmlinkage long
sys32_mmap(struct mmap_arg_struct *arg)
{
int error = -EFAULT;
@@ -337,7 +344,7 @@
return(sys_mprotect(start & PAGE_MASK, len & PAGE_MASK, prot));
}
-asmlinkage int
+asmlinkage long
sys32_rt_sigaction(int sig, struct sigaction32 *act,
struct sigaction32 *oact, unsigned int sigsetsize)
{
@@ -396,10 +403,10 @@
}
-extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset,
- size_t sigsetsize);
+extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset,
+ size_t sigsetsize);
-asmlinkage int
+asmlinkage long
sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset,
unsigned int sigsetsize)
{
@@ -454,9 +461,9 @@
return err;
}
-extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);
+extern asmlinkage long sys_statfs(const char * path, struct statfs * buf);
-asmlinkage int
+asmlinkage long
sys32_statfs(const char * path, struct statfs32 *buf)
{
int ret;
@@ -471,9 +478,9 @@
return ret;
}
-extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf);
+extern asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf);
-asmlinkage int
+asmlinkage long
sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
{
int ret;
@@ -540,7 +547,7 @@
extern int do_getitimer(int which, struct itimerval *value);
-asmlinkage int
+asmlinkage long
sys32_getitimer(int which, struct itimerval32 *it)
{
struct itimerval kit;
@@ -555,7 +562,7 @@
extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
-asmlinkage int
+asmlinkage long
sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
{
struct itimerval kin, kout;
@@ -600,7 +607,7 @@
extern struct timezone sys_tz;
extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
-asmlinkage int
+asmlinkage long
sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
{
if (tv) {
@@ -616,7 +623,7 @@
return 0;
}
-asmlinkage int
+asmlinkage long
sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
{
struct timeval ktv;
@@ -634,56 +641,135 @@
return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
}
-struct dirent32 {
- unsigned int d_ino;
- unsigned int d_off;
- unsigned short d_reclen;
- char d_name[NAME_MAX + 1];
+struct linux32_dirent {
+ u32 d_ino;
+ u32 d_off;
+ u16 d_reclen;
+ char d_name[1];
};
-static void
-xlate_dirent(void *dirent64, void *dirent32, long n)
+struct old_linux32_dirent {
+ u32 d_ino;
+ u32 d_offset;
+ u16 d_namlen;
+ char d_name[1];
+};
+
+struct getdents32_callback {
+ struct linux32_dirent * current_dir;
+ struct linux32_dirent * previous;
+ int count;
+ int error;
+};
+
+struct readdir32_callback {
+ struct old_linux32_dirent * dirent;
+ int count;
+};
+
+static int
+filldir32 (void *__buf, const char *name, int namlen, off_t offset, ino_t ino)
{
- long off;
- struct dirent *dirp;
- struct dirent32 *dirp32;
-
- off = 0;
- while (off < n) {
- dirp = (struct dirent *)(dirent64 + off);
- dirp32 = (struct dirent32 *)(dirent32 + off);
- off += dirp->d_reclen;
- dirp32->d_ino = dirp->d_ino;
- dirp32->d_off = (unsigned int)dirp->d_off;
- dirp32->d_reclen = dirp->d_reclen;
- strncpy(dirp32->d_name, dirp->d_name, dirp->d_reclen - ((3 * 4) + 2));
- }
- return;
+ struct linux32_dirent * dirent;
+ struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
+ int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
+
+ buf->error = -EINVAL; /* only used if we fail.. */
+ if (reclen > buf->count)
+ return -EINVAL;
+ dirent = buf->previous;
+ if (dirent)
+ put_user(offset, &dirent->d_off);
+ dirent = buf->current_dir;
+ buf->previous = dirent;
+ put_user(ino, &dirent->d_ino);
+ put_user(reclen, &dirent->d_reclen);
+ copy_to_user(dirent->d_name, name, namlen);
+ put_user(0, dirent->d_name + namlen);
+ ((char *) dirent) += reclen;
+ buf->current_dir = dirent;
+ buf->count -= reclen;
+ return 0;
}
asmlinkage long
-sys32_getdents(unsigned int fd, void * dirent32, unsigned int count)
+sys32_getdents (unsigned int fd, void * dirent, unsigned int count)
{
- long n;
- void *dirent64;
+ struct file * file;
+ struct linux32_dirent * lastdirent;
+ struct getdents32_callback buf;
+ int error;
- dirent64 = (unsigned long)(dirent32 + (sizeof(long) - 1)) & ~(sizeof(long) - 1);
- if ((n = sys_getdents(fd, dirent64, count - (dirent64 - dirent32))) < 0)
- return(n);
- xlate_dirent(dirent64, dirent32, n);
- return(n);
+ error = -EBADF;
+ file = fget(fd);
+ if (!file)
+ goto out;
+
+ buf.current_dir = (struct linux32_dirent *) dirent;
+ buf.previous = NULL;
+ buf.count = count;
+ buf.error = 0;
+
+ lock_kernel();
+ error = vfs_readdir(file, filldir32, &buf);
+ if (error < 0)
+ goto out_putf;
+ error = buf.error;
+ lastdirent = buf.previous;
+ if (lastdirent) {
+ put_user(file->f_pos, &lastdirent->d_off);
+ error = count - buf.count;
+ }
+
+out_putf:
+ unlock_kernel();
+ fput(file);
+out:
+ return error;
}
-asmlinkage int
-sys32_readdir(unsigned int fd, void * dirent32, unsigned int count)
+static int
+fillonedir32 (void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
{
- int n;
- struct dirent dirent64;
+ struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
+ struct old_linux32_dirent * dirent;
- if ((n = old_readdir(fd, &dirent64, count)) < 0)
- return(n);
- xlate_dirent(&dirent64, dirent32, dirent64.d_reclen);
- return(n);
+ if (buf->count)
+ return -EINVAL;
+ buf->count++;
+ dirent = buf->dirent;
+ put_user(ino, &dirent->d_ino);
+ put_user(offset, &dirent->d_offset);
+ put_user(namlen, &dirent->d_namlen);
+ copy_to_user(dirent->d_name, name, namlen);
+ put_user(0, dirent->d_name + namlen);
+ return 0;
+}
+
+asmlinkage long
+sys32_readdir (unsigned int fd, void * dirent, unsigned int count)
+{
+ int error;
+ struct file * file;
+ struct readdir32_callback buf;
+
+ error = -EBADF;
+ file = fget(fd);
+ if (!file)
+ goto out;
+
+ buf.count = 0;
+ buf.dirent = dirent;
+
+ lock_kernel();
+ error = vfs_readdir(file, fillonedir32, &buf);
+ if (error >= 0)
+ error = buf.count;
+ unlock_kernel();
+
+ fput(file);
+out:
+ return error;
}
/*
@@ -696,9 +782,9 @@
*/
#define MAX_SELECT_SECONDS \
((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
-#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
+#define ROUND_UP_TIME(x,y) (((x)+(y)-1)/(y))
-asmlinkage int
+asmlinkage long
sys32_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval32 *tvp32)
{
fd_set_bits fds;
@@ -718,7 +804,7 @@
goto out_nofds;
if ((unsigned long) sec < MAX_SELECT_SECONDS) {
- timeout = ROUND_UP(usec, 1000000/HZ);
+ timeout = ROUND_UP_TIME(usec, 1000000/HZ);
timeout += sec * (unsigned long) HZ;
}
}
@@ -795,13 +881,15 @@
unsigned int tvp;
};
-asmlinkage int old_select(struct sel_arg_struct *arg)
+asmlinkage long
+old_select(struct sel_arg_struct *arg)
{
struct sel_arg_struct a;
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
- return sys32_select(a.n, a.inp, a.outp, a.exp, a.tvp);
+ return sys32_select(a.n, (fd_set *)A(a.inp), (fd_set *)A(a.outp), (fd_set *)A(a.exp),
+ (struct timeval32 *)A(a.tvp));
}
struct timespec32 {
@@ -809,10 +897,9 @@
int tv_nsec;
};
-extern asmlinkage int sys_nanosleep(struct timespec *rqtp,
- struct timespec *rmtp);
+extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-asmlinkage int
+asmlinkage long
sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
{
struct timespec t;
@@ -993,9 +1080,9 @@
int rlim_max;
};
-extern asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim);
+extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
-asmlinkage int
+asmlinkage long
sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
{
struct rlimit r;
@@ -1012,9 +1099,9 @@
return ret;
}
-extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
+extern asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim);
-asmlinkage int
+asmlinkage long
sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
{
struct rlimit r;
@@ -1035,118 +1122,6 @@
return ret;
}
-/* Argument list sizes for sys_socketcall */
-#define AL(x) ((x) * sizeof(u32))
-static unsigned char nas[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
- AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
- AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
-#undef AL
-
-extern asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
-extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr,
- int addrlen);
-extern asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr,
- int *upeer_addrlen);
-extern asmlinkage int sys_getsockname(int fd, struct sockaddr *usockaddr,
- int *usockaddr_len);
-extern asmlinkage int sys_getpeername(int fd, struct sockaddr *usockaddr,
- int *usockaddr_len);
-extern asmlinkage int sys_send(int fd, void *buff, size_t len, unsigned flags);
-extern asmlinkage int sys_sendto(int fd, u32 buff, __kernel_size_t32 len,
- unsigned flags, u32 addr, int addr_len);
-extern asmlinkage int sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
-extern asmlinkage int sys_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
- unsigned flags, u32 addr, u32 addr_len);
-extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
- char *optval, int optlen);
-extern asmlinkage int sys_getsockopt(int fd, int level, int optname,
- u32 optval, u32 optlen);
-
-extern asmlinkage int sys_socket(int family, int type, int protocol);
-extern asmlinkage int sys_socketpair(int family, int type, int protocol,
- int usockvec[2]);
-extern asmlinkage int sys_shutdown(int fd, int how);
-extern asmlinkage int sys_listen(int fd, int backlog);
-
-asmlinkage int sys32_socketcall(int call, u32 *args)
-{
- int i, ret;
- u32 a[6];
- u32 a0,a1;
-
- if (call<SYS_SOCKET||call>SYS_RECVMSG)
- return -EINVAL;
- if (copy_from_user(a, args, nas[call]))
- return -EFAULT;
- a0=a[0];
- a1=a[1];
-
- switch(call)
- {
- case SYS_SOCKET:
- ret = sys_socket(a0, a1, a[2]);
- break;
- case SYS_BIND:
- ret = sys_bind(a0, (struct sockaddr *)A(a1), a[2]);
- break;
- case SYS_CONNECT:
- ret = sys_connect(a0, (struct sockaddr *)A(a1), a[2]);
- break;
- case SYS_LISTEN:
- ret = sys_listen(a0, a1);
- break;
- case SYS_ACCEPT:
- ret = sys_accept(a0, (struct sockaddr *)A(a1),
- (int *)A(a[2]));
- break;
- case SYS_GETSOCKNAME:
- ret = sys_getsockname(a0, (struct sockaddr *)A(a1),
- (int *)A(a[2]));
- break;
- case SYS_GETPEERNAME:
- ret = sys_getpeername(a0, (struct sockaddr *)A(a1),
- (int *)A(a[2]));
- break;
- case SYS_SOCKETPAIR:
- ret = sys_socketpair(a0, a1, a[2], (int *)A(a[3]));
- break;
- case SYS_SEND:
- ret = sys_send(a0, (void *)A(a1), a[2], a[3]);
- break;
- case SYS_SENDTO:
- ret = sys_sendto(a0, a1, a[2], a[3], a[4], a[5]);
- break;
- case SYS_RECV:
- ret = sys_recv(a0, (void *)A(a1), a[2], a[3]);
- break;
- case SYS_RECVFROM:
- ret = sys_recvfrom(a0, a1, a[2], a[3], a[4], a[5]);
- break;
- case SYS_SHUTDOWN:
- ret = sys_shutdown(a0,a1);
- break;
- case SYS_SETSOCKOPT:
- ret = sys_setsockopt(a0, a1, a[2], (char *)A(a[3]),
- a[4]);
- break;
- case SYS_GETSOCKOPT:
- ret = sys_getsockopt(a0, a1, a[2], a[3], a[4]);
- break;
- case SYS_SENDMSG:
- ret = sys32_sendmsg(a0, (struct msghdr32 *)A(a1),
- a[2]);
- break;
- case SYS_RECVMSG:
- ret = sys32_recvmsg(a0, (struct msghdr32 *)A(a1),
- a[2]);
- break;
- default:
- ret = EINVAL;
- break;
- }
- return ret;
-}
-
/*
* Declare the IA32 version of the msghdr
*/
@@ -1169,13 +1144,13 @@
if (!access_ok(VERIFY_READ, mp32, sizeof(*mp32)))
return(-EFAULT);
__get_user(i, &mp32->msg_name);
- mp->msg_name = (void *)i;
+ mp->msg_name = (void *)A(i);
__get_user(mp->msg_namelen, &mp32->msg_namelen);
__get_user(i, &mp32->msg_iov);
- mp->msg_iov = (struct iov *)i;
+ mp->msg_iov = (struct iovec *)A(i);
__get_user(mp->msg_iovlen, &mp32->msg_iovlen);
__get_user(i, &mp32->msg_control);
- mp->msg_control = (void *)i;
+ mp->msg_control = (void *)A(i);
__get_user(mp->msg_controllen, &mp32->msg_controllen);
__get_user(mp->msg_flags, &mp32->msg_flags);
return(0);
@@ -1221,7 +1196,7 @@
iov32 = (struct iovec32 *)iov;
for (ct = m->msg_iovlen; ct-- > 0; ) {
iov[ct].iov_len = (__kernel_size_t)iov32[ct].iov_len;
- iov[ct].iov_base = (void *)iov32[ct].iov_base;
+ iov[ct].iov_base = (void *) A(iov32[ct].iov_base);
err += iov[ct].iov_len;
}
out:
@@ -1246,7 +1221,7 @@
* BSD sendmsg interface
*/
-asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *msg, unsigned flags)
+int sys32_sendmsg(int fd, struct msghdr32 *msg, unsigned flags)
{
struct socket *sock;
char address[MAX_SOCK_ADDR];
@@ -1325,7 +1300,8 @@
* BSD recvmsg interface
*/
-asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *msg, unsigned int flags)
+int
+sys32_recvmsg (int fd, struct msghdr32 *msg, unsigned int flags)
{
struct socket *sock;
struct iovec iovstack[UIO_FASTIOV];
@@ -1407,6 +1383,118 @@
return err;
}
+/* Argument list sizes for sys_socketcall */
+#define AL(x) ((x) * sizeof(u32))
+static unsigned char nas[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
+ AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
+ AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
+#undef AL
+
+extern asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
+extern asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr,
+ int addrlen);
+extern asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr,
+ int *upeer_addrlen);
+extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr,
+ int *usockaddr_len);
+extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr,
+ int *usockaddr_len);
+extern asmlinkage long sys_send(int fd, void *buff, size_t len, unsigned flags);
+extern asmlinkage long sys_sendto(int fd, u32 buff, __kernel_size_t32 len,
+ unsigned flags, u32 addr, int addr_len);
+extern asmlinkage long sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
+extern asmlinkage long sys_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
+ unsigned flags, u32 addr, u32 addr_len);
+extern asmlinkage long sys_setsockopt(int fd, int level, int optname,
+ char *optval, int optlen);
+extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
+ u32 optval, u32 optlen);
+
+extern asmlinkage long sys_socket(int family, int type, int protocol);
+extern asmlinkage long sys_socketpair(int family, int type, int protocol,
+ int usockvec[2]);
+extern asmlinkage long sys_shutdown(int fd, int how);
+extern asmlinkage long sys_listen(int fd, int backlog);
+
+asmlinkage long sys32_socketcall(int call, u32 *args)
+{
+ int ret;
+ u32 a[6];
+ u32 a0,a1;
+
+ if (call<SYS_SOCKET||call>SYS_RECVMSG)
+ return -EINVAL;
+ if (copy_from_user(a, args, nas[call]))
+ return -EFAULT;
+ a0=a[0];
+ a1=a[1];
+
+ switch(call)
+ {
+ case SYS_SOCKET:
+ ret = sys_socket(a0, a1, a[2]);
+ break;
+ case SYS_BIND:
+ ret = sys_bind(a0, (struct sockaddr *)A(a1), a[2]);
+ break;
+ case SYS_CONNECT:
+ ret = sys_connect(a0, (struct sockaddr *)A(a1), a[2]);
+ break;
+ case SYS_LISTEN:
+ ret = sys_listen(a0, a1);
+ break;
+ case SYS_ACCEPT:
+ ret = sys_accept(a0, (struct sockaddr *)A(a1),
+ (int *)A(a[2]));
+ break;
+ case SYS_GETSOCKNAME:
+ ret = sys_getsockname(a0, (struct sockaddr *)A(a1),
+ (int *)A(a[2]));
+ break;
+ case SYS_GETPEERNAME:
+ ret = sys_getpeername(a0, (struct sockaddr *)A(a1),
+ (int *)A(a[2]));
+ break;
+ case SYS_SOCKETPAIR:
+ ret = sys_socketpair(a0, a1, a[2], (int *)A(a[3]));
+ break;
+ case SYS_SEND:
+ ret = sys_send(a0, (void *)A(a1), a[2], a[3]);
+ break;
+ case SYS_SENDTO:
+ ret = sys_sendto(a0, a1, a[2], a[3], a[4], a[5]);
+ break;
+ case SYS_RECV:
+ ret = sys_recv(a0, (void *)A(a1), a[2], a[3]);
+ break;
+ case SYS_RECVFROM:
+ ret = sys_recvfrom(a0, a1, a[2], a[3], a[4], a[5]);
+ break;
+ case SYS_SHUTDOWN:
+ ret = sys_shutdown(a0,a1);
+ break;
+ case SYS_SETSOCKOPT:
+ ret = sys_setsockopt(a0, a1, a[2], (char *)A(a[3]),
+ a[4]);
+ break;
+ case SYS_GETSOCKOPT:
+ ret = sys_getsockopt(a0, a1, a[2], a[3], a[4]);
+ break;
+ case SYS_SENDMSG:
+ ret = sys32_sendmsg(a0, (struct msghdr32 *)A(a1),
+ a[2]);
+ break;
+ case SYS_RECVMSG:
+ ret = sys32_recvmsg(a0, (struct msghdr32 *)A(a1),
+ a[2]);
+ break;
+ default:
+ ret = EINVAL;
+ break;
+ }
+ return ret;
+}
+
/*
* sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
*
@@ -1601,7 +1689,7 @@
static int
do_sys32_msgctl (int first, int second, void *uptr)
{
- int err, err2;
+ int err = -EINVAL, err2;
struct msqid_ds m;
struct msqid64_ds m64;
struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
@@ -1632,7 +1720,7 @@
case MSG_STAT:
old_fs = get_fs ();
set_fs (KERNEL_DS);
- err = sys_msgctl (first, second, &m64);
+ err = sys_msgctl (first, second, (void *) &m64);
set_fs (old_fs);
err2 = put_user (m64.msg_perm.key, &up->msg_perm.key);
err2 |= __put_user(m64.msg_perm.uid, &up->msg_perm.uid);
@@ -1713,7 +1801,7 @@
case SHM_STAT:
old_fs = get_fs ();
set_fs (KERNEL_DS);
- err = sys_shmctl (first, second, &s64);
+ err = sys_shmctl (first, second, (void *) &s64);
set_fs (old_fs);
if (err < 0)
break;
@@ -1741,7 +1829,7 @@
case SHM_INFO:
old_fs = get_fs ();
set_fs (KERNEL_DS);
- err = sys_shmctl (first, second, &si);
+ err = sys_shmctl (first, second, (void *)&si);
set_fs (old_fs);
if (err < 0)
break;
@@ -1761,7 +1849,7 @@
return err;
}
-asmlinkage int
+asmlinkage long
sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
{
int version, err;
@@ -1886,10 +1974,10 @@
return err;
}
-extern asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr,
+extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr,
int options, struct rusage * ru);
-asmlinkage int
+asmlinkage long
sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options,
struct rusage32 *ru)
{
@@ -1911,17 +1999,17 @@
}
}
-asmlinkage int
+asmlinkage long
sys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options)
{
return sys32_wait4(pid, stat_addr, options, NULL);
}
-extern asmlinkage int
+extern asmlinkage long
sys_getrusage(int who, struct rusage *ru);
-asmlinkage int
+asmlinkage long
sys32_getrusage(int who, struct rusage32 *ru)
{
struct rusage r;
@@ -2417,9 +2505,9 @@
/* 32-bit timeval and related flotsam. */
-extern asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
+extern asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on);
-asmlinkage int
+asmlinkage long
sys32_ioperm(u32 from, u32 num, int on)
{
return sys_ioperm((unsigned long)from, (unsigned long)num, on);
@@ -2491,10 +2579,10 @@
__kernel_time_t32 dqb_itime;
};
-extern asmlinkage int sys_quotactl(int cmd, const char *special, int id,
+extern asmlinkage long sys_quotactl(int cmd, const char *special, int id,
caddr_t addr);
-asmlinkage int
+asmlinkage long
sys32_quotactl(int cmd, const char *special, int id, unsigned long addr)
{
int cmds = cmd >> SUBCMDSHIFT;
@@ -2538,13 +2626,13 @@
return err;
}
-extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
+extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
struct utimbuf32 {
__kernel_time_t32 actime, modtime;
};
-asmlinkage int
+asmlinkage long
sys32_utime(char * filename, struct utimbuf32 *times)
{
struct utimbuf t;
@@ -2628,10 +2716,10 @@
__put_user(*fdset, ufdset);
}
-extern asmlinkage int sys_sysfs(int option, unsigned long arg1,
+extern asmlinkage long sys_sysfs(int option, unsigned long arg1,
unsigned long arg2);
-asmlinkage int
+asmlinkage long
sys32_sysfs(int option, u32 arg1, u32 arg2)
{
return sys_sysfs(option, arg1, arg2);
@@ -2729,7 +2817,7 @@
#define SMBFS_NAME "smbfs"
#define NCPFS_NAME "ncpfs"
-asmlinkage int
+asmlinkage long
sys32_mount(char *dev_name, char *dir_name, char *type,
unsigned long new_flags, u32 data)
{
@@ -2803,9 +2891,9 @@
char _f[22];
};
-extern asmlinkage int sys_sysinfo(struct sysinfo *info);
+extern asmlinkage long sys_sysinfo(struct sysinfo *info);
-asmlinkage int
+asmlinkage long
sys32_sysinfo(struct sysinfo32 *info)
{
struct sysinfo s;
@@ -2831,10 +2919,10 @@
return ret;
}
-extern asmlinkage int sys_sched_rr_get_interval(pid_t pid,
+extern asmlinkage long sys_sched_rr_get_interval(pid_t pid,
struct timespec *interval);
-asmlinkage int
+asmlinkage long
sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
{
struct timespec t;
@@ -2850,10 +2938,10 @@
return ret;
}
-extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set,
+extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set,
old_sigset_t *oset);
-asmlinkage int
+asmlinkage long
sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
{
old_sigset_t s;
@@ -2869,9 +2957,9 @@
return 0;
}
-extern asmlinkage int sys_sigpending(old_sigset_t *set);
+extern asmlinkage long sys_sigpending(old_sigset_t *set);
-asmlinkage int
+asmlinkage long
sys32_sigpending(old_sigset_t32 *set)
{
old_sigset_t s;
@@ -2885,9 +2973,9 @@
return ret;
}
-extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
+extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
-asmlinkage int
+asmlinkage long
sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize)
{
sigset_t s;
@@ -2990,11 +3078,11 @@
return d;
}
-extern asmlinkage int
+extern asmlinkage long
sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
const struct timespec *uts, size_t sigsetsize);
-asmlinkage int
+asmlinkage long
sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
struct timespec32 *uts, __kernel_size_t32 sigsetsize)
{
@@ -3031,10 +3119,10 @@
return ret;
}
-extern asmlinkage int
+extern asmlinkage long
sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
-asmlinkage int
+asmlinkage long
sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
{
siginfo_t info;
@@ -3052,9 +3140,9 @@
return ret;
}
-extern asmlinkage int sys_setreuid(uid_t ruid, uid_t euid);
+extern asmlinkage long sys_setreuid(uid_t ruid, uid_t euid);
-asmlinkage int sys32_setreuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid)
+asmlinkage long sys32_setreuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid)
{
uid_t sruid, seuid;
@@ -3063,9 +3151,9 @@
return sys_setreuid(sruid, seuid);
}
-extern asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
+extern asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
-asmlinkage int
+asmlinkage long
sys32_setresuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid,
__kernel_uid_t32 suid)
{
@@ -3077,9 +3165,9 @@
return sys_setresuid(sruid, seuid, ssuid);
}
-extern asmlinkage int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
+extern asmlinkage long sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
-asmlinkage int
+asmlinkage long
sys32_getresuid(__kernel_uid_t32 *ruid, __kernel_uid_t32 *euid,
__kernel_uid_t32 *suid)
{
@@ -3095,9 +3183,9 @@
return ret;
}
-extern asmlinkage int sys_setregid(gid_t rgid, gid_t egid);
+extern asmlinkage long sys_setregid(gid_t rgid, gid_t egid);
-asmlinkage int
+asmlinkage long
sys32_setregid(__kernel_gid_t32 rgid, __kernel_gid_t32 egid)
{
gid_t srgid, segid;
@@ -3107,9 +3195,9 @@
return sys_setregid(srgid, segid);
}
-extern asmlinkage int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
+extern asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
-asmlinkage int
+asmlinkage long
sys32_setresgid(__kernel_gid_t32 rgid, __kernel_gid_t32 egid,
__kernel_gid_t32 sgid)
{
@@ -3121,9 +3209,9 @@
return sys_setresgid(srgid, segid, ssgid);
}
-extern asmlinkage int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
+extern asmlinkage long sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
-asmlinkage int
+asmlinkage long
sys32_getresgid(__kernel_gid_t32 *rgid, __kernel_gid_t32 *egid,
__kernel_gid_t32 *sgid)
{
@@ -3142,9 +3230,9 @@
return ret;
}
-extern asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist);
+extern asmlinkage long sys_getgroups(int gidsetsize, gid_t *grouplist);
-asmlinkage int
+asmlinkage long
sys32_getgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
{
gid_t gl[NGROUPS];
@@ -3161,9 +3249,9 @@
return ret;
}
-extern asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist);
+extern asmlinkage long sys_setgroups(int gidsetsize, gid_t *grouplist);
-asmlinkage int
+asmlinkage long
sys32_setgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
{
gid_t gl[NGROUPS];
@@ -3607,7 +3695,7 @@
kmsg->msg_control = (void *) orig_cmsg_uptr;
}
-asmlinkage int
+asmlinkage long
sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
{
struct socket *sock;
@@ -3655,7 +3743,7 @@
return err;
}
-asmlinkage int
+asmlinkage long
sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
{
struct iovec iovstack[UIO_FASTIOV];
@@ -3746,7 +3834,7 @@
extern void check_pending(int signum);
-asmlinkage int
+asmlinkage long
sys32_sigaction (int sig, struct old_sigaction32 *act,
struct old_sigaction32 *oact)
{
@@ -3791,21 +3879,21 @@
return sys_create_module(name_user, (size_t)size);
}
-extern asmlinkage int sys_init_module(const char *name_user,
+extern asmlinkage long sys_init_module(const char *name_user,
struct module *mod_user);
/* Hey, when you're trying to init module, take time and prepare us a nice 64bit
* module structure, even if from 32bit modutils... Why to pollute kernel... :))
*/
-asmlinkage int
+asmlinkage long
sys32_init_module(const char *name_user, struct module *mod_user)
{
return sys_init_module(name_user, mod_user);
}
-extern asmlinkage int sys_delete_module(const char *name_user);
+extern asmlinkage long sys_delete_module(const char *name_user);
-asmlinkage int
+asmlinkage long
sys32_delete_module(const char *name_user)
{
return sys_delete_module(name_user);
@@ -4080,7 +4168,7 @@
return error;
}
-asmlinkage int
+asmlinkage long
sys32_query_module(char *name_user, int which, char *buf,
__kernel_size_t32 bufsize, u32 ret)
{
@@ -4148,9 +4236,9 @@
char name[60];
};
-extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
+extern asmlinkage long sys_get_kernel_syms(struct kernel_sym *table);
-asmlinkage int
+asmlinkage long
sys32_get_kernel_syms(struct kernel_sym32 *table)
{
int len, i;
@@ -4182,19 +4270,19 @@
return -ENOSYS;
}
-asmlinkage int
+asmlinkage long
sys32_init_module(const char *name_user, struct module *mod_user)
{
return -ENOSYS;
}
-asmlinkage int
+asmlinkage long
sys32_delete_module(const char *name_user)
{
return -ENOSYS;
}
-asmlinkage int
+asmlinkage long
sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
size_t *ret)
{
@@ -4206,7 +4294,7 @@
return -ENOSYS;
}
-asmlinkage int
+asmlinkage long
sys32_get_kernel_syms(struct kernel_sym *table)
{
return -ENOSYS;
@@ -4422,7 +4510,7 @@
return err;
}
-extern asmlinkage int sys_nfsservctl(int cmd, void *arg, void *resp);
+extern asmlinkage long sys_nfsservctl(int cmd, void *arg, void *resp);
int asmlinkage
sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
@@ -4493,9 +4581,9 @@
return err;
}
-asmlinkage int sys_utimes(char *, struct timeval *);
+asmlinkage long sys_utimes(char *, struct timeval *);
-asmlinkage int
+asmlinkage long
sys32_utimes(char *filename, struct timeval32 *tvs)
{
char *kfilename;
@@ -4523,7 +4611,7 @@
}
/* These are here just in case some old ia32 binary calls it. */
-asmlinkage int
+asmlinkage long
sys32_pause(void)
{
current->state = TASK_INTERRUPTIBLE;
@@ -4532,19 +4620,19 @@
}
/* PCI config space poking. */
-extern asmlinkage int sys_pciconfig_read(unsigned long bus,
+extern asmlinkage long sys_pciconfig_read(unsigned long bus,
unsigned long dfn,
unsigned long off,
unsigned long len,
unsigned char *buf);
-extern asmlinkage int sys_pciconfig_write(unsigned long bus,
+extern asmlinkage long sys_pciconfig_write(unsigned long bus,
unsigned long dfn,
unsigned long off,
unsigned long len,
unsigned char *buf);
-asmlinkage int
+asmlinkage long
sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
{
return sys_pciconfig_read((unsigned long) bus,
@@ -4554,7 +4642,7 @@
(unsigned char *)AA(ubuf));
}
-asmlinkage int
+asmlinkage long
sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
{
return sys_pciconfig_write((unsigned long) bus,
@@ -4564,11 +4652,11 @@
(unsigned char *)AA(ubuf));
}
-extern asmlinkage int sys_prctl(int option, unsigned long arg2,
+extern asmlinkage long sys_prctl(int option, unsigned long arg2,
unsigned long arg3, unsigned long arg4,
unsigned long arg5);
-asmlinkage int
+asmlinkage long
sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
{
return sys_prctl(option,
@@ -4579,9 +4667,9 @@
}
-extern asmlinkage int sys_newuname(struct new_utsname * name);
+extern asmlinkage long sys_newuname(struct new_utsname * name);
-asmlinkage int
+asmlinkage long
sys32_newuname(struct new_utsname * name)
{
int ret = sys_newuname(name);
@@ -4617,9 +4705,9 @@
}
-extern asmlinkage int sys_personality(unsigned long);
+extern asmlinkage long sys_personality(unsigned long);
-asmlinkage int
+asmlinkage long
sys32_personality(unsigned long personality)
{
int ret;
@@ -4636,7 +4724,7 @@
extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset,
size_t count);
-asmlinkage int
+asmlinkage long
sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
{
mm_segment_t old_fs = get_fs();
@@ -4673,7 +4761,7 @@
extern int do_adjtimex(struct timex *);
-asmlinkage int
+asmlinkage long
sys32_adjtimex(struct timex32 *utp)
{
struct timex txc;
diff -urN linux-davidm/arch/ia64/kernel/Makefile linux-2.3.99-pre6-lia/arch/ia64/kernel/Makefile
--- linux-davidm/arch/ia64/kernel/Makefile Fri Apr 21 15:21:24 2000
+++ linux-2.3.99-pre6-lia/arch/ia64/kernel/Makefile Thu May 25 19:44:00 2000
@@ -15,11 +15,10 @@
all: kernel.o head.o init_task.o
O_TARGET := kernel.o
-O_OBJS := acpi.o entry.o gate.o efi.o efi_stub.o irq.o irq_ia64.o irq_sapic.o ivt.o \
- pal.o pci-dma.o process.o perfmon.o ptrace.o sal.o sal_stub.o semaphore.o setup.o \
+O_OBJS := acpi.o entry.o gate.o efi.o efi_stub.o irq.o irq_ia64.o irq_sapic.o ivt.o \
+ pal.o pci-dma.o process.o perfmon.o ptrace.o sal.o semaphore.o setup.o \
signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o
-#O_OBJS := fpreg.o
-#OX_OBJS := ia64_ksyms.o
+OX_OBJS := ia64_ksyms.o
ifdef CONFIG_IA64_GENERIC
O_OBJS += machvec.o
diff -urN linux-davidm/arch/ia64/kernel/acpi.c linux-2.3.99-pre6-lia/arch/ia64/kernel/acpi.c
--- linux-davidm/arch/ia64/kernel/acpi.c Fri Apr 21 15:21:24 2000
+++ linux-2.3.99-pre6-lia/arch/ia64/kernel/acpi.c Thu May 25 22:56:31 2000
@@ -89,16 +89,16 @@
#ifdef CONFIG_IA64_DIG
acpi_entry_iosapic_t *iosapic = (acpi_entry_iosapic_t *) p;
unsigned int ver, v;
- int l, pins;
+ int l, max_pin;
ver = iosapic_version(iosapic->address);
- pins = (ver >> 16) & 0xff;
+ max_pin = (ver >> 16) & 0xff;
printk("IOSAPIC Version %x.%x: address 0x%lx IRQs 0x%x - 0x%x\n",
(ver & 0xf0) >> 4, (ver & 0x0f), iosapic->address,
- iosapic->irq_base, iosapic->irq_base + pins);
+ iosapic->irq_base, iosapic->irq_base + max_pin);
- for (l = 0; l < pins; l++) {
+ for (l = 0; l <= max_pin; l++) {
v = iosapic->irq_base + l;
if (v < 16)
v = isa_irq_to_vector(v);
@@ -110,7 +110,7 @@
iosapic_addr(v) = (unsigned long) ioremap(iosapic->address, 0);
iosapic_baseirq(v) = iosapic->irq_base;
}
- iosapic_init(iosapic->address);
+ iosapic_init(iosapic->address, iosapic->irq_base);
#endif
}
diff -urN linux-davidm/arch/ia64/kernel/efi_stub.S linux-2.3.99-pre6-lia/arch/ia64/kernel/efi_stub.S
--- linux-davidm/arch/ia64/kernel/efi_stub.S Sun Feb 6 18:42:40 2000
+++ linux-2.3.99-pre6-lia/arch/ia64/kernel/efi_stub.S Thu May 25 22:56:41 2000
@@ -1,7 +1,8 @@
/*
* EFI call stub.
*
- * Copyright (C) 1999 David Mosberger <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2000 Hewlett-Packard Co
+ * Copyright (C) 1999-2000 David Mosberger <davidm@hpl.hp.com>
*
* This stub allows us to make EFI calls in physical mode with interrupts
* turned off. We need this because we can't call SetVirtualMap() until
@@ -30,6 +31,7 @@
(IA64_PSR_BN)
#include <asm/processor.h>
+#include <asm/asmmacro.h>
.text
.psr abi64
@@ -44,8 +46,7 @@
* Inputs:
* r16 = new psr to establish
*/
- .proc switch_mode
-switch_mode:
+ENTRY(switch_mode)
{
alloc r2=ar.pfs,0,0,0,0
rsm psr.i | psr.ic // disable interrupts and interrupt collection
@@ -83,7 +84,7 @@
;;
1: mov rp=r14
br.ret.sptk.few rp
- .endp switch_mode
+END(switch_mode)
/*
* Inputs:
@@ -94,13 +95,12 @@
* r8 = EFI_STATUS returned by called function
*/
- .global efi_call_phys
- .proc efi_call_phys
-efi_call_phys:
-
- alloc loc0=ar.pfs,8,5,7,0
+GLOBAL_ENTRY(efi_call_phys)
+ UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8))
+ alloc loc1=ar.pfs,8,5,7,0
ld8 r2=[in0],8 // load EFI function's entry point
- mov loc1=rp
+ mov loc0=rp
+ UNW(.body)
;;
mov loc2=gp // save global pointer
mov loc4=ar.rsc // save RSE configuration
@@ -133,9 +133,8 @@
br.call.sptk.few rp=switch_mode // return to virtual mode
.ret2:
mov ar.rsc=loc4 // restore RSE configuration
- mov ar.pfs=loc0
- mov rp=loc1
+ mov ar.pfs=loc1
+ mov rp=loc0
mov gp=loc2
br.ret.sptk.few rp
-
- .endp efi_call_phys
+END(efi_call_phys)
diff -urN linux-davidm/arch/ia64/kernel/entry.S linux-2.3.99-pre6-lia/arch/ia64/kernel/entry.S
--- linux-davidm/arch/ia64/kernel/entry.S Thu May 25 23:22:10 2000
+++ linux-2.3.99-pre6-lia/arch/ia64/kernel/entry.S Thu May 25 22:57:38 2000
@@ -13,8 +13,6 @@
/*
* Global (preserved) predicate usage on syscall entry/exit path:
*
- *
- * pEOI: See entry.h.
* pKern: See entry.h.
* pSys: See entry.h.
* pNonSys: !pSys
@@ -30,6 +28,7 @@
#include <asm/offsets.h>
#include <asm/processor.h>
#include <asm/unistd.h>
+#include <asm/asmmacro.h>
#include "entry.h"
@@ -42,11 +41,11 @@
* execve() is special because in case of success, we need to
* setup a null register window frame.
*/
- .align 16
- .proc ia64_execve
-ia64_execve:
- alloc loc0=ar.pfs,3,2,4,0
- mov loc1=rp
+ENTRY(ia64_execve)
+ UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3))
+ alloc loc1=ar.pfs,3,2,4,0
+ mov loc0=rp
+ UNW(.body)
mov out0=in0 // filename
;; // stop bit between alloc and call
mov out1=in1 // argv
@@ -54,25 +53,22 @@
add out3\x16,sp // regs
br.call.sptk.few rp=sys_execve
.ret0: cmp4.ge p6,p0=r8,r0
- mov ar.pfs=loc0 // restore ar.pfs
+ mov ar.pfs=loc1 // restore ar.pfs
;;
(p6) mov ar.pfs=r0 // clear ar.pfs in case of success
sxt4 r8=r8 // return 64-bit result
- mov rp=loc1
+ mov rp=loc0
br.ret.sptk.few rp
- .endp ia64_execve
+END(ia64_execve)
- .align 16
- .global sys_clone
- .proc sys_clone
-sys_clone:
+GLOBAL_ENTRY(sys_clone)
+ UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2))
alloc r16=ar.pfs,2,2,3,0;;
- movl r28\x1f
- mov loc1=rp
- br.cond.sptk.many save_switch_stack
-1:
- mov loc0=r16 // save ar.pfs across do_fork
+ mov loc0=rp
+ DO_SAVE_SWITCH_STACK
+ mov loc1=r16 // save ar.pfs across do_fork
+ UNW(.body)
adds out2=IA64_SWITCH_STACK_SIZE+16,sp
adds r2=IA64_SWITCH_STACK_SIZE+IA64_PT_REGS_R12_OFFSET+16,sp
cmp.eq p8,p9=in1,r0 // usp = 0?
@@ -82,24 +78,22 @@
(p9) mov out1=in1
br.call.sptk.few rp=do_fork
.ret1:
- mov ar.pfs=loc0
+ mov ar.pfs=loc1
+ UNW(.restore sp)
adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
- mov rp=loc1
+ mov rp=loc0
;;
br.ret.sptk.many rp
- .endp sys_clone
+END(sys_clone)
/*
- * prev_task <- switch_to(struct task_struct *next)
+ * prev_task <- ia64_switch_to(struct task_struct *next)
*/
- .align 16
- .global ia64_switch_to
- .proc ia64_switch_to
-ia64_switch_to:
+GLOBAL_ENTRY(ia64_switch_to)
+ UNW(.prologue)
alloc r16=ar.pfs,1,0,0,0
- movl r28\x1f
- br.cond.sptk.many save_switch_stack
-1:
+ DO_SAVE_SWITCH_STACK
+ UNW(.body)
// disable interrupts to ensure atomicity for next few instructions:
mov r17=psr // M-unit
;;
@@ -126,63 +120,58 @@
movl r28\x1f
br.cond.sptk.many load_switch_stack
-1:
+1: UNW(.restore sp)
+ adds sp=IA64_SWITCH_STACK_SIZE,sp // pop switch_stack
br.ret.sptk.few rp
- .endp ia64_switch_to
+END(ia64_switch_to)
/*
* Like save_switch_stack, but also save the stack frame that is active
* at the time this function is called.
*/
- .align 16
- .proc save_switch_stack_with_current_frame
-save_switch_stack_with_current_frame:
-1: {
- alloc r16=ar.pfs,0,0,0,0 // pass ar.pfs to save_switch_stack
- mov r28=ip
- }
- ;;
- adds r28\x1f-1b,r28
- br.cond.sptk.many save_switch_stack
-1: br.ret.sptk.few rp
- .endp save_switch_stack_with_current_frame
+ENTRY(save_switch_stack_with_current_frame)
+ UNW(.prologue)
+ alloc r16=ar.pfs,0,0,0,0 // pass ar.pfs to save_switch_stack
+ DO_SAVE_SWITCH_STACK
+ br.ret.sptk.few rp
+END(save_switch_stack_with_current_frame)
/*
* Note that interrupts are enabled during save_switch_stack and
* load_switch_stack. This means that we may get an interrupt with
* "sp" pointing to the new kernel stack while ar.bspstore is still
* pointing to the old kernel backing store area. Since ar.rsc,
* ar.rnat, ar.bsp, and ar.bspstore are all preserved by interrupts,
- * this is not a problem.
+ * this is not a problem. Also, we don't need to specify unwind
+ * information for preserved registers that are not modified in
+ * save_switch_stack as the right unwind information is already
+ * specified at the call-site of save_switch_stack.
*/
/*
* save_switch_stack:
* - r16 holds ar.pfs
- * - r28 holds address to return to
+ * - b7 holds address to return to
* - rp (b0) holds return address to save
*/
- .align 16
- .global save_switch_stack
- .proc save_switch_stack
-save_switch_stack:
+GLOBAL_ENTRY(save_switch_stack)
+ UNW(.prologue)
+ UNW(.altrp b7)
flushrs // flush dirty regs to backing store (must be first in insn group)
mov r17=ar.unat // preserve caller's
- adds r2=-IA64_SWITCH_STACK_SIZE+16,sp // r2 = &sw->caller_unat
+ adds r2\x16,sp // r2 = &sw->caller_unat
;;
mov r18=ar.fpsr // preserve fpsr
mov ar.rsc=r0 // put RSE in mode: enforced lazy, little endian, pl 0
;;
mov r19=ar.rnat
- adds r3=-IA64_SWITCH_STACK_SIZE+24,sp // r3 = &sw->ar_fpsr
-
- // Note: the instruction ordering is important here: we can't
- // store anything to the switch stack before sp is updated
- // as otherwise an interrupt might overwrite the memory!
- adds sp=-IA64_SWITCH_STACK_SIZE,sp
+ adds r3$,sp // r3 = &sw->ar_fpsr
;;
+ .savesp ar.unat,SW(CALLER_UNAT)
st8 [r2]=r17,16
+ .savesp ar.fpsr,SW(AR_FPSR)
st8 [r3]=r18,24
;;
+ UNW(.body)
stf.spill [r2]ò,32
stf.spill [r3]ó,32
mov r21°
@@ -259,16 +248,17 @@
st8 [r3]=r21 // save predicate registers
mov ar.rsc=3 // put RSE back into eager mode, pl 0
br.cond.sptk.few b7
- .endp save_switch_stack
+END(save_switch_stack)
/*
* load_switch_stack:
- * - r28 holds address to return to
+ * - b7 holds address to return to
*/
- .align 16
- .proc load_switch_stack
-load_switch_stack:
+ENTRY(load_switch_stack)
+ UNW(.prologue)
+ UNW(.altrp b7)
invala // invalidate ALAT
+ UNW(.body)
adds r2=IA64_SWITCH_STACK_B0_OFFSET+16,sp // get pointer to switch_stack.b0
mov ar.rsc=r0 // put RSE into enforced lazy mode
adds r3=IA64_SWITCH_STACK_B0_OFFSET+24,sp // get pointer to switch_stack.b1
@@ -360,14 +350,10 @@
mov ar.unat=r18 // restore caller's unat
mov ar.fpsr=r19 // restore fpsr
mov ar.rsc=3 // put RSE back into eager mode, pl 0
- adds sp=IA64_SWITCH_STACK_SIZE,sp // pop switch_stack
br.cond.sptk.few b7
- .endp load_switch_stack
+END(load_switch_stack)
- .align 16
- .global __ia64_syscall
- .proc __ia64_syscall
-__ia64_syscall:
+GLOBAL_ENTRY(__ia64_syscall)
.regstk 6,0,0,0
mov r15=in5 // put syscall number in place
break __BREAK_SYSCALL
@@ -377,30 +363,30 @@
(p6) st4 [r2]=r8
(p6) mov r8=-1
br.ret.sptk.few rp
- .endp __ia64_syscall
+END(__ia64_syscall)
//
// We invoke syscall_trace through this intermediate function to
// ensure that the syscall input arguments are not clobbered. We
// also use it to preserve b6, which contains the syscall entry point.
//
- .align 16
- .global invoke_syscall_trace
- .proc invoke_syscall_trace
-invoke_syscall_trace:
- alloc loc0=ar.pfs,8,3,0,0
+GLOBAL_ENTRY(invoke_syscall_trace)
+ UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8))
+ alloc loc1=ar.pfs,8,3,0,0
;; // WAW on CFM at the br.call
- mov loc1=rp
+ mov loc0=rp
+ .fframe IA64_SWITCH_STACK_SIZE
+ adds sp=-IA64_SWITCH_STACK_SIZE,sp
br.call.sptk.many rp=save_switch_stack_with_current_frame // must preserve b6!!
.ret2: mov loc2¶
br.call.sptk.few rp=syscall_trace
.ret3: adds sp=IA64_SWITCH_STACK_SIZE,sp // drop switch_stack frame
- mov rp=loc1
- mov ar.pfs=loc0
+ mov rp=loc0
+ mov ar.pfs=loc1
mov b6=loc2
;;
br.ret.sptk.few rp
- .endp invoke_syscall_trace
+END(invoke_syscall_trace)
//
// Invoke a system call, but do some tracing before and after the call.
@@ -414,19 +400,19 @@
//
.global ia64_trace_syscall
.global ia64_strace_leave_kernel
- .global ia64_strace_clear_r8
- .proc ia64_strace_clear_r8
-ia64_strace_clear_r8: // this is where we return after cloning when PF_TRACESYS is on
+GLOBAL_ENTRY(ia64_strace_clear_r8)
+ // this is where we return after cloning when PF_TRACESYS is on
+ PT_REGS_UNWIND_INFO
# ifdef CONFIG_SMP
br.call.sptk.few rp=invoke_schedule_tail
# endif
mov r8=0
br strace_check_retval
- .endp ia64_strace_clear_r8
+END(ia64_strace_clear_r8)
- .proc ia64_trace_syscall
-ia64_trace_syscall:
+ENTRY(ia64_trace_syscall)
+ PT_REGS_UNWIND_INFO
br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch syscall args
.ret4: br.call.sptk.few rp¶ // do the syscall
strace_check_retval:
@@ -454,7 +440,7 @@
(p6) mov r10=-1
(p6) mov r8=r9
br.cond.sptk.few strace_save_retval
- .endp ia64_trace_syscall
+END(ia64_trace_syscall)
/*
* A couple of convenience macros to help implement/understand the state
@@ -472,12 +458,8 @@
#define rKRBS r22
#define rB6 r21
- .align 16
- .global ia64_ret_from_syscall
- .global ia64_ret_from_syscall_clear_r8
- .global ia64_leave_kernel
- .proc ia64_ret_from_syscall
-ia64_ret_from_syscall_clear_r8:
+GLOBAL_ENTRY(ia64_ret_from_syscall_clear_r8)
+ PT_REGS_UNWIND_INFO
#ifdef CONFIG_SMP
// In SMP mode, we need to call schedule_tail to complete the scheduling process.
// Called by ia64_switch_to after do_fork()->copy_thread(). r8 contains the
@@ -487,7 +469,10 @@
#endif
mov r8=0
;; // added stop bits to prevent r8 dependency
-ia64_ret_from_syscall:
+END(ia64_ret_from_syscall_clear_r8)
+ // fall through
+GLOBAL_ENTRY(ia64_ret_from_syscall)
+ PT_REGS_UNWIND_INFO
cmp.ge p6,p7=r8,r0 // syscall executed successfully?
adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8
adds r3=IA64_PT_REGS_R8_OFFSET+32,sp // r3 = &pt_regs.r10
@@ -497,19 +482,21 @@
.mem.offset 8,0
(p6) st8.spill [r3]=r0 // clear error indication in slot for r10 and
reply other threads:[~2000-05-26 7:49 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=marc-linux-ia64-105590678205108@msgid-missing \
--to=davidm@hpl.hp.com \
--cc=linux-ia64@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox