diff options
Diffstat (limited to 'arch')
105 files changed, 972 insertions, 499 deletions
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 1cb8602dd9d..4ed149cbb32 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -256,8 +256,17 @@ int dmabounce_sync_for_cpu(struct device *, dma_addr_t, unsigned long, int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long, size_t, enum dma_data_direction); #else -#define dmabounce_sync_for_cpu(dev,dma,off,sz,dir) (1) -#define dmabounce_sync_for_device(dev,dma,off,sz,dir) (1) +static inline int dmabounce_sync_for_cpu(struct device *d, dma_addr_t addr, + unsigned long offset, size_t size, enum dma_data_direction dir) +{ + return 1; +} + +static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr, + unsigned long offset, size_t size, enum dma_data_direction dir) +{ + return 1; +} /** diff --git a/arch/arm/include/asm/hardware/iop3xx-adma.h b/arch/arm/include/asm/hardware/iop3xx-adma.h index 87bff09633a..83e6ba338e2 100644 --- a/arch/arm/include/asm/hardware/iop3xx-adma.h +++ b/arch/arm/include/asm/hardware/iop3xx-adma.h @@ -730,7 +730,8 @@ static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc, { /* hw_desc->next_desc is the same location for all channels */ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; - BUG_ON(hw_desc.dma->next_desc); + + iop_paranoia(hw_desc.dma->next_desc); hw_desc.dma->next_desc = next_desc_addr; } @@ -760,7 +761,7 @@ static inline int iop_desc_get_zero_result(struct iop_adma_desc_slot *desc) struct iop3xx_desc_aau *hw_desc = desc->hw_desc; struct iop3xx_aau_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field; - BUG_ON(!(desc_ctrl.tx_complete && desc_ctrl.zero_result_en)); + iop_paranoia(!(desc_ctrl.tx_complete && desc_ctrl.zero_result_en)); return desc_ctrl.zero_result_err; } diff --git a/arch/arm/include/asm/hardware/iop_adma.h b/arch/arm/include/asm/hardware/iop_adma.h index cb7e3611bcb..385c6e8cbbd 100644 --- a/arch/arm/include/asm/hardware/iop_adma.h +++ b/arch/arm/include/asm/hardware/iop_adma.h @@ -23,6 +23,12 @@ #define IOP_ADMA_SLOT_SIZE 32 #define IOP_ADMA_THRESHOLD 4 +#ifdef DEBUG +#define IOP_PARANOIA 1 +#else +#define IOP_PARANOIA 0 +#endif +#define iop_paranoia(x) BUG_ON(IOP_PARANOIA && (x)) /** * struct iop_adma_device - internal representation of an ADMA device diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h index cb1139ac194..39d949b63e8 100644 --- a/arch/arm/include/asm/mach/map.h +++ b/arch/arm/include/asm/mach/map.h @@ -19,12 +19,13 @@ struct map_desc { }; /* types 0-3 are defined in asm/io.h */ -#define MT_CACHECLEAN 4 -#define MT_MINICLEAN 5 -#define MT_LOW_VECTORS 6 -#define MT_HIGH_VECTORS 7 -#define MT_MEMORY 8 -#define MT_ROM 9 +#define MT_UNCACHED 4 +#define MT_CACHECLEAN 5 +#define MT_MINICLEAN 6 +#define MT_LOW_VECTORS 7 +#define MT_HIGH_VECTORS 8 +#define MT_MEMORY 9 +#define MT_ROM 10 #ifdef CONFIG_MMU extern void iotable_init(struct map_desc *, int); diff --git a/arch/arm/mach-clps711x/include/mach/hardware.h b/arch/arm/mach-clps711x/include/mach/hardware.h index 4c3e101b96c..b3ebe9e4871 100644 --- a/arch/arm/mach-clps711x/include/mach/hardware.h +++ b/arch/arm/mach-clps711x/include/mach/hardware.h @@ -94,20 +94,6 @@ #include <asm/hardware/ep7212.h> #include <asm/hardware/cs89712.h> -/* dynamic ioremap() areas */ -#define FLASH_START 0x00000000 -#define FLASH_SIZE 0x800000 -#define FLASH_WIDTH 4 - -#define SRAM_START 0x60000000 -#define SRAM_SIZE 0xc000 -#define SRAM_WIDTH 4 - -#define BOOTROM_START 0x70000000 -#define BOOTROM_SIZE 0x80 -#define BOOTROM_WIDTH 4 - - /* static cdb89712_map_io() areas */ #define REGISTER_START 0x80000000 #define REGISTER_SIZE 0x4000 @@ -198,14 +184,6 @@ #define CEIVA_FLASH_SIZE 0x100000 #define CEIVA_FLASH_WIDTH 2 -#define SRAM_START 0x60000000 -#define SRAM_SIZE 0xc000 -#define SRAM_WIDTH 4 - -#define BOOTROM_START 0x70000000 -#define BOOTROM_SIZE 0x80 -#define BOOTROM_WIDTH 4 - /* * SED1355 LCD controller */ diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index c3a33b8a5aa..7e247c04d41 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c @@ -275,9 +275,9 @@ static struct map_desc cl7500_io_desc[] __initdata = { .length = ISA_SIZE, .type = MT_DEVICE }, { /* Flash */ - .virtual = FLASH_BASE, - .pfn = __phys_to_pfn(FLASH_START), - .length = FLASH_SIZE, + .virtual = CLPS7500_FLASH_BASE, + .pfn = __phys_to_pfn(CLPS7500_FLASH_START), + .length = CLPS7500_FLASH_SIZE, .type = MT_DEVICE }, { /* LED */ .virtual = LED_BASE, diff --git a/arch/arm/mach-clps7500/include/mach/hardware.h b/arch/arm/mach-clps7500/include/mach/hardware.h index d66578a3371..a6ad1d44bad 100644 --- a/arch/arm/mach-clps7500/include/mach/hardware.h +++ b/arch/arm/mach-clps7500/include/mach/hardware.h @@ -39,9 +39,9 @@ #define ISA_SIZE 0x00010000 #define ISA_BASE 0xe1000000 -#define FLASH_START 0x01000000 /* XXX */ -#define FLASH_SIZE 0x01000000 -#define FLASH_BASE 0xe2000000 +#define CLPS7500_FLASH_START 0x01000000 /* XXX */ +#define CLPS7500_FLASH_SIZE 0x01000000 +#define CLPS7500_FLASH_BASE 0xe2000000 #define LED_START 0x0302B000 #define LED_SIZE 0x00001000 diff --git a/arch/arm/mach-h720x/include/mach/boards.h b/arch/arm/mach-h720x/include/mach/boards.h index 079b279e124..38b8e0d61fb 100644 --- a/arch/arm/mach-h720x/include/mach/boards.h +++ b/arch/arm/mach-h720x/include/mach/boards.h @@ -19,9 +19,9 @@ #ifdef CONFIG_ARCH_H7202 /* FLASH */ -#define FLASH_VIRT 0xd0000000 -#define FLASH_PHYS 0x00000000 -#define FLASH_SIZE 0x02000000 +#define H720X_FLASH_VIRT 0xd0000000 +#define H720X_FLASH_PHYS 0x00000000 +#define H720X_FLASH_SIZE 0x02000000 /* onboard LAN controller */ # define ETH0_PHYS 0x08000000 diff --git a/arch/arm/mach-integrator/include/mach/platform.h b/arch/arm/mach-integrator/include/mach/platform.h index 028b87839c0..e00a2624f26 100644 --- a/arch/arm/mach-integrator/include/mach/platform.h +++ b/arch/arm/mach-integrator/include/mach/platform.h @@ -408,27 +408,10 @@ #define uHAL_MEMORY_SIZE INTEGRATOR_SSRAM_SIZE /* - * Application Flash - * - */ -#define FLASH_BASE INTEGRATOR_FLASH_BASE -#define FLASH_SIZE INTEGRATOR_FLASH_SIZE -#define FLASH_END (FLASH_BASE + FLASH_SIZE - 1) -#define FLASH_BLOCK_SIZE SZ_128K - -/* - * Boot Flash - * - */ -#define EPROM_BASE INTEGRATOR_BOOT_ROM_HI -#define EPROM_SIZE INTEGRATOR_BOOT_ROM_SIZE -#define EPROM_END (EPROM_BASE + EPROM_SIZE - 1) - -/* * Clean base - dummy * */ -#define CLEAN_BASE EPROM_BASE +#define CLEAN_BASE INTEGRATOR_BOOT_ROM_HI /* * Timer definitions diff --git a/arch/arm/mach-iop13xx/include/mach/adma.h b/arch/arm/mach-iop13xx/include/mach/adma.h index 60019c8e646..5722e86f217 100644 --- a/arch/arm/mach-iop13xx/include/mach/adma.h +++ b/arch/arm/mach-iop13xx/include/mach/adma.h @@ -404,7 +404,8 @@ static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc, u32 next_desc_addr) { struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc; - BUG_ON(hw_desc->next_desc); + + iop_paranoia(hw_desc->next_desc); hw_desc->next_desc = next_desc_addr; } diff --git a/arch/arm/mach-pxa/include/mach/pxafb.h b/arch/arm/mach-pxa/include/mach/pxafb.h index 8e591118371..cbda4d35c42 100644 --- a/arch/arm/mach-pxa/include/mach/pxafb.h +++ b/arch/arm/mach-pxa/include/mach/pxafb.h @@ -33,6 +33,7 @@ #define LCD_CONN_TYPE(_x) ((_x) & 0x0f) #define LCD_CONN_WIDTH(_x) (((_x) >> 4) & 0x1f) +#define LCD_TYPE_MASK 0xf #define LCD_TYPE_UNKNOWN 0 #define LCD_TYPE_MONO_STN 1 #define LCD_TYPE_MONO_DSTN 2 diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c index 1b2af575c40..00b2dc2a107 100644 --- a/arch/arm/mach-pxa/reset.c +++ b/arch/arm/mach-pxa/reset.c @@ -90,12 +90,13 @@ void arch_reset(char mode) /* Jump into ROM at address 0 */ cpu_reset(0); break; - case 'h': - do_hw_reset(); - break; case 'g': do_gpio_reset(); break; + case 'h': + default: + do_hw_reset(); + break; } } diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index f0a5bbae0b4..3be76ee2bdb 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -67,6 +67,7 @@ static unsigned long spitz_pin_config[] __initdata = { /* Chip Selects */ GPIO78_nCS_2, /* SCOOP #2 */ + GPIO79_nCS_3, /* NAND */ GPIO80_nCS_4, /* SCOOP #1 */ /* LCD - 16bpp Active TFT */ @@ -97,10 +98,10 @@ static unsigned long spitz_pin_config[] __initdata = { GPIO51_nPIOW, GPIO85_nPCE_1, GPIO54_nPCE_2, - GPIO79_PSKTSEL, GPIO55_nPREG, GPIO56_nPWAIT, GPIO57_nIOIS16, + GPIO104_PSKTSEL, /* MMC */ GPIO32_MMC_CLK, @@ -686,7 +687,6 @@ static void __init akita_init(void) spitz_pcmcia_config.num_devs = 1; platform_scoop_config = &spitz_pcmcia_config; - pxa_set_i2c_info(NULL); i2c_register_board_info(0, ARRAY_AND_SIZE(akita_i2c_board_info)); common_init(); diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c index 3e706c57833..3347c4236a6 100644 --- a/arch/arm/mach-realview/clock.c +++ b/arch/arm/mach-realview/clock.c @@ -104,7 +104,7 @@ static struct clk uart_clk = { static struct clk mmci_clk = { .name = "MCLK", - .rate = 33000000, + .rate = 24000000, }; int clk_register(struct clk *clk) diff --git a/arch/arm/mach-realview/include/mach/platform.h b/arch/arm/mach-realview/include/mach/platform.h index 4034b54950c..793a3a33271 100644 --- a/arch/arm/mach-realview/include/mach/platform.h +++ b/arch/arm/mach-realview/include/mach/platform.h @@ -239,27 +239,10 @@ #define REALVIEW_DECODE_OFFSET 0xC /* Fitted logic modules */ /* - * Application Flash - * - */ -#define FLASH_BASE REALVIEW_FLASH_BASE -#define FLASH_SIZE REALVIEW_FLASH_SIZE -#define FLASH_END (FLASH_BASE + FLASH_SIZE - 1) -#define FLASH_BLOCK_SIZE SZ_128K - -/* - * Boot Flash - * - */ -#define EPROM_BASE REALVIEW_BOOT_ROM_HI -#define EPROM_SIZE REALVIEW_BOOT_ROM_SIZE -#define EPROM_END (EPROM_BASE + EPROM_SIZE - 1) - -/* * Clean base - dummy * */ -#define CLEAN_BASE EPROM_BASE +#define CLEAN_BASE REALVIEW_BOOT_ROM_HI /* * System controller bit assignment diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c index 9336508ec0b..58937f1fb38 100644 --- a/arch/arm/mach-versatile/clock.c +++ b/arch/arm/mach-versatile/clock.c @@ -105,7 +105,7 @@ static struct clk uart_clk = { static struct clk mmci_clk = { .name = "MCLK", - .rate = 33000000, + .rate = 24000000, }; int clk_register(struct clk *clk) diff --git a/arch/arm/mach-versatile/include/mach/platform.h b/arch/arm/mach-versatile/include/mach/platform.h index 27cbe6a3f22..f91ba930ca8 100644 --- a/arch/arm/mach-versatile/include/mach/platform.h +++ b/arch/arm/mach-versatile/include/mach/platform.h @@ -436,28 +436,12 @@ #define SIC_INTMASK_PCI1 (1 << SIC_INT_PCI1) #define SIC_INTMASK_PCI2 (1 << SIC_INT_PCI2) #define SIC_INTMASK_PCI3 (1 << SIC_INT_PCI3) -/* - * Application Flash - * - */ -#define FLASH_BASE VERSATILE_FLASH_BASE -#define FLASH_SIZE VERSATILE_FLASH_SIZE -#define FLASH_END (FLASH_BASE + FLASH_SIZE - 1) -#define FLASH_BLOCK_SIZE SZ_128K - -/* - * Boot Flash - * - */ -#define EPROM_BASE VERSATILE_BOOT_ROM_HI -#define EPROM_SIZE VERSATILE_BOOT_ROM_SIZE -#define EPROM_END (EPROM_BASE + EPROM_SIZE - 1) /* * Clean base - dummy * */ -#define CLEAN_BASE EPROM_BASE +#define CLEAN_BASE VERSATILE_BOOT_ROM_HI /* * System controller bit assignment diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c index 13cdae8b0d4..80cd207cbae 100644 --- a/arch/arm/mm/cache-feroceon-l2.c +++ b/arch/arm/mm/cache-feroceon-l2.c @@ -150,7 +150,7 @@ static void feroceon_l2_inv_range(unsigned long start, unsigned long end) /* * Clean and invalidate partial last cache line. */ - if (end & (CACHE_LINE_SIZE - 1)) { + if (start < end && end & (CACHE_LINE_SIZE - 1)) { l2_clean_inv_pa(end & ~(CACHE_LINE_SIZE - 1)); end &= ~(CACHE_LINE_SIZE - 1); } @@ -158,7 +158,7 @@ static void feroceon_l2_inv_range(unsigned long start, unsigned long end) /* * Invalidate all full cache lines between 'start' and 'end'. */ - while (start != end) { + while (start < end) { unsigned long range_end = calc_range_end(start, end); l2_inv_pa_range(start, range_end - CACHE_LINE_SIZE); start = range_end; diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index e63db11f16a..7f36c825718 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -208,6 +208,12 @@ static struct mem_type mem_types[] = { .prot_sect = PROT_SECT_DEVICE, .domain = DOMAIN_IO, }, + [MT_UNCACHED] = { + .prot_pte = PROT_PTE_DEVICE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, + .domain = DOMAIN_IO, + }, [MT_CACHECLEAN] = { .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, .domain = DOMAIN_KERNEL, diff --git a/arch/arm/plat-iop/setup.c b/arch/arm/plat-iop/setup.c index 4689db638e9..9e573e78176 100644 --- a/arch/arm/plat-iop/setup.c +++ b/arch/arm/plat-iop/setup.c @@ -16,14 +16,15 @@ #include <asm/hardware/iop3xx.h> /* - * Standard IO mapping for all IOP3xx based systems + * Standard IO mapping for all IOP3xx based systems. Note that + * the IOP3xx OCCDR must be mapped uncached and unbuffered. */ static struct map_desc iop3xx_std_desc[] __initdata = { { /* mem mapped registers */ .virtual = IOP3XX_PERIPHERAL_VIRT_BASE, .pfn = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE), .length = IOP3XX_PERIPHERAL_SIZE, - .type = MT_DEVICE, + .type = MT_UNCACHED, }, { /* PCI IO space */ .virtual = IOP3XX_PCI_LOWER_IO_VA, .pfn = __phys_to_pfn(IOP3XX_PCI_LOWER_IO_PA), diff --git a/arch/blackfin/include/asm/bfin-global.h b/arch/blackfin/include/asm/bfin-global.h index 56dcb0a2d24..77295666c34 100644 --- a/arch/blackfin/include/asm/bfin-global.h +++ b/arch/blackfin/include/asm/bfin-global.h @@ -101,7 +101,7 @@ extern u16 _bfin_swrst; /* shadow for Software Reset Register (SWRST) */ extern unsigned long _ramstart, _ramend, _rambase; extern unsigned long memory_start, memory_end, physical_mem_end; extern char _stext_l1[], _etext_l1[], _sdata_l1[], _edata_l1[], _sbss_l1[], - _ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _ebss_b_l1[], + _ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _sbss_b_l1[], _ebss_b_l1[], _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[], _sbss_l2[], _ebss_l2[], _l2_lma_start[]; diff --git a/arch/blackfin/include/asm/dma-mapping.h b/arch/blackfin/include/asm/dma-mapping.h index ede748d67ef..d7d9148e433 100644 --- a/arch/blackfin/include/asm/dma-mapping.h +++ b/arch/blackfin/include/asm/dma-mapping.h @@ -15,7 +15,11 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr, #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_mapping_error +static inline +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return 0; +} /* * Map a single buffer of the indicated size for DMA in streaming mode. diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 6e08f425bb4..5c0800adb4d 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -218,7 +218,7 @@ inline int check_gpio(unsigned gpio) if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 || gpio == GPIO_PH14 || gpio == GPIO_PH15 || gpio == GPIO_PJ14 || gpio == GPIO_PJ15 - || gpio > MAX_BLACKFIN_GPIOS) + || gpio >= MAX_BLACKFIN_GPIOS) return -EINVAL; return 0; } diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 512f8c92ead..2debc900e24 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c @@ -188,10 +188,11 @@ static struct cplb_desc cplb_data[] = { static u16 __init lock_kernel_check(u32 start, u32 end) { - if ((end <= (u32) _end && end >= (u32)_stext) || - (start <= (u32) _end && start >= (u32)_stext)) - return IN_KERNEL; - return 0; + if (start >= (u32)_end || end <= (u32)_stext) + return 0; + + /* This cplb block overlapped with kernel area. */ + return IN_KERNEL; } static unsigned short __init diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 77800dd83e5..0c3ea118b65 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -351,10 +351,15 @@ int _access_ok(unsigned long addr, unsigned long size) return 1; #endif #if L1_DATA_B_LENGTH != 0 - if (addr >= L1_DATA_B_START + if (addr >= L1_DATA_B_START + (_ebss_b_l1 - _sdata_b_l1) && addr + size <= L1_DATA_B_START + L1_DATA_B_LENGTH) return 1; #endif +#if L2_LENGTH != 0 + if (addr >= L2_START + (_ebss_l2 - _stext_l2) + && addr + size <= L2_START + L2_LENGTH) + return 1; +#endif return 0; } EXPORT_SYMBOL(_access_ok); diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 7f35d1046cd..71a9a8c53ce 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -119,23 +119,23 @@ void __init bfin_relocate_l1_mem(void) /* Copy _stext_l1 to _etext_l1 to L1 instruction SRAM */ dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length); - l1_data_a_length = _ebss_l1 - _sdata_l1; + l1_data_a_length = _sbss_l1 - _sdata_l1; if (l1_data_a_length > L1_DATA_A_LENGTH) panic("L1 Data SRAM Bank A Overflow\n"); - /* Copy _sdata_l1 to _ebss_l1 to L1 data bank A SRAM */ + /* Copy _sdata_l1 to _sbss_l1 to L1 data bank A SRAM */ dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length); - l1_data_b_length = _ebss_b_l1 - _sdata_b_l1; + l1_data_b_length = _sbss_b_l1 - _sdata_b_l1; if (l1_data_b_length > L1_DATA_B_LENGTH) panic("L1 Data SRAM Bank B Overflow\n"); - /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ + /* Copy _sdata_b_l1 to _sbss_b_l1 to L1 data bank B SRAM */ dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + l1_data_a_length, l1_data_b_length); if (L2_LENGTH != 0) { - l2_length = _ebss_l2 - _stext_l2; + l2_length = _sbss_l2 - _stext_l2; if (l2_length > L2_LENGTH) panic("L2 SRAM Overflow\n"); @@ -827,7 +827,7 @@ void __init setup_arch(char **cmdline_p) printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n", bfin_compiled_revid(), bfin_revid()); } - if (bfin_revid() <= CONFIG_BF_REV_MIN || bfin_revid() > CONFIG_BF_REV_MAX) + if (bfin_revid() < CONFIG_BF_REV_MIN || bfin_revid() > CONFIG_BF_REV_MAX) printk(KERN_ERR "Warning: Unsupported Chip Revision ADSP-%s Rev 0.%d detected\n", CPU, bfin_revid()); } diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 1aa2c788e22..bef025b0744 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -59,7 +59,7 @@ #endif -#ifdef CONFIG_VERBOSE_DEBUG +#ifdef CONFIG_DEBUG_VERBOSE #define verbose_printk(fmt, arg...) \ printk(fmt, ##arg) #else @@ -147,9 +147,12 @@ static void decode_address(char *buf, unsigned long address) char *name = p->comm; struct file *file = vma->vm_file; - if (file) - name = d_path(&file->f_path, _tmpbuf, + if (file) { + char *d_name = d_path(&file->f_path, _tmpbuf, sizeof(_tmpbuf)); + if (!IS_ERR(d_name)) + name = d_name; + } /* FLAT does not have its text aligned to the start of * the map while FDPIC ELF does ... @@ -571,7 +574,7 @@ asmlinkage void trap_c(struct pt_regs *fp) #endif panic("Kernel exception"); } else { -#ifdef CONFIG_VERBOSE_DEBUG +#ifdef CONFIG_DEBUG_VERBOSE unsigned long *stack; /* Dump the user space stack */ stack = (unsigned long *)rdusp(); diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S index db532181fbd..a028e945041 100644 --- a/arch/blackfin/mach-common/cache.S +++ b/arch/blackfin/mach-common/cache.S @@ -25,9 +25,13 @@ */ .macro do_flush flushins:req optflushins optnopins label + R2 = -L1_CACHE_BYTES; + + /* start = (start & -L1_CACHE_BYTES) */ + R0 = R0 & R2; + /* end = ((end - 1) & -L1_CACHE_BYTES) + L1_CACHE_BYTES; */ R1 += -1; - R2 = -L1_CACHE_BYTES; R1 = R1 & R2; R1 += L1_CACHE_BYTES; @@ -63,7 +67,7 @@ ENDPROC(_blackfin_icache_flush_range) /* Flush all cache lines assocoiated with this area of memory. */ ENTRY(_blackfin_icache_dcache_flush_range) - do_flush IFLUSH, FLUSH + do_flush FLUSH, IFLUSH ENDPROC(_blackfin_icache_dcache_flush_range) /* Throw away all D-cached data in specified region without any obligation to diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c index c22c47b6012..dda5443b37e 100644 --- a/arch/blackfin/mach-common/cpufreq.c +++ b/arch/blackfin/mach-common/cpufreq.c @@ -72,13 +72,13 @@ unsigned int __bfin_cycles_mod; /**************************************************************************/ -static unsigned int bfin_getfreq(unsigned int cpu) +static unsigned int bfin_getfreq_khz(unsigned int cpu) { /* The driver only support single cpu */ if (cpu != 0) return -1; - return get_cclk(); + return get_cclk() / 1000; } @@ -96,7 +96,7 @@ static int bfin_target(struct cpufreq_policy *policy, cclk_hz = bfin_freq_table[index].frequency; - freqs.old = bfin_getfreq(0); + freqs.old = bfin_getfreq_khz(0); freqs.new = cclk_hz; freqs.cpu = 0; @@ -137,8 +137,8 @@ static int __init __bfin_cpu_init(struct cpufreq_policy *policy) if (policy->cpu != 0) return -EINVAL; - cclk = get_cclk(); - sclk = get_sclk(); + cclk = get_cclk() / 1000; + sclk = get_sclk() / 1000; #if ANOMALY_05000273 || (!defined(CONFIG_BF54x) && defined(CONFIG_BFIN_DCACHE)) min_cclk = sclk * 2; @@ -152,7 +152,7 @@ static int __init __bfin_cpu_init(struct cpufreq_policy *policy) dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */ dpm_state_table[index].tscale = (TIME_SCALE / (1 << csel)) - 1; - pr_debug("cpufreq: freq:%d csel:%d tscale:%d\n", + pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n", bfin_freq_table[index].frequency, dpm_state_table[index].csel, dpm_state_table[index].tscale); @@ -173,7 +173,7 @@ static struct freq_attr *bfin_freq_attr[] = { static struct cpufreq_driver bfin_driver = { .verify = bfin_verify_speed, .target = bfin_target, - .get = bfin_getfreq, + .get = bfin_getfreq_khz, .init = __bfin_cpu_init, .name = "bfin cpufreq", .owner = THIS_MODULE, diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index c13fa8da28c..bde6dc4e261 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -277,7 +277,7 @@ ENTRY(_bfin_return_from_exception) p5.h = hi(ILAT); r6 = [p5]; r7 = 0x20; /* Did I just cause anther HW error? */ - r7 = r7 & r1; + r6 = r7 & r6; CC = R7 == R6; if CC JUMP _double_fault; #endif diff --git a/arch/blackfin/mm/sram-alloc.c b/arch/blackfin/mm/sram-alloc.c index 0f1ca6930c1..cc6f336e731 100644 --- a/arch/blackfin/mm/sram-alloc.c +++ b/arch/blackfin/mm/sram-alloc.c @@ -183,10 +183,10 @@ static void __init l2_sram_init(void) return; } - free_l2_sram_head.next->paddr = (void *)L2_START + - (_etext_l2 - _stext_l2) + (_edata_l2 - _sdata_l2); - free_l2_sram_head.next->size = L2_LENGTH - - (_etext_l2 - _stext_l2) + (_edata_l2 - _sdata_l2); + free_l2_sram_head.next->paddr = + (void *)L2_START + (_ebss_l2 - _stext_l2); + free_l2_sram_head.next->size = + L2_LENGTH - (_ebss_l2 - _stext_l2); free_l2_sram_head.next->pid = 0; free_l2_sram_head.next->next = NULL; diff --git a/arch/ia64/include/asm/intrinsics.h b/arch/ia64/include/asm/intrinsics.h index 47d686dba1e..a3e44a5ed49 100644 --- a/arch/ia64/include/asm/intrinsics.h +++ b/arch/ia64/include/asm/intrinsics.h @@ -226,7 +226,7 @@ extern long ia64_cmpxchg_called_with_bad_pointer (void); /************************************************/ #define ia64_ssm IA64_INTRINSIC_MACRO(ssm) #define ia64_rsm IA64_INTRINSIC_MACRO(rsm) -#define ia64_getreg IA64_INTRINSIC_API(getreg) +#define ia64_getreg IA64_INTRINSIC_MACRO(getreg) #define ia64_setreg IA64_INTRINSIC_API(setreg) #define ia64_set_rr IA64_INTRINSIC_API(set_rr) #define ia64_get_rr IA64_INTRINSIC_API(get_rr) diff --git a/arch/ia64/include/asm/paravirt_privop.h b/arch/ia64/include/asm/paravirt_privop.h index d577aac1183..0b597424fcf 100644 --- a/arch/ia64/include/asm/paravirt_privop.h +++ b/arch/ia64/include/asm/paravirt_privop.h @@ -78,6 +78,19 @@ extern unsigned long ia64_native_getreg_func(int regnum); ia64_native_rsm(mask); \ } while (0) +/* returned ip value should be the one in the caller, + * not in __paravirt_getreg() */ +#define paravirt_getreg(reg) \ + ({ \ + unsigned long res; \ + BUILD_BUG_ON(!__builtin_constant_p(reg)); \ + if ((reg) == _IA64_REG_IP) \ + res = ia64_native_getreg(_IA64_REG_IP); \ + else \ + res = pv_cpu_ops.getreg(reg); \ + res; \ + }) + /****************************************************************************** * replacement of hand written assembly codes. */ diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 7ef0c594f5e..d435f4a7a96 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -499,6 +499,7 @@ GLOBAL_ENTRY(prefetch_stack) END(prefetch_stack) GLOBAL_ENTRY(kernel_execve) + rum psr.ac mov r15=__NR_execve // put syscall number in place break __BREAK_SYSCALL br.ret.sptk.many rp diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index 66e491d8baa..59301c47280 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -260,7 +260,7 @@ start_ap: * Switch into virtual mode: */ movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \ - |IA64_PSR_DI) + |IA64_PSR_DI|IA64_PSR_AC) ;; mov cr.ipsr=r16 movl r17=1f diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 7dd96c12717..bab1de2d2f6 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -1139,7 +1139,7 @@ ia64_mca_modify_original_stack(struct pt_regs *regs, return previous_current; no_mod: - printk(KERN_INFO "cpu %d, %s %s, original stack not modified\n", + mprintk(KERN_INFO "cpu %d, %s %s, original stack not modified\n", smp_processor_id(), type, msg); return previous_current; } diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c index de35d8e8b7d..9f14c16f636 100644 --- a/arch/ia64/kernel/paravirt.c +++ b/arch/ia64/kernel/paravirt.c @@ -130,7 +130,7 @@ ia64_native_getreg_func(int regnum) unsigned long res = -1; switch (regnum) { CASE_GET_REG(GP); - CASE_GET_REG(IP); + /*CASE_GET_REG(IP);*/ /* returned ip value shouldn't be constant */ CASE_GET_REG(PSR); CASE_GET_REG(TP); CASE_GET_REG(SP); diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c index dbdb778efa0..2a92f637431 100644 --- a/arch/ia64/kernel/pci-dma.c +++ b/arch/ia64/kernel/pci-dma.c @@ -19,7 +19,6 @@ #include <linux/kernel.h> #include <asm/page.h> -#include <asm/iommu.h> dma_addr_t bad_dma_address __read_mostly; EXPORT_SYMBOL(bad_dma_address); diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig index 8e99fed6b3f..f833a0b4188 100644 --- a/arch/ia64/kvm/Kconfig +++ b/arch/ia64/kvm/Kconfig @@ -20,6 +20,8 @@ if VIRTUALIZATION config KVM tristate "Kernel-based Virtual Machine (KVM) support" depends on HAVE_KVM && EXPERIMENTAL + # for device assignment: + depends on PCI select PREEMPT_NOTIFIERS select ANON_INODES ---help--- diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 3caac477de9..af1464f7a6a 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -673,16 +673,16 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) vcpu_load(vcpu); + if (vcpu->sigset_active) + sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); + if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) { kvm_vcpu_block(vcpu); clear_bit(KVM_REQ_UNHALT, &vcpu->requests); - vcpu_put(vcpu); - return -EAGAIN; + r = -EAGAIN; + goto out; } - if (vcpu->sigset_active) - sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); - if (vcpu->mmio_needed) { memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); kvm_set_mmio_data(vcpu); @@ -690,7 +690,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) vcpu->mmio_needed = 0; } r = __vcpu_run(vcpu, kvm_run); - +out: if (vcpu->sigset_active) sigprocmask(SIG_SETMASK, &sigsaved, NULL); diff --git a/arch/ia64/kvm/vcpu.h b/arch/ia64/kvm/vcpu.h index 341e3fee280..e9b2a4e121c 100644 --- a/arch/ia64/kvm/vcpu.h +++ b/arch/ia64/kvm/vcpu.h @@ -384,6 +384,10 @@ static inline u64 __gpfn_is_io(u64 gpfn) #define MODE_IND(psr) \ (((psr).it << 2) + ((psr).dt << 1) + (psr).rt) +#ifndef CONFIG_SMP +#define _vmm_raw_spin_lock(x) do {}while(0) +#define _vmm_raw_spin_unlock(x) do {}while(0) +#else #define _vmm_raw_spin_lock(x) \ do { \ __u32 *ia64_spinlock_ptr = (__u32 *) (x); \ @@ -403,6 +407,7 @@ static inline u64 __gpfn_is_io(u64 gpfn) do { barrier(); \ ((spinlock_t *)x)->raw_lock.lock = 0; } \ while (0) +#endif void vmm_spin_lock(spinlock_t *lock); void vmm_spin_unlock(spinlock_t *lock); diff --git a/arch/ia64/xen/hypercall.S b/arch/ia64/xen/hypercall.S index d4ff0b9e79f..45e02bb64a9 100644 --- a/arch/ia64/xen/hypercall.S +++ b/arch/ia64/xen/hypercall.S @@ -58,7 +58,7 @@ __HCALL2(xen_set_rr, HYPERPRIVOP_SET_RR) __HCALL2(xen_set_kr, HYPERPRIVOP_SET_KR) #ifdef CONFIG_IA32_SUPPORT -__HCALL1(xen_get_eflag, HYPERPRIVOP_GET_EFLAG) +__HCALL0(xen_get_eflag, HYPERPRIVOP_GET_EFLAG) __HCALL1(xen_set_eflag, HYPERPRIVOP_SET_EFLAG) // refer SDM vol1 3.1.8 #endif /* CONFIG_IA32_SUPPORT */ diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index 7e8a0d394e6..761ee0440c9 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -133,7 +133,7 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, { int i; - BUG_ON(IRQ_USER + cnt >= NR_IRQS); + BUG_ON(IRQ_USER + cnt > NR_IRQS); m68k_first_user_vec = vec; for (i = 0; i < cnt; i++) irq_controller[IRQ_USER + i] = &user_irq_controller; diff --git a/arch/mips/include/asm/mach-rc32434/gpio.h b/arch/mips/include/asm/mach-rc32434/gpio.h index c8e554eafce..b5cf6457305 100644 --- a/arch/mips/include/asm/mach-rc32434/gpio.h +++ b/arch/mips/include/asm/mach-rc32434/gpio.h @@ -84,5 +84,7 @@ extern void set_434_reg(unsigned reg_offs, unsigned bit, unsigned len, unsigned extern unsigned get_434_reg(unsigned reg_offs); extern void set_latch_u5(unsigned char or_mask, unsigned char nand_mask); extern unsigned char get_latch_u5(void); +extern void rb532_gpio_set_ilevel(int bit, unsigned gpio); +extern void rb532_gpio_set_istat(int bit, unsigned gpio); #endif /* _RC32434_GPIO_H_ */ diff --git a/arch/mips/include/asm/mach-rc32434/rb.h b/arch/mips/include/asm/mach-rc32434/rb.h index 79e8ef67d0d..f25a8491670 100644 --- a/arch/mips/include/asm/mach-rc32434/rb.h +++ b/arch/mips/include/asm/mach-rc32434/rb.h @@ -40,12 +40,14 @@ #define BTCS 0x010040 #define BTCOMPARE 0x010044 #define GPIOBASE 0x050000 -#define GPIOCFG 0x050004 -#define GPIOD 0x050008 -#define GPIOILEVEL 0x05000C -#define GPIOISTAT 0x050010 -#define GPIONMIEN 0x050014 -#define IMASK6 0x038038 +/* Offsets relative to GPIOBASE */ +#define GPIOFUNC 0x00 +#define GPIOCFG 0x04 +#define GPIOD 0x08 +#define GPIOILEVEL 0x0C +#define GPIOISTAT 0x10 +#define GPIONMIEN 0x14 +#define IMASK6 0x38 #define LO_WPX (1 << 0) #define LO_ALE (1 << 1) #define LO_CLE (1 << 2) diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h index d3bd5c5aa2e..9601ea95054 100644 --- a/arch/mips/include/asm/time.h +++ b/arch/mips/include/asm/time.h @@ -63,7 +63,7 @@ static inline int mips_clockevent_init(void) /* * Initialize the count register as a clocksource */ -#ifdef CONFIG_CEVT_R4K +#ifdef CONFIG_CSRC_R4K extern int init_mips_clocksource(void); #else static inline int init_mips_clocksource(void) diff --git a/arch/mips/kernel/csrc-r4k.c b/arch/mips/kernel/csrc-r4k.c index 86e026f067b..74fb74583b4 100644 --- a/arch/mips/kernel/csrc-r4k.c +++ b/arch/mips/kernel/csrc-r4k.c @@ -27,7 +27,7 @@ int __init init_mips_clocksource(void) if (!cpu_has_counter || !mips_hpt_frequency) return -ENXIO; - /* Calclate a somewhat reasonable rating value */ + /* Calculate a somewhat reasonable rating value */ clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; clocksource_set_clock(&clocksource_mips, mips_hpt_frequency); diff --git a/arch/mips/mm/sc-ip22.c b/arch/mips/mm/sc-ip22.c index 1f602a110e1..13adb578211 100644 --- a/arch/mips/mm/sc-ip22.c +++ b/arch/mips/mm/sc-ip22.c @@ -161,7 +161,7 @@ static inline int __init indy_sc_probe(void) /* XXX Check with wje if the Indy caches can differenciate between writeback + invalidate and just invalidate. */ -struct bcache_ops indy_sc_ops = { +static struct bcache_ops indy_sc_ops = { .bc_enable = indy_sc_enable, .bc_disable = indy_sc_disable, .bc_wback_inv = indy_sc_wback_invalidate, diff --git a/arch/mips/mti-malta/malta-amon.c b/arch/mips/mti-malta/malta-amon.c index 96236bf3383..df9e526312a 100644 --- a/arch/mips/mti-malta/malta-amon.c +++ b/arch/mips/mti-malta/malta-amon.c @@ -22,9 +22,9 @@ #include <linux/init.h> #include <linux/smp.h> -#include <asm-mips/addrspace.h> -#include <asm-mips/mips-boards/launch.h> -#include <asm-mips/mipsmtregs.h> +#include <asm/addrspace.h> +#include <asm/mips-boards/launch.h> +#include <asm/mipsmtregs.h> int amon_cpu_avail(int cpu) { diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c index 2f22d714d5b..c1c29181bd4 100644 --- a/arch/mips/rb532/devices.c +++ b/arch/mips/rb532/devices.c @@ -118,7 +118,7 @@ static struct platform_device cf_slot0 = { /* Resources and device for NAND */ static int rb532_dev_ready(struct mtd_info *mtd) { - return readl(IDT434_REG_BASE + GPIOD) & GPIO_RDY; + return gpio_get_value(GPIO_RDY); } static void rb532_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c index 70c4a672637..0e84c8ab6a3 100644 --- a/arch/mips/rb532/gpio.c +++ b/arch/mips/rb532/gpio.c @@ -39,10 +39,6 @@ struct rb532_gpio_chip { struct gpio_chip chip; void __iomem *regbase; - void (*set_int_level)(struct gpio_chip *chip, unsigned offset, int value); - int (*get_int_level)(struct gpio_chip *chip, unsigned offset); - void (*set_int_status)(struct gpio_chip *chip, unsigned offset, int value); - int (*get_int_status)(struct gpio_chip *chip, unsigned offset); }; struct mpmc_device dev3; @@ -111,15 +107,47 @@ unsigned char get_latch_u5(void) } EXPORT_SYMBOL(get_latch_u5); +/* rb532_set_bit - sanely set a bit + * + * bitval: new value for the bit + * offset: bit index in the 4 byte address range + * ioaddr: 4 byte aligned address being altered + */ +static inline void rb532_set_bit(unsigned bitval, + unsigned offset, void __iomem *ioaddr) +{ + unsigned long flags; + u32 val; + + bitval = !!bitval; /* map parameter to {0,1} */ + + local_irq_save(flags); + + val = readl(ioaddr); + val &= ~( ~bitval << offset ); /* unset bit if bitval == 0 */ + val |= ( bitval << offset ); /* set bit if bitval == 1 */ + writel(val, ioaddr); + + local_irq_restore(flags); +} + +/* rb532_get_bit - read a bit + * + * returns the boolean state of the bit, which may be > 1 + */ +static inline int rb532_get_bit(unsigned offset, void __iomem *ioaddr) +{ + return (readl(ioaddr) & (1 << offset)); +} + /* * Return GPIO level */ static int rb532_gpio_get(struct gpio_chip *chip, unsigned offset) { - u32 mask = 1 << offset; struct rb532_gpio_chip *gpch; gpch = container_of(chip, struct rb532_gpio_chip, chip); - return readl(gpch->regbase + GPIOD) & mask; + return rb532_get_bit(offset, gpch->regbase + GPIOD); } /* @@ -128,23 +156,10 @@ static int rb532_gpio_get(struct gpio_chip *chip, unsigned offset) static void rb532_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { - unsigned long flags; - u32 mask = 1 << offset; - u32 tmp; struct rb532_gpio_chip *gpch; - void __iomem *gpvr; gpch = container_of(chip, struct rb532_gpio_chip, chip); - gpvr = gpch->regbase + GPIOD; - - local_irq_save(flags); - tmp = readl(gpvr); - if (value) - tmp |= mask; - else - tmp &= ~mask; - writel(tmp, gpvr); - local_irq_restore(flags); + rb532_set_bit(value, offset, gpch->regbase + GPIOD); } /* @@ -152,21 +167,14 @@ static void rb532_gpio_set(struct gpio_chip *chip, */ static int rb532_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { - unsigned long flags; - u32 mask = 1 << offset; - u32 value; struct rb532_gpio_chip *gpch; - void __iomem *gpdr; gpch = container_of(chip, struct rb532_gpio_chip, chip); - gpdr = gpch->regbase + GPIOCFG; - local_irq_save(flags); - value = readl(gpdr); - value &= ~mask; - writel(value, gpdr); - local_irq_restore(flags); + if (rb532_get_bit(offset, gpch->regbase + GPIOFUNC)) + return 1; /* alternate function, GPIOCFG is ignored */ + rb532_set_bit(0, offset, gpch->regbase + GPIOCFG); return 0; } @@ -176,117 +184,60 @@ static int rb532_gpio_direction_input(struct gpio_chip *chip, unsigned offset) static int rb532_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) { - unsigned long flags; - u32 mask = 1 << offset; - u32 tmp; struct rb532_gpio_chip *gpch; - void __iomem *gpdr; gpch = container_of(chip, struct rb532_gpio_chip, chip); - writel(mask, gpch->regbase + GPIOD); - gpdr = gpch->regbase + GPIOCFG; - local_irq_save(flags); - tmp = readl(gpdr); - tmp |= mask; - writel(tmp, gpdr); - local_irq_restore(flags); + if (rb532_get_bit(offset, gpch->regbase + GPIOFUNC)) + return 1; /* alternate function, GPIOCFG is ignored */ + /* set the initial output value */ + rb532_set_bit(value, offset, gpch->regbase + GPIOD); + + rb532_set_bit(1, offset, gpch->regbase + GPIOCFG); return 0; } -/* - * Set the GPIO interrupt level - */ -static void rb532_gpio_set_int_level(struct gpio_chip *chip, - unsigned offset, int value) -{ - unsigned long flags; - u32 mask = 1 << offset; - u32 tmp; - struct rb532_gpio_chip *gpch; - void __iomem *gpil; - - gpch = container_of(chip, struct rb532_gpio_chip, chip); - gpil = gpch->regbase + GPIOILEVEL; - - local_irq_save(flags); - tmp = readl(gpil); - if (value) - tmp |= mask; - else - tmp &= ~mask; - writel(tmp, gpil); - local_irq_restore(flags); -} +static struct rb532_gpio_chip rb532_gpio_chip[] = { + [0] = { + .chip = { + .label = "gpio0", + .direction_input = rb532_gpio_direction_input, + .direction_output = rb532_gpio_direction_output, + .get = rb532_gpio_get, + .set = rb532_gpio_set, + .base = 0, + .ngpio = 32, + }, + }, +}; /* - * Get the GPIO interrupt level + * Set GPIO interrupt level */ -static int rb532_gpio_get_int_level(struct gpio_chip *chip, unsigned offset) +void rb532_gpio_set_ilevel(int bit, unsigned gpio) { - u32 mask = 1 << offset; - struct rb532_gpio_chip *gpch; - - gpch = container_of(chip, struct rb532_gpio_chip, chip); - return readl(gpch->regbase + GPIOILEVEL) & mask; + rb532_set_bit(bit, gpio, rb532_gpio_chip->regbase + GPIOILEVEL); } +EXPORT_SYMBOL(rb532_gpio_set_ilevel); /* - * Set the GPIO interrupt status + * Set GPIO interrupt status */ -static void rb532_gpio_set_int_status(struct gpio_chip *chip, - unsigned offset, int value) +void rb532_gpio_set_istat(int bit, unsigned gpio) { - unsigned long flags; - u32 mask = 1 << offset; - u32 tmp; - struct rb532_gpio_chip *gpch; - void __iomem *gpis; - - gpch = container_of(chip, struct rb532_gpio_chip, chip); - gpis = gpch->regbase + GPIOISTAT; - - local_irq_save(flags); - tmp = readl(gpis); - if (value) - tmp |= mask; - else - tmp &= ~mask; - writel(tmp, gpis); - local_irq_restore(flags); + rb532_set_bit(bit, gpio, rb532_gpio_chip->regbase + GPIOISTAT); } +EXPORT_SYMBOL(rb532_gpio_set_istat); /* - * Get the GPIO interrupt status + * Configure GPIO alternate function */ -static int rb532_gpio_get_int_status(struct gpio_chip *chip, unsigned offset) +static void rb532_gpio_set_func(int bit, unsigned gpio) { - u32 mask = 1 << offset; - struct rb532_gpio_chip *gpch; - - gpch = container_of(chip, struct rb532_gpio_chip, chip); - return readl(gpch->regbase + GPIOISTAT) & mask; + rb532_set_bit(bit, gpio, rb532_gpio_chip->regbase + GPIOFUNC); } -static struct rb532_gpio_chip rb532_gpio_chip[] = { - [0] = { - .chip = { - .label = "gpio0", - .direction_input = rb532_gpio_direction_input, - .direction_output = rb532_gpio_direction_output, - .get = rb532_gpio_get, - .set = rb532_gpio_set, - .base = 0, - .ngpio = 32, - }, - .get_int_level = rb532_gpio_get_int_level, - .set_int_level = rb532_gpio_set_int_level, - .get_int_status = rb532_gpio_get_int_status, - .set_int_status = rb532_gpio_set_int_status, - }, -}; - int __init rb532_gpio_init(void) { struct resource *r; @@ -310,9 +261,11 @@ int __init rb532_gpio_init(void) return -ENXIO; } - /* Set the interrupt status and level for the CF pin */ - rb532_gpio_set_int_level(&rb532_gpio_chip->chip, CF_GPIO_NUM, 1); - rb532_gpio_set_int_status(&rb532_gpio_chip->chip, CF_GPIO_NUM, 0); + /* configure CF_GPIO_NUM as CFRDY IRQ source */ + rb532_gpio_set_func(0, CF_GPIO_NUM); + rb532_gpio_direction_input(&rb532_gpio_chip->chip, CF_GPIO_NUM); + rb532_gpio_set_ilevel(1, CF_GPIO_NUM); + rb532_gpio_set_istat(0, CF_GPIO_NUM); return 0; } diff --git a/arch/mn10300/Kconfig.debug b/arch/mn10300/Kconfig.debug index 524e33819f3..ff80e86b9bd 100644 --- a/arch/mn10300/Kconfig.debug +++ b/arch/mn10300/Kconfig.debug @@ -15,6 +15,15 @@ config DEBUG_DECOMPRESS_KERNEL decompressing Linux seeing "Uncompressing Linux... " and "Ok, booting the kernel.\n" on console. +config TEST_MISALIGNMENT_HANDLER + bool "Run tests on the misalignment handler" + depends on DEBUG_KERNEL + default n + help + If you say Y here the kernel will execute a list of misaligned memory + accesses to make sure the misalignment handler deals them with + correctly. If it does not, the kernel will throw a BUG. + config KPROBES bool "Kprobes" depends on DEBUG_KERNEL diff --git a/arch/mn10300/mm/misalignment.c b/arch/mn10300/mm/misalignment.c index 32aa89dc384..94c4a435806 100644 --- a/arch/mn10300/mm/misalignment.c +++ b/arch/mn10300/mm/misalignment.c @@ -37,26 +37,22 @@ #include <asm/asm-offsets.h> #if 0 -#define kdebug(FMT, ...) printk(KERN_DEBUG FMT, ##__VA_ARGS__) +#define kdebug(FMT, ...) printk(KERN_DEBUG "MISALIGN: "FMT"\n", ##__VA_ARGS__) #else #define kdebug(FMT, ...) do {} while (0) #endif -static int misalignment_addr(unsigned long *registers, unsigned params, - unsigned opcode, unsigned disp, - void **_address, unsigned long **_postinc); +static int misalignment_addr(unsigned long *registers, unsigned long sp, + unsigned params, unsigned opcode, + unsigned long disp, + void **_address, unsigned long **_postinc, + unsigned long *_inc); static int misalignment_reg(unsigned long *registers, unsigned params, - unsigned opcode, unsigned disp, + unsigned opcode, unsigned long disp, unsigned long **_register); -static inline unsigned int_log2(unsigned x) -{ - unsigned y; - asm("bsch %1,%0" : "=r"(y) : "r"(x), "0"(0)); - return y; -} -#define log2(x) int_log2(x) +static void misalignment_MOV_Lcc(struct pt_regs *regs, uint32_t opcode); static const unsigned Dreg_index[] = { REG_D0 >> 2, REG_D1 >> 2, REG_D2 >> 2, REG_D3 >> 2 @@ -86,9 +82,10 @@ enum format_id { FMT_D7, FMT_D8, FMT_D9, + FMT_D10, }; -struct { +static const struct { u_int8_t opsz, dispsz; } format_tbl[16] = { [FMT_S0] = { 8, 0 }, @@ -103,6 +100,7 @@ struct { [FMT_D7] = { 24, 8 }, [FMT_D8] = { 24, 24 }, [FMT_D9] = { 24, 32 }, + [FMT_D10] = { 32, 0 }, }; enum value_id { @@ -128,9 +126,14 @@ enum value_id { SD24, /* 24-bit signed displacement */ SIMM4_2, /* 4-bit signed displacement in opcode bits 4-7 */ SIMM8, /* 8-bit signed immediate */ + IMM8, /* 8-bit unsigned immediate */ + IMM16, /* 16-bit unsigned immediate */ IMM24, /* 24-bit unsigned immediate */ IMM32, /* 32-bit unsigned immediate */ - IMM32_HIGH8, /* 32-bit unsigned immediate, high 8-bits in opcode */ + IMM32_HIGH8, /* 32-bit unsigned immediate, LSB in opcode */ + + IMM32_MEM, /* 32-bit unsigned displacement */ + IMM32_HIGH8_MEM, /* 32-bit unsigned displacement, LSB in opcode */ DN0 = DM0, DN1 = DM1, @@ -149,7 +152,7 @@ enum value_id { }; struct mn10300_opcode { - const char *name; + const char name[8]; u_int32_t opcode; u_int32_t opmask; unsigned exclusion; @@ -185,6 +188,10 @@ struct mn10300_opcode { Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ static const struct mn10300_opcode mn10300_opcodes[] = { +{ "mov", 0x4200, 0xf300, 0, FMT_S1, 0, {DM1, MEM2(IMM8, SP)}}, +{ "mov", 0x4300, 0xf300, 0, FMT_S1, 0, {AM1, MEM2(IMM8, SP)}}, +{ "mov", 0x5800, 0xfc00, 0, FMT_S1, 0, {MEM2(IMM8, SP), DN0}}, +{ "mov", 0x5c00, 0xfc00, 0, FMT_S1, 0, {MEM2(IMM8, SP), AN0}}, { "mov", 0x60, 0xf0, 0, FMT_S0, 0, {DM1, MEM(AN0)}}, { "mov", 0x70, 0xf0, 0, FMT_S0, 0, {MEM(AM0), DN1}}, { "mov", 0xf000, 0xfff0, 0, FMT_D0, 0, {MEM(AM0), AN1}}, @@ -197,8 +204,6 @@ static const struct mn10300_opcode mn10300_opcodes[] = { { "mov", 0xf81000, 0xfff000, 0, FMT_D1, 0, {DM1, MEM2(SD8, AN0)}}, { "mov", 0xf82000, 0xfff000, 0, FMT_D1, 0, {MEM2(SD8,AM0), AN1}}, { "mov", 0xf83000, 0xfff000, 0, FMT_D1, 0, {AM1, MEM2(SD8, AN0)}}, -{ "mov", 0xf8f000, 0xfffc00, 0, FMT_D1, AM33, {MEM2(SD8, AM0), SP}}, -{ "mov", 0xf8f400, 0xfffc00, 0, FMT_D1, AM33, {SP, MEM2(SD8, AN0)}}, { "mov", 0xf90a00, 0xffff00, 0, FMT_D6, AM33, {MEM(RM0), RN2}}, { "mov", 0xf91a00, 0xffff00, 0, FMT_D6, AM33, {RM2, MEM(RN0)}}, { "mov", 0xf96a00, 0xffff00, 0x12, FMT_D6, AM33, {MEMINC(RM0), RN2}}, @@ -207,24 +212,46 @@ static const struct mn10300_opcode mn10300_opcodes[] = { { "mov", 0xfa100000, 0xfff00000, 0, FMT_D2, 0, {DM1, MEM2(SD16, AN0)}}, { "mov", 0xfa200000, 0xfff00000, 0, FMT_D2, 0, {MEM2(SD16, AM0), AN1}}, { "mov", 0xfa300000, 0xfff00000, 0, FMT_D2, 0, {AM1, MEM2(SD16, AN0)}}, +{ "mov", 0xfa900000, 0xfff30000, 0, FMT_D2, 0, {AM1, MEM2(IMM16, SP)}}, +{ "mov", 0xfa910000, 0xfff30000, 0, FMT_D2, 0, {DM1, MEM2(IMM16, SP)}}, +{ "mov", 0xfab00000, 0xfffc0000, 0, FMT_D2, 0, {MEM2(IMM16, SP), AN0}}, +{ "mov", 0xfab40000, 0xfffc0000, 0, FMT_D2, 0, {MEM2(IMM16, SP), DN0}}, { "mov", 0xfb0a0000, 0xffff0000, 0, FMT_D7, AM33, {MEM2(SD8, RM0), RN2}}, { "mov", 0xfb1a0000, 0xffff0000, 0, FMT_D7, AM33, {RM2, MEM2(SD8, RN0)}}, { "mov", 0xfb6a0000, 0xffff0000, 0x22, FMT_D7, AM33, {MEMINC2 (RM0, SIMM8), RN2}}, { "mov", 0xfb7a0000, 0xffff0000, 0, FMT_D7, AM33, {RM2, MEMINC2 (RN0, SIMM8)}}, +{ "mov", 0xfb8a0000, 0xffff0f00, 0, FMT_D7, AM33, {MEM2(IMM8, SP), RN2}}, { "mov", 0xfb8e0000, 0xffff000f, 0, FMT_D7, AM33, {MEM2(RI, RM0), RD2}}, +{ "mov", 0xfb9a0000, 0xffff0f00, 0, FMT_D7, AM33, {RM2, MEM2(IMM8, SP)}}, { "mov", 0xfb9e0000, 0xffff000f, 0, FMT_D7, AM33, {RD2, MEM2(RI, RN0)}}, { "mov", 0xfc000000, 0xfff00000, 0, FMT_D4, 0, {MEM2(IMM32,AM0), DN1}}, { "mov", 0xfc100000, 0xfff00000, 0, FMT_D4, 0, {DM1, MEM2(IMM32,AN0)}}, { "mov", 0xfc200000, 0xfff00000, 0, FMT_D4, 0, {MEM2(IMM32,AM0), AN1}}, { "mov", 0xfc300000, 0xfff00000, 0, FMT_D4, 0, {AM1, MEM2(IMM32,AN0)}}, +{ "mov", 0xfc800000, 0xfff30000, 0, FMT_D4, 0, {AM1, MEM(IMM32_MEM)}}, +{ "mov", 0xfc810000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM(IMM32_MEM)}}, +{ "mov", 0xfc900000, 0xfff30000, 0, FMT_D4, 0, {AM1, MEM2(IMM32, SP)}}, +{ "mov", 0xfc910000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM2(IMM32, SP)}}, +{ "mov", 0xfca00000, 0xfffc0000, 0, FMT_D4, 0, {MEM(IMM32_MEM), AN0}}, +{ "mov", 0xfca40000, 0xfffc0000, 0, FMT_D4, 0, {MEM(IMM32_MEM), DN0}}, +{ "mov", 0xfcb00000, 0xfffc0000, 0, FMT_D4, 0, {MEM2(IMM32, SP), AN0}}, +{ "mov", 0xfcb40000, 0xfffc0000, 0, FMT_D4, 0, {MEM2(IMM32, SP), DN0}}, { "mov", 0xfd0a0000, 0xffff0000, 0, FMT_D8, AM33, {MEM2(SD24, RM0), RN2}}, { "mov", 0xfd1a0000, 0xffff0000, 0, FMT_D8, AM33, {RM2, MEM2(SD24, RN0)}}, { "mov", 0xfd6a0000, 0xffff0000, 0x22, FMT_D8, AM33, {MEMINC2 (RM0, IMM24), RN2}}, { "mov", 0xfd7a0000, 0xffff0000, 0, FMT_D8, AM33, {RM2, MEMINC2 (RN0, IMM24)}}, +{ "mov", 0xfd8a0000, 0xffff0f00, 0, FMT_D8, AM33, {MEM2(IMM24, SP), RN2}}, +{ "mov", 0xfd9a0000, 0xffff0f00, 0, FMT_D8, AM33, {RM2, MEM2(IMM24, SP)}}, { "mov", 0xfe0a0000, 0xffff0000, 0, FMT_D9, AM33, {MEM2(IMM32_HIGH8,RM0), RN2}}, +{ "mov", 0xfe0a0000, 0xffff0000, 0, FMT_D9, AM33, {MEM2(IMM32_HIGH8,RM0), RN2}}, +{ "mov", 0xfe0e0000, 0xffff0f00, 0, FMT_D9, AM33, {MEM(IMM32_HIGH8_MEM), RN2}}, +{ "mov", 0xfe1a0000, 0xffff0000, 0, FMT_D9, AM33, {RM2, MEM2(IMM32_HIGH8, RN0)}}, { "mov", 0xfe1a0000, 0xffff0000, 0, FMT_D9, AM33, {RM2, MEM2(IMM32_HIGH8, RN0)}}, +{ "mov", 0xfe1e0000, 0xffff0f00, 0, FMT_D9, AM33, {RM2, MEM(IMM32_HIGH8_MEM)}}, { "mov", 0xfe6a0000, 0xffff0000, 0x22, FMT_D9, AM33, {MEMINC2 (RM0, IMM32_HIGH8), RN2}}, { "mov", 0xfe7a0000, 0xffff0000, 0, FMT_D9, AM33, {RN2, MEMINC2 (RM0, IMM32_HIGH8)}}, +{ "mov", 0xfe8a0000, 0xffff0f00, 0, FMT_D9, AM33, {MEM2(IMM32_HIGH8, SP), RN2}}, +{ "mov", 0xfe9a0000, 0xffff0f00, 0, FMT_D9, AM33, {RM2, MEM2(IMM32_HIGH8, SP)}}, { "movhu", 0xf060, 0xfff0, 0, FMT_D0, 0, {MEM(AM0), DN1}}, { "movhu", 0xf070, 0xfff0, 0, FMT_D0, 0, {DM1, MEM(AN0)}}, @@ -232,29 +259,58 @@ static const struct mn10300_opcode mn10300_opcodes[] = { { "movhu", 0xf4c0, 0xffc0, 0, FMT_D0, 0, {DM2, MEM2(DI, AN0)}}, { "movhu", 0xf86000, 0xfff000, 0, FMT_D1, 0, {MEM2(SD8, AM0), DN1}}, { "movhu", 0xf87000, 0xfff000, 0, FMT_D1, 0, {DM1, MEM2(SD8, AN0)}}, +{ "movhu", 0xf89300, 0xfff300, 0, FMT_D1, 0, {DM1, MEM2(IMM8, SP)}}, +{ "movhu", 0xf8bc00, 0xfffc00, 0, FMT_D1, 0, {MEM2(IMM8, SP), DN0}}, { "movhu", 0xf94a00, 0xffff00, 0, FMT_D6, AM33, {MEM(RM0), RN2}}, { "movhu", 0xf95a00, 0xffff00, 0, FMT_D6, AM33, {RM2, MEM(RN0)}}, { "movhu", 0xf9ea00, 0xffff00, 0x12, FMT_D6, AM33, {MEMINC(RM0), RN2}}, { "movhu", 0xf9fa00, 0xffff00, 0, FMT_D6, AM33, {RM2, MEMINC(RN0)}}, { "movhu", 0xfa600000, 0xfff00000, 0, FMT_D2, 0, {MEM2(SD16, AM0), DN1}}, { "movhu", 0xfa700000, 0xfff00000, 0, FMT_D2, 0, {DM1, MEM2(SD16, AN0)}}, +{ "movhu", 0xfa930000, 0xfff30000, 0, FMT_D2, 0, {DM1, MEM2(IMM16, SP)}}, +{ "movhu", 0xfabc0000, 0xfffc0000, 0, FMT_D2, 0, {MEM2(IMM16, SP), DN0}}, { "movhu", 0xfb4a0000, 0xffff0000, 0, FMT_D7, AM33, {MEM2(SD8, RM0), RN2}}, { "movhu", 0xfb5a0000, 0xffff0000, 0, FMT_D7, AM33, {RM2, MEM2(SD8, RN0)}}, +{ "movhu", 0xfbca0000, 0xffff0f00, 0, FMT_D7, AM33, {MEM2(IMM8, SP), RN2}}, { "movhu", 0xfbce0000, 0xffff000f, 0, FMT_D7, AM33, {MEM2(RI, RM0), RD2}}, +{ "movhu", 0xfbda0000, 0xffff0f00, 0, FMT_D7, AM33, {RM2, MEM2(IMM8, SP)}}, { "movhu", 0xfbde0000, 0xffff000f, 0, FMT_D7, AM33, {RD2, MEM2(RI, RN0)}}, { "movhu", 0xfbea0000, 0xffff0000, 0x22, FMT_D7, AM33, {MEMINC2 (RM0, SIMM8), RN2}}, { "movhu", 0xfbfa0000, 0xffff0000, 0, FMT_D7, AM33, {RM2, MEMINC2 (RN0, SIMM8)}}, { "movhu", 0xfc600000, 0xfff00000, 0, FMT_D4, 0, {MEM2(IMM32,AM0), DN1}}, { "movhu", 0xfc700000, 0xfff00000, 0, FMT_D4, 0, {DM1, MEM2(IMM32,AN0)}}, +{ "movhu", 0xfc830000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM(IMM32_MEM)}}, +{ "movhu", 0xfc930000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM2(IMM32, SP)}}, +{ "movhu", 0xfcac0000, 0xfffc0000, 0, FMT_D4, 0, {MEM(IMM32_MEM), DN0}}, +{ "movhu", 0xfcbc0000, 0xfffc0000, 0, FMT_D4, 0, {MEM2(IMM32, SP), DN0}}, { "movhu", 0xfd4a0000, 0xffff0000, 0, FMT_D8, AM33, {MEM2(SD24, RM0), RN2}}, { "movhu", 0xfd5a0000, 0xffff0000, 0, FMT_D8, AM33, {RM2, MEM2(SD24, RN0)}}, +{ "movhu", 0xfdca0000, 0xffff0f00, 0, FMT_D8, AM33, {MEM2(IMM24, SP), RN2}}, +{ "movhu", 0xfdda0000, 0xffff0f00, 0, FMT_D8, AM33, {RM2, MEM2(IMM24, SP)}}, { "movhu", 0xfdea0000, 0xffff0000, 0x22, FMT_D8, AM33, {MEMINC2 (RM0, IMM24), RN2}}, { "movhu", 0xfdfa0000, 0xffff0000, 0, FMT_D8, AM33, {RM2, MEMINC2 (RN0, IMM24)}}, { "movhu", 0xfe4a0000, 0xffff0000, 0, FMT_D9, AM33, {MEM2(IMM32_HIGH8,RM0), RN2}}, +{ "movhu", 0xfe4e0000, 0xffff0f00, 0, FMT_D9, AM33, {MEM(IMM32_HIGH8_MEM), RN2}}, { "movhu", 0xfe5a0000, 0xffff0000, 0, FMT_D9, AM33, {RM2, MEM2(IMM32_HIGH8, RN0)}}, +{ "movhu", 0xfe5e0000, 0xffff0f00, 0, FMT_D9, AM33, {RM2, MEM(IMM32_HIGH8_MEM)}}, +{ "movhu", 0xfeca0000, 0xffff0f00, 0, FMT_D9, AM33, {MEM2(IMM32_HIGH8, SP), RN2}}, +{ "movhu", 0xfeda0000, 0xffff0f00, 0, FMT_D9, AM33, {RM2, MEM2(IMM32_HIGH8, SP)}}, { "movhu", 0xfeea0000, 0xffff0000, 0x22, FMT_D9, AM33, {MEMINC2 (RM0, IMM32_HIGH8), RN2}}, { "movhu", 0xfefa0000, 0xffff0000, 0, FMT_D9, AM33, {RN2, MEMINC2 (RM0, IMM32_HIGH8)}}, -{ 0, 0, 0, 0, 0, 0, {0}}, + +{ "mov_llt", 0xf7e00000, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}}, +{ "mov_lgt", 0xf7e00001, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}}, +{ "mov_lge", 0xf7e00002, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}}, +{ "mov_lle", 0xf7e00003, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}}, +{ "mov_lcs", 0xf7e00004, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}}, +{ "mov_lhi", 0xf7e00005, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}}, +{ "mov_lcc", 0xf7e00006, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}}, +{ "mov_lls", 0xf7e00007, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}}, +{ "mov_leq", 0xf7e00008, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}}, +{ "mov_lne", 0xf7e00009, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}}, +{ "mov_lra", 0xf7e0000a, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}}, + +{ "", 0, 0, 0, 0, 0, {0}}, }; /* @@ -265,18 +321,21 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code) const struct exception_table_entry *fixup; const struct mn10300_opcode *pop; unsigned long *registers = (unsigned long *) regs; - unsigned long data, *store, *postinc; + unsigned long data, *store, *postinc, disp, inc, sp; mm_segment_t seg; siginfo_t info; - uint32_t opcode, disp, noc, xo, xm; - uint8_t *pc, byte; + uint32_t opcode, noc, xo, xm; + uint8_t *pc, byte, datasz; void *address; - unsigned tmp, npop; + unsigned tmp, npop, dispsz, loop; + + /* we don't fix up userspace misalignment faults */ + if (user_mode(regs)) + goto bus_error; - kdebug("MISALIGN at %lx\n", regs->pc); + sp = (unsigned long) regs + sizeof(*regs); - if (in_interrupt()) - die("Misalignment trap in interrupt context", regs, code); + kdebug("==>misalignment({pc=%lx,sp=%lx})", regs->pc, sp); if (regs->epsw & EPSW_IE) asm volatile("or %0,epsw" : : "i"(EPSW_IE)); @@ -294,8 +353,8 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code) opcode = byte; noc = 8; - for (pop = mn10300_opcodes; pop->name; pop++) { - npop = log2(pop->opcode | pop->opmask); + for (pop = mn10300_opcodes; pop->name[0]; pop++) { + npop = ilog2(pop->opcode | pop->opmask); if (npop <= 0 || npop > 31) continue; npop = (npop + 8) & ~7; @@ -328,15 +387,15 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code) } /* didn't manage to find a fixup */ - if (!user_mode(regs)) - printk(KERN_CRIT "MISALIGN: %lx: unsupported instruction %x\n", - regs->pc, opcode); + printk(KERN_CRIT "MISALIGN: %lx: unsupported instruction %x\n", + regs->pc, opcode); failed: set_fs(seg); if (die_if_no_fixup("misalignment error", regs, code)) return; +bus_error: info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRALN; @@ -346,31 +405,27 @@ failed: /* error reading opcodes */ fetch_error: - if (!user_mode(regs)) - printk(KERN_CRIT - "MISALIGN: %p: fault whilst reading instruction data\n", - pc); + printk(KERN_CRIT + "MISALIGN: %p: fault whilst reading instruction data\n", + pc); goto failed; bad_addr_mode: - if (!user_mode(regs)) - printk(KERN_CRIT - "MISALIGN: %lx: unsupported addressing mode %x\n", - regs->pc, opcode); + printk(KERN_CRIT + "MISALIGN: %lx: unsupported addressing mode %x\n", + regs->pc, opcode); goto failed; bad_reg_mode: - if (!user_mode(regs)) - printk(KERN_CRIT - "MISALIGN: %lx: unsupported register mode %x\n", - regs->pc, opcode); + printk(KERN_CRIT + "MISALIGN: %lx: unsupported register mode %x\n", + regs->pc, opcode); goto failed; unsupported_instruction: - if (!user_mode(regs)) - printk(KERN_CRIT - "MISALIGN: %lx: unsupported instruction %x (%s)\n", - regs->pc, opcode, pop->name); + printk(KERN_CRIT + "MISALIGN: %lx: unsupported instruction %x (%s)\n", + regs->pc, opcode, pop->name); goto failed; transfer_failed: @@ -391,7 +446,7 @@ transfer_failed: /* we matched the opcode */ found_opcode: - kdebug("MISALIGN: %lx: %x==%x { %x, %x }\n", + kdebug("%lx: %x==%x { %x, %x }", regs->pc, opcode, pop->opcode, pop->params[0], pop->params[1]); tmp = format_tbl[pop->format].opsz; @@ -406,106 +461,108 @@ found_opcode: /* grab the extra displacement (note it's LSB first) */ disp = 0; - tmp = format_tbl[pop->format].dispsz >> 3; - while (tmp > 0) { - tmp--; - disp <<= 8; - + dispsz = format_tbl[pop->format].dispsz; + for (loop = 0; loop < dispsz; loop += 8) { pc++; if (__get_user(byte, pc) != 0) goto fetch_error; - disp |= byte; + disp |= byte << loop; + kdebug("{%p} disp[%02x]=%02x", pc, loop, byte); } + kdebug("disp=%lx", disp); + set_fs(KERNEL_XDS); - if (fixup || regs->epsw & EPSW_nSL) + if (fixup) set_fs(seg); tmp = (pop->params[0] ^ pop->params[1]) & 0x80000000; if (!tmp) { - if (!user_mode(regs)) - printk(KERN_CRIT - "MISALIGN: %lx:" - " insn not move to/from memory %x\n", - regs->pc, opcode); + printk(KERN_CRIT + "MISALIGN: %lx: insn not move to/from memory %x\n", + regs->pc, opcode); goto failed; } + /* determine the data transfer size of the move */ + if (pop->name[3] == 0 || /* "mov" */ + pop->name[4] == 'l') /* mov_lcc */ + inc = datasz = 4; + else if (pop->name[3] == 'h') /* movhu */ + inc = datasz = 2; + else + goto unsupported_instruction; + if (pop->params[0] & 0x80000000) { /* move memory to register */ - if (!misalignment_addr(registers, pop->params[0], opcode, disp, - &address, &postinc)) + if (!misalignment_addr(registers, sp, + pop->params[0], opcode, disp, + &address, &postinc, &inc)) goto bad_addr_mode; if (!misalignment_reg(registers, pop->params[1], opcode, disp, &store)) goto bad_reg_mode; - if (strcmp(pop->name, "mov") == 0) { - kdebug("FIXUP: mov (%p),DARn\n", address); - if (copy_from_user(&data, (void *) address, 4) != 0) - goto transfer_failed; - if (pop->params[0] & 0x1000000) - *postinc += 4; - } else if (strcmp(pop->name, "movhu") == 0) { - kdebug("FIXUP: movhu (%p),DARn\n", address); - data = 0; - if (copy_from_user(&data, (void *) address, 2) != 0) - goto transfer_failed; - if (pop->params[0] & 0x1000000) - *postinc += 2; - } else { - goto unsupported_instruction; + kdebug("mov%u (%p),DARn", datasz, address); + if (copy_from_user(&data, (void *) address, datasz) != 0) + goto transfer_failed; + if (pop->params[0] & 0x1000000) { + kdebug("inc=%lx", inc); + *postinc += inc; } *store = data; + kdebug("loaded %lx", data); } else { /* move register to memory */ if (!misalignment_reg(registers, pop->params[0], opcode, disp, &store)) goto bad_reg_mode; - if (!misalignment_addr(registers, pop->params[1], opcode, disp, - &address, &postinc)) + if (!misalignment_addr(registers, sp, + pop->params[1], opcode, disp, + &address, &postinc, &inc)) goto bad_addr_mode; data = *store; - if (strcmp(pop->name, "mov") == 0) { - kdebug("FIXUP: mov %lx,(%p)\n", data, address); - if (copy_to_user((void *) address, &data, 4) != 0) - goto transfer_failed; - if (pop->params[1] & 0x1000000) - *postinc += 4; - } else if (strcmp(pop->name, "movhu") == 0) { - kdebug("FIXUP: movhu %hx,(%p)\n", - (uint16_t) data, address); - if (copy_to_user((void *) address, &data, 2) != 0) - goto transfer_failed; - if (pop->params[1] & 0x1000000) - *postinc += 2; - } else { - goto unsupported_instruction; - } + kdebug("mov%u %lx,(%p)", datasz, data, address); + if (copy_to_user((void *) address, &data, datasz) != 0) + goto transfer_failed; + if (pop->params[1] & 0x1000000) + *postinc += inc; } tmp = format_tbl[pop->format].opsz + format_tbl[pop->format].dispsz; regs->pc += tmp >> 3; + /* handle MOV_Lcc, which are currently the only FMT_D10 insns that + * access memory */ + if (pop->format == FMT_D10) + misalignment_MOV_Lcc(regs, opcode); + set_fs(seg); - return; } /* * determine the address that was being accessed */ -static int misalignment_addr(unsigned long *registers, unsigned params, - unsigned opcode, unsigned disp, - void **_address, unsigned long **_postinc) +static int misalignment_addr(unsigned long *registers, unsigned long sp, + unsigned params, unsigned opcode, + unsigned long disp, + void **_address, unsigned long **_postinc, + unsigned long *_inc) { unsigned long *postinc = NULL, address = 0, tmp; - params &= 0x7fffffff; + if (!(params & 0x1000000)) { + kdebug("noinc"); + *_inc = 0; + _inc = NULL; + } + + params &= 0x00ffffff; do { switch (params & 0xff) { @@ -514,11 +571,11 @@ static int misalignment_addr(unsigned long *registers, unsigned params, address += *postinc; break; case DM1: - postinc = ®isters[Dreg_index[opcode >> 2 & 0x0c]]; + postinc = ®isters[Dreg_index[opcode >> 2 & 0x03]]; address += *postinc; break; case DM2: - postinc = ®isters[Dreg_index[opcode >> 4 & 0x30]]; + postinc = ®isters[Dreg_index[opcode >> 4 & 0x03]]; address += *postinc; break; case AM0: @@ -526,11 +583,11 @@ static int misalignment_addr(unsigned long *registers, unsigned params, address += *postinc; break; case AM1: - postinc = ®isters[Areg_index[opcode >> 2 & 0x0c]]; + postinc = ®isters[Areg_index[opcode >> 2 & 0x03]]; address += *postinc; break; case AM2: - postinc = ®isters[Areg_index[opcode >> 4 & 0x30]]; + postinc = ®isters[Areg_index[opcode >> 4 & 0x03]]; address += *postinc; break; case RM0: @@ -561,33 +618,53 @@ static int misalignment_addr(unsigned long *registers, unsigned params, postinc = ®isters[Rreg_index[disp >> 4 & 0x0f]]; address += *postinc; break; + case SP: + address += sp; + break; + /* displacements are either to be added to the address + * before use, or, in the case of post-inc addressing, + * to be added into the base register after use */ case SD8: case SIMM8: - address += (int32_t) (int8_t) (disp & 0xff); - break; + disp = (long) (int8_t) (disp & 0xff); + goto displace_or_inc; case SD16: - address += (int32_t) (int16_t) (disp & 0xffff); - break; + disp = (long) (int16_t) (disp & 0xffff); + goto displace_or_inc; case SD24: tmp = disp << 8; asm("asr 8,%0" : "=r"(tmp) : "0"(tmp)); - address += tmp; - break; + disp = (long) tmp; + goto displace_or_inc; case SIMM4_2: tmp = opcode >> 4 & 0x0f; tmp <<= 28; asm("asr 28,%0" : "=r"(tmp) : "0"(tmp)); - address += tmp; - break; + disp = (long) tmp; + goto displace_or_inc; + case IMM8: + disp &= 0x000000ff; + goto displace_or_inc; + case IMM16: + disp &= 0x0000ffff; + goto displace_or_inc; case IMM24: - address += disp & 0x00ffffff; - break; + disp &= 0x00ffffff; + goto displace_or_inc; case IMM32: + case IMM32_MEM: case IMM32_HIGH8: - address += disp; + case IMM32_HIGH8_MEM: + displace_or_inc: + kdebug("%s %lx", _inc ? "incr" : "disp", disp); + if (!_inc) + address += disp; + else + *_inc = disp; break; default: + BUG(); return 0; } } while ((params >>= 8)); @@ -601,7 +678,7 @@ static int misalignment_addr(unsigned long *registers, unsigned params, * determine the register that is acting as source/dest */ static int misalignment_reg(unsigned long *registers, unsigned params, - unsigned opcode, unsigned disp, + unsigned opcode, unsigned long disp, unsigned long **_register) { params &= 0x7fffffff; @@ -654,8 +731,239 @@ static int misalignment_reg(unsigned long *registers, unsigned params, break; default: + BUG(); return 0; } return 1; } + +/* + * handle the conditional loop part of the move-and-loop instructions + */ +static void misalignment_MOV_Lcc(struct pt_regs *regs, uint32_t opcode) +{ + unsigned long epsw = regs->epsw; + unsigned long NxorV; + + kdebug("MOV_Lcc %x [flags=%lx]", opcode, epsw & 0xf); + + /* calculate N^V and shift onto the same bit position as Z */ + NxorV = ((epsw >> 3) ^ epsw >> 1) & 1; + + switch (opcode & 0xf) { + case 0x0: /* MOV_LLT: N^V */ + if (NxorV) + goto take_the_loop; + return; + case 0x1: /* MOV_LGT: ~(Z or (N^V))*/ + if (!((epsw & EPSW_FLAG_Z) | NxorV)) + goto take_the_loop; + return; + case 0x2: /* MOV_LGE: ~(N^V) */ + if (!NxorV) + goto take_the_loop; + return; + case 0x3: /* MOV_LLE: Z or (N^V) */ + if ((epsw & EPSW_FLAG_Z) | NxorV) + goto take_the_loop; + return; + + case 0x4: /* MOV_LCS: C */ + if (epsw & EPSW_FLAG_C) + goto take_the_loop; + return; + case 0x5: /* MOV_LHI: ~(C or Z) */ + if (!(epsw & (EPSW_FLAG_C | EPSW_FLAG_Z))) + goto take_the_loop; + return; + case 0x6: /* MOV_LCC: ~C */ + if (!(epsw & EPSW_FLAG_C)) + goto take_the_loop; + return; + case 0x7: /* MOV_LLS: C or Z */ + if (epsw & (EPSW_FLAG_C | EPSW_FLAG_Z)) + goto take_the_loop; + return; + + case 0x8: /* MOV_LEQ: Z */ + if (epsw & EPSW_FLAG_Z) + goto take_the_loop; + return; + case 0x9: /* MOV_LNE: ~Z */ + if (!(epsw & EPSW_FLAG_Z)) + goto take_the_loop; + return; + case 0xa: /* MOV_LRA: always */ + goto take_the_loop; + + default: + BUG(); + } + +take_the_loop: + /* wind the PC back to just after the SETLB insn */ + kdebug("loop LAR=%lx", regs->lar); + regs->pc = regs->lar - 4; +} + +/* + * misalignment handler tests + */ +#ifdef CONFIG_TEST_MISALIGNMENT_HANDLER +static u8 __initdata testbuf[512] __attribute__((aligned(16))) = { + [257] = 0x11, + [258] = 0x22, + [259] = 0x33, + [260] = 0x44, +}; + +#define ASSERTCMP(X, OP, Y) \ +do { \ + if (unlikely(!((X) OP (Y)))) { \ + printk(KERN_ERR "\n"); \ + printk(KERN_ERR "MISALIGN: Assertion failed at line %u\n", \ + __LINE__); \ + printk(KERN_ERR "0x%lx " #OP " 0x%lx is false\n", \ + (unsigned long)(X), (unsigned long)(Y)); \ + BUG(); \ + } \ +} while(0) + +static int __init test_misalignment(void) +{ + register void *r asm("e0"); + register u32 y asm("e1"); + void *p = testbuf, *q; + u32 tmp, tmp2, x; + + printk(KERN_NOTICE "==>test_misalignment() [testbuf=%p]\n", p); + p++; + + printk(KERN_NOTICE "___ MOV (Am),Dn ___\n"); + q = p + 256; + asm volatile("mov (%0),%1" : "+a"(q), "=d"(x)); + ASSERTCMP(q, ==, p + 256); + ASSERTCMP(x, ==, 0x44332211); + + printk(KERN_NOTICE "___ MOV (256,Am),Dn ___\n"); + q = p; + asm volatile("mov (256,%0),%1" : "+a"(q), "=d"(x)); + ASSERTCMP(q, ==, p); + ASSERTCMP(x, ==, 0x44332211); + + printk(KERN_NOTICE "___ MOV (Di,Am),Dn ___\n"); + tmp = 256; + q = p; + asm volatile("mov (%2,%0),%1" : "+a"(q), "=d"(x), "+d"(tmp)); + ASSERTCMP(q, ==, p); + ASSERTCMP(x, ==, 0x44332211); + ASSERTCMP(tmp, ==, 256); + + printk(KERN_NOTICE "___ MOV (256,Rm),Rn ___\n"); + r = p; + asm volatile("mov (256,%0),%1" : "+r"(r), "=r"(y)); + ASSERTCMP(r, ==, p); + ASSERTCMP(y, ==, 0x44332211); + + printk(KERN_NOTICE "___ MOV (Rm+),Rn ___\n"); + r = p + 256; + asm volatile("mov (%0+),%1" : "+r"(r), "=r"(y)); + ASSERTCMP(r, ==, p + 256 + 4); + ASSERTCMP(y, ==, 0x44332211); + + printk(KERN_NOTICE "___ MOV (Rm+,8),Rn ___\n"); + r = p + 256; + asm volatile("mov (%0+,8),%1" : "+r"(r), "=r"(y)); + ASSERTCMP(r, ==, p + 256 + 8); + ASSERTCMP(y, ==, 0x44332211); + + printk(KERN_NOTICE "___ MOV (7,SP),Rn ___\n"); + asm volatile( + "add -16,sp \n" + "mov +0x11,%0 \n" + "movbu %0,(7,sp) \n" + "mov +0x22,%0 \n" + "movbu %0,(8,sp) \n" + "mov +0x33,%0 \n" + "movbu %0,(9,sp) \n" + "mov +0x44,%0 \n" + "movbu %0,(10,sp) \n" + "mov (7,sp),%1 \n" + "add +16,sp \n" + : "+a"(q), "=d"(x)); + ASSERTCMP(x, ==, 0x44332211); + + printk(KERN_NOTICE "___ MOV (259,SP),Rn ___\n"); + asm volatile( + "add -264,sp \n" + "mov +0x11,%0 \n" + "movbu %0,(259,sp) \n" + "mov +0x22,%0 \n" + "movbu %0,(260,sp) \n" + "mov +0x33,%0 \n" + "movbu %0,(261,sp) \n" + "mov +0x55,%0 \n" + "movbu %0,(262,sp) \n" + "mov (259,sp),%1 \n" + "add +264,sp \n" + : "+d"(tmp), "=d"(x)); + ASSERTCMP(x, ==, 0x55332211); + + printk(KERN_NOTICE "___ MOV (260,SP),Rn ___\n"); + asm volatile( + "add -264,sp \n" + "mov +0x11,%0 \n" + "movbu %0,(260,sp) \n" + "mov +0x22,%0 \n" + "movbu %0,(261,sp) \n" + "mov +0x33,%0 \n" + "movbu %0,(262,sp) \n" + "mov +0x55,%0 \n" + "movbu %0,(263,sp) \n" + "mov (260,sp),%1 \n" + "add +264,sp \n" + : "+d"(tmp), "=d"(x)); + ASSERTCMP(x, ==, 0x55332211); + + + printk(KERN_NOTICE "___ MOV_LNE ___\n"); + tmp = 1; + tmp2 = 2; + q = p + 256; + asm volatile( + "setlb \n" + "mov %2,%3 \n" + "mov %1,%2 \n" + "cmp +0,%1 \n" + "mov_lne (%0+,4),%1" + : "+r"(q), "+d"(tmp), "+d"(tmp2), "=d"(x) + : + : "cc"); + ASSERTCMP(q, ==, p + 256 + 12); + ASSERTCMP(x, ==, 0x44332211); + + printk(KERN_NOTICE "___ MOV in SETLB ___\n"); + tmp = 1; + tmp2 = 2; + q = p + 256; + asm volatile( + "setlb \n" + "mov %1,%3 \n" + "mov (%0+),%1 \n" + "cmp +0,%1 \n" + "lne " + : "+a"(q), "+d"(tmp), "+d"(tmp2), "=d"(x) + : + : "cc"); + + ASSERTCMP(q, ==, p + 256 + 8); + ASSERTCMP(x, ==, 0x44332211); + + printk(KERN_NOTICE "<==test_misalignment()\n"); + return 0; +} + +arch_initcall(test_misalignment); + +#endif /* CONFIG_TEST_MISALIGNMENT_HANDLER */ diff --git a/arch/parisc/include/asm/smp.h b/arch/parisc/include/asm/smp.h index 398cdbaf4e5..409e698f436 100644 --- a/arch/parisc/include/asm/smp.h +++ b/arch/parisc/include/asm/smp.h @@ -44,8 +44,6 @@ extern void arch_send_call_function_ipi(cpumask_t mask); #define PROC_CHANGE_PENALTY 15 /* Schedule penalty */ -extern unsigned long cpu_present_mask; - #define raw_smp_processor_id() (current_thread_info()->cpu) #else /* CONFIG_SMP */ diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 90904f9dfc5..927db3668b6 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -183,10 +183,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) * being 64 bit in both cases. */ -static long translate_usr_offset(long offset) +static compat_ulong_t translate_usr_offset(compat_ulong_t offset) { if (offset < 0) - return -1; + return sizeof(struct pt_regs); else if (offset <= 32*4) /* gr[0..31] */ return offset * 2 + 4; else if (offset <= 32*4+32*8) /* gr[0..31] + fr[0..31] */ @@ -194,7 +194,7 @@ static long translate_usr_offset(long offset) else if (offset < sizeof(struct pt_regs)/2 + 32*4) return offset * 2 + 4 - 32*8; else - return -1; + return sizeof(struct pt_regs); } long compat_arch_ptrace(struct task_struct *child, compat_long_t request, @@ -209,7 +209,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, if (addr & (sizeof(compat_uint_t)-1)) break; addr = translate_usr_offset(addr); - if (addr < 0) + if (addr >= sizeof(struct pt_regs)) break; tmp = *(compat_uint_t *) ((char *) task_regs(child) + addr); @@ -236,7 +236,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, if (addr & (sizeof(compat_uint_t)-1)) break; addr = translate_usr_offset(addr); - if (addr < 0) + if (addr >= sizeof(struct pt_regs)) break; if (addr >= PT_FR0 && addr <= PT_FR31 + 4) { /* Special case, fp regs are 64 bits anyway */ diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index ed500ef799b..08844fc24a2 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -61,22 +61,25 @@ STACK_SIZE = 1 << STACK_SHIFT #ifdef CONFIG_TRACE_IRQFLAGS .macro TRACE_IRQS_ON - l %r1,BASED(.Ltrace_irq_on) + basr %r2,%r0 + l %r1,BASED(.Ltrace_irq_on_caller) basr %r14,%r1 .endm .macro TRACE_IRQS_OFF - l %r1,BASED(.Ltrace_irq_off) + basr %r2,%r0 + l %r1,BASED(.Ltrace_irq_off_caller) basr %r14,%r1 .endm .macro TRACE_IRQS_CHECK + basr %r2,%r0 tm SP_PSW(%r15),0x03 # irqs enabled? jz 0f - l %r1,BASED(.Ltrace_irq_on) + l %r1,BASED(.Ltrace_irq_on_caller) basr %r14,%r1 j 1f -0: l %r1,BASED(.Ltrace_irq_off) +0: l %r1,BASED(.Ltrace_irq_off_caller) basr %r14,%r1 1: .endm @@ -1113,9 +1116,12 @@ cleanup_io_leave_insn: .Lschedtail: .long schedule_tail .Lsysc_table: .long sys_call_table #ifdef CONFIG_TRACE_IRQFLAGS -.Ltrace_irq_on: .long trace_hardirqs_on -.Ltrace_irq_off: - .long trace_hardirqs_off +.Ltrace_irq_on_caller: + .long trace_hardirqs_on_caller +.Ltrace_irq_off_caller: + .long trace_hardirqs_off_caller +#endif +#ifdef CONFIG_LOCKDEP .Llockdep_sys_exit: .long lockdep_sys_exit #endif diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index d7ce150453f..41aca06682a 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -61,19 +61,22 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ #ifdef CONFIG_TRACE_IRQFLAGS .macro TRACE_IRQS_ON - brasl %r14,trace_hardirqs_on + basr %r2,%r0 + brasl %r14,trace_hardirqs_on_caller .endm .macro TRACE_IRQS_OFF - brasl %r14,trace_hardirqs_off + basr %r2,%r0 + brasl %r14,trace_hardirqs_off_caller .endm .macro TRACE_IRQS_CHECK + basr %r2,%r0 tm SP_PSW(%r15),0x03 # irqs enabled? jz 0f - brasl %r14,trace_hardirqs_on + brasl %r14,trace_hardirqs_on_caller j 1f -0: brasl %r14,trace_hardirqs_off +0: brasl %r14,trace_hardirqs_off_caller 1: .endm #else diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 3e2c05cb6a8..04f8c67a610 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -136,9 +136,12 @@ static void default_idle(void) return; } trace_hardirqs_on(); + /* Don't trace preempt off for idle. */ + stop_critical_timings(); /* Wait for external, I/O or machine check interrupt. */ __load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_IO | PSW_MASK_EXT); + start_critical_timings(); } void cpu_idle(void) diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 62122bad1e3..400b040df7f 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -604,13 +604,13 @@ setup_memory(void) if (memory_chunk[i].type != CHUNK_READ_WRITE) continue; start_chunk = PFN_DOWN(memory_chunk[i].addr); - end_chunk = start_chunk + PFN_DOWN(memory_chunk[i].size) - 1; + end_chunk = start_chunk + PFN_DOWN(memory_chunk[i].size); end_chunk = min(end_chunk, end_pfn); if (start_chunk >= end_chunk) continue; add_active_range(0, start_chunk, end_chunk); pfn = max(start_chunk, start_pfn); - for (; pfn <= end_chunk; pfn++) + for (; pfn < end_chunk; pfn++) page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY); } diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c index 5fdb799062b..4fe952e557a 100644 --- a/arch/s390/kernel/sys_s390.c +++ b/arch/s390/kernel/sys_s390.c @@ -198,7 +198,7 @@ asmlinkage long s390x_newuname(struct new_utsname __user *name) { int ret = sys_newuname(name); - if (current->personality == PER_LINUX32 && !ret) { + if (personality(current->personality) == PER_LINUX32 && !ret) { ret = copy_to_user(name->machine, "s390\0\0\0\0", 8); if (ret) ret = -EFAULT; } diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 632b13e1005..a947899dcba 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -65,18 +65,21 @@ static int machine_has_topology_irq; static struct timer_list topology_timer; static void set_topology_timer(void); static DECLARE_WORK(topology_work, topology_work_fn); +/* topology_lock protects the core linked list */ +static DEFINE_SPINLOCK(topology_lock); cpumask_t cpu_core_map[NR_CPUS]; cpumask_t cpu_coregroup_map(unsigned int cpu) { struct core_info *core = &core_info; + unsigned long flags; cpumask_t mask; cpus_clear(mask); if (!machine_has_topology) return cpu_present_map; - mutex_lock(&smp_cpu_state_mutex); + spin_lock_irqsave(&topology_lock, flags); while (core) { if (cpu_isset(cpu, core->mask)) { mask = core->mask; @@ -84,7 +87,7 @@ cpumask_t cpu_coregroup_map(unsigned int cpu) } core = core->next; } - mutex_unlock(&smp_cpu_state_mutex); + spin_unlock_irqrestore(&topology_lock, flags); if (cpus_empty(mask)) mask = cpumask_of_cpu(cpu); return mask; @@ -133,7 +136,7 @@ static void tl_to_cores(struct tl_info *info) union tl_entry *tle, *end; struct core_info *core = &core_info; - mutex_lock(&smp_cpu_state_mutex); + spin_lock_irq(&topology_lock); clear_cores(); tle = info->tle; end = (union tl_entry *)((unsigned long)info + info->length); @@ -157,7 +160,7 @@ static void tl_to_cores(struct tl_info *info) } tle = next_tle(tle); } - mutex_unlock(&smp_cpu_state_mutex); + spin_unlock_irq(&topology_lock); } static void topology_update_polarization_simple(void) diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 436c2853957..65eaae34e75 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -293,6 +293,10 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) */ #define xlate_dev_kmem_ptr(p) p +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE +int valid_phys_addr_range(unsigned long addr, size_t size); +int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); + #endif /* __KERNEL__ */ #endif /* __ASM_SH_IO_H */ diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index 52220d70a09..b517ae08b9c 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -148,6 +148,12 @@ extern void paging_init(void); extern void page_table_range_init(unsigned long start, unsigned long end, pgd_t *pgd); +#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_CPU_SH4) && defined(CONFIG_MMU) +extern void kmap_coherent_init(void); +#else +#define kmap_coherent_init() do { } while (0) +#endif + #include <asm-generic/pgtable.h> #endif /* __ASM_SH_PGTABLE_H */ diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index a7412cede53..6d9e6972cfc 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -119,17 +119,17 @@ static struct plat_sci_port sci_platform_data[] = { },{ .mapbase = 0xa4e30000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCI, + .type = PORT_SCIFA, .irqs = { 56, 56, 56, 56 }, },{ .mapbase = 0xa4e40000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCI, + .type = PORT_SCIFA, .irqs = { 88, 88, 88, 88 }, },{ .mapbase = 0xa4e50000, .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCI, + .type = PORT_SCIFA, .irqs = { 109, 109, 109, 109 }, }, { .flags = 0, diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index 6b7d166694e..a952dcf9999 100644 --- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -75,6 +75,7 @@ static struct console bios_console = { #endif static struct uart_port scif_port = { + .type = PORT_SCIF, .mapbase = CONFIG_EARLY_SCIF_CONSOLE_PORT, .membase = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT, }; @@ -84,9 +85,9 @@ static void scif_sercon_putc(int c) while (((sci_in(&scif_port, SCFDR) & EPK_FIFO_BITS) >= EPK_FIFO_SIZE)) ; - sci_out(&scif_port, SCxTDR, c); sci_in(&scif_port, SCxSR); sci_out(&scif_port, SCxSR, 0xf3 & ~(0x20 | 0x40)); + sci_out(&scif_port, SCxTDR, c); while ((sci_in(&scif_port, SCxSR) & 0x40) == 0) ; diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index aaaf90d06b8..3c61ddd4d43 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c @@ -120,7 +120,7 @@ static void tmu_set_mode(enum clock_event_mode mode, { switch (mode) { case CLOCK_EVT_MODE_PERIODIC: - ctrl_outl(ctrl_inl(TMU0_TCNT), TMU0_TCOR); + ctrl_outl(tmu_latest_interval[TMU0], TMU0_TCOR); break; case CLOCK_EVT_MODE_ONESHOT: ctrl_outl(0, TMU0_TCOR); diff --git a/arch/sh/lib/copy_page.S b/arch/sh/lib/copy_page.S index 5d12e657be3..43de7e8e4e1 100644 --- a/arch/sh/lib/copy_page.S +++ b/arch/sh/lib/copy_page.S @@ -80,6 +80,11 @@ ENTRY(copy_page) .section __ex_table, "a"; \ .long 9999b, 6000f ; \ .previous +#define EX_NO_POP(...) \ + 9999: __VA_ARGS__ ; \ + .section __ex_table, "a"; \ + .long 9999b, 6005f ; \ + .previous ENTRY(__copy_user) ! Check if small number of bytes mov #11,r0 @@ -139,9 +144,9 @@ EX( mov.b r1,@r4 ) bt 1f 2: -EX( mov.b @r5+,r0 ) +EX_NO_POP( mov.b @r5+,r0 ) dt r6 -EX( mov.b r0,@r4 ) +EX_NO_POP( mov.b r0,@r4 ) bf/s 2b add #1,r4 @@ -150,7 +155,7 @@ EX( mov.b r0,@r4 ) # Exception handler: .section .fixup, "ax" -6000: +6005: mov.l 8000f,r1 mov r3,r0 jmp @r1 diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32 index 70e0906023c..f066e76da20 100644 --- a/arch/sh/mm/Makefile_32 +++ b/arch/sh/mm/Makefile_32 @@ -2,7 +2,7 @@ # Makefile for the Linux SuperH-specific parts of the memory manager. # -obj-y := init.o extable_32.o consistent.o +obj-y := init.o extable_32.o consistent.o mmap.o ifndef CONFIG_CACHE_OFF cache-$(CONFIG_CPU_SH2) := cache-sh2.o diff --git a/arch/sh/mm/Makefile_64 b/arch/sh/mm/Makefile_64 index 0d92a8a3ac9..9481d0f54ef 100644 --- a/arch/sh/mm/Makefile_64 +++ b/arch/sh/mm/Makefile_64 @@ -2,7 +2,7 @@ # Makefile for the Linux SuperH-specific parts of the memory manager. # -obj-y := init.o consistent.o +obj-y := init.o consistent.o mmap.o mmu-y := tlb-nommu.o pg-nommu.o extable_32.o mmu-$(CONFIG_MMU) := fault_64.o ioremap_64.o tlbflush_64.o tlb-sh5.o \ diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 4abf00031da..6cbef8caeb5 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -137,6 +137,7 @@ void __init page_table_range_init(unsigned long start, unsigned long end, void __init paging_init(void) { unsigned long max_zone_pfns[MAX_NR_ZONES]; + unsigned long vaddr; int nid; /* We don't need to map the kernel through the TLB, as @@ -148,10 +149,15 @@ void __init paging_init(void) * check for a null value. */ set_TTB(swapper_pg_dir); - /* Populate the relevant portions of swapper_pg_dir so that + /* + * Populate the relevant portions of swapper_pg_dir so that * we can use the fixmap entries without calling kmalloc. - * pte's will be filled in by __set_fixmap(). */ - page_table_range_init(FIXADDR_START, FIXADDR_TOP, swapper_pg_dir); + * pte's will be filled in by __set_fixmap(). + */ + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; + page_table_range_init(vaddr, 0, swapper_pg_dir); + + kmap_coherent_init(); memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c new file mode 100644 index 00000000000..8837d511710 --- /dev/null +++ b/arch/sh/mm/mmap.c @@ -0,0 +1,31 @@ +/* + * arch/sh/mm/mmap.c + * + * Copyright (C) 2008 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/io.h> +#include <linux/mm.h> +#include <asm/page.h> + +/* + * You really shouldn't be using read() or write() on /dev/mem. This + * might go away in the future. + */ +int valid_phys_addr_range(unsigned long addr, size_t count) +{ + if (addr < __MEMORY_START) + return 0; + if (addr + count > __pa(high_memory)) + return 0; + + return 1; +} + +int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) +{ + return 1; +} diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c index 38870e0fc18..2fe14da1f83 100644 --- a/arch/sh/mm/pg-sh4.c +++ b/arch/sh/mm/pg-sh4.c @@ -7,6 +7,7 @@ * Released under the terms of the GNU GPL v2.0. */ #include <linux/mm.h> +#include <linux/init.h> #include <linux/mutex.h> #include <linux/fs.h> #include <linux/highmem.h> @@ -16,6 +17,20 @@ #define CACHE_ALIAS (current_cpu_data.dcache.alias_mask) +#define kmap_get_fixmap_pte(vaddr) \ + pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) + +static pte_t *kmap_coherent_pte; + +void __init kmap_coherent_init(void) +{ + unsigned long vaddr; + + /* cache the first coherent kmap pte */ + vaddr = __fix_to_virt(FIX_CMAP_BEGIN); + kmap_coherent_pte = kmap_get_fixmap_pte(vaddr); +} + static inline void *kmap_coherent(struct page *page, unsigned long addr) { enum fixed_addresses idx; @@ -34,6 +49,8 @@ static inline void *kmap_coherent(struct page *page, unsigned long addr) update_mmu_cache(NULL, vaddr, pte); + set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte); + return (void *)vaddr; } diff --git a/arch/sparc/include/asm/termbits.h b/arch/sparc/include/asm/termbits.h index d6ca3e2754f..d72dfed1f9d 100644 --- a/arch/sparc/include/asm/termbits.h +++ b/arch/sparc/include/asm/termbits.h @@ -29,10 +29,11 @@ struct termios { tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */ cc_t c_line; /* line discipline */ +#ifndef __KERNEL__ cc_t c_cc[NCCS]; /* control characters */ -#ifdef __KERNEL__ +#else + cc_t c_cc[NCCS+2]; /* kernel needs 2 more to hold vmin/vtime */ #define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t)) - cc_t _x_cc[2]; /* We need them to hold vmin/vtime */ #endif }; @@ -42,8 +43,7 @@ struct termios2 { tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */ cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ - cc_t _x_cc[2]; /* padding to match ktermios */ + cc_t c_cc[NCCS+2]; /* control characters */ speed_t c_ispeed; /* input speed */ speed_t c_ospeed; /* output speed */ }; @@ -54,8 +54,7 @@ struct ktermios { tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */ cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ - cc_t _x_cc[2]; /* We need them to hold vmin/vtime */ + cc_t c_cc[NCCS+2]; /* control characters */ speed_t c_ispeed; /* input speed */ speed_t c_ospeed; /* output speed */ }; diff --git a/arch/sparc/include/asm/unistd_32.h b/arch/sparc/include/asm/unistd_32.h index 648643a9f13..0d13d2a4c76 100644 --- a/arch/sparc/include/asm/unistd_32.h +++ b/arch/sparc/include/asm/unistd_32.h @@ -338,8 +338,9 @@ #define __NR_dup3 320 #define __NR_pipe2 321 #define __NR_inotify_init1 322 +#define __NR_accept4 323 -#define NR_SYSCALLS 323 +#define NR_SYSCALLS 324 /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, * it never had the plain ones and there is no value to adding those diff --git a/arch/sparc/include/asm/unistd_64.h b/arch/sparc/include/asm/unistd_64.h index c5cc0e05232..fa5d3c0343c 100644 --- a/arch/sparc/include/asm/unistd_64.h +++ b/arch/sparc/include/asm/unistd_64.h @@ -340,8 +340,9 @@ #define __NR_dup3 320 #define __NR_pipe2 321 #define __NR_inotify_init1 322 +#define __NR_accept4 323 -#define NR_SYSCALLS 323 +#define NR_SYSCALLS 324 #ifdef __KERNEL__ #define __ARCH_WANT_IPC_PARSE_VERSION diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index 0837bd52e28..0a83bd73765 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c @@ -563,9 +563,9 @@ build_resources: op->dev.parent = parent; op->dev.bus = &of_platform_bus_type; if (!parent) - strcpy(op->dev.bus_id, "root"); + dev_set_name(&op->dev, "root"); else - sprintf(op->dev.bus_id, "%08x", dp->node); + dev_set_name(&op->dev, "%08x", dp->node); if (of_device_register(op)) { printk("%s: Could not register of device.\n", diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index e1b9233b90a..7d080758644 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -81,4 +81,4 @@ sys_call_table: /*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait /*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate /*315*/ .long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 -/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1 +/*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4 diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S index ade18ba0c68..f061c4dda9e 100644 --- a/arch/sparc64/kernel/sys32.S +++ b/arch/sparc64/kernel/sys32.S @@ -150,7 +150,7 @@ sys32_mmap2: sys32_socketcall: /* %o0=call, %o1=args */ cmp %o0, 1 bl,pn %xcc, do_einval - cmp %o0, 17 + cmp %o0, 18 bg,pn %xcc, do_einval sub %o0, 1, %o0 sllx %o0, 5, %o0 @@ -319,6 +319,15 @@ do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) nop nop nop +do_sys_accept4: /* sys_accept4(int, struct sockaddr *, int *, int) */ +63: ldswa [%o1 + 0x0] %asi, %o0 + sethi %hi(sys_accept4), %g1 +64: lduwa [%o1 + 0x8] %asi, %o2 +65: ldswa [%o1 + 0xc] %asi, %o3 + jmpl %g1 + %lo(sys_accept4), %g0 +66: lduwa [%o1 + 0x4] %asi, %o1 + nop + nop .section __ex_table,"a" .align 4 @@ -353,4 +362,6 @@ do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) .word 57b, __retl_efault, 58b, __retl_efault .word 59b, __retl_efault, 60b, __retl_efault .word 61b, __retl_efault, 62b, __retl_efault + .word 63b, __retl_efault, 64b, __retl_efault + .word 65b, __retl_efault, 66b, __retl_efault .previous diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index b2fa4c16363..9fc78cf354b 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -82,7 +82,7 @@ sys_call_table32: .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait /*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate .word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1 -/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1 +/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4 #endif /* CONFIG_COMPAT */ @@ -156,4 +156,4 @@ sys_call_table: .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate .word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1 -/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1 +/*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4 diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 93224b56918..ac22bb7719f 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -167,9 +167,12 @@ config GENERIC_PENDING_IRQ config X86_SMP bool depends on SMP && ((X86_32 && !X86_VOYAGER) || X86_64) - select USE_GENERIC_SMP_HELPERS default y +config USE_GENERIC_SMP_HELPERS + def_bool y + depends on SMP + config X86_32_SMP def_bool y depends on X86_32 && SMP @@ -957,7 +960,7 @@ config ARCH_PHYS_ADDR_T_64BIT config NUMA bool "Numa Memory Allocation and Scheduler Support (EXPERIMENTAL)" depends on SMP - depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || X86_BIGSMP || X86_SUMMIT && ACPI) && BROKEN) + depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || X86_BIGSMP || X86_SUMMIT && ACPI) && EXPERIMENTAL) default n if X86_PC default y if (X86_NUMAQ || X86_SUMMIT || X86_BIGSMP) help diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 8d676d8ecde..9830681446a 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -113,7 +113,6 @@ static inline void acpi_disable_pci(void) acpi_pci_disabled = 1; acpi_noirq_set(); } -extern int acpi_irq_balance_set(char *str); /* routines for saving/restoring kernel state */ extern int acpi_save_state_mem(void); diff --git a/arch/x86/include/asm/iomap.h b/arch/x86/include/asm/iomap.h new file mode 100644 index 00000000000..c1f06289b14 --- /dev/null +++ b/arch/x86/include/asm/iomap.h @@ -0,0 +1,30 @@ +/* + * Copyright © 2008 Ingo Molnar + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/uaccess.h> +#include <asm/cacheflush.h> +#include <asm/pgtable.h> +#include <asm/tlbflush.h> + +void * +iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); + +void +iounmap_atomic(void *kvaddr, enum km_type type); diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h index e4a552d4446..0b500c5b644 100644 --- a/arch/x86/include/asm/iommu.h +++ b/arch/x86/include/asm/iommu.h @@ -6,7 +6,6 @@ extern void no_iommu_init(void); extern struct dma_mapping_ops nommu_dma_ops; extern int force_iommu, no_iommu; extern int iommu_detected; -extern int dmar_disabled; extern unsigned long iommu_nr_pages(unsigned long addr, unsigned long len); diff --git a/arch/x86/include/asm/mmzone_32.h b/arch/x86/include/asm/mmzone_32.h index 485bdf059ff..07f1af494ca 100644 --- a/arch/x86/include/asm/mmzone_32.h +++ b/arch/x86/include/asm/mmzone_32.h @@ -34,10 +34,14 @@ static inline void get_memcfg_numa(void) extern int early_pfn_to_nid(unsigned long pfn); +extern void resume_map_numa_kva(pgd_t *pgd); + #else /* !CONFIG_NUMA */ #define get_memcfg_numa get_memcfg_numa_flat +static inline void resume_map_numa_kva(pgd_t *pgd) {} + #endif /* CONFIG_NUMA */ #ifdef CONFIG_DISCONTIGMEM diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 543ba883cc6..84210c479fc 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -48,7 +48,7 @@ int __copy_from_user(void *dst, const void __user *src, unsigned size) return ret; case 10: __get_user_asm(*(u64 *)dst, (u64 __user *)src, - ret, "q", "", "=r", 16); + ret, "q", "", "=r", 10); if (unlikely(ret)) return ret; __get_user_asm(*(u16 *)(8 + (char *)dst), diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h index 834b2c1d89f..d2e415e6666 100644 --- a/arch/x86/include/asm/unistd_64.h +++ b/arch/x86/include/asm/unistd_64.h @@ -639,8 +639,8 @@ __SYSCALL(__NR_fallocate, sys_fallocate) __SYSCALL(__NR_timerfd_settime, sys_timerfd_settime) #define __NR_timerfd_gettime 287 __SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime) -#define __NR_paccept 288 -__SYSCALL(__NR_paccept, sys_paccept) +#define __NR_accept4 288 +__SYSCALL(__NR_accept4, sys_accept4) #define __NR_signalfd4 289 __SYSCALL(__NR_signalfd4, sys_signalfd4) #define __NR_eventfd2 290 diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 8c1f76abae9..4c51a2f8fd3 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1343,7 +1343,6 @@ static void __init acpi_process_madt(void) error = acpi_parse_madt_ioapic_entries(); if (!error) { acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; - acpi_irq_balance_set(NULL); acpi_ioapic = 1; smp_found_config = 1; diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index 331b318304e..e4899e0e878 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -537,7 +537,7 @@ static void dma_ops_free_addresses(struct dma_ops_domain *dom, address >>= PAGE_SHIFT; iommu_area_free(dom->bitmap, address, pages); - if (address + pages >= dom->next_bit) + if (address >= dom->next_bit) dom->need_flush = true; } diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 0cdcda35a05..30ae2701b3d 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c @@ -121,7 +121,7 @@ u16 amd_iommu_last_bdf; /* largest PCI device id we have LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings we find in ACPI */ unsigned amd_iommu_aperture_order = 26; /* size of aperture in power of 2 */ -int amd_iommu_isolate; /* if 1, device isolation is enabled */ +int amd_iommu_isolate = 1; /* if 1, device isolation is enabled */ bool amd_iommu_unmap_flush; /* if true, flush on every unmap */ LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the @@ -1213,7 +1213,9 @@ static int __init parse_amd_iommu_options(char *str) for (; *str; ++str) { if (strncmp(str, "isolate", 7) == 0) amd_iommu_isolate = 1; - if (strncmp(str, "fullflush", 11) == 0) + if (strncmp(str, "share", 5) == 0) + amd_iommu_isolate = 0; + if (strncmp(str, "fullflush", 9) == 0) amd_iommu_unmap_flush = true; } diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c index 2b69994fd3a..d1a121443bd 100644 --- a/arch/x86/kernel/ds.c +++ b/arch/x86/kernel/ds.c @@ -236,17 +236,33 @@ static inline struct ds_context *ds_alloc_context(struct task_struct *task) struct ds_context *context = *p_context; if (!context) { + spin_unlock(&ds_lock); + context = kzalloc(sizeof(*context), GFP_KERNEL); - if (!context) + if (!context) { + spin_lock(&ds_lock); return NULL; + } context->ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL); if (!context->ds) { kfree(context); + spin_lock(&ds_lock); return NULL; } + spin_lock(&ds_lock); + /* + * Check for race - another CPU could have allocated + * it meanwhile: + */ + if (*p_context) { + kfree(context->ds); + kfree(context); + return *p_context; + } + *p_context = context; context->this = p_context; @@ -384,14 +400,15 @@ static int ds_request(struct task_struct *task, void *base, size_t size, spin_lock(&ds_lock); - if (!check_tracer(task)) - return -EPERM; - error = -ENOMEM; context = ds_alloc_context(task); if (!context) goto out_unlock; + error = -EPERM; + if (!check_tracer(task)) + goto out_unlock; + error = -EALREADY; if (context->owner[qual] == current) goto out_unlock; diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 3ce029ffaa5..1b894b72c0f 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -188,20 +188,6 @@ static void __init ati_bugs_contd(int num, int slot, int func) } #endif -#ifdef CONFIG_DMAR -static void __init intel_g33_dmar(int num, int slot, int func) -{ - struct acpi_table_header *dmar_tbl; - acpi_status status; - - status = acpi_get_table(ACPI_SIG_DMAR, 0, &dmar_tbl); - if (ACPI_SUCCESS(status)) { - printk(KERN_INFO "BIOS BUG: DMAR advertised on Intel G31/G33 chipset -- ignoring\n"); - dmar_disabled = 1; - } -} -#endif - #define QFLAG_APPLY_ONCE 0x1 #define QFLAG_APPLIED 0x2 #define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED) @@ -225,10 +211,6 @@ static struct chipset early_qrk[] __initdata = { PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs }, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd }, -#ifdef CONFIG_DMAR - { PCI_VENDOR_ID_INTEL, 0x29c0, - PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, intel_g33_dmar }, -#endif {} }; diff --git a/arch/x86/kernel/es7000_32.c b/arch/x86/kernel/es7000_32.c index f454c78fcef..0aa2c443d60 100644 --- a/arch/x86/kernel/es7000_32.c +++ b/arch/x86/kernel/es7000_32.c @@ -250,31 +250,24 @@ int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) { struct acpi_table_header *header = NULL; int i = 0; - acpi_size tbl_size; - while (ACPI_SUCCESS(acpi_get_table_with_size("OEM1", i++, &header, &tbl_size))) { + while (ACPI_SUCCESS(acpi_get_table("OEM1", i++, &header))) { if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) { struct oem_table *t = (struct oem_table *)header; oem_addrX = t->OEMTableAddr; oem_size = t->OEMTableSize; - early_acpi_os_unmap_memory(header, tbl_size); *oem_addr = (unsigned long)__acpi_map_table(oem_addrX, oem_size); return 0; } - early_acpi_os_unmap_memory(header, tbl_size); } return -1; } void __init unmap_unisys_acpi_oem_table(unsigned long oem_addr) { - if (!oem_addr) - return; - - __acpi_unmap_table((char *)oem_addr, oem_size); } #endif diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c index 7a3f2028e2e..c9513e1ff28 100644 --- a/arch/x86/kernel/io_apic.c +++ b/arch/x86/kernel/io_apic.c @@ -1140,6 +1140,20 @@ static void __clear_irq_vector(int irq) cfg->vector = 0; cpus_clear(cfg->domain); + + if (likely(!cfg->move_in_progress)) + return; + cpus_and(mask, cfg->old_domain, cpu_online_map); + for_each_cpu_mask_nr(cpu, mask) { + for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; + vector++) { + if (per_cpu(vector_irq, cpu)[vector] != irq) + continue; + per_cpu(vector_irq, cpu)[vector] = -1; + break; + } + } + cfg->move_in_progress = 0; } void __setup_vector_irq(int cpu) diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 774ac499156..1c9cc431ea4 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -128,7 +128,7 @@ static int kvm_register_clock(char *txt) } #ifdef CONFIG_X86_LOCAL_APIC -static void kvm_setup_secondary_clock(void) +static void __devinit kvm_setup_secondary_clock(void) { /* * Now that the first cpu already had this clocksource initialized, diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 724adfc63cb..cc5a2545dd4 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -169,6 +169,15 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "0KW626"), }, }, + { /* Handle problems with rebooting on Dell Optiplex 330 with 0KP561 */ + .callback = set_bios_reboot, + .ident = "Dell OptiPlex 330", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 330"), + DMI_MATCH(DMI_BOARD_NAME, "0KP561"), + }, + }, { /* Handle problems with rebooting on Dell 2400's */ .callback = set_bios_reboot, .ident = "Dell PowerEdge 2400", diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 0fa6790c1dd..9d5674f7b6c 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -764,7 +764,7 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = { .callback = dmi_low_memory_corruption, .ident = "Phoenix BIOS", .matches = { - DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"), + DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies"), }, }, #endif diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c index 9ffb01c31c4..1c0dfbca87c 100644 --- a/arch/x86/kernel/tsc_sync.c +++ b/arch/x86/kernel/tsc_sync.c @@ -46,7 +46,9 @@ static __cpuinit void check_tsc_warp(void) cycles_t start, now, prev, end; int i; + rdtsc_barrier(); start = get_cycles(); + rdtsc_barrier(); /* * The measurement runs for 20 msecs: */ @@ -61,7 +63,9 @@ static __cpuinit void check_tsc_warp(void) */ __raw_spin_lock(&sync_lock); prev = last_tsc; + rdtsc_barrier(); now = get_cycles(); + rdtsc_barrier(); last_tsc = now; __raw_spin_unlock(&sync_lock); diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index ce3251ce550..b81125f0bde 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -20,6 +20,8 @@ if VIRTUALIZATION config KVM tristate "Kernel-based Virtual Machine (KVM) support" depends on HAVE_KVM + # for device assignment: + depends on PCI select PREEMPT_NOTIFIERS select MMU_NOTIFIER select ANON_INODES diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 8772dc94682..59ebd37ad79 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -548,8 +548,10 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm) mutex_lock(&kvm->lock); pit->irq_source_id = kvm_request_irq_source_id(kvm); mutex_unlock(&kvm->lock); - if (pit->irq_source_id < 0) + if (pit->irq_source_id < 0) { + kfree(pit); return NULL; + } mutex_init(&pit->pit_state.lock); mutex_lock(&pit->pit_state.lock); diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 2a5e64881d9..f1983d9477c 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -314,7 +314,7 @@ static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu) if (r) goto out; r = mmu_topup_memory_cache(&vcpu->arch.mmu_rmap_desc_cache, - rmap_desc_cache, 1); + rmap_desc_cache, 4); if (r) goto out; r = mmu_topup_memory_cache_page(&vcpu->arch.mmu_page_cache, 8); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 2643b430d83..d06b4dc0e2e 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3564,7 +3564,8 @@ static int __init vmx_init(void) bypass_guest_pf = 0; kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK | VMX_EPT_WRITABLE_MASK | - VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT); + VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT | + VMX_EPT_IGMT_BIT); kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull, VMX_EPT_EXECUTABLE_MASK); kvm_enable_tdp(); diff --git a/arch/x86/kvm/vmx.h b/arch/x86/kvm/vmx.h index 3e010d21fdd..ec5edc339da 100644 --- a/arch/x86/kvm/vmx.h +++ b/arch/x86/kvm/vmx.h @@ -352,6 +352,7 @@ enum vmcs_field { #define VMX_EPT_READABLE_MASK 0x1ull #define VMX_EPT_WRITABLE_MASK 0x2ull #define VMX_EPT_EXECUTABLE_MASK 0x4ull +#define VMX_EPT_IGMT_BIT (1ull << 6) #define VMX_EPT_IDENTITY_PAGETABLE_ADDR 0xfffbc000ul diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c index 0e331652681..52145007bd7 100644 --- a/arch/x86/mach-voyager/voyager_smp.c +++ b/arch/x86/mach-voyager/voyager_smp.c @@ -7,6 +7,7 @@ * This file provides all the same external entries as smp.c but uses * the voyager hal to provide the functionality */ +#include <linux/cpu.h> #include <linux/module.h> #include <linux/mm.h> #include <linux/kernel_stat.h> @@ -1790,6 +1791,17 @@ void __init smp_setup_processor_id(void) x86_write_percpu(cpu_number, hard_smp_processor_id()); } +static void voyager_send_call_func(cpumask_t callmask) +{ + __u32 mask = cpus_addr(callmask)[0] & ~(1 << smp_processor_id()); + send_CPI(mask, VIC_CALL_FUNCTION_CPI); +} + +static void voyager_send_call_func_single(int cpu) +{ + send_CPI(1 << cpu, VIC_CALL_FUNCTION_SINGLE_CPI); +} + struct smp_ops smp_ops = { .smp_prepare_boot_cpu = voyager_smp_prepare_boot_cpu, .smp_prepare_cpus = voyager_smp_prepare_cpus, @@ -1799,6 +1811,6 @@ struct smp_ops smp_ops = { .smp_send_stop = voyager_smp_send_stop, .smp_send_reschedule = voyager_smp_send_reschedule, - .send_call_func_ipi = native_send_call_func_ipi, - .send_call_func_single_ipi = native_send_call_func_single_ipi, + .send_call_func_ipi = voyager_send_call_func, + .send_call_func_single_ipi = voyager_send_call_func_single, }; diff --git a/arch/x86/mm/numa_32.c b/arch/x86/mm/numa_32.c index 847c164725f..8518c678d83 100644 --- a/arch/x86/mm/numa_32.c +++ b/arch/x86/mm/numa_32.c @@ -222,6 +222,41 @@ static void __init remap_numa_kva(void) } } +#ifdef CONFIG_HIBERNATION +/** + * resume_map_numa_kva - add KVA mapping to the temporary page tables created + * during resume from hibernation + * @pgd_base - temporary resume page directory + */ +void resume_map_numa_kva(pgd_t *pgd_base) +{ + int node; + + for_each_online_node(node) { + unsigned long start_va, start_pfn, size, pfn; + + start_va = (unsigned long)node_remap_start_vaddr[node]; + start_pfn = node_remap_start_pfn[node]; + size = node_remap_size[node]; + + printk(KERN_DEBUG "%s: node %d\n", __FUNCTION__, node); + + for (pfn = 0; pfn < size; pfn += PTRS_PER_PTE) { + unsigned long vaddr = start_va + (pfn << PAGE_SHIFT); + pgd_t *pgd = pgd_base + pgd_index(vaddr); + pud_t *pud = pud_offset(pgd, vaddr); + pmd_t *pmd = pmd_offset(pud, vaddr); + + set_pmd(pmd, pfn_pmd(start_pfn + pfn, + PAGE_KERNEL_LARGE_EXEC)); + + printk(KERN_DEBUG "%s: %08lx -> pfn %08lx\n", + __FUNCTION__, vaddr, start_pfn + pfn); + } + } +} +#endif + static unsigned long calculate_numa_remap_pages(void) { int nid; diff --git a/arch/x86/power/hibernate_32.c b/arch/x86/power/hibernate_32.c index f2b6e3f11bf..81197c62d5b 100644 --- a/arch/x86/power/hibernate_32.c +++ b/arch/x86/power/hibernate_32.c @@ -12,6 +12,7 @@ #include <asm/system.h> #include <asm/page.h> #include <asm/pgtable.h> +#include <asm/mmzone.h> /* Defined in hibernate_asm_32.S */ extern int restore_image(void); @@ -127,6 +128,9 @@ static int resume_physical_mapping_init(pgd_t *pgd_base) } } } + + resume_map_numa_kva(pgd_base); + return 0; } |