* [PATCH v2 0/2] SEV-SNP Unaccepted Memory Hotplug
@ 2026-01-12 20:22 Pratik R. Sampat
2026-01-12 20:22 ` [PATCH v2 1/2] mm/memory_hotplug: Add support to accept memory during hot-add Pratik R. Sampat
2026-01-12 20:23 ` [PATCH v2 2/2] mm/memory_hotplug: Add support to unaccept memory after hot-remove Pratik R. Sampat
0 siblings, 2 replies; 6+ messages in thread
From: Pratik R. Sampat @ 2026-01-12 20:22 UTC (permalink / raw)
To: linux-mm, linux-coco, x86, linux-kernel
Cc: tglx, mingo, bp, dave.hansen, kas, ardb, akpm, david, osalvador,
thomas.lendacky, michael.roth, prsampat
Guest memory hot-plug/remove via the QEMU monitor is used by virtual
machines to dynamically scale the memory capacity of a system with
virtually zero downtime to the guest. For confidential VMs, memory has
to be first accepted before it can be used. Add support to accept
memory that has been hot-added and revert back it's state for
hypervisors to be able to use the pages during hot-remove.
Usage (for SNP guests)
----------------------
Step1: Spawn a QEMU SNP guest with the additional parameter of slots and
maximum possible memory, along with the initial memory as below:
"-m X,slots=Y,maxmem=Z".
Step2: Once the guest is booted, launch the qemu monitor and hotplug
the memory as follows:
(qemu) object_add memory-backend-memfd,id=mem1,size=1G
(qemu) device_add pc-dimm,id=dimm1,memdev=mem1
Memory is accepted up-front when added to the guest.
If using auto-onlining by either:
a) echo online > /sys/devices/system/memory/auto_online_blocks, OR
b) enable CONFIG_MHP_DEFAULT_ONLINE_TYPE_* while compiling kernel
Memory should show up automatically.
Otherwise, memory can also be onlined by echoing 1 to the newly added
blocks in: /sys/devices/system/memory/memoryXX/online
Step3: memory can be hot-removed using the qemu monitor using:
(qemu) device_remove dimm1
(qemu) object_remove mem1
Tip: Enable the kvm_convert_memory event in QEMU to observe memory
conversions between private and shared during hotplug/remove.
The series is based on
git.kernel.org/pub/scm/virt/kvm/kvm.git next
Comments and feedback appreciated!
Changelog RFC..Patch v2:
------------------------
https://lore.kernel.org/all/20251125175753.1428857-1-prsampat@amd.com/
Based on feedback from the RFC, reworked the series to accept memory
upfront on hotplug. This is done for two reasons:
1. Avoids modifying the unaccepted bitmap. Extending the bitmap would
require either:
* Dynamically allocating the bitmap, which would need changes to EFI
struct definitions, or
* Pre-allocating a larger bitmap to accommodate hotpluggable memory.
This poses challenges since e820 is parsed before SRAT, which
contains the actual memory ranges information.
2. There are currently no known use-cases that would benefit from lazy
acceptance of hotplugged ranges which warrants this additional
complexity.
Pratik R. Sampat (2):
mm/memory_hotplug: Add support to accept memory during hot-add
mm/memory_hotplug: Add support to unaccept memory after hot-remove
arch/x86/coco/sev/core.c | 13 +++++++++++++
arch/x86/include/asm/sev.h | 2 ++
arch/x86/include/asm/unaccepted_memory.h | 9 +++++++++
mm/memory_hotplug.c | 7 +++++++
4 files changed, 31 insertions(+)
--
2.52.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/2] mm/memory_hotplug: Add support to accept memory during hot-add
2026-01-12 20:22 [PATCH v2 0/2] SEV-SNP Unaccepted Memory Hotplug Pratik R. Sampat
@ 2026-01-12 20:22 ` Pratik R. Sampat
2026-01-12 21:04 ` Andrew Morton
2026-01-12 20:23 ` [PATCH v2 2/2] mm/memory_hotplug: Add support to unaccept memory after hot-remove Pratik R. Sampat
1 sibling, 1 reply; 6+ messages in thread
From: Pratik R. Sampat @ 2026-01-12 20:22 UTC (permalink / raw)
To: linux-mm, linux-coco, x86, linux-kernel
Cc: tglx, mingo, bp, dave.hansen, kas, ardb, akpm, david, osalvador,
thomas.lendacky, michael.roth, prsampat
Confidential computing guests require memory to be accepted before use.
The unaccepted memory bitmap maintained by firmware does not track
hotplugged memory ranges.
Call arch_accept_memory() during the hot-add path to explicitly validate
and transition the newly added memory to a private state, making it
usable by the guest.
Signed-off-by: Pratik R. Sampat <prsampat@amd.com>
---
mm/memory_hotplug.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index a63ec679d861..8cfbf0541430 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -38,6 +38,7 @@
#include <linux/node.h>
#include <asm/tlbflush.h>
+#include <asm/unaccepted_memory.h>
#include "internal.h"
#include "shuffle.h"
@@ -1567,6 +1568,9 @@ int add_memory_resource(int nid, struct resource *res, mhp_t mhp_flags)
if (!strcmp(res->name, "System RAM"))
firmware_map_add_hotplug(start, start + size, "System RAM");
+ if (IS_ENABLED(CONFIG_UNACCEPTED_MEMORY))
+ arch_accept_memory(start, start + size);
+
/* device_online() will take the lock when calling online_pages() */
mem_hotplug_done();
--
2.52.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] mm/memory_hotplug: Add support to unaccept memory after hot-remove
2026-01-12 20:22 [PATCH v2 0/2] SEV-SNP Unaccepted Memory Hotplug Pratik R. Sampat
2026-01-12 20:22 ` [PATCH v2 1/2] mm/memory_hotplug: Add support to accept memory during hot-add Pratik R. Sampat
@ 2026-01-12 20:23 ` Pratik R. Sampat
1 sibling, 0 replies; 6+ messages in thread
From: Pratik R. Sampat @ 2026-01-12 20:23 UTC (permalink / raw)
To: linux-mm, linux-coco, x86, linux-kernel
Cc: tglx, mingo, bp, dave.hansen, kas, ardb, akpm, david, osalvador,
thomas.lendacky, michael.roth, prsampat
Transition memory to the shared state during a hot-remove operation so
that it can be re-used by the hypervisor. This also applies when memory
is intended to be hotplugged back in later, as those pages will need to
be re-accepted after crossing the trust boundary.
Signed-off-by: Pratik R. Sampat <prsampat@amd.com>
---
arch/x86/coco/sev/core.c | 13 +++++++++++++
arch/x86/include/asm/sev.h | 2 ++
arch/x86/include/asm/unaccepted_memory.h | 9 +++++++++
mm/memory_hotplug.c | 3 +++
4 files changed, 27 insertions(+)
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index 9ae3b11754e6..63d8f44b76eb 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -703,6 +703,19 @@ void snp_accept_memory(phys_addr_t start, phys_addr_t end)
set_pages_state(vaddr, npages, SNP_PAGE_STATE_PRIVATE);
}
+void snp_unaccept_memory(phys_addr_t start, phys_addr_t end)
+{
+ unsigned long vaddr, npages;
+
+ if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
+ return;
+
+ vaddr = (unsigned long)__va(start);
+ npages = (end - start) >> PAGE_SHIFT;
+
+ set_pages_state(vaddr, npages, SNP_PAGE_STATE_SHARED);
+}
+
static int vmgexit_ap_control(u64 event, struct sev_es_save_area *vmsa, u32 apic_id)
{
bool create = event != SVM_VMGEXIT_AP_DESTROY;
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index 0e6c0940100f..3327de663793 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -514,6 +514,7 @@ bool snp_init(struct boot_params *bp);
void snp_dmi_setup(void);
int snp_issue_svsm_attest_req(u64 call_id, struct svsm_call *call, struct svsm_attest_call *input);
void snp_accept_memory(phys_addr_t start, phys_addr_t end);
+void snp_unaccept_memory(phys_addr_t start, phys_addr_t end);
u64 snp_get_unsupported_features(u64 status);
u64 sev_get_status(void);
void sev_show_status(void);
@@ -623,6 +624,7 @@ static inline int snp_issue_svsm_attest_req(u64 call_id, struct svsm_call *call,
return -ENOTTY;
}
static inline void snp_accept_memory(phys_addr_t start, phys_addr_t end) { }
+static inline void snp_unaccept_memory(phys_addr_t start, phys_addr_t end) { }
static inline u64 snp_get_unsupported_features(u64 status) { return 0; }
static inline u64 sev_get_status(void) { return 0; }
static inline void sev_show_status(void) { }
diff --git a/arch/x86/include/asm/unaccepted_memory.h b/arch/x86/include/asm/unaccepted_memory.h
index f5937e9866ac..8715be843e65 100644
--- a/arch/x86/include/asm/unaccepted_memory.h
+++ b/arch/x86/include/asm/unaccepted_memory.h
@@ -18,6 +18,15 @@ static inline void arch_accept_memory(phys_addr_t start, phys_addr_t end)
}
}
+static inline void arch_unaccept_memory(phys_addr_t start, phys_addr_t end)
+{
+ if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) {
+ snp_unaccept_memory(start, end);
+ } else {
+ panic("Cannot unaccept memory: unknown platform\n");
+ }
+}
+
static inline struct efi_unaccepted_memory *efi_get_unaccepted_table(void)
{
if (efi.unaccepted == EFI_INVALID_TABLE_ADDR)
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 8cfbf0541430..718f729cf687 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -2242,6 +2242,9 @@ static int try_remove_memory(u64 start, u64 size)
mem_hotplug_begin();
+ if (IS_ENABLED(CONFIG_UNACCEPTED_MEMORY))
+ arch_unaccept_memory(start, start + size);
+
rc = memory_blocks_have_altmaps(start, size);
if (rc < 0) {
mem_hotplug_done();
--
2.52.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] mm/memory_hotplug: Add support to accept memory during hot-add
2026-01-12 20:22 ` [PATCH v2 1/2] mm/memory_hotplug: Add support to accept memory during hot-add Pratik R. Sampat
@ 2026-01-12 21:04 ` Andrew Morton
2026-01-12 22:23 ` Pratik R. Sampat
0 siblings, 1 reply; 6+ messages in thread
From: Andrew Morton @ 2026-01-12 21:04 UTC (permalink / raw)
To: Pratik R. Sampat
Cc: linux-mm, linux-coco, x86, linux-kernel, tglx, mingo, bp,
dave.hansen, kas, ardb, david, osalvador, thomas.lendacky,
michael.roth
On Mon, 12 Jan 2026 14:22:59 -0600 "Pratik R. Sampat" <prsampat@amd.com> wrote:
> Confidential computing guests require memory to be accepted before use.
> The unaccepted memory bitmap maintained by firmware does not track
> hotplugged memory ranges.
>
> Call arch_accept_memory() during the hot-add path to explicitly validate
> and transition the newly added memory to a private state, making it
> usable by the guest.
>
> Signed-off-by: Pratik R. Sampat <prsampat@amd.com>
> ---
> mm/memory_hotplug.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index a63ec679d861..8cfbf0541430 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -38,6 +38,7 @@
> #include <linux/node.h>
>
> #include <asm/tlbflush.h>
> +#include <asm/unaccepted_memory.h>
This only exists for x86!
Otherwise, the mm/ changes are minimal so I volunteer this patchset
for the x86 tree ;)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] mm/memory_hotplug: Add support to accept memory during hot-add
2026-01-12 21:04 ` Andrew Morton
@ 2026-01-12 22:23 ` Pratik R. Sampat
2026-01-12 22:43 ` Andrew Morton
0 siblings, 1 reply; 6+ messages in thread
From: Pratik R. Sampat @ 2026-01-12 22:23 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-mm, linux-coco, x86, linux-kernel, tglx, mingo, bp,
dave.hansen, kas, ardb, david, osalvador, thomas.lendacky,
michael.roth
On 1/12/26 3:04 PM, Andrew Morton wrote:
> On Mon, 12 Jan 2026 14:22:59 -0600 "Pratik R. Sampat" <prsampat@amd.com> wrote:
>
>> Confidential computing guests require memory to be accepted before use.
>> The unaccepted memory bitmap maintained by firmware does not track
>> hotplugged memory ranges.
>>
>> Call arch_accept_memory() during the hot-add path to explicitly validate
>> and transition the newly added memory to a private state, making it
>> usable by the guest.
>>
>> Signed-off-by: Pratik R. Sampat <prsampat@amd.com>
>> ---
>> mm/memory_hotplug.c | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
>> index a63ec679d861..8cfbf0541430 100644
>> --- a/mm/memory_hotplug.c
>> +++ b/mm/memory_hotplug.c
>> @@ -38,6 +38,7 @@
>> #include <linux/node.h>
>>
>> #include <asm/tlbflush.h>
>> +#include <asm/unaccepted_memory.h>
>
> This only exists for x86!
Ah, I missed that entirely. Thanks for catching that.
Probably not the best option to have a generic unaccepted_memory.h as well.
Maybe, I should have arch_[un]accept_memory() definitions within mm.h wrapped
within CONFIG_UNACCEPTED_MEMORY instead so that its cleaner.
>
> Otherwise, the mm/ changes are minimal so I volunteer this patchset
> for the x86 tree ;)
Ack!
--Pratik
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] mm/memory_hotplug: Add support to accept memory during hot-add
2026-01-12 22:23 ` Pratik R. Sampat
@ 2026-01-12 22:43 ` Andrew Morton
0 siblings, 0 replies; 6+ messages in thread
From: Andrew Morton @ 2026-01-12 22:43 UTC (permalink / raw)
To: Pratik R. Sampat
Cc: linux-mm, linux-coco, x86, linux-kernel, tglx, mingo, bp,
dave.hansen, kas, ardb, david, osalvador, thomas.lendacky,
michael.roth
On Mon, 12 Jan 2026 16:23:37 -0600 "Pratik R. Sampat" <prsampat@amd.com> wrote:
>
>
> On 1/12/26 3:04 PM, Andrew Morton wrote:
> > On Mon, 12 Jan 2026 14:22:59 -0600 "Pratik R. Sampat" <prsampat@amd.com> wrote:
> >
> >> Confidential computing guests require memory to be accepted before use.
> >> The unaccepted memory bitmap maintained by firmware does not track
> >> hotplugged memory ranges.
> >>
> >> Call arch_accept_memory() during the hot-add path to explicitly validate
> >> and transition the newly added memory to a private state, making it
> >> usable by the guest.
> >>
> >> Signed-off-by: Pratik R. Sampat <prsampat@amd.com>
> >> ---
> >> mm/memory_hotplug.c | 4 ++++
> >> 1 file changed, 4 insertions(+)
> >>
> >> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> >> index a63ec679d861..8cfbf0541430 100644
> >> --- a/mm/memory_hotplug.c
> >> +++ b/mm/memory_hotplug.c
> >> @@ -38,6 +38,7 @@
> >> #include <linux/node.h>
> >>
> >> #include <asm/tlbflush.h>
> >> +#include <asm/unaccepted_memory.h>
> >
> > This only exists for x86!
>
> Ah, I missed that entirely. Thanks for catching that.
>
> Probably not the best option to have a generic unaccepted_memory.h as well.
> Maybe, I should have arch_[un]accept_memory() definitions within mm.h wrapped
> within CONFIG_UNACCEPTED_MEMORY instead so that its cleaner.
Something like that.
The idiomatic Linus way is to use
#ifndef arch_accept_memory
#define arch_accept_memory ...
#endif
Lots of prior art here:
grep -r include/linux "ifndef arch_"
Oh, arch_get_idle_state_flags() got it all wrong.
#ifdef CONFIG_ACPI_PROCESSOR_IDLE
#ifndef arch_get_idle_state_flags
static inline unsigned int arch_get_idle_state_flags(u32 arch_flags)
{
return 0;
}
#endif
#endif /* CONFIG_ACPI_PROCESSOR_IDLE */
- shouldn't have needed "ifdef CONFIG_ACPI_PROCESSOR_IDLE"
- should have appended
#define arch_get_idle_state_flags arch_get_idle_state_flags
in case cpp hit the same lines a second time.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-01-12 22:43 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-01-12 20:22 [PATCH v2 0/2] SEV-SNP Unaccepted Memory Hotplug Pratik R. Sampat
2026-01-12 20:22 ` [PATCH v2 1/2] mm/memory_hotplug: Add support to accept memory during hot-add Pratik R. Sampat
2026-01-12 21:04 ` Andrew Morton
2026-01-12 22:23 ` Pratik R. Sampat
2026-01-12 22:43 ` Andrew Morton
2026-01-12 20:23 ` [PATCH v2 2/2] mm/memory_hotplug: Add support to unaccept memory after hot-remove Pratik R. Sampat
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox