Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Commit

Permalink
BACKPORT: ACPI / APEI: Make estatus pool allocation a static size
Browse files Browse the repository at this point in the history
Adding new NMI-like notifications duplicates the calls that grow
and shrink the estatus pool. This is all pretty pointless, as the
size is capped to 64K. Allocate this for each ghes and drop
the code that grows and shrinks the pool.

This patch is needed because Quicksilver firmware-first error handling
uses the SDEI notification type for communication between trusted
firmware and the OS. This adds needed NMI and SDEI functionality so
that the SDEI path in the kernel through APEI acts as an NMI and is
properly wired up to the APEI interfaces.

Backported from: torvalds/linux@fb7be08

Suggested-by: Borislav Petkov <[email protected]>
Signed-off-by: James Morse <[email protected]>
Reviewed-by: Borislav Petkov <[email protected]>
Signed-off-by: Tyler Baicar <[email protected]>
  • Loading branch information
James Morse authored and tphan-ampere committed Apr 21, 2020
1 parent 9778f65 commit 2888525
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 45 deletions.
49 changes: 6 additions & 43 deletions drivers/acpi/apei/ghes.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,27 +162,18 @@ static void ghes_iounmap_irq(void)
clear_fixmap(FIX_APEI_GHES_IRQ);
}

static int ghes_estatus_pool_expand(unsigned long len); //temporary

int ghes_estatus_pool_init(void)
int ghes_estatus_pool_init(int num_ghes)
{
unsigned long addr, len;

ghes_estatus_pool = gen_pool_create(GHES_ESTATUS_POOL_MIN_ALLOC_ORDER, -1);
if (!ghes_estatus_pool)
return -ENOMEM;

return ghes_estatus_pool_expand(GHES_ESTATUS_CACHE_AVG_SIZE *
GHES_ESTATUS_CACHE_ALLOCED_MAX);
}

static int ghes_estatus_pool_expand(unsigned long len)
{
unsigned long size, addr;

ghes_estatus_pool_size_request += PAGE_ALIGN(len);
size = gen_pool_size(ghes_estatus_pool);
if (size >= ghes_estatus_pool_size_request)
return 0;
len = GHES_ESTATUS_CACHE_AVG_SIZE * GHES_ESTATUS_CACHE_ALLOCED_MAX;
len += (num_ghes * GHES_ESOURCE_PREALLOC_MAX_SIZE);

ghes_estatus_pool_size_request = PAGE_ALIGN(len);
addr = (unsigned long)vmalloc(PAGE_ALIGN(len));
if (!addr)
return -ENOMEM;
Expand Down Expand Up @@ -956,32 +947,8 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
return ret;
}

static unsigned long ghes_esource_prealloc_size(
const struct acpi_hest_generic *generic)
{
unsigned long block_length, prealloc_records, prealloc_size;

block_length = min_t(unsigned long, generic->error_block_length,
GHES_ESTATUS_MAX_SIZE);
prealloc_records = max_t(unsigned long,
generic->records_to_preallocate, 1);
prealloc_size = min_t(unsigned long, block_length * prealloc_records,
GHES_ESOURCE_PREALLOC_MAX_SIZE);

return prealloc_size;
}

static void ghes_estatus_pool_shrink(unsigned long len)
{
ghes_estatus_pool_size_request -= PAGE_ALIGN(len);
}

static void ghes_nmi_add(struct ghes *ghes)
{
unsigned long len;

len = ghes_esource_prealloc_size(ghes->generic);
ghes_estatus_pool_expand(len);
mutex_lock(&ghes_list_mutex);
if (list_empty(&ghes_nmi))
register_nmi_handler(NMI_LOCAL, ghes_notify_nmi, 0, "ghes");
Expand All @@ -991,8 +958,6 @@ static void ghes_nmi_add(struct ghes *ghes)

static void ghes_nmi_remove(struct ghes *ghes)
{
unsigned long len;

mutex_lock(&ghes_list_mutex);
list_del_rcu(&ghes->list);
if (list_empty(&ghes_nmi))
Expand All @@ -1003,8 +968,6 @@ static void ghes_nmi_remove(struct ghes *ghes)
* freed after NMI handler finishes.
*/
synchronize_rcu();
len = ghes_esource_prealloc_size(ghes->generic);
ghes_estatus_pool_shrink(len);
}

static void ghes_nmi_init_cxt(void)
Expand Down
2 changes: 1 addition & 1 deletion drivers/acpi/apei/hest.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ static int __init hest_ghes_dev_register(unsigned int ghes_count)
if (rc)
goto err;

rc = ghes_estatus_pool_init();
rc = ghes_estatus_pool_init(ghes_count);
if (rc)
goto err;

Expand Down
2 changes: 1 addition & 1 deletion include/acpi/ghes.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ enum {
GHES_SEV_PANIC = 0x3,
};

int ghes_estatus_pool_init(void);
int ghes_estatus_pool_init(int num_ghes);

/* From drivers/edac/ghes_edac.c */

Expand Down

0 comments on commit 2888525

Please sign in to comment.