On Thu, Jul 15, 2021, Brijesh Singh wrote: > > > On 7/15/21 1:39 PM, Sean Christopherson wrote: > > On Thu, Jul 15, 2021, Brijesh Singh wrote: > > > The memfd_secrets uses the set_direct_map_{invalid,default}_noflush() and it > > > is designed to remove/add the present bit in the direct map. We can't use > > > them, because in our case the page may get accessed by the KVM (e.g > > > kvm_guest_write, kvm_guest_map etc). > > > > But KVM should never access a guest private page, i.e. the direct map should > > always be restored to PRESENT before KVM attempts to access the page. > > > > Yes, KVM should *never* access the guest private pages. So, we could > potentially enhance the RMPUPDATE() to check for the assigned and act > accordingly. > > Are you thinking something along the line of this: > > int rmpupdate(struct page *page, struct rmpupdate *val) > { > ... > > /* > * If page is getting assigned in the RMP entry then unmap > * it from the direct map before its added in the RMP table. > */ > if (val.assigned) > set_direct_map_invalid_noflush(page_to_virt(page), 1); > > ... > > /* > * If the page is getting unassigned then restore the mapping > * in the direct map after its removed from the RMP table. > */ > if (!val.assigned) > set_direct_map_default_noflush(page_to_virt(page), 1); > > ... > } Yep. However, looking at the KVM usage, rmpupdate() appears to be broken. When handling a page state change, the guest can specify a 2mb page. In that case, rmpupdate() will be called once for a 2mb page, but this flow assumes a single 4kb page. The current code works because set_memory_4k() will cause the entire 2mb page to be shattered, but it's technically wrong and switching to the above would cause problems.