diff options
Diffstat (limited to 'arch')
92 files changed, 1021 insertions, 1067 deletions
diff --git a/arch/alpha/lib/csum_partial_copy.c b/arch/alpha/lib/csum_partial_copy.c index 40736da9bea8..ffb19b7da999 100644 --- a/arch/alpha/lib/csum_partial_copy.c +++ b/arch/alpha/lib/csum_partial_copy.c @@ -338,6 +338,11 @@ csum_partial_copy_from_user(const void __user *src, void *dst, int len, unsigned long doff = 7 & (unsigned long) dst; if (len) { + if (!access_ok(VERIFY_READ, src, len)) { + *errp = -EFAULT; + memset(dst, 0, len); + return sum; + } if (!doff) { if (!soff) checksum = csum_partial_cfu_aligned( diff --git a/arch/arc/include/asm/sections.h b/arch/arc/include/asm/sections.h index 6fc1159dfefe..764f1e3ba752 100644 --- a/arch/arc/include/asm/sections.h +++ b/arch/arc/include/asm/sections.h @@ -11,7 +11,6 @@ #include <asm-generic/sections.h> -extern char _int_vec_base_lds[]; extern char __arc_dccm_base[]; extern char __dtb_start[]; diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c index bdee3a812052..2340af0e1d6f 100644 --- a/arch/arc/kernel/devtree.c +++ b/arch/arc/kernel/devtree.c @@ -18,12 +18,6 @@ #include <asm/clk.h> #include <asm/mach_desc.h> -/* called from unflatten_device_tree() to bootstrap devicetree itself */ -void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) -{ - return __va(memblock_alloc(size, align)); -} - /** * setup_machine_fdt - Machine setup when an dtb was passed to the kernel * @dt: virtual address pointer to dt blob diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S index 2a913f85a747..0f944f024513 100644 --- a/arch/arc/kernel/head.S +++ b/arch/arc/kernel/head.S @@ -34,6 +34,9 @@ stext: ; IDENTITY Reg [ 3 2 1 0 ] ; (cpu-id) ^^^ => Zero for UP ARC700 ; => #Core-ID if SMP (Master 0) + ; Note that non-boot CPUs might not land here if halt-on-reset and + ; instead breath life from @first_lines_of_secondary, but we still + ; need to make sure only boot cpu takes this path. GET_CPU_ID r5 cmp r5, 0 jnz arc_platform_smp_wait_to_boot @@ -98,6 +101,8 @@ stext: first_lines_of_secondary: + sr @_int_vec_base_lds, [AUX_INTR_VEC_BASE] + ; setup per-cpu idle task as "current" on this CPU ld r0, [@secondary_idle_tsk] SET_CURR_TASK_ON_CPU r0, r1 diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c index 305b3f866aa7..5fc92455da36 100644 --- a/arch/arc/kernel/irq.c +++ b/arch/arc/kernel/irq.c @@ -24,7 +24,6 @@ * -Needed for each CPU (hence not foldable into init_IRQ) * * what it does ? - * -setup Vector Table Base Reg - in case Linux not linked at 0x8000_0000 * -Disable all IRQs (on CPU side) * -Optionally, setup the High priority Interrupts as Level 2 IRQs */ diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index b011f8c164a1..2c68bc7e6a78 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -47,10 +47,7 @@ void read_arc_build_cfg_regs(void) READ_BCR(AUX_IDENTITY, cpu->core); cpu->timers = read_aux_reg(ARC_REG_TIMERS_BCR); - cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE); - if (cpu->vec_base == 0) - cpu->vec_base = (unsigned int)_int_vec_base_lds; READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space); cpu->uncached_base = uncached_space.start << 24; diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c index a08ce7185423..81279ec73a6a 100644 --- a/arch/arc/mm/init.c +++ b/arch/arc/mm/init.c @@ -127,9 +127,8 @@ void __init free_initrd_mem(unsigned long start, unsigned long end) #endif #ifdef CONFIG_OF_FLATTREE -void __init early_init_dt_setup_initrd_arch(unsigned long start, - unsigned long end) +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) { - pr_err("%s(%lx, %lx)\n", __func__, start, end); + pr_err("%s(%llx, %llx)\n", __func__, start, end); } #endif /* CONFIG_OF_FLATTREE */ diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c8a916fcd54b..d13f6743df4b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -3,20 +3,21 @@ config ARM default y select ARCH_BINFMT_ELF_RANDOMIZE_PIE select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE - select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST + select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_WANT_IPC_PARSE_VERSION select BUILDTIME_EXTABLE_SORT if MMU + select CLONE_BACKWARDS select CPU_PM if (SUSPEND || CPU_IDLE) select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN && MMU select GENERIC_ATOMIC64 if (CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI) select GENERIC_CLOCKEVENTS_BROADCAST if SMP + select GENERIC_IDLE_POLL_SETUP select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW select GENERIC_PCI_IOMAP select GENERIC_SCHED_CLOCK select GENERIC_SMP_IDLE_THREAD - select GENERIC_IDLE_POLL_SETUP select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER select HARDIRQS_SW_RESEND @@ -25,6 +26,7 @@ config ARM select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_BPF_JIT + select HAVE_CONTEXT_TRACKING select HAVE_C_RECORDMCOUNT select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_API_DEBUG @@ -47,6 +49,7 @@ config ARM select HAVE_KPROBES if !XIP_KERNEL select HAVE_KRETPROBES if (HAVE_KPROBES) select HAVE_MEMBLOCK + select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND select HAVE_OPROFILE if (HAVE_PERF_EVENTS) select HAVE_PERF_EVENTS select HAVE_REGS_AND_STACK_ACCESS_API @@ -54,15 +57,14 @@ config ARM select HAVE_UID16 select IRQ_FORCED_THREADING select KTIME_SCALAR + select MODULES_USE_ELF_REL + select OLD_SIGACTION + select OLD_SIGSUSPEND3 select PERF_USE_VMALLOC select RTC_LIB select SYS_SUPPORTS_APM_EMULATION - select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND - select MODULES_USE_ELF_REL - select CLONE_BACKWARDS - select OLD_SIGSUSPEND3 - select OLD_SIGACTION - select HAVE_CONTEXT_TRACKING + # Above selects are sorted alphabetically; please add new ones + # according to that. Thanks. help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and @@ -386,8 +388,8 @@ config ARCH_GEMINI bool "Cortina Systems Gemini" select ARCH_REQUIRE_GPIOLIB select ARCH_USES_GETTIMEOFFSET - select NEED_MACH_GPIO_H select CPU_FA526 + select NEED_MACH_GPIO_H help Support for the Cortina Systems Gemini family SoCs @@ -487,8 +489,8 @@ config ARCH_IXP4XX select GENERIC_CLOCKEVENTS select MIGHT_HAVE_PCI select NEED_MACH_IO_H - select USB_EHCI_BIG_ENDIAN_MMIO select USB_EHCI_BIG_ENDIAN_DESC + select USB_EHCI_BIG_ENDIAN_MMIO help Support for Intel's IXP4XX (XScale) family of processors. @@ -498,11 +500,11 @@ config ARCH_DOVE select CPU_PJ4 select GENERIC_CLOCKEVENTS select MIGHT_HAVE_PCI + select MVEBU_MBUS select PINCTRL select PINCTRL_DOVE select PLAT_ORION_LEGACY select USB_ARCH_HAS_EHCI - select MVEBU_MBUS help Support for the Marvell Dove SoC 88AP510 @@ -512,12 +514,12 @@ config ARCH_KIRKWOOD select ARCH_REQUIRE_GPIOLIB select CPU_FEROCEON select GENERIC_CLOCKEVENTS + select MVEBU_MBUS select PCI select PCI_QUIRKS select PINCTRL select PINCTRL_KIRKWOOD select PLAT_ORION_LEGACY - select MVEBU_MBUS help Support for the following Marvell Kirkwood series SoCs: 88F6180, 88F6192 and 88F6281. @@ -527,9 +529,9 @@ config ARCH_MV78XX0 select ARCH_REQUIRE_GPIOLIB select CPU_FEROCEON select GENERIC_CLOCKEVENTS + select MVEBU_MBUS select PCI select PLAT_ORION_LEGACY - select MVEBU_MBUS help Support for the following Marvell MV78xx0 series SoCs: MV781x0, MV782x0. @@ -540,9 +542,9 @@ config ARCH_ORION5X select ARCH_REQUIRE_GPIOLIB select CPU_FEROCEON select GENERIC_CLOCKEVENTS + select MVEBU_MBUS select PCI select PLAT_ORION_LEGACY - select MVEBU_MBUS help Support for the following Marvell Orion 5x series SoCs: Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182), @@ -758,8 +760,8 @@ config ARCH_S5P64X0 select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS select NEED_MACH_GPIO_H - select SAMSUNG_WDT_RESET select SAMSUNG_ATAGS + select SAMSUNG_WDT_RESET help Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440, SMDK6450. @@ -777,8 +779,8 @@ config ARCH_S5PC100 select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS select NEED_MACH_GPIO_H - select SAMSUNG_WDT_RESET select SAMSUNG_ATAGS + select SAMSUNG_WDT_RESET help Samsung S5PC100 series based systems @@ -1619,9 +1621,10 @@ config HZ_FIXED ARCH_S5PV210 || ARCH_EXYNOS4 default AT91_TIMER_HZ if ARCH_AT91 default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE + default 0 choice - depends on !HZ_FIXED + depends on HZ_FIXED = 0 prompt "Timer frequency" config HZ_100 @@ -1646,7 +1649,7 @@ endchoice config HZ int - default HZ_FIXED if HZ_FIXED + default HZ_FIXED if HZ_FIXED != 0 default 100 if HZ_100 default 200 if HZ_200 default 250 if HZ_250 diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index 39ad030ac0c7..117f955a2a06 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -1235,6 +1235,23 @@ void edma_resume(unsigned channel) } EXPORT_SYMBOL(edma_resume); +int edma_trigger_channel(unsigned channel) +{ + unsigned ctlr; + unsigned int mask; + + ctlr = EDMA_CTLR(channel); + channel = EDMA_CHAN_SLOT(channel); + mask = BIT(channel & 0x1f); + + edma_shadow0_write_array(ctlr, SH_ESR, (channel >> 5), mask); + + pr_debug("EDMA: ESR%d %08x\n", (channel >> 5), + edma_shadow0_read_array(ctlr, SH_ESR, (channel >> 5))); + return 0; +} +EXPORT_SYMBOL(edma_trigger_channel); + /** * edma_start - start dma on a channel * @channel: channel being activated diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index aaf3a8731136..bd454b09133e 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -49,5 +49,5 @@ $(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S ifeq ($(CONFIG_KERNEL_MODE_NEON),y) NEON_FLAGS := -mfloat-abi=softfp -mfpu=neon CFLAGS_xor-neon.o += $(NEON_FLAGS) - lib-$(CONFIG_XOR_BLOCKS) += xor-neon.o + obj-$(CONFIG_XOR_BLOCKS) += xor-neon.o endif diff --git a/arch/arm/lib/xor-neon.c b/arch/arm/lib/xor-neon.c index f485e5a2af4b..2c40aeab3eaa 100644 --- a/arch/arm/lib/xor-neon.c +++ b/arch/arm/lib/xor-neon.c @@ -9,6 +9,9 @@ */ #include <linux/raid/xor.h> +#include <linux/module.h> + +MODULE_LICENSE("GPL"); #ifndef __ARM_NEON__ #error You should compile this file with '-mfloat-abi=softfp -mfpu=neon' @@ -40,3 +43,4 @@ struct xor_block_template const xor_block_neon_inner = { .do_4 = xor_8regs_4, .do_5 = xor_8regs_5, }; +EXPORT_SYMBOL(xor_block_neon_inner); diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c index 64f2e50e19ca..6bc1c181581d 100644 --- a/arch/arm/mach-ep93xx/vision_ep9307.c +++ b/arch/arm/mach-ep93xx/vision_ep9307.c @@ -224,62 +224,15 @@ static struct ep93xx_spi_chip_ops vision_spi_flash_hw = { #define VISION_SPI_MMC_WP EP93XX_GPIO_LINE_F(0) #define VISION_SPI_MMC_CD EP93XX_GPIO_LINE_EGPIO15 -static struct gpio vision_spi_mmc_gpios[] = { - { VISION_SPI_MMC_WP, GPIOF_DIR_IN, "mmc_spi:wp" }, - { VISION_SPI_MMC_CD, GPIOF_DIR_IN, "mmc_spi:cd" }, -}; - -static int vision_spi_mmc_init(struct device *pdev, - irqreturn_t (*func)(int, void *), void *pdata) -{ - int err; - - err = gpio_request_array(vision_spi_mmc_gpios, - ARRAY_SIZE(vision_spi_mmc_gpios)); - if (err) - return err; - - err = gpio_set_debounce(VISION_SPI_MMC_CD, 1); - if (err) - goto exit_err; - - err = request_irq(gpio_to_irq(VISION_SPI_MMC_CD), func, - IRQ_TYPE_EDGE_BOTH, "mmc_spi:cd", pdata); - if (err) - goto exit_err; - - return 0; - -exit_err: - gpio_free_array(vision_spi_mmc_gpios, ARRAY_SIZE(vision_spi_mmc_gpios)); - return err; - -} - -static void vision_spi_mmc_exit(struct device *pdev, void *pdata) -{ - free_irq(gpio_to_irq(VISION_SPI_MMC_CD), pdata); - gpio_free_array(vision_spi_mmc_gpios, ARRAY_SIZE(vision_spi_mmc_gpios)); -} - -static int vision_spi_mmc_get_ro(struct device *pdev) -{ - return !!gpio_get_value(VISION_SPI_MMC_WP); -} - -static int vision_spi_mmc_get_cd(struct device *pdev) -{ - return !gpio_get_value(VISION_SPI_MMC_CD); -} - static struct mmc_spi_platform_data vision_spi_mmc_data = { - .init = vision_spi_mmc_init, - .exit = vision_spi_mmc_exit, - .get_ro = vision_spi_mmc_get_ro, - .get_cd = vision_spi_mmc_get_cd, .detect_delay = 100, .powerup_msecs = 100, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO, + .cd_gpio = VISION_SPI_MMC_CD, + .cd_debounce = 1, + .ro_gpio = VISION_SPI_MMC_WP, + .caps2 = MMC_CAP2_RO_ACTIVE_HIGH, }; static int vision_spi_mmc_hw_setup(struct spi_device *spi) diff --git a/arch/arm/mach-imx/mm-imx25.c b/arch/arm/mach-imx/mm-imx25.c index e065c117f5a6..5211f62c624e 100644 --- a/arch/arm/mach-imx/mm-imx25.c +++ b/arch/arm/mach-imx/mm-imx25.c @@ -61,25 +61,8 @@ void __init mx25_init_irq(void) mxc_init_irq(MX25_IO_ADDRESS(MX25_AVIC_BASE_ADDR)); } -static struct sdma_script_start_addrs imx25_sdma_script __initdata = { - .ap_2_ap_addr = 729, - .uart_2_mcu_addr = 904, - .per_2_app_addr = 1255, - .mcu_2_app_addr = 834, - .uartsh_2_mcu_addr = 1120, - .per_2_shp_addr = 1329, - .mcu_2_shp_addr = 1048, - .ata_2_mcu_addr = 1560, - .mcu_2_ata_addr = 1479, - .app_2_per_addr = 1189, - .app_2_mcu_addr = 770, - .shp_2_per_addr = 1407, - .shp_2_mcu_addr = 979, -}; - static struct sdma_platform_data imx25_sdma_pdata __initdata = { .fw_name = "sdma-imx25.bin", - .script_addrs = &imx25_sdma_script, }; static const struct resource imx25_audmux_res[] __initconst = { diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c index a8229b7f10bf..eb3cce38c70d 100644 --- a/arch/arm/mach-imx/mm-imx5.c +++ b/arch/arm/mach-imx/mm-imx5.c @@ -103,22 +103,8 @@ void __init mx53_init_irq(void) tzic_init_irq(MX53_IO_ADDRESS(MX53_TZIC_BASE_ADDR)); } -static struct sdma_script_start_addrs imx51_sdma_script __initdata = { - .ap_2_ap_addr = 642, - .uart_2_mcu_addr = 817, - .mcu_2_app_addr = 747, - .mcu_2_shp_addr = 961, - .ata_2_mcu_addr = 1473, - .mcu_2_ata_addr = 1392, - .app_2_per_addr = 1033, - .app_2_mcu_addr = 683, - .shp_2_per_addr = 1251, - .shp_2_mcu_addr = 892, -}; - static struct sdma_platform_data imx51_sdma_pdata __initdata = { .fw_name = "sdma-imx51.bin", - .script_addrs = &imx51_sdma_script, }; static const struct resource imx51_audmux_res[] __initconst = { diff --git a/arch/arm/mm/hugetlbpage.c b/arch/arm/mm/hugetlbpage.c index 66781bf34077..54ee6163c181 100644 --- a/arch/arm/mm/hugetlbpage.c +++ b/arch/arm/mm/hugetlbpage.c @@ -56,3 +56,8 @@ int pmd_huge(pmd_t pmd) { return pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT); } + +int pmd_huge_support(void) +{ + return 1; +} diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 93cbf566a972..febaee7ca57b 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -78,7 +78,7 @@ static int __init parse_tag_initrd2(const struct tag *tag) __tagtable(ATAG_INITRD2, parse_tag_initrd2); #ifdef CONFIG_OF_FLATTREE -void __init early_init_dt_setup_initrd_arch(unsigned long start, unsigned long end) +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) { phys_initrd_start = start; phys_initrd_size = end - start; diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 8a6295c86209..83e4f959ee47 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -21,6 +21,8 @@ #include <linux/of.h> #include <linux/of_irq.h> #include <linux/of_address.h> +#include <linux/cpuidle.h> +#include <linux/cpufreq.h> #include <linux/mm.h> @@ -267,18 +269,28 @@ static int __init xen_guest_init(void) if (!xen_initial_domain()) xenbus_probe(NULL); + /* + * Making sure board specific code will not set up ops for + * cpu idle and cpu freq. + */ + disable_cpuidle(); + disable_cpufreq(); + return 0; } core_initcall(xen_guest_init); static int __init xen_pm_init(void) { + if (!xen_domain()) + return -ENODEV; + pm_power_off = xen_power_off; arm_pm_restart = xen_restart; return 0; } -subsys_initcall(xen_pm_init); +late_initcall(xen_pm_init); static irqreturn_t xen_arm_callback(int irq, void *arg) { diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index bca4c1c2052a..12ad8f3d0cfd 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -190,11 +190,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) memblock_add(base, size); } -void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) -{ - return __va(memblock_alloc(size, align)); -} - /* * Limit the memory size that was specified via FDT. */ diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 2fc8258bab2d..5e9aec358306 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -54,6 +54,11 @@ int pud_huge(pud_t pud) return !(pud_val(pud) & PUD_TABLE_BIT); } +int pmd_huge_support(void) +{ + return 1; +} + static __init int setup_hugepagesz(char *opt) { unsigned long ps = memparse(opt, &opt); diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 67e8d7ce3fe7..de2de5db628d 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -44,8 +44,7 @@ static unsigned long phys_initrd_size __initdata = 0; phys_addr_t memstart_addr __read_mostly = 0; -void __init early_init_dt_setup_initrd_arch(unsigned long start, - unsigned long end) +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) { phys_initrd_start = start; phys_initrd_size = end - start; diff --git a/arch/c6x/kernel/devicetree.c b/arch/c6x/kernel/devicetree.c index bdb56f09d0ac..9e15ab9199b2 100644 --- a/arch/c6x/kernel/devicetree.c +++ b/arch/c6x/kernel/devicetree.c @@ -33,8 +33,7 @@ void __init early_init_devtree(void *params) #ifdef CONFIG_BLK_DEV_INITRD -void __init early_init_dt_setup_initrd_arch(unsigned long start, - unsigned long end) +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) { initrd_start = (unsigned long)__va(start); initrd_end = (unsigned long)__va(end); @@ -46,8 +45,3 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) { c6x_add_memory(base, size); } - -void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) -{ - return __va(memblock_alloc(size, align)); -} diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 3201ddb8da6a..c699d3259872 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -99,9 +99,6 @@ config ETRAX_KMALLOCED_MODULES help Enable module allocation with kmalloc instead of vmalloc. -config OOM_REBOOT - bool "Enable reboot at out of memory" - source "kernel/Kconfig.preempt" source mm/Kconfig @@ -175,12 +172,6 @@ config ETRAX_FLASH_BUSWIDTH help Width in bytes of the NOR Flash bus (1, 2 or 4). Is usually 2. -config ETRAX_NANDFLASH_BUSWIDTH - int "Buswidth of NAND flash in bytes" - default "1" - help - Width in bytes of the NAND flash (1 or 2). - config ETRAX_FLASH1_SIZE int "FLASH1 size (dec, in MB. 0 = Unknown)" default "0" @@ -272,38 +263,6 @@ config ETRAX_AXISFLASHMAP This option enables MTD mapping of flash devices. Needed to use flash memories. If unsure, say Y. -config ETRAX_RTC - bool "Real Time Clock support" - depends on ETRAX_I2C - help - Enables drivers for the Real-Time Clock battery-backed chips on - some products. The kernel reads the time when booting, and - the date can be set using ioctl(fd, RTC_SET_TIME, &rt) with rt a - rtc_time struct (see <file:arch/cris/include/asm/rtc.h>) on the - /dev/rtc device. You can check the time with cat /proc/rtc, but - normal time reading should be done using libc function time and - friends. - -choice - prompt "RTC chip" - depends on ETRAX_RTC - default ETRAX_DS1302 - -config ETRAX_DS1302 - depends on ETRAX_ARCH_V10 - bool "DS1302" - help - Enables the driver for the DS1302 Real-Time Clock battery-backed - chip on some products. - -config ETRAX_PCF8563 - bool "PCF8563" - help - Enables the driver for the PCF8563 Real-Time Clock battery-backed - chip on some products. - -endchoice - config ETRAX_SYNCHRONOUS_SERIAL bool "Synchronous serial-port support" help @@ -578,26 +537,6 @@ config ETRAX_SERIAL_PORT3_DMA5_IN depends on ETRAX_ARCH_V10 bool "DMA 5" -config ETRAX_SERIAL_PORT3_DMA9_IN - bool "Ser3 uses DMA9 for input" - depends on ETRAXFS - help - Enables the DMA9 input channel for ser3 (ttyS3). - If you do not enable DMA, an interrupt for each character will be - used when receiving data. - Normally you want to use DMA, unless you use the DMA channel for - something else. - -config ETRAX_SERIAL_PORT3_DMA3_IN - bool "Ser3 uses DMA3 for input" - depends on CRIS_MACH_ARTPEC3 - help - Enables the DMA3 input channel for ser3 (ttyS3). - If you do not enable DMA, an interrupt for each character will be - used when receiving data. - Normally you want to use DMA, unless you use the DMA channel for - something else. - endchoice choice @@ -615,26 +554,6 @@ config ETRAX_SERIAL_PORT3_DMA4_OUT depends on ETRAX_ARCH_V10 bool "DMA 4" -config ETRAX_SERIAL_PORT3_DMA8_OUT - bool "Ser3 uses DMA8 for output" - depends on ETRAXFS - help - Enables the DMA8 output channel for ser3 (ttyS3). - If you do not enable DMA, an interrupt for each character will be - used when transmitting data. - Normally you want to use DMA, unless you use the DMA channel for - something else. - -config ETRAX_SERIAL_PORT3_DMA2_OUT - bool "Ser3 uses DMA2 for output" - depends on CRIS_MACH_ARTPEC3 - help - Enables the DMA2 output channel for ser3 (ttyS3). - If you do not enable DMA, an interrupt for each character will be - used when transmitting data. - Normally you want to use DMA, unless you use the DMA channel for - something else. - endchoice endmenu diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig index daf5f19b61a1..239dab0b95c1 100644 --- a/arch/cris/arch-v10/drivers/Kconfig +++ b/arch/cris/arch-v10/drivers/Kconfig @@ -417,16 +417,6 @@ config ETRAX_USB_HOST for CTRL and BULK traffic only, INTR traffic may work as well however (depending on the requirements of timeliness). -config ETRAX_USB_HOST_PORT1 - bool "USB port 1 enabled" - depends on ETRAX_USB_HOST - default n - -config ETRAX_USB_HOST_PORT2 - bool "USB port 2 enabled" - depends on ETRAX_USB_HOST - default n - config ETRAX_PTABLE_SECTOR int "Byte-offset of partition table sector" depends on ETRAX_AXISFLASHMAP @@ -527,19 +517,6 @@ config ETRAX_GPIO Remember that you need to setup the port directions appropriately in the General configuration. -config ETRAX_PA_BUTTON_BITMASK - hex "PA-buttons bitmask" - depends on ETRAX_GPIO - default "02" - help - This is a bitmask with information about what bits on PA that - are used for buttons. - Most products has a so called TEST button on PA1, if that's true - use 02 here. - Use 00 if there are no buttons on PA. - If the bitmask is <> 00 a button driver will be included in the gpio - driver. ETRAX general I/O support must be enabled. - config ETRAX_PA_CHANGEABLE_DIR hex "PA user changeable dir mask" depends on ETRAX_GPIO @@ -580,51 +557,4 @@ config ETRAX_PB_CHANGEABLE_BITS Bit set = changeable. You probably want 00 here. -config ETRAX_DS1302_RST_ON_GENERIC_PORT - bool "DS1302 RST on Generic Port" - depends on ETRAX_DS1302 - help - If your product has the RST signal line for the DS1302 RTC on the - Generic Port then say Y here, otherwise leave it as N in which - case the RST signal line is assumed to be connected to Port PB - (just like the SCL and SDA lines). - -config ETRAX_DS1302_RSTBIT - int "DS1302 RST bit number" - depends on ETRAX_DS1302 - default "2" - help - This is the bit number for the RST signal line of the DS1302 RTC on - the selected port. If you have selected the generic port then it - should be bit 27, otherwise your best bet is bit 5. - -config ETRAX_DS1302_SCLBIT - int "DS1302 SCL bit number" - depends on ETRAX_DS1302 - default "1" - help - This is the bit number for the SCL signal line of the DS1302 RTC on - Port PB. This is probably best left at 3. - -config ETRAX_DS1302_SDABIT - int "DS1302 SDA bit number" - depends on ETRAX_DS1302 - default "0" - help - This is the bit number for the SDA signal line of the DS1302 RTC on - Port PB. This is probably best left at 2. - -config ETRAX_DS1302_TRICKLE_CHARGE - int "DS1302 Trickle charger value" - depends on ETRAX_DS1302 - default "0" - help - This controls the initial value of the trickle charge register. - 0 = disabled (use this if you are unsure or have a non rechargeable battery) - Otherwise the following values can be OR:ed together to control the - charge current: - 1 = 2kohm, 2 = 4kohm, 3 = 4kohm - 4 = 1 diode, 8 = 2 diodes - Allowed values are (increasing current): 0, 11, 10, 9, 7, 6, 5 - endif diff --git a/arch/cris/arch-v10/drivers/Makefile b/arch/cris/arch-v10/drivers/Makefile index 44bf2e88c26e..e5c13183b97c 100644 --- a/arch/cris/arch-v10/drivers/Makefile +++ b/arch/cris/arch-v10/drivers/Makefile @@ -6,7 +6,5 @@ obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o obj-$(CONFIG_ETRAX_I2C) += i2c.o obj-$(CONFIG_ETRAX_I2C_EEPROM) += eeprom.o obj-$(CONFIG_ETRAX_GPIO) += gpio.o -obj-$(CONFIG_ETRAX_DS1302) += ds1302.o -obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig index 1d866d3ee2f8..6792503aaf79 100644 --- a/arch/cris/arch-v32/drivers/Kconfig +++ b/arch/cris/arch-v32/drivers/Kconfig @@ -19,64 +19,6 @@ config ETRAX_NO_PHY switch. This option should normally be disabled. If enabled, speed and duplex will be locked to 100 Mbit and full duplex. -config ETRAX_ETHERNET_IFACE0 - depends on ETRAX_ETHERNET - bool "Enable network interface 0" - -config ETRAX_ETHERNET_IFACE1 - depends on (ETRAX_ETHERNET && ETRAXFS) - bool "Enable network interface 1 (uses DMA6 and DMA7)" - -config ETRAX_ETHERNET_GBIT - depends on (ETRAX_ETHERNET && CRIS_MACH_ARTPEC3) - bool "Enable gigabit Ethernet support" - -choice - prompt "Eth0 led group" - depends on ETRAX_ETHERNET_IFACE0 - default ETRAX_ETH0_USE_LEDGRP0 - -config ETRAX_ETH0_USE_LEDGRP0 - bool "Use LED grp 0" - depends on ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO - help - Use LED grp 0 for eth0 - -config ETRAX_ETH0_USE_LEDGRP1 - bool "Use LED grp 1" - depends on ETRAX_NBR_LED_GRP_TWO - help - Use LED grp 1 for eth0 - -config ETRAX_ETH0_USE_LEDGRPNULL - bool "Use no LEDs for eth0" - help - Use no LEDs for eth0 -endchoice - -choice - prompt "Eth1 led group" - depends on ETRAX_ETHERNET_IFACE1 - default ETRAX_ETH1_USE_LEDGRP1 - -config ETRAX_ETH1_USE_LEDGRP0 - bool "Use LED grp 0" - depends on ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO - help - Use LED grp 0 for eth1 - -config ETRAX_ETH1_USE_LEDGRP1 - bool "Use LED grp 1" - depends on ETRAX_NBR_LED_GRP_TWO - help - Use LED grp 1 for eth1 - -config ETRAX_ETH1_USE_LEDGRPNULL - bool "Use no LEDs for eth1" - help - Use no LEDs for eth1 -endchoice - config ETRAXFS_SERIAL bool "Serial-port support" depends on ETRAX_ARCH_V32 @@ -108,261 +50,24 @@ config ETRAX_SERIAL_PORT0 if you do not need DMA to something else. ser0 can use dma4 or dma6 for output and dma5 or dma7 for input. -choice - prompt "Ser0 default port type " - depends on ETRAX_SERIAL_PORT0 - default ETRAX_SERIAL_PORT0_TYPE_232 - help - Type of serial port. - -config ETRAX_SERIAL_PORT0_TYPE_232 - bool "Ser0 is a RS-232 port" - help - Configure serial port 0 to be a RS-232 port. - -config ETRAX_SERIAL_PORT0_TYPE_485HD - bool "Ser0 is a half duplex RS-485 port" - depends on ETRAX_RS485 - help - Configure serial port 0 to be a half duplex (two wires) RS-485 port. - -config ETRAX_SERIAL_PORT0_TYPE_485FD - bool "Ser0 is a full duplex RS-485 port" - depends on ETRAX_RS485 - help - Configure serial port 0 to be a full duplex (four wires) RS-485 port. -endchoice - -config ETRAX_SER0_DTR_BIT - string "Ser 0 DTR bit (empty = not used)" - depends on ETRAX_SERIAL_PORT0 - -config ETRAX_SER0_RI_BIT - string "Ser 0 RI bit (empty = not used)" - depends on ETRAX_SERIAL_PORT0 - -config ETRAX_SER0_DSR_BIT - string "Ser 0 DSR bit (empty = not used)" - depends on ETRAX_SERIAL_PORT0 - -config ETRAX_SER0_CD_BIT - string "Ser 0 CD bit (empty = not used)" - depends on ETRAX_SERIAL_PORT0 - config ETRAX_SERIAL_PORT1 bool "Serial port 1 enabled" depends on ETRAXFS_SERIAL help Enables the ETRAX FS serial driver for ser1 (ttyS1). -choice - prompt "Ser1 default port type" - depends on ETRAX_SERIAL_PORT1 - default ETRAX_SERIAL_PORT1_TYPE_232 - help - Type of serial port. - -config ETRAX_SERIAL_PORT1_TYPE_232 - bool "Ser1 is a RS-232 port" - help - Configure serial port 1 to be a RS-232 port. - -config ETRAX_SERIAL_PORT1_TYPE_485HD - bool "Ser1 is a half duplex RS-485 port" - depends on ETRAX_RS485 - help - Configure serial port 1 to be a half duplex (two wires) RS-485 port. - -config ETRAX_SERIAL_PORT1_TYPE_485FD - bool "Ser1 is a full duplex RS-485 port" - depends on ETRAX_RS485 - help - Configure serial port 1 to be a full duplex (four wires) RS-485 port. -endchoice - -config ETRAX_SER1_DTR_BIT - string "Ser 1 DTR bit (empty = not used)" - depends on ETRAX_SERIAL_PORT1 - -config ETRAX_SER1_RI_BIT - string "Ser 1 RI bit (empty = not used)" - depends on ETRAX_SERIAL_PORT1 - -config ETRAX_SER1_DSR_BIT - string "Ser 1 DSR bit (empty = not used)" - depends on ETRAX_SERIAL_PORT1 - -config ETRAX_SER1_CD_BIT - string "Ser 1 CD bit (empty = not used)" - depends on ETRAX_SERIAL_PORT1 - config ETRAX_SERIAL_PORT2 bool "Serial port 2 enabled" depends on ETRAXFS_SERIAL help Enables the ETRAX FS serial driver for ser2 (ttyS2). -choice - prompt "Ser2 default port type" - depends on ETRAX_SERIAL_PORT2 - default ETRAX_SERIAL_PORT2_TYPE_232 - help - What DMA channel to use for ser2 - -config ETRAX_SERIAL_PORT2_TYPE_232 - bool "Ser2 is a RS-232 port" - help - Configure serial port 2 to be a RS-232 port. - -config ETRAX_SERIAL_PORT2_TYPE_485HD - bool "Ser2 is a half duplex RS-485 port" - depends on ETRAX_RS485 - help - Configure serial port 2 to be a half duplex (two wires) RS-485 port. - -config ETRAX_SERIAL_PORT2_TYPE_485FD - bool "Ser2 is a full duplex RS-485 port" - depends on ETRAX_RS485 - help - Configure serial port 2 to be a full duplex (four wires) RS-485 port. -endchoice - - -config ETRAX_SER2_DTR_BIT - string "Ser 2 DTR bit (empty = not used)" - depends on ETRAX_SERIAL_PORT2 - -config ETRAX_SER2_RI_BIT - string "Ser 2 RI bit (empty = not used)" - depends on ETRAX_SERIAL_PORT2 - -config ETRAX_SER2_DSR_BIT - string "Ser 2 DSR bit (empty = not used)" - depends on ETRAX_SERIAL_PORT2 - -config ETRAX_SER2_CD_BIT - string "Ser 2 CD bit (empty = not used)" - depends on ETRAX_SERIAL_PORT2 - config ETRAX_SERIAL_PORT3 bool "Serial port 3 enabled" depends on ETRAXFS_SERIAL help Enables the ETRAX FS serial driver for ser3 (ttyS3). -choice - prompt "Ser3 default port type" - depends on ETRAX_SERIAL_PORT3 - default ETRAX_SERIAL_PORT3_TYPE_232 - help - What DMA channel to use for ser3. - -config ETRAX_SERIAL_PORT3_TYPE_232 - bool "Ser3 is a RS-232 port" - help - Configure serial port 3 to be a RS-232 port. - -config ETRAX_SERIAL_PORT3_TYPE_485HD - bool "Ser3 is a half duplex RS-485 port" - depends on ETRAX_RS485 - help - Configure serial port 3 to be a half duplex (two wires) RS-485 port. - -config ETRAX_SERIAL_PORT3_TYPE_485FD - bool "Ser3 is a full duplex RS-485 port" - depends on ETRAX_RS485 - help - Configure serial port 3 to be a full duplex (four wires) RS-485 port. -endchoice - -config ETRAX_SER3_DTR_BIT - string "Ser 3 DTR bit (empty = not used)" - depends on ETRAX_SERIAL_PORT3 - -config ETRAX_SER3_RI_BIT - string "Ser 3 RI bit (empty = not used)" - depends on ETRAX_SERIAL_PORT3 - -config ETRAX_SER3_DSR_BIT - string "Ser 3 DSR bit (empty = not used)" - depends on ETRAX_SERIAL_PORT3 - -config ETRAX_SER3_CD_BIT - string "Ser 3 CD bit (empty = not used)" - depends on ETRAX_SERIAL_PORT3 - -config ETRAX_SERIAL_PORT4 - bool "Serial port 4 enabled" - depends on ETRAXFS_SERIAL && CRIS_MACH_ARTPEC3 - help - Enables the ETRAX FS serial driver for ser4 (ttyS4). - -choice - prompt "Ser4 default port type" - depends on ETRAX_SERIAL_PORT4 - default ETRAX_SERIAL_PORT4_TYPE_232 - help - What DMA channel to use for ser4. - -config ETRAX_SERIAL_PORT4_TYPE_232 - bool "Ser4 is a RS-232 port" - help - Configure serial port 4 to be a RS-232 port. - -config ETRAX_SERIAL_PORT4_TYPE_485HD - bool "Ser4 is a half duplex RS-485 port" - depends on ETRAX_RS485 - help - Configure serial port 4 to be a half duplex (two wires) RS-485 port. - -config ETRAX_SERIAL_PORT4_TYPE_485FD - bool "Ser4 is a full duplex RS-485 port" - depends on ETRAX_RS485 - help - Configure serial port 4 to be a full duplex (four wires) RS-485 port. -endchoice - -choice - prompt "Ser4 DMA in channel " - depends on ETRAX_SERIAL_PORT4 - default ETRAX_SERIAL_PORT4_NO_DMA_IN - help - What DMA channel to use for ser4. - - -config ETRAX_SERIAL_PORT4_NO_DMA_IN - bool "Ser4 uses no DMA for input" - help - Do not use DMA for ser4 input. - -config ETRAX_SERIAL_PORT4_DMA9_IN - bool "Ser4 uses DMA9 for input" - depends on ETRAX_SERIAL_PORT4 - help - Enables the DMA9 input channel for ser4 (ttyS4). - If you do not enable DMA, an interrupt for each character will be - used when receiving data. - Normally you want to use DMA, unless you use the DMA channel for - something else. - -endchoice - -config ETRAX_SER4_DTR_BIT - string "Ser 4 DTR bit (empty = not used)" - depends on ETRAX_SERIAL_PORT4 - -config ETRAX_SER4_RI_BIT - string "Ser 4 RI bit (empty = not used)" - depends on ETRAX_SERIAL_PORT4 - -config ETRAX_SER4_DSR_BIT - string "Ser 4 DSR bit (empty = not used)" - depends on ETRAX_SERIAL_PORT4 - -config ETRAX_SER4_CD_BIT - string "Ser 4 CD bit (empty = not used)" - depends on ETRAX_SERIAL_PORT4 - config ETRAX_SYNCHRONOUS_SERIAL bool "Synchronous serial-port support" depends on ETRAX_ARCH_V32 @@ -703,32 +408,6 @@ config ETRAX_SPI_SSER0 want to build it as a module, which will be named spi_crisv32_sser. (You need to select MMC separately.) -config ETRAX_SPI_SSER0_DMA - bool "DMA for SPI on sser0 enabled" - depends on ETRAX_SPI_SSER0 - depends on !ETRAX_SERIAL_PORT1_DMA4_OUT && !ETRAX_SERIAL_PORT1_DMA5_IN - default y - help - Say Y if using DMA (dma4/dma5) for SPI on synchronous serial port 0. - -config ETRAX_SPI_MMC_CD_SSER0_PIN - string "MMC/SD card detect pin for SPI on sser0" - depends on ETRAX_SPI_SSER0 && MMC_SPI - default "pd11" - help - The pin to use for SD/MMC card detect. This pin should be pulled up - and grounded when a card is present. If defined as " " (space), no - pin is selected. A card must then always be inserted for proper - action. - -config ETRAX_SPI_MMC_WP_SSER0_PIN - string "MMC/SD card write-protect pin for SPI on sser0" - depends on ETRAX_SPI_SSER0 && MMC_SPI - default "pd10" - help - The pin to use for the SD/MMC write-protect signal for a memory - card. If defined as " " (space), the card is considered writable. - config ETRAX_SPI_SSER1 tristate "SPI using synchronous serial port 1 (sser1)" depends on ETRAX_SPI_MMC @@ -742,32 +421,6 @@ config ETRAX_SPI_SSER1 want to build it as a module, which will be named spi_crisv32_sser. (You need to select MMC separately.) -config ETRAX_SPI_SSER1_DMA - bool "DMA for SPI on sser1 enabled" - depends on ETRAX_SPI_SSER1 && !ETRAX_ETHERNET_IFACE1 - depends on !ETRAX_SERIAL_PORT0_DMA6_OUT && !ETRAX_SERIAL_PORT0_DMA7_IN - default y - help - Say Y if using DMA (dma6/dma7) for SPI on synchronous serial port 1. - -config ETRAX_SPI_MMC_CD_SSER1_PIN - string "MMC/SD card detect pin for SPI on sser1" - depends on ETRAX_SPI_SSER1 && MMC_SPI - default "pd12" - help - The pin to use for SD/MMC card detect. This pin should be pulled up - and grounded when a card is present. If defined as " " (space), no - pin is selected. A card must then always be inserted for proper - action. - -config ETRAX_SPI_MMC_WP_SSER1_PIN - string "MMC/SD card write-protect pin for SPI on sser1" - depends on ETRAX_SPI_SSER1 && MMC_SPI - default "pd9" - help - The pin to use for the SD/MMC write-protect signal for a memory - card. If defined as " " (space), the card is considered writable. - config ETRAX_SPI_GPIO tristate "Bitbanged SPI using gpio pins" depends on ETRAX_SPI_MMC @@ -782,51 +435,4 @@ config ETRAX_SPI_GPIO Say m to build it as a module, which will be called spi_crisv32_gpio. (You need to select MMC separately.) -# The default match that of sser0, only because that's how it was tested. -config ETRAX_SPI_CS_PIN - string "SPI chip select pin" - depends on ETRAX_SPI_GPIO - default "pc3" - help - The pin to use for SPI chip select. - -config ETRAX_SPI_CLK_PIN - string "SPI clock pin" - depends on ETRAX_SPI_GPIO - default "pc1" - help - The pin to use for the SPI clock. - -config ETRAX_SPI_DATAIN_PIN - string "SPI MISO (data in) pin" - depends on ETRAX_SPI_GPIO - default "pc16" - help - The pin to use for SPI data in from the device. - -config ETRAX_SPI_DATAOUT_PIN - string "SPI MOSI (data out) pin" - depends on ETRAX_SPI_GPIO - default "pc0" - help - The pin to use for SPI data out to the device. - -config ETRAX_SPI_MMC_CD_GPIO_PIN - string "MMC/SD card detect pin for SPI using gpio (space for none)" - depends on ETRAX_SPI_GPIO && MMC_SPI - default "pd11" - help - The pin to use for SD/MMC card detect. This pin should be pulled up - and grounded when a card is present. If defined as " " (space), no - pin is selected. A card must then always be inserted for proper - action. - -config ETRAX_SPI_MMC_WP_GPIO_PIN - string "MMC/SD card write-protect pin for SPI using gpio (space for none)" - depends on ETRAX_SPI_GPIO && MMC_SPI - default "pd10" - help - The pin to use for the SD/MMC write-protect signal for a memory - card. If defined as " " (space), the card is considered writable. - endif diff --git a/arch/cris/arch-v32/mach-a3/Kconfig b/arch/cris/arch-v32/mach-a3/Kconfig index 7796aafc711e..87547271a595 100644 --- a/arch/cris/arch-v32/mach-a3/Kconfig +++ b/arch/cris/arch-v32/mach-a3/Kconfig @@ -15,10 +15,6 @@ config ETRAX_SERIAL_PORTS int default 5 -config ETRAX_DDR - bool - default y - config ETRAX_DDR2_MRS hex "DDR2 MRS" default "0" diff --git a/arch/cris/include/asm/processor.h b/arch/cris/include/asm/processor.h index c0a29b96b92b..15b815df29c1 100644 --- a/arch/cris/include/asm/processor.h +++ b/arch/cris/include/asm/processor.h @@ -47,7 +47,6 @@ struct task_struct; */ #define task_pt_regs(task) user_regs(task_thread_info(task)) -#define current_regs() task_pt_regs(current) unsigned long get_wchan(struct task_struct *p); diff --git a/arch/cris/include/uapi/asm/kvm_para.h b/arch/cris/include/uapi/asm/kvm_para.h new file mode 100644 index 000000000000..14fab8f0b957 --- /dev/null +++ b/arch/cris/include/uapi/asm/kvm_para.h @@ -0,0 +1 @@ +#include <asm-generic/kvm_para.h> diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c index 76069c18ee42..68232db98baa 100644 --- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c @@ -114,6 +114,11 @@ int pud_huge(pud_t pud) return 0; } +int pmd_huge_support(void) +{ + return 0; +} + struct page * follow_huge_pmd(struct mm_struct *mm, unsigned long address, pmd_t *pmd, int write) { diff --git a/arch/metag/mm/hugetlbpage.c b/arch/metag/mm/hugetlbpage.c index 3c52fa6d0f8e..042431509b56 100644 --- a/arch/metag/mm/hugetlbpage.c +++ b/arch/metag/mm/hugetlbpage.c @@ -110,6 +110,11 @@ int pud_huge(pud_t pud) return 0; } +int pmd_huge_support(void) +{ + return 1; +} + struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, pmd_t *pmd, int write) { diff --git a/arch/metag/mm/init.c b/arch/metag/mm/init.c index 28813f164730..123919534b80 100644 --- a/arch/metag/mm/init.c +++ b/arch/metag/mm/init.c @@ -407,10 +407,9 @@ void free_initrd_mem(unsigned long start, unsigned long end) #endif #ifdef CONFIG_OF_FLATTREE -void __init early_init_dt_setup_initrd_arch(unsigned long start, - unsigned long end) +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) { - pr_err("%s(%lx, %lx)\n", + pr_err("%s(%llx, %llx)\n", __func__, start, end); } #endif /* CONFIG_OF_FLATTREE */ diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c index 0a2c68f9f9b0..0c4453f134cb 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c @@ -46,11 +46,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) memblock_add(base, size); } -void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) -{ - return __va(memblock_alloc(size, align)); -} - #ifdef CONFIG_EARLY_PRINTK static char *stdout; @@ -136,8 +131,7 @@ void __init early_init_devtree(void *params) } #ifdef CONFIG_BLK_DEV_INITRD -void __init early_init_dt_setup_initrd_arch(unsigned long start, - unsigned long end) +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) { initrd_start = (unsigned long)__va(start); initrd_end = (unsigned long)__va(end); diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index 7e954042f252..0fa0b69cdd53 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c @@ -58,8 +58,7 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) } #ifdef CONFIG_BLK_DEV_INITRD -void __init early_init_dt_setup_initrd_arch(unsigned long start, - unsigned long end) +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) { initrd_start = (unsigned long)__va(start); initrd_end = (unsigned long)__va(end); diff --git a/arch/mips/mm/hugetlbpage.c b/arch/mips/mm/hugetlbpage.c index a7fee0dfb7a9..01fda4419ed0 100644 --- a/arch/mips/mm/hugetlbpage.c +++ b/arch/mips/mm/hugetlbpage.c @@ -85,6 +85,11 @@ int pud_huge(pud_t pud) return (pud_val(pud) & _PAGE_HUGE) != 0; } +int pmd_huge_support(void) +{ + return 1; +} + struct page * follow_huge_pmd(struct mm_struct *mm, unsigned long address, pmd_t *pmd, int write) diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S index 222152a3f751..177d61de51c9 100644 --- a/arch/mn10300/kernel/entry.S +++ b/arch/mn10300/kernel/entry.S @@ -171,10 +171,10 @@ ret_from_intr: mov (REG_EPSW,fp),d0 # need to deliver signals before # returning to userspace and EPSW_nSL,d0 - beq resume_kernel # returning to supervisor mode + bne resume_userspace # returning to userspace #ifdef CONFIG_PREEMPT -ENTRY(resume_kernel) +resume_kernel: LOCAL_IRQ_DISABLE mov (TI_preempt_count,a2),d0 # non-zero preempt_count ? cmp 0,d0 @@ -189,6 +189,8 @@ need_resched: bne restore_all call preempt_schedule_irq[],0 jmp need_resched +#else + jmp resume_kernel #endif diff --git a/arch/openrisc/kernel/prom.c b/arch/openrisc/kernel/prom.c index 5869e3fa5dd3..a63e76872f84 100644 --- a/arch/openrisc/kernel/prom.c +++ b/arch/openrisc/kernel/prom.c @@ -55,11 +55,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) memblock_add(base, size); } -void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) -{ - return __va(memblock_alloc(size, align)); -} - void __init early_init_devtree(void *params) { void *alloc; @@ -96,8 +91,7 @@ void __init early_init_devtree(void *params) } #ifdef CONFIG_BLK_DEV_INITRD -void __init early_init_dt_setup_initrd_arch(unsigned long start, - unsigned long end) +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) { initrd_start = (unsigned long)__va(start); initrd_end = (unsigned long)__va(end); diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index 77e97dd0c15d..38faeded7d59 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -28,6 +28,9 @@ struct dev_archdata { void *iommu_table_base; } dma_data; +#ifdef CONFIG_IOMMU_API + void *iommu_domain; +#endif #ifdef CONFIG_SWIOTLB dma_addr_t max_direct_dma_addr; #endif diff --git a/arch/powerpc/include/asm/fsl_pamu_stash.h b/arch/powerpc/include/asm/fsl_pamu_stash.h new file mode 100644 index 000000000000..caa1b21c25cd --- /dev/null +++ b/arch/powerpc/include/asm/fsl_pamu_stash.h @@ -0,0 +1,39 @@ +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright (C) 2013 Freescale Semiconductor, Inc. + * + */ + +#ifndef __FSL_PAMU_STASH_H +#define __FSL_PAMU_STASH_H + +/* cache stash targets */ +enum pamu_stash_target { + PAMU_ATTR_CACHE_L1 = 1, + PAMU_ATTR_CACHE_L2, + PAMU_ATTR_CACHE_L3, +}; + +/* + * This attribute allows configuring stashig specific parameters + * in the PAMU hardware. + */ + +struct pamu_stash_attribute { + u32 cpu; /* cpu number */ + u32 cache; /* cache to stash to: L1,L2,L3 */ +}; + +#endif /* __FSL_PAMU_STASH_H */ diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 6bfcab97c981..b7634ce41dbc 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -546,14 +546,8 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) memblock_add(base, size); } -void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) -{ - return __va(memblock_alloc(size, align)); -} - #ifdef CONFIG_BLK_DEV_INITRD -void __init early_init_dt_setup_initrd_arch(unsigned long start, - unsigned long end) +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) { initrd_start = (unsigned long)__va(start); initrd_end = (unsigned long)__va(end); diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 7b6391b68fb8..12e656ffe60e 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1297,7 +1297,8 @@ static void __init prom_query_opal(void) prom_opal_align = 0x10000; } -static int prom_rtas_call(int token, int nargs, int nret, int *outputs, ...) +static int __init prom_rtas_call(int token, int nargs, int nret, + int *outputs, ...) { struct rtas_args rtas_args; va_list list; diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 442d8e23f8f4..8e59abc237d7 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -611,6 +611,7 @@ int cpu_to_chip_id(int cpu) of_node_put(np); return of_get_ibm_chip_id(np); } +EXPORT_SYMBOL(cpu_to_chip_id); /* Helper routines for cpu to core mapping */ int cpu_core_index_of_thread(int cpu) diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 76d8e7cc7805..2dd69bf4af46 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -206,7 +206,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, int trap = TRAP(regs); int is_exec = trap == 0x400; int fault; - int rc = 0; + int rc = 0, store_update_sp = 0; #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) /* @@ -280,6 +280,14 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); + /* + * We want to do this outside mmap_sem, because reading code around nip + * can result in fault, which will cause a deadlock when called with + * mmap_sem held + */ + if (user_mode(regs)) + store_update_sp = store_updates_sp(regs); + /* When running in the kernel we expect faults to occur only to * addresses in user space. All other faults represent errors in the * kernel and should generate an OOPS. Unfortunately, in the case of an @@ -345,8 +353,7 @@ retry: * between the last mapped region and the stack will * expand the stack rather than segfaulting. */ - if (address + 2048 < uregs->gpr[1] - && (!user_mode(regs) || !store_updates_sp(regs))) + if (address + 2048 < uregs->gpr[1] && !store_update_sp) goto bad_area; } if (expand_stack(vma, address)) diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 834ca8eb38f2..d67db4bd672d 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -86,6 +86,11 @@ int pgd_huge(pgd_t pgd) */ return ((pgd_val(pgd) & 0x3) != 0x0); } + +int pmd_huge_support(void) +{ + return 1; +} #else int pmd_huge(pmd_t pmd) { @@ -101,6 +106,11 @@ int pgd_huge(pgd_t pgd) { return 0; } + +int pmd_huge_support(void) +{ + return 0; +} #endif pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index d64feb3ea0be..1f97e2b87a62 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -354,7 +354,7 @@ static int alloc_dispatch_log_kmem_cache(void) } early_initcall(alloc_dispatch_log_kmem_cache); -static void pSeries_idle(void) +static void pseries_lpar_idle(void) { /* This would call on the cpuidle framework, and the back-end pseries * driver to go to idle states @@ -362,10 +362,22 @@ static void pSeries_idle(void) if (cpuidle_idle_call()) { /* On error, execute default handler * to go into low thread priority and possibly - * low power mode. + * low power mode by cedeing processor to hypervisor */ - HMT_low(); - HMT_very_low(); + + /* Indicate to hypervisor that we are idle. */ + get_lppaca()->idle = 1; + + /* + * Yield the processor to the hypervisor. We return if + * an external interrupt occurs (which are driven prior + * to returning here) or if a prod occurs from another + * processor. When returning here, external interrupts + * are enabled. + */ + cede_processor(); + + get_lppaca()->idle = 0; } } @@ -456,15 +468,14 @@ static void __init pSeries_setup_arch(void) pSeries_nvram_init(); - if (firmware_has_feature(FW_FEATURE_SPLPAR)) { + if (firmware_has_feature(FW_FEATURE_LPAR)) { vpa_init(boot_cpuid); - ppc_md.power_save = pSeries_idle; - } - - if (firmware_has_feature(FW_FEATURE_LPAR)) + ppc_md.power_save = pseries_lpar_idle; ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; - else + } else { + /* No special idle routine */ ppc_md.enable_pmcs = power4_enable_pmcs; + } ppc_md.pcibios_root_bridge_prepare = pseries_root_bridge_prepare; diff --git a/arch/powerpc/sysdev/fsl_pci.h b/arch/powerpc/sysdev/fsl_pci.h index defc422a375f..8d455df58471 100644 --- a/arch/powerpc/sysdev/fsl_pci.h +++ b/arch/powerpc/sysdev/fsl_pci.h @@ -16,6 +16,11 @@ struct platform_device; + +/* FSL PCI controller BRR1 register */ +#define PCI_FSL_BRR1 0xbf8 +#define PCI_FSL_BRR1_VER 0xffff + #define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */ #define PCIE_LTSSM_L0 0x16 /* L0 state */ #define PCIE_IP_REV_2_2 0x02080202 /* PCIE IP block version Rev2.2 */ diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index c696ad7d3439..3ec272859e1e 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -62,6 +62,7 @@ config S390 def_bool y select ARCH_DISCARD_MEMBLOCK select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE + select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_INLINE_READ_LOCK select ARCH_INLINE_READ_LOCK_BH @@ -91,7 +92,6 @@ config S390 select ARCH_INLINE_WRITE_UNLOCK_BH select ARCH_INLINE_WRITE_UNLOCK_IRQ select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE - select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS select ARCH_SAVE_PAGE_KEYS if HIBERNATION select ARCH_WANT_IPC_PARSE_VERSION select BUILDTIME_EXTABLE_SORT @@ -135,15 +135,15 @@ config S390 select HAVE_SYSCALL_TRACEPOINTS select HAVE_UID16 if 32BIT select HAVE_VIRT_CPU_ACCOUNTING - select VIRT_TO_BUS select INIT_ALL_POSSIBLE select KTIME_SCALAR if 32BIT select MODULES_USE_ELF_RELA - select OLD_SIGSUSPEND3 select OLD_SIGACTION + select OLD_SIGSUSPEND3 select SYSCTL_EXCEPTION_TRACE select USE_GENERIC_SMP_HELPERS if SMP select VIRT_CPU_ACCOUNTING + select VIRT_TO_BUS config SCHED_OMIT_FRAME_POINTER def_bool y @@ -526,6 +526,7 @@ config CRASH_DUMP bool "kernel crash dumps" depends on 64BIT && SMP select KEXEC + select ZFCPDUMP help Generate crash dump after being started by kexec. Crash dump kernels are loaded in the main kernel with kexec-tools @@ -536,7 +537,7 @@ config CRASH_DUMP config ZFCPDUMP def_bool n prompt "zfcpdump support" - select SMP + depends on SMP help Select this option if you want to build an zfcpdump enabled kernel. Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this. diff --git a/arch/s390/defconfig b/arch/s390/defconfig index b74400e3e035..d204c65bf722 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -1,14 +1,13 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_FHANDLE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y -CONFIG_AUDIT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y CONFIG_RCU_FAST_NO_HZ=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -27,6 +26,7 @@ CONFIG_RD_BZIP2=y CONFIG_RD_LZMA=y CONFIG_RD_XZ=y CONFIG_RD_LZO=y +CONFIG_RD_LZ4=y CONFIG_EXPERT=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y @@ -38,11 +38,13 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_PARTITION_ADVANCED=y CONFIG_IBM_PARTITION=y +# CONFIG_EFI_PARTITION is not set CONFIG_DEFAULT_DEADLINE=y CONFIG_HZ_100=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y CONFIG_KSM=y +CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_CRASH_DUMP=y CONFIG_BINFMT_MISC=m CONFIG_HIBERNATION=y @@ -92,40 +94,49 @@ CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_ZFCP=y +CONFIG_SCSI_VIRTIO=y CONFIG_NETDEVICES=y CONFIG_BONDING=m CONFIG_DUMMY=m CONFIG_EQUALIZER=m CONFIG_TUN=m CONFIG_VIRTIO_NET=y +# CONFIG_INPUT is not set +# CONFIG_SERIO is not set CONFIG_RAW_DRIVER=m CONFIG_VIRTIO_BALLOON=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y +CONFIG_XFS_FS=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_BTRFS_FS=y +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_FANOTIFY=y +CONFIG_FUSE_FS=y CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y # CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_PAGEALLOC=y CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y -CONFIG_PROVE_RCU=y CONFIG_LOCK_STAT=y CONFIG_DEBUG_LOCKDEP=y CONFIG_DEBUG_LIST=y CONFIG_DEBUG_NOTIFIERS=y +CONFIG_PROVE_RCU=y +CONFIG_RCU_CPU_STALL_TIMEOUT=60 CONFIG_RCU_TRACE=y -CONFIG_KPROBES_SANITY_TEST=y -CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y CONFIG_LATENCYTOP=y -CONFIG_DEBUG_PAGEALLOC=y CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_KPROBES_SANITY_TEST=y # CONFIG_STRICT_DEVMEM is not set -CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_TEST=m @@ -137,8 +148,10 @@ CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_CMAC=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_CRC32=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m @@ -165,6 +178,8 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m CONFIG_ZCRYPT=m CONFIG_CRYPTO_SHA1_S390=m CONFIG_CRYPTO_SHA256_S390=m diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h index 1eaa3625803c..5f8bcc5fe423 100644 --- a/arch/s390/include/asm/irq.h +++ b/arch/s390/include/asm/irq.h @@ -78,10 +78,14 @@ typedef void (*ext_int_handler_t)(struct ext_code, unsigned int, unsigned long); int register_external_interrupt(u16 code, ext_int_handler_t handler); int unregister_external_interrupt(u16 code, ext_int_handler_t handler); -void service_subclass_irq_register(void); -void service_subclass_irq_unregister(void); -void measurement_alert_subclass_register(void); -void measurement_alert_subclass_unregister(void); + +enum irq_subclass { + IRQ_SUBCLASS_MEASUREMENT_ALERT = 5, + IRQ_SUBCLASS_SERVICE_SIGNAL = 9, +}; + +void irq_subclass_register(enum irq_subclass subclass); +void irq_subclass_unregister(enum irq_subclass subclass); #define irq_canonicalize(irq) (irq) diff --git a/arch/s390/include/asm/kprobes.h b/arch/s390/include/asm/kprobes.h index dcf6948a875c..4176dfe0fba1 100644 --- a/arch/s390/include/asm/kprobes.h +++ b/arch/s390/include/asm/kprobes.h @@ -31,6 +31,8 @@ #include <linux/ptrace.h> #include <linux/percpu.h> +#define __ARCH_WANT_KPROBES_INSN_SLOT + struct pt_regs; struct kprobe; @@ -57,7 +59,7 @@ typedef u16 kprobe_opcode_t; /* Architecture specific copy of original instruction */ struct arch_specific_insn { /* copy of original instruction */ - kprobe_opcode_t insn[MAX_INSN_SIZE]; + kprobe_opcode_t *insn; }; struct prev_kprobe { diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index 06a136136047..7dc7f9c63b65 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -56,5 +56,6 @@ bool sclp_has_linemode(void); bool sclp_has_vt220(void); int sclp_pci_configure(u32 fid); int sclp_pci_deconfigure(u32 fid); +int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode); #endif /* _ASM_S390_SCLP_H */ diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 8b6e4f5288a2..1f1b8c70ab97 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -221,25 +221,26 @@ static int groups16_from_user(struct group_info *group_info, u16 __user *groupli asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist) { + const struct cred *cred = current_cred(); int i; if (gidsetsize < 0) return -EINVAL; - get_group_info(current->cred->group_info); - i = current->cred->group_info->ngroups; + get_group_info(cred->group_info); + i = cred->group_info->ngroups; if (gidsetsize) { if (i > gidsetsize) { i = -EINVAL; goto out; } - if (groups16_to_user(grouplist, current->cred->group_info)) { + if (groups16_to_user(grouplist, cred->group_info)) { i = -EFAULT; goto out; } } out: - put_group_info(current->cred->group_info); + put_group_info(cred->group_info); return i; } diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index c439ac9ced09..1389b637dae5 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -332,9 +332,9 @@ static int setup_frame32(int sig, struct k_sigaction *ka, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { - regs->gprs[14] = (__u64) ka->sa.sa_restorer | PSW32_ADDR_AMODE; + regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE; } else { - regs->gprs[14] = (__u64) frame->retcode | PSW32_ADDR_AMODE; + regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE; if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, (u16 __force __user *)(frame->retcode))) goto give_sigsegv; @@ -400,9 +400,9 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { - regs->gprs[14] = (__u64) ka->sa.sa_restorer | PSW32_ADDR_AMODE; + regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE; } else { - regs->gprs[14] = (__u64) frame->retcode | PSW32_ADDR_AMODE; + regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE; err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, (u16 __force __user *)(frame->retcode)); } @@ -417,7 +417,7 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, regs->psw.mask = PSW_MASK_BA | (psw_user_bits & PSW_MASK_ASC) | (regs->psw.mask & ~PSW_MASK_ASC); - regs->psw.addr = (__u64) ka->sa.sa_handler; + regs->psw.addr = (__u64 __force) ka->sa.sa_handler; regs->gprs[2] = map_signal(sig); regs->gprs[3] = (__force __u64) &frame->info; diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index d8f355657171..c84f33d51f7b 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -16,6 +16,7 @@ #include <asm/os_info.h> #include <asm/elf.h> #include <asm/ipl.h> +#include <asm/sclp.h> #define PTR_ADD(x, y) (((char *) (x)) + ((unsigned long) (y))) #define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y))) @@ -64,22 +65,46 @@ static ssize_t copy_page_real(void *buf, void *src, size_t csize) } /* - * Copy one page from "oldmem" + * Pointer to ELF header in new kernel + */ +static void *elfcorehdr_newmem; + +/* + * Copy one page from zfcpdump "oldmem" + * + * For pages below ZFCPDUMP_HSA_SIZE memory from the HSA is copied. Otherwise + * real memory copy is used. + */ +static ssize_t copy_oldmem_page_zfcpdump(char *buf, size_t csize, + unsigned long src, int userbuf) +{ + int rc; + + if (src < ZFCPDUMP_HSA_SIZE) { + rc = memcpy_hsa(buf, src, csize, userbuf); + } else { + if (userbuf) + rc = copy_to_user_real((void __force __user *) buf, + (void *) src, csize); + else + rc = memcpy_real(buf, (void *) src, csize); + } + return rc ? rc : csize; +} + +/* + * Copy one page from kdump "oldmem" * * For the kdump reserved memory this functions performs a swap operation: * - [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE] is mapped to [0 - OLDMEM_SIZE]. * - [0 - OLDMEM_SIZE] is mapped to [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE] */ -ssize_t copy_oldmem_page(unsigned long pfn, char *buf, - size_t csize, unsigned long offset, int userbuf) +static ssize_t copy_oldmem_page_kdump(char *buf, size_t csize, + unsigned long src, int userbuf) + { - unsigned long src; int rc; - if (!csize) - return 0; - - src = (pfn << PAGE_SHIFT) + offset; if (src < OLDMEM_SIZE) src += OLDMEM_BASE; else if (src > OLDMEM_BASE && @@ -90,7 +115,88 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, (void *) src, csize); else rc = copy_page_real(buf, (void *) src, csize); - return (rc == 0) ? csize : rc; + return (rc == 0) ? rc : csize; +} + +/* + * Copy one page from "oldmem" + */ +ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, + unsigned long offset, int userbuf) +{ + unsigned long src; + + if (!csize) + return 0; + src = (pfn << PAGE_SHIFT) + offset; + if (OLDMEM_BASE) + return copy_oldmem_page_kdump(buf, csize, src, userbuf); + else + return copy_oldmem_page_zfcpdump(buf, csize, src, userbuf); +} + +/* + * Remap "oldmem" for kdump + * + * For the kdump reserved memory this functions performs a swap operation: + * [0 - OLDMEM_SIZE] is mapped to [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE] + */ +static int remap_oldmem_pfn_range_kdump(struct vm_area_struct *vma, + unsigned long from, unsigned long pfn, + unsigned long size, pgprot_t prot) +{ + unsigned long size_old; + int rc; + + if (pfn < OLDMEM_SIZE >> PAGE_SHIFT) { + size_old = min(size, OLDMEM_SIZE - (pfn << PAGE_SHIFT)); + rc = remap_pfn_range(vma, from, + pfn + (OLDMEM_BASE >> PAGE_SHIFT), + size_old, prot); + if (rc || size == size_old) + return rc; + size -= size_old; + from += size_old; + pfn += size_old >> PAGE_SHIFT; + } + return remap_pfn_range(vma, from, pfn, size, prot); +} + +/* + * Remap "oldmem" for zfcpdump + * + * We only map available memory above ZFCPDUMP_HSA_SIZE. Memory below + * ZFCPDUMP_HSA_SIZE is read on demand using the copy_oldmem_page() function. + */ +static int remap_oldmem_pfn_range_zfcpdump(struct vm_area_struct *vma, + unsigned long from, + unsigned long pfn, + unsigned long size, pgprot_t prot) +{ + unsigned long size_hsa; + + if (pfn < ZFCPDUMP_HSA_SIZE >> PAGE_SHIFT) { + size_hsa = min(size, ZFCPDUMP_HSA_SIZE - (pfn << PAGE_SHIFT)); + if (size == size_hsa) + return 0; + size -= size_hsa; + from += size_hsa; + pfn += size_hsa >> PAGE_SHIFT; + } + return remap_pfn_range(vma, from, pfn, size, prot); +} + +/* + * Remap "oldmem" for kdump or zfcpdump + */ +int remap_oldmem_pfn_range(struct vm_area_struct *vma, unsigned long from, + unsigned long pfn, unsigned long size, pgprot_t prot) +{ + if (OLDMEM_BASE) + return remap_oldmem_pfn_range_kdump(vma, from, pfn, size, prot); + else + return remap_oldmem_pfn_range_zfcpdump(vma, from, pfn, size, + prot); } /* @@ -101,11 +207,21 @@ int copy_from_oldmem(void *dest, void *src, size_t count) unsigned long copied = 0; int rc; - if ((unsigned long) src < OLDMEM_SIZE) { - copied = min(count, OLDMEM_SIZE - (unsigned long) src); - rc = memcpy_real(dest, src + OLDMEM_BASE, copied); - if (rc) - return rc; + if (OLDMEM_BASE) { + if ((unsigned long) src < OLDMEM_SIZE) { + copied = min(count, OLDMEM_SIZE - (unsigned long) src); + rc = memcpy_real(dest, src + OLDMEM_BASE, copied); + if (rc) + return rc; + } + } else { + if ((unsigned long) src < ZFCPDUMP_HSA_SIZE) { + copied = min(count, + ZFCPDUMP_HSA_SIZE - (unsigned long) src); + rc = memcpy_hsa(dest, (unsigned long) src, copied, 0); + if (rc) + return rc; + } } return memcpy_real(dest + copied, src + copied, count - copied); } @@ -368,14 +484,6 @@ static int get_mem_chunk_cnt(void) } /* - * Relocate pointer in order to allow vmcore code access the data - */ -static inline unsigned long relocate(unsigned long addr) -{ - return OLDMEM_BASE + addr; -} - -/* * Initialize ELF loads (new kernel) */ static int loads_init(Elf64_Phdr *phdr, u64 loads_offset) @@ -426,7 +534,7 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset) ptr = nt_vmcoreinfo(ptr); memset(phdr, 0, sizeof(*phdr)); phdr->p_type = PT_NOTE; - phdr->p_offset = relocate(notes_offset); + phdr->p_offset = notes_offset; phdr->p_filesz = (unsigned long) PTR_SUB(ptr, ptr_start); phdr->p_memsz = phdr->p_filesz; return ptr; @@ -435,7 +543,7 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset) /* * Create ELF core header (new kernel) */ -static void s390_elf_corehdr_create(char **elfcorebuf, size_t *elfcorebuf_sz) +int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size) { Elf64_Phdr *phdr_notes, *phdr_loads; int mem_chunk_cnt; @@ -443,6 +551,12 @@ static void s390_elf_corehdr_create(char **elfcorebuf, size_t *elfcorebuf_sz) u32 alloc_size; u64 hdr_off; + /* If we are not in kdump or zfcpdump mode return */ + if (!OLDMEM_BASE && ipl_info.type != IPL_TYPE_FCP_DUMP) + return 0; + /* If elfcorehdr= has been passed via cmdline, we use that one */ + if (elfcorehdr_addr != ELFCORE_ADDR_MAX) + return 0; mem_chunk_cnt = get_mem_chunk_cnt(); alloc_size = 0x1000 + get_cpu_cnt() * 0x300 + @@ -460,27 +574,52 @@ static void s390_elf_corehdr_create(char **elfcorebuf, size_t *elfcorebuf_sz) ptr = notes_init(phdr_notes, ptr, ((unsigned long) hdr) + hdr_off); /* Init loads */ hdr_off = PTR_DIFF(ptr, hdr); - loads_init(phdr_loads, ((unsigned long) hdr) + hdr_off); - *elfcorebuf_sz = hdr_off; - *elfcorebuf = (void *) relocate((unsigned long) hdr); - BUG_ON(*elfcorebuf_sz > alloc_size); + loads_init(phdr_loads, hdr_off); + *addr = (unsigned long long) hdr; + elfcorehdr_newmem = hdr; + *size = (unsigned long long) hdr_off; + BUG_ON(elfcorehdr_size > alloc_size); + return 0; } /* - * Create kdump ELF core header in new kernel, if it has not been passed via - * the "elfcorehdr" kernel parameter + * Free ELF core header (new kernel) */ -static int setup_kdump_elfcorehdr(void) +void elfcorehdr_free(unsigned long long addr) { - size_t elfcorebuf_sz; - char *elfcorebuf; + if (!elfcorehdr_newmem) + return; + kfree((void *)(unsigned long)addr); +} - if (!OLDMEM_BASE || is_kdump_kernel()) - return -EINVAL; - s390_elf_corehdr_create(&elfcorebuf, &elfcorebuf_sz); - elfcorehdr_addr = (unsigned long long) elfcorebuf; - elfcorehdr_size = elfcorebuf_sz; - return 0; +/* + * Read from ELF header + */ +ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) +{ + void *src = (void *)(unsigned long)*ppos; + + src = elfcorehdr_newmem ? src : src - OLDMEM_BASE; + memcpy(buf, src, count); + *ppos += count; + return count; } -subsys_initcall(setup_kdump_elfcorehdr); +/* + * Read from ELF notes data + */ +ssize_t elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos) +{ + void *src = (void *)(unsigned long)*ppos; + int rc; + + if (elfcorehdr_newmem) { + memcpy(buf, src, count); + } else { + rc = copy_from_oldmem(buf, src, count); + if (rc) + return rc; + } + *ppos += count; + return count; +} diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index 87acc38f73c6..99e7f6035895 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -40,14 +40,15 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high) { struct stack_frame *sf; struct pt_regs *regs; + unsigned long addr; while (1) { sp = sp & PSW_ADDR_INSN; if (sp < low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; - printk("([<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); - print_symbol("%s)\n", sf->gprs[8] & PSW_ADDR_INSN); + addr = sf->gprs[8] & PSW_ADDR_INSN; + printk("([<%016lx>] %pSR)\n", addr, (void *)addr); /* Follow the backchain. */ while (1) { low = sp; @@ -57,16 +58,16 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high) if (sp <= low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; - printk(" [<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); - print_symbol("%s\n", sf->gprs[8] & PSW_ADDR_INSN); + addr = sf->gprs[8] & PSW_ADDR_INSN; + printk(" [<%016lx>] %pSR\n", addr, (void *)addr); } /* Zero backchain detected, check for interrupt frame. */ sp = (unsigned long) (sf + 1); if (sp <= low || sp > high - sizeof(*regs)) return sp; regs = (struct pt_regs *) sp; - printk(" [<%016lx>] ", regs->psw.addr & PSW_ADDR_INSN); - print_symbol("%s\n", regs->psw.addr & PSW_ADDR_INSN); + addr = regs->psw.addr & PSW_ADDR_INSN; + printk(" [<%016lx>] %pSR\n", addr, (void *)addr); low = sp; sp = regs->gprs[15]; } @@ -128,8 +129,7 @@ static void show_last_breaking_event(struct pt_regs *regs) { #ifdef CONFIG_64BIT printk("Last Breaking-Event-Address:\n"); - printk(" [<%016lx>] ", regs->args[0] & PSW_ADDR_INSN); - print_symbol("%s\n", regs->args[0] & PSW_ADDR_INSN); + printk(" [<%016lx>] %pSR\n", regs->args[0], (void *)regs->args[0]); #endif } @@ -143,10 +143,10 @@ void show_registers(struct pt_regs *regs) char *mode; mode = user_mode(regs) ? "User" : "Krnl"; - printk("%s PSW : %p %p", + printk("%s PSW : %p %p (%pSR)\n", mode, (void *) regs->psw.mask, + (void *) regs->psw.addr, (void *) regs->psw.addr); - print_symbol(" (%s)\n", regs->psw.addr & PSW_ADDR_INSN); printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER), mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO), diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index 3ddbc26d246e..e9b04c33d383 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -53,27 +53,21 @@ void handle_signal32(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs); void do_notify_resume(struct pt_regs *regs); -struct ext_code; -void do_extint(struct pt_regs *regs); +void __init init_IRQ(void); +void do_IRQ(struct pt_regs *regs, int irq); void do_restart(void); void __init startup_init(void); void die(struct pt_regs *regs, const char *str); - +int setup_profiling_timer(unsigned int multiplier); void __init time_init(void); +int pfn_is_nosave(unsigned long); +void s390_early_resume(void); +unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip); struct s390_mmap_arg_struct; struct fadvise64_64_args; struct old_sigaction; -long sys_mmap2(struct s390_mmap_arg_struct __user *arg); -long sys_s390_ipc(uint call, int first, unsigned long second, - unsigned long third, void __user *ptr); -long sys_s390_personality(unsigned int personality); -long sys_s390_fadvise64(int fd, u32 offset_high, u32 offset_low, - size_t len, int advice); -long sys_s390_fadvise64_64(struct fadvise64_64_args __user *args); -long sys_s390_fallocate(int fd, int mode, loff_t offset, u32 len_high, - u32 len_low); long sys_sigreturn(void); long sys_rt_sigreturn(void); long sys32_sigreturn(void); diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index e3043aef87a9..1014ad5f7693 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -15,6 +15,7 @@ #include <linux/kprobes.h> #include <trace/syscall.h> #include <asm/asm-offsets.h> +#include "entry.h" #ifdef CONFIG_DYNAMIC_FTRACE @@ -177,7 +178,7 @@ int ftrace_enable_ftrace_graph_caller(void) offset = ((void *) prepare_ftrace_return - (void *) ftrace_graph_caller) / 2; - return probe_kernel_write(ftrace_graph_caller + 2, + return probe_kernel_write((void *) ftrace_graph_caller + 2, &offset, sizeof(offset)); } @@ -185,7 +186,7 @@ int ftrace_disable_ftrace_graph_caller(void) { static unsigned short offset = 0x0002; - return probe_kernel_write(ftrace_graph_caller + 2, + return probe_kernel_write((void *) ftrace_graph_caller + 2, &offset, sizeof(offset)); } diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index b34ba0ea96a9..8ac2097f13d4 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -196,21 +196,23 @@ asmlinkage void do_softirq(void) * ext_int_hash[index] is the list head for all external interrupts that hash * to this index. */ -static struct list_head ext_int_hash[256]; +static struct hlist_head ext_int_hash[32] ____cacheline_aligned; struct ext_int_info { ext_int_handler_t handler; - u16 code; - struct list_head entry; + struct hlist_node entry; struct rcu_head rcu; + u16 code; }; /* ext_int_hash_lock protects the handler lists for external interrupts */ -DEFINE_SPINLOCK(ext_int_hash_lock); +static DEFINE_SPINLOCK(ext_int_hash_lock); static inline int ext_hash(u16 code) { - return (code + (code >> 9)) & 0xff; + BUILD_BUG_ON(!is_power_of_2(ARRAY_SIZE(ext_int_hash))); + + return (code + (code >> 9)) & (ARRAY_SIZE(ext_int_hash) - 1); } int register_external_interrupt(u16 code, ext_int_handler_t handler) @@ -227,7 +229,7 @@ int register_external_interrupt(u16 code, ext_int_handler_t handler) index = ext_hash(code); spin_lock_irqsave(&ext_int_hash_lock, flags); - list_add_rcu(&p->entry, &ext_int_hash[index]); + hlist_add_head_rcu(&p->entry, &ext_int_hash[index]); spin_unlock_irqrestore(&ext_int_hash_lock, flags); return 0; } @@ -240,9 +242,9 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler) int index = ext_hash(code); spin_lock_irqsave(&ext_int_hash_lock, flags); - list_for_each_entry_rcu(p, &ext_int_hash[index], entry) { + hlist_for_each_entry_rcu(p, &ext_int_hash[index], entry) { if (p->code == code && p->handler == handler) { - list_del_rcu(&p->entry); + hlist_del_rcu(&p->entry); kfree_rcu(p, rcu); } } @@ -264,12 +266,12 @@ static irqreturn_t do_ext_interrupt(int irq, void *dummy) index = ext_hash(ext_code.code); rcu_read_lock(); - list_for_each_entry_rcu(p, &ext_int_hash[index], entry) - if (likely(p->code == ext_code.code)) - p->handler(ext_code, regs->int_parm, - regs->int_parm_long); + hlist_for_each_entry_rcu(p, &ext_int_hash[index], entry) { + if (unlikely(p->code != ext_code.code)) + continue; + p->handler(ext_code, regs->int_parm, regs->int_parm_long); + } rcu_read_unlock(); - return IRQ_HANDLED; } @@ -283,55 +285,32 @@ void __init init_ext_interrupts(void) int idx; for (idx = 0; idx < ARRAY_SIZE(ext_int_hash); idx++) - INIT_LIST_HEAD(&ext_int_hash[idx]); + INIT_HLIST_HEAD(&ext_int_hash[idx]); irq_set_chip_and_handler(EXT_INTERRUPT, &dummy_irq_chip, handle_percpu_irq); setup_irq(EXT_INTERRUPT, &external_interrupt); } -static DEFINE_SPINLOCK(sc_irq_lock); -static int sc_irq_refcount; - -void service_subclass_irq_register(void) -{ - spin_lock(&sc_irq_lock); - if (!sc_irq_refcount) - ctl_set_bit(0, 9); - sc_irq_refcount++; - spin_unlock(&sc_irq_lock); -} -EXPORT_SYMBOL(service_subclass_irq_register); - -void service_subclass_irq_unregister(void) -{ - spin_lock(&sc_irq_lock); - sc_irq_refcount--; - if (!sc_irq_refcount) - ctl_clear_bit(0, 9); - spin_unlock(&sc_irq_lock); -} -EXPORT_SYMBOL(service_subclass_irq_unregister); - -static DEFINE_SPINLOCK(ma_subclass_lock); -static int ma_subclass_refcount; +static DEFINE_SPINLOCK(irq_subclass_lock); +static unsigned char irq_subclass_refcount[64]; -void measurement_alert_subclass_register(void) +void irq_subclass_register(enum irq_subclass subclass) { - spin_lock(&ma_subclass_lock); - if (!ma_subclass_refcount) - ctl_set_bit(0, 5); - ma_subclass_refcount++; - spin_unlock(&ma_subclass_lock); + spin_lock(&irq_subclass_lock); + if (!irq_subclass_refcount[subclass]) + ctl_set_bit(0, subclass); + irq_subclass_refcount[subclass]++; + spin_unlock(&irq_subclass_lock); } -EXPORT_SYMBOL(measurement_alert_subclass_register); +EXPORT_SYMBOL(irq_subclass_register); -void measurement_alert_subclass_unregister(void) +void irq_subclass_unregister(enum irq_subclass subclass) { - spin_lock(&ma_subclass_lock); - ma_subclass_refcount--; - if (!ma_subclass_refcount) - ctl_clear_bit(0, 5); - spin_unlock(&ma_subclass_lock); + spin_lock(&irq_subclass_lock); + irq_subclass_refcount[subclass]--; + if (!irq_subclass_refcount[subclass]) + ctl_clear_bit(0, subclass); + spin_unlock(&irq_subclass_lock); } -EXPORT_SYMBOL(measurement_alert_subclass_unregister); +EXPORT_SYMBOL(irq_subclass_unregister); diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index adbbe7f1cb0d..0ce9fb245034 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -37,6 +37,26 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); struct kretprobe_blackpoint kretprobe_blacklist[] = { }; +DEFINE_INSN_CACHE_OPS(dmainsn); + +static void *alloc_dmainsn_page(void) +{ + return (void *)__get_free_page(GFP_KERNEL | GFP_DMA); +} + +static void free_dmainsn_page(void *page) +{ + free_page((unsigned long)page); +} + +struct kprobe_insn_cache kprobe_dmainsn_slots = { + .mutex = __MUTEX_INITIALIZER(kprobe_dmainsn_slots.mutex), + .alloc = alloc_dmainsn_page, + .free = free_dmainsn_page, + .pages = LIST_HEAD_INIT(kprobe_dmainsn_slots.pages), + .insn_size = MAX_INSN_SIZE, +}; + static int __kprobes is_prohibited_opcode(kprobe_opcode_t *insn) { switch (insn[0] >> 8) { @@ -100,9 +120,8 @@ static int __kprobes get_fixup_type(kprobe_opcode_t *insn) fixup |= FIXUP_RETURN_REGISTER; break; case 0xc0: - if ((insn[0] & 0x0f) == 0x00 || /* larl */ - (insn[0] & 0x0f) == 0x05) /* brasl */ - fixup |= FIXUP_RETURN_REGISTER; + if ((insn[0] & 0x0f) == 0x05) /* brasl */ + fixup |= FIXUP_RETURN_REGISTER; break; case 0xeb: switch (insn[2] & 0xff) { @@ -134,18 +153,128 @@ static int __kprobes get_fixup_type(kprobe_opcode_t *insn) return fixup; } +static int __kprobes is_insn_relative_long(kprobe_opcode_t *insn) +{ + /* Check if we have a RIL-b or RIL-c format instruction which + * we need to modify in order to avoid instruction emulation. */ + switch (insn[0] >> 8) { + case 0xc0: + if ((insn[0] & 0x0f) == 0x00) /* larl */ + return true; + break; + case 0xc4: + switch (insn[0] & 0x0f) { + case 0x02: /* llhrl */ + case 0x04: /* lghrl */ + case 0x05: /* lhrl */ + case 0x06: /* llghrl */ + case 0x07: /* sthrl */ + case 0x08: /* lgrl */ + case 0x0b: /* stgrl */ + case 0x0c: /* lgfrl */ + case 0x0d: /* lrl */ + case 0x0e: /* llgfrl */ + case 0x0f: /* strl */ + return true; + } + break; + case 0xc6: + switch (insn[0] & 0x0f) { + case 0x00: /* exrl */ + case 0x02: /* pfdrl */ + case 0x04: /* cghrl */ + case 0x05: /* chrl */ + case 0x06: /* clghrl */ + case 0x07: /* clhrl */ + case 0x08: /* cgrl */ + case 0x0a: /* clgrl */ + case 0x0c: /* cgfrl */ + case 0x0d: /* crl */ + case 0x0e: /* clgfrl */ + case 0x0f: /* clrl */ + return true; + } + break; + } + return false; +} + +static void __kprobes copy_instruction(struct kprobe *p) +{ + s64 disp, new_disp; + u64 addr, new_addr; + + memcpy(p->ainsn.insn, p->addr, ((p->opcode >> 14) + 3) & -2); + if (!is_insn_relative_long(p->ainsn.insn)) + return; + /* + * For pc-relative instructions in RIL-b or RIL-c format patch the + * RI2 displacement field. We have already made sure that the insn + * slot for the patched instruction is within the same 2GB area + * as the original instruction (either kernel image or module area). + * Therefore the new displacement will always fit. + */ + disp = *(s32 *)&p->ainsn.insn[1]; + addr = (u64)(unsigned long)p->addr; + new_addr = (u64)(unsigned long)p->ainsn.insn; + new_disp = ((addr + (disp * 2)) - new_addr) / 2; + *(s32 *)&p->ainsn.insn[1] = new_disp; +} + +static inline int is_kernel_addr(void *addr) +{ + return addr < (void *)_end; +} + +static inline int is_module_addr(void *addr) +{ +#ifdef CONFIG_64BIT + BUILD_BUG_ON(MODULES_LEN > (1UL << 31)); + if (addr < (void *)MODULES_VADDR) + return 0; + if (addr > (void *)MODULES_END) + return 0; +#endif + return 1; +} + +static int __kprobes s390_get_insn_slot(struct kprobe *p) +{ + /* + * Get an insn slot that is within the same 2GB area like the original + * instruction. That way instructions with a 32bit signed displacement + * field can be patched and executed within the insn slot. + */ + p->ainsn.insn = NULL; + if (is_kernel_addr(p->addr)) + p->ainsn.insn = get_dmainsn_slot(); + if (is_module_addr(p->addr)) + p->ainsn.insn = get_insn_slot(); + return p->ainsn.insn ? 0 : -ENOMEM; +} + +static void __kprobes s390_free_insn_slot(struct kprobe *p) +{ + if (!p->ainsn.insn) + return; + if (is_kernel_addr(p->addr)) + free_dmainsn_slot(p->ainsn.insn, 0); + else + free_insn_slot(p->ainsn.insn, 0); + p->ainsn.insn = NULL; +} + int __kprobes arch_prepare_kprobe(struct kprobe *p) { if ((unsigned long) p->addr & 0x01) return -EINVAL; - /* Make sure the probe isn't going on a difficult instruction */ if (is_prohibited_opcode(p->addr)) return -EINVAL; - + if (s390_get_insn_slot(p)) + return -ENOMEM; p->opcode = *p->addr; - memcpy(p->ainsn.insn, p->addr, ((p->opcode >> 14) + 3) & -2); - + copy_instruction(p); return 0; } @@ -186,6 +315,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) void __kprobes arch_remove_kprobe(struct kprobe *p) { + s390_free_insn_slot(p); } static void __kprobes enable_singlestep(struct kprobe_ctlblk *kcb, diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index ac2178161ec3..719e27b2cf22 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -50,7 +50,7 @@ static void add_elf_notes(int cpu) /* * Initialize CPU ELF notes */ -void setup_regs(void) +static void setup_regs(void) { unsigned long sa = S390_lowcore.prefixreg_save_area + SAVE_AREA_BASE; int cpu, this_cpu; diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index fb99c2057b85..1105502bf6e9 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c @@ -274,7 +274,7 @@ static int reserve_pmc_hardware(void) int flags = PMC_INIT; on_each_cpu(setup_pmc_cpu, &flags, 1); - measurement_alert_subclass_register(); + irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); return 0; } @@ -285,7 +285,7 @@ static void release_pmc_hardware(void) int flags = PMC_RELEASE; on_each_cpu(setup_pmc_cpu, &flags, 1); - measurement_alert_subclass_unregister(); + irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); } /* Release the PMU if event is the last perf event */ diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c index 500aa1029bcb..2343c218b8f9 100644 --- a/arch/s390/kernel/perf_event.c +++ b/arch/s390/kernel/perf_event.c @@ -105,13 +105,10 @@ void perf_event_print_debug(void) cpu = smp_processor_id(); memset(&cf_info, 0, sizeof(cf_info)); - if (!qctri(&cf_info)) { + if (!qctri(&cf_info)) pr_info("CPU[%i] CPUM_CF: ver=%u.%u A=%04x E=%04x C=%04x\n", cpu, cf_info.cfvn, cf_info.csvn, cf_info.auth_ctl, cf_info.enable_ctl, cf_info.act_ctl); - print_hex_dump_bytes("CPUMF Query: ", DUMP_PREFIX_OFFSET, - &cf_info, sizeof(cf_info)); - } local_irq_restore(flags); } diff --git a/arch/s390/kernel/runtime_instr.c b/arch/s390/kernel/runtime_instr.c index 077a99389b07..e1c9d1c292fa 100644 --- a/arch/s390/kernel/runtime_instr.c +++ b/arch/s390/kernel/runtime_instr.c @@ -139,10 +139,10 @@ static int __init runtime_instr_init(void) if (!runtime_instr_avail()) return 0; - measurement_alert_subclass_register(); + irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); rc = register_external_interrupt(0x1407, runtime_instr_int_handler); if (rc) - measurement_alert_subclass_unregister(); + irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); else pr_info("Runtime instrumentation facility initialized\n"); return rc; diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index d386c4e9d2e5..1a4313a1b60f 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -362,7 +362,7 @@ void smp_yield_cpu(int cpu) * Send cpus emergency shutdown signal. This gives the cpus the * opportunity to complete outstanding interrupts. */ -void smp_emergency_stop(cpumask_t *cpumask) +static void smp_emergency_stop(cpumask_t *cpumask) { u64 end; int cpu; diff --git a/arch/s390/kernel/suspend.c b/arch/s390/kernel/suspend.c index 737bff38e3ee..a7a7537ce1e7 100644 --- a/arch/s390/kernel/suspend.c +++ b/arch/s390/kernel/suspend.c @@ -13,6 +13,7 @@ #include <asm/ipl.h> #include <asm/cio.h> #include <asm/pci.h> +#include "entry.h" /* * References to section boundaries diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index f00aefb66a4e..7de4469915f0 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -673,7 +673,7 @@ static int __init pfault_irq_init(void) rc = pfault_init() == 0 ? 0 : -EOPNOTSUPP; if (rc) goto out_pfault; - service_subclass_irq_register(); + irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL); hotcpu_notifier(pfault_cpu_notify, 0); return 0; diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c index 248445f92604..d261c62e40a6 100644 --- a/arch/s390/mm/hugetlbpage.c +++ b/arch/s390/mm/hugetlbpage.c @@ -223,6 +223,11 @@ int pud_huge(pud_t pud) return 0; } +int pmd_huge_support(void) +{ + return 1; +} + struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, pmd_t *pmdp, int write) { diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 921fa541dc04..d1e0e0c7a7e2 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -14,6 +14,7 @@ #include <linux/gfp.h> #include <linux/cpu.h> #include <asm/ctl_reg.h> +#include <asm/io.h> /* * This function writes to kernel memory bypassing DAT and possible diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index bf7c0dc64a76..de8cbc30dcd1 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -245,7 +245,9 @@ EXPORT_SYMBOL_GPL(gmap_disable); * gmap_alloc_table is assumed to be called with mmap_sem held */ static int gmap_alloc_table(struct gmap *gmap, - unsigned long *table, unsigned long init) + unsigned long *table, unsigned long init) + __releases(&gmap->mm->page_table_lock) + __acquires(&gmap->mm->page_table_lock) { struct page *page; unsigned long *new; @@ -966,7 +968,7 @@ void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table) tlb_remove_table(tlb, table); } -void __tlb_remove_table(void *_table) +static void __tlb_remove_table(void *_table) { const unsigned long mask = (FRAG_MASK << 4) | FRAG_MASK; void *table = (void *)((unsigned long) _table & ~mask); diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index d5f10a43a58f..709239285869 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -805,7 +805,7 @@ static struct bpf_binary_header *bpf_alloc_binary(unsigned int bpfsize, return NULL; memset(header, 0, sz); header->pages = sz / PAGE_SIZE; - hole = sz - bpfsize + sizeof(*header); + hole = sz - (bpfsize + sizeof(*header)); /* Insert random number of illegal instructions before BPF code * and make sure the first instruction starts at an even address. */ diff --git a/arch/s390/oprofile/hwsampler.c b/arch/s390/oprofile/hwsampler.c index b5b2916895e0..231cecafc2f1 100644 --- a/arch/s390/oprofile/hwsampler.c +++ b/arch/s390/oprofile/hwsampler.c @@ -1001,7 +1001,7 @@ int hwsampler_deallocate(void) if (hws_state != HWS_STOPPED) goto deallocate_exit; - measurement_alert_subclass_unregister(); + irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); deallocate_sdbt(); hws_state = HWS_DEALLOCATED; @@ -1115,7 +1115,7 @@ int hwsampler_shutdown(void) mutex_lock(&hws_sem); if (hws_state == HWS_STOPPED) { - measurement_alert_subclass_unregister(); + irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); deallocate_sdbt(); } if (hws_wq) { @@ -1190,7 +1190,7 @@ start_all_exit: hws_oom = 1; hws_flush_all = 0; /* now let them in, 1407 CPUMF external interrupts */ - measurement_alert_subclass_register(); + irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); return 0; } diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 65dd81baa7f6..1fa8be409771 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -600,37 +600,13 @@ static struct platform_device sdhi0_power = { }, }; -static void sdhi0_set_pwr(struct platform_device *pdev, int state) -{ - static int power_gpio = -EINVAL; - - if (power_gpio < 0) { - int ret = gpio_request(GPIO_PTB6, NULL); - if (!ret) { - power_gpio = GPIO_PTB6; - gpio_direction_output(power_gpio, 0); - } - } - - /* - * Toggle the GPIO regardless, whether we managed to grab it above or - * the fixed regulator driver did. - */ - gpio_set_value(GPIO_PTB6, state); -} - -static int sdhi0_get_cd(struct platform_device *pdev) -{ - return !gpio_get_value(GPIO_PTY7); -} - static struct sh_mobile_sdhi_info sdhi0_info = { .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, - .set_pwr = sdhi0_set_pwr, .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD | MMC_CAP_NEEDS_POLL, - .get_cd = sdhi0_get_cd, + .tmio_flags = TMIO_MMC_USE_GPIO_CD, + .cd_gpio = GPIO_PTY7, }; static struct resource sdhi0_resources[] = { @@ -656,39 +632,15 @@ static struct platform_device sdhi0_device = { }, }; -static void cn12_set_pwr(struct platform_device *pdev, int state) -{ - static int power_gpio = -EINVAL; - - if (power_gpio < 0) { - int ret = gpio_request(GPIO_PTB7, NULL); - if (!ret) { - power_gpio = GPIO_PTB7; - gpio_direction_output(power_gpio, 0); - } - } - - /* - * Toggle the GPIO regardless, whether we managed to grab it above or - * the fixed regulator driver did. - */ - gpio_set_value(GPIO_PTB7, state); -} - #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) /* SDHI1 */ -static int sdhi1_get_cd(struct platform_device *pdev) -{ - return !gpio_get_value(GPIO_PTW7); -} - static struct sh_mobile_sdhi_info sdhi1_info = { .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX, .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD | MMC_CAP_NEEDS_POLL, - .set_pwr = cn12_set_pwr, - .get_cd = sdhi1_get_cd, + .tmio_flags = TMIO_MMC_USE_GPIO_CD, + .cd_gpio = GPIO_PTW7, }; static struct resource sdhi1_resources[] = { @@ -718,27 +670,19 @@ static struct platform_device sdhi1_device = { #else /* MMC SPI */ -static int mmc_spi_get_ro(struct device *dev) -{ - return gpio_get_value(GPIO_PTY6); -} - -static int mmc_spi_get_cd(struct device *dev) -{ - return !gpio_get_value(GPIO_PTY7); -} - static void mmc_spi_setpower(struct device *dev, unsigned int maskval) { gpio_set_value(GPIO_PTB6, maskval ? 1 : 0); } static struct mmc_spi_platform_data mmc_spi_info = { - .get_ro = mmc_spi_get_ro, - .get_cd = mmc_spi_get_cd, .caps = MMC_CAP_NEEDS_POLL, + .caps2 = MMC_CAP2_RO_ACTIVE_HIGH, .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* 3.3V only */ .setpower = mmc_spi_setpower, + .flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO, + .cd_gpio = GPIO_PTY7, + .ro_gpio = GPIO_PTY6, }; static struct spi_board_info spi_bus[] = { @@ -998,11 +942,6 @@ static struct platform_device vou_device = { #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) /* SH_MMCIF */ -static void mmcif_down_pwr(struct platform_device *pdev) -{ - cn12_set_pwr(pdev, 0); -} - static struct resource sh_mmcif_resources[] = { [0] = { .name = "SH_MMCIF", @@ -1023,8 +962,6 @@ static struct resource sh_mmcif_resources[] = { }; static struct sh_mmcif_plat_data sh_mmcif_plat = { - .set_pwr = cn12_set_pwr, - .down_pwr = mmcif_down_pwr, .sup_pclk = 0, /* SH7724: Max Pclk/2 */ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | @@ -1341,10 +1278,6 @@ static int __init arch_setup(void) gpio_direction_input(GPIO_PTR6); /* SD-card slot CN11 */ - /* Card-detect, used on CN11, either with SDHI0 or with SPI */ - gpio_request(GPIO_PTY7, NULL); - gpio_direction_input(GPIO_PTY7); - #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) /* enable SDHI0 on CN11 (needs DS2.4 set to ON) */ gpio_request(GPIO_FN_SDHI0WP, NULL); @@ -1363,8 +1296,6 @@ static int __init arch_setup(void) gpio_direction_output(GPIO_PTM4, 1); /* active low CS */ gpio_request(GPIO_PTB6, NULL); /* 3.3V power control */ gpio_direction_output(GPIO_PTB6, 0); /* disable power by default */ - gpio_request(GPIO_PTY6, NULL); /* write protect */ - gpio_direction_input(GPIO_PTY6); spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus)); #endif @@ -1394,10 +1325,6 @@ static int __init arch_setup(void) gpio_request(GPIO_FN_SDHI1D1, NULL); gpio_request(GPIO_FN_SDHI1D0, NULL); - /* Card-detect, used on CN12 with SDHI1 */ - gpio_request(GPIO_PTW7, NULL); - gpio_direction_input(GPIO_PTW7); - cn12_enabled = true; #endif diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c index d7762349ea48..0d676a41081e 100644 --- a/arch/sh/mm/hugetlbpage.c +++ b/arch/sh/mm/hugetlbpage.c @@ -83,6 +83,11 @@ int pud_huge(pud_t pud) return 0; } +int pmd_huge_support(void) +{ + return 0; +} + struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, pmd_t *pmd, int write) { diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index 3d0ddbc005fe..71368850dfc0 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -169,10 +169,10 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig, new_ka.ka_restorer = restorer; ret = get_user(u_handler, &act->sa_handler); new_ka.sa.sa_handler = compat_ptr(u_handler); - ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t)); + ret |= copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t)); sigset_from_compat(&new_ka.sa.sa_mask, &set32); - ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); - ret |= __get_user(u_restorer, &act->sa_restorer); + ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags); + ret |= get_user(u_restorer, &act->sa_restorer); new_ka.sa.sa_restorer = compat_ptr(u_restorer); if (ret) return -EFAULT; @@ -183,9 +183,9 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig, if (!ret && oact) { sigset_to_compat(&set32, &old_ka.sa.sa_mask); ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler); - ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t)); - ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - ret |= __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer); + ret |= copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t)); + ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags); + ret |= put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer); if (ret) ret = -EFAULT; } diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c index d2b59441ebdd..96399646570a 100644 --- a/arch/sparc/mm/hugetlbpage.c +++ b/arch/sparc/mm/hugetlbpage.c @@ -234,6 +234,11 @@ int pud_huge(pud_t pud) return 0; } +int pmd_huge_support(void) +{ + return 0; +} + struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, pmd_t *pmd, int write) { diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c index e514899e1100..0cb3bbaa580c 100644 --- a/arch/tile/mm/hugetlbpage.c +++ b/arch/tile/mm/hugetlbpage.c @@ -166,6 +166,11 @@ int pud_huge(pud_t pud) return !!(pud_val(pud) & _PAGE_HUGE_PAGE); } +int pmd_huge_support(void) +{ + return 1; +} + struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address, pmd_t *pmd, int write) { diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h index 3a16c1483b45..64507f35800c 100644 --- a/arch/x86/include/asm/jump_label.h +++ b/arch/x86/include/asm/jump_label.h @@ -3,18 +3,23 @@ #ifdef __KERNEL__ +#include <linux/stringify.h> #include <linux/types.h> #include <asm/nops.h> #include <asm/asm.h> #define JUMP_LABEL_NOP_SIZE 5 -#define STATIC_KEY_INITIAL_NOP ".byte 0xe9 \n\t .long 0\n\t" +#ifdef CONFIG_X86_64 +# define STATIC_KEY_INIT_NOP P6_NOP5_ATOMIC +#else +# define STATIC_KEY_INIT_NOP GENERIC_NOP5_ATOMIC +#endif static __always_inline bool arch_static_branch(struct static_key *key) { asm goto("1:" - STATIC_KEY_INITIAL_NOP + ".byte " __stringify(STATIC_KEY_INIT_NOP) "\n\t" ".pushsection __jump_table, \"aw\" \n\t" _ASM_ALIGN "\n\t" _ASM_PTR "1b, %l[l_yes], %c0 \n\t" diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 8d16befdec88..3d1999458709 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -315,21 +315,6 @@ static inline pmd_t pmd_mksoft_dirty(pmd_t pmd) return pmd_set_flags(pmd, _PAGE_SOFT_DIRTY); } -static inline pte_t pte_swp_mksoft_dirty(pte_t pte) -{ - return pte_set_flags(pte, _PAGE_SWP_SOFT_DIRTY); -} - -static inline int pte_swp_soft_dirty(pte_t pte) -{ - return pte_flags(pte) & _PAGE_SWP_SOFT_DIRTY; -} - -static inline pte_t pte_swp_clear_soft_dirty(pte_t pte) -{ - return pte_clear_flags(pte, _PAGE_SWP_SOFT_DIRTY); -} - static inline pte_t pte_file_clear_soft_dirty(pte_t pte) { return pte_clear_flags(pte, _PAGE_SOFT_DIRTY); @@ -446,6 +431,7 @@ pte_t *populate_extra_pte(unsigned long vaddr); #ifndef __ASSEMBLY__ #include <linux/mm_types.h> +#include <linux/mmdebug.h> #include <linux/log2.h> static inline int pte_none(pte_t pte) @@ -864,6 +850,24 @@ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, { } +static inline pte_t pte_swp_mksoft_dirty(pte_t pte) +{ + VM_BUG_ON(pte_present(pte)); + return pte_set_flags(pte, _PAGE_SWP_SOFT_DIRTY); +} + +static inline int pte_swp_soft_dirty(pte_t pte) +{ + VM_BUG_ON(pte_present(pte)); + return pte_flags(pte) & _PAGE_SWP_SOFT_DIRTY; +} + +static inline pte_t pte_swp_clear_soft_dirty(pte_t pte) +{ + VM_BUG_ON(pte_present(pte)); + return pte_clear_flags(pte, _PAGE_SWP_SOFT_DIRTY); +} + #include <asm-generic/pgtable.h> #endif /* __ASSEMBLY__ */ diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index f4843e031131..0ecac257fb26 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -75,6 +75,9 @@ * with swap entry format. On x86 bits 6 and 7 are *not* involved * into swap entry computation, but bit 6 is used for nonlinear * file mapping, so we borrow bit 7 for soft dirty tracking. + * + * Please note that this bit must be treated as swap dirty page + * mark if and only if the PTE has present bit clear! */ #ifdef CONFIG_MEM_SOFT_DIRTY #define _PAGE_SWP_SOFT_DIRTY _PAGE_PSE diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index cf512003e663..e6d90babc245 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -62,6 +62,7 @@ static inline void __flush_tlb_all(void) static inline void __flush_tlb_one(unsigned long addr) { + count_vm_event(NR_TLB_LOCAL_FLUSH_ONE); __flush_tlb_single(addr); } @@ -84,14 +85,38 @@ static inline void __flush_tlb_one(unsigned long addr) #ifndef CONFIG_SMP -#define flush_tlb() __flush_tlb() -#define flush_tlb_all() __flush_tlb_all() -#define local_flush_tlb() __flush_tlb() +/* "_up" is for UniProcessor. + * + * This is a helper for other header functions. *Not* intended to be called + * directly. All global TLB flushes need to either call this, or to bump the + * vm statistics themselves. + */ +static inline void __flush_tlb_up(void) +{ + count_vm_event(NR_TLB_LOCAL_FLUSH_ALL); + __flush_tlb(); +} + +static inline void flush_tlb_all(void) +{ + count_vm_event(NR_TLB_LOCAL_FLUSH_ALL); + __flush_tlb_all(); +} + +static inline void flush_tlb(void) +{ + __flush_tlb_up(); +} + +static inline void local_flush_tlb(void) +{ + __flush_tlb_up(); +} static inline void flush_tlb_mm(struct mm_struct *mm) { if (mm == current->active_mm) - __flush_tlb(); + __flush_tlb_up(); } static inline void flush_tlb_page(struct vm_area_struct *vma, @@ -105,14 +130,14 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { if (vma->vm_mm == current->active_mm) - __flush_tlb(); + __flush_tlb_up(); } static inline void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long vmflag) { if (mm == current->active_mm) - __flush_tlb(); + __flush_tlb_up(); } static inline void native_flush_tlb_others(const struct cpumask *cpumask, diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index d4cdfa67509e..ce2d0a2c3e4f 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -683,6 +683,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock) } /* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */ + count_vm_event(NR_TLB_LOCAL_FLUSH_ALL); __flush_tlb(); /* Save MTRR state */ @@ -696,6 +697,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock) static void post_set(void) __releases(set_atomicity_lock) { /* Flush TLBs (no need to flush caches - they are disabled) */ + count_vm_event(NR_TLB_LOCAL_FLUSH_ALL); __flush_tlb(); /* Intel (P6) standard MTRRs */ diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 0abf6742a8b0..c62d88396ad5 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -124,6 +124,7 @@ static struct event_constraint intel_ivb_event_constraints[] __read_mostly = INTEL_UEVENT_CONSTRAINT(0x0148, 0x4), /* L1D_PEND_MISS.PENDING */ INTEL_UEVENT_CONSTRAINT(0x0279, 0xf), /* IDQ.EMTPY */ INTEL_UEVENT_CONSTRAINT(0x019c, 0xf), /* IDQ_UOPS_NOT_DELIVERED.CORE */ + INTEL_UEVENT_CONSTRAINT(0x02a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_LDM_PENDING */ INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_EXECUTE */ INTEL_UEVENT_CONSTRAINT(0x05a3, 0xf), /* CYCLE_ACTIVITY.STALLS_L2_PENDING */ INTEL_UEVENT_CONSTRAINT(0x06a3, 0xf), /* CYCLE_ACTIVITY.STALLS_LDM_PENDING */ diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index fd8011ed4dcd..8ed44589b0e4 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -2808,7 +2808,7 @@ uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *eve return c; } - if (event->hw.config == ~0ULL) + if (event->attr.config == UNCORE_FIXED_EVENT) return &constraint_fixed; if (type->constraints) { @@ -3112,7 +3112,9 @@ static int uncore_pmu_event_init(struct perf_event *event) */ if (pmu->type->single_fixed && pmu->pmu_idx > 0) return -EINVAL; - hwc->config = ~0ULL; + + /* fixed counters have event field hardcoded to zero */ + hwc->config = 0ULL; } else { hwc->config = event->attr.config & pmu->type->event_mask; if (pmu->type->ops->hw_config) { diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index 69eb2fa25494..376dc7873447 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -52,8 +52,7 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) } #ifdef CONFIG_BLK_DEV_INITRD -void __init early_init_dt_setup_initrd_arch(unsigned long start, - unsigned long end) +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) { initrd_start = (unsigned long)__va(start); initrd_end = (unsigned long)__va(end); diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 63bdb29b2549..b3cd3ebae077 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -12,6 +12,7 @@ #include <linux/pci.h> #include <linux/acpi.h> #include <linux/pci_ids.h> +#include <drm/i915_drm.h> #include <asm/pci-direct.h> #include <asm/dma.h> #include <asm/io_apic.h> @@ -216,6 +217,157 @@ static void __init intel_remapping_check(int num, int slot, int func) } +/* + * Systems with Intel graphics controllers set aside memory exclusively + * for gfx driver use. This memory is not marked in the E820 as reserved + * or as RAM, and so is subject to overlap from E820 manipulation later + * in the boot process. On some systems, MMIO space is allocated on top, + * despite the efforts of the "RAM buffer" approach, which simply rounds + * memory boundaries up to 64M to try to catch space that may decode + * as RAM and so is not suitable for MMIO. + * + * And yes, so far on current devices the base addr is always under 4G. + */ +static u32 __init intel_stolen_base(int num, int slot, int func) +{ + u32 base; + + /* + * For the PCI IDs in this quirk, the stolen base is always + * in 0x5c, aka the BDSM register (yes that's really what + * it's called). + */ + base = read_pci_config(num, slot, func, 0x5c); + base &= ~((1<<20) - 1); + + return base; +} + +#define KB(x) ((x) * 1024) +#define MB(x) (KB (KB (x))) +#define GB(x) (MB (KB (x))) + +static size_t __init gen3_stolen_size(int num, int slot, int func) +{ + size_t stolen_size; + u16 gmch_ctrl; + + gmch_ctrl = read_pci_config_16(0, 0, 0, I830_GMCH_CTRL); + + switch (gmch_ctrl & I855_GMCH_GMS_MASK) { + case I855_GMCH_GMS_STOLEN_1M: + stolen_size = MB(1); + break; + case I855_GMCH_GMS_STOLEN_4M: + stolen_size = MB(4); + break; + case I855_GMCH_GMS_STOLEN_8M: + stolen_size = MB(8); + break; + case I855_GMCH_GMS_STOLEN_16M: + stolen_size = MB(16); + break; + case I855_GMCH_GMS_STOLEN_32M: + stolen_size = MB(32); + break; + case I915_GMCH_GMS_STOLEN_48M: + stolen_size = MB(48); + break; + case I915_GMCH_GMS_STOLEN_64M: + stolen_size = MB(64); + break; + case G33_GMCH_GMS_STOLEN_128M: + stolen_size = MB(128); + break; + case G33_GMCH_GMS_STOLEN_256M: + stolen_size = MB(256); + break; + case INTEL_GMCH_GMS_STOLEN_96M: + stolen_size = MB(96); + break; + case INTEL_GMCH_GMS_STOLEN_160M: + stolen_size = MB(160); + break; + case INTEL_GMCH_GMS_STOLEN_224M: + stolen_size = MB(224); + break; + case INTEL_GMCH_GMS_STOLEN_352M: + stolen_size = MB(352); + break; + default: + stolen_size = 0; + break; + } + + return stolen_size; +} + +static size_t __init gen6_stolen_size(int num, int slot, int func) +{ + u16 gmch_ctrl; + + gmch_ctrl = read_pci_config_16(num, slot, func, SNB_GMCH_CTRL); + gmch_ctrl >>= SNB_GMCH_GMS_SHIFT; + gmch_ctrl &= SNB_GMCH_GMS_MASK; + + return gmch_ctrl << 25; /* 32 MB units */ +} + +typedef size_t (*stolen_size_fn)(int num, int slot, int func); + +static struct pci_device_id intel_stolen_ids[] __initdata = { + INTEL_I915G_IDS(gen3_stolen_size), + INTEL_I915GM_IDS(gen3_stolen_size), + INTEL_I945G_IDS(gen3_stolen_size), + INTEL_I945GM_IDS(gen3_stolen_size), + INTEL_VLV_M_IDS(gen3_stolen_size), + INTEL_VLV_D_IDS(gen3_stolen_size), + INTEL_PINEVIEW_IDS(gen3_stolen_size), + INTEL_I965G_IDS(gen3_stolen_size), + INTEL_G33_IDS(gen3_stolen_size), + INTEL_I965GM_IDS(gen3_stolen_size), + INTEL_GM45_IDS(gen3_stolen_size), + INTEL_G45_IDS(gen3_stolen_size), + INTEL_IRONLAKE_D_IDS(gen3_stolen_size), + INTEL_IRONLAKE_M_IDS(gen3_stolen_size), + INTEL_SNB_D_IDS(gen6_stolen_size), + INTEL_SNB_M_IDS(gen6_stolen_size), + INTEL_IVB_M_IDS(gen6_stolen_size), + INTEL_IVB_D_IDS(gen6_stolen_size), + INTEL_HSW_D_IDS(gen6_stolen_size), + INTEL_HSW_M_IDS(gen6_stolen_size), +}; + +static void __init intel_graphics_stolen(int num, int slot, int func) +{ + size_t size; + int i; + u32 start; + u16 device, subvendor, subdevice; + + device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID); + subvendor = read_pci_config_16(num, slot, func, + PCI_SUBSYSTEM_VENDOR_ID); + subdevice = read_pci_config_16(num, slot, func, PCI_SUBSYSTEM_ID); + + for (i = 0; i < ARRAY_SIZE(intel_stolen_ids); i++) { + if (intel_stolen_ids[i].device == device) { + stolen_size_fn stolen_size = + (stolen_size_fn)intel_stolen_ids[i].driver_data; + size = stolen_size(num, slot, func); + start = intel_stolen_base(num, slot, func); + if (size && start) { + /* Mark this space as reserved */ + e820_add_region(start, size, E820_RESERVED); + sanitize_e820_map(e820.map, + ARRAY_SIZE(e820.map), + &e820.nr_map); + } + return; + } + } +} + #define QFLAG_APPLY_ONCE 0x1 #define QFLAG_APPLIED 0x2 #define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED) @@ -251,6 +403,8 @@ static struct chipset early_qrk[] __initdata = { PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check }, { PCI_VENDOR_ID_INTEL, 0x3406, PCI_CLASS_BRIDGE_HOST, PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check }, + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA, PCI_ANY_ID, + QFLAG_APPLY_ONCE, intel_graphics_stolen }, {} }; diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c index 460f5d9ceebb..ee11b7dfbfbb 100644 --- a/arch/x86/kernel/jump_label.c +++ b/arch/x86/kernel/jump_label.c @@ -24,18 +24,57 @@ union jump_code_union { } __attribute__((packed)); }; +static void bug_at(unsigned char *ip, int line) +{ + /* + * The location is not an op that we were expecting. + * Something went wrong. Crash the box, as something could be + * corrupting the kernel. + */ + pr_warning("Unexpected op at %pS [%p] (%02x %02x %02x %02x %02x) %s:%d\n", + ip, ip, ip[0], ip[1], ip[2], ip[3], ip[4], __FILE__, line); + BUG(); +} + static void __jump_label_transform(struct jump_entry *entry, enum jump_label_type type, - void *(*poker)(void *, const void *, size_t)) + void *(*poker)(void *, const void *, size_t), + int init) { union jump_code_union code; + const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5]; if (type == JUMP_LABEL_ENABLE) { + /* + * We are enabling this jump label. If it is not a nop + * then something must have gone wrong. + */ + if (unlikely(memcmp((void *)entry->code, ideal_nop, 5) != 0)) + bug_at((void *)entry->code, __LINE__); + code.jump = 0xe9; code.offset = entry->target - (entry->code + JUMP_LABEL_NOP_SIZE); - } else + } else { + /* + * We are disabling this jump label. If it is not what + * we think it is, then something must have gone wrong. + * If this is the first initialization call, then we + * are converting the default nop to the ideal nop. + */ + if (init) { + const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP }; + if (unlikely(memcmp((void *)entry->code, default_nop, 5) != 0)) + bug_at((void *)entry->code, __LINE__); + } else { + code.jump = 0xe9; + code.offset = entry->target - + (entry->code + JUMP_LABEL_NOP_SIZE); + if (unlikely(memcmp((void *)entry->code, &code, 5) != 0)) + bug_at((void *)entry->code, __LINE__); + } memcpy(&code, ideal_nops[NOP_ATOMIC5], JUMP_LABEL_NOP_SIZE); + } /* * Make text_poke_bp() a default fallback poker. @@ -57,15 +96,38 @@ void arch_jump_label_transform(struct jump_entry *entry, { get_online_cpus(); mutex_lock(&text_mutex); - __jump_label_transform(entry, type, NULL); + __jump_label_transform(entry, type, NULL, 0); mutex_unlock(&text_mutex); put_online_cpus(); } +static enum { + JL_STATE_START, + JL_STATE_NO_UPDATE, + JL_STATE_UPDATE, +} jlstate __initdata_or_module = JL_STATE_START; + __init_or_module void arch_jump_label_transform_static(struct jump_entry *entry, enum jump_label_type type) { - __jump_label_transform(entry, type, text_poke_early); + /* + * This function is called at boot up and when modules are + * first loaded. Check if the default nop, the one that is + * inserted at compile time, is the ideal nop. If it is, then + * we do not need to update the nop, and we can leave it as is. + * If it is not, then we need to update the nop to the ideal nop. + */ + if (jlstate == JL_STATE_START) { + const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP }; + const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5]; + + if (memcmp(ideal_nop, default_nop, 5) != 0) + jlstate = JL_STATE_UPDATE; + else + jlstate = JL_STATE_NO_UPDATE; + } + if (jlstate == JL_STATE_UPDATE) + __jump_label_transform(entry, type, text_poke_early, 1); } #endif diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c index 7e73e8c69096..9d980d88b747 100644 --- a/arch/x86/mm/hugetlbpage.c +++ b/arch/x86/mm/hugetlbpage.c @@ -59,6 +59,10 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address, return NULL; } +int pmd_huge_support(void) +{ + return 0; +} #else struct page * @@ -77,6 +81,10 @@ int pud_huge(pud_t pud) return !!(pud_val(pud) & _PAGE_PSE); } +int pmd_huge_support(void) +{ + return 1; +} #endif /* x86_64 also uses this file */ diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 282375f13c7e..ae699b3bbac8 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -103,6 +103,7 @@ static void flush_tlb_func(void *info) if (f->flush_mm != this_cpu_read(cpu_tlbstate.active_mm)) return; + count_vm_event(NR_TLB_REMOTE_FLUSH_RECEIVED); if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) { if (f->flush_end == TLB_FLUSH_ALL) local_flush_tlb(); @@ -130,6 +131,7 @@ void native_flush_tlb_others(const struct cpumask *cpumask, info.flush_start = start; info.flush_end = end; + count_vm_event(NR_TLB_REMOTE_FLUSH); if (is_uv_system()) { unsigned int cpu; @@ -149,6 +151,7 @@ void flush_tlb_current_task(void) preempt_disable(); + count_vm_event(NR_TLB_LOCAL_FLUSH_ALL); local_flush_tlb(); if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL); @@ -211,16 +214,19 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, act_entries = mm->total_vm > tlb_entries ? tlb_entries : mm->total_vm; /* tlb_flushall_shift is on balance point, details in commit log */ - if ((end - start) >> PAGE_SHIFT > act_entries >> tlb_flushall_shift) + if ((end - start) >> PAGE_SHIFT > act_entries >> tlb_flushall_shift) { + count_vm_event(NR_TLB_LOCAL_FLUSH_ALL); local_flush_tlb(); - else { + } else { if (has_large_page(mm, start, end)) { local_flush_tlb(); goto flush_all; } /* flush range by one by one 'invlpg' */ - for (addr = start; addr < end; addr += PAGE_SIZE) + for (addr = start; addr < end; addr += PAGE_SIZE) { + count_vm_event(NR_TLB_LOCAL_FLUSH_ONE); __flush_tlb_single(addr); + } if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids) @@ -256,6 +262,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long start) static void do_flush_tlb_all(void *info) { + count_vm_event(NR_TLB_REMOTE_FLUSH_RECEIVED); __flush_tlb_all(); if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_LAZY) leave_mm(smp_processor_id()); @@ -263,6 +270,7 @@ static void do_flush_tlb_all(void *info) void flush_tlb_all(void) { + count_vm_event(NR_TLB_REMOTE_FLUSH); on_each_cpu(do_flush_tlb_all, NULL, 1); } diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 2fc216dfbd9c..fa6ade76ef3f 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1692,7 +1692,6 @@ static int xen_hvm_cpu_notify(struct notifier_block *self, unsigned long action, case CPU_UP_PREPARE: xen_vcpu_setup(cpu); if (xen_have_vector_callback) { - xen_init_lock_cpu(cpu); if (xen_feature(XENFEAT_hvm_safe_pvclock)) xen_setup_timer(cpu); } diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 0d4ec35895d4..8b901e8d782d 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c @@ -990,10 +990,13 @@ int m2p_remove_override(struct page *page, printk(KERN_WARNING "m2p_remove_override: " "pfn %lx mfn %lx, failed to modify kernel mappings", pfn, mfn); + put_balloon_scratch_page(); return -1; } - mcs = xen_mc_entry( + xen_mc_batch(); + + mcs = __xen_mc_entry( sizeof(struct gnttab_unmap_and_replace)); unmap_op = mcs.args; unmap_op->host_addr = kmap_op->host_addr; @@ -1003,12 +1006,11 @@ int m2p_remove_override(struct page *page, MULTI_grant_table_op(mcs.mc, GNTTABOP_unmap_and_replace, unmap_op, 1); - xen_mc_issue(PARAVIRT_LAZY_MMU); - mcs = __xen_mc_entry(0); MULTI_update_va_mapping(mcs.mc, scratch_page_address, - pfn_pte(page_to_pfn(get_balloon_scratch_page()), + pfn_pte(page_to_pfn(scratch_page), PAGE_KERNEL_RO), 0); + xen_mc_issue(PARAVIRT_LAZY_MMU); kmap_op->host_addr = 0; diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 9235842cd76a..d1e4777b4e75 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -273,12 +273,20 @@ static void __init xen_smp_prepare_boot_cpu(void) BUG_ON(smp_processor_id() != 0); native_smp_prepare_boot_cpu(); - /* We've switched to the "real" per-cpu gdt, so make sure the - old memory can be recycled */ - make_lowmem_page_readwrite(xen_initial_gdt); + if (xen_pv_domain()) { + /* We've switched to the "real" per-cpu gdt, so make sure the + old memory can be recycled */ + make_lowmem_page_readwrite(xen_initial_gdt); - xen_filter_cpu_maps(); - xen_setup_vcpu_info_placement(); + xen_filter_cpu_maps(); + xen_setup_vcpu_info_placement(); + } + /* + * The alternative logic (which patches the unlock/lock) runs before + * the smp bootup up code is activated. Hence we need to set this up + * the core kernel is being patched. Otherwise we will have only + * modules patched but not core code. + */ xen_init_spinlocks(); } @@ -709,6 +717,15 @@ static int xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle) WARN_ON(rc); if (!rc) rc = native_cpu_up(cpu, tidle); + + /* + * We must initialize the slowpath CPU kicker _after_ the native + * path has executed. If we initialized it before none of the + * unlocker IPI kicks would reach the booting CPU as the booting + * CPU had not set itself 'online' in cpu_online_mask. That mask + * is checked when IPIs are sent (on HVM at least). + */ + xen_init_lock_cpu(cpu); return rc; } @@ -728,4 +745,5 @@ void __init xen_hvm_smp_init(void) smp_ops.cpu_die = xen_hvm_cpu_die; smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi; smp_ops.send_call_func_single_ipi = xen_smp_send_call_function_single_ipi; + smp_ops.smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu; } diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 0438b9324a72..253f63fceea1 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c @@ -81,7 +81,6 @@ static inline void spin_time_accum_blocked(u64 start) spinlock_stats.time_blocked += delta; } #else /* !CONFIG_XEN_DEBUG_FS */ -#define TIMEOUT (1 << 10) static inline void add_stats(enum xen_contention_stat var, u32 val) { } @@ -96,23 +95,6 @@ static inline void spin_time_accum_blocked(u64 start) } #endif /* CONFIG_XEN_DEBUG_FS */ -/* - * Size struct xen_spinlock so it's the same as arch_spinlock_t. - */ -#if NR_CPUS < 256 -typedef u8 xen_spinners_t; -# define inc_spinners(xl) \ - asm(LOCK_PREFIX " incb %0" : "+m" ((xl)->spinners) : : "memory"); -# define dec_spinners(xl) \ - asm(LOCK_PREFIX " decb %0" : "+m" ((xl)->spinners) : : "memory"); -#else -typedef u16 xen_spinners_t; -# define inc_spinners(xl) \ - asm(LOCK_PREFIX " incw %0" : "+m" ((xl)->spinners) : : "memory"); -# define dec_spinners(xl) \ - asm(LOCK_PREFIX " decw %0" : "+m" ((xl)->spinners) : : "memory"); -#endif - struct xen_lock_waiting { struct arch_spinlock *lock; __ticket_t want; @@ -123,6 +105,7 @@ static DEFINE_PER_CPU(char *, irq_name); static DEFINE_PER_CPU(struct xen_lock_waiting, lock_waiting); static cpumask_t waiting_cpus; +static bool xen_pvspin = true; static void xen_lock_spinning(struct arch_spinlock *lock, __ticket_t want) { int irq = __this_cpu_read(lock_kicker_irq); @@ -241,16 +224,12 @@ void xen_init_lock_cpu(int cpu) int irq; char *name; + if (!xen_pvspin) + return; + WARN(per_cpu(lock_kicker_irq, cpu) >= 0, "spinlock on CPU%d exists on IRQ%d!\n", cpu, per_cpu(lock_kicker_irq, cpu)); - /* - * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23 - * (xen: disable PV spinlocks on HVM) - */ - if (xen_hvm_domain()) - return; - name = kasprintf(GFP_KERNEL, "spinlock%d", cpu); irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR, cpu, @@ -270,11 +249,7 @@ void xen_init_lock_cpu(int cpu) void xen_uninit_lock_cpu(int cpu) { - /* - * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23 - * (xen: disable PV spinlocks on HVM) - */ - if (xen_hvm_domain()) + if (!xen_pvspin) return; unbind_from_irqhandler(per_cpu(lock_kicker_irq, cpu), NULL); @@ -283,16 +258,9 @@ void xen_uninit_lock_cpu(int cpu) per_cpu(irq_name, cpu) = NULL; } -static bool xen_pvspin __initdata = true; void __init xen_init_spinlocks(void) { - /* - * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23 - * (xen: disable PV spinlocks on HVM) - */ - if (xen_hvm_domain()) - return; if (!xen_pvspin) { printk(KERN_DEBUG "xen: PV spinlocks disabled\n"); @@ -323,6 +291,9 @@ static int __init xen_spinlock_debugfs(void) if (d_xen == NULL) return -ENOMEM; + if (!xen_pvspin) + return 0; + d_spin_debug = debugfs_create_dir("spinlocks", d_xen); debugfs_create_u8("zero_stats", 0644, d_spin_debug, &zero_stats); diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 42a8bba0b0ea..101012bc1ff6 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -170,8 +170,7 @@ static int __init parse_tag_fdt(const bp_tag_t *tag) __tagtable(BP_TAG_FDT, parse_tag_fdt); -void __init early_init_dt_setup_initrd_arch(unsigned long start, - unsigned long end) +void __init early_init_dt_setup_initrd_arch(u64 start, u64 end) { initrd_start = (void *)__va(start); initrd_end = (void *)__va(end); |