diff options
Diffstat (limited to 'arch')
55 files changed, 229 insertions, 159 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ade7e924bef5..9759fec0b704 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -547,6 +547,7 @@ config ARCH_KIRKWOOD select CPU_FEROCEON select GENERIC_CLOCKEVENTS select PCI + select PCI_QUIRKS select PLAT_ORION_LEGACY help Support for the following Marvell Kirkwood series SoCs: diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 90275f036cd1..49ca86e37b8d 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -652,6 +652,15 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size mov pc, lr ENDPROC(__setup_mmu) +@ Enable unaligned access on v6, to allow better code generation +@ for the decompressor C code: +__armv6_mmu_cache_on: + mrc p15, 0, r0, c1, c0, 0 @ read SCTLR + bic r0, r0, #2 @ A (no unaligned access fault) + orr r0, r0, #1 << 22 @ U (v6 unaligned access model) + mcr p15, 0, r0, c1, c0, 0 @ write SCTLR + b __armv4_mmu_cache_on + __arm926ejs_mmu_cache_on: #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mov r0, #4 @ put dcache in WT mode @@ -694,6 +703,9 @@ __armv7_mmu_cache_on: bic r0, r0, #1 << 28 @ clear SCTLR.TRE orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement orr r0, r0, #0x003c @ write buffer + bic r0, r0, #2 @ A (no unaligned access fault) + orr r0, r0, #1 << 22 @ U (v6 unaligned access model) + @ (needed for ARM1176) #ifdef CONFIG_MMU #ifdef CONFIG_CPU_ENDIAN_BE8 orr r0, r0, #1 << 25 @ big-endian page tables @@ -914,7 +926,7 @@ proc_types: .word 0x0007b000 @ ARMv6 .word 0x000ff000 - W(b) __armv4_mmu_cache_on + W(b) __armv6_mmu_cache_on W(b) __armv4_mmu_cache_off W(b) __armv6_mmu_cache_flush diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c index df13a3ffff35..9d2d3ba339ff 100644 --- a/arch/arm/common/timer-sp.c +++ b/arch/arm/common/timer-sp.c @@ -162,7 +162,6 @@ static struct clock_event_device sp804_clockevent = { .set_mode = sp804_set_mode, .set_next_event = sp804_set_next_event, .rating = 300, - .cpumask = cpu_all_mask, }; static struct irqaction sp804_timer_irq = { @@ -185,6 +184,7 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ); evt->name = name; evt->irq = irq; + evt->cpumask = cpu_possible_mask; setup_irq(irq, &sp804_timer_irq); clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 23004847bb05..78d8e9b5544f 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -91,6 +91,7 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) */ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { + debug_dma_mapping_error(dev, dma_addr); return dma_addr == DMA_ERROR_CODE; } diff --git a/arch/arm/mach-dove/include/mach/pm.h b/arch/arm/mach-dove/include/mach/pm.h index 7bcd0dfce4b1..b47f75038686 100644 --- a/arch/arm/mach-dove/include/mach/pm.h +++ b/arch/arm/mach-dove/include/mach/pm.h @@ -63,7 +63,7 @@ static inline int pmu_to_irq(int pin) static inline int irq_to_pmu(int irq) { - if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS) + if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS) return irq - IRQ_DOVE_PMU_START; return -EINVAL; diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c index 087711524e8a..bc4344aa1009 100644 --- a/arch/arm/mach-dove/irq.c +++ b/arch/arm/mach-dove/irq.c @@ -46,8 +46,20 @@ static void pmu_irq_ack(struct irq_data *d) int pin = irq_to_pmu(d->irq); u32 u; + /* + * The PMU mask register is not RW0C: it is RW. This means that + * the bits take whatever value is written to them; if you write + * a '1', you will set the interrupt. + * + * Unfortunately this means there is NO race free way to clear + * these interrupts. + * + * So, let's structure the code so that the window is as small as + * possible. + */ u = ~(1 << (pin & 31)); - writel(u, PMU_INTERRUPT_CAUSE); + u &= readl_relaxed(PMU_INTERRUPT_CAUSE); + writel_relaxed(u, PMU_INTERRUPT_CAUSE); } static struct irq_chip pmu_irq_chip = { diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 1694f01ce2b6..6d6bde3e15fa 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -410,6 +410,7 @@ void __init ixp4xx_pci_preinit(void) * Enable the IO window to be way up high, at 0xfffffc00 */ local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01); + local_write_config(0x40, 4, 0x000080FF); /* No TRDY time limit */ } else { printk("PCI: IXP4xx is target - No bus scan performed\n"); } diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index fdf91a160884..8c0c0e2d0727 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -67,15 +67,12 @@ static struct map_desc ixp4xx_io_desc[] __initdata = { .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS), .length = IXP4XX_PCI_CFG_REGION_SIZE, .type = MT_DEVICE - }, -#ifdef CONFIG_DEBUG_LL - { /* Debug UART mapping */ - .virtual = (unsigned long)IXP4XX_DEBUG_UART_BASE_VIRT, - .pfn = __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS), - .length = IXP4XX_DEBUG_UART_REGION_SIZE, + }, { /* Queue Manager */ + .virtual = (unsigned long)IXP4XX_QMGR_BASE_VIRT, + .pfn = __phys_to_pfn(IXP4XX_QMGR_BASE_PHYS), + .length = IXP4XX_QMGR_REGION_SIZE, .type = MT_DEVICE - } -#endif + }, }; void __init ixp4xx_map_io(void) diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c index b800a031207c..53b8348dfcc2 100644 --- a/arch/arm/mach-ixp4xx/goramo_mlr.c +++ b/arch/arm/mach-ixp4xx/goramo_mlr.c @@ -15,6 +15,7 @@ #include <asm/mach/arch.h> #include <asm/mach/flash.h> #include <asm/mach/pci.h> +#include <asm/system_info.h> #define SLOT_ETHA 0x0B /* IDSEL = AD21 */ #define SLOT_ETHB 0x0C /* IDSEL = AD20 */ @@ -329,7 +330,7 @@ static struct platform_device device_hss_tab[] = { }; -static struct platform_device *device_tab[6] __initdata = { +static struct platform_device *device_tab[7] __initdata = { &device_flash, /* index 0 */ }; diff --git a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S index 8c9f8d564492..ff686cbc5df4 100644 --- a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S +++ b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S @@ -17,8 +17,8 @@ #else mov \rp, #0 #endif - orr \rv, \rp, #0xff000000 @ virtual - orr \rv, \rv, #0x00b00000 + orr \rv, \rp, #0xfe000000 @ virtual + orr \rv, \rv, #0x00f00000 orr \rp, \rp, #0xc8000000 @ physical .endm diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h index eb68b61ce975..c5bae9c035d5 100644 --- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h +++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h @@ -30,51 +30,43 @@ * * 0x50000000 0x10000000 ioremap'd EXP BUS * - * 0x6000000 0x00004000 ioremap'd QMgr + * 0xC8000000 0x00013000 0xFEF00000 On-Chip Peripherals * - * 0xC0000000 0x00001000 0xffbff000 PCI CFG + * 0xC0000000 0x00001000 0xFEF13000 PCI CFG * - * 0xC4000000 0x00001000 0xffbfe000 EXP CFG + * 0xC4000000 0x00001000 0xFEF14000 EXP CFG * - * 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals + * 0x60000000 0x00004000 0xFEF15000 QMgr */ /* * Queue Manager */ -#define IXP4XX_QMGR_BASE_PHYS (0x60000000) -#define IXP4XX_QMGR_REGION_SIZE (0x00004000) +#define IXP4XX_QMGR_BASE_PHYS 0x60000000 +#define IXP4XX_QMGR_BASE_VIRT IOMEM(0xFEF15000) +#define IXP4XX_QMGR_REGION_SIZE 0x00004000 /* - * Expansion BUS Configuration registers + * Peripheral space, including debug UART. Must be section-aligned so that + * it can be used with the low-level debug code. */ -#define IXP4XX_EXP_CFG_BASE_PHYS (0xC4000000) -#define IXP4XX_EXP_CFG_BASE_VIRT IOMEM(0xFFBFE000) -#define IXP4XX_EXP_CFG_REGION_SIZE (0x00001000) +#define IXP4XX_PERIPHERAL_BASE_PHYS 0xC8000000 +#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFEF00000) +#define IXP4XX_PERIPHERAL_REGION_SIZE 0x00013000 /* * PCI Config registers */ -#define IXP4XX_PCI_CFG_BASE_PHYS (0xC0000000) -#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFFBFF000) -#define IXP4XX_PCI_CFG_REGION_SIZE (0x00001000) - -/* - * Peripheral space - */ -#define IXP4XX_PERIPHERAL_BASE_PHYS (0xC8000000) -#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFFBEB000) -#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000) +#define IXP4XX_PCI_CFG_BASE_PHYS 0xC0000000 +#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFEF13000) +#define IXP4XX_PCI_CFG_REGION_SIZE 0x00001000 /* - * Debug UART - * - * This is basically a remap of UART1 into a region that is section - * aligned so that it * can be used with the low-level debug code. + * Expansion BUS Configuration registers */ -#define IXP4XX_DEBUG_UART_BASE_PHYS (0xC8000000) -#define IXP4XX_DEBUG_UART_BASE_VIRT IOMEM(0xffb00000) -#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000) +#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000 +#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEF14000 +#define IXP4XX_EXP_CFG_REGION_SIZE 0x00001000 #define IXP4XX_EXP_CS0_OFFSET 0x00 #define IXP4XX_EXP_CS1_OFFSET 0x04 diff --git a/arch/arm/mach-ixp4xx/include/mach/qmgr.h b/arch/arm/mach-ixp4xx/include/mach/qmgr.h index 9e7cad2d54cb..4de8da536dbb 100644 --- a/arch/arm/mach-ixp4xx/include/mach/qmgr.h +++ b/arch/arm/mach-ixp4xx/include/mach/qmgr.h @@ -86,7 +86,7 @@ void qmgr_release_queue(unsigned int queue); static inline void qmgr_put_entry(unsigned int queue, u32 val) { - extern struct qmgr_regs __iomem *qmgr_regs; + struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; #if DEBUG_QMGR BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ @@ -99,7 +99,7 @@ static inline void qmgr_put_entry(unsigned int queue, u32 val) static inline u32 qmgr_get_entry(unsigned int queue) { u32 val; - extern struct qmgr_regs __iomem *qmgr_regs; + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; val = __raw_readl(&qmgr_regs->acc[queue][0]); #if DEBUG_QMGR BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ @@ -112,14 +112,14 @@ static inline u32 qmgr_get_entry(unsigned int queue) static inline int __qmgr_get_stat1(unsigned int queue) { - extern struct qmgr_regs __iomem *qmgr_regs; + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; return (__raw_readl(&qmgr_regs->stat1[queue >> 3]) >> ((queue & 7) << 2)) & 0xF; } static inline int __qmgr_get_stat2(unsigned int queue) { - extern struct qmgr_regs __iomem *qmgr_regs; + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; BUG_ON(queue >= HALF_QUEUES); return (__raw_readl(&qmgr_regs->stat2[queue >> 4]) >> ((queue & 0xF) << 1)) & 0x3; @@ -145,7 +145,7 @@ static inline int qmgr_stat_empty(unsigned int queue) */ static inline int qmgr_stat_below_low_watermark(unsigned int queue) { - extern struct qmgr_regs __iomem *qmgr_regs; + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; if (queue >= HALF_QUEUES) return (__raw_readl(&qmgr_regs->statne_h) >> (queue - HALF_QUEUES)) & 0x01; @@ -172,7 +172,7 @@ static inline int qmgr_stat_above_high_watermark(unsigned int queue) */ static inline int qmgr_stat_full(unsigned int queue) { - extern struct qmgr_regs __iomem *qmgr_regs; + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; if (queue >= HALF_QUEUES) return (__raw_readl(&qmgr_regs->statf_h) >> (queue - HALF_QUEUES)) & 0x01; diff --git a/arch/arm/mach-ixp4xx/ixp4xx_npe.c b/arch/arm/mach-ixp4xx/ixp4xx_npe.c index a17ed79207a4..d4eb09a62863 100644 --- a/arch/arm/mach-ixp4xx/ixp4xx_npe.c +++ b/arch/arm/mach-ixp4xx/ixp4xx_npe.c @@ -116,7 +116,11 @@ /* NPE mailbox_status value for reset */ #define RESET_MBOX_STAT 0x0000F0F0 -const char *npe_names[] = { "NPE-A", "NPE-B", "NPE-C" }; +#define NPE_A_FIRMWARE "NPE-A" +#define NPE_B_FIRMWARE "NPE-B" +#define NPE_C_FIRMWARE "NPE-C" + +const char *npe_names[] = { NPE_A_FIRMWARE, NPE_B_FIRMWARE, NPE_C_FIRMWARE }; #define print_npe(pri, npe, fmt, ...) \ printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__) @@ -724,6 +728,9 @@ module_exit(npe_cleanup_module); MODULE_AUTHOR("Krzysztof Halasa"); MODULE_LICENSE("GPL v2"); +MODULE_FIRMWARE(NPE_A_FIRMWARE); +MODULE_FIRMWARE(NPE_B_FIRMWARE); +MODULE_FIRMWARE(NPE_C_FIRMWARE); EXPORT_SYMBOL(npe_names); EXPORT_SYMBOL(npe_running); diff --git a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c index 852f7c9f87d0..9d1b6b7c394c 100644 --- a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c +++ b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c @@ -14,7 +14,7 @@ #include <linux/module.h> #include <mach/qmgr.h> -struct qmgr_regs __iomem *qmgr_regs; +static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; static struct resource *mem_res; static spinlock_t qmgr_lock; static u32 used_sram_bitmap[4]; /* 128 16-dword pages */ @@ -293,12 +293,6 @@ static int qmgr_init(void) if (mem_res == NULL) return -EBUSY; - qmgr_regs = ioremap(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); - if (qmgr_regs == NULL) { - err = -ENOMEM; - goto error_map; - } - /* reset qmgr registers */ for (i = 0; i < 4; i++) { __raw_writel(0x33333333, &qmgr_regs->stat1[i]); @@ -347,8 +341,6 @@ static int qmgr_init(void) error_irq2: free_irq(IRQ_IXP4XX_QM1, NULL); error_irq: - iounmap(qmgr_regs); -error_map: release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); return err; } @@ -359,7 +351,6 @@ static void qmgr_remove(void) free_irq(IRQ_IXP4XX_QM2, NULL); synchronize_irq(IRQ_IXP4XX_QM1); synchronize_irq(IRQ_IXP4XX_QM2); - iounmap(qmgr_regs); release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); } @@ -369,7 +360,6 @@ module_exit(qmgr_remove); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Krzysztof Halasa"); -EXPORT_SYMBOL(qmgr_regs); EXPORT_SYMBOL(qmgr_set_irq); EXPORT_SYMBOL(qmgr_enable_irq); EXPORT_SYMBOL(qmgr_disable_irq); diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index ec544918b12c..74fc5a074fc4 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -207,14 +207,19 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) return 1; } +/* + * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it + * is operating as a root complex this needs to be switched to + * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on + * the device. Decoding setup is handled by the orion code. + */ static void __devinit rc_pci_fixup(struct pci_dev *dev) { - /* - * Prevent enumeration of root complex. - */ if (dev->bus->parent == NULL && dev->devfn == 0) { int i; + dev->class &= 0xff; + dev->class |= PCI_CLASS_BRIDGE_HOST << 8; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { dev->resource[i].start = 0; dev->resource[i].end = 0; diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 86b8b480634f..09c5233f4dfc 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -89,7 +89,7 @@ ENTRY(cpu_v6_dcache_clean_area) mov pc, lr /* - * cpu_arm926_switch_mm(pgd_phys, tsk) + * cpu_v6_switch_mm(pgd_phys, tsk) * * Set the translation table base pointer to be pgd_phys * diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index db98e7021f0d..0abd1c469887 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -473,12 +473,13 @@ int s3c2410_dma_enqueue(enum dma_ch channel, void *id, pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n", chan->number, __func__, buf); - if (chan->end == NULL) + if (chan->end == NULL) { pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n", chan->number, __func__, chan); - - chan->end->next = buf; - chan->end = buf; + } else { + chan->end->next = buf; + chan->end = buf; + } } /* if necessary, update the next buffer field */ diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h index 538f4b44db5d..994776894198 100644 --- a/arch/arm64/include/asm/dma-mapping.h +++ b/arch/arm64/include/asm/dma-mapping.h @@ -50,6 +50,7 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr) static inline int dma_mapping_error(struct device *dev, dma_addr_t dev_addr) { struct dma_map_ops *ops = get_dma_ops(dev); + debug_dma_mapping_error(dev, dev_addr); return ops->mapping_error(dev, dev_addr); } diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h index 6d909faebf28..656a6f291a35 100644 --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h @@ -392,7 +392,7 @@ __SYSCALL(367, sys_fanotify_init) __SYSCALL(368, compat_sys_fanotify_mark_wrapper) __SYSCALL(369, sys_prlimit64) __SYSCALL(370, sys_name_to_handle_at) -__SYSCALL(371, sys_open_by_handle_at) +__SYSCALL(371, compat_sys_open_by_handle_at) __SYSCALL(372, sys_clock_adjtime) __SYSCALL(373, sys_syncfs) diff --git a/arch/c6x/include/asm/dma-mapping.h b/arch/c6x/include/asm/dma-mapping.h index 03579fd99dba..3c694065030f 100644 --- a/arch/c6x/include/asm/dma-mapping.h +++ b/arch/c6x/include/asm/dma-mapping.h @@ -32,6 +32,7 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) */ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { + debug_dma_mapping_error(dev, dma_addr); return dma_addr == ~0; } diff --git a/arch/c6x/include/asm/setup.h b/arch/c6x/include/asm/setup.h new file mode 100644 index 000000000000..ecead15872a6 --- /dev/null +++ b/arch/c6x/include/asm/setup.h @@ -0,0 +1,33 @@ +/* + * Port on Texas Instruments TMS320C6x architecture + * + * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _ASM_C6X_SETUP_H +#define _ASM_C6X_SETUP_H + +#include <uapi/asm/setup.h> + +#ifndef __ASSEMBLY__ +extern char c6x_command_line[COMMAND_LINE_SIZE]; + +extern int c6x_add_memory(phys_addr_t start, unsigned long size); + +extern unsigned long ram_start; +extern unsigned long ram_end; + +extern int c6x_num_cores; +extern unsigned int c6x_silicon_rev; +extern unsigned int c6x_devstat; +extern unsigned char c6x_fuse_mac[6]; + +extern void machine_init(unsigned long dt_ptr); +extern void time_init(void); + +#endif /* !__ASSEMBLY__ */ +#endif /* _ASM_C6X_SETUP_H */ diff --git a/arch/c6x/include/uapi/asm/Kbuild b/arch/c6x/include/uapi/asm/Kbuild index c312b424c433..e9bc2b2b8147 100644 --- a/arch/c6x/include/uapi/asm/Kbuild +++ b/arch/c6x/include/uapi/asm/Kbuild @@ -1,6 +1,8 @@ # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm +generic-y += kvm_para.h + header-y += byteorder.h header-y += kvm_para.h header-y += ptrace.h diff --git a/arch/c6x/include/uapi/asm/kvm_para.h b/arch/c6x/include/uapi/asm/kvm_para.h deleted file mode 100644 index 14fab8f0b957..000000000000 --- a/arch/c6x/include/uapi/asm/kvm_para.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/kvm_para.h> diff --git a/arch/c6x/include/uapi/asm/setup.h b/arch/c6x/include/uapi/asm/setup.h index a01e31896fa9..ad9ac97a8dad 100644 --- a/arch/c6x/include/uapi/asm/setup.h +++ b/arch/c6x/include/uapi/asm/setup.h @@ -1,33 +1,6 @@ -/* - * Port on Texas Instruments TMS320C6x architecture - * - * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated - * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _ASM_C6X_SETUP_H -#define _ASM_C6X_SETUP_H +#ifndef _UAPI_ASM_C6X_SETUP_H +#define _UAPI_ASM_C6X_SETUP_H #define COMMAND_LINE_SIZE 1024 -#ifndef __ASSEMBLY__ -extern char c6x_command_line[COMMAND_LINE_SIZE]; - -extern int c6x_add_memory(phys_addr_t start, unsigned long size); - -extern unsigned long ram_start; -extern unsigned long ram_end; - -extern int c6x_num_cores; -extern unsigned int c6x_silicon_rev; -extern unsigned int c6x_devstat; -extern unsigned char c6x_fuse_mac[6]; - -extern void machine_init(unsigned long dt_ptr); -extern void time_init(void); - -#endif /* !__ASSEMBLY__ */ -#endif /* _ASM_C6X_SETUP_H */ +#endif /* _UAPI_ASM_C6X_SETUP_H */ diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S index 5449c36018fe..0ed6157dd256 100644 --- a/arch/c6x/kernel/entry.S +++ b/arch/c6x/kernel/entry.S @@ -277,6 +277,8 @@ work_rescheduled: [A1] BNOP .S1 work_resched,5 work_notifysig: + ;; enable interrupts for do_notify_resume() + UNMASK_INT B2 B .S2 do_notify_resume LDW .D2T1 *+SP(REGS__END+8),A6 ; syscall flag ADDKPC .S2 resume_userspace,B3,1 @@ -427,8 +429,7 @@ ENTRY(ret_from_kernel_execve) ENDPROC(ret_from_kernel_execve) ;; - ;; These are the interrupt handlers, responsible for calling __do_IRQ() - ;; int6 is used for syscalls (see _system_call entry) + ;; These are the interrupt handlers, responsible for calling c6x_do_IRQ() ;; .macro SAVE_ALL_INT SAVE_ALL IRP,ITSR diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h index 4f5e8148440d..cf3ab7e784b5 100644 --- a/arch/ia64/include/asm/dma-mapping.h +++ b/arch/ia64/include/asm/dma-mapping.h @@ -58,6 +58,7 @@ static inline void dma_free_attrs(struct device *dev, size_t size, static inline int dma_mapping_error(struct device *dev, dma_addr_t daddr) { struct dma_map_ops *ops = platform_dma_get_ops(dev); + debug_dma_mapping_error(dev, daddr); return ops->mapping_error(dev, daddr); } diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h index 01d228286cb0..46460f1c49c4 100644 --- a/arch/microblaze/include/asm/dma-mapping.h +++ b/arch/microblaze/include/asm/dma-mapping.h @@ -114,6 +114,8 @@ static inline void __dma_sync(unsigned long paddr, static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { struct dma_map_ops *ops = get_dma_ops(dev); + + debug_dma_mapping_error(dev, dma_addr); if (ops->mapping_error) return ops->mapping_error(dev, dma_addr); diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c index 3847e5b9c601..3903e3d11f5a 100644 --- a/arch/microblaze/kernel/signal.c +++ b/arch/microblaze/kernel/signal.c @@ -111,7 +111,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1)) + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1) == -EFAULT) goto badframe; return rval; diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index be39a12901c6..006b43e38a9c 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -40,6 +40,8 @@ static inline int dma_supported(struct device *dev, u64 mask) static inline int dma_mapping_error(struct device *dev, u64 mask) { struct dma_map_ops *ops = get_dma_ops(dev); + + debug_dma_mapping_error(dev, mask); return ops->mapping_error(dev, mask); } diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h index bd94946a18f3..ef99db994c2f 100644 --- a/arch/mips/include/asm/hugetlb.h +++ b/arch/mips/include/asm/hugetlb.h @@ -95,7 +95,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep, pte_t pte, int dirty) { - return ptep_set_access_flags(vma, addr, ptep, pte, dirty); + int changed = !pte_same(*ptep, pte); + + if (changed) { + set_pte_at(vma->vm_mm, addr, ptep, pte); + /* + * There could be some standard sized pages in there, + * get them all. + */ + flush_tlb_range(vma, addr, addr + HPAGE_SIZE); + } + return changed; } static inline pte_t huge_ptep_get(pte_t *ptep) diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index b1fb7af3c350..cce3782c96c9 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -510,7 +510,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) c->cputype = CPU_R3000A; __cpu_name[cpu] = "R3000A"; } - break; } else { c->cputype = CPU_R3000; __cpu_name[cpu] = "R3000"; diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index a6c133212003..9b00362f32f6 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S @@ -36,6 +36,11 @@ FEXPORT(ret_from_exception) FEXPORT(ret_from_irq) LONG_S s0, TI_REGS($28) FEXPORT(__ret_from_irq) +/* + * We can be coming here from a syscall done in the kernel space, + * e.g. a failed kernel_execve(). + */ +resume_userspace_check: LONG_L t0, PT_STATUS(sp) # returning to kernel mode? andi t0, t0, KU_USER beqz t0, resume_kernel @@ -162,7 +167,7 @@ work_notifysig: # deal with pending signals and move a0, sp li a1, 0 jal do_notify_resume # a2 already loaded - j resume_userspace + j resume_userspace_check FEXPORT(syscall_exit_partial) local_irq_disable # make sure need_resched doesn't diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index f6ba8381ee01..86ec03f0e00c 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -397,14 +397,14 @@ EXPORT(sysn32_call_table) PTR sys_timerfd_create PTR compat_sys_timerfd_gettime /* 6285 */ PTR compat_sys_timerfd_settime - PTR sys_signalfd4 + PTR compat_sys_signalfd4 PTR sys_eventfd2 PTR sys_epoll_create1 PTR sys_dup3 /* 6290 */ PTR sys_pipe2 PTR sys_inotify_init1 - PTR sys_preadv - PTR sys_pwritev + PTR compat_sys_preadv + PTR compat_sys_pwritev PTR compat_sys_rt_tgsigqueueinfo /* 6295 */ PTR sys_perf_event_open PTR sys_accept4 diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 4b9b935a070e..88e79ad6f811 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -120,18 +120,11 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, if (cpu_context(cpu, mm) != 0) { unsigned long size, flags; - int huge = is_vm_hugetlb_page(vma); ENTER_CRITICAL(flags); - if (huge) { - start = round_down(start, HPAGE_SIZE); - end = round_up(end, HPAGE_SIZE); - size = (end - start) >> HPAGE_SHIFT; - } else { - start = round_down(start, PAGE_SIZE << 1); - end = round_up(end, PAGE_SIZE << 1); - size = (end - start) >> (PAGE_SHIFT + 1); - } + start = round_down(start, PAGE_SIZE << 1); + end = round_up(end, PAGE_SIZE << 1); + size = (end - start) >> (PAGE_SHIFT + 1); if (size <= current_cpu_data.tlbsize/2) { int oldpid = read_c0_entryhi(); int newpid = cpu_asid(cpu, mm); @@ -140,10 +133,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, int idx; write_c0_entryhi(start | newpid); - if (huge) - start += HPAGE_SIZE; - else - start += (PAGE_SIZE << 1); + start += (PAGE_SIZE << 1); mtc0_tlbw_hazard(); tlb_probe(); tlb_probe_hazard(); diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c index 30110297f4f9..ddedc8a77861 100644 --- a/arch/openrisc/kernel/signal.c +++ b/arch/openrisc/kernel/signal.c @@ -84,7 +84,6 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe *frame = (struct rt_sigframe __user *)regs->sp; sigset_t set; - stack_t st; /* * Since we stacked the signal on a dword boundary, @@ -104,11 +103,10 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; - if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) - goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack(&st, NULL, regs->sp); + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) + goto badframe; return regs->gpr[11]; diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 3735abd7f8f6..cbf5d59d5d6a 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -60,7 +60,7 @@ ENTRY_SAME(fork_wrapper) ENTRY_SAME(read) ENTRY_SAME(write) - ENTRY_SAME(open) /* 5 */ + ENTRY_COMP(open) /* 5 */ ENTRY_SAME(close) ENTRY_SAME(waitpid) ENTRY_SAME(creat) diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 78160874809a..e27e9ad6818e 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -172,6 +172,7 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { struct dma_map_ops *dma_ops = get_dma_ops(dev); + debug_dma_mapping_error(dev, dma_addr); if (dma_ops->mapping_error) return dma_ops->mapping_error(dev, dma_addr); diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index ad79b846535c..827e094a2f49 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -28,7 +28,7 @@ ENTRY(sys32_open_wrapper) llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int lgfr %r4,%r4 # int - jg sys_open # branch to system call + jg compat_sys_open # branch to system call ENTRY(sys32_close_wrapper) llgfr %r2,%r2 # unsigned int diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c index c268bbf8b410..02353bde92d8 100644 --- a/arch/score/kernel/signal.c +++ b/arch/score/kernel/signal.c @@ -148,7 +148,6 @@ score_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe __user *frame; sigset_t set; - stack_t st; int sig; /* Always make any pending restarted system calls return -EINTR */ @@ -168,12 +167,10 @@ score_rt_sigreturn(struct pt_regs *regs) else if (sig) force_sig(sig, current); - if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) - goto badframe; - /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]); + if (do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs->regs[0]) == -EFAULT) + goto badframe; regs->is_syscall = 0; __asm__ __volatile__( diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h index 8bd965e00a15..b437f2c780b8 100644 --- a/arch/sh/include/asm/dma-mapping.h +++ b/arch/sh/include/asm/dma-mapping.h @@ -46,6 +46,7 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { struct dma_map_ops *ops = get_dma_ops(dev); + debug_dma_mapping_error(dev, dma_addr); if (ops->mapping_error) return ops->mapping_error(dev, dma_addr); diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c index 23853814bd17..d867cd95a622 100644 --- a/arch/sh/kernel/signal_64.c +++ b/arch/sh/kernel/signal_64.c @@ -347,7 +347,6 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, { struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP; sigset_t set; - stack_t __user st; long long ret; /* Always make any pending restarted system calls return -EINTR */ @@ -365,11 +364,10 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, goto badframe; regs->pc -= 4; - if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) - goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack(&st, NULL, REF_REG_SP); + if (do_sigaltstack(&frame->uc.uc_stack, NULL, REF_REG_SP) == -EFAULT) + goto badframe; return (int) ret; diff --git a/arch/sparc/boot/piggyback.c b/arch/sparc/boot/piggyback.c index c0a798fcf030..bb7c95161d71 100644 --- a/arch/sparc/boot/piggyback.c +++ b/arch/sparc/boot/piggyback.c @@ -81,18 +81,18 @@ static void usage(void) static int start_line(const char *line) { - if (strcmp(line + 8, " T _start\n") == 0) + if (strcmp(line + 10, " _start\n") == 0) return 1; - else if (strcmp(line + 16, " T _start\n") == 0) + else if (strcmp(line + 18, " _start\n") == 0) return 1; return 0; } static int end_line(const char *line) { - if (strcmp(line + 8, " A _end\n") == 0) + if (strcmp(line + 10, " _end\n") == 0) return 1; - else if (strcmp (line + 16, " A _end\n") == 0) + else if (strcmp (line + 18, " _end\n") == 0) return 1; return 0; } @@ -100,8 +100,8 @@ static int end_line(const char *line) /* * Find address for start and end in System.map. * The file looks like this: - * f0004000 T _start - * f0379f79 A _end + * f0004000 ... _start + * f0379f79 ... _end * 1234567890123456 * ^coloumn 1 * There is support for 64 bit addresses too. diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index 8493fd3c7ba5..05fe53f5346e 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h @@ -59,6 +59,7 @@ static inline void dma_free_attrs(struct device *dev, size_t size, static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { + debug_dma_mapping_error(dev, dma_addr); return (dma_addr == DMA_ERROR_CODE); } diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index 44025f4ba41f..8475a474273a 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S @@ -47,7 +47,7 @@ STUB: sra REG1, 0, REG1; \ sra REG4, 0, REG4 SIGN1(sys32_exit, sparc_exit, %o0) -SIGN1(sys32_exit_group, sys_exit_group, %o0) +SIGN1(sys32_exit_group, sparc_exit_group, %o0) SIGN1(sys32_wait4, compat_sys_wait4, %o2) SIGN1(sys32_creat, sys_creat, %o1) SIGN1(sys32_mknod, sys_mknod, %o1) diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index 7f5f65d0b3fd..bf2347794e33 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -118,10 +118,20 @@ ret_from_syscall: ba,pt %xcc, ret_sys_call ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 + .globl sparc_exit_group + .type sparc_exit_group,#function +sparc_exit_group: + sethi %hi(sys_exit_group), %g7 + ba,pt %xcc, 1f + or %g7, %lo(sys_exit_group), %g7 + .size sparc_exit_group,.-sparc_exit_group + .globl sparc_exit .type sparc_exit,#function sparc_exit: - rdpr %pstate, %g2 + sethi %hi(sys_exit), %g7 + or %g7, %lo(sys_exit), %g7 +1: rdpr %pstate, %g2 wrpr %g2, PSTATE_IE, %pstate rdpr %otherwin, %g1 rdpr %cansave, %g3 @@ -129,7 +139,7 @@ sparc_exit: wrpr %g3, 0x0, %cansave wrpr %g0, 0x0, %otherwin wrpr %g2, 0x0, %pstate - ba,pt %xcc, sys_exit + jmpl %g7, %g0 stb %g0, [%g6 + TI_WSAVED] .size sparc_exit,.-sparc_exit diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 1c9af9fa38e9..017b74a63dcb 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -133,7 +133,7 @@ sys_call_table: /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall - .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname + .word sys_setpgid, sys_fremovexattr, sys_tkill, sparc_exit_group, sys_newuname /*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall diff --git a/arch/tile/include/asm/dma-mapping.h b/arch/tile/include/asm/dma-mapping.h index 4b6247d1a315..f2ff191376b4 100644 --- a/arch/tile/include/asm/dma-mapping.h +++ b/arch/tile/include/asm/dma-mapping.h @@ -72,6 +72,7 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { + debug_dma_mapping_error(dev, dma_addr); return get_dma_ops(dev)->mapping_error(dev, dma_addr); } diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 3a8ece7d09ca..0d7103c9eff3 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -32,13 +32,14 @@ void flush_thread(void) "err = %d\n", ret); force_sig(SIGKILL, current); } + get_safe_registers(current_pt_regs()->regs.gp, + current_pt_regs()->regs.fp); __switch_mm(¤t->mm->context.id); } void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) { - get_safe_registers(regs->regs.gp, regs->regs.fp); PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; current->ptrace &= ~PT_DTRACE; diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 66e5f0ef0523..79fd8a3418f9 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -12,6 +12,7 @@ header-y += mce.h header-y += msr-index.h header-y += msr.h header-y += mtrr.h +header-y += perf_regs.h header-y += posix_types_32.h header-y += posix_types_64.h header-y += posix_types_x32.h @@ -19,8 +20,10 @@ header-y += prctl.h header-y += processor-flags.h header-y += ptrace-abi.h header-y += sigcontext32.h +header-y += svm.h header-y += ucontext.h header-y += vm86.h +header-y += vmx.h header-y += vsyscall.h genhdr-y += unistd_32.h diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index f7b4c7903e7e..808dae63eeea 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -47,6 +47,7 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev) static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { struct dma_map_ops *ops = get_dma_ops(dev); + debug_dma_mapping_error(dev, dma_addr); if (ops->mapping_error) return ops->mapping_error(dev, dma_addr); diff --git a/arch/x86/include/asm/fpu-internal.h b/arch/x86/include/asm/fpu-internal.h index 831dbb9c6c02..41ab26ea6564 100644 --- a/arch/x86/include/asm/fpu-internal.h +++ b/arch/x86/include/asm/fpu-internal.h @@ -399,14 +399,17 @@ static inline void drop_init_fpu(struct task_struct *tsk) typedef struct { int preload; } fpu_switch_t; /* - * FIXME! We could do a totally lazy restore, but we need to - * add a per-cpu "this was the task that last touched the FPU - * on this CPU" variable, and the task needs to have a "I last - * touched the FPU on this CPU" and check them. + * Must be run with preemption disabled: this clears the fpu_owner_task, + * on this CPU. * - * We don't do that yet, so "fpu_lazy_restore()" always returns - * false, but some day.. + * This will disable any lazy FPU state restore of the current FPU state, + * but if the current thread owns the FPU, it will still be saved by. */ +static inline void __cpu_disable_lazy_restore(unsigned int cpu) +{ + per_cpu(fpu_owner_task, cpu) = NULL; +} + static inline int fpu_lazy_restore(struct task_struct *new, unsigned int cpu) { return new == this_cpu_read_stable(fpu_owner_task) && diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 957a47aec64e..4dac2f68ed4a 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -292,8 +292,8 @@ default_entry: * be using the global pages. * * NOTE! If we are on a 486 we may have no cr4 at all! - * Specifically, cr4 exists if and only if CPUID exists, - * which in turn exists if and only if EFLAGS.ID exists. + * Specifically, cr4 exists if and only if CPUID exists + * and has flags other than the FPU flag set. */ movl $X86_EFLAGS_ID,%ecx pushl %ecx @@ -308,6 +308,11 @@ default_entry: testl %ecx,%eax jz 6f # No ID flag = no CPUID = no CR4 + movl $1,%eax + cpuid + andl $~1,%edx # Ignore CPUID.FPU + jz 6f # No flags or only CPUID.FPU = no CR4 + movl pa(mmu_cr4_features),%eax movl %eax,%cr4 diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 5e0596b0632e..974b67e46dd0 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -1541,6 +1541,13 @@ void syscall_trace_leave(struct pt_regs *regs) { bool step; + /* + * We may come here right after calling schedule_user() + * or do_notify_resume(), in which case we can be in RCU + * user mode. + */ + rcu_user_exit(); + audit_syscall_exit(regs); if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index c80a33bc528b..f3e2ec878b8c 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -68,6 +68,8 @@ #include <asm/mwait.h> #include <asm/apic.h> #include <asm/io_apic.h> +#include <asm/i387.h> +#include <asm/fpu-internal.h> #include <asm/setup.h> #include <asm/uv/uv.h> #include <linux/mc146818rtc.h> @@ -818,6 +820,9 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle) per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; + /* the FPU context is blank, nobody can own it */ + __cpu_disable_lazy_restore(cpu); + err = do_boot_cpu(apicid, cpu, tidle); if (err) { pr_debug("do_boot_cpu failed %d\n", err); diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 39171cb307ea..bba39bfa1c4b 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -426,8 +426,7 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) _ASM_EXTABLE(1b, 3b) \ : "=m" ((ctxt)->eflags), "=&r" (_tmp), \ "+a" (*rax), "+d" (*rdx), "+qm"(_ex) \ - : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val), \ - "a" (*rax), "d" (*rdx)); \ + : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \ } while (0) /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */ |