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 hest.c manage the estatus memory pool
Browse files Browse the repository at this point in the history
ghes.c has a memory pool it uses for the estatus cache and the estatus
queue. The cache is initialised when registering the platform driver.
For the queue, an NMI-like notification has to grow/shrink the pool
as it is registered and unregistered.

This is all pretty noisy when adding new NMI-like notifications, it
would be better to replace this with a static pool size based on the
number of users.

As a precursor, move the call that creates the pool from ghes_init(),
into hest.c. Later this will take the number of ghes entries and
consolidate the queue allocations.
Remove ghes_estatus_pool_exit() as hest.c doesn't have anywhere to put
this.

The pool is now initialised as part of ACPI's subsys_initcall():
(acpi_init(), acpi_scan_init(), acpi_pci_root_init(), acpi_hest_init())
Before this patch it happened later as a GHES specific device_initcall().

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@e147133

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 a33b383 commit 9778f65
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 28 deletions.
33 changes: 6 additions & 27 deletions drivers/acpi/apei/ghes.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,26 +162,16 @@ static void ghes_iounmap_irq(void)
clear_fixmap(FIX_APEI_GHES_IRQ);
}

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

int ghes_estatus_pool_init(void)
{
ghes_estatus_pool = gen_pool_create(GHES_ESTATUS_POOL_MIN_ALLOC_ORDER, -1);
if (!ghes_estatus_pool)
return -ENOMEM;
return 0;
}

static void ghes_estatus_pool_free_chunk(struct gen_pool *pool,
struct gen_pool_chunk *chunk,
void *data)
{
vfree((void *)chunk->start_addr);
}

static void ghes_estatus_pool_exit(void)
{
gen_pool_for_each_chunk(ghes_estatus_pool,
ghes_estatus_pool_free_chunk, NULL);
gen_pool_destroy(ghes_estatus_pool);
return ghes_estatus_pool_expand(GHES_ESTATUS_CACHE_AVG_SIZE *
GHES_ESTATUS_CACHE_ALLOCED_MAX);
}

static int ghes_estatus_pool_expand(unsigned long len)
Expand Down Expand Up @@ -1227,18 +1217,9 @@ static int __init ghes_init(void)

ghes_nmi_init_cxt();

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

rc = ghes_estatus_pool_expand(GHES_ESTATUS_CACHE_AVG_SIZE *
GHES_ESTATUS_CACHE_ALLOCED_MAX);
if (rc)
goto err_pool_exit;

rc = platform_driver_register(&ghes_platform_driver);
if (rc)
goto err_pool_exit;
goto err;

rc = apei_osc_setup();
if (rc == 0 && osc_sb_apei_support_acked)
Expand All @@ -1251,8 +1232,6 @@ static int __init ghes_init(void)
pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");

return 0;
err_pool_exit:
ghes_estatus_pool_exit();
err:
return rc;
}
Expand Down
10 changes: 9 additions & 1 deletion drivers/acpi/apei/hest.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <linux/io.h>
#include <linux/platform_device.h>
#include <acpi/apei.h>
#include <acpi/ghes.h>

#include "apei-internal.h"

Expand Down Expand Up @@ -211,6 +212,11 @@ static int __init hest_ghes_dev_register(unsigned int ghes_count)
rc = apei_hest_parse(hest_parse_ghes, &ghes_arr);
if (rc)
goto err;

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

out:
kfree(ghes_arr.ghes_devs);
return rc;
Expand Down Expand Up @@ -259,7 +265,9 @@ void __init acpi_hest_init(void)
rc = apei_hest_parse(hest_parse_ghes_count, &ghes_count);
if (rc)
goto err;
rc = hest_ghes_dev_register(ghes_count);

if (ghes_count)
rc = hest_ghes_dev_register(ghes_count);
if (rc)
goto err;
}
Expand Down
2 changes: 2 additions & 0 deletions include/acpi/ghes.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ enum {
GHES_SEV_PANIC = 0x3,
};

int ghes_estatus_pool_init(void);

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

#ifdef CONFIG_EDAC_GHES
Expand Down

0 comments on commit 9778f65

Please sign in to comment.