diff options
| author | David Woodhouse <dwmw2@infradead.org> | 2006-05-06 14:59:18 -0400 |
|---|---|---|
| committer | David Woodhouse <dwmw2@infradead.org> | 2006-05-06 14:59:18 -0400 |
| commit | 5047f09b56d0bc3c21aec9cb16de60283da645c6 (patch) | |
| tree | 09a07554b933c3bb912ce3bfc0ea7c7e1f16041c | |
| parent | c0f1fe00c3923135b2c2f443448585482da8a53e (diff) | |
| parent | 5528e568a760442e0ec8fd2dea1f0791875a066b (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
211 files changed, 3293 insertions, 1441 deletions
| @@ -1194,15 +1194,9 @@ S: Brecksville, OH 44141-1334 | |||
| 1194 | S: USA | 1194 | S: USA |
| 1195 | 1195 | ||
| 1196 | N: Tristan Greaves | 1196 | N: Tristan Greaves |
| 1197 | E: Tristan.Greaves@icl.com | 1197 | E: tristan@extricate.org |
| 1198 | E: tmg296@ecs.soton.ac.uk | 1198 | W: http://www.extricate.org/ |
| 1199 | W: http://www.ecs.soton.ac.uk/~tmg296 | ||
| 1200 | D: Miscellaneous ipv4 sysctl patches | 1199 | D: Miscellaneous ipv4 sysctl patches |
| 1201 | S: 15 Little Mead | ||
| 1202 | S: Denmead | ||
| 1203 | S: Hampshire | ||
| 1204 | S: PO7 6HS | ||
| 1205 | S: United Kingdom | ||
| 1206 | 1200 | ||
| 1207 | N: Michael A. Griffith | 1201 | N: Michael A. Griffith |
| 1208 | E: grif@cs.ucr.edu | 1202 | E: grif@cs.ucr.edu |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1dbf6ddb300d..08b7cc900cae 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -150,8 +150,6 @@ config ARCH_IOP3XX | |||
| 150 | 150 | ||
| 151 | config ARCH_IXP4XX | 151 | config ARCH_IXP4XX |
| 152 | bool "IXP4xx-based" | 152 | bool "IXP4xx-based" |
| 153 | select DMABOUNCE | ||
| 154 | select PCI | ||
| 155 | help | 153 | help |
| 156 | Support for Intel's IXP4XX (XScale) family of processors. | 154 | Support for Intel's IXP4XX (XScale) family of processors. |
| 157 | 155 | ||
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 0af3772efcb7..ace3fb5835d9 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c | |||
| @@ -38,10 +38,10 @@ static void icedcc_putc(int ch) | |||
| 38 | if (--i < 0) | 38 | if (--i < 0) |
| 39 | return; | 39 | return; |
| 40 | 40 | ||
| 41 | asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (status)); | 41 | asm volatile ("mrc p14, 0, %0, c0, c0, 0" : "=r" (status)); |
| 42 | } while (status & 2); | 42 | } while (status & 2); |
| 43 | 43 | ||
| 44 | asm("mcr p15, 0, %0, c1, c0, 0" : : "r" (ch)); | 44 | asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch)); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | #define putc(ch) icedcc_putc(ch) | 47 | #define putc(ch) icedcc_putc(ch) |
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index b324dcac1c56..45fdf4a51a2a 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c | |||
| @@ -95,5 +95,11 @@ int main(void) | |||
| 95 | DEFINE(SYS_ERROR0, 0x9f0000); | 95 | DEFINE(SYS_ERROR0, 0x9f0000); |
| 96 | BLANK(); | 96 | BLANK(); |
| 97 | DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc)); | 97 | DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc)); |
| 98 | DEFINE(MACHINFO_TYPE, offsetof(struct machine_desc, nr)); | ||
| 99 | DEFINE(MACHINFO_NAME, offsetof(struct machine_desc, name)); | ||
| 100 | DEFINE(MACHINFO_PHYSIO, offsetof(struct machine_desc, phys_io)); | ||
| 101 | DEFINE(MACHINFO_PGOFFIO, offsetof(struct machine_desc, io_pg_offst)); | ||
| 102 | DEFINE(PROCINFO_INITFUNC, offsetof(struct proc_info_list, __cpu_flush)); | ||
| 103 | DEFINE(PROCINFO_MMUFLAGS, offsetof(struct proc_info_list, __cpu_mmu_flags)); | ||
| 98 | return 0; | 104 | return 0; |
| 99 | } | 105 | } |
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index 0bea65864051..adf62e5eaad7 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S | |||
| @@ -20,12 +20,10 @@ | |||
| 20 | #include <asm/mach-types.h> | 20 | #include <asm/mach-types.h> |
| 21 | #include <asm/procinfo.h> | 21 | #include <asm/procinfo.h> |
| 22 | #include <asm/ptrace.h> | 22 | #include <asm/ptrace.h> |
| 23 | #include <asm/asm-offsets.h> | ||
| 23 | #include <asm/thread_info.h> | 24 | #include <asm/thread_info.h> |
| 24 | #include <asm/system.h> | 25 | #include <asm/system.h> |
| 25 | 26 | ||
| 26 | #define PROCINFO_INITFUNC 12 | ||
| 27 | #define MACHINFO_TYPE 0 | ||
| 28 | |||
| 29 | /* | 27 | /* |
| 30 | * Kernel startup entry point. | 28 | * Kernel startup entry point. |
| 31 | * --------------------------- | 29 | * --------------------------- |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 04b66a9328ef..04f7344e356a 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
| @@ -24,14 +24,6 @@ | |||
| 24 | #include <asm/thread_info.h> | 24 | #include <asm/thread_info.h> |
| 25 | #include <asm/system.h> | 25 | #include <asm/system.h> |
| 26 | 26 | ||
| 27 | #define PROCINFO_MMUFLAGS 8 | ||
| 28 | #define PROCINFO_INITFUNC 12 | ||
| 29 | |||
| 30 | #define MACHINFO_TYPE 0 | ||
| 31 | #define MACHINFO_PHYSIO 4 | ||
| 32 | #define MACHINFO_PGOFFIO 8 | ||
| 33 | #define MACHINFO_NAME 12 | ||
| 34 | |||
| 35 | #define KERNEL_RAM_ADDR (PAGE_OFFSET + TEXT_OFFSET) | 27 | #define KERNEL_RAM_ADDR (PAGE_OFFSET + TEXT_OFFSET) |
| 36 | 28 | ||
| 37 | /* | 29 | /* |
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c index 9d8331be2b58..12ea58a3b84f 100644 --- a/arch/arm/mach-imx/generic.c +++ b/arch/arm/mach-imx/generic.c | |||
| @@ -195,56 +195,6 @@ void __init imx_set_mmc_info(struct imxmmc_platform_data *info) | |||
| 195 | } | 195 | } |
| 196 | EXPORT_SYMBOL(imx_set_mmc_info); | 196 | EXPORT_SYMBOL(imx_set_mmc_info); |
| 197 | 197 | ||
| 198 | static struct resource imx_uart1_resources[] = { | ||
| 199 | [0] = { | ||
| 200 | .start = 0x00206000, | ||
| 201 | .end = 0x002060FF, | ||
| 202 | .flags = IORESOURCE_MEM, | ||
| 203 | }, | ||
| 204 | [1] = { | ||
| 205 | .start = (UART1_MINT_RX), | ||
| 206 | .end = (UART1_MINT_RX), | ||
| 207 | .flags = IORESOURCE_IRQ, | ||
| 208 | }, | ||
| 209 | [2] = { | ||
| 210 | .start = (UART1_MINT_TX), | ||
| 211 | .end = (UART1_MINT_TX), | ||
| 212 | .flags = IORESOURCE_IRQ, | ||
| 213 | }, | ||
| 214 | }; | ||
| 215 | |||
| 216 | static struct platform_device imx_uart1_device = { | ||
| 217 | .name = "imx-uart", | ||
| 218 | .id = 0, | ||
| 219 | .num_resources = ARRAY_SIZE(imx_uart1_resources), | ||
| 220 | .resource = imx_uart1_resources, | ||
| 221 | }; | ||
| 222 | |||
| 223 | static struct resource imx_uart2_resources[] = { | ||
| 224 | [0] = { | ||
| 225 | .start = 0x00207000, | ||
| 226 | .end = 0x002070FF, | ||
| 227 | .flags = IORESOURCE_MEM, | ||
| 228 | }, | ||
| 229 | [1] = { | ||
| 230 | .start = (UART2_MINT_RX), | ||
| 231 | .end = (UART2_MINT_RX), | ||
| 232 | .flags = IORESOURCE_IRQ, | ||
| 233 | }, | ||
| 234 | [2] = { | ||
| 235 | .start = (UART2_MINT_TX), | ||
| 236 | .end = (UART2_MINT_TX), | ||
| 237 | .flags = IORESOURCE_IRQ, | ||
| 238 | }, | ||
| 239 | }; | ||
| 240 | |||
| 241 | static struct platform_device imx_uart2_device = { | ||
| 242 | .name = "imx-uart", | ||
| 243 | .id = 1, | ||
| 244 | .num_resources = ARRAY_SIZE(imx_uart2_resources), | ||
| 245 | .resource = imx_uart2_resources, | ||
| 246 | }; | ||
| 247 | |||
| 248 | static struct imxfb_mach_info imx_fb_info; | 198 | static struct imxfb_mach_info imx_fb_info; |
| 249 | 199 | ||
| 250 | void __init set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info) | 200 | void __init set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info) |
| @@ -283,8 +233,6 @@ static struct platform_device imxfb_device = { | |||
| 283 | static struct platform_device *devices[] __initdata = { | 233 | static struct platform_device *devices[] __initdata = { |
| 284 | &imx_mmc_device, | 234 | &imx_mmc_device, |
| 285 | &imxfb_device, | 235 | &imxfb_device, |
| 286 | &imx_uart1_device, | ||
| 287 | &imx_uart2_device, | ||
| 288 | }; | 236 | }; |
| 289 | 237 | ||
| 290 | static struct map_desc imx_io_desc[] __initdata = { | 238 | static struct map_desc imx_io_desc[] __initdata = { |
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index e34d0df90aed..e1f6c0bbe1e7 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | #include <asm/mach/arch.h> | 27 | #include <asm/mach/arch.h> |
| 28 | #include <asm/arch/mmc.h> | 28 | #include <asm/arch/mmc.h> |
| 29 | #include <asm/arch/imx-uart.h> | ||
| 29 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
| 30 | #include "generic.h" | 31 | #include "generic.h" |
| 31 | 32 | ||
| @@ -48,8 +49,70 @@ static struct platform_device cs89x0_device = { | |||
| 48 | .resource = cs89x0_resources, | 49 | .resource = cs89x0_resources, |
| 49 | }; | 50 | }; |
| 50 | 51 | ||
| 52 | static struct imxuart_platform_data uart_pdata = { | ||
| 53 | .flags = IMXUART_HAVE_RTSCTS, | ||
| 54 | }; | ||
| 55 | |||
| 56 | static struct resource imx_uart1_resources[] = { | ||
| 57 | [0] = { | ||
| 58 | .start = 0x00206000, | ||
| 59 | .end = 0x002060FF, | ||
| 60 | .flags = IORESOURCE_MEM, | ||
| 61 | }, | ||
| 62 | [1] = { | ||
| 63 | .start = (UART1_MINT_RX), | ||
| 64 | .end = (UART1_MINT_RX), | ||
| 65 | .flags = IORESOURCE_IRQ, | ||
| 66 | }, | ||
| 67 | [2] = { | ||
| 68 | .start = (UART1_MINT_TX), | ||
| 69 | .end = (UART1_MINT_TX), | ||
| 70 | .flags = IORESOURCE_IRQ, | ||
| 71 | }, | ||
| 72 | }; | ||
| 73 | |||
| 74 | static struct platform_device imx_uart1_device = { | ||
| 75 | .name = "imx-uart", | ||
| 76 | .id = 0, | ||
| 77 | .num_resources = ARRAY_SIZE(imx_uart1_resources), | ||
| 78 | .resource = imx_uart1_resources, | ||
| 79 | .dev = { | ||
| 80 | .platform_data = &uart_pdata, | ||
| 81 | } | ||
| 82 | }; | ||
| 83 | |||
| 84 | static struct resource imx_uart2_resources[] = { | ||
| 85 | [0] = { | ||
| 86 | .start = 0x00207000, | ||
| 87 | .end = 0x002070FF, | ||
| 88 | .flags = IORESOURCE_MEM, | ||
| 89 | }, | ||
| 90 | [1] = { | ||
| 91 | .start = (UART2_MINT_RX), | ||
| 92 | .end = (UART2_MINT_RX), | ||
| 93 | .flags = IORESOURCE_IRQ, | ||
| 94 | }, | ||
| 95 | [2] = { | ||
| 96 | .start = (UART2_MINT_TX), | ||
| 97 | .end = (UART2_MINT_TX), | ||
| 98 | .flags = IORESOURCE_IRQ, | ||
| 99 | }, | ||
| 100 | }; | ||
| 101 | |||
| 102 | static struct platform_device imx_uart2_device = { | ||
| 103 | .name = "imx-uart", | ||
| 104 | .id = 1, | ||
| 105 | .num_resources = ARRAY_SIZE(imx_uart2_resources), | ||
| 106 | .resource = imx_uart2_resources, | ||
| 107 | .dev = { | ||
| 108 | .platform_data = &uart_pdata, | ||
| 109 | } | ||
| 110 | }; | ||
| 111 | |||
| 51 | static struct platform_device *devices[] __initdata = { | 112 | static struct platform_device *devices[] __initdata = { |
| 52 | &cs89x0_device, | 113 | &cs89x0_device, |
| 114 | &imx_uart1_device, | ||
| 115 | &imx_uart2_device, | ||
| 53 | }; | 116 | }; |
| 54 | 117 | ||
| 55 | #ifdef CONFIG_MMC_IMX | 118 | #ifdef CONFIG_MMC_IMX |
| @@ -75,6 +138,17 @@ mx1ads_init(void) | |||
| 75 | imx_gpio_mode(GPIO_PORTB | GPIO_GIUS | GPIO_IN | 20); | 138 | imx_gpio_mode(GPIO_PORTB | GPIO_GIUS | GPIO_IN | 20); |
| 76 | imx_set_mmc_info(&mx1ads_mmc_info); | 139 | imx_set_mmc_info(&mx1ads_mmc_info); |
| 77 | #endif | 140 | #endif |
| 141 | |||
| 142 | imx_gpio_mode(PC9_PF_UART1_CTS); | ||
| 143 | imx_gpio_mode(PC10_PF_UART1_RTS); | ||
| 144 | imx_gpio_mode(PC11_PF_UART1_TXD); | ||
| 145 | imx_gpio_mode(PC12_PF_UART1_RXD); | ||
| 146 | |||
| 147 | imx_gpio_mode(PB28_PF_UART2_CTS); | ||
| 148 | imx_gpio_mode(PB29_PF_UART2_RTS); | ||
| 149 | imx_gpio_mode(PB30_PF_UART2_TXD); | ||
| 150 | imx_gpio_mode(PB31_PF_UART2_RXD); | ||
| 151 | |||
| 78 | platform_add_devices(devices, ARRAY_SIZE(devices)); | 152 | platform_add_devices(devices, ARRAY_SIZE(devices)); |
| 79 | } | 153 | } |
| 80 | 154 | ||
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 5bf50a2a737d..2a39f9e481ad 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig | |||
| @@ -11,6 +11,7 @@ comment "IXP4xx Platforms" | |||
| 11 | config MACH_NSLU2 | 11 | config MACH_NSLU2 |
| 12 | bool | 12 | bool |
| 13 | prompt "Linksys NSLU2" | 13 | prompt "Linksys NSLU2" |
| 14 | select PCI | ||
| 14 | help | 15 | help |
| 15 | Say 'Y' here if you want your kernel to support Linksys's | 16 | Say 'Y' here if you want your kernel to support Linksys's |
| 16 | NSLU2 NAS device. For more information on this platform, | 17 | NSLU2 NAS device. For more information on this platform, |
| @@ -18,6 +19,7 @@ config MACH_NSLU2 | |||
| 18 | 19 | ||
| 19 | config ARCH_AVILA | 20 | config ARCH_AVILA |
| 20 | bool "Avila" | 21 | bool "Avila" |
| 22 | select PCI | ||
| 21 | help | 23 | help |
| 22 | Say 'Y' here if you want your kernel to support the Gateworks | 24 | Say 'Y' here if you want your kernel to support the Gateworks |
| 23 | Avila Network Platform. For more information on this platform, | 25 | Avila Network Platform. For more information on this platform, |
| @@ -25,6 +27,7 @@ config ARCH_AVILA | |||
| 25 | 27 | ||
| 26 | config ARCH_ADI_COYOTE | 28 | config ARCH_ADI_COYOTE |
| 27 | bool "Coyote" | 29 | bool "Coyote" |
| 30 | select PCI | ||
| 28 | help | 31 | help |
| 29 | Say 'Y' here if you want your kernel to support the ADI | 32 | Say 'Y' here if you want your kernel to support the ADI |
| 30 | Engineering Coyote Gateway Reference Platform. For more | 33 | Engineering Coyote Gateway Reference Platform. For more |
| @@ -32,6 +35,7 @@ config ARCH_ADI_COYOTE | |||
| 32 | 35 | ||
| 33 | config ARCH_IXDP425 | 36 | config ARCH_IXDP425 |
| 34 | bool "IXDP425" | 37 | bool "IXDP425" |
| 38 | select PCI | ||
| 35 | help | 39 | help |
| 36 | Say 'Y' here if you want your kernel to support Intel's | 40 | Say 'Y' here if you want your kernel to support Intel's |
| 37 | IXDP425 Development Platform (Also known as Richfield). | 41 | IXDP425 Development Platform (Also known as Richfield). |
| @@ -39,6 +43,7 @@ config ARCH_IXDP425 | |||
| 39 | 43 | ||
| 40 | config MACH_IXDPG425 | 44 | config MACH_IXDPG425 |
| 41 | bool "IXDPG425" | 45 | bool "IXDPG425" |
| 46 | select PCI | ||
| 42 | help | 47 | help |
| 43 | Say 'Y' here if you want your kernel to support Intel's | 48 | Say 'Y' here if you want your kernel to support Intel's |
| 44 | IXDPG425 Development Platform (Also known as Montajade). | 49 | IXDPG425 Development Platform (Also known as Montajade). |
| @@ -46,6 +51,7 @@ config MACH_IXDPG425 | |||
| 46 | 51 | ||
| 47 | config MACH_IXDP465 | 52 | config MACH_IXDP465 |
| 48 | bool "IXDP465" | 53 | bool "IXDP465" |
| 54 | select PCI | ||
| 49 | help | 55 | help |
| 50 | Say 'Y' here if you want your kernel to support Intel's | 56 | Say 'Y' here if you want your kernel to support Intel's |
| 51 | IXDP465 Development Platform (Also known as BMP). | 57 | IXDP465 Development Platform (Also known as BMP). |
| @@ -72,6 +78,7 @@ config ARCH_PRPMC1100 | |||
| 72 | config MACH_NAS100D | 78 | config MACH_NAS100D |
| 73 | bool | 79 | bool |
| 74 | prompt "NAS100D" | 80 | prompt "NAS100D" |
| 81 | select PCI | ||
| 75 | help | 82 | help |
| 76 | Say 'Y' here if you want your kernel to support Iomega's | 83 | Say 'Y' here if you want your kernel to support Iomega's |
| 77 | NAS 100d device. For more information on this platform, | 84 | NAS 100d device. For more information on this platform, |
| @@ -96,6 +103,7 @@ config CPU_IXP46X | |||
| 96 | config MACH_GTWX5715 | 103 | config MACH_GTWX5715 |
| 97 | bool "Gemtek WX5715 (Linksys WRV54G)" | 104 | bool "Gemtek WX5715 (Linksys WRV54G)" |
| 98 | depends on ARCH_IXP4XX | 105 | depends on ARCH_IXP4XX |
| 106 | select PCI | ||
| 99 | help | 107 | help |
| 100 | This board is currently inside the Linksys WRV54G Gateways. | 108 | This board is currently inside the Linksys WRV54G Gateways. |
| 101 | 109 | ||
| @@ -110,11 +118,16 @@ config MACH_GTWX5715 | |||
| 110 | "High Speed" UART is n/c (as far as I can tell) | 118 | "High Speed" UART is n/c (as far as I can tell) |
| 111 | 20 Pin ARM/Xscale JTAG interface on J2 | 119 | 20 Pin ARM/Xscale JTAG interface on J2 |
| 112 | 120 | ||
| 113 | |||
| 114 | comment "IXP4xx Options" | 121 | comment "IXP4xx Options" |
| 115 | 122 | ||
| 123 | config DMABOUNCE | ||
| 124 | bool | ||
| 125 | default y | ||
| 126 | depends on PCI | ||
| 127 | |||
| 116 | config IXP4XX_INDIRECT_PCI | 128 | config IXP4XX_INDIRECT_PCI |
| 117 | bool "Use indirect PCI memory access" | 129 | bool "Use indirect PCI memory access" |
| 130 | depends on PCI | ||
| 118 | help | 131 | help |
| 119 | IXP4xx provides two methods of accessing PCI memory space: | 132 | IXP4xx provides two methods of accessing PCI memory space: |
| 120 | 133 | ||
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile index 0471044fa179..5a4aaa0e0a09 100644 --- a/arch/arm/mach-ixp4xx/Makefile +++ b/arch/arm/mach-ixp4xx/Makefile | |||
| @@ -2,8 +2,9 @@ | |||
| 2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y += common.o common-pci.o | 5 | obj-y += common.o |
| 6 | 6 | ||
| 7 | obj-$(CONFIG_PCI) += common-pci.o | ||
| 7 | obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o ixdp425-setup.o | 8 | obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o ixdp425-setup.o |
| 8 | obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o | 9 | obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o |
| 9 | obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o | 10 | obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o |
diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c index 458112b21e25..7d8c85486c66 100644 --- a/arch/arm/mach-pxa/dma.c +++ b/arch/arm/mach-pxa/dma.c | |||
| @@ -45,23 +45,16 @@ int pxa_request_dma (char *name, pxa_dma_prio prio, | |||
| 45 | 45 | ||
| 46 | local_irq_save(flags); | 46 | local_irq_save(flags); |
| 47 | 47 | ||
| 48 | /* try grabbing a DMA channel with the requested priority */ | 48 | do { |
| 49 | for (i = prio; i < prio + PXA_DMA_NBCH(prio); i++) { | 49 | /* try grabbing a DMA channel with the requested priority */ |
| 50 | if (!dma_channels[i].name) { | 50 | pxa_for_each_dma_prio (i, prio) { |
| 51 | found = 1; | ||
| 52 | break; | ||
| 53 | } | ||
| 54 | } | ||
| 55 | |||
| 56 | if (!found) { | ||
| 57 | /* requested prio group is full, try hier priorities */ | ||
| 58 | for (i = prio-1; i >= 0; i--) { | ||
| 59 | if (!dma_channels[i].name) { | 51 | if (!dma_channels[i].name) { |
| 60 | found = 1; | 52 | found = 1; |
| 61 | break; | 53 | break; |
| 62 | } | 54 | } |
| 63 | } | 55 | } |
| 64 | } | 56 | /* if requested prio group is full, try a hier priority */ |
| 57 | } while (!found && prio--); | ||
| 65 | 58 | ||
| 66 | if (found) { | 59 | if (found) { |
| 67 | DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; | 60 | DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 37ff8145b5b5..03486be04193 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
| @@ -245,7 +245,7 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs) | |||
| 245 | */ | 245 | */ |
| 246 | barrier(); | 246 | barrier(); |
| 247 | trigger = fmrx(FPINST2); | 247 | trigger = fmrx(FPINST2); |
| 248 | fpscr = fmrx(FPSCR); | 248 | orig_fpscr = fpscr = fmrx(FPSCR); |
| 249 | 249 | ||
| 250 | emulate: | 250 | emulate: |
| 251 | exceptions = vfp_emulate_instruction(trigger, fpscr, regs); | 251 | exceptions = vfp_emulate_instruction(trigger, fpscr, regs); |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 049a25583793..40e5aba3ad3d 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
| @@ -215,7 +215,7 @@ static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size) | |||
| 215 | { | 215 | { |
| 216 | struct acpi_table_madt *madt = NULL; | 216 | struct acpi_table_madt *madt = NULL; |
| 217 | 217 | ||
| 218 | if (!phys_addr || !size || !cpu_has_apic) | 218 | if (!phys_addr || !size) |
| 219 | return -EINVAL; | 219 | return -EINVAL; |
| 220 | 220 | ||
| 221 | madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); | 221 | madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); |
| @@ -1102,9 +1102,6 @@ int __init acpi_boot_table_init(void) | |||
| 1102 | dmi_check_system(acpi_dmi_table); | 1102 | dmi_check_system(acpi_dmi_table); |
| 1103 | #endif | 1103 | #endif |
| 1104 | 1104 | ||
| 1105 | if (!cpu_has_apic) | ||
| 1106 | return -ENODEV; | ||
| 1107 | |||
| 1108 | /* | 1105 | /* |
| 1109 | * If acpi_disabled, bail out | 1106 | * If acpi_disabled, bail out |
| 1110 | * One exception: acpi=ht continues far enough to enumerate LAPICs | 1107 | * One exception: acpi=ht continues far enough to enumerate LAPICs |
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 254cee9f0b7b..013b85df18c6 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
| @@ -757,10 +757,6 @@ static int __init apic_set_verbosity(char *str) | |||
| 757 | apic_verbosity = APIC_DEBUG; | 757 | apic_verbosity = APIC_DEBUG; |
| 758 | else if (strcmp("verbose", str) == 0) | 758 | else if (strcmp("verbose", str) == 0) |
| 759 | apic_verbosity = APIC_VERBOSE; | 759 | apic_verbosity = APIC_VERBOSE; |
| 760 | else | ||
| 761 | printk(KERN_WARNING "APIC Verbosity level %s not recognised" | ||
| 762 | " use apic=verbose or apic=debug\n", str); | ||
| 763 | |||
| 764 | return 1; | 760 | return 1; |
| 765 | } | 761 | } |
| 766 | 762 | ||
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index 506462ef36a0..fd7eaf7866e0 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c | |||
| @@ -671,7 +671,7 @@ int do_syscall_trace(struct pt_regs *regs, int entryexit) | |||
| 671 | 671 | ||
| 672 | if (unlikely(current->audit_context)) { | 672 | if (unlikely(current->audit_context)) { |
| 673 | if (entryexit) | 673 | if (entryexit) |
| 674 | audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), | 674 | audit_syscall_exit(AUDITSC_RESULT(regs->eax), |
| 675 | regs->eax); | 675 | regs->eax); |
| 676 | /* Debug traps, when using PTRACE_SINGLESTEP, must be sent only | 676 | /* Debug traps, when using PTRACE_SINGLESTEP, must be sent only |
| 677 | * on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is | 677 | * on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is |
| @@ -720,14 +720,13 @@ int do_syscall_trace(struct pt_regs *regs, int entryexit) | |||
| 720 | ret = is_sysemu; | 720 | ret = is_sysemu; |
| 721 | out: | 721 | out: |
| 722 | if (unlikely(current->audit_context) && !entryexit) | 722 | if (unlikely(current->audit_context) && !entryexit) |
| 723 | audit_syscall_entry(current, AUDIT_ARCH_I386, regs->orig_eax, | 723 | audit_syscall_entry(AUDIT_ARCH_I386, regs->orig_eax, |
| 724 | regs->ebx, regs->ecx, regs->edx, regs->esi); | 724 | regs->ebx, regs->ecx, regs->edx, regs->esi); |
| 725 | if (ret == 0) | 725 | if (ret == 0) |
| 726 | return 0; | 726 | return 0; |
| 727 | 727 | ||
| 728 | regs->orig_eax = -1; /* force skip of syscall restarting */ | 728 | regs->orig_eax = -1; /* force skip of syscall restarting */ |
| 729 | if (unlikely(current->audit_context)) | 729 | if (unlikely(current->audit_context)) |
| 730 | audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), | 730 | audit_syscall_exit(AUDITSC_RESULT(regs->eax), regs->eax); |
| 731 | regs->eax); | ||
| 732 | return 1; | 731 | return 1; |
| 733 | } | 732 | } |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 80cb3b2d0997..d77e89ac0d54 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
| @@ -970,8 +970,10 @@ efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) | |||
| 970 | * not-overlapping, which is the case | 970 | * not-overlapping, which is the case |
| 971 | */ | 971 | */ |
| 972 | int __init | 972 | int __init |
| 973 | e820_all_mapped(unsigned long start, unsigned long end, unsigned type) | 973 | e820_all_mapped(unsigned long s, unsigned long e, unsigned type) |
| 974 | { | 974 | { |
| 975 | u64 start = s; | ||
| 976 | u64 end = e; | ||
| 975 | int i; | 977 | int i; |
| 976 | for (i = 0; i < e820.nr_map; i++) { | 978 | for (i = 0; i < e820.nr_map; i++) { |
| 977 | struct e820entry *ei = &e820.map[i]; | 979 | struct e820entry *ei = &e820.map[i]; |
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index 5e41ee29c8cf..f1187ddb0d0f 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c | |||
| @@ -279,7 +279,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | |||
| 279 | { | 279 | { |
| 280 | struct cpufreq_freqs *freq = data; | 280 | struct cpufreq_freqs *freq = data; |
| 281 | 281 | ||
| 282 | if (val != CPUFREQ_RESUMECHANGE) | 282 | if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) |
| 283 | write_seqlock_irq(&xtime_lock); | 283 | write_seqlock_irq(&xtime_lock); |
| 284 | if (!ref_freq) { | 284 | if (!ref_freq) { |
| 285 | if (!freq->old){ | 285 | if (!freq->old){ |
| @@ -312,7 +312,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | |||
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | end: | 314 | end: |
| 315 | if (val != CPUFREQ_RESUMECHANGE) | 315 | if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) |
| 316 | write_sequnlock_irq(&xtime_lock); | 316 | write_sequnlock_irq(&xtime_lock); |
| 317 | 317 | ||
| 318 | return 0; | 318 | return 0; |
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index aee14fafd13d..00e0118e717c 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c | |||
| @@ -312,7 +312,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk | |||
| 312 | 312 | ||
| 313 | /*call audit_syscall_exit since we do not exit via the normal paths */ | 313 | /*call audit_syscall_exit since we do not exit via the normal paths */ |
| 314 | if (unlikely(current->audit_context)) | 314 | if (unlikely(current->audit_context)) |
| 315 | audit_syscall_exit(current, AUDITSC_RESULT(eax), eax); | 315 | audit_syscall_exit(AUDITSC_RESULT(eax), eax); |
| 316 | 316 | ||
| 317 | __asm__ __volatile__( | 317 | __asm__ __volatile__( |
| 318 | "movl %0,%%esp\n\t" | 318 | "movl %0,%%esp\n\t" |
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 9887c8787e7a..e61e15e28d8b 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c | |||
| @@ -1644,7 +1644,7 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3, | |||
| 1644 | arch = AUDIT_ARCH_IA64; | 1644 | arch = AUDIT_ARCH_IA64; |
| 1645 | } | 1645 | } |
| 1646 | 1646 | ||
| 1647 | audit_syscall_entry(current, arch, syscall, arg0, arg1, arg2, arg3); | 1647 | audit_syscall_entry(arch, syscall, arg0, arg1, arg2, arg3); |
| 1648 | } | 1648 | } |
| 1649 | 1649 | ||
| 1650 | } | 1650 | } |
| @@ -1662,7 +1662,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3, | |||
| 1662 | 1662 | ||
| 1663 | if (success != AUDITSC_SUCCESS) | 1663 | if (success != AUDITSC_SUCCESS) |
| 1664 | result = -result; | 1664 | result = -result; |
| 1665 | audit_syscall_exit(current, success, result); | 1665 | audit_syscall_exit(success, result); |
| 1666 | } | 1666 | } |
| 1667 | 1667 | ||
| 1668 | if (test_thread_flag(TIF_SYSCALL_TRACE) | 1668 | if (test_thread_flag(TIF_SYSCALL_TRACE) |
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index f3106d0771b0..9b4733c12395 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
| @@ -483,7 +483,7 @@ static inline int audit_arch(void) | |||
| 483 | asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) | 483 | asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) |
| 484 | { | 484 | { |
| 485 | if (unlikely(current->audit_context) && entryexit) | 485 | if (unlikely(current->audit_context) && entryexit) |
| 486 | audit_syscall_exit(current, AUDITSC_RESULT(regs->regs[2]), | 486 | audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]), |
| 487 | regs->regs[2]); | 487 | regs->regs[2]); |
| 488 | 488 | ||
| 489 | if (!(current->ptrace & PT_PTRACED)) | 489 | if (!(current->ptrace & PT_PTRACED)) |
| @@ -507,7 +507,7 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) | |||
| 507 | } | 507 | } |
| 508 | out: | 508 | out: |
| 509 | if (unlikely(current->audit_context) && !entryexit) | 509 | if (unlikely(current->audit_context) && !entryexit) |
| 510 | audit_syscall_entry(current, audit_arch(), regs->regs[2], | 510 | audit_syscall_entry(audit_arch(), regs->regs[2], |
| 511 | regs->regs[4], regs->regs[5], | 511 | regs->regs[4], regs->regs[5], |
| 512 | regs->regs[6], regs->regs[7]); | 512 | regs->regs[6], regs->regs[7]); |
| 513 | } | 513 | } |
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 856ef1a832b9..f78866367b70 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c | |||
| @@ -90,15 +90,15 @@ void __kprobes arch_remove_kprobe(struct kprobe *p) | |||
| 90 | 90 | ||
| 91 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | 91 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) |
| 92 | { | 92 | { |
| 93 | kprobe_opcode_t insn = *p->ainsn.insn; | ||
| 94 | |||
| 95 | regs->msr |= MSR_SE; | 93 | regs->msr |= MSR_SE; |
| 96 | 94 | ||
| 97 | /* single step inline if it is a trap variant */ | 95 | /* |
| 98 | if (is_trap(insn)) | 96 | * On powerpc we should single step on the original |
| 99 | regs->nip = (unsigned long)p->addr; | 97 | * instruction even if the probed insn is a trap |
| 100 | else | 98 | * variant as values in regs could play a part in |
| 101 | regs->nip = (unsigned long)p->ainsn.insn; | 99 | * if the trap is taken or not |
| 100 | */ | ||
| 101 | regs->nip = (unsigned long)p->ainsn.insn; | ||
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) | 104 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 1cb69e8fb0b1..9a07f97f0712 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
| @@ -885,6 +885,74 @@ void __init unflatten_device_tree(void) | |||
| 885 | DBG(" <- unflatten_device_tree()\n"); | 885 | DBG(" <- unflatten_device_tree()\n"); |
| 886 | } | 886 | } |
| 887 | 887 | ||
| 888 | /* | ||
| 889 | * ibm,pa-features is a per-cpu property that contains a string of | ||
| 890 | * attribute descriptors, each of which has a 2 byte header plus up | ||
| 891 | * to 254 bytes worth of processor attribute bits. First header | ||
| 892 | * byte specifies the number of bytes following the header. | ||
| 893 | * Second header byte is an "attribute-specifier" type, of which | ||
| 894 | * zero is the only currently-defined value. | ||
| 895 | * Implementation: Pass in the byte and bit offset for the feature | ||
| 896 | * that we are interested in. The function will return -1 if the | ||
| 897 | * pa-features property is missing, or a 1/0 to indicate if the feature | ||
| 898 | * is supported/not supported. Note that the bit numbers are | ||
| 899 | * big-endian to match the definition in PAPR. | ||
| 900 | */ | ||
| 901 | static struct ibm_pa_feature { | ||
| 902 | unsigned long cpu_features; /* CPU_FTR_xxx bit */ | ||
| 903 | unsigned int cpu_user_ftrs; /* PPC_FEATURE_xxx bit */ | ||
| 904 | unsigned char pabyte; /* byte number in ibm,pa-features */ | ||
| 905 | unsigned char pabit; /* bit number (big-endian) */ | ||
| 906 | unsigned char invert; /* if 1, pa bit set => clear feature */ | ||
| 907 | } ibm_pa_features[] __initdata = { | ||
| 908 | {0, PPC_FEATURE_HAS_MMU, 0, 0, 0}, | ||
| 909 | {0, PPC_FEATURE_HAS_FPU, 0, 1, 0}, | ||
| 910 | {CPU_FTR_SLB, 0, 0, 2, 0}, | ||
| 911 | {CPU_FTR_CTRL, 0, 0, 3, 0}, | ||
| 912 | {CPU_FTR_NOEXECUTE, 0, 0, 6, 0}, | ||
| 913 | {CPU_FTR_NODSISRALIGN, 0, 1, 1, 1}, | ||
| 914 | {CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, | ||
| 915 | }; | ||
| 916 | |||
| 917 | static void __init check_cpu_pa_features(unsigned long node) | ||
| 918 | { | ||
| 919 | unsigned char *pa_ftrs; | ||
| 920 | unsigned long len, tablelen, i, bit; | ||
| 921 | |||
| 922 | pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen); | ||
| 923 | if (pa_ftrs == NULL) | ||
| 924 | return; | ||
| 925 | |||
| 926 | /* find descriptor with type == 0 */ | ||
| 927 | for (;;) { | ||
| 928 | if (tablelen < 3) | ||
| 929 | return; | ||
| 930 | len = 2 + pa_ftrs[0]; | ||
| 931 | if (tablelen < len) | ||
| 932 | return; /* descriptor 0 not found */ | ||
| 933 | if (pa_ftrs[1] == 0) | ||
| 934 | break; | ||
| 935 | tablelen -= len; | ||
| 936 | pa_ftrs += len; | ||
| 937 | } | ||
| 938 | |||
| 939 | /* loop over bits we know about */ | ||
| 940 | for (i = 0; i < ARRAY_SIZE(ibm_pa_features); ++i) { | ||
| 941 | struct ibm_pa_feature *fp = &ibm_pa_features[i]; | ||
| 942 | |||
| 943 | if (fp->pabyte >= pa_ftrs[0]) | ||
| 944 | continue; | ||
| 945 | bit = (pa_ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1; | ||
| 946 | if (bit ^ fp->invert) { | ||
| 947 | cur_cpu_spec->cpu_features |= fp->cpu_features; | ||
| 948 | cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs; | ||
| 949 | } else { | ||
| 950 | cur_cpu_spec->cpu_features &= ~fp->cpu_features; | ||
| 951 | cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs; | ||
| 952 | } | ||
| 953 | } | ||
| 954 | } | ||
| 955 | |||
| 888 | static int __init early_init_dt_scan_cpus(unsigned long node, | 956 | static int __init early_init_dt_scan_cpus(unsigned long node, |
| 889 | const char *uname, int depth, | 957 | const char *uname, int depth, |
| 890 | void *data) | 958 | void *data) |
| @@ -969,6 +1037,8 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
| 969 | } | 1037 | } |
| 970 | #endif /* CONFIG_ALTIVEC */ | 1038 | #endif /* CONFIG_ALTIVEC */ |
| 971 | 1039 | ||
| 1040 | check_cpu_pa_features(node); | ||
| 1041 | |||
| 972 | #ifdef CONFIG_PPC_PSERIES | 1042 | #ifdef CONFIG_PPC_PSERIES |
| 973 | if (nthreads > 1) | 1043 | if (nthreads > 1) |
| 974 | cur_cpu_spec->cpu_features |= CPU_FTR_SMT; | 1044 | cur_cpu_spec->cpu_features |= CPU_FTR_SMT; |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index bcb83574335b..4a677d1bd4ef 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
| @@ -538,7 +538,7 @@ void do_syscall_trace_enter(struct pt_regs *regs) | |||
| 538 | do_syscall_trace(); | 538 | do_syscall_trace(); |
| 539 | 539 | ||
| 540 | if (unlikely(current->audit_context)) | 540 | if (unlikely(current->audit_context)) |
| 541 | audit_syscall_entry(current, | 541 | audit_syscall_entry( |
| 542 | #ifdef CONFIG_PPC32 | 542 | #ifdef CONFIG_PPC32 |
| 543 | AUDIT_ARCH_PPC, | 543 | AUDIT_ARCH_PPC, |
| 544 | #else | 544 | #else |
| @@ -556,8 +556,7 @@ void do_syscall_trace_leave(struct pt_regs *regs) | |||
| 556 | #endif | 556 | #endif |
| 557 | 557 | ||
| 558 | if (unlikely(current->audit_context)) | 558 | if (unlikely(current->audit_context)) |
| 559 | audit_syscall_exit(current, | 559 | audit_syscall_exit((regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, |
| 560 | (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, | ||
| 561 | regs->result); | 560 | regs->result); |
| 562 | 561 | ||
| 563 | if ((test_thread_flag(TIF_SYSCALL_TRACE) | 562 | if ((test_thread_flag(TIF_SYSCALL_TRACE) |
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index ed737cacf92d..5bc2585c8036 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
| @@ -322,13 +322,31 @@ static void register_nodes(void) | |||
| 322 | } | 322 | } |
| 323 | } | 323 | } |
| 324 | } | 324 | } |
| 325 | |||
| 326 | int sysfs_add_device_to_node(struct sys_device *dev, int nid) | ||
| 327 | { | ||
| 328 | struct node *node = &node_devices[nid]; | ||
| 329 | return sysfs_create_link(&node->sysdev.kobj, &dev->kobj, | ||
| 330 | kobject_name(&dev->kobj)); | ||
| 331 | } | ||
| 332 | |||
| 333 | void sysfs_remove_device_from_node(struct sys_device *dev, int nid) | ||
| 334 | { | ||
| 335 | struct node *node = &node_devices[nid]; | ||
| 336 | sysfs_remove_link(&node->sysdev.kobj, kobject_name(&dev->kobj)); | ||
| 337 | } | ||
| 338 | |||
| 325 | #else | 339 | #else |
| 326 | static void register_nodes(void) | 340 | static void register_nodes(void) |
| 327 | { | 341 | { |
| 328 | return; | 342 | return; |
| 329 | } | 343 | } |
| 344 | |||
| 330 | #endif | 345 | #endif |
| 331 | 346 | ||
| 347 | EXPORT_SYMBOL_GPL(sysfs_add_device_to_node); | ||
| 348 | EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node); | ||
| 349 | |||
| 332 | /* Only valid if CPU is present. */ | 350 | /* Only valid if CPU is present. */ |
| 333 | static ssize_t show_physical_id(struct sys_device *dev, char *buf) | 351 | static ssize_t show_physical_id(struct sys_device *dev, char *buf) |
| 334 | { | 352 | { |
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 0a335f34974c..092355f37399 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
| @@ -194,7 +194,7 @@ static int *of_get_associativity(struct device_node *dev) | |||
| 194 | /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa | 194 | /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa |
| 195 | * info is found. | 195 | * info is found. |
| 196 | */ | 196 | */ |
| 197 | static int of_node_to_nid(struct device_node *device) | 197 | static int of_node_to_nid_single(struct device_node *device) |
| 198 | { | 198 | { |
| 199 | int nid = -1; | 199 | int nid = -1; |
| 200 | unsigned int *tmp; | 200 | unsigned int *tmp; |
| @@ -216,6 +216,28 @@ out: | |||
| 216 | return nid; | 216 | return nid; |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | /* Walk the device tree upwards, looking for an associativity id */ | ||
| 220 | int of_node_to_nid(struct device_node *device) | ||
| 221 | { | ||
| 222 | struct device_node *tmp; | ||
| 223 | int nid = -1; | ||
| 224 | |||
| 225 | of_node_get(device); | ||
| 226 | while (device) { | ||
| 227 | nid = of_node_to_nid_single(device); | ||
| 228 | if (nid != -1) | ||
| 229 | break; | ||
| 230 | |||
| 231 | tmp = device; | ||
| 232 | device = of_get_parent(tmp); | ||
| 233 | of_node_put(tmp); | ||
| 234 | } | ||
| 235 | of_node_put(device); | ||
| 236 | |||
| 237 | return nid; | ||
| 238 | } | ||
| 239 | EXPORT_SYMBOL_GPL(of_node_to_nid); | ||
| 240 | |||
| 219 | /* | 241 | /* |
| 220 | * In theory, the "ibm,associativity" property may contain multiple | 242 | * In theory, the "ibm,associativity" property may contain multiple |
| 221 | * associativity lists because a resource may be multiply connected | 243 | * associativity lists because a resource may be multiply connected |
| @@ -300,7 +322,7 @@ static int __cpuinit numa_setup_cpu(unsigned long lcpu) | |||
| 300 | goto out; | 322 | goto out; |
| 301 | } | 323 | } |
| 302 | 324 | ||
| 303 | nid = of_node_to_nid(cpu); | 325 | nid = of_node_to_nid_single(cpu); |
| 304 | 326 | ||
| 305 | if (nid < 0 || !node_online(nid)) | 327 | if (nid < 0 || !node_online(nid)) |
| 306 | nid = any_online_node(NODE_MASK_ALL); | 328 | nid = any_online_node(NODE_MASK_ALL); |
| @@ -393,7 +415,7 @@ static int __init parse_numa_properties(void) | |||
| 393 | 415 | ||
| 394 | cpu = find_cpu_node(i); | 416 | cpu = find_cpu_node(i); |
| 395 | BUG_ON(!cpu); | 417 | BUG_ON(!cpu); |
| 396 | nid = of_node_to_nid(cpu); | 418 | nid = of_node_to_nid_single(cpu); |
| 397 | of_node_put(cpu); | 419 | of_node_put(cpu); |
| 398 | 420 | ||
| 399 | /* | 421 | /* |
| @@ -437,7 +459,7 @@ new_range: | |||
| 437 | * have associativity properties. If none, then | 459 | * have associativity properties. If none, then |
| 438 | * everything goes to default_nid. | 460 | * everything goes to default_nid. |
| 439 | */ | 461 | */ |
| 440 | nid = of_node_to_nid(memory); | 462 | nid = of_node_to_nid_single(memory); |
| 441 | if (nid < 0) | 463 | if (nid < 0) |
| 442 | nid = default_nid; | 464 | nid = default_nid; |
| 443 | node_set_online(nid); | 465 | node_set_online(nid); |
| @@ -776,7 +798,7 @@ int hot_add_scn_to_nid(unsigned long scn_addr) | |||
| 776 | ha_new_range: | 798 | ha_new_range: |
| 777 | start = read_n_cells(n_mem_addr_cells, &memcell_buf); | 799 | start = read_n_cells(n_mem_addr_cells, &memcell_buf); |
| 778 | size = read_n_cells(n_mem_size_cells, &memcell_buf); | 800 | size = read_n_cells(n_mem_size_cells, &memcell_buf); |
| 779 | nid = of_node_to_nid(memory); | 801 | nid = of_node_to_nid_single(memory); |
| 780 | 802 | ||
| 781 | /* Domains not present at boot default to 0 */ | 803 | /* Domains not present at boot default to 0 */ |
| 782 | if (nid < 0 || !node_online(nid)) | 804 | if (nid < 0 || !node_online(nid)) |
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index c2a3db8edb0c..6a02d51086c8 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig | |||
| @@ -12,7 +12,8 @@ config SPU_FS | |||
| 12 | 12 | ||
| 13 | config SPUFS_MMAP | 13 | config SPUFS_MMAP |
| 14 | bool | 14 | bool |
| 15 | depends on SPU_FS && SPARSEMEM && !PPC_64K_PAGES | 15 | depends on SPU_FS && SPARSEMEM |
| 16 | select MEMORY_HOTPLUG | ||
| 16 | default y | 17 | default y |
| 17 | 18 | ||
| 18 | endmenu | 19 | endmenu |
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index dac5d0365fde..6574b22b3cf3 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c | |||
| @@ -29,6 +29,8 @@ | |||
| 29 | #include <linux/seq_file.h> | 29 | #include <linux/seq_file.h> |
| 30 | #include <linux/root_dev.h> | 30 | #include <linux/root_dev.h> |
| 31 | #include <linux/console.h> | 31 | #include <linux/console.h> |
| 32 | #include <linux/mutex.h> | ||
| 33 | #include <linux/memory_hotplug.h> | ||
| 32 | 34 | ||
| 33 | #include <asm/mmu.h> | 35 | #include <asm/mmu.h> |
| 34 | #include <asm/processor.h> | 36 | #include <asm/processor.h> |
| @@ -46,6 +48,7 @@ | |||
| 46 | #include <asm/cputable.h> | 48 | #include <asm/cputable.h> |
| 47 | #include <asm/ppc-pci.h> | 49 | #include <asm/ppc-pci.h> |
| 48 | #include <asm/irq.h> | 50 | #include <asm/irq.h> |
| 51 | #include <asm/spu.h> | ||
| 49 | 52 | ||
| 50 | #include "interrupt.h" | 53 | #include "interrupt.h" |
| 51 | #include "iommu.h" | 54 | #include "iommu.h" |
| @@ -69,77 +72,6 @@ static void cell_show_cpuinfo(struct seq_file *m) | |||
| 69 | of_node_put(root); | 72 | of_node_put(root); |
| 70 | } | 73 | } |
| 71 | 74 | ||
| 72 | #ifdef CONFIG_SPARSEMEM | ||
| 73 | static int __init find_spu_node_id(struct device_node *spe) | ||
| 74 | { | ||
| 75 | unsigned int *id; | ||
| 76 | #ifdef CONFIG_NUMA | ||
| 77 | struct device_node *cpu; | ||
| 78 | cpu = spe->parent->parent; | ||
| 79 | id = (unsigned int *)get_property(cpu, "node-id", NULL); | ||
| 80 | #else | ||
| 81 | id = NULL; | ||
| 82 | #endif | ||
| 83 | return id ? *id : 0; | ||
| 84 | } | ||
| 85 | |||
| 86 | static void __init cell_spuprop_present(struct device_node *spe, | ||
| 87 | const char *prop, int early) | ||
| 88 | { | ||
| 89 | struct address_prop { | ||
| 90 | unsigned long address; | ||
| 91 | unsigned int len; | ||
| 92 | } __attribute__((packed)) *p; | ||
| 93 | int proplen; | ||
| 94 | |||
| 95 | unsigned long start_pfn, end_pfn, pfn; | ||
| 96 | int node_id; | ||
| 97 | |||
| 98 | p = (void*)get_property(spe, prop, &proplen); | ||
| 99 | WARN_ON(proplen != sizeof (*p)); | ||
| 100 | |||
| 101 | node_id = find_spu_node_id(spe); | ||
| 102 | |||
| 103 | start_pfn = p->address >> PAGE_SHIFT; | ||
| 104 | end_pfn = (p->address + p->len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
| 105 | |||
| 106 | /* We need to call memory_present *before* the call to sparse_init, | ||
| 107 | but we can initialize the page structs only *after* that call. | ||
| 108 | Thus, we're being called twice. */ | ||
| 109 | if (early) | ||
| 110 | memory_present(node_id, start_pfn, end_pfn); | ||
| 111 | else { | ||
| 112 | /* As the pages backing SPU LS and I/O are outside the range | ||
| 113 | of regular memory, their page structs were not initialized | ||
| 114 | by free_area_init. Do it here instead. */ | ||
| 115 | for (pfn = start_pfn; pfn < end_pfn; pfn++) { | ||
| 116 | struct page *page = pfn_to_page(pfn); | ||
| 117 | set_page_links(page, ZONE_DMA, node_id, pfn); | ||
| 118 | init_page_count(page); | ||
| 119 | reset_page_mapcount(page); | ||
| 120 | SetPageReserved(page); | ||
| 121 | INIT_LIST_HEAD(&page->lru); | ||
| 122 | } | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | static void __init cell_spumem_init(int early) | ||
| 127 | { | ||
| 128 | struct device_node *node; | ||
| 129 | for (node = of_find_node_by_type(NULL, "spe"); | ||
| 130 | node; node = of_find_node_by_type(node, "spe")) { | ||
| 131 | cell_spuprop_present(node, "local-store", early); | ||
| 132 | cell_spuprop_present(node, "problem", early); | ||
| 133 | cell_spuprop_present(node, "priv1", early); | ||
| 134 | cell_spuprop_present(node, "priv2", early); | ||
| 135 | } | ||
| 136 | } | ||
| 137 | #else | ||
| 138 | static void __init cell_spumem_init(int early) | ||
| 139 | { | ||
| 140 | } | ||
| 141 | #endif | ||
| 142 | |||
| 143 | static void cell_progress(char *s, unsigned short hex) | 75 | static void cell_progress(char *s, unsigned short hex) |
| 144 | { | 76 | { |
| 145 | printk("*** %04x : %s\n", hex, s ? s : ""); | 77 | printk("*** %04x : %s\n", hex, s ? s : ""); |
| @@ -172,8 +104,6 @@ static void __init cell_setup_arch(void) | |||
| 172 | #endif | 104 | #endif |
| 173 | 105 | ||
| 174 | mmio_nvram_init(); | 106 | mmio_nvram_init(); |
| 175 | |||
| 176 | cell_spumem_init(0); | ||
| 177 | } | 107 | } |
| 178 | 108 | ||
| 179 | /* | 109 | /* |
| @@ -189,8 +119,6 @@ static void __init cell_init_early(void) | |||
| 189 | 119 | ||
| 190 | ppc64_interrupt_controller = IC_CELL_PIC; | 120 | ppc64_interrupt_controller = IC_CELL_PIC; |
| 191 | 121 | ||
| 192 | cell_spumem_init(1); | ||
| 193 | |||
| 194 | DBG(" <- cell_init_early()\n"); | 122 | DBG(" <- cell_init_early()\n"); |
| 195 | } | 123 | } |
| 196 | 124 | ||
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index ef47a6239d48..ad141fe8d52d 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
| @@ -520,8 +520,50 @@ void spu_irq_setaffinity(struct spu *spu, int cpu) | |||
| 520 | } | 520 | } |
| 521 | EXPORT_SYMBOL_GPL(spu_irq_setaffinity); | 521 | EXPORT_SYMBOL_GPL(spu_irq_setaffinity); |
| 522 | 522 | ||
| 523 | static void __iomem * __init map_spe_prop(struct device_node *n, | 523 | static int __init find_spu_node_id(struct device_node *spe) |
| 524 | const char *name) | 524 | { |
| 525 | unsigned int *id; | ||
| 526 | struct device_node *cpu; | ||
| 527 | cpu = spe->parent->parent; | ||
| 528 | id = (unsigned int *)get_property(cpu, "node-id", NULL); | ||
| 529 | return id ? *id : 0; | ||
| 530 | } | ||
| 531 | |||
| 532 | static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe, | ||
| 533 | const char *prop) | ||
| 534 | { | ||
| 535 | static DEFINE_MUTEX(add_spumem_mutex); | ||
| 536 | |||
| 537 | struct address_prop { | ||
| 538 | unsigned long address; | ||
| 539 | unsigned int len; | ||
| 540 | } __attribute__((packed)) *p; | ||
| 541 | int proplen; | ||
| 542 | |||
| 543 | unsigned long start_pfn, nr_pages; | ||
| 544 | struct pglist_data *pgdata; | ||
| 545 | struct zone *zone; | ||
| 546 | int ret; | ||
| 547 | |||
| 548 | p = (void*)get_property(spe, prop, &proplen); | ||
| 549 | WARN_ON(proplen != sizeof (*p)); | ||
| 550 | |||
| 551 | start_pfn = p->address >> PAGE_SHIFT; | ||
| 552 | nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
| 553 | |||
| 554 | pgdata = NODE_DATA(spu->nid); | ||
| 555 | zone = pgdata->node_zones; | ||
| 556 | |||
| 557 | /* XXX rethink locking here */ | ||
| 558 | mutex_lock(&add_spumem_mutex); | ||
| 559 | ret = __add_pages(zone, start_pfn, nr_pages); | ||
| 560 | mutex_unlock(&add_spumem_mutex); | ||
| 561 | |||
| 562 | return ret; | ||
| 563 | } | ||
| 564 | |||
| 565 | static void __iomem * __init map_spe_prop(struct spu *spu, | ||
| 566 | struct device_node *n, const char *name) | ||
| 525 | { | 567 | { |
| 526 | struct address_prop { | 568 | struct address_prop { |
| 527 | unsigned long address; | 569 | unsigned long address; |
| @@ -530,6 +572,8 @@ static void __iomem * __init map_spe_prop(struct device_node *n, | |||
| 530 | 572 | ||
| 531 | void *p; | 573 | void *p; |
| 532 | int proplen; | 574 | int proplen; |
| 575 | void* ret = NULL; | ||
| 576 | int err = 0; | ||
| 533 | 577 | ||
| 534 | p = get_property(n, name, &proplen); | 578 | p = get_property(n, name, &proplen); |
| 535 | if (proplen != sizeof (struct address_prop)) | 579 | if (proplen != sizeof (struct address_prop)) |
| @@ -537,7 +581,14 @@ static void __iomem * __init map_spe_prop(struct device_node *n, | |||
| 537 | 581 | ||
| 538 | prop = p; | 582 | prop = p; |
| 539 | 583 | ||
| 540 | return ioremap(prop->address, prop->len); | 584 | err = cell_spuprop_present(spu, n, name); |
| 585 | if (err && (err != -EEXIST)) | ||
| 586 | goto out; | ||
| 587 | |||
| 588 | ret = ioremap(prop->address, prop->len); | ||
| 589 | |||
| 590 | out: | ||
| 591 | return ret; | ||
| 541 | } | 592 | } |
| 542 | 593 | ||
| 543 | static void spu_unmap(struct spu *spu) | 594 | static void spu_unmap(struct spu *spu) |
| @@ -548,44 +599,45 @@ static void spu_unmap(struct spu *spu) | |||
| 548 | iounmap((u8 __iomem *)spu->local_store); | 599 | iounmap((u8 __iomem *)spu->local_store); |
| 549 | } | 600 | } |
| 550 | 601 | ||
| 551 | static int __init spu_map_device(struct spu *spu, struct device_node *spe) | 602 | static int __init spu_map_device(struct spu *spu, struct device_node *node) |
| 552 | { | 603 | { |
| 553 | char *prop; | 604 | char *prop; |
| 554 | int ret; | 605 | int ret; |
| 555 | 606 | ||
| 556 | ret = -ENODEV; | 607 | ret = -ENODEV; |
| 557 | prop = get_property(spe, "isrc", NULL); | 608 | prop = get_property(node, "isrc", NULL); |
| 558 | if (!prop) | 609 | if (!prop) |
| 559 | goto out; | 610 | goto out; |
| 560 | spu->isrc = *(unsigned int *)prop; | 611 | spu->isrc = *(unsigned int *)prop; |
| 561 | 612 | ||
| 562 | spu->name = get_property(spe, "name", NULL); | 613 | spu->name = get_property(node, "name", NULL); |
| 563 | if (!spu->name) | 614 | if (!spu->name) |
| 564 | goto out; | 615 | goto out; |
| 565 | 616 | ||
| 566 | prop = get_property(spe, "local-store", NULL); | 617 | prop = get_property(node, "local-store", NULL); |
| 567 | if (!prop) | 618 | if (!prop) |
| 568 | goto out; | 619 | goto out; |
| 569 | spu->local_store_phys = *(unsigned long *)prop; | 620 | spu->local_store_phys = *(unsigned long *)prop; |
| 570 | 621 | ||
| 571 | /* we use local store as ram, not io memory */ | 622 | /* we use local store as ram, not io memory */ |
| 572 | spu->local_store = (void __force *)map_spe_prop(spe, "local-store"); | 623 | spu->local_store = (void __force *) |
| 624 | map_spe_prop(spu, node, "local-store"); | ||
| 573 | if (!spu->local_store) | 625 | if (!spu->local_store) |
| 574 | goto out; | 626 | goto out; |
| 575 | 627 | ||
| 576 | prop = get_property(spe, "problem", NULL); | 628 | prop = get_property(node, "problem", NULL); |
| 577 | if (!prop) | 629 | if (!prop) |
| 578 | goto out_unmap; | 630 | goto out_unmap; |
| 579 | spu->problem_phys = *(unsigned long *)prop; | 631 | spu->problem_phys = *(unsigned long *)prop; |
| 580 | 632 | ||
| 581 | spu->problem= map_spe_prop(spe, "problem"); | 633 | spu->problem= map_spe_prop(spu, node, "problem"); |
| 582 | if (!spu->problem) | 634 | if (!spu->problem) |
| 583 | goto out_unmap; | 635 | goto out_unmap; |
| 584 | 636 | ||
| 585 | spu->priv1= map_spe_prop(spe, "priv1"); | 637 | spu->priv1= map_spe_prop(spu, node, "priv1"); |
| 586 | /* priv1 is not available on a hypervisor */ | 638 | /* priv1 is not available on a hypervisor */ |
| 587 | 639 | ||
| 588 | spu->priv2= map_spe_prop(spe, "priv2"); | 640 | spu->priv2= map_spe_prop(spu, node, "priv2"); |
| 589 | if (!spu->priv2) | 641 | if (!spu->priv2) |
| 590 | goto out_unmap; | 642 | goto out_unmap; |
| 591 | ret = 0; | 643 | ret = 0; |
| @@ -597,17 +649,6 @@ out: | |||
| 597 | return ret; | 649 | return ret; |
| 598 | } | 650 | } |
| 599 | 651 | ||
| 600 | static int __init find_spu_node_id(struct device_node *spe) | ||
| 601 | { | ||
| 602 | unsigned int *id; | ||
| 603 | struct device_node *cpu; | ||
| 604 | |||
| 605 | cpu = spe->parent->parent; | ||
| 606 | id = (unsigned int *)get_property(cpu, "node-id", NULL); | ||
| 607 | |||
| 608 | return id ? *id : 0; | ||
| 609 | } | ||
| 610 | |||
| 611 | static int __init create_spu(struct device_node *spe) | 652 | static int __init create_spu(struct device_node *spe) |
| 612 | { | 653 | { |
| 613 | struct spu *spu; | 654 | struct spu *spu; |
| @@ -624,6 +665,10 @@ static int __init create_spu(struct device_node *spe) | |||
| 624 | goto out_free; | 665 | goto out_free; |
| 625 | 666 | ||
| 626 | spu->node = find_spu_node_id(spe); | 667 | spu->node = find_spu_node_id(spe); |
| 668 | spu->nid = of_node_to_nid(spe); | ||
| 669 | if (spu->nid == -1) | ||
| 670 | spu->nid = 0; | ||
| 671 | |||
| 627 | spu->stop_code = 0; | 672 | spu->stop_code = 0; |
| 628 | spu->slb_replace = 0; | 673 | spu->slb_replace = 0; |
| 629 | spu->mm = NULL; | 674 | spu->mm = NULL; |
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c index a1bda6f96fd1..40020c65c89e 100644 --- a/arch/powerpc/platforms/pseries/eeh_event.c +++ b/arch/powerpc/platforms/pseries/eeh_event.c | |||
| @@ -118,7 +118,15 @@ int eeh_send_failure_event (struct device_node *dn, | |||
| 118 | { | 118 | { |
| 119 | unsigned long flags; | 119 | unsigned long flags; |
| 120 | struct eeh_event *event; | 120 | struct eeh_event *event; |
| 121 | char *location; | ||
| 121 | 122 | ||
| 123 | if (!mem_init_done) { | ||
| 124 | printk(KERN_ERR "EEH: event during early boot not handled\n"); | ||
| 125 | location = (char *) get_property(dn, "ibm,loc-code", NULL); | ||
| 126 | printk(KERN_ERR "EEH: device node = %s\n", dn->full_name); | ||
| 127 | printk(KERN_ERR "EEH: PCI location = %s\n", location); | ||
| 128 | return 1; | ||
| 129 | } | ||
| 122 | event = kmalloc(sizeof(*event), GFP_ATOMIC); | 130 | event = kmalloc(sizeof(*event), GFP_ATOMIC); |
| 123 | if (event == NULL) { | 131 | if (event == NULL) { |
| 124 | printk (KERN_ERR "EEH: out of memory, event not handled\n"); | 132 | printk (KERN_ERR "EEH: out of memory, event not handled\n"); |
diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c index 6ce3b842defe..d919dab61347 100644 --- a/arch/ppc/platforms/mpc866ads_setup.c +++ b/arch/ppc/platforms/mpc866ads_setup.c | |||
| @@ -378,7 +378,7 @@ int __init mpc866ads_init(void) | |||
| 378 | ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART); | 378 | ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART); |
| 379 | #endif | 379 | #endif |
| 380 | 380 | ||
| 381 | #ifdef CONFIG_SERIAL_CPM_SMCer | 381 | #ifdef CONFIG_SERIAL_CPM_SMC |
| 382 | ppc_sys_device_enable(MPC8xx_CPM_SMC2); | 382 | ppc_sys_device_enable(MPC8xx_CPM_SMC2); |
| 383 | ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART); | 383 | ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART); |
| 384 | #endif | 384 | #endif |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 37dfe33dab73..8f36504075ed 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
| @@ -734,7 +734,7 @@ asmlinkage void | |||
| 734 | syscall_trace(struct pt_regs *regs, int entryexit) | 734 | syscall_trace(struct pt_regs *regs, int entryexit) |
| 735 | { | 735 | { |
| 736 | if (unlikely(current->audit_context) && entryexit) | 736 | if (unlikely(current->audit_context) && entryexit) |
| 737 | audit_syscall_exit(current, AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]); | 737 | audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]); |
| 738 | 738 | ||
| 739 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | 739 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) |
| 740 | goto out; | 740 | goto out; |
| @@ -761,8 +761,7 @@ syscall_trace(struct pt_regs *regs, int entryexit) | |||
| 761 | } | 761 | } |
| 762 | out: | 762 | out: |
| 763 | if (unlikely(current->audit_context) && !entryexit) | 763 | if (unlikely(current->audit_context) && !entryexit) |
| 764 | audit_syscall_entry(current, | 764 | audit_syscall_entry(test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X, |
| 765 | test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X, | ||
| 766 | regs->gprs[2], regs->orig_gpr2, regs->gprs[3], | 765 | regs->gprs[2], regs->orig_gpr2, regs->gprs[3], |
| 767 | regs->gprs[4], regs->gprs[5]); | 766 | regs->gprs[4], regs->gprs[5]); |
| 768 | } | 767 | } |
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index ae1927e48cfb..d48cfc726b68 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
| @@ -358,8 +358,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 358 | } else { | 358 | } else { |
| 359 | regs->gprs[14] = (unsigned long) | 359 | regs->gprs[14] = (unsigned long) |
| 360 | frame->retcode | PSW_ADDR_AMODE; | 360 | frame->retcode | PSW_ADDR_AMODE; |
| 361 | err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, | 361 | if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, |
| 362 | (u16 __user *)(frame->retcode)); | 362 | (u16 __user *)(frame->retcode))) |
| 363 | goto give_sigsegv; | ||
| 363 | } | 364 | } |
| 364 | 365 | ||
| 365 | /* Set up backchain. */ | 366 | /* Set up backchain. */ |
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index db8faa75f94d..6e1135cc03b0 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S | |||
| @@ -23,7 +23,7 @@ sys_call_table: | |||
| 23 | /*10*/ .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod | 23 | /*10*/ .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod |
| 24 | /*15*/ .long sys_chmod, sys_lchown16, sparc_brk, sys_nis_syscall, sys_lseek | 24 | /*15*/ .long sys_chmod, sys_lchown16, sparc_brk, sys_nis_syscall, sys_lseek |
| 25 | /*20*/ .long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 | 25 | /*20*/ .long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 |
| 26 | /*25*/ .long sys_time, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause | 26 | /*25*/ .long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause |
| 27 | /*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice | 27 | /*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice |
| 28 | /*35*/ .long sys_chown, sys_sync, sys_kill, sys_newstat, sys_sendfile | 28 | /*35*/ .long sys_chown, sys_sync, sys_kill, sys_newstat, sys_sendfile |
| 29 | /*40*/ .long sys_newlstat, sys_dup, sys_pipe, sys_times, sys_getuid | 29 | /*40*/ .long sys_newlstat, sys_dup, sys_pipe, sys_times, sys_getuid |
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index 49e6dedd027d..d31975e6d6f6 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c | |||
| @@ -653,7 +653,7 @@ asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p) | |||
| 653 | if (unlikely(tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) | 653 | if (unlikely(tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) |
| 654 | result = AUDITSC_FAILURE; | 654 | result = AUDITSC_FAILURE; |
| 655 | 655 | ||
| 656 | audit_syscall_exit(current, result, regs->u_regs[UREG_I0]); | 656 | audit_syscall_exit(result, regs->u_regs[UREG_I0]); |
| 657 | } | 657 | } |
| 658 | 658 | ||
| 659 | if (!(current->ptrace & PT_PTRACED)) | 659 | if (!(current->ptrace & PT_PTRACED)) |
| @@ -677,8 +677,7 @@ asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p) | |||
| 677 | 677 | ||
| 678 | out: | 678 | out: |
| 679 | if (unlikely(current->audit_context) && !syscall_exit_p) | 679 | if (unlikely(current->audit_context) && !syscall_exit_p) |
| 680 | audit_syscall_entry(current, | 680 | audit_syscall_entry((test_thread_flag(TIF_32BIT) ? |
| 681 | (test_thread_flag(TIF_32BIT) ? | ||
| 682 | AUDIT_ARCH_SPARC : | 681 | AUDIT_ARCH_SPARC : |
| 683 | AUDIT_ARCH_SPARC64), | 682 | AUDIT_ARCH_SPARC64), |
| 684 | regs->u_regs[UREG_G1], | 683 | regs->u_regs[UREG_G1], |
diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S index f9b75760163c..bdf1f4d02e3f 100644 --- a/arch/sparc64/kernel/sys32.S +++ b/arch/sparc64/kernel/sys32.S | |||
| @@ -139,6 +139,7 @@ SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2) | |||
| 139 | SIGN2(sys32_splice, sys_splice, %o0, %o1) | 139 | SIGN2(sys32_splice, sys_splice, %o0, %o1) |
| 140 | SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5) | 140 | SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5) |
| 141 | SIGN2(sys32_tee, sys_tee, %o0, %o1) | 141 | SIGN2(sys32_tee, sys_tee, %o0, %o1) |
| 142 | SIGN1(sys32_vmsplice, compat_sys_vmsplice, %o0) | ||
| 142 | 143 | ||
| 143 | .globl sys32_mmap2 | 144 | .globl sys32_mmap2 |
| 144 | sys32_mmap2: | 145 | sys32_mmap2: |
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 62672cd92eca..d4b39cd30310 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S | |||
| @@ -25,7 +25,7 @@ sys_call_table32: | |||
| 25 | /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod | 25 | /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod |
| 26 | /*15*/ .word sys_chmod, sys32_lchown16, sparc_brk, sys32_perfctr, sys32_lseek | 26 | /*15*/ .word sys_chmod, sys32_lchown16, sparc_brk, sys32_perfctr, sys32_lseek |
| 27 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys32_setuid16, sys32_getuid16 | 27 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys32_setuid16, sys32_getuid16 |
| 28 | /*25*/ .word compat_sys_time, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause | 28 | /*25*/ .word sys32_vmsplice, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause |
| 29 | /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice | 29 | /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice |
| 30 | .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile | 30 | .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile |
| 31 | /*40*/ .word compat_sys_newlstat, sys_dup, sys_pipe, compat_sys_times, sys_getuid | 31 | /*40*/ .word compat_sys_newlstat, sys_dup, sys_pipe, compat_sys_times, sys_getuid |
| @@ -94,7 +94,7 @@ sys_call_table: | |||
| 94 | /*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod | 94 | /*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod |
| 95 | /*15*/ .word sys_chmod, sys_lchown, sparc_brk, sys_perfctr, sys_lseek | 95 | /*15*/ .word sys_chmod, sys_lchown, sparc_brk, sys_perfctr, sys_lseek |
| 96 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid | 96 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid |
| 97 | /*25*/ .word sys_nis_syscall, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall | 97 | /*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall |
| 98 | /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice | 98 | /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice |
| 99 | .word sys_nis_syscall, sys_sync, sys_kill, sys_newstat, sys_sendfile64 | 99 | .word sys_nis_syscall, sys_sync, sys_kill, sys_newstat, sys_sendfile64 |
| 100 | /*40*/ .word sys_newlstat, sys_dup, sys_pipe, sys_times, sys_nis_syscall | 100 | /*40*/ .word sys_newlstat, sys_dup, sys_pipe, sys_times, sys_nis_syscall |
diff --git a/arch/sparc64/mm/tlb.c b/arch/sparc64/mm/tlb.c index a079cf42505e..3f10fc921b00 100644 --- a/arch/sparc64/mm/tlb.c +++ b/arch/sparc64/mm/tlb.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <linux/percpu.h> | 8 | #include <linux/percpu.h> |
| 9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
| 10 | #include <linux/swap.h> | 10 | #include <linux/swap.h> |
| 11 | #include <linux/preempt.h> | ||
| 11 | 12 | ||
| 12 | #include <asm/pgtable.h> | 13 | #include <asm/pgtable.h> |
| 13 | #include <asm/pgalloc.h> | 14 | #include <asm/pgalloc.h> |
| @@ -24,6 +25,8 @@ void flush_tlb_pending(void) | |||
| 24 | { | 25 | { |
| 25 | struct mmu_gather *mp = &__get_cpu_var(mmu_gathers); | 26 | struct mmu_gather *mp = &__get_cpu_var(mmu_gathers); |
| 26 | 27 | ||
| 28 | preempt_disable(); | ||
| 29 | |||
| 27 | if (mp->tlb_nr) { | 30 | if (mp->tlb_nr) { |
| 28 | flush_tsb_user(mp); | 31 | flush_tsb_user(mp); |
| 29 | 32 | ||
| @@ -38,6 +41,8 @@ void flush_tlb_pending(void) | |||
| 38 | } | 41 | } |
| 39 | mp->tlb_nr = 0; | 42 | mp->tlb_nr = 0; |
| 40 | } | 43 | } |
| 44 | |||
| 45 | preempt_enable(); | ||
| 41 | } | 46 | } |
| 42 | 47 | ||
| 43 | void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig) | 48 | void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig) |
diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 05fbb20636cb..76e85bbaea55 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig | |||
| @@ -57,20 +57,6 @@ config STATIC_LINK | |||
| 57 | chroot, and you disable CONFIG_MODE_TT, you probably want to say Y | 57 | chroot, and you disable CONFIG_MODE_TT, you probably want to say Y |
| 58 | here. | 58 | here. |
| 59 | 59 | ||
| 60 | config HOST_2G_2G | ||
| 61 | bool "2G/2G host address space split" | ||
| 62 | default n | ||
| 63 | depends on MODE_TT | ||
| 64 | help | ||
| 65 | This is needed when the host on which you run has a 2G/2G memory | ||
| 66 | split, instead of the customary 3G/1G. | ||
| 67 | |||
| 68 | Note that to enable such a host | ||
| 69 | configuration, which makes sense only in some cases, you need special | ||
| 70 | host patches. | ||
| 71 | |||
| 72 | So, if you do not know what to do here, say 'N'. | ||
| 73 | |||
| 74 | config KERNEL_HALF_GIGS | 60 | config KERNEL_HALF_GIGS |
| 75 | int "Kernel address space size (in .5G units)" | 61 | int "Kernel address space size (in .5G units)" |
| 76 | default "1" | 62 | default "1" |
diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386 index 85e6a55b3b59..f6eb72d117b9 100644 --- a/arch/um/Kconfig.i386 +++ b/arch/um/Kconfig.i386 | |||
| @@ -16,6 +16,19 @@ config SEMAPHORE_SLEEPERS | |||
| 16 | bool | 16 | bool |
| 17 | default y | 17 | default y |
| 18 | 18 | ||
| 19 | config HOST_2G_2G | ||
| 20 | bool "2G/2G host address space split" | ||
| 21 | default n | ||
| 22 | help | ||
| 23 | This is needed when the host on which you run has a 2G/2G memory | ||
| 24 | split, instead of the customary 3G/1G. | ||
| 25 | |||
| 26 | Note that to enable such a host | ||
| 27 | configuration, which makes sense only in some cases, you need special | ||
| 28 | host patches. | ||
| 29 | |||
| 30 | So, if you do not know what to do here, say 'N'. | ||
| 31 | |||
| 19 | config TOP_ADDR | 32 | config TOP_ADDR |
| 20 | hex | 33 | hex |
| 21 | default 0xc0000000 if !HOST_2G_2G | 34 | default 0xc0000000 if !HOST_2G_2G |
| @@ -35,11 +48,13 @@ config 3_LEVEL_PGTABLES | |||
| 35 | 48 | ||
| 36 | config STUB_CODE | 49 | config STUB_CODE |
| 37 | hex | 50 | hex |
| 38 | default 0xbfffe000 | 51 | default 0xbfffe000 if !HOST_2G_2G |
| 52 | default 0x7fffe000 if HOST_2G_2G | ||
| 39 | 53 | ||
| 40 | config STUB_DATA | 54 | config STUB_DATA |
| 41 | hex | 55 | hex |
| 42 | default 0xbffff000 | 56 | default 0xbffff000 if !HOST_2G_2G |
| 57 | default 0x7ffff000 if HOST_2G_2G | ||
| 43 | 58 | ||
| 44 | config STUB_START | 59 | config STUB_START |
| 45 | hex | 60 | hex |
diff --git a/arch/um/Makefile b/arch/um/Makefile index a508e7a02891..f6ad832faf13 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile | |||
| @@ -96,7 +96,8 @@ PHONY += linux | |||
| 96 | all: linux | 96 | all: linux |
| 97 | 97 | ||
| 98 | linux: vmlinux | 98 | linux: vmlinux |
| 99 | ln -f $< $@ | 99 | @echo ' LINK $@' |
| 100 | $(Q)ln -f $< $@ | ||
| 100 | 101 | ||
| 101 | define archhelp | 102 | define archhelp |
| 102 | echo '* linux - Binary kernel image (./linux) - for backward' | 103 | echo '* linux - Binary kernel image (./linux) - for backward' |
| @@ -117,6 +118,10 @@ prepare: $(ARCH_DIR)/include/kern_constants.h | |||
| 117 | LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static | 118 | LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static |
| 118 | LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib | 119 | LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib |
| 119 | 120 | ||
| 121 | CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \ | ||
| 122 | $(call cc-option, -fno-stack-protector,) \ | ||
| 123 | $(call cc-option, -fno-stack-protector-all,) | ||
| 124 | |||
| 120 | CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT | 125 | CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT |
| 121 | CONFIG_KERNEL_STACK_ORDER ?= 2 | 126 | CONFIG_KERNEL_STACK_ORDER ?= 2 |
| 122 | STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) | 127 | STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) |
| @@ -203,8 +208,8 @@ endef | |||
| 203 | $(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h | 208 | $(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h |
| 204 | $(call filechk,umlconfig) | 209 | $(call filechk,umlconfig) |
| 205 | 210 | ||
| 206 | $(ARCH_DIR)/user-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.c | 211 | $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s: FORCE |
| 207 | $(CC) $(USER_CFLAGS) -S -o $@ $< | 212 | $(Q)$(MAKE) $(build)=$(ARCH_DIR)/sys-$(SUBARCH) $@ |
| 208 | 213 | ||
| 209 | define filechk_gen-asm-offsets | 214 | define filechk_gen-asm-offsets |
| 210 | (set -e; \ | 215 | (set -e; \ |
| @@ -219,13 +224,11 @@ define filechk_gen-asm-offsets | |||
| 219 | echo ""; ) | 224 | echo ""; ) |
| 220 | endef | 225 | endef |
| 221 | 226 | ||
| 222 | $(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/user-offsets.s | 227 | $(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s |
| 223 | $(call filechk,gen-asm-offsets) | 228 | $(call filechk,gen-asm-offsets) |
| 224 | 229 | ||
| 225 | CLEAN_FILES += $(ARCH_DIR)/user-offsets.s | ||
| 226 | |||
| 227 | $(ARCH_DIR)/include/kern_constants.h: $(objtree)/$(ARCH_DIR)/include | 230 | $(ARCH_DIR)/include/kern_constants.h: $(objtree)/$(ARCH_DIR)/include |
| 228 | @echo ' SYMLINK $@' | 231 | @echo ' SYMLINK $@' |
| 229 | $(Q) ln -sf ../../../include/asm-um/asm-offsets.h $@ | 232 | $(Q)ln -sf ../../../include/asm-um/asm-offsets.h $@ |
| 230 | 233 | ||
| 231 | export SUBARCH USER_CFLAGS OS | 234 | export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS |
diff --git a/arch/um/defconfig b/arch/um/defconfig index 80d30d19d750..402a74dc5026 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig | |||
| @@ -1,14 +1,13 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.12-rc6-mm1 | 3 | # Linux kernel version: 2.6.17-rc3 |
| 4 | # Tue Jun 14 18:22:21 2005 | 4 | # Fri Apr 28 09:31:20 2006 |
| 5 | # | 5 | # |
| 6 | CONFIG_GENERIC_HARDIRQS=y | 6 | CONFIG_GENERIC_HARDIRQS=y |
| 7 | CONFIG_UML=y | 7 | CONFIG_UML=y |
| 8 | CONFIG_MMU=y | 8 | CONFIG_MMU=y |
| 9 | CONFIG_UID16=y | ||
| 10 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
| 11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 9 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
| 10 | CONFIG_IRQ_RELEASE_METHOD=y | ||
| 12 | 11 | ||
| 13 | # | 12 | # |
| 14 | # UML-specific options | 13 | # UML-specific options |
| @@ -16,8 +15,50 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y | |||
| 16 | # CONFIG_MODE_TT is not set | 15 | # CONFIG_MODE_TT is not set |
| 17 | # CONFIG_STATIC_LINK is not set | 16 | # CONFIG_STATIC_LINK is not set |
| 18 | CONFIG_MODE_SKAS=y | 17 | CONFIG_MODE_SKAS=y |
| 18 | |||
| 19 | # | ||
| 20 | # Host processor type and features | ||
| 21 | # | ||
| 22 | # CONFIG_M386 is not set | ||
| 23 | # CONFIG_M486 is not set | ||
| 24 | # CONFIG_M586 is not set | ||
| 25 | # CONFIG_M586TSC is not set | ||
| 26 | # CONFIG_M586MMX is not set | ||
| 27 | CONFIG_M686=y | ||
| 28 | # CONFIG_MPENTIUMII is not set | ||
| 29 | # CONFIG_MPENTIUMIII is not set | ||
| 30 | # CONFIG_MPENTIUMM is not set | ||
| 31 | # CONFIG_MPENTIUM4 is not set | ||
| 32 | # CONFIG_MK6 is not set | ||
| 33 | # CONFIG_MK7 is not set | ||
| 34 | # CONFIG_MK8 is not set | ||
| 35 | # CONFIG_MCRUSOE is not set | ||
| 36 | # CONFIG_MEFFICEON is not set | ||
| 37 | # CONFIG_MWINCHIPC6 is not set | ||
| 38 | # CONFIG_MWINCHIP2 is not set | ||
| 39 | # CONFIG_MWINCHIP3D is not set | ||
| 40 | # CONFIG_MGEODEGX1 is not set | ||
| 41 | # CONFIG_MGEODE_LX is not set | ||
| 42 | # CONFIG_MCYRIXIII is not set | ||
| 43 | # CONFIG_MVIAC3_2 is not set | ||
| 44 | # CONFIG_X86_GENERIC is not set | ||
| 45 | CONFIG_X86_CMPXCHG=y | ||
| 46 | CONFIG_X86_XADD=y | ||
| 47 | CONFIG_X86_L1_CACHE_SHIFT=5 | ||
| 48 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | ||
| 49 | CONFIG_X86_PPRO_FENCE=y | ||
| 50 | CONFIG_X86_WP_WORKS_OK=y | ||
| 51 | CONFIG_X86_INVLPG=y | ||
| 52 | CONFIG_X86_BSWAP=y | ||
| 53 | CONFIG_X86_POPAD_OK=y | ||
| 54 | CONFIG_X86_CMPXCHG64=y | ||
| 55 | CONFIG_X86_GOOD_APIC=y | ||
| 56 | CONFIG_X86_USE_PPRO_CHECKSUM=y | ||
| 57 | CONFIG_X86_TSC=y | ||
| 19 | CONFIG_UML_X86=y | 58 | CONFIG_UML_X86=y |
| 20 | # CONFIG_64BIT is not set | 59 | # CONFIG_64BIT is not set |
| 60 | CONFIG_SEMAPHORE_SLEEPERS=y | ||
| 61 | # CONFIG_HOST_2G_2G is not set | ||
| 21 | CONFIG_TOP_ADDR=0xc0000000 | 62 | CONFIG_TOP_ADDR=0xc0000000 |
| 22 | # CONFIG_3_LEVEL_PGTABLES is not set | 63 | # CONFIG_3_LEVEL_PGTABLES is not set |
| 23 | CONFIG_STUB_CODE=0xbfffe000 | 64 | CONFIG_STUB_CODE=0xbfffe000 |
| @@ -25,22 +66,24 @@ CONFIG_STUB_DATA=0xbffff000 | |||
| 25 | CONFIG_STUB_START=0xbfffe000 | 66 | CONFIG_STUB_START=0xbfffe000 |
| 26 | CONFIG_ARCH_HAS_SC_SIGNALS=y | 67 | CONFIG_ARCH_HAS_SC_SIGNALS=y |
| 27 | CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y | 68 | CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y |
| 69 | CONFIG_GENERIC_HWEIGHT=y | ||
| 28 | CONFIG_SELECT_MEMORY_MODEL=y | 70 | CONFIG_SELECT_MEMORY_MODEL=y |
| 29 | CONFIG_FLATMEM_MANUAL=y | 71 | CONFIG_FLATMEM_MANUAL=y |
| 30 | # CONFIG_DISCONTIGMEM_MANUAL is not set | 72 | # CONFIG_DISCONTIGMEM_MANUAL is not set |
| 31 | # CONFIG_SPARSEMEM_MANUAL is not set | 73 | # CONFIG_SPARSEMEM_MANUAL is not set |
| 32 | CONFIG_FLATMEM=y | 74 | CONFIG_FLATMEM=y |
| 33 | CONFIG_FLAT_NODE_MEM_MAP=y | 75 | CONFIG_FLAT_NODE_MEM_MAP=y |
| 76 | # CONFIG_SPARSEMEM_STATIC is not set | ||
| 77 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
| 34 | CONFIG_LD_SCRIPT_DYN=y | 78 | CONFIG_LD_SCRIPT_DYN=y |
| 35 | CONFIG_NET=y | 79 | CONFIG_NET=y |
| 36 | CONFIG_BINFMT_ELF=y | 80 | CONFIG_BINFMT_ELF=y |
| 37 | CONFIG_BINFMT_MISC=m | 81 | CONFIG_BINFMT_MISC=m |
| 38 | # CONFIG_HOSTFS is not set | 82 | # CONFIG_HOSTFS is not set |
| 83 | # CONFIG_HPPFS is not set | ||
| 39 | CONFIG_MCONSOLE=y | 84 | CONFIG_MCONSOLE=y |
| 40 | # CONFIG_MAGIC_SYSRQ is not set | 85 | # CONFIG_MAGIC_SYSRQ is not set |
| 41 | # CONFIG_HOST_2G_2G is not set | ||
| 42 | CONFIG_NEST_LEVEL=0 | 86 | CONFIG_NEST_LEVEL=0 |
| 43 | CONFIG_KERNEL_HALF_GIGS=1 | ||
| 44 | # CONFIG_HIGHMEM is not set | 87 | # CONFIG_HIGHMEM is not set |
| 45 | CONFIG_KERNEL_STACK_ORDER=2 | 88 | CONFIG_KERNEL_STACK_ORDER=2 |
| 46 | CONFIG_UML_REAL_TIME_CLOCK=y | 89 | CONFIG_UML_REAL_TIME_CLOCK=y |
| @@ -49,7 +92,6 @@ CONFIG_UML_REAL_TIME_CLOCK=y | |||
| 49 | # Code maturity level options | 92 | # Code maturity level options |
| 50 | # | 93 | # |
| 51 | CONFIG_EXPERIMENTAL=y | 94 | CONFIG_EXPERIMENTAL=y |
| 52 | CONFIG_CLEAN_COMPILE=y | ||
| 53 | CONFIG_BROKEN_ON_SMP=y | 95 | CONFIG_BROKEN_ON_SMP=y |
| 54 | CONFIG_INIT_ENV_ARG_LIMIT=32 | 96 | CONFIG_INIT_ENV_ARG_LIMIT=32 |
| 55 | 97 | ||
| @@ -57,6 +99,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 | |||
| 57 | # General setup | 99 | # General setup |
| 58 | # | 100 | # |
| 59 | CONFIG_LOCALVERSION="" | 101 | CONFIG_LOCALVERSION="" |
| 102 | CONFIG_LOCALVERSION_AUTO=y | ||
| 60 | CONFIG_SWAP=y | 103 | CONFIG_SWAP=y |
| 61 | CONFIG_SYSVIPC=y | 104 | CONFIG_SYSVIPC=y |
| 62 | CONFIG_POSIX_MQUEUE=y | 105 | CONFIG_POSIX_MQUEUE=y |
| @@ -64,26 +107,28 @@ CONFIG_BSD_PROCESS_ACCT=y | |||
| 64 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set | 107 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set |
| 65 | CONFIG_SYSCTL=y | 108 | CONFIG_SYSCTL=y |
| 66 | # CONFIG_AUDIT is not set | 109 | # CONFIG_AUDIT is not set |
| 67 | # CONFIG_HOTPLUG is not set | ||
| 68 | CONFIG_KOBJECT_UEVENT=y | ||
| 69 | CONFIG_IKCONFIG=y | 110 | CONFIG_IKCONFIG=y |
| 70 | CONFIG_IKCONFIG_PROC=y | 111 | CONFIG_IKCONFIG_PROC=y |
| 112 | # CONFIG_RELAY is not set | ||
| 113 | CONFIG_INITRAMFS_SOURCE="" | ||
| 114 | CONFIG_UID16=y | ||
| 115 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
| 71 | # CONFIG_EMBEDDED is not set | 116 | # CONFIG_EMBEDDED is not set |
| 72 | CONFIG_KALLSYMS=y | 117 | CONFIG_KALLSYMS=y |
| 73 | # CONFIG_KALLSYMS_ALL is not set | 118 | # CONFIG_KALLSYMS_ALL is not set |
| 74 | CONFIG_KALLSYMS_EXTRA_PASS=y | 119 | CONFIG_KALLSYMS_EXTRA_PASS=y |
| 120 | CONFIG_HOTPLUG=y | ||
| 75 | CONFIG_PRINTK=y | 121 | CONFIG_PRINTK=y |
| 76 | CONFIG_BUG=y | 122 | CONFIG_BUG=y |
| 123 | CONFIG_ELF_CORE=y | ||
| 77 | CONFIG_BASE_FULL=y | 124 | CONFIG_BASE_FULL=y |
| 78 | CONFIG_FUTEX=y | 125 | CONFIG_FUTEX=y |
| 79 | CONFIG_EPOLL=y | 126 | CONFIG_EPOLL=y |
| 80 | CONFIG_SHMEM=y | 127 | CONFIG_SHMEM=y |
| 81 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 128 | CONFIG_SLAB=y |
| 82 | CONFIG_CC_ALIGN_LABELS=0 | ||
| 83 | CONFIG_CC_ALIGN_LOOPS=0 | ||
| 84 | CONFIG_CC_ALIGN_JUMPS=0 | ||
| 85 | # CONFIG_TINY_SHMEM is not set | 129 | # CONFIG_TINY_SHMEM is not set |
| 86 | CONFIG_BASE_SMALL=0 | 130 | CONFIG_BASE_SMALL=0 |
| 131 | # CONFIG_SLOB is not set | ||
| 87 | 132 | ||
| 88 | # | 133 | # |
| 89 | # Loadable module support | 134 | # Loadable module support |
| @@ -91,18 +136,43 @@ CONFIG_BASE_SMALL=0 | |||
| 91 | CONFIG_MODULES=y | 136 | CONFIG_MODULES=y |
| 92 | CONFIG_MODULE_UNLOAD=y | 137 | CONFIG_MODULE_UNLOAD=y |
| 93 | # CONFIG_MODULE_FORCE_UNLOAD is not set | 138 | # CONFIG_MODULE_FORCE_UNLOAD is not set |
| 94 | CONFIG_OBSOLETE_MODPARM=y | ||
| 95 | # CONFIG_MODVERSIONS is not set | 139 | # CONFIG_MODVERSIONS is not set |
| 96 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 140 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
| 97 | CONFIG_KMOD=y | 141 | CONFIG_KMOD=y |
| 98 | 142 | ||
| 99 | # | 143 | # |
| 100 | # Generic Driver Options | 144 | # Block layer |
| 101 | # | 145 | # |
| 102 | CONFIG_STANDALONE=y | 146 | # CONFIG_LBD is not set |
| 103 | CONFIG_PREVENT_FIRMWARE_BUILD=y | 147 | # CONFIG_BLK_DEV_IO_TRACE is not set |
| 104 | # CONFIG_FW_LOADER is not set | 148 | # CONFIG_LSF is not set |
| 105 | # CONFIG_DEBUG_DRIVER is not set | 149 | |
| 150 | # | ||
| 151 | # IO Schedulers | ||
| 152 | # | ||
| 153 | CONFIG_IOSCHED_NOOP=y | ||
| 154 | CONFIG_IOSCHED_AS=y | ||
| 155 | CONFIG_IOSCHED_DEADLINE=y | ||
| 156 | CONFIG_IOSCHED_CFQ=y | ||
| 157 | CONFIG_DEFAULT_AS=y | ||
| 158 | # CONFIG_DEFAULT_DEADLINE is not set | ||
| 159 | # CONFIG_DEFAULT_CFQ is not set | ||
| 160 | # CONFIG_DEFAULT_NOOP is not set | ||
| 161 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
| 162 | |||
| 163 | # | ||
| 164 | # Block devices | ||
| 165 | # | ||
| 166 | CONFIG_BLK_DEV_UBD=y | ||
| 167 | # CONFIG_BLK_DEV_UBD_SYNC is not set | ||
| 168 | CONFIG_BLK_DEV_COW_COMMON=y | ||
| 169 | # CONFIG_MMAPPER is not set | ||
| 170 | CONFIG_BLK_DEV_LOOP=m | ||
| 171 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
| 172 | CONFIG_BLK_DEV_NBD=m | ||
| 173 | # CONFIG_BLK_DEV_RAM is not set | ||
| 174 | # CONFIG_BLK_DEV_INITRD is not set | ||
| 175 | # CONFIG_ATA_OVER_ETH is not set | ||
| 106 | 176 | ||
| 107 | # | 177 | # |
| 108 | # Character Devices | 178 | # Character Devices |
| @@ -127,50 +197,23 @@ CONFIG_UML_SOUND=m | |||
| 127 | CONFIG_SOUND=m | 197 | CONFIG_SOUND=m |
| 128 | CONFIG_HOSTAUDIO=m | 198 | CONFIG_HOSTAUDIO=m |
| 129 | CONFIG_UML_RANDOM=y | 199 | CONFIG_UML_RANDOM=y |
| 130 | # CONFIG_MMAPPER is not set | ||
| 131 | |||
| 132 | # | ||
| 133 | # Block devices | ||
| 134 | # | ||
| 135 | CONFIG_BLK_DEV_UBD=y | ||
| 136 | CONFIG_BLK_DEV_UBD_SYNC=y | ||
| 137 | CONFIG_BLK_DEV_COW_COMMON=y | ||
| 138 | CONFIG_BLK_DEV_LOOP=m | ||
| 139 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
| 140 | CONFIG_BLK_DEV_NBD=m | ||
| 141 | # CONFIG_BLK_DEV_RAM is not set | ||
| 142 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
| 143 | CONFIG_INITRAMFS_SOURCE="" | ||
| 144 | # CONFIG_LBD is not set | ||
| 145 | |||
| 146 | # | ||
| 147 | # IO Schedulers | ||
| 148 | # | ||
| 149 | CONFIG_IOSCHED_NOOP=y | ||
| 150 | CONFIG_IOSCHED_AS=y | ||
| 151 | CONFIG_IOSCHED_DEADLINE=y | ||
| 152 | CONFIG_IOSCHED_CFQ=y | ||
| 153 | # CONFIG_ATA_OVER_ETH is not set | ||
| 154 | CONFIG_NETDEVICES=y | ||
| 155 | 200 | ||
| 156 | # | 201 | # |
| 157 | # UML Network Devices | 202 | # Generic Driver Options |
| 158 | # | 203 | # |
| 159 | CONFIG_UML_NET=y | 204 | CONFIG_STANDALONE=y |
| 160 | CONFIG_UML_NET_ETHERTAP=y | 205 | CONFIG_PREVENT_FIRMWARE_BUILD=y |
| 161 | CONFIG_UML_NET_TUNTAP=y | 206 | # CONFIG_FW_LOADER is not set |
| 162 | CONFIG_UML_NET_SLIP=y | 207 | # CONFIG_DEBUG_DRIVER is not set |
| 163 | CONFIG_UML_NET_DAEMON=y | ||
| 164 | CONFIG_UML_NET_MCAST=y | ||
| 165 | CONFIG_UML_NET_SLIRP=y | ||
| 166 | 208 | ||
| 167 | # | 209 | # |
| 168 | # Networking support | 210 | # Networking |
| 169 | # | 211 | # |
| 170 | 212 | ||
| 171 | # | 213 | # |
| 172 | # Networking options | 214 | # Networking options |
| 173 | # | 215 | # |
| 216 | # CONFIG_NETDEBUG is not set | ||
| 174 | CONFIG_PACKET=y | 217 | CONFIG_PACKET=y |
| 175 | CONFIG_PACKET_MMAP=y | 218 | CONFIG_PACKET_MMAP=y |
| 176 | CONFIG_UNIX=y | 219 | CONFIG_UNIX=y |
| @@ -178,6 +221,7 @@ CONFIG_UNIX=y | |||
| 178 | CONFIG_INET=y | 221 | CONFIG_INET=y |
| 179 | # CONFIG_IP_MULTICAST is not set | 222 | # CONFIG_IP_MULTICAST is not set |
| 180 | # CONFIG_IP_ADVANCED_ROUTER is not set | 223 | # CONFIG_IP_ADVANCED_ROUTER is not set |
| 224 | CONFIG_IP_FIB_HASH=y | ||
| 181 | # CONFIG_IP_PNP is not set | 225 | # CONFIG_IP_PNP is not set |
| 182 | # CONFIG_NET_IPIP is not set | 226 | # CONFIG_NET_IPIP is not set |
| 183 | # CONFIG_NET_IPGRE is not set | 227 | # CONFIG_NET_IPGRE is not set |
| @@ -186,27 +230,31 @@ CONFIG_INET=y | |||
| 186 | # CONFIG_INET_AH is not set | 230 | # CONFIG_INET_AH is not set |
| 187 | # CONFIG_INET_ESP is not set | 231 | # CONFIG_INET_ESP is not set |
| 188 | # CONFIG_INET_IPCOMP is not set | 232 | # CONFIG_INET_IPCOMP is not set |
| 233 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
| 189 | # CONFIG_INET_TUNNEL is not set | 234 | # CONFIG_INET_TUNNEL is not set |
| 190 | CONFIG_IP_TCPDIAG=y | 235 | CONFIG_INET_DIAG=y |
| 191 | # CONFIG_IP_TCPDIAG_IPV6 is not set | 236 | CONFIG_INET_TCP_DIAG=y |
| 192 | 237 | # CONFIG_TCP_CONG_ADVANCED is not set | |
| 193 | # | ||
| 194 | # TCP congestion control | ||
| 195 | # | ||
| 196 | CONFIG_TCP_CONG_BIC=y | 238 | CONFIG_TCP_CONG_BIC=y |
| 197 | CONFIG_TCP_CONG_WESTWOOD=y | ||
| 198 | CONFIG_TCP_CONG_HTCP=y | ||
| 199 | # CONFIG_TCP_CONG_HSTCP is not set | ||
| 200 | # CONFIG_TCP_CONG_HYBLA is not set | ||
| 201 | # CONFIG_TCP_CONG_VEGAS is not set | ||
| 202 | # CONFIG_TCP_CONG_SCALABLE is not set | ||
| 203 | # CONFIG_IPV6 is not set | 239 | # CONFIG_IPV6 is not set |
| 240 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
| 241 | # CONFIG_INET6_TUNNEL is not set | ||
| 204 | # CONFIG_NETFILTER is not set | 242 | # CONFIG_NETFILTER is not set |
| 205 | 243 | ||
| 206 | # | 244 | # |
| 245 | # DCCP Configuration (EXPERIMENTAL) | ||
| 246 | # | ||
| 247 | # CONFIG_IP_DCCP is not set | ||
| 248 | |||
| 249 | # | ||
| 207 | # SCTP Configuration (EXPERIMENTAL) | 250 | # SCTP Configuration (EXPERIMENTAL) |
| 208 | # | 251 | # |
| 209 | # CONFIG_IP_SCTP is not set | 252 | # CONFIG_IP_SCTP is not set |
| 253 | |||
| 254 | # | ||
| 255 | # TIPC Configuration (EXPERIMENTAL) | ||
| 256 | # | ||
| 257 | # CONFIG_TIPC is not set | ||
| 210 | # CONFIG_ATM is not set | 258 | # CONFIG_ATM is not set |
| 211 | # CONFIG_BRIDGE is not set | 259 | # CONFIG_BRIDGE is not set |
| 212 | # CONFIG_VLAN_8021Q is not set | 260 | # CONFIG_VLAN_8021Q is not set |
| @@ -224,27 +272,47 @@ CONFIG_TCP_CONG_HTCP=y | |||
| 224 | # QoS and/or fair queueing | 272 | # QoS and/or fair queueing |
| 225 | # | 273 | # |
| 226 | # CONFIG_NET_SCHED is not set | 274 | # CONFIG_NET_SCHED is not set |
| 227 | # CONFIG_NET_CLS_ROUTE is not set | ||
| 228 | 275 | ||
| 229 | # | 276 | # |
| 230 | # Network testing | 277 | # Network testing |
| 231 | # | 278 | # |
| 232 | # CONFIG_NET_PKTGEN is not set | 279 | # CONFIG_NET_PKTGEN is not set |
| 233 | # CONFIG_KGDBOE is not set | ||
| 234 | # CONFIG_NETPOLL is not set | ||
| 235 | # CONFIG_NETPOLL_RX is not set | ||
| 236 | # CONFIG_NETPOLL_TRAP is not set | ||
| 237 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
| 238 | # CONFIG_HAMRADIO is not set | 280 | # CONFIG_HAMRADIO is not set |
| 239 | # CONFIG_IRDA is not set | 281 | # CONFIG_IRDA is not set |
| 240 | # CONFIG_BT is not set | 282 | # CONFIG_BT is not set |
| 241 | # CONFIG_IEEE80211 is not set | 283 | # CONFIG_IEEE80211 is not set |
| 284 | |||
| 285 | # | ||
| 286 | # UML Network Devices | ||
| 287 | # | ||
| 288 | CONFIG_UML_NET=y | ||
| 289 | CONFIG_UML_NET_ETHERTAP=y | ||
| 290 | CONFIG_UML_NET_TUNTAP=y | ||
| 291 | CONFIG_UML_NET_SLIP=y | ||
| 292 | CONFIG_UML_NET_DAEMON=y | ||
| 293 | CONFIG_UML_NET_MCAST=y | ||
| 294 | # CONFIG_UML_NET_PCAP is not set | ||
| 295 | CONFIG_UML_NET_SLIRP=y | ||
| 296 | |||
| 297 | # | ||
| 298 | # Network device support | ||
| 299 | # | ||
| 300 | CONFIG_NETDEVICES=y | ||
| 242 | CONFIG_DUMMY=m | 301 | CONFIG_DUMMY=m |
| 243 | # CONFIG_BONDING is not set | 302 | # CONFIG_BONDING is not set |
| 244 | # CONFIG_EQUALIZER is not set | 303 | # CONFIG_EQUALIZER is not set |
| 245 | CONFIG_TUN=m | 304 | CONFIG_TUN=m |
| 246 | 305 | ||
| 247 | # | 306 | # |
| 307 | # PHY device support | ||
| 308 | # | ||
| 309 | |||
| 310 | # | ||
| 311 | # Wireless LAN (non-hamradio) | ||
| 312 | # | ||
| 313 | # CONFIG_NET_RADIO is not set | ||
| 314 | |||
| 315 | # | ||
| 248 | # Wan interfaces | 316 | # Wan interfaces |
| 249 | # | 317 | # |
| 250 | # CONFIG_WAN is not set | 318 | # CONFIG_WAN is not set |
| @@ -263,6 +331,13 @@ CONFIG_SLIP=m | |||
| 263 | # CONFIG_SLIP_MODE_SLIP6 is not set | 331 | # CONFIG_SLIP_MODE_SLIP6 is not set |
| 264 | # CONFIG_SHAPER is not set | 332 | # CONFIG_SHAPER is not set |
| 265 | # CONFIG_NETCONSOLE is not set | 333 | # CONFIG_NETCONSOLE is not set |
| 334 | # CONFIG_NETPOLL is not set | ||
| 335 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
| 336 | |||
| 337 | # | ||
| 338 | # Connector - unified userspace <-> kernelspace linker | ||
| 339 | # | ||
| 340 | # CONFIG_CONNECTOR is not set | ||
| 266 | 341 | ||
| 267 | # | 342 | # |
| 268 | # File systems | 343 | # File systems |
| @@ -274,17 +349,14 @@ CONFIG_EXT3_FS=y | |||
| 274 | # CONFIG_EXT3_FS_XATTR is not set | 349 | # CONFIG_EXT3_FS_XATTR is not set |
| 275 | CONFIG_JBD=y | 350 | CONFIG_JBD=y |
| 276 | # CONFIG_JBD_DEBUG is not set | 351 | # CONFIG_JBD_DEBUG is not set |
| 277 | # CONFIG_REISER4_FS is not set | ||
| 278 | CONFIG_REISERFS_FS=y | 352 | CONFIG_REISERFS_FS=y |
| 279 | # CONFIG_REISERFS_CHECK is not set | 353 | # CONFIG_REISERFS_CHECK is not set |
| 280 | # CONFIG_REISERFS_PROC_INFO is not set | 354 | # CONFIG_REISERFS_PROC_INFO is not set |
| 281 | # CONFIG_REISERFS_FS_XATTR is not set | 355 | # CONFIG_REISERFS_FS_XATTR is not set |
| 282 | # CONFIG_JFS_FS is not set | 356 | # CONFIG_JFS_FS is not set |
| 283 | 357 | # CONFIG_FS_POSIX_ACL is not set | |
| 284 | # | ||
| 285 | # XFS support | ||
| 286 | # | ||
| 287 | # CONFIG_XFS_FS is not set | 358 | # CONFIG_XFS_FS is not set |
| 359 | # CONFIG_OCFS2_FS is not set | ||
| 288 | # CONFIG_MINIX_FS is not set | 360 | # CONFIG_MINIX_FS is not set |
| 289 | # CONFIG_ROMFS_FS is not set | 361 | # CONFIG_ROMFS_FS is not set |
| 290 | CONFIG_INOTIFY=y | 362 | CONFIG_INOTIFY=y |
| @@ -295,11 +367,6 @@ CONFIG_QUOTACTL=y | |||
| 295 | CONFIG_DNOTIFY=y | 367 | CONFIG_DNOTIFY=y |
| 296 | CONFIG_AUTOFS_FS=m | 368 | CONFIG_AUTOFS_FS=m |
| 297 | CONFIG_AUTOFS4_FS=m | 369 | CONFIG_AUTOFS4_FS=m |
| 298 | |||
| 299 | # | ||
| 300 | # Caches | ||
| 301 | # | ||
| 302 | # CONFIG_FSCACHE is not set | ||
| 303 | # CONFIG_FUSE_FS is not set | 370 | # CONFIG_FUSE_FS is not set |
| 304 | 371 | ||
| 305 | # | 372 | # |
| @@ -323,14 +390,10 @@ CONFIG_JOLIET=y | |||
| 323 | CONFIG_PROC_FS=y | 390 | CONFIG_PROC_FS=y |
| 324 | CONFIG_PROC_KCORE=y | 391 | CONFIG_PROC_KCORE=y |
| 325 | CONFIG_SYSFS=y | 392 | CONFIG_SYSFS=y |
| 326 | # CONFIG_DEVFS_FS is not set | ||
| 327 | # CONFIG_DEVPTS_FS_XATTR is not set | ||
| 328 | CONFIG_TMPFS=y | 393 | CONFIG_TMPFS=y |
| 329 | # CONFIG_TMPFS_XATTR is not set | ||
| 330 | # CONFIG_HUGETLB_PAGE is not set | 394 | # CONFIG_HUGETLB_PAGE is not set |
| 331 | CONFIG_RAMFS=y | 395 | CONFIG_RAMFS=y |
| 332 | # CONFIG_CONFIGFS_FS is not set | 396 | # CONFIG_CONFIGFS_FS is not set |
| 333 | # CONFIG_RELAYFS_FS is not set | ||
| 334 | 397 | ||
| 335 | # | 398 | # |
| 336 | # Miscellaneous filesystems | 399 | # Miscellaneous filesystems |
| @@ -430,6 +493,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" | |||
| 430 | # Library routines | 493 | # Library routines |
| 431 | # | 494 | # |
| 432 | # CONFIG_CRC_CCITT is not set | 495 | # CONFIG_CRC_CCITT is not set |
| 496 | # CONFIG_CRC16 is not set | ||
| 433 | CONFIG_CRC32=m | 497 | CONFIG_CRC32=m |
| 434 | # CONFIG_LIBCRC32C is not set | 498 | # CONFIG_LIBCRC32C is not set |
| 435 | 499 | ||
| @@ -448,12 +512,18 @@ CONFIG_LOG_BUF_SHIFT=14 | |||
| 448 | CONFIG_DETECT_SOFTLOCKUP=y | 512 | CONFIG_DETECT_SOFTLOCKUP=y |
| 449 | # CONFIG_SCHEDSTATS is not set | 513 | # CONFIG_SCHEDSTATS is not set |
| 450 | CONFIG_DEBUG_SLAB=y | 514 | CONFIG_DEBUG_SLAB=y |
| 515 | # CONFIG_DEBUG_SLAB_LEAK is not set | ||
| 516 | # CONFIG_DEBUG_MUTEXES is not set | ||
| 451 | # CONFIG_DEBUG_SPINLOCK is not set | 517 | # CONFIG_DEBUG_SPINLOCK is not set |
| 452 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 518 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
| 453 | # CONFIG_DEBUG_KOBJECT is not set | 519 | # CONFIG_DEBUG_KOBJECT is not set |
| 454 | CONFIG_DEBUG_INFO=y | 520 | CONFIG_DEBUG_INFO=y |
| 455 | # CONFIG_DEBUG_FS is not set | 521 | # CONFIG_DEBUG_FS is not set |
| 522 | # CONFIG_DEBUG_VM is not set | ||
| 456 | CONFIG_FRAME_POINTER=y | 523 | CONFIG_FRAME_POINTER=y |
| 524 | # CONFIG_UNWIND_INFO is not set | ||
| 525 | CONFIG_FORCED_INLINING=y | ||
| 526 | # CONFIG_RCU_TORTURE_TEST is not set | ||
| 457 | # CONFIG_GPROF is not set | 527 | # CONFIG_GPROF is not set |
| 458 | # CONFIG_GCOV is not set | 528 | # CONFIG_GCOV is not set |
| 459 | # CONFIG_SYSCALL_DEBUG is not set | 529 | # CONFIG_SYSCALL_DEBUG is not set |
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c index 6ab852bfcd3a..0ec4052db9c5 100644 --- a/arch/um/drivers/cow_user.c +++ b/arch/um/drivers/cow_user.c | |||
| @@ -100,7 +100,7 @@ struct cow_header_v3_broken { | |||
| 100 | __u32 alignment; | 100 | __u32 alignment; |
| 101 | __u32 cow_format; | 101 | __u32 cow_format; |
| 102 | char backing_file[PATH_LEN_V3]; | 102 | char backing_file[PATH_LEN_V3]; |
| 103 | } __attribute__((packed)); | 103 | }; |
| 104 | 104 | ||
| 105 | /* COW format definitions - for now, we have only the usual COW bitmap */ | 105 | /* COW format definitions - for now, we have only the usual COW bitmap */ |
| 106 | #define COW_BITMAP 0 | 106 | #define COW_BITMAP 0 |
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index c39ea3abeda4..2ffda012385e 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
| @@ -89,16 +89,18 @@ void sigio_handler(int sig, union uml_pt_regs *regs) | |||
| 89 | struct irq_fd *irq_fd; | 89 | struct irq_fd *irq_fd; |
| 90 | int n; | 90 | int n; |
| 91 | 91 | ||
| 92 | if(smp_sigio_handler()) return; | 92 | if (smp_sigio_handler()) |
| 93 | while(1){ | 93 | return; |
| 94 | |||
| 95 | while (1) { | ||
| 94 | n = os_waiting_for_events(active_fds); | 96 | n = os_waiting_for_events(active_fds); |
| 95 | if (n <= 0) { | 97 | if (n <= 0) { |
| 96 | if(n == -EINTR) continue; | 98 | if(n == -EINTR) continue; |
| 97 | else break; | 99 | else break; |
| 98 | } | 100 | } |
| 99 | 101 | ||
| 100 | for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){ | 102 | for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { |
| 101 | if(irq_fd->current_events != 0){ | 103 | if (irq_fd->current_events != 0) { |
| 102 | irq_fd->current_events = 0; | 104 | irq_fd->current_events = 0; |
| 103 | do_IRQ(irq_fd->irq, regs); | 105 | do_IRQ(irq_fd->irq, regs); |
| 104 | } | 106 | } |
| @@ -110,19 +112,17 @@ void sigio_handler(int sig, union uml_pt_regs *regs) | |||
| 110 | 112 | ||
| 111 | static void maybe_sigio_broken(int fd, int type) | 113 | static void maybe_sigio_broken(int fd, int type) |
| 112 | { | 114 | { |
| 113 | if(os_isatty(fd)){ | 115 | if (os_isatty(fd)) { |
| 114 | if((type == IRQ_WRITE) && !pty_output_sigio){ | 116 | if ((type == IRQ_WRITE) && !pty_output_sigio) { |
| 115 | write_sigio_workaround(); | 117 | write_sigio_workaround(); |
| 116 | add_sigio_fd(fd, 0); | 118 | add_sigio_fd(fd, 0); |
| 117 | } | 119 | } else if ((type == IRQ_READ) && !pty_close_sigio) { |
| 118 | else if((type == IRQ_READ) && !pty_close_sigio){ | ||
| 119 | write_sigio_workaround(); | 120 | write_sigio_workaround(); |
| 120 | add_sigio_fd(fd, 1); | 121 | add_sigio_fd(fd, 1); |
| 121 | } | 122 | } |
| 122 | } | 123 | } |
| 123 | } | 124 | } |
| 124 | 125 | ||
| 125 | |||
| 126 | int activate_fd(int irq, int fd, int type, void *dev_id) | 126 | int activate_fd(int irq, int fd, int type, void *dev_id) |
| 127 | { | 127 | { |
| 128 | struct pollfd *tmp_pfd; | 128 | struct pollfd *tmp_pfd; |
| @@ -132,16 +132,18 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
| 132 | 132 | ||
| 133 | pid = os_getpid(); | 133 | pid = os_getpid(); |
| 134 | err = os_set_fd_async(fd, pid); | 134 | err = os_set_fd_async(fd, pid); |
| 135 | if(err < 0) | 135 | if (err < 0) |
| 136 | goto out; | 136 | goto out; |
| 137 | 137 | ||
| 138 | new_fd = um_kmalloc(sizeof(*new_fd)); | 138 | new_fd = um_kmalloc(sizeof(*new_fd)); |
| 139 | err = -ENOMEM; | 139 | err = -ENOMEM; |
| 140 | if(new_fd == NULL) | 140 | if (new_fd == NULL) |
| 141 | goto out; | 141 | goto out; |
| 142 | 142 | ||
| 143 | if(type == IRQ_READ) events = UM_POLLIN | UM_POLLPRI; | 143 | if (type == IRQ_READ) |
| 144 | else events = UM_POLLOUT; | 144 | events = UM_POLLIN | UM_POLLPRI; |
| 145 | else | ||
| 146 | events = UM_POLLOUT; | ||
| 145 | *new_fd = ((struct irq_fd) { .next = NULL, | 147 | *new_fd = ((struct irq_fd) { .next = NULL, |
| 146 | .id = dev_id, | 148 | .id = dev_id, |
| 147 | .fd = fd, | 149 | .fd = fd, |
| @@ -165,8 +167,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
| 165 | * a semaphore. | 167 | * a semaphore. |
| 166 | */ | 168 | */ |
| 167 | flags = irq_lock(); | 169 | flags = irq_lock(); |
| 168 | for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){ | 170 | for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { |
| 169 | if((irq_fd->fd == fd) && (irq_fd->type == type)){ | 171 | if ((irq_fd->fd == fd) && (irq_fd->type == type)) { |
| 170 | printk("Registering fd %d twice\n", fd); | 172 | printk("Registering fd %d twice\n", fd); |
| 171 | printk("Irqs : %d, %d\n", irq_fd->irq, irq); | 173 | printk("Irqs : %d, %d\n", irq_fd->irq, irq); |
| 172 | printk("Ids : 0x%p, 0x%p\n", irq_fd->id, dev_id); | 174 | printk("Ids : 0x%p, 0x%p\n", irq_fd->id, dev_id); |
| @@ -175,13 +177,13 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
| 175 | } | 177 | } |
| 176 | 178 | ||
| 177 | /*-------------*/ | 179 | /*-------------*/ |
| 178 | if(type == IRQ_WRITE) | 180 | if (type == IRQ_WRITE) |
| 179 | fd = -1; | 181 | fd = -1; |
| 180 | 182 | ||
| 181 | tmp_pfd = NULL; | 183 | tmp_pfd = NULL; |
| 182 | n = 0; | 184 | n = 0; |
| 183 | 185 | ||
| 184 | while(1){ | 186 | while (1) { |
| 185 | n = os_create_pollfd(fd, events, tmp_pfd, n); | 187 | n = os_create_pollfd(fd, events, tmp_pfd, n); |
| 186 | if (n == 0) | 188 | if (n == 0) |
| 187 | break; | 189 | break; |
| @@ -198,10 +200,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
| 198 | * then we free the buffer tmp_fds and try again. | 200 | * then we free the buffer tmp_fds and try again. |
| 199 | */ | 201 | */ |
| 200 | irq_unlock(flags); | 202 | irq_unlock(flags); |
| 201 | if (tmp_pfd != NULL) { | 203 | kfree(tmp_pfd); |
| 202 | kfree(tmp_pfd); | 204 | tmp_pfd = NULL; |
| 203 | tmp_pfd = NULL; | ||
| 204 | } | ||
| 205 | 205 | ||
| 206 | tmp_pfd = um_kmalloc(n); | 206 | tmp_pfd = um_kmalloc(n); |
| 207 | if (tmp_pfd == NULL) | 207 | if (tmp_pfd == NULL) |
| @@ -249,7 +249,7 @@ static int same_irq_and_dev(struct irq_fd *irq, void *d) | |||
| 249 | { | 249 | { |
| 250 | struct irq_and_dev *data = d; | 250 | struct irq_and_dev *data = d; |
| 251 | 251 | ||
| 252 | return((irq->irq == data->irq) && (irq->id == data->dev)); | 252 | return ((irq->irq == data->irq) && (irq->id == data->dev)); |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | void free_irq_by_irq_and_dev(unsigned int irq, void *dev) | 255 | void free_irq_by_irq_and_dev(unsigned int irq, void *dev) |
| @@ -262,7 +262,7 @@ void free_irq_by_irq_and_dev(unsigned int irq, void *dev) | |||
| 262 | 262 | ||
| 263 | static int same_fd(struct irq_fd *irq, void *fd) | 263 | static int same_fd(struct irq_fd *irq, void *fd) |
| 264 | { | 264 | { |
| 265 | return(irq->fd == *((int *) fd)); | 265 | return (irq->fd == *((int *)fd)); |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | void free_irq_by_fd(int fd) | 268 | void free_irq_by_fd(int fd) |
| @@ -276,16 +276,17 @@ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out) | |||
| 276 | int i = 0; | 276 | int i = 0; |
| 277 | int fdi; | 277 | int fdi; |
| 278 | 278 | ||
| 279 | for(irq=active_fds; irq != NULL; irq = irq->next){ | 279 | for (irq = active_fds; irq != NULL; irq = irq->next) { |
| 280 | if((irq->fd == fd) && (irq->irq == irqnum)) break; | 280 | if ((irq->fd == fd) && (irq->irq == irqnum)) |
| 281 | break; | ||
| 281 | i++; | 282 | i++; |
| 282 | } | 283 | } |
| 283 | if(irq == NULL){ | 284 | if (irq == NULL) { |
| 284 | printk("find_irq_by_fd doesn't have descriptor %d\n", fd); | 285 | printk("find_irq_by_fd doesn't have descriptor %d\n", fd); |
| 285 | goto out; | 286 | goto out; |
| 286 | } | 287 | } |
| 287 | fdi = os_get_pollfd(i); | 288 | fdi = os_get_pollfd(i); |
| 288 | if((fdi != -1) && (fdi != fd)){ | 289 | if ((fdi != -1) && (fdi != fd)) { |
| 289 | printk("find_irq_by_fd - mismatch between active_fds and " | 290 | printk("find_irq_by_fd - mismatch between active_fds and " |
| 290 | "pollfds, fd %d vs %d, need %d\n", irq->fd, | 291 | "pollfds, fd %d vs %d, need %d\n", irq->fd, |
| 291 | fdi, fd); | 292 | fdi, fd); |
| @@ -294,7 +295,7 @@ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out) | |||
| 294 | } | 295 | } |
| 295 | *index_out = i; | 296 | *index_out = i; |
| 296 | out: | 297 | out: |
| 297 | return(irq); | 298 | return irq; |
| 298 | } | 299 | } |
| 299 | 300 | ||
| 300 | void reactivate_fd(int fd, int irqnum) | 301 | void reactivate_fd(int fd, int irqnum) |
| @@ -305,7 +306,7 @@ void reactivate_fd(int fd, int irqnum) | |||
| 305 | 306 | ||
| 306 | flags = irq_lock(); | 307 | flags = irq_lock(); |
| 307 | irq = find_irq_by_fd(fd, irqnum, &i); | 308 | irq = find_irq_by_fd(fd, irqnum, &i); |
| 308 | if(irq == NULL){ | 309 | if (irq == NULL) { |
| 309 | irq_unlock(flags); | 310 | irq_unlock(flags); |
| 310 | return; | 311 | return; |
| 311 | } | 312 | } |
| @@ -326,7 +327,7 @@ void deactivate_fd(int fd, int irqnum) | |||
| 326 | 327 | ||
| 327 | flags = irq_lock(); | 328 | flags = irq_lock(); |
| 328 | irq = find_irq_by_fd(fd, irqnum, &i); | 329 | irq = find_irq_by_fd(fd, irqnum, &i); |
| 329 | if(irq == NULL) | 330 | if (irq == NULL) |
| 330 | goto out; | 331 | goto out; |
| 331 | os_set_pollfd(i, -1); | 332 | os_set_pollfd(i, -1); |
| 332 | out: | 333 | out: |
| @@ -338,15 +339,15 @@ int deactivate_all_fds(void) | |||
| 338 | struct irq_fd *irq; | 339 | struct irq_fd *irq; |
| 339 | int err; | 340 | int err; |
| 340 | 341 | ||
| 341 | for(irq=active_fds;irq != NULL;irq = irq->next){ | 342 | for (irq = active_fds; irq != NULL; irq = irq->next) { |
| 342 | err = os_clear_fd_async(irq->fd); | 343 | err = os_clear_fd_async(irq->fd); |
| 343 | if(err) | 344 | if (err) |
| 344 | return(err); | 345 | return err; |
| 345 | } | 346 | } |
| 346 | /* If there is a signal already queued, after unblocking ignore it */ | 347 | /* If there is a signal already queued, after unblocking ignore it */ |
| 347 | os_set_ioignore(); | 348 | os_set_ioignore(); |
| 348 | 349 | ||
| 349 | return(0); | 350 | return 0; |
| 350 | } | 351 | } |
| 351 | 352 | ||
| 352 | void forward_interrupts(int pid) | 353 | void forward_interrupts(int pid) |
| @@ -356,9 +357,9 @@ void forward_interrupts(int pid) | |||
| 356 | int err; | 357 | int err; |
| 357 | 358 | ||
| 358 | flags = irq_lock(); | 359 | flags = irq_lock(); |
| 359 | for(irq=active_fds;irq != NULL;irq = irq->next){ | 360 | for (irq = active_fds; irq != NULL; irq = irq->next) { |
| 360 | err = os_set_owner(irq->fd, pid); | 361 | err = os_set_owner(irq->fd, pid); |
| 361 | if(err < 0){ | 362 | if (err < 0) { |
| 362 | /* XXX Just remove the irq rather than | 363 | /* XXX Just remove the irq rather than |
| 363 | * print out an infinite stream of these | 364 | * print out an infinite stream of these |
| 364 | */ | 365 | */ |
| @@ -379,7 +380,7 @@ void forward_interrupts(int pid) | |||
| 379 | unsigned int do_IRQ(int irq, union uml_pt_regs *regs) | 380 | unsigned int do_IRQ(int irq, union uml_pt_regs *regs) |
| 380 | { | 381 | { |
| 381 | irq_enter(); | 382 | irq_enter(); |
| 382 | __do_IRQ(irq, (struct pt_regs *) regs); | 383 | __do_IRQ(irq, (struct pt_regs *)regs); |
| 383 | irq_exit(); | 384 | irq_exit(); |
| 384 | return 1; | 385 | return 1; |
| 385 | } | 386 | } |
| @@ -392,12 +393,12 @@ int um_request_irq(unsigned int irq, int fd, int type, | |||
| 392 | int err; | 393 | int err; |
| 393 | 394 | ||
| 394 | err = request_irq(irq, handler, irqflags, devname, dev_id); | 395 | err = request_irq(irq, handler, irqflags, devname, dev_id); |
| 395 | if(err) | 396 | if (err) |
| 396 | return(err); | 397 | return err; |
| 397 | 398 | ||
| 398 | if(fd != -1) | 399 | if (fd != -1) |
| 399 | err = activate_fd(irq, fd, type, dev_id); | 400 | err = activate_fd(irq, fd, type, dev_id); |
| 400 | return(err); | 401 | return err; |
| 401 | } | 402 | } |
| 402 | EXPORT_SYMBOL(um_request_irq); | 403 | EXPORT_SYMBOL(um_request_irq); |
| 403 | EXPORT_SYMBOL(reactivate_fd); | 404 | EXPORT_SYMBOL(reactivate_fd); |
| @@ -409,7 +410,7 @@ unsigned long irq_lock(void) | |||
| 409 | unsigned long flags; | 410 | unsigned long flags; |
| 410 | 411 | ||
| 411 | spin_lock_irqsave(&irq_spinlock, flags); | 412 | spin_lock_irqsave(&irq_spinlock, flags); |
| 412 | return(flags); | 413 | return flags; |
| 413 | } | 414 | } |
| 414 | 415 | ||
| 415 | void irq_unlock(unsigned long flags) | 416 | void irq_unlock(unsigned long flags) |
| @@ -452,7 +453,7 @@ void __init init_IRQ(void) | |||
| 452 | irq_desc[TIMER_IRQ].depth = 1; | 453 | irq_desc[TIMER_IRQ].depth = 1; |
| 453 | irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type; | 454 | irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type; |
| 454 | enable_irq(TIMER_IRQ); | 455 | enable_irq(TIMER_IRQ); |
| 455 | for(i=1;i<NR_IRQS;i++){ | 456 | for (i = 1; i < NR_IRQS; i++) { |
| 456 | irq_desc[i].status = IRQ_DISABLED; | 457 | irq_desc[i].status = IRQ_DISABLED; |
| 457 | irq_desc[i].action = NULL; | 458 | irq_desc[i].action = NULL; |
| 458 | irq_desc[i].depth = 1; | 459 | irq_desc[i].depth = 1; |
| @@ -467,7 +468,7 @@ int init_aio_irq(int irq, char *name, irqreturn_t (*handler)(int, void *, | |||
| 467 | int fds[2], err; | 468 | int fds[2], err; |
| 468 | 469 | ||
| 469 | err = os_pipe(fds, 1, 1); | 470 | err = os_pipe(fds, 1, 1); |
| 470 | if(err){ | 471 | if (err) { |
| 471 | printk("init_aio_irq - os_pipe failed, err = %d\n", -err); | 472 | printk("init_aio_irq - os_pipe failed, err = %d\n", -err); |
| 472 | goto out; | 473 | goto out; |
| 473 | } | 474 | } |
| @@ -475,7 +476,7 @@ int init_aio_irq(int irq, char *name, irqreturn_t (*handler)(int, void *, | |||
| 475 | err = um_request_irq(irq, fds[0], IRQ_READ, handler, | 476 | err = um_request_irq(irq, fds[0], IRQ_READ, handler, |
| 476 | SA_INTERRUPT | SA_SAMPLE_RANDOM, name, | 477 | SA_INTERRUPT | SA_SAMPLE_RANDOM, name, |
| 477 | (void *) (long) fds[0]); | 478 | (void *) (long) fds[0]); |
| 478 | if(err){ | 479 | if (err) { |
| 479 | printk("init_aio_irq - : um_request_irq failed, err = %d\n", | 480 | printk("init_aio_irq - : um_request_irq failed, err = %d\n", |
| 480 | err); | 481 | err); |
| 481 | goto out_close; | 482 | goto out_close; |
| @@ -488,5 +489,5 @@ int init_aio_irq(int irq, char *name, irqreturn_t (*handler)(int, void *, | |||
| 488 | os_close_file(fds[0]); | 489 | os_close_file(fds[0]); |
| 489 | os_close_file(fds[1]); | 490 | os_close_file(fds[1]); |
| 490 | out: | 491 | out: |
| 491 | return(err); | 492 | return err; |
| 492 | } | 493 | } |
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index 0500800df1c1..fc0f0b085ca7 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c | |||
| @@ -407,6 +407,8 @@ unsigned long find_iomem(char *driver, unsigned long *len_out) | |||
| 407 | *len_out = region->size; | 407 | *len_out = region->size; |
| 408 | return(region->virt); | 408 | return(region->virt); |
| 409 | } | 409 | } |
| 410 | |||
| 411 | region = region->next; | ||
| 410 | } | 412 | } |
| 411 | 413 | ||
| 412 | return(0); | 414 | return(0); |
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 60d2eda995c1..9a77fb3c269d 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
| @@ -275,15 +275,13 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit) | |||
| 275 | 275 | ||
| 276 | if (unlikely(current->audit_context)) { | 276 | if (unlikely(current->audit_context)) { |
| 277 | if (!entryexit) | 277 | if (!entryexit) |
| 278 | audit_syscall_entry(current, | 278 | audit_syscall_entry(HOST_AUDIT_ARCH, |
| 279 | HOST_AUDIT_ARCH, | ||
| 280 | UPT_SYSCALL_NR(regs), | 279 | UPT_SYSCALL_NR(regs), |
| 281 | UPT_SYSCALL_ARG1(regs), | 280 | UPT_SYSCALL_ARG1(regs), |
| 282 | UPT_SYSCALL_ARG2(regs), | 281 | UPT_SYSCALL_ARG2(regs), |
| 283 | UPT_SYSCALL_ARG3(regs), | 282 | UPT_SYSCALL_ARG3(regs), |
| 284 | UPT_SYSCALL_ARG4(regs)); | 283 | UPT_SYSCALL_ARG4(regs)); |
| 285 | else audit_syscall_exit(current, | 284 | else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs)), |
| 286 | AUDITSC_RESULT(UPT_SYSCALL_RET(regs)), | ||
| 287 | UPT_SYSCALL_RET(regs)); | 285 | UPT_SYSCALL_RET(regs)); |
| 288 | } | 286 | } |
| 289 | 287 | ||
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile index 57181a920d48..ea3a8e409a6e 100644 --- a/arch/um/kernel/skas/Makefile +++ b/arch/um/kernel/skas/Makefile | |||
| @@ -6,9 +6,11 @@ | |||
| 6 | obj-y := clone.o exec_kern.o mem.o mmu.o process_kern.o \ | 6 | obj-y := clone.o exec_kern.o mem.o mmu.o process_kern.o \ |
| 7 | syscall.o tlb.o uaccess.o | 7 | syscall.o tlb.o uaccess.o |
| 8 | 8 | ||
| 9 | USER_OBJS := clone.o | 9 | # clone.o is in the stub, so it can't be built with profiling |
| 10 | # GCC hardened also auto-enables -fpic, but we need %ebx so it can't work -> | ||
| 11 | # disable it | ||
| 10 | 12 | ||
| 11 | include arch/um/scripts/Makefile.rules | 13 | CFLAGS_clone.o := $(CFLAGS_NO_HARDENING) |
| 14 | UNPROFILE_OBJS := clone.o | ||
| 12 | 15 | ||
| 13 | # clone.o is in the stub, so it can't be built with profiling | 16 | include arch/um/scripts/Makefile.rules |
| 14 | $(obj)/clone.o : c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) | ||
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c index 3c7626cdba4b..528cf623f8b4 100644 --- a/arch/um/kernel/time_kern.c +++ b/arch/um/kernel/time_kern.c | |||
| @@ -209,4 +209,4 @@ int __init timer_init(void) | |||
| 209 | return(0); | 209 | return(0); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | __initcall(timer_init); | 212 | arch_initcall(timer_init); |
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 3bd10deea280..09251338d99e 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c | |||
| @@ -171,7 +171,7 @@ int os_sigio_async(int master, int slave) | |||
| 171 | 171 | ||
| 172 | flags = fcntl(master, F_GETFL); | 172 | flags = fcntl(master, F_GETFL); |
| 173 | if(flags < 0) | 173 | if(flags < 0) |
| 174 | return errno; | 174 | return -errno; |
| 175 | 175 | ||
| 176 | if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || | 176 | if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || |
| 177 | (fcntl(master, F_SETOWN, os_getpid()) < 0)) | 177 | (fcntl(master, F_SETOWN, os_getpid()) < 0)) |
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index e599be423da1..3788d4568d33 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c | |||
| @@ -29,21 +29,21 @@ int os_waiting_for_events(struct irq_fd *active_fds) | |||
| 29 | int i, n, err; | 29 | int i, n, err; |
| 30 | 30 | ||
| 31 | n = poll(pollfds, pollfds_num, 0); | 31 | n = poll(pollfds, pollfds_num, 0); |
| 32 | if(n < 0){ | 32 | if (n < 0) { |
| 33 | err = -errno; | 33 | err = -errno; |
| 34 | if(errno != EINTR) | 34 | if (errno != EINTR) |
| 35 | printk("sigio_handler: os_waiting_for_events:" | 35 | printk("sigio_handler: os_waiting_for_events:" |
| 36 | " poll returned %d, errno = %d\n", n, errno); | 36 | " poll returned %d, errno = %d\n", n, errno); |
| 37 | return err; | 37 | return err; |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | if(n == 0) | 40 | if (n == 0) |
| 41 | return 0; | 41 | return 0; |
| 42 | 42 | ||
| 43 | irq_fd = active_fds; | 43 | irq_fd = active_fds; |
| 44 | 44 | ||
| 45 | for(i = 0; i < pollfds_num; i++){ | 45 | for (i = 0; i < pollfds_num; i++) { |
| 46 | if(pollfds[i].revents != 0){ | 46 | if (pollfds[i].revents != 0) { |
| 47 | irq_fd->current_events = pollfds[i].revents; | 47 | irq_fd->current_events = pollfds[i].revents; |
| 48 | pollfds[i].fd = -1; | 48 | pollfds[i].fd = -1; |
| 49 | } | 49 | } |
| @@ -54,7 +54,7 @@ int os_waiting_for_events(struct irq_fd *active_fds) | |||
| 54 | 54 | ||
| 55 | int os_isatty(int fd) | 55 | int os_isatty(int fd) |
| 56 | { | 56 | { |
| 57 | return(isatty(fd)); | 57 | return isatty(fd); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds) | 60 | int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds) |
| @@ -65,7 +65,7 @@ int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds) | |||
| 65 | return((pollfds_size + 1) * sizeof(pollfds[0])); | 65 | return((pollfds_size + 1) * sizeof(pollfds[0])); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | if(pollfds != NULL){ | 68 | if (pollfds != NULL) { |
| 69 | memcpy(tmp_pfd, pollfds, | 69 | memcpy(tmp_pfd, pollfds, |
| 70 | sizeof(pollfds[0]) * pollfds_size); | 70 | sizeof(pollfds[0]) * pollfds_size); |
| 71 | /* remove old pollfds */ | 71 | /* remove old pollfds */ |
| @@ -73,18 +73,15 @@ int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds) | |||
| 73 | } | 73 | } |
| 74 | pollfds = tmp_pfd; | 74 | pollfds = tmp_pfd; |
| 75 | pollfds_size++; | 75 | pollfds_size++; |
| 76 | } else { | 76 | } else |
| 77 | /* remove not used tmp_pfd */ | 77 | kfree(tmp_pfd); /* remove not used tmp_pfd */ |
| 78 | if (tmp_pfd != NULL) | ||
| 79 | kfree(tmp_pfd); | ||
| 80 | } | ||
| 81 | 78 | ||
| 82 | pollfds[pollfds_num] = ((struct pollfd) { .fd = fd, | 79 | pollfds[pollfds_num] = ((struct pollfd) { .fd = fd, |
| 83 | .events = events, | 80 | .events = events, |
| 84 | .revents = 0 }); | 81 | .revents = 0 }); |
| 85 | pollfds_num++; | 82 | pollfds_num++; |
| 86 | 83 | ||
| 87 | return(0); | 84 | return 0; |
| 88 | } | 85 | } |
| 89 | 86 | ||
| 90 | void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg, | 87 | void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg, |
| @@ -94,11 +91,11 @@ void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg, | |||
| 94 | int i = 0; | 91 | int i = 0; |
| 95 | 92 | ||
| 96 | prev = &active_fds; | 93 | prev = &active_fds; |
| 97 | while(*prev != NULL){ | 94 | while (*prev != NULL) { |
| 98 | if((*test)(*prev, arg)){ | 95 | if ((*test)(*prev, arg)) { |
| 99 | struct irq_fd *old_fd = *prev; | 96 | struct irq_fd *old_fd = *prev; |
| 100 | if((pollfds[i].fd != -1) && | 97 | if ((pollfds[i].fd != -1) && |
| 101 | (pollfds[i].fd != (*prev)->fd)){ | 98 | (pollfds[i].fd != (*prev)->fd)) { |
| 102 | printk("os_free_irq_by_cb - mismatch between " | 99 | printk("os_free_irq_by_cb - mismatch between " |
| 103 | "active_fds and pollfds, fd %d vs %d\n", | 100 | "active_fds and pollfds, fd %d vs %d\n", |
| 104 | (*prev)->fd, pollfds[i].fd); | 101 | (*prev)->fd, pollfds[i].fd); |
| @@ -110,7 +107,6 @@ void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg, | |||
| 110 | /* This moves the *whole* array after pollfds[i] | 107 | /* This moves the *whole* array after pollfds[i] |
| 111 | * (though it doesn't spot as such)! | 108 | * (though it doesn't spot as such)! |
| 112 | */ | 109 | */ |
| 113 | |||
| 114 | memmove(&pollfds[i], &pollfds[i + 1], | 110 | memmove(&pollfds[i], &pollfds[i + 1], |
| 115 | (pollfds_num - i) * sizeof(pollfds[0])); | 111 | (pollfds_num - i) * sizeof(pollfds[0])); |
| 116 | if(*last_irq_ptr2 == &old_fd->next) | 112 | if(*last_irq_ptr2 == &old_fd->next) |
| @@ -129,10 +125,9 @@ void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg, | |||
| 129 | return; | 125 | return; |
| 130 | } | 126 | } |
| 131 | 127 | ||
| 132 | |||
| 133 | int os_get_pollfd(int i) | 128 | int os_get_pollfd(int i) |
| 134 | { | 129 | { |
| 135 | return(pollfds[i].fd); | 130 | return pollfds[i].fd; |
| 136 | } | 131 | } |
| 137 | 132 | ||
| 138 | void os_set_pollfd(int i, int fd) | 133 | void os_set_pollfd(int i, int fd) |
| @@ -151,8 +146,10 @@ void init_irq_signals(int on_sigstack) | |||
| 151 | int flags; | 146 | int flags; |
| 152 | 147 | ||
| 153 | flags = on_sigstack ? SA_ONSTACK : 0; | 148 | flags = on_sigstack ? SA_ONSTACK : 0; |
| 154 | if(timer_irq_inited) h = (__sighandler_t) alarm_handler; | 149 | if (timer_irq_inited) |
| 155 | else h = boot_timer_handler; | 150 | h = (__sighandler_t)alarm_handler; |
| 151 | else | ||
| 152 | h = boot_timer_handler; | ||
| 156 | 153 | ||
| 157 | set_handler(SIGVTALRM, h, flags | SA_RESTART, | 154 | set_handler(SIGVTALRM, h, flags | SA_RESTART, |
| 158 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); | 155 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); |
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 2878e89a674f..3a0ac38e978b 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c | |||
| @@ -74,6 +74,34 @@ static void last_ditch_exit(int sig) | |||
| 74 | exit(1); | 74 | exit(1); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | #define UML_LIB_PATH ":/usr/lib/uml" | ||
| 78 | |||
| 79 | static void setup_env_path(void) | ||
| 80 | { | ||
| 81 | char *new_path = NULL; | ||
| 82 | char *old_path = NULL; | ||
| 83 | int path_len = 0; | ||
| 84 | |||
| 85 | old_path = getenv("PATH"); | ||
| 86 | /* if no PATH variable is set or it has an empty value | ||
| 87 | * just use the default + /usr/lib/uml | ||
| 88 | */ | ||
| 89 | if (!old_path || (path_len = strlen(old_path)) == 0) { | ||
| 90 | putenv("PATH=:/bin:/usr/bin/" UML_LIB_PATH); | ||
| 91 | return; | ||
| 92 | } | ||
| 93 | |||
| 94 | /* append /usr/lib/uml to the existing path */ | ||
| 95 | path_len += strlen("PATH=" UML_LIB_PATH) + 1; | ||
| 96 | new_path = malloc(path_len); | ||
| 97 | if (!new_path) { | ||
| 98 | perror("coudn't malloc to set a new PATH"); | ||
| 99 | return; | ||
| 100 | } | ||
| 101 | snprintf(new_path, path_len, "PATH=%s" UML_LIB_PATH, old_path); | ||
| 102 | putenv(new_path); | ||
| 103 | } | ||
| 104 | |||
| 77 | extern int uml_exitcode; | 105 | extern int uml_exitcode; |
| 78 | 106 | ||
| 79 | extern void scan_elf_aux( char **envp); | 107 | extern void scan_elf_aux( char **envp); |
| @@ -114,6 +142,8 @@ int main(int argc, char **argv, char **envp) | |||
| 114 | 142 | ||
| 115 | set_stklim(); | 143 | set_stklim(); |
| 116 | 144 | ||
| 145 | setup_env_path(); | ||
| 146 | |||
| 117 | new_argv = malloc((argc + 1) * sizeof(char *)); | 147 | new_argv = malloc((argc + 1) * sizeof(char *)); |
| 118 | if(new_argv == NULL){ | 148 | if(new_argv == NULL){ |
| 119 | perror("Mallocing argv"); | 149 | perror("Mallocing argv"); |
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 3505f44f8a25..233be2f4f8cb 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
| @@ -206,29 +206,36 @@ int os_drop_memory(void *addr, int length) | |||
| 206 | int can_drop_memory(void) | 206 | int can_drop_memory(void) |
| 207 | { | 207 | { |
| 208 | void *addr; | 208 | void *addr; |
| 209 | int fd; | 209 | int fd, ok = 0; |
| 210 | 210 | ||
| 211 | printk("Checking host MADV_REMOVE support..."); | 211 | printk("Checking host MADV_REMOVE support..."); |
| 212 | fd = create_mem_file(UM_KERN_PAGE_SIZE); | 212 | fd = create_mem_file(UM_KERN_PAGE_SIZE); |
| 213 | if(fd < 0){ | 213 | if(fd < 0){ |
| 214 | printk("Creating test memory file failed, err = %d\n", -fd); | 214 | printk("Creating test memory file failed, err = %d\n", -fd); |
| 215 | return 0; | 215 | goto out; |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, | 218 | addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, |
| 219 | MAP_SHARED, fd, 0); | 219 | MAP_SHARED, fd, 0); |
| 220 | if(addr == MAP_FAILED){ | 220 | if(addr == MAP_FAILED){ |
| 221 | printk("Mapping test memory file failed, err = %d\n", -errno); | 221 | printk("Mapping test memory file failed, err = %d\n", -errno); |
| 222 | return 0; | 222 | goto out_close; |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | if(madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0){ | 225 | if(madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0){ |
| 226 | printk("MADV_REMOVE failed, err = %d\n", -errno); | 226 | printk("MADV_REMOVE failed, err = %d\n", -errno); |
| 227 | return 0; | 227 | goto out_unmap; |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | printk("OK\n"); | 230 | printk("OK\n"); |
| 231 | return 1; | 231 | ok = 1; |
| 232 | |||
| 233 | out_unmap: | ||
| 234 | munmap(addr, UM_KERN_PAGE_SIZE); | ||
| 235 | out_close: | ||
| 236 | close(fd); | ||
| 237 | out: | ||
| 238 | return ok; | ||
| 232 | } | 239 | } |
| 233 | 240 | ||
| 234 | void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) | 241 | void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 0776bc18ca85..bd89c6b99d5d 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
| @@ -344,12 +344,12 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
| 344 | err = ptrace_setregs(pid, regs); | 344 | err = ptrace_setregs(pid, regs); |
| 345 | if(err < 0) | 345 | if(err < 0) |
| 346 | panic("copy_context_skas0 : PTRACE_SETREGS failed, " | 346 | panic("copy_context_skas0 : PTRACE_SETREGS failed, " |
| 347 | "pid = %d, errno = %d\n", pid, errno); | 347 | "pid = %d, errno = %d\n", pid, -err); |
| 348 | 348 | ||
| 349 | err = ptrace_setfpregs(pid, fp_regs); | 349 | err = ptrace_setfpregs(pid, fp_regs); |
| 350 | if(err < 0) | 350 | if(err < 0) |
| 351 | panic("copy_context_skas0 : PTRACE_SETFPREGS failed, " | 351 | panic("copy_context_skas0 : PTRACE_SETFPREGS failed, " |
| 352 | "pid = %d, errno = %d\n", pid, errno); | 352 | "pid = %d, errno = %d\n", pid, -err); |
| 353 | 353 | ||
| 354 | /* set a well known return code for detection of child write failure */ | 354 | /* set a well known return code for detection of child write failure */ |
| 355 | child_data->err = 12345678; | 355 | child_data->err = 12345678; |
| @@ -362,7 +362,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
| 362 | pid = data->err; | 362 | pid = data->err; |
| 363 | if(pid < 0) | 363 | if(pid < 0) |
| 364 | panic("copy_context_skas0 - stub-parent reports error %d\n", | 364 | panic("copy_context_skas0 - stub-parent reports error %d\n", |
| 365 | pid); | 365 | -pid); |
| 366 | 366 | ||
| 367 | /* Wait, until child has finished too: read child's result from | 367 | /* Wait, until child has finished too: read child's result from |
| 368 | * child's stack and check it. | 368 | * child's stack and check it. |
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index 7a6f6b99ceff..516f66dd87e3 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c | |||
| @@ -104,7 +104,7 @@ void init_registers(int pid) | |||
| 104 | err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); | 104 | err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); |
| 105 | if(err) | 105 | if(err) |
| 106 | panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", | 106 | panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", |
| 107 | err); | 107 | errno); |
| 108 | 108 | ||
| 109 | errno = 0; | 109 | errno = 0; |
| 110 | err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs); | 110 | err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs); |
| @@ -119,7 +119,7 @@ void init_registers(int pid) | |||
| 119 | err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); | 119 | err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); |
| 120 | if(err) | 120 | if(err) |
| 121 | panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", | 121 | panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", |
| 122 | err); | 122 | errno); |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) | 125 | void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) |
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c index 001941fa1a1e..becd898d9398 100644 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ b/arch/um/os-Linux/sys-x86_64/registers.c | |||
| @@ -62,12 +62,12 @@ void init_registers(int pid) | |||
| 62 | err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); | 62 | err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); |
| 63 | if(err) | 63 | if(err) |
| 64 | panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", | 64 | panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", |
| 65 | err); | 65 | errno); |
| 66 | 66 | ||
| 67 | err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); | 67 | err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); |
| 68 | if(err) | 68 | if(err) |
| 69 | panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", | 69 | panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", |
| 70 | err); | 70 | errno); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) | 73 | void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) |
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index 34bfc1bb9e38..362db059fe30 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c | |||
| @@ -178,14 +178,14 @@ static void __init create_pid_file(void) | |||
| 178 | fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644); | 178 | fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644); |
| 179 | if(fd < 0){ | 179 | if(fd < 0){ |
| 180 | printk("Open of machine pid file \"%s\" failed: %s\n", | 180 | printk("Open of machine pid file \"%s\" failed: %s\n", |
| 181 | file, strerror(-fd)); | 181 | file, strerror(errno)); |
| 182 | return; | 182 | return; |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | snprintf(pid, sizeof(pid), "%d\n", getpid()); | 185 | snprintf(pid, sizeof(pid), "%d\n", getpid()); |
| 186 | n = write(fd, pid, strlen(pid)); | 186 | n = write(fd, pid, strlen(pid)); |
| 187 | if(n != strlen(pid)) | 187 | if(n != strlen(pid)) |
| 188 | printk("Write of pid file failed - err = %d\n", -n); | 188 | printk("Write of pid file failed - err = %d\n", errno); |
| 189 | 189 | ||
| 190 | close(fd); | 190 | close(fd); |
| 191 | } | 191 | } |
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c index 2598158e1f53..3f33165ada68 100644 --- a/arch/um/os-Linux/user_syms.c +++ b/arch/um/os-Linux/user_syms.c | |||
| @@ -96,6 +96,13 @@ EXPORT_SYMBOL_PROTO(getuid); | |||
| 96 | EXPORT_SYMBOL_PROTO(fsync); | 96 | EXPORT_SYMBOL_PROTO(fsync); |
| 97 | EXPORT_SYMBOL_PROTO(fdatasync); | 97 | EXPORT_SYMBOL_PROTO(fdatasync); |
| 98 | 98 | ||
| 99 | /* Export symbols used by GCC for the stack protector. */ | ||
| 100 | extern void __stack_smash_handler(void *) __attribute__((weak)); | ||
| 101 | EXPORT_SYMBOL(__stack_smash_handler); | ||
| 102 | |||
| 103 | extern long __guard __attribute__((weak)); | ||
| 104 | EXPORT_SYMBOL(__guard); | ||
| 105 | |||
| 99 | /* | 106 | /* |
| 100 | * Overrides for Emacs so that we follow Linus's tabbing style. | 107 | * Overrides for Emacs so that we follow Linus's tabbing style. |
| 101 | * Emacs will notice this stuff at the end of the file and automatically | 108 | * Emacs will notice this stuff at the end of the file and automatically |
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 5e7a9c310aa5..1347dc6d5218 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules | |||
| @@ -7,11 +7,19 @@ USER_SINGLE_OBJS := \ | |||
| 7 | USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) | 7 | USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) |
| 8 | USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) | 8 | USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) |
| 9 | 9 | ||
| 10 | $(USER_OBJS) $(USER_OBJS:.o=.i) $(USER_OBJS:.o=.s) $(USER_OBJS:.o=.lst): \ | 10 | $(USER_OBJS:.o=.%): \ |
| 11 | c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@)) | 11 | c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(*F).o) |
| 12 | $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ | 12 | $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ |
| 13 | -Dunix -D__unix__ -D__$(SUBARCH)__ | 13 | -Dunix -D__unix__ -D__$(SUBARCH)__ |
| 14 | 14 | ||
| 15 | # These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of | ||
| 16 | # using it directly. | ||
| 17 | UNPROFILE_OBJS := $(foreach file,$(UNPROFILE_OBJS),$(obj)/$(file)) | ||
| 18 | |||
| 19 | $(UNPROFILE_OBJS:.o=.%): \ | ||
| 20 | c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) $(CFLAGS_$(*F).o) | ||
| 21 | $(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ | ||
| 22 | -Dunix -D__unix__ -D__$(SUBARCH)__ | ||
| 15 | 23 | ||
| 16 | # The stubs and unmap.o can't try to call mcount or update basic block data | 24 | # The stubs and unmap.o can't try to call mcount or update basic block data |
| 17 | define unprofile | 25 | define unprofile |
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 98b20b7bba4f..374d61a19439 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile | |||
| @@ -8,11 +8,16 @@ subarch-obj-y = lib/bitops.o kernel/semaphore.o | |||
| 8 | subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o | 8 | subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o |
| 9 | subarch-obj-$(CONFIG_MODULES) += kernel/module.o | 9 | subarch-obj-$(CONFIG_MODULES) += kernel/module.o |
| 10 | 10 | ||
| 11 | USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o stub_segv.o | 11 | USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o |
| 12 | 12 | ||
| 13 | include arch/um/scripts/Makefile.rules | 13 | USER_OBJS += user-offsets.s |
| 14 | extra-y += user-offsets.s | ||
| 14 | 15 | ||
| 15 | extra-$(CONFIG_MODE_TT) += unmap.o | 16 | extra-$(CONFIG_MODE_TT) += unmap.o |
| 16 | 17 | ||
| 17 | $(obj)/stub_segv.o $(obj)/unmap.o: \ | 18 | UNPROFILE_OBJS := stub_segv.o |
| 18 | _c_flags = $(call unprofile,$(CFLAGS)) | 19 | CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) |
| 20 | |||
| 21 | include arch/um/scripts/Makefile.rules | ||
| 22 | |||
| 23 | $(obj)/unmap.%: _c_flags = $(call unprofile,$(CFLAGS)) | ||
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index b5fc22babddf..c19794d435d6 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile | |||
| @@ -16,11 +16,16 @@ subarch-obj-$(CONFIG_MODULES) += kernel/module.o | |||
| 16 | 16 | ||
| 17 | ldt-y = ../sys-i386/ldt.o | 17 | ldt-y = ../sys-i386/ldt.o |
| 18 | 18 | ||
| 19 | USER_OBJS := ptrace_user.o sigcontext.o stub_segv.o | 19 | USER_OBJS := ptrace_user.o sigcontext.o |
| 20 | 20 | ||
| 21 | include arch/um/scripts/Makefile.rules | 21 | USER_OBJS += user-offsets.s |
| 22 | extra-y += user-offsets.s | ||
| 22 | 23 | ||
| 23 | extra-$(CONFIG_MODE_TT) += unmap.o | 24 | extra-$(CONFIG_MODE_TT) += unmap.o |
| 24 | 25 | ||
| 25 | $(obj)/stub_segv.o $(obj)/unmap.o: \ | 26 | UNPROFILE_OBJS := stub_segv.o |
| 26 | _c_flags = $(call unprofile,$(CFLAGS)) | 27 | CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) |
| 28 | |||
| 29 | include arch/um/scripts/Makefile.rules | ||
| 30 | |||
| 31 | $(obj)/unmap.%: _c_flags = $(call unprofile,$(CFLAGS)) | ||
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index 57fc37e0fb9c..5a92fed2d1d5 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S | |||
| @@ -695,4 +695,5 @@ ia32_sys_call_table: | |||
| 695 | .quad sys_splice | 695 | .quad sys_splice |
| 696 | .quad sys_sync_file_range | 696 | .quad sys_sync_file_range |
| 697 | .quad sys_tee | 697 | .quad sys_tee |
| 698 | .quad compat_sys_vmsplice | ||
| 698 | ia32_syscall_end: | 699 | ia32_syscall_end: |
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c index da8e7903d817..2d50024c9f30 100644 --- a/arch/x86_64/kernel/ptrace.c +++ b/arch/x86_64/kernel/ptrace.c | |||
| @@ -600,12 +600,12 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs) | |||
| 600 | 600 | ||
| 601 | if (unlikely(current->audit_context)) { | 601 | if (unlikely(current->audit_context)) { |
| 602 | if (test_thread_flag(TIF_IA32)) { | 602 | if (test_thread_flag(TIF_IA32)) { |
| 603 | audit_syscall_entry(current, AUDIT_ARCH_I386, | 603 | audit_syscall_entry(AUDIT_ARCH_I386, |
| 604 | regs->orig_rax, | 604 | regs->orig_rax, |
| 605 | regs->rbx, regs->rcx, | 605 | regs->rbx, regs->rcx, |
| 606 | regs->rdx, regs->rsi); | 606 | regs->rdx, regs->rsi); |
| 607 | } else { | 607 | } else { |
| 608 | audit_syscall_entry(current, AUDIT_ARCH_X86_64, | 608 | audit_syscall_entry(AUDIT_ARCH_X86_64, |
| 609 | regs->orig_rax, | 609 | regs->orig_rax, |
| 610 | regs->rdi, regs->rsi, | 610 | regs->rdi, regs->rsi, |
| 611 | regs->rdx, regs->r10); | 611 | regs->rdx, regs->r10); |
| @@ -616,7 +616,7 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs) | |||
| 616 | asmlinkage void syscall_trace_leave(struct pt_regs *regs) | 616 | asmlinkage void syscall_trace_leave(struct pt_regs *regs) |
| 617 | { | 617 | { |
| 618 | if (unlikely(current->audit_context)) | 618 | if (unlikely(current->audit_context)) |
| 619 | audit_syscall_exit(current, AUDITSC_RESULT(regs->rax), regs->rax); | 619 | audit_syscall_exit(AUDITSC_RESULT(regs->rax), regs->rax); |
| 620 | 620 | ||
| 621 | if ((test_thread_flag(TIF_SYSCALL_TRACE) | 621 | if ((test_thread_flag(TIF_SYSCALL_TRACE) |
| 622 | || test_thread_flag(TIF_SINGLESTEP)) | 622 | || test_thread_flag(TIF_SINGLESTEP)) |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 759070c82751..ebc3c33b1c6c 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
| @@ -1426,3 +1426,22 @@ struct seq_operations cpuinfo_op = { | |||
| 1426 | .show = show_cpuinfo, | 1426 | .show = show_cpuinfo, |
| 1427 | }; | 1427 | }; |
| 1428 | 1428 | ||
| 1429 | #ifdef CONFIG_INPUT_PCSPKR | ||
| 1430 | #include <linux/platform_device.h> | ||
| 1431 | static __init int add_pcspkr(void) | ||
| 1432 | { | ||
| 1433 | struct platform_device *pd; | ||
| 1434 | int ret; | ||
| 1435 | |||
| 1436 | pd = platform_device_alloc("pcspkr", -1); | ||
| 1437 | if (!pd) | ||
| 1438 | return -ENOMEM; | ||
| 1439 | |||
| 1440 | ret = platform_device_add(pd); | ||
| 1441 | if (ret) | ||
| 1442 | platform_device_put(pd); | ||
| 1443 | |||
| 1444 | return ret; | ||
| 1445 | } | ||
| 1446 | device_initcall(add_pcspkr); | ||
| 1447 | #endif | ||
diff --git a/block/genhd.c b/block/genhd.c index 5a8d3bf02f17..d96572589621 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
| @@ -182,6 +182,7 @@ static int exact_lock(dev_t dev, void *data) | |||
| 182 | */ | 182 | */ |
| 183 | void add_disk(struct gendisk *disk) | 183 | void add_disk(struct gendisk *disk) |
| 184 | { | 184 | { |
| 185 | get_device(disk->driverfs_dev); | ||
| 185 | disk->flags |= GENHD_FL_UP; | 186 | disk->flags |= GENHD_FL_UP; |
| 186 | blk_register_region(MKDEV(disk->major, disk->first_minor), | 187 | blk_register_region(MKDEV(disk->major, disk->first_minor), |
| 187 | disk->minors, NULL, exact_match, exact_lock, disk); | 188 | disk->minors, NULL, exact_match, exact_lock, disk); |
| @@ -427,6 +428,7 @@ static struct attribute * default_attrs[] = { | |||
| 427 | static void disk_release(struct kobject * kobj) | 428 | static void disk_release(struct kobject * kobj) |
| 428 | { | 429 | { |
| 429 | struct gendisk *disk = to_disk(kobj); | 430 | struct gendisk *disk = to_disk(kobj); |
| 431 | put_device(disk->driverfs_dev); | ||
| 430 | kfree(disk->random); | 432 | kfree(disk->random); |
| 431 | kfree(disk->part); | 433 | kfree(disk->part); |
| 432 | free_disk_stats(disk); | 434 | free_disk_stats(disk); |
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c index d3a2bc36129b..588fca542a98 100644 --- a/drivers/char/genrtc.c +++ b/drivers/char/genrtc.c | |||
| @@ -200,13 +200,13 @@ static ssize_t gen_rtc_read(struct file *file, char __user *buf, | |||
| 200 | /* first test allows optimizer to nuke this case for 32-bit machines */ | 200 | /* first test allows optimizer to nuke this case for 32-bit machines */ |
| 201 | if (sizeof (int) != sizeof (long) && count == sizeof (unsigned int)) { | 201 | if (sizeof (int) != sizeof (long) && count == sizeof (unsigned int)) { |
| 202 | unsigned int uidata = data; | 202 | unsigned int uidata = data; |
| 203 | retval = put_user(uidata, (unsigned long __user *)buf); | 203 | retval = put_user(uidata, (unsigned int __user *)buf) ?: |
| 204 | sizeof(unsigned int); | ||
| 204 | } | 205 | } |
| 205 | else { | 206 | else { |
| 206 | retval = put_user(data, (unsigned long __user *)buf); | 207 | retval = put_user(data, (unsigned long __user *)buf) ?: |
| 208 | sizeof(unsigned long); | ||
| 207 | } | 209 | } |
| 208 | if (!retval) | ||
| 209 | retval = sizeof(unsigned long); | ||
| 210 | out: | 210 | out: |
| 211 | current->state = TASK_RUNNING; | 211 | current->state = TASK_RUNNING; |
| 212 | remove_wait_queue(&gen_rtc_wait, &wait); | 212 | remove_wait_queue(&gen_rtc_wait, &wait); |
diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c index 66572c5323ad..fce31936e6d7 100644 --- a/drivers/edac/e752x_edac.c +++ b/drivers/edac/e752x_edac.c | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 26 | #include "edac_mc.h" | 26 | #include "edac_mc.h" |
| 27 | 27 | ||
| 28 | static int force_function_unhide; | ||
| 29 | |||
| 28 | #define e752x_printk(level, fmt, arg...) \ | 30 | #define e752x_printk(level, fmt, arg...) \ |
| 29 | edac_printk(level, "e752x", fmt, ##arg) | 31 | edac_printk(level, "e752x", fmt, ##arg) |
| 30 | 32 | ||
| @@ -782,8 +784,16 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) | |||
| 782 | debugf0("%s(): mci\n", __func__); | 784 | debugf0("%s(): mci\n", __func__); |
| 783 | debugf0("Starting Probe1\n"); | 785 | debugf0("Starting Probe1\n"); |
| 784 | 786 | ||
| 785 | /* enable device 0 function 1 */ | 787 | /* check to see if device 0 function 1 is enabled; if it isn't, we |
| 788 | * assume the BIOS has reserved it for a reason and is expecting | ||
| 789 | * exclusive access, we take care not to violate that assumption and | ||
| 790 | * fail the probe. */ | ||
| 786 | pci_read_config_byte(pdev, E752X_DEVPRES1, &stat8); | 791 | pci_read_config_byte(pdev, E752X_DEVPRES1, &stat8); |
| 792 | if (!force_function_unhide && !(stat8 & (1 << 5))) { | ||
| 793 | printk(KERN_INFO "Contact your BIOS vendor to see if the " | ||
| 794 | "E752x error registers can be safely un-hidden\n"); | ||
| 795 | goto fail; | ||
| 796 | } | ||
| 787 | stat8 |= (1 << 5); | 797 | stat8 |= (1 << 5); |
| 788 | pci_write_config_byte(pdev, E752X_DEVPRES1, stat8); | 798 | pci_write_config_byte(pdev, E752X_DEVPRES1, stat8); |
| 789 | 799 | ||
| @@ -1063,3 +1073,8 @@ module_exit(e752x_exit); | |||
| 1063 | MODULE_LICENSE("GPL"); | 1073 | MODULE_LICENSE("GPL"); |
| 1064 | MODULE_AUTHOR("Linux Networx (http://lnxi.com) Tom Zimmerman\n"); | 1074 | MODULE_AUTHOR("Linux Networx (http://lnxi.com) Tom Zimmerman\n"); |
| 1065 | MODULE_DESCRIPTION("MC support for Intel e752x memory controllers"); | 1075 | MODULE_DESCRIPTION("MC support for Intel e752x memory controllers"); |
| 1076 | |||
| 1077 | module_param(force_function_unhide, int, 0444); | ||
| 1078 | MODULE_PARM_DESC(force_function_unhide, "if BIOS sets Dev0:Fun1 up as hidden:" | ||
| 1079 | " 1=force unhide and hope BIOS doesn't fight driver for Dev0:Fun1 access"); | ||
| 1080 | |||
diff --git a/drivers/infiniband/hw/ipath/ipath_debug.h b/drivers/infiniband/hw/ipath/ipath_debug.h index 593e28969c69..46762387f5f8 100644 --- a/drivers/infiniband/hw/ipath/ipath_debug.h +++ b/drivers/infiniband/hw/ipath/ipath_debug.h | |||
| @@ -60,11 +60,11 @@ | |||
| 60 | #define __IPATH_KERNEL_SEND 0x2000 /* use kernel mode send */ | 60 | #define __IPATH_KERNEL_SEND 0x2000 /* use kernel mode send */ |
| 61 | #define __IPATH_EPKTDBG 0x4000 /* print ethernet packet data */ | 61 | #define __IPATH_EPKTDBG 0x4000 /* print ethernet packet data */ |
| 62 | #define __IPATH_SMADBG 0x8000 /* sma packet debug */ | 62 | #define __IPATH_SMADBG 0x8000 /* sma packet debug */ |
| 63 | #define __IPATH_IPATHDBG 0x10000 /* Ethernet (IPATH) general debug on */ | 63 | #define __IPATH_IPATHDBG 0x10000 /* Ethernet (IPATH) gen debug */ |
| 64 | #define __IPATH_IPATHWARN 0x20000 /* Ethernet (IPATH) warnings on */ | 64 | #define __IPATH_IPATHWARN 0x20000 /* Ethernet (IPATH) warnings */ |
| 65 | #define __IPATH_IPATHERR 0x40000 /* Ethernet (IPATH) errors on */ | 65 | #define __IPATH_IPATHERR 0x40000 /* Ethernet (IPATH) errors */ |
| 66 | #define __IPATH_IPATHPD 0x80000 /* Ethernet (IPATH) packet dump on */ | 66 | #define __IPATH_IPATHPD 0x80000 /* Ethernet (IPATH) packet dump */ |
| 67 | #define __IPATH_IPATHTABLE 0x100000 /* Ethernet (IPATH) table dump on */ | 67 | #define __IPATH_IPATHTABLE 0x100000 /* Ethernet (IPATH) table dump */ |
| 68 | 68 | ||
| 69 | #else /* _IPATH_DEBUGGING */ | 69 | #else /* _IPATH_DEBUGGING */ |
| 70 | 70 | ||
| @@ -79,11 +79,12 @@ | |||
| 79 | #define __IPATH_TRSAMPLE 0x0 /* generate trace buffer sample entries */ | 79 | #define __IPATH_TRSAMPLE 0x0 /* generate trace buffer sample entries */ |
| 80 | #define __IPATH_VERBDBG 0x0 /* very verbose debug */ | 80 | #define __IPATH_VERBDBG 0x0 /* very verbose debug */ |
| 81 | #define __IPATH_PKTDBG 0x0 /* print packet data */ | 81 | #define __IPATH_PKTDBG 0x0 /* print packet data */ |
| 82 | #define __IPATH_PROCDBG 0x0 /* print process startup (init)/exit messages */ | 82 | #define __IPATH_PROCDBG 0x0 /* process startup (init)/exit messages */ |
| 83 | /* print mmap/nopage stuff, not using VDBG any more */ | 83 | /* print mmap/nopage stuff, not using VDBG any more */ |
| 84 | #define __IPATH_MMDBG 0x0 | 84 | #define __IPATH_MMDBG 0x0 |
| 85 | #define __IPATH_EPKTDBG 0x0 /* print ethernet packet data */ | 85 | #define __IPATH_EPKTDBG 0x0 /* print ethernet packet data */ |
| 86 | #define __IPATH_SMADBG 0x0 /* print process startup (init)/exit messages */#define __IPATH_IPATHDBG 0x0 /* Ethernet (IPATH) table dump on */ | 86 | #define __IPATH_SMADBG 0x0 /* process startup (init)/exit messages */ |
| 87 | #define __IPATH_IPATHDBG 0x0 /* Ethernet (IPATH) table dump on */ | ||
| 87 | #define __IPATH_IPATHWARN 0x0 /* Ethernet (IPATH) warnings on */ | 88 | #define __IPATH_IPATHWARN 0x0 /* Ethernet (IPATH) warnings on */ |
| 88 | #define __IPATH_IPATHERR 0x0 /* Ethernet (IPATH) errors on */ | 89 | #define __IPATH_IPATHERR 0x0 /* Ethernet (IPATH) errors on */ |
| 89 | #define __IPATH_IPATHPD 0x0 /* Ethernet (IPATH) packet dump on */ | 90 | #define __IPATH_IPATHPD 0x0 /* Ethernet (IPATH) packet dump on */ |
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c index 7d3fb6996b41..28ddceb260e8 100644 --- a/drivers/infiniband/hw/ipath/ipath_diag.c +++ b/drivers/infiniband/hw/ipath/ipath_diag.c | |||
| @@ -277,13 +277,14 @@ static int ipath_diag_open(struct inode *in, struct file *fp) | |||
| 277 | 277 | ||
| 278 | bail: | 278 | bail: |
| 279 | spin_unlock_irqrestore(&ipath_devs_lock, flags); | 279 | spin_unlock_irqrestore(&ipath_devs_lock, flags); |
| 280 | mutex_unlock(&ipath_mutex); | ||
| 281 | 280 | ||
| 282 | /* Only expose a way to reset the device if we | 281 | /* Only expose a way to reset the device if we |
| 283 | make it into diag mode. */ | 282 | make it into diag mode. */ |
| 284 | if (ret == 0) | 283 | if (ret == 0) |
| 285 | ipath_expose_reset(&dd->pcidev->dev); | 284 | ipath_expose_reset(&dd->pcidev->dev); |
| 286 | 285 | ||
| 286 | mutex_unlock(&ipath_mutex); | ||
| 287 | |||
| 287 | return ret; | 288 | return ret; |
| 288 | } | 289 | } |
| 289 | 290 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index e7617c3982ea..398add4d4cb1 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
| @@ -418,9 +418,19 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, | |||
| 418 | 418 | ||
| 419 | ret = pci_set_dma_mask(pdev, DMA_64BIT_MASK); | 419 | ret = pci_set_dma_mask(pdev, DMA_64BIT_MASK); |
| 420 | if (ret) { | 420 | if (ret) { |
| 421 | dev_info(&pdev->dev, "pci_set_dma_mask unit %u " | 421 | /* |
| 422 | "fails: %d\n", dd->ipath_unit, ret); | 422 | * if the 64 bit setup fails, try 32 bit. Some systems |
| 423 | goto bail_regions; | 423 | * do not setup 64 bit maps on systems with 2GB or less |
| 424 | * memory installed. | ||
| 425 | */ | ||
| 426 | ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
| 427 | if (ret) { | ||
| 428 | dev_info(&pdev->dev, "pci_set_dma_mask unit %u " | ||
| 429 | "fails: %d\n", dd->ipath_unit, ret); | ||
| 430 | goto bail_regions; | ||
| 431 | } | ||
| 432 | else | ||
| 433 | ipath_dbg("No 64bit DMA mask, used 32 bit mask\n"); | ||
| 424 | } | 434 | } |
| 425 | 435 | ||
| 426 | pci_set_master(pdev); | 436 | pci_set_master(pdev); |
| @@ -1949,7 +1959,7 @@ int ipath_reset_device(int unit) | |||
| 1949 | } | 1959 | } |
| 1950 | 1960 | ||
| 1951 | if (dd->ipath_pd) | 1961 | if (dd->ipath_pd) |
| 1952 | for (i = 1; i < dd->ipath_portcnt; i++) { | 1962 | for (i = 1; i < dd->ipath_cfgports; i++) { |
| 1953 | if (dd->ipath_pd[i] && dd->ipath_pd[i]->port_cnt) { | 1963 | if (dd->ipath_pd[i] && dd->ipath_pd[i]->port_cnt) { |
| 1954 | ipath_dbg("unit %u port %d is in use " | 1964 | ipath_dbg("unit %u port %d is in use " |
| 1955 | "(PID %u cmd %s), can't reset\n", | 1965 | "(PID %u cmd %s), can't reset\n", |
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c index 2823ff9c0c62..16f640e1c16e 100644 --- a/drivers/infiniband/hw/ipath/ipath_init_chip.c +++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c | |||
| @@ -53,13 +53,19 @@ MODULE_PARM_DESC(cfgports, "Set max number of ports to use"); | |||
| 53 | 53 | ||
| 54 | /* | 54 | /* |
| 55 | * Number of buffers reserved for driver (layered drivers and SMA | 55 | * Number of buffers reserved for driver (layered drivers and SMA |
| 56 | * send). Reserved at end of buffer list. | 56 | * send). Reserved at end of buffer list. Initialized based on |
| 57 | * number of PIO buffers if not set via module interface. | ||
| 58 | * The problem with this is that it's global, but we'll use different | ||
| 59 | * numbers for different chip types. So the default value is not | ||
| 60 | * very useful. I've redefined it for the 1.3 release so that it's | ||
| 61 | * zero unless set by the user to something else, in which case we | ||
| 62 | * try to respect it. | ||
| 57 | */ | 63 | */ |
| 58 | static ushort ipath_kpiobufs = 32; | 64 | static ushort ipath_kpiobufs; |
| 59 | 65 | ||
| 60 | static int ipath_set_kpiobufs(const char *val, struct kernel_param *kp); | 66 | static int ipath_set_kpiobufs(const char *val, struct kernel_param *kp); |
| 61 | 67 | ||
| 62 | module_param_call(kpiobufs, ipath_set_kpiobufs, param_get_uint, | 68 | module_param_call(kpiobufs, ipath_set_kpiobufs, param_get_ushort, |
| 63 | &ipath_kpiobufs, S_IWUSR | S_IRUGO); | 69 | &ipath_kpiobufs, S_IWUSR | S_IRUGO); |
| 64 | MODULE_PARM_DESC(kpiobufs, "Set number of PIO buffers for driver"); | 70 | MODULE_PARM_DESC(kpiobufs, "Set number of PIO buffers for driver"); |
| 65 | 71 | ||
| @@ -531,8 +537,11 @@ static int init_housekeeping(struct ipath_devdata *dd, | |||
| 531 | * Don't clear ipath_flags as 8bit mode was set before | 537 | * Don't clear ipath_flags as 8bit mode was set before |
| 532 | * entering this func. However, we do set the linkstate to | 538 | * entering this func. However, we do set the linkstate to |
| 533 | * unknown, so we can watch for a transition. | 539 | * unknown, so we can watch for a transition. |
| 540 | * PRESENT is set because we want register reads to work, | ||
| 541 | * and the kernel infrastructure saw it in config space; | ||
| 542 | * We clear it if we have failures. | ||
| 534 | */ | 543 | */ |
| 535 | dd->ipath_flags |= IPATH_LINKUNK; | 544 | dd->ipath_flags |= IPATH_LINKUNK | IPATH_PRESENT; |
| 536 | dd->ipath_flags &= ~(IPATH_LINKACTIVE | IPATH_LINKARMED | | 545 | dd->ipath_flags &= ~(IPATH_LINKACTIVE | IPATH_LINKARMED | |
| 537 | IPATH_LINKDOWN | IPATH_LINKINIT); | 546 | IPATH_LINKDOWN | IPATH_LINKINIT); |
| 538 | 547 | ||
| @@ -560,6 +569,7 @@ static int init_housekeeping(struct ipath_devdata *dd, | |||
| 560 | || (dd->ipath_uregbase & 0xffffffff) == 0xffffffff) { | 569 | || (dd->ipath_uregbase & 0xffffffff) == 0xffffffff) { |
| 561 | ipath_dev_err(dd, "Register read failures from chip, " | 570 | ipath_dev_err(dd, "Register read failures from chip, " |
| 562 | "giving up initialization\n"); | 571 | "giving up initialization\n"); |
| 572 | dd->ipath_flags &= ~IPATH_PRESENT; | ||
| 563 | ret = -ENODEV; | 573 | ret = -ENODEV; |
| 564 | goto done; | 574 | goto done; |
| 565 | } | 575 | } |
| @@ -682,16 +692,14 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) | |||
| 682 | */ | 692 | */ |
| 683 | dd->ipath_pioavregs = ALIGN(val, sizeof(u64) * BITS_PER_BYTE / 2) | 693 | dd->ipath_pioavregs = ALIGN(val, sizeof(u64) * BITS_PER_BYTE / 2) |
| 684 | / (sizeof(u64) * BITS_PER_BYTE / 2); | 694 | / (sizeof(u64) * BITS_PER_BYTE / 2); |
| 685 | if (!ipath_kpiobufs) /* have to have at least 1, for SMA */ | 695 | if (ipath_kpiobufs == 0) { |
| 686 | kpiobufs = ipath_kpiobufs = 1; | 696 | /* not set by user, or set explictly to default */ |
| 687 | else if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) < | 697 | if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) > 128) |
| 688 | (dd->ipath_cfgports * IPATH_MIN_USER_PORT_BUFCNT)) { | 698 | kpiobufs = 32; |
| 689 | dev_info(&dd->pcidev->dev, "Too few PIO buffers (%u) " | 699 | else |
| 690 | "for %u ports to have %u each!\n", | 700 | kpiobufs = 16; |
| 691 | dd->ipath_piobcnt2k + dd->ipath_piobcnt4k, | 701 | } |
| 692 | dd->ipath_cfgports, IPATH_MIN_USER_PORT_BUFCNT); | 702 | else |
| 693 | kpiobufs = 1; /* reserve just the minimum for SMA/ether */ | ||
| 694 | } else | ||
| 695 | kpiobufs = ipath_kpiobufs; | 703 | kpiobufs = ipath_kpiobufs; |
| 696 | 704 | ||
| 697 | if (kpiobufs > | 705 | if (kpiobufs > |
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c index 0bcb428041f3..3e72a1fe3d73 100644 --- a/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/drivers/infiniband/hw/ipath/ipath_intr.c | |||
| @@ -665,14 +665,14 @@ static void handle_layer_pioavail(struct ipath_devdata *dd) | |||
| 665 | 665 | ||
| 666 | ret = __ipath_layer_intr(dd, IPATH_LAYER_INT_SEND_CONTINUE); | 666 | ret = __ipath_layer_intr(dd, IPATH_LAYER_INT_SEND_CONTINUE); |
| 667 | if (ret > 0) | 667 | if (ret > 0) |
| 668 | goto clear; | 668 | goto set; |
| 669 | 669 | ||
| 670 | ret = __ipath_verbs_piobufavail(dd); | 670 | ret = __ipath_verbs_piobufavail(dd); |
| 671 | if (ret > 0) | 671 | if (ret > 0) |
| 672 | goto clear; | 672 | goto set; |
| 673 | 673 | ||
| 674 | return; | 674 | return; |
| 675 | clear: | 675 | set: |
| 676 | set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); | 676 | set_bit(IPATH_S_PIOINTBUFAVAIL, &dd->ipath_sendctrl); |
| 677 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 677 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
| 678 | dd->ipath_sendctrl); | 678 | dd->ipath_sendctrl); |
| @@ -719,11 +719,24 @@ static void handle_rcv(struct ipath_devdata *dd, u32 istat) | |||
| 719 | irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs) | 719 | irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs) |
| 720 | { | 720 | { |
| 721 | struct ipath_devdata *dd = data; | 721 | struct ipath_devdata *dd = data; |
| 722 | u32 istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus); | 722 | u32 istat; |
| 723 | ipath_err_t estat = 0; | 723 | ipath_err_t estat = 0; |
| 724 | static unsigned unexpected = 0; | 724 | static unsigned unexpected = 0; |
| 725 | irqreturn_t ret; | 725 | irqreturn_t ret; |
| 726 | 726 | ||
| 727 | if(!(dd->ipath_flags & IPATH_PRESENT)) { | ||
| 728 | /* this is mostly so we don't try to touch the chip while | ||
| 729 | * it is being reset */ | ||
| 730 | /* | ||
| 731 | * This return value is perhaps odd, but we do not want the | ||
| 732 | * interrupt core code to remove our interrupt handler | ||
| 733 | * because we don't appear to be handling an interrupt | ||
| 734 | * during a chip reset. | ||
| 735 | */ | ||
| 736 | return IRQ_HANDLED; | ||
| 737 | } | ||
| 738 | |||
| 739 | istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus); | ||
| 727 | if (unlikely(!istat)) { | 740 | if (unlikely(!istat)) { |
| 728 | ipath_stats.sps_nullintr++; | 741 | ipath_stats.sps_nullintr++; |
| 729 | ret = IRQ_NONE; /* not our interrupt, or already handled */ | 742 | ret = IRQ_NONE; /* not our interrupt, or already handled */ |
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index 0ce5f19c9d62..e6507f8115bc 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h | |||
| @@ -731,7 +731,7 @@ u64 ipath_read_kreg64_port(const struct ipath_devdata *, ipath_kreg, | |||
| 731 | static inline u32 ipath_read_ureg32(const struct ipath_devdata *dd, | 731 | static inline u32 ipath_read_ureg32(const struct ipath_devdata *dd, |
| 732 | ipath_ureg regno, int port) | 732 | ipath_ureg regno, int port) |
| 733 | { | 733 | { |
| 734 | if (!dd->ipath_kregbase) | 734 | if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT)) |
| 735 | return 0; | 735 | return 0; |
| 736 | 736 | ||
| 737 | return readl(regno + (u64 __iomem *) | 737 | return readl(regno + (u64 __iomem *) |
| @@ -762,7 +762,7 @@ static inline void ipath_write_ureg(const struct ipath_devdata *dd, | |||
| 762 | static inline u32 ipath_read_kreg32(const struct ipath_devdata *dd, | 762 | static inline u32 ipath_read_kreg32(const struct ipath_devdata *dd, |
| 763 | ipath_kreg regno) | 763 | ipath_kreg regno) |
| 764 | { | 764 | { |
| 765 | if (!dd->ipath_kregbase) | 765 | if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT)) |
| 766 | return -1; | 766 | return -1; |
| 767 | return readl((u32 __iomem *) & dd->ipath_kregbase[regno]); | 767 | return readl((u32 __iomem *) & dd->ipath_kregbase[regno]); |
| 768 | } | 768 | } |
| @@ -770,7 +770,7 @@ static inline u32 ipath_read_kreg32(const struct ipath_devdata *dd, | |||
| 770 | static inline u64 ipath_read_kreg64(const struct ipath_devdata *dd, | 770 | static inline u64 ipath_read_kreg64(const struct ipath_devdata *dd, |
| 771 | ipath_kreg regno) | 771 | ipath_kreg regno) |
| 772 | { | 772 | { |
| 773 | if (!dd->ipath_kregbase) | 773 | if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT)) |
| 774 | return -1; | 774 | return -1; |
| 775 | 775 | ||
| 776 | return readq(&dd->ipath_kregbase[regno]); | 776 | return readq(&dd->ipath_kregbase[regno]); |
| @@ -786,7 +786,7 @@ static inline void ipath_write_kreg(const struct ipath_devdata *dd, | |||
| 786 | static inline u64 ipath_read_creg(const struct ipath_devdata *dd, | 786 | static inline u64 ipath_read_creg(const struct ipath_devdata *dd, |
| 787 | ipath_sreg regno) | 787 | ipath_sreg regno) |
| 788 | { | 788 | { |
| 789 | if (!dd->ipath_kregbase) | 789 | if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT)) |
| 790 | return 0; | 790 | return 0; |
| 791 | 791 | ||
| 792 | return readq(regno + (u64 __iomem *) | 792 | return readq(regno + (u64 __iomem *) |
| @@ -797,7 +797,7 @@ static inline u64 ipath_read_creg(const struct ipath_devdata *dd, | |||
| 797 | static inline u32 ipath_read_creg32(const struct ipath_devdata *dd, | 797 | static inline u32 ipath_read_creg32(const struct ipath_devdata *dd, |
| 798 | ipath_sreg regno) | 798 | ipath_sreg regno) |
| 799 | { | 799 | { |
| 800 | if (!dd->ipath_kregbase) | 800 | if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT)) |
| 801 | return 0; | 801 | return 0; |
| 802 | return readl(regno + (u64 __iomem *) | 802 | return readl(regno + (u64 __iomem *) |
| 803 | (dd->ipath_cregbase + | 803 | (dd->ipath_cregbase + |
diff --git a/drivers/infiniband/hw/ipath/ipath_layer.c b/drivers/infiniband/hw/ipath/ipath_layer.c index 69ed1100701a..9cb5258ffed9 100644 --- a/drivers/infiniband/hw/ipath/ipath_layer.c +++ b/drivers/infiniband/hw/ipath/ipath_layer.c | |||
| @@ -46,13 +46,15 @@ | |||
| 46 | /* Acquire before ipath_devs_lock. */ | 46 | /* Acquire before ipath_devs_lock. */ |
| 47 | static DEFINE_MUTEX(ipath_layer_mutex); | 47 | static DEFINE_MUTEX(ipath_layer_mutex); |
| 48 | 48 | ||
| 49 | static int ipath_verbs_registered; | ||
| 50 | |||
| 49 | u16 ipath_layer_rcv_opcode; | 51 | u16 ipath_layer_rcv_opcode; |
| 52 | |||
| 50 | static int (*layer_intr)(void *, u32); | 53 | static int (*layer_intr)(void *, u32); |
| 51 | static int (*layer_rcv)(void *, void *, struct sk_buff *); | 54 | static int (*layer_rcv)(void *, void *, struct sk_buff *); |
| 52 | static int (*layer_rcv_lid)(void *, void *); | 55 | static int (*layer_rcv_lid)(void *, void *); |
| 53 | static int (*verbs_piobufavail)(void *); | 56 | static int (*verbs_piobufavail)(void *); |
| 54 | static void (*verbs_rcv)(void *, void *, void *, u32); | 57 | static void (*verbs_rcv)(void *, void *, void *, u32); |
| 55 | static int ipath_verbs_registered; | ||
| 56 | 58 | ||
| 57 | static void *(*layer_add_one)(int, struct ipath_devdata *); | 59 | static void *(*layer_add_one)(int, struct ipath_devdata *); |
| 58 | static void (*layer_remove_one)(void *); | 60 | static void (*layer_remove_one)(void *); |
| @@ -586,6 +588,8 @@ void ipath_verbs_unregister(void) | |||
| 586 | verbs_rcv = NULL; | 588 | verbs_rcv = NULL; |
| 587 | verbs_timer_cb = NULL; | 589 | verbs_timer_cb = NULL; |
| 588 | 590 | ||
| 591 | ipath_verbs_registered = 0; | ||
| 592 | |||
| 589 | mutex_unlock(&ipath_layer_mutex); | 593 | mutex_unlock(&ipath_layer_mutex); |
| 590 | } | 594 | } |
| 591 | 595 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_pe800.c b/drivers/infiniband/hw/ipath/ipath_pe800.c index e1dc4f757062..6318067ab5ec 100644 --- a/drivers/infiniband/hw/ipath/ipath_pe800.c +++ b/drivers/infiniband/hw/ipath/ipath_pe800.c | |||
| @@ -972,6 +972,8 @@ static int ipath_setup_pe_reset(struct ipath_devdata *dd) | |||
| 972 | /* Use ERROR so it shows up in logs, etc. */ | 972 | /* Use ERROR so it shows up in logs, etc. */ |
| 973 | ipath_dev_err(dd, "Resetting PE-800 unit %u\n", | 973 | ipath_dev_err(dd, "Resetting PE-800 unit %u\n", |
| 974 | dd->ipath_unit); | 974 | dd->ipath_unit); |
| 975 | /* keep chip from being accessed in a few places */ | ||
| 976 | dd->ipath_flags &= ~(IPATH_INITTED|IPATH_PRESENT); | ||
| 975 | val = dd->ipath_control | INFINIPATH_C_RESET; | 977 | val = dd->ipath_control | INFINIPATH_C_RESET; |
| 976 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, val); | 978 | ipath_write_kreg(dd, dd->ipath_kregs->kr_control, val); |
| 977 | mb(); | 979 | mb(); |
| @@ -997,6 +999,8 @@ static int ipath_setup_pe_reset(struct ipath_devdata *dd) | |||
| 997 | if ((r = pci_enable_device(dd->pcidev))) | 999 | if ((r = pci_enable_device(dd->pcidev))) |
| 998 | ipath_dev_err(dd, "pci_enable_device failed after " | 1000 | ipath_dev_err(dd, "pci_enable_device failed after " |
| 999 | "reset: %d\n", r); | 1001 | "reset: %d\n", r); |
| 1002 | /* whether it worked or not, mark as present, again */ | ||
| 1003 | dd->ipath_flags |= IPATH_PRESENT; | ||
| 1000 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_revision); | 1004 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_revision); |
| 1001 | if (val == dd->ipath_revision) { | 1005 | if (val == dd->ipath_revision) { |
| 1002 | ipath_cdbg(VERBOSE, "Got matching revision " | 1006 | ipath_cdbg(VERBOSE, "Got matching revision " |
diff --git a/drivers/infiniband/hw/ipath/ipath_registers.h b/drivers/infiniband/hw/ipath/ipath_registers.h index 1e59750c5f63..402126eb79c9 100644 --- a/drivers/infiniband/hw/ipath/ipath_registers.h +++ b/drivers/infiniband/hw/ipath/ipath_registers.h | |||
| @@ -34,8 +34,9 @@ | |||
| 34 | #define _IPATH_REGISTERS_H | 34 | #define _IPATH_REGISTERS_H |
| 35 | 35 | ||
| 36 | /* | 36 | /* |
| 37 | * This file should only be included by kernel source, and by the diags. | 37 | * This file should only be included by kernel source, and by the diags. It |
| 38 | * It defines the registers, and their contents, for the InfiniPath HT-400 chip | 38 | * defines the registers, and their contents, for the InfiniPath HT-400 |
| 39 | * chip. | ||
| 39 | */ | 40 | */ |
| 40 | 41 | ||
| 41 | /* | 42 | /* |
| @@ -156,8 +157,10 @@ | |||
| 156 | #define INFINIPATH_IBCC_FLOWCTRLWATERMARK_SHIFT 8 | 157 | #define INFINIPATH_IBCC_FLOWCTRLWATERMARK_SHIFT 8 |
| 157 | #define INFINIPATH_IBCC_LINKINITCMD_MASK 0x3ULL | 158 | #define INFINIPATH_IBCC_LINKINITCMD_MASK 0x3ULL |
| 158 | #define INFINIPATH_IBCC_LINKINITCMD_DISABLE 1 | 159 | #define INFINIPATH_IBCC_LINKINITCMD_DISABLE 1 |
| 159 | #define INFINIPATH_IBCC_LINKINITCMD_POLL 2 /* cycle through TS1/TS2 till OK */ | 160 | /* cycle through TS1/TS2 till OK */ |
| 160 | #define INFINIPATH_IBCC_LINKINITCMD_SLEEP 3 /* wait for TS1, then go on */ | 161 | #define INFINIPATH_IBCC_LINKINITCMD_POLL 2 |
| 162 | /* wait for TS1, then go on */ | ||
| 163 | #define INFINIPATH_IBCC_LINKINITCMD_SLEEP 3 | ||
| 161 | #define INFINIPATH_IBCC_LINKINITCMD_SHIFT 16 | 164 | #define INFINIPATH_IBCC_LINKINITCMD_SHIFT 16 |
| 162 | #define INFINIPATH_IBCC_LINKCMD_MASK 0x3ULL | 165 | #define INFINIPATH_IBCC_LINKCMD_MASK 0x3ULL |
| 163 | #define INFINIPATH_IBCC_LINKCMD_INIT 1 /* move to 0x11 */ | 166 | #define INFINIPATH_IBCC_LINKCMD_INIT 1 /* move to 0x11 */ |
| @@ -182,7 +185,8 @@ | |||
| 182 | #define INFINIPATH_IBCS_LINKSTATE_SHIFT 4 | 185 | #define INFINIPATH_IBCS_LINKSTATE_SHIFT 4 |
| 183 | #define INFINIPATH_IBCS_TXREADY 0x40000000 | 186 | #define INFINIPATH_IBCS_TXREADY 0x40000000 |
| 184 | #define INFINIPATH_IBCS_TXCREDITOK 0x80000000 | 187 | #define INFINIPATH_IBCS_TXCREDITOK 0x80000000 |
| 185 | /* link training states (shift by INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) */ | 188 | /* link training states (shift by |
| 189 | INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) */ | ||
| 186 | #define INFINIPATH_IBCS_LT_STATE_DISABLED 0x00 | 190 | #define INFINIPATH_IBCS_LT_STATE_DISABLED 0x00 |
| 187 | #define INFINIPATH_IBCS_LT_STATE_LINKUP 0x01 | 191 | #define INFINIPATH_IBCS_LT_STATE_LINKUP 0x01 |
| 188 | #define INFINIPATH_IBCS_LT_STATE_POLLACTIVE 0x02 | 192 | #define INFINIPATH_IBCS_LT_STATE_POLLACTIVE 0x02 |
| @@ -267,10 +271,12 @@ | |||
| 267 | /* kr_serdesconfig0 bits */ | 271 | /* kr_serdesconfig0 bits */ |
| 268 | #define INFINIPATH_SERDC0_RESET_MASK 0xfULL /* overal reset bits */ | 272 | #define INFINIPATH_SERDC0_RESET_MASK 0xfULL /* overal reset bits */ |
| 269 | #define INFINIPATH_SERDC0_RESET_PLL 0x10000000ULL /* pll reset */ | 273 | #define INFINIPATH_SERDC0_RESET_PLL 0x10000000ULL /* pll reset */ |
| 270 | #define INFINIPATH_SERDC0_TXIDLE 0xF000ULL /* tx idle enables (per lane) */ | 274 | /* tx idle enables (per lane) */ |
| 271 | #define INFINIPATH_SERDC0_RXDETECT_EN 0xF0000ULL /* rx detect enables (per lane) */ | 275 | #define INFINIPATH_SERDC0_TXIDLE 0xF000ULL |
| 272 | #define INFINIPATH_SERDC0_L1PWR_DN 0xF0ULL /* L1 Power down; use with RXDETECT, | 276 | /* rx detect enables (per lane) */ |
| 273 | Otherwise not used on IB side */ | 277 | #define INFINIPATH_SERDC0_RXDETECT_EN 0xF0000ULL |
| 278 | /* L1 Power down; use with RXDETECT, Otherwise not used on IB side */ | ||
| 279 | #define INFINIPATH_SERDC0_L1PWR_DN 0xF0ULL | ||
| 274 | 280 | ||
| 275 | /* kr_xgxsconfig bits */ | 281 | /* kr_xgxsconfig bits */ |
| 276 | #define INFINIPATH_XGXS_RESET 0x7ULL | 282 | #define INFINIPATH_XGXS_RESET 0x7ULL |
| @@ -390,12 +396,13 @@ struct ipath_kregs { | |||
| 390 | ipath_kreg kr_txintmemsize; | 396 | ipath_kreg kr_txintmemsize; |
| 391 | ipath_kreg kr_xgxsconfig; | 397 | ipath_kreg kr_xgxsconfig; |
| 392 | ipath_kreg kr_ibpllcfg; | 398 | ipath_kreg kr_ibpllcfg; |
| 393 | /* use these two (and the following N ports) only with ipath_k*_kreg64_port(); | 399 | /* use these two (and the following N ports) only with |
| 394 | * not *kreg64() */ | 400 | * ipath_k*_kreg64_port(); not *kreg64() */ |
| 395 | ipath_kreg kr_rcvhdraddr; | 401 | ipath_kreg kr_rcvhdraddr; |
| 396 | ipath_kreg kr_rcvhdrtailaddr; | 402 | ipath_kreg kr_rcvhdrtailaddr; |
| 397 | 403 | ||
| 398 | /* remaining registers are not present on all types of infinipath chips */ | 404 | /* remaining registers are not present on all types of infinipath |
| 405 | chips */ | ||
| 399 | ipath_kreg kr_rcvpktledcnt; | 406 | ipath_kreg kr_rcvpktledcnt; |
| 400 | ipath_kreg kr_pcierbuftestreg0; | 407 | ipath_kreg kr_pcierbuftestreg0; |
| 401 | ipath_kreg kr_pcierbuftestreg1; | 408 | ipath_kreg kr_pcierbuftestreg1; |
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c index f232e77b78ee..eb81424b3c5b 100644 --- a/drivers/infiniband/hw/ipath/ipath_ruc.c +++ b/drivers/infiniband/hw/ipath/ipath_ruc.c | |||
| @@ -531,19 +531,12 @@ int ipath_post_rc_send(struct ipath_qp *qp, struct ib_send_wr *wr) | |||
| 531 | } | 531 | } |
| 532 | wqe->wr.num_sge = j; | 532 | wqe->wr.num_sge = j; |
| 533 | qp->s_head = next; | 533 | qp->s_head = next; |
| 534 | /* | ||
| 535 | * Wake up the send tasklet if the QP is not waiting | ||
| 536 | * for an RNR timeout. | ||
| 537 | */ | ||
| 538 | next = qp->s_rnr_timeout; | ||
| 539 | spin_unlock_irqrestore(&qp->s_lock, flags); | 534 | spin_unlock_irqrestore(&qp->s_lock, flags); |
| 540 | 535 | ||
| 541 | if (next == 0) { | 536 | if (qp->ibqp.qp_type == IB_QPT_UC) |
| 542 | if (qp->ibqp.qp_type == IB_QPT_UC) | 537 | ipath_do_uc_send((unsigned long) qp); |
| 543 | ipath_do_uc_send((unsigned long) qp); | 538 | else |
| 544 | else | 539 | ipath_do_rc_send((unsigned long) qp); |
| 545 | ipath_do_rc_send((unsigned long) qp); | ||
| 546 | } | ||
| 547 | 540 | ||
| 548 | ret = 0; | 541 | ret = 0; |
| 549 | 542 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c index 32acd8048b49..f323791cc495 100644 --- a/drivers/infiniband/hw/ipath/ipath_sysfs.c +++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c | |||
| @@ -711,10 +711,22 @@ static struct attribute_group dev_attr_group = { | |||
| 711 | * enters diag mode. A device reset is quite likely to crash the | 711 | * enters diag mode. A device reset is quite likely to crash the |
| 712 | * machine entirely, so we don't want to normally make it | 712 | * machine entirely, so we don't want to normally make it |
| 713 | * available. | 713 | * available. |
| 714 | * | ||
| 715 | * Called with ipath_mutex held. | ||
| 714 | */ | 716 | */ |
| 715 | int ipath_expose_reset(struct device *dev) | 717 | int ipath_expose_reset(struct device *dev) |
| 716 | { | 718 | { |
| 717 | return device_create_file(dev, &dev_attr_reset); | 719 | static int exposed; |
| 720 | int ret; | ||
| 721 | |||
| 722 | if (!exposed) { | ||
| 723 | ret = device_create_file(dev, &dev_attr_reset); | ||
| 724 | exposed = 1; | ||
| 725 | } | ||
| 726 | else | ||
| 727 | ret = 0; | ||
| 728 | |||
| 729 | return ret; | ||
| 718 | } | 730 | } |
| 719 | 731 | ||
| 720 | int ipath_driver_create_group(struct device_driver *drv) | 732 | int ipath_driver_create_group(struct device_driver *drv) |
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c index 01cfb30ee160..e606daf83210 100644 --- a/drivers/infiniband/hw/ipath/ipath_ud.c +++ b/drivers/infiniband/hw/ipath/ipath_ud.c | |||
| @@ -46,8 +46,10 @@ | |||
| 46 | * This is called from ipath_post_ud_send() to forward a WQE addressed | 46 | * This is called from ipath_post_ud_send() to forward a WQE addressed |
| 47 | * to the same HCA. | 47 | * to the same HCA. |
| 48 | */ | 48 | */ |
| 49 | static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_sge_state *ss, | 49 | static void ipath_ud_loopback(struct ipath_qp *sqp, |
| 50 | u32 length, struct ib_send_wr *wr, struct ib_wc *wc) | 50 | struct ipath_sge_state *ss, |
| 51 | u32 length, struct ib_send_wr *wr, | ||
| 52 | struct ib_wc *wc) | ||
| 51 | { | 53 | { |
| 52 | struct ipath_ibdev *dev = to_idev(sqp->ibqp.device); | 54 | struct ipath_ibdev *dev = to_idev(sqp->ibqp.device); |
| 53 | struct ipath_qp *qp; | 55 | struct ipath_qp *qp; |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index 8d2558a01f35..cb9e387c301f 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c | |||
| @@ -449,7 +449,6 @@ static void ipath_ib_timer(void *arg) | |||
| 449 | { | 449 | { |
| 450 | struct ipath_ibdev *dev = (struct ipath_ibdev *) arg; | 450 | struct ipath_ibdev *dev = (struct ipath_ibdev *) arg; |
| 451 | struct ipath_qp *resend = NULL; | 451 | struct ipath_qp *resend = NULL; |
| 452 | struct ipath_qp *rnr = NULL; | ||
| 453 | struct list_head *last; | 452 | struct list_head *last; |
| 454 | struct ipath_qp *qp; | 453 | struct ipath_qp *qp; |
| 455 | unsigned long flags; | 454 | unsigned long flags; |
| @@ -465,32 +464,18 @@ static void ipath_ib_timer(void *arg) | |||
| 465 | last = &dev->pending[dev->pending_index]; | 464 | last = &dev->pending[dev->pending_index]; |
| 466 | while (!list_empty(last)) { | 465 | while (!list_empty(last)) { |
| 467 | qp = list_entry(last->next, struct ipath_qp, timerwait); | 466 | qp = list_entry(last->next, struct ipath_qp, timerwait); |
| 468 | if (last->next == LIST_POISON1 || | 467 | list_del(&qp->timerwait); |
| 469 | last->next != &qp->timerwait || | 468 | qp->timer_next = resend; |
| 470 | qp->timerwait.prev != last) { | 469 | resend = qp; |
| 471 | INIT_LIST_HEAD(last); | 470 | atomic_inc(&qp->refcount); |
| 472 | } else { | ||
| 473 | list_del(&qp->timerwait); | ||
| 474 | qp->timerwait.prev = (struct list_head *) resend; | ||
| 475 | resend = qp; | ||
| 476 | atomic_inc(&qp->refcount); | ||
| 477 | } | ||
| 478 | } | 471 | } |
| 479 | last = &dev->rnrwait; | 472 | last = &dev->rnrwait; |
| 480 | if (!list_empty(last)) { | 473 | if (!list_empty(last)) { |
| 481 | qp = list_entry(last->next, struct ipath_qp, timerwait); | 474 | qp = list_entry(last->next, struct ipath_qp, timerwait); |
| 482 | if (--qp->s_rnr_timeout == 0) { | 475 | if (--qp->s_rnr_timeout == 0) { |
| 483 | do { | 476 | do { |
| 484 | if (last->next == LIST_POISON1 || | ||
| 485 | last->next != &qp->timerwait || | ||
| 486 | qp->timerwait.prev != last) { | ||
| 487 | INIT_LIST_HEAD(last); | ||
| 488 | break; | ||
| 489 | } | ||
| 490 | list_del(&qp->timerwait); | 477 | list_del(&qp->timerwait); |
| 491 | qp->timerwait.prev = | 478 | tasklet_hi_schedule(&qp->s_task); |
| 492 | (struct list_head *) rnr; | ||
| 493 | rnr = qp; | ||
| 494 | if (list_empty(last)) | 479 | if (list_empty(last)) |
| 495 | break; | 480 | break; |
| 496 | qp = list_entry(last->next, struct ipath_qp, | 481 | qp = list_entry(last->next, struct ipath_qp, |
| @@ -530,8 +515,7 @@ static void ipath_ib_timer(void *arg) | |||
| 530 | spin_unlock_irqrestore(&dev->pending_lock, flags); | 515 | spin_unlock_irqrestore(&dev->pending_lock, flags); |
| 531 | 516 | ||
| 532 | /* XXX What if timer fires again while this is running? */ | 517 | /* XXX What if timer fires again while this is running? */ |
| 533 | for (qp = resend; qp != NULL; | 518 | for (qp = resend; qp != NULL; qp = qp->timer_next) { |
| 534 | qp = (struct ipath_qp *) qp->timerwait.prev) { | ||
| 535 | struct ib_wc wc; | 519 | struct ib_wc wc; |
| 536 | 520 | ||
| 537 | spin_lock_irqsave(&qp->s_lock, flags); | 521 | spin_lock_irqsave(&qp->s_lock, flags); |
| @@ -545,9 +529,6 @@ static void ipath_ib_timer(void *arg) | |||
| 545 | if (atomic_dec_and_test(&qp->refcount)) | 529 | if (atomic_dec_and_test(&qp->refcount)) |
| 546 | wake_up(&qp->wait); | 530 | wake_up(&qp->wait); |
| 547 | } | 531 | } |
| 548 | for (qp = rnr; qp != NULL; | ||
| 549 | qp = (struct ipath_qp *) qp->timerwait.prev) | ||
| 550 | tasklet_hi_schedule(&qp->s_task); | ||
| 551 | } | 532 | } |
| 552 | 533 | ||
| 553 | /** | 534 | /** |
| @@ -556,9 +537,9 @@ static void ipath_ib_timer(void *arg) | |||
| 556 | * | 537 | * |
| 557 | * This is called from ipath_intr() at interrupt level when a PIO buffer is | 538 | * This is called from ipath_intr() at interrupt level when a PIO buffer is |
| 558 | * available after ipath_verbs_send() returned an error that no buffers were | 539 | * available after ipath_verbs_send() returned an error that no buffers were |
| 559 | * available. Return 0 if we consumed all the PIO buffers and we still have | 540 | * available. Return 1 if we consumed all the PIO buffers and we still have |
| 560 | * QPs waiting for buffers (for now, just do a tasklet_hi_schedule and | 541 | * QPs waiting for buffers (for now, just do a tasklet_hi_schedule and |
| 561 | * return one). | 542 | * return zero). |
| 562 | */ | 543 | */ |
| 563 | static int ipath_ib_piobufavail(void *arg) | 544 | static int ipath_ib_piobufavail(void *arg) |
| 564 | { | 545 | { |
| @@ -579,7 +560,7 @@ static int ipath_ib_piobufavail(void *arg) | |||
| 579 | spin_unlock_irqrestore(&dev->pending_lock, flags); | 560 | spin_unlock_irqrestore(&dev->pending_lock, flags); |
| 580 | 561 | ||
| 581 | bail: | 562 | bail: |
| 582 | return 1; | 563 | return 0; |
| 583 | } | 564 | } |
| 584 | 565 | ||
| 585 | static int ipath_query_device(struct ib_device *ibdev, | 566 | static int ipath_query_device(struct ib_device *ibdev, |
| @@ -1159,7 +1140,7 @@ static ssize_t show_stats(struct class_device *cdev, char *buf) | |||
| 1159 | 1140 | ||
| 1160 | len = sprintf(buf, | 1141 | len = sprintf(buf, |
| 1161 | "RC resends %d\n" | 1142 | "RC resends %d\n" |
| 1162 | "RC QACKs %d\n" | 1143 | "RC no QACK %d\n" |
| 1163 | "RC ACKs %d\n" | 1144 | "RC ACKs %d\n" |
| 1164 | "RC SEQ NAKs %d\n" | 1145 | "RC SEQ NAKs %d\n" |
| 1165 | "RC RDMA seq %d\n" | 1146 | "RC RDMA seq %d\n" |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h index fcafbc7c9e71..4f8d59300e9b 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.h +++ b/drivers/infiniband/hw/ipath/ipath_verbs.h | |||
| @@ -282,7 +282,8 @@ struct ipath_srq { | |||
| 282 | */ | 282 | */ |
| 283 | struct ipath_qp { | 283 | struct ipath_qp { |
| 284 | struct ib_qp ibqp; | 284 | struct ib_qp ibqp; |
| 285 | struct ipath_qp *next; /* link list for QPN hash table */ | 285 | struct ipath_qp *next; /* link list for QPN hash table */ |
| 286 | struct ipath_qp *timer_next; /* link list for ipath_ib_timer() */ | ||
| 286 | struct list_head piowait; /* link for wait PIO buf */ | 287 | struct list_head piowait; /* link for wait PIO buf */ |
| 287 | struct list_head timerwait; /* link for waiting for timeouts */ | 288 | struct list_head timerwait; /* link for waiting for timeouts */ |
| 288 | struct ib_ah_attr remote_ah_attr; | 289 | struct ib_ah_attr remote_ah_attr; |
diff --git a/drivers/infiniband/hw/ipath/ips_common.h b/drivers/infiniband/hw/ipath/ips_common.h index 410a764dfcef..ab7cbbbfd03a 100644 --- a/drivers/infiniband/hw/ipath/ips_common.h +++ b/drivers/infiniband/hw/ipath/ips_common.h | |||
| @@ -95,7 +95,7 @@ struct ether_header { | |||
| 95 | __u8 seq_num; | 95 | __u8 seq_num; |
| 96 | __le32 len; | 96 | __le32 len; |
| 97 | /* MUST be of word size due to PIO write requirements */ | 97 | /* MUST be of word size due to PIO write requirements */ |
| 98 | __u32 csum; | 98 | __le32 csum; |
| 99 | __le16 csum_offset; | 99 | __le16 csum_offset; |
| 100 | __le16 flags; | 100 | __le16 flags; |
| 101 | __u16 first_2_bytes; | 101 | __u16 first_2_bytes; |
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 565a24b1756f..a2eae8a30167 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c | |||
| @@ -306,7 +306,7 @@ static int mthca_query_gid(struct ib_device *ibdev, u8 port, | |||
| 306 | goto out; | 306 | goto out; |
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | memcpy(gid->raw + 8, out_mad->data + (index % 8) * 16, 8); | 309 | memcpy(gid->raw + 8, out_mad->data + (index % 8) * 8, 8); |
| 310 | 310 | ||
| 311 | out: | 311 | out: |
| 312 | kfree(in_mad); | 312 | kfree(in_mad); |
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 1042987856f7..5013703db0e6 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 20 | #include <asm/irq.h> | 20 | //#include <asm/irq.h> |
| 21 | 21 | ||
| 22 | #include <asm/arch/sharpsl.h> | 22 | #include <asm/arch/sharpsl.h> |
| 23 | #include <asm/arch/hardware.h> | 23 | #include <asm/arch/hardware.h> |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 6081941de1b3..4070eff6f0f8 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -315,10 +315,11 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int | |||
| 315 | if (r1_bio->bios[mirror] == bio) | 315 | if (r1_bio->bios[mirror] == bio) |
| 316 | break; | 316 | break; |
| 317 | 317 | ||
| 318 | if (error == -ENOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) { | 318 | if (error == -EOPNOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) { |
| 319 | set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags); | 319 | set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags); |
| 320 | set_bit(R1BIO_BarrierRetry, &r1_bio->state); | 320 | set_bit(R1BIO_BarrierRetry, &r1_bio->state); |
| 321 | r1_bio->mddev->barriers_work = 0; | 321 | r1_bio->mddev->barriers_work = 0; |
| 322 | /* Don't rdev_dec_pending in this branch - keep it for the retry */ | ||
| 322 | } else { | 323 | } else { |
| 323 | /* | 324 | /* |
| 324 | * this branch is our 'one mirror IO has finished' event handler: | 325 | * this branch is our 'one mirror IO has finished' event handler: |
| @@ -365,6 +366,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int | |||
| 365 | } | 366 | } |
| 366 | } | 367 | } |
| 367 | } | 368 | } |
| 369 | rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); | ||
| 368 | } | 370 | } |
| 369 | /* | 371 | /* |
| 370 | * | 372 | * |
| @@ -374,11 +376,9 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int | |||
| 374 | if (atomic_dec_and_test(&r1_bio->remaining)) { | 376 | if (atomic_dec_and_test(&r1_bio->remaining)) { |
| 375 | if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) { | 377 | if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) { |
| 376 | reschedule_retry(r1_bio); | 378 | reschedule_retry(r1_bio); |
| 377 | /* Don't dec_pending yet, we want to hold | ||
| 378 | * the reference over the retry | ||
| 379 | */ | ||
| 380 | goto out; | 379 | goto out; |
| 381 | } | 380 | } |
| 381 | /* it really is the end of this request */ | ||
| 382 | if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { | 382 | if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { |
| 383 | /* free extra copy of the data pages */ | 383 | /* free extra copy of the data pages */ |
| 384 | int i = bio->bi_vcnt; | 384 | int i = bio->bi_vcnt; |
| @@ -393,8 +393,6 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int | |||
| 393 | md_write_end(r1_bio->mddev); | 393 | md_write_end(r1_bio->mddev); |
| 394 | raid_end_bio_io(r1_bio); | 394 | raid_end_bio_io(r1_bio); |
| 395 | } | 395 | } |
| 396 | |||
| 397 | rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); | ||
| 398 | out: | 396 | out: |
| 399 | if (to_put) | 397 | if (to_put) |
| 400 | bio_put(to_put); | 398 | bio_put(to_put); |
| @@ -753,18 +751,24 @@ static int make_request(request_queue_t *q, struct bio * bio) | |||
| 753 | const int rw = bio_data_dir(bio); | 751 | const int rw = bio_data_dir(bio); |
| 754 | int do_barriers; | 752 | int do_barriers; |
| 755 | 753 | ||
| 756 | if (unlikely(!mddev->barriers_work && bio_barrier(bio))) { | ||
| 757 | bio_endio(bio, bio->bi_size, -EOPNOTSUPP); | ||
| 758 | return 0; | ||
| 759 | } | ||
| 760 | |||
| 761 | /* | 754 | /* |
| 762 | * Register the new request and wait if the reconstruction | 755 | * Register the new request and wait if the reconstruction |
| 763 | * thread has put up a bar for new requests. | 756 | * thread has put up a bar for new requests. |
| 764 | * Continue immediately if no resync is active currently. | 757 | * Continue immediately if no resync is active currently. |
| 758 | * We test barriers_work *after* md_write_start as md_write_start | ||
| 759 | * may cause the first superblock write, and that will check out | ||
| 760 | * if barriers work. | ||
| 765 | */ | 761 | */ |
| 762 | |||
| 766 | md_write_start(mddev, bio); /* wait on superblock update early */ | 763 | md_write_start(mddev, bio); /* wait on superblock update early */ |
| 767 | 764 | ||
| 765 | if (unlikely(!mddev->barriers_work && bio_barrier(bio))) { | ||
| 766 | if (rw == WRITE) | ||
| 767 | md_write_end(mddev); | ||
| 768 | bio_endio(bio, bio->bi_size, -EOPNOTSUPP); | ||
| 769 | return 0; | ||
| 770 | } | ||
| 771 | |||
| 768 | wait_barrier(conf); | 772 | wait_barrier(conf); |
| 769 | 773 | ||
| 770 | disk_stat_inc(mddev->gendisk, ios[rw]); | 774 | disk_stat_inc(mddev->gendisk, ios[rw]); |
| @@ -1404,10 +1408,11 @@ static void raid1d(mddev_t *mddev) | |||
| 1404 | unplug = 1; | 1408 | unplug = 1; |
| 1405 | } else if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) { | 1409 | } else if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) { |
| 1406 | /* some requests in the r1bio were BIO_RW_BARRIER | 1410 | /* some requests in the r1bio were BIO_RW_BARRIER |
| 1407 | * requests which failed with -ENOTSUPP. Hohumm.. | 1411 | * requests which failed with -EOPNOTSUPP. Hohumm.. |
| 1408 | * Better resubmit without the barrier. | 1412 | * Better resubmit without the barrier. |
| 1409 | * We know which devices to resubmit for, because | 1413 | * We know which devices to resubmit for, because |
| 1410 | * all others have had their bios[] entry cleared. | 1414 | * all others have had their bios[] entry cleared. |
| 1415 | * We already have a nr_pending reference on these rdevs. | ||
| 1411 | */ | 1416 | */ |
| 1412 | int i; | 1417 | int i; |
| 1413 | clear_bit(R1BIO_BarrierRetry, &r1_bio->state); | 1418 | clear_bit(R1BIO_BarrierRetry, &r1_bio->state); |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 617012bc107a..1440935414e6 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -1407,43 +1407,54 @@ static void raid10d(mddev_t *mddev) | |||
| 1407 | if (s > (PAGE_SIZE>>9)) | 1407 | if (s > (PAGE_SIZE>>9)) |
| 1408 | s = PAGE_SIZE >> 9; | 1408 | s = PAGE_SIZE >> 9; |
| 1409 | 1409 | ||
| 1410 | rcu_read_lock(); | ||
| 1410 | do { | 1411 | do { |
| 1411 | int d = r10_bio->devs[sl].devnum; | 1412 | int d = r10_bio->devs[sl].devnum; |
| 1412 | rdev = conf->mirrors[d].rdev; | 1413 | rdev = rcu_dereference(conf->mirrors[d].rdev); |
| 1413 | if (rdev && | 1414 | if (rdev && |
| 1414 | test_bit(In_sync, &rdev->flags) && | 1415 | test_bit(In_sync, &rdev->flags)) { |
| 1415 | sync_page_io(rdev->bdev, | 1416 | atomic_inc(&rdev->nr_pending); |
| 1416 | r10_bio->devs[sl].addr + | 1417 | rcu_read_unlock(); |
| 1417 | sect + rdev->data_offset, | 1418 | success = sync_page_io(rdev->bdev, |
| 1418 | s<<9, | 1419 | r10_bio->devs[sl].addr + |
| 1419 | conf->tmppage, READ)) | 1420 | sect + rdev->data_offset, |
| 1420 | success = 1; | 1421 | s<<9, |
| 1421 | else { | 1422 | conf->tmppage, READ); |
| 1422 | sl++; | 1423 | rdev_dec_pending(rdev, mddev); |
| 1423 | if (sl == conf->copies) | 1424 | rcu_read_lock(); |
| 1424 | sl = 0; | 1425 | if (success) |
| 1426 | break; | ||
| 1425 | } | 1427 | } |
| 1428 | sl++; | ||
| 1429 | if (sl == conf->copies) | ||
| 1430 | sl = 0; | ||
| 1426 | } while (!success && sl != r10_bio->read_slot); | 1431 | } while (!success && sl != r10_bio->read_slot); |
| 1432 | rcu_read_unlock(); | ||
| 1427 | 1433 | ||
| 1428 | if (success) { | 1434 | if (success) { |
| 1429 | int start = sl; | 1435 | int start = sl; |
| 1430 | /* write it back and re-read */ | 1436 | /* write it back and re-read */ |
| 1437 | rcu_read_lock(); | ||
| 1431 | while (sl != r10_bio->read_slot) { | 1438 | while (sl != r10_bio->read_slot) { |
| 1432 | int d; | 1439 | int d; |
| 1433 | if (sl==0) | 1440 | if (sl==0) |
| 1434 | sl = conf->copies; | 1441 | sl = conf->copies; |
| 1435 | sl--; | 1442 | sl--; |
| 1436 | d = r10_bio->devs[sl].devnum; | 1443 | d = r10_bio->devs[sl].devnum; |
| 1437 | rdev = conf->mirrors[d].rdev; | 1444 | rdev = rcu_dereference(conf->mirrors[d].rdev); |
| 1438 | atomic_add(s, &rdev->corrected_errors); | ||
| 1439 | if (rdev && | 1445 | if (rdev && |
| 1440 | test_bit(In_sync, &rdev->flags)) { | 1446 | test_bit(In_sync, &rdev->flags)) { |
| 1447 | atomic_inc(&rdev->nr_pending); | ||
| 1448 | rcu_read_unlock(); | ||
| 1449 | atomic_add(s, &rdev->corrected_errors); | ||
| 1441 | if (sync_page_io(rdev->bdev, | 1450 | if (sync_page_io(rdev->bdev, |
| 1442 | r10_bio->devs[sl].addr + | 1451 | r10_bio->devs[sl].addr + |
| 1443 | sect + rdev->data_offset, | 1452 | sect + rdev->data_offset, |
| 1444 | s<<9, conf->tmppage, WRITE) == 0) | 1453 | s<<9, conf->tmppage, WRITE) == 0) |
| 1445 | /* Well, this device is dead */ | 1454 | /* Well, this device is dead */ |
| 1446 | md_error(mddev, rdev); | 1455 | md_error(mddev, rdev); |
| 1456 | rdev_dec_pending(rdev, mddev); | ||
| 1457 | rcu_read_lock(); | ||
| 1447 | } | 1458 | } |
| 1448 | } | 1459 | } |
| 1449 | sl = start; | 1460 | sl = start; |
| @@ -1453,17 +1464,22 @@ static void raid10d(mddev_t *mddev) | |||
| 1453 | sl = conf->copies; | 1464 | sl = conf->copies; |
| 1454 | sl--; | 1465 | sl--; |
| 1455 | d = r10_bio->devs[sl].devnum; | 1466 | d = r10_bio->devs[sl].devnum; |
| 1456 | rdev = conf->mirrors[d].rdev; | 1467 | rdev = rcu_dereference(conf->mirrors[d].rdev); |
| 1457 | if (rdev && | 1468 | if (rdev && |
| 1458 | test_bit(In_sync, &rdev->flags)) { | 1469 | test_bit(In_sync, &rdev->flags)) { |
| 1470 | atomic_inc(&rdev->nr_pending); | ||
| 1471 | rcu_read_unlock(); | ||
| 1459 | if (sync_page_io(rdev->bdev, | 1472 | if (sync_page_io(rdev->bdev, |
| 1460 | r10_bio->devs[sl].addr + | 1473 | r10_bio->devs[sl].addr + |
| 1461 | sect + rdev->data_offset, | 1474 | sect + rdev->data_offset, |
| 1462 | s<<9, conf->tmppage, READ) == 0) | 1475 | s<<9, conf->tmppage, READ) == 0) |
| 1463 | /* Well, this device is dead */ | 1476 | /* Well, this device is dead */ |
| 1464 | md_error(mddev, rdev); | 1477 | md_error(mddev, rdev); |
| 1478 | rdev_dec_pending(rdev, mddev); | ||
| 1479 | rcu_read_lock(); | ||
| 1465 | } | 1480 | } |
| 1466 | } | 1481 | } |
| 1482 | rcu_read_unlock(); | ||
| 1467 | } else { | 1483 | } else { |
| 1468 | /* Cannot read from anywhere -- bye bye array */ | 1484 | /* Cannot read from anywhere -- bye bye array */ |
| 1469 | md_error(mddev, conf->mirrors[r10_bio->devs[r10_bio->read_slot].devnum].rdev); | 1485 | md_error(mddev, conf->mirrors[r10_bio->devs[r10_bio->read_slot].devnum].rdev); |
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c index 6061c2d101a0..88f0eef9cf33 100644 --- a/drivers/mmc/at91_mci.c +++ b/drivers/mmc/at91_mci.c | |||
| @@ -621,9 +621,6 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 621 | struct at91mci_host *host = mmc_priv(mmc); | 621 | struct at91mci_host *host = mmc_priv(mmc); |
| 622 | unsigned long at91_master_clock = clk_get_rate(mci_clk); | 622 | unsigned long at91_master_clock = clk_get_rate(mci_clk); |
| 623 | 623 | ||
| 624 | DBG("Clock %uHz, busmode %u, powermode %u, Vdd %u\n", | ||
| 625 | ios->clock, ios->bus_mode, ios->power_mode, ios->vdd); | ||
| 626 | |||
| 627 | if (host) | 624 | if (host) |
| 628 | host->bus_mode = ios->bus_mode; | 625 | host->bus_mode = ios->bus_mode; |
| 629 | else | 626 | else |
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c index c0326bbc5f28..914d62b24064 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/au1xmmc.c | |||
| @@ -720,10 +720,6 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
| 720 | { | 720 | { |
| 721 | struct au1xmmc_host *host = mmc_priv(mmc); | 721 | struct au1xmmc_host *host = mmc_priv(mmc); |
| 722 | 722 | ||
| 723 | DBG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n", | ||
| 724 | host->id, ios->power_mode, ios->clock, ios->vdd, | ||
| 725 | ios->bus_mode); | ||
| 726 | |||
| 727 | if (ios->power_mode == MMC_POWER_OFF) | 723 | if (ios->power_mode == MMC_POWER_OFF) |
| 728 | au1xmmc_set_power(host, 0); | 724 | au1xmmc_set_power(host, 0); |
| 729 | else if (ios->power_mode == MMC_POWER_ON) { | 725 | else if (ios->power_mode == MMC_POWER_ON) { |
diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c index ffb7f55d3467..79358e223f57 100644 --- a/drivers/mmc/imxmmc.c +++ b/drivers/mmc/imxmmc.c | |||
| @@ -102,6 +102,7 @@ struct imxmci_host { | |||
| 102 | #define IMXMCI_PEND_CPU_DATA_b 5 | 102 | #define IMXMCI_PEND_CPU_DATA_b 5 |
| 103 | #define IMXMCI_PEND_CARD_XCHG_b 6 | 103 | #define IMXMCI_PEND_CARD_XCHG_b 6 |
| 104 | #define IMXMCI_PEND_SET_INIT_b 7 | 104 | #define IMXMCI_PEND_SET_INIT_b 7 |
| 105 | #define IMXMCI_PEND_STARTED_b 8 | ||
| 105 | 106 | ||
| 106 | #define IMXMCI_PEND_IRQ_m (1 << IMXMCI_PEND_IRQ_b) | 107 | #define IMXMCI_PEND_IRQ_m (1 << IMXMCI_PEND_IRQ_b) |
| 107 | #define IMXMCI_PEND_DMA_END_m (1 << IMXMCI_PEND_DMA_END_b) | 108 | #define IMXMCI_PEND_DMA_END_m (1 << IMXMCI_PEND_DMA_END_b) |
| @@ -111,6 +112,7 @@ struct imxmci_host { | |||
| 111 | #define IMXMCI_PEND_CPU_DATA_m (1 << IMXMCI_PEND_CPU_DATA_b) | 112 | #define IMXMCI_PEND_CPU_DATA_m (1 << IMXMCI_PEND_CPU_DATA_b) |
| 112 | #define IMXMCI_PEND_CARD_XCHG_m (1 << IMXMCI_PEND_CARD_XCHG_b) | 113 | #define IMXMCI_PEND_CARD_XCHG_m (1 << IMXMCI_PEND_CARD_XCHG_b) |
| 113 | #define IMXMCI_PEND_SET_INIT_m (1 << IMXMCI_PEND_SET_INIT_b) | 114 | #define IMXMCI_PEND_SET_INIT_m (1 << IMXMCI_PEND_SET_INIT_b) |
| 115 | #define IMXMCI_PEND_STARTED_m (1 << IMXMCI_PEND_STARTED_b) | ||
| 114 | 116 | ||
| 115 | static void imxmci_stop_clock(struct imxmci_host *host) | 117 | static void imxmci_stop_clock(struct imxmci_host *host) |
| 116 | { | 118 | { |
| @@ -131,23 +133,52 @@ static void imxmci_stop_clock(struct imxmci_host *host) | |||
| 131 | dev_dbg(mmc_dev(host->mmc), "imxmci_stop_clock blocked, no luck\n"); | 133 | dev_dbg(mmc_dev(host->mmc), "imxmci_stop_clock blocked, no luck\n"); |
| 132 | } | 134 | } |
| 133 | 135 | ||
| 134 | static void imxmci_start_clock(struct imxmci_host *host) | 136 | static int imxmci_start_clock(struct imxmci_host *host) |
| 135 | { | 137 | { |
| 136 | int i = 0; | 138 | unsigned int trials = 0; |
| 139 | unsigned int delay_limit = 128; | ||
| 140 | unsigned long flags; | ||
| 141 | |||
| 137 | MMC_STR_STP_CLK &= ~STR_STP_CLK_STOP_CLK; | 142 | MMC_STR_STP_CLK &= ~STR_STP_CLK_STOP_CLK; |
| 138 | while(i < 0x1000) { | ||
| 139 | if(!(i & 0x7f)) | ||
| 140 | MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; | ||
| 141 | 143 | ||
| 142 | if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) { | 144 | clear_bit(IMXMCI_PEND_STARTED_b, &host->pending_events); |
| 143 | /* Check twice before cut */ | 145 | |
| 146 | /* | ||
| 147 | * Command start of the clock, this usually succeeds in less | ||
| 148 | * then 6 delay loops, but during card detection (low clockrate) | ||
| 149 | * it takes up to 5000 delay loops and sometimes fails for the first time | ||
| 150 | */ | ||
| 151 | MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; | ||
| 152 | |||
| 153 | do { | ||
| 154 | unsigned int delay = delay_limit; | ||
| 155 | |||
| 156 | while(delay--){ | ||
| 144 | if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) | 157 | if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) |
| 145 | return; | 158 | /* Check twice before cut */ |
| 159 | if(MMC_STATUS & STATUS_CARD_BUS_CLK_RUN) | ||
| 160 | return 0; | ||
| 161 | |||
| 162 | if(test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) | ||
| 163 | return 0; | ||
| 146 | } | 164 | } |
| 147 | 165 | ||
| 148 | i++; | 166 | local_irq_save(flags); |
| 149 | } | 167 | /* |
| 150 | dev_dbg(mmc_dev(host->mmc), "imxmci_start_clock blocked, no luck\n"); | 168 | * Ensure, that request is not doubled under all possible circumstances. |
| 169 | * It is possible, that cock running state is missed, because some other | ||
| 170 | * IRQ or schedule delays this function execution and the clocks has | ||
| 171 | * been already stopped by other means (response processing, SDHC HW) | ||
| 172 | */ | ||
| 173 | if(!test_bit(IMXMCI_PEND_STARTED_b, &host->pending_events)) | ||
| 174 | MMC_STR_STP_CLK |= STR_STP_CLK_START_CLK; | ||
| 175 | local_irq_restore(flags); | ||
| 176 | |||
| 177 | } while(++trials<256); | ||
| 178 | |||
| 179 | dev_err(mmc_dev(host->mmc), "imxmci_start_clock blocked, no luck\n"); | ||
| 180 | |||
| 181 | return -1; | ||
| 151 | } | 182 | } |
| 152 | 183 | ||
| 153 | static void imxmci_softreset(void) | 184 | static void imxmci_softreset(void) |
| @@ -498,7 +529,7 @@ static int imxmci_data_done(struct imxmci_host *host, unsigned int stat) | |||
| 498 | 529 | ||
| 499 | data_error = imxmci_finish_data(host, stat); | 530 | data_error = imxmci_finish_data(host, stat); |
| 500 | 531 | ||
| 501 | if (host->req->stop && (data_error == MMC_ERR_NONE)) { | 532 | if (host->req->stop) { |
| 502 | imxmci_stop_clock(host); | 533 | imxmci_stop_clock(host); |
| 503 | imxmci_start_cmd(host, host->req->stop, 0); | 534 | imxmci_start_cmd(host, host->req->stop, 0); |
| 504 | } else { | 535 | } else { |
| @@ -622,6 +653,7 @@ static irqreturn_t imxmci_irq(int irq, void *devid, struct pt_regs *regs) | |||
| 622 | atomic_set(&host->stuck_timeout, 0); | 653 | atomic_set(&host->stuck_timeout, 0); |
| 623 | host->status_reg = stat; | 654 | host->status_reg = stat; |
| 624 | set_bit(IMXMCI_PEND_IRQ_b, &host->pending_events); | 655 | set_bit(IMXMCI_PEND_IRQ_b, &host->pending_events); |
| 656 | set_bit(IMXMCI_PEND_STARTED_b, &host->pending_events); | ||
| 625 | tasklet_schedule(&host->tasklet); | 657 | tasklet_schedule(&host->tasklet); |
| 626 | 658 | ||
| 627 | return IRQ_RETVAL(handled);; | 659 | return IRQ_RETVAL(handled);; |
| @@ -775,10 +807,6 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 775 | struct imxmci_host *host = mmc_priv(mmc); | 807 | struct imxmci_host *host = mmc_priv(mmc); |
| 776 | int prescaler; | 808 | int prescaler; |
| 777 | 809 | ||
| 778 | dev_dbg(mmc_dev(host->mmc), "clock %u power %u vdd %u width %u\n", | ||
| 779 | ios->clock, ios->power_mode, ios->vdd, | ||
| 780 | (ios->bus_width==MMC_BUS_WIDTH_4)?4:1); | ||
| 781 | |||
| 782 | if( ios->bus_width==MMC_BUS_WIDTH_4 ) { | 810 | if( ios->bus_width==MMC_BUS_WIDTH_4 ) { |
| 783 | host->actual_bus_width = MMC_BUS_WIDTH_4; | 811 | host->actual_bus_width = MMC_BUS_WIDTH_4; |
| 784 | imx_gpio_mode(PB11_PF_SD_DAT3); | 812 | imx_gpio_mode(PB11_PF_SD_DAT3); |
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index da6ddd910fc5..1ca2c8b9c9b5 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c | |||
| @@ -59,21 +59,23 @@ static const unsigned int tacc_mant[] = { | |||
| 59 | 59 | ||
| 60 | 60 | ||
| 61 | /** | 61 | /** |
| 62 | * mmc_request_done - finish processing an MMC command | 62 | * mmc_request_done - finish processing an MMC request |
| 63 | * @host: MMC host which completed command | 63 | * @host: MMC host which completed request |
| 64 | * @mrq: MMC request which completed | 64 | * @mrq: MMC request which request |
| 65 | * | 65 | * |
| 66 | * MMC drivers should call this function when they have completed | 66 | * MMC drivers should call this function when they have completed |
| 67 | * their processing of a command. This should be called before the | 67 | * their processing of a request. |
| 68 | * data part of the command has completed. | ||
| 69 | */ | 68 | */ |
| 70 | void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | 69 | void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) |
| 71 | { | 70 | { |
| 72 | struct mmc_command *cmd = mrq->cmd; | 71 | struct mmc_command *cmd = mrq->cmd; |
| 73 | int err = mrq->cmd->error; | 72 | int err = cmd->error; |
| 74 | pr_debug("MMC: req done (%02x): %d: %08x %08x %08x %08x\n", | 73 | |
| 75 | cmd->opcode, err, cmd->resp[0], cmd->resp[1], | 74 | pr_debug("%s: req done (CMD%u): %d/%d/%d: %08x %08x %08x %08x\n", |
| 76 | cmd->resp[2], cmd->resp[3]); | 75 | mmc_hostname(host), cmd->opcode, err, |
| 76 | mrq->data ? mrq->data->error : 0, | ||
| 77 | mrq->stop ? mrq->stop->error : 0, | ||
| 78 | cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); | ||
| 77 | 79 | ||
| 78 | if (err && cmd->retries) { | 80 | if (err && cmd->retries) { |
| 79 | cmd->retries--; | 81 | cmd->retries--; |
| @@ -97,8 +99,9 @@ EXPORT_SYMBOL(mmc_request_done); | |||
| 97 | void | 99 | void |
| 98 | mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) | 100 | mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) |
| 99 | { | 101 | { |
| 100 | pr_debug("MMC: starting cmd %02x arg %08x flags %08x\n", | 102 | pr_debug("%s: starting CMD%u arg %08x flags %08x\n", |
| 101 | mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags); | 103 | mmc_hostname(host), mrq->cmd->opcode, |
| 104 | mrq->cmd->arg, mrq->cmd->flags); | ||
| 102 | 105 | ||
| 103 | WARN_ON(host->card_busy == NULL); | 106 | WARN_ON(host->card_busy == NULL); |
| 104 | 107 | ||
| @@ -312,6 +315,18 @@ void mmc_release_host(struct mmc_host *host) | |||
| 312 | 315 | ||
| 313 | EXPORT_SYMBOL(mmc_release_host); | 316 | EXPORT_SYMBOL(mmc_release_host); |
| 314 | 317 | ||
| 318 | static inline void mmc_set_ios(struct mmc_host *host) | ||
| 319 | { | ||
| 320 | struct mmc_ios *ios = &host->ios; | ||
| 321 | |||
| 322 | pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", | ||
| 323 | mmc_hostname(host), ios->clock, ios->bus_mode, | ||
| 324 | ios->power_mode, ios->chip_select, ios->vdd, | ||
| 325 | ios->bus_width); | ||
| 326 | |||
| 327 | host->ops->set_ios(host, ios); | ||
| 328 | } | ||
| 329 | |||
| 315 | static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) | 330 | static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) |
| 316 | { | 331 | { |
| 317 | int err; | 332 | int err; |
| @@ -364,7 +379,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) | |||
| 364 | } | 379 | } |
| 365 | } | 380 | } |
| 366 | 381 | ||
| 367 | host->ops->set_ios(host, &host->ios); | 382 | mmc_set_ios(host); |
| 368 | 383 | ||
| 369 | return MMC_ERR_NONE; | 384 | return MMC_ERR_NONE; |
| 370 | } | 385 | } |
| @@ -415,7 +430,7 @@ static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) | |||
| 415 | ocr = 3 << bit; | 430 | ocr = 3 << bit; |
| 416 | 431 | ||
| 417 | host->ios.vdd = bit; | 432 | host->ios.vdd = bit; |
| 418 | host->ops->set_ios(host, &host->ios); | 433 | mmc_set_ios(host); |
| 419 | } else { | 434 | } else { |
| 420 | ocr = 0; | 435 | ocr = 0; |
| 421 | } | 436 | } |
| @@ -549,6 +564,7 @@ static void mmc_decode_csd(struct mmc_card *card) | |||
| 549 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); | 564 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); |
| 550 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); | 565 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); |
| 551 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); | 566 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); |
| 567 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | ||
| 552 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | 568 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); |
| 553 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | 569 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); |
| 554 | } else { | 570 | } else { |
| @@ -583,6 +599,7 @@ static void mmc_decode_csd(struct mmc_card *card) | |||
| 583 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); | 599 | csd->read_partial = UNSTUFF_BITS(resp, 79, 1); |
| 584 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); | 600 | csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); |
| 585 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); | 601 | csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); |
| 602 | csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); | ||
| 586 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); | 603 | csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); |
| 587 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); | 604 | csd->write_partial = UNSTUFF_BITS(resp, 21, 1); |
| 588 | } | 605 | } |
| @@ -666,7 +683,7 @@ static void mmc_idle_cards(struct mmc_host *host) | |||
| 666 | struct mmc_command cmd; | 683 | struct mmc_command cmd; |
| 667 | 684 | ||
| 668 | host->ios.chip_select = MMC_CS_HIGH; | 685 | host->ios.chip_select = MMC_CS_HIGH; |
| 669 | host->ops->set_ios(host, &host->ios); | 686 | mmc_set_ios(host); |
| 670 | 687 | ||
| 671 | mmc_delay(1); | 688 | mmc_delay(1); |
| 672 | 689 | ||
| @@ -679,7 +696,7 @@ static void mmc_idle_cards(struct mmc_host *host) | |||
| 679 | mmc_delay(1); | 696 | mmc_delay(1); |
| 680 | 697 | ||
| 681 | host->ios.chip_select = MMC_CS_DONTCARE; | 698 | host->ios.chip_select = MMC_CS_DONTCARE; |
| 682 | host->ops->set_ios(host, &host->ios); | 699 | mmc_set_ios(host); |
| 683 | 700 | ||
| 684 | mmc_delay(1); | 701 | mmc_delay(1); |
| 685 | } | 702 | } |
| @@ -704,13 +721,13 @@ static void mmc_power_up(struct mmc_host *host) | |||
| 704 | host->ios.chip_select = MMC_CS_DONTCARE; | 721 | host->ios.chip_select = MMC_CS_DONTCARE; |
| 705 | host->ios.power_mode = MMC_POWER_UP; | 722 | host->ios.power_mode = MMC_POWER_UP; |
| 706 | host->ios.bus_width = MMC_BUS_WIDTH_1; | 723 | host->ios.bus_width = MMC_BUS_WIDTH_1; |
| 707 | host->ops->set_ios(host, &host->ios); | 724 | mmc_set_ios(host); |
| 708 | 725 | ||
| 709 | mmc_delay(1); | 726 | mmc_delay(1); |
| 710 | 727 | ||
| 711 | host->ios.clock = host->f_min; | 728 | host->ios.clock = host->f_min; |
| 712 | host->ios.power_mode = MMC_POWER_ON; | 729 | host->ios.power_mode = MMC_POWER_ON; |
| 713 | host->ops->set_ios(host, &host->ios); | 730 | mmc_set_ios(host); |
| 714 | 731 | ||
| 715 | mmc_delay(2); | 732 | mmc_delay(2); |
| 716 | } | 733 | } |
| @@ -723,7 +740,7 @@ static void mmc_power_off(struct mmc_host *host) | |||
| 723 | host->ios.chip_select = MMC_CS_DONTCARE; | 740 | host->ios.chip_select = MMC_CS_DONTCARE; |
| 724 | host->ios.power_mode = MMC_POWER_OFF; | 741 | host->ios.power_mode = MMC_POWER_OFF; |
| 725 | host->ios.bus_width = MMC_BUS_WIDTH_1; | 742 | host->ios.bus_width = MMC_BUS_WIDTH_1; |
| 726 | host->ops->set_ios(host, &host->ios); | 743 | mmc_set_ios(host); |
| 727 | } | 744 | } |
| 728 | 745 | ||
| 729 | static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | 746 | static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) |
| @@ -971,7 +988,8 @@ static unsigned int mmc_calculate_clock(struct mmc_host *host) | |||
| 971 | if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr) | 988 | if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr) |
| 972 | max_dtr = card->csd.max_dtr; | 989 | max_dtr = card->csd.max_dtr; |
| 973 | 990 | ||
| 974 | pr_debug("MMC: selected %d.%03dMHz transfer rate\n", | 991 | pr_debug("%s: selected %d.%03dMHz transfer rate\n", |
| 992 | mmc_hostname(host), | ||
| 975 | max_dtr / 1000000, (max_dtr / 1000) % 1000); | 993 | max_dtr / 1000000, (max_dtr / 1000) % 1000); |
| 976 | 994 | ||
| 977 | return max_dtr; | 995 | return max_dtr; |
| @@ -1046,7 +1064,7 @@ static void mmc_setup(struct mmc_host *host) | |||
| 1046 | } else { | 1064 | } else { |
| 1047 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; | 1065 | host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; |
| 1048 | host->ios.clock = host->f_min; | 1066 | host->ios.clock = host->f_min; |
| 1049 | host->ops->set_ios(host, &host->ios); | 1067 | mmc_set_ios(host); |
| 1050 | 1068 | ||
| 1051 | /* | 1069 | /* |
| 1052 | * We should remember the OCR mask from the existing | 1070 | * We should remember the OCR mask from the existing |
| @@ -1082,7 +1100,7 @@ static void mmc_setup(struct mmc_host *host) | |||
| 1082 | * Ok, now switch to push-pull mode. | 1100 | * Ok, now switch to push-pull mode. |
| 1083 | */ | 1101 | */ |
| 1084 | host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; | 1102 | host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; |
| 1085 | host->ops->set_ios(host, &host->ios); | 1103 | mmc_set_ios(host); |
| 1086 | 1104 | ||
| 1087 | mmc_read_csds(host); | 1105 | mmc_read_csds(host); |
| 1088 | 1106 | ||
| @@ -1128,7 +1146,7 @@ static void mmc_rescan(void *data) | |||
| 1128 | * attached cards and the host support. | 1146 | * attached cards and the host support. |
| 1129 | */ | 1147 | */ |
| 1130 | host->ios.clock = mmc_calculate_clock(host); | 1148 | host->ios.clock = mmc_calculate_clock(host); |
| 1131 | host->ops->set_ios(host, &host->ios); | 1149 | mmc_set_ios(host); |
| 1132 | } | 1150 | } |
| 1133 | 1151 | ||
| 1134 | mmc_release_host(host); | 1152 | mmc_release_host(host); |
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index 8eb2a2ede64b..06bd1f4cb9b1 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c | |||
| @@ -187,6 +187,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 187 | brq.cmd.opcode = MMC_WRITE_BLOCK; | 187 | brq.cmd.opcode = MMC_WRITE_BLOCK; |
| 188 | brq.data.flags |= MMC_DATA_WRITE; | 188 | brq.data.flags |= MMC_DATA_WRITE; |
| 189 | brq.data.blocks = 1; | 189 | brq.data.blocks = 1; |
| 190 | |||
| 191 | /* | ||
| 192 | * Scale up the timeout by the r2w factor | ||
| 193 | */ | ||
| 194 | brq.data.timeout_ns <<= card->csd.r2w_factor; | ||
| 195 | brq.data.timeout_clks <<= card->csd.r2w_factor; | ||
| 190 | } | 196 | } |
| 191 | 197 | ||
| 192 | if (brq.data.blocks > 1) { | 198 | if (brq.data.blocks > 1) { |
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index df7e861e2fc7..da8e4d7339cc 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c | |||
| @@ -402,9 +402,6 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 402 | struct mmci_host *host = mmc_priv(mmc); | 402 | struct mmci_host *host = mmc_priv(mmc); |
| 403 | u32 clk = 0, pwr = 0; | 403 | u32 clk = 0, pwr = 0; |
| 404 | 404 | ||
| 405 | DBG(host, "clock %uHz busmode %u powermode %u Vdd %u\n", | ||
| 406 | ios->clock, ios->bus_mode, ios->power_mode, ios->vdd); | ||
| 407 | |||
| 408 | if (ios->clock) { | 405 | if (ios->clock) { |
| 409 | if (ios->clock >= host->mclk) { | 406 | if (ios->clock >= host->mclk) { |
| 410 | clk = MCI_CLK_BYPASS; | 407 | clk = MCI_CLK_BYPASS; |
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index eb42cb349420..f97b472085cb 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c | |||
| @@ -198,7 +198,6 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, | |||
| 198 | 198 | ||
| 199 | static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *mrq) | 199 | static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *mrq) |
| 200 | { | 200 | { |
| 201 | pr_debug("PXAMCI: request done\n"); | ||
| 202 | host->mrq = NULL; | 201 | host->mrq = NULL; |
| 203 | host->cmd = NULL; | 202 | host->cmd = NULL; |
| 204 | host->data = NULL; | 203 | host->data = NULL; |
| @@ -291,7 +290,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat) | |||
| 291 | pxamci_disable_irq(host, DATA_TRAN_DONE); | 290 | pxamci_disable_irq(host, DATA_TRAN_DONE); |
| 292 | 291 | ||
| 293 | host->data = NULL; | 292 | host->data = NULL; |
| 294 | if (host->mrq->stop && data->error == MMC_ERR_NONE) { | 293 | if (host->mrq->stop) { |
| 295 | pxamci_stop_clock(host); | 294 | pxamci_stop_clock(host); |
| 296 | pxamci_start_cmd(host, host->mrq->stop, 0); | 295 | pxamci_start_cmd(host, host->mrq->stop, 0); |
| 297 | } else { | 296 | } else { |
| @@ -309,12 +308,10 @@ static irqreturn_t pxamci_irq(int irq, void *devid, struct pt_regs *regs) | |||
| 309 | 308 | ||
| 310 | ireg = readl(host->base + MMC_I_REG); | 309 | ireg = readl(host->base + MMC_I_REG); |
| 311 | 310 | ||
| 312 | pr_debug("PXAMCI: irq %08x\n", ireg); | ||
| 313 | |||
| 314 | if (ireg) { | 311 | if (ireg) { |
| 315 | unsigned stat = readl(host->base + MMC_STAT); | 312 | unsigned stat = readl(host->base + MMC_STAT); |
| 316 | 313 | ||
| 317 | pr_debug("PXAMCI: stat %08x\n", stat); | 314 | pr_debug("PXAMCI: irq %08x stat %08x\n", ireg, stat); |
| 318 | 315 | ||
| 319 | if (ireg & END_CMD_RES) | 316 | if (ireg & END_CMD_RES) |
| 320 | handled |= pxamci_cmd_done(host, stat); | 317 | handled |= pxamci_cmd_done(host, stat); |
| @@ -368,10 +365,6 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 368 | { | 365 | { |
| 369 | struct pxamci_host *host = mmc_priv(mmc); | 366 | struct pxamci_host *host = mmc_priv(mmc); |
| 370 | 367 | ||
| 371 | pr_debug("pxamci_set_ios: clock %u power %u vdd %u.%02u\n", | ||
| 372 | ios->clock, ios->power_mode, ios->vdd / 100, | ||
| 373 | ios->vdd % 100); | ||
| 374 | |||
| 375 | if (ios->clock) { | 368 | if (ios->clock) { |
| 376 | unsigned int clk = CLOCKRATE / ios->clock; | 369 | unsigned int clk = CLOCKRATE / ios->clock; |
| 377 | if (CLOCKRATE / clk > ios->clock) | 370 | if (CLOCKRATE / clk > ios->clock) |
| @@ -397,7 +390,7 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 397 | host->cmdat |= CMDAT_INIT; | 390 | host->cmdat |= CMDAT_INIT; |
| 398 | } | 391 | } |
| 399 | 392 | ||
| 400 | pr_debug("pxamci_set_ios: clkrt = %x cmdat = %x\n", | 393 | pr_debug("PXAMCI: clkrt = %x cmdat = %x\n", |
| 401 | host->clkrt, host->cmdat); | 394 | host->clkrt, host->cmdat); |
| 402 | } | 395 | } |
| 403 | 396 | ||
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index bdbfca050029..b0053280ff2d 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c | |||
| @@ -570,10 +570,6 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 570 | 570 | ||
| 571 | spin_lock_irqsave(&host->lock, flags); | 571 | spin_lock_irqsave(&host->lock, flags); |
| 572 | 572 | ||
| 573 | DBG("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", | ||
| 574 | ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, | ||
| 575 | ios->vdd, ios->bus_width); | ||
| 576 | |||
| 577 | /* | 573 | /* |
| 578 | * Reset the chip on each power off. | 574 | * Reset the chip on each power off. |
| 579 | * Should clear out any weird states. | 575 | * Should clear out any weird states. |
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 511f7b0b31d2..39b3d97f891e 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c | |||
| @@ -931,10 +931,6 @@ static void wbsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 931 | struct wbsd_host *host = mmc_priv(mmc); | 931 | struct wbsd_host *host = mmc_priv(mmc); |
| 932 | u8 clk, setup, pwr; | 932 | u8 clk, setup, pwr; |
| 933 | 933 | ||
| 934 | DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", | ||
| 935 | ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, | ||
| 936 | ios->vdd, ios->bus_width); | ||
| 937 | |||
| 938 | spin_lock_bh(&host->lock); | 934 | spin_lock_bh(&host->lock); |
| 939 | 935 | ||
| 940 | /* | 936 | /* |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 9788b1ef2e7d..f7235c9bc421 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
| @@ -106,6 +106,7 @@ | |||
| 106 | * 0.51: 20 Jan 2006: Add 64bit consistent memory allocation for rings. | 106 | * 0.51: 20 Jan 2006: Add 64bit consistent memory allocation for rings. |
| 107 | * 0.52: 20 Jan 2006: Add MSI/MSIX support. | 107 | * 0.52: 20 Jan 2006: Add MSI/MSIX support. |
| 108 | * 0.53: 19 Mar 2006: Fix init from low power mode and add hw reset. | 108 | * 0.53: 19 Mar 2006: Fix init from low power mode and add hw reset. |
| 109 | * 0.54: 21 Mar 2006: Fix spin locks for multi irqs and cleanup. | ||
| 109 | * | 110 | * |
| 110 | * Known bugs: | 111 | * Known bugs: |
| 111 | * We suspect that on some hardware no TX done interrupts are generated. | 112 | * We suspect that on some hardware no TX done interrupts are generated. |
| @@ -117,7 +118,7 @@ | |||
| 117 | * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few | 118 | * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few |
| 118 | * superfluous timer interrupts from the nic. | 119 | * superfluous timer interrupts from the nic. |
| 119 | */ | 120 | */ |
| 120 | #define FORCEDETH_VERSION "0.53" | 121 | #define FORCEDETH_VERSION "0.54" |
| 121 | #define DRV_NAME "forcedeth" | 122 | #define DRV_NAME "forcedeth" |
| 122 | 123 | ||
| 123 | #include <linux/module.h> | 124 | #include <linux/module.h> |
| @@ -710,6 +711,72 @@ static void setup_hw_rings(struct net_device *dev, int rxtx_flags) | |||
| 710 | } | 711 | } |
| 711 | } | 712 | } |
| 712 | 713 | ||
| 714 | static int using_multi_irqs(struct net_device *dev) | ||
| 715 | { | ||
| 716 | struct fe_priv *np = get_nvpriv(dev); | ||
| 717 | |||
| 718 | if (!(np->msi_flags & NV_MSI_X_ENABLED) || | ||
| 719 | ((np->msi_flags & NV_MSI_X_ENABLED) && | ||
| 720 | ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) | ||
| 721 | return 0; | ||
| 722 | else | ||
| 723 | return 1; | ||
| 724 | } | ||
| 725 | |||
| 726 | static void nv_enable_irq(struct net_device *dev) | ||
| 727 | { | ||
| 728 | struct fe_priv *np = get_nvpriv(dev); | ||
| 729 | |||
| 730 | if (!using_multi_irqs(dev)) { | ||
| 731 | if (np->msi_flags & NV_MSI_X_ENABLED) | ||
| 732 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); | ||
| 733 | else | ||
| 734 | enable_irq(dev->irq); | ||
| 735 | } else { | ||
| 736 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); | ||
| 737 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); | ||
| 738 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); | ||
| 739 | } | ||
| 740 | } | ||
| 741 | |||
| 742 | static void nv_disable_irq(struct net_device *dev) | ||
| 743 | { | ||
| 744 | struct fe_priv *np = get_nvpriv(dev); | ||
| 745 | |||
| 746 | if (!using_multi_irqs(dev)) { | ||
| 747 | if (np->msi_flags & NV_MSI_X_ENABLED) | ||
| 748 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); | ||
| 749 | else | ||
| 750 | disable_irq(dev->irq); | ||
| 751 | } else { | ||
| 752 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); | ||
| 753 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); | ||
| 754 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); | ||
| 755 | } | ||
| 756 | } | ||
| 757 | |||
| 758 | /* In MSIX mode, a write to irqmask behaves as XOR */ | ||
| 759 | static void nv_enable_hw_interrupts(struct net_device *dev, u32 mask) | ||
| 760 | { | ||
| 761 | u8 __iomem *base = get_hwbase(dev); | ||
| 762 | |||
| 763 | writel(mask, base + NvRegIrqMask); | ||
| 764 | } | ||
| 765 | |||
| 766 | static void nv_disable_hw_interrupts(struct net_device *dev, u32 mask) | ||
| 767 | { | ||
| 768 | struct fe_priv *np = get_nvpriv(dev); | ||
| 769 | u8 __iomem *base = get_hwbase(dev); | ||
| 770 | |||
| 771 | if (np->msi_flags & NV_MSI_X_ENABLED) { | ||
| 772 | writel(mask, base + NvRegIrqMask); | ||
| 773 | } else { | ||
| 774 | if (np->msi_flags & NV_MSI_ENABLED) | ||
| 775 | writel(0, base + NvRegMSIIrqMask); | ||
| 776 | writel(0, base + NvRegIrqMask); | ||
| 777 | } | ||
| 778 | } | ||
| 779 | |||
| 713 | #define MII_READ (-1) | 780 | #define MII_READ (-1) |
| 714 | /* mii_rw: read/write a register on the PHY. | 781 | /* mii_rw: read/write a register on the PHY. |
| 715 | * | 782 | * |
| @@ -1019,24 +1086,25 @@ static void nv_do_rx_refill(unsigned long data) | |||
| 1019 | struct net_device *dev = (struct net_device *) data; | 1086 | struct net_device *dev = (struct net_device *) data; |
| 1020 | struct fe_priv *np = netdev_priv(dev); | 1087 | struct fe_priv *np = netdev_priv(dev); |
| 1021 | 1088 | ||
| 1022 | 1089 | if (!using_multi_irqs(dev)) { | |
| 1023 | if (!(np->msi_flags & NV_MSI_X_ENABLED) || | 1090 | if (np->msi_flags & NV_MSI_X_ENABLED) |
| 1024 | ((np->msi_flags & NV_MSI_X_ENABLED) && | 1091 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); |
| 1025 | ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) { | 1092 | else |
| 1026 | disable_irq(dev->irq); | 1093 | disable_irq(dev->irq); |
| 1027 | } else { | 1094 | } else { |
| 1028 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); | 1095 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); |
| 1029 | } | 1096 | } |
| 1030 | if (nv_alloc_rx(dev)) { | 1097 | if (nv_alloc_rx(dev)) { |
| 1031 | spin_lock(&np->lock); | 1098 | spin_lock_irq(&np->lock); |
| 1032 | if (!np->in_shutdown) | 1099 | if (!np->in_shutdown) |
| 1033 | mod_timer(&np->oom_kick, jiffies + OOM_REFILL); | 1100 | mod_timer(&np->oom_kick, jiffies + OOM_REFILL); |
| 1034 | spin_unlock(&np->lock); | 1101 | spin_unlock_irq(&np->lock); |
| 1035 | } | 1102 | } |
| 1036 | if (!(np->msi_flags & NV_MSI_X_ENABLED) || | 1103 | if (!using_multi_irqs(dev)) { |
| 1037 | ((np->msi_flags & NV_MSI_X_ENABLED) && | 1104 | if (np->msi_flags & NV_MSI_X_ENABLED) |
| 1038 | ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) { | 1105 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); |
| 1039 | enable_irq(dev->irq); | 1106 | else |
| 1107 | enable_irq(dev->irq); | ||
| 1040 | } else { | 1108 | } else { |
| 1041 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); | 1109 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); |
| 1042 | } | 1110 | } |
| @@ -1668,15 +1736,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1668 | * guessed, there is probably a simpler approach. | 1736 | * guessed, there is probably a simpler approach. |
| 1669 | * Changing the MTU is a rare event, it shouldn't matter. | 1737 | * Changing the MTU is a rare event, it shouldn't matter. |
| 1670 | */ | 1738 | */ |
| 1671 | if (!(np->msi_flags & NV_MSI_X_ENABLED) || | 1739 | nv_disable_irq(dev); |
| 1672 | ((np->msi_flags & NV_MSI_X_ENABLED) && | ||
| 1673 | ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) { | ||
| 1674 | disable_irq(dev->irq); | ||
| 1675 | } else { | ||
| 1676 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); | ||
| 1677 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); | ||
| 1678 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); | ||
| 1679 | } | ||
| 1680 | spin_lock_bh(&dev->xmit_lock); | 1740 | spin_lock_bh(&dev->xmit_lock); |
| 1681 | spin_lock(&np->lock); | 1741 | spin_lock(&np->lock); |
| 1682 | /* stop engines */ | 1742 | /* stop engines */ |
| @@ -1709,15 +1769,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1709 | nv_start_tx(dev); | 1769 | nv_start_tx(dev); |
| 1710 | spin_unlock(&np->lock); | 1770 | spin_unlock(&np->lock); |
| 1711 | spin_unlock_bh(&dev->xmit_lock); | 1771 | spin_unlock_bh(&dev->xmit_lock); |
| 1712 | if (!(np->msi_flags & NV_MSI_X_ENABLED) || | 1772 | nv_enable_irq(dev); |
| 1713 | ((np->msi_flags & NV_MSI_X_ENABLED) && | ||
| 1714 | ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) { | ||
| 1715 | enable_irq(dev->irq); | ||
| 1716 | } else { | ||
| 1717 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); | ||
| 1718 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); | ||
| 1719 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); | ||
| 1720 | } | ||
| 1721 | } | 1773 | } |
| 1722 | return 0; | 1774 | return 0; |
| 1723 | } | 1775 | } |
| @@ -2108,16 +2160,16 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data, struct pt_regs *regs) | |||
| 2108 | if (!(events & np->irqmask)) | 2160 | if (!(events & np->irqmask)) |
| 2109 | break; | 2161 | break; |
| 2110 | 2162 | ||
| 2111 | spin_lock(&np->lock); | 2163 | spin_lock_irq(&np->lock); |
| 2112 | nv_tx_done(dev); | 2164 | nv_tx_done(dev); |
| 2113 | spin_unlock(&np->lock); | 2165 | spin_unlock_irq(&np->lock); |
| 2114 | 2166 | ||
| 2115 | if (events & (NVREG_IRQ_TX_ERR)) { | 2167 | if (events & (NVREG_IRQ_TX_ERR)) { |
| 2116 | dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", | 2168 | dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", |
| 2117 | dev->name, events); | 2169 | dev->name, events); |
| 2118 | } | 2170 | } |
| 2119 | if (i > max_interrupt_work) { | 2171 | if (i > max_interrupt_work) { |
| 2120 | spin_lock(&np->lock); | 2172 | spin_lock_irq(&np->lock); |
| 2121 | /* disable interrupts on the nic */ | 2173 | /* disable interrupts on the nic */ |
| 2122 | writel(NVREG_IRQ_TX_ALL, base + NvRegIrqMask); | 2174 | writel(NVREG_IRQ_TX_ALL, base + NvRegIrqMask); |
| 2123 | pci_push(base); | 2175 | pci_push(base); |
| @@ -2127,7 +2179,7 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data, struct pt_regs *regs) | |||
| 2127 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); | 2179 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); |
| 2128 | } | 2180 | } |
| 2129 | printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); | 2181 | printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); |
| 2130 | spin_unlock(&np->lock); | 2182 | spin_unlock_irq(&np->lock); |
| 2131 | break; | 2183 | break; |
| 2132 | } | 2184 | } |
| 2133 | 2185 | ||
| @@ -2157,14 +2209,14 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs) | |||
| 2157 | 2209 | ||
| 2158 | nv_rx_process(dev); | 2210 | nv_rx_process(dev); |
| 2159 | if (nv_alloc_rx(dev)) { | 2211 | if (nv_alloc_rx(dev)) { |
| 2160 | spin_lock(&np->lock); | 2212 | spin_lock_irq(&np->lock); |
| 2161 | if (!np->in_shutdown) | 2213 | if (!np->in_shutdown) |
| 2162 | mod_timer(&np->oom_kick, jiffies + OOM_REFILL); | 2214 | mod_timer(&np->oom_kick, jiffies + OOM_REFILL); |
| 2163 | spin_unlock(&np->lock); | 2215 | spin_unlock_irq(&np->lock); |
| 2164 | } | 2216 | } |
| 2165 | 2217 | ||
| 2166 | if (i > max_interrupt_work) { | 2218 | if (i > max_interrupt_work) { |
| 2167 | spin_lock(&np->lock); | 2219 | spin_lock_irq(&np->lock); |
| 2168 | /* disable interrupts on the nic */ | 2220 | /* disable interrupts on the nic */ |
| 2169 | writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); | 2221 | writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask); |
| 2170 | pci_push(base); | 2222 | pci_push(base); |
| @@ -2174,7 +2226,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs) | |||
| 2174 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); | 2226 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); |
| 2175 | } | 2227 | } |
| 2176 | printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); | 2228 | printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); |
| 2177 | spin_unlock(&np->lock); | 2229 | spin_unlock_irq(&np->lock); |
| 2178 | break; | 2230 | break; |
| 2179 | } | 2231 | } |
| 2180 | 2232 | ||
| @@ -2203,14 +2255,14 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs) | |||
| 2203 | break; | 2255 | break; |
| 2204 | 2256 | ||
| 2205 | if (events & NVREG_IRQ_LINK) { | 2257 | if (events & NVREG_IRQ_LINK) { |
| 2206 | spin_lock(&np->lock); | 2258 | spin_lock_irq(&np->lock); |
| 2207 | nv_link_irq(dev); | 2259 | nv_link_irq(dev); |
| 2208 | spin_unlock(&np->lock); | 2260 | spin_unlock_irq(&np->lock); |
| 2209 | } | 2261 | } |
| 2210 | if (np->need_linktimer && time_after(jiffies, np->link_timeout)) { | 2262 | if (np->need_linktimer && time_after(jiffies, np->link_timeout)) { |
| 2211 | spin_lock(&np->lock); | 2263 | spin_lock_irq(&np->lock); |
| 2212 | nv_linkchange(dev); | 2264 | nv_linkchange(dev); |
| 2213 | spin_unlock(&np->lock); | 2265 | spin_unlock_irq(&np->lock); |
| 2214 | np->link_timeout = jiffies + LINK_TIMEOUT; | 2266 | np->link_timeout = jiffies + LINK_TIMEOUT; |
| 2215 | } | 2267 | } |
| 2216 | if (events & (NVREG_IRQ_UNKNOWN)) { | 2268 | if (events & (NVREG_IRQ_UNKNOWN)) { |
| @@ -2218,7 +2270,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs) | |||
| 2218 | dev->name, events); | 2270 | dev->name, events); |
| 2219 | } | 2271 | } |
| 2220 | if (i > max_interrupt_work) { | 2272 | if (i > max_interrupt_work) { |
| 2221 | spin_lock(&np->lock); | 2273 | spin_lock_irq(&np->lock); |
| 2222 | /* disable interrupts on the nic */ | 2274 | /* disable interrupts on the nic */ |
| 2223 | writel(NVREG_IRQ_OTHER, base + NvRegIrqMask); | 2275 | writel(NVREG_IRQ_OTHER, base + NvRegIrqMask); |
| 2224 | pci_push(base); | 2276 | pci_push(base); |
| @@ -2228,7 +2280,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs) | |||
| 2228 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); | 2280 | mod_timer(&np->nic_poll, jiffies + POLL_WAIT); |
| 2229 | } | 2281 | } |
| 2230 | printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); | 2282 | printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); |
| 2231 | spin_unlock(&np->lock); | 2283 | spin_unlock_irq(&np->lock); |
| 2232 | break; | 2284 | break; |
| 2233 | } | 2285 | } |
| 2234 | 2286 | ||
| @@ -2251,10 +2303,11 @@ static void nv_do_nic_poll(unsigned long data) | |||
| 2251 | * nv_nic_irq because that may decide to do otherwise | 2303 | * nv_nic_irq because that may decide to do otherwise |
| 2252 | */ | 2304 | */ |
| 2253 | 2305 | ||
| 2254 | if (!(np->msi_flags & NV_MSI_X_ENABLED) || | 2306 | if (!using_multi_irqs(dev)) { |
| 2255 | ((np->msi_flags & NV_MSI_X_ENABLED) && | 2307 | if (np->msi_flags & NV_MSI_X_ENABLED) |
| 2256 | ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) { | 2308 | disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); |
| 2257 | disable_irq(dev->irq); | 2309 | else |
| 2310 | disable_irq(dev->irq); | ||
| 2258 | mask = np->irqmask; | 2311 | mask = np->irqmask; |
| 2259 | } else { | 2312 | } else { |
| 2260 | if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { | 2313 | if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { |
| @@ -2277,11 +2330,12 @@ static void nv_do_nic_poll(unsigned long data) | |||
| 2277 | writel(mask, base + NvRegIrqMask); | 2330 | writel(mask, base + NvRegIrqMask); |
| 2278 | pci_push(base); | 2331 | pci_push(base); |
| 2279 | 2332 | ||
| 2280 | if (!(np->msi_flags & NV_MSI_X_ENABLED) || | 2333 | if (!using_multi_irqs(dev)) { |
| 2281 | ((np->msi_flags & NV_MSI_X_ENABLED) && | ||
| 2282 | ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) { | ||
| 2283 | nv_nic_irq((int) 0, (void *) data, (struct pt_regs *) NULL); | 2334 | nv_nic_irq((int) 0, (void *) data, (struct pt_regs *) NULL); |
| 2284 | enable_irq(dev->irq); | 2335 | if (np->msi_flags & NV_MSI_X_ENABLED) |
| 2336 | enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); | ||
| 2337 | else | ||
| 2338 | enable_irq(dev->irq); | ||
| 2285 | } else { | 2339 | } else { |
| 2286 | if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { | 2340 | if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { |
| 2287 | nv_nic_irq_rx((int) 0, (void *) data, (struct pt_regs *) NULL); | 2341 | nv_nic_irq_rx((int) 0, (void *) data, (struct pt_regs *) NULL); |
| @@ -2628,6 +2682,113 @@ static void set_msix_vector_map(struct net_device *dev, u32 vector, u32 irqmask) | |||
| 2628 | writel(readl(base + NvRegMSIXMap1) | msixmap, base + NvRegMSIXMap1); | 2682 | writel(readl(base + NvRegMSIXMap1) | msixmap, base + NvRegMSIXMap1); |
| 2629 | } | 2683 | } |
| 2630 | 2684 | ||
| 2685 | static int nv_request_irq(struct net_device *dev) | ||
| 2686 | { | ||
| 2687 | struct fe_priv *np = get_nvpriv(dev); | ||
| 2688 | u8 __iomem *base = get_hwbase(dev); | ||
| 2689 | int ret = 1; | ||
| 2690 | int i; | ||
| 2691 | |||
| 2692 | if (np->msi_flags & NV_MSI_X_CAPABLE) { | ||
| 2693 | for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { | ||
| 2694 | np->msi_x_entry[i].entry = i; | ||
| 2695 | } | ||
| 2696 | if ((ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK))) == 0) { | ||
| 2697 | np->msi_flags |= NV_MSI_X_ENABLED; | ||
| 2698 | if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT) { | ||
| 2699 | /* Request irq for rx handling */ | ||
| 2700 | if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, SA_SHIRQ, dev->name, dev) != 0) { | ||
| 2701 | printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret); | ||
| 2702 | pci_disable_msix(np->pci_dev); | ||
| 2703 | np->msi_flags &= ~NV_MSI_X_ENABLED; | ||
| 2704 | goto out_err; | ||
| 2705 | } | ||
| 2706 | /* Request irq for tx handling */ | ||
| 2707 | if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, &nv_nic_irq_tx, SA_SHIRQ, dev->name, dev) != 0) { | ||
| 2708 | printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret); | ||
| 2709 | pci_disable_msix(np->pci_dev); | ||
| 2710 | np->msi_flags &= ~NV_MSI_X_ENABLED; | ||
| 2711 | goto out_free_rx; | ||
| 2712 | } | ||
| 2713 | /* Request irq for link and timer handling */ | ||
| 2714 | if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, &nv_nic_irq_other, SA_SHIRQ, dev->name, dev) != 0) { | ||
| 2715 | printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret); | ||
| 2716 | pci_disable_msix(np->pci_dev); | ||
| 2717 | np->msi_flags &= ~NV_MSI_X_ENABLED; | ||
| 2718 | goto out_free_tx; | ||
| 2719 | } | ||
| 2720 | /* map interrupts to their respective vector */ | ||
| 2721 | writel(0, base + NvRegMSIXMap0); | ||
| 2722 | writel(0, base + NvRegMSIXMap1); | ||
| 2723 | set_msix_vector_map(dev, NV_MSI_X_VECTOR_RX, NVREG_IRQ_RX_ALL); | ||
| 2724 | set_msix_vector_map(dev, NV_MSI_X_VECTOR_TX, NVREG_IRQ_TX_ALL); | ||
| 2725 | set_msix_vector_map(dev, NV_MSI_X_VECTOR_OTHER, NVREG_IRQ_OTHER); | ||
| 2726 | } else { | ||
| 2727 | /* Request irq for all interrupts */ | ||
| 2728 | if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) { | ||
| 2729 | printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); | ||
| 2730 | pci_disable_msix(np->pci_dev); | ||
| 2731 | np->msi_flags &= ~NV_MSI_X_ENABLED; | ||
| 2732 | goto out_err; | ||
| 2733 | } | ||
| 2734 | |||
| 2735 | /* map interrupts to vector 0 */ | ||
| 2736 | writel(0, base + NvRegMSIXMap0); | ||
| 2737 | writel(0, base + NvRegMSIXMap1); | ||
| 2738 | } | ||
| 2739 | } | ||
| 2740 | } | ||
| 2741 | if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { | ||
| 2742 | if ((ret = pci_enable_msi(np->pci_dev)) == 0) { | ||
| 2743 | np->msi_flags |= NV_MSI_ENABLED; | ||
| 2744 | if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) { | ||
| 2745 | printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); | ||
| 2746 | pci_disable_msi(np->pci_dev); | ||
| 2747 | np->msi_flags &= ~NV_MSI_ENABLED; | ||
| 2748 | goto out_err; | ||
| 2749 | } | ||
| 2750 | |||
| 2751 | /* map interrupts to vector 0 */ | ||
| 2752 | writel(0, base + NvRegMSIMap0); | ||
| 2753 | writel(0, base + NvRegMSIMap1); | ||
| 2754 | /* enable msi vector 0 */ | ||
| 2755 | writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask); | ||
| 2756 | } | ||
| 2757 | } | ||
| 2758 | if (ret != 0) { | ||
| 2759 | if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) | ||
| 2760 | goto out_err; | ||
| 2761 | } | ||
| 2762 | |||
| 2763 | return 0; | ||
| 2764 | out_free_tx: | ||
| 2765 | free_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, dev); | ||
| 2766 | out_free_rx: | ||
| 2767 | free_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, dev); | ||
| 2768 | out_err: | ||
| 2769 | return 1; | ||
| 2770 | } | ||
| 2771 | |||
| 2772 | static void nv_free_irq(struct net_device *dev) | ||
| 2773 | { | ||
| 2774 | struct fe_priv *np = get_nvpriv(dev); | ||
| 2775 | int i; | ||
| 2776 | |||
| 2777 | if (np->msi_flags & NV_MSI_X_ENABLED) { | ||
| 2778 | for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { | ||
| 2779 | free_irq(np->msi_x_entry[i].vector, dev); | ||
| 2780 | } | ||
| 2781 | pci_disable_msix(np->pci_dev); | ||
| 2782 | np->msi_flags &= ~NV_MSI_X_ENABLED; | ||
| 2783 | } else { | ||
| 2784 | free_irq(np->pci_dev->irq, dev); | ||
| 2785 | if (np->msi_flags & NV_MSI_ENABLED) { | ||
| 2786 | pci_disable_msi(np->pci_dev); | ||
| 2787 | np->msi_flags &= ~NV_MSI_ENABLED; | ||
| 2788 | } | ||
| 2789 | } | ||
| 2790 | } | ||
| 2791 | |||
| 2631 | static int nv_open(struct net_device *dev) | 2792 | static int nv_open(struct net_device *dev) |
| 2632 | { | 2793 | { |
| 2633 | struct fe_priv *np = netdev_priv(dev); | 2794 | struct fe_priv *np = netdev_priv(dev); |
| @@ -2720,12 +2881,16 @@ static int nv_open(struct net_device *dev) | |||
| 2720 | udelay(10); | 2881 | udelay(10); |
| 2721 | writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState); | 2882 | writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState); |
| 2722 | 2883 | ||
| 2723 | writel(0, base + NvRegIrqMask); | 2884 | nv_disable_hw_interrupts(dev, np->irqmask); |
| 2724 | pci_push(base); | 2885 | pci_push(base); |
| 2725 | writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); | 2886 | writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); |
| 2726 | writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); | 2887 | writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); |
| 2727 | pci_push(base); | 2888 | pci_push(base); |
| 2728 | 2889 | ||
| 2890 | if (nv_request_irq(dev)) { | ||
| 2891 | goto out_drain; | ||
| 2892 | } | ||
| 2893 | |||
| 2729 | if (np->msi_flags & NV_MSI_X_CAPABLE) { | 2894 | if (np->msi_flags & NV_MSI_X_CAPABLE) { |
| 2730 | for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { | 2895 | for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { |
| 2731 | np->msi_x_entry[i].entry = i; | 2896 | np->msi_x_entry[i].entry = i; |
| @@ -2799,7 +2964,7 @@ static int nv_open(struct net_device *dev) | |||
| 2799 | } | 2964 | } |
| 2800 | 2965 | ||
| 2801 | /* ask for interrupts */ | 2966 | /* ask for interrupts */ |
| 2802 | writel(np->irqmask, base + NvRegIrqMask); | 2967 | nv_enable_hw_interrupts(dev, np->irqmask); |
| 2803 | 2968 | ||
| 2804 | spin_lock_irq(&np->lock); | 2969 | spin_lock_irq(&np->lock); |
| 2805 | writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA); | 2970 | writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA); |
| @@ -2843,7 +3008,6 @@ static int nv_close(struct net_device *dev) | |||
| 2843 | { | 3008 | { |
| 2844 | struct fe_priv *np = netdev_priv(dev); | 3009 | struct fe_priv *np = netdev_priv(dev); |
| 2845 | u8 __iomem *base; | 3010 | u8 __iomem *base; |
| 2846 | int i; | ||
| 2847 | 3011 | ||
| 2848 | spin_lock_irq(&np->lock); | 3012 | spin_lock_irq(&np->lock); |
| 2849 | np->in_shutdown = 1; | 3013 | np->in_shutdown = 1; |
| @@ -2861,31 +3025,13 @@ static int nv_close(struct net_device *dev) | |||
| 2861 | 3025 | ||
| 2862 | /* disable interrupts on the nic or we will lock up */ | 3026 | /* disable interrupts on the nic or we will lock up */ |
| 2863 | base = get_hwbase(dev); | 3027 | base = get_hwbase(dev); |
| 2864 | if (np->msi_flags & NV_MSI_X_ENABLED) { | 3028 | nv_disable_hw_interrupts(dev, np->irqmask); |
| 2865 | writel(np->irqmask, base + NvRegIrqMask); | ||
| 2866 | } else { | ||
| 2867 | if (np->msi_flags & NV_MSI_ENABLED) | ||
| 2868 | writel(0, base + NvRegMSIIrqMask); | ||
| 2869 | writel(0, base + NvRegIrqMask); | ||
| 2870 | } | ||
| 2871 | pci_push(base); | 3029 | pci_push(base); |
| 2872 | dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name); | 3030 | dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name); |
| 2873 | 3031 | ||
| 2874 | spin_unlock_irq(&np->lock); | 3032 | spin_unlock_irq(&np->lock); |
| 2875 | 3033 | ||
| 2876 | if (np->msi_flags & NV_MSI_X_ENABLED) { | 3034 | nv_free_irq(dev); |
| 2877 | for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) { | ||
| 2878 | free_irq(np->msi_x_entry[i].vector, dev); | ||
| 2879 | } | ||
| 2880 | pci_disable_msix(np->pci_dev); | ||
| 2881 | np->msi_flags &= ~NV_MSI_X_ENABLED; | ||
| 2882 | } else { | ||
| 2883 | free_irq(np->pci_dev->irq, dev); | ||
| 2884 | if (np->msi_flags & NV_MSI_ENABLED) { | ||
| 2885 | pci_disable_msi(np->pci_dev); | ||
| 2886 | np->msi_flags &= ~NV_MSI_ENABLED; | ||
| 2887 | } | ||
| 2888 | } | ||
| 2889 | 3035 | ||
| 2890 | drain_ring(dev); | 3036 | drain_ring(dev); |
| 2891 | 3037 | ||
| @@ -2974,20 +3120,18 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
| 2974 | if (id->driver_data & DEV_HAS_HIGH_DMA) { | 3120 | if (id->driver_data & DEV_HAS_HIGH_DMA) { |
| 2975 | /* packet format 3: supports 40-bit addressing */ | 3121 | /* packet format 3: supports 40-bit addressing */ |
| 2976 | np->desc_ver = DESC_VER_3; | 3122 | np->desc_ver = DESC_VER_3; |
| 3123 | np->txrxctl_bits = NVREG_TXRXCTL_DESC_3; | ||
| 2977 | if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK)) { | 3124 | if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK)) { |
| 2978 | printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n", | 3125 | printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n", |
| 2979 | pci_name(pci_dev)); | 3126 | pci_name(pci_dev)); |
| 2980 | } else { | 3127 | } else { |
| 2981 | if (pci_set_consistent_dma_mask(pci_dev, 0x0000007fffffffffULL)) { | 3128 | dev->features |= NETIF_F_HIGHDMA; |
| 2982 | printk(KERN_INFO "forcedeth: 64-bit DMA (consistent) failed for device %s.\n", | 3129 | printk(KERN_INFO "forcedeth: using HIGHDMA\n"); |
| 2983 | pci_name(pci_dev)); | 3130 | } |
| 2984 | goto out_relreg; | 3131 | if (pci_set_consistent_dma_mask(pci_dev, 0x0000007fffffffffULL)) { |
| 2985 | } else { | 3132 | printk(KERN_INFO "forcedeth: 64-bit DMA (consistent) failed for device %s.\n", |
| 2986 | dev->features |= NETIF_F_HIGHDMA; | 3133 | pci_name(pci_dev)); |
| 2987 | printk(KERN_INFO "forcedeth: using HIGHDMA\n"); | ||
| 2988 | } | ||
| 2989 | } | 3134 | } |
| 2990 | np->txrxctl_bits = NVREG_TXRXCTL_DESC_3; | ||
| 2991 | } else if (id->driver_data & DEV_HAS_LARGEDESC) { | 3135 | } else if (id->driver_data & DEV_HAS_LARGEDESC) { |
| 2992 | /* packet format 2: supports jumbo frames */ | 3136 | /* packet format 2: supports jumbo frames */ |
| 2993 | np->desc_ver = DESC_VER_2; | 3137 | np->desc_ver = DESC_VER_2; |
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 79a8fbcf5f93..0d5fccc984bb 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c | |||
| @@ -582,7 +582,6 @@ static int __init setup_adapter(int card_base, int type, int n) | |||
| 582 | INIT_WORK(&priv->rx_work, rx_bh, priv); | 582 | INIT_WORK(&priv->rx_work, rx_bh, priv); |
| 583 | dev->priv = priv; | 583 | dev->priv = priv; |
| 584 | sprintf(dev->name, "dmascc%i", 2 * n + i); | 584 | sprintf(dev->name, "dmascc%i", 2 * n + i); |
| 585 | SET_MODULE_OWNER(dev); | ||
| 586 | dev->base_addr = card_base; | 585 | dev->base_addr = card_base; |
| 587 | dev->irq = irq; | 586 | dev->irq = irq; |
| 588 | dev->open = scc_open; | 587 | dev->open = scc_open; |
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 6ace0e914fd1..5927784df3f9 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c | |||
| @@ -1550,7 +1550,6 @@ static unsigned char ax25_nocall[AX25_ADDR_LEN] = | |||
| 1550 | 1550 | ||
| 1551 | static void scc_net_setup(struct net_device *dev) | 1551 | static void scc_net_setup(struct net_device *dev) |
| 1552 | { | 1552 | { |
| 1553 | SET_MODULE_OWNER(dev); | ||
| 1554 | dev->tx_queue_len = 16; /* should be enough... */ | 1553 | dev->tx_queue_len = 16; /* should be enough... */ |
| 1555 | 1554 | ||
| 1556 | dev->open = scc_net_open; | 1555 | dev->open = scc_net_open; |
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index fe22479eb202..b49884048caa 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c | |||
| @@ -1098,7 +1098,6 @@ static void yam_setup(struct net_device *dev) | |||
| 1098 | 1098 | ||
| 1099 | dev->base_addr = yp->iobase; | 1099 | dev->base_addr = yp->iobase; |
| 1100 | dev->irq = yp->irq; | 1100 | dev->irq = yp->irq; |
| 1101 | SET_MODULE_OWNER(dev); | ||
| 1102 | 1101 | ||
| 1103 | dev->open = yam_open; | 1102 | dev->open = yam_open; |
| 1104 | dev->stop = yam_close; | 1103 | dev->stop = yam_close; |
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index ea62a3e7d586..411f4d809c47 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
| @@ -1419,6 +1419,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
| 1419 | mv643xx_eth_update_pscr(dev, &cmd); | 1419 | mv643xx_eth_update_pscr(dev, &cmd); |
| 1420 | mv643xx_set_settings(dev, &cmd); | 1420 | mv643xx_set_settings(dev, &cmd); |
| 1421 | 1421 | ||
| 1422 | SET_MODULE_OWNER(dev); | ||
| 1423 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
| 1422 | err = register_netdev(dev); | 1424 | err = register_netdev(dev); |
| 1423 | if (err) | 1425 | if (err) |
| 1424 | goto out; | 1426 | goto out; |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 73e271e59c6a..beeb612be98f 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
| @@ -69,8 +69,8 @@ | |||
| 69 | 69 | ||
| 70 | #define DRV_MODULE_NAME "tg3" | 70 | #define DRV_MODULE_NAME "tg3" |
| 71 | #define PFX DRV_MODULE_NAME ": " | 71 | #define PFX DRV_MODULE_NAME ": " |
| 72 | #define DRV_MODULE_VERSION "3.56" | 72 | #define DRV_MODULE_VERSION "3.57" |
| 73 | #define DRV_MODULE_RELDATE "Apr 1, 2006" | 73 | #define DRV_MODULE_RELDATE "Apr 28, 2006" |
| 74 | 74 | ||
| 75 | #define TG3_DEF_MAC_MODE 0 | 75 | #define TG3_DEF_MAC_MODE 0 |
| 76 | #define TG3_DEF_RX_MODE 0 | 76 | #define TG3_DEF_RX_MODE 0 |
| @@ -974,6 +974,8 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) | |||
| 974 | return err; | 974 | return err; |
| 975 | } | 975 | } |
| 976 | 976 | ||
| 977 | static void tg3_link_report(struct tg3 *); | ||
| 978 | |||
| 977 | /* This will reset the tigon3 PHY if there is no valid | 979 | /* This will reset the tigon3 PHY if there is no valid |
| 978 | * link unless the FORCE argument is non-zero. | 980 | * link unless the FORCE argument is non-zero. |
| 979 | */ | 981 | */ |
| @@ -987,6 +989,11 @@ static int tg3_phy_reset(struct tg3 *tp) | |||
| 987 | if (err != 0) | 989 | if (err != 0) |
| 988 | return -EBUSY; | 990 | return -EBUSY; |
| 989 | 991 | ||
| 992 | if (netif_running(tp->dev) && netif_carrier_ok(tp->dev)) { | ||
| 993 | netif_carrier_off(tp->dev); | ||
| 994 | tg3_link_report(tp); | ||
| 995 | } | ||
| 996 | |||
| 990 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || | 997 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || |
| 991 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || | 998 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || |
| 992 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { | 999 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { |
| @@ -1023,6 +1030,12 @@ out: | |||
| 1023 | tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x14e2); | 1030 | tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x14e2); |
| 1024 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); | 1031 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); |
| 1025 | } | 1032 | } |
| 1033 | else if (tp->tg3_flags2 & TG3_FLG2_PHY_JITTER_BUG) { | ||
| 1034 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00); | ||
| 1035 | tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a); | ||
| 1036 | tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b); | ||
| 1037 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); | ||
| 1038 | } | ||
| 1026 | /* Set Extended packet length bit (bit 14) on all chips that */ | 1039 | /* Set Extended packet length bit (bit 14) on all chips that */ |
| 1027 | /* support jumbo frames */ | 1040 | /* support jumbo frames */ |
| 1028 | if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { | 1041 | if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { |
| @@ -3531,7 +3544,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, | |||
| 3531 | return IRQ_RETVAL(0); | 3544 | return IRQ_RETVAL(0); |
| 3532 | } | 3545 | } |
| 3533 | 3546 | ||
| 3534 | static int tg3_init_hw(struct tg3 *); | 3547 | static int tg3_init_hw(struct tg3 *, int); |
| 3535 | static int tg3_halt(struct tg3 *, int, int); | 3548 | static int tg3_halt(struct tg3 *, int, int); |
| 3536 | 3549 | ||
| 3537 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3550 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| @@ -3567,7 +3580,7 @@ static void tg3_reset_task(void *_data) | |||
| 3567 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; | 3580 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; |
| 3568 | 3581 | ||
| 3569 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); | 3582 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); |
| 3570 | tg3_init_hw(tp); | 3583 | tg3_init_hw(tp, 1); |
| 3571 | 3584 | ||
| 3572 | tg3_netif_start(tp); | 3585 | tg3_netif_start(tp); |
| 3573 | 3586 | ||
| @@ -4042,7 +4055,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
| 4042 | 4055 | ||
| 4043 | tg3_set_mtu(dev, tp, new_mtu); | 4056 | tg3_set_mtu(dev, tp, new_mtu); |
| 4044 | 4057 | ||
| 4045 | tg3_init_hw(tp); | 4058 | tg3_init_hw(tp, 0); |
| 4046 | 4059 | ||
| 4047 | tg3_netif_start(tp); | 4060 | tg3_netif_start(tp); |
| 4048 | 4061 | ||
| @@ -5719,9 +5732,23 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) | |||
| 5719 | if (!netif_running(dev)) | 5732 | if (!netif_running(dev)) |
| 5720 | return 0; | 5733 | return 0; |
| 5721 | 5734 | ||
| 5722 | spin_lock_bh(&tp->lock); | 5735 | if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { |
| 5723 | __tg3_set_mac_addr(tp); | 5736 | /* Reset chip so that ASF can re-init any MAC addresses it |
| 5724 | spin_unlock_bh(&tp->lock); | 5737 | * needs. |
| 5738 | */ | ||
| 5739 | tg3_netif_stop(tp); | ||
| 5740 | tg3_full_lock(tp, 1); | ||
| 5741 | |||
| 5742 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | ||
| 5743 | tg3_init_hw(tp, 0); | ||
| 5744 | |||
| 5745 | tg3_netif_start(tp); | ||
| 5746 | tg3_full_unlock(tp); | ||
| 5747 | } else { | ||
| 5748 | spin_lock_bh(&tp->lock); | ||
| 5749 | __tg3_set_mac_addr(tp); | ||
| 5750 | spin_unlock_bh(&tp->lock); | ||
| 5751 | } | ||
| 5725 | 5752 | ||
| 5726 | return 0; | 5753 | return 0; |
| 5727 | } | 5754 | } |
| @@ -5771,7 +5798,7 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec) | |||
| 5771 | } | 5798 | } |
| 5772 | 5799 | ||
| 5773 | /* tp->lock is held. */ | 5800 | /* tp->lock is held. */ |
| 5774 | static int tg3_reset_hw(struct tg3 *tp) | 5801 | static int tg3_reset_hw(struct tg3 *tp, int reset_phy) |
| 5775 | { | 5802 | { |
| 5776 | u32 val, rdmac_mode; | 5803 | u32 val, rdmac_mode; |
| 5777 | int i, err, limit; | 5804 | int i, err, limit; |
| @@ -5786,7 +5813,7 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
| 5786 | tg3_abort_hw(tp, 1); | 5813 | tg3_abort_hw(tp, 1); |
| 5787 | } | 5814 | } |
| 5788 | 5815 | ||
| 5789 | if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) | 5816 | if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) && reset_phy) |
| 5790 | tg3_phy_reset(tp); | 5817 | tg3_phy_reset(tp); |
| 5791 | 5818 | ||
| 5792 | err = tg3_chip_reset(tp); | 5819 | err = tg3_chip_reset(tp); |
| @@ -6327,7 +6354,7 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
| 6327 | tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl); | 6354 | tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl); |
| 6328 | } | 6355 | } |
| 6329 | 6356 | ||
| 6330 | err = tg3_setup_phy(tp, 1); | 6357 | err = tg3_setup_phy(tp, reset_phy); |
| 6331 | if (err) | 6358 | if (err) |
| 6332 | return err; | 6359 | return err; |
| 6333 | 6360 | ||
| @@ -6400,7 +6427,7 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
| 6400 | /* Called at device open time to get the chip ready for | 6427 | /* Called at device open time to get the chip ready for |
| 6401 | * packet processing. Invoked with tp->lock held. | 6428 | * packet processing. Invoked with tp->lock held. |
| 6402 | */ | 6429 | */ |
| 6403 | static int tg3_init_hw(struct tg3 *tp) | 6430 | static int tg3_init_hw(struct tg3 *tp, int reset_phy) |
| 6404 | { | 6431 | { |
| 6405 | int err; | 6432 | int err; |
| 6406 | 6433 | ||
| @@ -6413,7 +6440,7 @@ static int tg3_init_hw(struct tg3 *tp) | |||
| 6413 | 6440 | ||
| 6414 | tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); | 6441 | tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); |
| 6415 | 6442 | ||
| 6416 | err = tg3_reset_hw(tp); | 6443 | err = tg3_reset_hw(tp, reset_phy); |
| 6417 | 6444 | ||
| 6418 | out: | 6445 | out: |
| 6419 | return err; | 6446 | return err; |
| @@ -6683,7 +6710,7 @@ static int tg3_test_msi(struct tg3 *tp) | |||
| 6683 | tg3_full_lock(tp, 1); | 6710 | tg3_full_lock(tp, 1); |
| 6684 | 6711 | ||
| 6685 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 6712 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 6686 | err = tg3_init_hw(tp); | 6713 | err = tg3_init_hw(tp, 1); |
| 6687 | 6714 | ||
| 6688 | tg3_full_unlock(tp); | 6715 | tg3_full_unlock(tp); |
| 6689 | 6716 | ||
| @@ -6748,7 +6775,7 @@ static int tg3_open(struct net_device *dev) | |||
| 6748 | 6775 | ||
| 6749 | tg3_full_lock(tp, 0); | 6776 | tg3_full_lock(tp, 0); |
| 6750 | 6777 | ||
| 6751 | err = tg3_init_hw(tp); | 6778 | err = tg3_init_hw(tp, 1); |
| 6752 | if (err) { | 6779 | if (err) { |
| 6753 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 6780 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 6754 | tg3_free_rings(tp); | 6781 | tg3_free_rings(tp); |
| @@ -7839,7 +7866,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
| 7839 | 7866 | ||
| 7840 | if (netif_running(dev)) { | 7867 | if (netif_running(dev)) { |
| 7841 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 7868 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 7842 | tg3_init_hw(tp); | 7869 | tg3_init_hw(tp, 1); |
| 7843 | tg3_netif_start(tp); | 7870 | tg3_netif_start(tp); |
| 7844 | } | 7871 | } |
| 7845 | 7872 | ||
| @@ -7884,7 +7911,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
| 7884 | 7911 | ||
| 7885 | if (netif_running(dev)) { | 7912 | if (netif_running(dev)) { |
| 7886 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 7913 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 7887 | tg3_init_hw(tp); | 7914 | tg3_init_hw(tp, 1); |
| 7888 | tg3_netif_start(tp); | 7915 | tg3_netif_start(tp); |
| 7889 | } | 7916 | } |
| 7890 | 7917 | ||
| @@ -8522,7 +8549,7 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
| 8522 | if (!netif_running(tp->dev)) | 8549 | if (!netif_running(tp->dev)) |
| 8523 | return TG3_LOOPBACK_FAILED; | 8550 | return TG3_LOOPBACK_FAILED; |
| 8524 | 8551 | ||
| 8525 | tg3_reset_hw(tp); | 8552 | tg3_reset_hw(tp, 1); |
| 8526 | 8553 | ||
| 8527 | if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) | 8554 | if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) |
| 8528 | err |= TG3_MAC_LOOPBACK_FAILED; | 8555 | err |= TG3_MAC_LOOPBACK_FAILED; |
| @@ -8596,7 +8623,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | |||
| 8596 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 8623 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 8597 | if (netif_running(dev)) { | 8624 | if (netif_running(dev)) { |
| 8598 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | 8625 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; |
| 8599 | tg3_init_hw(tp); | 8626 | tg3_init_hw(tp, 1); |
| 8600 | tg3_netif_start(tp); | 8627 | tg3_netif_start(tp); |
| 8601 | } | 8628 | } |
| 8602 | 8629 | ||
| @@ -9377,7 +9404,7 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len, | |||
| 9377 | 9404 | ||
| 9378 | if ((page_off == 0) || (i == 0)) | 9405 | if ((page_off == 0) || (i == 0)) |
| 9379 | nvram_cmd |= NVRAM_CMD_FIRST; | 9406 | nvram_cmd |= NVRAM_CMD_FIRST; |
| 9380 | else if (page_off == (tp->nvram_pagesize - 4)) | 9407 | if (page_off == (tp->nvram_pagesize - 4)) |
| 9381 | nvram_cmd |= NVRAM_CMD_LAST; | 9408 | nvram_cmd |= NVRAM_CMD_LAST; |
| 9382 | 9409 | ||
| 9383 | if (i == (len - 4)) | 9410 | if (i == (len - 4)) |
| @@ -10353,10 +10380,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
| 10353 | if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) | 10380 | if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) |
| 10354 | tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG; | 10381 | tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG; |
| 10355 | 10382 | ||
| 10356 | if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) && | 10383 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { |
| 10357 | (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755) && | 10384 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || |
| 10358 | (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787)) | 10385 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) |
| 10359 | tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG; | 10386 | tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG; |
| 10387 | else | ||
| 10388 | tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG; | ||
| 10389 | } | ||
| 10360 | 10390 | ||
| 10361 | tp->coalesce_mode = 0; | 10391 | tp->coalesce_mode = 0; |
| 10362 | if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX && | 10392 | if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX && |
| @@ -11569,7 +11599,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 11569 | tg3_full_lock(tp, 0); | 11599 | tg3_full_lock(tp, 0); |
| 11570 | 11600 | ||
| 11571 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | 11601 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; |
| 11572 | tg3_init_hw(tp); | 11602 | tg3_init_hw(tp, 1); |
| 11573 | 11603 | ||
| 11574 | tp->timer.expires = jiffies + tp->timer_offset; | 11604 | tp->timer.expires = jiffies + tp->timer_offset; |
| 11575 | add_timer(&tp->timer); | 11605 | add_timer(&tp->timer); |
| @@ -11603,7 +11633,7 @@ static int tg3_resume(struct pci_dev *pdev) | |||
| 11603 | tg3_full_lock(tp, 0); | 11633 | tg3_full_lock(tp, 0); |
| 11604 | 11634 | ||
| 11605 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | 11635 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; |
| 11606 | tg3_init_hw(tp); | 11636 | tg3_init_hw(tp, 1); |
| 11607 | 11637 | ||
| 11608 | tp->timer.expires = jiffies + tp->timer_offset; | 11638 | tp->timer.expires = jiffies + tp->timer_offset; |
| 11609 | add_timer(&tp->timer); | 11639 | add_timer(&tp->timer); |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 8c8b987d1250..0e29b885d449 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
| @@ -2215,6 +2215,7 @@ struct tg3 { | |||
| 2215 | #define TG3_FLG2_HW_TSO_2 0x08000000 | 2215 | #define TG3_FLG2_HW_TSO_2 0x08000000 |
| 2216 | #define TG3_FLG2_HW_TSO (TG3_FLG2_HW_TSO_1 | TG3_FLG2_HW_TSO_2) | 2216 | #define TG3_FLG2_HW_TSO (TG3_FLG2_HW_TSO_1 | TG3_FLG2_HW_TSO_2) |
| 2217 | #define TG3_FLG2_1SHOT_MSI 0x10000000 | 2217 | #define TG3_FLG2_1SHOT_MSI 0x10000000 |
| 2218 | #define TG3_FLG2_PHY_JITTER_BUG 0x20000000 | ||
| 2218 | 2219 | ||
| 2219 | u32 split_mode_max_reqs; | 2220 | u32 split_mode_max_reqs; |
| 2220 | #define SPLIT_MODE_5704_MAX_REQ 3 | 2221 | #define SPLIT_MODE_5704_MAX_REQ 3 |
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 6a23964c1317..a6dc53b4250d 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c | |||
| @@ -129,6 +129,7 @@ | |||
| 129 | - Massive clean-up | 129 | - Massive clean-up |
| 130 | - Rewrite PHY, media handling (remove options, full_duplex, backoff) | 130 | - Rewrite PHY, media handling (remove options, full_duplex, backoff) |
| 131 | - Fix Tx engine race for good | 131 | - Fix Tx engine race for good |
| 132 | - Craig Brind: Zero padded aligned buffers for short packets. | ||
| 132 | 133 | ||
| 133 | */ | 134 | */ |
| 134 | 135 | ||
| @@ -1326,7 +1327,12 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev) | |||
| 1326 | rp->stats.tx_dropped++; | 1327 | rp->stats.tx_dropped++; |
| 1327 | return 0; | 1328 | return 0; |
| 1328 | } | 1329 | } |
| 1330 | |||
| 1331 | /* Padding is not copied and so must be redone. */ | ||
| 1329 | skb_copy_and_csum_dev(skb, rp->tx_buf[entry]); | 1332 | skb_copy_and_csum_dev(skb, rp->tx_buf[entry]); |
| 1333 | if (skb->len < ETH_ZLEN) | ||
| 1334 | memset(rp->tx_buf[entry] + skb->len, 0, | ||
| 1335 | ETH_ZLEN - skb->len); | ||
| 1330 | rp->tx_skbuff_dma[entry] = 0; | 1336 | rp->tx_skbuff_dma[entry] = 0; |
| 1331 | rp->tx_ring[entry].addr = cpu_to_le32(rp->tx_bufs_dma + | 1337 | rp->tx_ring[entry].addr = cpu_to_le32(rp->tx_bufs_dma + |
| 1332 | (rp->tx_buf[entry] - | 1338 | (rp->tx_buf[entry] - |
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index b1e3e6179e56..6c9ad92747fd 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
| @@ -58,7 +58,7 @@ rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
| 58 | unsigned long data; | 58 | unsigned long data; |
| 59 | ssize_t ret; | 59 | ssize_t ret; |
| 60 | 60 | ||
| 61 | if (count < sizeof(unsigned long)) | 61 | if (count != sizeof(unsigned int) && count < sizeof(unsigned long)) |
| 62 | return -EINVAL; | 62 | return -EINVAL; |
| 63 | 63 | ||
| 64 | add_wait_queue(&rtc->irq_queue, &wait); | 64 | add_wait_queue(&rtc->irq_queue, &wait); |
| @@ -90,11 +90,16 @@ rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
| 90 | if (ret == 0) { | 90 | if (ret == 0) { |
| 91 | /* Check for any data updates */ | 91 | /* Check for any data updates */ |
| 92 | if (rtc->ops->read_callback) | 92 | if (rtc->ops->read_callback) |
| 93 | data = rtc->ops->read_callback(rtc->class_dev.dev, data); | 93 | data = rtc->ops->read_callback(rtc->class_dev.dev, |
| 94 | 94 | data); | |
| 95 | ret = put_user(data, (unsigned long __user *)buf); | 95 | |
| 96 | if (ret == 0) | 96 | if (sizeof(int) != sizeof(long) && |
| 97 | ret = sizeof(unsigned long); | 97 | count == sizeof(unsigned int)) |
| 98 | ret = put_user(data, (unsigned int __user *)buf) ?: | ||
| 99 | sizeof(unsigned int); | ||
| 100 | else | ||
| 101 | ret = put_user(data, (unsigned long __user *)buf) ?: | ||
| 102 | sizeof(unsigned long); | ||
| 98 | } | 103 | } |
| 99 | return ret; | 104 | return ret; |
| 100 | } | 105 | } |
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index b3c6e7907790..cb14642d97aa 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
| @@ -8014,7 +8014,6 @@ static int (*qeth_old_arp_constructor) (struct neighbour *); | |||
| 8014 | 8014 | ||
| 8015 | static struct neigh_ops arp_direct_ops_template = { | 8015 | static struct neigh_ops arp_direct_ops_template = { |
| 8016 | .family = AF_INET, | 8016 | .family = AF_INET, |
| 8017 | .destructor = NULL, | ||
| 8018 | .solicit = NULL, | 8017 | .solicit = NULL, |
| 8019 | .error_report = NULL, | 8018 | .error_report = NULL, |
| 8020 | .output = dev_queue_xmit, | 8019 | .output = dev_queue_xmit, |
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index 5ae14803091f..f99e55308b32 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
| 14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
| 15 | #include <linux/workqueue.h> | 15 | #include <linux/workqueue.h> |
| 16 | #include <linux/time.h> | ||
| 16 | 17 | ||
| 17 | #include <asm/lowcore.h> | 18 | #include <asm/lowcore.h> |
| 18 | 19 | ||
| @@ -363,7 +364,7 @@ s390_revalidate_registers(struct mci *mci) | |||
| 363 | } | 364 | } |
| 364 | 365 | ||
| 365 | #define MAX_IPD_COUNT 29 | 366 | #define MAX_IPD_COUNT 29 |
| 366 | #define MAX_IPD_TIME (5 * 60 * 100 * 1000) /* 5 minutes */ | 367 | #define MAX_IPD_TIME (5 * 60 * USEC_PER_SEC) /* 5 minutes */ |
| 367 | 368 | ||
| 368 | /* | 369 | /* |
| 369 | * machine check handler. | 370 | * machine check handler. |
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index aa5eb7ddeda9..3b35cb779539 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h | |||
| @@ -5,6 +5,13 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 6 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
| 7 | * | 7 | * |
| 8 | * 2006 (c) MontaVista Software, Inc. | ||
| 9 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
| 10 | * | ||
| 11 | * This file is licensed under the terms of the GNU General Public License | ||
| 12 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 13 | * kind, whether express or implied. | ||
| 14 | * | ||
| 8 | */ | 15 | */ |
| 9 | #ifndef CPM_UART_H | 16 | #ifndef CPM_UART_H |
| 10 | #define CPM_UART_H | 17 | #define CPM_UART_H |
| @@ -101,12 +108,13 @@ static inline unsigned long cpu2cpm_addr(void* addr, struct uart_cpm_port *pinfo | |||
| 101 | int offset; | 108 | int offset; |
| 102 | u32 val = (u32)addr; | 109 | u32 val = (u32)addr; |
| 103 | /* sane check */ | 110 | /* sane check */ |
| 104 | if ((val >= (u32)pinfo->mem_addr) && | 111 | if (likely((val >= (u32)pinfo->mem_addr)) && |
| 105 | (val<((u32)pinfo->mem_addr + pinfo->mem_size))) { | 112 | (val<((u32)pinfo->mem_addr + pinfo->mem_size))) { |
| 106 | offset = val - (u32)pinfo->mem_addr; | 113 | offset = val - (u32)pinfo->mem_addr; |
| 107 | return pinfo->dma_addr+offset; | 114 | return pinfo->dma_addr+offset; |
| 108 | } | 115 | } |
| 109 | printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val); | 116 | /* something nasty happened */ |
| 117 | BUG(); | ||
| 110 | return 0; | 118 | return 0; |
| 111 | } | 119 | } |
| 112 | 120 | ||
| @@ -115,12 +123,13 @@ static inline void *cpm2cpu_addr(unsigned long addr, struct uart_cpm_port *pinfo | |||
| 115 | int offset; | 123 | int offset; |
| 116 | u32 val = addr; | 124 | u32 val = addr; |
| 117 | /* sane check */ | 125 | /* sane check */ |
| 118 | if ((val >= pinfo->dma_addr) && | 126 | if (likely((val >= pinfo->dma_addr) && |
| 119 | (val<(pinfo->dma_addr + pinfo->mem_size))) { | 127 | (val<(pinfo->dma_addr + pinfo->mem_size)))) { |
| 120 | offset = val - (u32)pinfo->dma_addr; | 128 | offset = val - (u32)pinfo->dma_addr; |
| 121 | return (void*)(pinfo->mem_addr+offset); | 129 | return (void*)(pinfo->mem_addr+offset); |
| 122 | } | 130 | } |
| 123 | printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val); | 131 | /* something nasty happened */ |
| 132 | BUG(); | ||
| 124 | return 0; | 133 | return 0; |
| 125 | } | 134 | } |
| 126 | 135 | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index ced193bf9e1e..969f94900431 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
| @@ -12,7 +12,8 @@ | |||
| 12 | * | 12 | * |
| 13 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 13 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
| 14 | * (C) 2004 Intracom, S.A. | 14 | * (C) 2004 Intracom, S.A. |
| 15 | * (C) 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.com> | 15 | * (C) 2005-2006 MontaVista Software, Inc. |
| 16 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
| 16 | * | 17 | * |
| 17 | * This program is free software; you can redistribute it and/or modify | 18 | * This program is free software; you can redistribute it and/or modify |
| 18 | * it under the terms of the GNU General Public License as published by | 19 | * it under the terms of the GNU General Public License as published by |
| @@ -81,7 +82,7 @@ early_uart_get_pdev(int index) | |||
| 81 | } | 82 | } |
| 82 | 83 | ||
| 83 | 84 | ||
| 84 | void cpm_uart_count(void) | 85 | static void cpm_uart_count(void) |
| 85 | { | 86 | { |
| 86 | cpm_uart_nr = 0; | 87 | cpm_uart_nr = 0; |
| 87 | #ifdef CONFIG_SERIAL_CPM_SMC1 | 88 | #ifdef CONFIG_SERIAL_CPM_SMC1 |
| @@ -104,6 +105,21 @@ void cpm_uart_count(void) | |||
| 104 | #endif | 105 | #endif |
| 105 | } | 106 | } |
| 106 | 107 | ||
| 108 | /* Get UART number by its id */ | ||
| 109 | static int cpm_uart_id2nr(int id) | ||
| 110 | { | ||
| 111 | int i; | ||
| 112 | if (id < UART_NR) { | ||
| 113 | for (i=0; i<UART_NR; i++) { | ||
| 114 | if (cpm_uart_port_map[i] == id) | ||
| 115 | return i; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | /* not found or invalid argument */ | ||
| 120 | return -1; | ||
| 121 | } | ||
| 122 | |||
| 107 | /* | 123 | /* |
| 108 | * Check, if transmit buffers are processed | 124 | * Check, if transmit buffers are processed |
| 109 | */ | 125 | */ |
| @@ -457,7 +473,11 @@ static void cpm_uart_shutdown(struct uart_port *port) | |||
| 457 | } | 473 | } |
| 458 | 474 | ||
| 459 | /* Shut them really down and reinit buffer descriptors */ | 475 | /* Shut them really down and reinit buffer descriptors */ |
| 460 | cpm_line_cr_cmd(line, CPM_CR_STOP_TX); | 476 | if (IS_SMC(pinfo)) |
| 477 | cpm_line_cr_cmd(line, CPM_CR_STOP_TX); | ||
| 478 | else | ||
| 479 | cpm_line_cr_cmd(line, CPM_CR_GRA_STOP_TX); | ||
| 480 | |||
| 461 | cpm_uart_initbd(pinfo); | 481 | cpm_uart_initbd(pinfo); |
| 462 | } | 482 | } |
| 463 | } | 483 | } |
| @@ -1008,7 +1028,11 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con) | |||
| 1008 | int line; | 1028 | int line; |
| 1009 | u32 mem, pram; | 1029 | u32 mem, pram; |
| 1010 | 1030 | ||
| 1011 | for (line=0; line<UART_NR && cpm_uart_port_map[line]!=pdata->fs_no; line++); | 1031 | line = cpm_uart_id2nr(idx); |
| 1032 | if(line < 0) { | ||
| 1033 | printk(KERN_ERR"%s(): port %d is not registered", __FUNCTION__, idx); | ||
| 1034 | return -1; | ||
| 1035 | } | ||
| 1012 | 1036 | ||
| 1013 | pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx]; | 1037 | pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx]; |
| 1014 | 1038 | ||
| @@ -1241,8 +1265,7 @@ static int cpm_uart_drv_probe(struct device *dev) | |||
| 1241 | } | 1265 | } |
| 1242 | 1266 | ||
| 1243 | pdata = pdev->dev.platform_data; | 1267 | pdata = pdev->dev.platform_data; |
| 1244 | pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", | 1268 | pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n", cpm_uart_id2nr(pdata->fs_no)); |
| 1245 | cpm_uart_port_map[pdata->fs_no]); | ||
| 1246 | 1269 | ||
| 1247 | if ((ret = cpm_uart_drv_get_platform_data(pdev, 0))) | 1270 | if ((ret = cpm_uart_drv_get_platform_data(pdev, 0))) |
| 1248 | return ret; | 1271 | return ret; |
| @@ -1261,7 +1284,7 @@ static int cpm_uart_drv_remove(struct device *dev) | |||
| 1261 | struct fs_uart_platform_info *pdata = pdev->dev.platform_data; | 1284 | struct fs_uart_platform_info *pdata = pdev->dev.platform_data; |
| 1262 | 1285 | ||
| 1263 | pr_debug("cpm_uart_drv_remove: Removing CPM UART %d\n", | 1286 | pr_debug("cpm_uart_drv_remove: Removing CPM UART %d\n", |
| 1264 | cpm_uart_port_map[pdata->fs_no]); | 1287 | cpm_uart_id2nr(pdata->fs_no)); |
| 1265 | 1288 | ||
| 1266 | uart_remove_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port); | 1289 | uart_remove_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port); |
| 1267 | return 0; | 1290 | return 0; |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index a5a30622637a..17406a05ce1f 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | * | 8 | * |
| 9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
| 10 | * (C) 2004 Intracom, S.A. | 10 | * (C) 2004 Intracom, S.A. |
| 11 | * (C) 2006 MontaVista Software, Inc. | ||
| 12 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
| 11 | * | 13 | * |
| 12 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
| 13 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index 7c6b07aeea92..4b2de08f46d0 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | * | 8 | * |
| 9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
| 10 | * (C) 2004 Intracom, S.A. | 10 | * (C) 2004 Intracom, S.A. |
| 11 | * (C) 2006 MontaVista Software, Inc. | ||
| 12 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
| 11 | * | 13 | * |
| 12 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
| 13 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index c3b7a6673e9c..d202eb4f3848 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #include <asm/io.h> | 45 | #include <asm/io.h> |
| 46 | #include <asm/irq.h> | 46 | #include <asm/irq.h> |
| 47 | #include <asm/hardware.h> | 47 | #include <asm/hardware.h> |
| 48 | #include <asm/arch/imx-uart.h> | ||
| 48 | 49 | ||
| 49 | /* We've been assigned a range on the "Low-density serial ports" major */ | 50 | /* We've been assigned a range on the "Low-density serial ports" major */ |
| 50 | #define SERIAL_IMX_MAJOR 204 | 51 | #define SERIAL_IMX_MAJOR 204 |
| @@ -73,7 +74,8 @@ struct imx_port { | |||
| 73 | struct uart_port port; | 74 | struct uart_port port; |
| 74 | struct timer_list timer; | 75 | struct timer_list timer; |
| 75 | unsigned int old_status; | 76 | unsigned int old_status; |
| 76 | int txirq,rxirq,rtsirq; | 77 | int txirq,rxirq,rtsirq; |
| 78 | int have_rtscts:1; | ||
| 77 | }; | 79 | }; |
| 78 | 80 | ||
| 79 | /* | 81 | /* |
| @@ -491,8 +493,12 @@ imx_set_termios(struct uart_port *port, struct termios *termios, | |||
| 491 | ucr2 = UCR2_SRST | UCR2_IRTS; | 493 | ucr2 = UCR2_SRST | UCR2_IRTS; |
| 492 | 494 | ||
| 493 | if (termios->c_cflag & CRTSCTS) { | 495 | if (termios->c_cflag & CRTSCTS) { |
| 494 | ucr2 &= ~UCR2_IRTS; | 496 | if( sport->have_rtscts ) { |
| 495 | ucr2 |= UCR2_CTSC; | 497 | ucr2 &= ~UCR2_IRTS; |
| 498 | ucr2 |= UCR2_CTSC; | ||
| 499 | } else { | ||
| 500 | termios->c_cflag &= ~CRTSCTS; | ||
| 501 | } | ||
| 496 | } | 502 | } |
| 497 | 503 | ||
| 498 | if (termios->c_cflag & CSTOPB) | 504 | if (termios->c_cflag & CSTOPB) |
| @@ -719,27 +725,6 @@ static void __init imx_init_ports(void) | |||
| 719 | imx_ports[i].timer.function = imx_timeout; | 725 | imx_ports[i].timer.function = imx_timeout; |
| 720 | imx_ports[i].timer.data = (unsigned long)&imx_ports[i]; | 726 | imx_ports[i].timer.data = (unsigned long)&imx_ports[i]; |
| 721 | } | 727 | } |
| 722 | |||
| 723 | imx_gpio_mode(PC9_PF_UART1_CTS); | ||
| 724 | imx_gpio_mode(PC10_PF_UART1_RTS); | ||
| 725 | imx_gpio_mode(PC11_PF_UART1_TXD); | ||
| 726 | imx_gpio_mode(PC12_PF_UART1_RXD); | ||
| 727 | imx_gpio_mode(PB28_PF_UART2_CTS); | ||
| 728 | imx_gpio_mode(PB29_PF_UART2_RTS); | ||
| 729 | |||
| 730 | imx_gpio_mode(PB30_PF_UART2_TXD); | ||
| 731 | imx_gpio_mode(PB31_PF_UART2_RXD); | ||
| 732 | |||
| 733 | #if 0 /* We don't need these, on the mx1 the _modem_ side of the uart | ||
| 734 | * is implemented. | ||
| 735 | */ | ||
| 736 | imx_gpio_mode(PD7_AF_UART2_DTR); | ||
| 737 | imx_gpio_mode(PD8_AF_UART2_DCD); | ||
| 738 | imx_gpio_mode(PD9_AF_UART2_RI); | ||
| 739 | imx_gpio_mode(PD10_AF_UART2_DSR); | ||
| 740 | #endif | ||
| 741 | |||
| 742 | |||
| 743 | } | 728 | } |
| 744 | 729 | ||
| 745 | #ifdef CONFIG_SERIAL_IMX_CONSOLE | 730 | #ifdef CONFIG_SERIAL_IMX_CONSOLE |
| @@ -932,7 +917,14 @@ static int serial_imx_resume(struct platform_device *dev) | |||
| 932 | 917 | ||
| 933 | static int serial_imx_probe(struct platform_device *dev) | 918 | static int serial_imx_probe(struct platform_device *dev) |
| 934 | { | 919 | { |
| 920 | struct imxuart_platform_data *pdata; | ||
| 921 | |||
| 935 | imx_ports[dev->id].port.dev = &dev->dev; | 922 | imx_ports[dev->id].port.dev = &dev->dev; |
| 923 | |||
| 924 | pdata = (struct imxuart_platform_data *)dev->dev.platform_data; | ||
| 925 | if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS)) | ||
| 926 | imx_ports[dev->id].have_rtscts = 1; | ||
| 927 | |||
| 936 | uart_add_one_port(&imx_reg, &imx_ports[dev->id].port); | 928 | uart_add_one_port(&imx_reg, &imx_ports[dev->id].port); |
| 937 | platform_set_drvdata(dev, &imx_ports[dev->id]); | 929 | platform_set_drvdata(dev, &imx_ports[dev->id]); |
| 938 | return 0; | 930 | return 0; |
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c index 0b49ff78efc1..501316b198e5 100644 --- a/drivers/sn/ioc3.c +++ b/drivers/sn/ioc3.c | |||
| @@ -678,7 +678,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
| 678 | /* Track PCI-device specific data */ | 678 | /* Track PCI-device specific data */ |
| 679 | pci_set_drvdata(pdev, idd); | 679 | pci_set_drvdata(pdev, idd); |
| 680 | down_write(&ioc3_devices_rwsem); | 680 | down_write(&ioc3_devices_rwsem); |
| 681 | list_add(&idd->list, &ioc3_devices); | 681 | list_add_tail(&idd->list, &ioc3_devices); |
| 682 | idd->id = ioc3_counter++; | 682 | idd->id = ioc3_counter++; |
| 683 | up_write(&ioc3_devices_rwsem); | 683 | up_write(&ioc3_devices_rwsem); |
| 684 | 684 | ||
diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c index 67140a5804f5..cdeff909403e 100644 --- a/drivers/sn/ioc4.c +++ b/drivers/sn/ioc4.c | |||
| @@ -310,7 +310,7 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
| 310 | pci_set_drvdata(idd->idd_pdev, idd); | 310 | pci_set_drvdata(idd->idd_pdev, idd); |
| 311 | 311 | ||
| 312 | mutex_lock(&ioc4_mutex); | 312 | mutex_lock(&ioc4_mutex); |
| 313 | list_add(&idd->idd_list, &ioc4_devices); | 313 | list_add_tail(&idd->idd_list, &ioc4_devices); |
| 314 | 314 | ||
| 315 | /* Add this IOC4 to all submodules */ | 315 | /* Add this IOC4 to all submodules */ |
| 316 | list_for_each_entry(is, &ioc4_submodules, is_list) { | 316 | list_for_each_entry(is, &ioc4_submodules, is_list) { |
diff --git a/fs/block_dev.c b/fs/block_dev.c index af88c43043d5..f5958f413bd1 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
| @@ -1104,6 +1104,8 @@ const struct file_operations def_blk_fops = { | |||
| 1104 | .readv = generic_file_readv, | 1104 | .readv = generic_file_readv, |
| 1105 | .writev = generic_file_write_nolock, | 1105 | .writev = generic_file_write_nolock, |
| 1106 | .sendfile = generic_file_sendfile, | 1106 | .sendfile = generic_file_sendfile, |
| 1107 | .splice_read = generic_file_splice_read, | ||
| 1108 | .splice_write = generic_file_splice_write, | ||
| 1107 | }; | 1109 | }; |
| 1108 | 1110 | ||
| 1109 | int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) | 1111 | int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg) |
diff --git a/fs/compat.c b/fs/compat.c index 2e32bd340474..970888aad843 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
| @@ -1317,6 +1317,26 @@ out: | |||
| 1317 | return ret; | 1317 | return ret; |
| 1318 | } | 1318 | } |
| 1319 | 1319 | ||
| 1320 | asmlinkage long | ||
| 1321 | compat_sys_vmsplice(int fd, const struct compat_iovec __user *iov32, | ||
| 1322 | unsigned int nr_segs, unsigned int flags) | ||
| 1323 | { | ||
| 1324 | unsigned i; | ||
| 1325 | struct iovec *iov; | ||
| 1326 | if (nr_segs > UIO_MAXIOV) | ||
| 1327 | return -EINVAL; | ||
| 1328 | iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec)); | ||
| 1329 | for (i = 0; i < nr_segs; i++) { | ||
| 1330 | struct compat_iovec v; | ||
| 1331 | if (get_user(v.iov_base, &iov32[i].iov_base) || | ||
| 1332 | get_user(v.iov_len, &iov32[i].iov_len) || | ||
| 1333 | put_user(compat_ptr(v.iov_base), &iov[i].iov_base) || | ||
| 1334 | put_user(v.iov_len, &iov[i].iov_len)) | ||
| 1335 | return -EFAULT; | ||
| 1336 | } | ||
| 1337 | return sys_vmsplice(fd, iov, nr_segs, flags); | ||
| 1338 | } | ||
| 1339 | |||
| 1320 | /* | 1340 | /* |
| 1321 | * Exactly like fs/open.c:sys_open(), except that it doesn't set the | 1341 | * Exactly like fs/open.c:sys_open(), except that it doesn't set the |
| 1322 | * O_LARGEFILE flag. | 1342 | * O_LARGEFILE flag. |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 48ae0339af17..2edd7eec88fd 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
| @@ -711,7 +711,7 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode, | |||
| 711 | * direct blocks blocks | 711 | * direct blocks blocks |
| 712 | */ | 712 | */ |
| 713 | if (num == 0 && blks > 1) { | 713 | if (num == 0 && blks > 1) { |
| 714 | current_block = le32_to_cpu(where->key + 1); | 714 | current_block = le32_to_cpu(where->key) + 1; |
| 715 | for (i = 1; i < blks; i++) | 715 | for (i = 1; i < blks; i++) |
| 716 | *(where->p + i ) = cpu_to_le32(current_block++); | 716 | *(where->p + i ) = cpu_to_le32(current_block++); |
| 717 | } | 717 | } |
| @@ -724,7 +724,7 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode, | |||
| 724 | if (block_i) { | 724 | if (block_i) { |
| 725 | block_i->last_alloc_logical_block = block + blks - 1; | 725 | block_i->last_alloc_logical_block = block + blks - 1; |
| 726 | block_i->last_alloc_physical_block = | 726 | block_i->last_alloc_physical_block = |
| 727 | le32_to_cpu(where[num].key + blks - 1); | 727 | le32_to_cpu(where[num].key) + blks - 1; |
| 728 | } | 728 | } |
| 729 | 729 | ||
| 730 | /* We are done with atomic stuff, now do the rest of housekeeping */ | 730 | /* We are done with atomic stuff, now do the rest of housekeeping */ |
| @@ -814,11 +814,13 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
| 814 | 814 | ||
| 815 | /* Simplest case - block found, no allocation needed */ | 815 | /* Simplest case - block found, no allocation needed */ |
| 816 | if (!partial) { | 816 | if (!partial) { |
| 817 | first_block = chain[depth - 1].key; | 817 | first_block = le32_to_cpu(chain[depth - 1].key); |
| 818 | clear_buffer_new(bh_result); | 818 | clear_buffer_new(bh_result); |
| 819 | count++; | 819 | count++; |
| 820 | /*map more blocks*/ | 820 | /*map more blocks*/ |
| 821 | while (count < maxblocks && count <= blocks_to_boundary) { | 821 | while (count < maxblocks && count <= blocks_to_boundary) { |
| 822 | unsigned long blk; | ||
| 823 | |||
| 822 | if (!verify_chain(chain, partial)) { | 824 | if (!verify_chain(chain, partial)) { |
| 823 | /* | 825 | /* |
| 824 | * Indirect block might be removed by | 826 | * Indirect block might be removed by |
| @@ -831,8 +833,9 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
| 831 | count = 0; | 833 | count = 0; |
| 832 | break; | 834 | break; |
| 833 | } | 835 | } |
| 834 | if (le32_to_cpu(*(chain[depth-1].p+count) == | 836 | blk = le32_to_cpu(*(chain[depth-1].p + count)); |
| 835 | (first_block + count))) | 837 | |
| 838 | if (blk == first_block + count) | ||
| 836 | count++; | 839 | count++; |
| 837 | else | 840 | else |
| 838 | break; | 841 | break; |
| @@ -55,7 +55,8 @@ void pipe_wait(struct pipe_inode_info *pipe) | |||
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | static int | 57 | static int |
| 58 | pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len) | 58 | pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len, |
| 59 | int atomic) | ||
| 59 | { | 60 | { |
| 60 | unsigned long copy; | 61 | unsigned long copy; |
| 61 | 62 | ||
| @@ -64,8 +65,13 @@ pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len) | |||
| 64 | iov++; | 65 | iov++; |
| 65 | copy = min_t(unsigned long, len, iov->iov_len); | 66 | copy = min_t(unsigned long, len, iov->iov_len); |
| 66 | 67 | ||
| 67 | if (copy_from_user(to, iov->iov_base, copy)) | 68 | if (atomic) { |
| 68 | return -EFAULT; | 69 | if (__copy_from_user_inatomic(to, iov->iov_base, copy)) |
| 70 | return -EFAULT; | ||
| 71 | } else { | ||
| 72 | if (copy_from_user(to, iov->iov_base, copy)) | ||
| 73 | return -EFAULT; | ||
| 74 | } | ||
| 69 | to += copy; | 75 | to += copy; |
| 70 | len -= copy; | 76 | len -= copy; |
| 71 | iov->iov_base += copy; | 77 | iov->iov_base += copy; |
| @@ -75,7 +81,8 @@ pipe_iov_copy_from_user(void *to, struct iovec *iov, unsigned long len) | |||
| 75 | } | 81 | } |
| 76 | 82 | ||
| 77 | static int | 83 | static int |
| 78 | pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len) | 84 | pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len, |
| 85 | int atomic) | ||
| 79 | { | 86 | { |
| 80 | unsigned long copy; | 87 | unsigned long copy; |
| 81 | 88 | ||
| @@ -84,8 +91,13 @@ pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len) | |||
| 84 | iov++; | 91 | iov++; |
| 85 | copy = min_t(unsigned long, len, iov->iov_len); | 92 | copy = min_t(unsigned long, len, iov->iov_len); |
| 86 | 93 | ||
| 87 | if (copy_to_user(iov->iov_base, from, copy)) | 94 | if (atomic) { |
| 88 | return -EFAULT; | 95 | if (__copy_to_user_inatomic(iov->iov_base, from, copy)) |
| 96 | return -EFAULT; | ||
| 97 | } else { | ||
| 98 | if (copy_to_user(iov->iov_base, from, copy)) | ||
| 99 | return -EFAULT; | ||
| 100 | } | ||
| 89 | from += copy; | 101 | from += copy; |
| 90 | len -= copy; | 102 | len -= copy; |
| 91 | iov->iov_base += copy; | 103 | iov->iov_base += copy; |
| @@ -94,13 +106,52 @@ pipe_iov_copy_to_user(struct iovec *iov, const void *from, unsigned long len) | |||
| 94 | return 0; | 106 | return 0; |
| 95 | } | 107 | } |
| 96 | 108 | ||
| 109 | /* | ||
| 110 | * Attempt to pre-fault in the user memory, so we can use atomic copies. | ||
| 111 | * Returns the number of bytes not faulted in. | ||
| 112 | */ | ||
| 113 | static int iov_fault_in_pages_write(struct iovec *iov, unsigned long len) | ||
| 114 | { | ||
| 115 | while (!iov->iov_len) | ||
| 116 | iov++; | ||
| 117 | |||
| 118 | while (len > 0) { | ||
| 119 | unsigned long this_len; | ||
| 120 | |||
| 121 | this_len = min_t(unsigned long, len, iov->iov_len); | ||
| 122 | if (fault_in_pages_writeable(iov->iov_base, this_len)) | ||
| 123 | break; | ||
| 124 | |||
| 125 | len -= this_len; | ||
| 126 | iov++; | ||
| 127 | } | ||
| 128 | |||
| 129 | return len; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* | ||
| 133 | * Pre-fault in the user memory, so we can use atomic copies. | ||
| 134 | */ | ||
| 135 | static void iov_fault_in_pages_read(struct iovec *iov, unsigned long len) | ||
| 136 | { | ||
| 137 | while (!iov->iov_len) | ||
| 138 | iov++; | ||
| 139 | |||
| 140 | while (len > 0) { | ||
| 141 | unsigned long this_len; | ||
| 142 | |||
| 143 | this_len = min_t(unsigned long, len, iov->iov_len); | ||
| 144 | fault_in_pages_readable(iov->iov_base, this_len); | ||
| 145 | len -= this_len; | ||
| 146 | iov++; | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 97 | static void anon_pipe_buf_release(struct pipe_inode_info *pipe, | 150 | static void anon_pipe_buf_release(struct pipe_inode_info *pipe, |
| 98 | struct pipe_buffer *buf) | 151 | struct pipe_buffer *buf) |
| 99 | { | 152 | { |
| 100 | struct page *page = buf->page; | 153 | struct page *page = buf->page; |
| 101 | 154 | ||
| 102 | buf->flags &= ~PIPE_BUF_FLAG_STOLEN; | ||
| 103 | |||
| 104 | /* | 155 | /* |
| 105 | * If nobody else uses this page, and we don't already have a | 156 | * If nobody else uses this page, and we don't already have a |
| 106 | * temporary page, let's keep track of it as a one-deep | 157 | * temporary page, let's keep track of it as a one-deep |
| @@ -112,38 +163,58 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe, | |||
| 112 | page_cache_release(page); | 163 | page_cache_release(page); |
| 113 | } | 164 | } |
| 114 | 165 | ||
| 115 | static void * anon_pipe_buf_map(struct file *file, struct pipe_inode_info *pipe, | 166 | void *generic_pipe_buf_map(struct pipe_inode_info *pipe, |
| 116 | struct pipe_buffer *buf) | 167 | struct pipe_buffer *buf, int atomic) |
| 117 | { | 168 | { |
| 169 | if (atomic) { | ||
| 170 | buf->flags |= PIPE_BUF_FLAG_ATOMIC; | ||
| 171 | return kmap_atomic(buf->page, KM_USER0); | ||
| 172 | } | ||
| 173 | |||
| 118 | return kmap(buf->page); | 174 | return kmap(buf->page); |
| 119 | } | 175 | } |
| 120 | 176 | ||
| 121 | static void anon_pipe_buf_unmap(struct pipe_inode_info *pipe, | 177 | void generic_pipe_buf_unmap(struct pipe_inode_info *pipe, |
| 122 | struct pipe_buffer *buf) | 178 | struct pipe_buffer *buf, void *map_data) |
| 123 | { | 179 | { |
| 124 | kunmap(buf->page); | 180 | if (buf->flags & PIPE_BUF_FLAG_ATOMIC) { |
| 181 | buf->flags &= ~PIPE_BUF_FLAG_ATOMIC; | ||
| 182 | kunmap_atomic(map_data, KM_USER0); | ||
| 183 | } else | ||
| 184 | kunmap(buf->page); | ||
| 125 | } | 185 | } |
| 126 | 186 | ||
| 127 | static int anon_pipe_buf_steal(struct pipe_inode_info *pipe, | 187 | int generic_pipe_buf_steal(struct pipe_inode_info *pipe, |
| 128 | struct pipe_buffer *buf) | 188 | struct pipe_buffer *buf) |
| 129 | { | 189 | { |
| 130 | buf->flags |= PIPE_BUF_FLAG_STOLEN; | 190 | struct page *page = buf->page; |
| 131 | return 0; | 191 | |
| 192 | if (page_count(page) == 1) { | ||
| 193 | lock_page(page); | ||
| 194 | return 0; | ||
| 195 | } | ||
| 196 | |||
| 197 | return 1; | ||
| 132 | } | 198 | } |
| 133 | 199 | ||
| 134 | static void anon_pipe_buf_get(struct pipe_inode_info *info, | 200 | void generic_pipe_buf_get(struct pipe_inode_info *info, struct pipe_buffer *buf) |
| 135 | struct pipe_buffer *buf) | ||
| 136 | { | 201 | { |
| 137 | page_cache_get(buf->page); | 202 | page_cache_get(buf->page); |
| 138 | } | 203 | } |
| 139 | 204 | ||
| 205 | int generic_pipe_buf_pin(struct pipe_inode_info *info, struct pipe_buffer *buf) | ||
| 206 | { | ||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | |||
| 140 | static struct pipe_buf_operations anon_pipe_buf_ops = { | 210 | static struct pipe_buf_operations anon_pipe_buf_ops = { |
| 141 | .can_merge = 1, | 211 | .can_merge = 1, |
| 142 | .map = anon_pipe_buf_map, | 212 | .map = generic_pipe_buf_map, |
| 143 | .unmap = anon_pipe_buf_unmap, | 213 | .unmap = generic_pipe_buf_unmap, |
| 214 | .pin = generic_pipe_buf_pin, | ||
| 144 | .release = anon_pipe_buf_release, | 215 | .release = anon_pipe_buf_release, |
| 145 | .steal = anon_pipe_buf_steal, | 216 | .steal = generic_pipe_buf_steal, |
| 146 | .get = anon_pipe_buf_get, | 217 | .get = generic_pipe_buf_get, |
| 147 | }; | 218 | }; |
| 148 | 219 | ||
| 149 | static ssize_t | 220 | static ssize_t |
| @@ -174,22 +245,33 @@ pipe_readv(struct file *filp, const struct iovec *_iov, | |||
| 174 | struct pipe_buf_operations *ops = buf->ops; | 245 | struct pipe_buf_operations *ops = buf->ops; |
| 175 | void *addr; | 246 | void *addr; |
| 176 | size_t chars = buf->len; | 247 | size_t chars = buf->len; |
| 177 | int error; | 248 | int error, atomic; |
| 178 | 249 | ||
| 179 | if (chars > total_len) | 250 | if (chars > total_len) |
| 180 | chars = total_len; | 251 | chars = total_len; |
| 181 | 252 | ||
| 182 | addr = ops->map(filp, pipe, buf); | 253 | error = ops->pin(pipe, buf); |
| 183 | if (IS_ERR(addr)) { | 254 | if (error) { |
| 184 | if (!ret) | 255 | if (!ret) |
| 185 | ret = PTR_ERR(addr); | 256 | error = ret; |
| 186 | break; | 257 | break; |
| 187 | } | 258 | } |
| 188 | error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars); | 259 | |
| 189 | ops->unmap(pipe, buf); | 260 | atomic = !iov_fault_in_pages_write(iov, chars); |
| 261 | redo: | ||
| 262 | addr = ops->map(pipe, buf, atomic); | ||
| 263 | error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars, atomic); | ||
| 264 | ops->unmap(pipe, buf, addr); | ||
| 190 | if (unlikely(error)) { | 265 | if (unlikely(error)) { |
| 266 | /* | ||
| 267 | * Just retry with the slow path if we failed. | ||
| 268 | */ | ||
| 269 | if (atomic) { | ||
| 270 | atomic = 0; | ||
| 271 | goto redo; | ||
| 272 | } | ||
| 191 | if (!ret) | 273 | if (!ret) |
| 192 | ret = -EFAULT; | 274 | ret = error; |
| 193 | break; | 275 | break; |
| 194 | } | 276 | } |
| 195 | ret += chars; | 277 | ret += chars; |
| @@ -293,21 +375,28 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
| 293 | int offset = buf->offset + buf->len; | 375 | int offset = buf->offset + buf->len; |
| 294 | 376 | ||
| 295 | if (ops->can_merge && offset + chars <= PAGE_SIZE) { | 377 | if (ops->can_merge && offset + chars <= PAGE_SIZE) { |
| 378 | int error, atomic = 1; | ||
| 296 | void *addr; | 379 | void *addr; |
| 297 | int error; | ||
| 298 | 380 | ||
| 299 | addr = ops->map(filp, pipe, buf); | 381 | error = ops->pin(pipe, buf); |
| 300 | if (IS_ERR(addr)) { | 382 | if (error) |
| 301 | error = PTR_ERR(addr); | ||
| 302 | goto out; | 383 | goto out; |
| 303 | } | 384 | |
| 385 | iov_fault_in_pages_read(iov, chars); | ||
| 386 | redo1: | ||
| 387 | addr = ops->map(pipe, buf, atomic); | ||
| 304 | error = pipe_iov_copy_from_user(offset + addr, iov, | 388 | error = pipe_iov_copy_from_user(offset + addr, iov, |
| 305 | chars); | 389 | chars, atomic); |
| 306 | ops->unmap(pipe, buf); | 390 | ops->unmap(pipe, buf, addr); |
| 307 | ret = error; | 391 | ret = error; |
| 308 | do_wakeup = 1; | 392 | do_wakeup = 1; |
| 309 | if (error) | 393 | if (error) { |
| 394 | if (atomic) { | ||
| 395 | atomic = 0; | ||
| 396 | goto redo1; | ||
| 397 | } | ||
| 310 | goto out; | 398 | goto out; |
| 399 | } | ||
| 311 | buf->len += chars; | 400 | buf->len += chars; |
| 312 | total_len -= chars; | 401 | total_len -= chars; |
| 313 | ret = chars; | 402 | ret = chars; |
| @@ -330,7 +419,8 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
| 330 | int newbuf = (pipe->curbuf + bufs) & (PIPE_BUFFERS-1); | 419 | int newbuf = (pipe->curbuf + bufs) & (PIPE_BUFFERS-1); |
| 331 | struct pipe_buffer *buf = pipe->bufs + newbuf; | 420 | struct pipe_buffer *buf = pipe->bufs + newbuf; |
| 332 | struct page *page = pipe->tmp_page; | 421 | struct page *page = pipe->tmp_page; |
| 333 | int error; | 422 | char *src; |
| 423 | int error, atomic = 1; | ||
| 334 | 424 | ||
| 335 | if (!page) { | 425 | if (!page) { |
| 336 | page = alloc_page(GFP_HIGHUSER); | 426 | page = alloc_page(GFP_HIGHUSER); |
| @@ -350,11 +440,27 @@ pipe_writev(struct file *filp, const struct iovec *_iov, | |||
| 350 | if (chars > total_len) | 440 | if (chars > total_len) |
| 351 | chars = total_len; | 441 | chars = total_len; |
| 352 | 442 | ||
| 353 | error = pipe_iov_copy_from_user(kmap(page), iov, chars); | 443 | iov_fault_in_pages_read(iov, chars); |
| 354 | kunmap(page); | 444 | redo2: |
| 445 | if (atomic) | ||
| 446 | src = kmap_atomic(page, KM_USER0); | ||
| 447 | else | ||
| 448 | src = kmap(page); | ||
| 449 | |||
| 450 | error = pipe_iov_copy_from_user(src, iov, chars, | ||
| 451 | atomic); | ||
| 452 | if (atomic) | ||
| 453 | kunmap_atomic(src, KM_USER0); | ||
| 454 | else | ||
| 455 | kunmap(page); | ||
| 456 | |||
| 355 | if (unlikely(error)) { | 457 | if (unlikely(error)) { |
| 458 | if (atomic) { | ||
| 459 | atomic = 0; | ||
| 460 | goto redo2; | ||
| 461 | } | ||
| 356 | if (!ret) | 462 | if (!ret) |
| 357 | ret = -EFAULT; | 463 | ret = error; |
| 358 | break; | 464 | break; |
| 359 | } | 465 | } |
| 360 | ret += chars; | 466 | ret += chars; |
diff --git a/fs/splice.c b/fs/splice.c index a46ddd28561e..a285fd746dc0 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
| @@ -51,7 +51,7 @@ struct splice_pipe_desc { | |||
| 51 | * addition of remove_mapping(). If success is returned, the caller may | 51 | * addition of remove_mapping(). If success is returned, the caller may |
| 52 | * attempt to reuse this page for another destination. | 52 | * attempt to reuse this page for another destination. |
| 53 | */ | 53 | */ |
| 54 | static int page_cache_pipe_buf_steal(struct pipe_inode_info *info, | 54 | static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe, |
| 55 | struct pipe_buffer *buf) | 55 | struct pipe_buffer *buf) |
| 56 | { | 56 | { |
| 57 | struct page *page = buf->page; | 57 | struct page *page = buf->page; |
| @@ -78,21 +78,19 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *info, | |||
| 78 | return 1; | 78 | return 1; |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | buf->flags |= PIPE_BUF_FLAG_STOLEN | PIPE_BUF_FLAG_LRU; | 81 | buf->flags |= PIPE_BUF_FLAG_LRU; |
| 82 | return 0; | 82 | return 0; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | static void page_cache_pipe_buf_release(struct pipe_inode_info *info, | 85 | static void page_cache_pipe_buf_release(struct pipe_inode_info *pipe, |
| 86 | struct pipe_buffer *buf) | 86 | struct pipe_buffer *buf) |
| 87 | { | 87 | { |
| 88 | page_cache_release(buf->page); | 88 | page_cache_release(buf->page); |
| 89 | buf->page = NULL; | 89 | buf->flags &= ~PIPE_BUF_FLAG_LRU; |
| 90 | buf->flags &= ~(PIPE_BUF_FLAG_STOLEN | PIPE_BUF_FLAG_LRU); | ||
| 91 | } | 90 | } |
| 92 | 91 | ||
| 93 | static void *page_cache_pipe_buf_map(struct file *file, | 92 | static int page_cache_pipe_buf_pin(struct pipe_inode_info *pipe, |
| 94 | struct pipe_inode_info *info, | 93 | struct pipe_buffer *buf) |
| 95 | struct pipe_buffer *buf) | ||
| 96 | { | 94 | { |
| 97 | struct page *page = buf->page; | 95 | struct page *page = buf->page; |
| 98 | int err; | 96 | int err; |
| @@ -118,64 +116,45 @@ static void *page_cache_pipe_buf_map(struct file *file, | |||
| 118 | } | 116 | } |
| 119 | 117 | ||
| 120 | /* | 118 | /* |
| 121 | * Page is ok afterall, fall through to mapping. | 119 | * Page is ok afterall, we are done. |
| 122 | */ | 120 | */ |
| 123 | unlock_page(page); | 121 | unlock_page(page); |
| 124 | } | 122 | } |
| 125 | 123 | ||
| 126 | return kmap(page); | 124 | return 0; |
| 127 | error: | 125 | error: |
| 128 | unlock_page(page); | 126 | unlock_page(page); |
| 129 | return ERR_PTR(err); | 127 | return err; |
| 130 | } | ||
| 131 | |||
| 132 | static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info, | ||
| 133 | struct pipe_buffer *buf) | ||
| 134 | { | ||
| 135 | kunmap(buf->page); | ||
| 136 | } | ||
| 137 | |||
| 138 | static void *user_page_pipe_buf_map(struct file *file, | ||
| 139 | struct pipe_inode_info *pipe, | ||
| 140 | struct pipe_buffer *buf) | ||
| 141 | { | ||
| 142 | return kmap(buf->page); | ||
| 143 | } | ||
| 144 | |||
| 145 | static void user_page_pipe_buf_unmap(struct pipe_inode_info *pipe, | ||
| 146 | struct pipe_buffer *buf) | ||
| 147 | { | ||
| 148 | kunmap(buf->page); | ||
| 149 | } | ||
| 150 | |||
| 151 | static void page_cache_pipe_buf_get(struct pipe_inode_info *info, | ||
| 152 | struct pipe_buffer *buf) | ||
| 153 | { | ||
| 154 | page_cache_get(buf->page); | ||
| 155 | } | 128 | } |
| 156 | 129 | ||
| 157 | static struct pipe_buf_operations page_cache_pipe_buf_ops = { | 130 | static struct pipe_buf_operations page_cache_pipe_buf_ops = { |
| 158 | .can_merge = 0, | 131 | .can_merge = 0, |
| 159 | .map = page_cache_pipe_buf_map, | 132 | .map = generic_pipe_buf_map, |
| 160 | .unmap = page_cache_pipe_buf_unmap, | 133 | .unmap = generic_pipe_buf_unmap, |
| 134 | .pin = page_cache_pipe_buf_pin, | ||
| 161 | .release = page_cache_pipe_buf_release, | 135 | .release = page_cache_pipe_buf_release, |
| 162 | .steal = page_cache_pipe_buf_steal, | 136 | .steal = page_cache_pipe_buf_steal, |
| 163 | .get = page_cache_pipe_buf_get, | 137 | .get = generic_pipe_buf_get, |
| 164 | }; | 138 | }; |
| 165 | 139 | ||
| 166 | static int user_page_pipe_buf_steal(struct pipe_inode_info *pipe, | 140 | static int user_page_pipe_buf_steal(struct pipe_inode_info *pipe, |
| 167 | struct pipe_buffer *buf) | 141 | struct pipe_buffer *buf) |
| 168 | { | 142 | { |
| 169 | return 1; | 143 | if (!(buf->flags & PIPE_BUF_FLAG_GIFT)) |
| 144 | return 1; | ||
| 145 | |||
| 146 | buf->flags |= PIPE_BUF_FLAG_LRU; | ||
| 147 | return generic_pipe_buf_steal(pipe, buf); | ||
| 170 | } | 148 | } |
| 171 | 149 | ||
| 172 | static struct pipe_buf_operations user_page_pipe_buf_ops = { | 150 | static struct pipe_buf_operations user_page_pipe_buf_ops = { |
| 173 | .can_merge = 0, | 151 | .can_merge = 0, |
| 174 | .map = user_page_pipe_buf_map, | 152 | .map = generic_pipe_buf_map, |
| 175 | .unmap = user_page_pipe_buf_unmap, | 153 | .unmap = generic_pipe_buf_unmap, |
| 154 | .pin = generic_pipe_buf_pin, | ||
| 176 | .release = page_cache_pipe_buf_release, | 155 | .release = page_cache_pipe_buf_release, |
| 177 | .steal = user_page_pipe_buf_steal, | 156 | .steal = user_page_pipe_buf_steal, |
| 178 | .get = page_cache_pipe_buf_get, | 157 | .get = generic_pipe_buf_get, |
| 179 | }; | 158 | }; |
| 180 | 159 | ||
| 181 | /* | 160 | /* |
| @@ -210,6 +189,9 @@ static ssize_t splice_to_pipe(struct pipe_inode_info *pipe, | |||
| 210 | buf->offset = spd->partial[page_nr].offset; | 189 | buf->offset = spd->partial[page_nr].offset; |
| 211 | buf->len = spd->partial[page_nr].len; | 190 | buf->len = spd->partial[page_nr].len; |
| 212 | buf->ops = spd->ops; | 191 | buf->ops = spd->ops; |
| 192 | if (spd->flags & SPLICE_F_GIFT) | ||
| 193 | buf->flags |= PIPE_BUF_FLAG_GIFT; | ||
| 194 | |||
| 213 | pipe->nrbufs++; | 195 | pipe->nrbufs++; |
| 214 | page_nr++; | 196 | page_nr++; |
| 215 | ret += buf->len; | 197 | ret += buf->len; |
| @@ -326,6 +308,12 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
| 326 | page = find_get_page(mapping, index); | 308 | page = find_get_page(mapping, index); |
| 327 | if (!page) { | 309 | if (!page) { |
| 328 | /* | 310 | /* |
| 311 | * Make sure the read-ahead engine is notified | ||
| 312 | * about this failure. | ||
| 313 | */ | ||
| 314 | handle_ra_miss(mapping, &in->f_ra, index); | ||
| 315 | |||
| 316 | /* | ||
| 329 | * page didn't exist, allocate one. | 317 | * page didn't exist, allocate one. |
| 330 | */ | 318 | */ |
| 331 | page = page_cache_alloc_cold(mapping); | 319 | page = page_cache_alloc_cold(mapping); |
| @@ -336,6 +324,8 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
| 336 | mapping_gfp_mask(mapping)); | 324 | mapping_gfp_mask(mapping)); |
| 337 | if (unlikely(error)) { | 325 | if (unlikely(error)) { |
| 338 | page_cache_release(page); | 326 | page_cache_release(page); |
| 327 | if (error == -EEXIST) | ||
| 328 | continue; | ||
| 339 | break; | 329 | break; |
| 340 | } | 330 | } |
| 341 | /* | 331 | /* |
| @@ -512,31 +502,21 @@ EXPORT_SYMBOL(generic_file_splice_read); | |||
| 512 | * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos' | 502 | * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos' |
| 513 | * using sendpage(). Return the number of bytes sent. | 503 | * using sendpage(). Return the number of bytes sent. |
| 514 | */ | 504 | */ |
| 515 | static int pipe_to_sendpage(struct pipe_inode_info *info, | 505 | static int pipe_to_sendpage(struct pipe_inode_info *pipe, |
| 516 | struct pipe_buffer *buf, struct splice_desc *sd) | 506 | struct pipe_buffer *buf, struct splice_desc *sd) |
| 517 | { | 507 | { |
| 518 | struct file *file = sd->file; | 508 | struct file *file = sd->file; |
| 519 | loff_t pos = sd->pos; | 509 | loff_t pos = sd->pos; |
| 520 | ssize_t ret; | 510 | int ret, more; |
| 521 | void *ptr; | ||
| 522 | int more; | ||
| 523 | |||
| 524 | /* | ||
| 525 | * Sub-optimal, but we are limited by the pipe ->map. We don't | ||
| 526 | * need a kmap'ed buffer here, we just want to make sure we | ||
| 527 | * have the page pinned if the pipe page originates from the | ||
| 528 | * page cache. | ||
| 529 | */ | ||
| 530 | ptr = buf->ops->map(file, info, buf); | ||
| 531 | if (IS_ERR(ptr)) | ||
| 532 | return PTR_ERR(ptr); | ||
| 533 | 511 | ||
| 534 | more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; | 512 | ret = buf->ops->pin(pipe, buf); |
| 513 | if (!ret) { | ||
| 514 | more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; | ||
| 535 | 515 | ||
| 536 | ret = file->f_op->sendpage(file, buf->page, buf->offset, sd->len, | 516 | ret = file->f_op->sendpage(file, buf->page, buf->offset, |
| 537 | &pos, more); | 517 | sd->len, &pos, more); |
| 518 | } | ||
| 538 | 519 | ||
| 539 | buf->ops->unmap(info, buf); | ||
| 540 | return ret; | 520 | return ret; |
| 541 | } | 521 | } |
| 542 | 522 | ||
| @@ -560,7 +540,7 @@ static int pipe_to_sendpage(struct pipe_inode_info *info, | |||
| 560 | * SPLICE_F_MOVE isn't set, or we cannot move the page, we simply create | 540 | * SPLICE_F_MOVE isn't set, or we cannot move the page, we simply create |
| 561 | * a new page in the output file page cache and fill/dirty that. | 541 | * a new page in the output file page cache and fill/dirty that. |
| 562 | */ | 542 | */ |
| 563 | static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, | 543 | static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, |
| 564 | struct splice_desc *sd) | 544 | struct splice_desc *sd) |
| 565 | { | 545 | { |
| 566 | struct file *file = sd->file; | 546 | struct file *file = sd->file; |
| @@ -569,15 +549,14 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, | |||
| 569 | unsigned int offset, this_len; | 549 | unsigned int offset, this_len; |
| 570 | struct page *page; | 550 | struct page *page; |
| 571 | pgoff_t index; | 551 | pgoff_t index; |
| 572 | char *src; | ||
| 573 | int ret; | 552 | int ret; |
| 574 | 553 | ||
| 575 | /* | 554 | /* |
| 576 | * make sure the data in this buffer is uptodate | 555 | * make sure the data in this buffer is uptodate |
| 577 | */ | 556 | */ |
| 578 | src = buf->ops->map(file, info, buf); | 557 | ret = buf->ops->pin(pipe, buf); |
| 579 | if (IS_ERR(src)) | 558 | if (unlikely(ret)) |
| 580 | return PTR_ERR(src); | 559 | return ret; |
| 581 | 560 | ||
| 582 | index = sd->pos >> PAGE_CACHE_SHIFT; | 561 | index = sd->pos >> PAGE_CACHE_SHIFT; |
| 583 | offset = sd->pos & ~PAGE_CACHE_MASK; | 562 | offset = sd->pos & ~PAGE_CACHE_MASK; |
| @@ -587,20 +566,25 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, | |||
| 587 | this_len = PAGE_CACHE_SIZE - offset; | 566 | this_len = PAGE_CACHE_SIZE - offset; |
| 588 | 567 | ||
| 589 | /* | 568 | /* |
| 590 | * Reuse buf page, if SPLICE_F_MOVE is set. | 569 | * Reuse buf page, if SPLICE_F_MOVE is set and we are doing a full |
| 570 | * page. | ||
| 591 | */ | 571 | */ |
| 592 | if (sd->flags & SPLICE_F_MOVE) { | 572 | if ((sd->flags & SPLICE_F_MOVE) && this_len == PAGE_CACHE_SIZE) { |
| 593 | /* | 573 | /* |
| 594 | * If steal succeeds, buf->page is now pruned from the vm | 574 | * If steal succeeds, buf->page is now pruned from the |
| 595 | * side (LRU and page cache) and we can reuse it. The page | 575 | * pagecache and we can reuse it. The page will also be |
| 596 | * will also be looked on successful return. | 576 | * locked on successful return. |
| 597 | */ | 577 | */ |
| 598 | if (buf->ops->steal(info, buf)) | 578 | if (buf->ops->steal(pipe, buf)) |
| 599 | goto find_page; | 579 | goto find_page; |
| 600 | 580 | ||
| 601 | page = buf->page; | 581 | page = buf->page; |
| 602 | if (add_to_page_cache(page, mapping, index, gfp_mask)) | 582 | if (add_to_page_cache(page, mapping, index, gfp_mask)) { |
| 583 | unlock_page(page); | ||
| 603 | goto find_page; | 584 | goto find_page; |
| 585 | } | ||
| 586 | |||
| 587 | page_cache_get(page); | ||
| 604 | 588 | ||
| 605 | if (!(buf->flags & PIPE_BUF_FLAG_LRU)) | 589 | if (!(buf->flags & PIPE_BUF_FLAG_LRU)) |
| 606 | lru_cache_add(page); | 590 | lru_cache_add(page); |
| @@ -654,40 +638,55 @@ find_page: | |||
| 654 | } | 638 | } |
| 655 | 639 | ||
| 656 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); | 640 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); |
| 657 | if (ret == AOP_TRUNCATED_PAGE) { | 641 | if (unlikely(ret)) { |
| 642 | loff_t isize = i_size_read(mapping->host); | ||
| 643 | |||
| 644 | if (ret != AOP_TRUNCATED_PAGE) | ||
| 645 | unlock_page(page); | ||
| 658 | page_cache_release(page); | 646 | page_cache_release(page); |
| 659 | goto find_page; | 647 | if (ret == AOP_TRUNCATED_PAGE) |
| 660 | } else if (ret) | 648 | goto find_page; |
| 649 | |||
| 650 | /* | ||
| 651 | * prepare_write() may have instantiated a few blocks | ||
| 652 | * outside i_size. Trim these off again. | ||
| 653 | */ | ||
| 654 | if (sd->pos + this_len > isize) | ||
| 655 | vmtruncate(mapping->host, isize); | ||
| 656 | |||
| 661 | goto out; | 657 | goto out; |
| 658 | } | ||
| 662 | 659 | ||
| 663 | if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) { | 660 | if (buf->page != page) { |
| 664 | char *dst = kmap_atomic(page, KM_USER0); | 661 | /* |
| 662 | * Careful, ->map() uses KM_USER0! | ||
| 663 | */ | ||
| 664 | char *src = buf->ops->map(pipe, buf, 1); | ||
| 665 | char *dst = kmap_atomic(page, KM_USER1); | ||
| 665 | 666 | ||
| 666 | memcpy(dst + offset, src + buf->offset, this_len); | 667 | memcpy(dst + offset, src + buf->offset, this_len); |
| 667 | flush_dcache_page(page); | 668 | flush_dcache_page(page); |
| 668 | kunmap_atomic(dst, KM_USER0); | 669 | kunmap_atomic(dst, KM_USER1); |
| 670 | buf->ops->unmap(pipe, buf, src); | ||
| 669 | } | 671 | } |
| 670 | 672 | ||
| 671 | ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len); | 673 | ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len); |
| 672 | if (ret == AOP_TRUNCATED_PAGE) { | 674 | if (!ret) { |
| 675 | /* | ||
| 676 | * Return the number of bytes written and mark page as | ||
| 677 | * accessed, we are now done! | ||
| 678 | */ | ||
| 679 | ret = this_len; | ||
| 680 | mark_page_accessed(page); | ||
| 681 | balance_dirty_pages_ratelimited(mapping); | ||
| 682 | } else if (ret == AOP_TRUNCATED_PAGE) { | ||
| 673 | page_cache_release(page); | 683 | page_cache_release(page); |
| 674 | goto find_page; | 684 | goto find_page; |
| 675 | } else if (ret) | 685 | } |
| 676 | goto out; | ||
| 677 | |||
| 678 | /* | ||
| 679 | * Return the number of bytes written. | ||
| 680 | */ | ||
| 681 | ret = this_len; | ||
| 682 | mark_page_accessed(page); | ||
| 683 | balance_dirty_pages_ratelimited(mapping); | ||
| 684 | out: | 686 | out: |
| 685 | if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) | 687 | page_cache_release(page); |
| 686 | page_cache_release(page); | ||
| 687 | |||
| 688 | unlock_page(page); | 688 | unlock_page(page); |
| 689 | out_nomem: | 689 | out_nomem: |
| 690 | buf->ops->unmap(info, buf); | ||
| 691 | return ret; | 690 | return ret; |
| 692 | } | 691 | } |
| 693 | 692 | ||
| @@ -1095,7 +1094,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
| 1095 | */ | 1094 | */ |
| 1096 | static int get_iovec_page_array(const struct iovec __user *iov, | 1095 | static int get_iovec_page_array(const struct iovec __user *iov, |
| 1097 | unsigned int nr_vecs, struct page **pages, | 1096 | unsigned int nr_vecs, struct page **pages, |
| 1098 | struct partial_page *partial) | 1097 | struct partial_page *partial, int aligned) |
| 1099 | { | 1098 | { |
| 1100 | int buffers = 0, error = 0; | 1099 | int buffers = 0, error = 0; |
| 1101 | 1100 | ||
| @@ -1135,6 +1134,15 @@ static int get_iovec_page_array(const struct iovec __user *iov, | |||
| 1135 | * in the user pages. | 1134 | * in the user pages. |
| 1136 | */ | 1135 | */ |
| 1137 | off = (unsigned long) base & ~PAGE_MASK; | 1136 | off = (unsigned long) base & ~PAGE_MASK; |
| 1137 | |||
| 1138 | /* | ||
| 1139 | * If asked for alignment, the offset must be zero and the | ||
| 1140 | * length a multiple of the PAGE_SIZE. | ||
| 1141 | */ | ||
| 1142 | error = -EINVAL; | ||
| 1143 | if (aligned && (off || len & ~PAGE_MASK)) | ||
| 1144 | break; | ||
| 1145 | |||
| 1138 | npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; | 1146 | npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; |
| 1139 | if (npages > PIPE_BUFFERS - buffers) | 1147 | if (npages > PIPE_BUFFERS - buffers) |
| 1140 | npages = PIPE_BUFFERS - buffers; | 1148 | npages = PIPE_BUFFERS - buffers; |
| @@ -1150,7 +1158,7 @@ static int get_iovec_page_array(const struct iovec __user *iov, | |||
| 1150 | * Fill this contiguous range into the partial page map. | 1158 | * Fill this contiguous range into the partial page map. |
| 1151 | */ | 1159 | */ |
| 1152 | for (i = 0; i < error; i++) { | 1160 | for (i = 0; i < error; i++) { |
| 1153 | const int plen = min_t(size_t, len, PAGE_SIZE) - off; | 1161 | const int plen = min_t(size_t, len, PAGE_SIZE - off); |
| 1154 | 1162 | ||
| 1155 | partial[buffers].offset = off; | 1163 | partial[buffers].offset = off; |
| 1156 | partial[buffers].len = plen; | 1164 | partial[buffers].len = plen; |
| @@ -1228,7 +1236,8 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov, | |||
| 1228 | else if (unlikely(!nr_segs)) | 1236 | else if (unlikely(!nr_segs)) |
| 1229 | return 0; | 1237 | return 0; |
| 1230 | 1238 | ||
| 1231 | spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial); | 1239 | spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial, |
| 1240 | flags & SPLICE_F_GIFT); | ||
| 1232 | if (spd.nr_pages <= 0) | 1241 | if (spd.nr_pages <= 0) |
| 1233 | return spd.nr_pages; | 1242 | return spd.nr_pages; |
| 1234 | 1243 | ||
| @@ -1336,6 +1345,12 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
| 1336 | obuf = opipe->bufs + nbuf; | 1345 | obuf = opipe->bufs + nbuf; |
| 1337 | *obuf = *ibuf; | 1346 | *obuf = *ibuf; |
| 1338 | 1347 | ||
| 1348 | /* | ||
| 1349 | * Don't inherit the gift flag, we need to | ||
| 1350 | * prevent multiple steals of this page. | ||
| 1351 | */ | ||
| 1352 | obuf->flags &= ~PIPE_BUF_FLAG_GIFT; | ||
| 1353 | |||
| 1339 | if (obuf->len > len) | 1354 | if (obuf->len > len) |
| 1340 | obuf->len = len; | 1355 | obuf->len = len; |
| 1341 | 1356 | ||
diff --git a/include/asm-arm/arch-imx/imx-uart.h b/include/asm-arm/arch-imx/imx-uart.h new file mode 100644 index 000000000000..3a685e1780ea --- /dev/null +++ b/include/asm-arm/arch-imx/imx-uart.h | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | #ifndef ASMARM_ARCH_UART_H | ||
| 2 | #define ASMARM_ARCH_UART_H | ||
| 3 | |||
| 4 | #define IMXUART_HAVE_RTSCTS (1<<0) | ||
| 5 | |||
| 6 | struct imxuart_platform_data { | ||
| 7 | unsigned int flags; | ||
| 8 | }; | ||
| 9 | |||
| 10 | #endif | ||
diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h index 942b622455bc..b59520e56fc7 100644 --- a/include/asm-arm/arch-ixp4xx/io.h +++ b/include/asm-arm/arch-ixp4xx/io.h | |||
| @@ -260,6 +260,12 @@ out: | |||
| 260 | 260 | ||
| 261 | #endif | 261 | #endif |
| 262 | 262 | ||
| 263 | #ifndef CONFIG_PCI | ||
| 264 | |||
| 265 | #define __io(v) v | ||
| 266 | |||
| 267 | #else | ||
| 268 | |||
| 263 | /* | 269 | /* |
| 264 | * IXP4xx does not have a transparent cpu -> PCI I/O translation | 270 | * IXP4xx does not have a transparent cpu -> PCI I/O translation |
| 265 | * window. Instead, it has a set of registers that must be tweaked | 271 | * window. Instead, it has a set of registers that must be tweaked |
| @@ -578,6 +584,7 @@ __ixp4xx_iowrite32_rep(void __iomem *addr, const void *vaddr, u32 count) | |||
| 578 | 584 | ||
| 579 | #define ioport_map(port, nr) ((void __iomem*)(port + PIO_OFFSET)) | 585 | #define ioport_map(port, nr) ((void __iomem*)(port + PIO_OFFSET)) |
| 580 | #define ioport_unmap(addr) | 586 | #define ioport_unmap(addr) |
| 587 | #endif // !CONFIG_PCI | ||
| 581 | 588 | ||
| 582 | #endif // __ASM_ARM_ARCH_IO_H | 589 | #endif // __ASM_ARM_ARCH_IO_H |
| 583 | 590 | ||
diff --git a/include/asm-arm/arch-ixp4xx/memory.h b/include/asm-arm/arch-ixp4xx/memory.h index ee211d28a3ef..af9667b57ab3 100644 --- a/include/asm-arm/arch-ixp4xx/memory.h +++ b/include/asm-arm/arch-ixp4xx/memory.h | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | */ | 14 | */ |
| 15 | #define PHYS_OFFSET UL(0x00000000) | 15 | #define PHYS_OFFSET UL(0x00000000) |
| 16 | 16 | ||
| 17 | #ifndef __ASSEMBLY__ | 17 | #if !defined(__ASSEMBLY__) && defined(CONFIG_PCI) |
| 18 | 18 | ||
| 19 | void ixp4xx_adjust_zones(int node, unsigned long *size, unsigned long *holes); | 19 | void ixp4xx_adjust_zones(int node, unsigned long *size, unsigned long *holes); |
| 20 | 20 | ||
diff --git a/include/asm-arm/arch-pxa/dma.h b/include/asm-arm/arch-pxa/dma.h index 3e88a2a02a0f..a008150abc59 100644 --- a/include/asm-arm/arch-pxa/dma.h +++ b/include/asm-arm/arch-pxa/dma.h | |||
| @@ -24,27 +24,29 @@ typedef struct pxa_dma_desc { | |||
| 24 | volatile u32 dcmd; /* DCMD value for the current transfer */ | 24 | volatile u32 dcmd; /* DCMD value for the current transfer */ |
| 25 | } pxa_dma_desc; | 25 | } pxa_dma_desc; |
| 26 | 26 | ||
| 27 | typedef enum { | ||
| 28 | DMA_PRIO_HIGH = 0, | ||
| 29 | DMA_PRIO_MEDIUM = 1, | ||
| 30 | DMA_PRIO_LOW = 2 | ||
| 31 | } pxa_dma_prio; | ||
| 32 | |||
| 27 | #if defined(CONFIG_PXA27x) | 33 | #if defined(CONFIG_PXA27x) |
| 28 | 34 | ||
| 29 | #define PXA_DMA_CHANNELS 32 | 35 | #define PXA_DMA_CHANNELS 32 |
| 30 | #define PXA_DMA_NBCH(prio) ((prio == DMA_PRIO_LOW) ? 16 : 8) | ||
| 31 | 36 | ||
| 32 | typedef enum { | 37 | #define pxa_for_each_dma_prio(ch, prio) \ |
| 33 | DMA_PRIO_HIGH = 0, | 38 | for ( \ |
| 34 | DMA_PRIO_MEDIUM = 8, | 39 | ch = prio * 4; \ |
| 35 | DMA_PRIO_LOW = 16 | 40 | ch != (4 << prio) + 16; \ |
| 36 | } pxa_dma_prio; | 41 | ch = (ch + 1 == (4 << prio)) ? (prio * 4 + 16) : (ch + 1) \ |
| 42 | ) | ||
| 37 | 43 | ||
| 38 | #elif defined(CONFIG_PXA25x) | 44 | #elif defined(CONFIG_PXA25x) |
| 39 | 45 | ||
| 40 | #define PXA_DMA_CHANNELS 16 | 46 | #define PXA_DMA_CHANNELS 16 |
| 41 | #define PXA_DMA_NBCH(prio) ((prio == DMA_PRIO_LOW) ? 8 : 4) | ||
| 42 | 47 | ||
| 43 | typedef enum { | 48 | #define pxa_for_each_dma_prio(ch, prio) \ |
| 44 | DMA_PRIO_HIGH = 0, | 49 | for (ch = prio * 4; ch != (4 << prio); ch++) |
| 45 | DMA_PRIO_MEDIUM = 4, | ||
| 46 | DMA_PRIO_LOW = 8 | ||
| 47 | } pxa_dma_prio; | ||
| 48 | 50 | ||
| 49 | #endif | 51 | #endif |
| 50 | 52 | ||
diff --git a/include/asm-arm/bug.h b/include/asm-arm/bug.h index 0e36fd5d87df..7fb02138f585 100644 --- a/include/asm-arm/bug.h +++ b/include/asm-arm/bug.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #ifndef _ASMARM_BUG_H | 1 | #ifndef _ASMARM_BUG_H |
| 2 | #define _ASMARM_BUG_H | 2 | #define _ASMARM_BUG_H |
| 3 | 3 | ||
| 4 | #include <linux/config.h> | ||
| 4 | 5 | ||
| 5 | #ifdef CONFIG_BUG | 6 | #ifdef CONFIG_BUG |
| 6 | #ifdef CONFIG_DEBUG_BUGVERBOSE | 7 | #ifdef CONFIG_DEBUG_BUGVERBOSE |
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h index a5896d94e1ad..1e891f860ef3 100644 --- a/include/asm-arm/unistd.h +++ b/include/asm-arm/unistd.h | |||
| @@ -361,7 +361,7 @@ | |||
| 361 | /* | 361 | /* |
| 362 | * The following syscalls are obsolete and no longer available for EABI. | 362 | * The following syscalls are obsolete and no longer available for EABI. |
| 363 | */ | 363 | */ |
| 364 | #if defined(__ARM_EABI__) | 364 | #if defined(__ARM_EABI__) && !defined(__KERNEL__) |
| 365 | #undef __NR_time | 365 | #undef __NR_time |
| 366 | #undef __NR_umount | 366 | #undef __NR_umount |
| 367 | #undef __NR_stime | 367 | #undef __NR_stime |
| @@ -411,7 +411,8 @@ type name(void) { \ | |||
| 411 | __asm__ __volatile__ ( \ | 411 | __asm__ __volatile__ ( \ |
| 412 | __syscall(name) \ | 412 | __syscall(name) \ |
| 413 | : "=r" (__res_r0) \ | 413 | : "=r" (__res_r0) \ |
| 414 | : __SYS_REG_LIST() ); \ | 414 | : __SYS_REG_LIST() \ |
| 415 | : "memory" ); \ | ||
| 415 | __res = __res_r0; \ | 416 | __res = __res_r0; \ |
| 416 | __syscall_return(type,__res); \ | 417 | __syscall_return(type,__res); \ |
| 417 | } | 418 | } |
| @@ -425,7 +426,8 @@ type name(type1 arg1) { \ | |||
| 425 | __asm__ __volatile__ ( \ | 426 | __asm__ __volatile__ ( \ |
| 426 | __syscall(name) \ | 427 | __syscall(name) \ |
| 427 | : "=r" (__res_r0) \ | 428 | : "=r" (__res_r0) \ |
| 428 | : __SYS_REG_LIST( "0" (__r0) ) ); \ | 429 | : __SYS_REG_LIST( "0" (__r0) ) \ |
| 430 | : "memory" ); \ | ||
| 429 | __res = __res_r0; \ | 431 | __res = __res_r0; \ |
| 430 | __syscall_return(type,__res); \ | 432 | __syscall_return(type,__res); \ |
| 431 | } | 433 | } |
| @@ -440,7 +442,8 @@ type name(type1 arg1,type2 arg2) { \ | |||
| 440 | __asm__ __volatile__ ( \ | 442 | __asm__ __volatile__ ( \ |
| 441 | __syscall(name) \ | 443 | __syscall(name) \ |
| 442 | : "=r" (__res_r0) \ | 444 | : "=r" (__res_r0) \ |
| 443 | : __SYS_REG_LIST( "0" (__r0), "r" (__r1) ) ); \ | 445 | : __SYS_REG_LIST( "0" (__r0), "r" (__r1) ) \ |
| 446 | : "memory" ); \ | ||
| 444 | __res = __res_r0; \ | 447 | __res = __res_r0; \ |
| 445 | __syscall_return(type,__res); \ | 448 | __syscall_return(type,__res); \ |
| 446 | } | 449 | } |
| @@ -457,7 +460,8 @@ type name(type1 arg1,type2 arg2,type3 arg3) { \ | |||
| 457 | __asm__ __volatile__ ( \ | 460 | __asm__ __volatile__ ( \ |
| 458 | __syscall(name) \ | 461 | __syscall(name) \ |
| 459 | : "=r" (__res_r0) \ | 462 | : "=r" (__res_r0) \ |
| 460 | : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2) ) ); \ | 463 | : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2) ) \ |
| 464 | : "memory" ); \ | ||
| 461 | __res = __res_r0; \ | 465 | __res = __res_r0; \ |
| 462 | __syscall_return(type,__res); \ | 466 | __syscall_return(type,__res); \ |
| 463 | } | 467 | } |
| @@ -475,7 +479,8 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ | |||
| 475 | __asm__ __volatile__ ( \ | 479 | __asm__ __volatile__ ( \ |
| 476 | __syscall(name) \ | 480 | __syscall(name) \ |
| 477 | : "=r" (__res_r0) \ | 481 | : "=r" (__res_r0) \ |
| 478 | : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) ) ); \ | 482 | : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) ) \ |
| 483 | : "memory" ); \ | ||
| 479 | __res = __res_r0; \ | 484 | __res = __res_r0; \ |
| 480 | __syscall_return(type,__res); \ | 485 | __syscall_return(type,__res); \ |
| 481 | } | 486 | } |
| @@ -495,7 +500,8 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \ | |||
| 495 | __syscall(name) \ | 500 | __syscall(name) \ |
| 496 | : "=r" (__res_r0) \ | 501 | : "=r" (__res_r0) \ |
| 497 | : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \ | 502 | : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \ |
| 498 | "r" (__r3), "r" (__r4) ) ); \ | 503 | "r" (__r3), "r" (__r4) ) \ |
| 504 | : "memory" ); \ | ||
| 499 | __res = __res_r0; \ | 505 | __res = __res_r0; \ |
| 500 | __syscall_return(type,__res); \ | 506 | __syscall_return(type,__res); \ |
| 501 | } | 507 | } |
| @@ -515,7 +521,8 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6 | |||
| 515 | __syscall(name) \ | 521 | __syscall(name) \ |
| 516 | : "=r" (__res_r0) \ | 522 | : "=r" (__res_r0) \ |
| 517 | : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \ | 523 | : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \ |
| 518 | "r" (__r3), "r" (__r4), "r" (__r5) ) ); \ | 524 | "r" (__r3), "r" (__r4), "r" (__r5) ) \ |
| 525 | : "memory" ); \ | ||
| 519 | __res = __res_r0; \ | 526 | __res = __res_r0; \ |
| 520 | __syscall_return(type,__res); \ | 527 | __syscall_return(type,__res); \ |
| 521 | } | 528 | } |
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h index fb519a1e49bd..95713f397357 100644 --- a/include/asm-powerpc/spu.h +++ b/include/asm-powerpc/spu.h | |||
| @@ -116,6 +116,7 @@ struct spu { | |||
| 116 | struct list_head list; | 116 | struct list_head list; |
| 117 | struct list_head sched_list; | 117 | struct list_head sched_list; |
| 118 | int number; | 118 | int number; |
| 119 | int nid; | ||
| 119 | u32 isrc; | 120 | u32 isrc; |
| 120 | u32 node; | 121 | u32 node; |
| 121 | u64 flags; | 122 | u64 flags; |
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h index 4cf340ccb4cd..19c575f39164 100644 --- a/include/asm-powerpc/topology.h +++ b/include/asm-powerpc/topology.h | |||
| @@ -3,6 +3,9 @@ | |||
| 3 | #ifdef __KERNEL__ | 3 | #ifdef __KERNEL__ |
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | struct sys_device; | ||
| 7 | struct device_node; | ||
| 8 | |||
| 6 | #ifdef CONFIG_NUMA | 9 | #ifdef CONFIG_NUMA |
| 7 | 10 | ||
| 8 | #include <asm/mmzone.h> | 11 | #include <asm/mmzone.h> |
| @@ -26,6 +29,8 @@ static inline int node_to_first_cpu(int node) | |||
| 26 | return first_cpu(tmp); | 29 | return first_cpu(tmp); |
| 27 | } | 30 | } |
| 28 | 31 | ||
| 32 | int of_node_to_nid(struct device_node *device); | ||
| 33 | |||
| 29 | #define pcibus_to_node(node) (-1) | 34 | #define pcibus_to_node(node) (-1) |
| 30 | #define pcibus_to_cpumask(bus) (cpu_online_map) | 35 | #define pcibus_to_cpumask(bus) (cpu_online_map) |
| 31 | 36 | ||
| @@ -56,10 +61,29 @@ static inline int node_to_first_cpu(int node) | |||
| 56 | 61 | ||
| 57 | extern void __init dump_numa_cpu_topology(void); | 62 | extern void __init dump_numa_cpu_topology(void); |
| 58 | 63 | ||
| 64 | extern int sysfs_add_device_to_node(struct sys_device *dev, int nid); | ||
| 65 | extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid); | ||
| 66 | |||
| 59 | #else | 67 | #else |
| 60 | 68 | ||
| 69 | static inline int of_node_to_nid(struct device_node *device) | ||
| 70 | { | ||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | |||
| 61 | static inline void dump_numa_cpu_topology(void) {} | 74 | static inline void dump_numa_cpu_topology(void) {} |
| 62 | 75 | ||
| 76 | static inline int sysfs_add_device_to_node(struct sys_device *dev, int nid) | ||
| 77 | { | ||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 81 | static inline void sysfs_remove_device_from_node(struct sys_device *dev, | ||
| 82 | int nid) | ||
| 83 | { | ||
| 84 | } | ||
| 85 | |||
| 86 | |||
| 63 | #include <asm-generic/topology.h> | 87 | #include <asm-generic/topology.h> |
| 64 | 88 | ||
| 65 | #endif /* CONFIG_NUMA */ | 89 | #endif /* CONFIG_NUMA */ |
diff --git a/include/asm-powerpc/uaccess.h b/include/asm-powerpc/uaccess.h index 3872e924cdd6..d83fc29c2bbf 100644 --- a/include/asm-powerpc/uaccess.h +++ b/include/asm-powerpc/uaccess.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
| 8 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
| 9 | #include <asm/processor.h> | 9 | #include <asm/processor.h> |
| 10 | #include <asm/page.h> | ||
| 10 | 11 | ||
| 11 | #define VERIFY_READ 0 | 12 | #define VERIFY_READ 0 |
| 12 | #define VERIFY_WRITE 1 | 13 | #define VERIFY_WRITE 1 |
| @@ -179,9 +180,11 @@ do { \ | |||
| 179 | #define __put_user_nocheck(x, ptr, size) \ | 180 | #define __put_user_nocheck(x, ptr, size) \ |
| 180 | ({ \ | 181 | ({ \ |
| 181 | long __pu_err; \ | 182 | long __pu_err; \ |
| 182 | might_sleep(); \ | 183 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ |
| 184 | if (!is_kernel_addr((unsigned long)__pu_addr)) \ | ||
| 185 | might_sleep(); \ | ||
| 183 | __chk_user_ptr(ptr); \ | 186 | __chk_user_ptr(ptr); \ |
| 184 | __put_user_size((x), (ptr), (size), __pu_err); \ | 187 | __put_user_size((x), __pu_addr, (size), __pu_err); \ |
| 185 | __pu_err; \ | 188 | __pu_err; \ |
| 186 | }) | 189 | }) |
| 187 | 190 | ||
| @@ -258,9 +261,11 @@ do { \ | |||
| 258 | ({ \ | 261 | ({ \ |
| 259 | long __gu_err; \ | 262 | long __gu_err; \ |
| 260 | unsigned long __gu_val; \ | 263 | unsigned long __gu_val; \ |
| 264 | const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ | ||
| 261 | __chk_user_ptr(ptr); \ | 265 | __chk_user_ptr(ptr); \ |
| 262 | might_sleep(); \ | 266 | if (!is_kernel_addr((unsigned long)__gu_addr)) \ |
| 263 | __get_user_size(__gu_val, (ptr), (size), __gu_err); \ | 267 | might_sleep(); \ |
| 268 | __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ | ||
| 264 | (x) = (__typeof__(*(ptr)))__gu_val; \ | 269 | (x) = (__typeof__(*(ptr)))__gu_val; \ |
| 265 | __gu_err; \ | 270 | __gu_err; \ |
| 266 | }) | 271 | }) |
| @@ -270,9 +275,11 @@ do { \ | |||
| 270 | ({ \ | 275 | ({ \ |
| 271 | long __gu_err; \ | 276 | long __gu_err; \ |
| 272 | long long __gu_val; \ | 277 | long long __gu_val; \ |
| 278 | const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ | ||
| 273 | __chk_user_ptr(ptr); \ | 279 | __chk_user_ptr(ptr); \ |
| 274 | might_sleep(); \ | 280 | if (!is_kernel_addr((unsigned long)__gu_addr)) \ |
| 275 | __get_user_size(__gu_val, (ptr), (size), __gu_err); \ | 281 | might_sleep(); \ |
| 282 | __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ | ||
| 276 | (x) = (__typeof__(*(ptr)))__gu_val; \ | 283 | (x) = (__typeof__(*(ptr)))__gu_val; \ |
| 277 | __gu_err; \ | 284 | __gu_err; \ |
| 278 | }) | 285 | }) |
diff --git a/include/asm-ppc/commproc.h b/include/asm-ppc/commproc.h index 64a2623def02..3247bea5fc2b 100644 --- a/include/asm-ppc/commproc.h +++ b/include/asm-ppc/commproc.h | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #define CPM_CR_INIT_TX ((ushort)0x0002) | 34 | #define CPM_CR_INIT_TX ((ushort)0x0002) |
| 35 | #define CPM_CR_HUNT_MODE ((ushort)0x0003) | 35 | #define CPM_CR_HUNT_MODE ((ushort)0x0003) |
| 36 | #define CPM_CR_STOP_TX ((ushort)0x0004) | 36 | #define CPM_CR_STOP_TX ((ushort)0x0004) |
| 37 | #define CPM_CR_GRA_STOP_TX ((ushort)0x0005) | ||
| 37 | #define CPM_CR_RESTART_TX ((ushort)0x0006) | 38 | #define CPM_CR_RESTART_TX ((ushort)0x0006) |
| 38 | #define CPM_CR_CLOSE_RX_BD ((ushort)0x0007) | 39 | #define CPM_CR_CLOSE_RX_BD ((ushort)0x0007) |
| 39 | #define CPM_CR_SET_GADDR ((ushort)0x0008) | 40 | #define CPM_CR_SET_GADDR ((ushort)0x0008) |
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h index b638b87cebe3..c70344b91049 100644 --- a/include/asm-ppc/cpm2.h +++ b/include/asm-ppc/cpm2.h | |||
| @@ -69,7 +69,7 @@ | |||
| 69 | #define CPM_CR_INIT_TX ((ushort)0x0002) | 69 | #define CPM_CR_INIT_TX ((ushort)0x0002) |
| 70 | #define CPM_CR_HUNT_MODE ((ushort)0x0003) | 70 | #define CPM_CR_HUNT_MODE ((ushort)0x0003) |
| 71 | #define CPM_CR_STOP_TX ((ushort)0x0004) | 71 | #define CPM_CR_STOP_TX ((ushort)0x0004) |
| 72 | #define CPM_CR_GRA_STOP_TX ((ushort)0x0005) | 72 | #define CPM_CR_GRA_STOP_TX ((ushort)0x0005) |
| 73 | #define CPM_CR_RESTART_TX ((ushort)0x0006) | 73 | #define CPM_CR_RESTART_TX ((ushort)0x0006) |
| 74 | #define CPM_CR_SET_GADDR ((ushort)0x0008) | 74 | #define CPM_CR_SET_GADDR ((ushort)0x0008) |
| 75 | #define CPM_CR_START_IDMA ((ushort)0x0009) | 75 | #define CPM_CR_START_IDMA ((ushort)0x0009) |
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 7bd5a7dd6781..5489c5a3c777 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | #define __NR_capset 22 /* Linux Specific */ | 41 | #define __NR_capset 22 /* Linux Specific */ |
| 42 | #define __NR_setuid 23 /* Implemented via setreuid in SunOS */ | 42 | #define __NR_setuid 23 /* Implemented via setreuid in SunOS */ |
| 43 | #define __NR_getuid 24 /* Common */ | 43 | #define __NR_getuid 24 /* Common */ |
| 44 | /* #define __NR_time alias 25 ENOSYS under SunOS */ | 44 | #define __NR_vmsplice 25 /* ENOSYS under SunOS */ |
| 45 | #define __NR_ptrace 26 /* Common */ | 45 | #define __NR_ptrace 26 /* Common */ |
| 46 | #define __NR_alarm 27 /* Implemented via setitimer in SunOS */ | 46 | #define __NR_alarm 27 /* Implemented via setitimer in SunOS */ |
| 47 | #define __NR_sigaltstack 28 /* Common */ | 47 | #define __NR_sigaltstack 28 /* Common */ |
diff --git a/include/asm-sparc64/tlbflush.h b/include/asm-sparc64/tlbflush.h index 0386014ecf27..3487328570ed 100644 --- a/include/asm-sparc64/tlbflush.h +++ b/include/asm-sparc64/tlbflush.h | |||
| @@ -21,8 +21,6 @@ extern void flush_tlb_pending(void); | |||
| 21 | /* Local cpu only. */ | 21 | /* Local cpu only. */ |
| 22 | extern void __flush_tlb_all(void); | 22 | extern void __flush_tlb_all(void); |
| 23 | 23 | ||
| 24 | extern void __flush_tlb_page(unsigned long context, unsigned long page, unsigned long r); | ||
| 25 | |||
| 26 | extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end); | 24 | extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end); |
| 27 | 25 | ||
| 28 | #ifndef CONFIG_SMP | 26 | #ifndef CONFIG_SMP |
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 18f7b1a2517c..a73b7ce1a042 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | #define __NR_capset 22 /* Linux Specific */ | 41 | #define __NR_capset 22 /* Linux Specific */ |
| 42 | #define __NR_setuid 23 /* Implemented via setreuid in SunOS */ | 42 | #define __NR_setuid 23 /* Implemented via setreuid in SunOS */ |
| 43 | #define __NR_getuid 24 /* Common */ | 43 | #define __NR_getuid 24 /* Common */ |
| 44 | /* #define __NR_time alias 25 ENOSYS under SunOS */ | 44 | #define __NR_vmsplice 25 /* ENOSYS under SunOS */ |
| 45 | #define __NR_ptrace 26 /* Common */ | 45 | #define __NR_ptrace 26 /* Common */ |
| 46 | #define __NR_alarm 27 /* Implemented via setitimer in SunOS */ | 46 | #define __NR_alarm 27 /* Implemented via setitimer in SunOS */ |
| 47 | #define __NR_sigaltstack 28 /* Common */ | 47 | #define __NR_sigaltstack 28 /* Common */ |
diff --git a/include/linux/audit.h b/include/linux/audit.h index 319975532943..14259f6db5bc 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
| @@ -82,6 +82,7 @@ | |||
| 82 | #define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */ | 82 | #define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */ |
| 83 | #define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */ | 83 | #define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */ |
| 84 | #define AUDIT_CWD 1307 /* Current working directory */ | 84 | #define AUDIT_CWD 1307 /* Current working directory */ |
| 85 | #define AUDIT_IPC_SET_PERM 1311 /* IPC new permissions record type */ | ||
| 85 | 86 | ||
| 86 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ | 87 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ |
| 87 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ | 88 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ |
| @@ -144,6 +145,11 @@ | |||
| 144 | #define AUDIT_PERS 10 | 145 | #define AUDIT_PERS 10 |
| 145 | #define AUDIT_ARCH 11 | 146 | #define AUDIT_ARCH 11 |
| 146 | #define AUDIT_MSGTYPE 12 | 147 | #define AUDIT_MSGTYPE 12 |
| 148 | #define AUDIT_SE_USER 13 /* security label user */ | ||
| 149 | #define AUDIT_SE_ROLE 14 /* security label role */ | ||
| 150 | #define AUDIT_SE_TYPE 15 /* security label type */ | ||
| 151 | #define AUDIT_SE_SEN 16 /* security label sensitivity label */ | ||
| 152 | #define AUDIT_SE_CLR 17 /* security label clearance label */ | ||
| 147 | 153 | ||
| 148 | /* These are ONLY useful when checking | 154 | /* These are ONLY useful when checking |
| 149 | * at syscall exit time (AUDIT_AT_EXIT). */ | 155 | * at syscall exit time (AUDIT_AT_EXIT). */ |
| @@ -287,10 +293,10 @@ struct netlink_skb_parms; | |||
| 287 | /* Public API */ | 293 | /* Public API */ |
| 288 | extern int audit_alloc(struct task_struct *task); | 294 | extern int audit_alloc(struct task_struct *task); |
| 289 | extern void audit_free(struct task_struct *task); | 295 | extern void audit_free(struct task_struct *task); |
| 290 | extern void audit_syscall_entry(struct task_struct *task, int arch, | 296 | extern void audit_syscall_entry(int arch, |
| 291 | int major, unsigned long a0, unsigned long a1, | 297 | int major, unsigned long a0, unsigned long a1, |
| 292 | unsigned long a2, unsigned long a3); | 298 | unsigned long a2, unsigned long a3); |
| 293 | extern void audit_syscall_exit(struct task_struct *task, int failed, long return_code); | 299 | extern void audit_syscall_exit(int failed, long return_code); |
| 294 | extern void audit_getname(const char *name); | 300 | extern void audit_getname(const char *name); |
| 295 | extern void audit_putname(const char *name); | 301 | extern void audit_putname(const char *name); |
| 296 | extern void __audit_inode(const char *name, const struct inode *inode, unsigned flags); | 302 | extern void __audit_inode(const char *name, const struct inode *inode, unsigned flags); |
| @@ -314,7 +320,8 @@ extern void auditsc_get_stamp(struct audit_context *ctx, | |||
| 314 | struct timespec *t, unsigned int *serial); | 320 | struct timespec *t, unsigned int *serial); |
| 315 | extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); | 321 | extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); |
| 316 | extern uid_t audit_get_loginuid(struct audit_context *ctx); | 322 | extern uid_t audit_get_loginuid(struct audit_context *ctx); |
| 317 | extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp); | 323 | extern int audit_ipc_obj(struct kern_ipc_perm *ipcp); |
| 324 | extern int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp); | ||
| 318 | extern int audit_socketcall(int nargs, unsigned long *args); | 325 | extern int audit_socketcall(int nargs, unsigned long *args); |
| 319 | extern int audit_sockaddr(int len, void *addr); | 326 | extern int audit_sockaddr(int len, void *addr); |
| 320 | extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); | 327 | extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); |
| @@ -323,8 +330,8 @@ extern int audit_set_macxattr(const char *name); | |||
| 323 | #else | 330 | #else |
| 324 | #define audit_alloc(t) ({ 0; }) | 331 | #define audit_alloc(t) ({ 0; }) |
| 325 | #define audit_free(t) do { ; } while (0) | 332 | #define audit_free(t) do { ; } while (0) |
| 326 | #define audit_syscall_entry(t,ta,a,b,c,d,e) do { ; } while (0) | 333 | #define audit_syscall_entry(ta,a,b,c,d,e) do { ; } while (0) |
| 327 | #define audit_syscall_exit(t,f,r) do { ; } while (0) | 334 | #define audit_syscall_exit(f,r) do { ; } while (0) |
| 328 | #define audit_getname(n) do { ; } while (0) | 335 | #define audit_getname(n) do { ; } while (0) |
| 329 | #define audit_putname(n) do { ; } while (0) | 336 | #define audit_putname(n) do { ; } while (0) |
| 330 | #define __audit_inode(n,i,f) do { ; } while (0) | 337 | #define __audit_inode(n,i,f) do { ; } while (0) |
| @@ -333,7 +340,8 @@ extern int audit_set_macxattr(const char *name); | |||
| 333 | #define audit_inode_child(d,i,p) do { ; } while (0) | 340 | #define audit_inode_child(d,i,p) do { ; } while (0) |
| 334 | #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0) | 341 | #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0) |
| 335 | #define audit_get_loginuid(c) ({ -1; }) | 342 | #define audit_get_loginuid(c) ({ -1; }) |
| 336 | #define audit_ipc_perms(q,u,g,m,i) ({ 0; }) | 343 | #define audit_ipc_obj(i) ({ 0; }) |
| 344 | #define audit_ipc_set_perm(q,u,g,m,i) ({ 0; }) | ||
| 337 | #define audit_socketcall(n,a) ({ 0; }) | 345 | #define audit_socketcall(n,a) ({ 0; }) |
| 338 | #define audit_sockaddr(len, addr) ({ 0; }) | 346 | #define audit_sockaddr(len, addr) ({ 0; }) |
| 339 | #define audit_avc_path(dentry, mnt) ({ 0; }) | 347 | #define audit_avc_path(dentry, mnt) ({ 0; }) |
| @@ -366,7 +374,7 @@ extern void audit_log_d_path(struct audit_buffer *ab, | |||
| 366 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); | 374 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); |
| 367 | extern int audit_filter_type(int type); | 375 | extern int audit_filter_type(int type); |
| 368 | extern int audit_receive_filter(int type, int pid, int uid, int seq, | 376 | extern int audit_receive_filter(int type, int pid, int uid, int seq, |
| 369 | void *data, size_t datasz, uid_t loginuid); | 377 | void *data, size_t datasz, uid_t loginuid, u32 sid); |
| 370 | #else | 378 | #else |
| 371 | #define audit_log(c,g,t,f,...) do { ; } while (0) | 379 | #define audit_log(c,g,t,f,...) do { ; } while (0) |
| 372 | #define audit_log_start(c,g,t) ({ NULL; }) | 380 | #define audit_log_start(c,g,t) ({ NULL; }) |
diff --git a/include/linux/fs_uart_pd.h b/include/linux/fs_uart_pd.h new file mode 100644 index 000000000000..f5975126b712 --- /dev/null +++ b/include/linux/fs_uart_pd.h | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /* | ||
| 2 | * Platform information definitions for the CPM Uart driver. | ||
| 3 | * | ||
| 4 | * 2006 (c) MontaVista Software, Inc. | ||
| 5 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
| 6 | * | ||
| 7 | * This file is licensed under the terms of the GNU General Public License | ||
| 8 | * version 2. This program is licensed "as is" without any warranty of any | ||
| 9 | * kind, whether express or implied. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef FS_UART_PD_H | ||
| 13 | #define FS_UART_PD_H | ||
| 14 | |||
| 15 | #include <linux/version.h> | ||
| 16 | #include <asm/types.h> | ||
| 17 | |||
| 18 | enum fs_uart_id { | ||
| 19 | fsid_smc1_uart, | ||
| 20 | fsid_smc2_uart, | ||
| 21 | fsid_scc1_uart, | ||
| 22 | fsid_scc2_uart, | ||
| 23 | fsid_scc3_uart, | ||
| 24 | fsid_scc4_uart, | ||
| 25 | fs_uart_nr, | ||
| 26 | }; | ||
| 27 | |||
| 28 | static inline int fs_uart_id_scc2fsid(int id) | ||
| 29 | { | ||
| 30 | return fsid_scc1_uart + id - 1; | ||
| 31 | } | ||
| 32 | |||
| 33 | static inline int fs_uart_id_fsid2scc(int id) | ||
| 34 | { | ||
| 35 | return id - fsid_scc1_uart + 1; | ||
| 36 | } | ||
| 37 | |||
| 38 | static inline int fs_uart_id_smc2fsid(int id) | ||
| 39 | { | ||
| 40 | return fsid_smc1_uart + id - 1; | ||
| 41 | } | ||
| 42 | |||
| 43 | static inline int fs_uart_id_fsid2smc(int id) | ||
| 44 | { | ||
| 45 | return id - fsid_smc1_uart + 1; | ||
| 46 | } | ||
| 47 | |||
| 48 | struct fs_uart_platform_info { | ||
| 49 | void(*init_ioports)(void); | ||
| 50 | /* device specific information */ | ||
| 51 | int fs_no; /* controller index */ | ||
| 52 | u32 uart_clk; | ||
| 53 | u8 tx_num_fifo; | ||
| 54 | u8 tx_buf_size; | ||
| 55 | u8 rx_num_fifo; | ||
| 56 | u8 rx_buf_size; | ||
| 57 | u8 brg; | ||
| 58 | }; | ||
| 59 | |||
| 60 | #endif | ||
diff --git a/include/linux/list.h b/include/linux/list.h index 67258b47e9ca..76f05718342c 100644 --- a/include/linux/list.h +++ b/include/linux/list.h | |||
| @@ -619,7 +619,7 @@ static inline void hlist_del_rcu(struct hlist_node *n) | |||
| 619 | 619 | ||
| 620 | static inline void hlist_del_init(struct hlist_node *n) | 620 | static inline void hlist_del_init(struct hlist_node *n) |
| 621 | { | 621 | { |
| 622 | if (n->pprev) { | 622 | if (!hlist_unhashed(n)) { |
| 623 | __hlist_del(n); | 623 | __hlist_del(n); |
| 624 | INIT_HLIST_NODE(n); | 624 | INIT_HLIST_NODE(n); |
| 625 | } | 625 | } |
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 30dd978c1ec8..991a37382a22 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
| @@ -28,6 +28,7 @@ struct mmc_csd { | |||
| 28 | unsigned short cmdclass; | 28 | unsigned short cmdclass; |
| 29 | unsigned short tacc_clks; | 29 | unsigned short tacc_clks; |
| 30 | unsigned int tacc_ns; | 30 | unsigned int tacc_ns; |
| 31 | unsigned int r2w_factor; | ||
| 31 | unsigned int max_dtr; | 32 | unsigned int max_dtr; |
| 32 | unsigned int read_blkbits; | 33 | unsigned int read_blkbits; |
| 33 | unsigned int write_blkbits; | 34 | unsigned int write_blkbits; |
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 38701454e197..48cc32d83f77 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h | |||
| @@ -337,6 +337,10 @@ struct compat_xt_entry_match | |||
| 337 | char name[XT_FUNCTION_MAXNAMELEN - 1]; | 337 | char name[XT_FUNCTION_MAXNAMELEN - 1]; |
| 338 | u_int8_t revision; | 338 | u_int8_t revision; |
| 339 | } user; | 339 | } user; |
| 340 | struct { | ||
| 341 | u_int16_t match_size; | ||
| 342 | compat_uptr_t match; | ||
| 343 | } kernel; | ||
| 340 | u_int16_t match_size; | 344 | u_int16_t match_size; |
| 341 | } u; | 345 | } u; |
| 342 | unsigned char data[0]; | 346 | unsigned char data[0]; |
| @@ -350,6 +354,10 @@ struct compat_xt_entry_target | |||
| 350 | char name[XT_FUNCTION_MAXNAMELEN - 1]; | 354 | char name[XT_FUNCTION_MAXNAMELEN - 1]; |
| 351 | u_int8_t revision; | 355 | u_int8_t revision; |
| 352 | } user; | 356 | } user; |
| 357 | struct { | ||
| 358 | u_int16_t target_size; | ||
| 359 | compat_uptr_t target; | ||
| 360 | } kernel; | ||
| 353 | u_int16_t target_size; | 361 | u_int16_t target_size; |
| 354 | } u; | 362 | } u; |
| 355 | unsigned char data[0]; | 363 | unsigned char data[0]; |
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_helper_h323_asn1.h b/include/linux/netfilter_ipv4/ip_conntrack_helper_h323_asn1.h index 0bd828081c0c..c6e9a0b6d30b 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_helper_h323_asn1.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_helper_h323_asn1.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * ip_conntrack_helper_h323_asn1.h - BER and PER decoding library for H.323 | 2 | * ip_conntrack_helper_h323_asn1.h - BER and PER decoding library for H.323 |
| 3 | * conntrack/NAT module. | 3 | * conntrack/NAT module. |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@hotmail.com> | 5 | * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net> |
| 6 | * | 6 | * |
| 7 | * This source code is licensed under General Public License version 2. | 7 | * This source code is licensed under General Public License version 2. |
| 8 | * | 8 | * |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index f8f3d1c927f8..87b8a5703ebc 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
| @@ -143,6 +143,7 @@ struct netlink_skb_parms | |||
| 143 | __u32 dst_group; | 143 | __u32 dst_group; |
| 144 | kernel_cap_t eff_cap; | 144 | kernel_cap_t eff_cap; |
| 145 | __u32 loginuid; /* Login (audit) uid */ | 145 | __u32 loginuid; /* Login (audit) uid */ |
| 146 | __u32 sid; /* SELinux security id */ | ||
| 146 | }; | 147 | }; |
| 147 | 148 | ||
| 148 | #define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb)) | 149 | #define NETLINK_CB(skb) (*(struct netlink_skb_parms*)&((skb)->cb)) |
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 0008d4bd4059..ea4f7cd7bfd8 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h | |||
| @@ -5,8 +5,9 @@ | |||
| 5 | 5 | ||
| 6 | #define PIPE_BUFFERS (16) | 6 | #define PIPE_BUFFERS (16) |
| 7 | 7 | ||
| 8 | #define PIPE_BUF_FLAG_STOLEN 0x01 | 8 | #define PIPE_BUF_FLAG_LRU 0x01 /* page is on the LRU */ |
| 9 | #define PIPE_BUF_FLAG_LRU 0x02 | 9 | #define PIPE_BUF_FLAG_ATOMIC 0x02 /* was atomically mapped */ |
| 10 | #define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */ | ||
| 10 | 11 | ||
| 11 | struct pipe_buffer { | 12 | struct pipe_buffer { |
| 12 | struct page *page; | 13 | struct page *page; |
| @@ -15,10 +16,23 @@ struct pipe_buffer { | |||
| 15 | unsigned int flags; | 16 | unsigned int flags; |
| 16 | }; | 17 | }; |
| 17 | 18 | ||
| 19 | /* | ||
| 20 | * Note on the nesting of these functions: | ||
| 21 | * | ||
| 22 | * ->pin() | ||
| 23 | * ->steal() | ||
| 24 | * ... | ||
| 25 | * ->map() | ||
| 26 | * ... | ||
| 27 | * ->unmap() | ||
| 28 | * | ||
| 29 | * That is, ->map() must be called on a pinned buffer, same goes for ->steal(). | ||
| 30 | */ | ||
| 18 | struct pipe_buf_operations { | 31 | struct pipe_buf_operations { |
| 19 | int can_merge; | 32 | int can_merge; |
| 20 | void * (*map)(struct file *, struct pipe_inode_info *, struct pipe_buffer *); | 33 | void * (*map)(struct pipe_inode_info *, struct pipe_buffer *, int); |
| 21 | void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *); | 34 | void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *, void *); |
| 35 | int (*pin)(struct pipe_inode_info *, struct pipe_buffer *); | ||
| 22 | void (*release)(struct pipe_inode_info *, struct pipe_buffer *); | 36 | void (*release)(struct pipe_inode_info *, struct pipe_buffer *); |
| 23 | int (*steal)(struct pipe_inode_info *, struct pipe_buffer *); | 37 | int (*steal)(struct pipe_inode_info *, struct pipe_buffer *); |
| 24 | void (*get)(struct pipe_inode_info *, struct pipe_buffer *); | 38 | void (*get)(struct pipe_inode_info *, struct pipe_buffer *); |
| @@ -51,6 +65,13 @@ struct pipe_inode_info * alloc_pipe_info(struct inode * inode); | |||
| 51 | void free_pipe_info(struct inode * inode); | 65 | void free_pipe_info(struct inode * inode); |
| 52 | void __free_pipe_info(struct pipe_inode_info *); | 66 | void __free_pipe_info(struct pipe_inode_info *); |
| 53 | 67 | ||
| 68 | /* Generic pipe buffer ops functions */ | ||
| 69 | void *generic_pipe_buf_map(struct pipe_inode_info *, struct pipe_buffer *, int); | ||
| 70 | void generic_pipe_buf_unmap(struct pipe_inode_info *, struct pipe_buffer *, void *); | ||
| 71 | void generic_pipe_buf_get(struct pipe_inode_info *, struct pipe_buffer *); | ||
| 72 | int generic_pipe_buf_pin(struct pipe_inode_info *, struct pipe_buffer *); | ||
| 73 | int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *); | ||
| 74 | |||
| 54 | /* | 75 | /* |
| 55 | * splice is tied to pipes as a transport (at least for now), so we'll just | 76 | * splice is tied to pipes as a transport (at least for now), so we'll just |
| 56 | * add the splice flags here. | 77 | * add the splice flags here. |
| @@ -60,6 +81,7 @@ void __free_pipe_info(struct pipe_inode_info *); | |||
| 60 | /* we may still block on the fd we splice */ | 81 | /* we may still block on the fd we splice */ |
| 61 | /* from/to, of course */ | 82 | /* from/to, of course */ |
| 62 | #define SPLICE_F_MORE (0x04) /* expect more data */ | 83 | #define SPLICE_F_MORE (0x04) /* expect more data */ |
| 84 | #define SPLICE_F_GIFT (0x08) /* pages passed in are a gift */ | ||
| 63 | 85 | ||
| 64 | /* | 86 | /* |
| 65 | * Passed to the actors | 87 | * Passed to the actors |
diff --git a/include/linux/security.h b/include/linux/security.h index aaa0a5cdbf75..1bab48f6aeac 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -869,11 +869,6 @@ struct swap_info_struct; | |||
| 869 | * @ipcp contains the kernel IPC permission structure | 869 | * @ipcp contains the kernel IPC permission structure |
| 870 | * @flag contains the desired (requested) permission set | 870 | * @flag contains the desired (requested) permission set |
| 871 | * Return 0 if permission is granted. | 871 | * Return 0 if permission is granted. |
| 872 | * @ipc_getsecurity: | ||
| 873 | * Copy the security label associated with the ipc object into | ||
| 874 | * @buffer. @buffer may be NULL to request the size of the buffer | ||
| 875 | * required. @size indicates the size of @buffer in bytes. Return | ||
| 876 | * number of bytes used/required on success. | ||
| 877 | * | 872 | * |
| 878 | * Security hooks for individual messages held in System V IPC message queues | 873 | * Security hooks for individual messages held in System V IPC message queues |
| 879 | * @msg_msg_alloc_security: | 874 | * @msg_msg_alloc_security: |
| @@ -1223,7 +1218,6 @@ struct security_operations { | |||
| 1223 | void (*task_to_inode)(struct task_struct *p, struct inode *inode); | 1218 | void (*task_to_inode)(struct task_struct *p, struct inode *inode); |
| 1224 | 1219 | ||
| 1225 | int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag); | 1220 | int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag); |
| 1226 | int (*ipc_getsecurity)(struct kern_ipc_perm *ipcp, void *buffer, size_t size); | ||
| 1227 | 1221 | ||
| 1228 | int (*msg_msg_alloc_security) (struct msg_msg * msg); | 1222 | int (*msg_msg_alloc_security) (struct msg_msg * msg); |
| 1229 | void (*msg_msg_free_security) (struct msg_msg * msg); | 1223 | void (*msg_msg_free_security) (struct msg_msg * msg); |
| @@ -1887,11 +1881,6 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp, | |||
| 1887 | return security_ops->ipc_permission (ipcp, flag); | 1881 | return security_ops->ipc_permission (ipcp, flag); |
| 1888 | } | 1882 | } |
| 1889 | 1883 | ||
| 1890 | static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) | ||
| 1891 | { | ||
| 1892 | return security_ops->ipc_getsecurity(ipcp, buffer, size); | ||
| 1893 | } | ||
| 1894 | |||
| 1895 | static inline int security_msg_msg_alloc (struct msg_msg * msg) | 1884 | static inline int security_msg_msg_alloc (struct msg_msg * msg) |
| 1896 | { | 1885 | { |
| 1897 | return security_ops->msg_msg_alloc_security (msg); | 1886 | return security_ops->msg_msg_alloc_security (msg); |
| @@ -2532,11 +2521,6 @@ static inline int security_ipc_permission (struct kern_ipc_perm *ipcp, | |||
| 2532 | return 0; | 2521 | return 0; |
| 2533 | } | 2522 | } |
| 2534 | 2523 | ||
| 2535 | static inline int security_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) | ||
| 2536 | { | ||
| 2537 | return -EOPNOTSUPP; | ||
| 2538 | } | ||
| 2539 | |||
| 2540 | static inline int security_msg_msg_alloc (struct msg_msg * msg) | 2524 | static inline int security_msg_msg_alloc (struct msg_msg * msg) |
| 2541 | { | 2525 | { |
| 2542 | return 0; | 2526 | return 0; |
diff --git a/include/linux/selinux.h b/include/linux/selinux.h new file mode 100644 index 000000000000..4047bcde4484 --- /dev/null +++ b/include/linux/selinux.h | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | /* | ||
| 2 | * SELinux services exported to the rest of the kernel. | ||
| 3 | * | ||
| 4 | * Author: James Morris <jmorris@redhat.com> | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 Red Hat, Inc., James Morris <jmorris@redhat.com> | ||
| 7 | * Copyright (C) 2006 Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> | ||
| 8 | * Copyright (C) 2006 IBM Corporation, Timothy R. Chavez <tinytim@us.ibm.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2, | ||
| 12 | * as published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | #ifndef _LINUX_SELINUX_H | ||
| 15 | #define _LINUX_SELINUX_H | ||
| 16 | |||
| 17 | struct selinux_audit_rule; | ||
| 18 | struct audit_context; | ||
| 19 | struct inode; | ||
| 20 | struct kern_ipc_perm; | ||
| 21 | |||
| 22 | #ifdef CONFIG_SECURITY_SELINUX | ||
| 23 | |||
| 24 | /** | ||
| 25 | * selinux_audit_rule_init - alloc/init an selinux audit rule structure. | ||
| 26 | * @field: the field this rule refers to | ||
| 27 | * @op: the operater the rule uses | ||
| 28 | * @rulestr: the text "target" of the rule | ||
| 29 | * @rule: pointer to the new rule structure returned via this | ||
| 30 | * | ||
| 31 | * Returns 0 if successful, -errno if not. On success, the rule structure | ||
| 32 | * will be allocated internally. The caller must free this structure with | ||
| 33 | * selinux_audit_rule_free() after use. | ||
| 34 | */ | ||
| 35 | int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, | ||
| 36 | struct selinux_audit_rule **rule); | ||
| 37 | |||
| 38 | /** | ||
| 39 | * selinux_audit_rule_free - free an selinux audit rule structure. | ||
| 40 | * @rule: pointer to the audit rule to be freed | ||
| 41 | * | ||
| 42 | * This will free all memory associated with the given rule. | ||
| 43 | * If @rule is NULL, no operation is performed. | ||
| 44 | */ | ||
| 45 | void selinux_audit_rule_free(struct selinux_audit_rule *rule); | ||
| 46 | |||
| 47 | /** | ||
| 48 | * selinux_audit_rule_match - determine if a context ID matches a rule. | ||
| 49 | * @ctxid: the context ID to check | ||
| 50 | * @field: the field this rule refers to | ||
| 51 | * @op: the operater the rule uses | ||
| 52 | * @rule: pointer to the audit rule to check against | ||
| 53 | * @actx: the audit context (can be NULL) associated with the check | ||
| 54 | * | ||
| 55 | * Returns 1 if the context id matches the rule, 0 if it does not, and | ||
| 56 | * -errno on failure. | ||
| 57 | */ | ||
| 58 | int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op, | ||
| 59 | struct selinux_audit_rule *rule, | ||
| 60 | struct audit_context *actx); | ||
| 61 | |||
| 62 | /** | ||
| 63 | * selinux_audit_set_callback - set the callback for policy reloads. | ||
| 64 | * @callback: the function to call when the policy is reloaded | ||
| 65 | * | ||
| 66 | * This sets the function callback function that will update the rules | ||
| 67 | * upon policy reloads. This callback should rebuild all existing rules | ||
| 68 | * using selinux_audit_rule_init(). | ||
| 69 | */ | ||
| 70 | void selinux_audit_set_callback(int (*callback)(void)); | ||
| 71 | |||
| 72 | /** | ||
| 73 | * selinux_task_ctxid - determine a context ID for a process. | ||
| 74 | * @tsk: the task object | ||
| 75 | * @ctxid: ID value returned via this | ||
| 76 | * | ||
| 77 | * On return, ctxid will contain an ID for the context. This value | ||
| 78 | * should only be used opaquely. | ||
| 79 | */ | ||
| 80 | void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid); | ||
| 81 | |||
| 82 | /** | ||
| 83 | * selinux_ctxid_to_string - map a security context ID to a string | ||
| 84 | * @ctxid: security context ID to be converted. | ||
| 85 | * @ctx: address of context string to be returned | ||
| 86 | * @ctxlen: length of returned context string. | ||
| 87 | * | ||
| 88 | * Returns 0 if successful, -errno if not. On success, the context | ||
| 89 | * string will be allocated internally, and the caller must call | ||
| 90 | * kfree() on it after use. | ||
| 91 | */ | ||
| 92 | int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen); | ||
| 93 | |||
| 94 | /** | ||
| 95 | * selinux_get_inode_sid - get the inode's security context ID | ||
| 96 | * @inode: inode structure to get the sid from. | ||
| 97 | * @sid: pointer to security context ID to be filled in. | ||
| 98 | * | ||
| 99 | * Returns nothing | ||
| 100 | */ | ||
| 101 | void selinux_get_inode_sid(const struct inode *inode, u32 *sid); | ||
| 102 | |||
| 103 | /** | ||
| 104 | * selinux_get_ipc_sid - get the ipc security context ID | ||
| 105 | * @ipcp: ipc structure to get the sid from. | ||
| 106 | * @sid: pointer to security context ID to be filled in. | ||
| 107 | * | ||
| 108 | * Returns nothing | ||
| 109 | */ | ||
| 110 | void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid); | ||
| 111 | |||
| 112 | /** | ||
| 113 | * selinux_get_task_sid - return the SID of task | ||
| 114 | * @tsk: the task whose SID will be returned | ||
| 115 | * @sid: pointer to security context ID to be filled in. | ||
| 116 | * | ||
| 117 | * Returns nothing | ||
| 118 | */ | ||
| 119 | void selinux_get_task_sid(struct task_struct *tsk, u32 *sid); | ||
| 120 | |||
| 121 | |||
| 122 | #else | ||
| 123 | |||
| 124 | static inline int selinux_audit_rule_init(u32 field, u32 op, | ||
| 125 | char *rulestr, | ||
| 126 | struct selinux_audit_rule **rule) | ||
| 127 | { | ||
| 128 | return -ENOTSUPP; | ||
| 129 | } | ||
| 130 | |||
| 131 | static inline void selinux_audit_rule_free(struct selinux_audit_rule *rule) | ||
| 132 | { | ||
| 133 | return; | ||
| 134 | } | ||
| 135 | |||
| 136 | static inline int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op, | ||
| 137 | struct selinux_audit_rule *rule, | ||
| 138 | struct audit_context *actx) | ||
| 139 | { | ||
| 140 | return 0; | ||
| 141 | } | ||
| 142 | |||
| 143 | static inline void selinux_audit_set_callback(int (*callback)(void)) | ||
| 144 | { | ||
| 145 | return; | ||
| 146 | } | ||
| 147 | |||
| 148 | static inline void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid) | ||
| 149 | { | ||
| 150 | *ctxid = 0; | ||
| 151 | } | ||
| 152 | |||
| 153 | static inline int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen) | ||
| 154 | { | ||
| 155 | *ctx = NULL; | ||
| 156 | *ctxlen = 0; | ||
| 157 | return 0; | ||
| 158 | } | ||
| 159 | |||
| 160 | static inline void selinux_get_inode_sid(const struct inode *inode, u32 *sid) | ||
| 161 | { | ||
| 162 | *sid = 0; | ||
| 163 | } | ||
| 164 | |||
| 165 | static inline void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid) | ||
| 166 | { | ||
| 167 | *sid = 0; | ||
| 168 | } | ||
| 169 | |||
| 170 | static inline void selinux_get_task_sid(struct task_struct *tsk, u32 *sid) | ||
| 171 | { | ||
| 172 | *sid = 0; | ||
| 173 | } | ||
| 174 | |||
| 175 | #endif /* CONFIG_SECURITY_SELINUX */ | ||
| 176 | |||
| 177 | #endif /* _LINUX_SELINUX_H */ | ||
diff --git a/include/net/ax25.h b/include/net/ax25.h index b74945288dfc..7cd528e9d668 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h | |||
| @@ -144,14 +144,14 @@ enum { | |||
| 144 | #define AX25_DEF_CONMODE 2 /* Connected mode allowed */ | 144 | #define AX25_DEF_CONMODE 2 /* Connected mode allowed */ |
| 145 | #define AX25_DEF_WINDOW 2 /* Window=2 */ | 145 | #define AX25_DEF_WINDOW 2 /* Window=2 */ |
| 146 | #define AX25_DEF_EWINDOW 32 /* Module-128 Window=32 */ | 146 | #define AX25_DEF_EWINDOW 32 /* Module-128 Window=32 */ |
| 147 | #define AX25_DEF_T1 (10 * HZ) /* T1=10s */ | 147 | #define AX25_DEF_T1 10000 /* T1=10s */ |
| 148 | #define AX25_DEF_T2 (3 * HZ) /* T2=3s */ | 148 | #define AX25_DEF_T2 3000 /* T2=3s */ |
| 149 | #define AX25_DEF_T3 (300 * HZ) /* T3=300s */ | 149 | #define AX25_DEF_T3 300000 /* T3=300s */ |
| 150 | #define AX25_DEF_N2 10 /* N2=10 */ | 150 | #define AX25_DEF_N2 10 /* N2=10 */ |
| 151 | #define AX25_DEF_IDLE (0 * 60 * HZ) /* Idle=None */ | 151 | #define AX25_DEF_IDLE 0 /* Idle=None */ |
| 152 | #define AX25_DEF_PACLEN 256 /* Paclen=256 */ | 152 | #define AX25_DEF_PACLEN 256 /* Paclen=256 */ |
| 153 | #define AX25_DEF_PROTOCOL AX25_PROTO_STD_SIMPLEX /* Standard AX.25 */ | 153 | #define AX25_DEF_PROTOCOL AX25_PROTO_STD_SIMPLEX /* Standard AX.25 */ |
| 154 | #define AX25_DEF_DS_TIMEOUT (3 * 60 * HZ) /* DAMA timeout 3 minutes */ | 154 | #define AX25_DEF_DS_TIMEOUT 180000 /* DAMA timeout 3 minutes */ |
| 155 | 155 | ||
| 156 | typedef struct ax25_uid_assoc { | 156 | typedef struct ax25_uid_assoc { |
| 157 | struct hlist_node uid_node; | 157 | struct hlist_node uid_node; |
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index 519d3a077c62..600cb543550d 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h | |||
| @@ -149,7 +149,7 @@ static inline void inet_twsk_add_bind_node(struct inet_timewait_sock *tw, | |||
| 149 | 149 | ||
| 150 | static inline int inet_twsk_dead_hashed(const struct inet_timewait_sock *tw) | 150 | static inline int inet_twsk_dead_hashed(const struct inet_timewait_sock *tw) |
| 151 | { | 151 | { |
| 152 | return tw->tw_death_node.pprev != NULL; | 152 | return !hlist_unhashed(&tw->tw_death_node); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static inline void inet_twsk_dead_node_init(struct inet_timewait_sock *tw) | 155 | static inline void inet_twsk_dead_node_init(struct inet_timewait_sock *tw) |
diff --git a/include/net/netrom.h b/include/net/netrom.h index a5ee53bce62f..e0ca112024a3 100644 --- a/include/net/netrom.h +++ b/include/net/netrom.h | |||
| @@ -42,11 +42,11 @@ enum { | |||
| 42 | #define NR_COND_PEER_RX_BUSY 0x04 | 42 | #define NR_COND_PEER_RX_BUSY 0x04 |
| 43 | #define NR_COND_OWN_RX_BUSY 0x08 | 43 | #define NR_COND_OWN_RX_BUSY 0x08 |
| 44 | 44 | ||
| 45 | #define NR_DEFAULT_T1 (120 * HZ) /* Outstanding frames - 120 seconds */ | 45 | #define NR_DEFAULT_T1 120000 /* Outstanding frames - 120 seconds */ |
| 46 | #define NR_DEFAULT_T2 (5 * HZ) /* Response delay - 5 seconds */ | 46 | #define NR_DEFAULT_T2 5000 /* Response delay - 5 seconds */ |
| 47 | #define NR_DEFAULT_N2 3 /* Number of Retries - 3 */ | 47 | #define NR_DEFAULT_N2 3 /* Number of Retries - 3 */ |
| 48 | #define NR_DEFAULT_T4 (180 * HZ) /* Busy Delay - 180 seconds */ | 48 | #define NR_DEFAULT_T4 180000 /* Busy Delay - 180 seconds */ |
| 49 | #define NR_DEFAULT_IDLE (0 * 60 * HZ) /* No Activity Timeout - none */ | 49 | #define NR_DEFAULT_IDLE 0 /* No Activity Timeout - none */ |
| 50 | #define NR_DEFAULT_WINDOW 4 /* Default Window Size - 4 */ | 50 | #define NR_DEFAULT_WINDOW 4 /* Default Window Size - 4 */ |
| 51 | #define NR_DEFAULT_OBS 6 /* Default Obsolescence Count - 6 */ | 51 | #define NR_DEFAULT_OBS 6 /* Default Obsolescence Count - 6 */ |
| 52 | #define NR_DEFAULT_QUAL 10 /* Default Neighbour Quality - 10 */ | 52 | #define NR_DEFAULT_QUAL 10 /* Default Neighbour Quality - 10 */ |
diff --git a/include/net/rose.h b/include/net/rose.h index 3249b979605a..012b09ed2401 100644 --- a/include/net/rose.h +++ b/include/net/rose.h | |||
| @@ -49,14 +49,14 @@ enum { | |||
| 49 | ROSE_STATE_5 /* Deferred Call Acceptance */ | 49 | ROSE_STATE_5 /* Deferred Call Acceptance */ |
| 50 | }; | 50 | }; |
| 51 | 51 | ||
| 52 | #define ROSE_DEFAULT_T0 (180 * HZ) /* Default T10 T20 value */ | 52 | #define ROSE_DEFAULT_T0 180000 /* Default T10 T20 value */ |
| 53 | #define ROSE_DEFAULT_T1 (200 * HZ) /* Default T11 T21 value */ | 53 | #define ROSE_DEFAULT_T1 200000 /* Default T11 T21 value */ |
| 54 | #define ROSE_DEFAULT_T2 (180 * HZ) /* Default T12 T22 value */ | 54 | #define ROSE_DEFAULT_T2 180000 /* Default T12 T22 value */ |
| 55 | #define ROSE_DEFAULT_T3 (180 * HZ) /* Default T13 T23 value */ | 55 | #define ROSE_DEFAULT_T3 180000 /* Default T13 T23 value */ |
| 56 | #define ROSE_DEFAULT_HB (5 * HZ) /* Default Holdback value */ | 56 | #define ROSE_DEFAULT_HB 5000 /* Default Holdback value */ |
| 57 | #define ROSE_DEFAULT_IDLE (0 * 60 * HZ) /* No Activity Timeout - none */ | 57 | #define ROSE_DEFAULT_IDLE 0 /* No Activity Timeout - none */ |
| 58 | #define ROSE_DEFAULT_ROUTING 1 /* Default routing flag */ | 58 | #define ROSE_DEFAULT_ROUTING 1 /* Default routing flag */ |
| 59 | #define ROSE_DEFAULT_FAIL_TIMEOUT (120 * HZ) /* Time until link considered usable */ | 59 | #define ROSE_DEFAULT_FAIL_TIMEOUT 120000 /* Time until link considered usable */ |
| 60 | #define ROSE_DEFAULT_MAXVC 50 /* Maximum number of VCs per neighbour */ | 60 | #define ROSE_DEFAULT_MAXVC 50 /* Maximum number of VCs per neighbour */ |
| 61 | #define ROSE_DEFAULT_WINDOW_SIZE 7 /* Default window size */ | 61 | #define ROSE_DEFAULT_WINDOW_SIZE 7 /* Default window size */ |
| 62 | 62 | ||
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index eba99f375517..7f4fea173fb1 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
| @@ -712,6 +712,7 @@ struct sctp_chunk { | |||
| 712 | __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ | 712 | __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ |
| 713 | __s8 fast_retransmit; /* Is this chunk fast retransmitted? */ | 713 | __s8 fast_retransmit; /* Is this chunk fast retransmitted? */ |
| 714 | __u8 tsn_missing_report; /* Data chunk missing counter. */ | 714 | __u8 tsn_missing_report; /* Data chunk missing counter. */ |
| 715 | __u8 data_accepted; /* At least 1 chunk in this packet accepted */ | ||
| 715 | }; | 716 | }; |
| 716 | 717 | ||
| 717 | void sctp_chunk_hold(struct sctp_chunk *); | 718 | void sctp_chunk_hold(struct sctp_chunk *); |
diff --git a/include/net/sock.h b/include/net/sock.h index d8a5d87ad145..d27e748a8259 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
| @@ -278,7 +278,7 @@ static inline int sk_unhashed(const struct sock *sk) | |||
| 278 | 278 | ||
| 279 | static inline int sk_hashed(const struct sock *sk) | 279 | static inline int sk_hashed(const struct sock *sk) |
| 280 | { | 280 | { |
| 281 | return sk->sk_node.pprev != NULL; | 281 | return !sk_unhashed(sk); |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | static __inline__ void sk_node_init(struct hlist_node *node) | 284 | static __inline__ void sk_node_init(struct hlist_node *node) |
diff --git a/init/main.c b/init/main.c index 4a2f0898dda1..f715b9b89753 100644 --- a/init/main.c +++ b/init/main.c | |||
| @@ -582,7 +582,7 @@ static void __init do_initcalls(void) | |||
| 582 | 582 | ||
| 583 | result = (*call)(); | 583 | result = (*call)(); |
| 584 | 584 | ||
| 585 | if (result && (result != -ENODEV || initcall_debug)) { | 585 | if (result && result != -ENODEV && initcall_debug) { |
| 586 | sprintf(msgbuf, "error code %d", result); | 586 | sprintf(msgbuf, "error code %d", result); |
| 587 | msg = msgbuf; | 587 | msg = msgbuf; |
| 588 | } | 588 | } |
| @@ -13,6 +13,9 @@ | |||
| 13 | * mostly rewritten, threaded and wake-one semantics added | 13 | * mostly rewritten, threaded and wake-one semantics added |
| 14 | * MSGMAX limit removed, sysctl's added | 14 | * MSGMAX limit removed, sysctl's added |
| 15 | * (c) 1999 Manfred Spraul <manfred@colorfullife.com> | 15 | * (c) 1999 Manfred Spraul <manfred@colorfullife.com> |
| 16 | * | ||
| 17 | * support for audit of ipc object properties and permission changes | ||
| 18 | * Dustin Kirkland <dustin.kirkland@us.ibm.com> | ||
| 16 | */ | 19 | */ |
| 17 | 20 | ||
| 18 | #include <linux/capability.h> | 21 | #include <linux/capability.h> |
| @@ -447,6 +450,11 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf) | |||
| 447 | if (msg_checkid(msq,msqid)) | 450 | if (msg_checkid(msq,msqid)) |
| 448 | goto out_unlock_up; | 451 | goto out_unlock_up; |
| 449 | ipcp = &msq->q_perm; | 452 | ipcp = &msq->q_perm; |
| 453 | |||
| 454 | err = audit_ipc_obj(ipcp); | ||
| 455 | if (err) | ||
| 456 | goto out_unlock_up; | ||
| 457 | |||
| 450 | err = -EPERM; | 458 | err = -EPERM; |
| 451 | if (current->euid != ipcp->cuid && | 459 | if (current->euid != ipcp->cuid && |
| 452 | current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) | 460 | current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) |
| @@ -460,7 +468,8 @@ asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf) | |||
| 460 | switch (cmd) { | 468 | switch (cmd) { |
| 461 | case IPC_SET: | 469 | case IPC_SET: |
| 462 | { | 470 | { |
| 463 | if ((err = audit_ipc_perms(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode, ipcp))) | 471 | err = audit_ipc_set_perm(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode, ipcp); |
| 472 | if (err) | ||
| 464 | goto out_unlock_up; | 473 | goto out_unlock_up; |
| 465 | 474 | ||
| 466 | err = -EPERM; | 475 | err = -EPERM; |
| @@ -61,6 +61,9 @@ | |||
| 61 | * (c) 2001 Red Hat Inc <alan@redhat.com> | 61 | * (c) 2001 Red Hat Inc <alan@redhat.com> |
| 62 | * Lockless wakeup | 62 | * Lockless wakeup |
| 63 | * (c) 2003 Manfred Spraul <manfred@colorfullife.com> | 63 | * (c) 2003 Manfred Spraul <manfred@colorfullife.com> |
| 64 | * | ||
| 65 | * support for audit of ipc object properties and permission changes | ||
| 66 | * Dustin Kirkland <dustin.kirkland@us.ibm.com> | ||
| 64 | */ | 67 | */ |
| 65 | 68 | ||
| 66 | #include <linux/config.h> | 69 | #include <linux/config.h> |
| @@ -820,6 +823,11 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun | |||
| 820 | goto out_unlock; | 823 | goto out_unlock; |
| 821 | } | 824 | } |
| 822 | ipcp = &sma->sem_perm; | 825 | ipcp = &sma->sem_perm; |
| 826 | |||
| 827 | err = audit_ipc_obj(ipcp); | ||
| 828 | if (err) | ||
| 829 | goto out_unlock; | ||
| 830 | |||
| 823 | if (current->euid != ipcp->cuid && | 831 | if (current->euid != ipcp->cuid && |
| 824 | current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) { | 832 | current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) { |
| 825 | err=-EPERM; | 833 | err=-EPERM; |
| @@ -836,7 +844,8 @@ static int semctl_down(int semid, int semnum, int cmd, int version, union semun | |||
| 836 | err = 0; | 844 | err = 0; |
| 837 | break; | 845 | break; |
| 838 | case IPC_SET: | 846 | case IPC_SET: |
| 839 | if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, setbuf.mode, ipcp))) | 847 | err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode, ipcp); |
| 848 | if (err) | ||
| 840 | goto out_unlock; | 849 | goto out_unlock; |
| 841 | ipcp->uid = setbuf.uid; | 850 | ipcp->uid = setbuf.uid; |
| 842 | ipcp->gid = setbuf.gid; | 851 | ipcp->gid = setbuf.gid; |
| @@ -13,6 +13,8 @@ | |||
| 13 | * Shared /dev/zero support, Kanoj Sarcar <kanoj@sgi.com> | 13 | * Shared /dev/zero support, Kanoj Sarcar <kanoj@sgi.com> |
| 14 | * Move the mm functionality over to mm/shmem.c, Christoph Rohland <cr@sap.com> | 14 | * Move the mm functionality over to mm/shmem.c, Christoph Rohland <cr@sap.com> |
| 15 | * | 15 | * |
| 16 | * support for audit of ipc object properties and permission changes | ||
| 17 | * Dustin Kirkland <dustin.kirkland@us.ibm.com> | ||
| 16 | */ | 18 | */ |
| 17 | 19 | ||
| 18 | #include <linux/config.h> | 20 | #include <linux/config.h> |
| @@ -542,6 +544,10 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) | |||
| 542 | if(err) | 544 | if(err) |
| 543 | goto out_unlock; | 545 | goto out_unlock; |
| 544 | 546 | ||
| 547 | err = audit_ipc_obj(&(shp->shm_perm)); | ||
| 548 | if (err) | ||
| 549 | goto out_unlock; | ||
| 550 | |||
| 545 | if (!capable(CAP_IPC_LOCK)) { | 551 | if (!capable(CAP_IPC_LOCK)) { |
| 546 | err = -EPERM; | 552 | err = -EPERM; |
| 547 | if (current->euid != shp->shm_perm.uid && | 553 | if (current->euid != shp->shm_perm.uid && |
| @@ -594,6 +600,10 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) | |||
| 594 | if(err) | 600 | if(err) |
| 595 | goto out_unlock_up; | 601 | goto out_unlock_up; |
| 596 | 602 | ||
| 603 | err = audit_ipc_obj(&(shp->shm_perm)); | ||
| 604 | if (err) | ||
| 605 | goto out_unlock_up; | ||
| 606 | |||
| 597 | if (current->euid != shp->shm_perm.uid && | 607 | if (current->euid != shp->shm_perm.uid && |
| 598 | current->euid != shp->shm_perm.cuid && | 608 | current->euid != shp->shm_perm.cuid && |
| 599 | !capable(CAP_SYS_ADMIN)) { | 609 | !capable(CAP_SYS_ADMIN)) { |
| @@ -627,12 +637,15 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) | |||
| 627 | err=-EINVAL; | 637 | err=-EINVAL; |
| 628 | if(shp==NULL) | 638 | if(shp==NULL) |
| 629 | goto out_up; | 639 | goto out_up; |
| 630 | if ((err = audit_ipc_perms(0, setbuf.uid, setbuf.gid, | ||
| 631 | setbuf.mode, &(shp->shm_perm)))) | ||
| 632 | goto out_unlock_up; | ||
| 633 | err = shm_checkid(shp,shmid); | 640 | err = shm_checkid(shp,shmid); |
| 634 | if(err) | 641 | if(err) |
| 635 | goto out_unlock_up; | 642 | goto out_unlock_up; |
| 643 | err = audit_ipc_obj(&(shp->shm_perm)); | ||
| 644 | if (err) | ||
| 645 | goto out_unlock_up; | ||
| 646 | err = audit_ipc_set_perm(0, setbuf.uid, setbuf.gid, setbuf.mode, &(shp->shm_perm)); | ||
| 647 | if (err) | ||
| 648 | goto out_unlock_up; | ||
| 636 | err=-EPERM; | 649 | err=-EPERM; |
| 637 | if (current->euid != shp->shm_perm.uid && | 650 | if (current->euid != shp->shm_perm.uid && |
| 638 | current->euid != shp->shm_perm.cuid && | 651 | current->euid != shp->shm_perm.cuid && |
diff --git a/ipc/util.c b/ipc/util.c index b3dcfad3b4f7..8193299f45f6 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | * Manfred Spraul <manfred@colorfullife.com> | 10 | * Manfred Spraul <manfred@colorfullife.com> |
| 11 | * Oct 2002 - One lock per IPC id. RCU ipc_free for lock-free grow_ary(). | 11 | * Oct 2002 - One lock per IPC id. RCU ipc_free for lock-free grow_ary(). |
| 12 | * Mingming Cao <cmm@us.ibm.com> | 12 | * Mingming Cao <cmm@us.ibm.com> |
| 13 | * Mar 2006 - support for audit of ipc object properties | ||
| 14 | * Dustin Kirkland <dustin.kirkland@us.ibm.com> | ||
| 13 | */ | 15 | */ |
| 14 | 16 | ||
| 15 | #include <linux/config.h> | 17 | #include <linux/config.h> |
| @@ -27,6 +29,7 @@ | |||
| 27 | #include <linux/workqueue.h> | 29 | #include <linux/workqueue.h> |
| 28 | #include <linux/seq_file.h> | 30 | #include <linux/seq_file.h> |
| 29 | #include <linux/proc_fs.h> | 31 | #include <linux/proc_fs.h> |
| 32 | #include <linux/audit.h> | ||
| 30 | 33 | ||
| 31 | #include <asm/unistd.h> | 34 | #include <asm/unistd.h> |
| 32 | 35 | ||
| @@ -464,8 +467,10 @@ void ipc_rcu_putref(void *ptr) | |||
| 464 | 467 | ||
| 465 | int ipcperms (struct kern_ipc_perm *ipcp, short flag) | 468 | int ipcperms (struct kern_ipc_perm *ipcp, short flag) |
| 466 | { /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */ | 469 | { /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */ |
| 467 | int requested_mode, granted_mode; | 470 | int requested_mode, granted_mode, err; |
| 468 | 471 | ||
| 472 | if (unlikely((err = audit_ipc_obj(ipcp)))) | ||
| 473 | return err; | ||
| 469 | requested_mode = (flag >> 6) | (flag >> 3) | flag; | 474 | requested_mode = (flag >> 6) | (flag >> 3) | flag; |
| 470 | granted_mode = ipcp->mode; | 475 | granted_mode = ipcp->mode; |
| 471 | if (current->euid == ipcp->cuid || current->euid == ipcp->uid) | 476 | if (current->euid == ipcp->cuid || current->euid == ipcp->uid) |
diff --git a/kernel/audit.c b/kernel/audit.c index c8ccbd09048f..df57b493e1cb 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -55,6 +55,9 @@ | |||
| 55 | #include <net/netlink.h> | 55 | #include <net/netlink.h> |
| 56 | #include <linux/skbuff.h> | 56 | #include <linux/skbuff.h> |
| 57 | #include <linux/netlink.h> | 57 | #include <linux/netlink.h> |
| 58 | #include <linux/selinux.h> | ||
| 59 | |||
| 60 | #include "audit.h" | ||
| 58 | 61 | ||
| 59 | /* No auditing will take place until audit_initialized != 0. | 62 | /* No auditing will take place until audit_initialized != 0. |
| 60 | * (Initialization happens after skb_init is called.) */ | 63 | * (Initialization happens after skb_init is called.) */ |
| @@ -227,49 +230,103 @@ void audit_log_lost(const char *message) | |||
| 227 | } | 230 | } |
| 228 | } | 231 | } |
| 229 | 232 | ||
| 230 | static int audit_set_rate_limit(int limit, uid_t loginuid) | 233 | static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sid) |
| 231 | { | 234 | { |
| 232 | int old = audit_rate_limit; | 235 | int old = audit_rate_limit; |
| 233 | audit_rate_limit = limit; | 236 | |
| 234 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 237 | if (sid) { |
| 238 | char *ctx = NULL; | ||
| 239 | u32 len; | ||
| 240 | int rc; | ||
| 241 | if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) | ||
| 242 | return rc; | ||
| 243 | else | ||
| 244 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 245 | "audit_rate_limit=%d old=%d by auid=%u subj=%s", | ||
| 246 | limit, old, loginuid, ctx); | ||
| 247 | kfree(ctx); | ||
| 248 | } else | ||
| 249 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 235 | "audit_rate_limit=%d old=%d by auid=%u", | 250 | "audit_rate_limit=%d old=%d by auid=%u", |
| 236 | audit_rate_limit, old, loginuid); | 251 | limit, old, loginuid); |
| 252 | audit_rate_limit = limit; | ||
| 237 | return old; | 253 | return old; |
| 238 | } | 254 | } |
| 239 | 255 | ||
| 240 | static int audit_set_backlog_limit(int limit, uid_t loginuid) | 256 | static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sid) |
| 241 | { | 257 | { |
| 242 | int old = audit_backlog_limit; | 258 | int old = audit_backlog_limit; |
| 243 | audit_backlog_limit = limit; | 259 | |
| 244 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 260 | if (sid) { |
| 261 | char *ctx = NULL; | ||
| 262 | u32 len; | ||
| 263 | int rc; | ||
| 264 | if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) | ||
| 265 | return rc; | ||
| 266 | else | ||
| 267 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 268 | "audit_backlog_limit=%d old=%d by auid=%u subj=%s", | ||
| 269 | limit, old, loginuid, ctx); | ||
| 270 | kfree(ctx); | ||
| 271 | } else | ||
| 272 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 245 | "audit_backlog_limit=%d old=%d by auid=%u", | 273 | "audit_backlog_limit=%d old=%d by auid=%u", |
| 246 | audit_backlog_limit, old, loginuid); | 274 | limit, old, loginuid); |
| 275 | audit_backlog_limit = limit; | ||
| 247 | return old; | 276 | return old; |
| 248 | } | 277 | } |
| 249 | 278 | ||
| 250 | static int audit_set_enabled(int state, uid_t loginuid) | 279 | static int audit_set_enabled(int state, uid_t loginuid, u32 sid) |
| 251 | { | 280 | { |
| 252 | int old = audit_enabled; | 281 | int old = audit_enabled; |
| 282 | |||
| 253 | if (state != 0 && state != 1) | 283 | if (state != 0 && state != 1) |
| 254 | return -EINVAL; | 284 | return -EINVAL; |
| 255 | audit_enabled = state; | 285 | |
| 256 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 286 | if (sid) { |
| 287 | char *ctx = NULL; | ||
| 288 | u32 len; | ||
| 289 | int rc; | ||
| 290 | if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) | ||
| 291 | return rc; | ||
| 292 | else | ||
| 293 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 294 | "audit_enabled=%d old=%d by auid=%u subj=%s", | ||
| 295 | state, old, loginuid, ctx); | ||
| 296 | kfree(ctx); | ||
| 297 | } else | ||
| 298 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 257 | "audit_enabled=%d old=%d by auid=%u", | 299 | "audit_enabled=%d old=%d by auid=%u", |
| 258 | audit_enabled, old, loginuid); | 300 | state, old, loginuid); |
| 301 | audit_enabled = state; | ||
| 259 | return old; | 302 | return old; |
| 260 | } | 303 | } |
| 261 | 304 | ||
| 262 | static int audit_set_failure(int state, uid_t loginuid) | 305 | static int audit_set_failure(int state, uid_t loginuid, u32 sid) |
| 263 | { | 306 | { |
| 264 | int old = audit_failure; | 307 | int old = audit_failure; |
| 308 | |||
| 265 | if (state != AUDIT_FAIL_SILENT | 309 | if (state != AUDIT_FAIL_SILENT |
| 266 | && state != AUDIT_FAIL_PRINTK | 310 | && state != AUDIT_FAIL_PRINTK |
| 267 | && state != AUDIT_FAIL_PANIC) | 311 | && state != AUDIT_FAIL_PANIC) |
| 268 | return -EINVAL; | 312 | return -EINVAL; |
| 269 | audit_failure = state; | 313 | |
| 270 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 314 | if (sid) { |
| 315 | char *ctx = NULL; | ||
| 316 | u32 len; | ||
| 317 | int rc; | ||
| 318 | if ((rc = selinux_ctxid_to_string(sid, &ctx, &len))) | ||
| 319 | return rc; | ||
| 320 | else | ||
| 321 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 322 | "audit_failure=%d old=%d by auid=%u subj=%s", | ||
| 323 | state, old, loginuid, ctx); | ||
| 324 | kfree(ctx); | ||
| 325 | } else | ||
| 326 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 271 | "audit_failure=%d old=%d by auid=%u", | 327 | "audit_failure=%d old=%d by auid=%u", |
| 272 | audit_failure, old, loginuid); | 328 | state, old, loginuid); |
| 329 | audit_failure = state; | ||
| 273 | return old; | 330 | return old; |
| 274 | } | 331 | } |
| 275 | 332 | ||
| @@ -387,7 +444,7 @@ static int audit_netlink_ok(kernel_cap_t eff_cap, u16 msg_type) | |||
| 387 | 444 | ||
| 388 | static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 445 | static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
| 389 | { | 446 | { |
| 390 | u32 uid, pid, seq; | 447 | u32 uid, pid, seq, sid; |
| 391 | void *data; | 448 | void *data; |
| 392 | struct audit_status *status_get, status_set; | 449 | struct audit_status *status_get, status_set; |
| 393 | int err; | 450 | int err; |
| @@ -413,6 +470,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 413 | pid = NETLINK_CREDS(skb)->pid; | 470 | pid = NETLINK_CREDS(skb)->pid; |
| 414 | uid = NETLINK_CREDS(skb)->uid; | 471 | uid = NETLINK_CREDS(skb)->uid; |
| 415 | loginuid = NETLINK_CB(skb).loginuid; | 472 | loginuid = NETLINK_CB(skb).loginuid; |
| 473 | sid = NETLINK_CB(skb).sid; | ||
| 416 | seq = nlh->nlmsg_seq; | 474 | seq = nlh->nlmsg_seq; |
| 417 | data = NLMSG_DATA(nlh); | 475 | data = NLMSG_DATA(nlh); |
| 418 | 476 | ||
| @@ -433,25 +491,43 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 433 | return -EINVAL; | 491 | return -EINVAL; |
| 434 | status_get = (struct audit_status *)data; | 492 | status_get = (struct audit_status *)data; |
| 435 | if (status_get->mask & AUDIT_STATUS_ENABLED) { | 493 | if (status_get->mask & AUDIT_STATUS_ENABLED) { |
| 436 | err = audit_set_enabled(status_get->enabled, loginuid); | 494 | err = audit_set_enabled(status_get->enabled, |
| 495 | loginuid, sid); | ||
| 437 | if (err < 0) return err; | 496 | if (err < 0) return err; |
| 438 | } | 497 | } |
| 439 | if (status_get->mask & AUDIT_STATUS_FAILURE) { | 498 | if (status_get->mask & AUDIT_STATUS_FAILURE) { |
| 440 | err = audit_set_failure(status_get->failure, loginuid); | 499 | err = audit_set_failure(status_get->failure, |
| 500 | loginuid, sid); | ||
| 441 | if (err < 0) return err; | 501 | if (err < 0) return err; |
| 442 | } | 502 | } |
| 443 | if (status_get->mask & AUDIT_STATUS_PID) { | 503 | if (status_get->mask & AUDIT_STATUS_PID) { |
| 444 | int old = audit_pid; | 504 | int old = audit_pid; |
| 505 | if (sid) { | ||
| 506 | char *ctx = NULL; | ||
| 507 | u32 len; | ||
| 508 | int rc; | ||
| 509 | if ((rc = selinux_ctxid_to_string( | ||
| 510 | sid, &ctx, &len))) | ||
| 511 | return rc; | ||
| 512 | else | ||
| 513 | audit_log(NULL, GFP_KERNEL, | ||
| 514 | AUDIT_CONFIG_CHANGE, | ||
| 515 | "audit_pid=%d old=%d by auid=%u subj=%s", | ||
| 516 | status_get->pid, old, | ||
| 517 | loginuid, ctx); | ||
| 518 | kfree(ctx); | ||
| 519 | } else | ||
| 520 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 521 | "audit_pid=%d old=%d by auid=%u", | ||
| 522 | status_get->pid, old, loginuid); | ||
| 445 | audit_pid = status_get->pid; | 523 | audit_pid = status_get->pid; |
| 446 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 447 | "audit_pid=%d old=%d by auid=%u", | ||
| 448 | audit_pid, old, loginuid); | ||
| 449 | } | 524 | } |
| 450 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) | 525 | if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) |
| 451 | audit_set_rate_limit(status_get->rate_limit, loginuid); | 526 | audit_set_rate_limit(status_get->rate_limit, |
| 527 | loginuid, sid); | ||
| 452 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) | 528 | if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) |
| 453 | audit_set_backlog_limit(status_get->backlog_limit, | 529 | audit_set_backlog_limit(status_get->backlog_limit, |
| 454 | loginuid); | 530 | loginuid, sid); |
| 455 | break; | 531 | break; |
| 456 | case AUDIT_USER: | 532 | case AUDIT_USER: |
| 457 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: | 533 | case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG: |
| @@ -465,8 +541,23 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 465 | ab = audit_log_start(NULL, GFP_KERNEL, msg_type); | 541 | ab = audit_log_start(NULL, GFP_KERNEL, msg_type); |
| 466 | if (ab) { | 542 | if (ab) { |
| 467 | audit_log_format(ab, | 543 | audit_log_format(ab, |
| 468 | "user pid=%d uid=%u auid=%u msg='%.1024s'", | 544 | "user pid=%d uid=%u auid=%u", |
| 469 | pid, uid, loginuid, (char *)data); | 545 | pid, uid, loginuid); |
| 546 | if (sid) { | ||
| 547 | char *ctx = NULL; | ||
| 548 | u32 len; | ||
| 549 | if (selinux_ctxid_to_string( | ||
| 550 | sid, &ctx, &len)) { | ||
| 551 | audit_log_format(ab, | ||
| 552 | " ssid=%u", sid); | ||
| 553 | /* Maybe call audit_panic? */ | ||
| 554 | } else | ||
| 555 | audit_log_format(ab, | ||
| 556 | " subj=%s", ctx); | ||
| 557 | kfree(ctx); | ||
| 558 | } | ||
| 559 | audit_log_format(ab, " msg='%.1024s'", | ||
| 560 | (char *)data); | ||
| 470 | audit_set_pid(ab, pid); | 561 | audit_set_pid(ab, pid); |
| 471 | audit_log_end(ab); | 562 | audit_log_end(ab); |
| 472 | } | 563 | } |
| @@ -480,7 +571,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 480 | case AUDIT_LIST: | 571 | case AUDIT_LIST: |
| 481 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 572 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
| 482 | uid, seq, data, nlmsg_len(nlh), | 573 | uid, seq, data, nlmsg_len(nlh), |
| 483 | loginuid); | 574 | loginuid, sid); |
| 484 | break; | 575 | break; |
| 485 | case AUDIT_ADD_RULE: | 576 | case AUDIT_ADD_RULE: |
| 486 | case AUDIT_DEL_RULE: | 577 | case AUDIT_DEL_RULE: |
| @@ -490,7 +581,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 490 | case AUDIT_LIST_RULES: | 581 | case AUDIT_LIST_RULES: |
| 491 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, | 582 | err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid, |
| 492 | uid, seq, data, nlmsg_len(nlh), | 583 | uid, seq, data, nlmsg_len(nlh), |
| 493 | loginuid); | 584 | loginuid, sid); |
| 494 | break; | 585 | break; |
| 495 | case AUDIT_SIGNAL_INFO: | 586 | case AUDIT_SIGNAL_INFO: |
| 496 | sig_data.uid = audit_sig_uid; | 587 | sig_data.uid = audit_sig_uid; |
| @@ -564,6 +655,11 @@ static int __init audit_init(void) | |||
| 564 | skb_queue_head_init(&audit_skb_queue); | 655 | skb_queue_head_init(&audit_skb_queue); |
| 565 | audit_initialized = 1; | 656 | audit_initialized = 1; |
| 566 | audit_enabled = audit_default; | 657 | audit_enabled = audit_default; |
| 658 | |||
| 659 | /* Register the callback with selinux. This callback will be invoked | ||
| 660 | * when a new policy is loaded. */ | ||
| 661 | selinux_audit_set_callback(&selinux_audit_rule_update); | ||
| 662 | |||
| 567 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); | 663 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); |
| 568 | return 0; | 664 | return 0; |
| 569 | } | 665 | } |
diff --git a/kernel/audit.h b/kernel/audit.h index bc5392076e2b..6f733920fd32 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
| @@ -54,9 +54,11 @@ enum audit_state { | |||
| 54 | 54 | ||
| 55 | /* Rule lists */ | 55 | /* Rule lists */ |
| 56 | struct audit_field { | 56 | struct audit_field { |
| 57 | u32 type; | 57 | u32 type; |
| 58 | u32 val; | 58 | u32 val; |
| 59 | u32 op; | 59 | u32 op; |
| 60 | char *se_str; | ||
| 61 | struct selinux_audit_rule *se_rule; | ||
| 60 | }; | 62 | }; |
| 61 | 63 | ||
| 62 | struct audit_krule { | 64 | struct audit_krule { |
| @@ -86,3 +88,5 @@ extern void audit_send_reply(int pid, int seq, int type, | |||
| 86 | extern void audit_log_lost(const char *message); | 88 | extern void audit_log_lost(const char *message); |
| 87 | extern void audit_panic(const char *message); | 89 | extern void audit_panic(const char *message); |
| 88 | extern struct mutex audit_netlink_mutex; | 90 | extern struct mutex audit_netlink_mutex; |
| 91 | |||
| 92 | extern int selinux_audit_rule_update(void); | ||
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index d3a8539f3a83..7c134906d689 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/audit.h> | 23 | #include <linux/audit.h> |
| 24 | #include <linux/kthread.h> | 24 | #include <linux/kthread.h> |
| 25 | #include <linux/netlink.h> | 25 | #include <linux/netlink.h> |
| 26 | #include <linux/selinux.h> | ||
| 26 | #include "audit.h" | 27 | #include "audit.h" |
| 27 | 28 | ||
| 28 | /* There are three lists of rules -- one to search at task creation | 29 | /* There are three lists of rules -- one to search at task creation |
| @@ -42,6 +43,13 @@ struct list_head audit_filter_list[AUDIT_NR_FILTERS] = { | |||
| 42 | 43 | ||
| 43 | static inline void audit_free_rule(struct audit_entry *e) | 44 | static inline void audit_free_rule(struct audit_entry *e) |
| 44 | { | 45 | { |
| 46 | int i; | ||
| 47 | if (e->rule.fields) | ||
| 48 | for (i = 0; i < e->rule.field_count; i++) { | ||
| 49 | struct audit_field *f = &e->rule.fields[i]; | ||
| 50 | kfree(f->se_str); | ||
| 51 | selinux_audit_rule_free(f->se_rule); | ||
| 52 | } | ||
| 45 | kfree(e->rule.fields); | 53 | kfree(e->rule.fields); |
| 46 | kfree(e); | 54 | kfree(e); |
| 47 | } | 55 | } |
| @@ -52,9 +60,29 @@ static inline void audit_free_rule_rcu(struct rcu_head *head) | |||
| 52 | audit_free_rule(e); | 60 | audit_free_rule(e); |
| 53 | } | 61 | } |
| 54 | 62 | ||
| 63 | /* Initialize an audit filterlist entry. */ | ||
| 64 | static inline struct audit_entry *audit_init_entry(u32 field_count) | ||
| 65 | { | ||
| 66 | struct audit_entry *entry; | ||
| 67 | struct audit_field *fields; | ||
| 68 | |||
| 69 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | ||
| 70 | if (unlikely(!entry)) | ||
| 71 | return NULL; | ||
| 72 | |||
| 73 | fields = kzalloc(sizeof(*fields) * field_count, GFP_KERNEL); | ||
| 74 | if (unlikely(!fields)) { | ||
| 75 | kfree(entry); | ||
| 76 | return NULL; | ||
| 77 | } | ||
| 78 | entry->rule.fields = fields; | ||
| 79 | |||
| 80 | return entry; | ||
| 81 | } | ||
| 82 | |||
| 55 | /* Unpack a filter field's string representation from user-space | 83 | /* Unpack a filter field's string representation from user-space |
| 56 | * buffer. */ | 84 | * buffer. */ |
| 57 | static __attribute__((unused)) char *audit_unpack_string(void **bufp, size_t *remain, size_t len) | 85 | static char *audit_unpack_string(void **bufp, size_t *remain, size_t len) |
| 58 | { | 86 | { |
| 59 | char *str; | 87 | char *str; |
| 60 | 88 | ||
| @@ -84,7 +112,6 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) | |||
| 84 | { | 112 | { |
| 85 | unsigned listnr; | 113 | unsigned listnr; |
| 86 | struct audit_entry *entry; | 114 | struct audit_entry *entry; |
| 87 | struct audit_field *fields; | ||
| 88 | int i, err; | 115 | int i, err; |
| 89 | 116 | ||
| 90 | err = -EINVAL; | 117 | err = -EINVAL; |
| @@ -108,23 +135,14 @@ static inline struct audit_entry *audit_to_entry_common(struct audit_rule *rule) | |||
| 108 | goto exit_err; | 135 | goto exit_err; |
| 109 | 136 | ||
| 110 | err = -ENOMEM; | 137 | err = -ENOMEM; |
| 111 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); | 138 | entry = audit_init_entry(rule->field_count); |
| 112 | if (unlikely(!entry)) | 139 | if (!entry) |
| 113 | goto exit_err; | ||
| 114 | fields = kmalloc(sizeof(*fields) * rule->field_count, GFP_KERNEL); | ||
| 115 | if (unlikely(!fields)) { | ||
| 116 | kfree(entry); | ||
| 117 | goto exit_err; | 140 | goto exit_err; |
| 118 | } | ||
| 119 | |||
| 120 | memset(&entry->rule, 0, sizeof(struct audit_krule)); | ||
| 121 | memset(fields, 0, sizeof(struct audit_field)); | ||
| 122 | 141 | ||
| 123 | entry->rule.flags = rule->flags & AUDIT_FILTER_PREPEND; | 142 | entry->rule.flags = rule->flags & AUDIT_FILTER_PREPEND; |
| 124 | entry->rule.listnr = listnr; | 143 | entry->rule.listnr = listnr; |
| 125 | entry->rule.action = rule->action; | 144 | entry->rule.action = rule->action; |
| 126 | entry->rule.field_count = rule->field_count; | 145 | entry->rule.field_count = rule->field_count; |
| 127 | entry->rule.fields = fields; | ||
| 128 | 146 | ||
| 129 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) | 147 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) |
| 130 | entry->rule.mask[i] = rule->mask[i]; | 148 | entry->rule.mask[i] = rule->mask[i]; |
| @@ -150,15 +168,20 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) | |||
| 150 | for (i = 0; i < rule->field_count; i++) { | 168 | for (i = 0; i < rule->field_count; i++) { |
| 151 | struct audit_field *f = &entry->rule.fields[i]; | 169 | struct audit_field *f = &entry->rule.fields[i]; |
| 152 | 170 | ||
| 153 | if (rule->fields[i] & AUDIT_UNUSED_BITS) { | ||
| 154 | err = -EINVAL; | ||
| 155 | goto exit_free; | ||
| 156 | } | ||
| 157 | |||
| 158 | f->op = rule->fields[i] & (AUDIT_NEGATE|AUDIT_OPERATORS); | 171 | f->op = rule->fields[i] & (AUDIT_NEGATE|AUDIT_OPERATORS); |
| 159 | f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS); | 172 | f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS); |
| 160 | f->val = rule->values[i]; | 173 | f->val = rule->values[i]; |
| 161 | 174 | ||
| 175 | if (f->type & AUDIT_UNUSED_BITS || | ||
| 176 | f->type == AUDIT_SE_USER || | ||
| 177 | f->type == AUDIT_SE_ROLE || | ||
| 178 | f->type == AUDIT_SE_TYPE || | ||
| 179 | f->type == AUDIT_SE_SEN || | ||
| 180 | f->type == AUDIT_SE_CLR) { | ||
| 181 | err = -EINVAL; | ||
| 182 | goto exit_free; | ||
| 183 | } | ||
| 184 | |||
| 162 | entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1; | 185 | entry->rule.vers_ops = (f->op & AUDIT_OPERATORS) ? 2 : 1; |
| 163 | 186 | ||
| 164 | /* Support for legacy operators where | 187 | /* Support for legacy operators where |
| @@ -188,8 +211,9 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
| 188 | int err = 0; | 211 | int err = 0; |
| 189 | struct audit_entry *entry; | 212 | struct audit_entry *entry; |
| 190 | void *bufp; | 213 | void *bufp; |
| 191 | /* size_t remain = datasz - sizeof(struct audit_rule_data); */ | 214 | size_t remain = datasz - sizeof(struct audit_rule_data); |
| 192 | int i; | 215 | int i; |
| 216 | char *str; | ||
| 193 | 217 | ||
| 194 | entry = audit_to_entry_common((struct audit_rule *)data); | 218 | entry = audit_to_entry_common((struct audit_rule *)data); |
| 195 | if (IS_ERR(entry)) | 219 | if (IS_ERR(entry)) |
| @@ -207,10 +231,35 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, | |||
| 207 | 231 | ||
| 208 | f->op = data->fieldflags[i] & AUDIT_OPERATORS; | 232 | f->op = data->fieldflags[i] & AUDIT_OPERATORS; |
| 209 | f->type = data->fields[i]; | 233 | f->type = data->fields[i]; |
| 234 | f->val = data->values[i]; | ||
| 235 | f->se_str = NULL; | ||
| 236 | f->se_rule = NULL; | ||
| 210 | switch(f->type) { | 237 | switch(f->type) { |
| 211 | /* call type-specific conversion routines here */ | 238 | case AUDIT_SE_USER: |
| 212 | default: | 239 | case AUDIT_SE_ROLE: |
| 213 | f->val = data->values[i]; | 240 | case AUDIT_SE_TYPE: |
| 241 | case AUDIT_SE_SEN: | ||
| 242 | case AUDIT_SE_CLR: | ||
| 243 | str = audit_unpack_string(&bufp, &remain, f->val); | ||
| 244 | if (IS_ERR(str)) | ||
| 245 | goto exit_free; | ||
| 246 | entry->rule.buflen += f->val; | ||
| 247 | |||
| 248 | err = selinux_audit_rule_init(f->type, f->op, str, | ||
| 249 | &f->se_rule); | ||
| 250 | /* Keep currently invalid fields around in case they | ||
| 251 | * become valid after a policy reload. */ | ||
| 252 | if (err == -EINVAL) { | ||
| 253 | printk(KERN_WARNING "audit rule for selinux " | ||
| 254 | "\'%s\' is invalid\n", str); | ||
| 255 | err = 0; | ||
| 256 | } | ||
| 257 | if (err) { | ||
| 258 | kfree(str); | ||
| 259 | goto exit_free; | ||
| 260 | } else | ||
| 261 | f->se_str = str; | ||
| 262 | break; | ||
| 214 | } | 263 | } |
| 215 | } | 264 | } |
| 216 | 265 | ||
| @@ -286,7 +335,14 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) | |||
| 286 | data->fields[i] = f->type; | 335 | data->fields[i] = f->type; |
| 287 | data->fieldflags[i] = f->op; | 336 | data->fieldflags[i] = f->op; |
| 288 | switch(f->type) { | 337 | switch(f->type) { |
| 289 | /* call type-specific conversion routines here */ | 338 | case AUDIT_SE_USER: |
| 339 | case AUDIT_SE_ROLE: | ||
| 340 | case AUDIT_SE_TYPE: | ||
| 341 | case AUDIT_SE_SEN: | ||
| 342 | case AUDIT_SE_CLR: | ||
| 343 | data->buflen += data->values[i] = | ||
| 344 | audit_pack_string(&bufp, f->se_str); | ||
| 345 | break; | ||
| 290 | default: | 346 | default: |
| 291 | data->values[i] = f->val; | 347 | data->values[i] = f->val; |
| 292 | } | 348 | } |
| @@ -314,7 +370,14 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b) | |||
| 314 | return 1; | 370 | return 1; |
| 315 | 371 | ||
| 316 | switch(a->fields[i].type) { | 372 | switch(a->fields[i].type) { |
| 317 | /* call type-specific comparison routines here */ | 373 | case AUDIT_SE_USER: |
| 374 | case AUDIT_SE_ROLE: | ||
| 375 | case AUDIT_SE_TYPE: | ||
| 376 | case AUDIT_SE_SEN: | ||
| 377 | case AUDIT_SE_CLR: | ||
| 378 | if (strcmp(a->fields[i].se_str, b->fields[i].se_str)) | ||
| 379 | return 1; | ||
| 380 | break; | ||
| 318 | default: | 381 | default: |
| 319 | if (a->fields[i].val != b->fields[i].val) | 382 | if (a->fields[i].val != b->fields[i].val) |
| 320 | return 1; | 383 | return 1; |
| @@ -328,6 +391,81 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b) | |||
| 328 | return 0; | 391 | return 0; |
| 329 | } | 392 | } |
| 330 | 393 | ||
| 394 | /* Duplicate selinux field information. The se_rule is opaque, so must be | ||
| 395 | * re-initialized. */ | ||
| 396 | static inline int audit_dupe_selinux_field(struct audit_field *df, | ||
| 397 | struct audit_field *sf) | ||
| 398 | { | ||
| 399 | int ret = 0; | ||
| 400 | char *se_str; | ||
| 401 | |||
| 402 | /* our own copy of se_str */ | ||
| 403 | se_str = kstrdup(sf->se_str, GFP_KERNEL); | ||
| 404 | if (unlikely(IS_ERR(se_str))) | ||
| 405 | return -ENOMEM; | ||
| 406 | df->se_str = se_str; | ||
| 407 | |||
| 408 | /* our own (refreshed) copy of se_rule */ | ||
| 409 | ret = selinux_audit_rule_init(df->type, df->op, df->se_str, | ||
| 410 | &df->se_rule); | ||
| 411 | /* Keep currently invalid fields around in case they | ||
| 412 | * become valid after a policy reload. */ | ||
| 413 | if (ret == -EINVAL) { | ||
| 414 | printk(KERN_WARNING "audit rule for selinux \'%s\' is " | ||
| 415 | "invalid\n", df->se_str); | ||
| 416 | ret = 0; | ||
| 417 | } | ||
| 418 | |||
| 419 | return ret; | ||
| 420 | } | ||
| 421 | |||
| 422 | /* Duplicate an audit rule. This will be a deep copy with the exception | ||
| 423 | * of the watch - that pointer is carried over. The selinux specific fields | ||
| 424 | * will be updated in the copy. The point is to be able to replace the old | ||
| 425 | * rule with the new rule in the filterlist, then free the old rule. */ | ||
| 426 | static struct audit_entry *audit_dupe_rule(struct audit_krule *old) | ||
| 427 | { | ||
| 428 | u32 fcount = old->field_count; | ||
| 429 | struct audit_entry *entry; | ||
| 430 | struct audit_krule *new; | ||
| 431 | int i, err = 0; | ||
| 432 | |||
| 433 | entry = audit_init_entry(fcount); | ||
| 434 | if (unlikely(!entry)) | ||
| 435 | return ERR_PTR(-ENOMEM); | ||
| 436 | |||
| 437 | new = &entry->rule; | ||
| 438 | new->vers_ops = old->vers_ops; | ||
| 439 | new->flags = old->flags; | ||
| 440 | new->listnr = old->listnr; | ||
| 441 | new->action = old->action; | ||
| 442 | for (i = 0; i < AUDIT_BITMASK_SIZE; i++) | ||
| 443 | new->mask[i] = old->mask[i]; | ||
| 444 | new->buflen = old->buflen; | ||
| 445 | new->field_count = old->field_count; | ||
| 446 | memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount); | ||
| 447 | |||
| 448 | /* deep copy this information, updating the se_rule fields, because | ||
| 449 | * the originals will all be freed when the old rule is freed. */ | ||
| 450 | for (i = 0; i < fcount; i++) { | ||
| 451 | switch (new->fields[i].type) { | ||
| 452 | case AUDIT_SE_USER: | ||
| 453 | case AUDIT_SE_ROLE: | ||
| 454 | case AUDIT_SE_TYPE: | ||
| 455 | case AUDIT_SE_SEN: | ||
| 456 | case AUDIT_SE_CLR: | ||
| 457 | err = audit_dupe_selinux_field(&new->fields[i], | ||
| 458 | &old->fields[i]); | ||
| 459 | } | ||
| 460 | if (err) { | ||
| 461 | audit_free_rule(entry); | ||
| 462 | return ERR_PTR(err); | ||
| 463 | } | ||
| 464 | } | ||
| 465 | |||
| 466 | return entry; | ||
| 467 | } | ||
| 468 | |||
| 331 | /* Add rule to given filterlist if not a duplicate. Protected by | 469 | /* Add rule to given filterlist if not a duplicate. Protected by |
| 332 | * audit_netlink_mutex. */ | 470 | * audit_netlink_mutex. */ |
| 333 | static inline int audit_add_rule(struct audit_entry *entry, | 471 | static inline int audit_add_rule(struct audit_entry *entry, |
| @@ -448,9 +586,10 @@ static int audit_list_rules(void *_dest) | |||
| 448 | * @data: payload data | 586 | * @data: payload data |
| 449 | * @datasz: size of payload data | 587 | * @datasz: size of payload data |
| 450 | * @loginuid: loginuid of sender | 588 | * @loginuid: loginuid of sender |
| 589 | * @sid: SE Linux Security ID of sender | ||
| 451 | */ | 590 | */ |
| 452 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | 591 | int audit_receive_filter(int type, int pid, int uid, int seq, void *data, |
| 453 | size_t datasz, uid_t loginuid) | 592 | size_t datasz, uid_t loginuid, u32 sid) |
| 454 | { | 593 | { |
| 455 | struct task_struct *tsk; | 594 | struct task_struct *tsk; |
| 456 | int *dest; | 595 | int *dest; |
| @@ -493,9 +632,23 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
| 493 | 632 | ||
| 494 | err = audit_add_rule(entry, | 633 | err = audit_add_rule(entry, |
| 495 | &audit_filter_list[entry->rule.listnr]); | 634 | &audit_filter_list[entry->rule.listnr]); |
| 496 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 635 | if (sid) { |
| 497 | "auid=%u add rule to list=%d res=%d\n", | 636 | char *ctx = NULL; |
| 498 | loginuid, entry->rule.listnr, !err); | 637 | u32 len; |
| 638 | if (selinux_ctxid_to_string(sid, &ctx, &len)) { | ||
| 639 | /* Maybe call audit_panic? */ | ||
| 640 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 641 | "auid=%u ssid=%u add rule to list=%d res=%d", | ||
| 642 | loginuid, sid, entry->rule.listnr, !err); | ||
| 643 | } else | ||
| 644 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 645 | "auid=%u subj=%s add rule to list=%d res=%d", | ||
| 646 | loginuid, ctx, entry->rule.listnr, !err); | ||
| 647 | kfree(ctx); | ||
| 648 | } else | ||
| 649 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 650 | "auid=%u add rule to list=%d res=%d", | ||
| 651 | loginuid, entry->rule.listnr, !err); | ||
| 499 | 652 | ||
| 500 | if (err) | 653 | if (err) |
| 501 | audit_free_rule(entry); | 654 | audit_free_rule(entry); |
| @@ -511,9 +664,24 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
| 511 | 664 | ||
| 512 | err = audit_del_rule(entry, | 665 | err = audit_del_rule(entry, |
| 513 | &audit_filter_list[entry->rule.listnr]); | 666 | &audit_filter_list[entry->rule.listnr]); |
| 514 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | 667 | |
| 515 | "auid=%u remove rule from list=%d res=%d\n", | 668 | if (sid) { |
| 516 | loginuid, entry->rule.listnr, !err); | 669 | char *ctx = NULL; |
| 670 | u32 len; | ||
| 671 | if (selinux_ctxid_to_string(sid, &ctx, &len)) { | ||
| 672 | /* Maybe call audit_panic? */ | ||
| 673 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 674 | "auid=%u ssid=%u remove rule from list=%d res=%d", | ||
| 675 | loginuid, sid, entry->rule.listnr, !err); | ||
| 676 | } else | ||
| 677 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 678 | "auid=%u subj=%s remove rule from list=%d res=%d", | ||
| 679 | loginuid, ctx, entry->rule.listnr, !err); | ||
| 680 | kfree(ctx); | ||
| 681 | } else | ||
| 682 | audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, | ||
| 683 | "auid=%u remove rule from list=%d res=%d", | ||
| 684 | loginuid, entry->rule.listnr, !err); | ||
| 517 | 685 | ||
| 518 | audit_free_rule(entry); | 686 | audit_free_rule(entry); |
| 519 | break; | 687 | break; |
| @@ -628,3 +796,62 @@ unlock_and_return: | |||
| 628 | rcu_read_unlock(); | 796 | rcu_read_unlock(); |
| 629 | return result; | 797 | return result; |
| 630 | } | 798 | } |
| 799 | |||
| 800 | /* Check to see if the rule contains any selinux fields. Returns 1 if there | ||
| 801 | are selinux fields specified in the rule, 0 otherwise. */ | ||
| 802 | static inline int audit_rule_has_selinux(struct audit_krule *rule) | ||
| 803 | { | ||
| 804 | int i; | ||
| 805 | |||
| 806 | for (i = 0; i < rule->field_count; i++) { | ||
| 807 | struct audit_field *f = &rule->fields[i]; | ||
| 808 | switch (f->type) { | ||
| 809 | case AUDIT_SE_USER: | ||
| 810 | case AUDIT_SE_ROLE: | ||
| 811 | case AUDIT_SE_TYPE: | ||
| 812 | case AUDIT_SE_SEN: | ||
| 813 | case AUDIT_SE_CLR: | ||
| 814 | return 1; | ||
| 815 | } | ||
| 816 | } | ||
| 817 | |||
| 818 | return 0; | ||
| 819 | } | ||
| 820 | |||
| 821 | /* This function will re-initialize the se_rule field of all applicable rules. | ||
| 822 | * It will traverse the filter lists serarching for rules that contain selinux | ||
| 823 | * specific filter fields. When such a rule is found, it is copied, the | ||
| 824 | * selinux field is re-initialized, and the old rule is replaced with the | ||
| 825 | * updated rule. */ | ||
| 826 | int selinux_audit_rule_update(void) | ||
| 827 | { | ||
| 828 | struct audit_entry *entry, *n, *nentry; | ||
| 829 | int i, err = 0; | ||
| 830 | |||
| 831 | /* audit_netlink_mutex synchronizes the writers */ | ||
| 832 | mutex_lock(&audit_netlink_mutex); | ||
| 833 | |||
| 834 | for (i = 0; i < AUDIT_NR_FILTERS; i++) { | ||
| 835 | list_for_each_entry_safe(entry, n, &audit_filter_list[i], list) { | ||
| 836 | if (!audit_rule_has_selinux(&entry->rule)) | ||
| 837 | continue; | ||
| 838 | |||
| 839 | nentry = audit_dupe_rule(&entry->rule); | ||
| 840 | if (unlikely(IS_ERR(nentry))) { | ||
| 841 | /* save the first error encountered for the | ||
| 842 | * return value */ | ||
| 843 | if (!err) | ||
| 844 | err = PTR_ERR(nentry); | ||
| 845 | audit_panic("error updating selinux filters"); | ||
| 846 | list_del_rcu(&entry->list); | ||
| 847 | } else { | ||
| 848 | list_replace_rcu(&entry->list, &nentry->list); | ||
| 849 | } | ||
| 850 | call_rcu(&entry->rcu, audit_free_rule_rcu); | ||
| 851 | } | ||
| 852 | } | ||
| 853 | |||
| 854 | mutex_unlock(&audit_netlink_mutex); | ||
| 855 | |||
| 856 | return err; | ||
| 857 | } | ||
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 7f160df21a23..1c03a4ed1b27 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -58,6 +58,7 @@ | |||
| 58 | #include <linux/security.h> | 58 | #include <linux/security.h> |
| 59 | #include <linux/list.h> | 59 | #include <linux/list.h> |
| 60 | #include <linux/tty.h> | 60 | #include <linux/tty.h> |
| 61 | #include <linux/selinux.h> | ||
| 61 | 62 | ||
| 62 | #include "audit.h" | 63 | #include "audit.h" |
| 63 | 64 | ||
| @@ -89,7 +90,7 @@ struct audit_names { | |||
| 89 | uid_t uid; | 90 | uid_t uid; |
| 90 | gid_t gid; | 91 | gid_t gid; |
| 91 | dev_t rdev; | 92 | dev_t rdev; |
| 92 | char *ctx; | 93 | u32 osid; |
| 93 | }; | 94 | }; |
| 94 | 95 | ||
| 95 | struct audit_aux_data { | 96 | struct audit_aux_data { |
| @@ -106,7 +107,7 @@ struct audit_aux_data_ipcctl { | |||
| 106 | uid_t uid; | 107 | uid_t uid; |
| 107 | gid_t gid; | 108 | gid_t gid; |
| 108 | mode_t mode; | 109 | mode_t mode; |
| 109 | char *ctx; | 110 | u32 osid; |
| 110 | }; | 111 | }; |
| 111 | 112 | ||
| 112 | struct audit_aux_data_socketcall { | 113 | struct audit_aux_data_socketcall { |
| @@ -167,7 +168,8 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
| 167 | struct audit_context *ctx, | 168 | struct audit_context *ctx, |
| 168 | enum audit_state *state) | 169 | enum audit_state *state) |
| 169 | { | 170 | { |
| 170 | int i, j; | 171 | int i, j, need_sid = 1; |
| 172 | u32 sid; | ||
| 171 | 173 | ||
| 172 | for (i = 0; i < rule->field_count; i++) { | 174 | for (i = 0; i < rule->field_count; i++) { |
| 173 | struct audit_field *f = &rule->fields[i]; | 175 | struct audit_field *f = &rule->fields[i]; |
| @@ -257,6 +259,27 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
| 257 | if (ctx) | 259 | if (ctx) |
| 258 | result = audit_comparator(ctx->loginuid, f->op, f->val); | 260 | result = audit_comparator(ctx->loginuid, f->op, f->val); |
| 259 | break; | 261 | break; |
| 262 | case AUDIT_SE_USER: | ||
| 263 | case AUDIT_SE_ROLE: | ||
| 264 | case AUDIT_SE_TYPE: | ||
| 265 | case AUDIT_SE_SEN: | ||
| 266 | case AUDIT_SE_CLR: | ||
| 267 | /* NOTE: this may return negative values indicating | ||
| 268 | a temporary error. We simply treat this as a | ||
| 269 | match for now to avoid losing information that | ||
| 270 | may be wanted. An error message will also be | ||
| 271 | logged upon error */ | ||
| 272 | if (f->se_rule) { | ||
| 273 | if (need_sid) { | ||
| 274 | selinux_task_ctxid(tsk, &sid); | ||
| 275 | need_sid = 0; | ||
| 276 | } | ||
| 277 | result = selinux_audit_rule_match(sid, f->type, | ||
| 278 | f->op, | ||
| 279 | f->se_rule, | ||
| 280 | ctx); | ||
| 281 | } | ||
| 282 | break; | ||
| 260 | case AUDIT_ARG0: | 283 | case AUDIT_ARG0: |
| 261 | case AUDIT_ARG1: | 284 | case AUDIT_ARG1: |
| 262 | case AUDIT_ARG2: | 285 | case AUDIT_ARG2: |
| @@ -329,7 +352,6 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, | |||
| 329 | return AUDIT_BUILD_CONTEXT; | 352 | return AUDIT_BUILD_CONTEXT; |
| 330 | } | 353 | } |
| 331 | 354 | ||
| 332 | /* This should be called with task_lock() held. */ | ||
| 333 | static inline struct audit_context *audit_get_context(struct task_struct *tsk, | 355 | static inline struct audit_context *audit_get_context(struct task_struct *tsk, |
| 334 | int return_valid, | 356 | int return_valid, |
| 335 | int return_code) | 357 | int return_code) |
| @@ -391,9 +413,6 @@ static inline void audit_free_names(struct audit_context *context) | |||
| 391 | #endif | 413 | #endif |
| 392 | 414 | ||
| 393 | for (i = 0; i < context->name_count; i++) { | 415 | for (i = 0; i < context->name_count; i++) { |
| 394 | char *p = context->names[i].ctx; | ||
| 395 | context->names[i].ctx = NULL; | ||
| 396 | kfree(p); | ||
| 397 | if (context->names[i].name) | 416 | if (context->names[i].name) |
| 398 | __putname(context->names[i].name); | 417 | __putname(context->names[i].name); |
| 399 | } | 418 | } |
| @@ -416,11 +435,6 @@ static inline void audit_free_aux(struct audit_context *context) | |||
| 416 | dput(axi->dentry); | 435 | dput(axi->dentry); |
| 417 | mntput(axi->mnt); | 436 | mntput(axi->mnt); |
| 418 | } | 437 | } |
| 419 | if ( aux->type == AUDIT_IPC ) { | ||
| 420 | struct audit_aux_data_ipcctl *axi = (void *)aux; | ||
| 421 | if (axi->ctx) | ||
| 422 | kfree(axi->ctx); | ||
| 423 | } | ||
| 424 | 438 | ||
| 425 | context->aux = aux->next; | 439 | context->aux = aux->next; |
| 426 | kfree(aux); | 440 | kfree(aux); |
| @@ -506,7 +520,7 @@ static inline void audit_free_context(struct audit_context *context) | |||
| 506 | printk(KERN_ERR "audit: freed %d contexts\n", count); | 520 | printk(KERN_ERR "audit: freed %d contexts\n", count); |
| 507 | } | 521 | } |
| 508 | 522 | ||
| 509 | static void audit_log_task_context(struct audit_buffer *ab, gfp_t gfp_mask) | 523 | static void audit_log_task_context(struct audit_buffer *ab) |
| 510 | { | 524 | { |
| 511 | char *ctx = NULL; | 525 | char *ctx = NULL; |
| 512 | ssize_t len = 0; | 526 | ssize_t len = 0; |
| @@ -518,7 +532,7 @@ static void audit_log_task_context(struct audit_buffer *ab, gfp_t gfp_mask) | |||
| 518 | return; | 532 | return; |
| 519 | } | 533 | } |
| 520 | 534 | ||
| 521 | ctx = kmalloc(len, gfp_mask); | 535 | ctx = kmalloc(len, GFP_KERNEL); |
| 522 | if (!ctx) | 536 | if (!ctx) |
| 523 | goto error_path; | 537 | goto error_path; |
| 524 | 538 | ||
| @@ -536,47 +550,46 @@ error_path: | |||
| 536 | return; | 550 | return; |
| 537 | } | 551 | } |
| 538 | 552 | ||
| 539 | static void audit_log_task_info(struct audit_buffer *ab, gfp_t gfp_mask) | 553 | static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) |
| 540 | { | 554 | { |
| 541 | char name[sizeof(current->comm)]; | 555 | char name[sizeof(tsk->comm)]; |
| 542 | struct mm_struct *mm = current->mm; | 556 | struct mm_struct *mm = tsk->mm; |
| 543 | struct vm_area_struct *vma; | 557 | struct vm_area_struct *vma; |
| 544 | 558 | ||
| 545 | get_task_comm(name, current); | 559 | /* tsk == current */ |
| 560 | |||
| 561 | get_task_comm(name, tsk); | ||
| 546 | audit_log_format(ab, " comm="); | 562 | audit_log_format(ab, " comm="); |
| 547 | audit_log_untrustedstring(ab, name); | 563 | audit_log_untrustedstring(ab, name); |
| 548 | 564 | ||
| 549 | if (!mm) | 565 | if (mm) { |
| 550 | return; | 566 | down_read(&mm->mmap_sem); |
| 551 | 567 | vma = mm->mmap; | |
| 552 | /* | 568 | while (vma) { |
| 553 | * this is brittle; all callers that pass GFP_ATOMIC will have | 569 | if ((vma->vm_flags & VM_EXECUTABLE) && |
| 554 | * NULL current->mm and we won't get here. | 570 | vma->vm_file) { |
| 555 | */ | 571 | audit_log_d_path(ab, "exe=", |
| 556 | down_read(&mm->mmap_sem); | 572 | vma->vm_file->f_dentry, |
| 557 | vma = mm->mmap; | 573 | vma->vm_file->f_vfsmnt); |
| 558 | while (vma) { | 574 | break; |
| 559 | if ((vma->vm_flags & VM_EXECUTABLE) && | 575 | } |
| 560 | vma->vm_file) { | 576 | vma = vma->vm_next; |
| 561 | audit_log_d_path(ab, "exe=", | ||
| 562 | vma->vm_file->f_dentry, | ||
| 563 | vma->vm_file->f_vfsmnt); | ||
| 564 | break; | ||
| 565 | } | 577 | } |
| 566 | vma = vma->vm_next; | 578 | up_read(&mm->mmap_sem); |
| 567 | } | 579 | } |
| 568 | up_read(&mm->mmap_sem); | 580 | audit_log_task_context(ab); |
| 569 | audit_log_task_context(ab, gfp_mask); | ||
| 570 | } | 581 | } |
| 571 | 582 | ||
| 572 | static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask) | 583 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) |
| 573 | { | 584 | { |
| 574 | int i; | 585 | int i, call_panic = 0; |
| 575 | struct audit_buffer *ab; | 586 | struct audit_buffer *ab; |
| 576 | struct audit_aux_data *aux; | 587 | struct audit_aux_data *aux; |
| 577 | const char *tty; | 588 | const char *tty; |
| 578 | 589 | ||
| 579 | ab = audit_log_start(context, gfp_mask, AUDIT_SYSCALL); | 590 | /* tsk == current */ |
| 591 | |||
| 592 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL); | ||
| 580 | if (!ab) | 593 | if (!ab) |
| 581 | return; /* audit_panic has been called */ | 594 | return; /* audit_panic has been called */ |
| 582 | audit_log_format(ab, "arch=%x syscall=%d", | 595 | audit_log_format(ab, "arch=%x syscall=%d", |
| @@ -587,8 +600,8 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask) | |||
| 587 | audit_log_format(ab, " success=%s exit=%ld", | 600 | audit_log_format(ab, " success=%s exit=%ld", |
| 588 | (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", | 601 | (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", |
| 589 | context->return_code); | 602 | context->return_code); |
| 590 | if (current->signal->tty && current->signal->tty->name) | 603 | if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name) |
| 591 | tty = current->signal->tty->name; | 604 | tty = tsk->signal->tty->name; |
| 592 | else | 605 | else |
| 593 | tty = "(none)"; | 606 | tty = "(none)"; |
| 594 | audit_log_format(ab, | 607 | audit_log_format(ab, |
| @@ -607,12 +620,12 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask) | |||
| 607 | context->gid, | 620 | context->gid, |
| 608 | context->euid, context->suid, context->fsuid, | 621 | context->euid, context->suid, context->fsuid, |
| 609 | context->egid, context->sgid, context->fsgid, tty); | 622 | context->egid, context->sgid, context->fsgid, tty); |
| 610 | audit_log_task_info(ab, gfp_mask); | 623 | audit_log_task_info(ab, tsk); |
| 611 | audit_log_end(ab); | 624 | audit_log_end(ab); |
| 612 | 625 | ||
| 613 | for (aux = context->aux; aux; aux = aux->next) { | 626 | for (aux = context->aux; aux; aux = aux->next) { |
| 614 | 627 | ||
| 615 | ab = audit_log_start(context, gfp_mask, aux->type); | 628 | ab = audit_log_start(context, GFP_KERNEL, aux->type); |
| 616 | if (!ab) | 629 | if (!ab) |
| 617 | continue; /* audit_panic has been called */ | 630 | continue; /* audit_panic has been called */ |
| 618 | 631 | ||
| @@ -620,8 +633,39 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask) | |||
| 620 | case AUDIT_IPC: { | 633 | case AUDIT_IPC: { |
| 621 | struct audit_aux_data_ipcctl *axi = (void *)aux; | 634 | struct audit_aux_data_ipcctl *axi = (void *)aux; |
| 622 | audit_log_format(ab, | 635 | audit_log_format(ab, |
| 623 | " qbytes=%lx iuid=%u igid=%u mode=%x obj=%s", | 636 | " qbytes=%lx iuid=%u igid=%u mode=%x", |
| 624 | axi->qbytes, axi->uid, axi->gid, axi->mode, axi->ctx); | 637 | axi->qbytes, axi->uid, axi->gid, axi->mode); |
| 638 | if (axi->osid != 0) { | ||
| 639 | char *ctx = NULL; | ||
| 640 | u32 len; | ||
| 641 | if (selinux_ctxid_to_string( | ||
| 642 | axi->osid, &ctx, &len)) { | ||
| 643 | audit_log_format(ab, " osid=%u", | ||
| 644 | axi->osid); | ||
| 645 | call_panic = 1; | ||
| 646 | } else | ||
| 647 | audit_log_format(ab, " obj=%s", ctx); | ||
| 648 | kfree(ctx); | ||
| 649 | } | ||
| 650 | break; } | ||
| 651 | |||
| 652 | case AUDIT_IPC_SET_PERM: { | ||
| 653 | struct audit_aux_data_ipcctl *axi = (void *)aux; | ||
| 654 | audit_log_format(ab, | ||
| 655 | " new qbytes=%lx new iuid=%u new igid=%u new mode=%x", | ||
| 656 | axi->qbytes, axi->uid, axi->gid, axi->mode); | ||
| 657 | if (axi->osid != 0) { | ||
| 658 | char *ctx = NULL; | ||
| 659 | u32 len; | ||
| 660 | if (selinux_ctxid_to_string( | ||
| 661 | axi->osid, &ctx, &len)) { | ||
| 662 | audit_log_format(ab, " osid=%u", | ||
| 663 | axi->osid); | ||
| 664 | call_panic = 1; | ||
| 665 | } else | ||
| 666 | audit_log_format(ab, " obj=%s", ctx); | ||
| 667 | kfree(ctx); | ||
| 668 | } | ||
| 625 | break; } | 669 | break; } |
| 626 | 670 | ||
| 627 | case AUDIT_SOCKETCALL: { | 671 | case AUDIT_SOCKETCALL: { |
| @@ -649,7 +693,7 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask) | |||
| 649 | } | 693 | } |
| 650 | 694 | ||
| 651 | if (context->pwd && context->pwdmnt) { | 695 | if (context->pwd && context->pwdmnt) { |
| 652 | ab = audit_log_start(context, gfp_mask, AUDIT_CWD); | 696 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); |
| 653 | if (ab) { | 697 | if (ab) { |
| 654 | audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt); | 698 | audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt); |
| 655 | audit_log_end(ab); | 699 | audit_log_end(ab); |
| @@ -659,7 +703,7 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask) | |||
| 659 | unsigned long ino = context->names[i].ino; | 703 | unsigned long ino = context->names[i].ino; |
| 660 | unsigned long pino = context->names[i].pino; | 704 | unsigned long pino = context->names[i].pino; |
| 661 | 705 | ||
| 662 | ab = audit_log_start(context, gfp_mask, AUDIT_PATH); | 706 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH); |
| 663 | if (!ab) | 707 | if (!ab) |
| 664 | continue; /* audit_panic has been called */ | 708 | continue; /* audit_panic has been called */ |
| 665 | 709 | ||
| @@ -685,32 +729,35 @@ static void audit_log_exit(struct audit_context *context, gfp_t gfp_mask) | |||
| 685 | context->names[i].gid, | 729 | context->names[i].gid, |
| 686 | MAJOR(context->names[i].rdev), | 730 | MAJOR(context->names[i].rdev), |
| 687 | MINOR(context->names[i].rdev)); | 731 | MINOR(context->names[i].rdev)); |
| 688 | if (context->names[i].ctx) { | 732 | if (context->names[i].osid != 0) { |
| 689 | audit_log_format(ab, " obj=%s", | 733 | char *ctx = NULL; |
| 690 | context->names[i].ctx); | 734 | u32 len; |
| 735 | if (selinux_ctxid_to_string( | ||
| 736 | context->names[i].osid, &ctx, &len)) { | ||
| 737 | audit_log_format(ab, " osid=%u", | ||
| 738 | context->names[i].osid); | ||
| 739 | call_panic = 2; | ||
| 740 | } else | ||
| 741 | audit_log_format(ab, " obj=%s", ctx); | ||
| 742 | kfree(ctx); | ||
| 691 | } | 743 | } |
| 692 | 744 | ||
| 693 | audit_log_end(ab); | 745 | audit_log_end(ab); |
| 694 | } | 746 | } |
| 747 | if (call_panic) | ||
| 748 | audit_panic("error converting sid to string"); | ||
| 695 | } | 749 | } |
| 696 | 750 | ||
| 697 | /** | 751 | /** |
| 698 | * audit_free - free a per-task audit context | 752 | * audit_free - free a per-task audit context |
| 699 | * @tsk: task whose audit context block to free | 753 | * @tsk: task whose audit context block to free |
| 700 | * | 754 | * |
| 701 | * Called from copy_process and __put_task_struct. | 755 | * Called from copy_process and do_exit |
| 702 | */ | 756 | */ |
| 703 | void audit_free(struct task_struct *tsk) | 757 | void audit_free(struct task_struct *tsk) |
| 704 | { | 758 | { |
| 705 | struct audit_context *context; | 759 | struct audit_context *context; |
| 706 | 760 | ||
| 707 | /* | ||
| 708 | * No need to lock the task - when we execute audit_free() | ||
| 709 | * then the task has no external references anymore, and | ||
| 710 | * we are tearing it down. (The locking also confuses | ||
| 711 | * DEBUG_LOCKDEP - this freeing may occur in softirq | ||
| 712 | * contexts as well, via RCU.) | ||
| 713 | */ | ||
| 714 | context = audit_get_context(tsk, 0, 0); | 761 | context = audit_get_context(tsk, 0, 0); |
| 715 | if (likely(!context)) | 762 | if (likely(!context)) |
| 716 | return; | 763 | return; |
| @@ -719,8 +766,9 @@ void audit_free(struct task_struct *tsk) | |||
| 719 | * function (e.g., exit_group), then free context block. | 766 | * function (e.g., exit_group), then free context block. |
| 720 | * We use GFP_ATOMIC here because we might be doing this | 767 | * We use GFP_ATOMIC here because we might be doing this |
| 721 | * in the context of the idle thread */ | 768 | * in the context of the idle thread */ |
| 769 | /* that can happen only if we are called from do_exit() */ | ||
| 722 | if (context->in_syscall && context->auditable) | 770 | if (context->in_syscall && context->auditable) |
| 723 | audit_log_exit(context, GFP_ATOMIC); | 771 | audit_log_exit(context, tsk); |
| 724 | 772 | ||
| 725 | audit_free_context(context); | 773 | audit_free_context(context); |
| 726 | } | 774 | } |
| @@ -743,10 +791,11 @@ void audit_free(struct task_struct *tsk) | |||
| 743 | * will only be written if another part of the kernel requests that it | 791 | * will only be written if another part of the kernel requests that it |
| 744 | * be written). | 792 | * be written). |
| 745 | */ | 793 | */ |
| 746 | void audit_syscall_entry(struct task_struct *tsk, int arch, int major, | 794 | void audit_syscall_entry(int arch, int major, |
| 747 | unsigned long a1, unsigned long a2, | 795 | unsigned long a1, unsigned long a2, |
| 748 | unsigned long a3, unsigned long a4) | 796 | unsigned long a3, unsigned long a4) |
| 749 | { | 797 | { |
| 798 | struct task_struct *tsk = current; | ||
| 750 | struct audit_context *context = tsk->audit_context; | 799 | struct audit_context *context = tsk->audit_context; |
| 751 | enum audit_state state; | 800 | enum audit_state state; |
| 752 | 801 | ||
| @@ -824,22 +873,18 @@ void audit_syscall_entry(struct task_struct *tsk, int arch, int major, | |||
| 824 | * message), then write out the syscall information. In call cases, | 873 | * message), then write out the syscall information. In call cases, |
| 825 | * free the names stored from getname(). | 874 | * free the names stored from getname(). |
| 826 | */ | 875 | */ |
| 827 | void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code) | 876 | void audit_syscall_exit(int valid, long return_code) |
| 828 | { | 877 | { |
| 878 | struct task_struct *tsk = current; | ||
| 829 | struct audit_context *context; | 879 | struct audit_context *context; |
| 830 | 880 | ||
| 831 | get_task_struct(tsk); | ||
| 832 | task_lock(tsk); | ||
| 833 | context = audit_get_context(tsk, valid, return_code); | 881 | context = audit_get_context(tsk, valid, return_code); |
| 834 | task_unlock(tsk); | ||
| 835 | 882 | ||
| 836 | /* Not having a context here is ok, since the parent may have | ||
| 837 | * called __put_task_struct. */ | ||
| 838 | if (likely(!context)) | 883 | if (likely(!context)) |
| 839 | goto out; | 884 | return; |
| 840 | 885 | ||
| 841 | if (context->in_syscall && context->auditable) | 886 | if (context->in_syscall && context->auditable) |
| 842 | audit_log_exit(context, GFP_KERNEL); | 887 | audit_log_exit(context, tsk); |
| 843 | 888 | ||
| 844 | context->in_syscall = 0; | 889 | context->in_syscall = 0; |
| 845 | context->auditable = 0; | 890 | context->auditable = 0; |
| @@ -854,8 +899,6 @@ void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code) | |||
| 854 | audit_free_aux(context); | 899 | audit_free_aux(context); |
| 855 | tsk->audit_context = context; | 900 | tsk->audit_context = context; |
| 856 | } | 901 | } |
| 857 | out: | ||
| 858 | put_task_struct(tsk); | ||
| 859 | } | 902 | } |
| 860 | 903 | ||
| 861 | /** | 904 | /** |
| @@ -936,40 +979,11 @@ void audit_putname(const char *name) | |||
| 936 | #endif | 979 | #endif |
| 937 | } | 980 | } |
| 938 | 981 | ||
| 939 | void audit_inode_context(int idx, const struct inode *inode) | 982 | static void audit_inode_context(int idx, const struct inode *inode) |
| 940 | { | 983 | { |
| 941 | struct audit_context *context = current->audit_context; | 984 | struct audit_context *context = current->audit_context; |
| 942 | const char *suffix = security_inode_xattr_getsuffix(); | ||
| 943 | char *ctx = NULL; | ||
| 944 | int len = 0; | ||
| 945 | |||
| 946 | if (!suffix) | ||
| 947 | goto ret; | ||
| 948 | |||
| 949 | len = security_inode_getsecurity(inode, suffix, NULL, 0, 0); | ||
| 950 | if (len == -EOPNOTSUPP) | ||
| 951 | goto ret; | ||
| 952 | if (len < 0) | ||
| 953 | goto error_path; | ||
| 954 | |||
| 955 | ctx = kmalloc(len, GFP_KERNEL); | ||
| 956 | if (!ctx) | ||
| 957 | goto error_path; | ||
| 958 | 985 | ||
| 959 | len = security_inode_getsecurity(inode, suffix, ctx, len, 0); | 986 | selinux_get_inode_sid(inode, &context->names[idx].osid); |
| 960 | if (len < 0) | ||
| 961 | goto error_path; | ||
| 962 | |||
| 963 | kfree(context->names[idx].ctx); | ||
| 964 | context->names[idx].ctx = ctx; | ||
| 965 | goto ret; | ||
| 966 | |||
| 967 | error_path: | ||
| 968 | if (ctx) | ||
| 969 | kfree(ctx); | ||
| 970 | audit_panic("error in audit_inode_context"); | ||
| 971 | ret: | ||
| 972 | return; | ||
| 973 | } | 987 | } |
| 974 | 988 | ||
| 975 | 989 | ||
| @@ -1155,40 +1169,37 @@ uid_t audit_get_loginuid(struct audit_context *ctx) | |||
| 1155 | return ctx ? ctx->loginuid : -1; | 1169 | return ctx ? ctx->loginuid : -1; |
| 1156 | } | 1170 | } |
| 1157 | 1171 | ||
| 1158 | static char *audit_ipc_context(struct kern_ipc_perm *ipcp) | 1172 | /** |
| 1173 | * audit_ipc_obj - record audit data for ipc object | ||
| 1174 | * @ipcp: ipc permissions | ||
| 1175 | * | ||
| 1176 | * Returns 0 for success or NULL context or < 0 on error. | ||
| 1177 | */ | ||
| 1178 | int audit_ipc_obj(struct kern_ipc_perm *ipcp) | ||
| 1159 | { | 1179 | { |
| 1180 | struct audit_aux_data_ipcctl *ax; | ||
| 1160 | struct audit_context *context = current->audit_context; | 1181 | struct audit_context *context = current->audit_context; |
| 1161 | char *ctx = NULL; | ||
| 1162 | int len = 0; | ||
| 1163 | 1182 | ||
| 1164 | if (likely(!context)) | 1183 | if (likely(!context)) |
| 1165 | return NULL; | 1184 | return 0; |
| 1166 | |||
| 1167 | len = security_ipc_getsecurity(ipcp, NULL, 0); | ||
| 1168 | if (len == -EOPNOTSUPP) | ||
| 1169 | goto ret; | ||
| 1170 | if (len < 0) | ||
| 1171 | goto error_path; | ||
| 1172 | |||
| 1173 | ctx = kmalloc(len, GFP_ATOMIC); | ||
| 1174 | if (!ctx) | ||
| 1175 | goto error_path; | ||
| 1176 | 1185 | ||
| 1177 | len = security_ipc_getsecurity(ipcp, ctx, len); | 1186 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); |
| 1178 | if (len < 0) | 1187 | if (!ax) |
| 1179 | goto error_path; | 1188 | return -ENOMEM; |
| 1180 | 1189 | ||
| 1181 | return ctx; | 1190 | ax->uid = ipcp->uid; |
| 1191 | ax->gid = ipcp->gid; | ||
| 1192 | ax->mode = ipcp->mode; | ||
| 1193 | selinux_get_ipc_sid(ipcp, &ax->osid); | ||
| 1182 | 1194 | ||
| 1183 | error_path: | 1195 | ax->d.type = AUDIT_IPC; |
| 1184 | kfree(ctx); | 1196 | ax->d.next = context->aux; |
| 1185 | audit_panic("error in audit_ipc_context"); | 1197 | context->aux = (void *)ax; |
| 1186 | ret: | 1198 | return 0; |
| 1187 | return NULL; | ||
| 1188 | } | 1199 | } |
| 1189 | 1200 | ||
| 1190 | /** | 1201 | /** |
| 1191 | * audit_ipc_perms - record audit data for ipc | 1202 | * audit_ipc_set_perm - record audit data for new ipc permissions |
| 1192 | * @qbytes: msgq bytes | 1203 | * @qbytes: msgq bytes |
| 1193 | * @uid: msgq user id | 1204 | * @uid: msgq user id |
| 1194 | * @gid: msgq group id | 1205 | * @gid: msgq group id |
| @@ -1196,7 +1207,7 @@ ret: | |||
| 1196 | * | 1207 | * |
| 1197 | * Returns 0 for success or NULL context or < 0 on error. | 1208 | * Returns 0 for success or NULL context or < 0 on error. |
| 1198 | */ | 1209 | */ |
| 1199 | int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp) | 1210 | int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, struct kern_ipc_perm *ipcp) |
| 1200 | { | 1211 | { |
| 1201 | struct audit_aux_data_ipcctl *ax; | 1212 | struct audit_aux_data_ipcctl *ax; |
| 1202 | struct audit_context *context = current->audit_context; | 1213 | struct audit_context *context = current->audit_context; |
| @@ -1212,9 +1223,9 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode, str | |||
| 1212 | ax->uid = uid; | 1223 | ax->uid = uid; |
| 1213 | ax->gid = gid; | 1224 | ax->gid = gid; |
| 1214 | ax->mode = mode; | 1225 | ax->mode = mode; |
| 1215 | ax->ctx = audit_ipc_context(ipcp); | 1226 | selinux_get_ipc_sid(ipcp, &ax->osid); |
| 1216 | 1227 | ||
| 1217 | ax->d.type = AUDIT_IPC; | 1228 | ax->d.type = AUDIT_IPC_SET_PERM; |
| 1218 | ax->d.next = context->aux; | 1229 | ax->d.next = context->aux; |
| 1219 | context->aux = (void *)ax; | 1230 | context->aux = (void *)ax; |
| 1220 | return 0; | 1231 | return 0; |
diff --git a/kernel/exit.c b/kernel/exit.c index f86434d7b3d1..e95b93282210 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/futex.h> | 35 | #include <linux/futex.h> |
| 36 | #include <linux/compat.h> | 36 | #include <linux/compat.h> |
| 37 | #include <linux/pipe_fs_i.h> | 37 | #include <linux/pipe_fs_i.h> |
| 38 | #include <linux/audit.h> /* for audit_free() */ | ||
| 38 | 39 | ||
| 39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
| 40 | #include <asm/unistd.h> | 41 | #include <asm/unistd.h> |
| @@ -910,6 +911,8 @@ fastcall NORET_TYPE void do_exit(long code) | |||
| 910 | if (unlikely(tsk->compat_robust_list)) | 911 | if (unlikely(tsk->compat_robust_list)) |
| 911 | compat_exit_robust_list(tsk); | 912 | compat_exit_robust_list(tsk); |
| 912 | #endif | 913 | #endif |
| 914 | if (unlikely(tsk->audit_context)) | ||
| 915 | audit_free(tsk); | ||
| 913 | exit_mm(tsk); | 916 | exit_mm(tsk); |
| 914 | 917 | ||
| 915 | exit_sem(tsk); | 918 | exit_sem(tsk); |
diff --git a/kernel/fork.c b/kernel/fork.c index d2fa57d480d4..ac8100e3088a 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -114,8 +114,6 @@ void __put_task_struct(struct task_struct *tsk) | |||
| 114 | WARN_ON(atomic_read(&tsk->usage)); | 114 | WARN_ON(atomic_read(&tsk->usage)); |
| 115 | WARN_ON(tsk == current); | 115 | WARN_ON(tsk == current); |
| 116 | 116 | ||
| 117 | if (unlikely(tsk->audit_context)) | ||
| 118 | audit_free(tsk); | ||
| 119 | security_task_free(tsk); | 117 | security_task_free(tsk); |
| 120 | free_uid(tsk->user); | 118 | free_uid(tsk->user); |
| 121 | put_group_info(tsk->group_info); | 119 | put_group_info(tsk->group_info); |
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 1fe76d963ac2..1ae2b2cc3a54 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
| @@ -69,12 +69,16 @@ int __add_pages(struct zone *zone, unsigned long phys_start_pfn, | |||
| 69 | for (i = 0; i < nr_pages; i += PAGES_PER_SECTION) { | 69 | for (i = 0; i < nr_pages; i += PAGES_PER_SECTION) { |
| 70 | err = __add_section(zone, phys_start_pfn + i); | 70 | err = __add_section(zone, phys_start_pfn + i); |
| 71 | 71 | ||
| 72 | if (err) | 72 | /* We want to keep adding the rest of the |
| 73 | * sections if the first ones already exist | ||
| 74 | */ | ||
| 75 | if (err && (err != -EEXIST)) | ||
| 73 | break; | 76 | break; |
| 74 | } | 77 | } |
| 75 | 78 | ||
| 76 | return err; | 79 | return err; |
| 77 | } | 80 | } |
| 81 | EXPORT_SYMBOL_GPL(__add_pages); | ||
| 78 | 82 | ||
| 79 | static void grow_zone_span(struct zone *zone, | 83 | static void grow_zone_span(struct zone *zone, |
| 80 | unsigned long start_pfn, unsigned long end_pfn) | 84 | unsigned long start_pfn, unsigned long end_pfn) |
diff --git a/mm/migrate.c b/mm/migrate.c index d444229f2599..1c25040693d2 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
| @@ -439,6 +439,17 @@ redo: | |||
| 439 | goto unlock_both; | 439 | goto unlock_both; |
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | /* Make sure the dirty bit is up to date */ | ||
| 443 | if (try_to_unmap(page, 1) == SWAP_FAIL) { | ||
| 444 | rc = -EPERM; | ||
| 445 | goto unlock_both; | ||
| 446 | } | ||
| 447 | |||
| 448 | if (page_mapcount(page)) { | ||
| 449 | rc = -EAGAIN; | ||
| 450 | goto unlock_both; | ||
| 451 | } | ||
| 452 | |||
| 442 | /* | 453 | /* |
| 443 | * Default handling if a filesystem does not provide | 454 | * Default handling if a filesystem does not provide |
| 444 | * a migration function. We can only migrate clean | 455 | * a migration function. We can only migrate clean |
diff --git a/mm/sparse.c b/mm/sparse.c index 0a51f36ba3a1..d7c32de99ee8 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
| @@ -32,7 +32,10 @@ static struct mem_section *sparse_index_alloc(int nid) | |||
| 32 | unsigned long array_size = SECTIONS_PER_ROOT * | 32 | unsigned long array_size = SECTIONS_PER_ROOT * |
| 33 | sizeof(struct mem_section); | 33 | sizeof(struct mem_section); |
| 34 | 34 | ||
| 35 | section = alloc_bootmem_node(NODE_DATA(nid), array_size); | 35 | if (system_state == SYSTEM_RUNNING) |
| 36 | section = kmalloc_node(array_size, GFP_KERNEL, nid); | ||
| 37 | else | ||
| 38 | section = alloc_bootmem_node(NODE_DATA(nid), array_size); | ||
| 36 | 39 | ||
| 37 | if (section) | 40 | if (section) |
| 38 | memset(section, 0, array_size); | 41 | memset(section, 0, array_size); |
| @@ -281,9 +284,9 @@ int sparse_add_one_section(struct zone *zone, unsigned long start_pfn, | |||
| 281 | 284 | ||
| 282 | ret = sparse_init_one_section(ms, section_nr, memmap); | 285 | ret = sparse_init_one_section(ms, section_nr, memmap); |
| 283 | 286 | ||
| 284 | if (ret <= 0) | ||
| 285 | __kfree_section_memmap(memmap, nr_pages); | ||
| 286 | out: | 287 | out: |
| 287 | pgdat_resize_unlock(pgdat, &flags); | 288 | pgdat_resize_unlock(pgdat, &flags); |
| 289 | if (ret <= 0) | ||
| 290 | __kfree_section_memmap(memmap, nr_pages); | ||
| 288 | return ret; | 291 | return ret; |
| 289 | } | 292 | } |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index dbf9b47681f7..a2e0dd047e9f 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
| @@ -228,6 +228,8 @@ ax25_cb *ax25_find_cb(ax25_address *src_addr, ax25_address *dest_addr, | |||
| 228 | return NULL; | 228 | return NULL; |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | EXPORT_SYMBOL(ax25_find_cb); | ||
| 232 | |||
| 231 | void ax25_send_to_raw(ax25_address *addr, struct sk_buff *skb, int proto) | 233 | void ax25_send_to_raw(ax25_address *addr, struct sk_buff *skb, int proto) |
| 232 | { | 234 | { |
| 233 | ax25_cb *s; | 235 | ax25_cb *s; |
| @@ -424,6 +426,26 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg) | |||
| 424 | return 0; | 426 | return 0; |
| 425 | } | 427 | } |
| 426 | 428 | ||
| 429 | static void ax25_fillin_cb_from_dev(ax25_cb *ax25, ax25_dev *ax25_dev) | ||
| 430 | { | ||
| 431 | ax25->rtt = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]) / 2; | ||
| 432 | ax25->t1 = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T1]); | ||
| 433 | ax25->t2 = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T2]); | ||
| 434 | ax25->t3 = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_T3]); | ||
| 435 | ax25->n2 = ax25_dev->values[AX25_VALUES_N2]; | ||
| 436 | ax25->paclen = ax25_dev->values[AX25_VALUES_PACLEN]; | ||
| 437 | ax25->idle = msecs_to_jiffies(ax25_dev->values[AX25_VALUES_IDLE]); | ||
| 438 | ax25->backoff = ax25_dev->values[AX25_VALUES_BACKOFF]; | ||
| 439 | |||
| 440 | if (ax25_dev->values[AX25_VALUES_AXDEFMODE]) { | ||
| 441 | ax25->modulus = AX25_EMODULUS; | ||
| 442 | ax25->window = ax25_dev->values[AX25_VALUES_EWINDOW]; | ||
| 443 | } else { | ||
| 444 | ax25->modulus = AX25_MODULUS; | ||
| 445 | ax25->window = ax25_dev->values[AX25_VALUES_WINDOW]; | ||
| 446 | } | ||
| 447 | } | ||
| 448 | |||
| 427 | /* | 449 | /* |
| 428 | * Fill in a created AX.25 created control block with the default | 450 | * Fill in a created AX.25 created control block with the default |
| 429 | * values for a particular device. | 451 | * values for a particular device. |
| @@ -433,39 +455,28 @@ void ax25_fillin_cb(ax25_cb *ax25, ax25_dev *ax25_dev) | |||
| 433 | ax25->ax25_dev = ax25_dev; | 455 | ax25->ax25_dev = ax25_dev; |
| 434 | 456 | ||
| 435 | if (ax25->ax25_dev != NULL) { | 457 | if (ax25->ax25_dev != NULL) { |
| 436 | ax25->rtt = ax25_dev->values[AX25_VALUES_T1] / 2; | 458 | ax25_fillin_cb_from_dev(ax25, ax25_dev); |
| 437 | ax25->t1 = ax25_dev->values[AX25_VALUES_T1]; | 459 | return; |
| 438 | ax25->t2 = ax25_dev->values[AX25_VALUES_T2]; | 460 | } |
| 439 | ax25->t3 = ax25_dev->values[AX25_VALUES_T3]; | 461 | |
| 440 | ax25->n2 = ax25_dev->values[AX25_VALUES_N2]; | 462 | /* |
| 441 | ax25->paclen = ax25_dev->values[AX25_VALUES_PACLEN]; | 463 | * No device, use kernel / AX.25 spec default values |
| 442 | ax25->idle = ax25_dev->values[AX25_VALUES_IDLE]; | 464 | */ |
| 443 | ax25->backoff = ax25_dev->values[AX25_VALUES_BACKOFF]; | 465 | ax25->rtt = msecs_to_jiffies(AX25_DEF_T1) / 2; |
| 444 | 466 | ax25->t1 = msecs_to_jiffies(AX25_DEF_T1); | |
| 445 | if (ax25_dev->values[AX25_VALUES_AXDEFMODE]) { | 467 | ax25->t2 = msecs_to_jiffies(AX25_DEF_T2); |
| 446 | ax25->modulus = AX25_EMODULUS; | 468 | ax25->t3 = msecs_to_jiffies(AX25_DEF_T3); |
| 447 | ax25->window = ax25_dev->values[AX25_VALUES_EWINDOW]; | 469 | ax25->n2 = AX25_DEF_N2; |
| 448 | } else { | 470 | ax25->paclen = AX25_DEF_PACLEN; |
| 449 | ax25->modulus = AX25_MODULUS; | 471 | ax25->idle = msecs_to_jiffies(AX25_DEF_IDLE); |
| 450 | ax25->window = ax25_dev->values[AX25_VALUES_WINDOW]; | 472 | ax25->backoff = AX25_DEF_BACKOFF; |
| 451 | } | 473 | |
| 474 | if (AX25_DEF_AXDEFMODE) { | ||
| 475 | ax25->modulus = AX25_EMODULUS; | ||
| 476 | ax25->window = AX25_DEF_EWINDOW; | ||
| 452 | } else { | 477 | } else { |
| 453 | ax25->rtt = AX25_DEF_T1 / 2; | 478 | ax25->modulus = AX25_MODULUS; |
| 454 | ax25->t1 = AX25_DEF_T1; | 479 | ax25->window = AX25_DEF_WINDOW; |
| 455 | ax25->t2 = AX25_DEF_T2; | ||
| 456 | ax25->t3 = AX25_DEF_T3; | ||
| 457 | ax25->n2 = AX25_DEF_N2; | ||
| 458 | ax25->paclen = AX25_DEF_PACLEN; | ||
| 459 | ax25->idle = AX25_DEF_IDLE; | ||
| 460 | ax25->backoff = AX25_DEF_BACKOFF; | ||
| 461 | |||
| 462 | if (AX25_DEF_AXDEFMODE) { | ||
| 463 | ax25->modulus = AX25_EMODULUS; | ||
| 464 | ax25->window = AX25_DEF_EWINDOW; | ||
| 465 | } else { | ||
| 466 | ax25->modulus = AX25_MODULUS; | ||
| 467 | ax25->window = AX25_DEF_WINDOW; | ||
| 468 | } | ||
| 469 | } | 480 | } |
| 470 | } | 481 | } |
| 471 | 482 | ||
| @@ -1979,24 +1990,6 @@ static struct notifier_block ax25_dev_notifier = { | |||
| 1979 | .notifier_call =ax25_device_event, | 1990 | .notifier_call =ax25_device_event, |
| 1980 | }; | 1991 | }; |
| 1981 | 1992 | ||
| 1982 | EXPORT_SYMBOL(ax25_hard_header); | ||
| 1983 | EXPORT_SYMBOL(ax25_rebuild_header); | ||
| 1984 | EXPORT_SYMBOL(ax25_findbyuid); | ||
| 1985 | EXPORT_SYMBOL(ax25_find_cb); | ||
| 1986 | EXPORT_SYMBOL(ax25_linkfail_register); | ||
| 1987 | EXPORT_SYMBOL(ax25_linkfail_release); | ||
| 1988 | EXPORT_SYMBOL(ax25_listen_register); | ||
| 1989 | EXPORT_SYMBOL(ax25_listen_release); | ||
| 1990 | EXPORT_SYMBOL(ax25_protocol_register); | ||
| 1991 | EXPORT_SYMBOL(ax25_protocol_release); | ||
| 1992 | EXPORT_SYMBOL(ax25_send_frame); | ||
| 1993 | EXPORT_SYMBOL(ax25_uid_policy); | ||
| 1994 | EXPORT_SYMBOL(ax25cmp); | ||
| 1995 | EXPORT_SYMBOL(ax2asc); | ||
| 1996 | EXPORT_SYMBOL(asc2ax); | ||
| 1997 | EXPORT_SYMBOL(null_ax25_address); | ||
| 1998 | EXPORT_SYMBOL(ax25_display_timer); | ||
| 1999 | |||
| 2000 | static int __init ax25_init(void) | 1993 | static int __init ax25_init(void) |
| 2001 | { | 1994 | { |
| 2002 | int rc = proto_register(&ax25_proto, 0); | 1995 | int rc = proto_register(&ax25_proto, 0); |
diff --git a/net/ax25/ax25_addr.c b/net/ax25/ax25_addr.c index 0164a155b8c4..5f0896ad0042 100644 --- a/net/ax25/ax25_addr.c +++ b/net/ax25/ax25_addr.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/socket.h> | 11 | #include <linux/socket.h> |
| 12 | #include <linux/in.h> | 12 | #include <linux/in.h> |
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/module.h> | ||
| 14 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
| 15 | #include <linux/timer.h> | 16 | #include <linux/timer.h> |
| 16 | #include <linux/string.h> | 17 | #include <linux/string.h> |
| @@ -33,6 +34,8 @@ | |||
| 33 | */ | 34 | */ |
| 34 | ax25_address null_ax25_address = {{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00}}; | 35 | ax25_address null_ax25_address = {{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00}}; |
| 35 | 36 | ||
| 37 | EXPORT_SYMBOL(null_ax25_address); | ||
| 38 | |||
| 36 | /* | 39 | /* |
| 37 | * ax25 -> ascii conversion | 40 | * ax25 -> ascii conversion |
| 38 | */ | 41 | */ |
| @@ -64,6 +67,8 @@ char *ax2asc(char *buf, ax25_address *a) | |||
| 64 | 67 | ||
| 65 | } | 68 | } |
| 66 | 69 | ||
| 70 | EXPORT_SYMBOL(ax2asc); | ||
| 71 | |||
| 67 | /* | 72 | /* |
| 68 | * ascii -> ax25 conversion | 73 | * ascii -> ax25 conversion |
| 69 | */ | 74 | */ |
| @@ -97,6 +102,8 @@ void asc2ax(ax25_address *addr, char *callsign) | |||
| 97 | addr->ax25_call[6] &= 0x1E; | 102 | addr->ax25_call[6] &= 0x1E; |
| 98 | } | 103 | } |
| 99 | 104 | ||
| 105 | EXPORT_SYMBOL(asc2ax); | ||
| 106 | |||
| 100 | /* | 107 | /* |
| 101 | * Compare two ax.25 addresses | 108 | * Compare two ax.25 addresses |
| 102 | */ | 109 | */ |
| @@ -116,6 +123,8 @@ int ax25cmp(ax25_address *a, ax25_address *b) | |||
| 116 | return 2; /* Partial match */ | 123 | return 2; /* Partial match */ |
| 117 | } | 124 | } |
| 118 | 125 | ||
| 126 | EXPORT_SYMBOL(ax25cmp); | ||
| 127 | |||
| 119 | /* | 128 | /* |
| 120 | * Compare two AX.25 digipeater paths. | 129 | * Compare two AX.25 digipeater paths. |
| 121 | */ | 130 | */ |
diff --git a/net/ax25/ax25_ds_timer.c b/net/ax25/ax25_ds_timer.c index 061083efc1dc..5961459935eb 100644 --- a/net/ax25/ax25_ds_timer.c +++ b/net/ax25/ax25_ds_timer.c | |||
| @@ -61,7 +61,8 @@ void ax25_ds_set_timer(ax25_dev *ax25_dev) | |||
| 61 | return; | 61 | return; |
| 62 | 62 | ||
| 63 | del_timer(&ax25_dev->dama.slave_timer); | 63 | del_timer(&ax25_dev->dama.slave_timer); |
| 64 | ax25_dev->dama.slave_timeout = ax25_dev->values[AX25_VALUES_DS_TIMEOUT] / 10; | 64 | ax25_dev->dama.slave_timeout = |
| 65 | msecs_to_jiffies(ax25_dev->values[AX25_VALUES_DS_TIMEOUT]) / 10; | ||
| 65 | ax25_ds_add_timer(ax25_dev); | 66 | ax25_ds_add_timer(ax25_dev); |
| 66 | } | 67 | } |
| 67 | 68 | ||
diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c index d68aff100729..3bb152710b77 100644 --- a/net/ax25/ax25_iface.c +++ b/net/ax25/ax25_iface.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/socket.h> | 12 | #include <linux/socket.h> |
| 13 | #include <linux/in.h> | 13 | #include <linux/in.h> |
| 14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 15 | #include <linux/module.h> | ||
| 15 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
| 16 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
| 17 | #include <linux/timer.h> | 18 | #include <linux/timer.h> |
| @@ -74,6 +75,8 @@ int ax25_protocol_register(unsigned int pid, | |||
| 74 | return 1; | 75 | return 1; |
| 75 | } | 76 | } |
| 76 | 77 | ||
| 78 | EXPORT_SYMBOL(ax25_protocol_register); | ||
| 79 | |||
| 77 | void ax25_protocol_release(unsigned int pid) | 80 | void ax25_protocol_release(unsigned int pid) |
| 78 | { | 81 | { |
| 79 | struct protocol_struct *s, *protocol; | 82 | struct protocol_struct *s, *protocol; |
| @@ -106,6 +109,8 @@ void ax25_protocol_release(unsigned int pid) | |||
| 106 | write_unlock(&protocol_list_lock); | 109 | write_unlock(&protocol_list_lock); |
| 107 | } | 110 | } |
| 108 | 111 | ||
| 112 | EXPORT_SYMBOL(ax25_protocol_release); | ||
| 113 | |||
| 109 | int ax25_linkfail_register(void (*func)(ax25_cb *, int)) | 114 | int ax25_linkfail_register(void (*func)(ax25_cb *, int)) |
| 110 | { | 115 | { |
| 111 | struct linkfail_struct *linkfail; | 116 | struct linkfail_struct *linkfail; |
| @@ -123,6 +128,8 @@ int ax25_linkfail_register(void (*func)(ax25_cb *, int)) | |||
| 123 | return 1; | 128 | return 1; |
| 124 | } | 129 | } |
| 125 | 130 | ||
| 131 | EXPORT_SYMBOL(ax25_linkfail_register); | ||
| 132 | |||
| 126 | void ax25_linkfail_release(void (*func)(ax25_cb *, int)) | 133 | void ax25_linkfail_release(void (*func)(ax25_cb *, int)) |
| 127 | { | 134 | { |
| 128 | struct linkfail_struct *s, *linkfail; | 135 | struct linkfail_struct *s, *linkfail; |
| @@ -155,6 +162,8 @@ void ax25_linkfail_release(void (*func)(ax25_cb *, int)) | |||
| 155 | spin_unlock_bh(&linkfail_lock); | 162 | spin_unlock_bh(&linkfail_lock); |
| 156 | } | 163 | } |
| 157 | 164 | ||
| 165 | EXPORT_SYMBOL(ax25_linkfail_release); | ||
| 166 | |||
| 158 | int ax25_listen_register(ax25_address *callsign, struct net_device *dev) | 167 | int ax25_listen_register(ax25_address *callsign, struct net_device *dev) |
| 159 | { | 168 | { |
| 160 | struct listen_struct *listen; | 169 | struct listen_struct *listen; |
| @@ -176,6 +185,8 @@ int ax25_listen_register(ax25_address *callsign, struct net_device *dev) | |||
| 176 | return 1; | 185 | return 1; |
| 177 | } | 186 | } |
| 178 | 187 | ||
| 188 | EXPORT_SYMBOL(ax25_listen_register); | ||
| 189 | |||
| 179 | void ax25_listen_release(ax25_address *callsign, struct net_device *dev) | 190 | void ax25_listen_release(ax25_address *callsign, struct net_device *dev) |
| 180 | { | 191 | { |
| 181 | struct listen_struct *s, *listen; | 192 | struct listen_struct *s, *listen; |
| @@ -208,6 +219,8 @@ void ax25_listen_release(ax25_address *callsign, struct net_device *dev) | |||
| 208 | spin_unlock_bh(&listen_lock); | 219 | spin_unlock_bh(&listen_lock); |
| 209 | } | 220 | } |
| 210 | 221 | ||
| 222 | EXPORT_SYMBOL(ax25_listen_release); | ||
| 223 | |||
| 211 | int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *) | 224 | int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *) |
| 212 | { | 225 | { |
| 213 | int (*res)(struct sk_buff *, ax25_cb *) = NULL; | 226 | int (*res)(struct sk_buff *, ax25_cb *) = NULL; |
diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c index d643dac3eccc..a0b534f80f17 100644 --- a/net/ax25/ax25_ip.c +++ b/net/ax25/ax25_ip.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/socket.h> | 12 | #include <linux/socket.h> |
| 13 | #include <linux/in.h> | 13 | #include <linux/in.h> |
| 14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 15 | #include <linux/module.h> | ||
| 15 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
| 16 | #include <linux/timer.h> | 17 | #include <linux/timer.h> |
| 17 | #include <linux/string.h> | 18 | #include <linux/string.h> |
| @@ -221,3 +222,5 @@ int ax25_rebuild_header(struct sk_buff *skb) | |||
| 221 | 222 | ||
| 222 | #endif | 223 | #endif |
| 223 | 224 | ||
| 225 | EXPORT_SYMBOL(ax25_hard_header); | ||
| 226 | EXPORT_SYMBOL(ax25_rebuild_header); | ||
diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c index 5fc048dcd39a..5d99852b239c 100644 --- a/net/ax25/ax25_out.c +++ b/net/ax25/ax25_out.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/socket.h> | 14 | #include <linux/socket.h> |
| 15 | #include <linux/in.h> | 15 | #include <linux/in.h> |
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/module.h> | ||
| 17 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
| 18 | #include <linux/timer.h> | 19 | #include <linux/timer.h> |
| 19 | #include <linux/string.h> | 20 | #include <linux/string.h> |
| @@ -104,6 +105,8 @@ ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax2 | |||
| 104 | return ax25; /* We had to create it */ | 105 | return ax25; /* We had to create it */ |
| 105 | } | 106 | } |
| 106 | 107 | ||
| 108 | EXPORT_SYMBOL(ax25_send_frame); | ||
| 109 | |||
| 107 | /* | 110 | /* |
| 108 | * All outgoing AX.25 I frames pass via this routine. Therefore this is | 111 | * All outgoing AX.25 I frames pass via this routine. Therefore this is |
| 109 | * where the fragmentation of frames takes place. If fragment is set to | 112 | * where the fragmentation of frames takes place. If fragment is set to |
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index f04f8630fd28..5ac98250797b 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c | |||
| @@ -360,7 +360,7 @@ struct file_operations ax25_route_fops = { | |||
| 360 | /* | 360 | /* |
| 361 | * Find AX.25 route | 361 | * Find AX.25 route |
| 362 | * | 362 | * |
| 363 | * Only routes with a refernce rout of zero can be destroyed. | 363 | * Only routes with a reference count of zero can be destroyed. |
| 364 | */ | 364 | */ |
| 365 | static ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev) | 365 | static ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev) |
| 366 | { | 366 | { |
diff --git a/net/ax25/ax25_timer.c b/net/ax25/ax25_timer.c index 7a6b50a14554..ec254057f212 100644 --- a/net/ax25/ax25_timer.c +++ b/net/ax25/ax25_timer.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/socket.h> | 18 | #include <linux/socket.h> |
| 19 | #include <linux/in.h> | 19 | #include <linux/in.h> |
| 20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
| 21 | #include <linux/module.h> | ||
| 21 | #include <linux/jiffies.h> | 22 | #include <linux/jiffies.h> |
| 22 | #include <linux/timer.h> | 23 | #include <linux/timer.h> |
| 23 | #include <linux/string.h> | 24 | #include <linux/string.h> |
| @@ -137,6 +138,8 @@ unsigned long ax25_display_timer(struct timer_list *timer) | |||
| 137 | return timer->expires - jiffies; | 138 | return timer->expires - jiffies; |
| 138 | } | 139 | } |
| 139 | 140 | ||
| 141 | EXPORT_SYMBOL(ax25_display_timer); | ||
| 142 | |||
| 140 | static void ax25_heartbeat_expiry(unsigned long param) | 143 | static void ax25_heartbeat_expiry(unsigned long param) |
| 141 | { | 144 | { |
| 142 | int proto = AX25_PROTO_STD_SIMPLEX; | 145 | int proto = AX25_PROTO_STD_SIMPLEX; |
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c index b8b5854bce9a..5e9a81e8b214 100644 --- a/net/ax25/ax25_uid.c +++ b/net/ax25/ax25_uid.c | |||
| @@ -49,6 +49,8 @@ static DEFINE_RWLOCK(ax25_uid_lock); | |||
| 49 | 49 | ||
| 50 | int ax25_uid_policy = 0; | 50 | int ax25_uid_policy = 0; |
| 51 | 51 | ||
| 52 | EXPORT_SYMBOL(ax25_uid_policy); | ||
| 53 | |||
| 52 | ax25_uid_assoc *ax25_findbyuid(uid_t uid) | 54 | ax25_uid_assoc *ax25_findbyuid(uid_t uid) |
| 53 | { | 55 | { |
| 54 | ax25_uid_assoc *ax25_uid, *res = NULL; | 56 | ax25_uid_assoc *ax25_uid, *res = NULL; |
| @@ -67,6 +69,8 @@ ax25_uid_assoc *ax25_findbyuid(uid_t uid) | |||
| 67 | return res; | 69 | return res; |
| 68 | } | 70 | } |
| 69 | 71 | ||
| 72 | EXPORT_SYMBOL(ax25_findbyuid); | ||
| 73 | |||
| 70 | int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) | 74 | int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) |
| 71 | { | 75 | { |
| 72 | ax25_uid_assoc *ax25_uid; | 76 | ax25_uid_assoc *ax25_uid; |
diff --git a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c index 894a22558d9d..bdb64c36df12 100644 --- a/net/ax25/sysctl_net_ax25.c +++ b/net/ax25/sysctl_net_ax25.c | |||
| @@ -18,14 +18,14 @@ static int min_backoff[1], max_backoff[] = {2}; | |||
| 18 | static int min_conmode[1], max_conmode[] = {2}; | 18 | static int min_conmode[1], max_conmode[] = {2}; |
| 19 | static int min_window[] = {1}, max_window[] = {7}; | 19 | static int min_window[] = {1}, max_window[] = {7}; |
| 20 | static int min_ewindow[] = {1}, max_ewindow[] = {63}; | 20 | static int min_ewindow[] = {1}, max_ewindow[] = {63}; |
| 21 | static int min_t1[] = {1}, max_t1[] = {30 * HZ}; | 21 | static int min_t1[] = {1}, max_t1[] = {30000}; |
| 22 | static int min_t2[] = {1}, max_t2[] = {20 * HZ}; | 22 | static int min_t2[] = {1}, max_t2[] = {20000}; |
| 23 | static int min_t3[1], max_t3[] = {3600 * HZ}; | 23 | static int min_t3[1], max_t3[] = {3600000}; |
| 24 | static int min_idle[1], max_idle[] = {65535 * HZ}; | 24 | static int min_idle[1], max_idle[] = {65535000}; |
| 25 | static int min_n2[] = {1}, max_n2[] = {31}; | 25 | static int min_n2[] = {1}, max_n2[] = {31}; |
| 26 | static int min_paclen[] = {1}, max_paclen[] = {512}; | 26 | static int min_paclen[] = {1}, max_paclen[] = {512}; |
| 27 | static int min_proto[1], max_proto[] = { AX25_PROTO_MAX }; | 27 | static int min_proto[1], max_proto[] = { AX25_PROTO_MAX }; |
| 28 | static int min_ds_timeout[1], max_ds_timeout[] = {65535 * HZ}; | 28 | static int min_ds_timeout[1], max_ds_timeout[] = {65535000}; |
| 29 | 29 | ||
| 30 | static struct ctl_table_header *ax25_table_header; | 30 | static struct ctl_table_header *ax25_table_header; |
| 31 | 31 | ||
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index b0b7f55c1edd..bfa4d8c333f7 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
| @@ -66,6 +66,7 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | if (is_multicast_ether_addr(dest)) { | 68 | if (is_multicast_ether_addr(dest)) { |
| 69 | br->statistics.multicast++; | ||
| 69 | br_flood_forward(br, skb, !passedup); | 70 | br_flood_forward(br, skb, !passedup); |
| 70 | if (!passedup) | 71 | if (!passedup) |
| 71 | br_pass_frame_up(br, skb); | 72 | br_pass_frame_up(br, skb); |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 1ff7328b0e17..2e0ee8355c41 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
| @@ -848,6 +848,7 @@ static int dccp_close_state(struct sock *sk) | |||
| 848 | void dccp_close(struct sock *sk, long timeout) | 848 | void dccp_close(struct sock *sk, long timeout) |
| 849 | { | 849 | { |
| 850 | struct sk_buff *skb; | 850 | struct sk_buff *skb; |
| 851 | int state; | ||
| 851 | 852 | ||
| 852 | lock_sock(sk); | 853 | lock_sock(sk); |
| 853 | 854 | ||
| @@ -882,6 +883,11 @@ void dccp_close(struct sock *sk, long timeout) | |||
| 882 | sk_stream_wait_close(sk, timeout); | 883 | sk_stream_wait_close(sk, timeout); |
| 883 | 884 | ||
| 884 | adjudge_to_death: | 885 | adjudge_to_death: |
| 886 | state = sk->sk_state; | ||
| 887 | sock_hold(sk); | ||
| 888 | sock_orphan(sk); | ||
| 889 | atomic_inc(sk->sk_prot->orphan_count); | ||
| 890 | |||
| 885 | /* | 891 | /* |
| 886 | * It is the last release_sock in its life. It will remove backlog. | 892 | * It is the last release_sock in its life. It will remove backlog. |
| 887 | */ | 893 | */ |
| @@ -894,8 +900,9 @@ adjudge_to_death: | |||
| 894 | bh_lock_sock(sk); | 900 | bh_lock_sock(sk); |
| 895 | BUG_TRAP(!sock_owned_by_user(sk)); | 901 | BUG_TRAP(!sock_owned_by_user(sk)); |
| 896 | 902 | ||
| 897 | sock_hold(sk); | 903 | /* Have we already been destroyed by a softirq or backlog? */ |
| 898 | sock_orphan(sk); | 904 | if (state != DCCP_CLOSED && sk->sk_state == DCCP_CLOSED) |
| 905 | goto out; | ||
| 899 | 906 | ||
| 900 | /* | 907 | /* |
| 901 | * The last release_sock may have processed the CLOSE or RESET | 908 | * The last release_sock may have processed the CLOSE or RESET |
| @@ -915,12 +922,12 @@ adjudge_to_death: | |||
| 915 | #endif | 922 | #endif |
| 916 | } | 923 | } |
| 917 | 924 | ||
| 918 | atomic_inc(sk->sk_prot->orphan_count); | ||
| 919 | if (sk->sk_state == DCCP_CLOSED) | 925 | if (sk->sk_state == DCCP_CLOSED) |
| 920 | inet_csk_destroy_sock(sk); | 926 | inet_csk_destroy_sock(sk); |
| 921 | 927 | ||
| 922 | /* Otherwise, socket is reprieved until protocol close. */ | 928 | /* Otherwise, socket is reprieved until protocol close. */ |
| 923 | 929 | ||
| 930 | out: | ||
| 924 | bh_unlock_sock(sk); | 931 | bh_unlock_sock(sk); |
| 925 | local_bh_enable(); | 932 | local_bh_enable(); |
| 926 | sock_put(sk); | 933 | sock_put(sk); |
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 7c8692c26bfe..66e230c3b328 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c | |||
| @@ -493,7 +493,6 @@ struct elist_cb_state { | |||
| 493 | static void neigh_elist_cb(struct neighbour *neigh, void *_info) | 493 | static void neigh_elist_cb(struct neighbour *neigh, void *_info) |
| 494 | { | 494 | { |
| 495 | struct elist_cb_state *s = _info; | 495 | struct elist_cb_state *s = _info; |
| 496 | struct dn_dev *dn_db; | ||
| 497 | struct dn_neigh *dn; | 496 | struct dn_neigh *dn; |
| 498 | 497 | ||
| 499 | if (neigh->dev != s->dev) | 498 | if (neigh->dev != s->dev) |
| @@ -503,10 +502,6 @@ static void neigh_elist_cb(struct neighbour *neigh, void *_info) | |||
| 503 | if (!(dn->flags & (DN_NDFLAG_R1|DN_NDFLAG_R2))) | 502 | if (!(dn->flags & (DN_NDFLAG_R1|DN_NDFLAG_R2))) |
| 504 | return; | 503 | return; |
| 505 | 504 | ||
| 506 | dn_db = (struct dn_dev *) s->dev->dn_ptr; | ||
| 507 | if (dn_db->parms.forwarding == 1 && (dn->flags & DN_NDFLAG_R2)) | ||
| 508 | return; | ||
| 509 | |||
| 510 | if (s->t == s->n) | 505 | if (s->t == s->n) |
| 511 | s->rs = dn_find_slot(s->ptr, s->n, dn->priority); | 506 | s->rs = dn_find_slot(s->ptr, s->n, dn->priority); |
| 512 | else | 507 | else |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index dc206f1f914f..0a277453526b 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -1257,7 +1257,7 @@ out_unregister_udp_proto: | |||
| 1257 | goto out; | 1257 | goto out; |
| 1258 | } | 1258 | } |
| 1259 | 1259 | ||
| 1260 | module_init(inet_init); | 1260 | fs_initcall(inet_init); |
| 1261 | 1261 | ||
| 1262 | /* ------------------------------------------------------------------------ */ | 1262 | /* ------------------------------------------------------------------------ */ |
| 1263 | 1263 | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c index 2c2fb700d835..518f581d39ec 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c | |||
| @@ -162,6 +162,8 @@ static int get_tpkt_data(struct sk_buff **pskb, struct ip_conntrack *ct, | |||
| 162 | 162 | ||
| 163 | /* Validate TPKT length */ | 163 | /* Validate TPKT length */ |
| 164 | tpktlen = tpkt[2] * 256 + tpkt[3]; | 164 | tpktlen = tpkt[2] * 256 + tpkt[3]; |
| 165 | if (tpktlen < 4) | ||
| 166 | goto clear_out; | ||
| 165 | if (tpktlen > tcpdatalen) { | 167 | if (tpktlen > tcpdatalen) { |
| 166 | if (tcpdatalen == 4) { /* Separate TPKT header */ | 168 | if (tcpdatalen == 4) { /* Separate TPKT header */ |
| 167 | /* Netmeeting sends TPKT header and data separately */ | 169 | /* Netmeeting sends TPKT header and data separately */ |
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c index 48078002e450..355a53a5b6cd 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * ip_conntrack_helper_h323_asn1.c - BER and PER decoding library for H.323 | 2 | * ip_conntrack_helper_h323_asn1.c - BER and PER decoding library for H.323 |
| 3 | * conntrack/NAT module. | 3 | * conntrack/NAT module. |
| 4 | * | 4 | * |
| 5 | * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@hotmail.com> | 5 | * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net> |
| 6 | * | 6 | * |
| 7 | * This source code is licensed under General Public License version 2. | 7 | * This source code is licensed under General Public License version 2. |
| 8 | * | 8 | * |
| @@ -703,6 +703,10 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level) | |||
| 703 | type = get_bits(bs, f->sz); | 703 | type = get_bits(bs, f->sz); |
| 704 | } | 704 | } |
| 705 | 705 | ||
| 706 | /* Write Type */ | ||
| 707 | if (base) | ||
| 708 | *(unsigned *) base = type; | ||
| 709 | |||
| 706 | /* Check Range */ | 710 | /* Check Range */ |
| 707 | if (type >= f->ub) { /* Newer version? */ | 711 | if (type >= f->ub) { /* Newer version? */ |
| 708 | BYTE_ALIGN(bs); | 712 | BYTE_ALIGN(bs); |
| @@ -712,10 +716,6 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level) | |||
| 712 | return H323_ERROR_NONE; | 716 | return H323_ERROR_NONE; |
| 713 | } | 717 | } |
| 714 | 718 | ||
| 715 | /* Write Type */ | ||
| 716 | if (base) | ||
| 717 | *(unsigned *) base = type; | ||
| 718 | |||
| 719 | /* Transfer to son level */ | 719 | /* Transfer to son level */ |
| 720 | son = &f->fields[type]; | 720 | son = &f->fields[type]; |
| 721 | if (son->attr & STOP) { | 721 | if (son->attr & STOP) { |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c index 5259abd0fb42..0416073c5600 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c | |||
| @@ -235,12 +235,15 @@ static int do_basic_checks(struct ip_conntrack *conntrack, | |||
| 235 | flag = 1; | 235 | flag = 1; |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | /* Cookie Ack/Echo chunks not the first OR | 238 | /* |
| 239 | Init / Init Ack / Shutdown compl chunks not the only chunks */ | 239 | * Cookie Ack/Echo chunks not the first OR |
| 240 | if ((sch->type == SCTP_CID_COOKIE_ACK | 240 | * Init / Init Ack / Shutdown compl chunks not the only chunks |
| 241 | * OR zero-length. | ||
| 242 | */ | ||
| 243 | if (((sch->type == SCTP_CID_COOKIE_ACK | ||
| 241 | || sch->type == SCTP_CID_COOKIE_ECHO | 244 | || sch->type == SCTP_CID_COOKIE_ECHO |
| 242 | || flag) | 245 | || flag) |
| 243 | && count !=0 ) { | 246 | && count !=0) || !sch->length) { |
| 244 | DEBUGP("Basic checks failed\n"); | 247 | DEBUGP("Basic checks failed\n"); |
| 245 | return 1; | 248 | return 1; |
| 246 | } | 249 | } |
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 8f760b28617e..67e676783da9 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
| @@ -219,8 +219,10 @@ ip_nat_out(unsigned int hooknum, | |||
| 219 | const struct net_device *out, | 219 | const struct net_device *out, |
| 220 | int (*okfn)(struct sk_buff *)) | 220 | int (*okfn)(struct sk_buff *)) |
| 221 | { | 221 | { |
| 222 | #ifdef CONFIG_XFRM | ||
| 222 | struct ip_conntrack *ct; | 223 | struct ip_conntrack *ct; |
| 223 | enum ip_conntrack_info ctinfo; | 224 | enum ip_conntrack_info ctinfo; |
| 225 | #endif | ||
| 224 | unsigned int ret; | 226 | unsigned int ret; |
| 225 | 227 | ||
| 226 | /* root is playing with raw sockets. */ | 228 | /* root is playing with raw sockets. */ |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index d25ac8ba6eba..cee3397ec277 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
| @@ -956,15 +956,16 @@ struct compat_ipt_standard_target | |||
| 956 | compat_int_t verdict; | 956 | compat_int_t verdict; |
| 957 | }; | 957 | }; |
| 958 | 958 | ||
| 959 | #define IPT_ST_OFFSET (sizeof(struct ipt_standard_target) - \ | ||
| 960 | sizeof(struct compat_ipt_standard_target)) | ||
| 961 | |||
| 962 | struct compat_ipt_standard | 959 | struct compat_ipt_standard |
| 963 | { | 960 | { |
| 964 | struct compat_ipt_entry entry; | 961 | struct compat_ipt_entry entry; |
| 965 | struct compat_ipt_standard_target target; | 962 | struct compat_ipt_standard_target target; |
| 966 | }; | 963 | }; |
| 967 | 964 | ||
| 965 | #define IPT_ST_LEN XT_ALIGN(sizeof(struct ipt_standard_target)) | ||
| 966 | #define IPT_ST_COMPAT_LEN COMPAT_XT_ALIGN(sizeof(struct compat_ipt_standard_target)) | ||
| 967 | #define IPT_ST_OFFSET (IPT_ST_LEN - IPT_ST_COMPAT_LEN) | ||
| 968 | |||
| 968 | static int compat_ipt_standard_fn(void *target, | 969 | static int compat_ipt_standard_fn(void *target, |
| 969 | void **dstptr, int *size, int convert) | 970 | void **dstptr, int *size, int convert) |
| 970 | { | 971 | { |
| @@ -975,35 +976,29 @@ static int compat_ipt_standard_fn(void *target, | |||
| 975 | ret = 0; | 976 | ret = 0; |
| 976 | switch (convert) { | 977 | switch (convert) { |
| 977 | case COMPAT_TO_USER: | 978 | case COMPAT_TO_USER: |
| 978 | pst = (struct ipt_standard_target *)target; | 979 | pst = target; |
| 979 | memcpy(&compat_st.target, &pst->target, | 980 | memcpy(&compat_st.target, &pst->target, |
| 980 | sizeof(struct ipt_entry_target)); | 981 | sizeof(compat_st.target)); |
| 981 | compat_st.verdict = pst->verdict; | 982 | compat_st.verdict = pst->verdict; |
| 982 | if (compat_st.verdict > 0) | 983 | if (compat_st.verdict > 0) |
| 983 | compat_st.verdict -= | 984 | compat_st.verdict -= |
| 984 | compat_calc_jump(compat_st.verdict); | 985 | compat_calc_jump(compat_st.verdict); |
| 985 | compat_st.target.u.user.target_size = | 986 | compat_st.target.u.user.target_size = IPT_ST_COMPAT_LEN; |
| 986 | sizeof(struct compat_ipt_standard_target); | 987 | if (copy_to_user(*dstptr, &compat_st, IPT_ST_COMPAT_LEN)) |
| 987 | if (__copy_to_user(*dstptr, &compat_st, | ||
| 988 | sizeof(struct compat_ipt_standard_target))) | ||
| 989 | ret = -EFAULT; | 988 | ret = -EFAULT; |
| 990 | *size -= IPT_ST_OFFSET; | 989 | *size -= IPT_ST_OFFSET; |
| 991 | *dstptr += sizeof(struct compat_ipt_standard_target); | 990 | *dstptr += IPT_ST_COMPAT_LEN; |
| 992 | break; | 991 | break; |
| 993 | case COMPAT_FROM_USER: | 992 | case COMPAT_FROM_USER: |
| 994 | pcompat_st = | 993 | pcompat_st = target; |
| 995 | (struct compat_ipt_standard_target *)target; | 994 | memcpy(&st.target, &pcompat_st->target, IPT_ST_COMPAT_LEN); |
| 996 | memcpy(&st.target, &pcompat_st->target, | ||
| 997 | sizeof(struct ipt_entry_target)); | ||
| 998 | st.verdict = pcompat_st->verdict; | 995 | st.verdict = pcompat_st->verdict; |
| 999 | if (st.verdict > 0) | 996 | if (st.verdict > 0) |
| 1000 | st.verdict += compat_calc_jump(st.verdict); | 997 | st.verdict += compat_calc_jump(st.verdict); |
| 1001 | st.target.u.user.target_size = | 998 | st.target.u.user.target_size = IPT_ST_LEN; |
| 1002 | sizeof(struct ipt_standard_target); | 999 | memcpy(*dstptr, &st, IPT_ST_LEN); |
| 1003 | memcpy(*dstptr, &st, | ||
| 1004 | sizeof(struct ipt_standard_target)); | ||
| 1005 | *size += IPT_ST_OFFSET; | 1000 | *size += IPT_ST_OFFSET; |
| 1006 | *dstptr += sizeof(struct ipt_standard_target); | 1001 | *dstptr += IPT_ST_LEN; |
| 1007 | break; | 1002 | break; |
| 1008 | case COMPAT_CALC_SIZE: | 1003 | case COMPAT_CALC_SIZE: |
| 1009 | *size += IPT_ST_OFFSET; | 1004 | *size += IPT_ST_OFFSET; |
| @@ -1446,7 +1441,7 @@ static int compat_copy_entry_to_user(struct ipt_entry *e, | |||
| 1446 | ret = -EFAULT; | 1441 | ret = -EFAULT; |
| 1447 | origsize = *size; | 1442 | origsize = *size; |
| 1448 | ce = (struct compat_ipt_entry __user *)*dstptr; | 1443 | ce = (struct compat_ipt_entry __user *)*dstptr; |
| 1449 | if (__copy_to_user(ce, e, sizeof(struct ipt_entry))) | 1444 | if (copy_to_user(ce, e, sizeof(struct ipt_entry))) |
| 1450 | goto out; | 1445 | goto out; |
| 1451 | 1446 | ||
| 1452 | *dstptr += sizeof(struct compat_ipt_entry); | 1447 | *dstptr += sizeof(struct compat_ipt_entry); |
| @@ -1464,9 +1459,9 @@ static int compat_copy_entry_to_user(struct ipt_entry *e, | |||
| 1464 | goto out; | 1459 | goto out; |
| 1465 | ret = -EFAULT; | 1460 | ret = -EFAULT; |
| 1466 | next_offset = e->next_offset - (origsize - *size); | 1461 | next_offset = e->next_offset - (origsize - *size); |
| 1467 | if (__put_user(target_offset, &ce->target_offset)) | 1462 | if (put_user(target_offset, &ce->target_offset)) |
| 1468 | goto out; | 1463 | goto out; |
| 1469 | if (__put_user(next_offset, &ce->next_offset)) | 1464 | if (put_user(next_offset, &ce->next_offset)) |
| 1470 | goto out; | 1465 | goto out; |
| 1471 | return 0; | 1466 | return 0; |
| 1472 | out: | 1467 | out: |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 87f68e787d0c..e2b7b8055037 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -1468,6 +1468,7 @@ void tcp_close(struct sock *sk, long timeout) | |||
| 1468 | { | 1468 | { |
| 1469 | struct sk_buff *skb; | 1469 | struct sk_buff *skb; |
| 1470 | int data_was_unread = 0; | 1470 | int data_was_unread = 0; |
| 1471 | int state; | ||
| 1471 | 1472 | ||
| 1472 | lock_sock(sk); | 1473 | lock_sock(sk); |
| 1473 | sk->sk_shutdown = SHUTDOWN_MASK; | 1474 | sk->sk_shutdown = SHUTDOWN_MASK; |
| @@ -1544,6 +1545,11 @@ void tcp_close(struct sock *sk, long timeout) | |||
| 1544 | sk_stream_wait_close(sk, timeout); | 1545 | sk_stream_wait_close(sk, timeout); |
| 1545 | 1546 | ||
| 1546 | adjudge_to_death: | 1547 | adjudge_to_death: |
| 1548 | state = sk->sk_state; | ||
| 1549 | sock_hold(sk); | ||
| 1550 | sock_orphan(sk); | ||
| 1551 | atomic_inc(sk->sk_prot->orphan_count); | ||
| 1552 | |||
| 1547 | /* It is the last release_sock in its life. It will remove backlog. */ | 1553 | /* It is the last release_sock in its life. It will remove backlog. */ |
| 1548 | release_sock(sk); | 1554 | release_sock(sk); |
| 1549 | 1555 | ||
| @@ -1555,8 +1561,9 @@ adjudge_to_death: | |||
| 1555 | bh_lock_sock(sk); | 1561 | bh_lock_sock(sk); |
| 1556 | BUG_TRAP(!sock_owned_by_user(sk)); | 1562 | BUG_TRAP(!sock_owned_by_user(sk)); |
| 1557 | 1563 | ||
| 1558 | sock_hold(sk); | 1564 | /* Have we already been destroyed by a softirq or backlog? */ |
| 1559 | sock_orphan(sk); | 1565 | if (state != TCP_CLOSE && sk->sk_state == TCP_CLOSE) |
| 1566 | goto out; | ||
| 1560 | 1567 | ||
| 1561 | /* This is a (useful) BSD violating of the RFC. There is a | 1568 | /* This is a (useful) BSD violating of the RFC. There is a |
| 1562 | * problem with TCP as specified in that the other end could | 1569 | * problem with TCP as specified in that the other end could |
| @@ -1584,7 +1591,6 @@ adjudge_to_death: | |||
| 1584 | if (tmo > TCP_TIMEWAIT_LEN) { | 1591 | if (tmo > TCP_TIMEWAIT_LEN) { |
| 1585 | inet_csk_reset_keepalive_timer(sk, tcp_fin_time(sk)); | 1592 | inet_csk_reset_keepalive_timer(sk, tcp_fin_time(sk)); |
| 1586 | } else { | 1593 | } else { |
| 1587 | atomic_inc(sk->sk_prot->orphan_count); | ||
| 1588 | tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); | 1594 | tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); |
| 1589 | goto out; | 1595 | goto out; |
| 1590 | } | 1596 | } |
| @@ -1603,7 +1609,6 @@ adjudge_to_death: | |||
| 1603 | NET_INC_STATS_BH(LINUX_MIB_TCPABORTONMEMORY); | 1609 | NET_INC_STATS_BH(LINUX_MIB_TCPABORTONMEMORY); |
| 1604 | } | 1610 | } |
| 1605 | } | 1611 | } |
| 1606 | atomic_inc(sk->sk_prot->orphan_count); | ||
| 1607 | 1612 | ||
| 1608 | if (sk->sk_state == TCP_CLOSE) | 1613 | if (sk->sk_state == TCP_CLOSE) |
| 1609 | inet_csk_destroy_sock(sk); | 1614 | inet_csk_destroy_sock(sk); |
diff --git a/net/ipv4/tcp_highspeed.c b/net/ipv4/tcp_highspeed.c index e0e9d1383c7c..b72fa55dfb84 100644 --- a/net/ipv4/tcp_highspeed.c +++ b/net/ipv4/tcp_highspeed.c | |||
| @@ -137,8 +137,8 @@ static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt, | |||
| 137 | if (tp->snd_cwnd < tp->snd_cwnd_clamp) { | 137 | if (tp->snd_cwnd < tp->snd_cwnd_clamp) { |
| 138 | tp->snd_cwnd_cnt += ca->ai; | 138 | tp->snd_cwnd_cnt += ca->ai; |
| 139 | if (tp->snd_cwnd_cnt >= tp->snd_cwnd) { | 139 | if (tp->snd_cwnd_cnt >= tp->snd_cwnd) { |
| 140 | tp->snd_cwnd++; | ||
| 141 | tp->snd_cwnd_cnt -= tp->snd_cwnd; | 140 | tp->snd_cwnd_cnt -= tp->snd_cwnd; |
| 141 | tp->snd_cwnd++; | ||
| 142 | } | 142 | } |
| 143 | } | 143 | } |
| 144 | } | 144 | } |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index a28ae593b976..743016baa048 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -465,7 +465,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
| 465 | TCP_INC_STATS(TCP_MIB_OUTSEGS); | 465 | TCP_INC_STATS(TCP_MIB_OUTSEGS); |
| 466 | 466 | ||
| 467 | err = icsk->icsk_af_ops->queue_xmit(skb, 0); | 467 | err = icsk->icsk_af_ops->queue_xmit(skb, 0); |
| 468 | if (unlikely(err <= 0)) | 468 | if (likely(err <= 0)) |
| 469 | return err; | 469 | return err; |
| 470 | 470 | ||
| 471 | tcp_enter_cwr(sk); | 471 | tcp_enter_cwr(sk); |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index 32ad229b4fed..4ef8efaf6a67 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
| @@ -62,7 +62,7 @@ static void xfrm4_encap(struct sk_buff *skb) | |||
| 62 | top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? | 62 | top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? |
| 63 | 0 : (iph->frag_off & htons(IP_DF)); | 63 | 0 : (iph->frag_off & htons(IP_DF)); |
| 64 | if (!top_iph->frag_off) | 64 | if (!top_iph->frag_off) |
| 65 | __ip_select_ident(top_iph, dst, 0); | 65 | __ip_select_ident(top_iph, dst->child, 0); |
| 66 | 66 | ||
| 67 | top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT); | 67 | top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT); |
| 68 | 68 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 79078747a646..0190e39096b9 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -317,7 +317,7 @@ static struct rt6_info *rt6_select(struct rt6_info **head, int oif, | |||
| 317 | __FUNCTION__, head, head ? *head : NULL, oif); | 317 | __FUNCTION__, head, head ? *head : NULL, oif); |
| 318 | 318 | ||
| 319 | for (rt = rt0, metric = rt0->rt6i_metric; | 319 | for (rt = rt0, metric = rt0->rt6i_metric; |
| 320 | rt && rt->rt6i_metric == metric; | 320 | rt && rt->rt6i_metric == metric && (!last || rt != rt0); |
| 321 | rt = rt->u.next) { | 321 | rt = rt->u.next) { |
| 322 | int m; | 322 | int m; |
| 323 | 323 | ||
| @@ -343,9 +343,12 @@ static struct rt6_info *rt6_select(struct rt6_info **head, int oif, | |||
| 343 | (strict & RT6_SELECT_F_REACHABLE) && | 343 | (strict & RT6_SELECT_F_REACHABLE) && |
| 344 | last && last != rt0) { | 344 | last && last != rt0) { |
| 345 | /* no entries matched; do round-robin */ | 345 | /* no entries matched; do round-robin */ |
| 346 | static spinlock_t lock = SPIN_LOCK_UNLOCKED; | ||
| 347 | spin_lock(&lock); | ||
| 346 | *head = rt0->u.next; | 348 | *head = rt0->u.next; |
| 347 | rt0->u.next = last->u.next; | 349 | rt0->u.next = last->u.next; |
| 348 | last->u.next = rt0; | 350 | last->u.next = rt0; |
| 351 | spin_unlock(&lock); | ||
| 349 | } | 352 | } |
| 350 | 353 | ||
| 351 | RT6_TRACE("%s() => %p, score=%d\n", | 354 | RT6_TRACE("%s() => %p, score=%d\n", |
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 9cccc325b687..0c6da496cfa9 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c | |||
| @@ -240,12 +240,15 @@ static int do_basic_checks(struct nf_conn *conntrack, | |||
| 240 | flag = 1; | 240 | flag = 1; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | /* Cookie Ack/Echo chunks not the first OR | 243 | /* |
| 244 | Init / Init Ack / Shutdown compl chunks not the only chunks */ | 244 | * Cookie Ack/Echo chunks not the first OR |
| 245 | if ((sch->type == SCTP_CID_COOKIE_ACK | 245 | * Init / Init Ack / Shutdown compl chunks not the only chunks |
| 246 | * OR zero-length. | ||
| 247 | */ | ||
| 248 | if (((sch->type == SCTP_CID_COOKIE_ACK | ||
| 246 | || sch->type == SCTP_CID_COOKIE_ECHO | 249 | || sch->type == SCTP_CID_COOKIE_ECHO |
| 247 | || flag) | 250 | || flag) |
| 248 | && count !=0 ) { | 251 | && count !=0) || !sch->length) { |
| 249 | DEBUGP("Basic checks failed\n"); | 252 | DEBUGP("Basic checks failed\n"); |
| 250 | return 1; | 253 | return 1; |
| 251 | } | 254 | } |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 17abf60f9570..99293c63ff73 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
| @@ -289,7 +289,7 @@ int xt_compat_match(void *match, void **dstptr, int *size, int convert) | |||
| 289 | case COMPAT_TO_USER: | 289 | case COMPAT_TO_USER: |
| 290 | pm = (struct xt_entry_match *)match; | 290 | pm = (struct xt_entry_match *)match; |
| 291 | msize = pm->u.user.match_size; | 291 | msize = pm->u.user.match_size; |
| 292 | if (__copy_to_user(*dstptr, pm, msize)) { | 292 | if (copy_to_user(*dstptr, pm, msize)) { |
| 293 | ret = -EFAULT; | 293 | ret = -EFAULT; |
| 294 | break; | 294 | break; |
| 295 | } | 295 | } |
| @@ -366,7 +366,7 @@ int xt_compat_target(void *target, void **dstptr, int *size, int convert) | |||
| 366 | case COMPAT_TO_USER: | 366 | case COMPAT_TO_USER: |
| 367 | pt = (struct xt_entry_target *)target; | 367 | pt = (struct xt_entry_target *)target; |
| 368 | tsize = pt->u.user.target_size; | 368 | tsize = pt->u.user.target_size; |
| 369 | if (__copy_to_user(*dstptr, pt, tsize)) { | 369 | if (copy_to_user(*dstptr, pt, tsize)) { |
| 370 | ret = -EFAULT; | 370 | ret = -EFAULT; |
| 371 | break; | 371 | break; |
| 372 | } | 372 | } |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 2a233ffcf618..3862e73d14d7 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -56,12 +56,12 @@ | |||
| 56 | #include <linux/mm.h> | 56 | #include <linux/mm.h> |
| 57 | #include <linux/types.h> | 57 | #include <linux/types.h> |
| 58 | #include <linux/audit.h> | 58 | #include <linux/audit.h> |
| 59 | #include <linux/selinux.h> | ||
| 59 | 60 | ||
| 60 | #include <net/sock.h> | 61 | #include <net/sock.h> |
| 61 | #include <net/scm.h> | 62 | #include <net/scm.h> |
| 62 | #include <net/netlink.h> | 63 | #include <net/netlink.h> |
| 63 | 64 | ||
| 64 | #define Nprintk(a...) | ||
| 65 | #define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8) | 65 | #define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8) |
| 66 | 66 | ||
| 67 | struct netlink_sock { | 67 | struct netlink_sock { |
| @@ -1157,6 +1157,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1157 | NETLINK_CB(skb).dst_pid = dst_pid; | 1157 | NETLINK_CB(skb).dst_pid = dst_pid; |
| 1158 | NETLINK_CB(skb).dst_group = dst_group; | 1158 | NETLINK_CB(skb).dst_group = dst_group; |
| 1159 | NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context); | 1159 | NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context); |
| 1160 | selinux_get_task_sid(current, &(NETLINK_CB(skb).sid)); | ||
| 1160 | memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); | 1161 | memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); |
| 1161 | 1162 | ||
| 1162 | /* What can I do? Netlink is asynchronous, so that | 1163 | /* What can I do? Netlink is asynchronous, so that |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index d44981f5a619..3669cb953e6e 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
| @@ -425,11 +425,16 @@ static int nr_create(struct socket *sock, int protocol) | |||
| 425 | 425 | ||
| 426 | nr_init_timers(sk); | 426 | nr_init_timers(sk); |
| 427 | 427 | ||
| 428 | nr->t1 = sysctl_netrom_transport_timeout; | 428 | nr->t1 = |
| 429 | nr->t2 = sysctl_netrom_transport_acknowledge_delay; | 429 | msecs_to_jiffies(sysctl_netrom_transport_timeout); |
| 430 | nr->n2 = sysctl_netrom_transport_maximum_tries; | 430 | nr->t2 = |
| 431 | nr->t4 = sysctl_netrom_transport_busy_delay; | 431 | msecs_to_jiffies(sysctl_netrom_transport_acknowledge_delay); |
| 432 | nr->idle = sysctl_netrom_transport_no_activity_timeout; | 432 | nr->n2 = |
| 433 | msecs_to_jiffies(sysctl_netrom_transport_maximum_tries); | ||
| 434 | nr->t4 = | ||
| 435 | msecs_to_jiffies(sysctl_netrom_transport_busy_delay); | ||
| 436 | nr->idle = | ||
| 437 | msecs_to_jiffies(sysctl_netrom_transport_no_activity_timeout); | ||
| 433 | nr->window = sysctl_netrom_transport_requested_window_size; | 438 | nr->window = sysctl_netrom_transport_requested_window_size; |
| 434 | 439 | ||
| 435 | nr->bpqext = 1; | 440 | nr->bpqext = 1; |
| @@ -1365,8 +1370,6 @@ static struct notifier_block nr_dev_notifier = { | |||
| 1365 | 1370 | ||
| 1366 | static struct net_device **dev_nr; | 1371 | static struct net_device **dev_nr; |
| 1367 | 1372 | ||
| 1368 | static char banner[] __initdata = KERN_INFO "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.4\n"; | ||
| 1369 | |||
| 1370 | static int __init nr_proto_init(void) | 1373 | static int __init nr_proto_init(void) |
| 1371 | { | 1374 | { |
| 1372 | int i; | 1375 | int i; |
| @@ -1414,7 +1417,6 @@ static int __init nr_proto_init(void) | |||
| 1414 | } | 1417 | } |
| 1415 | 1418 | ||
| 1416 | register_netdevice_notifier(&nr_dev_notifier); | 1419 | register_netdevice_notifier(&nr_dev_notifier); |
| 1417 | printk(banner); | ||
| 1418 | 1420 | ||
| 1419 | ax25_protocol_register(AX25_P_NETROM, nr_route_frame); | 1421 | ax25_protocol_register(AX25_P_NETROM, nr_route_frame); |
| 1420 | ax25_linkfail_register(nr_link_failed); | 1422 | ax25_linkfail_register(nr_link_failed); |
diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c index 509afddae569..621e5586ab03 100644 --- a/net/netrom/nr_dev.c +++ b/net/netrom/nr_dev.c | |||
| @@ -185,7 +185,6 @@ static struct net_device_stats *nr_get_stats(struct net_device *dev) | |||
| 185 | 185 | ||
| 186 | void nr_setup(struct net_device *dev) | 186 | void nr_setup(struct net_device *dev) |
| 187 | { | 187 | { |
| 188 | SET_MODULE_OWNER(dev); | ||
| 189 | dev->mtu = NR_MAX_PACKET_SIZE; | 188 | dev->mtu = NR_MAX_PACKET_SIZE; |
| 190 | dev->hard_start_xmit = nr_xmit; | 189 | dev->hard_start_xmit = nr_xmit; |
| 191 | dev->open = nr_open; | 190 | dev->open = nr_open; |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index ea65396d1619..55564efccf11 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
| @@ -518,11 +518,11 @@ static int rose_create(struct socket *sock, int protocol) | |||
| 518 | init_timer(&rose->timer); | 518 | init_timer(&rose->timer); |
| 519 | init_timer(&rose->idletimer); | 519 | init_timer(&rose->idletimer); |
| 520 | 520 | ||
| 521 | rose->t1 = sysctl_rose_call_request_timeout; | 521 | rose->t1 = msecs_to_jiffies(sysctl_rose_call_request_timeout); |
| 522 | rose->t2 = sysctl_rose_reset_request_timeout; | 522 | rose->t2 = msecs_to_jiffies(sysctl_rose_reset_request_timeout); |
| 523 | rose->t3 = sysctl_rose_clear_request_timeout; | 523 | rose->t3 = msecs_to_jiffies(sysctl_rose_clear_request_timeout); |
| 524 | rose->hb = sysctl_rose_ack_hold_back_timeout; | 524 | rose->hb = msecs_to_jiffies(sysctl_rose_ack_hold_back_timeout); |
| 525 | rose->idle = sysctl_rose_no_activity_timeout; | 525 | rose->idle = msecs_to_jiffies(sysctl_rose_no_activity_timeout); |
| 526 | 526 | ||
| 527 | rose->state = ROSE_STATE_0; | 527 | rose->state = ROSE_STATE_0; |
| 528 | 528 | ||
| @@ -1469,8 +1469,6 @@ static struct notifier_block rose_dev_notifier = { | |||
| 1469 | 1469 | ||
| 1470 | static struct net_device **dev_rose; | 1470 | static struct net_device **dev_rose; |
| 1471 | 1471 | ||
| 1472 | static const char banner[] = KERN_INFO "F6FBB/G4KLX ROSE for Linux. Version 0.62 for AX25.037 Linux 2.4\n"; | ||
| 1473 | |||
| 1474 | static int __init rose_proto_init(void) | 1472 | static int __init rose_proto_init(void) |
| 1475 | { | 1473 | { |
| 1476 | int i; | 1474 | int i; |
| @@ -1519,7 +1517,6 @@ static int __init rose_proto_init(void) | |||
| 1519 | 1517 | ||
| 1520 | sock_register(&rose_family_ops); | 1518 | sock_register(&rose_family_ops); |
| 1521 | register_netdevice_notifier(&rose_dev_notifier); | 1519 | register_netdevice_notifier(&rose_dev_notifier); |
| 1522 | printk(banner); | ||
| 1523 | 1520 | ||
| 1524 | ax25_protocol_register(AX25_P_ROSE, rose_route_frame); | 1521 | ax25_protocol_register(AX25_P_ROSE, rose_route_frame); |
| 1525 | ax25_linkfail_register(rose_link_failed); | 1522 | ax25_linkfail_register(rose_link_failed); |
diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c index d297af737d10..2a1bf8e119e5 100644 --- a/net/rose/rose_dev.c +++ b/net/rose/rose_dev.c | |||
| @@ -135,7 +135,6 @@ static struct net_device_stats *rose_get_stats(struct net_device *dev) | |||
| 135 | 135 | ||
| 136 | void rose_setup(struct net_device *dev) | 136 | void rose_setup(struct net_device *dev) |
| 137 | { | 137 | { |
| 138 | SET_MODULE_OWNER(dev); | ||
| 139 | dev->mtu = ROSE_MAX_PACKET_SIZE - 2; | 138 | dev->mtu = ROSE_MAX_PACKET_SIZE - 2; |
| 140 | dev->hard_start_xmit = rose_xmit; | 139 | dev->hard_start_xmit = rose_xmit; |
| 141 | dev->open = rose_open; | 140 | dev->open = rose_open; |
diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c index 09e9e9d04d92..bd86a63960ce 100644 --- a/net/rose/rose_link.c +++ b/net/rose/rose_link.c | |||
| @@ -40,7 +40,8 @@ void rose_start_ftimer(struct rose_neigh *neigh) | |||
| 40 | 40 | ||
| 41 | neigh->ftimer.data = (unsigned long)neigh; | 41 | neigh->ftimer.data = (unsigned long)neigh; |
| 42 | neigh->ftimer.function = &rose_ftimer_expiry; | 42 | neigh->ftimer.function = &rose_ftimer_expiry; |
| 43 | neigh->ftimer.expires = jiffies + sysctl_rose_link_fail_timeout; | 43 | neigh->ftimer.expires = |
| 44 | jiffies + msecs_to_jiffies(sysctl_rose_link_fail_timeout); | ||
| 44 | 45 | ||
| 45 | add_timer(&neigh->ftimer); | 46 | add_timer(&neigh->ftimer); |
| 46 | } | 47 | } |
| @@ -51,7 +52,8 @@ static void rose_start_t0timer(struct rose_neigh *neigh) | |||
| 51 | 52 | ||
| 52 | neigh->t0timer.data = (unsigned long)neigh; | 53 | neigh->t0timer.data = (unsigned long)neigh; |
| 53 | neigh->t0timer.function = &rose_t0timer_expiry; | 54 | neigh->t0timer.function = &rose_t0timer_expiry; |
| 54 | neigh->t0timer.expires = jiffies + sysctl_rose_restart_request_timeout; | 55 | neigh->t0timer.expires = |
| 56 | jiffies + msecs_to_jiffies(sysctl_rose_restart_request_timeout); | ||
| 55 | 57 | ||
| 56 | add_timer(&neigh->t0timer); | 58 | add_timer(&neigh->t0timer); |
| 57 | } | 59 | } |
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index 8631b65a7312..a22542fa1bc8 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c | |||
| @@ -48,8 +48,6 @@ static DEFINE_SPINLOCK(rose_route_list_lock); | |||
| 48 | 48 | ||
| 49 | struct rose_neigh *rose_loopback_neigh; | 49 | struct rose_neigh *rose_loopback_neigh; |
| 50 | 50 | ||
| 51 | static void rose_remove_neigh(struct rose_neigh *); | ||
| 52 | |||
| 53 | /* | 51 | /* |
| 54 | * Add a new route to a node, and in the process add the node and the | 52 | * Add a new route to a node, and in the process add the node and the |
| 55 | * neighbour if it is new. | 53 | * neighbour if it is new. |
| @@ -235,11 +233,8 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh) | |||
| 235 | 233 | ||
| 236 | skb_queue_purge(&rose_neigh->queue); | 234 | skb_queue_purge(&rose_neigh->queue); |
| 237 | 235 | ||
| 238 | spin_lock_bh(&rose_neigh_list_lock); | ||
| 239 | |||
| 240 | if ((s = rose_neigh_list) == rose_neigh) { | 236 | if ((s = rose_neigh_list) == rose_neigh) { |
| 241 | rose_neigh_list = rose_neigh->next; | 237 | rose_neigh_list = rose_neigh->next; |
| 242 | spin_unlock_bh(&rose_neigh_list_lock); | ||
| 243 | kfree(rose_neigh->digipeat); | 238 | kfree(rose_neigh->digipeat); |
| 244 | kfree(rose_neigh); | 239 | kfree(rose_neigh); |
| 245 | return; | 240 | return; |
| @@ -248,7 +243,6 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh) | |||
| 248 | while (s != NULL && s->next != NULL) { | 243 | while (s != NULL && s->next != NULL) { |
| 249 | if (s->next == rose_neigh) { | 244 | if (s->next == rose_neigh) { |
| 250 | s->next = rose_neigh->next; | 245 | s->next = rose_neigh->next; |
| 251 | spin_unlock_bh(&rose_neigh_list_lock); | ||
| 252 | kfree(rose_neigh->digipeat); | 246 | kfree(rose_neigh->digipeat); |
| 253 | kfree(rose_neigh); | 247 | kfree(rose_neigh); |
| 254 | return; | 248 | return; |
| @@ -256,7 +250,6 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh) | |||
| 256 | 250 | ||
| 257 | s = s->next; | 251 | s = s->next; |
| 258 | } | 252 | } |
| 259 | spin_unlock_bh(&rose_neigh_list_lock); | ||
| 260 | } | 253 | } |
| 261 | 254 | ||
| 262 | /* | 255 | /* |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 7228d30512c7..5a4a4d0ae502 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
| @@ -167,7 +167,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 167 | if (count == 0) { | 167 | if (count == 0) { |
| 168 | sch->qstats.drops++; | 168 | sch->qstats.drops++; |
| 169 | kfree_skb(skb); | 169 | kfree_skb(skb); |
| 170 | return NET_XMIT_DROP; | 170 | return NET_XMIT_BYPASS; |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | /* | 173 | /* |
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index 297b8951463e..cf0c767d43ae 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c | |||
| @@ -149,6 +149,7 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) | |||
| 149 | /* This is the first chunk in the packet. */ | 149 | /* This is the first chunk in the packet. */ |
| 150 | chunk->singleton = 1; | 150 | chunk->singleton = 1; |
| 151 | ch = (sctp_chunkhdr_t *) chunk->skb->data; | 151 | ch = (sctp_chunkhdr_t *) chunk->skb->data; |
| 152 | chunk->data_accepted = 0; | ||
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | chunk->chunk_hdr = ch; | 155 | chunk->chunk_hdr = ch; |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 2b9a832b29a7..8cdba51ec076 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -636,8 +636,9 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, | |||
| 636 | */ | 636 | */ |
| 637 | chunk->subh.cookie_hdr = | 637 | chunk->subh.cookie_hdr = |
| 638 | (struct sctp_signed_cookie *)chunk->skb->data; | 638 | (struct sctp_signed_cookie *)chunk->skb->data; |
| 639 | skb_pull(chunk->skb, | 639 | if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - |
| 640 | ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t)); | 640 | sizeof(sctp_chunkhdr_t))) |
| 641 | goto nomem; | ||
| 641 | 642 | ||
| 642 | /* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint | 643 | /* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint |
| 643 | * "Z" will reply with a COOKIE ACK chunk after building a TCB | 644 | * "Z" will reply with a COOKIE ACK chunk after building a TCB |
| @@ -965,7 +966,8 @@ sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep, | |||
| 965 | */ | 966 | */ |
| 966 | chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data; | 967 | chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data; |
| 967 | paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); | 968 | paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); |
| 968 | skb_pull(chunk->skb, paylen); | 969 | if (!pskb_pull(chunk->skb, paylen)) |
| 970 | goto nomem; | ||
| 969 | 971 | ||
| 970 | reply = sctp_make_heartbeat_ack(asoc, chunk, | 972 | reply = sctp_make_heartbeat_ack(asoc, chunk, |
| 971 | chunk->subh.hb_hdr, paylen); | 973 | chunk->subh.hb_hdr, paylen); |
| @@ -1860,8 +1862,9 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep, | |||
| 1860 | * are in good shape. | 1862 | * are in good shape. |
| 1861 | */ | 1863 | */ |
| 1862 | chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data; | 1864 | chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data; |
| 1863 | skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - | 1865 | if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - |
| 1864 | sizeof(sctp_chunkhdr_t)); | 1866 | sizeof(sctp_chunkhdr_t))) |
| 1867 | goto nomem; | ||
| 1865 | 1868 | ||
| 1866 | /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie | 1869 | /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie |
| 1867 | * of a duplicate COOKIE ECHO match the Verification Tags of the | 1870 | * of a duplicate COOKIE ECHO match the Verification Tags of the |
| @@ -5151,7 +5154,9 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
| 5151 | int tmp; | 5154 | int tmp; |
| 5152 | __u32 tsn; | 5155 | __u32 tsn; |
| 5153 | int account_value; | 5156 | int account_value; |
| 5157 | struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; | ||
| 5154 | struct sock *sk = asoc->base.sk; | 5158 | struct sock *sk = asoc->base.sk; |
| 5159 | int rcvbuf_over = 0; | ||
| 5155 | 5160 | ||
| 5156 | data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data; | 5161 | data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data; |
| 5157 | skb_pull(chunk->skb, sizeof(sctp_datahdr_t)); | 5162 | skb_pull(chunk->skb, sizeof(sctp_datahdr_t)); |
| @@ -5162,10 +5167,16 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
| 5162 | /* ASSERT: Now skb->data is really the user data. */ | 5167 | /* ASSERT: Now skb->data is really the user data. */ |
| 5163 | 5168 | ||
| 5164 | /* | 5169 | /* |
| 5165 | * if we are established, and we have used up our receive | 5170 | * If we are established, and we have used up our receive buffer |
| 5166 | * buffer memory, drop the frame | 5171 | * memory, think about droping the frame. |
| 5167 | */ | 5172 | * Note that we have an opportunity to improve performance here. |
| 5168 | if (asoc->state == SCTP_STATE_ESTABLISHED) { | 5173 | * If we accept one chunk from an skbuff, we have to keep all the |
| 5174 | * memory of that skbuff around until the chunk is read into user | ||
| 5175 | * space. Therefore, once we accept 1 chunk we may as well accept all | ||
| 5176 | * remaining chunks in the skbuff. The data_accepted flag helps us do | ||
| 5177 | * that. | ||
| 5178 | */ | ||
| 5179 | if ((asoc->state == SCTP_STATE_ESTABLISHED) && (!chunk->data_accepted)) { | ||
| 5169 | /* | 5180 | /* |
| 5170 | * If the receive buffer policy is 1, then each | 5181 | * If the receive buffer policy is 1, then each |
| 5171 | * association can allocate up to sk_rcvbuf bytes | 5182 | * association can allocate up to sk_rcvbuf bytes |
| @@ -5176,9 +5187,25 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
| 5176 | account_value = atomic_read(&asoc->rmem_alloc); | 5187 | account_value = atomic_read(&asoc->rmem_alloc); |
| 5177 | else | 5188 | else |
| 5178 | account_value = atomic_read(&sk->sk_rmem_alloc); | 5189 | account_value = atomic_read(&sk->sk_rmem_alloc); |
| 5179 | 5190 | if (account_value > sk->sk_rcvbuf) { | |
| 5180 | if (account_value > sk->sk_rcvbuf) | 5191 | /* |
| 5181 | return SCTP_IERROR_IGNORE_TSN; | 5192 | * We need to make forward progress, even when we are |
| 5193 | * under memory pressure, so we always allow the | ||
| 5194 | * next tsn after the ctsn ack point to be accepted. | ||
| 5195 | * This lets us avoid deadlocks in which we have to | ||
| 5196 | * drop frames that would otherwise let us drain the | ||
| 5197 | * receive queue. | ||
| 5198 | */ | ||
| 5199 | if ((sctp_tsnmap_get_ctsn(map) + 1) != tsn) | ||
| 5200 | return SCTP_IERROR_IGNORE_TSN; | ||
| 5201 | |||
| 5202 | /* | ||
| 5203 | * We're going to accept the frame but we should renege | ||
| 5204 | * to make space for it. This will send us down that | ||
| 5205 | * path later in this function. | ||
| 5206 | */ | ||
| 5207 | rcvbuf_over = 1; | ||
| 5208 | } | ||
| 5182 | } | 5209 | } |
| 5183 | 5210 | ||
| 5184 | /* Process ECN based congestion. | 5211 | /* Process ECN based congestion. |
| @@ -5226,6 +5253,7 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
| 5226 | datalen -= sizeof(sctp_data_chunk_t); | 5253 | datalen -= sizeof(sctp_data_chunk_t); |
| 5227 | 5254 | ||
| 5228 | deliver = SCTP_CMD_CHUNK_ULP; | 5255 | deliver = SCTP_CMD_CHUNK_ULP; |
| 5256 | chunk->data_accepted = 1; | ||
| 5229 | 5257 | ||
| 5230 | /* Think about partial delivery. */ | 5258 | /* Think about partial delivery. */ |
| 5231 | if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) { | 5259 | if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) { |
| @@ -5242,7 +5270,8 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
| 5242 | * large spill over. | 5270 | * large spill over. |
| 5243 | */ | 5271 | */ |
| 5244 | if (!asoc->rwnd || asoc->rwnd_over || | 5272 | if (!asoc->rwnd || asoc->rwnd_over || |
| 5245 | (datalen > asoc->rwnd + asoc->frag_point)) { | 5273 | (datalen > asoc->rwnd + asoc->frag_point) || |
| 5274 | rcvbuf_over) { | ||
| 5246 | 5275 | ||
| 5247 | /* If this is the next TSN, consider reneging to make | 5276 | /* If this is the next TSN, consider reneging to make |
| 5248 | * room. Note: Playing nice with a confused sender. A | 5277 | * room. Note: Playing nice with a confused sender. A |
| @@ -5250,8 +5279,8 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
| 5250 | * space and in the future we may want to detect and | 5279 | * space and in the future we may want to detect and |
| 5251 | * do more drastic reneging. | 5280 | * do more drastic reneging. |
| 5252 | */ | 5281 | */ |
| 5253 | if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) && | 5282 | if (sctp_tsnmap_has_gap(map) && |
| 5254 | (sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) { | 5283 | (sctp_tsnmap_get_ctsn(map) + 1) == tsn) { |
| 5255 | SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn); | 5284 | SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn); |
| 5256 | deliver = SCTP_CMD_RENEGE; | 5285 | deliver = SCTP_CMD_RENEGE; |
| 5257 | } else { | 5286 | } else { |
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c index 75ef10408764..8bcca5676151 100644 --- a/net/sctp/sm_statetable.c +++ b/net/sctp/sm_statetable.c | |||
| @@ -366,9 +366,9 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
| 366 | /* SCTP_STATE_EMPTY */ \ | 366 | /* SCTP_STATE_EMPTY */ \ |
| 367 | {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ | 367 | {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ |
| 368 | /* SCTP_STATE_CLOSED */ \ | 368 | /* SCTP_STATE_CLOSED */ \ |
| 369 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ | 369 | {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ |
| 370 | /* SCTP_STATE_COOKIE_WAIT */ \ | 370 | /* SCTP_STATE_COOKIE_WAIT */ \ |
| 371 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ | 371 | {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ |
| 372 | /* SCTP_STATE_COOKIE_ECHOED */ \ | 372 | /* SCTP_STATE_COOKIE_ECHOED */ \ |
| 373 | {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ | 373 | {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ |
| 374 | /* SCTP_STATE_ESTABLISHED */ \ | 374 | /* SCTP_STATE_ESTABLISHED */ \ |
| @@ -380,7 +380,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
| 380 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ | 380 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ |
| 381 | {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ | 381 | {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ |
| 382 | /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ | 382 | /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ |
| 383 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ | 383 | {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ |
| 384 | } /* TYPE_SCTP_ECN_ECNE */ | 384 | } /* TYPE_SCTP_ECN_ECNE */ |
| 385 | 385 | ||
| 386 | #define TYPE_SCTP_ECN_CWR { \ | 386 | #define TYPE_SCTP_ECN_CWR { \ |
| @@ -401,7 +401,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, | |||
| 401 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ | 401 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ |
| 402 | {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ | 402 | {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ |
| 403 | /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ | 403 | /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ |
| 404 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ | 404 | {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ |
| 405 | } /* TYPE_SCTP_ECN_CWR */ | 405 | } /* TYPE_SCTP_ECN_CWR */ |
| 406 | 406 | ||
| 407 | #define TYPE_SCTP_SHUTDOWN_COMPLETE { \ | 407 | #define TYPE_SCTP_SHUTDOWN_COMPLETE { \ |
| @@ -647,7 +647,7 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { | |||
| 647 | /* SCTP_STATE_EMPTY */ \ | 647 | /* SCTP_STATE_EMPTY */ \ |
| 648 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ | 648 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ |
| 649 | /* SCTP_STATE_CLOSED */ \ | 649 | /* SCTP_STATE_CLOSED */ \ |
| 650 | {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ | 650 | {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ |
| 651 | /* SCTP_STATE_COOKIE_WAIT */ \ | 651 | /* SCTP_STATE_COOKIE_WAIT */ \ |
| 652 | {.fn = sctp_sf_do_prm_requestheartbeat, \ | 652 | {.fn = sctp_sf_do_prm_requestheartbeat, \ |
| 653 | .name = "sctp_sf_do_prm_requestheartbeat"}, \ | 653 | .name = "sctp_sf_do_prm_requestheartbeat"}, \ |
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index 2080b2d28c98..575e556aeb3e 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c | |||
| @@ -279,6 +279,7 @@ static inline void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq, | |||
| 279 | static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *queue, struct sk_buff *f_frag, struct sk_buff *l_frag) | 279 | static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *queue, struct sk_buff *f_frag, struct sk_buff *l_frag) |
| 280 | { | 280 | { |
| 281 | struct sk_buff *pos; | 281 | struct sk_buff *pos; |
| 282 | struct sk_buff *new = NULL; | ||
| 282 | struct sctp_ulpevent *event; | 283 | struct sctp_ulpevent *event; |
| 283 | struct sk_buff *pnext, *last; | 284 | struct sk_buff *pnext, *last; |
| 284 | struct sk_buff *list = skb_shinfo(f_frag)->frag_list; | 285 | struct sk_buff *list = skb_shinfo(f_frag)->frag_list; |
| @@ -297,11 +298,33 @@ static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *qu | |||
| 297 | */ | 298 | */ |
| 298 | if (last) | 299 | if (last) |
| 299 | last->next = pos; | 300 | last->next = pos; |
| 300 | else | 301 | else { |
| 301 | skb_shinfo(f_frag)->frag_list = pos; | 302 | if (skb_cloned(f_frag)) { |
| 303 | /* This is a cloned skb, we can't just modify | ||
| 304 | * the frag_list. We need a new skb to do that. | ||
| 305 | * Instead of calling skb_unshare(), we'll do it | ||
| 306 | * ourselves since we need to delay the free. | ||
| 307 | */ | ||
| 308 | new = skb_copy(f_frag, GFP_ATOMIC); | ||
| 309 | if (!new) | ||
| 310 | return NULL; /* try again later */ | ||
| 311 | |||
| 312 | new->sk = f_frag->sk; | ||
| 313 | |||
| 314 | skb_shinfo(new)->frag_list = pos; | ||
| 315 | } else | ||
| 316 | skb_shinfo(f_frag)->frag_list = pos; | ||
| 317 | } | ||
| 302 | 318 | ||
| 303 | /* Remove the first fragment from the reassembly queue. */ | 319 | /* Remove the first fragment from the reassembly queue. */ |
| 304 | __skb_unlink(f_frag, queue); | 320 | __skb_unlink(f_frag, queue); |
| 321 | |||
| 322 | /* if we did unshare, then free the old skb and re-assign */ | ||
| 323 | if (new) { | ||
| 324 | kfree_skb(f_frag); | ||
| 325 | f_frag = new; | ||
| 326 | } | ||
| 327 | |||
| 305 | while (pos) { | 328 | while (pos) { |
| 306 | 329 | ||
| 307 | pnext = pos->next; | 330 | pnext = pos->next; |
diff --git a/net/socket.c b/net/socket.c index 0ce12dfc7a71..02948b622bd2 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -267,6 +267,8 @@ int move_addr_to_user(void *kaddr, int klen, void __user *uaddr, int __user *ule | |||
| 267 | return -EINVAL; | 267 | return -EINVAL; |
| 268 | if(len) | 268 | if(len) |
| 269 | { | 269 | { |
| 270 | if (audit_sockaddr(klen, kaddr)) | ||
| 271 | return -ENOMEM; | ||
| 270 | if(copy_to_user(uaddr,kaddr,len)) | 272 | if(copy_to_user(uaddr,kaddr,len)) |
| 271 | return -EFAULT; | 273 | return -EFAULT; |
| 272 | } | 274 | } |
diff --git a/net/x25/x25_timer.c b/net/x25/x25_timer.c index 0a92e1da3922..71ff3088f6fe 100644 --- a/net/x25/x25_timer.c +++ b/net/x25/x25_timer.c | |||
| @@ -114,8 +114,9 @@ static void x25_heartbeat_expiry(unsigned long param) | |||
| 114 | if (sock_flag(sk, SOCK_DESTROY) || | 114 | if (sock_flag(sk, SOCK_DESTROY) || |
| 115 | (sk->sk_state == TCP_LISTEN && | 115 | (sk->sk_state == TCP_LISTEN && |
| 116 | sock_flag(sk, SOCK_DEAD))) { | 116 | sock_flag(sk, SOCK_DEAD))) { |
| 117 | bh_unlock_sock(sk); | ||
| 117 | x25_destroy_socket(sk); | 118 | x25_destroy_socket(sk); |
| 118 | goto unlock; | 119 | return; |
| 119 | } | 120 | } |
| 120 | break; | 121 | break; |
| 121 | 122 | ||
| @@ -128,7 +129,6 @@ static void x25_heartbeat_expiry(unsigned long param) | |||
| 128 | } | 129 | } |
| 129 | restart_heartbeat: | 130 | restart_heartbeat: |
| 130 | x25_start_heartbeat(sk); | 131 | x25_start_heartbeat(sk); |
| 131 | unlock: | ||
| 132 | bh_unlock_sock(sk); | 132 | bh_unlock_sock(sk); |
| 133 | } | 133 | } |
| 134 | 134 | ||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index c3725fe2a8fb..b469c8b54613 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -57,12 +57,12 @@ int xfrm_register_type(struct xfrm_type *type, unsigned short family) | |||
| 57 | return -EAFNOSUPPORT; | 57 | return -EAFNOSUPPORT; |
| 58 | typemap = afinfo->type_map; | 58 | typemap = afinfo->type_map; |
| 59 | 59 | ||
| 60 | write_lock(&typemap->lock); | 60 | write_lock_bh(&typemap->lock); |
| 61 | if (likely(typemap->map[type->proto] == NULL)) | 61 | if (likely(typemap->map[type->proto] == NULL)) |
| 62 | typemap->map[type->proto] = type; | 62 | typemap->map[type->proto] = type; |
| 63 | else | 63 | else |
| 64 | err = -EEXIST; | 64 | err = -EEXIST; |
| 65 | write_unlock(&typemap->lock); | 65 | write_unlock_bh(&typemap->lock); |
| 66 | xfrm_policy_put_afinfo(afinfo); | 66 | xfrm_policy_put_afinfo(afinfo); |
| 67 | return err; | 67 | return err; |
| 68 | } | 68 | } |
| @@ -78,12 +78,12 @@ int xfrm_unregister_type(struct xfrm_type *type, unsigned short family) | |||
| 78 | return -EAFNOSUPPORT; | 78 | return -EAFNOSUPPORT; |
| 79 | typemap = afinfo->type_map; | 79 | typemap = afinfo->type_map; |
| 80 | 80 | ||
| 81 | write_lock(&typemap->lock); | 81 | write_lock_bh(&typemap->lock); |
| 82 | if (unlikely(typemap->map[type->proto] != type)) | 82 | if (unlikely(typemap->map[type->proto] != type)) |
| 83 | err = -ENOENT; | 83 | err = -ENOENT; |
| 84 | else | 84 | else |
| 85 | typemap->map[type->proto] = NULL; | 85 | typemap->map[type->proto] = NULL; |
| 86 | write_unlock(&typemap->lock); | 86 | write_unlock_bh(&typemap->lock); |
| 87 | xfrm_policy_put_afinfo(afinfo); | 87 | xfrm_policy_put_afinfo(afinfo); |
| 88 | return err; | 88 | return err; |
| 89 | } | 89 | } |
| @@ -1251,7 +1251,7 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
| 1251 | return -EINVAL; | 1251 | return -EINVAL; |
| 1252 | if (unlikely(afinfo->family >= NPROTO)) | 1252 | if (unlikely(afinfo->family >= NPROTO)) |
| 1253 | return -EAFNOSUPPORT; | 1253 | return -EAFNOSUPPORT; |
| 1254 | write_lock(&xfrm_policy_afinfo_lock); | 1254 | write_lock_bh(&xfrm_policy_afinfo_lock); |
| 1255 | if (unlikely(xfrm_policy_afinfo[afinfo->family] != NULL)) | 1255 | if (unlikely(xfrm_policy_afinfo[afinfo->family] != NULL)) |
| 1256 | err = -ENOBUFS; | 1256 | err = -ENOBUFS; |
| 1257 | else { | 1257 | else { |
| @@ -1268,7 +1268,7 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
| 1268 | afinfo->garbage_collect = __xfrm_garbage_collect; | 1268 | afinfo->garbage_collect = __xfrm_garbage_collect; |
| 1269 | xfrm_policy_afinfo[afinfo->family] = afinfo; | 1269 | xfrm_policy_afinfo[afinfo->family] = afinfo; |
| 1270 | } | 1270 | } |
| 1271 | write_unlock(&xfrm_policy_afinfo_lock); | 1271 | write_unlock_bh(&xfrm_policy_afinfo_lock); |
| 1272 | return err; | 1272 | return err; |
| 1273 | } | 1273 | } |
| 1274 | EXPORT_SYMBOL(xfrm_policy_register_afinfo); | 1274 | EXPORT_SYMBOL(xfrm_policy_register_afinfo); |
| @@ -1280,7 +1280,7 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
| 1280 | return -EINVAL; | 1280 | return -EINVAL; |
| 1281 | if (unlikely(afinfo->family >= NPROTO)) | 1281 | if (unlikely(afinfo->family >= NPROTO)) |
| 1282 | return -EAFNOSUPPORT; | 1282 | return -EAFNOSUPPORT; |
| 1283 | write_lock(&xfrm_policy_afinfo_lock); | 1283 | write_lock_bh(&xfrm_policy_afinfo_lock); |
| 1284 | if (likely(xfrm_policy_afinfo[afinfo->family] != NULL)) { | 1284 | if (likely(xfrm_policy_afinfo[afinfo->family] != NULL)) { |
| 1285 | if (unlikely(xfrm_policy_afinfo[afinfo->family] != afinfo)) | 1285 | if (unlikely(xfrm_policy_afinfo[afinfo->family] != afinfo)) |
| 1286 | err = -EINVAL; | 1286 | err = -EINVAL; |
| @@ -1294,7 +1294,7 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
| 1294 | afinfo->garbage_collect = NULL; | 1294 | afinfo->garbage_collect = NULL; |
| 1295 | } | 1295 | } |
| 1296 | } | 1296 | } |
| 1297 | write_unlock(&xfrm_policy_afinfo_lock); | 1297 | write_unlock_bh(&xfrm_policy_afinfo_lock); |
| 1298 | return err; | 1298 | return err; |
| 1299 | } | 1299 | } |
| 1300 | EXPORT_SYMBOL(xfrm_policy_unregister_afinfo); | 1300 | EXPORT_SYMBOL(xfrm_policy_unregister_afinfo); |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 3dc3e1f3b7aa..93a2f36ad3db 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -1061,7 +1061,7 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo) | |||
| 1061 | return -EINVAL; | 1061 | return -EINVAL; |
| 1062 | if (unlikely(afinfo->family >= NPROTO)) | 1062 | if (unlikely(afinfo->family >= NPROTO)) |
| 1063 | return -EAFNOSUPPORT; | 1063 | return -EAFNOSUPPORT; |
| 1064 | write_lock(&xfrm_state_afinfo_lock); | 1064 | write_lock_bh(&xfrm_state_afinfo_lock); |
| 1065 | if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL)) | 1065 | if (unlikely(xfrm_state_afinfo[afinfo->family] != NULL)) |
| 1066 | err = -ENOBUFS; | 1066 | err = -ENOBUFS; |
| 1067 | else { | 1067 | else { |
| @@ -1069,7 +1069,7 @@ int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo) | |||
| 1069 | afinfo->state_byspi = xfrm_state_byspi; | 1069 | afinfo->state_byspi = xfrm_state_byspi; |
| 1070 | xfrm_state_afinfo[afinfo->family] = afinfo; | 1070 | xfrm_state_afinfo[afinfo->family] = afinfo; |
| 1071 | } | 1071 | } |
| 1072 | write_unlock(&xfrm_state_afinfo_lock); | 1072 | write_unlock_bh(&xfrm_state_afinfo_lock); |
| 1073 | return err; | 1073 | return err; |
| 1074 | } | 1074 | } |
| 1075 | EXPORT_SYMBOL(xfrm_state_register_afinfo); | 1075 | EXPORT_SYMBOL(xfrm_state_register_afinfo); |
| @@ -1081,7 +1081,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo) | |||
| 1081 | return -EINVAL; | 1081 | return -EINVAL; |
| 1082 | if (unlikely(afinfo->family >= NPROTO)) | 1082 | if (unlikely(afinfo->family >= NPROTO)) |
| 1083 | return -EAFNOSUPPORT; | 1083 | return -EAFNOSUPPORT; |
| 1084 | write_lock(&xfrm_state_afinfo_lock); | 1084 | write_lock_bh(&xfrm_state_afinfo_lock); |
| 1085 | if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) { | 1085 | if (likely(xfrm_state_afinfo[afinfo->family] != NULL)) { |
| 1086 | if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo)) | 1086 | if (unlikely(xfrm_state_afinfo[afinfo->family] != afinfo)) |
| 1087 | err = -EINVAL; | 1087 | err = -EINVAL; |
| @@ -1091,7 +1091,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo) | |||
| 1091 | afinfo->state_bydst = NULL; | 1091 | afinfo->state_bydst = NULL; |
| 1092 | } | 1092 | } |
| 1093 | } | 1093 | } |
| 1094 | write_unlock(&xfrm_state_afinfo_lock); | 1094 | write_unlock_bh(&xfrm_state_afinfo_lock); |
| 1095 | return err; | 1095 | return err; |
| 1096 | } | 1096 | } |
| 1097 | EXPORT_SYMBOL(xfrm_state_unregister_afinfo); | 1097 | EXPORT_SYMBOL(xfrm_state_unregister_afinfo); |
diff --git a/security/dummy.c b/security/dummy.c index fd99429278e9..8ccccccc12ac 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
| @@ -563,11 +563,6 @@ static int dummy_ipc_permission (struct kern_ipc_perm *ipcp, short flag) | |||
| 563 | return 0; | 563 | return 0; |
| 564 | } | 564 | } |
| 565 | 565 | ||
| 566 | static int dummy_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) | ||
| 567 | { | ||
| 568 | return -EOPNOTSUPP; | ||
| 569 | } | ||
| 570 | |||
| 571 | static int dummy_msg_msg_alloc_security (struct msg_msg *msg) | 566 | static int dummy_msg_msg_alloc_security (struct msg_msg *msg) |
| 572 | { | 567 | { |
| 573 | return 0; | 568 | return 0; |
| @@ -976,7 +971,6 @@ void security_fixup_ops (struct security_operations *ops) | |||
| 976 | set_to_dummy_if_null(ops, task_reparent_to_init); | 971 | set_to_dummy_if_null(ops, task_reparent_to_init); |
| 977 | set_to_dummy_if_null(ops, task_to_inode); | 972 | set_to_dummy_if_null(ops, task_to_inode); |
| 978 | set_to_dummy_if_null(ops, ipc_permission); | 973 | set_to_dummy_if_null(ops, ipc_permission); |
| 979 | set_to_dummy_if_null(ops, ipc_getsecurity); | ||
| 980 | set_to_dummy_if_null(ops, msg_msg_alloc_security); | 974 | set_to_dummy_if_null(ops, msg_msg_alloc_security); |
| 981 | set_to_dummy_if_null(ops, msg_msg_free_security); | 975 | set_to_dummy_if_null(ops, msg_msg_free_security); |
| 982 | set_to_dummy_if_null(ops, msg_queue_alloc_security); | 976 | set_to_dummy_if_null(ops, msg_queue_alloc_security); |
diff --git a/security/selinux/Makefile b/security/selinux/Makefile index 688c0a267b62..faf2e02e4410 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/ | 5 | obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/ |
| 6 | 6 | ||
| 7 | selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o | 7 | selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o exports.o |
| 8 | 8 | ||
| 9 | selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o | 9 | selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o |
| 10 | 10 | ||
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index ac5d69bb3377..a300702da527 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
| @@ -800,7 +800,7 @@ out: | |||
| 800 | int avc_ss_reset(u32 seqno) | 800 | int avc_ss_reset(u32 seqno) |
| 801 | { | 801 | { |
| 802 | struct avc_callback_node *c; | 802 | struct avc_callback_node *c; |
| 803 | int i, rc = 0; | 803 | int i, rc = 0, tmprc; |
| 804 | unsigned long flag; | 804 | unsigned long flag; |
| 805 | struct avc_node *node; | 805 | struct avc_node *node; |
| 806 | 806 | ||
| @@ -813,15 +813,16 @@ int avc_ss_reset(u32 seqno) | |||
| 813 | 813 | ||
| 814 | for (c = avc_callbacks; c; c = c->next) { | 814 | for (c = avc_callbacks; c; c = c->next) { |
| 815 | if (c->events & AVC_CALLBACK_RESET) { | 815 | if (c->events & AVC_CALLBACK_RESET) { |
| 816 | rc = c->callback(AVC_CALLBACK_RESET, | 816 | tmprc = c->callback(AVC_CALLBACK_RESET, |
| 817 | 0, 0, 0, 0, NULL); | 817 | 0, 0, 0, 0, NULL); |
| 818 | if (rc) | 818 | /* save the first error encountered for the return |
| 819 | goto out; | 819 | value and continue processing the callbacks */ |
| 820 | if (!rc) | ||
| 821 | rc = tmprc; | ||
| 820 | } | 822 | } |
| 821 | } | 823 | } |
| 822 | 824 | ||
| 823 | avc_latest_notif_update(seqno, 0); | 825 | avc_latest_notif_update(seqno, 0); |
| 824 | out: | ||
| 825 | return rc; | 826 | return rc; |
| 826 | } | 827 | } |
| 827 | 828 | ||
diff --git a/security/selinux/exports.c b/security/selinux/exports.c new file mode 100644 index 000000000000..ae4c73eb3085 --- /dev/null +++ b/security/selinux/exports.c | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | /* | ||
| 2 | * SELinux services exported to the rest of the kernel. | ||
| 3 | * | ||
| 4 | * Author: James Morris <jmorris@redhat.com> | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 Red Hat, Inc., James Morris <jmorris@redhat.com> | ||
| 7 | * Copyright (C) 2006 Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> | ||
| 8 | * Copyright (C) 2006 IBM Corporation, Timothy R. Chavez <tinytim@us.ibm.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2, | ||
| 12 | * as published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | #include <linux/types.h> | ||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/selinux.h> | ||
| 18 | #include <linux/fs.h> | ||
| 19 | #include <linux/ipc.h> | ||
| 20 | |||
| 21 | #include "security.h" | ||
| 22 | #include "objsec.h" | ||
| 23 | |||
| 24 | void selinux_task_ctxid(struct task_struct *tsk, u32 *ctxid) | ||
| 25 | { | ||
| 26 | struct task_security_struct *tsec = tsk->security; | ||
| 27 | if (selinux_enabled) | ||
| 28 | *ctxid = tsec->sid; | ||
| 29 | else | ||
| 30 | *ctxid = 0; | ||
| 31 | } | ||
| 32 | |||
| 33 | int selinux_ctxid_to_string(u32 ctxid, char **ctx, u32 *ctxlen) | ||
| 34 | { | ||
| 35 | if (selinux_enabled) | ||
| 36 | return security_sid_to_context(ctxid, ctx, ctxlen); | ||
| 37 | else { | ||
| 38 | *ctx = NULL; | ||
| 39 | *ctxlen = 0; | ||
| 40 | } | ||
| 41 | |||
| 42 | return 0; | ||
| 43 | } | ||
| 44 | |||
| 45 | void selinux_get_inode_sid(const struct inode *inode, u32 *sid) | ||
| 46 | { | ||
| 47 | if (selinux_enabled) { | ||
| 48 | struct inode_security_struct *isec = inode->i_security; | ||
| 49 | *sid = isec->sid; | ||
| 50 | return; | ||
| 51 | } | ||
| 52 | *sid = 0; | ||
| 53 | } | ||
| 54 | |||
| 55 | void selinux_get_ipc_sid(const struct kern_ipc_perm *ipcp, u32 *sid) | ||
| 56 | { | ||
| 57 | if (selinux_enabled) { | ||
| 58 | struct ipc_security_struct *isec = ipcp->security; | ||
| 59 | *sid = isec->sid; | ||
| 60 | return; | ||
| 61 | } | ||
| 62 | *sid = 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | void selinux_get_task_sid(struct task_struct *tsk, u32 *sid) | ||
| 66 | { | ||
| 67 | if (selinux_enabled) { | ||
| 68 | struct task_security_struct *tsec = tsk->security; | ||
| 69 | *sid = tsec->sid; | ||
| 70 | return; | ||
| 71 | } | ||
| 72 | *sid = 0; | ||
| 73 | } | ||
| 74 | |||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b61b9554bc27..d987048d3f33 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -101,6 +101,8 @@ static int __init selinux_enabled_setup(char *str) | |||
| 101 | return 1; | 101 | return 1; |
| 102 | } | 102 | } |
| 103 | __setup("selinux=", selinux_enabled_setup); | 103 | __setup("selinux=", selinux_enabled_setup); |
| 104 | #else | ||
| 105 | int selinux_enabled = 1; | ||
| 104 | #endif | 106 | #endif |
| 105 | 107 | ||
| 106 | /* Original (dummy) security module. */ | 108 | /* Original (dummy) security module. */ |
| @@ -4052,13 +4054,6 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | |||
| 4052 | return ipc_has_perm(ipcp, av); | 4054 | return ipc_has_perm(ipcp, av); |
| 4053 | } | 4055 | } |
| 4054 | 4056 | ||
| 4055 | static int selinux_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size) | ||
| 4056 | { | ||
| 4057 | struct ipc_security_struct *isec = ipcp->security; | ||
| 4058 | |||
| 4059 | return selinux_getsecurity(isec->sid, buffer, size); | ||
| 4060 | } | ||
| 4061 | |||
| 4062 | /* module stacking operations */ | 4057 | /* module stacking operations */ |
| 4063 | static int selinux_register_security (const char *name, struct security_operations *ops) | 4058 | static int selinux_register_security (const char *name, struct security_operations *ops) |
| 4064 | { | 4059 | { |
| @@ -4321,7 +4316,6 @@ static struct security_operations selinux_ops = { | |||
| 4321 | .task_to_inode = selinux_task_to_inode, | 4316 | .task_to_inode = selinux_task_to_inode, |
| 4322 | 4317 | ||
| 4323 | .ipc_permission = selinux_ipc_permission, | 4318 | .ipc_permission = selinux_ipc_permission, |
| 4324 | .ipc_getsecurity = selinux_ipc_getsecurity, | ||
| 4325 | 4319 | ||
| 4326 | .msg_msg_alloc_security = selinux_msg_msg_alloc_security, | 4320 | .msg_msg_alloc_security = selinux_msg_msg_alloc_security, |
| 4327 | .msg_msg_free_security = selinux_msg_msg_free_security, | 4321 | .msg_msg_free_security = selinux_msg_msg_free_security, |
| @@ -4543,6 +4537,7 @@ int selinux_disable(void) | |||
| 4543 | printk(KERN_INFO "SELinux: Disabled at runtime.\n"); | 4537 | printk(KERN_INFO "SELinux: Disabled at runtime.\n"); |
| 4544 | 4538 | ||
| 4545 | selinux_disabled = 1; | 4539 | selinux_disabled = 1; |
| 4540 | selinux_enabled = 0; | ||
| 4546 | 4541 | ||
| 4547 | /* Reset security_ops to the secondary module, dummy or capability. */ | 4542 | /* Reset security_ops to the secondary module, dummy or capability. */ |
| 4548 | security_ops = secondary_ops; | 4543 | security_ops = secondary_ops; |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 5f016c98056f..063af47bb231 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
| @@ -29,12 +29,7 @@ | |||
| 29 | #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE | 29 | #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE |
| 30 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_AVTAB | 30 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_AVTAB |
| 31 | 31 | ||
| 32 | #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM | ||
| 33 | extern int selinux_enabled; | 32 | extern int selinux_enabled; |
| 34 | #else | ||
| 35 | #define selinux_enabled 1 | ||
| 36 | #endif | ||
| 37 | |||
| 38 | extern int selinux_mls_enabled; | 33 | extern int selinux_mls_enabled; |
| 39 | 34 | ||
| 40 | int security_load_policy(void * data, size_t len); | 35 | int security_load_policy(void * data, size_t len); |
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 84047f69f9c1..7bc5b6440f70 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | * | 8 | * |
| 9 | * Support for enhanced MLS infrastructure. | 9 | * Support for enhanced MLS infrastructure. |
| 10 | * | 10 | * |
| 11 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 11 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. |
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| @@ -385,6 +385,34 @@ out: | |||
| 385 | } | 385 | } |
| 386 | 386 | ||
| 387 | /* | 387 | /* |
| 388 | * Set the MLS fields in the security context structure | ||
| 389 | * `context' based on the string representation in | ||
| 390 | * the string `str'. This function will allocate temporary memory with the | ||
| 391 | * given constraints of gfp_mask. | ||
| 392 | */ | ||
| 393 | int mls_from_string(char *str, struct context *context, gfp_t gfp_mask) | ||
| 394 | { | ||
| 395 | char *tmpstr, *freestr; | ||
| 396 | int rc; | ||
| 397 | |||
| 398 | if (!selinux_mls_enabled) | ||
| 399 | return -EINVAL; | ||
| 400 | |||
| 401 | /* we need freestr because mls_context_to_sid will change | ||
| 402 | the value of tmpstr */ | ||
| 403 | tmpstr = freestr = kstrdup(str, gfp_mask); | ||
| 404 | if (!tmpstr) { | ||
| 405 | rc = -ENOMEM; | ||
| 406 | } else { | ||
| 407 | rc = mls_context_to_sid(':', &tmpstr, context, | ||
| 408 | NULL, SECSID_NULL); | ||
| 409 | kfree(freestr); | ||
| 410 | } | ||
| 411 | |||
| 412 | return rc; | ||
| 413 | } | ||
| 414 | |||
| 415 | /* | ||
| 388 | * Copies the effective MLS range from `src' into `dst'. | 416 | * Copies the effective MLS range from `src' into `dst'. |
| 389 | */ | 417 | */ |
| 390 | static inline int mls_scopy_context(struct context *dst, | 418 | static inline int mls_scopy_context(struct context *dst, |
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index 03de697c8058..fbb42f07dd7c 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | * | 8 | * |
| 9 | * Support for enhanced MLS infrastructure. | 9 | * Support for enhanced MLS infrastructure. |
| 10 | * | 10 | * |
| 11 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 11 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. |
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #ifndef _SS_MLS_H_ | 14 | #ifndef _SS_MLS_H_ |
| @@ -27,6 +27,8 @@ int mls_context_to_sid(char oldc, | |||
| 27 | struct sidtab *s, | 27 | struct sidtab *s, |
| 28 | u32 def_sid); | 28 | u32 def_sid); |
| 29 | 29 | ||
| 30 | int mls_from_string(char *str, struct context *context, gfp_t gfp_mask); | ||
| 31 | |||
| 30 | int mls_convert_context(struct policydb *oldp, | 32 | int mls_convert_context(struct policydb *oldp, |
| 31 | struct policydb *newp, | 33 | struct policydb *newp, |
| 32 | struct context *context); | 34 | struct context *context); |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 61492485de84..7177e98df7f3 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -7,12 +7,13 @@ | |||
| 7 | * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> | 7 | * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> |
| 8 | * | 8 | * |
| 9 | * Support for enhanced MLS infrastructure. | 9 | * Support for enhanced MLS infrastructure. |
| 10 | * Support for context based audit filters. | ||
| 10 | * | 11 | * |
| 11 | * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> | 12 | * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> |
| 12 | * | 13 | * |
| 13 | * Added conditional policy language extensions | 14 | * Added conditional policy language extensions |
| 14 | * | 15 | * |
| 15 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 16 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. |
| 16 | * Copyright (C) 2003 - 2004 Tresys Technology, LLC | 17 | * Copyright (C) 2003 - 2004 Tresys Technology, LLC |
| 17 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> | 18 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> |
| 18 | * This program is free software; you can redistribute it and/or modify | 19 | * This program is free software; you can redistribute it and/or modify |
| @@ -1811,3 +1812,235 @@ out: | |||
| 1811 | POLICY_RDUNLOCK; | 1812 | POLICY_RDUNLOCK; |
| 1812 | return rc; | 1813 | return rc; |
| 1813 | } | 1814 | } |
| 1815 | |||
| 1816 | struct selinux_audit_rule { | ||
| 1817 | u32 au_seqno; | ||
| 1818 | struct context au_ctxt; | ||
| 1819 | }; | ||
| 1820 | |||
| 1821 | void selinux_audit_rule_free(struct selinux_audit_rule *rule) | ||
| 1822 | { | ||
| 1823 | if (rule) { | ||
| 1824 | context_destroy(&rule->au_ctxt); | ||
| 1825 | kfree(rule); | ||
| 1826 | } | ||
| 1827 | } | ||
| 1828 | |||
| 1829 | int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, | ||
| 1830 | struct selinux_audit_rule **rule) | ||
| 1831 | { | ||
| 1832 | struct selinux_audit_rule *tmprule; | ||
| 1833 | struct role_datum *roledatum; | ||
| 1834 | struct type_datum *typedatum; | ||
| 1835 | struct user_datum *userdatum; | ||
| 1836 | int rc = 0; | ||
| 1837 | |||
| 1838 | *rule = NULL; | ||
| 1839 | |||
| 1840 | if (!ss_initialized) | ||
| 1841 | return -ENOTSUPP; | ||
| 1842 | |||
| 1843 | switch (field) { | ||
| 1844 | case AUDIT_SE_USER: | ||
| 1845 | case AUDIT_SE_ROLE: | ||
| 1846 | case AUDIT_SE_TYPE: | ||
| 1847 | /* only 'equals' and 'not equals' fit user, role, and type */ | ||
| 1848 | if (op != AUDIT_EQUAL && op != AUDIT_NOT_EQUAL) | ||
| 1849 | return -EINVAL; | ||
| 1850 | break; | ||
| 1851 | case AUDIT_SE_SEN: | ||
| 1852 | case AUDIT_SE_CLR: | ||
| 1853 | /* we do not allow a range, indicated by the presense of '-' */ | ||
| 1854 | if (strchr(rulestr, '-')) | ||
| 1855 | return -EINVAL; | ||
| 1856 | break; | ||
| 1857 | default: | ||
| 1858 | /* only the above fields are valid */ | ||
| 1859 | return -EINVAL; | ||
| 1860 | } | ||
| 1861 | |||
| 1862 | tmprule = kzalloc(sizeof(struct selinux_audit_rule), GFP_KERNEL); | ||
| 1863 | if (!tmprule) | ||
| 1864 | return -ENOMEM; | ||
| 1865 | |||
| 1866 | context_init(&tmprule->au_ctxt); | ||
| 1867 | |||
| 1868 | POLICY_RDLOCK; | ||
| 1869 | |||
| 1870 | tmprule->au_seqno = latest_granting; | ||
| 1871 | |||
| 1872 | switch (field) { | ||
| 1873 | case AUDIT_SE_USER: | ||
| 1874 | userdatum = hashtab_search(policydb.p_users.table, rulestr); | ||
| 1875 | if (!userdatum) | ||
| 1876 | rc = -EINVAL; | ||
| 1877 | else | ||
| 1878 | tmprule->au_ctxt.user = userdatum->value; | ||
| 1879 | break; | ||
| 1880 | case AUDIT_SE_ROLE: | ||
| 1881 | roledatum = hashtab_search(policydb.p_roles.table, rulestr); | ||
| 1882 | if (!roledatum) | ||
| 1883 | rc = -EINVAL; | ||
| 1884 | else | ||
| 1885 | tmprule->au_ctxt.role = roledatum->value; | ||
| 1886 | break; | ||
| 1887 | case AUDIT_SE_TYPE: | ||
| 1888 | typedatum = hashtab_search(policydb.p_types.table, rulestr); | ||
| 1889 | if (!typedatum) | ||
| 1890 | rc = -EINVAL; | ||
| 1891 | else | ||
| 1892 | tmprule->au_ctxt.type = typedatum->value; | ||
| 1893 | break; | ||
| 1894 | case AUDIT_SE_SEN: | ||
| 1895 | case AUDIT_SE_CLR: | ||
| 1896 | rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); | ||
| 1897 | break; | ||
| 1898 | } | ||
| 1899 | |||
| 1900 | POLICY_RDUNLOCK; | ||
| 1901 | |||
| 1902 | if (rc) { | ||
| 1903 | selinux_audit_rule_free(tmprule); | ||
| 1904 | tmprule = NULL; | ||
| 1905 | } | ||
| 1906 | |||
| 1907 | *rule = tmprule; | ||
| 1908 | |||
| 1909 | return rc; | ||
| 1910 | } | ||
| 1911 | |||
| 1912 | int selinux_audit_rule_match(u32 ctxid, u32 field, u32 op, | ||
| 1913 | struct selinux_audit_rule *rule, | ||
| 1914 | struct audit_context *actx) | ||
| 1915 | { | ||
| 1916 | struct context *ctxt; | ||
| 1917 | struct mls_level *level; | ||
| 1918 | int match = 0; | ||
| 1919 | |||
| 1920 | if (!rule) { | ||
| 1921 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | ||
| 1922 | "selinux_audit_rule_match: missing rule\n"); | ||
| 1923 | return -ENOENT; | ||
| 1924 | } | ||
| 1925 | |||
| 1926 | POLICY_RDLOCK; | ||
| 1927 | |||
| 1928 | if (rule->au_seqno < latest_granting) { | ||
| 1929 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | ||
| 1930 | "selinux_audit_rule_match: stale rule\n"); | ||
| 1931 | match = -ESTALE; | ||
| 1932 | goto out; | ||
| 1933 | } | ||
| 1934 | |||
| 1935 | ctxt = sidtab_search(&sidtab, ctxid); | ||
| 1936 | if (!ctxt) { | ||
| 1937 | audit_log(actx, GFP_ATOMIC, AUDIT_SELINUX_ERR, | ||
| 1938 | "selinux_audit_rule_match: unrecognized SID %d\n", | ||
| 1939 | ctxid); | ||
| 1940 | match = -ENOENT; | ||
| 1941 | goto out; | ||
| 1942 | } | ||
| 1943 | |||
| 1944 | /* a field/op pair that is not caught here will simply fall through | ||
| 1945 | without a match */ | ||
| 1946 | switch (field) { | ||
| 1947 | case AUDIT_SE_USER: | ||
| 1948 | switch (op) { | ||
| 1949 | case AUDIT_EQUAL: | ||
| 1950 | match = (ctxt->user == rule->au_ctxt.user); | ||
| 1951 | break; | ||
| 1952 | case AUDIT_NOT_EQUAL: | ||
| 1953 | match = (ctxt->user != rule->au_ctxt.user); | ||
| 1954 | break; | ||
| 1955 | } | ||
| 1956 | break; | ||
| 1957 | case AUDIT_SE_ROLE: | ||
| 1958 | switch (op) { | ||
| 1959 | case AUDIT_EQUAL: | ||
| 1960 | match = (ctxt->role == rule->au_ctxt.role); | ||
| 1961 | break; | ||
| 1962 | case AUDIT_NOT_EQUAL: | ||
| 1963 | match = (ctxt->role != rule->au_ctxt.role); | ||
| 1964 | break; | ||
| 1965 | } | ||
| 1966 | break; | ||
| 1967 | case AUDIT_SE_TYPE: | ||
| 1968 | switch (op) { | ||
| 1969 | case AUDIT_EQUAL: | ||
| 1970 | match = (ctxt->type == rule->au_ctxt.type); | ||
| 1971 | break; | ||
| 1972 | case AUDIT_NOT_EQUAL: | ||
| 1973 | match = (ctxt->type != rule->au_ctxt.type); | ||
| 1974 | break; | ||
| 1975 | } | ||
| 1976 | break; | ||
| 1977 | case AUDIT_SE_SEN: | ||
| 1978 | case AUDIT_SE_CLR: | ||
| 1979 | level = (op == AUDIT_SE_SEN ? | ||
| 1980 | &ctxt->range.level[0] : &ctxt->range.level[1]); | ||
| 1981 | switch (op) { | ||
| 1982 | case AUDIT_EQUAL: | ||
| 1983 | match = mls_level_eq(&rule->au_ctxt.range.level[0], | ||
| 1984 | level); | ||
| 1985 | break; | ||
| 1986 | case AUDIT_NOT_EQUAL: | ||
| 1987 | match = !mls_level_eq(&rule->au_ctxt.range.level[0], | ||
| 1988 | level); | ||
| 1989 | break; | ||
| 1990 | case AUDIT_LESS_THAN: | ||
| 1991 | match = (mls_level_dom(&rule->au_ctxt.range.level[0], | ||
| 1992 | level) && | ||
| 1993 | !mls_level_eq(&rule->au_ctxt.range.level[0], | ||
| 1994 | level)); | ||
| 1995 | break; | ||
| 1996 | case AUDIT_LESS_THAN_OR_EQUAL: | ||
| 1997 | match = mls_level_dom(&rule->au_ctxt.range.level[0], | ||
| 1998 | level); | ||
| 1999 | break; | ||
| 2000 | case AUDIT_GREATER_THAN: | ||
| 2001 | match = (mls_level_dom(level, | ||
| 2002 | &rule->au_ctxt.range.level[0]) && | ||
| 2003 | !mls_level_eq(level, | ||
| 2004 | &rule->au_ctxt.range.level[0])); | ||
| 2005 | break; | ||
| 2006 | case AUDIT_GREATER_THAN_OR_EQUAL: | ||
| 2007 | match = mls_level_dom(level, | ||
| 2008 | &rule->au_ctxt.range.level[0]); | ||
| 2009 | break; | ||
| 2010 | } | ||
| 2011 | } | ||
| 2012 | |||
| 2013 | out: | ||
| 2014 | POLICY_RDUNLOCK; | ||
| 2015 | return match; | ||
| 2016 | } | ||
| 2017 | |||
| 2018 | static int (*aurule_callback)(void) = NULL; | ||
| 2019 | |||
| 2020 | static int aurule_avc_callback(u32 event, u32 ssid, u32 tsid, | ||
| 2021 | u16 class, u32 perms, u32 *retained) | ||
| 2022 | { | ||
| 2023 | int err = 0; | ||
| 2024 | |||
| 2025 | if (event == AVC_CALLBACK_RESET && aurule_callback) | ||
| 2026 | err = aurule_callback(); | ||
| 2027 | return err; | ||
| 2028 | } | ||
| 2029 | |||
| 2030 | static int __init aurule_init(void) | ||
| 2031 | { | ||
| 2032 | int err; | ||
| 2033 | |||
| 2034 | err = avc_add_callback(aurule_avc_callback, AVC_CALLBACK_RESET, | ||
| 2035 | SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); | ||
| 2036 | if (err) | ||
| 2037 | panic("avc_add_callback() failed, error %d\n", err); | ||
| 2038 | |||
| 2039 | return err; | ||
| 2040 | } | ||
| 2041 | __initcall(aurule_init); | ||
| 2042 | |||
| 2043 | void selinux_audit_set_callback(int (*callback)(void)) | ||
| 2044 | { | ||
| 2045 | aurule_callback = callback; | ||
| 2046 | } | ||
