CVSROOT: /home/cvs
Module name: linux
Changes by: ralf@ftp.linux-mips.org 05/01/13 10:59:04
Modified files:
. : Tag: linux_2_4 MAINTAINERS Makefile
arch/ia64/ia32 : Tag: linux_2_4 sys_ia32.c
arch/mips/kernel: Tag: linux_2_4 irixelf.c
arch/mips64/kernel: Tag: linux_2_4 linux32.c
arch/parisc/kernel: Tag: linux_2_4 sys_parisc32.c
arch/ppc64/kernel: Tag: linux_2_4 sys_ppc32.c
arch/s390x/kernel: Tag: linux_2_4 linux32.c
arch/sparc64/kernel: Tag: linux_2_4 binfmt_aout32.c
sys_sparc32.c
drivers/char : Tag: linux_2_4 moxa.c random.c tty_io.c
tty_ioctl.c
drivers/net : Tag: linux_2_4 sungem.c
drivers/net/wan: Tag: linux_2_4 sdla.c
drivers/usb/host: Tag: linux_2_4 ehci-q.c
fs : Tag: linux_2_4 binfmt_aout.c binfmt_elf.c
fs/coda : Tag: linux_2_4 upcall.c
fs/xfs : Tag: linux_2_4 xfs_vfsops.c xfs_vnodeops.c
fs/xfs/linux-2.4: Tag: linux_2_4 xfs_buf.c xfs_ioctl.c
xfs_super.c
include/asm-x86_64: Tag: linux_2_4 socket32.h
include/linux : Tag: linux_2_4 coda.h mm.h pci_ids.h spinlock.h
kernel : Tag: linux_2_4 ksyms.c
mm : Tag: linux_2_4 memory.c mmap.c
net/rose : Tag: linux_2_4 rose_route.c
Added files:
Documentation : Tag: linux_2_4 tty.txt
Log message:
Merge with Linux 2.4.29-rc2.
See http://www.isec.pl/vulnerabilities/isec-0022-pagefault.txt for
details on the security hole fixed by this patch.
diff -urN linux/MAINTAINERS linux/MAINTAINERS
--- linux/MAINTAINERS 2004/12/27 04:13:37 1.76.2.30
+++ linux/MAINTAINERS 2005/01/13 10:59:02 1.76.2.31
@@ -841,7 +841,7 @@
i386 SETUP CODE / CPU ERRATA WORKAROUNDS
P: Dave Jones
-M: davej@suse.de
+M: davej@redhat.com
P: H. Peter Anvin
M: hpa@zytor.com
S: Maintained
diff -urN linux/Makefile linux/Makefile
--- linux/Makefile 2005/01/09 19:33:59 1.119.2.31
+++ linux/Makefile 2005/01/13 10:59:02 1.119.2.32
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 29
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
diff -urN linux/Documentation/tty.txt linux/Documentation/tty.txt
--- linux/Documentation/tty.txt 1970/01/01 00:00:00
+++ linux/Documentation/tty.txt Thu Jan 13 10:59:02 2005 1.3.2.1
@@ -0,0 +1,194 @@
+
+ The Lockronomicon
+
+Your guide to the ancient and twisted locking policies of the tty layer and
+the warped logic behind them. Beware all ye who read on.
+
+FIXME: still need to work out the full set of BKL assumptions and document
+them so they can eventually be killed off.
+
+
+Line Discipline
+---------------
+
+Line disciplines are registered with tty_register_ldisc() passing the
+discipline number and the ldisc structure. At the point of registration the
+discipline must be ready to use and it is possible it will get used before
+the call returns success. If the call returns an error then it won't get
+called. Do not re-use ldisc numbers as they are part of the userspace ABI
+and writing over an existing ldisc will cause demons to eat your computer.
+After the return the ldisc data has been copied so you may free your own
+copy of the structure. You must not re-register over the top of the line
+discipline even with the same data or your computer again will be eaten by
+demons.
+
+In order to remove a line discipline call tty_register_ldisc passing NULL.
+In ancient times this always worked. In modern times the function will
+return -EBUSY if the ldisc is currently in use. Since the ldisc referencing
+code manages the module counts this should not usually be a concern.
+
+Heed this warning: the reference count field of the registered copies of the
+tty_ldisc structure in the ldisc table counts the number of lines using this
+discipline. The reference count of the tty_ldisc structure within a tty
+counts the number of active users of the ldisc at this instant. In effect it
+counts the number of threads of execution within an ldisc method (plus those
+about to enter and exit although this detail matters not).
+
+Line Discipline Methods
+-----------------------
+
+TTY side interfaces:
+
+close() - This is called on a terminal when the line
+ discipline is being unplugged. At the point of
+ execution no further users will enter the
+ ldisc code for this tty. Can sleep.
+
+open() - Called when the line discipline is attached to
+ the terminal. No other call into the line
+ discipline for this tty will occur until it
+ completes successfully. Can sleep.
+
+write() - A process is writing data from user space
+ through the line discipline. Multiple write calls
+ are serialized by the tty layer for the ldisc. May
+ sleep.
+
+flush_buffer() - May be called at any point between open and close.
+
+chars_in_buffer() - Report the number of bytes in the buffer.
+
+set_termios() - Called on termios structure changes. The caller
+ passes the old termios data and the current data
+ is in the tty. Currently can be parallel entered
+ and ordering isn't predictable - FIXME
+
+read() - Move data from the line discipline to the user.
+ Multiple read calls may occur in parallel and the
+ ldisc must deal with serialization issues. May
+ sleep.
+
+poll() - Check the status for the poll/select calls. Multiple
+ poll calls may occur in parallel. May sleep.
+
+ioctl() - Called when an ioctl is handed to the tty layer
+ that might be for the ldisc. Multiple ioctl calls
+ may occur in parallel. May sleep.
+
+Driver Side Interfaces:
+
+receive_buf() - Hand buffers of bytes from the driver to the ldisc
+ for processing. Semantics currently rather
+ mysterious 8(
+
+receive_room() - Can be called by the driver layer at any time when
+ the ldisc is opened. The ldisc must be able to
+ handle the reported amount of data at that instant.
+ Synchronization between active receive_buf and
+ receive_room calls is down to the driver not the
+ ldisc. Must not sleep.
+
+write_wakeup() - May be called at any point between open and close.
+ The TTY_DO_WRITE_WAKEUP flag indicates if a call
+ is needed but always races versus calls. Thus the
+ ldisc must be careful about setting order and to
+ handle unexpected calls. Must not sleep.
+
+
+Locking
+
+Callers to the line discipline functions from the tty layer are required to
+take line discipline locks. The same is true of calls from the driver side
+but not yet enforced.
+
+Three calls are now provided
+
+ ldisc = tty_ldisc_ref(tty);
+
+takes a handle to the line discipline in the tty and returns it. If no ldisc
+is currently attached or the ldisc is being closed and re-opened at this
+point then NULL is returned. While this handle is held the ldisc will not
+change or go away.
+
+ tty_ldisc_deref(ldisc)
+
+Returns the ldisc reference and allows the ldisc to be closed. Returning the
+reference takes away your right to call the ldisc functions until you take
+a new reference.
+
+ ldisc = tty_ldisc_ref_wait(tty);
+
+Performs the same function as tty_ldisc_ref except that it will wait for an
+ldisc change to complete and then return a reference to the new ldisc.
+
+While these functions are slightly slower than the old code they should have
+minimal impact as most receive logic uses the flip buffers and they only
+need to take a reference when they push bits up through the driver.
+
+A caution: The ldisc->open(), ldisc->close() and driver->set_ldisc
+functions are called with the ldisc unavailable. Thus tty_ldisc_ref will
+fail in this situation if used within these functions. Ldisc and driver
+code calling its own functions must be careful in this case.
+
+
+Driver Interface
+----------------
+
+open() - Called when a device is opened. May sleep
+
+close() - Called when a device is closed. At the point of
+ return from this call the driver must make no
+ further ldisc calls of any kind. May sleep
+
+write() - Called to write bytes to the device. May not
+ sleep. May occur in parallel in special cases.
+ Because this includes panic paths drivers generally
+ shouldn't try and do clever locking here.
+
+put_char() - Stuff a single character onto the queue. The
+ driver is guaranteed following up calls to
+ flush_chars.
+
+flush_chars() - Ask the kernel to write put_char queue
+
+write_room() - Return the number of characters tht can be stuffed
+ into the port buffers without overflow (or less).
+ The ldisc is responsible for being intelligent
+ about multi-threading of write_room/write calls
+
+ioctl() - Called when an ioctl may be for the driver
+
+set_termios() - Called on termios change, serialized against
+ itself by a semaphore. May sleep.
+
+set_ldisc() - Notifier for discipline change. At the point this
+ is done the discipline is not yet usable. Can now
+ sleep (I think)
+
+throttle() - Called by the ldisc to ask the driver to do flow
+ control. Serialization including with unthrottle
+ is the job of the ldisc layer.
+
+unthrottle() - Called by the ldisc to ask the driver to stop flow
+ control.
+
+stop() - Ldisc notifier to the driver to stop output. As with
+ throttle the serializations with start() are down
+ to the ldisc layer.
+
+start() - Ldisc notifier to the driver to start output.
+
+hangup() - Ask the tty driver to cause a hangup initiated
+ from the host side. [Can sleep ??]
+
+break_ctl() - Send RS232 break. Can sleep. Can get called in
+ parallel, driver must serialize (for now), and
+ with write calls.
+
+wait_until_sent() - Wait for characters to exit the hardware queue
+ of the driver. Can sleep
+
+send_xchar() - Send XON/XOFF and if possible jump the queue with
+ it in order to get fast flow control responses.
+ Cannot sleep ??
+
diff -urN linux/arch/ia64/ia32/sys_ia32.c linux/arch/ia64/ia32/sys_ia32.c
--- linux/arch/ia64/ia32/sys_ia32.c 2004/12/27 04:13:39 1.22.2.10
+++ linux/arch/ia64/ia32/sys_ia32.c 2005/01/13 10:59:02 1.22.2.11
@@ -1370,7 +1370,7 @@
((len) >= sizeof(struct cmsghdr32) ? (struct cmsghdr32 *)(ctl) :
(struct cmsghdr32 *)NULL)
#define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control,
(msg)->msg_controllen)
#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
- ((ucmlen) >= sizeof(struct cmsghdr) && \
+ ((ucmlen) >= sizeof(struct cmsghdr32) && \
(ucmlen) <= (unsigned long) \
((mhdr)->msg_controllen - \
((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
diff -urN linux/arch/mips/kernel/irixelf.c linux/arch/mips/kernel/irixelf.c
--- linux/arch/mips/kernel/irixelf.c 2005/01/09 19:34:01 1.40.2.4
+++ linux/arch/mips/kernel/irixelf.c 2005/01/13 10:59:02 1.40.2.5
@@ -130,7 +130,10 @@
end = PAGE_ALIGN(end);
if (end <= start)
return;
- do_brk_locked(start, end - start);
+
+ down_write(¤t->mm->mmap_sem);
+ do_brk(start, end - start);
+ up_write(¤t->mm->mmap_sem);
}
@@ -379,7 +382,9 @@
/* Map the last of the bss segment */
if (last_bss > len) {
- do_brk_locked(len, (last_bss - len));
+ down_write(¤t->mm->mmap_sem);
+ do_brk(len, (last_bss - len));
+ up_write(¤t->mm->mmap_sem);
}
kfree(elf_phdata);
@@ -567,7 +572,9 @@
unsigned long v;
struct prda *pp;
- v = do_brk_locked (PRDA_ADDRESS, PAGE_SIZE);
+ down_write(¤t->mm->mmap_sem);
+ v = do_brk (PRDA_ADDRESS, PAGE_SIZE);
+ up_write(¤t->mm->mmap_sem);
if (v < 0)
return;
@@ -858,8 +865,11 @@
len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
- if (bss > len)
- do_brk_locked(len, bss-len);
+ if (bss > len) {
+ down_write(¤t->mm->mmap_sem);
+ do_brk(len, bss-len);
+ up_write(¤t->mm->mmap_sem);
+ }
kfree(elf_phdata);
return 0;
}
diff -urN linux/arch/mips64/kernel/linux32.c linux/arch/mips64/kernel/linux32.c
--- linux/arch/mips64/kernel/Attic/linux32.c 2004/12/27 04:13:39
1.42.2.43
+++ linux/arch/mips64/kernel/Attic/linux32.c 2005/01/13 10:59:02
1.42.2.44
@@ -2484,7 +2484,7 @@
(struct cmsghdr32 *)NULL)
#define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control,
(msg)->msg_controllen)
#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
- ((ucmlen) >= sizeof(struct cmsghdr) && \
+ ((ucmlen) >= sizeof(struct cmsghdr32) && \
(ucmlen) <= (unsigned long) \
((mhdr)->msg_controllen - \
((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
diff -urN linux/arch/parisc/kernel/sys_parisc32.c
linux/arch/parisc/kernel/sys_parisc32.c
--- linux/arch/parisc/kernel/sys_parisc32.c 2004/12/27 04:13:39 1.1.2.3
+++ linux/arch/parisc/kernel/sys_parisc32.c 2005/01/13 10:59:02 1.1.2.4
@@ -1815,7 +1815,7 @@
(struct cmsghdr32 *)NULL)
#define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control,
(msg)->msg_controllen)
#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
- ((ucmlen) >= sizeof(struct cmsghdr) && \
+ ((ucmlen) >= sizeof(struct cmsghdr32) && \
(ucmlen) <= (unsigned long) \
((mhdr)->msg_controllen - \
((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
diff -urN linux/arch/ppc64/kernel/sys_ppc32.c
linux/arch/ppc64/kernel/sys_ppc32.c
--- linux/arch/ppc64/kernel/sys_ppc32.c 2004/12/27 04:13:40 1.1.2.8
+++ linux/arch/ppc64/kernel/sys_ppc32.c 2005/01/13 10:59:02 1.1.2.9
@@ -3274,7 +3274,7 @@
(struct cmsghdr32 *)NULL)
#define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control,
(msg)->msg_controllen)
#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
- ((ucmlen) >= sizeof(struct cmsghdr) && \
+ ((ucmlen) >= sizeof(struct cmsghdr32) && \
(ucmlen) <= (unsigned long) \
((mhdr)->msg_controllen - \
((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
diff -urN linux/arch/s390x/kernel/linux32.c linux/arch/s390x/kernel/linux32.c
--- linux/arch/s390x/kernel/Attic/linux32.c 2004/12/27 04:13:40 1.7.2.6
+++ linux/arch/s390x/kernel/Attic/linux32.c 2005/01/13 10:59:02 1.7.2.7
@@ -2307,7 +2307,7 @@
(struct cmsghdr32 *)NULL)
#define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control,
(msg)->msg_controllen)
#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
- ((ucmlen) >= sizeof(struct cmsghdr) && \
+ ((ucmlen) >= sizeof(struct cmsghdr32) && \
(ucmlen) <= (unsigned long) \
((mhdr)->msg_controllen - \
((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
diff -urN linux/arch/sparc64/kernel/binfmt_aout32.c
linux/arch/sparc64/kernel/binfmt_aout32.c
--- linux/arch/sparc64/kernel/binfmt_aout32.c 2005/01/09 19:34:02 1.20.2.2
+++ linux/arch/sparc64/kernel/binfmt_aout32.c 2005/01/13 10:59:03 1.20.2.3
@@ -49,7 +49,9 @@
end = PAGE_ALIGN(end);
if (end <= start)
return;
- do_brk_locked(start, end - start);
+ down_write(¤t->mm->mmap_sem);
+ do_brk(start, end - start);
+ up_write(¤t->mm->mmap_sem);
}
/*
@@ -246,10 +248,14 @@
if (N_MAGIC(ex) == NMAGIC) {
loff_t pos = fd_offset;
/* Fuck me plenty... */
- error = do_brk_locked(N_TXTADDR(ex), ex.a_text);
+ down_write(¤t->mm->mmap_sem);
+ error = do_brk(N_TXTADDR(ex), ex.a_text);
+ up_write(¤t->mm->mmap_sem);
bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex),
ex.a_text, &pos);
- error = do_brk_locked(N_DATADDR(ex), ex.a_data);
+ down_write(¤t->mm->mmap_sem);
+ error = do_brk(N_DATADDR(ex), ex.a_data);
+ up_write(¤t->mm->mmap_sem);
bprm->file->f_op->read(bprm->file, (char *) N_DATADDR(ex),
ex.a_data, &pos);
goto beyond_if;
@@ -257,8 +263,11 @@
if (N_MAGIC(ex) == OMAGIC) {
loff_t pos = fd_offset;
- do_brk_locked(N_TXTADDR(ex) & PAGE_MASK,
+ down_write(¤t->mm->mmap_sem);
+ do_brk(N_TXTADDR(ex) & PAGE_MASK,
ex.a_text+ex.a_data + PAGE_SIZE - 1);
+ up_write(¤t->mm->mmap_sem);
+
bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex),
ex.a_text+ex.a_data, &pos);
} else {
@@ -272,7 +281,9 @@
if (!bprm->file->f_op->mmap) {
loff_t pos = fd_offset;
- do_brk_locked(0, ex.a_text+ex.a_data);
+ down_write(¤t->mm->mmap_sem);
+ do_brk(0, ex.a_text+ex.a_data);
+ up_write(¤t->mm->mmap_sem);
bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex),
ex.a_text+ex.a_data, &pos);
goto beyond_if;
@@ -388,7 +399,9 @@
len = PAGE_ALIGN(ex.a_text + ex.a_data);
bss = ex.a_text + ex.a_data + ex.a_bss;
if (bss > len) {
- error = do_brk_locked(start_addr + len, bss - len);
+ down_write(¤t->mm->mmap_sem);
+ error = do_brk(start_addr + len, bss - len);
+ up_write(¤t->mm->mmap_sem);
retval = error;
if (error != start_addr + len)
goto out;
diff -urN linux/arch/sparc64/kernel/sys_sparc32.c
linux/arch/sparc64/kernel/sys_sparc32.c
--- linux/arch/sparc64/kernel/sys_sparc32.c 2004/12/27 04:13:40
1.60.2.13
+++ linux/arch/sparc64/kernel/sys_sparc32.c 2005/01/13 10:59:03
1.60.2.14
@@ -2355,7 +2355,7 @@
(struct cmsghdr32 *)NULL)
#define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control,
(msg)->msg_controllen)
#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
- ((ucmlen) >= sizeof(struct cmsghdr) && \
+ ((ucmlen) >= sizeof(struct cmsghdr32) && \
(ucmlen) <= (unsigned long) \
((mhdr)->msg_controllen - \
((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
diff -urN linux/drivers/char/moxa.c linux/drivers/char/moxa.c
--- linux/drivers/char/moxa.c 2004/12/27 04:13:42 1.9.2.1
+++ linux/drivers/char/moxa.c 2005/01/13 10:59:03 1.9.2.2
@@ -905,6 +905,8 @@
case TIOCSSERIAL:
return (moxa_set_serial_info(ch, (struct serial_struct *) arg));
default:
+ if(!capable(CAP_SYS_RAWIO))
+ return -EPERM;
retval = MoxaDriverIoctl(cmd, arg, port);
}
return (retval);
diff -urN linux/drivers/char/random.c linux/drivers/char/random.c
--- linux/drivers/char/random.c 2004/11/19 00:28:37 1.26.2.5
+++ linux/drivers/char/random.c 2005/01/13 10:59:03 1.26.2.6
@@ -1771,7 +1771,7 @@
static int proc_do_poolsize(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
{
- int ret;
+ unsigned int ret;
sysctl_poolsize = random_state->poolinfo.POOLBYTES;
diff -urN linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c
--- linux/drivers/char/tty_io.c 2004/12/27 04:13:43 1.62.2.16
+++ linux/drivers/char/tty_io.c 2005/01/13 10:59:03 1.62.2.17
@@ -478,7 +478,6 @@
int retval = 0;
struct tty_ldisc o_ldisc;
char buf[64];
- int work;
unsigned long flags;
struct tty_ldisc *ld;
diff -urN linux/drivers/char/tty_ioctl.c linux/drivers/char/tty_ioctl.c
--- linux/drivers/char/tty_ioctl.c 2004/12/27 04:13:43 1.10.2.2
+++ linux/drivers/char/tty_ioctl.c 2005/01/13 10:59:03 1.10.2.3
@@ -387,7 +387,6 @@
struct tty_struct * real_tty;
int retval;
struct tty_ldisc *ld;
- unsigned long flags;
if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
tty->driver.subtype == PTY_TYPE_MASTER)
diff -urN linux/drivers/net/sungem.c linux/drivers/net/sungem.c
--- linux/drivers/net/sungem.c 2004/11/19 00:28:39 1.8.2.7
+++ linux/drivers/net/sungem.c 2005/01/13 10:59:03 1.8.2.8
@@ -119,6 +119,8 @@
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_GMACP,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_GMAC2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{0, }
};
diff -urN linux/drivers/net/wan/sdla.c linux/drivers/net/wan/sdla.c
--- linux/drivers/net/wan/sdla.c 2002/09/11 12:45:09 1.11.2.2
+++ linux/drivers/net/wan/sdla.c 2005/01/13 10:59:03 1.11.2.3
@@ -1300,6 +1300,8 @@
case SDLA_WRITEMEM:
case SDLA_READMEM:
+ if(!capable(CAP_SYS_RAWIO))
+ return -EPERM;
return(sdla_xfer(dev, (struct sdla_mem *)ifr->ifr_data,
cmd == SDLA_READMEM));
case SDLA_START:
diff -urN linux/drivers/usb/host/ehci-q.c linux/drivers/usb/host/ehci-q.c
--- linux/drivers/usb/host/ehci-q.c 2004/02/20 01:22:18 1.22.2.4
+++ linux/drivers/usb/host/ehci-q.c 2005/01/13 10:59:03 1.22.2.5
@@ -83,11 +83,11 @@
/*-------------------------------------------------------------------------*/
-/* update halted (but potentially linked) qh */
-
static inline void
qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
{
+ BUG_ON(qh->qh_state != QH_STATE_IDLE);
+
qh->hw_qtd_next = QTD_NEXT (qtd->qtd_dma);
qh->hw_alt_next = EHCI_LIST_END;
@@ -96,6 +96,24 @@
qh->hw_token &= __constant_cpu_to_le32 (QTD_TOGGLE | QTD_STS_PING);
}
+static void
+qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
+{
+ struct ehci_qtd *qtd;
+
+ if (list_empty (&qh->qtd_list))
+ qtd = qh->dummy;
+ else {
+ qtd = list_entry (qh->qtd_list.next,
+ struct ehci_qtd, qtd_list);
+ /* first qtd may already be partially processed */
+ if (cpu_to_le32 (qtd->qtd_dma) == qh->hw_current)
+ qtd = NULL;
+ }
+ if (qtd)
+ qh_update (ehci, qh, qtd);
+}
+
/*-------------------------------------------------------------------------*/
static void qtd_copy_status (
@@ -261,6 +279,7 @@
spin_lock (&ehci->lock);
}
+static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
/*
* Process and free completed qtds for a qh, returning URBs to drivers.
@@ -401,21 +420,20 @@
/* restore original state; caller must unlink or relink */
qh->qh_state = state;
- /* update qh after fault cleanup */
- if (unlikely (stopped != 0)
- /* some EHCI 0.95 impls will overlay dummy qtds */
- || qh->hw_qtd_next == EHCI_LIST_END) {
- if (list_empty (&qh->qtd_list))
- end = qh->dummy;
- else {
- end = list_entry (qh->qtd_list.next,
- struct ehci_qtd, qtd_list);
- /* first qtd may already be partially processed */
- if (cpu_to_le32 (end->qtd_dma) == qh->hw_current)
- end = 0;
+ /* be sure the hardware's done with the qh before refreshing
+ * it after fault cleanup, or recovering from silicon wrongly
+ * overlaying the dummy qtd (which reduces DMA chatter).
+ */
+ if (stopped != 0 || qh->hw_qtd_next == EHCI_LIST_END) {
+ switch (state) {
+ case QH_STATE_IDLE:
+ qh_refresh(ehci, qh);
+ break;
+ case QH_STATE_LINKED:
+ start_unlink_async (ehci, qh);
+ break;
+ /* otherwise, unlink already started */
}
- if (end)
- qh_update (ehci, qh, end);
}
return count;
@@ -742,8 +760,8 @@
qh->qh_state = QH_STATE_IDLE;
qh->hw_info1 = cpu_to_le32 (info1);
qh->hw_info2 = cpu_to_le32 (info2);
- qh_update (ehci, qh, qh->dummy);
usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
+ qh_refresh (ehci, qh);
return qh;
}
@@ -765,11 +783,6 @@
if (!(cmd & CMD_ASE)) {
/* in case a clear of CMD_ASE didn't take yet */
(void) handshake (&ehci->regs->status, STS_ASS, 0, 150);
-
- /* force async head to be valid */
- writel ((u32)ehci->async->qh_dma,
- &ehci->regs->async_next);
-
cmd |= CMD_ASE | CMD_RUN;
writel (cmd, &ehci->regs->command);
ehci->hcd.state = USB_STATE_RUNNING;
@@ -777,7 +790,9 @@
}
}
- qh->hw_token &= ~HALT_BIT;
+ /* clear halt and/or toggle; and maybe recover from silicon quirk */
+ if (qh->qh_state == QH_STATE_IDLE)
+ qh_refresh (ehci, qh);
/* splice right after start */
qh->qh_next = head->qh_next;
@@ -972,8 +987,6 @@
/* the async qh for the qtds being reclaimed are now unlinked from the HC */
-static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
-
static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs)
{
struct ehci_qh *qh = ehci->reclaim;
diff -urN linux/fs/binfmt_aout.c linux/fs/binfmt_aout.c
--- linux/fs/binfmt_aout.c 2005/01/09 19:34:04 1.37.2.2
+++ linux/fs/binfmt_aout.c 2005/01/13 10:59:03 1.37.2.3
@@ -46,7 +46,10 @@
start = PAGE_ALIGN(start);
end = PAGE_ALIGN(end);
if (end > start) {
- unsigned long addr = do_brk_locked(start, end - start);
+ unsigned long addr;
+ down_write(¤t->mm->mmap_sem);
+ addr = do_brk(start, end - start);
+ up_write(¤t->mm->mmap_sem);
if (BAD_ADDR(addr))
return addr;
}
@@ -317,10 +320,14 @@
loff_t pos = fd_offset;
/* Fuck me plenty... */
/* <AOL></AOL> */
- error = do_brk_locked(N_TXTADDR(ex), ex.a_text);
+ down_write(¤t->mm->mmap_sem);
+ error = do_brk(N_TXTADDR(ex), ex.a_text);
+ up_write(¤t->mm->mmap_sem);
bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex),
ex.a_text, &pos);
- error = do_brk_locked(N_DATADDR(ex), ex.a_data);
+ down_write(¤t->mm->mmap_sem);
+ error = do_brk(N_DATADDR(ex), ex.a_data);
+ up_write(¤t->mm->mmap_sem);
bprm->file->f_op->read(bprm->file, (char *) N_DATADDR(ex),
ex.a_data, &pos);
goto beyond_if;
@@ -340,8 +347,9 @@
pos = 32;
map_size = ex.a_text+ex.a_data;
#endif
-
- error = do_brk_locked(text_addr & PAGE_MASK, map_size);
+ down_write(¤t->mm->mmap_sem);
+ error = do_brk(text_addr & PAGE_MASK, map_size);
+ up_write(¤t->mm->mmap_sem);
if (error != (text_addr & PAGE_MASK)) {
send_sig(SIGKILL, current, 0);
return error;
@@ -375,7 +383,9 @@
if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
loff_t pos = fd_offset;
- do_brk_locked(N_TXTADDR(ex), ex.a_text+ex.a_data);
+ down_write(¤t->mm->mmap_sem);
+ do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
+ up_write(¤t->mm->mmap_sem);
bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex),
ex.a_text+ex.a_data, &pos);
flush_icache_range((unsigned long) N_TXTADDR(ex),
@@ -475,8 +485,10 @@
file->f_dentry->d_name.name);
error_time = jiffies;
}
-
- do_brk_locked(start_addr, ex.a_text + ex.a_data + ex.a_bss);
+
+ down_write(¤t->mm->mmap_sem);
+ do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
+ up_write(¤t->mm->mmap_sem);
file->f_op->read(file, (char *)start_addr,
ex.a_text + ex.a_data, &pos);
@@ -500,7 +512,10 @@
len = PAGE_ALIGN(ex.a_text + ex.a_data);
bss = ex.a_text + ex.a_data + ex.a_bss;
if (bss > len) {
- error = do_brk_locked(start_addr + len, bss - len);
+ down_write(¤t->mm->mmap_sem);
+ error = do_brk(start_addr + len, bss - len);
+ up_write(¤t->mm->mmap_sem);
+
retval = error;
if (error != start_addr + len)
goto out;
diff -urN linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- linux/fs/binfmt_elf.c 2005/01/09 19:34:04 1.52.2.15
+++ linux/fs/binfmt_elf.c 2005/01/13 10:59:03 1.52.2.16
@@ -84,7 +84,10 @@
start = ELF_PAGEALIGN(start);
end = ELF_PAGEALIGN(end);
if (end > start) {
- unsigned long addr = do_brk_locked(start, end - start);
+ unsigned long addr;
+ down_write(¤t->mm->mmap_sem);
+ addr = do_brk(start, end - start);
+ up_write(¤t->mm->mmap_sem);
if (BAD_ADDR(addr))
return addr;
}
@@ -379,7 +382,9 @@
/* Map the last of the bss segment */
if (last_bss > elf_bss) {
- error = do_brk_locked(elf_bss, last_bss - elf_bss);
+ down_write(¤t->mm->mmap_sem);
+ error = do_brk(elf_bss, last_bss - elf_bss);
+ up_write(¤t->mm->mmap_sem);
if (BAD_ADDR(error))
goto out_close;
}
@@ -425,7 +430,10 @@
goto out;
}
- do_brk_locked(0, text_data);
+ down_write(¤t->mm->mmap_sem);
+ do_brk(0, text_data);
+ up_write(¤t->mm->mmap_sem);
+
if (!interpreter->f_op || !interpreter->f_op->read)
goto out;
if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0)
@@ -433,8 +441,11 @@
flush_icache_range((unsigned long)addr,
(unsigned long)addr + text_data);
- do_brk_locked(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
+ down_write(¤t->mm->mmap_sem);
+ do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
interp_ex->a_bss);
+ up_write(¤t->mm->mmap_sem);
+
elf_entry = interp_ex->a_entry;
out:
@@ -976,8 +987,11 @@
len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr +
ELF_MIN_ALIGN - 1);
bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
- if (bss > len)
- do_brk_locked(len, bss - len);
+ if (bss > len) {
+ down_write(¤t->mm->mmap_sem);
+ do_brk(len, bss - len);
+ up_write(¤t->mm->mmap_sem);
+ }
error = 0;
out_free_ph:
diff -urN linux/fs/coda/upcall.c linux/fs/coda/upcall.c
--- linux/fs/coda/upcall.c 2002/06/26 22:36:19 1.19.2.2
+++ linux/fs/coda/upcall.c 2005/01/13 10:59:03 1.19.2.3
@@ -543,6 +543,11 @@
goto exit;
}
+ if (data->vi.out_size > VC_MAXDATASIZE) {
+ error = -EINVAL;
+ goto exit;
+ }
+
inp->coda_ioctl.VFid = *fid;
/* the cmd field was mutated by increasing its size field to
@@ -571,26 +576,30 @@
error, coda_f2s(fid));
goto exit;
}
-
- /* Copy out the OUT buffer. */
+
+ if (outsize < (long)outp->coda_ioctl.data + outp->coda_ioctl.len) {
+ CDEBUG(D_FILE, "reply size %d < reply len %ld\n", outsize,
+ (long)outp->coda_ioctl.data + outp->coda_ioctl.len);
+ error = -EINVAL;
+ goto exit;
+ }
+
if (outp->coda_ioctl.len > data->vi.out_size) {
- CDEBUG(D_FILE, "return len %d <= request len %d\n",
- outp->coda_ioctl.len,
- data->vi.out_size);
+ CDEBUG(D_FILE, "return len %d > request len %d\n",
+ outp->coda_ioctl.len, data->vi.out_size);
error = -EINVAL;
- } else {
- error = verify_area(VERIFY_WRITE, data->vi.out,
- data->vi.out_size);
- if ( error ) goto exit;
-
- if (copy_to_user(data->vi.out,
- (char *)outp + (long)outp->coda_ioctl.data,
- data->vi.out_size)) {
- error = -EINVAL;
- goto exit;
- }
+ goto exit;
}
+ /* Copy out the OUT buffer. */
+ error = verify_area(VERIFY_WRITE, data->vi.out, outp->coda_ioctl.len);
+ if ( error ) goto exit;
+
+ if (copy_to_user(data->vi.out,
+ (char *)outp + (long)outp->coda_ioctl.data,
+ outp->coda_ioctl.len)) {
+ error = -EINVAL;
+ }
exit:
CODA_FREE(inp, insize);
return error;
diff -urN linux/fs/xfs/xfs_vfsops.c linux/fs/xfs/xfs_vfsops.c
--- linux/fs/xfs/xfs_vfsops.c 2004/12/27 04:13:53 1.22.2.7
+++ linux/fs/xfs/xfs_vfsops.c 2005/01/13 10:59:04 1.22.2.8
@@ -1580,7 +1580,7 @@
}
/*
- * xfs_vget - called by DMAPI to get vnode from file handle
+ * xfs_vget - called by DMAPI and NFSD to get vnode from file handle
*/
STATIC int
xfs_vget(
@@ -1622,7 +1622,7 @@
return XFS_ERROR(EIO);
}
- if (ip->i_d.di_mode == 0 || (igen && (ip->i_d.di_gen != igen))) {
+ if (ip->i_d.di_mode == 0 || ip->i_d.di_gen != igen) {
xfs_iput_new(ip, XFS_ILOCK_SHARED);
*vpp = NULL;
return XFS_ERROR(ENOENT);
diff -urN linux/fs/xfs/xfs_vnodeops.c linux/fs/xfs/xfs_vnodeops.c
--- linux/fs/xfs/xfs_vnodeops.c 2004/12/27 04:13:53 1.18.2.5
+++ linux/fs/xfs/xfs_vnodeops.c 2005/01/13 10:59:04 1.18.2.6
@@ -3900,7 +3900,7 @@
int error;
if (vp && VN_BAD(vp))
- return 0;
+ goto reclaim;
/* The hash lock here protects a thread in xfs_iget_core from
* racing with us on linking the inode back with a vnode.
@@ -3948,8 +3948,7 @@
*/
if (error) {
xfs_iunlock(ip, XFS_ILOCK_EXCL);
- xfs_ireclaim(ip);
- return (0);
+ goto reclaim;
}
xfs_iflock(ip); /* synchronize with xfs_iflush_done */
}
@@ -3968,6 +3967,7 @@
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
+ reclaim:
xfs_ireclaim(ip);
return 0;
}
diff -urN linux/fs/xfs/linux-2.4/xfs_buf.c linux/fs/xfs/linux-2.4/xfs_buf.c
--- linux/fs/xfs/linux-2.4/Attic/xfs_buf.c 2004/12/27 04:13:53 1.1.2.3
+++ linux/fs/xfs/linux-2.4/Attic/xfs_buf.c 2005/01/13 10:59:04 1.1.2.4
@@ -1073,6 +1073,7 @@
return(locked ? 0 : -EBUSY);
}
+#ifdef DEBUG
/*
* pagebuf_lock_value
*
@@ -1084,6 +1085,7 @@
{
return(atomic_read(&pb->pb_sema.count));
}
+#endif
/*
* pagebuf_lock
@@ -1547,6 +1549,7 @@
case EVMS_MAJOR:
btp->pbr_flags = PBR_ALIGNED_ONLY;
break;
+ case LOOP_MAJOR:
case LVM_BLK_MAJOR:
btp->pbr_flags = PBR_SECTOR_ONLY;
break;
diff -urN linux/fs/xfs/linux-2.4/xfs_ioctl.c linux/fs/xfs/linux-2.4/xfs_ioctl.c
--- linux/fs/xfs/linux-2.4/Attic/xfs_ioctl.c 2004/12/27 04:13:53 1.1.2.3
+++ linux/fs/xfs/linux-2.4/Attic/xfs_ioctl.c 2005/01/13 10:59:04 1.1.2.4
@@ -497,7 +497,7 @@
xfs_fsop_attrmulti_handlereq_t am_hreq;
struct inode *inode;
vnode_t *vp;
- int i, size;
+ unsigned int i, size;
error = xfs_vget_fsop_handlereq(mp, parinode, CAP_SYS_ADMIN, arg,
sizeof(xfs_fsop_attrmulti_handlereq_t),
@@ -507,6 +507,11 @@
return -error;
size = am_hreq.opcount * sizeof(attr_multiop_t);
+ if (!size || size > 16 * PAGE_SIZE) {
+ VN_RELE(vp);
+ return -XFS_ERROR(E2BIG);
+ }
+
ops = (xfs_attr_multiop_t *)kmalloc(size, GFP_KERNEL);
if (!ops) {
VN_RELE(vp);
diff -urN linux/fs/xfs/linux-2.4/xfs_super.c linux/fs/xfs/linux-2.4/xfs_super.c
--- linux/fs/xfs/linux-2.4/Attic/xfs_super.c 2004/12/27 04:13:53 1.1.2.3
+++ linux/fs/xfs/linux-2.4/Attic/xfs_super.c 2005/01/13 10:59:04 1.1.2.4
@@ -787,10 +787,14 @@
xfid.fid_gen = data[1];
xfid.fid_ino = (__u64)data[0];
} else {
- if (fhtype == 4)
- xfid.fid_gen = data[3];
- else
- xfid.fid_gen = 0;
+ if (fhtype != 4) {
+ printk(KERN_WARNING
+ "XFS: detected filehandle without "
+ "parent inode generation information.");
+ return ERR_PTR(-ESTALE);
+ }
+
+ xfid.fid_gen = data[3];
xfid.fid_ino = (__u64)data[2];
}
diff -urN linux/include/asm-x86_64/socket32.h
linux/include/asm-x86_64/socket32.h
--- linux/include/asm-x86_64/Attic/socket32.h 2004/12/27 04:13:54 1.1.2.2
+++ linux/include/asm-x86_64/Attic/socket32.h 2005/01/13 10:59:04 1.1.2.3
@@ -46,7 +46,7 @@
(struct cmsghdr32 *)NULL)
#define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control,
(msg)->msg_controllen)
#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
- ((ucmlen) >= sizeof(struct cmsghdr) && \
+ ((ucmlen) >= sizeof(struct cmsghdr32) && \
(ucmlen) <= (unsigned long) \
((mhdr)->msg_controllen - \
((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
diff -urN linux/include/linux/coda.h linux/include/linux/coda.h
--- linux/include/linux/coda.h 2001/06/13 17:28:15 1.12
+++ linux/include/linux/coda.h 2005/01/13 10:59:04 1.12.2.1
@@ -767,8 +767,8 @@
#define PIOCPARM_MASK 0x0000ffff
struct ViceIoctl {
caddr_t in, out; /* Data to be transferred in, or out */
- short in_size; /* Size of input buffer <= 2K */
- short out_size; /* Maximum size of output buffer, <= 2K */
+ u_short in_size; /* Size of input buffer <= 2K */
+ u_short out_size; /* Maximum size of output buffer, <= 2K */
};
struct PioctlData {
diff -urN linux/include/linux/mm.h linux/include/linux/mm.h
--- linux/include/linux/mm.h 2005/01/09 19:34:04 1.63.2.10
+++ linux/include/linux/mm.h 2005/01/13 10:59:04 1.63.2.11
@@ -575,7 +575,6 @@
extern int do_munmap(struct mm_struct *, unsigned long, size_t);
extern unsigned long do_brk(unsigned long, unsigned long);
-extern unsigned long do_brk_locked(unsigned long, unsigned long);
static inline void __vma_unlink(struct mm_struct * mm, struct vm_area_struct *
vma, struct vm_area_struct * prev)
{
@@ -648,18 +647,33 @@
unsigned long grow;
/*
- * vma->vm_start/vm_end cannot change under us because the caller is
required
- * to hold the mmap_sem in write mode. We need to get the spinlock only
- * before relocating the vma range ourself.
+ * vma->vm_start/vm_end cannot change under us because the caller
+ * is required to hold the mmap_sem in read mode. We need the
+ * page_table_lock lock to serialize against concurrent expand_stacks.
*/
address &= PAGE_MASK;
spin_lock(&vma->vm_mm->page_table_lock);
+
+ /* already expanded while we were spinning? */
+ if (vma->vm_start <= address) {
+ spin_unlock(&vma->vm_mm->page_table_lock);
+ return 0;
+ }
+
grow = (vma->vm_start - address) >> PAGE_SHIFT;
if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
current->rlim[RLIMIT_AS].rlim_cur) {
spin_unlock(&vma->vm_mm->page_table_lock);
return -ENOMEM;
}
+
+ if ((vma->vm_flags & VM_LOCKED) &&
+ ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) >
current->rlim[RLIMIT_MEMLOCK].rlim_cur) {
+ spin_unlock(&vma->vm_mm->page_table_lock);
+ return -ENOMEM;
+ }
+
+
vma->vm_start = address;
vma->vm_pgoff -= grow;
vma->vm_mm->total_vm += grow;
diff -urN linux/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- linux/include/linux/pci_ids.h 2005/01/09 19:34:04 1.50.2.25
+++ linux/include/linux/pci_ids.h 2005/01/13 10:59:04 1.50.2.26
@@ -761,6 +761,7 @@
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P 0x0027
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP15 0x002d
#define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030
+#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032
#define PCI_DEVICE_ID_APPLE_TIGON3 0x1645
#define PCI_VENDOR_ID_YAMAHA 0x1073
diff -urN linux/include/linux/spinlock.h linux/include/linux/spinlock.h
--- linux/include/linux/spinlock.h 2003/01/11 17:53:18 1.11.2.4
+++ linux/include/linux/spinlock.h 2005/01/13 10:59:04 1.11.2.5
@@ -147,7 +147,7 @@
#define rwlock_init(lock) do { } while(0)
#define read_lock(lock) (void)(lock) /* Not "unused variable".
*/
-#define read_unlock(lock) do { } while(0)
+#define read_unlock(lock) (void)(lock) /* Not "unused variable". */
#define write_lock(lock) (void)(lock) /* Not "unused variable". */
#define write_unlock(lock) do { } while(0)
diff -urN linux/kernel/ksyms.c linux/kernel/ksyms.c
--- linux/kernel/Attic/ksyms.c 2005/01/09 19:34:04 1.76.2.12
+++ linux/kernel/Attic/ksyms.c 2005/01/13 10:59:04 1.76.2.13
@@ -88,7 +88,6 @@
EXPORT_SYMBOL(do_mmap_pgoff);
EXPORT_SYMBOL(do_munmap);
EXPORT_SYMBOL(do_brk);
-EXPORT_SYMBOL(do_brk_locked);
EXPORT_SYMBOL(exit_mm);
EXPORT_SYMBOL(exit_files);
EXPORT_SYMBOL(exit_fs);
diff -urN linux/mm/memory.c linux/mm/memory.c
--- linux/mm/memory.c 2004/11/29 17:47:18 1.59.2.10
+++ linux/mm/memory.c 2005/01/13 10:59:04 1.59.2.11
@@ -454,9 +454,8 @@
int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned
long start,
int len, int write, int force, struct page **pages, struct
vm_area_struct **vmas)
{
- int i, s;
+ int i;
unsigned int flags;
- struct vm_area_struct *savevma = NULL;
/*
* Require read or write permissions.
@@ -464,7 +463,7 @@
*/
flags = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
- i = s = 0;
+ i = 0;
do {
struct vm_area_struct * vma;
@@ -500,13 +499,9 @@
/* FIXME: call the correct function,
* depending on the type of the found page
*/
- if (!pages[i] || PageReserved(pages[i])) {
- if (pages[i] != ZERO_PAGE(start)) {
- savevma = vma;
- goto bad_page;
- }
- } else
- page_cache_get(pages[i]);
+ if (!pages[i])
+ goto bad_page;
+ page_cache_get(pages[i]);
}
if (vmas)
vmas[i] = vma;
@@ -525,15 +520,9 @@
*/
bad_page:
spin_unlock(&mm->page_table_lock);
- s = i;
while (i--)
page_cache_release(pages[i]);
- /* catch bad uses of PG_reserved on !VM_IO vma's */
- printk(KERN_ERR "get_user_pages PG_reserved page on"
- "vma:%p flags:%lx page:%d\n", savevma,
- savevma->vm_flags, s);
- BUG();
- i = -EFAULT;
+ i = -EFAULT;
goto out;
}
diff -urN linux/mm/mmap.c linux/mm/mmap.c
--- linux/mm/mmap.c 2005/01/09 19:34:04 1.49.2.9
+++ linux/mm/mmap.c 2005/01/13 10:59:04 1.49.2.10
@@ -1031,6 +1031,15 @@
return ret;
}
+
+static inline void verify_mmap_write_lock_held(struct mm_struct *mm)
+{
+ if (down_read_trylock(&mm->mmap_sem)) {
+ WARN_ON(1);
+ up_read(&mm->mmap_sem);
+ }
+}
+
/*
* this is really a simplified "do_mmap". it only handles
* anonymous maps. eventually we may be able to do some
@@ -1061,6 +1070,12 @@
}
/*
+ * mm->mmap_sem is required to protect against another thread
+ * changing the mappings while we sleep (on kmalloc for one).
+ */
+ verify_mmap_write_lock_held(mm);
+
+ /*
* Clear old maps. this also does some error checking for us
*/
munmap_back:
@@ -1116,21 +1131,6 @@
return addr;
}
-/* locking version of do_brk. */
-unsigned long do_brk_locked(unsigned long addr, unsigned long len)
-{
- unsigned long ret;
-
- down_write(¤t->mm->mmap_sem);
- ret = do_brk(addr, len);
- up_write(¤t->mm->mmap_sem);
-
- return ret;
-}
-
-
-
-
/* Build the RB tree corresponding to the VMA list. */
void build_mmap_rb(struct mm_struct * mm)
{
diff -urN linux/net/rose/rose_route.c linux/net/rose/rose_route.c
--- linux/net/rose/rose_route.c 2001/08/22 03:25:20 1.12
+++ linux/net/rose/rose_route.c 2005/01/13 10:59:04 1.12.2.1
@@ -655,6 +655,9 @@
if (rose_route.mask > 10) /* Mask can't be more than 10
digits */
return -EINVAL;
+ if(rose_route.ndigis > 8) /* No more than 8 digipeats */
+ return -EINVAL;
+
err = rose_add_node(&rose_route, dev);
dev_put(dev);
return err;
|