Re: [PATCH v4 08/12] hostmem: Support fully shared guest memfd to back a VM
Michael Roth via qemu development <[email protected]>
| Newsgroups | org.nongnu.qemu-devel |
|---|---|
| Message-ID | <2k6hph3cnf4djvjd72g26sdgxluixhm2mpyf2emvgmkrfturvj@ctnctjaks7jq> |
On Mon, Aug 17, 2026 at 09:01:43AM -0400, Peter Xu wrote: > On Fri, Aug 14, 2026 at 04:19:38PM +0100, Daniel P. Berrangé wrote: > > On Thu, Aug 13, 2026 at 10:06:17AM -0400, Peter Xu wrote: > > > On Thu, Aug 13, 2026 at 01:48:21PM +0100, Daniel P. Berrangé wrote: > > > > On Thu, Aug 13, 2026 at 08:28:24AM -0400, Peter Xu wrote: > > > > > On Thu, Aug 13, 2026 at 09:24:22AM +0100, Daniel P. Berrangé wrote: > > > > > > On Wed, Aug 12, 2026 at 03:16:46PM -0500, Michael Roth wrote: > > > > > > > From: Peter Xu <[email protected]> > > > > > > > > > > > > > > Host backends supports guest-memfd now by detecting whether it's a > > > > > > > confidential VM. There's no way to choose it yet from the memory level to > > > > > > > use it fully shared. If we use guest-memfd, it so far always implies we > > > > > > > need two layers of memory backends, while the guest-memfd only provides the > > > > > > > private set of pages. > > > > > > > > > > > > > > This patch introduces a way so that QEMU can consume guest memfd as the > > > > > > > only source of memory to back the object (aka, fully shared). > > > > > > > > > > > > > > To use the fully shared guest-memfd, one can add a memfd object with: > > > > > > > > > > > > > > -object memory-backend-memfd,guest-memfd=on,share=on > > > > > > > > > > > > > > Note that share=on is required with fully shared guest_memfd. > > > > > > > > > > > > > > PS: there's a trivial touch-up on fd<0 check, because the stub to create > > > > > > > guest-memfd may return negative but not -1. > > > > > > > > > > > > > > Signed-off-by: Peter Xu <[email protected]> > > > > > > > Reviewed-by: Xiaoyao Li <[email protected]> > > > > > > > Reviewed-by: Fabiano Rosas <[email protected]> > > > > > > > Signed-off-by: Michael Roth <[email protected]> > > > > > > > --- > > > > > > > backends/hostmem-memfd.c | 56 ++++++++++++++++++++++++++++++++++++---- > > > > > > > qapi/qom.json | 6 ++++- > > > > > > > 2 files changed, 56 insertions(+), 6 deletions(-) > > > > snip > > > > > > > > "memory-backend-memfd,guest-memfd=on|off" is switching between two > > > > > > separate implementations of the class. > > > > > > > > > > > > This whole thing is just shouting "use a different class". > > > > > > > > > > > > There is no meaningful sharing of code here, and the sharing of the > > > > > > public interface is offering apps no value as the impl prevents them > > > > > > from choosing the value of the properties - they have to be set of > > > > > > certain values which are not introspectable. > > > > > > > > > > > > Please introduce a "memory-backend-guest-memfd" backend instead. > > > > > > > > > > This is indeed what Michael used to suggest, and we were discussing in > > > > > previous version on which is better, > > > > > > > > > > https://lore.kernel.org/r/rjqfiwh57gip3u3psqg33jhmo7ixaj2qwzupc7zdk7f3d26qnu@tglactz67ogk > > > > > > > > > > The hope is this is also easier for either libvirt or most users, but > > > > > please correct me if it's not the case, especially for libvirt. The plan > > > > > is when CoCo flags are provided, all things will automatically switch to a > > > > > CoCo-friendly implementation within QEMU. > > > > > > > > > > It also means here the guest-memfd= parameter shouldn't be needed in real > > > > > CoCo contexts because they'll simply be implied (no cmdline change needed > > > > > for the same "-object memory-backend-memfd" one used to use without CoCo). > > > > > It's only needed for only special use of guest-memfd, in this case > > > > > init-shared is the special case where CoCo doesn't use. > > > > > > > > Reading all this, IMHO reusing memory-backend-memfd for the current > > > > Coco support was a design mistake, it should have have a > > > > memory-backend-guest-memfd object from the start. > > > > > > > > Given that we need to be able to control memfd vs guest-memfd for > > > > the non-Coco case, it is still worth introducing the new object > > > > class today. > > > > > > > > Even if the two classes shared all their properties (which they > > > > don't given the comment about 'seal' being always on), then a > > > > "foo=on|off" that toggles two separate impls is still creating > > > > a pair of sub-classes by the backdoor. > > > > > > The idea of that, at least in my mind.. is an user shouldn't need to worry > > > about differences of guest-memfd and memfd, QEMU should just do it for the > > > users, based on the machine configurations. Memfd is a concept more widely > > > spread, the hope is anyone using guest-memfd should simply treat it as one > > > memfd, no matter it is shared, in-place converted, two-layer-backed, or > > > whatever is happening underneath. > > > > > > Now we do create guest-memfd via a separate ioctl, what if we can create it > > > via memfd_create() syscall too? Then do we need to do the separation from > > > QEMU layer? > > > > If QEMU automatically did "the right thing" choosing between traditional > > memfd and guest-memfd, then I wouldn't have even started this thread :-) > > > > The "guest-memfd=on|off" is the trigger that made me think the design > > was wrong from a public interface POV, as that explicitly says that the > > memfd vs guest-memfd distinction is not automatic - it requires the > > mgmt app to understand it and choose between them. > > > > > IMHO that is now an ioctl is not required; it really can be part of > > > memfd_create() syscall, it's just easier to manage, e.g. it's completely > > > KVM alone, and it also has attached to the KVM instance. The idea is still > > > similar, and we can see that from possibly shared properties here on huge > > > pages and so. I don't treat seal= a block just to introduce a new object > > > for that, and I expect as gmemfd evolves it will gradually get most > > > features memfd supports.. like folio migration and so.. but I could be > > > wrong. > > > > > > IMHO one major question to ask is, is it more convenient for libvirt to > > > have that new object? Please keep in mind that after we introduce this as > > > a new object, we may start to introduce even more *-guest-memfd in the > > > future, we roughly talked about DAX in the previous discussion. My goal is > > > to make it most convenient for either user or libvirt to maintain the > > > cmdlines for QEMU, but if you think that makes libvirt live harder instead, > > > I've no strong feeling to go back to what Michael initially suggested. > > > > It is no more or less difficult for libvirt to use different object > > types vs using different guest-memfd=bool values. > > > > What makes a difference for libvirt is understanding whether QEMU > > implements a given feature or not. > > > > If we have the situation with > > > > memory-backend-memfd,hugetlb=bool,guest-memfd=bool > > > > with this series, IIUC, libvirt can introspect to see the new > > guest-memfd property, but it has no way of knowing that it can't > > use the hugetlb proeprty when guest-memfd=on > > > > If the next QEMU release now permits hugetlb=on at the same time > > as guest-memfd=on, then libvirt has no way to know the restriction > > was relaxed. > > > > The QAPI introspection data for memory-backend-memfd is identical > > in both cases. > > > > To deal with this, you need to introduce a workaround to QAPI > > by declaring a feature flag like > > > > features: ['hugetlb-with-guest-memfd-works'] > > > > that libvirt can probe for to determine the functional improvement > > in QEMU. > > > > By comparison, if we introduce a memory-backend-guest-memfd > > object today, then it will omit the hugetlb property entirely. > > > > If the next QEMU release adds a hugetlb property to the > > memory-backend-guest-memfd object, this change is now visible > > in the introspection data, and thus libvirt knows that combo > > is possible with QEMU > > > > (yes, there is the issue that this might have kernel dependancy > > that is not visible from QEMU's introspection, so not perfect, > > but at least libvirt can determine what QEMU is capable of) > > Yes. Due to that, I was expecting Libvirt will always need to query host > capabilities on its own. In this case Libvirt, if preferred, should also > be able to probe standalone with KVM_CAP_GUEST_MEMFD_FLAGS. Yah some generic routine to probe for guest_memfd flags seems unavoidable, and likely that probe will need to be per-VM-type (e.g. confidential vs. non-confidential) to be reliable. > > It's also more involved for sure when hugetlb is involved, if it will share > the same hugetlb reservation with hugetlbfs, it'll also somehow need to > make sure there're available pages later for allocations. Also IIUC not > all default users are accessible to huge pages.. > > From QEMU's POV, personally I still prefer sticking with the memfd object > with guest-memfd=on, then expose the "features" in QAPI, that seems cleaner > to me. > > > > > > > > For example, if libvirt wants to detect hugetlb supports for an object, it > > > can still pass in the parameters and test-boot a QEMU and then IIUC it'll > > > still correctly capture an error for gmemfd case. It might be that I > > > didn't really get what will make libvirt complex by reusing the object, but > > > I'll definitely follow your judgement on that. > > > > Trying parameters to see if they fail and then boot again with different > > options is not a viable approach. That is an indication that QEMU's > > design and/or introspection is flawed. > > It'll be the same when introducing the new -guest-memfd object per above > complications, IMHO. I'm not sure how hugetlbfs pages were managed now > with Libvirt, maybe that can help us understand how guest-memfd (when > hugetlb pages will be supported) will affect Libvirt's mgmt. For now, it > doesn't seem to me that the new object will help in anyway, if we have > QEMU's "features" option. It seemed like the guest_memfd support for directmap removal[1] might be a good test for how this all look like once new features start coming along for confidential vs. non-confidential so I've been trying to get that up and running to see. If we keep everything in memory-backend-memfd, there's a little bit of awkwardness, but the following schema should cover discoverability of QEMU support at least, and then libvirt/management can branch into whatever routine is needed for probing actual kernel support: diff --git a/qapi/qom.json b/qapi/qom.json index ee981fc44c..4777f09ad1 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -774,6 +774,19 @@ # @guest-memfd: if true, use guest-memfd to back the memory region. # (default: false, since: 11.2) # +# @no-directmap: if true, enable support for unmapping backend memory +# from the kernel directmap to better isolate it from +# host activity. This option is only available if a +# corresponding Features value advertises support for +# the intended use-case. +# (default: false, since: 11.2) +# +# Features: +# +# @no-directmap-for-guest-memfd: If present (and if the hypervisor +# supports the feature), the corresponding option is available if +# @guest-memfd is true. (since 11.2) +# # Since: 2.12 ## { 'struct': 'MemoryBackendMemfdProperties', @@ -781,8 +794,10 @@ 'data': { '*hugetlb': 'bool', '*hugetlbsize': 'size', '*seal': 'bool', - '*guest-memfd': 'bool' }, - 'if': 'CONFIG_LINUX' } + '*guest-memfd': 'bool', + '*no-directmap': 'bool' }, + 'if': 'CONFIG_LINUX', + 'features': ['no-directmap-for-guest-memfd'] } One notable thing there is the current code only enables it for non-confidential VM types, so that's where the KVM_CAP_* checks would need to come into play to distinguish between what's supported for specific VM types. On a side note: Ideally we'd be able to do something like the below so we can have one 'supported-for-guest-memfd' features that could be associated with multiple options, e.g.: +# Features: +# +# @supported-for-guest-memfd: If present (and if the hypervisor +# supports the feature), the corresponding option is available if +# @guest-memfd is true. (since 11.2) +# # Since: 2.12 ## { 'struct': 'MemoryBackendMemfdProperties', @@ -781,7 +794,9 @@ 'data': { '*hugetlb': 'bool', '*hugetlbsize': 'size', '*seal': 'bool', - '*guest-memfd': 'bool' }, + '*guest-memfd': 'bool', + { 'name': 'no-directmap', + 'features': ['supported-for-guest-memfd'] } }, But it doesn't seem like QAPI is wired up for that. I guess we could add that as part of enabling directmap support if it seems useful enough but the above should work as well. Thanks, Mike [1] https://lore.kernel.org/kvm/[email protected]/ > > Thanks, > > -- > Peter Xu >