On 7/15/21 5:01 PM, Sean Christopherson wrote: > 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. Yep, this was just an example to make sure I am able to follow you correctly. In the actual patch I am going to read the pagesize from the RMPUPDATE structure and calculated npages for the set_direct_map_default(...). As you said it was not needed in the case of set_memory_4k() because the function force splits the large page. Whereas with set_direct_map_default(), it first checks whether the split is required, if not, then skip and update the attributes. -Brijesh