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>
This commit is contained in:
Tomasz Nowicki
2014-07-22 11:20:13 +02:00
committed by Tony Luck
parent 44a69f6195
commit 594c7255dc
3 changed files with 18 additions and 7 deletions

View File

@@ -15,6 +15,7 @@
#include <acpi/apei.h> #include <acpi/apei.h>
#include <asm/mce.h> #include <asm/mce.h>
#include <asm/tlbflush.h>
int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data) int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data)
{ {
@@ -54,3 +55,8 @@ void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
apei_mce_report_mem_error(sev, mem_err); apei_mce_report_mem_error(sev, mem_err);
#endif #endif
} }
void arch_apei_flush_tlb_one(unsigned long addr)
{
__flush_tlb_one(addr);
}

View File

@@ -105,12 +105,16 @@ static DEFINE_MUTEX(ghes_list_mutex);
*/ */
/* /*
* Two virtual pages are used, one for NMI context, the other for * Two virtual pages are used, one for IRQ/PROCESS context, the other for
* IRQ/PROCESS context * NMI context (optionally).
*/ */
#define GHES_IOREMAP_PAGES 2 #ifdef CONFIG_HAVE_ACPI_APEI_NMI
#define GHES_IOREMAP_NMI_PAGE(base) (base) #define GHES_IOREMAP_PAGES 2
#define GHES_IOREMAP_IRQ_PAGE(base) ((base) + PAGE_SIZE) #else
#define GHES_IOREMAP_PAGES 1
#endif
#define GHES_IOREMAP_IRQ_PAGE(base) (base)
#define GHES_IOREMAP_NMI_PAGE(base) ((base) + PAGE_SIZE)
/* virtual memory area for atomic ioremap */ /* virtual memory area for atomic ioremap */
static struct vm_struct *ghes_ioremap_area; static struct vm_struct *ghes_ioremap_area;
@@ -173,7 +177,7 @@ static void ghes_iounmap_nmi(void __iomem *vaddr_ptr)
BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_NMI_PAGE(base)); BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_NMI_PAGE(base));
unmap_kernel_range_noflush(vaddr, PAGE_SIZE); unmap_kernel_range_noflush(vaddr, PAGE_SIZE);
__flush_tlb_one(vaddr); arch_apei_flush_tlb_one(vaddr);
} }
static void ghes_iounmap_irq(void __iomem *vaddr_ptr) static void ghes_iounmap_irq(void __iomem *vaddr_ptr)
@@ -183,7 +187,7 @@ static void ghes_iounmap_irq(void __iomem *vaddr_ptr)
BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_IRQ_PAGE(base)); BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_IRQ_PAGE(base));
unmap_kernel_range_noflush(vaddr, PAGE_SIZE); unmap_kernel_range_noflush(vaddr, PAGE_SIZE);
__flush_tlb_one(vaddr); arch_apei_flush_tlb_one(vaddr);
} }
static int ghes_estatus_pool_init(void) static int ghes_estatus_pool_init(void)

View File

@@ -44,6 +44,7 @@ int erst_clear(u64 record_id);
int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data); int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data);
void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err); void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err);
void arch_apei_flush_tlb_one(unsigned long addr);
#endif #endif
#endif #endif