Re: [PATCH v2] tools/mm: add hwpoison-panic tool

Miaohe Lin <[email protected]>
Newsgroups org.infradead.lists.linux-riscv,org.kernel.vger.linux-kernel,org.kvack.linux-mm
Message-ID <[email protected]>
On 2026/8/3 19:31, Breno Leitao wrote:
> Add a tool that enables the vm.panic_on_unrecoverable_memory_failure
> sysctl, picks a kernel-owned PFN and writes its physical address to
> hard_offline_page.  Three page kinds are selectable with -k: rodata
> (default), slab or pgtable. In all cases the host should panic.
> 
> Example:
> 
>         # ./hwpoison-panic -k slab --yes-panic-my-kernel
>         injecting hwpoison at phys 0x100032000 (pfn 0x100032, kind=slab)
>         expecting kernel panic: 'Memory failure: <pfn>: unrecoverable page'
> 
> In dmesg, you will see:
> 
>         Memory failure: 0x100032: unhandlable page.
>         Memory failure: 0x100032: recovery action for reserved kernel page: Ignored
>         Kernel panic - not syncing: Memory failure: 0x100032: unrecoverable page
> 
> This lives in tools/mm rather than selftests/mm because every successful
> run crashes the machine, which is not something to run from CI.
> 
> The --yes-panic-my-kernel argument is required so an accidental
> invocation does not take the box down.
> 
> Signed-off-by: Breno Leitao <[email protected]>

This patch looks good to me with some nits below.

> ---
> Changes in v2:
> - Reword the file header, the tool triggers a panic rather than
>   confirming one (SJ Park)
> - Rename -f to --yes-panic-my-kernel and say in usage() what it costs
>   (SJ Park)
> - Call check_prereqs() before getpagesize() (SJ Park)
> - Use 64-bit types for physical addresses and PFNs.  On a 32-bit build
>   the old long/unsigned long pair truncated addresses above 4G, and the
>   negative error sentinel was indistinguishable from a valid address at
>   or above 2G
> - Link to v1: https://patch.msgid.link/20260731-memory_failure_rewrite_test-v1-1-6aa8c6435693@debian.org
...
> +
> +static int pick_kpageflags_phys_addr(uint64_t want, uint64_t *phys_addr)
> +{
> +	uint64_t pfn = (16UL << 20) / page_size;

Could we use SZ_16M macro here?

> +	uint64_t flags;
> +	int ret = -1;
> +	int fd;
> +
> +	fd = open(PROC_KPAGEFLAGS, O_RDONLY);
> +	if (fd < 0)
> +		return -1;
> +
> +	for (; kpageflags_read(fd, pfn, &flags) == 0; pfn++) {
> +		if ((flags & want) && !(flags & BIT(HWPOISON)) &&
> +		    !(flags & BIT(NOPAGE)) && !(flags & BIT(COMPOUND_TAIL))) {
> +			*phys_addr = pfn * page_size;
> +			ret = 0;
> +			break;
> +		}
> +	}
> +
> +	close(fd);
> +	return ret;
> +}
> +
> +static int read_sysctl(unsigned long *val)
> +{
> +	FILE *f = fopen(SYSCTL_PATH, "r");
> +	int ret;
> +
> +	if (!f)
> +		return -1;
> +	ret = fscanf(f, "%lu", val) == 1 ? 0 : -1;
> +	fclose(f);
> +
> +	return ret;
> +}
> +
> +static int write_sysctl(unsigned long val)
> +{
> +	FILE *f = fopen(SYSCTL_PATH, "w");
> +	int ret;
> +
> +	if (!f)
> +		return -1;
> +	ret = fprintf(f, "%lu", val) < 0 ? -1 : 0;
> +	fclose(f);
> +
> +	return ret;
> +}
> +
> +/* hard_offline_page() injects with MF_SW_SIMULATED, so unpoison is allowed. */
> +static void unpoison_pfn(uint64_t pfn)
> +{
> +	char path[PATH_MAX], buf[32];
> +	const char *debugfs;
> +	int fd, len;
> +
> +	debugfs = debugfs__mount();

I might be miss something but I can't find the implementation of debugfs__mount.

> +	if (!debugfs)
> +		return;
> +
> +	snprintf(path, sizeof(path), "%s/hwpoison/unpoison-pfn", debugfs);
> +	fd = open(path, O_WRONLY);
> +	if (fd < 0)
> +		return;
> +
> +	len = snprintf(buf, sizeof(buf), "0x%llx\n", (unsigned long long)pfn);
> +	if (write(fd, buf, len) < 0)
> +		perror("unpoison-pfn");
> +	close(fd);
> +}
> +
...
> +
> +static void check_prereqs(int armed)
> +{
> +	if (geteuid())
> +		fatal("must run as root\n");
> +	if (access(SYSCTL_PATH, W_OK))
> +		fatal("%s not present (kernel without the sysctl?)\n",
> +		      SYSCTL_PATH);
> +	if (access(INJECT_PATH, W_OK))
> +		fatal("%s not present (no MEMORY_HOTPLUG?)\n", INJECT_PATH);

MEMORY_HOTPLUG?

Thanks.
.

_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.