diff options
author | Tomasz Nowicki <tomasz.nowicki@linaro.org> | 2014-07-22 05:20:13 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2014-07-22 18:05:06 -0400 |
commit | 594c7255dce7a13cac50cf2470cc56e2c3b0494e (patch) | |
tree | 057da64928a17b6e13e923ec2baad9181886c704 | |
parent | 44a69f6195628f6f940566d133a72987559e102d (diff) |
acpi, apei, ghes: Factor out ioremap virtual memory for IRQ and NMI context.
GHES currently maps two pages with atomic_ioremap. From now
on, NMI is architectural depended so there is no need to allocate
an NMI page for platforms without NMI support.
To make it possible to not use a second page, swap the existing
page order so that the IRQ context page is first, and the optional
NMI context page is second. Then, use HAVE_ACPI_APEI_NMI to decide
how many pages are to be allocated.
Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
Acked-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r-- | arch/x86/kernel/acpi/apei.c | 6 | ||||
-rw-r--r-- | drivers/acpi/apei/ghes.c | 18 | ||||
-rw-r--r-- | include/acpi/apei.h | 1 |
3 files changed, 18 insertions, 7 deletions
diff --git a/arch/x86/kernel/acpi/apei.c b/arch/x86/kernel/acpi/apei.c index 12b13de55255..c280df6b2aa2 100644 --- a/arch/x86/kernel/acpi/apei.c +++ b/arch/x86/kernel/acpi/apei.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <acpi/apei.h> | 15 | #include <acpi/apei.h> |
16 | 16 | ||
17 | #include <asm/mce.h> | 17 | #include <asm/mce.h> |
18 | #include <asm/tlbflush.h> | ||
18 | 19 | ||
19 | int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data) | 20 | int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data) |
20 | { | 21 | { |
@@ -54,3 +55,8 @@ void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err) | |||
54 | apei_mce_report_mem_error(sev, mem_err); | 55 | apei_mce_report_mem_error(sev, mem_err); |
55 | #endif | 56 | #endif |
56 | } | 57 | } |
58 | |||
59 | void arch_apei_flush_tlb_one(unsigned long addr) | ||
60 | { | ||
61 | __flush_tlb_one(addr); | ||
62 | } | ||
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 7fcf4d7b41f6..e05d84e7b06d 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -105,12 +105,16 @@ static DEFINE_MUTEX(ghes_list_mutex); | |||
105 | */ | 105 | */ |
106 | 106 | ||
107 | /* | 107 | /* |
108 | * Two virtual pages are used, one for NMI context, the other for | 108 | * Two virtual pages are used, one for IRQ/PROCESS context, the other for |
109 | * IRQ/PROCESS context | 109 | * NMI context (optionally). |
110 | */ | 110 | */ |
111 | #define GHES_IOREMAP_PAGES 2 | 111 | #ifdef CONFIG_HAVE_ACPI_APEI_NMI |
112 | #define GHES_IOREMAP_NMI_PAGE(base) (base) | 112 | #define GHES_IOREMAP_PAGES 2 |
113 | #define GHES_IOREMAP_IRQ_PAGE(base) ((base) + PAGE_SIZE) | 113 | #else |
114 | #define GHES_IOREMAP_PAGES 1 | ||
115 | #endif | ||
116 | #define GHES_IOREMAP_IRQ_PAGE(base) (base) | ||
117 | #define GHES_IOREMAP_NMI_PAGE(base) ((base) + PAGE_SIZE) | ||
114 | 118 | ||
115 | /* virtual memory area for atomic ioremap */ | 119 | /* virtual memory area for atomic ioremap */ |
116 | static struct vm_struct *ghes_ioremap_area; | 120 | static struct vm_struct *ghes_ioremap_area; |
@@ -173,7 +177,7 @@ static void ghes_iounmap_nmi(void __iomem *vaddr_ptr) | |||
173 | 177 | ||
174 | BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_NMI_PAGE(base)); | 178 | BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_NMI_PAGE(base)); |
175 | unmap_kernel_range_noflush(vaddr, PAGE_SIZE); | 179 | unmap_kernel_range_noflush(vaddr, PAGE_SIZE); |
176 | __flush_tlb_one(vaddr); | 180 | arch_apei_flush_tlb_one(vaddr); |
177 | } | 181 | } |
178 | 182 | ||
179 | static void ghes_iounmap_irq(void __iomem *vaddr_ptr) | 183 | static void ghes_iounmap_irq(void __iomem *vaddr_ptr) |
@@ -183,7 +187,7 @@ static void ghes_iounmap_irq(void __iomem *vaddr_ptr) | |||
183 | 187 | ||
184 | BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_IRQ_PAGE(base)); | 188 | BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_IRQ_PAGE(base)); |
185 | unmap_kernel_range_noflush(vaddr, PAGE_SIZE); | 189 | unmap_kernel_range_noflush(vaddr, PAGE_SIZE); |
186 | __flush_tlb_one(vaddr); | 190 | arch_apei_flush_tlb_one(vaddr); |
187 | } | 191 | } |
188 | 192 | ||
189 | static int ghes_estatus_pool_init(void) | 193 | static int ghes_estatus_pool_init(void) |
diff --git a/include/acpi/apei.h b/include/acpi/apei.h index 8a23c95109c6..76284bb560a6 100644 --- a/include/acpi/apei.h +++ b/include/acpi/apei.h | |||
@@ -44,6 +44,7 @@ int erst_clear(u64 record_id); | |||
44 | 44 | ||
45 | int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data); | 45 | int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data); |
46 | void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err); | 46 | void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err); |
47 | void arch_apei_flush_tlb_one(unsigned long addr); | ||
47 | 48 | ||
48 | #endif | 49 | #endif |
49 | #endif | 50 | #endif |