Merge git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-linus
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 8 Mar 2009 17:21:31 +0000 (10:21 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 8 Mar 2009 17:21:31 +0000 (10:21 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-linus:
  Squashfs: frag_size should be signed, as it can hold an error result
  Squashfs: fix documentation typo, Cramfs filesystem limit is 256 MiB
  Squashfs: Fix oops when reading fsfuzzer corrupted filesystems

46 files changed:
Makefile
arch/arm/kernel/setup.c
arch/arm/mach-at91/pm.c
arch/arm/mm/abort-ev6.S
arch/arm/plat-s3c64xx/irq-eint.c
arch/ia64/sn/pci/pcibr/pcibr_dma.c
arch/mips/include/asm/compat.h
arch/powerpc/platforms/86xx/gef_sbc610.c
arch/s390/crypto/aes_s390.c
arch/x86/mm/init_64.c
arch/x86/mm/kmmio.c
arch/x86/mm/testmmiotrace.c
arch/x86/oprofile/op_model_ppro.c
block/blk-merge.c
crypto/api.c
drivers/block/cciss.c
drivers/block/loop.c
drivers/block/xen-blkfront.c
drivers/crypto/ixp4xx_crypto.c
drivers/crypto/padlock-aes.c
drivers/crypto/padlock-sha.c
drivers/dma/iop-adma.c
drivers/dma/mv_xor.c
drivers/gpu/drm/drm_stub.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/mtd/nand/orion_nand.c
drivers/net/arm/Makefile
drivers/net/arm/etherh.c
drivers/video/pxafb.c
include/linux/rcuclassic.h
include/linux/rcupdate.h
include/linux/rcupreempt.h
include/linux/rcutree.h
include/linux/sched.h
include/linux/serio.h
init/main.c
kernel/rcuclassic.c
kernel/rcupdate.c
kernel/rcupreempt.c
kernel/rcutree.c
kernel/sched.c
kernel/sys.c
kernel/user.c
security/smack/smack_lsm.c
security/smack/smackfs.c
sound/pci/hda/patch_sigmatel.c

index df6ce3e8009091b4b6a4e96e131bd1f7adcea74d..d04ee0ad1dccce7ea2503637ffbe6d8753074ffe 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 29
-EXTRAVERSION = -rc6
+EXTRAVERSION = -rc7
 NAME = Erotic Pickled Herring
 
 # *DOCUMENTATION*
index 7049815d66d566e7d89c08fd3c25e33b8c48c995..68d6494c0389751d5584e94e833ae139ae53d76b 100644 (file)
@@ -233,12 +233,13 @@ static void __init cacheid_init(void)
        unsigned int cachetype = read_cpuid_cachetype();
        unsigned int arch = cpu_architecture();
 
-       if (arch >= CPU_ARCH_ARMv7) {
-               cacheid = CACHEID_VIPT_NONALIASING;
-               if ((cachetype & (3 << 14)) == 1 << 14)
-                       cacheid |= CACHEID_ASID_TAGGED;
-       } else if (arch >= CPU_ARCH_ARMv6) {
-               if (cachetype & (1 << 23))
+       if (arch >= CPU_ARCH_ARMv6) {
+               if ((cachetype & (7 << 29)) == 4 << 29) {
+                       /* ARMv7 register format */
+                       cacheid = CACHEID_VIPT_NONALIASING;
+                       if ((cachetype & (3 << 14)) == 1 << 14)
+                               cacheid |= CACHEID_ASID_TAGGED;
+               } else if (cachetype & (1 << 23))
                        cacheid = CACHEID_VIPT_ALIASING;
                else
                        cacheid = CACHEID_VIPT_NONALIASING;
index 9bb4f043aa22beb3fd08d0750cb75c155097b113..7ac812dc055a792476ffdc5a93e6568ae75e069a 100644 (file)
@@ -332,7 +332,6 @@ static int at91_pm_enter(suspend_state_t state)
                        at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR));
 
 error:
-       sdram_selfrefresh_disable();
        target_state = PM_SUSPEND_ON;
        at91_irq_resume();
        at91_gpio_resume();
index 8a7f65ba14b761cb81ceaa87689f1f0d9a91ed3f..94077fbd96b7691850275d71114eb2b9d328f5d3 100644 (file)
@@ -23,7 +23,8 @@ ENTRY(v6_early_abort)
 #ifdef CONFIG_CPU_32v6K
        clrex
 #else
-       strex   r0, r1, [sp]                    @ Clear the exclusive monitor
+       sub     r1, sp, #4                      @ Get unused stack location
+       strex   r0, r1, [r1]                    @ Clear the exclusive monitor
 #endif
        mrc     p15, 0, r1, c5, c0, 0           @ get FSR
        mrc     p15, 0, r0, c6, c0, 0           @ get FAR
index 1f7cc0067f5cdd19fad4c487b2a2821687de3b92..ebb305ce7689f2aa0499f6d582ceebc453cddaf0 100644 (file)
@@ -55,7 +55,7 @@ static void s3c_irq_eint_unmask(unsigned int irq)
        u32 mask;
 
        mask = __raw_readl(S3C64XX_EINT0MASK);
-       mask |= eint_irq_to_bit(irq);
+       mask &= ~eint_irq_to_bit(irq);
        __raw_writel(mask, S3C64XX_EINT0MASK);
 }
 
index e626e50a938a3ce91b2d9926f06d036d63f29609..060df4aa9916853297a0be09d4221c5a95e37654 100644 (file)
@@ -135,11 +135,10 @@ pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr,
        if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS)
                pci_addr = IS_PIC_SOFT(pcibus_info) ?
                                PHYS_TO_DMA(paddr) :
-                               PHYS_TO_TIODMA(paddr) | dma_attributes;
+                               PHYS_TO_TIODMA(paddr);
        else
-               pci_addr = IS_PIC_SOFT(pcibus_info) ?
-                               paddr :
-                               paddr | dma_attributes;
+               pci_addr = paddr;
+       pci_addr |= dma_attributes;
 
        /* Handle Bus mode */
        if (IS_PCIX(pcibus_info))
index ac5d541368e934a30ca17ac03e58bd990b9eb7ca..6c5b40905dd66daff610de074e5f17f7dd17fc8d 100644 (file)
@@ -3,6 +3,8 @@
 /*
  * Architecture specific compatibility types
  */
+#include <linux/seccomp.h>
+#include <linux/thread_info.h>
 #include <linux/types.h>
 #include <asm/page.h>
 #include <asm/ptrace.h>
@@ -218,4 +220,9 @@ struct compat_shmid64_ds {
        compat_ulong_t  __unused2;
 };
 
+static inline int is_compat_task(void)
+{
+       return test_thread_flag(TIF_32BIT);
+}
+
 #endif /* _ASM_COMPAT_H */
index fb371f5ce132c657ab910824d6d4c998b59c574d..d6b772ba3b8f8238ea3ecd5d27c2b77843b9dcda 100644 (file)
@@ -142,6 +142,10 @@ static void __init gef_sbc610_nec_fixup(struct pci_dev *pdev)
 {
        unsigned int val;
 
+       /* Do not do the fixup on other platforms! */
+       if (!machine_is(gef_sbc610))
+               return;
+
        printk(KERN_INFO "Running NEC uPD720101 Fixup\n");
 
        /* Ensure ports 1, 2, 3, 4 & 5 are enabled */
index c42cd898f68bfdece3e98706e44ab048abe61038..6118890c946d89244e587cdc880726a1d7893073 100644 (file)
@@ -556,7 +556,7 @@ static void __exit aes_s390_fini(void)
 module_init(aes_s390_init);
 module_exit(aes_s390_fini);
 
-MODULE_ALIAS("aes");
+MODULE_ALIAS("aes-all");
 
 MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
 MODULE_LICENSE("GPL");
index e6d36b490250bed6952f2d93de3d1f337c3cf7f4..b1352250096e0d734ea4a03650e7d92ae8c2d8ba 100644 (file)
@@ -714,6 +714,8 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
        pos = start_pfn << PAGE_SHIFT;
        end_pfn = ((pos + (PMD_SIZE - 1)) >> PMD_SHIFT)
                        << (PMD_SHIFT - PAGE_SHIFT);
+       if (end_pfn > (end >> PAGE_SHIFT))
+               end_pfn = end >> PAGE_SHIFT;
        if (start_pfn < end_pfn) {
                nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
                pos = end_pfn << PAGE_SHIFT;
index 93d82038af4b541853420a48502df0fc4c9c2407..9f205030d9aac6a6dbdb6f620b47fcba8b4acb2f 100644 (file)
@@ -32,11 +32,14 @@ struct kmmio_fault_page {
        struct list_head list;
        struct kmmio_fault_page *release_next;
        unsigned long page; /* location of the fault page */
+       bool old_presence; /* page presence prior to arming */
+       bool armed;
 
        /*
         * Number of times this page has been registered as a part
         * of a probe. If zero, page is disarmed and this may be freed.
-        * Used only by writers (RCU).
+        * Used only by writers (RCU) and post_kmmio_handler().
+        * Protected by kmmio_lock, when linked into kmmio_page_table.
         */
        int count;
 };
@@ -105,57 +108,85 @@ static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page)
        return NULL;
 }
 
-static void set_page_present(unsigned long addr, bool present,
-                                                       unsigned int *pglevel)
+static void set_pmd_presence(pmd_t *pmd, bool present, bool *old)
+{
+       pmdval_t v = pmd_val(*pmd);
+       *old = !!(v & _PAGE_PRESENT);
+       v &= ~_PAGE_PRESENT;
+       if (present)
+               v |= _PAGE_PRESENT;
+       set_pmd(pmd, __pmd(v));
+}
+
+static void set_pte_presence(pte_t *pte, bool present, bool *old)
+{
+       pteval_t v = pte_val(*pte);
+       *old = !!(v & _PAGE_PRESENT);
+       v &= ~_PAGE_PRESENT;
+       if (present)
+               v |= _PAGE_PRESENT;
+       set_pte_atomic(pte, __pte(v));
+}
+
+static int set_page_presence(unsigned long addr, bool present, bool *old)
 {
-       pteval_t pteval;
-       pmdval_t pmdval;
        unsigned int level;
-       pmd_t *pmd;
        pte_t *pte = lookup_address(addr, &level);
 
        if (!pte) {
                pr_err("kmmio: no pte for page 0x%08lx\n", addr);
-               return;
+               return -1;
        }
 
-       if (pglevel)
-               *pglevel = level;
-
        switch (level) {
        case PG_LEVEL_2M:
-               pmd = (pmd_t *)pte;
-               pmdval = pmd_val(*pmd) & ~_PAGE_PRESENT;
-               if (present)
-                       pmdval |= _PAGE_PRESENT;
-               set_pmd(pmd, __pmd(pmdval));
+               set_pmd_presence((pmd_t *)pte, present, old);
                break;
-
        case PG_LEVEL_4K:
-               pteval = pte_val(*pte) & ~_PAGE_PRESENT;
-               if (present)
-                       pteval |= _PAGE_PRESENT;
-               set_pte_atomic(pte, __pte(pteval));
+               set_pte_presence(pte, present, old);
                break;
-
        default:
                pr_err("kmmio: unexpected page level 0x%x.\n", level);
-               return;
+               return -1;
        }
 
        __flush_tlb_one(addr);
+       return 0;
 }
 
-/** Mark the given page as not present. Access to it will trigger a fault. */
-static void arm_kmmio_fault_page(unsigned long page, unsigned int *pglevel)
+/*
+ * Mark the given page as not present. Access to it will trigger a fault.
+ *
+ * Struct kmmio_fault_page is protected by RCU and kmmio_lock, but the
+ * protection is ignored here. RCU read lock is assumed held, so the struct
+ * will not disappear unexpectedly. Furthermore, the caller must guarantee,
+ * that double arming the same virtual address (page) cannot occur.
+ *
+ * Double disarming on the other hand is allowed, and may occur when a fault
+ * and mmiotrace shutdown happen simultaneously.
+ */
+static int arm_kmmio_fault_page(struct kmmio_fault_page *f)
 {
-       set_page_present(page & PAGE_MASK, false, pglevel);
+       int ret;
+       WARN_ONCE(f->armed, KERN_ERR "kmmio page already armed.\n");
+       if (f->armed) {
+               pr_warning("kmmio double-arm: page 0x%08lx, ref %d, old %d\n",
+                                       f->page, f->count, f->old_presence);
+       }
+       ret = set_page_presence(f->page, false, &f->old_presence);
+       WARN_ONCE(ret < 0, KERN_ERR "kmmio arming 0x%08lx failed.\n", f->page);
+       f->armed = true;
+       return ret;
 }
 
-/** Mark the given page as present. */
-static void disarm_kmmio_fault_page(unsigned long page, unsigned int *pglevel)
+/** Restore the given page to saved presence state. */
+static void disarm_kmmio_fault_page(struct kmmio_fault_page *f)
 {
-       set_page_present(page & PAGE_MASK, true, pglevel);
+       bool tmp;
+       int ret = set_page_presence(f->page, f->old_presence, &tmp);
+       WARN_ONCE(ret < 0,
+                       KERN_ERR "kmmio disarming 0x%08lx failed.\n", f->page);
+       f->armed = false;
 }
 
 /*
@@ -202,28 +233,32 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr)
 
        ctx = &get_cpu_var(kmmio_ctx);
        if (ctx->active) {
-               disarm_kmmio_fault_page(faultpage->page, NULL);
                if (addr == ctx->addr) {
                        /*
-                        * On SMP we sometimes get recursive probe hits on the
-                        * same address. Context is already saved, fall out.
+                        * A second fault on the same page means some other
+                        * condition needs handling by do_page_fault(), the
+                        * page really not being present is the most common.
                         */
-                       pr_debug("kmmio: duplicate probe hit on CPU %d, for "
-                                               "address 0x%08lx.\n",
-                                               smp_processor_id(), addr);
-                       ret = 1;
-                       goto no_kmmio_ctx;
-               }
-               /*
-                * Prevent overwriting already in-flight context.
-                * This should not happen, let's hope disarming at least
-                * prevents a panic.
-                */
-               pr_emerg("kmmio: recursive probe hit on CPU %d, "
+                       pr_debug("kmmio: secondary hit for 0x%08lx CPU %d.\n",
+                                       addr, smp_processor_id());
+
+                       if (!faultpage->old_presence)
+                               pr_info("kmmio: unexpected secondary hit for "
+                                       "address 0x%08lx on CPU %d.\n", addr,
+                                       smp_processor_id());
+               } else {
+                       /*
+                        * Prevent overwriting already in-flight context.
+                        * This should not happen, let's hope disarming at
+                        * least prevents a panic.
+                        */
+                       pr_emerg("kmmio: recursive probe hit on CPU %d, "
                                        "for address 0x%08lx. Ignoring.\n",
                                        smp_processor_id(), addr);
-               pr_emerg("kmmio: previous hit was at 0x%08lx.\n",
-                                       ctx->addr);
+                       pr_emerg("kmmio: previous hit was at 0x%08lx.\n",
+                                               ctx->addr);
+                       disarm_kmmio_fault_page(faultpage);
+               }
                goto no_kmmio_ctx;
        }
        ctx->active++;
@@ -244,7 +279,7 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr)
        regs->flags &= ~X86_EFLAGS_IF;
 
        /* Now we set present bit in PTE and single step. */
-       disarm_kmmio_fault_page(ctx->fpage->page, NULL);
+       disarm_kmmio_fault_page(ctx->fpage);
 
        /*
         * If another cpu accesses the same page while we are stepping,
@@ -275,7 +310,7 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs)
        struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx);
 
        if (!ctx->active) {
-               pr_debug("kmmio: spurious debug trap on CPU %d.\n",
+               pr_warning("kmmio: spurious debug trap on CPU %d.\n",
                                                        smp_processor_id());
                goto out;
        }
@@ -283,7 +318,11 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs)
        if (ctx->probe && ctx->probe->post_handler)
                ctx->probe->post_handler(ctx->probe, condition, regs);
 
-       arm_kmmio_fault_page(ctx->fpage->page, NULL);
+       /* Prevent racing against release_kmmio_fault_page(). */
+       spin_lock(&kmmio_lock);
+       if (ctx->fpage->count)
+               arm_kmmio_fault_page(ctx->fpage);
+       spin_unlock(&kmmio_lock);
 
        regs->flags &= ~X86_EFLAGS_TF;
        regs->flags |= ctx->saved_flags;
@@ -315,20 +354,24 @@ static int add_kmmio_fault_page(unsigned long page)
        f = get_kmmio_fault_page(page);
        if (f) {
                if (!f->count)
-                       arm_kmmio_fault_page(f->page, NULL);
+                       arm_kmmio_fault_page(f);
                f->count++;
                return 0;
        }
 
-       f = kmalloc(sizeof(*f), GFP_ATOMIC);
+       f = kzalloc(sizeof(*f), GFP_ATOMIC);
        if (!f)
                return -1;
 
        f->count = 1;
        f->page = page;
-       list_add_rcu(&f->list, kmmio_page_list(f->page));
 
-       arm_kmmio_fault_page(f->page, NULL);
+       if (arm_kmmio_fault_page(f)) {
+               kfree(f);
+               return -1;
+       }
+
+       list_add_rcu(&f->list, kmmio_page_list(f->page));
 
        return 0;
 }
@@ -347,7 +390,7 @@ static void release_kmmio_fault_page(unsigned long page,
        f->count--;
        BUG_ON(f->count < 0);
        if (!f->count) {
-               disarm_kmmio_fault_page(f->page, NULL);
+               disarm_kmmio_fault_page(f);
                f->release_next = *release_list;
                *release_list = f;
        }
index ab50a8d7402c8c7f4320f0fd803a22a2d9abf84a..427fd1b56df5540f6a871f31c99c92af4f3edacd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Written by Pekka Paalanen, 2008 <pq@iki.fi>
+ * Written by Pekka Paalanen, 2008-2009 <pq@iki.fi>
  */
 #include <linux/module.h>
 #include <linux/io.h>
@@ -9,35 +9,74 @@
 
 static unsigned long mmio_address;
 module_param(mmio_address, ulong, 0);
-MODULE_PARM_DESC(mmio_address, "Start address of the mapping of 16 kB.");
+MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB "
+                               "(or 8 MB if read_far is non-zero).");
+
+static unsigned long read_far = 0x400100;
+module_param(read_far, ulong, 0);
+MODULE_PARM_DESC(read_far, " Offset of a 32-bit read within 8 MB "
+                               "(default: 0x400100).");
+
+static unsigned v16(unsigned i)
+{
+       return i * 12 + 7;
+}
+
+static unsigned v32(unsigned i)
+{
+       return i * 212371 + 13;
+}
 
 static void do_write_test(void __iomem *p)
 {
        unsigned int i;
+       pr_info(MODULE_NAME ": write test.\n");
        mmiotrace_printk("Write test.\n");
+
        for (i = 0; i < 256; i++)
                iowrite8(i, p + i);
+
        for (i = 1024; i < (5 * 1024); i += 2)
-               iowrite16(i * 12 + 7, p + i);
+               iowrite16(v16(i), p + i);
+
        for (i = (5 * 1024); i < (16 * 1024); i += 4)
-               iowrite32(i * 212371 + 13, p + i);
+               iowrite32(v32(i), p + i);
 }
 
 static void do_read_test(void __iomem *p)
 {
        unsigned int i;
+       unsigned errs[3] = { 0 };
+       pr_info(MODULE_NAME ": read test.\n");
        mmiotrace_printk("Read test.\n");
+
        for (i = 0; i < 256; i++)
-               ioread8(p + i);
+               if (ioread8(p + i) != i)
+                       ++errs[0];
+
        for (i = 1024; i < (5 * 1024); i += 2)
-               ioread16(p + i);
+               if (ioread16(p + i) != v16(i))
+                       ++errs[1];
+
        for (i = (5 * 1024); i < (16 * 1024); i += 4)
-               ioread32(p + i);
+               if (ioread32(p + i) != v32(i))
+                       ++errs[2];
+
+       mmiotrace_printk("Read errors: 8-bit %d, 16-bit %d, 32-bit %d.\n",
+                                               errs[0], errs[1], errs[2]);
 }
 
-static void do_test(void)
+static void do_read_far_test(void __iomem *p)
 {
-       void __iomem *p = ioremap_nocache(mmio_address, 0x4000);
+       pr_info(MODULE_NAME ": read far test.\n");
+       mmiotrace_printk("Read far test.\n");
+
+       ioread32(p + read_far);
+}
+
+static void do_test(unsigned long size)
+{
+       void __iomem *p = ioremap_nocache(mmio_address, size);
        if (!p) {
                pr_err(MODULE_NAME ": could not ioremap, aborting.\n");
                return;
@@ -45,11 +84,15 @@ static void do_test(void)
        mmiotrace_printk("ioremap returned %p.\n", p);
        do_write_test(p);
        do_read_test(p);
+       if (read_far && read_far < size - 4)
+               do_read_far_test(p);
        iounmap(p);
 }
 
 static int __init init(void)
 {
+       unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
+
        if (mmio_address == 0) {
                pr_err(MODULE_NAME ": you have to use the module argument "
                                                        "mmio_address.\n");
@@ -58,10 +101,11 @@ static int __init init(void)
                return -ENXIO;
        }
 
-       pr_warning(MODULE_NAME ": WARNING: mapping 16 kB @ 0x%08lx "
-                                       "in PCI address space, and writing "
-                                       "rubbish in there.\n", mmio_address);
-       do_test();
+       pr_warning(MODULE_NAME ": WARNING: mapping %lu kB @ 0x%08lx in PCI "
+               "address space, and writing 16 kB of rubbish in there.\n",
+                size >> 10, mmio_address);
+       do_test(size);
+       pr_info(MODULE_NAME ": All done.\n");
        return 0;
 }
 
index e9f80c744cf3409d72f77dd9044ec1dd90534609..10131fbdaadada1781bddde6749e83a4cb200a8f 100644 (file)
@@ -78,8 +78,18 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs)
        if (cpu_has_arch_perfmon) {
                union cpuid10_eax eax;
                eax.full = cpuid_eax(0xa);
-               if (counter_width < eax.split.bit_width)
-                       counter_width = eax.split.bit_width;
+
+               /*
+                * For Core2 (family 6, model 15), don't reset the
+                * counter width:
+                */
+               if (!(eax.split.version_id == 0 &&
+                       current_cpu_data.x86 == 6 &&
+                               current_cpu_data.x86_model == 15)) {
+
+                       if (counter_width < eax.split.bit_width)
+                               counter_width = eax.split.bit_width;
+               }
        }
 
        /* clear all counters */
index a104593e70c38cdfdaebc1cf1214934e37ce3284..5a244f05360f5ca67592e29a7270f3874bf16c37 100644 (file)
@@ -39,14 +39,13 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect)
 }
 
 static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
-                                            struct bio *bio,
-                                            unsigned int *seg_size_ptr)
+                                            struct bio *bio)
 {
        unsigned int phys_size;
        struct bio_vec *bv, *bvprv = NULL;
        int cluster, i, high, highprv = 1;
        unsigned int seg_size, nr_phys_segs;
-       struct bio *fbio;
+       struct bio *fbio, *bbio;
 
        if (!bio)
                return 0;
@@ -87,26 +86,20 @@ new_segment:
                        seg_size = bv->bv_len;
                        highprv = high;
                }
+               bbio = bio;
        }
 
-       if (seg_size_ptr)
-               *seg_size_ptr = seg_size;
+       if (nr_phys_segs == 1 && seg_size > fbio->bi_seg_front_size)
+               fbio->bi_seg_front_size = seg_size;
+       if (seg_size > bbio->bi_seg_back_size)
+               bbio->bi_seg_back_size = seg_size;
 
        return nr_phys_segs;
 }
 
 void blk_recalc_rq_segments(struct request *rq)
 {
-       unsigned int seg_size = 0, phys_segs;
-
-       phys_segs = __blk_recalc_rq_segments(rq->q, rq->bio, &seg_size);
-
-       if (phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
-               rq->bio->bi_seg_front_size = seg_size;
-       if (seg_size > rq->biotail->bi_seg_back_size)
-               rq->biotail->bi_seg_back_size = seg_size;
-
-       rq->nr_phys_segments = phys_segs;
+       rq->nr_phys_segments = __blk_recalc_rq_segments(rq->q, rq->bio);
 }
 
 void blk_recount_segments(struct request_queue *q, struct bio *bio)
@@ -114,7 +107,7 @@ void blk_recount_segments(struct request_queue *q, struct bio *bio)
        struct bio *nxt = bio->bi_next;
 
        bio->bi_next = NULL;
-       bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, NULL);
+       bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio);
        bio->bi_next = nxt;
        bio->bi_flags |= (1 << BIO_SEG_VALID);
 }
index efe77df6863f4378f4f0da414591f940870b76ea..38a2bc02a98c7f6648f7a7a3388c6182b88c07f9 100644 (file)
@@ -215,8 +215,19 @@ struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask)
        mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD);
        type &= mask;
 
-       alg = try_then_request_module(crypto_alg_lookup(name, type, mask),
-                                     name);
+       alg = crypto_alg_lookup(name, type, mask);
+       if (!alg) {
+               char tmp[CRYPTO_MAX_ALG_NAME];
+
+               request_module(name);
+
+               if (!((type ^ CRYPTO_ALG_NEED_FALLBACK) & mask) &&
+                   snprintf(tmp, sizeof(tmp), "%s-all", name) < sizeof(tmp))
+                       request_module(tmp);
+
+               alg = crypto_alg_lookup(name, type, mask);
+       }
+
        if (alg)
                return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg;
 
index b5a06111463018b5d93f3d2b944caf9c60654281..4f9b6d7920173d19f85dc0cb822c3e33d87b1db9 100644 (file)
@@ -3606,11 +3606,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
                if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev))
                        return -ENODEV;
 
-               /* Some devices (notably the HP Smart Array 5i Controller)
-                  need a little pause here */
-               schedule_timeout_uninterruptible(30*HZ);
-
-               /* Now try to get the controller to respond to a no-op */
+               /* Now try to get the controller to respond to a no-op. Some
+                  devices (notably the HP Smart Array 5i Controller) need
+                  up to 30 seconds to respond. */
                for (i=0; i<30; i++) {
                        if (cciss_noop(pdev) == 0)
                                break;
index edbaac6c05739ab183e69f94c1dc230acea27176..bf034557767243ecbb0fd3c56538f7877e222345 100644 (file)
@@ -392,8 +392,7 @@ lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
        struct loop_device *lo = p->lo;
        struct page *page = buf->page;
        sector_t IV;
-       size_t size;
-       int ret;
+       int size, ret;
 
        ret = buf->ops->confirm(pipe, buf);
        if (unlikely(ret))
index b6c8ce25435994558885e9e4b9c4ac6aafaa9357..8f905089b72b7e49c2434d1b6abba9fa76321051 100644 (file)
@@ -977,6 +977,8 @@ static void backend_changed(struct xenbus_device *dev,
                break;
 
        case XenbusStateClosing:
+               if (info->gd == NULL)
+                       xenbus_dev_fatal(dev, -ENODEV, "gd is NULL");
                bd = bdget_disk(info->gd, 0);
                if (bd == NULL)
                        xenbus_dev_fatal(dev, -ENODEV, "bdget failed");
index 2d637e0fbc038df28dbfbff2d342b89edf6db4a4..d9e751be8c5fb120e5f0d06ef27684c8f33fa549 100644 (file)
@@ -457,10 +457,12 @@ static int init_ixp_crypto(void)
        if (!ctx_pool) {
                goto err;
        }
-       ret = qmgr_request_queue(SEND_QID, NPE_QLEN_TOTAL, 0, 0);
+       ret = qmgr_request_queue(SEND_QID, NPE_QLEN_TOTAL, 0, 0,
+                                "ixp_crypto:out", NULL);
        if (ret)
                goto err;
-       ret = qmgr_request_queue(RECV_QID, NPE_QLEN, 0, 0);
+       ret = qmgr_request_queue(RECV_QID, NPE_QLEN, 0, 0,
+                                "ixp_crypto:in", NULL);
        if (ret) {
                qmgr_release_queue(SEND_QID);
                goto err;
index 856b3cc2558387b7b239923c37c54f9d47b250ff..3f0fdd18255db9febb61836d44b3d7382385140d 100644 (file)
@@ -489,4 +489,4 @@ MODULE_DESCRIPTION("VIA PadLock AES algorithm support");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Michal Ludvig");
 
-MODULE_ALIAS("aes");
+MODULE_ALIAS("aes-all");
index a7fbadebf62330864734e5302be660d2f39ab51a..a2c8e8514b6340ac85915f158d7780491ce8b4a8 100644 (file)
@@ -304,7 +304,7 @@ MODULE_DESCRIPTION("VIA PadLock SHA1/SHA256 algorithms support.");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Michal Ludvig");
 
-MODULE_ALIAS("sha1");
-MODULE_ALIAS("sha256");
+MODULE_ALIAS("sha1-all");
+MODULE_ALIAS("sha256-all");
 MODULE_ALIAS("sha1-padlock");
 MODULE_ALIAS("sha256-padlock");
index ea5440dd10dc1ffb56dda5393d51f388e02ca87b..647374acba94a7c526d04236af5a855f81b7258c 100644 (file)
@@ -1401,7 +1401,7 @@ MODULE_ALIAS("platform:iop-adma");
 
 static struct platform_driver iop_adma_driver = {
        .probe          = iop_adma_probe,
-       .remove         = iop_adma_remove,
+       .remove         = __devexit_p(iop_adma_remove),
        .driver         = {
                .owner  = THIS_MODULE,
                .name   = "iop-adma",
index d35cbd1ff0b31e6635dd803eeae708cf75d68772..5d5d5b31867fc9e28dd70696e52ad00fa68c997c 100644 (file)
@@ -1287,7 +1287,7 @@ mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp,
 
 static struct platform_driver mv_xor_driver = {
        .probe          = mv_xor_probe,
-       .remove         = mv_xor_remove,
+       .remove         = __devexit_p(mv_xor_remove),
        .driver         = {
                .owner  = THIS_MODULE,
                .name   = MV_XOR_NAME,
index 096e2a37446d3e8fb333f45c342bc2a975607b34..7c8b15b22bf2e089fd9356debc9f967031723cbe 100644 (file)
@@ -168,7 +168,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
            file_priv->minor->master != file_priv->master) {
                mutex_lock(&dev->struct_mutex);
                file_priv->minor->master = drm_master_get(file_priv->master);
-               mutex_lock(&dev->struct_mutex);
+               mutex_unlock(&dev->struct_mutex);
        }
 
        return 0;
index eeda276f8f164021a9f59c12e1c7612ac60d94b4..7f186bbcb99d965bc69cdc8df5bd1cd83b8e89da 100644 (file)
@@ -482,7 +482,7 @@ mv64xxx_i2c_map_regs(struct platform_device *pd,
        return 0;
 }
 
-static void __devexit
+static void
 mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data)
 {
        if (drv_data->reg_base) {
@@ -577,7 +577,7 @@ mv64xxx_i2c_remove(struct platform_device *dev)
 
 static struct platform_driver mv64xxx_i2c_driver = {
        .probe  = mv64xxx_i2c_probe,
-       .remove = mv64xxx_i2c_remove,
+       .remove = __devexit_p(mv64xxx_i2c_remove),
        .driver = {
                .owner  = THIS_MODULE,
                .name   = MV64XXX_I2C_CTLR_NAME,
index 917cf8d3ae9561c5e4e1559758b46efb89d466d2..c2dfd3ea353d61315a8ed4bfc8c056201c30f67e 100644 (file)
@@ -149,7 +149,7 @@ static int __devexit orion_nand_remove(struct platform_device *pdev)
 
 static struct platform_driver orion_nand_driver = {
        .probe          = orion_nand_probe,
-       .remove         = orion_nand_remove,
+       .remove         = __devexit_p(orion_nand_remove),
        .driver         = {
                .name   = "orion_nand",
                .owner  = THIS_MODULE,
index c69c0cdba4a26b1cc254f1ac112cce46171c5f04..811a3ccd14c107c56136af8884022f7cd9f4498f 100644 (file)
@@ -4,7 +4,7 @@
 #
 
 obj-$(CONFIG_ARM_AM79C961A)    += am79c961a.o
-obj-$(CONFIG_ARM_ETHERH)       += etherh.o ../8390.o
+obj-$(CONFIG_ARM_ETHERH)       += etherh.o
 obj-$(CONFIG_ARM_ETHER3)       += ether3.o
 obj-$(CONFIG_ARM_ETHER1)       += ether1.o
 obj-$(CONFIG_ARM_AT91_ETHER)   += at91_ether.o
index 54b52e5b1821bbcd196b3f2f70cea19c51a5ec37..f52f668c49bfae5fcf526d299f9368661dd0d32c 100644 (file)
@@ -641,15 +641,15 @@ static const struct net_device_ops etherh_netdev_ops = {
        .ndo_open               = etherh_open,
        .ndo_stop               = etherh_close,
        .ndo_set_config         = etherh_set_config,
-       .ndo_start_xmit         = ei_start_xmit,
-       .ndo_tx_timeout         = ei_tx_timeout,
-       .ndo_get_stats          = ei_get_stats,
-       .ndo_set_multicast_list = ei_set_multicast_list,
+       .ndo_start_xmit         = __ei_start_xmit,
+       .ndo_tx_timeout         = __ei_tx_timeout,
+       .ndo_get_stats          = __ei_get_stats,
+       .ndo_set_multicast_list = __ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
 #ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = ei_poll,
+       .ndo_poll_controller    = __ei_poll,
 #endif
 };
 
index 48ff701d3a72b9cd1d5a6cb7b345a89e9678e50d..2552b9f325ee9b4c33eea202329e23e47b544c3e 100644 (file)
@@ -2230,7 +2230,7 @@ static int __devexit pxafb_remove(struct platform_device *dev)
 
 static struct platform_driver pxafb_driver = {
        .probe          = pxafb_probe,
-       .remove         = pxafb_remove,
+       .remove         = __devexit_p(pxafb_remove),
        .suspend        = pxafb_suspend,
        .resume         = pxafb_resume,
        .driver         = {
index f3f697df1d71b439b677efbc0da952ae6d25d066..80044a4f3ab9e1c890021fc0ff9dca533c00f71e 100644 (file)
@@ -181,4 +181,10 @@ extern long rcu_batches_completed_bh(void);
 #define rcu_enter_nohz()       do { } while (0)
 #define rcu_exit_nohz()                do { } while (0)
 
+/* A context switch is a grace period for rcuclassic. */
+static inline int rcu_blocking_is_gp(void)
+{
+       return num_online_cpus() == 1;
+}
+
 #endif /* __LINUX_RCUCLASSIC_H */
index 921340a7b71cf4c88638e2f905aa0fdc1385f958..528343e6da51a7c19cda8797c55cd6640612cb58 100644 (file)
@@ -52,6 +52,9 @@ struct rcu_head {
        void (*func)(struct rcu_head *head);
 };
 
+/* Internal to kernel, but needed by rcupreempt.h. */
+extern int rcu_scheduler_active;
+
 #if defined(CONFIG_CLASSIC_RCU)
 #include <linux/rcuclassic.h>
 #elif defined(CONFIG_TREE_RCU)
@@ -265,6 +268,7 @@ extern void rcu_barrier_sched(void);
 
 /* Internal to kernel */
 extern void rcu_init(void);
+extern void rcu_scheduler_starting(void);
 extern int rcu_needs_cpu(int cpu);
 
 #endif /* __LINUX_RCUPDATE_H */
index 3e05c09b54a22408db83e0f0a87a5a8bf9a40e8f..74304b4538d833ec7bcd26be28bdec8f436d73f7 100644 (file)
@@ -142,4 +142,19 @@ static inline void rcu_exit_nohz(void)
 #define rcu_exit_nohz()                do { } while (0)
 #endif /* CONFIG_NO_HZ */
 
+/*
+ * A context switch is a grace period for rcupreempt synchronize_rcu()
+ * only during early boot, before the scheduler has been initialized.
+ * So, how the heck do we get a context switch?  Well, if the caller
+ * invokes synchronize_rcu(), they are willing to accept a context
+ * switch, so we simply pretend that one happened.
+ *
+ * After boot, there might be a blocked or preempted task in an RCU
+ * read-side critical section, so we cannot then take the fastpath.
+ */
+static inline int rcu_blocking_is_gp(void)
+{
+       return num_online_cpus() == 1 && !rcu_scheduler_active;
+}
+
 #endif /* __LINUX_RCUPREEMPT_H */
index d4368b7975c3d09d5b1c08d2a822adebb06e62ac..a722fb67bb2d5a2500852c4fd5593f0e91777af0 100644 (file)
@@ -326,4 +326,10 @@ static inline void rcu_exit_nohz(void)
 }
 #endif /* CONFIG_NO_HZ */
 
+/* A context switch is a grace period for rcutree. */
+static inline int rcu_blocking_is_gp(void)
+{
+       return num_online_cpus() == 1;
+}
+
 #endif /* __LINUX_RCUTREE_H */
index 8981e52c714f05f19ad5727031058509e06bf6a8..8c216e057c94230ea01c110b0f5bc2c28e8f9ee3 100644 (file)
@@ -2291,9 +2291,13 @@ extern long sched_group_rt_runtime(struct task_group *tg);
 extern int sched_group_set_rt_period(struct task_group *tg,
                                      long rt_period_us);
 extern long sched_group_rt_period(struct task_group *tg);
+extern int sched_rt_can_attach(struct task_group *tg, struct task_struct *tsk);
 #endif
 #endif
 
+extern int task_can_switch_user(struct user_struct *up,
+                                       struct task_struct *tsk);
+
 #ifdef CONFIG_TASK_XACCT
 static inline void add_rchar(struct task_struct *tsk, ssize_t amt)
 {
index 1bcb357a01a1d00781b97fcad67eaa45dd82fba7..e0417e4d3f15ad3fdd66ef845c7ef8854f72aaae 100644 (file)
@@ -212,7 +212,7 @@ static inline void serio_unpin_driver(struct serio *serio)
 #define SERIO_FUJITSU  0x35
 #define SERIO_ZHENHUA  0x36
 #define SERIO_INEXIO   0x37
-#define SERIO_TOUCHIT213       0x37
+#define SERIO_TOUCHIT213       0x38
 #define SERIO_W8001    0x39
 
 #endif
index 844209453c02c2248114972fca3f0fcddbdf513d..83697e160b3a786d3d91c14000f116a441f61bfc 100644 (file)
@@ -97,7 +97,7 @@ static inline void mark_rodata_ro(void) { }
 extern void tc_init(void);
 #endif
 
-enum system_states system_state;
+enum system_states system_state __read_mostly;
 EXPORT_SYMBOL(system_state);
 
 /*
@@ -463,6 +463,7 @@ static noinline void __init_refok rest_init(void)
         * at least once to get things moving:
         */
        init_idle_bootup_task(current);
+       rcu_scheduler_starting();
        preempt_enable_no_resched();
        schedule();
        preempt_disable();
index bd5a9003497c200d7ef7a44ec252b2d96b2ac562..654c640a6b9c137b6a44c1e57159fbdeeac48b61 100644 (file)
@@ -679,8 +679,8 @@ int rcu_needs_cpu(int cpu)
 void rcu_check_callbacks(int cpu, int user)
 {
        if (user ||
-           (idle_cpu(cpu) && !in_softirq() &&
-                               hardirq_count() <= (1 << HARDIRQ_SHIFT))) {
+           (idle_cpu(cpu) && rcu_scheduler_active &&
+            !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) {
 
                /*
                 * Get here if this CPU took its interrupt from user
index d92a76a881aa47a9aa059c3221910834f6c50cf8..cae8a059cf47f4fab142b001c5f4d25ec8e95006 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/cpu.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
+#include <linux/kernel_stat.h>
 
 enum rcu_barrier {
        RCU_BARRIER_STD,
@@ -55,6 +56,7 @@ static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL};
 static atomic_t rcu_barrier_cpu_count;
 static DEFINE_MUTEX(rcu_barrier_mutex);
 static struct completion rcu_barrier_completion;
+int rcu_scheduler_active __read_mostly;
 
 /*
  * Awaken the corresponding synchronize_rcu() instance now that a
@@ -80,6 +82,10 @@ void wakeme_after_rcu(struct rcu_head  *head)
 void synchronize_rcu(void)
 {
        struct rcu_synchronize rcu;
+
+       if (rcu_blocking_is_gp())
+               return;
+
        init_completion(&rcu.completion);
        /* Will wake me after RCU finished. */
        call_rcu(&rcu.head, wakeme_after_rcu);
@@ -175,3 +181,9 @@ void __init rcu_init(void)
        __rcu_init();
 }
 
+void rcu_scheduler_starting(void)
+{
+       WARN_ON(num_online_cpus() != 1);
+       WARN_ON(nr_context_switches() > 0);
+       rcu_scheduler_active = 1;
+}
index 33cfc50781f9968d06e79edcb93049441a2a4231..5d59e850fb71f6f58b854cdbd0a1f1792f59c8ad 100644 (file)
@@ -1181,6 +1181,9 @@ void __synchronize_sched(void)
 {
        struct rcu_synchronize rcu;
 
+       if (num_online_cpus() == 1)
+               return;  /* blocking is gp if only one CPU! */
+
        init_completion(&rcu.completion);
        /* Will wake me after RCU finished. */
        call_rcu_sched(&rcu.head, wakeme_after_rcu);
index b2fd602a6f6f0433553a36a79e3a24172a8a2a2f..97ce31579ec0664682e1b2efb792cd77e7c0030e 100644 (file)
@@ -948,8 +948,8 @@ static void rcu_do_batch(struct rcu_data *rdp)
 void rcu_check_callbacks(int cpu, int user)
 {
        if (user ||
-           (idle_cpu(cpu) && !in_softirq() &&
-                               hardirq_count() <= (1 << HARDIRQ_SHIFT))) {
+           (idle_cpu(cpu) && rcu_scheduler_active &&
+            !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) {
 
                /*
                 * Get here if this CPU took its interrupt from user
index 410eec404133fd267eb80041395e21d266f0e552..8e2558c2ba67be440ef7bcb2d95ff8138c806404 100644 (file)
@@ -223,7 +223,7 @@ static void start_rt_bandwidth(struct rt_bandwidth *rt_b)
 {
        ktime_t now;
 
-       if (rt_bandwidth_enabled() && rt_b->rt_runtime == RUNTIME_INF)
+       if (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF)
                return;
 
        if (hrtimer_active(&rt_b->rt_period_timer))
@@ -9224,6 +9224,16 @@ static int sched_rt_global_constraints(void)
 
        return ret;
 }
+
+int sched_rt_can_attach(struct task_group *tg, struct task_struct *tsk)
+{
+       /* Don't accept realtime tasks when there is no way for them to run */
+       if (rt_task(tsk) && tg->rt_bandwidth.rt_runtime == 0)
+               return 0;
+
+       return 1;
+}
+
 #else /* !CONFIG_RT_GROUP_SCHED */
 static int sched_rt_global_constraints(void)
 {
@@ -9317,8 +9327,7 @@ cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
                      struct task_struct *tsk)
 {
 #ifdef CONFIG_RT_GROUP_SCHED
-       /* Don't accept realtime tasks when there is no way for them to run */
-       if (rt_task(tsk) && cgroup_tg(cgrp)->rt_bandwidth.rt_runtime == 0)
+       if (!sched_rt_can_attach(cgroup_tg(cgrp), tsk))
                return -EINVAL;
 #else
        /* We don't support RT-tasks being in separate groups */
index f145c415bc160e62b6d888cf6fa9d3198c00b4a7..37f458e6882adbd1f2b0697e5077c92e4252e03f 100644 (file)
@@ -559,7 +559,7 @@ error:
        abort_creds(new);
        return retval;
 }
-  
+
 /*
  * change the user struct in a credentials set to match the new UID
  */
@@ -571,6 +571,11 @@ static int set_user(struct cred *new)
        if (!new_user)
                return -EAGAIN;
 
+       if (!task_can_switch_user(new_user, current)) {
+               free_uid(new_user);
+               return -EINVAL;
+       }
+
        if (atomic_read(&new_user->processes) >=
                                current->signal->rlim[RLIMIT_NPROC].rlim_cur &&
                        new_user != INIT_USER) {
@@ -631,10 +636,11 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
                        goto error;
        }
 
-       retval = -EAGAIN;
-       if (new->uid != old->uid && set_user(new) < 0)
-               goto error;
-
+       if (new->uid != old->uid) {
+               retval = set_user(new);
+               if (retval < 0)
+                       goto error;
+       }
        if (ruid != (uid_t) -1 ||
            (euid != (uid_t) -1 && euid != old->uid))
                new->suid = new->euid;
@@ -680,9 +686,10 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
        retval = -EPERM;
        if (capable(CAP_SETUID)) {
                new->suid = new->uid = uid;
-               if (uid != old->uid && set_user(new) < 0) {
-                       retval = -EAGAIN;
-                       goto error;
+               if (uid != old->uid) {
+                       retval = set_user(new);
+                       if (retval < 0)
+                               goto error;
                }
        } else if (uid != old->uid && uid != new->suid) {
                goto error;
@@ -734,11 +741,13 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
                        goto error;
        }
 
-       retval = -EAGAIN;
        if (ruid != (uid_t) -1) {
                new->uid = ruid;
-               if (ruid != old->uid && set_user(new) < 0)
-                       goto error;
+               if (ruid != old->uid) {
+                       retval = set_user(new);
+                       if (retval < 0)
+                               goto error;
+               }
        }
        if (euid != (uid_t) -1)
                new->euid = euid;
index 3551ac742395c40af9edeb7d94d0d0b936caba9b..6a9b696128c855f9ddacfc9e3a7a128141379e49 100644 (file)
@@ -362,6 +362,24 @@ static void free_user(struct user_struct *up, unsigned long flags)
 
 #endif
 
+#if defined(CONFIG_RT_GROUP_SCHED) && defined(CONFIG_USER_SCHED)
+/*
+ * We need to check if a setuid can take place. This function should be called
+ * before successfully completing the setuid.
+ */
+int task_can_switch_user(struct user_struct *up, struct task_struct *tsk)
+{
+
+       return sched_rt_can_attach(up->tg, tsk);
+
+}
+#else
+int task_can_switch_user(struct user_struct *up, struct task_struct *tsk)
+{
+       return 1;
+}
+#endif
+
 /*
  * Locate the user_struct for the passed UID.  If found, take a ref on it.  The
  * caller must undo that ref with free_uid().
index 0278bc08304440df4af600670312e7bd3bce764c..e7ded1326b0ff835cec48f4e448b0c69f8df1d04 100644 (file)
@@ -1498,58 +1498,31 @@ static int smack_socket_post_create(struct socket *sock, int family,
  * looks for host based access restrictions
  *
  * This version will only be appropriate for really small
- * sets of single label hosts. Because of the masking
- * it cannot shortcut out on the first match. There are
- * numerious ways to address the problem, but none of them
- * have been applied here.
+ * sets of single label hosts.
  *
  * Returns the label of the far end or NULL if it's not special.
  */
 static char *smack_host_label(struct sockaddr_in *sip)
 {
        struct smk_netlbladdr *snp;
-       char *bestlabel = NULL;
        struct in_addr *siap = &sip->sin_addr;
-       struct in_addr *liap;
-       struct in_addr *miap;
-       struct in_addr bestmask;
 
        if (siap->s_addr == 0)
                return NULL;
 
-       bestmask.s_addr = 0;
-
        for (snp = smack_netlbladdrs; snp != NULL; snp = snp->smk_next) {
-               liap = &snp->smk_host.sin_addr;
-               miap = &snp->smk_mask;
-               /*
-                * If the addresses match after applying the list entry mask
-                * the entry matches the address. If it doesn't move along to
-                * the next entry.
-                */
-               if ((liap->s_addr & miap->s_addr) !=
-                   (siap->s_addr & miap->s_addr))
-                       continue;
                /*
-                * If the list entry mask identifies a single address
-                * it can't get any more specific.
+                * we break after finding the first match because
+                * the list is sorted from longest to shortest mask
+                * so we have found the most specific match
                 */
-               if (miap->s_addr == 0xffffffff)
+               if ((&snp->smk_host.sin_addr)->s_addr  ==
+                       (siap->s_addr & (&snp->smk_mask)->s_addr)) {
                        return snp->smk_label;
-               /*
-                * If the list entry mask is less specific than the best
-                * already found this entry is uninteresting.
-                */
-               if ((miap->s_addr | bestmask.s_addr) == bestmask.s_addr)
-                       continue;
-               /*
-                * This is better than any entry found so far.
-                */
-               bestmask.s_addr = miap->s_addr;
-               bestlabel = snp->smk_label;
+               }
        }
 
-       return bestlabel;
+       return NULL;
 }
 
 /**
index 8e42800878f468912c56cece9336e7c8c6bfa727..51f0efc50dab46a9200f98b6d22db0039a9a0653 100644 (file)
@@ -650,10 +650,6 @@ static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos)
 
        return skp;
 }
-/*
-#define BEMASK 0x80000000
-*/
-#define BEMASK 0x00000001
 #define BEBITS (sizeof(__be32) * 8)
 
 /*
@@ -663,12 +659,10 @@ static int netlbladdr_seq_show(struct seq_file *s, void *v)
 {
        struct smk_netlbladdr *skp = (struct smk_netlbladdr *) v;
        unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr;
-       __be32 bebits;
-       int maskn = 0;
+       int maskn;
+       u32 temp_mask = be32_to_cpu(skp->smk_mask.s_addr);
 
-       for (bebits = BEMASK; bebits != 0; maskn++, bebits <<= 1)
-               if ((skp->smk_mask.s_addr & bebits) == 0)
-                       break;
+       for (maskn = 0; temp_mask; temp_mask <<= 1, maskn++);
 
        seq_printf(s, "%u.%u.%u.%u/%d %s\n",
                hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label);
@@ -701,6 +695,42 @@ static int smk_open_netlbladdr(struct inode *inode, struct file *file)
        return seq_open(file, &netlbladdr_seq_ops);
 }
 
+/**
+ * smk_netlbladdr_insert
+ * @new : netlabel to insert
+ *
+ * This helper insert netlabel in the smack_netlbladdrs list
+ * sorted by netmask length (longest to smallest)
+ */
+static void smk_netlbladdr_insert(struct smk_netlbladdr *new)
+{
+       struct smk_netlbladdr *m;
+
+       if (smack_netlbladdrs == NULL) {
+               smack_netlbladdrs = new;
+               return;
+       }
+
+       /* the comparison '>' is a bit hacky, but works */
+       if (new->smk_mask.s_addr > smack_netlbladdrs->smk_mask.s_addr) {
+               new->smk_next = smack_netlbladdrs;
+               smack_netlbladdrs = new;
+               return;
+       }
+       for (m = smack_netlbladdrs; m != NULL; m = m->smk_next) {
+               if (m->smk_next == NULL) {
+                       m->smk_next = new;
+                       return;
+               }
+               if (new->smk_mask.s_addr > m->smk_next->smk_mask.s_addr) {
+                       new->smk_next = m->smk_next;
+                       m->smk_next = new;
+                       return;
+               }
+       }
+}
+
+
 /**
  * smk_write_netlbladdr - write() for /smack/netlabel
  * @filp: file pointer, not actually used
@@ -724,8 +754,9 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
        struct netlbl_audit audit_info;
        struct in_addr mask;
        unsigned int m;
-       __be32 bebits = BEMASK;
+       u32 mask_bits = (1<<31);
        __be32 nsa;
+       u32 temp_mask;
 
        /*
         * Must have privilege.
@@ -761,10 +792,13 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
        if (sp == NULL)
                return -EINVAL;
 
-       for (mask.s_addr = 0; m > 0; m--) {
-               mask.s_addr |= bebits;
-               bebits <<= 1;
+       for (temp_mask = 0; m > 0; m--) {
+               temp_mask |= mask_bits;
+               mask_bits >>= 1;
        }
+       mask.s_addr = cpu_to_be32(temp_mask);
+
+       newname.sin_addr.s_addr &= mask.s_addr;
        /*
         * Only allow one writer at a time. Writes should be
         * quite rare and small in any case.
@@ -772,6 +806,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
        mutex_lock(&smk_netlbladdr_lock);
 
        nsa = newname.sin_addr.s_addr;
+       /* try to find if the prefix is already in the list */
        for (skp = smack_netlbladdrs; skp != NULL; skp = skp->smk_next)
                if (skp->smk_host.sin_addr.s_addr == nsa &&
                    skp->smk_mask.s_addr == mask.s_addr)
@@ -787,9 +822,8 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,
                        rc = 0;
                        skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr;
                        skp->smk_mask.s_addr = mask.s_addr;
-                       skp->smk_next = smack_netlbladdrs;
                        skp->smk_label = sp;
-                       smack_netlbladdrs = skp;
+                       smk_netlbladdr_insert(skp);
                }
        } else {
                rc = netlbl_cfg_unlbl_static_del(&init_net, NULL,
index 3bc427645da8ef1411400990b67c9fc181e4cece..6094344fb223312bb668ad92b1cab3bcc626c068 100644 (file)
@@ -1207,7 +1207,7 @@ static const char *slave_vols[] = {
        "LFE Playback Volume",
        "Side Playback Volume",
        "Headphone Playback Volume",
-       "Headphone Playback Volume",
+       "Headphone2 Playback Volume",
        "Speaker Playback Volume",
        "External Speaker Playback Volume",
        "Speaker2 Playback Volume",
@@ -1221,7 +1221,7 @@ static const char *slave_sws[] = {
        "LFE Playback Switch",
        "Side Playback Switch",
        "Headphone Playback Switch",
-       "Headphone Playback Switch",
+       "Headphone2 Playback Switch",
        "Speaker Playback Switch",
        "External Speaker Playback Switch",
        "Speaker2 Playback Switch",
@@ -3516,6 +3516,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
        if (! spec->autocfg.line_outs)
                return 0; /* can't find valid pin config */
 
+#if 0 /* FIXME: temporarily disabled */
        /* If we have no real line-out pin and multiple hp-outs, HPs should
         * be set up as multi-channel outputs.
         */
@@ -3535,6 +3536,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
                spec->autocfg.line_out_type = AUTO_PIN_HP_OUT;
                spec->autocfg.hp_outs = 0;
        }
+#endif /* FIXME: temporarily disabled */
        if (spec->autocfg.mono_out_pin) {
                int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) &
                        (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP);