FILE
mce.c
File preview with syntax highlighting.
linux-6.19.14/drivers/cxl/core/mce.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.