Re: [PATCH 2/7] guest_memfd: Introduce an object to manage the guest-memfd with RamDiscardManager

Peter Xu
2025-02-06T20:03:16Z

On Thu, Feb 06, 2025 at 06:41:09PM +0800, Xu Yilun wrote:
> On Thu, Jan 30, 2025 at 11:28:11AM -0500, Peter Xu wrote:
> > On Sun, Jan 26, 2025 at 11:34:29AM +0800, Xu Yilun wrote:
> > > > Definitely not suggesting to install an invalid pointer anywhere. The
> > > > mapped pointer will still be valid for gmem for example, but the fault
> > > > isn't. We need to differenciate two things (1) virtual address mapping,
> > > > then (2) permission and accesses on the folios / pages of the mapping.
> > > > Here I think it's okay if the host pointer is correctly mapped.
> > > >
> > > > For your private MMIO use case, my question is if there's no host pointer
> > > > to be mapped anyway, then what's the benefit to make the MR to be ram=on?
> > > > Can we simply make it a normal IO memory region? The only benefit of a
> > >
> > > The guest access to normal IO memory region would be emulated by QEMU,
> > > while private assigned MMIO requires guest direct access via Secure EPT.
> > >
> > > Seems the existing code doesn't support guest direct access if
> > > mr->ram == false:
> >
> > Ah it's about this, ok.
> >
> > I am not sure what's the best approach, but IMHO it's still better we stick
> > with host pointer always available when ram=on. OTOH, VFIO private regions
> > may be able to provide a special mark somewhere, just like when romd_mode
> > was done previously as below (qemu 235e8982ad39), so that KVM should still
> > apply these MRs even if they're not RAM.
>
> Also good to me.
>
> >
> > >
> > > static void kvm_set_phys_mem(KVMMemoryListener *kml,
> > > MemoryRegionSection *section, bool add)
> > > {
> > > [...]
> > >
> > > if (!memory_region_is_ram(mr)) {
> > > if (writable || !kvm_readonly_mem_allowed) {
> > > return;
> > > } else if (!mr->romd_mode) {
> > > /* If the memory device is not in romd_mode, then we actually want
> > > * to remove the kvm memory slot so all accesses will trap. */
> > > add = false;
> > > }
> > > }
> > >
> > > [...]
> > >
> > > /* register the new slot */
> > > do {
> > >
> > > [...]
> > >
> > > err = kvm_set_user_memory_region(kml, mem, true);
> > > }
> > > }
> > >
> > > > ram=on MR is, IMHO, being able to be accessed as RAM-like. If there's no
> > > > host pointer at all, I don't yet understand how that helps private MMIO
> > > > from working.
> > >
> > > I expect private MMIO not accessible from host, but accessible from
> > > guest so has kvm_userspace_memory_region2 set. That means the resolving
> > > of its PFN during EPT fault cannot depends on host pointer.
> > >
> > > https://lore.kernel.org/all/20250107142719.179636-1-yilun.xu@linux.intel.com/
> >
> > I'll leave this to KVM experts, but I actually didn't follow exactly on why
> > mmu notifier is an issue to make , as I thought that was per-mm anyway, and KVM
> > should logically be able to skip all VFIO private MMIO regions if affected.
>
> I think this creates logical inconsistency. You builds the private MMIO
> EPT mapping on fault based on the HVA<->HPA mapping, but doesn't follow
> the HVA<->HPA mapping change. Why KVM believes the mapping on fault time
> but doesn't on mmu notify time?

IMHO as long as kvm knows it's a private MMIO and there's no mapping under
it guaranteed, then KVM can safely skip those ranges to speedup the mmu
notifier.

Said that, I'm not suggesting to stick with hvas if there're better
alternatives. It's only about the paragraph that confused me a bit.

>
> > This is a comment to this part of your commit message:
> >
> > Rely on userspace mapping also means private MMIO mapping should
> > follow userspace mapping change via mmu_notifier. This conflicts
> > with the current design that mmu_notifier never impacts private
> > mapping. It also makes no sense to support mmu_notifier just for
> > private MMIO, private MMIO mapping should be fixed when CoCo-VM
> > accepts the private MMIO, any following mapping change without
> > guest permission should be invalid.
> >
> > So I don't yet see a hard-no of reusing userspace mapping even if they're
> > not faultable as of now - what if they can be faultable in the future? I
>
> The first commit of guest_memfd emphasize a lot on the benifit of
> decoupling KVM mapping from host mapping. My understanding is even if
> guest memfd can be faultable later, KVM should still work in a way
> without userspace mapping.

I could have implied to suggest using hva, not my intention. I agree
fd-based API is better too in this case at least as of now.

What I'm not sure is how the whole things evolve with either gmemfd or
device fd when they're used with shared and mappable pages. We can leave
that for later discussion for sure.

>
> > am not sure..
> >
> > OTOH, I also don't think we need KVM_SET_USER_MEMORY_REGION3 anyway.. The
> > _REGION2 API is already smart enough to leave some reserved fields:
> >
> > /* for KVM_SET_USER_MEMORY_REGION2 */
> > struct kvm_userspace_memory_region2 {
> > __u32 slot;
> > __u32 flags;
> > __u64 guest_phys_addr;
> > __u64 memory_size;
> > __u64 userspace_addr;
> > __u64 guest_memfd_offset;
> > __u32 guest_memfd;
> > __u32 pad1;
> > __u64 pad2[14];
> > };
> >
> > I think we _could_ reuse some pad*? Reusing guest_memfd field sounds error
> > prone to me.
>
> It truly is. I'm expecting some suggestions here.

Maybe a generic fd+offset pair from pad*? I'm not sure whether at some
point that could also support guest-memfd there too, after all it's easy
for kvm to check whatever file->f_op it's backing, so logically kvm should
allow backing a memslot with whatever file without HVA. Just my 2 cents.

Thanks,

--
Peter Xu