diff options
59 files changed, 420 insertions, 324 deletions
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h index 446bec29b142..26460d15b338 100644 --- a/arch/microblaze/include/asm/uaccess.h +++ b/arch/microblaze/include/asm/uaccess.h | |||
| @@ -182,6 +182,39 @@ extern long __user_bad(void); | |||
| 182 | * Returns zero on success, or -EFAULT on error. | 182 | * Returns zero on success, or -EFAULT on error. |
| 183 | * On error, the variable @x is set to zero. | 183 | * On error, the variable @x is set to zero. |
| 184 | */ | 184 | */ |
| 185 | #define get_user(x, ptr) \ | ||
| 186 | __get_user_check((x), (ptr), sizeof(*(ptr))) | ||
| 187 | |||
| 188 | #define __get_user_check(x, ptr, size) \ | ||
| 189 | ({ \ | ||
| 190 | unsigned long __gu_val = 0; \ | ||
| 191 | const typeof(*(ptr)) __user *__gu_addr = (ptr); \ | ||
| 192 | int __gu_err = 0; \ | ||
| 193 | \ | ||
| 194 | if (access_ok(VERIFY_READ, __gu_addr, size)) { \ | ||
| 195 | switch (size) { \ | ||
| 196 | case 1: \ | ||
| 197 | __get_user_asm("lbu", __gu_addr, __gu_val, \ | ||
| 198 | __gu_err); \ | ||
| 199 | break; \ | ||
| 200 | case 2: \ | ||
| 201 | __get_user_asm("lhu", __gu_addr, __gu_val, \ | ||
| 202 | __gu_err); \ | ||
| 203 | break; \ | ||
| 204 | case 4: \ | ||
| 205 | __get_user_asm("lw", __gu_addr, __gu_val, \ | ||
| 206 | __gu_err); \ | ||
| 207 | break; \ | ||
| 208 | default: \ | ||
| 209 | __gu_err = __user_bad(); \ | ||
| 210 | break; \ | ||
| 211 | } \ | ||
| 212 | } else { \ | ||
| 213 | __gu_err = -EFAULT; \ | ||
| 214 | } \ | ||
| 215 | x = (typeof(*(ptr)))__gu_val; \ | ||
| 216 | __gu_err; \ | ||
| 217 | }) | ||
| 185 | 218 | ||
| 186 | #define __get_user(x, ptr) \ | 219 | #define __get_user(x, ptr) \ |
| 187 | ({ \ | 220 | ({ \ |
| @@ -206,12 +239,6 @@ extern long __user_bad(void); | |||
| 206 | }) | 239 | }) |
| 207 | 240 | ||
| 208 | 241 | ||
| 209 | #define get_user(x, ptr) \ | ||
| 210 | ({ \ | ||
| 211 | access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) \ | ||
| 212 | ? __get_user((x), (ptr)) : -EFAULT; \ | ||
| 213 | }) | ||
| 214 | |||
| 215 | #define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \ | 242 | #define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \ |
| 216 | ({ \ | 243 | ({ \ |
| 217 | __asm__ __volatile__ ( \ | 244 | __asm__ __volatile__ ( \ |
| @@ -266,6 +293,42 @@ extern long __user_bad(void); | |||
| 266 | * | 293 | * |
| 267 | * Returns zero on success, or -EFAULT on error. | 294 | * Returns zero on success, or -EFAULT on error. |
| 268 | */ | 295 | */ |
| 296 | #define put_user(x, ptr) \ | ||
| 297 | __put_user_check((x), (ptr), sizeof(*(ptr))) | ||
| 298 | |||
| 299 | #define __put_user_check(x, ptr, size) \ | ||
| 300 | ({ \ | ||
| 301 | typeof(*(ptr)) __pu_val; \ | ||
| 302 | typeof(*(ptr)) __user *__pu_addr = (ptr); \ | ||
| 303 | int __pu_err = 0; \ | ||
| 304 | \ | ||
| 305 | __pu_val = (x); \ | ||
| 306 | if (access_ok(VERIFY_WRITE, __pu_addr, size)) { \ | ||
| 307 | switch (size) { \ | ||
| 308 | case 1: \ | ||
| 309 | __put_user_asm("sb", __pu_addr, __pu_val, \ | ||
| 310 | __pu_err); \ | ||
| 311 | break; \ | ||
| 312 | case 2: \ | ||
| 313 | __put_user_asm("sh", __pu_addr, __pu_val, \ | ||
| 314 | __pu_err); \ | ||
| 315 | break; \ | ||
| 316 | case 4: \ | ||
| 317 | __put_user_asm("sw", __pu_addr, __pu_val, \ | ||
| 318 | __pu_err); \ | ||
| 319 | break; \ | ||
| 320 | case 8: \ | ||
| 321 | __put_user_asm_8(__pu_addr, __pu_val, __pu_err);\ | ||
| 322 | break; \ | ||
| 323 | default: \ | ||
| 324 | __pu_err = __user_bad(); \ | ||
| 325 | break; \ | ||
| 326 | } \ | ||
| 327 | } else { \ | ||
| 328 | __pu_err = -EFAULT; \ | ||
| 329 | } \ | ||
| 330 | __pu_err; \ | ||
| 331 | }) | ||
| 269 | 332 | ||
| 270 | #define __put_user(x, ptr) \ | 333 | #define __put_user(x, ptr) \ |
| 271 | ({ \ | 334 | ({ \ |
| @@ -290,18 +353,6 @@ extern long __user_bad(void); | |||
| 290 | __gu_err; \ | 353 | __gu_err; \ |
| 291 | }) | 354 | }) |
| 292 | 355 | ||
| 293 | #ifndef CONFIG_MMU | ||
| 294 | |||
| 295 | #define put_user(x, ptr) __put_user((x), (ptr)) | ||
| 296 | |||
| 297 | #else /* CONFIG_MMU */ | ||
| 298 | |||
| 299 | #define put_user(x, ptr) \ | ||
| 300 | ({ \ | ||
| 301 | access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) \ | ||
| 302 | ? __put_user((x), (ptr)) : -EFAULT; \ | ||
| 303 | }) | ||
| 304 | #endif /* CONFIG_MMU */ | ||
| 305 | 356 | ||
| 306 | /* copy_to_from_user */ | 357 | /* copy_to_from_user */ |
| 307 | #define __copy_from_user(to, from, n) \ | 358 | #define __copy_from_user(to, from, n) \ |
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c index 21c3a92394de..109876e8d643 100644 --- a/arch/microblaze/kernel/cpu/cache.c +++ b/arch/microblaze/kernel/cpu/cache.c | |||
| @@ -137,8 +137,9 @@ do { \ | |||
| 137 | do { \ | 137 | do { \ |
| 138 | int step = -line_length; \ | 138 | int step = -line_length; \ |
| 139 | int align = ~(line_length - 1); \ | 139 | int align = ~(line_length - 1); \ |
| 140 | int count; \ | ||
| 140 | end = ((end & align) == end) ? end - line_length : end & align; \ | 141 | end = ((end & align) == end) ? end - line_length : end & align; \ |
| 141 | int count = end - start; \ | 142 | count = end - start; \ |
| 142 | WARN_ON(count < 0); \ | 143 | WARN_ON(count < 0); \ |
| 143 | \ | 144 | \ |
| 144 | __asm__ __volatile__ (" 1: " #op " %0, %1; \ | 145 | __asm__ __volatile__ (" 1: " #op " %0, %1; \ |
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S index 391d6197fc3b..8cc18cd2cce6 100644 --- a/arch/microblaze/kernel/entry-nommu.S +++ b/arch/microblaze/kernel/entry-nommu.S | |||
| @@ -476,6 +476,8 @@ ENTRY(ret_from_fork) | |||
| 476 | nop | 476 | nop |
| 477 | 477 | ||
| 478 | work_pending: | 478 | work_pending: |
| 479 | enable_irq | ||
| 480 | |||
| 479 | andi r11, r19, _TIF_NEED_RESCHED | 481 | andi r11, r19, _TIF_NEED_RESCHED |
| 480 | beqi r11, 1f | 482 | beqi r11, 1f |
| 481 | bralid r15, schedule | 483 | bralid r15, schedule |
diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c index bc4dcb7d3861..ff85f7718035 100644 --- a/arch/microblaze/kernel/microblaze_ksyms.c +++ b/arch/microblaze/kernel/microblaze_ksyms.c | |||
| @@ -52,3 +52,14 @@ EXPORT_SYMBOL_GPL(_ebss); | |||
| 52 | extern void _mcount(void); | 52 | extern void _mcount(void); |
| 53 | EXPORT_SYMBOL(_mcount); | 53 | EXPORT_SYMBOL(_mcount); |
| 54 | #endif | 54 | #endif |
| 55 | |||
| 56 | /* | ||
| 57 | * Assembly functions that may be used (directly or indirectly) by modules | ||
| 58 | */ | ||
| 59 | EXPORT_SYMBOL(__copy_tofrom_user); | ||
| 60 | EXPORT_SYMBOL(__strncpy_user); | ||
| 61 | |||
| 62 | #ifdef CONFIG_OPT_LIB_ASM | ||
| 63 | EXPORT_SYMBOL(memcpy); | ||
| 64 | EXPORT_SYMBOL(memmove); | ||
| 65 | #endif | ||
diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c index cbecf110dc30..0e73f6606547 100644 --- a/arch/microblaze/kernel/module.c +++ b/arch/microblaze/kernel/module.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
| 17 | 17 | ||
| 18 | #include <asm/pgtable.h> | 18 | #include <asm/pgtable.h> |
| 19 | #include <asm/cacheflush.h> | ||
| 19 | 20 | ||
| 20 | void *module_alloc(unsigned long size) | 21 | void *module_alloc(unsigned long size) |
| 21 | { | 22 | { |
| @@ -151,6 +152,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, | |||
| 151 | int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, | 152 | int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, |
| 152 | struct module *module) | 153 | struct module *module) |
| 153 | { | 154 | { |
| 155 | flush_dcache(); | ||
| 154 | return 0; | 156 | return 0; |
| 155 | } | 157 | } |
| 156 | 158 | ||
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c index f42c2dde8b1c..cca3579d4268 100644 --- a/arch/microblaze/mm/init.c +++ b/arch/microblaze/mm/init.c | |||
| @@ -47,6 +47,7 @@ unsigned long memory_start; | |||
| 47 | EXPORT_SYMBOL(memory_start); | 47 | EXPORT_SYMBOL(memory_start); |
| 48 | unsigned long memory_end; /* due to mm/nommu.c */ | 48 | unsigned long memory_end; /* due to mm/nommu.c */ |
| 49 | unsigned long memory_size; | 49 | unsigned long memory_size; |
| 50 | EXPORT_SYMBOL(memory_size); | ||
| 50 | 51 | ||
| 51 | /* | 52 | /* |
| 52 | * paging_init() sets up the page tables - in fact we've already done this. | 53 | * paging_init() sets up the page tables - in fact we've already done this. |
diff --git a/arch/microblaze/mm/pgtable.c b/arch/microblaze/mm/pgtable.c index 784557fb28cf..59bf2335a4ce 100644 --- a/arch/microblaze/mm/pgtable.c +++ b/arch/microblaze/mm/pgtable.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | 42 | ||
| 43 | unsigned long ioremap_base; | 43 | unsigned long ioremap_base; |
| 44 | unsigned long ioremap_bot; | 44 | unsigned long ioremap_bot; |
| 45 | EXPORT_SYMBOL(ioremap_bot); | ||
| 45 | 46 | ||
| 46 | /* The maximum lowmem defaults to 768Mb, but this can be configured to | 47 | /* The maximum lowmem defaults to 768Mb, but this can be configured to |
| 47 | * another value. | 48 | * another value. |
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 01c8c97c15b7..9cb782b8e036 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c | |||
| @@ -1507,7 +1507,7 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus) | |||
| 1507 | pci_bus_add_devices(bus); | 1507 | pci_bus_add_devices(bus); |
| 1508 | 1508 | ||
| 1509 | /* Fixup EEH */ | 1509 | /* Fixup EEH */ |
| 1510 | eeh_add_device_tree_late(bus); | 1510 | /* eeh_add_device_tree_late(bus); */ |
| 1511 | } | 1511 | } |
| 1512 | EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); | 1512 | EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); |
| 1513 | 1513 | ||
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index 9f4c9d4f5803..bd100fcf40d0 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h | |||
| @@ -130,43 +130,5 @@ static inline int irqs_disabled_flags(unsigned long flags) | |||
| 130 | */ | 130 | */ |
| 131 | struct irq_chip; | 131 | struct irq_chip; |
| 132 | 132 | ||
| 133 | #ifdef CONFIG_PERF_EVENTS | ||
| 134 | |||
| 135 | #ifdef CONFIG_PPC64 | ||
| 136 | static inline unsigned long test_perf_event_pending(void) | ||
| 137 | { | ||
| 138 | unsigned long x; | ||
| 139 | |||
| 140 | asm volatile("lbz %0,%1(13)" | ||
| 141 | : "=r" (x) | ||
| 142 | : "i" (offsetof(struct paca_struct, perf_event_pending))); | ||
| 143 | return x; | ||
| 144 | } | ||
| 145 | |||
| 146 | static inline void set_perf_event_pending(void) | ||
| 147 | { | ||
| 148 | asm volatile("stb %0,%1(13)" : : | ||
| 149 | "r" (1), | ||
| 150 | "i" (offsetof(struct paca_struct, perf_event_pending))); | ||
| 151 | } | ||
| 152 | |||
| 153 | static inline void clear_perf_event_pending(void) | ||
| 154 | { | ||
| 155 | asm volatile("stb %0,%1(13)" : : | ||
| 156 | "r" (0), | ||
| 157 | "i" (offsetof(struct paca_struct, perf_event_pending))); | ||
| 158 | } | ||
| 159 | #endif /* CONFIG_PPC64 */ | ||
| 160 | |||
| 161 | #else /* CONFIG_PERF_EVENTS */ | ||
| 162 | |||
| 163 | static inline unsigned long test_perf_event_pending(void) | ||
| 164 | { | ||
| 165 | return 0; | ||
| 166 | } | ||
| 167 | |||
| 168 | static inline void clear_perf_event_pending(void) {} | ||
| 169 | #endif /* CONFIG_PERF_EVENTS */ | ||
| 170 | |||
| 171 | #endif /* __KERNEL__ */ | 133 | #endif /* __KERNEL__ */ |
| 172 | #endif /* _ASM_POWERPC_HW_IRQ_H */ | 134 | #endif /* _ASM_POWERPC_HW_IRQ_H */ |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 957ceb7059c5..c09138d150d4 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
| @@ -133,7 +133,6 @@ int main(void) | |||
| 133 | DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr)); | 133 | DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr)); |
| 134 | DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled)); | 134 | DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled)); |
| 135 | DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled)); | 135 | DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled)); |
| 136 | DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_event_pending)); | ||
| 137 | DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); | 136 | DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); |
| 138 | #ifdef CONFIG_PPC_MM_SLICES | 137 | #ifdef CONFIG_PPC_MM_SLICES |
| 139 | DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct, | 138 | DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct, |
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c index 59c928564a03..4ff4da2c238b 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Contains routines needed to support swiotlb for ppc. | 2 | * Contains routines needed to support swiotlb for ppc. |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2009 Becky Bruce, Freescale Semiconductor | 4 | * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. |
| 5 | * Author: Becky Bruce | ||
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
| @@ -70,7 +71,7 @@ static int ppc_swiotlb_bus_notify(struct notifier_block *nb, | |||
| 70 | sd->max_direct_dma_addr = 0; | 71 | sd->max_direct_dma_addr = 0; |
| 71 | 72 | ||
| 72 | /* May need to bounce if the device can't address all of DRAM */ | 73 | /* May need to bounce if the device can't address all of DRAM */ |
| 73 | if (dma_get_mask(dev) < lmb_end_of_DRAM()) | 74 | if ((dma_get_mask(dev) + 1) < lmb_end_of_DRAM()) |
| 74 | set_dma_ops(dev, &swiotlb_dma_ops); | 75 | set_dma_ops(dev, &swiotlb_dma_ops); |
| 75 | 76 | ||
| 76 | return NOTIFY_DONE; | 77 | return NOTIFY_DONE; |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 07109d843787..42e9d908914a 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
| @@ -556,15 +556,6 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES) | |||
| 556 | 2: | 556 | 2: |
| 557 | TRACE_AND_RESTORE_IRQ(r5); | 557 | TRACE_AND_RESTORE_IRQ(r5); |
| 558 | 558 | ||
| 559 | #ifdef CONFIG_PERF_EVENTS | ||
| 560 | /* check paca->perf_event_pending if we're enabling ints */ | ||
| 561 | lbz r3,PACAPERFPEND(r13) | ||
| 562 | and. r3,r3,r5 | ||
| 563 | beq 27f | ||
| 564 | bl .perf_event_do_pending | ||
| 565 | 27: | ||
| 566 | #endif /* CONFIG_PERF_EVENTS */ | ||
| 567 | |||
| 568 | /* extract EE bit and use it to restore paca->hard_enabled */ | 559 | /* extract EE bit and use it to restore paca->hard_enabled */ |
| 569 | ld r3,_MSR(r1) | 560 | ld r3,_MSR(r1) |
| 570 | rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */ | 561 | rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */ |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 64f6f2031c22..066bd31551d5 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
| @@ -53,7 +53,6 @@ | |||
| 53 | #include <linux/bootmem.h> | 53 | #include <linux/bootmem.h> |
| 54 | #include <linux/pci.h> | 54 | #include <linux/pci.h> |
| 55 | #include <linux/debugfs.h> | 55 | #include <linux/debugfs.h> |
| 56 | #include <linux/perf_event.h> | ||
| 57 | 56 | ||
| 58 | #include <asm/uaccess.h> | 57 | #include <asm/uaccess.h> |
| 59 | #include <asm/system.h> | 58 | #include <asm/system.h> |
| @@ -145,11 +144,6 @@ notrace void raw_local_irq_restore(unsigned long en) | |||
| 145 | } | 144 | } |
| 146 | #endif /* CONFIG_PPC_STD_MMU_64 */ | 145 | #endif /* CONFIG_PPC_STD_MMU_64 */ |
| 147 | 146 | ||
| 148 | if (test_perf_event_pending()) { | ||
| 149 | clear_perf_event_pending(); | ||
| 150 | perf_event_do_pending(); | ||
| 151 | } | ||
| 152 | |||
| 153 | /* | 147 | /* |
| 154 | * if (get_paca()->hard_enabled) return; | 148 | * if (get_paca()->hard_enabled) return; |
| 155 | * But again we need to take care that gcc gets hard_enabled directly | 149 | * But again we need to take care that gcc gets hard_enabled directly |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 1b16b9a3e49a..0441bbdadbd1 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
| @@ -532,25 +532,60 @@ void __init iSeries_time_init_early(void) | |||
| 532 | } | 532 | } |
| 533 | #endif /* CONFIG_PPC_ISERIES */ | 533 | #endif /* CONFIG_PPC_ISERIES */ |
| 534 | 534 | ||
| 535 | #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_PPC32) | 535 | #ifdef CONFIG_PERF_EVENTS |
| 536 | DEFINE_PER_CPU(u8, perf_event_pending); | ||
| 537 | 536 | ||
| 538 | void set_perf_event_pending(void) | 537 | /* |
| 538 | * 64-bit uses a byte in the PACA, 32-bit uses a per-cpu variable... | ||
| 539 | */ | ||
| 540 | #ifdef CONFIG_PPC64 | ||
| 541 | static inline unsigned long test_perf_event_pending(void) | ||
| 539 | { | 542 | { |
| 540 | get_cpu_var(perf_event_pending) = 1; | 543 | unsigned long x; |
| 541 | set_dec(1); | 544 | |
| 542 | put_cpu_var(perf_event_pending); | 545 | asm volatile("lbz %0,%1(13)" |
| 546 | : "=r" (x) | ||
| 547 | : "i" (offsetof(struct paca_struct, perf_event_pending))); | ||
| 548 | return x; | ||
| 543 | } | 549 | } |
| 544 | 550 | ||
| 551 | static inline void set_perf_event_pending_flag(void) | ||
| 552 | { | ||
| 553 | asm volatile("stb %0,%1(13)" : : | ||
| 554 | "r" (1), | ||
| 555 | "i" (offsetof(struct paca_struct, perf_event_pending))); | ||
| 556 | } | ||
| 557 | |||
| 558 | static inline void clear_perf_event_pending(void) | ||
| 559 | { | ||
| 560 | asm volatile("stb %0,%1(13)" : : | ||
| 561 | "r" (0), | ||
| 562 | "i" (offsetof(struct paca_struct, perf_event_pending))); | ||
| 563 | } | ||
| 564 | |||
| 565 | #else /* 32-bit */ | ||
| 566 | |||
| 567 | DEFINE_PER_CPU(u8, perf_event_pending); | ||
| 568 | |||
| 569 | #define set_perf_event_pending_flag() __get_cpu_var(perf_event_pending) = 1 | ||
| 545 | #define test_perf_event_pending() __get_cpu_var(perf_event_pending) | 570 | #define test_perf_event_pending() __get_cpu_var(perf_event_pending) |
| 546 | #define clear_perf_event_pending() __get_cpu_var(perf_event_pending) = 0 | 571 | #define clear_perf_event_pending() __get_cpu_var(perf_event_pending) = 0 |
| 547 | 572 | ||
| 548 | #else /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */ | 573 | #endif /* 32 vs 64 bit */ |
| 574 | |||
| 575 | void set_perf_event_pending(void) | ||
| 576 | { | ||
| 577 | preempt_disable(); | ||
| 578 | set_perf_event_pending_flag(); | ||
| 579 | set_dec(1); | ||
| 580 | preempt_enable(); | ||
| 581 | } | ||
| 582 | |||
| 583 | #else /* CONFIG_PERF_EVENTS */ | ||
| 549 | 584 | ||
| 550 | #define test_perf_event_pending() 0 | 585 | #define test_perf_event_pending() 0 |
| 551 | #define clear_perf_event_pending() | 586 | #define clear_perf_event_pending() |
| 552 | 587 | ||
| 553 | #endif /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */ | 588 | #endif /* CONFIG_PERF_EVENTS */ |
| 554 | 589 | ||
| 555 | /* | 590 | /* |
| 556 | * For iSeries shared processors, we have to let the hypervisor | 591 | * For iSeries shared processors, we have to let the hypervisor |
| @@ -582,10 +617,6 @@ void timer_interrupt(struct pt_regs * regs) | |||
| 582 | set_dec(DECREMENTER_MAX); | 617 | set_dec(DECREMENTER_MAX); |
| 583 | 618 | ||
| 584 | #ifdef CONFIG_PPC32 | 619 | #ifdef CONFIG_PPC32 |
| 585 | if (test_perf_event_pending()) { | ||
| 586 | clear_perf_event_pending(); | ||
| 587 | perf_event_do_pending(); | ||
| 588 | } | ||
| 589 | if (atomic_read(&ppc_n_lost_interrupts) != 0) | 620 | if (atomic_read(&ppc_n_lost_interrupts) != 0) |
| 590 | do_IRQ(regs); | 621 | do_IRQ(regs); |
| 591 | #endif | 622 | #endif |
| @@ -604,6 +635,11 @@ void timer_interrupt(struct pt_regs * regs) | |||
| 604 | 635 | ||
| 605 | calculate_steal_time(); | 636 | calculate_steal_time(); |
| 606 | 637 | ||
| 638 | if (test_perf_event_pending()) { | ||
| 639 | clear_perf_event_pending(); | ||
| 640 | perf_event_do_pending(); | ||
| 641 | } | ||
| 642 | |||
| 607 | #ifdef CONFIG_PPC_ISERIES | 643 | #ifdef CONFIG_PPC_ISERIES |
| 608 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | 644 | if (firmware_has_feature(FW_FEATURE_ISERIES)) |
| 609 | get_lppaca()->int_dword.fields.decr_int = 0; | 645 | get_lppaca()->int_dword.fields.decr_int = 0; |
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c index 2570fcc7665d..812312542e50 100644 --- a/arch/powerpc/kvm/44x_tlb.c +++ b/arch/powerpc/kvm/44x_tlb.c | |||
| @@ -440,7 +440,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws) | |||
| 440 | unsigned int gtlb_index; | 440 | unsigned int gtlb_index; |
| 441 | 441 | ||
| 442 | gtlb_index = kvmppc_get_gpr(vcpu, ra); | 442 | gtlb_index = kvmppc_get_gpr(vcpu, ra); |
| 443 | if (gtlb_index > KVM44x_GUEST_TLB_SIZE) { | 443 | if (gtlb_index >= KVM44x_GUEST_TLB_SIZE) { |
| 444 | printk("%s: index %d\n", __func__, gtlb_index); | 444 | printk("%s: index %d\n", __func__, gtlb_index); |
| 445 | kvmppc_dump_vcpu(vcpu); | 445 | kvmppc_dump_vcpu(vcpu); |
| 446 | return EMULATE_FAIL; | 446 | return EMULATE_FAIL; |
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index 1bbcc499d455..b8f8dc126102 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S | |||
| @@ -82,7 +82,7 @@ startup_continue: | |||
| 82 | _ehead: | 82 | _ehead: |
| 83 | 83 | ||
| 84 | #ifdef CONFIG_SHARED_KERNEL | 84 | #ifdef CONFIG_SHARED_KERNEL |
| 85 | .org 0x100000 | 85 | .org 0x100000 - 0x11000 # head.o ends at 0x11000 |
| 86 | #endif | 86 | #endif |
| 87 | 87 | ||
| 88 | # | 88 | # |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 1f70970de0aa..cdef68717416 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
| @@ -80,7 +80,7 @@ startup_continue: | |||
| 80 | _ehead: | 80 | _ehead: |
| 81 | 81 | ||
| 82 | #ifdef CONFIG_SHARED_KERNEL | 82 | #ifdef CONFIG_SHARED_KERNEL |
| 83 | .org 0x100000 | 83 | .org 0x100000 - 0x11000 # head.o ends at 0x11000 |
| 84 | #endif | 84 | #endif |
| 85 | 85 | ||
| 86 | # | 86 | # |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 33fdc5a79764..9f654da4cecc 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
| @@ -640,7 +640,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, | |||
| 640 | 640 | ||
| 641 | asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) | 641 | asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) |
| 642 | { | 642 | { |
| 643 | long ret; | 643 | long ret = 0; |
| 644 | 644 | ||
| 645 | /* Do the secure computing check first. */ | 645 | /* Do the secure computing check first. */ |
| 646 | secure_computing(regs->gprs[2]); | 646 | secure_computing(regs->gprs[2]); |
| @@ -649,7 +649,6 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) | |||
| 649 | * The sysc_tracesys code in entry.S stored the system | 649 | * The sysc_tracesys code in entry.S stored the system |
| 650 | * call number to gprs[2]. | 650 | * call number to gprs[2]. |
| 651 | */ | 651 | */ |
| 652 | ret = regs->gprs[2]; | ||
| 653 | if (test_thread_flag(TIF_SYSCALL_TRACE) && | 652 | if (test_thread_flag(TIF_SYSCALL_TRACE) && |
| 654 | (tracehook_report_syscall_entry(regs) || | 653 | (tracehook_report_syscall_entry(regs) || |
| 655 | regs->gprs[2] >= NR_syscalls)) { | 654 | regs->gprs[2] >= NR_syscalls)) { |
| @@ -671,7 +670,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) | |||
| 671 | regs->gprs[2], regs->orig_gpr2, | 670 | regs->gprs[2], regs->orig_gpr2, |
| 672 | regs->gprs[3], regs->gprs[4], | 671 | regs->gprs[3], regs->gprs[4], |
| 673 | regs->gprs[5]); | 672 | regs->gprs[5]); |
| 674 | return ret; | 673 | return ret ?: regs->gprs[2]; |
| 675 | } | 674 | } |
| 676 | 675 | ||
| 677 | asmlinkage void do_syscall_trace_exit(struct pt_regs *regs) | 676 | asmlinkage void do_syscall_trace_exit(struct pt_regs *regs) |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 2ba58206812a..737361fcd503 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
| @@ -2067,7 +2067,7 @@ static int cpuid_interception(struct vcpu_svm *svm) | |||
| 2067 | static int iret_interception(struct vcpu_svm *svm) | 2067 | static int iret_interception(struct vcpu_svm *svm) |
| 2068 | { | 2068 | { |
| 2069 | ++svm->vcpu.stat.nmi_window_exits; | 2069 | ++svm->vcpu.stat.nmi_window_exits; |
| 2070 | svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET); | 2070 | svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET); |
| 2071 | svm->vcpu.arch.hflags |= HF_IRET_MASK; | 2071 | svm->vcpu.arch.hflags |= HF_IRET_MASK; |
| 2072 | return 1; | 2072 | return 1; |
| 2073 | } | 2073 | } |
| @@ -2479,7 +2479,7 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu) | |||
| 2479 | 2479 | ||
| 2480 | svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_NMI; | 2480 | svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_NMI; |
| 2481 | vcpu->arch.hflags |= HF_NMI_MASK; | 2481 | vcpu->arch.hflags |= HF_NMI_MASK; |
| 2482 | svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET); | 2482 | svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET); |
| 2483 | ++vcpu->stat.nmi_injections; | 2483 | ++vcpu->stat.nmi_injections; |
| 2484 | } | 2484 | } |
| 2485 | 2485 | ||
| @@ -2539,10 +2539,10 @@ static void svm_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked) | |||
| 2539 | 2539 | ||
| 2540 | if (masked) { | 2540 | if (masked) { |
| 2541 | svm->vcpu.arch.hflags |= HF_NMI_MASK; | 2541 | svm->vcpu.arch.hflags |= HF_NMI_MASK; |
| 2542 | svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET); | 2542 | svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET); |
| 2543 | } else { | 2543 | } else { |
| 2544 | svm->vcpu.arch.hflags &= ~HF_NMI_MASK; | 2544 | svm->vcpu.arch.hflags &= ~HF_NMI_MASK; |
| 2545 | svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET); | 2545 | svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET); |
| 2546 | } | 2546 | } |
| 2547 | } | 2547 | } |
| 2548 | 2548 | ||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index bc933cfb4e66..2f8db0ec8ae4 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -2703,8 +2703,7 @@ static int vmx_nmi_allowed(struct kvm_vcpu *vcpu) | |||
| 2703 | return 0; | 2703 | return 0; |
| 2704 | 2704 | ||
| 2705 | return !(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & | 2705 | return !(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & |
| 2706 | (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS | | 2706 | (GUEST_INTR_STATE_MOV_SS | GUEST_INTR_STATE_NMI)); |
| 2707 | GUEST_INTR_STATE_NMI)); | ||
| 2708 | } | 2707 | } |
| 2709 | 2708 | ||
| 2710 | static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu) | 2709 | static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu) |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 3c4ca98ad27f..c4f35b545c1d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -1712,6 +1712,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, | |||
| 1712 | if (copy_from_user(cpuid_entries, entries, | 1712 | if (copy_from_user(cpuid_entries, entries, |
| 1713 | cpuid->nent * sizeof(struct kvm_cpuid_entry))) | 1713 | cpuid->nent * sizeof(struct kvm_cpuid_entry))) |
| 1714 | goto out_free; | 1714 | goto out_free; |
| 1715 | vcpu_load(vcpu); | ||
| 1715 | for (i = 0; i < cpuid->nent; i++) { | 1716 | for (i = 0; i < cpuid->nent; i++) { |
| 1716 | vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function; | 1717 | vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function; |
| 1717 | vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax; | 1718 | vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax; |
| @@ -1729,6 +1730,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, | |||
| 1729 | r = 0; | 1730 | r = 0; |
| 1730 | kvm_apic_set_version(vcpu); | 1731 | kvm_apic_set_version(vcpu); |
| 1731 | kvm_x86_ops->cpuid_update(vcpu); | 1732 | kvm_x86_ops->cpuid_update(vcpu); |
| 1733 | vcpu_put(vcpu); | ||
| 1732 | 1734 | ||
| 1733 | out_free: | 1735 | out_free: |
| 1734 | vfree(cpuid_entries); | 1736 | vfree(cpuid_entries); |
| @@ -1749,9 +1751,11 @@ static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu, | |||
| 1749 | if (copy_from_user(&vcpu->arch.cpuid_entries, entries, | 1751 | if (copy_from_user(&vcpu->arch.cpuid_entries, entries, |
| 1750 | cpuid->nent * sizeof(struct kvm_cpuid_entry2))) | 1752 | cpuid->nent * sizeof(struct kvm_cpuid_entry2))) |
| 1751 | goto out; | 1753 | goto out; |
| 1754 | vcpu_load(vcpu); | ||
| 1752 | vcpu->arch.cpuid_nent = cpuid->nent; | 1755 | vcpu->arch.cpuid_nent = cpuid->nent; |
| 1753 | kvm_apic_set_version(vcpu); | 1756 | kvm_apic_set_version(vcpu); |
| 1754 | kvm_x86_ops->cpuid_update(vcpu); | 1757 | kvm_x86_ops->cpuid_update(vcpu); |
| 1758 | vcpu_put(vcpu); | ||
| 1755 | return 0; | 1759 | return 0; |
| 1756 | 1760 | ||
| 1757 | out: | 1761 | out: |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 6da962c9b21c..d71f0fc34b46 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
| @@ -1875,6 +1875,7 @@ got_driver: | |||
| 1875 | */ | 1875 | */ |
| 1876 | if (filp->f_op == &hung_up_tty_fops) | 1876 | if (filp->f_op == &hung_up_tty_fops) |
| 1877 | filp->f_op = &tty_fops; | 1877 | filp->f_op = &tty_fops; |
| 1878 | unlock_kernel(); | ||
| 1878 | goto retry_open; | 1879 | goto retry_open; |
| 1879 | } | 1880 | } |
| 1880 | unlock_kernel(); | 1881 | unlock_kernel(); |
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index b1edd778639c..405febd94f24 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c | |||
| @@ -54,6 +54,9 @@ static signed short btn_avb_wheel[] = | |||
| 54 | static signed short abs_joystick[] = | 54 | static signed short abs_joystick[] = |
| 55 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 }; | 55 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 }; |
| 56 | 56 | ||
| 57 | static signed short abs_joystick_rudder[] = | ||
| 58 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, -1 }; | ||
| 59 | |||
| 57 | static signed short abs_avb_pegasus[] = | 60 | static signed short abs_avb_pegasus[] = |
| 58 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, | 61 | { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, |
| 59 | ABS_HAT1X, ABS_HAT1Y, -1 }; | 62 | ABS_HAT1X, ABS_HAT1Y, -1 }; |
| @@ -76,8 +79,9 @@ static struct iforce_device iforce_device[] = { | |||
| 76 | { 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //? | 79 | { 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //? |
| 77 | { 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, | 80 | { 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, |
| 78 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? | 81 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? |
| 82 | { 0x06f8, 0x0001, "Guillemot Jet Leader Force Feedback", btn_joystick, abs_joystick_rudder, ff_iforce }, | ||
| 79 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? | 83 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? |
| 80 | { 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? | 84 | { 0x06f8, 0xa302, "Guillemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? |
| 81 | { 0x06d6, 0x29bc, "Trust Force Feedback Race Master", btn_wheel, abs_wheel, ff_iforce }, | 85 | { 0x06d6, 0x29bc, "Trust Force Feedback Race Master", btn_wheel, abs_wheel, ff_iforce }, |
| 82 | { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } | 86 | { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } |
| 83 | }; | 87 | }; |
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index b41303d3ec54..6c96631ae5d9 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c | |||
| @@ -212,6 +212,7 @@ static struct usb_device_id iforce_usb_ids [] = { | |||
| 212 | { USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */ | 212 | { USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */ |
| 213 | { USB_DEVICE(0x061c, 0xc084) }, /* ACT LABS Force RS */ | 213 | { USB_DEVICE(0x061c, 0xc084) }, /* ACT LABS Force RS */ |
| 214 | { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */ | 214 | { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */ |
| 215 | { USB_DEVICE(0x06f8, 0x0003) }, /* Guillemot Jet Leader Force Feedback */ | ||
| 215 | { USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */ | 216 | { USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */ |
| 216 | { USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */ | 217 | { USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */ |
| 217 | { } /* Terminating entry */ | 218 | { } /* Terminating entry */ |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 0520c2e19927..112b4ee52ff2 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
| @@ -185,7 +185,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
| 185 | int fingers; | 185 | int fingers; |
| 186 | static int old_fingers; | 186 | static int old_fingers; |
| 187 | 187 | ||
| 188 | if (etd->fw_version_maj == 0x01) { | 188 | if (etd->fw_version < 0x020000) { |
| 189 | /* | 189 | /* |
| 190 | * byte 0: D U p1 p2 1 p3 R L | 190 | * byte 0: D U p1 p2 1 p3 R L |
| 191 | * byte 1: f 0 th tw x9 x8 y9 y8 | 191 | * byte 1: f 0 th tw x9 x8 y9 y8 |
| @@ -227,7 +227,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
| 227 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 227 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); |
| 228 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 228 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); |
| 229 | 229 | ||
| 230 | if ((etd->fw_version_maj == 0x01) && | 230 | if (etd->fw_version < 0x020000 && |
| 231 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { | 231 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { |
| 232 | /* rocker up */ | 232 | /* rocker up */ |
| 233 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); | 233 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); |
| @@ -321,7 +321,7 @@ static int elantech_check_parity_v1(struct psmouse *psmouse) | |||
| 321 | unsigned char p1, p2, p3; | 321 | unsigned char p1, p2, p3; |
| 322 | 322 | ||
| 323 | /* Parity bits are placed differently */ | 323 | /* Parity bits are placed differently */ |
| 324 | if (etd->fw_version_maj == 0x01) { | 324 | if (etd->fw_version < 0x020000) { |
| 325 | /* byte 0: D U p1 p2 1 p3 R L */ | 325 | /* byte 0: D U p1 p2 1 p3 R L */ |
| 326 | p1 = (packet[0] & 0x20) >> 5; | 326 | p1 = (packet[0] & 0x20) >> 5; |
| 327 | p2 = (packet[0] & 0x10) >> 4; | 327 | p2 = (packet[0] & 0x10) >> 4; |
| @@ -457,7 +457,7 @@ static void elantech_set_input_params(struct psmouse *psmouse) | |||
| 457 | switch (etd->hw_version) { | 457 | switch (etd->hw_version) { |
| 458 | case 1: | 458 | case 1: |
| 459 | /* Rocker button */ | 459 | /* Rocker button */ |
| 460 | if ((etd->fw_version_maj == 0x01) && | 460 | if (etd->fw_version < 0x020000 && |
| 461 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { | 461 | (etd->capabilities & ETP_CAP_HAS_ROCKER)) { |
| 462 | __set_bit(BTN_FORWARD, dev->keybit); | 462 | __set_bit(BTN_FORWARD, dev->keybit); |
| 463 | __set_bit(BTN_BACK, dev->keybit); | 463 | __set_bit(BTN_BACK, dev->keybit); |
| @@ -686,15 +686,14 @@ int elantech_init(struct psmouse *psmouse) | |||
| 686 | pr_err("elantech.c: failed to query firmware version.\n"); | 686 | pr_err("elantech.c: failed to query firmware version.\n"); |
| 687 | goto init_fail; | 687 | goto init_fail; |
| 688 | } | 688 | } |
| 689 | etd->fw_version_maj = param[0]; | 689 | |
| 690 | etd->fw_version_min = param[2]; | 690 | etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2]; |
| 691 | 691 | ||
| 692 | /* | 692 | /* |
| 693 | * Assume every version greater than this is new EeePC style | 693 | * Assume every version greater than this is new EeePC style |
| 694 | * hardware with 6 byte packets | 694 | * hardware with 6 byte packets |
| 695 | */ | 695 | */ |
| 696 | if ((etd->fw_version_maj == 0x02 && etd->fw_version_min >= 0x30) || | 696 | if (etd->fw_version >= 0x020030) { |
| 697 | etd->fw_version_maj > 0x02) { | ||
| 698 | etd->hw_version = 2; | 697 | etd->hw_version = 2; |
| 699 | /* For now show extra debug information */ | 698 | /* For now show extra debug information */ |
| 700 | etd->debug = 1; | 699 | etd->debug = 1; |
| @@ -704,8 +703,9 @@ int elantech_init(struct psmouse *psmouse) | |||
| 704 | etd->hw_version = 1; | 703 | etd->hw_version = 1; |
| 705 | etd->paritycheck = 1; | 704 | etd->paritycheck = 1; |
| 706 | } | 705 | } |
| 707 | pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d\n", | 706 | |
| 708 | etd->hw_version, etd->fw_version_maj, etd->fw_version_min); | 707 | pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d.%d\n", |
| 708 | etd->hw_version, param[0], param[1], param[2]); | ||
| 709 | 709 | ||
| 710 | if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { | 710 | if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) { |
| 711 | pr_err("elantech.c: failed to query capabilities.\n"); | 711 | pr_err("elantech.c: failed to query capabilities.\n"); |
| @@ -720,8 +720,8 @@ int elantech_init(struct psmouse *psmouse) | |||
| 720 | * a touch action starts causing the mouse cursor or scrolled page | 720 | * a touch action starts causing the mouse cursor or scrolled page |
| 721 | * to jump. Enable a workaround. | 721 | * to jump. Enable a workaround. |
| 722 | */ | 722 | */ |
| 723 | if (etd->fw_version_maj == 0x02 && etd->fw_version_min == 0x22) { | 723 | if (etd->fw_version == 0x020022) { |
| 724 | pr_info("elantech.c: firmware version 2.34 detected, " | 724 | pr_info("elantech.c: firmware version 2.0.34 detected, " |
| 725 | "enabling jumpy cursor workaround\n"); | 725 | "enabling jumpy cursor workaround\n"); |
| 726 | etd->jumpy_cursor = 1; | 726 | etd->jumpy_cursor = 1; |
| 727 | } | 727 | } |
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index feac5f7af966..ac57bde1bb9f 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
| @@ -100,11 +100,10 @@ struct elantech_data { | |||
| 100 | unsigned char reg_26; | 100 | unsigned char reg_26; |
| 101 | unsigned char debug; | 101 | unsigned char debug; |
| 102 | unsigned char capabilities; | 102 | unsigned char capabilities; |
| 103 | unsigned char fw_version_maj; | ||
| 104 | unsigned char fw_version_min; | ||
| 105 | unsigned char hw_version; | ||
| 106 | unsigned char paritycheck; | 103 | unsigned char paritycheck; |
| 107 | unsigned char jumpy_cursor; | 104 | unsigned char jumpy_cursor; |
| 105 | unsigned char hw_version; | ||
| 106 | unsigned int fw_version; | ||
| 108 | unsigned char parity[256]; | 107 | unsigned char parity[256]; |
| 109 | }; | 108 | }; |
| 110 | 109 | ||
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index cbc807264940..a3c97315a473 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -1394,6 +1394,7 @@ static int psmouse_reconnect(struct serio *serio) | |||
| 1394 | struct psmouse *psmouse = serio_get_drvdata(serio); | 1394 | struct psmouse *psmouse = serio_get_drvdata(serio); |
| 1395 | struct psmouse *parent = NULL; | 1395 | struct psmouse *parent = NULL; |
| 1396 | struct serio_driver *drv = serio->drv; | 1396 | struct serio_driver *drv = serio->drv; |
| 1397 | unsigned char type; | ||
| 1397 | int rc = -1; | 1398 | int rc = -1; |
| 1398 | 1399 | ||
| 1399 | if (!drv || !psmouse) { | 1400 | if (!drv || !psmouse) { |
| @@ -1413,10 +1414,15 @@ static int psmouse_reconnect(struct serio *serio) | |||
| 1413 | if (psmouse->reconnect) { | 1414 | if (psmouse->reconnect) { |
| 1414 | if (psmouse->reconnect(psmouse)) | 1415 | if (psmouse->reconnect(psmouse)) |
| 1415 | goto out; | 1416 | goto out; |
| 1416 | } else if (psmouse_probe(psmouse) < 0 || | 1417 | } else { |
| 1417 | psmouse->type != psmouse_extensions(psmouse, | 1418 | psmouse_reset(psmouse); |
| 1418 | psmouse_max_proto, false)) { | 1419 | |
| 1419 | goto out; | 1420 | if (psmouse_probe(psmouse) < 0) |
| 1421 | goto out; | ||
| 1422 | |||
| 1423 | type = psmouse_extensions(psmouse, psmouse_max_proto, false); | ||
| 1424 | if (psmouse->type != type) | ||
| 1425 | goto out; | ||
| 1420 | } | 1426 | } |
| 1421 | 1427 | ||
| 1422 | /* ok, the device type (and capabilities) match the old one, | 1428 | /* ok, the device type (and capabilities) match the old one, |
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index e019d53d1ab4..0d2d7e54b465 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c | |||
| @@ -156,9 +156,14 @@ struct ser_req { | |||
| 156 | u16 reset; | 156 | u16 reset; |
| 157 | u16 ref_on; | 157 | u16 ref_on; |
| 158 | u16 command; | 158 | u16 command; |
| 159 | u16 sample; | ||
| 160 | struct spi_message msg; | 159 | struct spi_message msg; |
| 161 | struct spi_transfer xfer[6]; | 160 | struct spi_transfer xfer[6]; |
| 161 | |||
| 162 | /* | ||
| 163 | * DMA (thus cache coherency maintenance) requires the | ||
| 164 | * transfer buffers to live in their own cache lines. | ||
| 165 | */ | ||
| 166 | u16 sample ____cacheline_aligned; | ||
| 162 | }; | 167 | }; |
| 163 | 168 | ||
| 164 | struct ad7877 { | 169 | struct ad7877 { |
| @@ -182,8 +187,6 @@ struct ad7877 { | |||
| 182 | u8 averaging; | 187 | u8 averaging; |
| 183 | u8 pen_down_acc_interval; | 188 | u8 pen_down_acc_interval; |
| 184 | 189 | ||
| 185 | u16 conversion_data[AD7877_NR_SENSE]; | ||
| 186 | |||
| 187 | struct spi_transfer xfer[AD7877_NR_SENSE + 2]; | 190 | struct spi_transfer xfer[AD7877_NR_SENSE + 2]; |
| 188 | struct spi_message msg; | 191 | struct spi_message msg; |
| 189 | 192 | ||
| @@ -195,6 +198,12 @@ struct ad7877 { | |||
| 195 | spinlock_t lock; | 198 | spinlock_t lock; |
| 196 | struct timer_list timer; /* P: lock */ | 199 | struct timer_list timer; /* P: lock */ |
| 197 | unsigned pending:1; /* P: lock */ | 200 | unsigned pending:1; /* P: lock */ |
| 201 | |||
| 202 | /* | ||
| 203 | * DMA (thus cache coherency maintenance) requires the | ||
| 204 | * transfer buffers to live in their own cache lines. | ||
| 205 | */ | ||
| 206 | u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned; | ||
| 198 | }; | 207 | }; |
| 199 | 208 | ||
| 200 | static int gpio3; | 209 | static int gpio3; |
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index a3d5728b6449..f2ab025ad97a 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c | |||
| @@ -349,6 +349,9 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) | |||
| 349 | goto disable; | 349 | goto disable; |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | /* If an interrupt arrived late clean up after it */ | ||
| 353 | try_wait_for_completion(&wm831x->auxadc_done); | ||
| 354 | |||
| 352 | /* Ignore the result to allow us to soldier on without IRQ hookup */ | 355 | /* Ignore the result to allow us to soldier on without IRQ hookup */ |
| 353 | wait_for_completion_timeout(&wm831x->auxadc_done, msecs_to_jiffies(5)); | 356 | wait_for_completion_timeout(&wm831x->auxadc_done, msecs_to_jiffies(5)); |
| 354 | 357 | ||
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index e400a3bed063..b5807484b4c9 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c | |||
| @@ -363,6 +363,10 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref) | |||
| 363 | reg |= 1 << channel | WM8350_AUXADC_POLL; | 363 | reg |= 1 << channel | WM8350_AUXADC_POLL; |
| 364 | wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg); | 364 | wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg); |
| 365 | 365 | ||
| 366 | /* If a late IRQ left the completion signalled then consume | ||
| 367 | * the completion. */ | ||
| 368 | try_wait_for_completion(&wm8350->auxadc_done); | ||
| 369 | |||
| 366 | /* We ignore the result of the completion and just check for a | 370 | /* We ignore the result of the completion and just check for a |
| 367 | * conversion result, allowing us to soldier on if the IRQ | 371 | * conversion result, allowing us to soldier on if the IRQ |
| 368 | * infrastructure is not set up for the chip. */ | 372 | * infrastructure is not set up for the chip. */ |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 4fe36d2e1049..19b111383f62 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
| @@ -838,65 +838,11 @@ static void pci_bus_dump_resources(struct pci_bus *bus) | |||
| 838 | } | 838 | } |
| 839 | } | 839 | } |
| 840 | 840 | ||
| 841 | static int __init pci_bus_get_depth(struct pci_bus *bus) | ||
| 842 | { | ||
| 843 | int depth = 0; | ||
| 844 | struct pci_dev *dev; | ||
| 845 | |||
| 846 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
| 847 | int ret; | ||
| 848 | struct pci_bus *b = dev->subordinate; | ||
| 849 | if (!b) | ||
| 850 | continue; | ||
| 851 | |||
| 852 | ret = pci_bus_get_depth(b); | ||
| 853 | if (ret + 1 > depth) | ||
| 854 | depth = ret + 1; | ||
| 855 | } | ||
| 856 | |||
| 857 | return depth; | ||
| 858 | } | ||
| 859 | static int __init pci_get_max_depth(void) | ||
| 860 | { | ||
| 861 | int depth = 0; | ||
| 862 | struct pci_bus *bus; | ||
| 863 | |||
| 864 | list_for_each_entry(bus, &pci_root_buses, node) { | ||
| 865 | int ret; | ||
| 866 | |||
| 867 | ret = pci_bus_get_depth(bus); | ||
| 868 | if (ret > depth) | ||
| 869 | depth = ret; | ||
| 870 | } | ||
| 871 | |||
| 872 | return depth; | ||
| 873 | } | ||
| 874 | |||
| 875 | /* | ||
| 876 | * first try will not touch pci bridge res | ||
| 877 | * second and later try will clear small leaf bridge res | ||
| 878 | * will stop till to the max deepth if can not find good one | ||
| 879 | */ | ||
| 880 | void __init | 841 | void __init |
| 881 | pci_assign_unassigned_resources(void) | 842 | pci_assign_unassigned_resources(void) |
| 882 | { | 843 | { |
| 883 | struct pci_bus *bus; | 844 | struct pci_bus *bus; |
| 884 | int tried_times = 0; | ||
| 885 | enum release_type rel_type = leaf_only; | ||
| 886 | struct resource_list_x head, *list; | ||
| 887 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | ||
| 888 | IORESOURCE_PREFETCH; | ||
| 889 | unsigned long failed_type; | ||
| 890 | int max_depth = pci_get_max_depth(); | ||
| 891 | int pci_try_num; | ||
| 892 | 845 | ||
| 893 | head.next = NULL; | ||
| 894 | |||
| 895 | pci_try_num = max_depth + 1; | ||
| 896 | printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", | ||
| 897 | max_depth, pci_try_num); | ||
| 898 | |||
| 899 | again: | ||
| 900 | /* Depth first, calculate sizes and alignments of all | 846 | /* Depth first, calculate sizes and alignments of all |
| 901 | subordinate buses. */ | 847 | subordinate buses. */ |
| 902 | list_for_each_entry(bus, &pci_root_buses, node) { | 848 | list_for_each_entry(bus, &pci_root_buses, node) { |
| @@ -904,65 +850,9 @@ again: | |||
| 904 | } | 850 | } |
| 905 | /* Depth last, allocate resources and update the hardware. */ | 851 | /* Depth last, allocate resources and update the hardware. */ |
| 906 | list_for_each_entry(bus, &pci_root_buses, node) { | 852 | list_for_each_entry(bus, &pci_root_buses, node) { |
| 907 | __pci_bus_assign_resources(bus, &head); | 853 | pci_bus_assign_resources(bus); |
| 908 | } | ||
| 909 | tried_times++; | ||
| 910 | |||
| 911 | /* any device complain? */ | ||
| 912 | if (!head.next) | ||
| 913 | goto enable_and_dump; | ||
| 914 | failed_type = 0; | ||
| 915 | for (list = head.next; list;) { | ||
| 916 | failed_type |= list->flags; | ||
| 917 | list = list->next; | ||
| 918 | } | ||
| 919 | /* | ||
| 920 | * io port are tight, don't try extra | ||
| 921 | * or if reach the limit, don't want to try more | ||
| 922 | */ | ||
| 923 | failed_type &= type_mask; | ||
| 924 | if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) { | ||
| 925 | free_failed_list(&head); | ||
| 926 | goto enable_and_dump; | ||
| 927 | } | ||
| 928 | |||
| 929 | printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n", | ||
| 930 | tried_times + 1); | ||
| 931 | |||
| 932 | /* third times and later will not check if it is leaf */ | ||
| 933 | if ((tried_times + 1) > 2) | ||
| 934 | rel_type = whole_subtree; | ||
| 935 | |||
| 936 | /* | ||
| 937 | * Try to release leaf bridge's resources that doesn't fit resource of | ||
| 938 | * child device under that bridge | ||
| 939 | */ | ||
| 940 | for (list = head.next; list;) { | ||
| 941 | bus = list->dev->bus; | ||
| 942 | pci_bus_release_bridge_resources(bus, list->flags & type_mask, | ||
| 943 | rel_type); | ||
| 944 | list = list->next; | ||
| 945 | } | ||
| 946 | /* restore size and flags */ | ||
| 947 | for (list = head.next; list;) { | ||
| 948 | struct resource *res = list->res; | ||
| 949 | |||
| 950 | res->start = list->start; | ||
| 951 | res->end = list->end; | ||
| 952 | res->flags = list->flags; | ||
| 953 | if (list->dev->subordinate) | ||
| 954 | res->flags = 0; | ||
| 955 | |||
| 956 | list = list->next; | ||
| 957 | } | ||
| 958 | free_failed_list(&head); | ||
| 959 | |||
| 960 | goto again; | ||
| 961 | |||
| 962 | enable_and_dump: | ||
| 963 | /* Depth last, update the hardware. */ | ||
| 964 | list_for_each_entry(bus, &pci_root_buses, node) | ||
| 965 | pci_enable_bridges(bus); | 854 | pci_enable_bridges(bus); |
| 855 | } | ||
| 966 | 856 | ||
| 967 | /* dump the resource on buses */ | 857 | /* dump the resource on buses */ |
| 968 | list_for_each_entry(bus, &pci_root_buses, node) { | 858 | list_for_each_entry(bus, &pci_root_buses, node) { |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index acf222f91f5a..fa2339cb1681 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
| @@ -37,6 +37,9 @@ | |||
| 37 | */ | 37 | */ |
| 38 | #define DASD_CHANQ_MAX_SIZE 4 | 38 | #define DASD_CHANQ_MAX_SIZE 4 |
| 39 | 39 | ||
| 40 | #define DASD_SLEEPON_START_TAG (void *) 1 | ||
| 41 | #define DASD_SLEEPON_END_TAG (void *) 2 | ||
| 42 | |||
| 40 | /* | 43 | /* |
| 41 | * SECTION: exported variables of dasd.c | 44 | * SECTION: exported variables of dasd.c |
| 42 | */ | 45 | */ |
| @@ -1472,7 +1475,10 @@ void dasd_add_request_tail(struct dasd_ccw_req *cqr) | |||
| 1472 | */ | 1475 | */ |
| 1473 | static void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data) | 1476 | static void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data) |
| 1474 | { | 1477 | { |
| 1475 | wake_up((wait_queue_head_t *) data); | 1478 | spin_lock_irq(get_ccwdev_lock(cqr->startdev->cdev)); |
| 1479 | cqr->callback_data = DASD_SLEEPON_END_TAG; | ||
| 1480 | spin_unlock_irq(get_ccwdev_lock(cqr->startdev->cdev)); | ||
| 1481 | wake_up(&generic_waitq); | ||
| 1476 | } | 1482 | } |
| 1477 | 1483 | ||
| 1478 | static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr) | 1484 | static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr) |
| @@ -1482,10 +1488,7 @@ static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr) | |||
| 1482 | 1488 | ||
| 1483 | device = cqr->startdev; | 1489 | device = cqr->startdev; |
| 1484 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 1490 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
| 1485 | rc = ((cqr->status == DASD_CQR_DONE || | 1491 | rc = (cqr->callback_data == DASD_SLEEPON_END_TAG); |
| 1486 | cqr->status == DASD_CQR_NEED_ERP || | ||
| 1487 | cqr->status == DASD_CQR_TERMINATED) && | ||
| 1488 | list_empty(&cqr->devlist)); | ||
| 1489 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 1492 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
| 1490 | return rc; | 1493 | return rc; |
| 1491 | } | 1494 | } |
| @@ -1573,7 +1576,7 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible) | |||
| 1573 | wait_event(generic_waitq, !(device->stopped)); | 1576 | wait_event(generic_waitq, !(device->stopped)); |
| 1574 | 1577 | ||
| 1575 | cqr->callback = dasd_wakeup_cb; | 1578 | cqr->callback = dasd_wakeup_cb; |
| 1576 | cqr->callback_data = (void *) &generic_waitq; | 1579 | cqr->callback_data = DASD_SLEEPON_START_TAG; |
| 1577 | dasd_add_request_tail(cqr); | 1580 | dasd_add_request_tail(cqr); |
| 1578 | if (interruptible) { | 1581 | if (interruptible) { |
| 1579 | rc = wait_event_interruptible( | 1582 | rc = wait_event_interruptible( |
| @@ -1652,7 +1655,7 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr) | |||
| 1652 | } | 1655 | } |
| 1653 | 1656 | ||
| 1654 | cqr->callback = dasd_wakeup_cb; | 1657 | cqr->callback = dasd_wakeup_cb; |
| 1655 | cqr->callback_data = (void *) &generic_waitq; | 1658 | cqr->callback_data = DASD_SLEEPON_START_TAG; |
| 1656 | cqr->status = DASD_CQR_QUEUED; | 1659 | cqr->status = DASD_CQR_QUEUED; |
| 1657 | list_add(&cqr->devlist, &device->ccw_queue); | 1660 | list_add(&cqr->devlist, &device->ccw_queue); |
| 1658 | 1661 | ||
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 4315b23590bd..eacb588a9345 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
| @@ -120,7 +120,8 @@ | |||
| 120 | #define MX2_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select, on mx2/mx3 */ | 120 | #define MX2_UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select, on mx2/mx3 */ |
| 121 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ | 121 | #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ |
| 122 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ | 122 | #define UCR3_BPEN (1<<0) /* Preset registers enable */ |
| 123 | #define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */ | 123 | #define UCR4_CTSTL_SHF 10 /* CTS trigger level shift */ |
| 124 | #define UCR4_CTSTL_MASK 0x3F /* CTS trigger is 6 bits wide */ | ||
| 124 | #define UCR4_INVR (1<<9) /* Inverted infrared reception */ | 125 | #define UCR4_INVR (1<<9) /* Inverted infrared reception */ |
| 125 | #define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ | 126 | #define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ |
| 126 | #define UCR4_WKEN (1<<7) /* Wake interrupt enable */ | 127 | #define UCR4_WKEN (1<<7) /* Wake interrupt enable */ |
| @@ -591,6 +592,9 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) | |||
| 591 | return 0; | 592 | return 0; |
| 592 | } | 593 | } |
| 593 | 594 | ||
| 595 | /* half the RX buffer size */ | ||
| 596 | #define CTSTL 16 | ||
| 597 | |||
| 594 | static int imx_startup(struct uart_port *port) | 598 | static int imx_startup(struct uart_port *port) |
| 595 | { | 599 | { |
| 596 | struct imx_port *sport = (struct imx_port *)port; | 600 | struct imx_port *sport = (struct imx_port *)port; |
| @@ -607,6 +611,10 @@ static int imx_startup(struct uart_port *port) | |||
| 607 | if (USE_IRDA(sport)) | 611 | if (USE_IRDA(sport)) |
| 608 | temp |= UCR4_IRSC; | 612 | temp |= UCR4_IRSC; |
| 609 | 613 | ||
| 614 | /* set the trigger level for CTS */ | ||
| 615 | temp &= ~(UCR4_CTSTL_MASK<< UCR4_CTSTL_SHF); | ||
| 616 | temp |= CTSTL<< UCR4_CTSTL_SHF; | ||
| 617 | |||
| 610 | writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); | 618 | writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); |
| 611 | 619 | ||
| 612 | if (USE_IRDA(sport)) { | 620 | if (USE_IRDA(sport)) { |
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index a176ab4bd65b..02469c31bf0b 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
| @@ -1467,7 +1467,7 @@ mpc52xx_uart_init(void) | |||
| 1467 | /* | 1467 | /* |
| 1468 | * Map the PSC FIFO Controller and init if on MPC512x. | 1468 | * Map the PSC FIFO Controller and init if on MPC512x. |
| 1469 | */ | 1469 | */ |
| 1470 | if (psc_ops->fifoc_init) { | 1470 | if (psc_ops && psc_ops->fifoc_init) { |
| 1471 | ret = psc_ops->fifoc_init(); | 1471 | ret = psc_ops->fifoc_init(); |
| 1472 | if (ret) | 1472 | if (ret) |
| 1473 | return ret; | 1473 | return ret; |
diff --git a/fs/cachefiles/security.c b/fs/cachefiles/security.c index b5808cdb2232..039b5011d83b 100644 --- a/fs/cachefiles/security.c +++ b/fs/cachefiles/security.c | |||
| @@ -77,6 +77,8 @@ static int cachefiles_check_cache_dir(struct cachefiles_cache *cache, | |||
| 77 | /* | 77 | /* |
| 78 | * check the security details of the on-disk cache | 78 | * check the security details of the on-disk cache |
| 79 | * - must be called with security override in force | 79 | * - must be called with security override in force |
| 80 | * - must return with a security override in force - even in the case of an | ||
| 81 | * error | ||
| 80 | */ | 82 | */ |
| 81 | int cachefiles_determine_cache_security(struct cachefiles_cache *cache, | 83 | int cachefiles_determine_cache_security(struct cachefiles_cache *cache, |
| 82 | struct dentry *root, | 84 | struct dentry *root, |
| @@ -99,6 +101,8 @@ int cachefiles_determine_cache_security(struct cachefiles_cache *cache, | |||
| 99 | * which create files */ | 101 | * which create files */ |
| 100 | ret = set_create_files_as(new, root->d_inode); | 102 | ret = set_create_files_as(new, root->d_inode); |
| 101 | if (ret < 0) { | 103 | if (ret < 0) { |
| 104 | abort_creds(new); | ||
| 105 | cachefiles_begin_secure(cache, _saved_cred); | ||
| 102 | _leave(" = %d [cfa]", ret); | 106 | _leave(" = %d [cfa]", ret); |
| 103 | return ret; | 107 | return ret; |
| 104 | } | 108 | } |
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 4b42c2bb603f..a9005d862ed4 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
| @@ -504,7 +504,6 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
| 504 | int i; | 504 | int i; |
| 505 | struct ceph_snap_context *snapc = req->r_snapc; | 505 | struct ceph_snap_context *snapc = req->r_snapc; |
| 506 | struct address_space *mapping = inode->i_mapping; | 506 | struct address_space *mapping = inode->i_mapping; |
| 507 | struct writeback_control *wbc = req->r_wbc; | ||
| 508 | __s32 rc = -EIO; | 507 | __s32 rc = -EIO; |
| 509 | u64 bytes = 0; | 508 | u64 bytes = 0; |
| 510 | struct ceph_client *client = ceph_inode_to_client(inode); | 509 | struct ceph_client *client = ceph_inode_to_client(inode); |
| @@ -546,10 +545,6 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
| 546 | clear_bdi_congested(&client->backing_dev_info, | 545 | clear_bdi_congested(&client->backing_dev_info, |
| 547 | BLK_RW_ASYNC); | 546 | BLK_RW_ASYNC); |
| 548 | 547 | ||
| 549 | if (i >= wrote) { | ||
| 550 | dout("inode %p skipping page %p\n", inode, page); | ||
| 551 | wbc->pages_skipped++; | ||
| 552 | } | ||
| 553 | ceph_put_snap_context((void *)page->private); | 548 | ceph_put_snap_context((void *)page->private); |
| 554 | page->private = 0; | 549 | page->private = 0; |
| 555 | ClearPagePrivate(page); | 550 | ClearPagePrivate(page); |
| @@ -799,7 +794,6 @@ get_more_pages: | |||
| 799 | alloc_page_vec(client, req); | 794 | alloc_page_vec(client, req); |
| 800 | req->r_callback = writepages_finish; | 795 | req->r_callback = writepages_finish; |
| 801 | req->r_inode = inode; | 796 | req->r_inode = inode; |
| 802 | req->r_wbc = wbc; | ||
| 803 | } | 797 | } |
| 804 | 798 | ||
| 805 | /* note position of first page in pvec */ | 799 | /* note position of first page in pvec */ |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 0c1681806867..d9400534b279 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
| @@ -858,6 +858,8 @@ static int __ceph_is_any_caps(struct ceph_inode_info *ci) | |||
| 858 | } | 858 | } |
| 859 | 859 | ||
| 860 | /* | 860 | /* |
| 861 | * Remove a cap. Take steps to deal with a racing iterate_session_caps. | ||
| 862 | * | ||
| 861 | * caller should hold i_lock. | 863 | * caller should hold i_lock. |
| 862 | * caller will not hold session s_mutex if called from destroy_inode. | 864 | * caller will not hold session s_mutex if called from destroy_inode. |
| 863 | */ | 865 | */ |
| @@ -866,15 +868,10 @@ void __ceph_remove_cap(struct ceph_cap *cap) | |||
| 866 | struct ceph_mds_session *session = cap->session; | 868 | struct ceph_mds_session *session = cap->session; |
| 867 | struct ceph_inode_info *ci = cap->ci; | 869 | struct ceph_inode_info *ci = cap->ci; |
| 868 | struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc; | 870 | struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc; |
| 871 | int removed = 0; | ||
| 869 | 872 | ||
| 870 | dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode); | 873 | dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode); |
| 871 | 874 | ||
| 872 | /* remove from inode list */ | ||
| 873 | rb_erase(&cap->ci_node, &ci->i_caps); | ||
| 874 | cap->ci = NULL; | ||
| 875 | if (ci->i_auth_cap == cap) | ||
| 876 | ci->i_auth_cap = NULL; | ||
| 877 | |||
| 878 | /* remove from session list */ | 875 | /* remove from session list */ |
| 879 | spin_lock(&session->s_cap_lock); | 876 | spin_lock(&session->s_cap_lock); |
| 880 | if (session->s_cap_iterator == cap) { | 877 | if (session->s_cap_iterator == cap) { |
| @@ -885,10 +882,18 @@ void __ceph_remove_cap(struct ceph_cap *cap) | |||
| 885 | list_del_init(&cap->session_caps); | 882 | list_del_init(&cap->session_caps); |
| 886 | session->s_nr_caps--; | 883 | session->s_nr_caps--; |
| 887 | cap->session = NULL; | 884 | cap->session = NULL; |
| 885 | removed = 1; | ||
| 888 | } | 886 | } |
| 887 | /* protect backpointer with s_cap_lock: see iterate_session_caps */ | ||
| 888 | cap->ci = NULL; | ||
| 889 | spin_unlock(&session->s_cap_lock); | 889 | spin_unlock(&session->s_cap_lock); |
| 890 | 890 | ||
| 891 | if (cap->session == NULL) | 891 | /* remove from inode list */ |
| 892 | rb_erase(&cap->ci_node, &ci->i_caps); | ||
| 893 | if (ci->i_auth_cap == cap) | ||
| 894 | ci->i_auth_cap = NULL; | ||
| 895 | |||
| 896 | if (removed) | ||
| 892 | ceph_put_cap(cap); | 897 | ceph_put_cap(cap); |
| 893 | 898 | ||
| 894 | if (!__ceph_is_any_caps(ci) && ci->i_snap_realm) { | 899 | if (!__ceph_is_any_caps(ci) && ci->i_snap_realm) { |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 261f3e6c0bcf..85b4d2ffdeba 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
| @@ -733,6 +733,10 @@ no_change: | |||
| 733 | __ceph_get_fmode(ci, cap_fmode); | 733 | __ceph_get_fmode(ci, cap_fmode); |
| 734 | spin_unlock(&inode->i_lock); | 734 | spin_unlock(&inode->i_lock); |
| 735 | } | 735 | } |
| 736 | } else if (cap_fmode >= 0) { | ||
| 737 | pr_warning("mds issued no caps on %llx.%llx\n", | ||
| 738 | ceph_vinop(inode)); | ||
| 739 | __ceph_get_fmode(ci, cap_fmode); | ||
| 736 | } | 740 | } |
| 737 | 741 | ||
| 738 | /* update delegation info? */ | 742 | /* update delegation info? */ |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 60a9a4ae47be..24561a557e01 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
| @@ -736,9 +736,10 @@ static void cleanup_cap_releases(struct ceph_mds_session *session) | |||
| 736 | } | 736 | } |
| 737 | 737 | ||
| 738 | /* | 738 | /* |
| 739 | * Helper to safely iterate over all caps associated with a session. | 739 | * Helper to safely iterate over all caps associated with a session, with |
| 740 | * special care taken to handle a racing __ceph_remove_cap(). | ||
| 740 | * | 741 | * |
| 741 | * caller must hold session s_mutex | 742 | * Caller must hold session s_mutex. |
| 742 | */ | 743 | */ |
| 743 | static int iterate_session_caps(struct ceph_mds_session *session, | 744 | static int iterate_session_caps(struct ceph_mds_session *session, |
| 744 | int (*cb)(struct inode *, struct ceph_cap *, | 745 | int (*cb)(struct inode *, struct ceph_cap *, |
| @@ -2136,7 +2137,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) | |||
| 2136 | struct ceph_mds_session *session = NULL; | 2137 | struct ceph_mds_session *session = NULL; |
| 2137 | struct ceph_msg *reply; | 2138 | struct ceph_msg *reply; |
| 2138 | struct rb_node *p; | 2139 | struct rb_node *p; |
| 2139 | int err; | 2140 | int err = -ENOMEM; |
| 2140 | struct ceph_pagelist *pagelist; | 2141 | struct ceph_pagelist *pagelist; |
| 2141 | 2142 | ||
| 2142 | pr_info("reconnect to recovering mds%d\n", mds); | 2143 | pr_info("reconnect to recovering mds%d\n", mds); |
| @@ -2185,7 +2186,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) | |||
| 2185 | goto fail; | 2186 | goto fail; |
| 2186 | err = iterate_session_caps(session, encode_caps_cb, pagelist); | 2187 | err = iterate_session_caps(session, encode_caps_cb, pagelist); |
| 2187 | if (err < 0) | 2188 | if (err < 0) |
| 2188 | goto out; | 2189 | goto fail; |
| 2189 | 2190 | ||
| 2190 | /* | 2191 | /* |
| 2191 | * snaprealms. we provide mds with the ino, seq (version), and | 2192 | * snaprealms. we provide mds with the ino, seq (version), and |
| @@ -2213,28 +2214,31 @@ send: | |||
| 2213 | reply->nr_pages = calc_pages_for(0, pagelist->length); | 2214 | reply->nr_pages = calc_pages_for(0, pagelist->length); |
| 2214 | ceph_con_send(&session->s_con, reply); | 2215 | ceph_con_send(&session->s_con, reply); |
| 2215 | 2216 | ||
| 2216 | if (session) { | 2217 | session->s_state = CEPH_MDS_SESSION_OPEN; |
| 2217 | session->s_state = CEPH_MDS_SESSION_OPEN; | 2218 | mutex_unlock(&session->s_mutex); |
| 2218 | __wake_requests(mdsc, &session->s_waiting); | 2219 | |
| 2219 | } | 2220 | mutex_lock(&mdsc->mutex); |
| 2221 | __wake_requests(mdsc, &session->s_waiting); | ||
| 2222 | mutex_unlock(&mdsc->mutex); | ||
| 2223 | |||
| 2224 | ceph_put_mds_session(session); | ||
| 2220 | 2225 | ||
| 2221 | out: | ||
| 2222 | up_read(&mdsc->snap_rwsem); | 2226 | up_read(&mdsc->snap_rwsem); |
| 2223 | if (session) { | ||
| 2224 | mutex_unlock(&session->s_mutex); | ||
| 2225 | ceph_put_mds_session(session); | ||
| 2226 | } | ||
| 2227 | mutex_lock(&mdsc->mutex); | 2227 | mutex_lock(&mdsc->mutex); |
| 2228 | return; | 2228 | return; |
| 2229 | 2229 | ||
| 2230 | fail: | 2230 | fail: |
| 2231 | ceph_msg_put(reply); | 2231 | ceph_msg_put(reply); |
| 2232 | up_read(&mdsc->snap_rwsem); | ||
| 2233 | mutex_unlock(&session->s_mutex); | ||
| 2234 | ceph_put_mds_session(session); | ||
| 2232 | fail_nomsg: | 2235 | fail_nomsg: |
| 2233 | ceph_pagelist_release(pagelist); | 2236 | ceph_pagelist_release(pagelist); |
| 2234 | kfree(pagelist); | 2237 | kfree(pagelist); |
| 2235 | fail_nopagelist: | 2238 | fail_nopagelist: |
| 2236 | pr_err("ENOMEM preparing reconnect for mds%d\n", mds); | 2239 | pr_err("error %d preparing reconnect for mds%d\n", err, mds); |
| 2237 | goto out; | 2240 | mutex_lock(&mdsc->mutex); |
| 2241 | return; | ||
| 2238 | } | 2242 | } |
| 2239 | 2243 | ||
| 2240 | 2244 | ||
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 509f57d9ccb3..cd4fadb6491a 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c | |||
| @@ -492,7 +492,14 @@ static void prepare_write_message(struct ceph_connection *con) | |||
| 492 | list_move_tail(&m->list_head, &con->out_sent); | 492 | list_move_tail(&m->list_head, &con->out_sent); |
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | m->hdr.seq = cpu_to_le64(++con->out_seq); | 495 | /* |
| 496 | * only assign outgoing seq # if we haven't sent this message | ||
| 497 | * yet. if it is requeued, resend with it's original seq. | ||
| 498 | */ | ||
| 499 | if (m->needs_out_seq) { | ||
| 500 | m->hdr.seq = cpu_to_le64(++con->out_seq); | ||
| 501 | m->needs_out_seq = false; | ||
| 502 | } | ||
| 496 | 503 | ||
| 497 | dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n", | 504 | dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n", |
| 498 | m, con->out_seq, le16_to_cpu(m->hdr.type), | 505 | m, con->out_seq, le16_to_cpu(m->hdr.type), |
| @@ -1986,6 +1993,8 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg) | |||
| 1986 | 1993 | ||
| 1987 | BUG_ON(msg->front.iov_len != le32_to_cpu(msg->hdr.front_len)); | 1994 | BUG_ON(msg->front.iov_len != le32_to_cpu(msg->hdr.front_len)); |
| 1988 | 1995 | ||
| 1996 | msg->needs_out_seq = true; | ||
| 1997 | |||
| 1989 | /* queue */ | 1998 | /* queue */ |
| 1990 | mutex_lock(&con->mutex); | 1999 | mutex_lock(&con->mutex); |
| 1991 | BUG_ON(!list_empty(&msg->list_head)); | 2000 | BUG_ON(!list_empty(&msg->list_head)); |
| @@ -2085,15 +2094,19 @@ struct ceph_msg *ceph_msg_new(int type, int front_len, | |||
| 2085 | kref_init(&m->kref); | 2094 | kref_init(&m->kref); |
| 2086 | INIT_LIST_HEAD(&m->list_head); | 2095 | INIT_LIST_HEAD(&m->list_head); |
| 2087 | 2096 | ||
| 2097 | m->hdr.tid = 0; | ||
| 2088 | m->hdr.type = cpu_to_le16(type); | 2098 | m->hdr.type = cpu_to_le16(type); |
| 2099 | m->hdr.priority = cpu_to_le16(CEPH_MSG_PRIO_DEFAULT); | ||
| 2100 | m->hdr.version = 0; | ||
| 2089 | m->hdr.front_len = cpu_to_le32(front_len); | 2101 | m->hdr.front_len = cpu_to_le32(front_len); |
| 2090 | m->hdr.middle_len = 0; | 2102 | m->hdr.middle_len = 0; |
| 2091 | m->hdr.data_len = cpu_to_le32(page_len); | 2103 | m->hdr.data_len = cpu_to_le32(page_len); |
| 2092 | m->hdr.data_off = cpu_to_le16(page_off); | 2104 | m->hdr.data_off = cpu_to_le16(page_off); |
| 2093 | m->hdr.priority = cpu_to_le16(CEPH_MSG_PRIO_DEFAULT); | 2105 | m->hdr.reserved = 0; |
| 2094 | m->footer.front_crc = 0; | 2106 | m->footer.front_crc = 0; |
| 2095 | m->footer.middle_crc = 0; | 2107 | m->footer.middle_crc = 0; |
| 2096 | m->footer.data_crc = 0; | 2108 | m->footer.data_crc = 0; |
| 2109 | m->footer.flags = 0; | ||
| 2097 | m->front_max = front_len; | 2110 | m->front_max = front_len; |
| 2098 | m->front_is_vmalloc = false; | 2111 | m->front_is_vmalloc = false; |
| 2099 | m->more_to_follow = false; | 2112 | m->more_to_follow = false; |
diff --git a/fs/ceph/messenger.h b/fs/ceph/messenger.h index a343dae73cdc..a5caf91cc971 100644 --- a/fs/ceph/messenger.h +++ b/fs/ceph/messenger.h | |||
| @@ -86,6 +86,7 @@ struct ceph_msg { | |||
| 86 | struct kref kref; | 86 | struct kref kref; |
| 87 | bool front_is_vmalloc; | 87 | bool front_is_vmalloc; |
| 88 | bool more_to_follow; | 88 | bool more_to_follow; |
| 89 | bool needs_out_seq; | ||
| 89 | int front_max; | 90 | int front_max; |
| 90 | 91 | ||
| 91 | struct ceph_msgpool *pool; | 92 | struct ceph_msgpool *pool; |
diff --git a/fs/ceph/osd_client.c b/fs/ceph/osd_client.c index c7b4dedaace6..3514f71ff85f 100644 --- a/fs/ceph/osd_client.c +++ b/fs/ceph/osd_client.c | |||
| @@ -565,7 +565,8 @@ static int __map_osds(struct ceph_osd_client *osdc, | |||
| 565 | { | 565 | { |
| 566 | struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; | 566 | struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; |
| 567 | struct ceph_pg pgid; | 567 | struct ceph_pg pgid; |
| 568 | int o = -1; | 568 | int acting[CEPH_PG_MAX_SIZE]; |
| 569 | int o = -1, num = 0; | ||
| 569 | int err; | 570 | int err; |
| 570 | 571 | ||
| 571 | dout("map_osds %p tid %lld\n", req, req->r_tid); | 572 | dout("map_osds %p tid %lld\n", req, req->r_tid); |
| @@ -576,10 +577,16 @@ static int __map_osds(struct ceph_osd_client *osdc, | |||
| 576 | pgid = reqhead->layout.ol_pgid; | 577 | pgid = reqhead->layout.ol_pgid; |
| 577 | req->r_pgid = pgid; | 578 | req->r_pgid = pgid; |
| 578 | 579 | ||
| 579 | o = ceph_calc_pg_primary(osdc->osdmap, pgid); | 580 | err = ceph_calc_pg_acting(osdc->osdmap, pgid, acting); |
| 581 | if (err > 0) { | ||
| 582 | o = acting[0]; | ||
| 583 | num = err; | ||
| 584 | } | ||
| 580 | 585 | ||
| 581 | if ((req->r_osd && req->r_osd->o_osd == o && | 586 | if ((req->r_osd && req->r_osd->o_osd == o && |
| 582 | req->r_sent >= req->r_osd->o_incarnation) || | 587 | req->r_sent >= req->r_osd->o_incarnation && |
| 588 | req->r_num_pg_osds == num && | ||
| 589 | memcmp(req->r_pg_osds, acting, sizeof(acting[0])*num) == 0) || | ||
| 583 | (req->r_osd == NULL && o == -1)) | 590 | (req->r_osd == NULL && o == -1)) |
| 584 | return 0; /* no change */ | 591 | return 0; /* no change */ |
| 585 | 592 | ||
| @@ -587,6 +594,10 @@ static int __map_osds(struct ceph_osd_client *osdc, | |||
| 587 | req->r_tid, le32_to_cpu(pgid.pool), le16_to_cpu(pgid.ps), o, | 594 | req->r_tid, le32_to_cpu(pgid.pool), le16_to_cpu(pgid.ps), o, |
| 588 | req->r_osd ? req->r_osd->o_osd : -1); | 595 | req->r_osd ? req->r_osd->o_osd : -1); |
| 589 | 596 | ||
| 597 | /* record full pg acting set */ | ||
| 598 | memcpy(req->r_pg_osds, acting, sizeof(acting[0]) * num); | ||
| 599 | req->r_num_pg_osds = num; | ||
| 600 | |||
| 590 | if (req->r_osd) { | 601 | if (req->r_osd) { |
| 591 | __cancel_request(req); | 602 | __cancel_request(req); |
| 592 | list_del_init(&req->r_osd_item); | 603 | list_del_init(&req->r_osd_item); |
| @@ -612,7 +623,7 @@ static int __map_osds(struct ceph_osd_client *osdc, | |||
| 612 | __remove_osd_from_lru(req->r_osd); | 623 | __remove_osd_from_lru(req->r_osd); |
| 613 | list_add(&req->r_osd_item, &req->r_osd->o_requests); | 624 | list_add(&req->r_osd_item, &req->r_osd->o_requests); |
| 614 | } | 625 | } |
| 615 | err = 1; /* osd changed */ | 626 | err = 1; /* osd or pg changed */ |
| 616 | 627 | ||
| 617 | out: | 628 | out: |
| 618 | return err; | 629 | return err; |
| @@ -779,16 +790,18 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, | |||
| 779 | struct ceph_osd_request *req; | 790 | struct ceph_osd_request *req; |
| 780 | u64 tid; | 791 | u64 tid; |
| 781 | int numops, object_len, flags; | 792 | int numops, object_len, flags; |
| 793 | s32 result; | ||
| 782 | 794 | ||
| 783 | tid = le64_to_cpu(msg->hdr.tid); | 795 | tid = le64_to_cpu(msg->hdr.tid); |
| 784 | if (msg->front.iov_len < sizeof(*rhead)) | 796 | if (msg->front.iov_len < sizeof(*rhead)) |
| 785 | goto bad; | 797 | goto bad; |
| 786 | numops = le32_to_cpu(rhead->num_ops); | 798 | numops = le32_to_cpu(rhead->num_ops); |
| 787 | object_len = le32_to_cpu(rhead->object_len); | 799 | object_len = le32_to_cpu(rhead->object_len); |
| 800 | result = le32_to_cpu(rhead->result); | ||
| 788 | if (msg->front.iov_len != sizeof(*rhead) + object_len + | 801 | if (msg->front.iov_len != sizeof(*rhead) + object_len + |
| 789 | numops * sizeof(struct ceph_osd_op)) | 802 | numops * sizeof(struct ceph_osd_op)) |
| 790 | goto bad; | 803 | goto bad; |
| 791 | dout("handle_reply %p tid %llu\n", msg, tid); | 804 | dout("handle_reply %p tid %llu result %d\n", msg, tid, (int)result); |
| 792 | 805 | ||
| 793 | /* lookup */ | 806 | /* lookup */ |
| 794 | mutex_lock(&osdc->request_mutex); | 807 | mutex_lock(&osdc->request_mutex); |
| @@ -834,7 +847,8 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg, | |||
| 834 | dout("handle_reply tid %llu flags %d\n", tid, flags); | 847 | dout("handle_reply tid %llu flags %d\n", tid, flags); |
| 835 | 848 | ||
| 836 | /* either this is a read, or we got the safe response */ | 849 | /* either this is a read, or we got the safe response */ |
| 837 | if ((flags & CEPH_OSD_FLAG_ONDISK) || | 850 | if (result < 0 || |
| 851 | (flags & CEPH_OSD_FLAG_ONDISK) || | ||
| 838 | ((flags & CEPH_OSD_FLAG_WRITE) == 0)) | 852 | ((flags & CEPH_OSD_FLAG_WRITE) == 0)) |
| 839 | __unregister_request(osdc, req); | 853 | __unregister_request(osdc, req); |
| 840 | 854 | ||
diff --git a/fs/ceph/osd_client.h b/fs/ceph/osd_client.h index b0759911e7c3..ce776989ef6a 100644 --- a/fs/ceph/osd_client.h +++ b/fs/ceph/osd_client.h | |||
| @@ -48,6 +48,8 @@ struct ceph_osd_request { | |||
| 48 | struct list_head r_osd_item; | 48 | struct list_head r_osd_item; |
| 49 | struct ceph_osd *r_osd; | 49 | struct ceph_osd *r_osd; |
| 50 | struct ceph_pg r_pgid; | 50 | struct ceph_pg r_pgid; |
| 51 | int r_pg_osds[CEPH_PG_MAX_SIZE]; | ||
| 52 | int r_num_pg_osds; | ||
| 51 | 53 | ||
| 52 | struct ceph_connection *r_con_filling_msg; | 54 | struct ceph_connection *r_con_filling_msg; |
| 53 | 55 | ||
| @@ -66,7 +68,6 @@ struct ceph_osd_request { | |||
| 66 | struct list_head r_unsafe_item; | 68 | struct list_head r_unsafe_item; |
| 67 | 69 | ||
| 68 | struct inode *r_inode; /* for use by callbacks */ | 70 | struct inode *r_inode; /* for use by callbacks */ |
| 69 | struct writeback_control *r_wbc; /* ditto */ | ||
| 70 | 71 | ||
| 71 | char r_oid[40]; /* object name */ | 72 | char r_oid[40]; /* object name */ |
| 72 | int r_oid_len; | 73 | int r_oid_len; |
diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 2e2c15eed82a..cfdd8f4388b7 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c | |||
| @@ -1041,12 +1041,33 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid, | |||
| 1041 | } | 1041 | } |
| 1042 | 1042 | ||
| 1043 | /* | 1043 | /* |
| 1044 | * Return acting set for given pgid. | ||
| 1045 | */ | ||
| 1046 | int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid, | ||
| 1047 | int *acting) | ||
| 1048 | { | ||
| 1049 | int rawosds[CEPH_PG_MAX_SIZE], *osds; | ||
| 1050 | int i, o, num = CEPH_PG_MAX_SIZE; | ||
| 1051 | |||
| 1052 | osds = calc_pg_raw(osdmap, pgid, rawosds, &num); | ||
| 1053 | if (!osds) | ||
| 1054 | return -1; | ||
| 1055 | |||
| 1056 | /* primary is first up osd */ | ||
| 1057 | o = 0; | ||
| 1058 | for (i = 0; i < num; i++) | ||
| 1059 | if (ceph_osd_is_up(osdmap, osds[i])) | ||
| 1060 | acting[o++] = osds[i]; | ||
| 1061 | return o; | ||
| 1062 | } | ||
| 1063 | |||
| 1064 | /* | ||
| 1044 | * Return primary osd for given pgid, or -1 if none. | 1065 | * Return primary osd for given pgid, or -1 if none. |
| 1045 | */ | 1066 | */ |
| 1046 | int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid) | 1067 | int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid) |
| 1047 | { | 1068 | { |
| 1048 | int rawosds[10], *osds; | 1069 | int rawosds[CEPH_PG_MAX_SIZE], *osds; |
| 1049 | int i, num = ARRAY_SIZE(rawosds); | 1070 | int i, num = CEPH_PG_MAX_SIZE; |
| 1050 | 1071 | ||
| 1051 | osds = calc_pg_raw(osdmap, pgid, rawosds, &num); | 1072 | osds = calc_pg_raw(osdmap, pgid, rawosds, &num); |
| 1052 | if (!osds) | 1073 | if (!osds) |
| @@ -1054,9 +1075,7 @@ int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid) | |||
| 1054 | 1075 | ||
| 1055 | /* primary is first up osd */ | 1076 | /* primary is first up osd */ |
| 1056 | for (i = 0; i < num; i++) | 1077 | for (i = 0; i < num; i++) |
| 1057 | if (ceph_osd_is_up(osdmap, osds[i])) { | 1078 | if (ceph_osd_is_up(osdmap, osds[i])) |
| 1058 | return osds[i]; | 1079 | return osds[i]; |
| 1059 | break; | ||
| 1060 | } | ||
| 1061 | return -1; | 1080 | return -1; |
| 1062 | } | 1081 | } |
diff --git a/fs/ceph/osdmap.h b/fs/ceph/osdmap.h index 8bc9f1e4f562..970b547e510d 100644 --- a/fs/ceph/osdmap.h +++ b/fs/ceph/osdmap.h | |||
| @@ -120,6 +120,8 @@ extern int ceph_calc_object_layout(struct ceph_object_layout *ol, | |||
| 120 | const char *oid, | 120 | const char *oid, |
| 121 | struct ceph_file_layout *fl, | 121 | struct ceph_file_layout *fl, |
| 122 | struct ceph_osdmap *osdmap); | 122 | struct ceph_osdmap *osdmap); |
| 123 | extern int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid, | ||
| 124 | int *acting); | ||
| 123 | extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, | 125 | extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, |
| 124 | struct ceph_pg pgid); | 126 | struct ceph_pg pgid); |
| 125 | 127 | ||
diff --git a/fs/ceph/rados.h b/fs/ceph/rados.h index a1fc1d017b58..fd56451a871f 100644 --- a/fs/ceph/rados.h +++ b/fs/ceph/rados.h | |||
| @@ -58,6 +58,7 @@ struct ceph_timespec { | |||
| 58 | #define CEPH_PG_LAYOUT_LINEAR 2 | 58 | #define CEPH_PG_LAYOUT_LINEAR 2 |
| 59 | #define CEPH_PG_LAYOUT_HYBRID 3 | 59 | #define CEPH_PG_LAYOUT_HYBRID 3 |
| 60 | 60 | ||
| 61 | #define CEPH_PG_MAX_SIZE 16 /* max # osds in a single pg */ | ||
| 61 | 62 | ||
| 62 | /* | 63 | /* |
| 63 | * placement group. | 64 | * placement group. |
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index f888cf487b7c..110857ba9269 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
| @@ -47,10 +47,20 @@ const char *ceph_file_part(const char *s, int len) | |||
| 47 | */ | 47 | */ |
| 48 | static void ceph_put_super(struct super_block *s) | 48 | static void ceph_put_super(struct super_block *s) |
| 49 | { | 49 | { |
| 50 | struct ceph_client *cl = ceph_client(s); | 50 | struct ceph_client *client = ceph_sb_to_client(s); |
| 51 | 51 | ||
| 52 | dout("put_super\n"); | 52 | dout("put_super\n"); |
| 53 | ceph_mdsc_close_sessions(&cl->mdsc); | 53 | ceph_mdsc_close_sessions(&client->mdsc); |
| 54 | |||
| 55 | /* | ||
| 56 | * ensure we release the bdi before put_anon_super releases | ||
| 57 | * the device name. | ||
| 58 | */ | ||
| 59 | if (s->s_bdi == &client->backing_dev_info) { | ||
| 60 | bdi_unregister(&client->backing_dev_info); | ||
| 61 | s->s_bdi = NULL; | ||
| 62 | } | ||
| 63 | |||
| 54 | return; | 64 | return; |
| 55 | } | 65 | } |
| 56 | 66 | ||
| @@ -636,6 +646,8 @@ static void ceph_destroy_client(struct ceph_client *client) | |||
| 636 | destroy_workqueue(client->pg_inv_wq); | 646 | destroy_workqueue(client->pg_inv_wq); |
| 637 | destroy_workqueue(client->trunc_wq); | 647 | destroy_workqueue(client->trunc_wq); |
| 638 | 648 | ||
| 649 | bdi_destroy(&client->backing_dev_info); | ||
| 650 | |||
| 639 | if (client->msgr) | 651 | if (client->msgr) |
| 640 | ceph_messenger_destroy(client->msgr); | 652 | ceph_messenger_destroy(client->msgr); |
| 641 | mempool_destroy(client->wb_pagevec_pool); | 653 | mempool_destroy(client->wb_pagevec_pool); |
| @@ -876,14 +888,14 @@ static int ceph_register_bdi(struct super_block *sb, struct ceph_client *client) | |||
| 876 | { | 888 | { |
| 877 | int err; | 889 | int err; |
| 878 | 890 | ||
| 879 | sb->s_bdi = &client->backing_dev_info; | ||
| 880 | |||
| 881 | /* set ra_pages based on rsize mount option? */ | 891 | /* set ra_pages based on rsize mount option? */ |
| 882 | if (client->mount_args->rsize >= PAGE_CACHE_SIZE) | 892 | if (client->mount_args->rsize >= PAGE_CACHE_SIZE) |
| 883 | client->backing_dev_info.ra_pages = | 893 | client->backing_dev_info.ra_pages = |
| 884 | (client->mount_args->rsize + PAGE_CACHE_SIZE - 1) | 894 | (client->mount_args->rsize + PAGE_CACHE_SIZE - 1) |
| 885 | >> PAGE_SHIFT; | 895 | >> PAGE_SHIFT; |
| 886 | err = bdi_register_dev(&client->backing_dev_info, sb->s_dev); | 896 | err = bdi_register_dev(&client->backing_dev_info, sb->s_dev); |
| 897 | if (!err) | ||
| 898 | sb->s_bdi = &client->backing_dev_info; | ||
| 887 | return err; | 899 | return err; |
| 888 | } | 900 | } |
| 889 | 901 | ||
| @@ -957,9 +969,6 @@ static void ceph_kill_sb(struct super_block *s) | |||
| 957 | dout("kill_sb %p\n", s); | 969 | dout("kill_sb %p\n", s); |
| 958 | ceph_mdsc_pre_umount(&client->mdsc); | 970 | ceph_mdsc_pre_umount(&client->mdsc); |
| 959 | kill_anon_super(s); /* will call put_super after sb is r/o */ | 971 | kill_anon_super(s); /* will call put_super after sb is r/o */ |
| 960 | if (s->s_bdi == &client->backing_dev_info) | ||
| 961 | bdi_unregister(&client->backing_dev_info); | ||
| 962 | bdi_destroy(&client->backing_dev_info); | ||
| 963 | ceph_destroy_client(client); | 972 | ceph_destroy_client(client); |
| 964 | } | 973 | } |
| 965 | 974 | ||
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index ecf0ffbe2b64..0c2fd17439c8 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -502,6 +502,7 @@ struct dfs_info3_param { | |||
| 502 | #define CIFS_FATTR_DFS_REFERRAL 0x1 | 502 | #define CIFS_FATTR_DFS_REFERRAL 0x1 |
| 503 | #define CIFS_FATTR_DELETE_PENDING 0x2 | 503 | #define CIFS_FATTR_DELETE_PENDING 0x2 |
| 504 | #define CIFS_FATTR_NEED_REVAL 0x4 | 504 | #define CIFS_FATTR_NEED_REVAL 0x4 |
| 505 | #define CIFS_FATTR_INO_COLLISION 0x8 | ||
| 505 | 506 | ||
| 506 | struct cifs_fattr { | 507 | struct cifs_fattr { |
| 507 | u32 cf_flags; | 508 | u32 cf_flags; |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 35ec11716213..29b9ea244c81 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -715,6 +715,16 @@ cifs_find_inode(struct inode *inode, void *opaque) | |||
| 715 | if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid) | 715 | if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid) |
| 716 | return 0; | 716 | return 0; |
| 717 | 717 | ||
| 718 | /* | ||
| 719 | * uh oh -- it's a directory. We can't use it since hardlinked dirs are | ||
| 720 | * verboten. Disable serverino and return it as if it were found, the | ||
| 721 | * caller can discard it, generate a uniqueid and retry the find | ||
| 722 | */ | ||
| 723 | if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry)) { | ||
| 724 | fattr->cf_flags |= CIFS_FATTR_INO_COLLISION; | ||
| 725 | cifs_autodisable_serverino(CIFS_SB(inode->i_sb)); | ||
| 726 | } | ||
| 727 | |||
| 718 | return 1; | 728 | return 1; |
| 719 | } | 729 | } |
| 720 | 730 | ||
| @@ -734,15 +744,22 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr) | |||
| 734 | unsigned long hash; | 744 | unsigned long hash; |
| 735 | struct inode *inode; | 745 | struct inode *inode; |
| 736 | 746 | ||
| 747 | retry_iget5_locked: | ||
| 737 | cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid)); | 748 | cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid)); |
| 738 | 749 | ||
| 739 | /* hash down to 32-bits on 32-bit arch */ | 750 | /* hash down to 32-bits on 32-bit arch */ |
| 740 | hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid); | 751 | hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid); |
| 741 | 752 | ||
| 742 | inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr); | 753 | inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr); |
| 743 | |||
| 744 | /* we have fattrs in hand, update the inode */ | ||
| 745 | if (inode) { | 754 | if (inode) { |
| 755 | /* was there a problematic inode number collision? */ | ||
| 756 | if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) { | ||
| 757 | iput(inode); | ||
| 758 | fattr->cf_uniqueid = iunique(sb, ROOT_I); | ||
| 759 | fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION; | ||
| 760 | goto retry_iget5_locked; | ||
| 761 | } | ||
| 762 | |||
| 746 | cifs_fattr_to_inode(inode, fattr); | 763 | cifs_fattr_to_inode(inode, fattr); |
| 747 | if (sb->s_flags & MS_NOATIME) | 764 | if (sb->s_flags & MS_NOATIME) |
| 748 | inode->i_flags |= S_NOATIME | S_NOCMTIME; | 765 | inode->i_flags |= S_NOATIME | S_NOCMTIME; |
diff --git a/fs/namei.c b/fs/namei.c index a7dce91a7e42..16df7277a92e 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -1641,7 +1641,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
| 1641 | if (nd->last.name[nd->last.len]) { | 1641 | if (nd->last.name[nd->last.len]) { |
| 1642 | if (open_flag & O_CREAT) | 1642 | if (open_flag & O_CREAT) |
| 1643 | goto exit; | 1643 | goto exit; |
| 1644 | nd->flags |= LOOKUP_DIRECTORY; | 1644 | nd->flags |= LOOKUP_DIRECTORY | LOOKUP_FOLLOW; |
| 1645 | } | 1645 | } |
| 1646 | 1646 | ||
| 1647 | /* just plain open? */ | 1647 | /* just plain open? */ |
| @@ -1830,6 +1830,8 @@ reval: | |||
| 1830 | } | 1830 | } |
| 1831 | if (open_flag & O_DIRECTORY) | 1831 | if (open_flag & O_DIRECTORY) |
| 1832 | nd.flags |= LOOKUP_DIRECTORY; | 1832 | nd.flags |= LOOKUP_DIRECTORY; |
| 1833 | if (!(open_flag & O_NOFOLLOW)) | ||
| 1834 | nd.flags |= LOOKUP_FOLLOW; | ||
| 1833 | filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); | 1835 | filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); |
| 1834 | while (unlikely(!filp)) { /* trailing symlink */ | 1836 | while (unlikely(!filp)) { /* trailing symlink */ |
| 1835 | struct path holder; | 1837 | struct path holder; |
| @@ -1837,7 +1839,7 @@ reval: | |||
| 1837 | void *cookie; | 1839 | void *cookie; |
| 1838 | error = -ELOOP; | 1840 | error = -ELOOP; |
| 1839 | /* S_ISDIR part is a temporary automount kludge */ | 1841 | /* S_ISDIR part is a temporary automount kludge */ |
| 1840 | if ((open_flag & O_NOFOLLOW) && !S_ISDIR(inode->i_mode)) | 1842 | if (!(nd.flags & LOOKUP_FOLLOW) && !S_ISDIR(inode->i_mode)) |
| 1841 | goto exit_dput; | 1843 | goto exit_dput; |
| 1842 | if (count++ == 32) | 1844 | if (count++ == 32) |
| 1843 | goto exit_dput; | 1845 | goto exit_dput; |
diff --git a/lib/rwsem.c b/lib/rwsem.c index 3e3365e5665e..ceba8e28807a 100644 --- a/lib/rwsem.c +++ b/lib/rwsem.c | |||
| @@ -136,9 +136,10 @@ __rwsem_do_wake(struct rw_semaphore *sem, int downgrading) | |||
| 136 | out: | 136 | out: |
| 137 | return sem; | 137 | return sem; |
| 138 | 138 | ||
| 139 | /* undo the change to count, but check for a transition 1->0 */ | 139 | /* undo the change to the active count, but check for a transition |
| 140 | * 1->0 */ | ||
| 140 | undo: | 141 | undo: |
| 141 | if (rwsem_atomic_update(-RWSEM_ACTIVE_BIAS, sem) != 0) | 142 | if (rwsem_atomic_update(-RWSEM_ACTIVE_BIAS, sem) & RWSEM_ACTIVE_MASK) |
| 142 | goto out; | 143 | goto out; |
| 143 | goto try_again; | 144 | goto try_again; |
| 144 | } | 145 | } |
diff --git a/security/min_addr.c b/security/min_addr.c index e86f297522bf..f728728f193b 100644 --- a/security/min_addr.c +++ b/security/min_addr.c | |||
| @@ -33,7 +33,7 @@ int mmap_min_addr_handler(struct ctl_table *table, int write, | |||
| 33 | { | 33 | { |
| 34 | int ret; | 34 | int ret; |
| 35 | 35 | ||
| 36 | if (!capable(CAP_SYS_RAWIO)) | 36 | if (write && !capable(CAP_SYS_RAWIO)) |
| 37 | return -EPERM; | 37 | return -EPERM; |
| 38 | 38 | ||
| 39 | ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); | 39 | ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 872887624030..20b5982c996b 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
| @@ -36,6 +36,9 @@ | |||
| 36 | #include <sound/timer.h> | 36 | #include <sound/timer.h> |
| 37 | #include <sound/minors.h> | 37 | #include <sound/minors.h> |
| 38 | #include <asm/io.h> | 38 | #include <asm/io.h> |
| 39 | #if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT) | ||
| 40 | #include <dma-coherence.h> | ||
| 41 | #endif | ||
| 39 | 42 | ||
| 40 | /* | 43 | /* |
| 41 | * Compatibility | 44 | * Compatibility |
| @@ -3184,6 +3187,10 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, | |||
| 3184 | substream->runtime->dma_area, | 3187 | substream->runtime->dma_area, |
| 3185 | substream->runtime->dma_addr, | 3188 | substream->runtime->dma_addr, |
| 3186 | area->vm_end - area->vm_start); | 3189 | area->vm_end - area->vm_start); |
| 3190 | #elif defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT) | ||
| 3191 | if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV && | ||
| 3192 | !plat_device_is_coherent(substream->dma_buffer.dev.dev)) | ||
| 3193 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); | ||
| 3187 | #endif /* ARCH_HAS_DMA_MMAP_COHERENT */ | 3194 | #endif /* ARCH_HAS_DMA_MMAP_COHERENT */ |
| 3188 | /* mmap with fault handler */ | 3195 | /* mmap with fault handler */ |
| 3189 | area->vm_ops = &snd_pcm_vm_ops_data_fault; | 3196 | area->vm_ops = &snd_pcm_vm_ops_data_fault; |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index d8213e2231a6..feabb44c7ca4 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
| @@ -1197,9 +1197,10 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
| 1197 | case 0x103c: | 1197 | case 0x103c: |
| 1198 | case 0x1631: | 1198 | case 0x1631: |
| 1199 | case 0x1734: | 1199 | case 0x1734: |
| 1200 | /* HP, Packard Bell, & Fujitsu-Siemens laptops have really bad | 1200 | case 0x17aa: |
| 1201 | * sound over 0dB on NID 0x17. Fix max PCM level to 0 dB | 1201 | /* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have |
| 1202 | * (originally it has 0x2b steps with 0dB offset 0x14) | 1202 | * really bad sound over 0dB on NID 0x17. Fix max PCM level to |
| 1203 | * 0 dB (originally it has 0x2b steps with 0dB offset 0x14) | ||
| 1203 | */ | 1204 | */ |
| 1204 | snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, | 1205 | snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, |
| 1205 | (0x14 << AC_AMPCAP_OFFSET_SHIFT) | | 1206 | (0x14 << AC_AMPCAP_OFFSET_SHIFT) | |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 12825aa03106..a0e06d82da1f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
| @@ -104,6 +104,7 @@ enum { | |||
| 104 | STAC_DELL_M4_2, | 104 | STAC_DELL_M4_2, |
| 105 | STAC_DELL_M4_3, | 105 | STAC_DELL_M4_3, |
| 106 | STAC_HP_M4, | 106 | STAC_HP_M4, |
| 107 | STAC_HP_DV4, | ||
| 107 | STAC_HP_DV5, | 108 | STAC_HP_DV5, |
| 108 | STAC_HP_HDX, | 109 | STAC_HP_HDX, |
| 109 | STAC_HP_DV4_1222NR, | 110 | STAC_HP_DV4_1222NR, |
| @@ -1691,6 +1692,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | |||
| 1691 | [STAC_DELL_M4_2] = dell_m4_2_pin_configs, | 1692 | [STAC_DELL_M4_2] = dell_m4_2_pin_configs, |
| 1692 | [STAC_DELL_M4_3] = dell_m4_3_pin_configs, | 1693 | [STAC_DELL_M4_3] = dell_m4_3_pin_configs, |
| 1693 | [STAC_HP_M4] = NULL, | 1694 | [STAC_HP_M4] = NULL, |
| 1695 | [STAC_HP_DV4] = NULL, | ||
| 1694 | [STAC_HP_DV5] = NULL, | 1696 | [STAC_HP_DV5] = NULL, |
| 1695 | [STAC_HP_HDX] = NULL, | 1697 | [STAC_HP_HDX] = NULL, |
| 1696 | [STAC_HP_DV4_1222NR] = NULL, | 1698 | [STAC_HP_DV4_1222NR] = NULL, |
| @@ -1703,6 +1705,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | |||
| 1703 | [STAC_DELL_M4_2] = "dell-m4-2", | 1705 | [STAC_DELL_M4_2] = "dell-m4-2", |
| 1704 | [STAC_DELL_M4_3] = "dell-m4-3", | 1706 | [STAC_DELL_M4_3] = "dell-m4-3", |
| 1705 | [STAC_HP_M4] = "hp-m4", | 1707 | [STAC_HP_M4] = "hp-m4", |
| 1708 | [STAC_HP_DV4] = "hp-dv4", | ||
| 1706 | [STAC_HP_DV5] = "hp-dv5", | 1709 | [STAC_HP_DV5] = "hp-dv5", |
| 1707 | [STAC_HP_HDX] = "hp-hdx", | 1710 | [STAC_HP_HDX] = "hp-hdx", |
| 1708 | [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", | 1711 | [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", |
| @@ -1721,7 +1724,7 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | |||
| 1721 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, | 1724 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, |
| 1722 | "HP", STAC_HP_DV5), | 1725 | "HP", STAC_HP_DV5), |
| 1723 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, | 1726 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, |
| 1724 | "HP dv4-7", STAC_HP_DV5), | 1727 | "HP dv4-7", STAC_HP_DV4), |
| 1725 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600, | 1728 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600, |
| 1726 | "HP dv4-7", STAC_HP_DV5), | 1729 | "HP dv4-7", STAC_HP_DV5), |
| 1727 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610, | 1730 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610, |
| @@ -4766,6 +4769,9 @@ static void set_hp_led_gpio(struct hda_codec *codec) | |||
| 4766 | struct sigmatel_spec *spec = codec->spec; | 4769 | struct sigmatel_spec *spec = codec->spec; |
| 4767 | unsigned int gpio; | 4770 | unsigned int gpio; |
| 4768 | 4771 | ||
| 4772 | if (spec->gpio_led) | ||
| 4773 | return; | ||
| 4774 | |||
| 4769 | gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP); | 4775 | gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP); |
| 4770 | gpio &= AC_GPIO_IO_COUNT; | 4776 | gpio &= AC_GPIO_IO_COUNT; |
| 4771 | if (gpio > 3) | 4777 | if (gpio > 3) |
| @@ -5675,6 +5681,9 @@ again: | |||
| 5675 | spec->num_smuxes = 1; | 5681 | spec->num_smuxes = 1; |
| 5676 | spec->num_dmuxes = 1; | 5682 | spec->num_dmuxes = 1; |
| 5677 | /* fallthrough */ | 5683 | /* fallthrough */ |
| 5684 | case STAC_HP_DV4: | ||
| 5685 | spec->gpio_led = 0x01; | ||
| 5686 | /* fallthrough */ | ||
| 5678 | case STAC_HP_DV5: | 5687 | case STAC_HP_DV5: |
| 5679 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); | 5688 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); |
| 5680 | stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); | 5689 | stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); |
| @@ -5688,6 +5697,7 @@ again: | |||
| 5688 | spec->num_dmics = 1; | 5697 | spec->num_dmics = 1; |
| 5689 | spec->num_dmuxes = 1; | 5698 | spec->num_dmuxes = 1; |
| 5690 | spec->num_smuxes = 1; | 5699 | spec->num_smuxes = 1; |
| 5700 | spec->gpio_led = 0x08; | ||
| 5691 | break; | 5701 | break; |
| 5692 | } | 5702 | } |
| 5693 | 5703 | ||
| @@ -5744,7 +5754,8 @@ again: | |||
| 5744 | } | 5754 | } |
| 5745 | 5755 | ||
| 5746 | /* enable bass on HP dv7 */ | 5756 | /* enable bass on HP dv7 */ |
| 5747 | if (spec->board_config == STAC_HP_DV5) { | 5757 | if (spec->board_config == STAC_HP_DV4 || |
| 5758 | spec->board_config == STAC_HP_DV5) { | ||
| 5748 | unsigned int cap; | 5759 | unsigned int cap; |
| 5749 | cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP); | 5760 | cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP); |
| 5750 | cap &= AC_GPIO_IO_COUNT; | 5761 | cap &= AC_GPIO_IO_COUNT; |
diff --git a/sound/pci/ice1712/maya44.c b/sound/pci/ice1712/maya44.c index 3e1c20ae2f1c..726fd4b92e19 100644 --- a/sound/pci/ice1712/maya44.c +++ b/sound/pci/ice1712/maya44.c | |||
| @@ -347,7 +347,7 @@ static int maya_gpio_sw_put(struct snd_kcontrol *kcontrol, | |||
| 347 | 347 | ||
| 348 | /* known working input slots (0-4) */ | 348 | /* known working input slots (0-4) */ |
| 349 | #define MAYA_LINE_IN 1 /* in-2 */ | 349 | #define MAYA_LINE_IN 1 /* in-2 */ |
| 350 | #define MAYA_MIC_IN 4 /* in-5 */ | 350 | #define MAYA_MIC_IN 3 /* in-4 */ |
| 351 | 351 | ||
| 352 | static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line) | 352 | static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line) |
| 353 | { | 353 | { |
| @@ -393,8 +393,8 @@ static int maya_rec_src_put(struct snd_kcontrol *kcontrol, | |||
| 393 | int changed; | 393 | int changed; |
| 394 | 394 | ||
| 395 | mutex_lock(&chip->mutex); | 395 | mutex_lock(&chip->mutex); |
| 396 | changed = maya_set_gpio_bits(chip->ice, GPIO_MIC_RELAY, | 396 | changed = maya_set_gpio_bits(chip->ice, 1 << GPIO_MIC_RELAY, |
| 397 | sel ? GPIO_MIC_RELAY : 0); | 397 | sel ? (1 << GPIO_MIC_RELAY) : 0); |
| 398 | wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN); | 398 | wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN); |
| 399 | mutex_unlock(&chip->mutex); | 399 | mutex_unlock(&chip->mutex); |
| 400 | return changed; | 400 | return changed; |
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index 16c226bfcd2b..7c4986b27f2b 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c | |||
| @@ -56,6 +56,7 @@ | |||
| 56 | #include <sound/pcm_params.h> | 56 | #include <sound/pcm_params.h> |
| 57 | #include <sound/tlv.h> | 57 | #include <sound/tlv.h> |
| 58 | #include "xonar.h" | 58 | #include "xonar.h" |
| 59 | #include "cm9780.h" | ||
| 59 | #include "cs4398.h" | 60 | #include "cs4398.h" |
| 60 | #include "cs4362a.h" | 61 | #include "cs4362a.h" |
| 61 | 62 | ||
| @@ -172,6 +173,8 @@ static void xonar_d1_init(struct oxygen *chip) | |||
| 172 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, | 173 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, |
| 173 | GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); | 174 | GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); |
| 174 | 175 | ||
| 176 | oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC); | ||
| 177 | |||
| 175 | xonar_init_cs53x1(chip); | 178 | xonar_init_cs53x1(chip); |
| 176 | xonar_enable_output(chip); | 179 | xonar_enable_output(chip); |
| 177 | 180 | ||
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 03a5eb22da2b..7c79c1d76d0c 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
| @@ -197,7 +197,7 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) | |||
| 197 | union kvm_ioapic_redirect_entry entry; | 197 | union kvm_ioapic_redirect_entry entry; |
| 198 | int ret = 1; | 198 | int ret = 1; |
| 199 | 199 | ||
| 200 | mutex_lock(&ioapic->lock); | 200 | spin_lock(&ioapic->lock); |
| 201 | if (irq >= 0 && irq < IOAPIC_NUM_PINS) { | 201 | if (irq >= 0 && irq < IOAPIC_NUM_PINS) { |
| 202 | entry = ioapic->redirtbl[irq]; | 202 | entry = ioapic->redirtbl[irq]; |
| 203 | level ^= entry.fields.polarity; | 203 | level ^= entry.fields.polarity; |
| @@ -214,7 +214,7 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) | |||
| 214 | } | 214 | } |
| 215 | trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0); | 215 | trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0); |
| 216 | } | 216 | } |
| 217 | mutex_unlock(&ioapic->lock); | 217 | spin_unlock(&ioapic->lock); |
| 218 | 218 | ||
| 219 | return ret; | 219 | return ret; |
| 220 | } | 220 | } |
| @@ -238,9 +238,9 @@ static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int vector, | |||
| 238 | * is dropped it will be put into irr and will be delivered | 238 | * is dropped it will be put into irr and will be delivered |
| 239 | * after ack notifier returns. | 239 | * after ack notifier returns. |
| 240 | */ | 240 | */ |
| 241 | mutex_unlock(&ioapic->lock); | 241 | spin_unlock(&ioapic->lock); |
| 242 | kvm_notify_acked_irq(ioapic->kvm, KVM_IRQCHIP_IOAPIC, i); | 242 | kvm_notify_acked_irq(ioapic->kvm, KVM_IRQCHIP_IOAPIC, i); |
| 243 | mutex_lock(&ioapic->lock); | 243 | spin_lock(&ioapic->lock); |
| 244 | 244 | ||
| 245 | if (trigger_mode != IOAPIC_LEVEL_TRIG) | 245 | if (trigger_mode != IOAPIC_LEVEL_TRIG) |
| 246 | continue; | 246 | continue; |
| @@ -259,9 +259,9 @@ void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode) | |||
| 259 | smp_rmb(); | 259 | smp_rmb(); |
| 260 | if (!test_bit(vector, ioapic->handled_vectors)) | 260 | if (!test_bit(vector, ioapic->handled_vectors)) |
| 261 | return; | 261 | return; |
| 262 | mutex_lock(&ioapic->lock); | 262 | spin_lock(&ioapic->lock); |
| 263 | __kvm_ioapic_update_eoi(ioapic, vector, trigger_mode); | 263 | __kvm_ioapic_update_eoi(ioapic, vector, trigger_mode); |
| 264 | mutex_unlock(&ioapic->lock); | 264 | spin_unlock(&ioapic->lock); |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | static inline struct kvm_ioapic *to_ioapic(struct kvm_io_device *dev) | 267 | static inline struct kvm_ioapic *to_ioapic(struct kvm_io_device *dev) |
| @@ -287,7 +287,7 @@ static int ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len, | |||
| 287 | ASSERT(!(addr & 0xf)); /* check alignment */ | 287 | ASSERT(!(addr & 0xf)); /* check alignment */ |
| 288 | 288 | ||
| 289 | addr &= 0xff; | 289 | addr &= 0xff; |
| 290 | mutex_lock(&ioapic->lock); | 290 | spin_lock(&ioapic->lock); |
| 291 | switch (addr) { | 291 | switch (addr) { |
| 292 | case IOAPIC_REG_SELECT: | 292 | case IOAPIC_REG_SELECT: |
| 293 | result = ioapic->ioregsel; | 293 | result = ioapic->ioregsel; |
| @@ -301,7 +301,7 @@ static int ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len, | |||
| 301 | result = 0; | 301 | result = 0; |
| 302 | break; | 302 | break; |
| 303 | } | 303 | } |
| 304 | mutex_unlock(&ioapic->lock); | 304 | spin_unlock(&ioapic->lock); |
| 305 | 305 | ||
| 306 | switch (len) { | 306 | switch (len) { |
| 307 | case 8: | 307 | case 8: |
| @@ -338,7 +338,7 @@ static int ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len, | |||
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | addr &= 0xff; | 340 | addr &= 0xff; |
| 341 | mutex_lock(&ioapic->lock); | 341 | spin_lock(&ioapic->lock); |
| 342 | switch (addr) { | 342 | switch (addr) { |
| 343 | case IOAPIC_REG_SELECT: | 343 | case IOAPIC_REG_SELECT: |
| 344 | ioapic->ioregsel = data; | 344 | ioapic->ioregsel = data; |
| @@ -356,7 +356,7 @@ static int ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len, | |||
| 356 | default: | 356 | default: |
| 357 | break; | 357 | break; |
| 358 | } | 358 | } |
| 359 | mutex_unlock(&ioapic->lock); | 359 | spin_unlock(&ioapic->lock); |
| 360 | return 0; | 360 | return 0; |
| 361 | } | 361 | } |
| 362 | 362 | ||
| @@ -386,7 +386,7 @@ int kvm_ioapic_init(struct kvm *kvm) | |||
| 386 | ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL); | 386 | ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL); |
| 387 | if (!ioapic) | 387 | if (!ioapic) |
| 388 | return -ENOMEM; | 388 | return -ENOMEM; |
| 389 | mutex_init(&ioapic->lock); | 389 | spin_lock_init(&ioapic->lock); |
| 390 | kvm->arch.vioapic = ioapic; | 390 | kvm->arch.vioapic = ioapic; |
| 391 | kvm_ioapic_reset(ioapic); | 391 | kvm_ioapic_reset(ioapic); |
| 392 | kvm_iodevice_init(&ioapic->dev, &ioapic_mmio_ops); | 392 | kvm_iodevice_init(&ioapic->dev, &ioapic_mmio_ops); |
| @@ -419,9 +419,9 @@ int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) | |||
| 419 | if (!ioapic) | 419 | if (!ioapic) |
| 420 | return -EINVAL; | 420 | return -EINVAL; |
| 421 | 421 | ||
| 422 | mutex_lock(&ioapic->lock); | 422 | spin_lock(&ioapic->lock); |
| 423 | memcpy(state, ioapic, sizeof(struct kvm_ioapic_state)); | 423 | memcpy(state, ioapic, sizeof(struct kvm_ioapic_state)); |
| 424 | mutex_unlock(&ioapic->lock); | 424 | spin_unlock(&ioapic->lock); |
| 425 | return 0; | 425 | return 0; |
| 426 | } | 426 | } |
| 427 | 427 | ||
| @@ -431,9 +431,9 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state) | |||
| 431 | if (!ioapic) | 431 | if (!ioapic) |
| 432 | return -EINVAL; | 432 | return -EINVAL; |
| 433 | 433 | ||
| 434 | mutex_lock(&ioapic->lock); | 434 | spin_lock(&ioapic->lock); |
| 435 | memcpy(ioapic, state, sizeof(struct kvm_ioapic_state)); | 435 | memcpy(ioapic, state, sizeof(struct kvm_ioapic_state)); |
| 436 | update_handled_vectors(ioapic); | 436 | update_handled_vectors(ioapic); |
| 437 | mutex_unlock(&ioapic->lock); | 437 | spin_unlock(&ioapic->lock); |
| 438 | return 0; | 438 | return 0; |
| 439 | } | 439 | } |
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h index 8a751b78a430..0b190c34ccc3 100644 --- a/virt/kvm/ioapic.h +++ b/virt/kvm/ioapic.h | |||
| @@ -45,7 +45,7 @@ struct kvm_ioapic { | |||
| 45 | struct kvm_io_device dev; | 45 | struct kvm_io_device dev; |
| 46 | struct kvm *kvm; | 46 | struct kvm *kvm; |
| 47 | void (*ack_notifier)(void *opaque, int irq); | 47 | void (*ack_notifier)(void *opaque, int irq); |
| 48 | struct mutex lock; | 48 | spinlock_t lock; |
| 49 | DECLARE_BITMAP(handled_vectors, 256); | 49 | DECLARE_BITMAP(handled_vectors, 256); |
| 50 | }; | 50 | }; |
| 51 | 51 | ||
