* [PATCH 05/11] of: reserved_mem: add linux,no-dump property support for reserved memory regions
From: Chen Wandun @ 2026-04-29 6:58 UTC (permalink / raw)
To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
linux-riscv, devicetree
Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao
In-Reply-To: <20260429065831.1510858-1-chenwandun@lixiang.com>
Add a 'no_dump' field to struct reserved_mem and parse the
'linux,no-dump' device tree property during reserved memory node
initialization. This property allows device tree authors to mark
specific reserved memory regions that should be excluded from kdump
vmcore dumps.
Reserved memory regions used by device firmware (e.g., GPU, DSP, modem)
typically contain data that is not useful for kernel crash analysis and
can significantly increase vmcore size. The 'linux,no-dump' property
provides a declarative way to indicate these regions should be filtered
out when constructing the elfcorehdr for kdump.
The property is named with a 'linux,' prefix because kdump/vmcore is
Linux-specific and the property is an OS hint rather than a hardware
description, matching existing properties such as 'linux,cma-default'
and 'linux,usable-memory-range'.
The 'linux,no-dump' property is only effective when the region:
- Does not have 'no-map': these regions are already excluded from
vmcore since they are removed from the linear mapping (MEMBLOCK_NOMAP).
- Does not have 'reusable': CMA reusable regions are actively used by
the kernel for movable page allocations, and their contents are
valuable for crash analysis.
The no-dump status is also printed in the boot log alongside the
existing nomap and reusable flags for diagnostic purposes.
Corresponding dt-schema binding update:
https://github.com/devicetree-org/dt-schema/pull/193
Signed-off-by: Chen Wandun <chenwandun@lixiang.com>
Tested-by: Zhao Meijing <zhaomeijing@lixiang.com>
---
drivers/of/of_reserved_mem.c | 13 ++++++++-----
include/linux/of_reserved_mem.h | 1 +
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 93585af9f8a3..ac3d8b837d61 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -654,6 +654,7 @@ static void __init fdt_init_reserved_mem_node(unsigned long node, const char *un
{
int err = 0;
bool nomap;
+ bool reusable;
struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
@@ -662,11 +663,14 @@ static void __init fdt_init_reserved_mem_node(unsigned long node, const char *un
return;
}
+ nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
+ reusable = of_get_flat_dt_prop(node, "reusable", NULL) != NULL;
+
rmem->name = uname;
rmem->base = base;
rmem->size = size;
-
- nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
+ rmem->no_dump = !nomap && !reusable &&
+ of_get_flat_dt_prop(node, "linux,no-dump", NULL) != NULL;
err = __reserved_mem_init_node(rmem, node);
if (err != 0 && err != -ENODEV) {
@@ -680,13 +684,12 @@ static void __init fdt_init_reserved_mem_node(unsigned long node, const char *un
return;
} else {
phys_addr_t end = rmem->base + rmem->size - 1;
- bool reusable =
- (of_get_flat_dt_prop(node, "reusable", NULL)) != NULL;
- pr_info("%pa..%pa (%lu KiB) %s %s %s\n",
+ pr_info("%pa..%pa (%lu KiB) %s %s %s %s\n",
&rmem->base, &end, (unsigned long)(rmem->size / SZ_1K),
nomap ? "nomap" : "map",
reusable ? "reusable" : "non-reusable",
+ rmem->no_dump ? "no-dump" : "dump",
rmem->name ? rmem->name : "unknown");
}
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index e8b20b29fa68..29674f572673 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -15,6 +15,7 @@ struct reserved_mem {
phys_addr_t base;
phys_addr_t size;
void *priv;
+ bool no_dump;
};
struct reserved_mem_ops {
--
2.43.0
^ permalink raw reply related
* [PATCH 04/11] of: reserved_mem: skip reserved_mem array allocation when there is nothing to save
From: Chen Wandun @ 2026-04-29 6:58 UTC (permalink / raw)
To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
linux-riscv, devicetree
Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao
In-Reply-To: <20260429065831.1510858-1-chenwandun@lixiang.com>
fdt_scan_reserved_mem_late() unconditionally calls
alloc_reserved_mem_array() after confirming /reserved-memory exists.
Two issues with that:
- When __reserved_mem_check_root() subsequently fails, the call
returns right away, leaving the freshly allocated array unused.
- When /reserved-memory exists but fdt_scan_reserved_mem() found no
entries to save (total_reserved_mem_cnt stays at its freshly-set
value of zero, e.g. empty node or all children disabled),
alloc_reserved_mem_array() ends up calling memblock_alloc() with
zero size, which returns NULL and logs an "Failed to allocate
memory for reserved_mem array" error even though nothing was
expected to be allocated.
Move alloc_reserved_mem_array() past the root-node check and gate it
on total_reserved_mem_cnt, so the array is only allocated when there
is at least one entry that needs a slot.
Fixes: 00c9a452a235 ("of: reserved_mem: Add code to dynamically allocate reserved_mem array")
Signed-off-by: Chen Wandun <chenwandun@lixiang.com>
Tested-by: Zhao Meijing <zhaomeijing@lixiang.com>
---
drivers/of/of_reserved_mem.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 807b222fce5f..93585af9f8a3 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -276,14 +276,22 @@ void __init fdt_scan_reserved_mem_late(void)
return;
}
- /* Attempt dynamic allocation of a new reserved_mem array */
- alloc_reserved_mem_array();
-
if (__reserved_mem_check_root(node)) {
pr_err("Reserved memory: unsupported node format, ignoring\n");
return;
}
+ /*
+ * fdt_scan_reserved_mem() sets total_reserved_mem_cnt to the
+ * number of entries that need a slot in reserved_mem[]. If it is
+ * zero there is nothing to allocate or save.
+ */
+ if (!total_reserved_mem_cnt)
+ return;
+
+ /* Attempt dynamic allocation of a new reserved_mem array */
+ alloc_reserved_mem_array();
+
fdt_for_each_subnode(child, fdt, node) {
const char *uname;
int i, len;
--
2.43.0
^ permalink raw reply related
* [PATCH 03/11] of: reserved_mem: avoid unconditional save of reg entries in fdt_scan_reserved_mem_late()
From: Chen Wandun @ 2026-04-29 6:58 UTC (permalink / raw)
To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
linux-riscv, devicetree
Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao
In-Reply-To: <20260429065831.1510858-1-chenwandun@lixiang.com>
fdt_scan_reserved_mem_late() iterates all reg entries of every
/reserved-memory child and unconditionally initialises each via
fdt_init_reserved_mem_node(), while fdt_scan_reserved_mem() in the
first pass may have rejected individual entries in
early_init_dt_reserve_memory() (e.g. outside physical memory or, on
the no-map path, overlapping an existing reservation).
When a single node mixes failing and succeeding reg entries, the
first-pass counter only accounts for the successful ones, and the
second-pass save then overflows into the wrong slots: the failing
entry may be written to reserved_mem[] while the succeeding one is
dropped by the "not enough space" guard in fdt_init_reserved_mem_node().
The stored entry does not correspond to any real memblock reservation
and misleads consumers such as of_reserved_mem_lookup().
Mirror early_init_dt_reserve_memory()'s preconditions in the
per-reg-entry save loop:
- skip the entry if it does not overlap memblock.memory;
- for nomap entries, skip if the region is already reserved.
This keeps reserved_mem[] strictly consistent with the regions that
were actually reserved.
Fixes: 8a6e02d0c00e ("of: reserved_mem: Restructure how the reserved memory regions are processed")
Signed-off-by: Chen Wandun <chenwandun@lixiang.com>
Tested-by: Zhao Meijing <zhaomeijing@lixiang.com>
---
drivers/of/of_reserved_mem.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 03c676052dab..807b222fce5f 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -288,6 +288,7 @@ void __init fdt_scan_reserved_mem_late(void)
const char *uname;
int i, len;
const __be32 *prop;
+ bool nomap;
int ret;
if (!of_fdt_device_is_available(fdt, child))
@@ -301,6 +302,7 @@ void __init fdt_scan_reserved_mem_late(void)
if (ret && ret != -ENODEV)
continue;
+ nomap = of_get_flat_dt_prop(child, "no-map", NULL) != NULL;
uname = fdt_get_name(fdt, child, NULL);
for (i = 0; i < len; i++) {
u64 b, s;
@@ -310,8 +312,23 @@ void __init fdt_scan_reserved_mem_late(void)
base = b;
size = s;
- if (size)
- fdt_init_reserved_mem_node(child, uname, base, size);
+ if (!size)
+ continue;
+
+ /*
+ * Save only entries that were successfully reserved
+ * in the first pass. Mirrors the preconditions in
+ * early_init_dt_reserve_memory() so that a per-reg
+ * entry failure (outside RAM, or nomap rejected due
+ * to an existing reservation) does not leave a
+ * ghost slot in reserved_mem[].
+ */
+ if (!memblock_overlaps_region(&memblock.memory, base, size))
+ continue;
+ if (nomap && memblock_is_region_reserved(base, size))
+ continue;
+
+ fdt_init_reserved_mem_node(child, uname, base, size);
}
}
--
2.43.0
^ permalink raw reply related
* [PATCH 02/11] of: reserved_mem: reject reserved memory outside physical address range
From: Chen Wandun @ 2026-04-29 6:58 UTC (permalink / raw)
To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
linux-riscv, devicetree
Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao
In-Reply-To: <20260429065831.1510858-1-chenwandun@lixiang.com>
early_init_dt_reserve_memory() does not validate whether the region
falls within physical memory. If a device tree incorrectly specifies a
reserved memory region outside the physical address range:
- For the non-nomap path, memblock_reserve() blindly adds the region
to memblock.reserved, creating a stale entry that refers to
non-existent memory.
- For the nomap path, memblock_mark_nomap() silently fails to match
any region in memblock.memory, but still returns success.
Add a memblock_overlaps_region() check at the entry of
early_init_dt_reserve_memory() to reject such regions before any
memblock operation takes place. This also simplifies the existing nomap
guard: the original "overlaps && is_reserved" condition reduces to just
"is_reserved", since the overlap with physical memory is already
guaranteed by the new check.
Signed-off-by: Chen Wandun <chenwandun@lixiang.com>
Tested-by: Zhao Meijing <zhaomeijing@lixiang.com>
---
drivers/of/of_reserved_mem.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 9d1b0193864c..03c676052dab 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -112,14 +112,21 @@ static int fdt_fixup_reserved_mem_node(unsigned long node,
static int __init early_init_dt_reserve_memory(phys_addr_t base,
phys_addr_t size, bool nomap)
{
+ if (!memblock_overlaps_region(&memblock.memory, base, size)) {
+ phys_addr_t end = base + size - 1;
+
+ pr_warn("Reserved memory region %pa..%pa is outside of physical memory\n",
+ &base, &end);
+ return -EINVAL;
+ }
+
if (nomap) {
/*
* If the memory is already reserved (by another region), we
- * should not allow it to be marked nomap, but don't worry
- * if the region isn't memory as it won't be mapped.
+ * should not allow it to be marked nomap. The region being
+ * physical memory is guaranteed by the overlap check above.
*/
- if (memblock_overlaps_region(&memblock.memory, base, size) &&
- memblock_is_region_reserved(base, size))
+ if (memblock_is_region_reserved(base, size))
return -EBUSY;
return memblock_mark_nomap(base, size);
--
2.43.0
^ permalink raw reply related
* [PATCH 01/11] of: reserved_mem: fix region count for nodes with multiple reg entries
From: Chen Wandun @ 2026-04-29 6:58 UTC (permalink / raw)
To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
linux-riscv, devicetree
Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao
In-Reply-To: <20260429065831.1510858-1-chenwandun@lixiang.com>
When a reserved-memory node contains multiple reg entries (e.g.,
reg = <base1 size1>, <base2 size2>), the count used for
total_reserved_mem_cnt is wrong in two places:
1) __reserved_mem_reserve_reg() returns 0 on success regardless of how
many regions it reserved in memblock. The caller in
fdt_scan_reserved_mem() then increments count by just 1.
2) fdt_scan_reserved_mem_late() uses of_flat_dt_get_addr_size() which
only reads the first reg entry. Subsequent entries are never
initialized via fdt_init_reserved_mem_node(), so their metadata is
lost.
Fix both issues:
- Make __reserved_mem_reserve_reg() return the actual number of
regions successfully reserved. Update the caller to accumulate
the returned count.
- Rewrite fdt_scan_reserved_mem_late() to use
of_flat_dt_get_addr_size_prop() and iterate all reg entries,
initializing each one via fdt_init_reserved_mem_node().
Fixes: 8a6e02d0c00e ("of: reserved_mem: Restructure how the reserved memory regions are processed")
Fixes: 00c9a452a235 ("of: reserved_mem: Add code to dynamically allocate reserved_mem array")
Signed-off-by: Chen Wandun <chenwandun@lixiang.com>
Tested-by: Zhao Meijing <zhaomeijing@lixiang.com>
---
drivers/of/of_reserved_mem.c | 37 +++++++++++++++++++++++-------------
1 file changed, 24 insertions(+), 13 deletions(-)
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 8d5777cb5d1b..9d1b0193864c 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -129,6 +129,8 @@ static int __init early_init_dt_reserve_memory(phys_addr_t base,
/*
* __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property
+ *
+ * Returns: number of regions successfully reserved, or negative error code
*/
static int __init __reserved_mem_reserve_reg(unsigned long node,
const char *uname)
@@ -137,6 +139,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
int i, len, err;
const __be32 *prop;
bool nomap;
+ int reserved_count = 0;
prop = of_flat_dt_get_addr_size_prop(node, "reg", &len);
if (!prop)
@@ -160,12 +163,13 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
fdt_fixup_reserved_mem_node(node, base, size);
pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n",
uname, &base, (unsigned long)(size / SZ_1M));
+ reserved_count++;
} else {
pr_err("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n",
uname, &base, (unsigned long)(size / SZ_1M));
}
}
- return 0;
+ return reserved_count;
}
/*
@@ -275,25 +279,32 @@ void __init fdt_scan_reserved_mem_late(void)
fdt_for_each_subnode(child, fdt, node) {
const char *uname;
- u64 b, s;
+ int i, len;
+ const __be32 *prop;
int ret;
if (!of_fdt_device_is_available(fdt, child))
continue;
- if (!of_flat_dt_get_addr_size(child, "reg", &b, &s))
+ prop = of_flat_dt_get_addr_size_prop(child, "reg", &len);
+ if (!prop)
continue;
ret = fdt_validate_reserved_mem_node(child, NULL);
if (ret && ret != -ENODEV)
continue;
- base = b;
- size = s;
+ uname = fdt_get_name(fdt, child, NULL);
+ for (i = 0; i < len; i++) {
+ u64 b, s;
- if (size) {
- uname = fdt_get_name(fdt, child, NULL);
- fdt_init_reserved_mem_node(child, uname, base, size);
+ of_flat_dt_read_addr_size(prop, i, &b, &s);
+
+ base = b;
+ size = s;
+
+ if (size)
+ fdt_init_reserved_mem_node(child, uname, base, size);
}
}
@@ -331,16 +342,16 @@ int __init fdt_scan_reserved_mem(void)
fdt_for_each_subnode(child, fdt, node) {
const char *uname;
- int err;
+ int ret;
if (!of_fdt_device_is_available(fdt, child))
continue;
uname = fdt_get_name(fdt, child, NULL);
- err = __reserved_mem_reserve_reg(child, uname);
- if (!err)
- count++;
+ ret = __reserved_mem_reserve_reg(child, uname);
+ if (ret > 0)
+ count += ret;
/*
* Save the nodes for the dynamically-placed regions
* into an array which will be used for allocation right
@@ -348,7 +359,7 @@ int __init fdt_scan_reserved_mem(void)
* or marked as no-map. This is done to avoid dynamically
* allocating from one of the statically-placed regions.
*/
- if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL)) {
+ if (ret == -ENOENT && of_get_flat_dt_prop(child, "size", NULL)) {
dynamic_nodes[dynamic_nodes_cnt] = child;
dynamic_nodes_cnt++;
}
--
2.43.0
^ permalink raw reply related
* [PATCH 00/11] kdump: reduce vmcore size and capture time via linux,no-dump
From: Chen Wandun @ 2026-04-29 6:58 UTC (permalink / raw)
To: kexec, linux-doc, linux-kernel, linux-arm-kernel, loongarch,
linux-riscv, devicetree
Cc: akpm, bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, corbet,
skhan, catalin.marinas, will, chenhuacai, kernel, pjw, palmer,
aou, robh, saravanak, chenwandun, zhaomeijing, everyzhao
This series has two parts:
- Patches 1-4 are OF reserved_mem bug fixes and small hardening
changes. They stand on their own and at the same time prepare the
ground for the feature work that follows (accurate region counts,
consistent two-pass save/reserve state, and an early-out when the
array is empty).
- Patches 5-11 introduce a new 'linux,no-dump' reserved-memory
device tree property and the kdump plumbing to honour it, split
further as:
* Patches 5-7: core OF changes - parse 'linux,no-dump' on
/reserved-memory/ children, save /memreserve/ firmware regions
into reserved_mem[] with no_dump defaulted on, and add generic
no-dump crash_mem exclusion helpers.
* Patches 8-10: arch kdump consumers - arm64, riscv and
loongarch each call the helpers from patch 7 in their
prepare_elf_headers() so that 'linux,no-dump' /reserved-memory/
children and /memreserve/ regions are filtered out of the
vmcore ELF PT_LOAD segments.
* Patch 11: user-facing documentation in
Documentation/admin-guide/kdump/kdump.rst.
Motivation
==========
On SoCs that carve out large firmware-owned reserved memory (GPU
firmware, DSP, modem, camera ISP, NPU, ...), kdump currently dumps
those carveouts as part of system RAM even though their contents are
firmware state that is not useful for kernel crash analysis. On a
machine with several hundred MiB of such carveouts, the overhead per
vmcore is substantial.
This series adds a declarative way for DT authors to mark such
regions:
reserved-memory {
npu_fw@a0000000 {
reg = <0x0 0xa0000000 0x0 0x10000000>;
linux,no-dump;
};
};
and also defaults /memreserve/ firmware regions (Trusted Firmware /
BL31 images, secondary-CPU spin-table pens, bootloader scratch per
Documentation/arch/arm64/booting.rst and upstream DTS files) to
no_dump=true.
Interaction with existing reserved-memory flags is kept simple:
'linux,no-dump' is an OS hint, it is redundant (but harmless) when
combined with 'no-map' and silently ignored on 'reusable' (CMA)
regions whose contents are relevant for crash analysis. The 'linux,'
prefix follows existing precedents like 'linux,cma-default' since
kdump is a Linux-specific concept.
Benefits
========
- Smaller vmcore. The excluded firmware carveouts are omitted from
the ELF PT_LOAD segments entirely, so the resulting dump file is
smaller by roughly the sum of the tagged regions - on SoCs with
hundreds of MiB of GPU/DSP/modem/NPU carveouts this is a
substantial saving, both on disk and in transit to a dump server.
- Faster kdump. The dump-capture kernel writes less data to storage
or over the network, which directly shortens the crash-to-dump
turnaround. Tools that walk the dump (makedumpfile, crash) also
spend less time on regions that were never going to be useful
anyway.
- No existing behaviour change for DTs that do not opt in: regions
without 'linux,no-dump' and systems without /memreserve/ entries
are dumped exactly as before.
DT binding
==========
The 'linux,no-dump' property is maintained in dt-schema
(reserved-memory.yaml moved there from the kernel tree).
Corresponding PR:
https://github.com/devicetree-org/dt-schema/pull/193
Follow-ups
==========
- powerpc also uses kexec_file and /reserved-memory/, but its
arch/powerpc/kexec/ranges.c uses the _guarded variant of
crash_exclude_mem_range with dynamic realloc and collects
additional RTAS/OPAL firmware ranges. Adapting it needs a small
extra helper; left as a follow-up.
---
Chen Wandun (11):
of: reserved_mem: fix region count for nodes with multiple reg entries
of: reserved_mem: reject reserved memory outside physical address
range
of: reserved_mem: avoid unconditional save of reg entries in
fdt_scan_reserved_mem_late()
of: reserved_mem: skip reserved_mem array allocation when there is
nothing to save
of: reserved_mem: add linux,no-dump property support for reserved
memory regions
of: reserved_mem: save /memreserve/ entries into reserved_mem array
of: reserved_mem: add no-dump crash_mem exclusion helpers
arm64: kdump: exclude no-dump reserved memory regions from vmcore
riscv: kdump: exclude no-dump reserved memory regions from vmcore
loongarch: kdump: exclude no-dump reserved memory regions from vmcore
Documentation: admin-guide: kdump: document linux,no-dump DT property
Documentation/admin-guide/kdump/kdump.rst | 59 ++++++
arch/arm64/kernel/machine_kexec_file.c | 6 +
arch/loongarch/kernel/machine_kexec_file.c | 6 +
arch/riscv/kernel/machine_kexec_file.c | 4 +
drivers/of/of_reserved_mem.c | 233 ++++++++++++++++++---
include/linux/of_reserved_mem.h | 16 ++
6 files changed, 295 insertions(+), 29 deletions(-)
--
2.43.0
^ permalink raw reply
* Re: [PATCH 2/3] Documentation: security-bugs: explain what is and is not a security bug
From: Greg KH @ 2026-04-29 6:10 UTC (permalink / raw)
To: Willy Tarreau
Cc: leon, security, Jonathan Corbet, skhan, workflows, linux-doc,
linux-kernel
In-Reply-To: <afF2d6RzRf2Flnv7@1wt.eu>
On Wed, Apr 29, 2026 at 05:09:43AM +0200, Willy Tarreau wrote:
> On Tue, Apr 28, 2026 at 03:13:01PM -0600, Greg KH wrote:
> > > > We can point at other files, as this list is going to get long over
> > > > time, which is a good thing.
> > >
> > > Sure. I'm just unsure where this could be enumerated, as it's likely
> > > that there would be just one or two lines max per subsystem for the
> > > majority of them. Or we could have a totally separate file, "threat
> > > model", that goes into great lengths detailing all this with sections
> > > per category or subsystem when they start to grow maybe, and refer only
> > > to that one from security-bugs ?
> >
> > I think a separate file is good, I know I need to write up what the USB
> > model is, and it's different from PCI, and different from other
> > subsystems. All should probably be documented eventually.
>
> Would you be interested in me trying to initiate a new "threat-model.rst"
> file that tries to unroll the points mentioned in the list ? I'm concerned
> that that withuot having many details initially, it could look a bit odd,
> because the list we currently have would be more suitable for an "other"
> section.
Sure, a small file to start with would be good for people to work off
of and add to.
> > > > > > (like what the IB subsystem does which I
> > > > > > don't think you listed above, or the USB subsystem.)
> > > > >
> > > > > Indeed I didn't list IB (I'm never sure about it, I seem to remember
> > > > > we simply trust any peer, is that right?), nor did I make specific
> > > > > mentions for USB which is implicitly covered by "hardware emulation
> > > > > or modification".
> > > >
> > > > Ah, but USB does cover "some" modification of devices, so this is going
> > > > to be something that is good to document over time, if for no other
> > > > reason to keep these scanning tools in check from hallucinating crazy
> > > > situations that are obviously not a valid thing we care about.
> > >
> > > OK but does this mean you still want to get these reports in the end ?
> >
> > I want a patch if a user cares about that threat-model (as Android does
> > but no one else) as it's up to the user groups that want to change the
> > default kernel's behavior like this to actually submit patches to do so.
>
> Yes, OK, but we want them in any case. That's the idea I tried to convey
> in the proposed doc (maybe not well enough), basically "this is a bug and
> it is worth reporting, but no need to involve s@k.o for this".
Yes, you conveyed that, sorry if I insinuated otherwise.
thanks,
greg k-h
^ permalink raw reply
* [PATCH 7/7] Docs/admin-guide/mm/damon/lru_sort: update for entire memory monitoring
From: SeongJae Park @ 2026-04-29 4:12 UTC (permalink / raw)
To: Andrew Morton
Cc: SeongJae Park, Liam R. Howlett, David Hildenbrand,
Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
Shuah Khan, Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
linux-kernel, linux-mm
In-Reply-To: <20260429041232.90257-1-sj@kernel.org>
Update DAMON_LRU_SORT usage document for the changed default monitoring
target region selection.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
Documentation/admin-guide/mm/damon/lru_sort.rst | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Documentation/admin-guide/mm/damon/lru_sort.rst b/Documentation/admin-guide/mm/damon/lru_sort.rst
index 25e2f042a383f..b93ca9b0853d2 100644
--- a/Documentation/admin-guide/mm/damon/lru_sort.rst
+++ b/Documentation/admin-guide/mm/damon/lru_sort.rst
@@ -246,7 +246,8 @@ monitor_region_start
Start of target memory region in physical address.
The start physical address of memory region that DAMON_LRU_SORT will do work
-against. By default, biggest System RAM is used as the region.
+against. By default, the system's entire physical memory is used as the
+region.
monitor_region_end
------------------
@@ -254,7 +255,8 @@ monitor_region_end
End of target memory region in physical address.
The end physical address of memory region that DAMON_LRU_SORT will do work
-against. By default, biggest System RAM is used as the region.
+against. By default, the system's entire physical memory is used as the
+region.
addr_unit
---------
--
2.47.3
^ permalink raw reply related
* [PATCH 6/7] Docs/admin-guide/mm/damon/reclaim: update for entire memory monitoring
From: SeongJae Park @ 2026-04-29 4:12 UTC (permalink / raw)
To: Andrew Morton
Cc: SeongJae Park, Liam R. Howlett, David Hildenbrand,
Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
Shuah Khan, Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
linux-kernel, linux-mm
In-Reply-To: <20260429041232.90257-1-sj@kernel.org>
Update DAMON_RECLAIM usage document for the changed default monitoring
target region selection.
Signed-off-by: SeongJae Park <sj@kernel.org>
---
Documentation/admin-guide/mm/damon/reclaim.rst | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Documentation/admin-guide/mm/damon/reclaim.rst b/Documentation/admin-guide/mm/damon/reclaim.rst
index 01a34c215b66f..57ab8b1876506 100644
--- a/Documentation/admin-guide/mm/damon/reclaim.rst
+++ b/Documentation/admin-guide/mm/damon/reclaim.rst
@@ -229,7 +229,8 @@ Start of target memory region in physical address.
The start physical address of memory region that DAMON_RECLAIM will do work
against. That is, DAMON_RECLAIM will find cold memory regions in this region
-and reclaims. By default, biggest System RAM is used as the region.
+and reclaims. By default, the system's entire physical memory is used as the
+region.
monitor_region_end
------------------
@@ -238,7 +239,8 @@ End of target memory region in physical address.
The end physical address of memory region that DAMON_RECLAIM will do work
against. That is, DAMON_RECLAIM will find cold memory regions in this region
-and reclaims. By default, biggest System RAM is used as the region.
+and reclaims. By default, the system's entire physical memory is used as the
+region.
addr_unit
---------
--
2.47.3
^ permalink raw reply related
* [PATCH 0/7] mm/damon/reclaim,lru_sort: monitor all system rams by default
From: SeongJae Park @ 2026-04-29 4:12 UTC (permalink / raw)
To: Andrew Morton
Cc: SeongJae Park, Liam R. Howlett, David Hildenbrand,
Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
Shuah Khan, Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
linux-kernel, linux-mm
DAMON_RECLAIM and DAMON_LRU_SORT set the biggest 'System RAM' resource
of the system as the default monitoring target address range. The main
intention behind the design is to minimize the overhead coming from
monitoring of non-System RAM areas.
This could result in an odd setup when there are multiple discrete
System RAMs of considerable sizes. For example, there are System RAMs
each having 500 GiB size. In this case, only the first 500 GiB will be
set as the monitoring region by default. This is particularly common on
NUMA systems. Hence the modules allow users to set the monitoring
target address range using the module parameters if the default setup
doesn't work for them. In other words, the current design trades ease
of setup for lower overhead.
However, because DAMON utilizes the sampling based access check and the
adaptive regions adjustment mechanisms, the overhead from the monitoring
of non-System RAM areas should be negligible in most setups. Meanwhile,
the setup complexity is causing real headaches for users who need to run
those modules on various types of systems. That is, the current
tradeoff is not a good deal.
Set the physical address range that can cover all System RAM areas of
the system as the default monitoring regions for DAMON_RECLAIM and
DAMON_LRU_SORT.
Technically speaking, this is changing documented behavior. However, it
makes no sense to believe there is a real use case that really depends
on the old weird default behavior. If the old default behavior was
working for them in the reasonable way, this change will only add a
negligible amount of monitoring overhead. If it didn't work, the users
may already be using manual monitoring regions setup, and they will not
be affected by this change.
Patches Sequence
================
Patch 1 introduces a new core function that will be used for the new
default monitoring target region setup. Patch 2 and 3 update
DAMON_RECLAIM and DAMON_LRU_SORT to use the new function instead of the
old one, respectively. Patch 4 removes the old core function that was
replaced by the new one, as there is no more user of it. Patch 5
updates DAMON_STAT to use the new one instead of its in-house
nearly-duplicate self implementation of the functionality. Finally
patches 6 and 7 update the DAMON_RECLAIM and DAMON_LRU_SORT user
documentation for the new behaviors, respectively.
Changes from RFC
- rfc: https://lore.kernel.org/20260415012048.76508-1-sj@kernel.org
- Fix typos: s/phiscal/physical/
SeongJae Park (7):
mm/damon: introduce damon_set_region_system_rams_default()
mm/damon/reclaim: cover all system rams
mm/damon/lru_sort: cover all system rams
mm/damon/core: remove damon_set_region_biggest_system_ram_default()
mm/damon/stat: use damon_set_region_system_rams_default()
Docs/admin-guide/mm/damon/reclaim: update for entire memory monitoring
Docs/admin-guide/mm/damon/lru_sort: update for entire memory
monitoring
.../admin-guide/mm/damon/lru_sort.rst | 6 ++-
.../admin-guide/mm/damon/reclaim.rst | 6 ++-
include/linux/damon.h | 2 +-
mm/damon/core.c | 49 +++++++++--------
mm/damon/lru_sort.c | 8 +--
mm/damon/reclaim.c | 14 ++---
mm/damon/stat.c | 53 ++-----------------
7 files changed, 50 insertions(+), 88 deletions(-)
base-commit: 01b1d4a72970ced030ffe246ba99c961c746527d
--
2.47.3
^ permalink raw reply
* Re: [PATCH v2 1/4] clk: move core flags into a new enum for kernel docs
From: Stephen Boyd @ 2026-04-29 2:22 UTC (permalink / raw)
To: Brian Masney, Jonathan Corbet, Maxime Ripard, Michael Turquette,
Shuah Khan
Cc: linux-clk, linux-kernel, linux-doc
In-Reply-To: <acaGfUueAm7lb_2x@redhat.com>
Quoting Brian Masney (2026-03-27 06:30:37)
> > +enum clk_core_flags {
> > + CLK_SET_RATE_GATE = BIT(0),
> > + CLK_SET_PARENT_GATE = BIT(1),
> > + CLK_SET_RATE_PARENT = BIT(2),
> > + CLK_IGNORE_UNUSED = BIT(3),
> > + /* unused */
> > + /* unused */
> > + CLK_GET_RATE_NOCACHE = BIT(6),
> > + CLK_SET_RATE_NO_REPARENT = BIT(7),
> > + CLK_GET_ACCURACY_NOCACHE = BIT(8),
> > + CLK_RECALC_NEW_RATES = BIT(9),
> > + CLK_SET_RATE_UNGATE = BIT(10),
> > + CLK_IS_CRITICAL = BIT(11),
> > + CLK_OPS_PARENT_ENABLE = BIT(12),
> > + CLK_DUTY_CYCLE_PARENT = BIT(13),
> > +};
>
> I just checked Sashiko [1] for this series and it has this comment:
>
> Could converting these unsigned long bitmasks to an enum create a silent
> type-safety trap if flags ever reach BIT(31)?
>
> The flags fields in the clock framework are explicitly designed to be 64-bit
> on 64-bit architectures (unsigned long). The BIT() macro evaluates to an
> unsigned long. When defined as macros, operations like clearing flags
> produce a 64-bit inverted mask, perfectly preserving the upper 32 bits.
>
> By moving these flags into an enum, their types are implicitly downgraded to
> int, since the current maximum flag BIT(13) fits in a 32-bit signed integer.
> If the flags ever grow to include BIT(31), the enumerator value will overflow
> a signed 32-bit int, causing the compiler to type it as an unsigned int.
>
> Applying a bitwise NOT to this unsigned int will produce an unsigned int.
> When this is bitwise ANDed with the 64-bit unsigned long flags variable,
> the unsigned mask will zero-extend to 64 bits, silently clearing all upper
> 32 bits (bits 32-63) of the flags field.
>
> Would it be safer to keep them as #define macros and use a DOC: block
> to properly document the flags using kernel-doc without breaking type safety?
>
Don't break type safety. I hope we don't get to the point that we have
more than 32 flags, but you never know. Why do we need an enum? Just to
make it easier to grab in docs? Presumably a doc block would work just
as well and not put down a land mine to be discovered later.
^ permalink raw reply
* Re: [PATCH v2] mm/page_alloc: trace PCP refills and PCP zone lock usage
From: SUVONOV BUNYOD @ 2026-04-29 3:31 UTC (permalink / raw)
To: Steven Rostedt
Cc: akpm, vbabka, linux-mm, mhiramat, mathieu desnoyers,
linux-trace-kernel, linux-kernel, surenb, mhocko, jackmanb,
hannes, ziy, david, vishal moola, corbet, skhan, linux-doc
In-Reply-To: <20260428142335.3bca0166@gandalf.local.home>
Thanks for reviewing Steven,
>Why this change? It makes it much harder to understand.
>
>The above is not a normal macro. Ignore any checkpatch warnings about it.
>The proper way to do the TP_STRUCT__entry() is to make it just like a struct:
>
>struct {
> unsigned long pfn;
> unsigned int order;
> int migratetype;
>};
>
>Thus, the macro should be:
>
> TP_STRUCT__entry(
> __field( unsigned long, pfn )
> __field( unsigned int, order )
> __field( int, migratetype )
> ),
Yeah sorry for the formatting issue, will fix in v3. Any other concerns?
What do you think about the introduction of those tracepoints themselves?
-- Bunyod
^ permalink raw reply
* Re: [PATCH 2/3] Documentation: security-bugs: explain what is and is not a security bug
From: Willy Tarreau @ 2026-04-29 3:09 UTC (permalink / raw)
To: Greg KH
Cc: leon, security, Jonathan Corbet, skhan, workflows, linux-doc,
linux-kernel
In-Reply-To: <2026042804-overbook-ripeness-73dd@gregkh>
On Tue, Apr 28, 2026 at 03:13:01PM -0600, Greg KH wrote:
> > > We can point at other files, as this list is going to get long over
> > > time, which is a good thing.
> >
> > Sure. I'm just unsure where this could be enumerated, as it's likely
> > that there would be just one or two lines max per subsystem for the
> > majority of them. Or we could have a totally separate file, "threat
> > model", that goes into great lengths detailing all this with sections
> > per category or subsystem when they start to grow maybe, and refer only
> > to that one from security-bugs ?
>
> I think a separate file is good, I know I need to write up what the USB
> model is, and it's different from PCI, and different from other
> subsystems. All should probably be documented eventually.
Would you be interested in me trying to initiate a new "threat-model.rst"
file that tries to unroll the points mentioned in the list ? I'm concerned
that that withuot having many details initially, it could look a bit odd,
because the list we currently have would be more suitable for an "other"
section.
> > > > > (like what the IB subsystem does which I
> > > > > don't think you listed above, or the USB subsystem.)
> > > >
> > > > Indeed I didn't list IB (I'm never sure about it, I seem to remember
> > > > we simply trust any peer, is that right?), nor did I make specific
> > > > mentions for USB which is implicitly covered by "hardware emulation
> > > > or modification".
> > >
> > > Ah, but USB does cover "some" modification of devices, so this is going
> > > to be something that is good to document over time, if for no other
> > > reason to keep these scanning tools in check from hallucinating crazy
> > > situations that are obviously not a valid thing we care about.
> >
> > OK but does this mean you still want to get these reports in the end ?
>
> I want a patch if a user cares about that threat-model (as Android does
> but no one else) as it's up to the user groups that want to change the
> default kernel's behavior like this to actually submit patches to do so.
Yes, OK, but we want them in any case. That's the idea I tried to convey
in the proposed doc (maybe not well enough), basically "this is a bug and
it is worth reporting, but no need to involve s@k.o for this".
thanks,
Willy
^ permalink raw reply
* [PATCH 01/14] kbuild: Bump minimum version of LLVM for building the kernel to 17.0.1
From: Nathan Chancellor @ 2026-04-29 2:59 UTC (permalink / raw)
To: Nathan Chancellor, Nicolas Schier, Bill Wendling, Justin Stitt,
Nick Desaulniers
Cc: linux-kernel, llvm, linux-kbuild, Jonathan Corbet, Shuah Khan,
linux-doc
In-Reply-To: <20260428-bump-minimum-supported-llvm-version-to-17-v1-0-81d9b2e8ee75@kernel.org>
The current minimum version of LLVM for building the kernel is 15.0.0.
However, there are two deficiencies compared to GCC that were fixed in
LLVM 17 that are starting to become more noticeable.
The first was a bug in LLVM's scope checker [1], where all labels in a
function were validated as potential targets of an asm goto statement,
even if they were not listed in the asm goto statement as targets. This
becomes particularly problematic when the cleanup attribute is used, as
asm goto(... : label_a);
...
label_a:
...
int var __free(foo);
asm goto(... : label_b);
...
label_b:
...
will trigger an error since the scope checker will complain that the
cleanup variable would be skipped when jumping from the first asm goto
to label_b (which obviously cannot happen). This issue was the catalyst
for commit e2ffa15b9baa ("kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on
clang < 17"). Unfortunately, this issue is reproducible with regular asm
goto in addition to asm goto with outputs, so that change was not
entirely sufficient to avoid the issue altogether. As asm goto has
effectively been required since commit a0a12c3ed057 ("asm goto:
eradicate CC_HAS_ASM_GOTO") and the usage of the cleanup attribute
continues to grow across the tree, raising the minimum to a version that
avoids this issue altogether is a better long term solution than
attempting to workaround it at every spot where it happens.
The second issue is an incompatibility with GCC 8.1+ around variables
marked with const being valid constant expressions for _Static_assert
and other macros [2]. With GCC 8.1 being the minimum supported version
since commit 118c40b7b503 ("kbuild: require gcc-8 and binutils-2.30"),
this incompatibility becomes more of a maintenance burden since only
clang-15 and clang-16 are affected by it.
Looking at the clang version of various major distributions through
Docker images, no one should be left behind as a result of this bump, as
the old ones cannot clear the current minimum of 15.0.0.
archlinux:latest clang version 22.1.3
debian:oldoldstable-slim Debian clang version 11.0.1-2
debian:oldstable-slim Debian clang version 14.0.6
debian:stable-slim Debian clang version 19.1.7 (3+b1)
debian:testing-slim Debian clang version 21.1.8 (3+b1)
debian:unstable-slim Debian clang version 21.1.8 (7+b1)
fedora:42 clang version 20.1.8 (Fedora 20.1.8-4.fc42)
fedora:latest clang version 21.1.8 (Fedora 21.1.8-4.fc43)
fedora:44 clang version 22.1.1 (Fedora 22.1.1-2.fc44)
fedora:rawhide clang version 22.1.3 (Fedora 22.1.3-1.fc45)
opensuse/leap:latest clang version 17.0.6
opensuse/tumbleweed:latest clang version 21.1.8
ubuntu:jammy Ubuntu clang version 14.0.0-1ubuntu1.1
ubuntu:noble Ubuntu clang version 18.1.3 (1ubuntu1)
ubuntu:questing Ubuntu clang version 20.1.8 (0ubuntu4)
ubuntu:resolute Ubuntu clang version 21.1.8 (6ubuntu1)
17.0.1 is chosen as the minimum instead of 17.0.0 to ensure that the
particular version of LLVM 17 has the two aforementioned bugs fixed, as
the second was fixed during the 17.0.0 release candidate phase and it
was not until LLVM 18 that LLVM adopted the scheme of x.0.0 being a
prerelease version and x.1.0 is a release version [3] to help with
scenarios such as this.
Link: https://github.com/llvm/llvm-project/commit/f023f5cdb2e6c19026f04a15b5a935c041835d14 [1]
Link: https://github.com/llvm/llvm-project/commit/0b2d5b967d98375793897295d651f58f6fbd3034 [2]
Link: https://github.com/llvm/llvm-project/commit/4532617ae420056bf32f6403dde07fb99d276a49 [3]
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
---
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Cc: linux-doc@vger.kernel.org
---
Documentation/process/changes.rst | 2 +-
scripts/min-tool-version.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
index 9a99037270ff..b9afce768446 100644
--- a/Documentation/process/changes.rst
+++ b/Documentation/process/changes.rst
@@ -36,7 +36,7 @@ bindgen (optional) 0.71.1 bindgen --version
binutils 2.30 ld -v
bison 2.0 bison --version
btrfs-progs 0.18 btrfs --version
-Clang/LLVM (optional) 15.0.0 clang --version
+Clang/LLVM (optional) 17.0.1 clang --version
e2fsprogs 1.41.4 e2fsck -V
flex 2.5.35 flex --version
gdb 7.2 gdb --version
diff --git a/scripts/min-tool-version.sh b/scripts/min-tool-version.sh
index b96ec2d379b6..ea2689bc9641 100755
--- a/scripts/min-tool-version.sh
+++ b/scripts/min-tool-version.sh
@@ -27,7 +27,7 @@ llvm)
if [ "$SRCARCH" = loongarch ]; then
echo 18.0.0
else
- echo 15.0.0
+ echo 17.0.1
fi
;;
rustc)
--
2.54.0
^ permalink raw reply related
* [PATCH 00/14] Bump minimum version of LLVM for building the kernel to 17.0.1
From: Nathan Chancellor @ 2026-04-29 2:59 UTC (permalink / raw)
To: Nathan Chancellor, Nicolas Schier, Bill Wendling, Justin Stitt,
Nick Desaulniers
Cc: linux-kernel, llvm, linux-kbuild, Jonathan Corbet, Shuah Khan,
linux-doc, Kees Cook, Gustavo A. R. Silva, linux-hardening,
linux-security-module, Rong Xu, Han Shen, Russell King,
Arnd Bergmann, linux-arm-kernel, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, linux-riscv, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Peter Zijlstra, Ard Biesheuvel
The current minimum version of LLVM for building the kernel is 15.0.0.
However, there are two deficiencies compared to GCC that were fixed in
LLVM 17 that are starting to become more noticeable.
The first was a bug in LLVM's scope checker [1], where all labels in a
function were validated as potential targets of an asm goto statement,
even if they were not listed in the asm goto statement as targets. This
becomes particularly problematic when the cleanup attribute is used, as
asm goto(... : label_a);
...
label_a:
...
int var __free(foo);
asm goto(... : label_b);
...
label_b:
...
will trigger an error since the scope checker will complain that the
cleanup variable would be skipped when jumping from the first asm goto
to label_b (which obviously cannot happen). This issue was the catalyst
for commit e2ffa15b9baa ("kbuild: Disable CC_HAS_ASM_GOTO_OUTPUT on
clang < 17"). Unfortunately, this issue is reproducible with regular asm
goto in addition to asm goto with outputs, so that change was not
entirely sufficient to avoid the issue altogether. As asm goto has
effectively been required since commit a0a12c3ed057 ("asm goto:
eradicate CC_HAS_ASM_GOTO") and the usage of the cleanup attribute
continues to grow across the tree, raising the minimum to a version that
avoids this issue altogether is a better long term solution than
attempting to workaround it at every spot where it happens.
The second issue is an incompatibility with GCC 8.1+ around variables
marked with const being valid constant expressions for _Static_assert
and other macros [2]. With GCC 8.1 being the minimum supported version
since commit 118c40b7b503 ("kbuild: require gcc-8 and binutils-2.30"),
this incompatibility becomes more of a maintenance burden since only
clang-15 and clang-16 are affected by it.
Looking at the clang version of various major distributions through
Docker images, no one should be left behind as a result of this bump, as
the old ones cannot clear the current minimum of 15.0.0.
archlinux:latest clang version 22.1.3
debian:oldoldstable-slim Debian clang version 11.0.1-2
debian:oldstable-slim Debian clang version 14.0.6
debian:stable-slim Debian clang version 19.1.7 (3+b1)
debian:testing-slim Debian clang version 21.1.8 (3+b1)
debian:unstable-slim Debian clang version 21.1.8 (7+b1)
fedora:42 clang version 20.1.8 (Fedora 20.1.8-4.fc42)
fedora:latest clang version 21.1.8 (Fedora 21.1.8-4.fc43)
fedora:44 clang version 22.1.1 (Fedora 22.1.1-2.fc44)
fedora:rawhide clang version 22.1.3 (Fedora 22.1.3-1.fc45)
opensuse/leap:latest clang version 17.0.6
opensuse/tumbleweed:latest clang version 21.1.8
ubuntu:jammy Ubuntu clang version 14.0.0-1ubuntu1.1
ubuntu:noble Ubuntu clang version 18.1.3 (1ubuntu1)
ubuntu:questing Ubuntu clang version 20.1.8 (0ubuntu4)
ubuntu:resolute Ubuntu clang version 21.1.8 (6ubuntu1)
17.0.1 is chosen as the minimum instead of 17.0.0 to ensure that the
particular version of LLVM 17 has the two aforementioned bugs fixed, as
the second was fixed during the 17.0.0 release candidate phase and it
was not until LLVM 18 that LLVM adopted the scheme of x.0.0 being a
prerelease version and x.1.0 is a release version [3] to help with
scenarios such as this.
The first patch in the series does the actual bump. The remaining
patches are cleanups of workarounds for various issues that are no
longer needed with the bump.
I plan to take this via the Kbuild tree for 7.2, please provide Acks as
necessary.
[1]: https://github.com/llvm/llvm-project/commit/f023f5cdb2e6c19026f04a15b5a935c041835d14
[2]: https://github.com/llvm/llvm-project/commit/0b2d5b967d98375793897295d651f58f6fbd3034
[3]: https://github.com/llvm/llvm-project/commit/4532617ae420056bf32f6403dde07fb99d276a49
---
Nathan Chancellor (14):
kbuild: Bump minimum version of LLVM for building the kernel to 17.0.1
security/Kconfig.hardening: Remove tautological condition from CC_HAS_ZERO_CALL_USED_REGS
security/Kconfig.hardening: Remove tautological condition from FORTIFY_SOURCE
security/Kconfig.hardening: Remove tautological condition from CC_HAS_RANDSTRUCT
arch/Kconfig: Remove tautological conditions from HAS_LTO_CLANG
arch/Kconfig: Remove tautological condition from AUTOFDO_CLANG
ARM: Drop tautological ld.lld conditions from ARCH_MULTI_V4{,T}
riscv: Remove tautological condition from selection of ARCH_SUPPORTS_CFI
riscv: Drop tautological condition from TOOLCHAIN_NEEDS_OLD_ISA_SPEC
scripts/Makefile.warn: Drop -Wformat handling for clang < 16
x86/build: Drop unused '-ffreestanding' addition to KBUILD_CFLAGS
x86/module: Revert "Deal with GOT based stack cookie load on Clang < 17"
x86/entry/vdso32: Remove conditional omission of '.cfi_offset eflags'
kbuild: Remove check for broken scoping with clang < 17 in CC_HAS_ASM_GOTO_OUTPUT
Documentation/process/changes.rst | 2 +-
arch/Kconfig | 5 +----
arch/arm/Kconfig.platforms | 4 ----
arch/riscv/Kconfig | 16 +++++++---------
arch/x86/Makefile | 5 -----
arch/x86/entry/vdso/vdso32/sigreturn.S | 10 ----------
arch/x86/include/asm/elf.h | 5 ++---
arch/x86/kernel/module.c | 15 ---------------
init/Kconfig | 3 ---
scripts/Makefile.warn | 10 ----------
scripts/min-tool-version.sh | 2 +-
security/Kconfig.hardening | 8 --------
12 files changed, 12 insertions(+), 73 deletions(-)
---
base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
change-id: 20260422-bump-minimum-supported-llvm-version-to-17-b4638a58b043
Best regards,
--
Nathan Chancellor <nathan@kernel.org>
^ permalink raw reply
* Re: [RFC PATCH 2/2] Documentation: dev-tools: add kconfirm
From: Miguel Ojeda @ 2026-04-29 0:38 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Arnd Bergmann, Julian Braha, Andrew Morton, ljs,
Greg Kroah-Hartman, Masahiro Yamada, Nicolas Schier, Miguel Ojeda,
Jonathan Corbet, linux-kernel, rust-for-linux, linux-doc,
linux-kbuild
In-Reply-To: <20260428184511.GB3304253@ax162>
On Tue, Apr 28, 2026 at 8:45 PM Nathan Chancellor <nathan@kernel.org> wrote:
>
> I agree with the sentiment that more host tools may want to be written
> in Rust. The Rust build in the kernel does not use cargo altogether, do
> we want the same restriction for host programs? Would these tools be
> able to share the Rust build rules so that we could have a simple
> hostprogs syntax for tools integrating with Kbuild to use? Obviously, it
> might be harder for some programs not to use some of the nice third
> party libraries available but it seems like it would eliminate the build
> system considerations from the discussion at that point.
Yeah, we have already 3 hostprogs in the tree, which just call the
compiler, but it would be nice to have a way to use ecosystem crates
for those and userprogs etc., even if just a particular vetted set.
Otherwise, it is quite painful sometimes to use Rust, and one may
prefer something like Python instead (like we did for
`scripts/generate_rust_analyzer.py`). Python works great for many
tasks thanks to its standard library, but we lose the advantages of
something like Rust. On the other hand, Rust without a few crates to
support certain common things isn't great.
I wouldn't say it is a rush, but it would be nice to agree on an
initial vetted set and try to set something up so that eventually it
is easy to write scripts/tools/hostprogs in Rust going forward.
We could also consider an earlier MSRV for those, i.e. lower than the
kernel image one, if that would allow us to use it in more places,
like for hostprogs without assuming `CONFIG_RUST=y`. Say, Debian
Oldstable instead of Stable.
Cheers,
Miguel
^ permalink raw reply
* Re: [PATCH v5 00/21] Virtual Swap Space
From: Yosry Ahmed @ 2026-04-28 23:53 UTC (permalink / raw)
To: Kairui Song
Cc: Nhat Pham, Liam R . Howlett, akpm, Alistair Popple,
Axel Rasmussen, Barry Song, Baolin Wang, Baoquan He,
Byungchul Park,
open list:CONTROL GROUP - MEMORY RESOURCE CONTROLLER (MEMCG),
Chengming Zhou, Chris Li, Jonathan Corbet, David Hildenbrand,
Dev Jain, Gregory Price, Johannes Weiner, Hugh Dickins, Jann Horn,
Joshua Hahn, Lance Yang, lenb, linux-doc, LKML, linux-mm,
open list:SUSPEND TO RAM, Lorenzo Stoakes, Matthew Brost,
Michal Hocko, Muchun Song, Mariano Pache, Pavel Machek, Peter Xu,
Peter Zijlstra, Pedro Falcato, Rafael J. Wysocki (Intel),
Rakie Kim, Roman Gushchin, Mike Rapoport, Ryan Roberts,
Shakeel Butt, Kemeng Shi, Suren Baghdasaryan, tglx,
Vlastimil Babka, Wei Xu, Huang, Ying, Yosry Ahmed, Yuanchu Xie,
Qi Zheng, Zi Yan, Meta kernel team, Rik van Riel
In-Reply-To: <CAMgjq7BZpU5K1xHyFiqpsjeFe6CZUouGY_gOGMwbkM2Duq-vGg@mail.gmail.com>
On Tue, Apr 28, 2026 at 11:46 AM Kairui Song <ryncsn@gmail.com> wrote:
>
> On Tue, Apr 28, 2026 at 2:23 AM Yosry Ahmed <yosry@kernel.org> wrote:
> >
> > On Fri, Apr 24, 2026 at 12:52 PM Kairui Song <ryncsn@gmail.com> wrote:
> > >
> > > On Sat, Apr 25, 2026 at 3:12 AM Yosry Ahmed <yosry@kernel.org> wrote
> > > > Why >16 bytes? Do we need anything extra other than the reverse
> > > > mapping? Also why do we need a double lookup?
> > >
> > > You will have to store at least the following info: memcg (2 bytes),
> > > shadow (8 bytes), count (at least 1 bytes), and revert mapping (8
> > > bytes, since you have to address a full virtual swap space). And some
> > > type info is also needed. Part of them can be shrinked but still,
> > > scientifically, merging two layers into one is considered a kind of
> > > optimization.
> > >
> > > You need lookup the virtual layer, then the lower layer for many
> > > decision making, is was discussed before to introduce more cache bit
> > > or things like that and I think that is getting over complex, reminds
> > > me of the slot cache or HAS_CACHE thing...:
> > > https://lore.kernel.org/linux-mm/CAMgjq7DJrtE-jARik849kCufd0qNnZQs7C8fcyzVOKE14-O+Dw@mail.gmail.com/
> >
> > I think that's where the disconnect is. You are considering these two
> > separate layers, each with its own metadata. The metadata should only
> > live in one place.
> >
> > If we only have swap tables in the virtual swap layer (with the
> > metadata), backends do not have to carry the metadata. In this case,
> > backends should only have a reverse mapping (if needed), and some
> > internal data structure (e.g. bitmaps) to track usage.
>
> Ah, you are right. This is currently an intermediate state, that
> problem might be gone if we unified everything.
>
> > This is difficult to achieve if the virtual swap layer is optional,
> > because then the metadata can live in different places. This is why I
>
> But that's not difficult to achieve at all with an optional layer, and
> actually will be achieved naturally without any design change with the
> RFC I posted. Swap count / cgroup / shadow all stay in the top layer,
> lower layer is "reverse map" only (the undone part though, it will
> require to move the cluster cache from global to device level, which
> is also required for YoungJun's tier or any functional tiering to
> work, we may run into more and more detail issue like this).
But then you have to deal with the swap entries in the page tables
potentially being virtual swap entries or physical swap slots, and
IIUC in your design, those physica swap slots could end up actually
having a redirection to another swap entry like virtual ones (e.g. if
we start with one tier then add another tier at runtime). Right?
>
> Might even be easier that way, it's pretty close to the unified states I think.
>
^ permalink raw reply
* Re: [PATCH v4 01/11] PCI: liveupdate: Set up FLB handler for the PCI core
From: David Matlack @ 2026-04-28 23:51 UTC (permalink / raw)
To: Vipin Sharma
Cc: iommu, kexec, linux-doc, linux-kernel, linux-mm, linux-pci,
Adithya Jayachandran, Alexander Graf, Alex Williamson,
Bjorn Helgaas, Chris Li, David Rientjes, Jacob Pan,
Jason Gunthorpe, Joerg Roedel, Jonathan Corbet, Josh Hilke,
Leon Romanovsky, Lukas Wunner, Mike Rapoport, Parav Pandit,
Pasha Tatashin, Pranjal Shrivastava, Pratyush Yadav, Robin Murphy,
Saeed Mahameed, Samiullah Khawaja, Shuah Khan, Will Deacon,
William Tu, Yi Liu
In-Reply-To: <20260428185242.GB3825533.vipinsh@google.com>
On 2026-04-28 12:45 PM, Vipin Sharma wrote:
> On Thu, Apr 23, 2026 at 09:23:05PM +0000, David Matlack wrote:
> > + pr_debug("Preserving struct pci_ser with room for %u devices\n",
> > + max_nr_devices);
> > +
> > + ser = kho_alloc_preserve(size);
> > + if (IS_ERR(ser))
> > + return PTR_ERR(ser);
>
> Should there be a similar pr_debug() in case of failure to denote that above
> "Preserving ..." message didn't finish, or, maybe just print one
> pr_debug() after the error check above?
Hm... I guess there could always be more pr_debug()s but I don't want to
instrument every error path. I could move it to the success path but I
don't see how that makes it any better.
>
> > +/**
> > + * struct pci_dev_ser - Serialized state about a single PCI device.
> > + *
> > + * @domain: The device's PCI domain number (segment).
> > + * @bdf: The device's PCI bus, device, and function number.
> > + * @reserved: Reserved (to naturally align struct pci_dev_ser).
> > + */
> > +struct pci_dev_ser {
> > + u32 domain;
> > + u16 bdf;
> > + u16 reserved;
>
> Should this be renamed to 'u8 __padding[2];' instead? This will allow to
> just change the array length based on the need (0, 1, 2, 3).
Sorry I'm not following what you mean here. What is the reason to rename
this field and change it to an array?
> > +} __packed;
> > +
> > +/**
> > + * struct pci_ser - PCI Subsystem Live Update State
> > + *
> > + * This struct tracks state about all devices that are being preserved across
> > + * a Live Update for the next kernel.
> > + *
> > + * @max_nr_devices: The length of the devices[] flexible array.
> > + * @nr_devices: The number of devices that were preserved.
> > + * @devices: Flexible array of pci_dev_ser structs for each device.
> > + */
> > +struct pci_ser {
> > + u32 max_nr_devices;
> > + u32 nr_devices;
> > + struct pci_dev_ser devices[];
> > +} __packed;
> > +
> > +/* Ensure all elements of devices[] are naturally aligned. */
> > +static_assert(offsetof(struct pci_ser, devices) % sizeof(unsigned long) == 0);
> > +static_assert(sizeof(struct pci_dev_ser) % sizeof(unsigned long) == 0);
>
> Nit: Maybe move this assert to be near to the definition of this struct,
> easier to find it when editing the struct vs finding it later during
> build.
The combination of these 2 asserts is what guarantees that every element
of the devices[] array are naturally aligned, that's why I put them
together here.
I can move it up though if you think it's better.
^ permalink raw reply
* Re: [PATCH v4 01/11] PCI: liveupdate: Set up FLB handler for the PCI core
From: David Matlack @ 2026-04-28 23:47 UTC (permalink / raw)
To: Pasha Tatashin
Cc: Pratyush Yadav, iommu, kexec, linux-doc, linux-kernel, linux-mm,
linux-pci, Adithya Jayachandran, Alexander Graf, Alex Williamson,
Bjorn Helgaas, Chris Li, David Rientjes, Jacob Pan,
Jason Gunthorpe, Joerg Roedel, Jonathan Corbet, Josh Hilke,
Leon Romanovsky, Lukas Wunner, Mike Rapoport, Parav Pandit,
Pranjal Shrivastava, Robin Murphy, Saeed Mahameed,
Samiullah Khawaja, Shuah Khan, Will Deacon, William Tu, Yi Liu
In-Reply-To: <afDroRNDr9ttY4O9@plex>
On 2026-04-28 05:50 PM, Pasha Tatashin wrote:
> On 04-27 23:59, David Matlack wrote:
> > On 2026-04-24 01:29 PM, Pasha Tatashin wrote:
> > > On 04-24 14:33, Pratyush Yadav wrote:
> > > > Hi David,
> > > >
> > > > On Thu, Apr 23 2026, David Matlack wrote:
> > > > [...]
> > > > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > > > index c9b7b6f9828e..94af31837375 100644
> > > > > --- a/MAINTAINERS
> > > > > +++ b/MAINTAINERS
> > > > > @@ -20555,6 +20555,18 @@ L: linux-pci@vger.kernel.org
> > > > > S: Supported
> > > > > F: Documentation/PCI/pci-error-recovery.rst
> > > > >
> > > > > +PCI LIVE UPDATE
> > > > > +M: Bjorn Helgaas <bhelgaas@google.com>
> > > > > +M: David Matlack <dmatlack@google.com>
> > > > > +L: linux-pci@vger.kernel.org
> > > > > +S: Supported
> > > > > +Q: https://patchwork.kernel.org/project/linux-pci/list/
> > > > > +B: https://bugzilla.kernel.org
> > > > > +C: irc://irc.oftc.net/linux-pci
> > > > > +T: git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git
> > > > > +F: drivers/pci/liveupdate.c
> > > > > +F: include/linux/kho/abi/pci.h
> > > > > +
> > > >
> > > > Can we please also add these files under the "LIVE UPDATE" entry. The
> > > > code here concerns both live update and PCI.
> >
> > Covering that intersection of Live Update and PCI was exactly my
> > intention with introducing this new PCI LIVE UPDATE entry. This ensures
> > we have maintenance coverage with knowledge of that intersection.
> >
> > > > We can figure out the
> > > > maintenance details as we go along, but I think the live update
> > > > maintainers should at least get all the patches for PCI live update.
> >
> > Would adding kexec@ here be sufficient or do you want to be CC'd
> > directly?
> >
> > If you want to be CC'd directly do you think makes more sense to add the
> > Live Update maintainers as Reviewers under PCI LIVE UPDATE, or add
> > drivers/pci/liveupdate.c under LIVE UPDATE?
> >
> > > >
> > > > Perhaps also add the kexec list here? We plan to use it to maintain the
> > > > LUO patches, and adding it will make sure we get the patches in case
> > > > someone updates the file list here but forgets to update it in the LIVE
> > > > UPDATE entry.
> > >
> > > +1
> > >
> > > These files should also be added to the Live Update entry, and the kexec
> > > mailing list should be included.
> > >
> > > Changes specific to Live Update should be routed through the
> > > liveupdate/linux.git tree, while generic PCI changes should go through
> > > pci/pci.git. In either case, if liveupdate.c or abi/pci.h are modified,
> > > acks are required from the Live Update group.
> >
> > Do you want to merge changes to drivers/pci/liveupdate.c through the
> > live update tree or PCI tree? We should probably decide now. I was
> > assuming the PCI tree since its part of PCI core.
> >
> > As we project this out there are going to be users of the Live Update
> > API across different parts of the kernel: PCI core, IOMMU core, IOMMU
> > drivers, VFIO core, VFIO PCI drivers, and KVM. I don't think it will
> > scale to take all that code through the live update tree.
>
> All Live-Update-specific changes should go through the liveupdate tree.
> The liveupdate tree is the only Linux tree that will cover full Live
> Update regression testing, and it contains reviewers and maintainers who
> know the details of the Live Update process, its lifecycle, and its
> requirements.
>
> The request we are hearing from other subsystem maintainers is that they
> want to make sure Live Update is isolated enough not to make their lives
> harder. This means reducing the number of conflicts, the maintenance
> burden, and testing responsibilities.
>
> Therefore, the "PCI LIVE UPDATE" entry should specify you as a
> maintainer, "kexec@lists.infradead.org" as the list to which all LU
> changes should be CC'd, and "liveupdate/linux.git" as the git tree
> against which changes should be applied.
>
> It should also include "linux-pci@vger.kernel.org" so the PCI
> maintainers are CC'd. In case there are larger changes that touch core
> PCI and liveupdate.c/abi, we can ACK them, ensuring we are aware of
> incoming conflicts during the current or next merge cycle.
>
> It should also specify the members of LU group so we can stage the
> changes.
Sorry what does this mean specifically?
> This is the way we agreed to handle kexec changes: Baoquan He is the
> maintainer, and without his Reviewed-by tag, we won't take changes to
> kexec. This is the approach we follow with MM for KHO changes to
> memblock and memfd preservation, as well as the upcoming
> hugetlb/guestmemfd preservation.
>
> This is also the approach we should continue using when adding LUO
> support to other components like PCI, VFIO, IOMMU, and KVM. It keeps
> life easier for the core component maintainers and ensures we do not
> regress LU by staging everything in the same tree and sending LU merge
> requests from a single tree.
Ok it sounds like we are aligned on keeping drivers/pci/liveupdate.c,
include/linux/kho/abi/pci.h, and Documentation/PCI/liveupdate.rst in the
PCI LIVE UPDATE entry and not duplicating them in the LIVE UPDATE entry.
I think the only open question is what tree to use for the PCI LIVE
UPDATE entry, PCI tree or Live Update tree. You are proposing the Live
Update tree.
Bjorn are you ok with that approach?
^ permalink raw reply
* Re: [PATCH RFC v5 24/53] KVM: SEV: Make 'uaddr' parameter optional for KVM_SEV_SNP_LAUNCH_UPDATE
From: Ackerley Tng @ 2026-04-28 23:40 UTC (permalink / raw)
To: Ackerley Tng via B4 Relay, aik, andrew.jones, binbin.wu, brauner,
chao.p.peng, david, ira.weiny, jmattson, jthoughton, michael.roth,
oupton, pankaj.gupta, qperret, rick.p.edgecombe, rientjes,
shivankg, steven.price, tabba, willy, wyihan, yan.y.zhao,
forkloop, pratyush, suzuki.poulose, aneesh.kumar, Paolo Bonzini,
Sean Christopherson, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Steven Rostedt,
Masami Hiramatsu, Mathieu Desnoyers, Jonathan Corbet, Shuah Khan,
Shuah Khan, Vishal Annapurve, Andrew Morton, Chris Li,
Kairui Song, Kemeng Shi, Nhat Pham, Baoquan He, Barry Song,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Youngjun Park, Qi Zheng,
Shakeel Butt, Kiryl Shutsemau, Jason Gunthorpe, Vlastimil Babka
Cc: kvm, linux-kernel, linux-trace-kernel, linux-doc, linux-kselftest,
linux-mm, linux-coco
In-Reply-To: <20260428-gmem-inplace-conversion-v5-24-d8608ccfca22@google.com>
Ackerley Tng via B4 Relay <devnull+ackerleytng.google.com@kernel.org>
writes:
> From: Michael Roth <michael.roth@amd.com>
>
Thanks Michael!
>
> [...snip...]
>
>
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index c2126b3c30724..bf10d24907a00 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -2343,7 +2343,15 @@ static int sev_gmem_post_populate(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn,
> int level;
> int ret;
>
> - if (WARN_ON_ONCE(sev_populate_args->type != KVM_SEV_SNP_PAGE_TYPE_ZERO && !src_page))
> + /*
> + * For vm_memory_attributes=1, in-place conversion/population is not
> + * supported, so the initial contents necessarily need to come from a
> + * separate src address. For vm_memory_attributes=0, this isn't
> + * necessarily the case, since the pages may have been populated
> + * directly from userspace before calling KVM_SEV_SNP_LAUNCH_UPDATE.
> + */
I dropped the #ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES from [1] since
vm_memory_attributes is #define-d as false when if
CONFIG_KVM_VM_MEMORY_ATTRIBUTES is not defined.
> + if (vm_memory_attributes &&
> + sev_populate_args->type != KVM_SEV_SNP_PAGE_TYPE_ZERO && !src_page)
> return -EINVAL;
>
> ret = snp_lookup_rmpentry((u64)pfn, &assigned, &level);
[1] https://github.com/AMDESE/linux/commit/7e7c29afdf3763822ced0b7007fc0f93b8fb993d
>
> [...snip...]
>
^ permalink raw reply
* [POC PATCH 6/6] KVM: selftests: Test content modes ZERO and PRESERVE for SNP
From: Ackerley Tng @ 2026-04-28 23:33 UTC (permalink / raw)
To: devnull+ackerleytng.google.com
Cc: ackerleytng, aik, akpm, andrew.jones, aneesh.kumar, axelrasmussen,
baohua, bhe, binbin.wu, bp, brauner, chao.p.peng, chrisl, corbet,
dave.hansen, david, forkloop, hpa, ira.weiny, jgg, jmattson,
jthoughton, kas, kasong, kvm, linux-coco, linux-doc, linux-kernel,
linux-kselftest, linux-mm, linux-trace-kernel, mathieu.desnoyers,
mhiramat, michael.roth, mingo, nphamcs, oupton, pankaj.gupta,
pbonzini, pratyush, qi.zheng, qperret, rick.p.edgecombe, rientjes,
rostedt, seanjc, shakeel.butt, shikemeng, shivankg, shuah, skhan,
steven.price, suzuki.poulose, tabba, tglx, vannapurve, vbabka,
weixugc, willy, wyihan, x86, yan.y.zhao, youngjun.park, yuanchu
In-Reply-To: <cover.1777418884.git.ackerleytng@google.com>
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
.../selftests/kvm/x86/sev_smoke_test.c | 47 +++++++++++++++++--
1 file changed, 44 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/kvm/x86/sev_smoke_test.c b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
index 86f17e59e9392..7a91a113c4fb7 100644
--- a/tools/testing/selftests/kvm/x86/sev_smoke_test.c
+++ b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
@@ -365,7 +365,26 @@ static void guest_code_conversion(u8 *test_shared_gva, u8 *test_private_gva, u64
vmgexit();
}
-static void test_conversion(u64 policy)
+static void vm_set_memory_attributes_expect_error(struct kvm_vm *vm, u64 gpa,
+ size_t size, u64 attributes,
+ u64 flags, int expected_errno)
+{
+ loff_t error_offset = -1;
+ size_t len_ignored;
+ loff_t offset;
+ int gmem_fd;
+ int ret;
+
+ gmem_fd = kvm_gpa_to_guest_memfd(vm, gpa, &offset, &len_ignored);
+ ret = __gmem_set_memory_attributes(gmem_fd, offset, size, attributes,
+ &error_offset, flags);
+
+ TEST_ASSERT_EQ(ret, -1);
+ TEST_ASSERT_EQ(offset, error_offset);
+ TEST_ASSERT_EQ(errno, expected_errno);
+}
+
+static void test_conversion(u64 policy, u64 content_mode)
{
gva_t test_private_gva;
gva_t test_shared_gva;
@@ -409,6 +428,21 @@ static void test_conversion(u64 policy)
TEST_ASSERT_EQ(vcpu->run->hypercall.args[1], 1);
TEST_ASSERT_EQ(vcpu->run->hypercall.args[2], KVM_MAP_GPA_RANGE_ENCRYPTED | KVM_MAP_GPA_RANGE_PAGE_SZ_4K);
+ /* ZERO when setting memory attributes to private is always not supported. */
+ vm_set_memory_attributes_expect_error(vm, test_gpa, PAGE_SIZE,
+ KVM_MEMORY_ATTRIBUTE_PRIVATE,
+ KVM_SET_MEMORY_ATTRIBUTES2_ZERO,
+ EOPNOTSUPP);
+
+ /* PRESERVE is not supported for SNP. */
+ vm_set_memory_attributes_expect_error(vm, test_gpa, PAGE_SIZE, 0,
+ KVM_SET_MEMORY_ATTRIBUTES2_PRESERVE,
+ EOPNOTSUPP);
+ vm_set_memory_attributes_expect_error(vm, test_gpa, PAGE_SIZE,
+ KVM_MEMORY_ATTRIBUTE_PRIVATE,
+ KVM_SET_MEMORY_ATTRIBUTES2_PRESERVE,
+ EOPNOTSUPP);
+
vm_mem_set_private(vm, test_gpa, PAGE_SIZE, KVM_SET_MEMORY_ATTRIBUTES2_MODE_UNSPECIFIED);
vcpu_run(vcpu);
@@ -419,7 +453,12 @@ static void test_conversion(u64 policy)
TEST_ASSERT_EQ(vcpu->run->hypercall.args[1], 1);
TEST_ASSERT_EQ(vcpu->run->hypercall.args[2], KVM_MAP_GPA_RANGE_DECRYPTED | KVM_MAP_GPA_RANGE_PAGE_SZ_4K);
- vm_mem_set_shared(vm, test_gpa, PAGE_SIZE, KVM_SET_MEMORY_ATTRIBUTES2_MODE_UNSPECIFIED);
+ vm_mem_set_shared(vm, test_gpa, PAGE_SIZE, content_mode);
+
+ if (content_mode == KVM_SET_MEMORY_ATTRIBUTES2_ZERO)
+ TEST_ASSERT_EQ(READ_ONCE(*(u8 *)test_hva), 0);
+ else
+ fprintf(stderr, "test_hva contents = %x\n", READ_ONCE(*(u8 *)test_hva));
vcpu_run(vcpu);
@@ -441,7 +480,9 @@ int main(int argc, char *argv[])
// test_sev_smoke(guest_sev_es_code, KVM_X86_SEV_ES_VM, SEV_POLICY_ES);
if (kvm_cpu_has(X86_FEATURE_SEV_SNP)) {
- test_conversion(snp_default_policy());
+ test_conversion(snp_default_policy(), KVM_SET_MEMORY_ATTRIBUTES2_MODE_UNSPECIFIED);
+ test_conversion(snp_default_policy(), KVM_SET_MEMORY_ATTRIBUTES2_ZERO);
+
// test_sev_smoke(guest_snp_code, KVM_X86_SNP_VM, snp_default_policy());
}
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [POC PATCH 5/6] KVM: selftests: Test conversions for SNP
From: Ackerley Tng @ 2026-04-28 23:33 UTC (permalink / raw)
To: devnull+ackerleytng.google.com
Cc: ackerleytng, aik, akpm, andrew.jones, aneesh.kumar, axelrasmussen,
baohua, bhe, binbin.wu, bp, brauner, chao.p.peng, chrisl, corbet,
dave.hansen, david, forkloop, hpa, ira.weiny, jgg, jmattson,
jthoughton, kas, kasong, kvm, linux-coco, linux-doc, linux-kernel,
linux-kselftest, linux-mm, linux-trace-kernel, mathieu.desnoyers,
mhiramat, michael.roth, mingo, nphamcs, oupton, pankaj.gupta,
pbonzini, pratyush, qi.zheng, qperret, rick.p.edgecombe, rientjes,
rostedt, seanjc, shakeel.butt, shikemeng, shivankg, shuah, skhan,
steven.price, suzuki.poulose, tabba, tglx, vannapurve, vbabka,
weixugc, willy, wyihan, x86, yan.y.zhao, youngjun.park, yuanchu
In-Reply-To: <cover.1777418884.git.ackerleytng@google.com>
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
.../selftests/kvm/x86/sev_smoke_test.c | 190 +++++++++++++++++-
1 file changed, 185 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/kvm/x86/sev_smoke_test.c b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
index 8b859adf4cf6f..86f17e59e9392 100644
--- a/tools/testing/selftests/kvm/x86/sev_smoke_test.c
+++ b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
@@ -253,17 +253,197 @@ static void test_sev_smoke(void *guest, u32 type, u64 policy)
}
}
+#define GHCB_MSR_REG_GPA_REQ 0x012
+#define GHCB_MSR_REG_GPA_REQ_VAL(v) \
+ /* GHCBData[63:12] */ \
+ (((u64)((v) & GENMASK_ULL(51, 0)) << 12) | \
+ /* GHCBData[11:0] */ \
+ GHCB_MSR_REG_GPA_REQ)
+
+#define GHCB_MSR_REG_GPA_RESP 0x013
+#define GHCB_MSR_REG_GPA_RESP_VAL(v) \
+ /* GHCBData[63:12] */ \
+ (((u64)(v) & GENMASK_ULL(63, 12)) >> 12)
+
+#define GHCB_DATA_LOW 12
+#define GHCB_MSR_INFO_MASK (BIT_ULL(GHCB_DATA_LOW) - 1)
+#define GHCB_RESP_CODE(v) ((v) & GHCB_MSR_INFO_MASK)
+
+/*
+ * SNP Page State Change Operation
+ *
+ * GHCBData[55:52] - Page operation:
+ * 0x0001 Page assignment, Private
+ * 0x0002 Page assignment, Shared
+ */
+enum psc_op {
+ SNP_PAGE_STATE_PRIVATE = 1,
+ SNP_PAGE_STATE_SHARED,
+};
+
+#define GHCB_MSR_PSC_REQ 0x014
+#define GHCB_MSR_PSC_REQ_GFN(gfn, op) \
+ /* GHCBData[55:52] */ \
+ (((u64)((op) & 0xf) << 52) | \
+ /* GHCBData[51:12] */ \
+ ((u64)((gfn) & GENMASK_ULL(39, 0)) << 12) | \
+ /* GHCBData[11:0] */ \
+ GHCB_MSR_PSC_REQ)
+
+#define GHCB_MSR_PSC_RESP 0x015
+#define GHCB_MSR_PSC_RESP_VAL(val) \
+ /* GHCBData[63:32] */ \
+ (((u64)(val) & GENMASK_ULL(63, 32)) >> 32)
+
+static u64 ghcb_gpa;
+static void snp_register_ghcb(void)
+{
+ u64 ghcb_pfn = ghcb_gpa >> PAGE_SHIFT;
+ u64 val;
+
+ GUEST_ASSERT(ghcb_gpa);
+
+ wrmsr(MSR_AMD64_SEV_ES_GHCB, GHCB_MSR_REG_GPA_REQ_VAL(ghcb_gpa >> PAGE_SHIFT));
+ vmgexit();
+
+ val = rdmsr(MSR_AMD64_SEV_ES_GHCB);
+ GUEST_ASSERT_EQ(GHCB_RESP_CODE(val), GHCB_MSR_REG_GPA_RESP);
+ GUEST_ASSERT_EQ(GHCB_MSR_REG_GPA_RESP_VAL(val), ghcb_pfn);
+}
+
+static void snp_page_state_change(u64 gpa, enum psc_op op)
+{
+ u64 val;
+
+ wrmsr(MSR_AMD64_SEV_ES_GHCB, GHCB_MSR_PSC_REQ_GFN(gpa >> PAGE_SHIFT, op));
+ vmgexit();
+
+ val = rdmsr(MSR_AMD64_SEV_ES_GHCB);
+ GUEST_ASSERT_EQ(GHCB_RESP_CODE(val), GHCB_MSR_PSC_RESP);
+ GUEST_ASSERT_EQ(GHCB_MSR_PSC_RESP_VAL(val), 0);
+}
+
+#define RMP_PG_SIZE_4K 0
+static inline void pvalidate(void *vaddr, bool validate)
+{
+ bool no_rmpupdate;
+ int rc;
+
+ /* "pvalidate" mnemonic support in binutils 2.36 and newer */
+ asm volatile(".byte 0xF2, 0x0F, 0x01, 0xFF\n\t"
+ : "=@ccc"(no_rmpupdate), "=a"(rc)
+ : "a"(vaddr), "c"(RMP_PG_SIZE_4K), "d"(validate)
+ : "memory", "cc");
+
+ GUEST_ASSERT(!no_rmpupdate);
+ GUEST_ASSERT_EQ(rc, 0);
+}
+
+#define CONVERSION_TEST_VALUE_SHARED_1 0xab
+#define CONVERSION_TEST_VALUE_SHARED_2 0xcd
+#define CONVERSION_TEST_VALUE_PRIVATE 0xef
+#define CONVERSION_TEST_VALUE_SHARED_3 0xbc
+static void guest_code_conversion(u8 *test_shared_gva, u8 *test_private_gva, u64 test_gpa)
+{
+ snp_register_ghcb();
+
+ GUEST_ASSERT_EQ(READ_ONCE(*test_shared_gva), CONVERSION_TEST_VALUE_SHARED_1);
+ WRITE_ONCE(*test_shared_gva, CONVERSION_TEST_VALUE_SHARED_2);
+
+ snp_page_state_change(test_gpa, SNP_PAGE_STATE_PRIVATE);
+ pvalidate(test_private_gva, true);
+
+ WRITE_ONCE(*test_private_gva, CONVERSION_TEST_VALUE_PRIVATE);
+ GUEST_ASSERT_EQ(READ_ONCE(*test_private_gva), CONVERSION_TEST_VALUE_PRIVATE);
+
+ pvalidate(test_private_gva, false);
+ snp_page_state_change(test_gpa, SNP_PAGE_STATE_SHARED);
+
+ WRITE_ONCE(*test_shared_gva, CONVERSION_TEST_VALUE_SHARED_3);
+
+ wrmsr(MSR_AMD64_SEV_ES_GHCB, GHCB_MSR_TERM_REQ);
+ vmgexit();
+}
+
+static void test_conversion(u64 policy)
+{
+ gva_t test_private_gva;
+ gva_t test_shared_gva;
+ struct kvm_vcpu *vcpu;
+ gva_t ghcb_gva;
+ gpa_t test_gpa;
+ struct kvm_vm *vm;
+ void *ghcb_hva;
+ void *test_hva;
+
+ vm = vm_sev_create_with_one_vcpu(KVM_X86_SNP_VM, guest_code_conversion, &vcpu);
+
+ ghcb_gva = vm_alloc_shared(vm, PAGE_SIZE, KVM_UTIL_MIN_VADDR,
+ MEM_REGION_TEST_DATA);
+ ghcb_hva = addr_gva2hva(vm, ghcb_gva);
+ ghcb_gpa = addr_gva2gpa(vm, ghcb_gva);
+ sync_global_to_guest(vm, ghcb_gpa);
+
+ test_shared_gva = vm_alloc_shared(vm, PAGE_SIZE, KVM_UTIL_MIN_VADDR,
+ MEM_REGION_TEST_DATA);
+ test_hva = addr_gva2hva(vm, test_shared_gva);
+ test_gpa = addr_gva2gpa(vm, test_shared_gva);
+
+ test_private_gva = vm_unused_gva_gap(vm, PAGE_SIZE, KVM_UTIL_MIN_VADDR);
+ ___virt_pg_map(vm, &vm->mmu, test_private_gva, test_gpa, PG_SIZE_4K, true);
+
+ vcpu_args_set(vcpu, 3, test_shared_gva, test_private_gva, test_gpa);
+
+ vm_sev_launch(vm, policy, NULL);
+
+ WRITE_ONCE(*(u8 *)test_hva, CONVERSION_TEST_VALUE_SHARED_1);
+
+ fprintf(stderr, "ghcb_hva=%p ghcb_gpa=%lx ghcb_gva=%lx\n", ghcb_hva, ghcb_gpa, ghcb_gva);
+ fprintf(stderr, "test_hva=%p test_gpa=%lx test_private_gva=%lx test_shared_gva=%lx\n", test_hva, test_gpa, test_private_gva, test_shared_gva);
+
+ vcpu_run(vcpu);
+
+ TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_HYPERCALL);
+ TEST_ASSERT_EQ(vcpu->run->hypercall.nr, KVM_HC_MAP_GPA_RANGE);
+ TEST_ASSERT_EQ(vcpu->run->hypercall.args[0], test_gpa);
+ TEST_ASSERT_EQ(vcpu->run->hypercall.args[1], 1);
+ TEST_ASSERT_EQ(vcpu->run->hypercall.args[2], KVM_MAP_GPA_RANGE_ENCRYPTED | KVM_MAP_GPA_RANGE_PAGE_SZ_4K);
+
+ vm_mem_set_private(vm, test_gpa, PAGE_SIZE, KVM_SET_MEMORY_ATTRIBUTES2_MODE_UNSPECIFIED);
+
+ vcpu_run(vcpu);
+
+ TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_HYPERCALL);
+ TEST_ASSERT_EQ(vcpu->run->hypercall.nr, KVM_HC_MAP_GPA_RANGE);
+ TEST_ASSERT_EQ(vcpu->run->hypercall.args[0], test_gpa);
+ TEST_ASSERT_EQ(vcpu->run->hypercall.args[1], 1);
+ TEST_ASSERT_EQ(vcpu->run->hypercall.args[2], KVM_MAP_GPA_RANGE_DECRYPTED | KVM_MAP_GPA_RANGE_PAGE_SZ_4K);
+
+ vm_mem_set_shared(vm, test_gpa, PAGE_SIZE, KVM_SET_MEMORY_ATTRIBUTES2_MODE_UNSPECIFIED);
+
+ vcpu_run(vcpu);
+
+ TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_SYSTEM_EVENT);
+ TEST_ASSERT_EQ(vcpu->run->system_event.type, KVM_SYSTEM_EVENT_SEV_TERM);
+ TEST_ASSERT_EQ(vcpu->run->system_event.ndata, 1);
+ TEST_ASSERT_EQ(vcpu->run->system_event.data[0], GHCB_MSR_TERM_REQ);
+
+ TEST_ASSERT_EQ(*(u8 *)test_hva, CONVERSION_TEST_VALUE_SHARED_3);
+}
+
int main(int argc, char *argv[])
{
TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_SEV));
- test_sev_smoke(guest_sev_code, KVM_X86_SEV_VM, 0);
+ // test_sev_smoke(guest_sev_code, KVM_X86_SEV_VM, 0);
- if (kvm_cpu_has(X86_FEATURE_SEV_ES))
- test_sev_smoke(guest_sev_es_code, KVM_X86_SEV_ES_VM, SEV_POLICY_ES);
+ // if (kvm_cpu_has(X86_FEATURE_SEV_ES))
+ // test_sev_smoke(guest_sev_es_code, KVM_X86_SEV_ES_VM, SEV_POLICY_ES);
- if (kvm_cpu_has(X86_FEATURE_SEV_SNP))
- test_sev_smoke(guest_snp_code, KVM_X86_SNP_VM, snp_default_policy());
+ if (kvm_cpu_has(X86_FEATURE_SEV_SNP)) {
+ test_conversion(snp_default_policy());
+ // test_sev_smoke(guest_snp_code, KVM_X86_SNP_VM, snp_default_policy());
+ }
return 0;
}
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [POC PATCH 4/6] KVM: selftests: Allow specifying CoCo-privateness while mapping a page
From: Ackerley Tng @ 2026-04-28 23:33 UTC (permalink / raw)
To: devnull+ackerleytng.google.com
Cc: ackerleytng, aik, akpm, andrew.jones, aneesh.kumar, axelrasmussen,
baohua, bhe, binbin.wu, bp, brauner, chao.p.peng, chrisl, corbet,
dave.hansen, david, forkloop, hpa, ira.weiny, jgg, jmattson,
jthoughton, kas, kasong, kvm, linux-coco, linux-doc, linux-kernel,
linux-kselftest, linux-mm, linux-trace-kernel, mathieu.desnoyers,
mhiramat, michael.roth, mingo, nphamcs, oupton, pankaj.gupta,
pbonzini, pratyush, qi.zheng, qperret, rick.p.edgecombe, rientjes,
rostedt, seanjc, shakeel.butt, shikemeng, shivankg, shuah, skhan,
steven.price, suzuki.poulose, tabba, tglx, vannapurve, vbabka,
weixugc, willy, wyihan, x86, yan.y.zhao, youngjun.park, yuanchu
In-Reply-To: <cover.1777418884.git.ackerleytng@google.com>
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
tools/testing/selftests/kvm/include/x86/processor.h | 2 ++
tools/testing/selftests/kvm/lib/x86/processor.c | 13 ++++++++++---
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/testing/selftests/kvm/include/x86/processor.h
index 77f576ee7789d..683f21452db58 100644
--- a/tools/testing/selftests/kvm/include/x86/processor.h
+++ b/tools/testing/selftests/kvm/include/x86/processor.h
@@ -1507,6 +1507,8 @@ enum pg_level {
void tdp_mmu_init(struct kvm_vm *vm, int pgtable_levels,
struct pte_masks *pte_masks);
+void ___virt_pg_map(struct kvm_vm *vm, struct kvm_mmu *mmu, gva_t gva,
+ gpa_t gpa, int level, bool private);
void __virt_pg_map(struct kvm_vm *vm, struct kvm_mmu *mmu, gva_t gva,
gpa_t gpa, int level);
void virt_map_level(struct kvm_vm *vm, gva_t gva, gpa_t gpa,
diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c
index b51467d70f6e7..02781194f51a2 100644
--- a/tools/testing/selftests/kvm/lib/x86/processor.c
+++ b/tools/testing/selftests/kvm/lib/x86/processor.c
@@ -256,8 +256,8 @@ static u64 *virt_create_upper_pte(struct kvm_vm *vm,
return pte;
}
-void __virt_pg_map(struct kvm_vm *vm, struct kvm_mmu *mmu, gva_t gva,
- gpa_t gpa, int level)
+void ___virt_pg_map(struct kvm_vm *vm, struct kvm_mmu *mmu, gva_t gva,
+ gpa_t gpa, int level, bool private)
{
const u64 pg_size = PG_LEVEL_SIZE(level);
u64 *pte = &mmu->pgd;
@@ -309,12 +309,19 @@ void __virt_pg_map(struct kvm_vm *vm, struct kvm_mmu *mmu, gva_t gva,
* Neither SEV nor TDX supports shared page tables, so only the final
* leaf PTE needs manually set the C/S-bit.
*/
- if (vm_is_gpa_protected(vm, gpa))
+ if (private)
*pte |= PTE_C_BIT_MASK(mmu);
else
*pte |= PTE_S_BIT_MASK(mmu);
}
+void __virt_pg_map(struct kvm_vm *vm, struct kvm_mmu *mmu, gva_t gva,
+ gpa_t gpa, int level)
+{
+ ___virt_pg_map(vm, mmu, gva, gpa, level,
+ vm_is_gpa_protected(vm, gpa));
+}
+
void virt_arch_pg_map(struct kvm_vm *vm, gva_t gva, gpa_t gpa)
{
__virt_pg_map(vm, &vm->mmu, gva, gpa, PG_LEVEL_4K);
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [POC PATCH 3/6] KVM: selftests: Make guest_code_xsave more friendly
From: Ackerley Tng @ 2026-04-28 23:33 UTC (permalink / raw)
To: devnull+ackerleytng.google.com
Cc: ackerleytng, aik, akpm, andrew.jones, aneesh.kumar, axelrasmussen,
baohua, bhe, binbin.wu, bp, brauner, chao.p.peng, chrisl, corbet,
dave.hansen, david, forkloop, hpa, ira.weiny, jgg, jmattson,
jthoughton, kas, kasong, kvm, linux-coco, linux-doc, linux-kernel,
linux-kselftest, linux-mm, linux-trace-kernel, mathieu.desnoyers,
mhiramat, michael.roth, mingo, nphamcs, oupton, pankaj.gupta,
pbonzini, pratyush, qi.zheng, qperret, rick.p.edgecombe, rientjes,
rostedt, seanjc, shakeel.butt, shikemeng, shivankg, shuah, skhan,
steven.price, suzuki.poulose, tabba, tglx, vannapurve, vbabka,
weixugc, willy, wyihan, x86, yan.y.zhao, youngjun.park, yuanchu
In-Reply-To: <cover.1777418884.git.ackerleytng@google.com>
The original implementation of guest_code_xsave makes a jmp to
guest_sev_es_code in inline assembly. When code that uses guest_sev_es_code
is removed, guest_sev_es_code will be optimized out, leading to a linking
error since guest_code_xsave still tries to jmp to guest_sev_es_code.
Rewrite guest_code_xsave() to instead make a call, in C, to
guest_sev_es_code(), so that usage of guest_sev_es_code() is made known to
the compiler.
This rewriting also gives a name to the xsave inline assembly, improving
readability.
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
.../selftests/kvm/x86/sev_smoke_test.c | 24 +++++++++++++------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/tools/testing/selftests/kvm/x86/sev_smoke_test.c b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
index 1a49ee3915864..8b859adf4cf6f 100644
--- a/tools/testing/selftests/kvm/x86/sev_smoke_test.c
+++ b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
@@ -80,13 +80,23 @@ static void guest_sev_code(void)
GUEST_DONE();
}
-/* Stash state passed via VMSA before any compiled code runs. */
-extern void guest_code_xsave(void);
-asm("guest_code_xsave:\n"
- "mov $" __stringify(XFEATURE_MASK_X87_AVX) ", %eax\n"
- "xor %edx, %edx\n"
- "xsave (%rdi)\n"
- "jmp guest_sev_es_code");
+static void xsave_all_registers(void *addr)
+{
+ __asm__ __volatile__(
+ "mov $" __stringify(XFEATURE_MASK_X87_AVX) ", %eax\n"
+ "xor %edx, %edx\n"
+ "xsave (%0)"
+ :
+ : "r"(addr)
+ : "eax", "edx", "memory"
+ );
+}
+
+static void guest_code_xsave(void *vmsa_gva)
+{
+ xsave_all_registers(vmsa_gva);
+ guest_sev_es_code();
+}
static void compare_xsave(u8 *from_host, u8 *from_guest)
{
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [POC PATCH 2/6] KVM: selftests: Use guest_memfd memory contents in-place for SNP launch update
From: Ackerley Tng @ 2026-04-28 23:33 UTC (permalink / raw)
To: devnull+ackerleytng.google.com
Cc: ackerleytng, aik, akpm, andrew.jones, aneesh.kumar, axelrasmussen,
baohua, bhe, binbin.wu, bp, brauner, chao.p.peng, chrisl, corbet,
dave.hansen, david, forkloop, hpa, ira.weiny, jgg, jmattson,
jthoughton, kas, kasong, kvm, linux-coco, linux-doc, linux-kernel,
linux-kselftest, linux-mm, linux-trace-kernel, mathieu.desnoyers,
mhiramat, michael.roth, mingo, nphamcs, oupton, pankaj.gupta,
pbonzini, pratyush, qi.zheng, qperret, rick.p.edgecombe, rientjes,
rostedt, seanjc, shakeel.butt, shikemeng, shivankg, shuah, skhan,
steven.price, suzuki.poulose, tabba, tglx, vannapurve, vbabka,
weixugc, willy, wyihan, x86, yan.y.zhao, youngjun.park, yuanchu
In-Reply-To: <cover.1777418884.git.ackerleytng@google.com>
Update the SEV-SNP launch update flow to utilize guest_memfd in-place
conversion.
Include the KVM_SET_MEMORY_ATTRIBUTES2_PRESERVE flag when setting memory
attributes to private. This is permitted before the SNP VM is finalized.
In snp_launch_update_data, pass 0 as the host virtual address. This
instructs the kernel to perform the launch update using the guest_memfd
backing the guest physical address rather than a userspace-provided
buffer.
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
tools/testing/selftests/kvm/lib/x86/sev.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/selftests/kvm/lib/x86/sev.c
index d0205b3299e0b..72b2935871fe4 100644
--- a/tools/testing/selftests/kvm/lib/x86/sev.c
+++ b/tools/testing/selftests/kvm/lib/x86/sev.c
@@ -32,13 +32,14 @@ static void encrypt_region(struct kvm_vm *vm, struct userspace_mem_region *regio
const u64 size = (j - i + 1) * vm->page_size;
const u64 offset = (i - lowest_page_in_region) * vm->page_size;
- if (private)
- vm_mem_set_private(vm, gpa_base + offset, size, 0);
+ if (private) {
+ vm_mem_set_private(vm, gpa_base + offset, size,
+ KVM_SET_MEMORY_ATTRIBUTES2_PRESERVE);
+ }
if (is_sev_snp_vm(vm))
snp_launch_update_data(vm, gpa_base + offset,
- (u64)addr_gpa2hva(vm, gpa_base + offset),
- size, page_type);
+ 0, size, page_type);
else
sev_launch_update_data(vm, gpa_base + offset, size);
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox