File Index
Files and directories
Sign in
FILE

mce.c

File preview with syntax highlighting.

linux-6.19.14/drivers/cxl/core/mce.c C
 1// SPDX-License-Identifier: GPL-2.0-only
 2/* Copyright(c) 2024 Intel Corporation. All rights reserved. */
 3#include <linux/mm.h>
 4#include <linux/notifier.h>
 5#include <linux/set_memory.h>
 6#include <asm/mce.h>
 7#include <cxlmem.h>
 8#include "mce.h"
 9
10static int cxl_handle_mce(struct notifier_block *nb, unsigned long val,
11			  void *data)
12{
13	struct cxl_memdev_state *mds = container_of(nb, struct cxl_memdev_state,
14						    mce_notifier);
15	struct cxl_memdev *cxlmd = mds->cxlds.cxlmd;
16	struct cxl_port *endpoint = cxlmd->endpoint;
17	struct mce *mce = data;
18	u64 spa, spa_alias;
19	unsigned long pfn;
20
21	if (!mce || !mce_usable_address(mce))
22		return NOTIFY_DONE;
23
24	if (!endpoint)
25		return NOTIFY_DONE;
26
27	spa = mce->addr & MCI_ADDR_PHYSADDR;
28
29	pfn = spa >> PAGE_SHIFT;
30	if (!pfn_valid(pfn))
31		return NOTIFY_DONE;
32
33	spa_alias = cxl_port_get_spa_cache_alias(endpoint, spa);
34	if (spa_alias == ~0ULL)
35		return NOTIFY_DONE;
36
37	pfn = spa_alias >> PAGE_SHIFT;
38
39	/*
40	 * Take down the aliased memory page. The original memory page flagged
41	 * by the MCE will be taken cared of by the standard MCE handler.
42	 */
43	dev_emerg(mds->cxlds.dev, "Offlining aliased SPA address0: %#llx\n",
44		  spa_alias);
45	if (!memory_failure(pfn, 0))
46		set_mce_nospec(pfn);
47
48	return NOTIFY_OK;
49}
50
51static void cxl_unregister_mce_notifier(void *mce_notifier)
52{
53	mce_unregister_decode_chain(mce_notifier);
54}
55
56int devm_cxl_register_mce_notifier(struct device *dev,
57				   struct notifier_block *mce_notifier)
58{
59	mce_notifier->notifier_call = cxl_handle_mce;
60	mce_notifier->priority = MCE_PRIO_UC;
61	mce_register_decode_chain(mce_notifier);
62
63	return devm_add_action_or_reset(dev, cxl_unregister_mce_notifier,
64					mce_notifier);
65}
~/ Read-only file preview.