diff options
Diffstat (limited to 'arch/x86')
65 files changed, 656 insertions, 325 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ddb52b8d38a7..b6cc9c9dc919 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -124,10 +124,18 @@ config ARCH_MAY_HAVE_PC_FDC | |||
| 124 | def_bool y | 124 | def_bool y |
| 125 | 125 | ||
| 126 | config RWSEM_GENERIC_SPINLOCK | 126 | config RWSEM_GENERIC_SPINLOCK |
| 127 | def_bool !X86_XADD | 127 | bool |
| 128 | depends on !X86_XADD || PREEMPT_RT | ||
| 129 | default y | ||
| 130 | |||
| 131 | config ASM_SEMAPHORES | ||
| 132 | bool | ||
| 133 | default y | ||
| 128 | 134 | ||
| 129 | config RWSEM_XCHGADD_ALGORITHM | 135 | config RWSEM_XCHGADD_ALGORITHM |
| 130 | def_bool X86_XADD | 136 | bool |
| 137 | depends on X86_XADD && !RWSEM_GENERIC_SPINLOCK && !PREEMPT_RT | ||
| 138 | default y | ||
| 131 | 139 | ||
| 132 | config ARCH_HAS_CPU_IDLE_WAIT | 140 | config ARCH_HAS_CPU_IDLE_WAIT |
| 133 | def_bool y | 141 | def_bool y |
| @@ -281,6 +289,7 @@ config X86_X2APIC | |||
| 281 | config SPARSE_IRQ | 289 | config SPARSE_IRQ |
| 282 | bool "Support sparse irq numbering" | 290 | bool "Support sparse irq numbering" |
| 283 | depends on PCI_MSI || HT_IRQ | 291 | depends on PCI_MSI || HT_IRQ |
| 292 | depends on !PREEMPT_RT | ||
| 284 | ---help--- | 293 | ---help--- |
| 285 | This enables support for sparse irqs. This is useful for distro | 294 | This enables support for sparse irqs. This is useful for distro |
| 286 | kernels that want to define a high CONFIG_NR_CPUS value but still | 295 | kernels that want to define a high CONFIG_NR_CPUS value but still |
| @@ -712,7 +721,7 @@ config IOMMU_API | |||
| 712 | 721 | ||
| 713 | config MAXSMP | 722 | config MAXSMP |
| 714 | bool "Configure Maximum number of SMP Processors and NUMA Nodes" | 723 | bool "Configure Maximum number of SMP Processors and NUMA Nodes" |
| 715 | depends on X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL | 724 | depends on 0 && X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL |
| 716 | select CPUMASK_OFFSTACK | 725 | select CPUMASK_OFFSTACK |
| 717 | default n | 726 | default n |
| 718 | ---help--- | 727 | ---help--- |
| @@ -1898,7 +1907,7 @@ config PCI_MMCONFIG | |||
| 1898 | 1907 | ||
| 1899 | config DMAR | 1908 | config DMAR |
| 1900 | bool "Support for DMA Remapping Devices (EXPERIMENTAL)" | 1909 | bool "Support for DMA Remapping Devices (EXPERIMENTAL)" |
| 1901 | depends on PCI_MSI && ACPI && EXPERIMENTAL | 1910 | depends on PCI_MSI && ACPI && EXPERIMENTAL && !PREEMPT_RT |
| 1902 | help | 1911 | help |
| 1903 | DMA remapping (DMAR) devices support enables independent address | 1912 | DMA remapping (DMAR) devices support enables independent address |
| 1904 | translations for Direct Memory Access (DMA) from devices. | 1913 | translations for Direct Memory Access (DMA) from devices. |
| @@ -1941,6 +1950,7 @@ config DMAR_FLOPPY_WA | |||
| 1941 | config INTR_REMAP | 1950 | config INTR_REMAP |
| 1942 | bool "Support for Interrupt Remapping (EXPERIMENTAL)" | 1951 | bool "Support for Interrupt Remapping (EXPERIMENTAL)" |
| 1943 | depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL | 1952 | depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL |
| 1953 | depends on !PREEMPT_RT | ||
| 1944 | ---help--- | 1954 | ---help--- |
| 1945 | Supports Interrupt remapping for IO-APIC and MSI devices. | 1955 | Supports Interrupt remapping for IO-APIC and MSI devices. |
| 1946 | To use x2apic mode in the CPU's which support x2APIC enhancements or | 1956 | To use x2apic mode in the CPU's which support x2APIC enhancements or |
| @@ -2071,7 +2081,7 @@ endmenu | |||
| 2071 | 2081 | ||
| 2072 | config HAVE_ATOMIC_IOMAP | 2082 | config HAVE_ATOMIC_IOMAP |
| 2073 | def_bool y | 2083 | def_bool y |
| 2074 | depends on X86_32 | 2084 | depends on X86_32 && (!PREEMPT_RT || HIGHMEM) |
| 2075 | 2085 | ||
| 2076 | source "net/Kconfig" | 2086 | source "net/Kconfig" |
| 2077 | 2087 | ||
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index bc01e3ebfeb2..93dc8cc1e91f 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug | |||
| @@ -76,6 +76,7 @@ config DEBUG_PER_CPU_MAPS | |||
| 76 | bool "Debug access to per_cpu maps" | 76 | bool "Debug access to per_cpu maps" |
| 77 | depends on DEBUG_KERNEL | 77 | depends on DEBUG_KERNEL |
| 78 | depends on SMP | 78 | depends on SMP |
| 79 | depends on !PREEMPT_RT | ||
| 79 | default n | 80 | default n |
| 80 | ---help--- | 81 | ---help--- |
| 81 | Say Y to verify that the per_cpu map being accessed has | 82 | Say Y to verify that the per_cpu map being accessed has |
| @@ -126,6 +127,7 @@ config DEBUG_NX_TEST | |||
| 126 | config 4KSTACKS | 127 | config 4KSTACKS |
| 127 | bool "Use 4Kb for kernel stacks instead of 8Kb" | 128 | bool "Use 4Kb for kernel stacks instead of 8Kb" |
| 128 | depends on X86_32 | 129 | depends on X86_32 |
| 130 | default y | ||
| 129 | ---help--- | 131 | ---help--- |
| 130 | If you say Y here the kernel will use a 4Kb stacksize for the | 132 | If you say Y here the kernel will use a 4Kb stacksize for the |
| 131 | kernel stack attached to each process/thread. This facilitates | 133 | kernel stack attached to each process/thread. This facilitates |
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 56f462cf22d2..ead7e0b3522d 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h | |||
| @@ -50,8 +50,8 @@ | |||
| 50 | 50 | ||
| 51 | #define ACPI_ASM_MACROS | 51 | #define ACPI_ASM_MACROS |
| 52 | #define BREAKPOINT3 | 52 | #define BREAKPOINT3 |
| 53 | #define ACPI_DISABLE_IRQS() local_irq_disable() | 53 | #define ACPI_DISABLE_IRQS() local_irq_disable_nort() |
| 54 | #define ACPI_ENABLE_IRQS() local_irq_enable() | 54 | #define ACPI_ENABLE_IRQS() local_irq_enable_nort() |
| 55 | #define ACPI_FLUSH_CPU_CACHE() wbinvd() | 55 | #define ACPI_FLUSH_CPU_CACHE() wbinvd() |
| 56 | 56 | ||
| 57 | int __acpi_acquire_global_lock(unsigned int *lock); | 57 | int __acpi_acquire_global_lock(unsigned int *lock); |
diff --git a/arch/x86/include/asm/atomic_32.h b/arch/x86/include/asm/atomic_32.h index dc5a667ff791..166704f52c84 100644 --- a/arch/x86/include/asm/atomic_32.h +++ b/arch/x86/include/asm/atomic_32.h | |||
| @@ -186,10 +186,10 @@ static inline int atomic_add_return(int i, atomic_t *v) | |||
| 186 | 186 | ||
| 187 | #ifdef CONFIG_M386 | 187 | #ifdef CONFIG_M386 |
| 188 | no_xadd: /* Legacy 386 processor */ | 188 | no_xadd: /* Legacy 386 processor */ |
| 189 | local_irq_save(flags); | 189 | raw_local_irq_save(flags); |
| 190 | __i = atomic_read(v); | 190 | __i = atomic_read(v); |
| 191 | atomic_set(v, i + __i); | 191 | atomic_set(v, i + __i); |
| 192 | local_irq_restore(flags); | 192 | raw_local_irq_restore(flags); |
| 193 | return i + __i; | 193 | return i + __i; |
| 194 | #endif | 194 | #endif |
| 195 | } | 195 | } |
diff --git a/arch/x86/include/asm/highmem.h b/arch/x86/include/asm/highmem.h index 014c2b85ae45..c21ba64f2fa0 100644 --- a/arch/x86/include/asm/highmem.h +++ b/arch/x86/include/asm/highmem.h | |||
| @@ -55,19 +55,26 @@ extern unsigned long highstart_pfn, highend_pfn; | |||
| 55 | #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) | 55 | #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) |
| 56 | 56 | ||
| 57 | extern void *kmap_high(struct page *page); | 57 | extern void *kmap_high(struct page *page); |
| 58 | extern void *kmap_pfn_prot(unsigned long pfn, pgprot_t prot); | ||
| 58 | extern void kunmap_high(struct page *page); | 59 | extern void kunmap_high(struct page *page); |
| 59 | 60 | ||
| 60 | void *kmap(struct page *page); | 61 | void *kmap(struct page *page); |
| 62 | void *kmap_page_prot(struct page *page, pgprot_t prot); | ||
| 63 | extern void kunmap_virt(void *ptr); | ||
| 64 | extern struct page *kmap_to_page(void *ptr); | ||
| 61 | void kunmap(struct page *page); | 65 | void kunmap(struct page *page); |
| 62 | void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot); | 66 | |
| 63 | void *kmap_atomic(struct page *page, enum km_type type); | 67 | void *__kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot); |
| 64 | void kunmap_atomic(void *kvaddr, enum km_type type); | 68 | void *__kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); |
| 65 | void *kmap_atomic_pfn(unsigned long pfn, enum km_type type); | 69 | void *__kmap_atomic(struct page *page, enum km_type type); |
| 66 | void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot); | 70 | void *__kmap_atomic_direct(struct page *page, enum km_type type); |
| 67 | struct page *kmap_atomic_to_page(void *ptr); | 71 | void __kunmap_atomic(void *kvaddr, enum km_type type); |
| 72 | void *__kmap_atomic_pfn(unsigned long pfn, enum km_type type); | ||
| 73 | struct page *__kmap_atomic_to_page(void *ptr); | ||
| 68 | 74 | ||
| 69 | #ifndef CONFIG_PARAVIRT | 75 | #ifndef CONFIG_PARAVIRT |
| 70 | #define kmap_atomic_pte(page, type) kmap_atomic(page, type) | 76 | #define kmap_atomic_pte(page, type) kmap_atomic(page, type) |
| 77 | #define kmap_atomic_pte_direct(page, type) kmap_atomic_direct(page, type) | ||
| 71 | #endif | 78 | #endif |
| 72 | 79 | ||
| 73 | #define flush_cache_kmaps() do { } while (0) | 80 | #define flush_cache_kmaps() do { } while (0) |
| @@ -75,6 +82,29 @@ struct page *kmap_atomic_to_page(void *ptr); | |||
| 75 | extern void add_highpages_with_active_regions(int nid, unsigned long start_pfn, | 82 | extern void add_highpages_with_active_regions(int nid, unsigned long start_pfn, |
| 76 | unsigned long end_pfn); | 83 | unsigned long end_pfn); |
| 77 | 84 | ||
| 85 | /* | ||
| 86 | * on PREEMPT_RT kmap_atomic() is a wrapper that uses kmap(): | ||
| 87 | */ | ||
| 88 | #ifdef CONFIG_PREEMPT_RT | ||
| 89 | # define kmap_atomic_prot(page, type, prot) ({ pagefault_disable(); kmap_pfn_prot(page_to_pfn(page), prot); }) | ||
| 90 | # define kmap_atomic_prot_pfn(pfn, type, prot) ({ pagefault_disable(); kmap_pfn_prot(pfn, prot); }) | ||
| 91 | # define kmap_atomic(page, type) ({ pagefault_disable(); kmap(page); }) | ||
| 92 | # define kmap_atomic_pfn(pfn, type) kmap(pfn_to_page(pfn)) | ||
| 93 | # define kunmap_atomic(kvaddr, type) do { kunmap_virt(kvaddr); pagefault_enable(); } while(0) | ||
| 94 | # define kmap_atomic_to_page(kvaddr) kmap_to_page(kvaddr) | ||
| 95 | # define kmap_atomic_direct(page, type) __kmap_atomic_direct(page, type) | ||
| 96 | # define kunmap_atomic_direct(kvaddr, type) __kunmap_atomic(kvaddr, type) | ||
| 97 | #else | ||
| 98 | # define kmap_atomic_prot(page, type, prot) __kmap_atomic_prot(page, type, prot) | ||
| 99 | # define kmap_atomic_prot_pfn(pfn, type, prot) __kmap_atomic_prot_pfn(pfn, type, prot) | ||
| 100 | # define kmap_atomic(page, type) __kmap_atomic(page, type) | ||
| 101 | # define kmap_atomic_pfn(pfn, type) __kmap_atomic_pfn(pfn, type) | ||
| 102 | # define kunmap_atomic(kvaddr, type) __kunmap_atomic(kvaddr, type) | ||
| 103 | # define kmap_atomic_to_page(kvaddr) __kmap_atomic_to_page(kvaddr) | ||
| 104 | # define kmap_atomic_direct(page, type) __kmap_atomic(page, type) | ||
| 105 | # define kunmap_atomic_direct(kvaddr, type) __kunmap_atomic(kvaddr, type) | ||
| 106 | #endif | ||
| 107 | |||
| 78 | #endif /* __KERNEL__ */ | 108 | #endif /* __KERNEL__ */ |
| 79 | 109 | ||
| 80 | #endif /* _ASM_X86_HIGHMEM_H */ | 110 | #endif /* _ASM_X86_HIGHMEM_H */ |
diff --git a/arch/x86/include/asm/i8253.h b/arch/x86/include/asm/i8253.h index 1edbf89680fd..fc1f579fb965 100644 --- a/arch/x86/include/asm/i8253.h +++ b/arch/x86/include/asm/i8253.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | #define PIT_CH0 0x40 | 6 | #define PIT_CH0 0x40 |
| 7 | #define PIT_CH2 0x42 | 7 | #define PIT_CH2 0x42 |
| 8 | 8 | ||
| 9 | extern spinlock_t i8253_lock; | 9 | extern raw_spinlock_t i8253_lock; |
| 10 | 10 | ||
| 11 | extern struct clock_event_device *global_clock_event; | 11 | extern struct clock_event_device *global_clock_event; |
| 12 | 12 | ||
diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h index 58d7091eeb1f..7ec65b18085d 100644 --- a/arch/x86/include/asm/i8259.h +++ b/arch/x86/include/asm/i8259.h | |||
| @@ -24,7 +24,7 @@ extern unsigned int cached_irq_mask; | |||
| 24 | #define SLAVE_ICW4_DEFAULT 0x01 | 24 | #define SLAVE_ICW4_DEFAULT 0x01 |
| 25 | #define PIC_ICW4_AEOI 2 | 25 | #define PIC_ICW4_AEOI 2 |
| 26 | 26 | ||
| 27 | extern spinlock_t i8259A_lock; | 27 | extern raw_spinlock_t i8259A_lock; |
| 28 | 28 | ||
| 29 | extern void init_8259A(int auto_eoi); | 29 | extern void init_8259A(int auto_eoi); |
| 30 | extern void enable_8259A_irq(unsigned int irq); | 30 | extern void enable_8259A_irq(unsigned int irq); |
diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h index 7639dbf5d223..0ec050a154be 100644 --- a/arch/x86/include/asm/page_64_types.h +++ b/arch/x86/include/asm/page_64_types.h | |||
| @@ -14,12 +14,21 @@ | |||
| 14 | #define IRQ_STACK_ORDER 2 | 14 | #define IRQ_STACK_ORDER 2 |
| 15 | #define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER) | 15 | #define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER) |
| 16 | 16 | ||
| 17 | #define STACKFAULT_STACK 1 | 17 | #ifdef CONFIG_PREEMPT_RT |
| 18 | #define DOUBLEFAULT_STACK 2 | 18 | # define STACKFAULT_STACK 0 |
| 19 | #define NMI_STACK 3 | 19 | # define DOUBLEFAULT_STACK 1 |
| 20 | #define DEBUG_STACK 4 | 20 | # define NMI_STACK 2 |
| 21 | #define MCE_STACK 5 | 21 | # define DEBUG_STACK 0 |
| 22 | #define N_EXCEPTION_STACKS 5 /* hw limit: 7 */ | 22 | # define MCE_STACK 3 |
| 23 | # define N_EXCEPTION_STACKS 3 /* hw limit: 7 */ | ||
| 24 | #else | ||
| 25 | # define STACKFAULT_STACK 1 | ||
| 26 | # define DOUBLEFAULT_STACK 2 | ||
| 27 | # define NMI_STACK 3 | ||
| 28 | # define DEBUG_STACK 4 | ||
| 29 | # define MCE_STACK 5 | ||
| 30 | # define N_EXCEPTION_STACKS 5 /* hw limit: 7 */ | ||
| 31 | #endif | ||
| 23 | 32 | ||
| 24 | #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) | 33 | #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) |
| 25 | #define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) | 34 | #define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index dd59a85a918f..fffef519b1f9 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
| @@ -442,6 +442,14 @@ static inline void *kmap_atomic_pte(struct page *page, enum km_type type) | |||
| 442 | ret = PVOP_CALL2(unsigned long, pv_mmu_ops.kmap_atomic_pte, page, type); | 442 | ret = PVOP_CALL2(unsigned long, pv_mmu_ops.kmap_atomic_pte, page, type); |
| 443 | return (void *)ret; | 443 | return (void *)ret; |
| 444 | } | 444 | } |
| 445 | |||
| 446 | static inline void *kmap_atomic_pte_direct(struct page *page, enum km_type type) | ||
| 447 | { | ||
| 448 | unsigned long ret; | ||
| 449 | ret = PVOP_CALL2(unsigned long, pv_mmu_ops.kmap_atomic_pte_direct, | ||
| 450 | page, type); | ||
| 451 | return (void *)ret; | ||
| 452 | } | ||
| 445 | #endif | 453 | #endif |
| 446 | 454 | ||
| 447 | static inline void pte_update(struct mm_struct *mm, unsigned long addr, | 455 | static inline void pte_update(struct mm_struct *mm, unsigned long addr, |
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index b1e70d51e40c..ca14f6c0720b 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h | |||
| @@ -306,6 +306,7 @@ struct pv_mmu_ops { | |||
| 306 | 306 | ||
| 307 | #ifdef CONFIG_HIGHPTE | 307 | #ifdef CONFIG_HIGHPTE |
| 308 | void *(*kmap_atomic_pte)(struct page *page, enum km_type type); | 308 | void *(*kmap_atomic_pte)(struct page *page, enum km_type type); |
| 309 | void *(*kmap_atomic_pte_direct)(struct page *page, enum km_type type); | ||
| 309 | #endif | 310 | #endif |
| 310 | 311 | ||
| 311 | struct pv_lazy_ops lazy_mode; | 312 | struct pv_lazy_ops lazy_mode; |
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index b4bf9a942ed0..567d00974b22 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
| @@ -83,7 +83,7 @@ struct irq_routing_table { | |||
| 83 | extern unsigned int pcibios_irq_mask; | 83 | extern unsigned int pcibios_irq_mask; |
| 84 | 84 | ||
| 85 | extern int pcibios_scanned; | 85 | extern int pcibios_scanned; |
| 86 | extern spinlock_t pci_config_lock; | 86 | extern raw_spinlock_t pci_config_lock; |
| 87 | 87 | ||
| 88 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); | 88 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); |
| 89 | extern void (*pcibios_disable_irq)(struct pci_dev *dev); | 89 | extern void (*pcibios_disable_irq)(struct pci_dev *dev); |
diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h index 177b0165ea01..0e989a1df2fb 100644 --- a/arch/x86/include/asm/pgtable-3level.h +++ b/arch/x86/include/asm/pgtable-3level.h | |||
| @@ -71,6 +71,7 @@ static inline void pud_clear(pud_t *pudp) | |||
| 71 | { | 71 | { |
| 72 | unsigned long pgd; | 72 | unsigned long pgd; |
| 73 | 73 | ||
| 74 | preempt_disable(); | ||
| 74 | set_pud(pudp, __pud(0)); | 75 | set_pud(pudp, __pud(0)); |
| 75 | 76 | ||
| 76 | /* | 77 | /* |
| @@ -86,6 +87,7 @@ static inline void pud_clear(pud_t *pudp) | |||
| 86 | if (__pa(pudp) >= pgd && __pa(pudp) < | 87 | if (__pa(pudp) >= pgd && __pa(pudp) < |
| 87 | (pgd + sizeof(pgd_t)*PTRS_PER_PGD)) | 88 | (pgd + sizeof(pgd_t)*PTRS_PER_PGD)) |
| 88 | write_cr3(pgd); | 89 | write_cr3(pgd); |
| 90 | preempt_enable(); | ||
| 89 | } | 91 | } |
| 90 | 92 | ||
| 91 | #ifdef CONFIG_SMP | 93 | #ifdef CONFIG_SMP |
diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h index 01fd9461d323..b323c3df7d36 100644 --- a/arch/x86/include/asm/pgtable_32.h +++ b/arch/x86/include/asm/pgtable_32.h | |||
| @@ -59,14 +59,20 @@ extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t); | |||
| 59 | #define pte_offset_map_nested(dir, address) \ | 59 | #define pte_offset_map_nested(dir, address) \ |
| 60 | ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)), KM_PTE1) + \ | 60 | ((pte_t *)kmap_atomic_pte(pmd_page(*(dir)), KM_PTE1) + \ |
| 61 | pte_index((address))) | 61 | pte_index((address))) |
| 62 | #define pte_offset_map_direct(dir, address) \ | ||
| 63 | ((pte_t *)kmap_atomic_pte_direct(pmd_page(*(dir)), __KM_PTE) + \ | ||
| 64 | pte_index((address))) | ||
| 62 | #define pte_unmap(pte) kunmap_atomic((pte), __KM_PTE) | 65 | #define pte_unmap(pte) kunmap_atomic((pte), __KM_PTE) |
| 63 | #define pte_unmap_nested(pte) kunmap_atomic((pte), KM_PTE1) | 66 | #define pte_unmap_nested(pte) kunmap_atomic((pte), KM_PTE1) |
| 67 | #define pte_unmap_direct(pte) kunmap_atomic_direct((pte), __KM_PTE) | ||
| 64 | #else | 68 | #else |
| 65 | #define pte_offset_map(dir, address) \ | 69 | #define pte_offset_map(dir, address) \ |
| 66 | ((pte_t *)page_address(pmd_page(*(dir))) + pte_index((address))) | 70 | ((pte_t *)page_address(pmd_page(*(dir))) + pte_index((address))) |
| 67 | #define pte_offset_map_nested(dir, address) pte_offset_map((dir), (address)) | 71 | #define pte_offset_map_nested(dir, address) pte_offset_map((dir), (address)) |
| 72 | #define pte_offset_map_direct(dir, address) pte_offset_map((dir), (address)) | ||
| 68 | #define pte_unmap(pte) do { } while (0) | 73 | #define pte_unmap(pte) do { } while (0) |
| 69 | #define pte_unmap_nested(pte) do { } while (0) | 74 | #define pte_unmap_nested(pte) do { } while (0) |
| 75 | #define pte_unmap_direct(pte) do { } while (0) | ||
| 70 | #endif | 76 | #endif |
| 71 | 77 | ||
| 72 | /* Clear a kernel PTE and flush it from the TLB */ | 78 | /* Clear a kernel PTE and flush it from the TLB */ |
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index c57a30117149..efc01aef51c5 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h | |||
| @@ -126,8 +126,10 @@ static inline int pgd_large(pgd_t pgd) { return 0; } | |||
| 126 | /* x86-64 always has all page tables mapped. */ | 126 | /* x86-64 always has all page tables mapped. */ |
| 127 | #define pte_offset_map(dir, address) pte_offset_kernel((dir), (address)) | 127 | #define pte_offset_map(dir, address) pte_offset_kernel((dir), (address)) |
| 128 | #define pte_offset_map_nested(dir, address) pte_offset_kernel((dir), (address)) | 128 | #define pte_offset_map_nested(dir, address) pte_offset_kernel((dir), (address)) |
| 129 | #define pte_unmap(pte) /* NOP */ | 129 | #define pte_offset_map_direct(dir, address) pte_offset_kernel((dir), (address)) |
| 130 | #define pte_unmap_nested(pte) /* NOP */ | 130 | #define pte_unmap(pte) do { } while (0) |
| 131 | #define pte_unmap_nested(pte) do { } while (0) | ||
| 132 | #define pte_unmap_direct(pte) do { } while (0) | ||
| 131 | 133 | ||
| 132 | #define update_mmu_cache(vma, address, pte) do { } while (0) | 134 | #define update_mmu_cache(vma, address, pte) do { } while (0) |
| 133 | 135 | ||
diff --git a/arch/x86/include/asm/rwsem.h b/arch/x86/include/asm/rwsem.h index 606ede126972..42f8a37db6fb 100644 --- a/arch/x86/include/asm/rwsem.h +++ b/arch/x86/include/asm/rwsem.h | |||
| @@ -45,14 +45,14 @@ | |||
| 45 | 45 | ||
| 46 | struct rwsem_waiter; | 46 | struct rwsem_waiter; |
| 47 | 47 | ||
| 48 | extern asmregparm struct rw_semaphore * | 48 | extern asmregparm struct rw_anon_semaphore * |
| 49 | rwsem_down_read_failed(struct rw_semaphore *sem); | 49 | rwsem_down_read_failed(struct rw_anon_semaphore *sem); |
| 50 | extern asmregparm struct rw_semaphore * | 50 | extern asmregparm struct rw_anon_semaphore * |
| 51 | rwsem_down_write_failed(struct rw_semaphore *sem); | 51 | rwsem_down_write_failed(struct rw_anon_semaphore *sem); |
| 52 | extern asmregparm struct rw_semaphore * | 52 | extern asmregparm struct rw_anon_semaphore * |
| 53 | rwsem_wake(struct rw_semaphore *); | 53 | rwsem_wake(struct rw_anon_semaphore *); |
| 54 | extern asmregparm struct rw_semaphore * | 54 | extern asmregparm struct rw_anon_semaphore * |
| 55 | rwsem_downgrade_wake(struct rw_semaphore *sem); | 55 | rwsem_downgrade_wake(struct rw_anon_semaphore *sem); |
| 56 | 56 | ||
| 57 | /* | 57 | /* |
| 58 | * the semaphore definition | 58 | * the semaphore definition |
| @@ -76,9 +76,9 @@ extern asmregparm struct rw_semaphore * | |||
| 76 | 76 | ||
| 77 | typedef signed long rwsem_count_t; | 77 | typedef signed long rwsem_count_t; |
| 78 | 78 | ||
| 79 | struct rw_semaphore { | 79 | struct rw_anon_semaphore { |
| 80 | rwsem_count_t count; | 80 | rwsem_count_t count; |
| 81 | spinlock_t wait_lock; | 81 | raw_spinlock_t wait_lock; |
| 82 | struct list_head wait_list; | 82 | struct list_head wait_list; |
| 83 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 83 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
| 84 | struct lockdep_map dep_map; | 84 | struct lockdep_map dep_map; |
| @@ -86,35 +86,34 @@ struct rw_semaphore { | |||
| 86 | }; | 86 | }; |
| 87 | 87 | ||
| 88 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 88 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
| 89 | # define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname } | 89 | # define __RWSEM_ANON_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname } |
| 90 | #else | 90 | #else |
| 91 | # define __RWSEM_DEP_MAP_INIT(lockname) | 91 | # define __RWSEM_ANON_DEP_MAP_INIT(lockname) |
| 92 | #endif | 92 | #endif |
| 93 | 93 | ||
| 94 | 94 | #define __RWSEM_ANON_INITIALIZER(name) \ | |
| 95 | #define __RWSEM_INITIALIZER(name) \ | ||
| 96 | { \ | 95 | { \ |
| 97 | RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait_lock), \ | 96 | RWSEM_UNLOCKED_VALUE, __RAW_SPIN_LOCK_UNLOCKED((name).wait_lock), \ |
| 98 | LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) \ | 97 | LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) \ |
| 99 | } | 98 | } |
| 100 | 99 | ||
| 101 | #define DECLARE_RWSEM(name) \ | 100 | #define DECLARE_ANON_RWSEM(name) \ |
| 102 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) | 101 | struct rw_anon_semaphore name = __RWSEM_ANON_INITIALIZER(name) |
| 103 | 102 | ||
| 104 | extern void __init_rwsem(struct rw_semaphore *sem, const char *name, | 103 | extern void __init_anon_rwsem(struct rw_anon_semaphore *sem, const char *name, |
| 105 | struct lock_class_key *key); | 104 | struct lock_class_key *key); |
| 106 | 105 | ||
| 107 | #define init_rwsem(sem) \ | 106 | #define init_anon_rwsem(sem) \ |
| 108 | do { \ | 107 | do { \ |
| 109 | static struct lock_class_key __key; \ | 108 | static struct lock_class_key __key; \ |
| 110 | \ | 109 | \ |
| 111 | __init_rwsem((sem), #sem, &__key); \ | 110 | __init_anon_rwsem((sem), #sem, &__key); \ |
| 112 | } while (0) | 111 | } while (0) |
| 113 | 112 | ||
| 114 | /* | 113 | /* |
| 115 | * lock for reading | 114 | * lock for reading |
| 116 | */ | 115 | */ |
| 117 | static inline void __down_read(struct rw_semaphore *sem) | 116 | static inline void __down_read(struct rw_anon_semaphore *sem) |
| 118 | { | 117 | { |
| 119 | asm volatile("# beginning down_read\n\t" | 118 | asm volatile("# beginning down_read\n\t" |
| 120 | LOCK_PREFIX _ASM_INC "(%1)\n\t" | 119 | LOCK_PREFIX _ASM_INC "(%1)\n\t" |
| @@ -131,7 +130,7 @@ static inline void __down_read(struct rw_semaphore *sem) | |||
| 131 | /* | 130 | /* |
| 132 | * trylock for reading -- returns 1 if successful, 0 if contention | 131 | * trylock for reading -- returns 1 if successful, 0 if contention |
| 133 | */ | 132 | */ |
| 134 | static inline int __down_read_trylock(struct rw_semaphore *sem) | 133 | static inline int __down_read_trylock(struct rw_anon_semaphore *sem) |
| 135 | { | 134 | { |
| 136 | rwsem_count_t result, tmp; | 135 | rwsem_count_t result, tmp; |
| 137 | asm volatile("# beginning __down_read_trylock\n\t" | 136 | asm volatile("# beginning __down_read_trylock\n\t" |
| @@ -153,7 +152,8 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) | |||
| 153 | /* | 152 | /* |
| 154 | * lock for writing | 153 | * lock for writing |
| 155 | */ | 154 | */ |
| 156 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) | 155 | static inline void |
| 156 | __down_write_nested(struct rw_anon_semaphore *sem, int subclass) | ||
| 157 | { | 157 | { |
| 158 | rwsem_count_t tmp; | 158 | rwsem_count_t tmp; |
| 159 | 159 | ||
| @@ -172,7 +172,7 @@ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) | |||
| 172 | : "memory", "cc"); | 172 | : "memory", "cc"); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | static inline void __down_write(struct rw_semaphore *sem) | 175 | static inline void __down_write(struct rw_anon_semaphore *sem) |
| 176 | { | 176 | { |
| 177 | __down_write_nested(sem, 0); | 177 | __down_write_nested(sem, 0); |
| 178 | } | 178 | } |
| @@ -180,7 +180,7 @@ static inline void __down_write(struct rw_semaphore *sem) | |||
| 180 | /* | 180 | /* |
| 181 | * trylock for writing -- returns 1 if successful, 0 if contention | 181 | * trylock for writing -- returns 1 if successful, 0 if contention |
| 182 | */ | 182 | */ |
| 183 | static inline int __down_write_trylock(struct rw_semaphore *sem) | 183 | static inline int __down_write_trylock(struct rw_anon_semaphore *sem) |
| 184 | { | 184 | { |
| 185 | rwsem_count_t ret = cmpxchg(&sem->count, | 185 | rwsem_count_t ret = cmpxchg(&sem->count, |
| 186 | RWSEM_UNLOCKED_VALUE, | 186 | RWSEM_UNLOCKED_VALUE, |
| @@ -193,7 +193,7 @@ static inline int __down_write_trylock(struct rw_semaphore *sem) | |||
| 193 | /* | 193 | /* |
| 194 | * unlock after reading | 194 | * unlock after reading |
| 195 | */ | 195 | */ |
| 196 | static inline void __up_read(struct rw_semaphore *sem) | 196 | static inline void __up_read(struct rw_anon_semaphore *sem) |
| 197 | { | 197 | { |
| 198 | rwsem_count_t tmp = -RWSEM_ACTIVE_READ_BIAS; | 198 | rwsem_count_t tmp = -RWSEM_ACTIVE_READ_BIAS; |
| 199 | asm volatile("# beginning __up_read\n\t" | 199 | asm volatile("# beginning __up_read\n\t" |
| @@ -211,7 +211,7 @@ static inline void __up_read(struct rw_semaphore *sem) | |||
| 211 | /* | 211 | /* |
| 212 | * unlock after writing | 212 | * unlock after writing |
| 213 | */ | 213 | */ |
| 214 | static inline void __up_write(struct rw_semaphore *sem) | 214 | static inline void __up_write(struct rw_anon_semaphore *sem) |
| 215 | { | 215 | { |
| 216 | rwsem_count_t tmp; | 216 | rwsem_count_t tmp; |
| 217 | asm volatile("# beginning __up_write\n\t" | 217 | asm volatile("# beginning __up_write\n\t" |
| @@ -230,7 +230,7 @@ static inline void __up_write(struct rw_semaphore *sem) | |||
| 230 | /* | 230 | /* |
| 231 | * downgrade write lock to read lock | 231 | * downgrade write lock to read lock |
| 232 | */ | 232 | */ |
| 233 | static inline void __downgrade_write(struct rw_semaphore *sem) | 233 | static inline void __downgrade_write(struct rw_anon_semaphore *sem) |
| 234 | { | 234 | { |
| 235 | asm volatile("# beginning __downgrade_write\n\t" | 235 | asm volatile("# beginning __downgrade_write\n\t" |
| 236 | LOCK_PREFIX _ASM_ADD "%2,(%1)\n\t" | 236 | LOCK_PREFIX _ASM_ADD "%2,(%1)\n\t" |
| @@ -251,7 +251,7 @@ static inline void __downgrade_write(struct rw_semaphore *sem) | |||
| 251 | * implement atomic add functionality | 251 | * implement atomic add functionality |
| 252 | */ | 252 | */ |
| 253 | static inline void rwsem_atomic_add(rwsem_count_t delta, | 253 | static inline void rwsem_atomic_add(rwsem_count_t delta, |
| 254 | struct rw_semaphore *sem) | 254 | struct rw_anon_semaphore *sem) |
| 255 | { | 255 | { |
| 256 | asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0" | 256 | asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0" |
| 257 | : "+m" (sem->count) | 257 | : "+m" (sem->count) |
| @@ -262,7 +262,7 @@ static inline void rwsem_atomic_add(rwsem_count_t delta, | |||
| 262 | * implement exchange and add functionality | 262 | * implement exchange and add functionality |
| 263 | */ | 263 | */ |
| 264 | static inline rwsem_count_t rwsem_atomic_update(rwsem_count_t delta, | 264 | static inline rwsem_count_t rwsem_atomic_update(rwsem_count_t delta, |
| 265 | struct rw_semaphore *sem) | 265 | struct rw_anon_semaphore *sem) |
| 266 | { | 266 | { |
| 267 | rwsem_count_t tmp = delta; | 267 | rwsem_count_t tmp = delta; |
| 268 | 268 | ||
| @@ -273,10 +273,54 @@ static inline rwsem_count_t rwsem_atomic_update(rwsem_count_t delta, | |||
| 273 | return tmp + delta; | 273 | return tmp + delta; |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | static inline int anon_rwsem_is_locked(struct rw_anon_semaphore *sem) | ||
| 277 | { | ||
| 278 | return (sem->count != 0); | ||
| 279 | } | ||
| 280 | |||
| 281 | #ifndef CONFIG_PREEMPT_RT | ||
| 282 | |||
| 283 | struct rw_semaphore { | ||
| 284 | signed long count; | ||
| 285 | raw_spinlock_t wait_lock; | ||
| 286 | struct list_head wait_list; | ||
| 287 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 288 | struct lockdep_map dep_map; | ||
| 289 | #endif | ||
| 290 | }; | ||
| 291 | |||
| 292 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 293 | # define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname } | ||
| 294 | #else | ||
| 295 | # define __RWSEM_DEP_MAP_INIT(lockname) | ||
| 296 | #endif | ||
| 297 | |||
| 298 | #define __RWSEM_INITIALIZER(name) \ | ||
| 299 | { 0, __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), LIST_HEAD_INIT((name).wait_list) \ | ||
| 300 | __RWSEM_DEP_MAP_INIT(name) } | ||
| 301 | |||
| 302 | #define DECLARE_RWSEM(name) \ | ||
| 303 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) | ||
| 304 | |||
| 305 | static inline void __init_rwsem(struct rw_semaphore *sem, const char *name, | ||
| 306 | struct lock_class_key *key) | ||
| 307 | { | ||
| 308 | __init_anon_rwsem((struct rw_anon_semaphore *)sem, name, key); | ||
| 309 | } | ||
| 310 | |||
| 311 | #define init_rwsem(sem) \ | ||
| 312 | do { \ | ||
| 313 | static struct lock_class_key __key; \ | ||
| 314 | \ | ||
| 315 | __init_rwsem((sem), #sem, &__key); \ | ||
| 316 | } while (0) | ||
| 317 | |||
| 318 | |||
| 276 | static inline int rwsem_is_locked(struct rw_semaphore *sem) | 319 | static inline int rwsem_is_locked(struct rw_semaphore *sem) |
| 277 | { | 320 | { |
| 278 | return (sem->count != 0); | 321 | return (sem->count != 0); |
| 279 | } | 322 | } |
| 323 | #endif | ||
| 280 | 324 | ||
| 281 | #endif /* __KERNEL__ */ | 325 | #endif /* __KERNEL__ */ |
| 282 | #endif /* _ASM_X86_RWSEM_H */ | 326 | #endif /* _ASM_X86_RWSEM_H */ |
diff --git a/arch/x86/include/asm/timer.h b/arch/x86/include/asm/timer.h index 5469630b27f5..3d201174ac0a 100644 --- a/arch/x86/include/asm/timer.h +++ b/arch/x86/include/asm/timer.h | |||
| @@ -58,9 +58,9 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc) | |||
| 58 | unsigned long long ns; | 58 | unsigned long long ns; |
| 59 | unsigned long flags; | 59 | unsigned long flags; |
| 60 | 60 | ||
| 61 | local_irq_save(flags); | 61 | raw_local_irq_save(flags); |
| 62 | ns = __cycles_2_ns(cyc); | 62 | ns = __cycles_2_ns(cyc); |
| 63 | local_irq_restore(flags); | 63 | raw_local_irq_restore(flags); |
| 64 | 64 | ||
| 65 | return ns; | 65 | return ns; |
| 66 | } | 66 | } |
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 7f3eba08e7de..1c77e8192f62 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h | |||
| @@ -7,6 +7,21 @@ | |||
| 7 | #include <asm/processor.h> | 7 | #include <asm/processor.h> |
| 8 | #include <asm/system.h> | 8 | #include <asm/system.h> |
| 9 | 9 | ||
| 10 | /* | ||
| 11 | * TLB-flush needs to be nonpreemptible on PREEMPT_RT due to the | ||
| 12 | * following complex race scenario: | ||
| 13 | * | ||
| 14 | * if the current task is lazy-TLB and does a TLB flush and | ||
| 15 | * gets preempted after the movl %%r3, %0 but before the | ||
| 16 | * movl %0, %%cr3 then its ->active_mm might change and it will | ||
| 17 | * install the wrong cr3 when it switches back. This is not a | ||
| 18 | * problem for the lazy-TLB task itself, but if the next task it | ||
| 19 | * switches to has an ->mm that is also the lazy-TLB task's | ||
| 20 | * new ->active_mm, then the scheduler will assume that cr3 is | ||
| 21 | * the new one, while we overwrote it with the old one. The result | ||
| 22 | * is the wrong cr3 in the new (non-lazy-TLB) task, which typically | ||
| 23 | * causes an infinite pagefault upon the next userspace access. | ||
| 24 | */ | ||
| 10 | #ifdef CONFIG_PARAVIRT | 25 | #ifdef CONFIG_PARAVIRT |
| 11 | #include <asm/paravirt.h> | 26 | #include <asm/paravirt.h> |
| 12 | #else | 27 | #else |
| @@ -17,7 +32,9 @@ | |||
| 17 | 32 | ||
| 18 | static inline void __native_flush_tlb(void) | 33 | static inline void __native_flush_tlb(void) |
| 19 | { | 34 | { |
| 35 | preempt_disable(); | ||
| 20 | native_write_cr3(native_read_cr3()); | 36 | native_write_cr3(native_read_cr3()); |
| 37 | preempt_enable(); | ||
| 21 | } | 38 | } |
| 22 | 39 | ||
| 23 | static inline void __native_flush_tlb_global(void) | 40 | static inline void __native_flush_tlb_global(void) |
| @@ -95,6 +112,13 @@ static inline void __flush_tlb_one(unsigned long addr) | |||
| 95 | 112 | ||
| 96 | static inline void flush_tlb_mm(struct mm_struct *mm) | 113 | static inline void flush_tlb_mm(struct mm_struct *mm) |
| 97 | { | 114 | { |
| 115 | /* | ||
| 116 | * This is safe on PREEMPT_RT because if we preempt | ||
| 117 | * right after the check but before the __flush_tlb(), | ||
| 118 | * and if ->active_mm changes, then we might miss a | ||
| 119 | * TLB flush, but that TLB flush happened already when | ||
| 120 | * ->active_mm was changed: | ||
| 121 | */ | ||
| 98 | if (mm == current->active_mm) | 122 | if (mm == current->active_mm) |
| 99 | __flush_tlb(); | 123 | __flush_tlb(); |
| 100 | } | 124 | } |
diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h index 3d61e204826f..81ccfb3bff66 100644 --- a/arch/x86/include/asm/vgtod.h +++ b/arch/x86/include/asm/vgtod.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | #include <linux/clocksource.h> | 5 | #include <linux/clocksource.h> |
| 6 | 6 | ||
| 7 | struct vsyscall_gtod_data { | 7 | struct vsyscall_gtod_data { |
| 8 | seqlock_t lock; | 8 | raw_seqlock_t lock; |
| 9 | 9 | ||
| 10 | /* open coded 'struct timespec' */ | 10 | /* open coded 'struct timespec' */ |
| 11 | time_t wall_time_sec; | 11 | time_t wall_time_sec; |
diff --git a/arch/x86/include/asm/xor_32.h b/arch/x86/include/asm/xor_32.h index 133b40a0f495..7a6aa6852678 100644 --- a/arch/x86/include/asm/xor_32.h +++ b/arch/x86/include/asm/xor_32.h | |||
| @@ -865,7 +865,21 @@ static struct xor_block_template xor_block_pIII_sse = { | |||
| 865 | #include <asm-generic/xor.h> | 865 | #include <asm-generic/xor.h> |
| 866 | 866 | ||
| 867 | #undef XOR_TRY_TEMPLATES | 867 | #undef XOR_TRY_TEMPLATES |
| 868 | #define XOR_TRY_TEMPLATES \ | 868 | /* |
| 869 | * MMX/SSE ops disable preemption for long periods of time, | ||
| 870 | * so on PREEMPT_RT use the register-based ops only: | ||
| 871 | */ | ||
| 872 | #ifdef CONFIG_PREEMPT_RT | ||
| 873 | # define XOR_TRY_TEMPLATES \ | ||
| 874 | do { \ | ||
| 875 | xor_speed(&xor_block_8regs); \ | ||
| 876 | xor_speed(&xor_block_8regs_p); \ | ||
| 877 | xor_speed(&xor_block_32regs); \ | ||
| 878 | xor_speed(&xor_block_32regs_p); \ | ||
| 879 | } while (0) | ||
| 880 | # define XOR_SELECT_TEMPLATE(FASTEST) (FASTEST) | ||
| 881 | #else | ||
| 882 | # define XOR_TRY_TEMPLATES \ | ||
| 869 | do { \ | 883 | do { \ |
| 870 | xor_speed(&xor_block_8regs); \ | 884 | xor_speed(&xor_block_8regs); \ |
| 871 | xor_speed(&xor_block_8regs_p); \ | 885 | xor_speed(&xor_block_8regs_p); \ |
| @@ -882,7 +896,8 @@ do { \ | |||
| 882 | /* We force the use of the SSE xor block because it can write around L2. | 896 | /* We force the use of the SSE xor block because it can write around L2. |
| 883 | We may also be able to load into the L1 only depending on how the cpu | 897 | We may also be able to load into the L1 only depending on how the cpu |
| 884 | deals with a load to a line that is being prefetched. */ | 898 | deals with a load to a line that is being prefetched. */ |
| 885 | #define XOR_SELECT_TEMPLATE(FASTEST) \ | 899 | # define XOR_SELECT_TEMPLATE(FASTEST) \ |
| 886 | (cpu_has_xmm ? &xor_block_pIII_sse : FASTEST) | 900 | (cpu_has_xmm ? &xor_block_pIII_sse : FASTEST) |
| 901 | #endif /* CONFIG_PREEMPT_RT */ | ||
| 887 | 902 | ||
| 888 | #endif /* _ASM_X86_XOR_32_H */ | 903 | #endif /* _ASM_X86_XOR_32_H */ |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index b35c160a4c3b..adcb4bfbaae4 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -73,8 +73,8 @@ | |||
| 73 | */ | 73 | */ |
| 74 | int sis_apic_bug = -1; | 74 | int sis_apic_bug = -1; |
| 75 | 75 | ||
| 76 | static DEFINE_SPINLOCK(ioapic_lock); | 76 | static DEFINE_RAW_SPINLOCK(ioapic_lock); |
| 77 | static DEFINE_SPINLOCK(vector_lock); | 77 | static DEFINE_RAW_SPINLOCK(vector_lock); |
| 78 | 78 | ||
| 79 | /* | 79 | /* |
| 80 | * # of IRQ routing registers | 80 | * # of IRQ routing registers |
| @@ -406,7 +406,7 @@ static bool io_apic_level_ack_pending(struct irq_cfg *cfg) | |||
| 406 | struct irq_pin_list *entry; | 406 | struct irq_pin_list *entry; |
| 407 | unsigned long flags; | 407 | unsigned long flags; |
| 408 | 408 | ||
| 409 | spin_lock_irqsave(&ioapic_lock, flags); | 409 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 410 | for_each_irq_pin(entry, cfg->irq_2_pin) { | 410 | for_each_irq_pin(entry, cfg->irq_2_pin) { |
| 411 | unsigned int reg; | 411 | unsigned int reg; |
| 412 | int pin; | 412 | int pin; |
| @@ -415,11 +415,11 @@ static bool io_apic_level_ack_pending(struct irq_cfg *cfg) | |||
| 415 | reg = io_apic_read(entry->apic, 0x10 + pin*2); | 415 | reg = io_apic_read(entry->apic, 0x10 + pin*2); |
| 416 | /* Is the remote IRR bit set? */ | 416 | /* Is the remote IRR bit set? */ |
| 417 | if (reg & IO_APIC_REDIR_REMOTE_IRR) { | 417 | if (reg & IO_APIC_REDIR_REMOTE_IRR) { |
| 418 | spin_unlock_irqrestore(&ioapic_lock, flags); | 418 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 419 | return true; | 419 | return true; |
| 420 | } | 420 | } |
| 421 | } | 421 | } |
| 422 | spin_unlock_irqrestore(&ioapic_lock, flags); | 422 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 423 | 423 | ||
| 424 | return false; | 424 | return false; |
| 425 | } | 425 | } |
| @@ -433,10 +433,10 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) | |||
| 433 | { | 433 | { |
| 434 | union entry_union eu; | 434 | union entry_union eu; |
| 435 | unsigned long flags; | 435 | unsigned long flags; |
| 436 | spin_lock_irqsave(&ioapic_lock, flags); | 436 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 437 | eu.w1 = io_apic_read(apic, 0x10 + 2 * pin); | 437 | eu.w1 = io_apic_read(apic, 0x10 + 2 * pin); |
| 438 | eu.w2 = io_apic_read(apic, 0x11 + 2 * pin); | 438 | eu.w2 = io_apic_read(apic, 0x11 + 2 * pin); |
| 439 | spin_unlock_irqrestore(&ioapic_lock, flags); | 439 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 440 | return eu.entry; | 440 | return eu.entry; |
| 441 | } | 441 | } |
| 442 | 442 | ||
| @@ -459,9 +459,9 @@ __ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) | |||
| 459 | void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) | 459 | void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) |
| 460 | { | 460 | { |
| 461 | unsigned long flags; | 461 | unsigned long flags; |
| 462 | spin_lock_irqsave(&ioapic_lock, flags); | 462 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 463 | __ioapic_write_entry(apic, pin, e); | 463 | __ioapic_write_entry(apic, pin, e); |
| 464 | spin_unlock_irqrestore(&ioapic_lock, flags); | 464 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 465 | } | 465 | } |
| 466 | 466 | ||
| 467 | /* | 467 | /* |
| @@ -474,10 +474,10 @@ static void ioapic_mask_entry(int apic, int pin) | |||
| 474 | unsigned long flags; | 474 | unsigned long flags; |
| 475 | union entry_union eu = { .entry.mask = 1 }; | 475 | union entry_union eu = { .entry.mask = 1 }; |
| 476 | 476 | ||
| 477 | spin_lock_irqsave(&ioapic_lock, flags); | 477 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 478 | io_apic_write(apic, 0x10 + 2*pin, eu.w1); | 478 | io_apic_write(apic, 0x10 + 2*pin, eu.w1); |
| 479 | io_apic_write(apic, 0x11 + 2*pin, eu.w2); | 479 | io_apic_write(apic, 0x11 + 2*pin, eu.w2); |
| 480 | spin_unlock_irqrestore(&ioapic_lock, flags); | 480 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 481 | } | 481 | } |
| 482 | 482 | ||
| 483 | /* | 483 | /* |
| @@ -604,9 +604,9 @@ static void mask_IO_APIC_irq_desc(struct irq_desc *desc) | |||
| 604 | 604 | ||
| 605 | BUG_ON(!cfg); | 605 | BUG_ON(!cfg); |
| 606 | 606 | ||
| 607 | spin_lock_irqsave(&ioapic_lock, flags); | 607 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 608 | __mask_IO_APIC_irq(cfg); | 608 | __mask_IO_APIC_irq(cfg); |
| 609 | spin_unlock_irqrestore(&ioapic_lock, flags); | 609 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 610 | } | 610 | } |
| 611 | 611 | ||
| 612 | static void unmask_IO_APIC_irq_desc(struct irq_desc *desc) | 612 | static void unmask_IO_APIC_irq_desc(struct irq_desc *desc) |
| @@ -614,9 +614,9 @@ static void unmask_IO_APIC_irq_desc(struct irq_desc *desc) | |||
| 614 | struct irq_cfg *cfg = desc->chip_data; | 614 | struct irq_cfg *cfg = desc->chip_data; |
| 615 | unsigned long flags; | 615 | unsigned long flags; |
| 616 | 616 | ||
| 617 | spin_lock_irqsave(&ioapic_lock, flags); | 617 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 618 | __unmask_IO_APIC_irq(cfg); | 618 | __unmask_IO_APIC_irq(cfg); |
| 619 | spin_unlock_irqrestore(&ioapic_lock, flags); | 619 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 620 | } | 620 | } |
| 621 | 621 | ||
| 622 | static void mask_IO_APIC_irq(unsigned int irq) | 622 | static void mask_IO_APIC_irq(unsigned int irq) |
| @@ -1140,12 +1140,12 @@ void lock_vector_lock(void) | |||
| 1140 | /* Used to the online set of cpus does not change | 1140 | /* Used to the online set of cpus does not change |
| 1141 | * during assign_irq_vector. | 1141 | * during assign_irq_vector. |
| 1142 | */ | 1142 | */ |
| 1143 | spin_lock(&vector_lock); | 1143 | raw_spin_lock(&vector_lock); |
| 1144 | } | 1144 | } |
| 1145 | 1145 | ||
| 1146 | void unlock_vector_lock(void) | 1146 | void unlock_vector_lock(void) |
| 1147 | { | 1147 | { |
| 1148 | spin_unlock(&vector_lock); | 1148 | raw_spin_unlock(&vector_lock); |
| 1149 | } | 1149 | } |
| 1150 | 1150 | ||
| 1151 | static int | 1151 | static int |
| @@ -1232,9 +1232,9 @@ int assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask) | |||
| 1232 | int err; | 1232 | int err; |
| 1233 | unsigned long flags; | 1233 | unsigned long flags; |
| 1234 | 1234 | ||
| 1235 | spin_lock_irqsave(&vector_lock, flags); | 1235 | raw_spin_lock_irqsave(&vector_lock, flags); |
| 1236 | err = __assign_irq_vector(irq, cfg, mask); | 1236 | err = __assign_irq_vector(irq, cfg, mask); |
| 1237 | spin_unlock_irqrestore(&vector_lock, flags); | 1237 | raw_spin_unlock_irqrestore(&vector_lock, flags); |
| 1238 | return err; | 1238 | return err; |
| 1239 | } | 1239 | } |
| 1240 | 1240 | ||
| @@ -1651,14 +1651,14 @@ __apicdebuginit(void) print_IO_APIC(void) | |||
| 1651 | 1651 | ||
| 1652 | for (apic = 0; apic < nr_ioapics; apic++) { | 1652 | for (apic = 0; apic < nr_ioapics; apic++) { |
| 1653 | 1653 | ||
| 1654 | spin_lock_irqsave(&ioapic_lock, flags); | 1654 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 1655 | reg_00.raw = io_apic_read(apic, 0); | 1655 | reg_00.raw = io_apic_read(apic, 0); |
| 1656 | reg_01.raw = io_apic_read(apic, 1); | 1656 | reg_01.raw = io_apic_read(apic, 1); |
| 1657 | if (reg_01.bits.version >= 0x10) | 1657 | if (reg_01.bits.version >= 0x10) |
| 1658 | reg_02.raw = io_apic_read(apic, 2); | 1658 | reg_02.raw = io_apic_read(apic, 2); |
| 1659 | if (reg_01.bits.version >= 0x20) | 1659 | if (reg_01.bits.version >= 0x20) |
| 1660 | reg_03.raw = io_apic_read(apic, 3); | 1660 | reg_03.raw = io_apic_read(apic, 3); |
| 1661 | spin_unlock_irqrestore(&ioapic_lock, flags); | 1661 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 1662 | 1662 | ||
| 1663 | printk("\n"); | 1663 | printk("\n"); |
| 1664 | printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].apicid); | 1664 | printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].apicid); |
| @@ -1880,7 +1880,7 @@ __apicdebuginit(void) print_PIC(void) | |||
| 1880 | 1880 | ||
| 1881 | printk(KERN_DEBUG "\nprinting PIC contents\n"); | 1881 | printk(KERN_DEBUG "\nprinting PIC contents\n"); |
| 1882 | 1882 | ||
| 1883 | spin_lock_irqsave(&i8259A_lock, flags); | 1883 | raw_spin_lock_irqsave(&i8259A_lock, flags); |
| 1884 | 1884 | ||
| 1885 | v = inb(0xa1) << 8 | inb(0x21); | 1885 | v = inb(0xa1) << 8 | inb(0x21); |
| 1886 | printk(KERN_DEBUG "... PIC IMR: %04x\n", v); | 1886 | printk(KERN_DEBUG "... PIC IMR: %04x\n", v); |
| @@ -1894,7 +1894,7 @@ __apicdebuginit(void) print_PIC(void) | |||
| 1894 | outb(0x0a,0xa0); | 1894 | outb(0x0a,0xa0); |
| 1895 | outb(0x0a,0x20); | 1895 | outb(0x0a,0x20); |
| 1896 | 1896 | ||
| 1897 | spin_unlock_irqrestore(&i8259A_lock, flags); | 1897 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
| 1898 | 1898 | ||
| 1899 | printk(KERN_DEBUG "... PIC ISR: %04x\n", v); | 1899 | printk(KERN_DEBUG "... PIC ISR: %04x\n", v); |
| 1900 | 1900 | ||
| @@ -1953,9 +1953,9 @@ void __init enable_IO_APIC(void) | |||
| 1953 | * The number of IO-APIC IRQ registers (== #pins): | 1953 | * The number of IO-APIC IRQ registers (== #pins): |
| 1954 | */ | 1954 | */ |
| 1955 | for (apic = 0; apic < nr_ioapics; apic++) { | 1955 | for (apic = 0; apic < nr_ioapics; apic++) { |
| 1956 | spin_lock_irqsave(&ioapic_lock, flags); | 1956 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 1957 | reg_01.raw = io_apic_read(apic, 1); | 1957 | reg_01.raw = io_apic_read(apic, 1); |
| 1958 | spin_unlock_irqrestore(&ioapic_lock, flags); | 1958 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 1959 | nr_ioapic_registers[apic] = reg_01.bits.entries+1; | 1959 | nr_ioapic_registers[apic] = reg_01.bits.entries+1; |
| 1960 | } | 1960 | } |
| 1961 | 1961 | ||
| @@ -2095,9 +2095,9 @@ void __init setup_ioapic_ids_from_mpc(void) | |||
| 2095 | for (apic_id = 0; apic_id < nr_ioapics; apic_id++) { | 2095 | for (apic_id = 0; apic_id < nr_ioapics; apic_id++) { |
| 2096 | 2096 | ||
| 2097 | /* Read the register 0 value */ | 2097 | /* Read the register 0 value */ |
| 2098 | spin_lock_irqsave(&ioapic_lock, flags); | 2098 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 2099 | reg_00.raw = io_apic_read(apic_id, 0); | 2099 | reg_00.raw = io_apic_read(apic_id, 0); |
| 2100 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2100 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 2101 | 2101 | ||
| 2102 | old_id = mp_ioapics[apic_id].apicid; | 2102 | old_id = mp_ioapics[apic_id].apicid; |
| 2103 | 2103 | ||
| @@ -2156,16 +2156,16 @@ void __init setup_ioapic_ids_from_mpc(void) | |||
| 2156 | mp_ioapics[apic_id].apicid); | 2156 | mp_ioapics[apic_id].apicid); |
| 2157 | 2157 | ||
| 2158 | reg_00.bits.ID = mp_ioapics[apic_id].apicid; | 2158 | reg_00.bits.ID = mp_ioapics[apic_id].apicid; |
| 2159 | spin_lock_irqsave(&ioapic_lock, flags); | 2159 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 2160 | io_apic_write(apic_id, 0, reg_00.raw); | 2160 | io_apic_write(apic_id, 0, reg_00.raw); |
| 2161 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2161 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 2162 | 2162 | ||
| 2163 | /* | 2163 | /* |
| 2164 | * Sanity check | 2164 | * Sanity check |
| 2165 | */ | 2165 | */ |
| 2166 | spin_lock_irqsave(&ioapic_lock, flags); | 2166 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 2167 | reg_00.raw = io_apic_read(apic_id, 0); | 2167 | reg_00.raw = io_apic_read(apic_id, 0); |
| 2168 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2168 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 2169 | if (reg_00.bits.ID != mp_ioapics[apic_id].apicid) | 2169 | if (reg_00.bits.ID != mp_ioapics[apic_id].apicid) |
| 2170 | printk("could not set ID!\n"); | 2170 | printk("could not set ID!\n"); |
| 2171 | else | 2171 | else |
| @@ -2248,7 +2248,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq) | |||
| 2248 | unsigned long flags; | 2248 | unsigned long flags; |
| 2249 | struct irq_cfg *cfg; | 2249 | struct irq_cfg *cfg; |
| 2250 | 2250 | ||
| 2251 | spin_lock_irqsave(&ioapic_lock, flags); | 2251 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 2252 | if (irq < nr_legacy_irqs) { | 2252 | if (irq < nr_legacy_irqs) { |
| 2253 | disable_8259A_irq(irq); | 2253 | disable_8259A_irq(irq); |
| 2254 | if (i8259A_irq_pending(irq)) | 2254 | if (i8259A_irq_pending(irq)) |
| @@ -2256,7 +2256,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq) | |||
| 2256 | } | 2256 | } |
| 2257 | cfg = irq_cfg(irq); | 2257 | cfg = irq_cfg(irq); |
| 2258 | __unmask_IO_APIC_irq(cfg); | 2258 | __unmask_IO_APIC_irq(cfg); |
| 2259 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2259 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 2260 | 2260 | ||
| 2261 | return was_pending; | 2261 | return was_pending; |
| 2262 | } | 2262 | } |
| @@ -2267,9 +2267,9 @@ static int ioapic_retrigger_irq(unsigned int irq) | |||
| 2267 | struct irq_cfg *cfg = irq_cfg(irq); | 2267 | struct irq_cfg *cfg = irq_cfg(irq); |
| 2268 | unsigned long flags; | 2268 | unsigned long flags; |
| 2269 | 2269 | ||
| 2270 | spin_lock_irqsave(&vector_lock, flags); | 2270 | raw_spin_lock_irqsave(&vector_lock, flags); |
| 2271 | apic->send_IPI_mask(cpumask_of(cpumask_first(cfg->domain)), cfg->vector); | 2271 | apic->send_IPI_mask(cpumask_of(cpumask_first(cfg->domain)), cfg->vector); |
| 2272 | spin_unlock_irqrestore(&vector_lock, flags); | 2272 | raw_spin_unlock_irqrestore(&vector_lock, flags); |
| 2273 | 2273 | ||
| 2274 | return 1; | 2274 | return 1; |
| 2275 | } | 2275 | } |
| @@ -2362,14 +2362,14 @@ set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask) | |||
| 2362 | irq = desc->irq; | 2362 | irq = desc->irq; |
| 2363 | cfg = desc->chip_data; | 2363 | cfg = desc->chip_data; |
| 2364 | 2364 | ||
| 2365 | spin_lock_irqsave(&ioapic_lock, flags); | 2365 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 2366 | ret = set_desc_affinity(desc, mask, &dest); | 2366 | ret = set_desc_affinity(desc, mask, &dest); |
| 2367 | if (!ret) { | 2367 | if (!ret) { |
| 2368 | /* Only the high 8 bits are valid. */ | 2368 | /* Only the high 8 bits are valid. */ |
| 2369 | dest = SET_APIC_LOGICAL_ID(dest); | 2369 | dest = SET_APIC_LOGICAL_ID(dest); |
| 2370 | __target_IO_APIC_irq(irq, dest, cfg); | 2370 | __target_IO_APIC_irq(irq, dest, cfg); |
| 2371 | } | 2371 | } |
| 2372 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2372 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 2373 | 2373 | ||
| 2374 | return ret; | 2374 | return ret; |
| 2375 | } | 2375 | } |
| @@ -2607,9 +2607,9 @@ static void eoi_ioapic_irq(struct irq_desc *desc) | |||
| 2607 | irq = desc->irq; | 2607 | irq = desc->irq; |
| 2608 | cfg = desc->chip_data; | 2608 | cfg = desc->chip_data; |
| 2609 | 2609 | ||
| 2610 | spin_lock_irqsave(&ioapic_lock, flags); | 2610 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 2611 | __eoi_ioapic_irq(irq, cfg); | 2611 | __eoi_ioapic_irq(irq, cfg); |
| 2612 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2612 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 2613 | } | 2613 | } |
| 2614 | 2614 | ||
| 2615 | static void ack_apic_level(unsigned int irq) | 2615 | static void ack_apic_level(unsigned int irq) |
| @@ -2623,7 +2623,8 @@ static void ack_apic_level(unsigned int irq) | |||
| 2623 | irq_complete_move(&desc); | 2623 | irq_complete_move(&desc); |
| 2624 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 2624 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
| 2625 | /* If we are moving the irq we need to mask it */ | 2625 | /* If we are moving the irq we need to mask it */ |
| 2626 | if (unlikely(desc->status & IRQ_MOVE_PENDING)) { | 2626 | if (unlikely(desc->status & IRQ_MOVE_PENDING) && |
| 2627 | !(desc->status & IRQ_INPROGRESS)) { | ||
| 2627 | do_unmask_irq = 1; | 2628 | do_unmask_irq = 1; |
| 2628 | mask_IO_APIC_irq_desc(desc); | 2629 | mask_IO_APIC_irq_desc(desc); |
| 2629 | } | 2630 | } |
| @@ -2717,6 +2718,16 @@ static void ack_apic_level(unsigned int irq) | |||
| 2717 | move_masked_irq(irq); | 2718 | move_masked_irq(irq); |
| 2718 | unmask_IO_APIC_irq_desc(desc); | 2719 | unmask_IO_APIC_irq_desc(desc); |
| 2719 | } | 2720 | } |
| 2721 | |||
| 2722 | #if (defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)) && \ | ||
| 2723 | defined(CONFIG_PREEMPT_HARDIRQS) | ||
| 2724 | /* | ||
| 2725 | * With threaded interrupts, we always have IRQ_INPROGRESS | ||
| 2726 | * when acking. CHECKME !!!!! | ||
| 2727 | */ | ||
| 2728 | else if (unlikely(desc->status & IRQ_MOVE_PENDING)) | ||
| 2729 | move_masked_irq(irq); | ||
| 2730 | #endif | ||
| 2720 | } | 2731 | } |
| 2721 | 2732 | ||
| 2722 | #ifdef CONFIG_INTR_REMAP | 2733 | #ifdef CONFIG_INTR_REMAP |
| @@ -3191,13 +3202,13 @@ static int ioapic_resume(struct sys_device *dev) | |||
| 3191 | data = container_of(dev, struct sysfs_ioapic_data, dev); | 3202 | data = container_of(dev, struct sysfs_ioapic_data, dev); |
| 3192 | entry = data->entry; | 3203 | entry = data->entry; |
| 3193 | 3204 | ||
| 3194 | spin_lock_irqsave(&ioapic_lock, flags); | 3205 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 3195 | reg_00.raw = io_apic_read(dev->id, 0); | 3206 | reg_00.raw = io_apic_read(dev->id, 0); |
| 3196 | if (reg_00.bits.ID != mp_ioapics[dev->id].apicid) { | 3207 | if (reg_00.bits.ID != mp_ioapics[dev->id].apicid) { |
| 3197 | reg_00.bits.ID = mp_ioapics[dev->id].apicid; | 3208 | reg_00.bits.ID = mp_ioapics[dev->id].apicid; |
| 3198 | io_apic_write(dev->id, 0, reg_00.raw); | 3209 | io_apic_write(dev->id, 0, reg_00.raw); |
| 3199 | } | 3210 | } |
| 3200 | spin_unlock_irqrestore(&ioapic_lock, flags); | 3211 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 3201 | for (i = 0; i < nr_ioapic_registers[dev->id]; i++) | 3212 | for (i = 0; i < nr_ioapic_registers[dev->id]; i++) |
| 3202 | ioapic_write_entry(dev->id, i, entry[i]); | 3213 | ioapic_write_entry(dev->id, i, entry[i]); |
| 3203 | 3214 | ||
| @@ -3260,7 +3271,6 @@ unsigned int create_irq_nr(unsigned int irq_want, int node) | |||
| 3260 | if (irq_want < nr_irqs_gsi) | 3271 | if (irq_want < nr_irqs_gsi) |
| 3261 | irq_want = nr_irqs_gsi; | 3272 | irq_want = nr_irqs_gsi; |
| 3262 | 3273 | ||
| 3263 | spin_lock_irqsave(&vector_lock, flags); | ||
| 3264 | for (new = irq_want; new < nr_irqs; new++) { | 3274 | for (new = irq_want; new < nr_irqs; new++) { |
| 3265 | desc_new = irq_to_desc_alloc_node(new, node); | 3275 | desc_new = irq_to_desc_alloc_node(new, node); |
| 3266 | if (!desc_new) { | 3276 | if (!desc_new) { |
| @@ -3272,14 +3282,15 @@ unsigned int create_irq_nr(unsigned int irq_want, int node) | |||
| 3272 | if (cfg_new->vector != 0) | 3282 | if (cfg_new->vector != 0) |
| 3273 | continue; | 3283 | continue; |
| 3274 | 3284 | ||
| 3285 | raw_spin_lock_irqsave(&vector_lock, flags); | ||
| 3275 | desc_new = move_irq_desc(desc_new, node); | 3286 | desc_new = move_irq_desc(desc_new, node); |
| 3276 | cfg_new = desc_new->chip_data; | 3287 | cfg_new = desc_new->chip_data; |
| 3277 | 3288 | ||
| 3278 | if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0) | 3289 | if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0) |
| 3279 | irq = new; | 3290 | irq = new; |
| 3291 | raw_spin_unlock_irqrestore(&vector_lock, flags); | ||
| 3280 | break; | 3292 | break; |
| 3281 | } | 3293 | } |
| 3282 | spin_unlock_irqrestore(&vector_lock, flags); | ||
| 3283 | 3294 | ||
| 3284 | if (irq > 0) | 3295 | if (irq > 0) |
| 3285 | dynamic_irq_init_keep_chip_data(irq); | 3296 | dynamic_irq_init_keep_chip_data(irq); |
| @@ -3310,10 +3321,10 @@ void destroy_irq(unsigned int irq) | |||
| 3310 | dynamic_irq_cleanup_keep_chip_data(irq); | 3321 | dynamic_irq_cleanup_keep_chip_data(irq); |
| 3311 | 3322 | ||
| 3312 | free_irte(irq); | 3323 | free_irte(irq); |
| 3313 | spin_lock_irqsave(&vector_lock, flags); | 3324 | raw_spin_lock_irqsave(&vector_lock, flags); |
| 3314 | cfg = irq_to_desc(irq)->chip_data; | 3325 | cfg = irq_to_desc(irq)->chip_data; |
| 3315 | __clear_irq_vector(irq, cfg); | 3326 | __clear_irq_vector(irq, cfg); |
| 3316 | spin_unlock_irqrestore(&vector_lock, flags); | 3327 | raw_spin_unlock_irqrestore(&vector_lock, flags); |
| 3317 | } | 3328 | } |
| 3318 | 3329 | ||
| 3319 | /* | 3330 | /* |
| @@ -3850,9 +3861,9 @@ int __init io_apic_get_redir_entries (int ioapic) | |||
| 3850 | union IO_APIC_reg_01 reg_01; | 3861 | union IO_APIC_reg_01 reg_01; |
| 3851 | unsigned long flags; | 3862 | unsigned long flags; |
| 3852 | 3863 | ||
| 3853 | spin_lock_irqsave(&ioapic_lock, flags); | 3864 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 3854 | reg_01.raw = io_apic_read(ioapic, 1); | 3865 | reg_01.raw = io_apic_read(ioapic, 1); |
| 3855 | spin_unlock_irqrestore(&ioapic_lock, flags); | 3866 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 3856 | 3867 | ||
| 3857 | return reg_01.bits.entries; | 3868 | return reg_01.bits.entries; |
| 3858 | } | 3869 | } |
| @@ -4014,9 +4025,9 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id) | |||
| 4014 | if (physids_empty(apic_id_map)) | 4025 | if (physids_empty(apic_id_map)) |
| 4015 | apic->ioapic_phys_id_map(&phys_cpu_present_map, &apic_id_map); | 4026 | apic->ioapic_phys_id_map(&phys_cpu_present_map, &apic_id_map); |
| 4016 | 4027 | ||
| 4017 | spin_lock_irqsave(&ioapic_lock, flags); | 4028 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 4018 | reg_00.raw = io_apic_read(ioapic, 0); | 4029 | reg_00.raw = io_apic_read(ioapic, 0); |
| 4019 | spin_unlock_irqrestore(&ioapic_lock, flags); | 4030 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 4020 | 4031 | ||
| 4021 | if (apic_id >= get_physical_broadcast()) { | 4032 | if (apic_id >= get_physical_broadcast()) { |
| 4022 | printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " | 4033 | printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " |
| @@ -4050,10 +4061,10 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id) | |||
| 4050 | if (reg_00.bits.ID != apic_id) { | 4061 | if (reg_00.bits.ID != apic_id) { |
| 4051 | reg_00.bits.ID = apic_id; | 4062 | reg_00.bits.ID = apic_id; |
| 4052 | 4063 | ||
| 4053 | spin_lock_irqsave(&ioapic_lock, flags); | 4064 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 4054 | io_apic_write(ioapic, 0, reg_00.raw); | 4065 | io_apic_write(ioapic, 0, reg_00.raw); |
| 4055 | reg_00.raw = io_apic_read(ioapic, 0); | 4066 | reg_00.raw = io_apic_read(ioapic, 0); |
| 4056 | spin_unlock_irqrestore(&ioapic_lock, flags); | 4067 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 4057 | 4068 | ||
| 4058 | /* Sanity check */ | 4069 | /* Sanity check */ |
| 4059 | if (reg_00.bits.ID != apic_id) { | 4070 | if (reg_00.bits.ID != apic_id) { |
| @@ -4074,9 +4085,9 @@ int __init io_apic_get_version(int ioapic) | |||
| 4074 | union IO_APIC_reg_01 reg_01; | 4085 | union IO_APIC_reg_01 reg_01; |
| 4075 | unsigned long flags; | 4086 | unsigned long flags; |
| 4076 | 4087 | ||
| 4077 | spin_lock_irqsave(&ioapic_lock, flags); | 4088 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
| 4078 | reg_01.raw = io_apic_read(ioapic, 1); | 4089 | reg_01.raw = io_apic_read(ioapic, 1); |
| 4079 | spin_unlock_irqrestore(&ioapic_lock, flags); | 4090 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
| 4080 | 4091 | ||
| 4081 | return reg_01.bits.version; | 4092 | return reg_01.bits.version; |
| 4082 | } | 4093 | } |
diff --git a/arch/x86/kernel/apic/ipi.c b/arch/x86/kernel/apic/ipi.c index 08385e090a6f..54e774dec0a6 100644 --- a/arch/x86/kernel/apic/ipi.c +++ b/arch/x86/kernel/apic/ipi.c | |||
| @@ -106,7 +106,7 @@ void default_send_IPI_mask_logical(const struct cpumask *cpumask, int vector) | |||
| 106 | unsigned long mask = cpumask_bits(cpumask)[0]; | 106 | unsigned long mask = cpumask_bits(cpumask)[0]; |
| 107 | unsigned long flags; | 107 | unsigned long flags; |
| 108 | 108 | ||
| 109 | if (WARN_ONCE(!mask, "empty IPI mask")) | 109 | if (!mask) |
| 110 | return; | 110 | return; |
| 111 | 111 | ||
| 112 | local_irq_save(flags); | 112 | local_irq_save(flags); |
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c index 0159a69396cb..1aaf2935e222 100644 --- a/arch/x86/kernel/apic/nmi.c +++ b/arch/x86/kernel/apic/nmi.c | |||
| @@ -91,7 +91,9 @@ static inline unsigned int get_timer_irqs(int cpu) | |||
| 91 | */ | 91 | */ |
| 92 | static __init void nmi_cpu_busy(void *data) | 92 | static __init void nmi_cpu_busy(void *data) |
| 93 | { | 93 | { |
| 94 | #ifndef CONFIG_PREEMPT_RT | ||
| 94 | local_irq_enable_in_hardirq(); | 95 | local_irq_enable_in_hardirq(); |
| 96 | #endif | ||
| 95 | /* | 97 | /* |
| 96 | * Intentionally don't use cpu_relax here. This is | 98 | * Intentionally don't use cpu_relax here. This is |
| 97 | * to make sure that the performance counter really ticks, | 99 | * to make sure that the performance counter really ticks, |
| @@ -416,13 +418,13 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason) | |||
| 416 | 418 | ||
| 417 | /* We can be called before check_nmi_watchdog, hence NULL check. */ | 419 | /* We can be called before check_nmi_watchdog, hence NULL check. */ |
| 418 | if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) { | 420 | if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) { |
| 419 | static DEFINE_SPINLOCK(lock); /* Serialise the printks */ | 421 | static DEFINE_RAW_SPINLOCK(lock); /* Serialise the printks */ |
| 420 | 422 | ||
| 421 | spin_lock(&lock); | 423 | raw_spin_lock(&lock); |
| 422 | printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); | 424 | printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); |
| 423 | show_regs(regs); | 425 | show_regs(regs); |
| 424 | dump_stack(); | 426 | dump_stack(); |
| 425 | spin_unlock(&lock); | 427 | raw_spin_unlock(&lock); |
| 426 | cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); | 428 | cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); |
| 427 | 429 | ||
| 428 | rc = 1; | 430 | rc = 1; |
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index b5b6b23bce53..a920e00f321b 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c | |||
| @@ -1224,7 +1224,7 @@ static void reinit_timer(void) | |||
| 1224 | #ifdef INIT_TIMER_AFTER_SUSPEND | 1224 | #ifdef INIT_TIMER_AFTER_SUSPEND |
| 1225 | unsigned long flags; | 1225 | unsigned long flags; |
| 1226 | 1226 | ||
| 1227 | spin_lock_irqsave(&i8253_lock, flags); | 1227 | raw_spin_lock_irqsave(&i8253_lock, flags); |
| 1228 | /* set the clock to HZ */ | 1228 | /* set the clock to HZ */ |
| 1229 | outb_pit(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */ | 1229 | outb_pit(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */ |
| 1230 | udelay(10); | 1230 | udelay(10); |
| @@ -1232,7 +1232,7 @@ static void reinit_timer(void) | |||
| 1232 | udelay(10); | 1232 | udelay(10); |
| 1233 | outb_pit(LATCH >> 8, PIT_CH0); /* MSB */ | 1233 | outb_pit(LATCH >> 8, PIT_CH0); /* MSB */ |
| 1234 | udelay(10); | 1234 | udelay(10); |
| 1235 | spin_unlock_irqrestore(&i8253_lock, flags); | 1235 | raw_spin_unlock_irqrestore(&i8253_lock, flags); |
| 1236 | #endif | 1236 | #endif |
| 1237 | } | 1237 | } |
| 1238 | 1238 | ||
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 4868e4a951ee..fae7a32cb040 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
| @@ -1013,7 +1013,9 @@ DEFINE_PER_CPU(unsigned int, irq_count) = -1; | |||
| 1013 | */ | 1013 | */ |
| 1014 | static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = { | 1014 | static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = { |
| 1015 | [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, | 1015 | [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, |
| 1016 | #if DEBUG_STACK > 0 | ||
| 1016 | [DEBUG_STACK - 1] = DEBUG_STKSZ | 1017 | [DEBUG_STACK - 1] = DEBUG_STKSZ |
| 1018 | #endif | ||
| 1017 | }; | 1019 | }; |
| 1018 | 1020 | ||
| 1019 | static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks | 1021 | static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks |
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 55da0c5f68dd..46f40f07631a 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c | |||
| @@ -570,7 +570,7 @@ static unsigned long set_mtrr_state(void) | |||
| 570 | 570 | ||
| 571 | 571 | ||
| 572 | static unsigned long cr4; | 572 | static unsigned long cr4; |
| 573 | static DEFINE_SPINLOCK(set_atomicity_lock); | 573 | static DEFINE_RAW_SPINLOCK(set_atomicity_lock); |
| 574 | 574 | ||
| 575 | /* | 575 | /* |
| 576 | * Since we are disabling the cache don't allow any interrupts, | 576 | * Since we are disabling the cache don't allow any interrupts, |
| @@ -590,7 +590,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock) | |||
| 590 | * changes to the way the kernel boots | 590 | * changes to the way the kernel boots |
| 591 | */ | 591 | */ |
| 592 | 592 | ||
| 593 | spin_lock(&set_atomicity_lock); | 593 | raw_spin_lock(&set_atomicity_lock); |
| 594 | 594 | ||
| 595 | /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */ | 595 | /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */ |
| 596 | cr0 = read_cr0() | X86_CR0_CD; | 596 | cr0 = read_cr0() | X86_CR0_CD; |
| @@ -627,7 +627,7 @@ static void post_set(void) __releases(set_atomicity_lock) | |||
| 627 | /* Restore value of CR4 */ | 627 | /* Restore value of CR4 */ |
| 628 | if (cpu_has_pge) | 628 | if (cpu_has_pge) |
| 629 | write_cr4(cr4); | 629 | write_cr4(cr4); |
| 630 | spin_unlock(&set_atomicity_lock); | 630 | raw_spin_unlock(&set_atomicity_lock); |
| 631 | } | 631 | } |
| 632 | 632 | ||
| 633 | static void generic_set_all(void) | 633 | static void generic_set_all(void) |
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index ae775ca47b25..04078f1896e6 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
| @@ -98,6 +98,12 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | 100 | ||
| 101 | #if defined(CONFIG_DEBUG_STACKOVERFLOW) && defined(CONFIG_EVENT_TRACE) | ||
| 102 | extern unsigned long worst_stack_left; | ||
| 103 | #else | ||
| 104 | # define worst_stack_left -1L | ||
| 105 | #endif | ||
| 106 | |||
| 101 | void show_registers(struct pt_regs *regs) | 107 | void show_registers(struct pt_regs *regs) |
| 102 | { | 108 | { |
| 103 | int i; | 109 | int i; |
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index a6c906c9b193..9c0393ad255a 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
| @@ -22,10 +22,14 @@ | |||
| 22 | (N_EXCEPTION_STACKS + DEBUG_STKSZ/EXCEPTION_STKSZ - 2) | 22 | (N_EXCEPTION_STACKS + DEBUG_STKSZ/EXCEPTION_STKSZ - 2) |
| 23 | 23 | ||
| 24 | static char x86_stack_ids[][8] = { | 24 | static char x86_stack_ids[][8] = { |
| 25 | #if DEBUG_STACK > 0 | ||
| 25 | [ DEBUG_STACK-1 ] = "#DB", | 26 | [ DEBUG_STACK-1 ] = "#DB", |
| 27 | #endif | ||
| 26 | [ NMI_STACK-1 ] = "NMI", | 28 | [ NMI_STACK-1 ] = "NMI", |
| 27 | [ DOUBLEFAULT_STACK-1 ] = "#DF", | 29 | [ DOUBLEFAULT_STACK-1 ] = "#DF", |
| 30 | #if STACKFAULT_STACK > 0 | ||
| 28 | [ STACKFAULT_STACK-1 ] = "#SS", | 31 | [ STACKFAULT_STACK-1 ] = "#SS", |
| 32 | #endif | ||
| 29 | [ MCE_STACK-1 ] = "#MC", | 33 | [ MCE_STACK-1 ] = "#MC", |
| 30 | #if DEBUG_STKSZ > EXCEPTION_STKSZ | 34 | #if DEBUG_STKSZ > EXCEPTION_STKSZ |
| 31 | [ N_EXCEPTION_STACKS ... | 35 | [ N_EXCEPTION_STACKS ... |
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index b9c830c12b4a..02aaf8f65c8e 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c | |||
| @@ -59,7 +59,7 @@ static void early_vga_write(struct console *con, const char *str, unsigned n) | |||
| 59 | static struct console early_vga_console = { | 59 | static struct console early_vga_console = { |
| 60 | .name = "earlyvga", | 60 | .name = "earlyvga", |
| 61 | .write = early_vga_write, | 61 | .write = early_vga_write, |
| 62 | .flags = CON_PRINTBUFFER, | 62 | .flags = CON_PRINTBUFFER | CON_ATOMIC, |
| 63 | .index = -1, | 63 | .index = -1, |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| @@ -156,7 +156,7 @@ static __init void early_serial_init(char *s) | |||
| 156 | static struct console early_serial_console = { | 156 | static struct console early_serial_console = { |
| 157 | .name = "earlyser", | 157 | .name = "earlyser", |
| 158 | .write = early_serial_write, | 158 | .write = early_serial_write, |
| 159 | .flags = CON_PRINTBUFFER, | 159 | .flags = CON_PRINTBUFFER | CON_ATOMIC, |
| 160 | .index = -1, | 160 | .index = -1, |
| 161 | }; | 161 | }; |
| 162 | 162 | ||
| @@ -166,7 +166,7 @@ static int __initdata early_console_initialized; | |||
| 166 | 166 | ||
| 167 | asmlinkage void early_printk(const char *fmt, ...) | 167 | asmlinkage void early_printk(const char *fmt, ...) |
| 168 | { | 168 | { |
| 169 | char buf[512]; | 169 | static char buf[512]; |
| 170 | int n; | 170 | int n; |
| 171 | va_list ap; | 171 | va_list ap; |
| 172 | 172 | ||
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 44a8e0dc6737..3dc8593dd2aa 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
| @@ -375,15 +375,18 @@ END(ret_from_exception) | |||
| 375 | ENTRY(resume_kernel) | 375 | ENTRY(resume_kernel) |
| 376 | DISABLE_INTERRUPTS(CLBR_ANY) | 376 | DISABLE_INTERRUPTS(CLBR_ANY) |
| 377 | cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? | 377 | cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? |
| 378 | jnz restore_all | 378 | jnz restore_nocheck_trace |
| 379 | need_resched: | 379 | need_resched: |
| 380 | movl TI_flags(%ebp), %ecx # need_resched set ? | 380 | movl TI_flags(%ebp), %ecx # need_resched set ? |
| 381 | testb $_TIF_NEED_RESCHED, %cl | 381 | testb $_TIF_NEED_RESCHED, %cl |
| 382 | jz restore_all | 382 | jz restore_nocheck_trace |
| 383 | testl $X86_EFLAGS_IF,PT_EFLAGS(%esp) # interrupts off (exception path) ? | 383 | testl $X86_EFLAGS_IF,PT_EFLAGS(%esp) # interrupts off (exception path) ? |
| 384 | jz restore_all | 384 | jz restore_nocheck_trace |
| 385 | call preempt_schedule_irq | 385 | call preempt_schedule_irq |
| 386 | jmp need_resched | 386 | jmp need_resched |
| 387 | restore_nocheck_trace: | ||
| 388 | TRACE_IRQS_IRET | ||
| 389 | jmp restore_nocheck | ||
| 387 | END(resume_kernel) | 390 | END(resume_kernel) |
| 388 | #endif | 391 | #endif |
| 389 | CFI_ENDPROC | 392 | CFI_ENDPROC |
| @@ -639,12 +642,9 @@ work_pending: | |||
| 639 | testb $_TIF_NEED_RESCHED, %cl | 642 | testb $_TIF_NEED_RESCHED, %cl |
| 640 | jz work_notifysig | 643 | jz work_notifysig |
| 641 | work_resched: | 644 | work_resched: |
| 642 | call schedule | 645 | call __schedule |
| 643 | LOCKDEP_SYS_EXIT | 646 | LOCKDEP_SYS_EXIT |
| 644 | DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt | 647 | |
| 645 | # setting need_resched or sigpending | ||
| 646 | # between sampling and the iret | ||
| 647 | TRACE_IRQS_OFF | ||
| 648 | movl TI_flags(%ebp), %ecx | 648 | movl TI_flags(%ebp), %ecx |
| 649 | andl $_TIF_WORK_MASK, %ecx # is there any work to be done other | 649 | andl $_TIF_WORK_MASK, %ecx # is there any work to be done other |
| 650 | # than syscall tracing? | 650 | # than syscall tracing? |
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index b5a9896ca1e7..8e77347df3e1 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
| @@ -30,7 +30,11 @@ static void __init zap_identity_mappings(void) | |||
| 30 | { | 30 | { |
| 31 | pgd_t *pgd = pgd_offset_k(0UL); | 31 | pgd_t *pgd = pgd_offset_k(0UL); |
| 32 | pgd_clear(pgd); | 32 | pgd_clear(pgd); |
| 33 | __flush_tlb_all(); | 33 | /* |
| 34 | * preempt_disable/enable does not work this early in the | ||
| 35 | * bootup yet: | ||
| 36 | */ | ||
| 37 | write_cr3(read_cr3()); | ||
| 34 | } | 38 | } |
| 35 | 39 | ||
| 36 | /* Don't add a printk in there. printk relies on the PDA which is not initialized | 40 | /* Don't add a printk in there. printk relies on the PDA which is not initialized |
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 7fd318bac59c..4fabb366f82e 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
| @@ -596,6 +596,7 @@ ignore_int: | |||
| 596 | call dump_stack | 596 | call dump_stack |
| 597 | 597 | ||
| 598 | addl $(5*4),%esp | 598 | addl $(5*4),%esp |
| 599 | call dump_stack | ||
| 599 | popl %ds | 600 | popl %ds |
| 600 | popl %es | 601 | popl %es |
| 601 | popl %edx | 602 | popl %edx |
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c index 23c167925a5c..2dfd31597443 100644 --- a/arch/x86/kernel/i8253.c +++ b/arch/x86/kernel/i8253.c | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include <asm/hpet.h> | 16 | #include <asm/hpet.h> |
| 17 | #include <asm/smp.h> | 17 | #include <asm/smp.h> |
| 18 | 18 | ||
| 19 | DEFINE_SPINLOCK(i8253_lock); | 19 | DEFINE_RAW_SPINLOCK(i8253_lock); |
| 20 | EXPORT_SYMBOL(i8253_lock); | 20 | EXPORT_SYMBOL(i8253_lock); |
| 21 | 21 | ||
| 22 | /* | 22 | /* |
| @@ -33,7 +33,7 @@ struct clock_event_device *global_clock_event; | |||
| 33 | static void init_pit_timer(enum clock_event_mode mode, | 33 | static void init_pit_timer(enum clock_event_mode mode, |
| 34 | struct clock_event_device *evt) | 34 | struct clock_event_device *evt) |
| 35 | { | 35 | { |
| 36 | spin_lock(&i8253_lock); | 36 | raw_spin_lock(&i8253_lock); |
| 37 | 37 | ||
| 38 | switch (mode) { | 38 | switch (mode) { |
| 39 | case CLOCK_EVT_MODE_PERIODIC: | 39 | case CLOCK_EVT_MODE_PERIODIC: |
| @@ -62,7 +62,7 @@ static void init_pit_timer(enum clock_event_mode mode, | |||
| 62 | /* Nothing to do here */ | 62 | /* Nothing to do here */ |
| 63 | break; | 63 | break; |
| 64 | } | 64 | } |
| 65 | spin_unlock(&i8253_lock); | 65 | raw_spin_unlock(&i8253_lock); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | /* | 68 | /* |
| @@ -72,10 +72,10 @@ static void init_pit_timer(enum clock_event_mode mode, | |||
| 72 | */ | 72 | */ |
| 73 | static int pit_next_event(unsigned long delta, struct clock_event_device *evt) | 73 | static int pit_next_event(unsigned long delta, struct clock_event_device *evt) |
| 74 | { | 74 | { |
| 75 | spin_lock(&i8253_lock); | 75 | raw_spin_lock(&i8253_lock); |
| 76 | outb_pit(delta & 0xff , PIT_CH0); /* LSB */ | 76 | outb_pit(delta & 0xff , PIT_CH0); /* LSB */ |
| 77 | outb_pit(delta >> 8 , PIT_CH0); /* MSB */ | 77 | outb_pit(delta >> 8 , PIT_CH0); /* MSB */ |
| 78 | spin_unlock(&i8253_lock); | 78 | raw_spin_unlock(&i8253_lock); |
| 79 | 79 | ||
| 80 | return 0; | 80 | return 0; |
| 81 | } | 81 | } |
| @@ -130,7 +130,7 @@ static cycle_t pit_read(struct clocksource *cs) | |||
| 130 | int count; | 130 | int count; |
| 131 | u32 jifs; | 131 | u32 jifs; |
| 132 | 132 | ||
| 133 | spin_lock_irqsave(&i8253_lock, flags); | 133 | raw_spin_lock_irqsave(&i8253_lock, flags); |
| 134 | /* | 134 | /* |
| 135 | * Although our caller may have the read side of xtime_lock, | 135 | * Although our caller may have the read side of xtime_lock, |
| 136 | * this is now a seqlock, and we are cheating in this routine | 136 | * this is now a seqlock, and we are cheating in this routine |
| @@ -176,7 +176,7 @@ static cycle_t pit_read(struct clocksource *cs) | |||
| 176 | old_count = count; | 176 | old_count = count; |
| 177 | old_jifs = jifs; | 177 | old_jifs = jifs; |
| 178 | 178 | ||
| 179 | spin_unlock_irqrestore(&i8253_lock, flags); | 179 | raw_spin_unlock_irqrestore(&i8253_lock, flags); |
| 180 | 180 | ||
| 181 | count = (LATCH - 1) - count; | 181 | count = (LATCH - 1) - count; |
| 182 | 182 | ||
diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index df89102bef80..96400fe7909f 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | static int i8259A_auto_eoi; | 34 | static int i8259A_auto_eoi; |
| 35 | DEFINE_SPINLOCK(i8259A_lock); | 35 | DEFINE_RAW_SPINLOCK(i8259A_lock); |
| 36 | static void mask_and_ack_8259A(unsigned int); | 36 | static void mask_and_ack_8259A(unsigned int); |
| 37 | 37 | ||
| 38 | struct irq_chip i8259A_chip = { | 38 | struct irq_chip i8259A_chip = { |
| @@ -68,13 +68,13 @@ void disable_8259A_irq(unsigned int irq) | |||
| 68 | unsigned int mask = 1 << irq; | 68 | unsigned int mask = 1 << irq; |
| 69 | unsigned long flags; | 69 | unsigned long flags; |
| 70 | 70 | ||
| 71 | spin_lock_irqsave(&i8259A_lock, flags); | 71 | raw_spin_lock_irqsave(&i8259A_lock, flags); |
| 72 | cached_irq_mask |= mask; | 72 | cached_irq_mask |= mask; |
| 73 | if (irq & 8) | 73 | if (irq & 8) |
| 74 | outb(cached_slave_mask, PIC_SLAVE_IMR); | 74 | outb(cached_slave_mask, PIC_SLAVE_IMR); |
| 75 | else | 75 | else |
| 76 | outb(cached_master_mask, PIC_MASTER_IMR); | 76 | outb(cached_master_mask, PIC_MASTER_IMR); |
| 77 | spin_unlock_irqrestore(&i8259A_lock, flags); | 77 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | void enable_8259A_irq(unsigned int irq) | 80 | void enable_8259A_irq(unsigned int irq) |
| @@ -82,13 +82,13 @@ void enable_8259A_irq(unsigned int irq) | |||
| 82 | unsigned int mask = ~(1 << irq); | 82 | unsigned int mask = ~(1 << irq); |
| 83 | unsigned long flags; | 83 | unsigned long flags; |
| 84 | 84 | ||
| 85 | spin_lock_irqsave(&i8259A_lock, flags); | 85 | raw_spin_lock_irqsave(&i8259A_lock, flags); |
| 86 | cached_irq_mask &= mask; | 86 | cached_irq_mask &= mask; |
| 87 | if (irq & 8) | 87 | if (irq & 8) |
| 88 | outb(cached_slave_mask, PIC_SLAVE_IMR); | 88 | outb(cached_slave_mask, PIC_SLAVE_IMR); |
| 89 | else | 89 | else |
| 90 | outb(cached_master_mask, PIC_MASTER_IMR); | 90 | outb(cached_master_mask, PIC_MASTER_IMR); |
| 91 | spin_unlock_irqrestore(&i8259A_lock, flags); | 91 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | int i8259A_irq_pending(unsigned int irq) | 94 | int i8259A_irq_pending(unsigned int irq) |
| @@ -97,12 +97,12 @@ int i8259A_irq_pending(unsigned int irq) | |||
| 97 | unsigned long flags; | 97 | unsigned long flags; |
| 98 | int ret; | 98 | int ret; |
| 99 | 99 | ||
| 100 | spin_lock_irqsave(&i8259A_lock, flags); | 100 | raw_spin_lock_irqsave(&i8259A_lock, flags); |
| 101 | if (irq < 8) | 101 | if (irq < 8) |
| 102 | ret = inb(PIC_MASTER_CMD) & mask; | 102 | ret = inb(PIC_MASTER_CMD) & mask; |
| 103 | else | 103 | else |
| 104 | ret = inb(PIC_SLAVE_CMD) & (mask >> 8); | 104 | ret = inb(PIC_SLAVE_CMD) & (mask >> 8); |
| 105 | spin_unlock_irqrestore(&i8259A_lock, flags); | 105 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
| 106 | 106 | ||
| 107 | return ret; | 107 | return ret; |
| 108 | } | 108 | } |
| @@ -150,7 +150,7 @@ static void mask_and_ack_8259A(unsigned int irq) | |||
| 150 | unsigned int irqmask = 1 << irq; | 150 | unsigned int irqmask = 1 << irq; |
| 151 | unsigned long flags; | 151 | unsigned long flags; |
| 152 | 152 | ||
| 153 | spin_lock_irqsave(&i8259A_lock, flags); | 153 | raw_spin_lock_irqsave(&i8259A_lock, flags); |
| 154 | /* | 154 | /* |
| 155 | * Lightweight spurious IRQ detection. We do not want | 155 | * Lightweight spurious IRQ detection. We do not want |
| 156 | * to overdo spurious IRQ handling - it's usually a sign | 156 | * to overdo spurious IRQ handling - it's usually a sign |
| @@ -168,6 +168,8 @@ static void mask_and_ack_8259A(unsigned int irq) | |||
| 168 | */ | 168 | */ |
| 169 | if (cached_irq_mask & irqmask) | 169 | if (cached_irq_mask & irqmask) |
| 170 | goto spurious_8259A_irq; | 170 | goto spurious_8259A_irq; |
| 171 | if (irq & 8) | ||
| 172 | outb(0x60+(irq&7), PIC_SLAVE_CMD); /* 'Specific EOI' to slave */ | ||
| 171 | cached_irq_mask |= irqmask; | 173 | cached_irq_mask |= irqmask; |
| 172 | 174 | ||
| 173 | handle_real_irq: | 175 | handle_real_irq: |
| @@ -183,7 +185,7 @@ handle_real_irq: | |||
| 183 | outb(cached_master_mask, PIC_MASTER_IMR); | 185 | outb(cached_master_mask, PIC_MASTER_IMR); |
| 184 | outb(0x60+irq, PIC_MASTER_CMD); /* 'Specific EOI to master */ | 186 | outb(0x60+irq, PIC_MASTER_CMD); /* 'Specific EOI to master */ |
| 185 | } | 187 | } |
| 186 | spin_unlock_irqrestore(&i8259A_lock, flags); | 188 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
| 187 | return; | 189 | return; |
| 188 | 190 | ||
| 189 | spurious_8259A_irq: | 191 | spurious_8259A_irq: |
| @@ -285,24 +287,24 @@ void mask_8259A(void) | |||
| 285 | { | 287 | { |
| 286 | unsigned long flags; | 288 | unsigned long flags; |
| 287 | 289 | ||
| 288 | spin_lock_irqsave(&i8259A_lock, flags); | 290 | raw_spin_lock_irqsave(&i8259A_lock, flags); |
| 289 | 291 | ||
| 290 | outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ | 292 | outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ |
| 291 | outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ | 293 | outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ |
| 292 | 294 | ||
| 293 | spin_unlock_irqrestore(&i8259A_lock, flags); | 295 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
| 294 | } | 296 | } |
| 295 | 297 | ||
| 296 | void unmask_8259A(void) | 298 | void unmask_8259A(void) |
| 297 | { | 299 | { |
| 298 | unsigned long flags; | 300 | unsigned long flags; |
| 299 | 301 | ||
| 300 | spin_lock_irqsave(&i8259A_lock, flags); | 302 | raw_spin_lock_irqsave(&i8259A_lock, flags); |
| 301 | 303 | ||
| 302 | outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */ | 304 | outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */ |
| 303 | outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */ | 305 | outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */ |
| 304 | 306 | ||
| 305 | spin_unlock_irqrestore(&i8259A_lock, flags); | 307 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
| 306 | } | 308 | } |
| 307 | 309 | ||
| 308 | void init_8259A(int auto_eoi) | 310 | void init_8259A(int auto_eoi) |
| @@ -311,7 +313,7 @@ void init_8259A(int auto_eoi) | |||
| 311 | 313 | ||
| 312 | i8259A_auto_eoi = auto_eoi; | 314 | i8259A_auto_eoi = auto_eoi; |
| 313 | 315 | ||
| 314 | spin_lock_irqsave(&i8259A_lock, flags); | 316 | raw_spin_lock_irqsave(&i8259A_lock, flags); |
| 315 | 317 | ||
| 316 | outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ | 318 | outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ |
| 317 | outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ | 319 | outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ |
| @@ -328,10 +330,10 @@ void init_8259A(int auto_eoi) | |||
| 328 | /* 8259A-1 (the master) has a slave on IR2 */ | 330 | /* 8259A-1 (the master) has a slave on IR2 */ |
| 329 | outb_pic(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); | 331 | outb_pic(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); |
| 330 | 332 | ||
| 331 | if (auto_eoi) /* master does Auto EOI */ | 333 | if (!auto_eoi) /* master expects normal EOI */ |
| 332 | outb_pic(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR); | 334 | outb_p(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR); |
| 333 | else /* master expects normal EOI */ | 335 | else /* master does Auto EOI */ |
| 334 | outb_pic(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR); | 336 | outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR); |
| 335 | 337 | ||
| 336 | outb_pic(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */ | 338 | outb_pic(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */ |
| 337 | 339 | ||
| @@ -356,5 +358,5 @@ void init_8259A(int auto_eoi) | |||
| 356 | outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */ | 358 | outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */ |
| 357 | outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */ | 359 | outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */ |
| 358 | 360 | ||
| 359 | spin_unlock_irqrestore(&i8259A_lock, flags); | 361 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
| 360 | } | 362 | } |
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index d5932226614f..7cdd31ca342d 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c | |||
| @@ -72,6 +72,7 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id) | |||
| 72 | static struct irqaction fpu_irq = { | 72 | static struct irqaction fpu_irq = { |
| 73 | .handler = math_error_irq, | 73 | .handler = math_error_irq, |
| 74 | .name = "fpu", | 74 | .name = "fpu", |
| 75 | .flags = IRQF_NODELAY, | ||
| 75 | }; | 76 | }; |
| 76 | #endif | 77 | #endif |
| 77 | 78 | ||
| @@ -81,6 +82,7 @@ static struct irqaction fpu_irq = { | |||
| 81 | static struct irqaction irq2 = { | 82 | static struct irqaction irq2 = { |
| 82 | .handler = no_action, | 83 | .handler = no_action, |
| 83 | .name = "cascade", | 84 | .name = "cascade", |
| 85 | .flags = IRQF_NODELAY, | ||
| 84 | }; | 86 | }; |
| 85 | 87 | ||
| 86 | DEFINE_PER_CPU(vector_irq_t, vector_irq) = { | 88 | DEFINE_PER_CPU(vector_irq_t, vector_irq) = { |
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index 5b8c7505b3bc..04bc8c9c43f9 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
| @@ -434,7 +434,7 @@ static void __kprobes setup_singlestep(struct kprobe *p, struct pt_regs *regs, | |||
| 434 | /* Boost up -- we can execute copied instructions directly */ | 434 | /* Boost up -- we can execute copied instructions directly */ |
| 435 | reset_current_kprobe(); | 435 | reset_current_kprobe(); |
| 436 | regs->ip = (unsigned long)p->ainsn.insn; | 436 | regs->ip = (unsigned long)p->ainsn.insn; |
| 437 | preempt_enable_no_resched(); | 437 | preempt_enable(); |
| 438 | return; | 438 | return; |
| 439 | } | 439 | } |
| 440 | #endif | 440 | #endif |
| @@ -543,7 +543,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
| 543 | } | 543 | } |
| 544 | } /* else: not a kprobe fault; let the kernel handle it */ | 544 | } /* else: not a kprobe fault; let the kernel handle it */ |
| 545 | 545 | ||
| 546 | preempt_enable_no_resched(); | 546 | preempt_enable(); |
| 547 | return 0; | 547 | return 0; |
| 548 | } | 548 | } |
| 549 | 549 | ||
| @@ -843,7 +843,7 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs) | |||
| 843 | } | 843 | } |
| 844 | reset_current_kprobe(); | 844 | reset_current_kprobe(); |
| 845 | out: | 845 | out: |
| 846 | preempt_enable_no_resched(); | 846 | preempt_enable(); |
| 847 | 847 | ||
| 848 | /* | 848 | /* |
| 849 | * if somebody else is singlestepping across a probe point, flags | 849 | * if somebody else is singlestepping across a probe point, flags |
| @@ -877,7 +877,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | |||
| 877 | restore_previous_kprobe(kcb); | 877 | restore_previous_kprobe(kcb); |
| 878 | else | 878 | else |
| 879 | reset_current_kprobe(); | 879 | reset_current_kprobe(); |
| 880 | preempt_enable_no_resched(); | 880 | preempt_enable(); |
| 881 | break; | 881 | break; |
| 882 | case KPROBE_HIT_ACTIVE: | 882 | case KPROBE_HIT_ACTIVE: |
| 883 | case KPROBE_HIT_SSDONE: | 883 | case KPROBE_HIT_SSDONE: |
| @@ -1024,7 +1024,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
| 1024 | memcpy((kprobe_opcode_t *)(kcb->jprobe_saved_sp), | 1024 | memcpy((kprobe_opcode_t *)(kcb->jprobe_saved_sp), |
| 1025 | kcb->jprobes_stack, | 1025 | kcb->jprobes_stack, |
| 1026 | MIN_STACK_SIZE(kcb->jprobe_saved_sp)); | 1026 | MIN_STACK_SIZE(kcb->jprobe_saved_sp)); |
| 1027 | preempt_enable_no_resched(); | 1027 | preempt_enable(); |
| 1028 | return 1; | 1028 | return 1; |
| 1029 | } | 1029 | } |
| 1030 | return 0; | 1030 | return 0; |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 1b1739d16310..024d2c1b751e 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
| @@ -396,6 +396,20 @@ struct pv_apic_ops pv_apic_ops = { | |||
| 396 | #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64) | 396 | #define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64) |
| 397 | #endif | 397 | #endif |
| 398 | 398 | ||
| 399 | #ifdef CONFIG_HIGHPTE | ||
| 400 | /* | ||
| 401 | * kmap_atomic() might be an inline or a macro: | ||
| 402 | */ | ||
| 403 | static void *kmap_atomic_func(struct page *page, enum km_type idx) | ||
| 404 | { | ||
| 405 | return kmap_atomic(page, idx); | ||
| 406 | } | ||
| 407 | static void *kmap_atomic_direct_func(struct page *page, enum km_type idx) | ||
| 408 | { | ||
| 409 | return kmap_atomic_direct(page, idx); | ||
| 410 | } | ||
| 411 | #endif | ||
| 412 | |||
| 399 | struct pv_mmu_ops pv_mmu_ops = { | 413 | struct pv_mmu_ops pv_mmu_ops = { |
| 400 | 414 | ||
| 401 | .read_cr2 = native_read_cr2, | 415 | .read_cr2 = native_read_cr2, |
| @@ -429,7 +443,8 @@ struct pv_mmu_ops pv_mmu_ops = { | |||
| 429 | .ptep_modify_prot_commit = __ptep_modify_prot_commit, | 443 | .ptep_modify_prot_commit = __ptep_modify_prot_commit, |
| 430 | 444 | ||
| 431 | #ifdef CONFIG_HIGHPTE | 445 | #ifdef CONFIG_HIGHPTE |
| 432 | .kmap_atomic_pte = kmap_atomic, | 446 | .kmap_atomic_pte = kmap_atomic_func, |
| 447 | .kmap_atomic_pte_direct = kmap_atomic_direct_func, | ||
| 433 | #endif | 448 | #endif |
| 434 | 449 | ||
| 435 | #if PAGETABLE_LEVELS >= 3 | 450 | #if PAGETABLE_LEVELS >= 3 |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 37ad1e046aae..46f588151d92 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
| @@ -101,7 +101,6 @@ void cpu_idle(void) | |||
| 101 | tick_nohz_stop_sched_tick(1); | 101 | tick_nohz_stop_sched_tick(1); |
| 102 | while (!need_resched()) { | 102 | while (!need_resched()) { |
| 103 | 103 | ||
| 104 | check_pgt_cache(); | ||
| 105 | rmb(); | 104 | rmb(); |
| 106 | 105 | ||
| 107 | if (cpu_is_offline(cpu)) | 106 | if (cpu_is_offline(cpu)) |
| @@ -113,10 +112,12 @@ void cpu_idle(void) | |||
| 113 | pm_idle(); | 112 | pm_idle(); |
| 114 | start_critical_timings(); | 113 | start_critical_timings(); |
| 115 | } | 114 | } |
| 115 | local_irq_disable(); | ||
| 116 | tick_nohz_restart_sched_tick(); | 116 | tick_nohz_restart_sched_tick(); |
| 117 | preempt_enable_no_resched(); | 117 | __preempt_enable_no_resched(); |
| 118 | schedule(); | 118 | __schedule(); |
| 119 | preempt_disable(); | 119 | preempt_disable(); |
| 120 | local_irq_enable(); | ||
| 120 | } | 121 | } |
| 121 | } | 122 | } |
| 122 | 123 | ||
| @@ -148,8 +149,10 @@ void __show_regs(struct pt_regs *regs, int all) | |||
| 148 | regs->ax, regs->bx, regs->cx, regs->dx); | 149 | regs->ax, regs->bx, regs->cx, regs->dx); |
| 149 | printk(KERN_DEFAULT "ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n", | 150 | printk(KERN_DEFAULT "ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n", |
| 150 | regs->si, regs->di, regs->bp, sp); | 151 | regs->si, regs->di, regs->bp, sp); |
| 151 | printk(KERN_DEFAULT " DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n", | 152 | printk(KERN_DEFAULT |
| 152 | (u16)regs->ds, (u16)regs->es, (u16)regs->fs, gs, ss); | 153 | " DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x preempt:%08x\n", |
| 154 | (u16)regs->ds, (u16)regs->es, (u16)regs->fs, gs, ss, | ||
| 155 | preempt_count()); | ||
| 153 | 156 | ||
| 154 | if (!all) | 157 | if (!all) |
| 155 | return; | 158 | return; |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 11d0702f0e0d..259f8ce8c0fe 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
| @@ -146,9 +146,11 @@ void cpu_idle(void) | |||
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | tick_nohz_restart_sched_tick(); | 148 | tick_nohz_restart_sched_tick(); |
| 149 | preempt_enable_no_resched(); | 149 | local_irq_disable(); |
| 150 | schedule(); | 150 | __preempt_enable_no_resched(); |
| 151 | __schedule(); | ||
| 151 | preempt_disable(); | 152 | preempt_disable(); |
| 153 | local_irq_enable(); | ||
| 152 | } | 154 | } |
| 153 | } | 155 | } |
| 154 | 156 | ||
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 4fd173cd8e57..fccd2c885ba2 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
| @@ -773,6 +773,13 @@ static void do_signal(struct pt_regs *regs) | |||
| 773 | int signr; | 773 | int signr; |
| 774 | sigset_t *oldset; | 774 | sigset_t *oldset; |
| 775 | 775 | ||
| 776 | #ifdef CONFIG_PREEMPT_RT | ||
| 777 | /* | ||
| 778 | * Fully-preemptible kernel does not need interrupts disabled: | ||
| 779 | */ | ||
| 780 | local_irq_enable(); | ||
| 781 | preempt_check_resched(); | ||
| 782 | #endif | ||
| 776 | /* | 783 | /* |
| 777 | * We want the common case to go fast, which is why we may in certain | 784 | * We want the common case to go fast, which is why we may in certain |
| 778 | * cases get here from kernel mode. Just return without doing anything | 785 | * cases get here from kernel mode. Just return without doing anything |
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index ec1de97600e7..a83e38d464f2 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c | |||
| @@ -120,6 +120,16 @@ static void native_smp_send_reschedule(int cpu) | |||
| 120 | apic->send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR); | 120 | apic->send_IPI_mask(cpumask_of(cpu), RESCHEDULE_VECTOR); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | /* | ||
| 124 | * this function sends a 'reschedule' IPI to all other CPUs. | ||
| 125 | * This is used when RT tasks are starving and other CPUs | ||
| 126 | * might be able to run them: | ||
| 127 | */ | ||
| 128 | void smp_send_reschedule_allbutself(void) | ||
| 129 | { | ||
| 130 | apic->send_IPI_allbutself(RESCHEDULE_VECTOR); | ||
| 131 | } | ||
| 132 | |||
| 123 | void native_send_call_func_single_ipi(int cpu) | 133 | void native_send_call_func_single_ipi(int cpu) |
| 124 | { | 134 | { |
| 125 | apic->send_IPI_mask(cpumask_of(cpu), CALL_FUNCTION_SINGLE_VECTOR); | 135 | apic->send_IPI_mask(cpumask_of(cpu), CALL_FUNCTION_SINGLE_VECTOR); |
diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c index be2573448ed9..fb5cc5e14cfa 100644 --- a/arch/x86/kernel/time.c +++ b/arch/x86/kernel/time.c | |||
| @@ -70,11 +70,11 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
| 70 | * manually to deassert NMI lines for the watchdog if run | 70 | * manually to deassert NMI lines for the watchdog if run |
| 71 | * on an 82489DX-based system. | 71 | * on an 82489DX-based system. |
| 72 | */ | 72 | */ |
| 73 | spin_lock(&i8259A_lock); | 73 | raw_spin_lock(&i8259A_lock); |
| 74 | outb(0x0c, PIC_MASTER_OCW3); | 74 | outb(0x0c, PIC_MASTER_OCW3); |
| 75 | /* Ack the IRQ; AEOI will end it automatically. */ | 75 | /* Ack the IRQ; AEOI will end it automatically. */ |
| 76 | inb(PIC_MASTER_POLL); | 76 | inb(PIC_MASTER_POLL); |
| 77 | spin_unlock(&i8259A_lock); | 77 | raw_spin_unlock(&i8259A_lock); |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | global_clock_event->event_handler(global_clock_event); | 80 | global_clock_event->event_handler(global_clock_event); |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 33399176512a..9288ccfcf6db 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
| @@ -88,9 +88,10 @@ static inline void conditional_sti(struct pt_regs *regs) | |||
| 88 | local_irq_enable(); | 88 | local_irq_enable(); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | static inline void preempt_conditional_sti(struct pt_regs *regs) | 91 | static inline void preempt_conditional_sti(struct pt_regs *regs, int stack) |
| 92 | { | 92 | { |
| 93 | inc_preempt_count(); | 93 | if (stack) |
| 94 | inc_preempt_count(); | ||
| 94 | if (regs->flags & X86_EFLAGS_IF) | 95 | if (regs->flags & X86_EFLAGS_IF) |
| 95 | local_irq_enable(); | 96 | local_irq_enable(); |
| 96 | } | 97 | } |
| @@ -101,11 +102,12 @@ static inline void conditional_cli(struct pt_regs *regs) | |||
| 101 | local_irq_disable(); | 102 | local_irq_disable(); |
| 102 | } | 103 | } |
| 103 | 104 | ||
| 104 | static inline void preempt_conditional_cli(struct pt_regs *regs) | 105 | static inline void preempt_conditional_cli(struct pt_regs *regs, int stack) |
| 105 | { | 106 | { |
| 106 | if (regs->flags & X86_EFLAGS_IF) | 107 | if (regs->flags & X86_EFLAGS_IF) |
| 107 | local_irq_disable(); | 108 | local_irq_disable(); |
| 108 | dec_preempt_count(); | 109 | if (stack) |
| 110 | dec_preempt_count(); | ||
| 109 | } | 111 | } |
| 110 | 112 | ||
| 111 | #ifdef CONFIG_X86_32 | 113 | #ifdef CONFIG_X86_32 |
| @@ -232,9 +234,9 @@ dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code) | |||
| 232 | if (notify_die(DIE_TRAP, "stack segment", regs, error_code, | 234 | if (notify_die(DIE_TRAP, "stack segment", regs, error_code, |
| 233 | 12, SIGBUS) == NOTIFY_STOP) | 235 | 12, SIGBUS) == NOTIFY_STOP) |
| 234 | return; | 236 | return; |
| 235 | preempt_conditional_sti(regs); | 237 | preempt_conditional_sti(regs, STACKFAULT_STACK); |
| 236 | do_trap(12, SIGBUS, "stack segment", regs, error_code, NULL); | 238 | do_trap(12, SIGBUS, "stack segment", regs, error_code, NULL); |
| 237 | preempt_conditional_cli(regs); | 239 | preempt_conditional_cli(regs, STACKFAULT_STACK); |
| 238 | } | 240 | } |
| 239 | 241 | ||
| 240 | dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) | 242 | dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) |
| @@ -470,9 +472,9 @@ dotraplinkage void __kprobes do_int3(struct pt_regs *regs, long error_code) | |||
| 470 | return; | 472 | return; |
| 471 | #endif | 473 | #endif |
| 472 | 474 | ||
| 473 | preempt_conditional_sti(regs); | 475 | preempt_conditional_sti(regs, DEBUG_STACK); |
| 474 | do_trap(3, SIGTRAP, "int3", regs, error_code, NULL); | 476 | do_trap(3, SIGTRAP, "int3", regs, error_code, NULL); |
| 475 | preempt_conditional_cli(regs); | 477 | preempt_conditional_cli(regs, DEBUG_STACK); |
| 476 | } | 478 | } |
| 477 | 479 | ||
| 478 | #ifdef CONFIG_X86_64 | 480 | #ifdef CONFIG_X86_64 |
| @@ -554,7 +556,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) | |||
| 554 | return; | 556 | return; |
| 555 | 557 | ||
| 556 | /* It's safe to allow irq's after DR6 has been saved */ | 558 | /* It's safe to allow irq's after DR6 has been saved */ |
| 557 | preempt_conditional_sti(regs); | 559 | preempt_conditional_sti(regs, DEBUG_STACK); |
| 558 | 560 | ||
| 559 | if (regs->flags & X86_VM_MASK) { | 561 | if (regs->flags & X86_VM_MASK) { |
| 560 | handle_vm86_trap((struct kernel_vm86_regs *) regs, | 562 | handle_vm86_trap((struct kernel_vm86_regs *) regs, |
| @@ -577,7 +579,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) | |||
| 577 | si_code = get_si_code(tsk->thread.debugreg6); | 579 | si_code = get_si_code(tsk->thread.debugreg6); |
| 578 | if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS)) | 580 | if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS)) |
| 579 | send_sigtrap(tsk, regs, error_code, si_code); | 581 | send_sigtrap(tsk, regs, error_code, si_code); |
| 580 | preempt_conditional_cli(regs); | 582 | preempt_conditional_cli(regs, DEBUG_STACK); |
| 581 | 583 | ||
| 582 | return; | 584 | return; |
| 583 | } | 585 | } |
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c index 34a279a7471d..ccbea12baef7 100644 --- a/arch/x86/kernel/visws_quirks.c +++ b/arch/x86/kernel/visws_quirks.c | |||
| @@ -559,7 +559,7 @@ static irqreturn_t piix4_master_intr(int irq, void *dev_id) | |||
| 559 | struct irq_desc *desc; | 559 | struct irq_desc *desc; |
| 560 | unsigned long flags; | 560 | unsigned long flags; |
| 561 | 561 | ||
| 562 | spin_lock_irqsave(&i8259A_lock, flags); | 562 | raw_spin_lock_irqsave(&i8259A_lock, flags); |
| 563 | 563 | ||
| 564 | /* Find out what's interrupting in the PIIX4 master 8259 */ | 564 | /* Find out what's interrupting in the PIIX4 master 8259 */ |
| 565 | outb(0x0c, 0x20); /* OCW3 Poll command */ | 565 | outb(0x0c, 0x20); /* OCW3 Poll command */ |
| @@ -596,7 +596,7 @@ static irqreturn_t piix4_master_intr(int irq, void *dev_id) | |||
| 596 | outb(0x60 + realirq, 0x20); | 596 | outb(0x60 + realirq, 0x20); |
| 597 | } | 597 | } |
| 598 | 598 | ||
| 599 | spin_unlock_irqrestore(&i8259A_lock, flags); | 599 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
| 600 | 600 | ||
| 601 | desc = irq_to_desc(realirq); | 601 | desc = irq_to_desc(realirq); |
| 602 | 602 | ||
| @@ -614,18 +614,20 @@ static irqreturn_t piix4_master_intr(int irq, void *dev_id) | |||
| 614 | return IRQ_HANDLED; | 614 | return IRQ_HANDLED; |
| 615 | 615 | ||
| 616 | out_unlock: | 616 | out_unlock: |
| 617 | spin_unlock_irqrestore(&i8259A_lock, flags); | 617 | raw_spin_unlock_irqrestore(&i8259A_lock, flags); |
| 618 | return IRQ_NONE; | 618 | return IRQ_NONE; |
| 619 | } | 619 | } |
| 620 | 620 | ||
| 621 | static struct irqaction master_action = { | 621 | static struct irqaction master_action = { |
| 622 | .handler = piix4_master_intr, | 622 | .handler = piix4_master_intr, |
| 623 | .name = "PIIX4-8259", | 623 | .name = "PIIX4-8259", |
| 624 | .flags = IRQF_NODELAY, | ||
| 624 | }; | 625 | }; |
| 625 | 626 | ||
| 626 | static struct irqaction cascade_action = { | 627 | static struct irqaction cascade_action = { |
| 627 | .handler = no_action, | 628 | .handler = no_action, |
| 628 | .name = "cascade", | 629 | .name = "cascade", |
| 630 | .flags = IRQF_NODELAY, | ||
| 629 | }; | 631 | }; |
| 630 | 632 | ||
| 631 | 633 | ||
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index 5ffb5622f793..8ea7e4869fc3 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c | |||
| @@ -137,6 +137,7 @@ struct pt_regs *save_v86_state(struct kernel_vm86_regs *regs) | |||
| 137 | local_irq_enable(); | 137 | local_irq_enable(); |
| 138 | 138 | ||
| 139 | if (!current->thread.vm86_info) { | 139 | if (!current->thread.vm86_info) { |
| 140 | local_irq_disable(); | ||
| 140 | printk("no vm86_info: BAD\n"); | 141 | printk("no vm86_info: BAD\n"); |
| 141 | do_exit(SIGSEGV); | 142 | do_exit(SIGSEGV); |
| 142 | } | 143 | } |
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 9055e5872ff0..1bd8ff302193 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c | |||
| @@ -59,7 +59,7 @@ int __vgetcpu_mode __section_vgetcpu_mode; | |||
| 59 | 59 | ||
| 60 | struct vsyscall_gtod_data __vsyscall_gtod_data __section_vsyscall_gtod_data = | 60 | struct vsyscall_gtod_data __vsyscall_gtod_data __section_vsyscall_gtod_data = |
| 61 | { | 61 | { |
| 62 | .lock = SEQLOCK_UNLOCKED, | 62 | .lock = __RAW_SEQLOCK_UNLOCKED(__vsyscall_gtod_data.lock), |
| 63 | .sysctl_enabled = 1, | 63 | .sysctl_enabled = 1, |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| @@ -67,10 +67,10 @@ void update_vsyscall_tz(void) | |||
| 67 | { | 67 | { |
| 68 | unsigned long flags; | 68 | unsigned long flags; |
| 69 | 69 | ||
| 70 | write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags); | 70 | write_raw_seqlock_irqsave(&vsyscall_gtod_data.lock, flags); |
| 71 | /* sys_tz has changed */ | 71 | /* sys_tz has changed */ |
| 72 | vsyscall_gtod_data.sys_tz = sys_tz; | 72 | vsyscall_gtod_data.sys_tz = sys_tz; |
| 73 | write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); | 73 | write_raw_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, | 76 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, |
| @@ -78,18 +78,45 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock, | |||
| 78 | { | 78 | { |
| 79 | unsigned long flags; | 79 | unsigned long flags; |
| 80 | 80 | ||
| 81 | write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags); | 81 | write_raw_seqlock_irqsave(&vsyscall_gtod_data.lock, flags); |
| 82 | |||
| 83 | if (likely(vsyscall_gtod_data.sysctl_enabled == 2)) { | ||
| 84 | struct timespec tmp = *(wall_time); | ||
| 85 | cycle_t (*vread)(void); | ||
| 86 | cycle_t now; | ||
| 87 | |||
| 88 | vread = vsyscall_gtod_data.clock.vread; | ||
| 89 | if (likely(vread)) | ||
| 90 | now = vread(); | ||
| 91 | else | ||
| 92 | now = clock->read(clock); | ||
| 93 | |||
| 94 | /* calculate interval: */ | ||
| 95 | now = (now - clock->cycle_last) & clock->mask; | ||
| 96 | /* convert to nsecs: */ | ||
| 97 | tmp.tv_nsec += ( now * clock->mult) >> clock->shift; | ||
| 98 | |||
| 99 | while (tmp.tv_nsec >= NSEC_PER_SEC) { | ||
| 100 | tmp.tv_sec += 1; | ||
| 101 | tmp.tv_nsec -= NSEC_PER_SEC; | ||
| 102 | } | ||
| 103 | |||
| 104 | vsyscall_gtod_data.wall_time_sec = tmp.tv_sec; | ||
| 105 | vsyscall_gtod_data.wall_time_nsec = tmp.tv_nsec; | ||
| 106 | } else { | ||
| 107 | vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; | ||
| 108 | vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; | ||
| 109 | } | ||
| 110 | |||
| 82 | /* copy vsyscall data */ | 111 | /* copy vsyscall data */ |
| 83 | vsyscall_gtod_data.clock.vread = clock->vread; | 112 | vsyscall_gtod_data.clock.vread = clock->vread; |
| 84 | vsyscall_gtod_data.clock.cycle_last = clock->cycle_last; | 113 | vsyscall_gtod_data.clock.cycle_last = clock->cycle_last; |
| 85 | vsyscall_gtod_data.clock.mask = clock->mask; | 114 | vsyscall_gtod_data.clock.mask = clock->mask; |
| 86 | vsyscall_gtod_data.clock.mult = mult; | 115 | vsyscall_gtod_data.clock.mult = mult; |
| 87 | vsyscall_gtod_data.clock.shift = clock->shift; | 116 | vsyscall_gtod_data.clock.shift = clock->shift; |
| 88 | vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; | ||
| 89 | vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; | ||
| 90 | vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic; | 117 | vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic; |
| 91 | vsyscall_gtod_data.wall_time_coarse = __current_kernel_time(); | 118 | vsyscall_gtod_data.wall_time_coarse = __current_kernel_time(); |
| 92 | write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); | 119 | write_raw_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); |
| 93 | } | 120 | } |
| 94 | 121 | ||
| 95 | /* RED-PEN may want to readd seq locking, but then the variable should be | 122 | /* RED-PEN may want to readd seq locking, but then the variable should be |
| @@ -125,8 +152,28 @@ static __always_inline void do_vgettimeofday(struct timeval * tv) | |||
| 125 | unsigned seq; | 152 | unsigned seq; |
| 126 | unsigned long mult, shift, nsec; | 153 | unsigned long mult, shift, nsec; |
| 127 | cycle_t (*vread)(void); | 154 | cycle_t (*vread)(void); |
| 155 | |||
| 156 | if (likely(__vsyscall_gtod_data.sysctl_enabled == 2)) { | ||
| 157 | struct timeval tmp; | ||
| 158 | |||
| 159 | do { | ||
| 160 | barrier(); | ||
| 161 | tv->tv_sec = __vsyscall_gtod_data.wall_time_sec; | ||
| 162 | tv->tv_usec = __vsyscall_gtod_data.wall_time_nsec; | ||
| 163 | barrier(); | ||
| 164 | tmp.tv_sec = __vsyscall_gtod_data.wall_time_sec; | ||
| 165 | tmp.tv_usec = __vsyscall_gtod_data.wall_time_nsec; | ||
| 166 | |||
| 167 | } while (tmp.tv_usec != tv->tv_usec || | ||
| 168 | tmp.tv_sec != tv->tv_sec); | ||
| 169 | |||
| 170 | tv->tv_usec /= NSEC_PER_MSEC; | ||
| 171 | tv->tv_usec *= USEC_PER_MSEC; | ||
| 172 | return; | ||
| 173 | } | ||
| 174 | |||
| 128 | do { | 175 | do { |
| 129 | seq = read_seqbegin(&__vsyscall_gtod_data.lock); | 176 | seq = read_raw_seqbegin(&__vsyscall_gtod_data.lock); |
| 130 | 177 | ||
| 131 | vread = __vsyscall_gtod_data.clock.vread; | 178 | vread = __vsyscall_gtod_data.clock.vread; |
| 132 | if (unlikely(!__vsyscall_gtod_data.sysctl_enabled || !vread)) { | 179 | if (unlikely(!__vsyscall_gtod_data.sysctl_enabled || !vread)) { |
| @@ -135,6 +182,7 @@ static __always_inline void do_vgettimeofday(struct timeval * tv) | |||
| 135 | } | 182 | } |
| 136 | 183 | ||
| 137 | now = vread(); | 184 | now = vread(); |
| 185 | |||
| 138 | base = __vsyscall_gtod_data.clock.cycle_last; | 186 | base = __vsyscall_gtod_data.clock.cycle_last; |
| 139 | mask = __vsyscall_gtod_data.clock.mask; | 187 | mask = __vsyscall_gtod_data.clock.mask; |
| 140 | mult = __vsyscall_gtod_data.clock.mult; | 188 | mult = __vsyscall_gtod_data.clock.mult; |
| @@ -142,7 +190,7 @@ static __always_inline void do_vgettimeofday(struct timeval * tv) | |||
| 142 | 190 | ||
| 143 | tv->tv_sec = __vsyscall_gtod_data.wall_time_sec; | 191 | tv->tv_sec = __vsyscall_gtod_data.wall_time_sec; |
| 144 | nsec = __vsyscall_gtod_data.wall_time_nsec; | 192 | nsec = __vsyscall_gtod_data.wall_time_nsec; |
| 145 | } while (read_seqretry(&__vsyscall_gtod_data.lock, seq)); | 193 | } while (read_raw_seqretry(&__vsyscall_gtod_data.lock, seq)); |
| 146 | 194 | ||
| 147 | /* calculate interval: */ | 195 | /* calculate interval: */ |
| 148 | cycle_delta = (now - base) & mask; | 196 | cycle_delta = (now - base) & mask; |
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 15578f180e59..6a9bee02ee54 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c | |||
| @@ -242,11 +242,11 @@ static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian) | |||
| 242 | { | 242 | { |
| 243 | struct kvm_kpit_state *ps = container_of(kian, struct kvm_kpit_state, | 243 | struct kvm_kpit_state *ps = container_of(kian, struct kvm_kpit_state, |
| 244 | irq_ack_notifier); | 244 | irq_ack_notifier); |
| 245 | spin_lock(&ps->inject_lock); | 245 | raw_spin_lock(&ps->inject_lock); |
| 246 | if (atomic_dec_return(&ps->pit_timer.pending) < 0) | 246 | if (atomic_dec_return(&ps->pit_timer.pending) < 0) |
| 247 | atomic_inc(&ps->pit_timer.pending); | 247 | atomic_inc(&ps->pit_timer.pending); |
| 248 | ps->irq_ack = 1; | 248 | ps->irq_ack = 1; |
| 249 | spin_unlock(&ps->inject_lock); | 249 | raw_spin_unlock(&ps->inject_lock); |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu) | 252 | void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu) |
| @@ -624,7 +624,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags) | |||
| 624 | 624 | ||
| 625 | mutex_init(&pit->pit_state.lock); | 625 | mutex_init(&pit->pit_state.lock); |
| 626 | mutex_lock(&pit->pit_state.lock); | 626 | mutex_lock(&pit->pit_state.lock); |
| 627 | spin_lock_init(&pit->pit_state.inject_lock); | 627 | raw_spin_lock_init(&pit->pit_state.inject_lock); |
| 628 | 628 | ||
| 629 | kvm->arch.vpit = pit; | 629 | kvm->arch.vpit = pit; |
| 630 | pit->kvm = kvm; | 630 | pit->kvm = kvm; |
| @@ -723,12 +723,12 @@ void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu) | |||
| 723 | /* Try to inject pending interrupts when | 723 | /* Try to inject pending interrupts when |
| 724 | * last one has been acked. | 724 | * last one has been acked. |
| 725 | */ | 725 | */ |
| 726 | spin_lock(&ps->inject_lock); | 726 | raw_spin_lock(&ps->inject_lock); |
| 727 | if (atomic_read(&ps->pit_timer.pending) && ps->irq_ack) { | 727 | if (atomic_read(&ps->pit_timer.pending) && ps->irq_ack) { |
| 728 | ps->irq_ack = 0; | 728 | ps->irq_ack = 0; |
| 729 | inject = 1; | 729 | inject = 1; |
| 730 | } | 730 | } |
| 731 | spin_unlock(&ps->inject_lock); | 731 | raw_spin_unlock(&ps->inject_lock); |
| 732 | if (inject) | 732 | if (inject) |
| 733 | __inject_pit_timer_intr(kvm); | 733 | __inject_pit_timer_intr(kvm); |
| 734 | } | 734 | } |
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h index d4c1c7ffdc09..900d6b0ba7c2 100644 --- a/arch/x86/kvm/i8254.h +++ b/arch/x86/kvm/i8254.h | |||
| @@ -27,7 +27,7 @@ struct kvm_kpit_state { | |||
| 27 | u32 speaker_data_on; | 27 | u32 speaker_data_on; |
| 28 | struct mutex lock; | 28 | struct mutex lock; |
| 29 | struct kvm_pit *pit; | 29 | struct kvm_pit *pit; |
| 30 | spinlock_t inject_lock; | 30 | raw_spinlock_t inject_lock; |
| 31 | unsigned long irq_ack; | 31 | unsigned long irq_ack; |
| 32 | struct kvm_irq_ack_notifier irq_ack_notifier; | 32 | struct kvm_irq_ack_notifier irq_ack_notifier; |
| 33 | }; | 33 | }; |
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index d057c0cbd245..a6a877e4ab4d 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c | |||
| @@ -32,6 +32,29 @@ | |||
| 32 | #include <linux/kvm_host.h> | 32 | #include <linux/kvm_host.h> |
| 33 | #include "trace.h" | 33 | #include "trace.h" |
| 34 | 34 | ||
| 35 | static void pic_lock(struct kvm_pic *s) | ||
| 36 | __acquires(&s->lock) | ||
| 37 | { | ||
| 38 | raw_spin_lock(&s->lock); | ||
| 39 | } | ||
| 40 | |||
| 41 | static void pic_unlock(struct kvm_pic *s) | ||
| 42 | __releases(&s->lock) | ||
| 43 | { | ||
| 44 | bool wakeup = s->wakeup_needed; | ||
| 45 | struct kvm_vcpu *vcpu; | ||
| 46 | |||
| 47 | s->wakeup_needed = false; | ||
| 48 | |||
| 49 | raw_spin_unlock(&s->lock); | ||
| 50 | |||
| 51 | if (wakeup) { | ||
| 52 | vcpu = s->kvm->bsp_vcpu; | ||
| 53 | if (vcpu) | ||
| 54 | kvm_vcpu_kick(vcpu); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 35 | static void pic_clear_isr(struct kvm_kpic_state *s, int irq) | 58 | static void pic_clear_isr(struct kvm_kpic_state *s, int irq) |
| 36 | { | 59 | { |
| 37 | s->isr &= ~(1 << irq); | 60 | s->isr &= ~(1 << irq); |
| @@ -44,18 +67,19 @@ static void pic_clear_isr(struct kvm_kpic_state *s, int irq) | |||
| 44 | * Other interrupt may be delivered to PIC while lock is dropped but | 67 | * Other interrupt may be delivered to PIC while lock is dropped but |
| 45 | * it should be safe since PIC state is already updated at this stage. | 68 | * it should be safe since PIC state is already updated at this stage. |
| 46 | */ | 69 | */ |
| 47 | spin_unlock(&s->pics_state->lock); | 70 | pic_unlock(s->pics_state); |
| 48 | kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq); | 71 | kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq); |
| 49 | spin_lock(&s->pics_state->lock); | 72 | pic_lock(s->pics_state); |
| 50 | } | 73 | } |
| 51 | 74 | ||
| 52 | void kvm_pic_clear_isr_ack(struct kvm *kvm) | 75 | void kvm_pic_clear_isr_ack(struct kvm *kvm) |
| 53 | { | 76 | { |
| 54 | struct kvm_pic *s = pic_irqchip(kvm); | 77 | struct kvm_pic *s = pic_irqchip(kvm); |
| 55 | spin_lock(&s->lock); | 78 | |
| 79 | pic_lock(s); | ||
| 56 | s->pics[0].isr_ack = 0xff; | 80 | s->pics[0].isr_ack = 0xff; |
| 57 | s->pics[1].isr_ack = 0xff; | 81 | s->pics[1].isr_ack = 0xff; |
| 58 | spin_unlock(&s->lock); | 82 | pic_unlock(s); |
| 59 | } | 83 | } |
| 60 | 84 | ||
| 61 | /* | 85 | /* |
| @@ -156,9 +180,9 @@ static void pic_update_irq(struct kvm_pic *s) | |||
| 156 | 180 | ||
| 157 | void kvm_pic_update_irq(struct kvm_pic *s) | 181 | void kvm_pic_update_irq(struct kvm_pic *s) |
| 158 | { | 182 | { |
| 159 | spin_lock(&s->lock); | 183 | pic_lock(s); |
| 160 | pic_update_irq(s); | 184 | pic_update_irq(s); |
| 161 | spin_unlock(&s->lock); | 185 | pic_unlock(s); |
| 162 | } | 186 | } |
| 163 | 187 | ||
| 164 | int kvm_pic_set_irq(void *opaque, int irq, int level) | 188 | int kvm_pic_set_irq(void *opaque, int irq, int level) |
| @@ -166,14 +190,14 @@ int kvm_pic_set_irq(void *opaque, int irq, int level) | |||
| 166 | struct kvm_pic *s = opaque; | 190 | struct kvm_pic *s = opaque; |
| 167 | int ret = -1; | 191 | int ret = -1; |
| 168 | 192 | ||
| 169 | spin_lock(&s->lock); | 193 | pic_lock(s); |
| 170 | if (irq >= 0 && irq < PIC_NUM_PINS) { | 194 | if (irq >= 0 && irq < PIC_NUM_PINS) { |
| 171 | ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); | 195 | ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); |
| 172 | pic_update_irq(s); | 196 | pic_update_irq(s); |
| 173 | trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr, | 197 | trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr, |
| 174 | s->pics[irq >> 3].imr, ret == 0); | 198 | s->pics[irq >> 3].imr, ret == 0); |
| 175 | } | 199 | } |
| 176 | spin_unlock(&s->lock); | 200 | pic_unlock(s); |
| 177 | 201 | ||
| 178 | return ret; | 202 | return ret; |
| 179 | } | 203 | } |
| @@ -203,7 +227,7 @@ int kvm_pic_read_irq(struct kvm *kvm) | |||
| 203 | int irq, irq2, intno; | 227 | int irq, irq2, intno; |
| 204 | struct kvm_pic *s = pic_irqchip(kvm); | 228 | struct kvm_pic *s = pic_irqchip(kvm); |
| 205 | 229 | ||
| 206 | spin_lock(&s->lock); | 230 | pic_lock(s); |
| 207 | irq = pic_get_irq(&s->pics[0]); | 231 | irq = pic_get_irq(&s->pics[0]); |
| 208 | if (irq >= 0) { | 232 | if (irq >= 0) { |
| 209 | pic_intack(&s->pics[0], irq); | 233 | pic_intack(&s->pics[0], irq); |
| @@ -228,7 +252,7 @@ int kvm_pic_read_irq(struct kvm *kvm) | |||
| 228 | intno = s->pics[0].irq_base + irq; | 252 | intno = s->pics[0].irq_base + irq; |
| 229 | } | 253 | } |
| 230 | pic_update_irq(s); | 254 | pic_update_irq(s); |
| 231 | spin_unlock(&s->lock); | 255 | pic_unlock(s); |
| 232 | 256 | ||
| 233 | return intno; | 257 | return intno; |
| 234 | } | 258 | } |
| @@ -442,7 +466,7 @@ static int picdev_write(struct kvm_io_device *this, | |||
| 442 | printk(KERN_ERR "PIC: non byte write\n"); | 466 | printk(KERN_ERR "PIC: non byte write\n"); |
| 443 | return 0; | 467 | return 0; |
| 444 | } | 468 | } |
| 445 | spin_lock(&s->lock); | 469 | pic_lock(s); |
| 446 | switch (addr) { | 470 | switch (addr) { |
| 447 | case 0x20: | 471 | case 0x20: |
| 448 | case 0x21: | 472 | case 0x21: |
| @@ -455,7 +479,7 @@ static int picdev_write(struct kvm_io_device *this, | |||
| 455 | elcr_ioport_write(&s->pics[addr & 1], addr, data); | 479 | elcr_ioport_write(&s->pics[addr & 1], addr, data); |
| 456 | break; | 480 | break; |
| 457 | } | 481 | } |
| 458 | spin_unlock(&s->lock); | 482 | pic_unlock(s); |
| 459 | return 0; | 483 | return 0; |
| 460 | } | 484 | } |
| 461 | 485 | ||
| @@ -472,7 +496,7 @@ static int picdev_read(struct kvm_io_device *this, | |||
| 472 | printk(KERN_ERR "PIC: non byte read\n"); | 496 | printk(KERN_ERR "PIC: non byte read\n"); |
| 473 | return 0; | 497 | return 0; |
| 474 | } | 498 | } |
| 475 | spin_lock(&s->lock); | 499 | pic_lock(s); |
| 476 | switch (addr) { | 500 | switch (addr) { |
| 477 | case 0x20: | 501 | case 0x20: |
| 478 | case 0x21: | 502 | case 0x21: |
| @@ -486,7 +510,7 @@ static int picdev_read(struct kvm_io_device *this, | |||
| 486 | break; | 510 | break; |
| 487 | } | 511 | } |
| 488 | *(unsigned char *)val = data; | 512 | *(unsigned char *)val = data; |
| 489 | spin_unlock(&s->lock); | 513 | pic_unlock(s); |
| 490 | return 0; | 514 | return 0; |
| 491 | } | 515 | } |
| 492 | 516 | ||
| @@ -503,7 +527,7 @@ static void pic_irq_request(void *opaque, int level) | |||
| 503 | s->output = level; | 527 | s->output = level; |
| 504 | if (vcpu && level && (s->pics[0].isr_ack & (1 << irq))) { | 528 | if (vcpu && level && (s->pics[0].isr_ack & (1 << irq))) { |
| 505 | s->pics[0].isr_ack &= ~(1 << irq); | 529 | s->pics[0].isr_ack &= ~(1 << irq); |
| 506 | kvm_vcpu_kick(vcpu); | 530 | s->wakeup_needed = true; |
| 507 | } | 531 | } |
| 508 | } | 532 | } |
| 509 | 533 | ||
| @@ -520,7 +544,7 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm) | |||
| 520 | s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL); | 544 | s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL); |
| 521 | if (!s) | 545 | if (!s) |
| 522 | return NULL; | 546 | return NULL; |
| 523 | spin_lock_init(&s->lock); | 547 | raw_spin_lock_init(&s->lock); |
| 524 | s->kvm = kvm; | 548 | s->kvm = kvm; |
| 525 | s->pics[0].elcr_mask = 0xf8; | 549 | s->pics[0].elcr_mask = 0xf8; |
| 526 | s->pics[1].elcr_mask = 0xde; | 550 | s->pics[1].elcr_mask = 0xde; |
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h index be399e207d57..4ba8ce287d6c 100644 --- a/arch/x86/kvm/irq.h +++ b/arch/x86/kvm/irq.h | |||
| @@ -62,7 +62,8 @@ struct kvm_kpic_state { | |||
| 62 | }; | 62 | }; |
| 63 | 63 | ||
| 64 | struct kvm_pic { | 64 | struct kvm_pic { |
| 65 | spinlock_t lock; | 65 | raw_spinlock_t lock; |
| 66 | bool wakeup_needed; | ||
| 66 | unsigned pending_acks; | 67 | unsigned pending_acks; |
| 67 | struct kvm *kvm; | 68 | struct kvm *kvm; |
| 68 | struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */ | 69 | struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */ |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index dd7892740314..55e20f8c518f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -2251,18 +2251,18 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip) | |||
| 2251 | r = 0; | 2251 | r = 0; |
| 2252 | switch (chip->chip_id) { | 2252 | switch (chip->chip_id) { |
| 2253 | case KVM_IRQCHIP_PIC_MASTER: | 2253 | case KVM_IRQCHIP_PIC_MASTER: |
| 2254 | spin_lock(&pic_irqchip(kvm)->lock); | 2254 | raw_spin_lock(&pic_irqchip(kvm)->lock); |
| 2255 | memcpy(&pic_irqchip(kvm)->pics[0], | 2255 | memcpy(&pic_irqchip(kvm)->pics[0], |
| 2256 | &chip->chip.pic, | 2256 | &chip->chip.pic, |
| 2257 | sizeof(struct kvm_pic_state)); | 2257 | sizeof(struct kvm_pic_state)); |
| 2258 | spin_unlock(&pic_irqchip(kvm)->lock); | 2258 | raw_spin_unlock(&pic_irqchip(kvm)->lock); |
| 2259 | break; | 2259 | break; |
| 2260 | case KVM_IRQCHIP_PIC_SLAVE: | 2260 | case KVM_IRQCHIP_PIC_SLAVE: |
| 2261 | spin_lock(&pic_irqchip(kvm)->lock); | 2261 | raw_spin_lock(&pic_irqchip(kvm)->lock); |
| 2262 | memcpy(&pic_irqchip(kvm)->pics[1], | 2262 | memcpy(&pic_irqchip(kvm)->pics[1], |
| 2263 | &chip->chip.pic, | 2263 | &chip->chip.pic, |
| 2264 | sizeof(struct kvm_pic_state)); | 2264 | sizeof(struct kvm_pic_state)); |
| 2265 | spin_unlock(&pic_irqchip(kvm)->lock); | 2265 | raw_spin_unlock(&pic_irqchip(kvm)->lock); |
| 2266 | break; | 2266 | break; |
| 2267 | case KVM_IRQCHIP_IOAPIC: | 2267 | case KVM_IRQCHIP_IOAPIC: |
| 2268 | r = kvm_set_ioapic(kvm, &chip->chip.ioapic); | 2268 | r = kvm_set_ioapic(kvm, &chip->chip.ioapic); |
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index f62777940dfb..60a0aa574dc6 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
| @@ -554,6 +554,7 @@ static int is_f00f_bug(struct pt_regs *regs, unsigned long address) | |||
| 554 | nr = (address - idt_descr.address) >> 3; | 554 | nr = (address - idt_descr.address) >> 3; |
| 555 | 555 | ||
| 556 | if (nr == 6) { | 556 | if (nr == 6) { |
| 557 | zap_rt_locks(); | ||
| 557 | do_invalid_op(regs, 0); | 558 | do_invalid_op(regs, 0); |
| 558 | return 1; | 559 | return 1; |
| 559 | } | 560 | } |
| @@ -1035,7 +1036,7 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
| 1035 | * If we're in an interrupt, have no user context or are running | 1036 | * If we're in an interrupt, have no user context or are running |
| 1036 | * in an atomic region then we must not take the fault: | 1037 | * in an atomic region then we must not take the fault: |
| 1037 | */ | 1038 | */ |
| 1038 | if (unlikely(in_atomic() || !mm)) { | 1039 | if (unlikely(in_atomic() || !mm || current->pagefault_disabled)) { |
| 1039 | bad_area_nosemaphore(regs, error_code, address); | 1040 | bad_area_nosemaphore(regs, error_code, address); |
| 1040 | return; | 1041 | return; |
| 1041 | } | 1042 | } |
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c index 738e6593799d..5aeae530a01b 100644 --- a/arch/x86/mm/gup.c +++ b/arch/x86/mm/gup.c | |||
| @@ -77,13 +77,13 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, | |||
| 77 | if (write) | 77 | if (write) |
| 78 | mask |= _PAGE_RW; | 78 | mask |= _PAGE_RW; |
| 79 | 79 | ||
| 80 | ptep = pte_offset_map(&pmd, addr); | 80 | ptep = pte_offset_map_direct(&pmd, addr); |
| 81 | do { | 81 | do { |
| 82 | pte_t pte = gup_get_pte(ptep); | 82 | pte_t pte = gup_get_pte(ptep); |
| 83 | struct page *page; | 83 | struct page *page; |
| 84 | 84 | ||
| 85 | if ((pte_flags(pte) & (mask | _PAGE_SPECIAL)) != mask) { | 85 | if ((pte_flags(pte) & (mask | _PAGE_SPECIAL)) != mask) { |
| 86 | pte_unmap(ptep); | 86 | pte_unmap_direct(ptep); |
| 87 | return 0; | 87 | return 0; |
| 88 | } | 88 | } |
| 89 | VM_BUG_ON(!pfn_valid(pte_pfn(pte))); | 89 | VM_BUG_ON(!pfn_valid(pte_pfn(pte))); |
| @@ -93,7 +93,7 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, | |||
| 93 | (*nr)++; | 93 | (*nr)++; |
| 94 | 94 | ||
| 95 | } while (ptep++, addr += PAGE_SIZE, addr != end); | 95 | } while (ptep++, addr += PAGE_SIZE, addr != end); |
| 96 | pte_unmap(ptep - 1); | 96 | pte_unmap_direct(ptep - 1); |
| 97 | 97 | ||
| 98 | return 1; | 98 | return 1; |
| 99 | } | 99 | } |
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c index 63a6ba66cbe0..83b4efc9e8e7 100644 --- a/arch/x86/mm/highmem_32.c +++ b/arch/x86/mm/highmem_32.c | |||
| @@ -4,9 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | void *kmap(struct page *page) | 5 | void *kmap(struct page *page) |
| 6 | { | 6 | { |
| 7 | might_sleep(); | ||
| 8 | if (!PageHighMem(page)) | 7 | if (!PageHighMem(page)) |
| 9 | return page_address(page); | 8 | return page_address(page); |
| 9 | might_sleep(); | ||
| 10 | return kmap_high(page); | 10 | return kmap_high(page); |
| 11 | } | 11 | } |
| 12 | 12 | ||
| @@ -19,6 +19,17 @@ void kunmap(struct page *page) | |||
| 19 | kunmap_high(page); | 19 | kunmap_high(page); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | struct page *kmap_to_page(void *ptr) | ||
| 23 | { | ||
| 24 | struct page *page; | ||
| 25 | |||
| 26 | if ((unsigned long)ptr < PKMAP_ADDR(0)) | ||
| 27 | return virt_to_page(ptr); | ||
| 28 | page = pte_page(pkmap_page_table[PKMAP_NR((unsigned long)ptr)]); | ||
| 29 | return page; | ||
| 30 | } | ||
| 31 | EXPORT_SYMBOL_GPL(kmap_to_page); /* PREEMPT_RT converts some modules to use this */ | ||
| 32 | |||
| 22 | /* | 33 | /* |
| 23 | * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because | 34 | * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because |
| 24 | * no global lock is needed and because the kmap code must perform a global TLB | 35 | * no global lock is needed and because the kmap code must perform a global TLB |
| @@ -27,12 +38,13 @@ void kunmap(struct page *page) | |||
| 27 | * However when holding an atomic kmap it is not legal to sleep, so atomic | 38 | * However when holding an atomic kmap it is not legal to sleep, so atomic |
| 28 | * kmaps are appropriate for short, tight code paths only. | 39 | * kmaps are appropriate for short, tight code paths only. |
| 29 | */ | 40 | */ |
| 30 | void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | 41 | void *__kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) |
| 31 | { | 42 | { |
| 32 | enum fixed_addresses idx; | 43 | enum fixed_addresses idx; |
| 33 | unsigned long vaddr; | 44 | unsigned long vaddr; |
| 34 | 45 | ||
| 35 | /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ | 46 | /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ |
| 47 | preempt_disable(); | ||
| 36 | pagefault_disable(); | 48 | pagefault_disable(); |
| 37 | 49 | ||
| 38 | if (!PageHighMem(page)) | 50 | if (!PageHighMem(page)) |
| @@ -42,51 +54,34 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | |||
| 42 | 54 | ||
| 43 | idx = type + KM_TYPE_NR*smp_processor_id(); | 55 | idx = type + KM_TYPE_NR*smp_processor_id(); |
| 44 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 56 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
| 45 | BUG_ON(!pte_none(*(kmap_pte-idx))); | 57 | WARN_ON(!pte_none(*(kmap_pte-idx))); |
| 46 | set_pte(kmap_pte-idx, mk_pte(page, prot)); | 58 | set_pte(kmap_pte-idx, mk_pte(page, prot)); |
| 47 | 59 | ||
| 48 | return (void *)vaddr; | 60 | return (void *)vaddr; |
| 49 | } | 61 | } |
| 50 | 62 | ||
| 51 | void *kmap_atomic(struct page *page, enum km_type type) | 63 | void *__kmap_atomic_direct(struct page *page, enum km_type type) |
| 52 | { | 64 | { |
| 53 | return kmap_atomic_prot(page, type, kmap_prot); | 65 | return __kmap_atomic_prot(page, type, kmap_prot); |
| 54 | } | 66 | } |
| 55 | 67 | ||
| 56 | void kunmap_atomic(void *kvaddr, enum km_type type) | 68 | void *__kmap_atomic(struct page *page, enum km_type type) |
| 57 | { | 69 | { |
| 58 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | 70 | return kmap_atomic_prot(page, type, kmap_prot); |
| 59 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); | ||
| 60 | |||
| 61 | /* | ||
| 62 | * Force other mappings to Oops if they'll try to access this pte | ||
| 63 | * without first remap it. Keeping stale mappings around is a bad idea | ||
| 64 | * also, in case the page changes cacheability attributes or becomes | ||
| 65 | * a protected page in a hypervisor. | ||
| 66 | */ | ||
| 67 | if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) | ||
| 68 | kpte_clear_flush(kmap_pte-idx, vaddr); | ||
| 69 | else { | ||
| 70 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
| 71 | BUG_ON(vaddr < PAGE_OFFSET); | ||
| 72 | BUG_ON(vaddr >= (unsigned long)high_memory); | ||
| 73 | #endif | ||
| 74 | } | ||
| 75 | |||
| 76 | pagefault_enable(); | ||
| 77 | } | 71 | } |
| 78 | 72 | ||
| 79 | /* | 73 | /* |
| 80 | * This is the same as kmap_atomic() but can map memory that doesn't | 74 | * This is the same as kmap_atomic() but can map memory that doesn't |
| 81 | * have a struct page associated with it. | 75 | * have a struct page associated with it. |
| 82 | */ | 76 | */ |
| 83 | void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) | 77 | void *__kmap_atomic_pfn(unsigned long pfn, enum km_type type) |
| 84 | { | 78 | { |
| 79 | preempt_disable(); | ||
| 85 | return kmap_atomic_prot_pfn(pfn, type, kmap_prot); | 80 | return kmap_atomic_prot_pfn(pfn, type, kmap_prot); |
| 86 | } | 81 | } |
| 87 | EXPORT_SYMBOL_GPL(kmap_atomic_pfn); /* temporarily in use by i915 GEM until vmap */ | 82 | EXPORT_SYMBOL_GPL(__kmap_atomic_pfn); /* temporarily in use by i915 GEM until vmap */ |
| 88 | 83 | ||
| 89 | struct page *kmap_atomic_to_page(void *ptr) | 84 | struct page *__kmap_atomic_to_page(void *ptr) |
| 90 | { | 85 | { |
| 91 | unsigned long idx, vaddr = (unsigned long)ptr; | 86 | unsigned long idx, vaddr = (unsigned long)ptr; |
| 92 | pte_t *pte; | 87 | pte_t *pte; |
| @@ -101,10 +96,10 @@ struct page *kmap_atomic_to_page(void *ptr) | |||
| 101 | 96 | ||
| 102 | EXPORT_SYMBOL(kmap); | 97 | EXPORT_SYMBOL(kmap); |
| 103 | EXPORT_SYMBOL(kunmap); | 98 | EXPORT_SYMBOL(kunmap); |
| 104 | EXPORT_SYMBOL(kmap_atomic); | 99 | EXPORT_SYMBOL(kunmap_virt); |
| 105 | EXPORT_SYMBOL(kunmap_atomic); | 100 | EXPORT_SYMBOL(__kmap_atomic); |
| 106 | EXPORT_SYMBOL(kmap_atomic_prot); | 101 | EXPORT_SYMBOL(__kmap_atomic_prot); |
| 107 | EXPORT_SYMBOL(kmap_atomic_to_page); | 102 | EXPORT_SYMBOL(__kmap_atomic_to_page); |
| 108 | 103 | ||
| 109 | void __init set_highmem_pages_init(void) | 104 | void __init set_highmem_pages_init(void) |
| 110 | { | 105 | { |
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index d406c5239019..9a69721bbb39 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
| @@ -14,8 +14,6 @@ | |||
| 14 | #include <asm/tlb.h> | 14 | #include <asm/tlb.h> |
| 15 | #include <asm/proto.h> | 15 | #include <asm/proto.h> |
| 16 | 16 | ||
| 17 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | ||
| 18 | |||
| 19 | unsigned long __initdata e820_table_start; | 17 | unsigned long __initdata e820_table_start; |
| 20 | unsigned long __meminitdata e820_table_end; | 18 | unsigned long __meminitdata e820_table_end; |
| 21 | unsigned long __meminitdata e820_table_top; | 19 | unsigned long __meminitdata e820_table_top; |
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c index 84e236ce76ba..d4fe51ac86f2 100644 --- a/arch/x86/mm/iomap_32.c +++ b/arch/x86/mm/iomap_32.c | |||
| @@ -55,11 +55,12 @@ iomap_free(resource_size_t base, unsigned long size) | |||
| 55 | } | 55 | } |
| 56 | EXPORT_SYMBOL_GPL(iomap_free); | 56 | EXPORT_SYMBOL_GPL(iomap_free); |
| 57 | 57 | ||
| 58 | void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) | 58 | void *__kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) |
| 59 | { | 59 | { |
| 60 | enum fixed_addresses idx; | 60 | enum fixed_addresses idx; |
| 61 | unsigned long vaddr; | 61 | unsigned long vaddr; |
| 62 | 62 | ||
| 63 | preempt_disable(); | ||
| 63 | pagefault_disable(); | 64 | pagefault_disable(); |
| 64 | 65 | ||
| 65 | debug_kmap_atomic(type); | 66 | debug_kmap_atomic(type); |
| @@ -71,6 +72,38 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) | |||
| 71 | return (void *)vaddr; | 72 | return (void *)vaddr; |
| 72 | } | 73 | } |
| 73 | 74 | ||
| 75 | void __kunmap_atomic(void *kvaddr, enum km_type type) | ||
| 76 | { | ||
| 77 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | ||
| 78 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); | ||
| 79 | |||
| 80 | /* | ||
| 81 | * Force other mappings to Oops if they'll try to access this pte | ||
| 82 | * without first remap it. Keeping stale mappings around is a bad idea | ||
| 83 | * also, in case the page changes cacheability attributes or becomes | ||
| 84 | * a protected page in a hypervisor. | ||
| 85 | */ | ||
| 86 | if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) | ||
| 87 | kpte_clear_flush(kmap_pte-idx, vaddr); | ||
| 88 | else { | ||
| 89 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
| 90 | BUG_ON(vaddr < PAGE_OFFSET); | ||
| 91 | BUG_ON(vaddr >= (unsigned long)high_memory); | ||
| 92 | #endif | ||
| 93 | } | ||
| 94 | |||
| 95 | pagefault_enable(); | ||
| 96 | preempt_enable(); | ||
| 97 | } | ||
| 98 | EXPORT_SYMBOL(__kunmap_atomic); | ||
| 99 | |||
| 100 | #if !defined(CONFIG_PREEMPT_RT) || defined(CONFIG_HIGHMEM) | ||
| 101 | |||
| 102 | # ifndef CONFIG_HIGHMEM | ||
| 103 | # define kmap_atomic_prot_pfn(pfn, type, prot) \ | ||
| 104 | __kmap_atomic_prot_pfn(pfn, type, prot) | ||
| 105 | # define kunmap_atomic(kvaddr, type) __kunmap_atomic(kvaddr, type) | ||
| 106 | # endif | ||
| 74 | /* | 107 | /* |
| 75 | * Map 'pfn' using fixed map 'type' and protections 'prot' | 108 | * Map 'pfn' using fixed map 'type' and protections 'prot' |
| 76 | */ | 109 | */ |
| @@ -93,18 +126,7 @@ EXPORT_SYMBOL_GPL(iomap_atomic_prot_pfn); | |||
| 93 | void | 126 | void |
| 94 | iounmap_atomic(void *kvaddr, enum km_type type) | 127 | iounmap_atomic(void *kvaddr, enum km_type type) |
| 95 | { | 128 | { |
| 96 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | 129 | kunmap_atomic(kvaddr, type); |
| 97 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); | ||
| 98 | |||
| 99 | /* | ||
| 100 | * Force other mappings to Oops if they'll try to access this pte | ||
| 101 | * without first remap it. Keeping stale mappings around is a bad idea | ||
| 102 | * also, in case the page changes cacheability attributes or becomes | ||
| 103 | * a protected page in a hypervisor. | ||
| 104 | */ | ||
| 105 | if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) | ||
| 106 | kpte_clear_flush(kmap_pte-idx, vaddr); | ||
| 107 | |||
| 108 | pagefault_enable(); | ||
| 109 | } | 130 | } |
| 110 | EXPORT_SYMBOL_GPL(iounmap_atomic); | 131 | EXPORT_SYMBOL_GPL(iounmap_atomic); |
| 132 | #endif | ||
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index cf07c26d9a4a..02e58e54cb83 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
| @@ -882,8 +882,10 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, | |||
| 882 | baddr = *addr; | 882 | baddr = *addr; |
| 883 | } | 883 | } |
| 884 | 884 | ||
| 885 | #if 0 | ||
| 885 | /* Must avoid aliasing mappings in the highmem code */ | 886 | /* Must avoid aliasing mappings in the highmem code */ |
| 886 | kmap_flush_unused(); | 887 | kmap_flush_unused(); |
| 888 | #endif | ||
| 887 | 889 | ||
| 888 | vm_unmap_aliases(); | 890 | vm_unmap_aliases(); |
| 889 | 891 | ||
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index c9ba9deafe83..7dfc1ea4b279 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c | |||
| @@ -153,6 +153,7 @@ void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd) | |||
| 153 | reserved at the pmd (PDPT) level. */ | 153 | reserved at the pmd (PDPT) level. */ |
| 154 | set_pud(pudp, __pud(__pa(pmd) | _PAGE_PRESENT)); | 154 | set_pud(pudp, __pud(__pa(pmd) | _PAGE_PRESENT)); |
| 155 | 155 | ||
| 156 | preempt_disable(); | ||
| 156 | /* | 157 | /* |
| 157 | * According to Intel App note "TLBs, Paging-Structure Caches, | 158 | * According to Intel App note "TLBs, Paging-Structure Caches, |
| 158 | * and Their Invalidation", April 2007, document 317080-001, | 159 | * and Their Invalidation", April 2007, document 317080-001, |
| @@ -161,6 +162,7 @@ void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd) | |||
| 161 | */ | 162 | */ |
| 162 | if (mm == current->active_mm) | 163 | if (mm == current->active_mm) |
| 163 | write_cr3(read_cr3()); | 164 | write_cr3(read_cr3()); |
| 165 | preempt_enable(); | ||
| 164 | } | 166 | } |
| 165 | #else /* !CONFIG_X86_PAE */ | 167 | #else /* !CONFIG_X86_PAE */ |
| 166 | 168 | ||
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 65b58e4b0b8b..426f3a1a64d3 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c | |||
| @@ -41,7 +41,7 @@ union smp_flush_state { | |||
| 41 | struct { | 41 | struct { |
| 42 | struct mm_struct *flush_mm; | 42 | struct mm_struct *flush_mm; |
| 43 | unsigned long flush_va; | 43 | unsigned long flush_va; |
| 44 | spinlock_t tlbstate_lock; | 44 | raw_spinlock_t tlbstate_lock; |
| 45 | DECLARE_BITMAP(flush_cpumask, NR_CPUS); | 45 | DECLARE_BITMAP(flush_cpumask, NR_CPUS); |
| 46 | }; | 46 | }; |
| 47 | char pad[INTERNODE_CACHE_BYTES]; | 47 | char pad[INTERNODE_CACHE_BYTES]; |
| @@ -181,7 +181,7 @@ static void flush_tlb_others_ipi(const struct cpumask *cpumask, | |||
| 181 | * num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is | 181 | * num_online_cpus() <= NUM_INVALIDATE_TLB_VECTORS, but it is |
| 182 | * probably not worth checking this for a cache-hot lock. | 182 | * probably not worth checking this for a cache-hot lock. |
| 183 | */ | 183 | */ |
| 184 | spin_lock(&f->tlbstate_lock); | 184 | raw_spin_lock(&f->tlbstate_lock); |
| 185 | 185 | ||
| 186 | f->flush_mm = mm; | 186 | f->flush_mm = mm; |
| 187 | f->flush_va = va; | 187 | f->flush_va = va; |
| @@ -199,7 +199,7 @@ static void flush_tlb_others_ipi(const struct cpumask *cpumask, | |||
| 199 | 199 | ||
| 200 | f->flush_mm = NULL; | 200 | f->flush_mm = NULL; |
| 201 | f->flush_va = 0; | 201 | f->flush_va = 0; |
| 202 | spin_unlock(&f->tlbstate_lock); | 202 | raw_spin_unlock(&f->tlbstate_lock); |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | void native_flush_tlb_others(const struct cpumask *cpumask, | 205 | void native_flush_tlb_others(const struct cpumask *cpumask, |
| @@ -223,7 +223,7 @@ static int __cpuinit init_smp_flush(void) | |||
| 223 | int i; | 223 | int i; |
| 224 | 224 | ||
| 225 | for (i = 0; i < ARRAY_SIZE(flush_state); i++) | 225 | for (i = 0; i < ARRAY_SIZE(flush_state); i++) |
| 226 | spin_lock_init(&flush_state[i].tlbstate_lock); | 226 | raw_spin_lock_init(&flush_state[i].tlbstate_lock); |
| 227 | 227 | ||
| 228 | return 0; | 228 | return 0; |
| 229 | } | 229 | } |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 2c505ee71014..18929a869dd3 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
| @@ -322,10 +322,10 @@ static void nmi_cpu_setup(void *dummy) | |||
| 322 | int cpu = smp_processor_id(); | 322 | int cpu = smp_processor_id(); |
| 323 | struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); | 323 | struct op_msrs *msrs = &per_cpu(cpu_msrs, cpu); |
| 324 | nmi_cpu_save_registers(msrs); | 324 | nmi_cpu_save_registers(msrs); |
| 325 | spin_lock(&oprofilefs_lock); | 325 | raw_spin_lock(&oprofilefs_lock); |
| 326 | model->setup_ctrs(model, msrs); | 326 | model->setup_ctrs(model, msrs); |
| 327 | nmi_cpu_setup_mux(cpu, msrs); | 327 | nmi_cpu_setup_mux(cpu, msrs); |
| 328 | spin_unlock(&oprofilefs_lock); | 328 | raw_spin_unlock(&oprofilefs_lock); |
| 329 | per_cpu(saved_lvtpc, cpu) = apic_read(APIC_LVTPC); | 329 | per_cpu(saved_lvtpc, cpu) = apic_read(APIC_LVTPC); |
| 330 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 330 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
| 331 | } | 331 | } |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index d2552c68e94d..b79d322ba1c3 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
| @@ -81,7 +81,7 @@ int pcibios_scanned; | |||
| 81 | * This interrupt-safe spinlock protects all accesses to PCI | 81 | * This interrupt-safe spinlock protects all accesses to PCI |
| 82 | * configuration space. | 82 | * configuration space. |
| 83 | */ | 83 | */ |
| 84 | DEFINE_SPINLOCK(pci_config_lock); | 84 | DEFINE_RAW_SPINLOCK(pci_config_lock); |
| 85 | 85 | ||
| 86 | static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d) | 86 | static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d) |
| 87 | { | 87 | { |
diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c index 347d882b3bb3..2cc41159f03c 100644 --- a/arch/x86/pci/direct.c +++ b/arch/x86/pci/direct.c | |||
| @@ -27,7 +27,7 @@ static int pci_conf1_read(unsigned int seg, unsigned int bus, | |||
| 27 | return -EINVAL; | 27 | return -EINVAL; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | spin_lock_irqsave(&pci_config_lock, flags); | 30 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
| 31 | 31 | ||
| 32 | outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8); | 32 | outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8); |
| 33 | 33 | ||
| @@ -43,7 +43,7 @@ static int pci_conf1_read(unsigned int seg, unsigned int bus, | |||
| 43 | break; | 43 | break; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | spin_unlock_irqrestore(&pci_config_lock, flags); | 46 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
| 47 | 47 | ||
| 48 | return 0; | 48 | return 0; |
| 49 | } | 49 | } |
| @@ -56,7 +56,7 @@ static int pci_conf1_write(unsigned int seg, unsigned int bus, | |||
| 56 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) | 56 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) |
| 57 | return -EINVAL; | 57 | return -EINVAL; |
| 58 | 58 | ||
| 59 | spin_lock_irqsave(&pci_config_lock, flags); | 59 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
| 60 | 60 | ||
| 61 | outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8); | 61 | outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8); |
| 62 | 62 | ||
| @@ -72,7 +72,7 @@ static int pci_conf1_write(unsigned int seg, unsigned int bus, | |||
| 72 | break; | 72 | break; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | spin_unlock_irqrestore(&pci_config_lock, flags); | 75 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
| 76 | 76 | ||
| 77 | return 0; | 77 | return 0; |
| 78 | } | 78 | } |
| @@ -108,7 +108,7 @@ static int pci_conf2_read(unsigned int seg, unsigned int bus, | |||
| 108 | if (dev & 0x10) | 108 | if (dev & 0x10) |
| 109 | return PCIBIOS_DEVICE_NOT_FOUND; | 109 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 110 | 110 | ||
| 111 | spin_lock_irqsave(&pci_config_lock, flags); | 111 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
| 112 | 112 | ||
| 113 | outb((u8)(0xF0 | (fn << 1)), 0xCF8); | 113 | outb((u8)(0xF0 | (fn << 1)), 0xCF8); |
| 114 | outb((u8)bus, 0xCFA); | 114 | outb((u8)bus, 0xCFA); |
| @@ -127,7 +127,7 @@ static int pci_conf2_read(unsigned int seg, unsigned int bus, | |||
| 127 | 127 | ||
| 128 | outb(0, 0xCF8); | 128 | outb(0, 0xCF8); |
| 129 | 129 | ||
| 130 | spin_unlock_irqrestore(&pci_config_lock, flags); | 130 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
| 131 | 131 | ||
| 132 | return 0; | 132 | return 0; |
| 133 | } | 133 | } |
| @@ -147,7 +147,7 @@ static int pci_conf2_write(unsigned int seg, unsigned int bus, | |||
| 147 | if (dev & 0x10) | 147 | if (dev & 0x10) |
| 148 | return PCIBIOS_DEVICE_NOT_FOUND; | 148 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 149 | 149 | ||
| 150 | spin_lock_irqsave(&pci_config_lock, flags); | 150 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
| 151 | 151 | ||
| 152 | outb((u8)(0xF0 | (fn << 1)), 0xCF8); | 152 | outb((u8)(0xF0 | (fn << 1)), 0xCF8); |
| 153 | outb((u8)bus, 0xCFA); | 153 | outb((u8)bus, 0xCFA); |
| @@ -166,7 +166,7 @@ static int pci_conf2_write(unsigned int seg, unsigned int bus, | |||
| 166 | 166 | ||
| 167 | outb(0, 0xCF8); | 167 | outb(0, 0xCF8); |
| 168 | 168 | ||
| 169 | spin_unlock_irqrestore(&pci_config_lock, flags); | 169 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
| 170 | 170 | ||
| 171 | return 0; | 171 | return 0; |
| 172 | } | 172 | } |
| @@ -224,16 +224,23 @@ static int __init pci_check_type1(void) | |||
| 224 | unsigned int tmp; | 224 | unsigned int tmp; |
| 225 | int works = 0; | 225 | int works = 0; |
| 226 | 226 | ||
| 227 | local_irq_save(flags); | 227 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
| 228 | 228 | ||
| 229 | outb(0x01, 0xCFB); | 229 | outb(0x01, 0xCFB); |
| 230 | tmp = inl(0xCF8); | 230 | tmp = inl(0xCF8); |
| 231 | outl(0x80000000, 0xCF8); | 231 | outl(0x80000000, 0xCF8); |
| 232 | if (inl(0xCF8) == 0x80000000 && pci_sanity_check(&pci_direct_conf1)) { | 232 | |
| 233 | works = 1; | 233 | if (inl(0xCF8) == 0x80000000) { |
| 234 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); | ||
| 235 | |||
| 236 | if (pci_sanity_check(&pci_direct_conf1)) | ||
| 237 | works = 1; | ||
| 238 | |||
| 239 | raw_spin_lock_irqsave(&pci_config_lock, flags); | ||
| 234 | } | 240 | } |
| 235 | outl(tmp, 0xCF8); | 241 | outl(tmp, 0xCF8); |
| 236 | local_irq_restore(flags); | 242 | |
| 243 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); | ||
| 237 | 244 | ||
| 238 | return works; | 245 | return works; |
| 239 | } | 246 | } |
| @@ -243,17 +250,19 @@ static int __init pci_check_type2(void) | |||
| 243 | unsigned long flags; | 250 | unsigned long flags; |
| 244 | int works = 0; | 251 | int works = 0; |
| 245 | 252 | ||
| 246 | local_irq_save(flags); | 253 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
| 247 | 254 | ||
| 248 | outb(0x00, 0xCFB); | 255 | outb(0x00, 0xCFB); |
| 249 | outb(0x00, 0xCF8); | 256 | outb(0x00, 0xCF8); |
| 250 | outb(0x00, 0xCFA); | 257 | outb(0x00, 0xCFA); |
| 251 | if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00 && | ||
| 252 | pci_sanity_check(&pci_direct_conf2)) { | ||
| 253 | works = 1; | ||
| 254 | } | ||
| 255 | 258 | ||
| 256 | local_irq_restore(flags); | 259 | if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00) { |
| 260 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); | ||
| 261 | |||
| 262 | if (pci_sanity_check(&pci_direct_conf2)) | ||
| 263 | works = 1; | ||
| 264 | } else | ||
| 265 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); | ||
| 257 | 266 | ||
| 258 | return works; | 267 | return works; |
| 259 | } | 268 | } |
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c index 90d5fd476ed4..a3d9c54792ae 100644 --- a/arch/x86/pci/mmconfig_32.c +++ b/arch/x86/pci/mmconfig_32.c | |||
| @@ -64,7 +64,7 @@ err: *value = -1; | |||
| 64 | if (!base) | 64 | if (!base) |
| 65 | goto err; | 65 | goto err; |
| 66 | 66 | ||
| 67 | spin_lock_irqsave(&pci_config_lock, flags); | 67 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
| 68 | 68 | ||
| 69 | pci_exp_set_dev_base(base, bus, devfn); | 69 | pci_exp_set_dev_base(base, bus, devfn); |
| 70 | 70 | ||
| @@ -79,7 +79,7 @@ err: *value = -1; | |||
| 79 | *value = mmio_config_readl(mmcfg_virt_addr + reg); | 79 | *value = mmio_config_readl(mmcfg_virt_addr + reg); |
| 80 | break; | 80 | break; |
| 81 | } | 81 | } |
| 82 | spin_unlock_irqrestore(&pci_config_lock, flags); | 82 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
| 83 | 83 | ||
| 84 | return 0; | 84 | return 0; |
| 85 | } | 85 | } |
| @@ -97,7 +97,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, | |||
| 97 | if (!base) | 97 | if (!base) |
| 98 | return -EINVAL; | 98 | return -EINVAL; |
| 99 | 99 | ||
| 100 | spin_lock_irqsave(&pci_config_lock, flags); | 100 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
| 101 | 101 | ||
| 102 | pci_exp_set_dev_base(base, bus, devfn); | 102 | pci_exp_set_dev_base(base, bus, devfn); |
| 103 | 103 | ||
| @@ -112,7 +112,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, | |||
| 112 | mmio_config_writel(mmcfg_virt_addr + reg, value); | 112 | mmio_config_writel(mmcfg_virt_addr + reg, value); |
| 113 | break; | 113 | break; |
| 114 | } | 114 | } |
| 115 | spin_unlock_irqrestore(&pci_config_lock, flags); | 115 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
| 116 | 116 | ||
| 117 | return 0; | 117 | return 0; |
| 118 | } | 118 | } |
diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c index 8eb295e116f6..2dad4dc34d88 100644 --- a/arch/x86/pci/numaq_32.c +++ b/arch/x86/pci/numaq_32.c | |||
| @@ -41,7 +41,7 @@ static int pci_conf1_mq_read(unsigned int seg, unsigned int bus, | |||
| 41 | if (!value || (bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) | 41 | if (!value || (bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) |
| 42 | return -EINVAL; | 42 | return -EINVAL; |
| 43 | 43 | ||
| 44 | spin_lock_irqsave(&pci_config_lock, flags); | 44 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
| 45 | 45 | ||
| 46 | write_cf8(bus, devfn, reg); | 46 | write_cf8(bus, devfn, reg); |
| 47 | 47 | ||
| @@ -66,7 +66,7 @@ static int pci_conf1_mq_read(unsigned int seg, unsigned int bus, | |||
| 66 | break; | 66 | break; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | spin_unlock_irqrestore(&pci_config_lock, flags); | 69 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
| 70 | 70 | ||
| 71 | return 0; | 71 | return 0; |
| 72 | } | 72 | } |
| @@ -80,7 +80,7 @@ static int pci_conf1_mq_write(unsigned int seg, unsigned int bus, | |||
| 80 | if ((bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) | 80 | if ((bus >= MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) |
| 81 | return -EINVAL; | 81 | return -EINVAL; |
| 82 | 82 | ||
| 83 | spin_lock_irqsave(&pci_config_lock, flags); | 83 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
| 84 | 84 | ||
| 85 | write_cf8(bus, devfn, reg); | 85 | write_cf8(bus, devfn, reg); |
| 86 | 86 | ||
| @@ -105,7 +105,7 @@ static int pci_conf1_mq_write(unsigned int seg, unsigned int bus, | |||
| 105 | break; | 105 | break; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | spin_unlock_irqrestore(&pci_config_lock, flags); | 108 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
| 109 | 109 | ||
| 110 | return 0; | 110 | return 0; |
| 111 | } | 111 | } |
diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c index 1c975cc9839e..2daa521f26b3 100644 --- a/arch/x86/pci/pcbios.c +++ b/arch/x86/pci/pcbios.c | |||
| @@ -161,7 +161,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus, | |||
| 161 | if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) | 161 | if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) |
| 162 | return -EINVAL; | 162 | return -EINVAL; |
| 163 | 163 | ||
| 164 | spin_lock_irqsave(&pci_config_lock, flags); | 164 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
| 165 | 165 | ||
| 166 | switch (len) { | 166 | switch (len) { |
| 167 | case 1: | 167 | case 1: |
| @@ -212,7 +212,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus, | |||
| 212 | break; | 212 | break; |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | spin_unlock_irqrestore(&pci_config_lock, flags); | 215 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
| 216 | 216 | ||
| 217 | return (int)((result & 0xff00) >> 8); | 217 | return (int)((result & 0xff00) >> 8); |
| 218 | } | 218 | } |
| @@ -227,7 +227,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus, | |||
| 227 | if ((bus > 255) || (devfn > 255) || (reg > 255)) | 227 | if ((bus > 255) || (devfn > 255) || (reg > 255)) |
| 228 | return -EINVAL; | 228 | return -EINVAL; |
| 229 | 229 | ||
| 230 | spin_lock_irqsave(&pci_config_lock, flags); | 230 | raw_spin_lock_irqsave(&pci_config_lock, flags); |
| 231 | 231 | ||
| 232 | switch (len) { | 232 | switch (len) { |
| 233 | case 1: | 233 | case 1: |
| @@ -268,7 +268,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus, | |||
| 268 | break; | 268 | break; |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | spin_unlock_irqrestore(&pci_config_lock, flags); | 271 | raw_spin_unlock_irqrestore(&pci_config_lock, flags); |
| 272 | 272 | ||
| 273 | return (int)((result & 0xff00) >> 8); | 273 | return (int)((result & 0xff00) >> 8); |
| 274 | } | 274 | } |
diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c index ee55754cc3c5..e1b68a559338 100644 --- a/arch/x86/vdso/vclock_gettime.c +++ b/arch/x86/vdso/vclock_gettime.c | |||
| @@ -47,11 +47,11 @@ notrace static noinline int do_realtime(struct timespec *ts) | |||
| 47 | { | 47 | { |
| 48 | unsigned long seq, ns; | 48 | unsigned long seq, ns; |
| 49 | do { | 49 | do { |
| 50 | seq = read_seqbegin(>od->lock); | 50 | seq = read_raw_seqbegin(>od->lock); |
| 51 | ts->tv_sec = gtod->wall_time_sec; | 51 | ts->tv_sec = gtod->wall_time_sec; |
| 52 | ts->tv_nsec = gtod->wall_time_nsec; | 52 | ts->tv_nsec = gtod->wall_time_nsec; |
| 53 | ns = vgetns(); | 53 | ns = vgetns(); |
| 54 | } while (unlikely(read_seqretry(>od->lock, seq))); | 54 | } while (unlikely(read_raw_seqretry(>od->lock, seq))); |
| 55 | timespec_add_ns(ts, ns); | 55 | timespec_add_ns(ts, ns); |
| 56 | return 0; | 56 | return 0; |
| 57 | } | 57 | } |
| @@ -76,12 +76,12 @@ notrace static noinline int do_monotonic(struct timespec *ts) | |||
| 76 | { | 76 | { |
| 77 | unsigned long seq, ns, secs; | 77 | unsigned long seq, ns, secs; |
| 78 | do { | 78 | do { |
| 79 | seq = read_seqbegin(>od->lock); | 79 | seq = read_raw_seqbegin(>od->lock); |
| 80 | secs = gtod->wall_time_sec; | 80 | secs = gtod->wall_time_sec; |
| 81 | ns = gtod->wall_time_nsec + vgetns(); | 81 | ns = gtod->wall_time_nsec + vgetns(); |
| 82 | secs += gtod->wall_to_monotonic.tv_sec; | 82 | secs += gtod->wall_to_monotonic.tv_sec; |
| 83 | ns += gtod->wall_to_monotonic.tv_nsec; | 83 | ns += gtod->wall_to_monotonic.tv_nsec; |
| 84 | } while (unlikely(read_seqretry(>od->lock, seq))); | 84 | } while (unlikely(read_raw_seqretry(>od->lock, seq))); |
| 85 | vset_normalized_timespec(ts, secs, ns); | 85 | vset_normalized_timespec(ts, secs, ns); |
| 86 | return 0; | 86 | return 0; |
| 87 | } | 87 | } |
| @@ -90,10 +90,10 @@ notrace static noinline int do_realtime_coarse(struct timespec *ts) | |||
| 90 | { | 90 | { |
| 91 | unsigned long seq; | 91 | unsigned long seq; |
| 92 | do { | 92 | do { |
| 93 | seq = read_seqbegin(>od->lock); | 93 | seq = read_raw_seqbegin(>od->lock); |
| 94 | ts->tv_sec = gtod->wall_time_coarse.tv_sec; | 94 | ts->tv_sec = gtod->wall_time_coarse.tv_sec; |
| 95 | ts->tv_nsec = gtod->wall_time_coarse.tv_nsec; | 95 | ts->tv_nsec = gtod->wall_time_coarse.tv_nsec; |
| 96 | } while (unlikely(read_seqretry(>od->lock, seq))); | 96 | } while (unlikely(read_raw_seqretry(>od->lock, seq))); |
| 97 | return 0; | 97 | return 0; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| @@ -101,12 +101,12 @@ notrace static noinline int do_monotonic_coarse(struct timespec *ts) | |||
| 101 | { | 101 | { |
| 102 | unsigned long seq, ns, secs; | 102 | unsigned long seq, ns, secs; |
| 103 | do { | 103 | do { |
| 104 | seq = read_seqbegin(>od->lock); | 104 | seq = read_raw_seqbegin(>od->lock); |
| 105 | secs = gtod->wall_time_coarse.tv_sec; | 105 | secs = gtod->wall_time_coarse.tv_sec; |
| 106 | ns = gtod->wall_time_coarse.tv_nsec; | 106 | ns = gtod->wall_time_coarse.tv_nsec; |
| 107 | secs += gtod->wall_to_monotonic.tv_sec; | 107 | secs += gtod->wall_to_monotonic.tv_sec; |
| 108 | ns += gtod->wall_to_monotonic.tv_nsec; | 108 | ns += gtod->wall_to_monotonic.tv_nsec; |
| 109 | } while (unlikely(read_seqretry(>od->lock, seq))); | 109 | } while (unlikely(read_raw_seqretry(>od->lock, seq))); |
| 110 | vset_normalized_timespec(ts, secs, ns); | 110 | vset_normalized_timespec(ts, secs, ns); |
| 111 | return 0; | 111 | return 0; |
| 112 | } | 112 | } |
