Commit 7b8989c7 authored by James Simmons's avatar James Simmons Committed by James Simmons

Merge kozmo.(none):/usr/src/linus-2.5

into kozmo.(none):/usr/src/fbdev-2.5
parents 1eb6218e 6cbb2ab5
......@@ -38,9 +38,8 @@ The API currently supports three types of transforms: Ciphers, Digests and
Compressors. The compression algorithms especially seem to be performing
very well so far.
An asynchronous scheduling interface is in planning but not yet
implemented, as we need to further analyze the requirements of all of
the possible hardware scenarios (e.g. IPsec NIC offload).
Support for hardware crypto devices via an asynchronous interface is
under development.
Here's an example of how to use the API:
......@@ -87,8 +86,8 @@ also need:
DEVELOPER NOTES
None of this code should be called from hardirq context, only softirq and
user contexts.
Transforms may only be allocated in user context, and cryptographic
methods may only be called from softirq and user contexts.
When using the API for ciphers, performance will be optimal if each
scatterlist contains data which is a multiple of the cipher's block
......@@ -137,16 +136,11 @@ For further patches and various updates, including the current TODO
list, see:
http://samba.org/~jamesm/crypto/
Ongoing development discussion may also be found on
kerneli cryptoapi-devel,
see http://www.kerneli.org/mailman/listinfo/cryptoapi-devel
AUTHORS
James Morris
David S. Miller
Jean-Francois Dive (SHA1 algorithm module)
CREDITS
......@@ -191,6 +185,10 @@ Original developers of the crypto algorithms:
Matthew Skala (Twofish)
Dag Arne Osvik (Serpent)
Brian Gladman (AES)
SHA1 algorithm contributors:
Jean-Francois Dive
DES algorithm contributors:
Raimar Falke
......@@ -216,6 +214,8 @@ AES algorithm contributors:
Kyle McMartin
Adam J. Richter
Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>
Please send any credits updates or corrections to:
James Morris <jmorris@intercode.com.au>
......@@ -65,33 +65,33 @@ $(obj)/compressed/vmlinux: FORCE
# Set this if you want to pass append arguments to the zdisk/fdimage kernel
FDARGS =
$(obj)/mtools.conf: $(obj)/mtools.conf.in
$(obj)/mtools.conf: $(src)/mtools.conf.in
sed -e 's|@OBJ@|$(obj)|g' < $< > $@
# This requires write access to /dev/fd0
zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
MTOOLSRC=$(src)/mtools.conf mformat a: ; sync
MTOOLSRC=$(obj)/mtools.conf mformat a: ; sync
syslinux /dev/fd0 ; sync
echo 'default linux $(FDARGS)' | \
MTOOLSRC=$(src)/mtools.conf mcopy - a:syslinux.cfg
MTOOLSRC=$(src)/mtools.conf mcopy $(BOOTIMAGE) a:linux ; sync
MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux ; sync
# These require being root or having syslinux 2.02 or higher installed
fdimage fdimage144: $(BOOTIMAGE) $(src)/mtools.conf
fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf
dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440
MTOOLSRC=$(src)/mtools.conf mformat v: ; sync
MTOOLSRC=$(obj)/mtools.conf mformat v: ; sync
syslinux $(obj)/fdimage ; sync
echo 'default linux $(FDARGS)' | \
MTOOLSRC=$(src)/mtools.conf mcopy - v:syslinux.cfg
MTOOLSRC=$(src)/mtools.conf mcopy $(BOOTIMAGE) v:linux ; sync
MTOOLSRC=$(obj)/mtools.conf mcopy - v:syslinux.cfg
MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux ; sync
fdimage288: $(BOOTIMAGE) $(src)/mtools.conf
fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf
dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880
MTOOLSRC=$(src)/mtools.conf mformat w: ; sync
MTOOLSRC=$(obj)/mtools.conf mformat w: ; sync
syslinux $(obj)/fdimage ; sync
echo 'default linux $(FDARGS)' | \
MTOOLSRC=$(src)/mtools.conf mcopy - w:syslinux.cfg
MTOOLSRC=$(src)/mtools.conf mcopy $(BOOTIMAGE) w:linux ; sync
MTOOLSRC=$(obj)/mtools.conf mcopy - w:syslinux.cfg
MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux ; sync
zlilo: $(BOOTIMAGE)
if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
......
......@@ -480,7 +480,7 @@ void __init cpu_init (void)
*/
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
if(current->mm)
if (current->mm)
BUG();
enter_lazy_tlb(&init_mm, current, cpu);
......@@ -508,7 +508,7 @@ void __init cpu_init (void)
/*
* Force FPU initialization:
*/
clear_thread_flag(TIF_USEDFPU);
current_thread_info()->status = 0;
current->used_math = 0;
stts();
}
......@@ -72,6 +72,12 @@ DF_MASK = 0x00000400
NT_MASK = 0x00004000
VM_MASK = 0x00020000
/*
* ESP0 is at offset 4. 0x100 is the size of the TSS, and
* also thus the top-of-stack pointer offset of SYSENTER_ESP
*/
TSS_ESP0_OFFSET = (4 - 0x100)
#ifdef CONFIG_PREEMPT
#define preempt_stop cli
#else
......@@ -229,6 +235,8 @@ need_resched:
# sysenter call handler stub
ENTRY(sysenter_entry)
movl TSS_ESP0_OFFSET(%esp),%esp
sysenter_past_esp:
sti
pushl $(__USER_DS)
pushl %ebp
......@@ -458,12 +466,36 @@ device_not_available_emulate:
addl $4, %esp
jmp ret_from_exception
/*
* Debug traps and NMI can happen at the one SYSENTER instruction
* that sets up the real kernel stack. Check here, since we can't
* allow the wrong stack to be used.
*
* "TSS_ESP0_OFFSET+12" is because the NMI/debug handler will have
* already pushed 3 words if it hits on the sysenter instruction:
* eflags, cs and eip.
*
* We just load the right stack, and push the three (known) values
* by hand onto the new stack - while updating the return eip past
* the instruction that would have done it for sysenter.
*/
#define CHECK_SYSENTER_EIP \
cmpl $sysenter_entry,(%esp); \
jne 1f; \
movl TSS_ESP0_OFFSET+12(%esp),%esp; \
pushfl; \
pushl $__KERNEL_CS; \
pushl $sysenter_past_esp; \
1:
ENTRY(debug)
CHECK_SYSENTER_EIP
pushl $0
pushl $do_debug
jmp error_code
ENTRY(nmi)
CHECK_SYSENTER_EIP
pushl %eax
SAVE_ALL
movl %esp, %edx
......
......@@ -54,9 +54,11 @@ void init_fpu(struct task_struct *tsk)
void kernel_fpu_begin(void)
{
struct thread_info *thread = current_thread_info();
preempt_disable();
if (test_thread_flag(TIF_USEDFPU)) {
__save_init_fpu(current);
if (thread->status & TS_USEDFPU) {
__save_init_fpu(thread->task);
return;
}
clts();
......
......@@ -275,6 +275,15 @@ void release_thread(struct task_struct *dead_task)
release_x86_irqs(dead_task);
}
/*
* This gets called before we allocate a new thread and copy
* the current task into it.
*/
void prepare_to_copy(struct task_struct *tsk)
{
unlazy_fpu(tsk);
}
int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
......@@ -297,9 +306,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
savesegment(gs,p->thread.gs);
tsk = current;
unlazy_fpu(tsk);
struct_cpy(&p->thread.i387, &tsk->thread.i387);
if (unlikely(NULL != tsk->thread.ts_io_bitmap)) {
p->thread.ts_io_bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
if (!p->thread.ts_io_bitmap)
......
......@@ -41,8 +41,9 @@ void enable_sep_cpu(void *info)
struct tss_struct *tss = init_tss + cpu;
tss->ss1 = __KERNEL_CS;
tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss;
wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp0, 0);
wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0);
wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0);
printk("Enabling SEP on CPU %d\n", cpu);
......
......@@ -737,13 +737,14 @@ asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs,
*/
asmlinkage void math_state_restore(struct pt_regs regs)
{
struct task_struct *tsk = current;
clts(); /* Allow maths ops (or we recurse) */
struct thread_info *thread = current_thread_info();
struct task_struct *tsk = thread->task;
clts(); /* Allow maths ops (or we recurse) */
if (!tsk->used_math)
init_fpu(tsk);
restore_fpu(tsk);
set_thread_flag(TIF_USEDFPU); /* So we fnsave on switch_to() */
thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */
}
#ifndef CONFIG_MATH_EMULATION
......
......@@ -300,7 +300,7 @@ ia32_syscall_table:
data8 compat_sys_statfs
data8 compat_sys_fstatfs /* 100 */
data8 sys32_ioperm
data8 sys32_socketcall
data8 compat_sys_socketcall
data8 sys_syslog
data8 compat_sys_setitimer
data8 compat_sys_getitimer /* 105 */
......
......@@ -97,11 +97,9 @@ typedef struct sg_io_hdr32 {
int info; /* [o] auxiliary information */
} sg_io_hdr32_t; /* 64 bytes long (on IA32) */
struct iovec32 { unsigned int iov_base; int iov_len; };
static int alloc_sg_iovec(sg_io_hdr_t *sgp, int uptr32)
{
struct iovec32 *uiov = (struct iovec32 *) P(uptr32);
struct compat_iovec *uiov = (struct compat_iovec *) P(uptr32);
sg_iovec_t *kiov;
int i;
......@@ -136,7 +134,7 @@ static int alloc_sg_iovec(sg_io_hdr_t *sgp, int uptr32)
static int copy_back_sg_iovec(sg_io_hdr_t *sgp, int uptr32)
{
struct iovec32 *uiov = (struct iovec32 *) P(uptr32);
struct compat_iovec *uiov = (struct compat_iovec *) P(uptr32);
sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
int i;
......
This diff is collapsed.
......@@ -729,12 +729,10 @@ extern asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
return sys_llseek(fd, offset_high, offset_low, result, origin);
}
struct iovec32 { unsigned int iov_base; int iov_len; };
typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);
static long
do_readv_writev32(int type, struct file *file, const struct iovec32 *vector,
do_readv_writev32(int type, struct file *file, const struct compat_iovec *vector,
u32 count)
{
unsigned long tot_len;
......@@ -749,7 +747,7 @@ do_readv_writev32(int type, struct file *file, const struct iovec32 *vector,
*/
if (!count)
return 0;
if(verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
if(verify_area(VERIFY_READ, vector, sizeof(struct compat_iovec)*count))
return -EFAULT;
if (count > UIO_MAXIOV)
return -EINVAL;
......@@ -835,7 +833,7 @@ do_readv_writev32(int type, struct file *file, const struct iovec32 *vector,
}
asmlinkage long
sys32_readv(int fd, struct iovec32 *vector, u32 count)
sys32_readv(int fd, struct compat_iovec *vector, u32 count)
{
struct file *file;
ssize_t ret;
......@@ -855,7 +853,7 @@ sys32_readv(int fd, struct iovec32 *vector, u32 count)
}
asmlinkage long
sys32_writev(int fd, struct iovec32 *vector, u32 count)
sys32_writev(int fd, struct compat_iovec *vector, u32 count)
{
struct file *file;
ssize_t ret;
......@@ -1155,48 +1153,6 @@ asmlinkage long sys32_times(struct tms32 *tbuf)
return ret;
}
extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
char *optval, int optlen);
asmlinkage int sys32_setsockopt(int fd, int level, int optname,
char *optval, int optlen)
{
if (optname == SO_ATTACH_FILTER) {
struct sock_fprog32 {
__u16 len;
__u32 filter;
} *fprog32 = (struct sock_fprog32 *)optval;
struct sock_fprog kfprog;
struct sock_filter *kfilter;
unsigned int fsize;
mm_segment_t old_fs;
__u32 uptr;
int ret;
if (get_user(kfprog.len, &fprog32->len) ||
__get_user(uptr, &fprog32->filter))
return -EFAULT;
kfprog.filter = (struct sock_filter *)A(uptr);
fsize = kfprog.len * sizeof(struct sock_filter);
kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
if (kfilter == NULL)
return -ENOMEM;
if (copy_from_user(kfilter, kfprog.filter, fsize)) {
kfree(kfilter);
return -EFAULT;
}
kfprog.filter = kfilter;
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sys_setsockopt(fd, level, optname,
(char *)&kfprog, sizeof(kfprog));
set_fs(old_fs);
kfree(kfilter);
return ret;
}
return sys_setsockopt(fd, level, optname, optval, optlen);
}
struct flock32 {
short l_type;
short l_whence;
......@@ -1873,256 +1829,3 @@ asmlinkage int sys32_adjtimex(struct timex32 *utp)
return ret;
}
/*
* Declare the 32-bit version of the msghdr
*/
struct msghdr32 {
unsigned int msg_name; /* Socket name */
int msg_namelen; /* Length of name */
unsigned int msg_iov; /* Data blocks */
unsigned int msg_iovlen; /* Number of blocks */
unsigned int msg_control; /* Per protocol magic (eg BSD file descriptor passing) */
unsigned int msg_controllen; /* Length of cmsg list */
unsigned msg_flags;
};
static inline int
shape_msg(struct msghdr *mp, struct msghdr32 *mp32)
{
int ret;
unsigned int i;
if (!access_ok(VERIFY_READ, mp32, sizeof(*mp32)))
return(-EFAULT);
ret = __get_user(i, &mp32->msg_name);
mp->msg_name = (void *)A(i);
ret |= __get_user(mp->msg_namelen, &mp32->msg_namelen);
ret |= __get_user(i, &mp32->msg_iov);
mp->msg_iov = (struct iovec *)A(i);
ret |= __get_user(mp->msg_iovlen, &mp32->msg_iovlen);
ret |= __get_user(i, &mp32->msg_control);
mp->msg_control = (void *)A(i);
ret |= __get_user(mp->msg_controllen, &mp32->msg_controllen);
ret |= __get_user(mp->msg_flags, &mp32->msg_flags);
return(ret ? -EFAULT : 0);
}
/*
* Verify & re-shape IA32 iovec. The caller must ensure that the
* iovec is big enough to hold the re-shaped message iovec.
*
* Save time not doing verify_area. copy_*_user will make this work
* in any case.
*
* Don't need to check the total size for overflow (cf net/core/iovec.c),
* 32-bit sizes can't overflow a 64-bit count.
*/
static inline int
verify_iovec32(struct msghdr *m, struct iovec *iov, char *address, int mode)
{
int size, err, ct;
struct iovec32 *iov32;
if(m->msg_namelen)
{
if(mode==VERIFY_READ)
{
err=move_addr_to_kernel(m->msg_name, m->msg_namelen, address);
if(err<0)
goto out;
}
m->msg_name = address;
} else
m->msg_name = NULL;
err = -EFAULT;
size = m->msg_iovlen * sizeof(struct iovec32);
if (copy_from_user(iov, m->msg_iov, size))
goto out;
m->msg_iov=iov;
err = 0;
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 *) A(iov32[ct].iov_base);
err += iov[ct].iov_len;
}
out:
return err;
}
/* XXX This really belongs in some header file... -DaveM */
#define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
16 for IP, 16 for IPX,
24 for IPv6,
about 80 for AX.25 */
/*
* BSD sendmsg interface
*/
int sys32_sendmsg(int fd, struct msghdr32 *msg, unsigned flags)
{
struct socket *sock;
char address[MAX_SOCK_ADDR];
struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
unsigned char ctl[sizeof(struct cmsghdr) + 20]; /* 20 is size of ipv6_pktinfo */
unsigned char *ctl_buf = ctl;
struct msghdr msg_sys;
int err, ctl_len, iov_size, total_len;
err = -EFAULT;
if (shape_msg(&msg_sys, msg))
goto out;
sock = sockfd_lookup(fd, &err);
if (!sock)
goto out;
/* do not move before msg_sys is valid */
err = -EINVAL;
if (msg_sys.msg_iovlen > UIO_MAXIOV)
goto out_put;
/* Check whether to allocate the iovec area*/
err = -ENOMEM;
iov_size = msg_sys.msg_iovlen * sizeof(struct iovec32);
if (msg_sys.msg_iovlen > UIO_FASTIOV) {
iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
if (!iov)
goto out_put;
}
/* This will also move the address data into kernel space */
err = verify_iovec32(&msg_sys, iov, address, VERIFY_READ);
if (err < 0)
goto out_freeiov;
total_len = err;
err = -ENOBUFS;
if (msg_sys.msg_controllen > INT_MAX)
goto out_freeiov;
ctl_len = msg_sys.msg_controllen;
if (ctl_len)
{
if (ctl_len > sizeof(ctl))
{
err = -ENOBUFS;
ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
if (ctl_buf == NULL)
goto out_freeiov;
}
err = -EFAULT;
if (copy_from_user(ctl_buf, msg_sys.msg_control, ctl_len))
goto out_freectl;
msg_sys.msg_control = ctl_buf;
}
msg_sys.msg_flags = flags;
if (sock->file->f_flags & O_NONBLOCK)
msg_sys.msg_flags |= MSG_DONTWAIT;
err = sock_sendmsg(sock, &msg_sys, total_len);
out_freectl:
if (ctl_buf != ctl)
sock_kfree_s(sock->sk, ctl_buf, ctl_len);
out_freeiov:
if (iov != iovstack)
sock_kfree_s(sock->sk, iov, iov_size);
out_put:
sockfd_put(sock);
out:
return err;
}
/*
* BSD recvmsg interface
*/
int
sys32_recvmsg (int fd, struct msghdr32 *msg, unsigned int flags)
{
struct socket *sock;
struct iovec iovstack[UIO_FASTIOV];
struct iovec *iov=iovstack;
struct msghdr msg_sys;
unsigned long cmsg_ptr;
int err, iov_size, total_len, len;
/* kernel mode address */
char addr[MAX_SOCK_ADDR];
/* user mode address pointers */
struct sockaddr *uaddr;
int *uaddr_len;
err=-EFAULT;
if (shape_msg(&msg_sys, msg))
goto out;
sock = sockfd_lookup(fd, &err);
if (!sock)
goto out;
err = -EINVAL;
if (msg_sys.msg_iovlen > UIO_MAXIOV)
goto out_put;
/* Check whether to allocate the iovec area*/
err = -ENOMEM;
iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
if (msg_sys.msg_iovlen > UIO_FASTIOV) {
iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
if (!iov)
goto out_put;
}
/*
* Save the user-mode address (verify_iovec will change the
* kernel msghdr to use the kernel address space)
*/
uaddr = msg_sys.msg_name;
uaddr_len = &msg->msg_namelen;
err = verify_iovec32(&msg_sys, iov, addr, VERIFY_WRITE);
if (err < 0)
goto out_freeiov;
total_len=err;
cmsg_ptr = (unsigned long)msg_sys.msg_control;
msg_sys.msg_flags = 0;
if (sock->file->f_flags & O_NONBLOCK)
flags |= MSG_DONTWAIT;
err = sock_recvmsg(sock, &msg_sys, total_len, flags);
if (err < 0)
goto out_freeiov;
len = err;
if (uaddr != NULL) {
err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
if (err < 0)
goto out_freeiov;
}
err = __put_user(msg_sys.msg_flags, &msg->msg_flags);
if (err)
goto out_freeiov;
err = __put_user((unsigned long)msg_sys.msg_control-cmsg_ptr,
&msg->msg_controllen);
if (err)
goto out_freeiov;
err = len;
out_freeiov:
if (iov != iovstack)
sock_kfree_s(sock->sk, iov, iov_size);
out_put:
sockfd_put(sock);
out:
return err;
}
......@@ -378,8 +378,8 @@ illegal_syscall:
sys sys32_select 5
sys sys_flock 2
sys sys_msync 3
sys sys32_readv 3 /* 4145 */
sys sys32_writev 3
sys compat_sys_readv 3 /* 4145 */
sys compat_sys_writev 3
sys sys_cacheflush 3
sys sys_cachectl 3
sys sys_sysmips 4
......@@ -410,11 +410,11 @@ illegal_syscall:
sys sys_listen 2
sys sys_recv 4 /* 4175 */
sys sys_recvfrom 6
sys sys32_recvmsg 3
sys compat_sys_recvmsg 3
sys sys_send 4
sys sys32_sendmsg 3
sys compat_sys_sendmsg 3
sys sys_sendto 6 /* 4180 */
sys sys32_setsockopt 5
sys compat_sys_setsockopt 5
sys sys_shutdown 2
sys sys_socket 3
sys sys_socketpair 4
......
This diff is collapsed.
......@@ -604,7 +604,7 @@ _GLOBAL(sys_call_table32)
.llong .compat_sys_statfs
.llong .compat_sys_fstatfs /* 100 */
.llong .sys_ioperm
.llong .sys32_socketcall
.llong .compat_sys_socketcall
.llong .sys32_syslog
.llong .compat_sys_setitimer
.llong .compat_sys_getitimer /* 105 */
......
......@@ -25,7 +25,7 @@ _GLOBAL(ppc32_lseek)
extsw r4,r4 /* sign extend off_t offset parm */
b .sys_lseek
_GLOBAL(sys32_socketcall) /* r3=call, r4=args */
_GLOBAL(compat_sys_socketcall) /* r3=call, r4=args */
cmpwi r3, 1
blt- .do_einval
cmpwi r3, 17
......@@ -221,14 +221,14 @@ _STATIC(do_sys_shutdown) /* sys_shutdown(int, int) */
.llong 2b,.do_efault
.previous
_STATIC(do_sys_setsockopt) /* sys32_setsockopt(int, int, int, char *, int) */
_STATIC(do_sys_setsockopt) /* compat_sys_setsockopt(int, int, int, char *, int) */
mr r10,r4
1: lwa r3,0(r10)
2: lwa r4,4(r10)
3: lwa r5,8(r10)
4: lwz r6,12(r10)
5: lwa r7,16(r10)
b .sys32_setsockopt
b .compat_sys_setsockopt
.section __ex_table,"a"
.align 3
.llong 1b,.do_efault
......@@ -238,14 +238,14 @@ _STATIC(do_sys_setsockopt) /* sys32_setsockopt(int, int, int, char *, int) */
.llong 5b,.do_efault
.previous
_STATIC(do_sys_getsockopt) /* sys32_getsockopt(int, int, int, u32, u32) */
_STATIC(do_sys_getsockopt) /* compat_sys_getsockopt(int, int, int, u32, u32) */
mr r10,r4
1: lwa r3,0(r10)
2: lwa r4,4(r10)
3: lwa r5,8(r10)
4: lwz r6,12(r10)
5: lwz r7,16(r10)
b .sys32_getsockopt
b .compat_sys_getsockopt
.section __ex_table,"a"
.align 3
.llong 1b,.do_efault
......@@ -255,12 +255,12 @@ _STATIC(do_sys_getsockopt) /* sys32_getsockopt(int, int, int, u32, u32) */
.llong 5b,.do_efault
.previous
_STATIC(do_sys_sendmsg) /* sys32_sendmsg(int, struct msghdr32 *, unsigned int) */
_STATIC(do_sys_sendmsg) /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */
mr r10,r4
1: lwa r3,0(r10)
2: lwz r4,4(r10)
3: lwa r5,8(r10)
b .sys32_sendmsg
b .compat_sys_sendmsg
.section __ex_table,"a"
.align 3
.llong 1b,.do_efault
......@@ -268,12 +268,12 @@ _STATIC(do_sys_sendmsg) /* sys32_sendmsg(int, struct msghdr32 *, unsigned int) *
.llong 3b,.do_efault
.previous
_STATIC(do_sys_recvmsg) /* sys32_recvmsg(int, struct msghdr32 *, unsigned int) */
_STATIC(do_sys_recvmsg) /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) */
mr r10,r4
1: lwa r3,0(r10)
2: lwz r4,4(r10)
3: lwa r5,8(r10)
b .sys32_recvmsg
b .compat_sys_recvmsg
.section __ex_table,"a"
.align 3
.llong 1b,.do_efault
......
This diff is collapsed.
......@@ -499,7 +499,7 @@ sys_call_table:
.long SYSCALL(sys_statfs,compat_sys_statfs_wrapper)
.long SYSCALL(sys_fstatfs,compat_sys_fstatfs_wrapper) /* 100 */
.long SYSCALL(sys_ni_syscall,sys_ni_syscall)
.long SYSCALL(sys_socketcall,sys32_socketcall_wrapper)
.long SYSCALL(sys_socketcall,compat_sys_socketcall_wrapper)
.long SYSCALL(sys_syslog,sys32_syslog_wrapper)
.long SYSCALL(sys_setitimer,compat_sys_setitimer_wrapper)
.long SYSCALL(sys_getitimer,compat_sys_getitimer_wrapper) /* 105 */
......
This diff is collapsed.
......@@ -452,11 +452,11 @@ compat_sys_fstatfs_wrapper:
llgtr %r3,%r3 # struct compat_statfs *
jg compat_sys_fstatfs # branch to system call
.globl sys32_socketcall_wrapper
sys32_socketcall_wrapper:
.globl compat_sys_socketcall_wrapper
compat_sys_socketcall_wrapper:
lgfr %r2,%r2 # int
llgtr %r3,%r3 # u32 *
jg sys32_socketcall # branch to system call
jg compat_sys_socketcall # branch to system call
.globl sys32_syslog_wrapper
sys32_syslog_wrapper:
......
......@@ -1107,38 +1107,16 @@ asmlinkage int sunos_send(int fd, void * buff, int len, unsigned flags)
return ret;
}
extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
char *optval, int optlen);
asmlinkage int sunos_socket(int family, int type, int protocol)
{
int ret, one = 1;
ret = sys_socket(family, type, protocol);
if (ret < 0)
goto out;
sys_setsockopt(ret, SOL_SOCKET, SO_BSDCOMPAT,
(char *)&one, sizeof(one));
out:
return ret;
}
asmlinkage int sunos_accept(int fd, struct sockaddr *sa, int *addrlen)
{
int ret, one = 1;
int ret;
while (1) {
ret = check_nonblock(sys_accept(fd,sa,addrlen),fd);
if (ret != -ENETUNREACH && ret != -EHOSTUNREACH)
break;
}
if (ret < 0)
goto out;
sys_setsockopt(ret, SOL_SOCKET, SO_BSDCOMPAT,
(char *)&one, sizeof(one));
out:
return ret;
}
......
......@@ -110,7 +110,7 @@ sunos_sys_table:
.long sys_getitimer, sys_gethostname, sys_sethostname
.long sunos_getdtablesize, sys_dup2, sunos_nop
.long sys_fcntl, sunos_select, sunos_nop
.long sys_fsync, sys_setpriority, sunos_socket
.long sys_fsync, sys_setpriority, sys_socket
.long sys_connect, sunos_accept
/*100*/ .long sys_getpriority, sunos_send, sunos_recv
.long sunos_nosys, sys_bind, sunos_setsockopt
......
......@@ -20,6 +20,7 @@
#include <linux/interrupt.h>
#include <linux/fs_struct.h>
#include <linux/mm.h>
#include <linux/socket.h>
#include <asm/oplib.h>
#include <asm/delay.h>
......@@ -243,6 +244,7 @@ EXPORT_SYMBOL(io_remap_page_range);
/* Solaris/SunOS binary compatibility */
EXPORT_SYMBOL(_sigpause_common);
EXPORT_SYMBOL(verify_compat_iovec);
/* Should really be in linux/kernel/ksyms.c */
EXPORT_SYMBOL(dump_thread);
......
......@@ -202,38 +202,38 @@ do_sys_shutdown: /* sys_shutdown(int, int) */
nop
nop
nop
do_sys_setsockopt: /* sys32_setsockopt(int, int, int, char *, int) */
do_sys_setsockopt: /* compat_sys_setsockopt(int, int, int, char *, int) */
ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys32_setsockopt), %g1
sethi %hi(compat_sys_setsockopt), %g1
ldswa [%o1 + 0x8] %asi, %o2
lduwa [%o1 + 0xc] %asi, %o3
ldswa [%o1 + 0x10] %asi, %o4
jmpl %g1 + %lo(sys32_setsockopt), %g0
jmpl %g1 + %lo(compat_sys_setsockopt), %g0
ldswa [%o1 + 0x4] %asi, %o1
nop
do_sys_getsockopt: /* sys32_getsockopt(int, int, int, u32, u32) */
do_sys_getsockopt: /* compat_sys_getsockopt(int, int, int, u32, u32) */
ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys32_getsockopt), %g1
sethi %hi(compat_sys_getsockopt), %g1
ldswa [%o1 + 0x8] %asi, %o2
lduwa [%o1 + 0xc] %asi, %o3
lduwa [%o1 + 0x10] %asi, %o4
jmpl %g1 + %lo(sys32_getsockopt), %g0
jmpl %g1 + %lo(compat_sys_getsockopt), %g0
ldswa [%o1 + 0x4] %asi, %o1
nop
do_sys_sendmsg: /* sys32_sendmsg(int, struct msghdr32 *, unsigned int) */
do_sys_sendmsg: /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */
ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys32_sendmsg), %g1
sethi %hi(compat_sys_sendmsg), %g1
lduwa [%o1 + 0x8] %asi, %o2
jmpl %g1 + %lo(sys32_sendmsg), %g0
jmpl %g1 + %lo(compat_sys_sendmsg), %g0
lduwa [%o1 + 0x4] %asi, %o1
nop
nop
nop
do_sys_recvmsg: /* sys32_recvmsg(int, struct msghdr32 *, unsigned int) */
do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) */
ldswa [%o1 + 0x0] %asi, %o0
sethi %hi(sys32_recvmsg), %g1
sethi %hi(compat_sys_recvmsg), %g1
lduwa [%o1 + 0x8] %asi, %o2
jmpl %g1 + %lo(sys32_recvmsg), %g0
jmpl %g1 + %lo(compat_sys_recvmsg), %g0
lduwa [%o1 + 0x4] %asi, %o1
nop
nop
......
This diff is collapsed.
......@@ -54,6 +54,7 @@
#include <linux/personality.h>
/* For SOCKET_I */
#include <linux/socket.h>
#include <net/sock.h>
/* Use this to get at 32-bit user passed pointers. */
......@@ -1253,26 +1254,9 @@ asmlinkage int sunos_send(int fd, u32 buff, int len, unsigned flags)
return ret;
}
extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
char *optval, int optlen);
asmlinkage int sunos_socket(int family, int type, int protocol)
{
int ret, one = 1;
ret = sys_socket(family, type, protocol);
if (ret < 0)
goto out;
sys_setsockopt(ret, SOL_SOCKET, SO_BSDCOMPAT,
(char *)&one, sizeof(one));
out:
return ret;
}
asmlinkage int sunos_accept(int fd, u32 sa, u32 addrlen)
{
int ret, one = 1;
int ret;
while (1) {
ret = check_nonblock(sys_accept(fd, (struct sockaddr *)A(sa),
......@@ -1280,12 +1264,6 @@ asmlinkage int sunos_accept(int fd, u32 sa, u32 addrlen)
if (ret != -ENETUNREACH && ret != -EHOSTUNREACH)
break;
}
if (ret < 0)
goto out;
sys_setsockopt(ret, SOL_SOCKET, SO_BSDCOMPAT,
(char *)&one, sizeof(one));
out:
return ret;
}
......@@ -1324,8 +1302,6 @@ asmlinkage int sunos_sigaction (int sig, u32 act, u32 oact)
extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
char *optval, int optlen);
extern asmlinkage int sys32_getsockopt(int fd, int level, int optname,
u32 optval, u32 optlen);
asmlinkage int sunos_setsockopt(int fd, int level, int optname, u32 optval,
int optlen)
......@@ -1353,6 +1329,6 @@ asmlinkage int sunos_getsockopt(int fd, int level, int optname,
if (tr_opt >=2 && tr_opt <= 6)
tr_opt += 30;
}
ret = sys32_getsockopt(fd, level, tr_opt, optval, optlen);
ret = compat_sys_getsockopt(fd, level, tr_opt, (void*)(unsigned long)optval, (void*)(unsigned long)optlen);
return ret;
}
......@@ -173,13 +173,13 @@ sunos_sys_table:
.word compat_sys_getitimer, sys_gethostname, sys_sethostname
.word sunos_getdtablesize, sys_dup2, sunos_nop
.word sys32_fcntl, sunos_select, sunos_nop
.word sys_fsync, sys_setpriority32, sunos_socket
.word sys_fsync, sys_setpriority32, sys_socket
.word sys_connect, sunos_accept
/*100*/ .word sys_getpriority, sunos_send, sunos_recv
.word sunos_nosys, sys_bind, sunos_setsockopt
.word sys_listen, sunos_nosys, sunos_sigaction
.word sunos_sigblock, sunos_sigsetmask, sys_sigpause
.word sys32_sigstack, sys32_recvmsg, sys32_sendmsg
.word sys32_sigstack, compat_sys_recvmsg, compat_sys_sendmsg
.word sunos_nosys, sys32_gettimeofday, sys32_getrusage
.word sunos_getsockopt, sunos_nosys, sunos_readv
.word sunos_writev, sys32_settimeofday, sys32_fchown16
......
......@@ -267,35 +267,6 @@ struct sol_cmsghdr {
unsigned char cmsg_data[0];
};
struct iovec32 {
u32 iov_base;
u32 iov_len;
};
static inline int iov_from_user32_to_kern(struct iovec *kiov,
struct iovec32 *uiov32,
int niov)
{
int tot_len = 0;
while(niov > 0) {
u32 len, buf;
if(get_user(len, &uiov32->iov_len) ||
get_user(buf, &uiov32->iov_base)) {
tot_len = -EFAULT;
break;
}
tot_len += len;
kiov->iov_base = (void *)A(buf);
kiov->iov_len = (__kernel_size_t) len;
uiov32++;
kiov++;
niov--;
}
return tot_len;
}
static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
struct sol_nmsghdr *umsg)
{
......@@ -321,42 +292,6 @@ static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
return err;
}
/* I've named the args so it is easy to tell whose space the pointers are in. */
static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
char *kern_address, int mode)
{
int tot_len;
if(kern_msg->msg_namelen) {
if(mode==VERIFY_READ) {
int err = move_addr_to_kernel(kern_msg->msg_name,
kern_msg->msg_namelen,
kern_address);
if(err < 0)
return err;
}
kern_msg->msg_name = kern_address;
} else
kern_msg->msg_name = NULL;
if(kern_msg->msg_iovlen > UIO_FASTIOV) {
kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
GFP_KERNEL);
if(!kern_iov)
return -ENOMEM;
}
tot_len = iov_from_user32_to_kern(kern_iov,
(struct iovec32 *)kern_msg->msg_iov,
kern_msg->msg_iovlen);
if(tot_len >= 0)
kern_msg->msg_iov = kern_iov;
else if(kern_msg->msg_iovlen > UIO_FASTIOV)
kfree(kern_iov);
return tot_len;
}
asmlinkage int solaris_sendmsg(int fd, struct sol_nmsghdr *user_msg, unsigned user_flags)
{
struct socket *sock;
......@@ -371,7 +306,7 @@ asmlinkage int solaris_sendmsg(int fd, struct sol_nmsghdr *user_msg, unsigned us
return -EFAULT;
if(kern_msg.msg_iovlen > UIO_MAXIOV)
return -EINVAL;
err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
err = verify_compat_iovec(&kern_msg, iov, address, VERIFY_READ);
if (err < 0)
goto out;
total_len = err;
......@@ -439,7 +374,7 @@ asmlinkage int solaris_recvmsg(int fd, struct sol_nmsghdr *user_msg, unsigned in
uaddr = kern_msg.msg_name;
uaddr_len = &user_msg->msg_namelen;
err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
err = verify_compat_iovec(&kern_msg, iov, addr, VERIFY_WRITE);
if (err < 0)
goto out;
total_len = err;
......
This diff is collapsed.
This diff is collapsed.
......@@ -4,4 +4,4 @@
obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \
ia32_signal.o \
ia32_binfmt.o fpu32.o socket32.o ptrace32.o ipc32.o syscall32.o
ia32_binfmt.o fpu32.o ptrace32.o ipc32.o syscall32.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment