diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-03-23 02:25:38 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-03-23 02:25:38 +0000 |
commit | 16b5d462f73eb29d1f67fa01cc1ea66afdc72569 (patch) | |
tree | 5407bd573f4840e473ea27cbe61e5c7a07131fcd /arch/sparc64/kernel | |
parent | ce8a076e11e7e5ee36007f9a3eee5bb3744cb8f6 (diff) |
Merge with Linux 2.3.99-pre2.
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r-- | arch/sparc64/kernel/binfmt_aout32.c | 28 | ||||
-rw-r--r-- | arch/sparc64/kernel/ioctl32.c | 425 | ||||
-rw-r--r-- | arch/sparc64/kernel/setup.c | 27 | ||||
-rw-r--r-- | arch/sparc64/kernel/smp.c | 17 | ||||
-rw-r--r-- | arch/sparc64/kernel/sparc64_ksyms.c | 12 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc.c | 7 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc32.c | 99 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sunos32.c | 29 | ||||
-rw-r--r-- | arch/sparc64/kernel/systbls.S | 10 | ||||
-rw-r--r-- | arch/sparc64/kernel/unaligned.c | 18 |
10 files changed, 517 insertions, 155 deletions
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c index 3e95ed9cf..3504533d1 100644 --- a/arch/sparc64/kernel/binfmt_aout32.c +++ b/arch/sparc64/kernel/binfmt_aout32.c @@ -33,7 +33,7 @@ #include <asm/pgalloc.h> static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs); -static int load_aout32_library(int fd); +static int load_aout32_library(struct file*); static int aout32_core_dump(long signr, struct pt_regs * regs, struct file *file); extern void dump_thread(struct pt_regs *, struct user *); @@ -343,9 +343,8 @@ beyond_if: } /* N.B. Move to .h file and use code in fs/binfmt_aout.c? */ -static int load_aout32_library(int fd) +static int load_aout32_library(struct file *file) { - struct file * file; struct inode * inode; unsigned long bss, start_addr, len; unsigned long error; @@ -353,12 +352,6 @@ static int load_aout32_library(int fd) loff_t offset = 0; struct exec ex; - retval = -EACCES; - file = fget(fd); - if (!file) - goto out; - if (!file->f_op) - goto out_putf; inode = file->f_dentry->d_inode; retval = -ENOEXEC; @@ -367,23 +360,23 @@ static int load_aout32_library(int fd) error = file->f_op->read(file, (char *) &ex, sizeof(ex), &offset); set_fs(USER_DS); if (error != sizeof(ex)) - goto out_putf; + goto out; /* We come in here for the regular a.out style of shared libraries */ if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) || N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) || inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { - goto out_putf; + goto out; } if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) && (N_TXTOFF(ex) < inode->i_sb->s_blocksize)) { printk("N_TXTOFF < BLOCK_SIZE. Please convert library\n"); - goto out_putf; + goto out; } if (N_FLAGS(ex)) - goto out_putf; + goto out; /* For QMAGIC, the starting address is 0x20 into the page. We mask this off to get the starting address for the page */ @@ -391,13 +384,15 @@ static int load_aout32_library(int fd) start_addr = ex.a_entry & 0xfffff000; /* Now use mmap to map the library into memory. */ + down(¤t->mm->mmap_sem); error = do_mmap(file, start_addr, ex.a_text + ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, N_TXTOFF(ex)); + up(¤t->mm->mmap_sem); retval = error; if (error != start_addr) - goto out_putf; + goto out; len = PAGE_ALIGN(ex.a_text + ex.a_data); bss = ex.a_text + ex.a_data + ex.a_bss; @@ -405,12 +400,9 @@ static int load_aout32_library(int fd) error = do_brk(start_addr + len, bss - len); retval = error; if (error != start_addr + len) - goto out_putf; + goto out; } retval = 0; - -out_putf: - fput(file); out: return retval; } diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index d3a3814a8..0ba88adf6 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.82 2000/03/13 21:57:27 davem Exp $ +/* $Id: ioctl32.c,v 1.83 2000/03/14 07:31:25 jj Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -8,6 +8,7 @@ * ioctls. */ +#include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -44,6 +45,14 @@ #include <linux/raw.h> #include <linux/smb_fs.h> #include <linux/blkpg.h> +#include <linux/blk.h> +#include <linux/elevator.h> +#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) +/* Ugh. This header really is not clean */ +#define min min +#define max max +#include <linux/lvm.h> +#endif /* LVM */ #include <scsi/scsi.h> /* Ugly hack. */ @@ -1980,6 +1989,353 @@ static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg) return -EINVAL; } +#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) +/* Ugh, LVM. Pitty it was not cleaned up before accepted :((. */ +typedef struct { + uint8_t vg_name[NAME_LEN]; + uint32_t vg_number; + uint32_t vg_access; + uint32_t vg_status; + uint32_t lv_max; + uint32_t lv_cur; + uint32_t lv_open; + uint32_t pv_max; + uint32_t pv_cur; + uint32_t pv_act; + uint32_t dummy; + uint32_t vgda; + uint32_t pe_size; + uint32_t pe_total; + uint32_t pe_allocated; + uint32_t pvg_total; + u32 proc; + u32 pv[ABS_MAX_PV + 1]; + u32 lv[ABS_MAX_LV + 1]; +} vg32_t; + +typedef struct { + uint8_t id[2]; + uint16_t version; + lvm_disk_data_t pv_on_disk; + lvm_disk_data_t vg_on_disk; + lvm_disk_data_t pv_namelist_on_disk; + lvm_disk_data_t lv_on_disk; + lvm_disk_data_t pe_on_disk; + uint8_t pv_name[NAME_LEN]; + uint8_t vg_name[NAME_LEN]; + uint8_t system_id[NAME_LEN]; + kdev_t pv_dev; + uint32_t pv_number; + uint32_t pv_status; + uint32_t pv_allocatable; + uint32_t pv_size; + uint32_t lv_cur; + uint32_t pe_size; + uint32_t pe_total; + uint32_t pe_allocated; + uint32_t pe_stale; + u32 pe; + u32 inode; +} pv32_t; + +typedef struct { + char lv_name[NAME_LEN]; + u32 lv; +} lv_req32_t; + +typedef struct { + u32 lv_index; + u32 lv; +} lv_status_byindex_req32_t; + +typedef struct { + uint8_t lv_name[NAME_LEN]; + kdev_t old_dev; + kdev_t new_dev; + u32 old_pe; + u32 new_pe; +} le_remap_req32_t; + +typedef struct { + char pv_name[NAME_LEN]; + u32 pv; +} pv_status_req32_t; + +typedef struct { + uint8_t lv_name[NAME_LEN]; + uint8_t vg_name[NAME_LEN]; + uint32_t lv_access; + uint32_t lv_status; + uint32_t lv_open; + kdev_t lv_dev; + uint32_t lv_number; + uint32_t lv_mirror_copies; + uint32_t lv_recovery; + uint32_t lv_schedule; + uint32_t lv_size; + u32 lv_current_pe; + uint32_t lv_current_le; + uint32_t lv_allocated_le; + uint32_t lv_stripes; + uint32_t lv_stripesize; + uint32_t lv_badblock; + uint32_t lv_allocation; + uint32_t lv_io_timeout; + uint32_t lv_read_ahead; + /* delta to version 1 starts here */ + u32 lv_snapshot_org; + u32 lv_snapshot_prev; + u32 lv_snapshot_next; + u32 lv_block_exception; + uint32_t lv_remap_ptr; + uint32_t lv_remap_end; + uint32_t lv_chunk_size; + uint32_t lv_snapshot_minor; + char dummy[200]; +} lv32_t; + +typedef struct { + u32 hash[2]; + u32 rsector_org; + kdev_t rdev_org; + u32 rsector_new; + kdev_t rdev_new; +} lv_block_exception32_t; + +static void put_lv_t(lv_t *l) +{ + if (l->lv_current_pe) vfree(l->lv_current_pe); + if (l->lv_block_exception) vfree(l->lv_block_exception); + kfree(l); +} + +static lv_t *get_lv_t(u32 p, int *errp) +{ + int err, i; + u32 ptr1, ptr2; + size_t size; + lv_block_exception32_t *lbe32; + lv_block_exception_t *lbe; + lv32_t *ul = (lv32_t *)A(p); + lv_t *l = (lv_t *)kmalloc(sizeof(lv_t), GFP_KERNEL); + if (!l) { + *errp = -ENOMEM; + return NULL; + } + memset(l, 0, sizeof(lv_t)); + err = copy_from_user(l, ul, (long)&((lv32_t *)0)->lv_current_pe); + err |= __copy_from_user(&l->lv_current_le, &ul->lv_current_le, + ((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le)); + err |= __copy_from_user(&l->lv_remap_ptr, &ul->lv_remap_ptr, + ((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr)); + err |= __get_user(ptr1, &ul->lv_current_pe); + err |= __get_user(ptr2, &ul->lv_block_exception); + if (err) { + kfree(l); + *errp = -EFAULT; + return NULL; + } + if (ptr1) { + size = l->lv_allocated_le * sizeof(pe_t); + l->lv_current_pe = vmalloc(size); + if (l->lv_current_pe) + err = copy_from_user(l->lv_current_pe, (void *)A(ptr1), size); + } + if (!err && ptr2) { + size = l->lv_remap_end * sizeof(lv_block_exception_t); + l->lv_block_exception = lbe = vmalloc(size); + if (l->lv_block_exception) { + lbe32 = (lv_block_exception32_t *)A(ptr2); + memset(lbe, 0, size); + for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) { + err |= get_user(lbe->rsector_org, &lbe32->rsector_org); + err |= __get_user(lbe->rdev_org, &lbe32->rdev_org); + err |= __get_user(lbe->rsector_new, &lbe32->rsector_new); + err |= __get_user(lbe->rdev_new, &lbe32->rdev_new); + } + } + } + if (err || (ptr1 && !l->lv_current_pe) || (ptr2 && !l->lv_block_exception)) { + if (!err) + *errp = -ENOMEM; + else + *errp = -EFAULT; + put_lv_t(l); + return NULL; + } + return l; +} + +static int copy_lv_t(u32 ptr, lv_t *l) +{ + int err; + lv32_t *ul = (lv32_t *)A(ptr); + u32 ptr1; + size_t size; + + err = get_user(ptr1, &ul->lv_current_pe); + if (err) + return -EFAULT; + err = copy_to_user(ul, l, (long)&((lv32_t *)0)->lv_current_pe); + err |= __copy_to_user(&ul->lv_current_le, &l->lv_current_le, + ((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le)); + err |= __copy_to_user(&ul->lv_remap_ptr, &l->lv_remap_ptr, + ((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr)); + size = l->lv_allocated_le * sizeof(pe_t); + err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size); + return -EFAULT; +} + +static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + vg_t *v; + union { + lv_req_t lv_req; + le_remap_req_t le_remap; + lv_status_byindex_req_t lv_byindex; + pv_status_req32_t pv_status; + } u; + pv_t p; + int err; + u32 ptr = 0; + int i; + mm_segment_t old_fs; + void *karg = &u; + + switch (cmd) { + case VG_STATUS: + v = kmalloc(sizeof(vg_t), GFP_KERNEL); + if (!v) return -ENOMEM; + karg = v; + break; + case VG_CREATE: + v = kmalloc(sizeof(vg_t), GFP_KERNEL); + if (!v) return -ENOMEM; + if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc) || + __get_user(v->proc, &((vg32_t *)arg)->proc)) { + kfree(v); + return -EFAULT; + } + karg = v; + memset(v->pv, 0, sizeof(v->pv) + sizeof(v->lv)); + if (v->pv_max > ABS_MAX_PV || v->lv_max == ABS_MAX_LV) return -EPERM; + for (i = 0; i < v->pv_max; i++) { + err = __get_user(ptr, &((vg32_t *)arg)->pv[i]); + if (err) break; + if (ptr) { + v->pv[i] = kmalloc(sizeof(pv_t), GFP_KERNEL); + if (!v->pv[i]) { + err = -ENOMEM; + break; + } + err = copy_from_user(v->pv[i], (void *)A(ptr), sizeof(pv32_t) - 8); + if (err) { + err = -EFAULT; + break; + } + v->pv[i]->pe = NULL; v->pv[i]->inode = NULL; + } + } + if (!err) { + for (i = 0; i < v->lv_max; i++) { + err = __get_user(ptr, &((vg32_t *)arg)->lv[i]); + if (err) break; + if (ptr) { + v->lv[i] = get_lv_t(ptr, &err); + if (err) break; + } + } + } + break; + case LV_CREATE: + case LV_EXTEND: + case LV_REDUCE: + case LV_REMOVE: + case LV_STATUS_BYNAME: + err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name)); + if (err) return -EFAULT; + if (cmd != LV_REMOVE) { + err = __get_user(ptr, &((lv_req32_t *)arg)->lv); + if (err) return err; + u.lv_req.lv = get_lv_t(ptr, &err); + } else + u.lv_req.lv = NULL; + break; + case LV_STATUS_BYINDEX: + err = get_user(u.lv_byindex.lv_index, &((lv_status_byindex_req32_t *)arg)->lv_index); + err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv); + if (err) return err; + u.lv_byindex.lv = get_lv_t(ptr, &err); + break; + case VG_EXTEND: + err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8); + if (err) return -EFAULT; + p.pe = NULL; p.inode = NULL; + karg = &p; + break; + case LE_REMAP: + err = copy_from_user(&u.le_remap, (void *)arg, sizeof(le_remap_req32_t)); + if (err) return -EFAULT; + u.le_remap.new_pe = ((le_remap_req32_t *)&u.le_remap)->new_pe; + u.le_remap.old_pe = ((le_remap_req32_t *)&u.le_remap)->old_pe; + break; + case PV_CHANGE: + case PV_STATUS: + err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name)); + if (err) return -EFAULT; + err = __get_user(ptr, &((pv_status_req32_t *)arg)->pv); + if (err) return err; + u.pv_status.pv = &p; + if (cmd == PV_CHANGE) { + err = copy_from_user(&p, (void *)A(ptr), sizeof(pv32_t) - 8); + if (err) return -EFAULT; + p.pe = NULL; p.inode = NULL; + } + break; + } + old_fs = get_fs(); set_fs (KERNEL_DS); + err = sys_ioctl (fd, cmd, (unsigned long)karg); + set_fs (old_fs); + switch (cmd) { + case VG_STATUS: + if (!err) { + if (copy_to_user((void *)arg, v, (long)&((vg32_t *)0)->proc) || + clear_user(&((vg32_t *)arg)->proc, sizeof(vg32_t) - (long)&((vg32_t *)0)->proc)) + err = -EFAULT; + } + kfree(v); + break; + case VG_CREATE: + for (i = 0; i < v->pv_max; i++) + if (v->pv[i]) kfree(v->pv[i]); + for (i = 0; i < v->lv_max; i++) + if (v->lv[i]) put_lv_t(v->lv[i]); + kfree(v); + break; + case LV_STATUS_BYNAME: + if (!err && u.lv_req.lv) err = copy_lv_t(ptr, u.lv_req.lv); + /* Fall through */ + case LV_CREATE: + case LV_EXTEND: + case LV_REDUCE: + if (u.lv_req.lv) put_lv_t(u.lv_req.lv); + break; + case LV_STATUS_BYINDEX: + if (u.lv_byindex.lv) { + if (!err) err = copy_lv_t(ptr, u.lv_byindex.lv); + put_lv_t(u.lv_byindex.lv); + } + case PV_STATUS: + if (!err) { + err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8); + if (err) return -EFAULT; + } + break; + } + return err; +} +#endif + static int ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg) { return -EINVAL; @@ -2027,6 +2383,39 @@ static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, struct blkpg_ioc return err; } +typedef struct blkelv_ioctl32_arg_s { + u32 queue_ID; + int read_latency; + int write_latency; + int max_bomb_segments; +} blkelv_ioctl32_arg_t; + +static int do_blkelv_ioctl(unsigned int fd, unsigned int cmd, blkelv_ioctl32_arg_t *arg) +{ + blkelv_ioctl_arg_t b; + int err; + mm_segment_t old_fs = get_fs(); + + if (cmd == BLKELVSET) { + err = get_user((long)b.queue_ID, &arg->queue_ID); + err |= __get_user(b.read_latency, &arg->read_latency); + err |= __get_user(b.write_latency, &arg->write_latency); + err |= __get_user(b.max_bomb_segments, &arg->max_bomb_segments); + if (err) return err; + } + set_fs (KERNEL_DS); + err = sys_ioctl(fd, cmd, (unsigned long)&b); + set_fs (old_fs); + if (cmd == BLKELVGET && !err) { + err = put_user((long)b.queue_ID, &arg->queue_ID); + err |= __put_user(b.read_latency, &arg->read_latency); + err |= __put_user(b.write_latency, &arg->write_latency); + err |= __put_user(b.max_bomb_segments, &arg->max_bomb_segments); + if (err) return err; + } + return err; +} + static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg) { return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); @@ -2548,6 +2937,24 @@ COMPATIBLE_IOCTL(ATMTCP_CREATE) COMPATIBLE_IOCTL(ATMTCP_REMOVE) COMPATIBLE_IOCTL(ATMMPC_CTRL) COMPATIBLE_IOCTL(ATMMPC_DATA) +#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) +/* 0xfe - lvm */ +COMPATIBLE_IOCTL(VG_SET_EXTENDABLE) +COMPATIBLE_IOCTL(VG_STATUS_GET_COUNT) +COMPATIBLE_IOCTL(VG_STATUS_GET_NAMELIST) +COMPATIBLE_IOCTL(VG_REMOVE) +COMPATIBLE_IOCTL(VG_REDUCE) +COMPATIBLE_IOCTL(PE_LOCK_UNLOCK) +COMPATIBLE_IOCTL(PV_FLUSH) +COMPATIBLE_IOCTL(LVM_LOCK_LVM) +COMPATIBLE_IOCTL(LVM_GET_IOP_VERSION) +#ifdef LVM_TOTAL_RESET +COMPATIBLE_IOCTL(LVM_RESET) +#endif +COMPATIBLE_IOCTL(LV_SET_ACCESS) +COMPATIBLE_IOCTL(LV_SET_STATUS) +COMPATIBLE_IOCTL(LV_SET_ALLOCATION) +#endif /* LVM */ /* And these ioctls need translation */ HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32) HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf) @@ -2594,6 +3001,8 @@ HANDLE_IOCTL(0x1260, broken_blkgetsize) HANDLE_IOCTL(BLKFRAGET, w_long) HANDLE_IOCTL(BLKSECTGET, w_long) HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans) +HANDLE_IOCTL(BLKELVGET, do_blkelv_ioctl) +HANDLE_IOCTL(BLKELVSET, do_blkelv_ioctl) HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap) HANDLE_IOCTL(FBIOGETCMAP32, fbiogetputcmap) HANDLE_IOCTL(FBIOSCURSOR32, fbiogscursor) @@ -2677,6 +3086,20 @@ HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl) HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl) HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl) HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl) +#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE) +HANDLE_IOCTL(VG_STATUS, do_lvm_ioctl) +HANDLE_IOCTL(VG_CREATE, do_lvm_ioctl) +HANDLE_IOCTL(VG_EXTEND, do_lvm_ioctl) +HANDLE_IOCTL(LV_CREATE, do_lvm_ioctl) +HANDLE_IOCTL(LV_REMOVE, do_lvm_ioctl) +HANDLE_IOCTL(LV_EXTEND, do_lvm_ioctl) +HANDLE_IOCTL(LV_REDUCE, do_lvm_ioctl) +HANDLE_IOCTL(LV_STATUS_BYNAME, do_lvm_ioctl) +HANDLE_IOCTL(LV_STATUS_BYINDEX, do_lvm_ioctl) +HANDLE_IOCTL(LE_REMAP, do_lvm_ioctl) +HANDLE_IOCTL(PV_CHANGE, do_lvm_ioctl) +HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl) +#endif /* LVM */ IOCTL_TABLE_END unsigned int ioctl32_hash_table[1024]; diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index 0d1b968fa..f0c9460fa 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.52 2000/03/03 23:48:41 davem Exp $ +/* $Id: setup.c,v 1.53 2000/03/15 14:42:52 jj Exp $ * linux/arch/sparc64/kernel/setup.c * * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu) @@ -431,8 +431,6 @@ extern void panic_setup(char *, int *); extern unsigned short root_flags; extern unsigned short root_dev; extern unsigned short ram_flags; -extern unsigned int sparc_ramdisk_image; -extern unsigned int sparc_ramdisk_size; #define RAMDISK_IMAGE_START_MASK 0x07FF #define RAMDISK_PROMPT_FLAG 0x8000 #define RAMDISK_LOAD_FLAG 0x4000 @@ -512,29 +510,6 @@ void __init setup_arch(char **cmdline_p) rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0); rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0); #endif -#ifdef CONFIG_BLK_DEV_INITRD -// FIXME needs to do the new bootmem alloc stuff - if (sparc_ramdisk_image) { - unsigned long start = 0; - - if (sparc_ramdisk_image >= (unsigned long)&end - 2 * PAGE_SIZE) - sparc_ramdisk_image -= KERNBASE; - initrd_start = sparc_ramdisk_image + phys_base + PAGE_OFFSET; - initrd_end = initrd_start + sparc_ramdisk_size; - if (initrd_end > *memory_end_p) { - printk(KERN_CRIT "initrd extends beyond end of memory " - "(0x%016lx > 0x%016lx)\ndisabling initrd\n", - initrd_end,*memory_end_p); - initrd_start = 0; - } - if (initrd_start) - start = sparc_ramdisk_image + KERNBASE; - if (start >= *memory_start_p && start < *memory_start_p + 2 * PAGE_SIZE) { - initrd_below_start_ok = 1; - *memory_start_p = PAGE_ALIGN (start + sparc_ramdisk_size); - } - } -#endif /* Due to stack alignment restrictions and assumptions... */ init_mm.mmap->vm_page_prot = PAGE_SHARED; diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index b4ee5625e..0d5f615cf 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -528,7 +528,7 @@ static unsigned long penguins_are_doing_time = 0; void smp_capture(void) { if (smp_processors_ready) { - int result = atomic_add_return(1, &smp_capture_depth); + int result = __atomic_add(1, &smp_capture_depth); membar("#StoreStore | #LoadStore"); if(result == 1) { @@ -596,18 +596,21 @@ void smp_promstop_others(void) smp_cross_call(&xcall_promstop, 0, 0, 0); } -static inline void sparc64_do_profile(unsigned long pc, unsigned long g3) +static inline void sparc64_do_profile(unsigned long pc, unsigned long o7) { if (prof_buffer && current->pid) { extern int _stext; extern int rwlock_impl_begin, rwlock_impl_end; extern int atomic_impl_begin, atomic_impl_end; + extern int __memcpy_begin, __memcpy_end; - if ((pc >= (unsigned long) &rwlock_impl_begin && + if ((pc >= (unsigned long) &atomic_impl_begin && + pc < (unsigned long) &atomic_impl_end) || + (pc >= (unsigned long) &rwlock_impl_begin && pc < (unsigned long) &rwlock_impl_end) || - (pc >= (unsigned long) &atomic_impl_begin && - pc < (unsigned long) &atomic_impl_end)) - pc = g3; + (pc >= (unsigned long) &__memcpy_begin && + pc < (unsigned long) &__memcpy_end)) + pc = o7; pc -= (unsigned long) &_stext; pc >>= prof_shift; @@ -646,7 +649,7 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs) clear_softint((1UL << 0)); do { if(!user) - sparc64_do_profile(regs->tpc, regs->u_regs[UREG_G3]); + sparc64_do_profile(regs->tpc, regs->u_regs[UREG_RETPC]); if(!--prof_counter(cpu)) { if (cpu == boot_cpu_id) { diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index f798358ce..26e11085d 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.75 2000/02/21 15:50:08 davem Exp $ +/* $Id: sparc64_ksyms.c,v 1.79 2000/03/17 14:41:18 davem Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -109,10 +109,10 @@ extern unsigned long phys_base; */ #define EXPORT_SYMBOL_PRIVATE(sym) \ -extern int __sparc_priv_ ## sym (int) __asm__("__" ## #sym); \ +extern int __sparc_priv_ ## sym (int) __asm__("__" #sym); \ const struct module_symbol __export_priv_##sym \ __attribute__((section("__ksymtab"))) = \ -{ (unsigned long) &__sparc_priv_ ## sym, "__" ## #sym } +{ (unsigned long) &__sparc_priv_ ## sym, "__" #sym } /* used by various drivers */ #ifdef __SMP__ @@ -142,6 +142,8 @@ EXPORT_SYMBOL(cpu_data); /* Misc SMP information */ EXPORT_SYMBOL(smp_num_cpus); +EXPORT_SYMBOL(__cpu_number_map); +EXPORT_SYMBOL(__cpu_logical_map); /* Spinlock debugging library, optional. */ #ifdef SPIN_LOCK_DEBUG @@ -207,6 +209,7 @@ EXPORT_SYMBOL(pci_map_sg); EXPORT_SYMBOL(pci_unmap_sg); EXPORT_SYMBOL(pci_dma_sync_single); EXPORT_SYMBOL(pci_dma_sync_sg); +EXPORT_SYMBOL(pci_dma_supported); #endif /* Solaris/SunOS binary compatibility */ @@ -288,6 +291,9 @@ EXPORT_SYMBOL(move_addr_to_user); EXPORT_SYMBOL(__memcpy); EXPORT_SYMBOL(__memset); EXPORT_SYMBOL(clear_page); +EXPORT_SYMBOL(copy_page); +EXPORT_SYMBOL(clear_user_page); +EXPORT_SYMBOL(copy_user_page); EXPORT_SYMBOL(__bzero); EXPORT_SYMBOL(__memscan_zero); EXPORT_SYMBOL(__memscan_generic); diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 81b4c4de1..82aedbb08 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.36 2000/02/16 07:31:35 davem Exp $ +/* $Id: sys_sparc.c,v 1.37 2000/03/17 05:48:46 anton Exp $ * linux/arch/sparc64/kernel/sys_sparc.c * * This file contains various random system calls that @@ -348,9 +348,10 @@ asmlinkage int solaris_syscall(struct pt_regs *regs) lock_kernel(); regs->tpc = regs->tnpc; regs->tnpc += 4; - if(++count <= 20) + if(++count <= 5) { printk ("For Solaris binary emulation you need solaris module loaded\n"); - show_regs (regs); + show_regs (regs); + } send_sig(SIGSEGV, current, 1); unlock_kernel(); return -ENOSYS; diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index d4ecb0f4f..763acdc0f 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.136 2000/03/13 21:57:29 davem Exp $ +/* $Id: sys_sparc32.c,v 1.139 2000/03/16 20:37:57 davem Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -1746,70 +1746,58 @@ static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel) return 0; } -extern asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type, - unsigned long new_flags, void *data); +extern long do_sys_mount(char * dev_name, char * dir_name, unsigned long type_page, + unsigned long new_flags, unsigned long data_page); #define SMBFS_NAME "smbfs" #define NCPFS_NAME "ncpfs" asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data) { - unsigned long type_page; + unsigned long type_page = 0; + unsigned long data_page = 0; int err, is_smb, is_ncp; - if(!capable(CAP_SYS_ADMIN)) - return -EPERM; is_smb = is_ncp = 0; + + lock_kernel(); err = copy_mount_stuff_to_kernel((const void *)type, &type_page); - if(err) - return err; - if(type_page) { - is_smb = !strcmp((char *)type_page, SMBFS_NAME); - is_ncp = !strcmp((char *)type_page, NCPFS_NAME); + if (err) + goto out; + + if (!type_page) { + err = -EINVAL; + goto out; } - if(!is_smb && !is_ncp) { - if(type_page) - free_page(type_page); - return sys_mount(dev_name, dir_name, type, new_flags, (void *)AA(data)); - } else { - unsigned long dev_page, dir_page, data_page; - mm_segment_t old_fs; - err = copy_mount_stuff_to_kernel((const void *)dev_name, &dev_page); - if(err) - goto out; - err = copy_mount_stuff_to_kernel((const void *)dir_name, &dir_page); - if(err) - goto dev_out; - err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page); - if(err) - goto dir_out; - if(is_ncp) + is_smb = !strcmp((char *)type_page, SMBFS_NAME); + is_ncp = !strcmp((char *)type_page, NCPFS_NAME); + + err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page); + if (err) + goto type_out; + + if (!is_smb && !is_ncp) { + err = do_sys_mount(dev_name, dir_name, type_page, new_flags, + data_page); + } else { + if (is_ncp) do_ncp_super_data_conv((void *)data_page); - else if(is_smb) - do_smb_super_data_conv((void *)data_page); else - panic("The problem is here..."); - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_mount((char *)dev_page, (char *)dir_page, - (char *)type_page, new_flags, - (void *)data_page); - set_fs(old_fs); + do_smb_super_data_conv((void *)data_page); - if(data_page) - free_page(data_page); - dir_out: - if(dir_page) - free_page(dir_page); - dev_out: - if(dev_page) - free_page(dev_page); - out: - if(type_page) - free_page(type_page); - return err; + err = do_sys_mount(dev_name, dir_name, type_page, new_flags, + data_page); } + + free_page(data_page); + +type_out: + free_page(type_page); + +out: + unlock_kernel(); + return err; } struct rusage32 { @@ -3071,7 +3059,7 @@ do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs) memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0])); lock_kernel(); - dentry = open_namei(filename, 0, 0); + dentry = open_namei(filename); unlock_kernel(); retval = PTR_ERR(dentry); @@ -4166,7 +4154,7 @@ asmlinkage long sparc32_open(const char * filename, int flags, int mode) if (fd >= 0) { struct file * f; lock_kernel(); - f = filp_open(tmp, flags, mode); + f = filp_open(tmp, flags, mode, NULL); unlock_kernel(); error = PTR_ERR(f); if (IS_ERR(f)) @@ -4218,12 +4206,3 @@ out_sem: out: return ret; } - -extern asmlinkage long sys_mincore(unsigned long start, size_t len, unsigned char *vec); - -asmlinkage long sys32_mincore(unsigned long start, u32 __len, unsigned char *vec) -{ - size_t len = (size_t) __len; - - return sys_mincore(start, len, vec); -} diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index f7f5964e9..a572e4976 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sunos32.c,v 1.41 2000/03/13 21:57:31 davem Exp $ +/* $Id: sys_sunos32.c,v 1.42 2000/03/15 02:43:35 davem Exp $ * sys_sunos32.c: SunOS binary compatability layer on sparc64. * * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -225,33 +225,6 @@ asmlinkage void sunos_vadvise(u32 strategy) unlock_kernel(); } -/* Same as vadvise, and just as bogus, but for a range of virtual - * process address space. - */ -#define MADV_NORMAL 0 /* Nothing special... */ -#define MADV_RANDOM 1 /* I am emacs... */ -#define MADV_SEQUENTIAL 2 /* I am researcher code... */ -#define MADV_WILLNEED 3 /* Pages in this range will be needed */ -#define MADV_DONTNEED 4 /* Pages in this range won't be needed */ - -static char *mstrings[] = { - "MADV_NORMAL", - "MADV_RANDOM", - "MADV_SEQUENTIAL", - "MADV_WILLNEED", - "MADV_DONTNEED", -}; - -asmlinkage void sunos_madvise(u32 address, u32 len, u32 strategy) -{ - /* I wanna see who uses this... */ - lock_kernel(); - printk("%s: Advises us to use %s paging strategy for addr<%08x> len<%08x>\n", - current->comm, strategy <= 4 ? mstrings[strategy] : "BOGUS", - address, len); - unlock_kernel(); -} - /* This just wants the soft limit (ie. rlim_cur element) of the RLIMIT_NOFILE * resource limit and is for backwards compatibility with older sunos * revs. diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 0a0edbf82..d86649bf7 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.69 2000/03/13 21:57:28 davem Exp $ +/* $Id: systbls.S,v 1.71 2000/03/15 02:43:36 davem Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -34,7 +34,7 @@ sys_call_table32: /*60*/ .word sys_umask, sys_chroot, sys32_newfstat, sys_fstat64, sys_getpagesize .word sys_msync, sys_vfork, sys32_pread, sys32_pwrite, sys_geteuid /*70*/ .word sys_getegid, sys32_mmap, sys_setreuid, sys_munmap, sys_mprotect - .word sys_nis_syscall, sys_vhangup, sys32_truncate64, sys32_mincore, sys32_getgroups16 + .word sys_madvise, sys_vhangup, sys32_truncate64, sys_mincore, sys32_getgroups16 /*80*/ .word sys32_setgroups16, sys_getpgrp, sys_setgroups, sys32_setitimer, sys32_ftruncate64 .word sys_swapon, sys32_getitimer, sys_setuid, sys_sethostname, sys_setgid /*90*/ .word sys_dup2, sys_setfsuid, sys32_fcntl, sys32_select, sys_setfsgid @@ -93,7 +93,7 @@ sys_call_table: /*60*/ .word sys_umask, sys_chroot, sys_newfstat, sys_nis_syscall, sys_getpagesize .word sys_msync, sys_vfork, sys_pread, sys_pwrite, sys_nis_syscall /*70*/ .word sys_nis_syscall, sys_mmap, sys_nis_syscall, sys64_munmap, sys_mprotect - .word sys_nis_syscall, sys_vhangup, sys_nis_syscall, sys_mincore, sys_getgroups + .word sys_madvise, sys_vhangup, sys_nis_syscall, sys_mincore, sys_getgroups /*80*/ .word sys_setgroups, sys_getpgrp, sys_nis_syscall, sys_setitimer, sys_nis_syscall .word sys_swapon, sys_getitimer, sys_nis_syscall, sys_sethostname, sys_nis_syscall /*90*/ .word sys_dup2, sys_nis_syscall, sys_fcntl, sys_select, sys_nis_syscall @@ -163,8 +163,8 @@ sunos_sys_table: .word sys_msync, sys_vfork, sunos_nosys .word sunos_nosys, sunos_sbrk, sunos_sstk .word sunos_mmap, sunos_vadvise, sys_munmap - .word sys_mprotect, sunos_madvise, sys_vhangup - .word sunos_nosys, sys32_mincore, sys32_getgroups16 + .word sys_mprotect, sys_madvise, sys_vhangup + .word sunos_nosys, sys_mincore, sys32_getgroups16 .word sys32_setgroups16, sys_getpgrp, sunos_setpgrp .word sys32_setitimer, sunos_nosys, sys_swapon .word sys32_getitimer, sys_gethostname, sys_sethostname diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c index 792334336..989e965a9 100644 --- a/arch/sparc64/kernel/unaligned.c +++ b/arch/sparc64/kernel/unaligned.c @@ -1,4 +1,4 @@ -/* $Id: unaligned.c,v 1.18 1999/08/02 08:39:44 davem Exp $ +/* $Id: unaligned.c,v 1.19 2000/03/16 11:53:05 jj Exp $ * unaligned.c: Unaligned load/store trap handling with special * cases for the kernel to do them more quickly. * @@ -590,9 +590,19 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) maybe_flush_windows(0, 0, rd, from_kernel); reg = fetch_reg_addr(rd, regs); - if ((insn & 0x780000) == 0x180000) - reg[1] = 0; - reg[0] = 0; + if (from_kernel || rd < 16) { + reg[0] = 0; + if ((insn & 0x780000) == 0x180000) + reg[1] = 0; + } else if (current->thread.flags & SPARC_FLAG_32BIT) { + put_user(0, (int *)reg); + if ((insn & 0x780000) == 0x180000) + put_user(0, ((int *)reg) + 1); + } else { + put_user(0, reg); + if ((insn & 0x780000) == 0x180000) + put_user(0, reg + 1); + } advance(regs); } |