Ioctl Numbers
-5 Apr 1997
+10 Apr 1997
Michael Chastain
<mec@shout.net>
'W' 28-2F linux/iso16-relay.h in development
'Y' all linux/cyclades.h
'a' all various, see http://lrcwww.epfl.ch/linux-atm/magic.html
+'b' 00-3F bit3 vme host bridge in development:
+ <mailto:natalia@nikhefk.nikhef.nl>
'c' all linux/comstats.h
'f' all linux/ext2_fs.h
'l' 00-3F linux/tcfs_fs.h in development:
'm' all linux/mtio.h conflict!
'm' all linux/soundcard.h conflict!
'n' all linux/ncp_fs.h
-'p' all linux/mc146818rtc.h
+'p' 00-3F linux/mc146818rtc.h
+'p' 40-7F linux/nvram.h
'r' all linux/msdos_fs.h
's' all linux/cdk.h
't' 00-7F linux/if_ppp.h
0x89 F0-FF linux/sockios.h SIOCDEVPRIVATE range
0x8B all linux/wireless.h
0x8C 00-3F WiNRADiO driver in development:
- <mailto:brian@proximity.com.au>
+ <http://www.proximity.com.au/~brian/winradio/>
0x90 00 linux/sbpcd.h
+0x93 60-7F linux/auto_fs.h
0x99 00-0F 537-Addinboard driver in development:
<mailto:b.kohl@ipn-b.comlink.apc.org>
0xA0 all Small Device Project in development:
@$(MAKEBOOT) BOOTIMAGE=bzImage zdisk
install: vmlinux
- @$(MAKEBOOT) BOOTIMAGE=zImage install
+ @$(MAKEBOOT) BOOTIMAGE=bzImage install
archclean:
@$(MAKEBOOT) clean
sep_bug = CD(have_cpuid) &&
(CD(x86_capability) & 0x800) &&
+ !memcmp(x86_vendor_id, "GenuineIntel", 12) &&
+ CD(x86) == 6 &&
CD(x86_model) < 3 &&
CD(x86_mask) < 3;
#define MAGIC_CONSTANT 0x80000000
-extern void do_wp_page(struct task_struct * tsk, struct vm_area_struct * vma,
- unsigned long address, int write_access);
-
-extern void do_no_page(struct task_struct * tsk, struct vm_area_struct * vma,
- unsigned long address, int write_access);
-
/*
* This routine gets a long from any process space by following the page
* tables. NOTE! You should check that the long isn't on a page boundary,
repeat:
pgdir = pgd_offset(vma->vm_mm, addr);
if (pgd_none(*pgdir)) {
- do_no_page(tsk, vma, addr, 0);
+ handle_mm_fault(tsk, vma, addr, 0);
goto repeat;
}
if (pgd_bad(*pgdir)) {
}
pgmiddle = pmd_offset(pgdir, addr);
if (pmd_none(*pgmiddle)) {
- do_no_page(tsk, vma, addr, 0);
+ handle_mm_fault(tsk, vma, addr, 0);
goto repeat;
}
if (pmd_bad(*pgmiddle)) {
}
pgtable = pte_offset(pgmiddle, addr);
if (!pte_present(*pgtable)) {
- do_no_page(tsk, vma, addr, 0);
+ handle_mm_fault(tsk, vma, addr, 0);
goto repeat;
}
page = pte_page(*pgtable);
repeat:
pgdir = pgd_offset(vma->vm_mm, addr);
if (!pgd_present(*pgdir)) {
- do_no_page(tsk, vma, addr, 1);
+ handle_mm_fault(tsk, vma, addr, 1);
goto repeat;
}
if (pgd_bad(*pgdir)) {
}
pgmiddle = pmd_offset(pgdir, addr);
if (pmd_none(*pgmiddle)) {
- do_no_page(tsk, vma, addr, 1);
+ handle_mm_fault(tsk, vma, addr, 1);
goto repeat;
}
if (pmd_bad(*pgmiddle)) {
}
pgtable = pte_offset(pgmiddle, addr);
if (!pte_present(*pgtable)) {
- do_no_page(tsk, vma, addr, 1);
+ handle_mm_fault(tsk, vma, addr, 1);
goto repeat;
}
page = pte_page(*pgtable);
if (!pte_write(*pgtable)) {
- do_wp_page(tsk, vma, addr, 1);
+ handle_mm_fault(tsk, vma, addr, 1);
goto repeat;
}
/* this is a hack for non-kernel-mapped video buffers and similar */
-/* $Id: signal.c,v 1.73 1997/04/16 05:56:05 davem Exp $
+/* $Id: signal.c,v 1.74 1997/05/15 19:57:09 davem Exp $
* linux/arch/sparc/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV: case SIGBUS:
if(current->binfmt && current->binfmt->core_dump) {
+ lock_kernel();
if(current->binfmt->core_dump(signr, regs))
signr |= 0x80;
+ unlock_kernel();
}
#ifdef DEBUG_SIGNALS
/* Very useful to debug dynamic linker problems */
-/* $Id: asyncd.c,v 1.9 1996/12/18 06:43:22 tridge Exp $
+/* $Id: asyncd.c,v 1.10 1997/05/15 21:14:24 davem Exp $
* The asyncd kernel daemon. This handles paging on behalf of
* processes that receive page faults due to remote (async) memory
* accesses.
if(!pte)
goto no_memory;
if(!pte_present(*pte)) {
- do_no_page(tsk, vma, address, write);
+ handle_mm_fault(tsk, vma, address, write);
goto finish_up;
}
set_pte(pte, pte_mkyoung(*pte));
flush_tlb_page(vma, address);
goto finish_up;
}
- do_wp_page(tsk, vma, address, write);
+ handle_mm_fault(tsk, vma, address, write);
/* Fall through for do_wp_page */
finish_up:
stats.success++;
- update_mmu_cache(vma, address, *pte);
return 0;
no_memory:
-/* $Id: fault.c,v 1.91 1997/03/18 17:56:00 jj Exp $
+/* $Id: fault.c,v 1.92 1997/05/15 21:14:21 davem Exp $
* fault.c: Page fault handlers for the Sparc.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
- handle_mm_fault(vma, address, write);
+ handle_mm_fault(current, vma, address, write);
up(&mm->mmap_sem);
goto out;
/*
else
if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
- handle_mm_fault(vma, address, write);
+ handle_mm_fault(current, vma, address, write);
up(&mm->mmap_sem);
return;
bad_area:
-/* $Id: asyncd.c,v 1.1 1996/12/26 10:24:24 davem Exp $
+/* $Id: asyncd.c,v 1.2 1997/05/15 21:14:32 davem Exp $
* The asyncd kernel daemon. This handles paging on behalf of
* processes that receive page faults due to remote (async) memory
* accesses.
if(!pte)
goto no_memory;
if(!pte_present(*pte)) {
- do_no_page(tsk, vma, address, write);
+ handle_mm_fault(tsk, vma, address, write);
goto finish_up;
}
set_pte(pte, pte_mkyoung(*pte));
flush_tlb_page(vma, address);
goto finish_up;
}
- do_wp_page(tsk, vma, address, write);
+ handle_mm_fault(tsk, vma, address, write);
/* Fall through for do_wp_page */
finish_up:
stats.success++;
- update_mmu_cache(vma, address, *pte);
return 0;
no_memory:
-/* $Id: fault.c,v 1.4 1997/03/11 17:37:07 jj Exp $
+/* $Id: fault.c,v 1.5 1997/05/15 21:14:31 davem Exp $
* arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
- handle_mm_fault(vma, address, write);
+ handle_mm_fault(current, vma, address, write);
up(&mm->mmap_sem);
goto out;
/*
#include <linux/string.h>
#include <linux/wait.h>
-#if LINUX_VERSION_CODE < 0x20100
+#define kver(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+
+#if LINUX_VERSION_CODE < kver(2,1,0)
/* Segmentation stuff for pre-2.1 kernels */
#include <asm/segment.h>
-#define copy_to_user memcpy_tofs
-#define copy_from_user memcpy_fromfs
+
+static inline int copy_to_user(void *dst, void *src, unsigned long len)
+{
+ int rv = verify_area(VERIFY_WRITE, dst, len);
+ if ( rv )
+ return -1;
+ memcpy_tofs(dst,src,len);
+ return 0;
+}
+
+static inline int copy_from_user(void *dst, void *src, unsigned long len)
+{
+ int rv = verify_area(VERIFY_READ, src, len);
+ if ( rv )
+ return -1;
+ memcpy_fromfs(dst,src,len);
+ return 0;
+}
#else
*
* ------------------------------------------------------------------------- */
-#include <linux/init.h>
#include <linux/module.h>
#include "autofs_i.h"
+#if LINUX_VERSION_CODE < kver(2,1,36)
+#define __initfunc(X) X
+#else
+#include <linux/init.h>
+#endif
+
static struct file_system_type autofs_fs_type = {
autofs_read_super, "autofs", 0, NULL
};
int rv;
unsigned long ntimeout;
+#if LINUX_VERSION_CODE < kver(2,1,0)
+ if ( (rv = verify_area(VERIFY_WRITE, p, sizeof(unsigned long))) )
+ return rv;
+ ntimeout = get_user(p);
+ put_user(sbi->exp_timeout/HZ, p);
+#else
if ( (rv = get_user(ntimeout, p)) ||
(rv = put_user(sbi->exp_timeout/HZ, p)) )
return rv;
+#endif
if ( ntimeout > ULONG_MAX/HZ )
sbi->exp_timeout = 0;
return 0;
}
+/* Return protocol version */
+static inline int autofs_get_protover(int *p)
+{
+#if LINUX_VERSION_CODE < kver(2,1,0)
+ int rv;
+ if ( (rv = verify_area(VERIFY_WRITE, p, sizeof(int))) )
+ return rv;
+ put_user(AUTOFS_PROTO_VERSION, p);
+ return 0;
+#else
+ return put_user(AUTOFS_PROTO_VERSION, p);
+#endif
+}
+
/* Perform an expiry operation */
static inline int autofs_expire_run(struct autofs_sb_info *sbi,
struct autofs_packet_expire *pkt_p)
autofs_catatonic_mode(sbi);
return 0;
case AUTOFS_IOC_PROTOVER: /* Get protocol version */
- return put_user(AUTOFS_PROTO_VERSION, (int *)arg);
+ return autofs_get_protover((int *)arg);
case AUTOFS_IOC_SETTIMEOUT:
return autofs_get_set_timeout(sbi,(unsigned long *)arg);
case AUTOFS_IOC_EXPIRE:
unsigned short fs;
unsigned long old_signal;
const char *data = (const char *)addr;
- int written;
+ int written = 0;
/** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/
*/
#define IPV6_ADDRFORM 1
-#define IPV6_RXINFO 2
+#define IPV6_PKTINFO 2
#define IPV6_RXHOPOPTS 3
#define IPV6_RXDSTOPTS 4
#define IPV6_RXSRCRT 5
/*
* Alternative names
*/
-#define IPV6_TXINFO IPV6_RXINFO
-#define SCM_SRCINFO IPV6_TXINFO
#define SCM_SRCRT IPV6_RXSRCRT
#define IPV6_UNICAST_HOPS 16
__kernel_size_t cmsg_len; /* data byte count, including hdr */
int cmsg_level; /* originating protocol */
int cmsg_type; /* protocol-specific type */
- unsigned char cmsg_data[0];
};
/*
* Table 5-14 of POSIX 1003.1g
*/
-#define CMSG_DATA(cmsg) (cmsg)->cmsg_data
#define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr(mhdr, cmsg)
#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )
-/* Stevens's Adv. API specifies CMSG_SPACE & CMSG_LENGTH,
- * I cannot understand, what the differenece? --ANK
- */
-
-#define CMSG_SPACE(len) CMSG_ALIGN((len)+sizeof(struct cmsghdr))
-#define CMSG_LENGTH(len) CMSG_ALIGN((len)+sizeof(struct cmsghdr))
+#define CMSG_DATA(cmsg) ((void *)(cmsg) + CMSG_ALIGN(sizeof(struct cmsghdr)))
+#define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len))
+#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
#define CMSG_FIRSTHDR(msg) ((msg)->msg_controllen >= sizeof(struct cmsghdr) ? \
(struct cmsghdr *)(msg)->msg_control : \
#define AF_DECNET 12 /* Reserved for DECnet project */
#define AF_NETBEUI 13 /* Reserved for 802.2LLC project*/
#define AF_SECURITY 14 /* Security callback pseudo AF */
+#define pseudo_AF_KEY 15 /* PF_KEY key management API */
#define AF_MAX 32 /* For now.. */
/* Protocol families, same as address families. */
#define PF_DECNET AF_DECNET
#define PF_NETBEUI AF_NETBEUI
#define PF_SECURITY AF_SECURITY
+#define PF_KEY pseudo_AF_KEY
#define PF_MAX AF_MAX
bad_wp_page:
printk("do_wp_page: bogus page at address %08lx (%08lx)\n",address,old_page);
send_sig(SIGKILL, tsk, 1);
- goto end_wp_page;
end_wp_page:
if (new_page)
free_page(new_page);
/* scm.c - Socket level control messages processing.
*
* Author: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+ * Alignment and value checking mods by Craig Metz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
int num;
struct scm_fp_list *fpl = *fplp;
struct file **fpp;
- int *fdp = (int*)cmsg->cmsg_data;
+ int *fdp = (int*)CMSG_DATA(cmsg);
int i;
- num = (cmsg->cmsg_len - sizeof(struct cmsghdr))/sizeof(int);
+ num = (cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)))/sizeof(int);
- if (!num)
+ if (num <= 0)
return 0;
if (num > SCM_MAX_FD)
goto error;
break;
case SCM_CREDENTIALS:
- if (cmsg->cmsg_len < sizeof(*cmsg) + sizeof(struct ucred))
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred)))
goto error;
- memcpy(&p->creds, cmsg->cmsg_data, sizeof(struct ucred));
+ memcpy(&p->creds, CMSG_DATA(cmsg), sizeof(struct ucred));
err = scm_check_creds(&p->creds);
if (err)
goto error;
case SCM_CONNECT:
if (scm_flags)
goto error;
- if (cmsg->cmsg_len < sizeof(*cmsg) + sizeof(int))
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
goto error;
- memcpy(&acc_fd, cmsg->cmsg_data, sizeof(int));
+ memcpy(&acc_fd, CMSG_DATA(cmsg), sizeof(int));
p->sock = NULL;
if (acc_fd != -1) {
if (acc_fd < 0 || acc_fd >= NR_OPEN ||
void put_cmsg(struct msghdr * msg, int level, int type, int len, void *data)
{
struct cmsghdr *cm = (struct cmsghdr*)msg->msg_control;
- int cmlen = sizeof(*cm) + len;
+ int cmlen = CMSG_LEN(len);
int err;
if (cm==NULL || msg->msg_controllen < sizeof(*cm)) {
if (!err)
err = put_user(cmlen, &cm->cmsg_len);
if (!err)
- err = copy_to_user(cm->cmsg_data, data, cmlen - sizeof(*cm));
+ err = copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr));
if (!err) {
- cmlen = CMSG_ALIGN(cmlen);
+ cmlen = CMSG_SPACE(len);
msg->msg_control += cmlen;
msg->msg_controllen -= cmlen;
}
if (fdnum < fdmax)
fdmax = fdnum;
- for (i=0, cmfptr=(int*)cm->cmsg_data; i<fdmax; i++, cmfptr++)
+ for (i=0, cmfptr=(int*)CMSG_DATA(cm); i<fdmax; i++, cmfptr++)
{
int new_fd = get_unused_fd();
if (new_fd < 0)
if (i > 0)
{
- int cmlen = i*sizeof(int) + sizeof(struct cmsghdr);
+ int cmlen = CMSG_LEN(i*sizeof(int));
if (!err)
err = put_user(SOL_SOCKET, &cm->cmsg_level);
if (!err)
if (!err)
err = put_user(cmlen, &cm->cmsg_len);
if (!err) {
- cmlen = CMSG_ALIGN(cmlen);
+ cmlen = CMSG_SPACE(i*sizeof(int));
msg->msg_control += cmlen;
msg->msg_controllen -= cmlen;
}
for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
if (cmsg->cmsg_level != SOL_IP)
continue;
- switch (cmsg->cmsg_type)
- {
+ switch (cmsg->cmsg_type) {
case IP_LOCALADDR:
- if (cmsg->cmsg_len < sizeof(struct in_addr)+sizeof(*cmsg))
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct in_addr)))
return -EINVAL;
- memcpy(&ipc->addr, cmsg->cmsg_data, 4);
+ memcpy(&ipc->addr, CMSG_DATA(cmsg), sizeof(struct in_addr));
break;
case IP_RETOPTS:
- err = cmsg->cmsg_len - sizeof(*cmsg);
- err = ip_options_get(&ipc->opt, cmsg->cmsg_data,
- err < 40 ? err : 40, 0);
+ err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr));
+ err = ip_options_get(&ipc->opt, CMSG_DATA(cmsg), err < 40 ? err : 40, 0);
if (err)
return err;
break;
case IP_TXINFO:
{
struct in_pktinfo *info;
- if (cmsg->cmsg_len < sizeof(*info)+sizeof(*cmsg))
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct in_pktinfo)))
return -EINVAL;
- info = (struct in_pktinfo*)cmsg->cmsg_data;
+ info = (struct in_pktinfo *)CMSG_DATA(cmsg);
if (info->ipi_ifindex && !devp)
return -EINVAL;
if ((*devp = dev_get_by_index(info->ipi_ifindex)) == NULL)
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: datagram.c,v 1.11 1997/05/03 00:58:25 davem Exp $
+ * $Id: datagram.c,v 1.12 1997/05/15 18:55:09 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
src_info.ipi6_ifindex = skb->dev->ifindex;
ipv6_addr_copy(&src_info.ipi6_addr, &skb->nh.ipv6h->daddr);
- put_cmsg(msg, SOL_IPV6, IPV6_RXINFO, sizeof(src_info), &src_info);
+ put_cmsg(msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info);
}
if (np->rxhlim) {
for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
if (cmsg->cmsg_level != SOL_IPV6) {
- printk(KERN_DEBUG "cmsg_level %d\n", cmsg->cmsg_level);
+ printk(KERN_DEBUG "invalid cmsg_level %d\n", cmsg->cmsg_level);
continue;
}
switch (cmsg->cmsg_type) {
-
- case IPV6_TXINFO:
- if (cmsg->cmsg_len < (sizeof(struct cmsghdr) +
- sizeof(struct in6_pktinfo))) {
+ case IPV6_PKTINFO:
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct in6_pktinfo))) {
err = -EINVAL;
goto exit_f;
}
- src_info = (struct in6_pktinfo *) cmsg->cmsg_data;
+ src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg);
if (src_info->ipi6_ifindex) {
int index = src_info->ipi6_ifindex;
break;
case IPV6_RXSRCRT:
-
- len = cmsg->cmsg_len;
-
- len -= sizeof(struct cmsghdr);
-
- /* validate option length */
- if (len < sizeof(struct ipv6_rt_hdr)) {
+ if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct ipv6_rt_hdr))) {
err = -EINVAL;
goto exit_f;
}
- rthdr = (struct ipv6_rt_hdr *) cmsg->cmsg_data;
+ len = cmsg->cmsg_len - sizeof(struct cmsghdr);
+ rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg);
/*
* TYPE 0
break;
case IPV6_HOPLIMIT:
-
- len = cmsg->cmsg_len;
- len -= sizeof(struct cmsghdr);
-
- if (len < sizeof(int)) {
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
err = -EINVAL;
goto exit_f;
}
- *hlimit = *((int *) cmsg->cmsg_data);
+ *hlimit = *(int *)CMSG_DATA(cmsg);
break;
default:
- printk(KERN_DEBUG "invalid cmsg type: %d\n",
- cmsg->cmsg_type);
+ printk(KERN_DEBUG "invalid cmsg type: %d\n", cmsg->cmsg_type);
err = -EINVAL;
break;
};
*
* Based on linux/net/ipv4/ip_sockglue.c
*
- * $Id: ipv6_sockglue.c,v 1.12 1997/04/29 09:38:45 mj Exp $
+ * $Id: ipv6_sockglue.c,v 1.13 1997/05/15 18:55:10 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
}
break;
- case IPV6_RXINFO:
+ case IPV6_PKTINFO:
np->rxinfo = val;
retv = 0;
break;