Re: [PATCH Part2 RFC v4 07/40] x86/sev: Split the physmap when adding the page in RMP table
From: Brijesh Singh <hidden>
Date: 2021-07-15 22:11:43
Also in:
kvm, linux-coco, linux-crypto, linux-mm, lkml, platform-driver-x86
On 7/15/21 5:01 PM, Sean Christopherson wrote:
On Thu, Jul 15, 2021, Brijesh Singh wrote:quoted
On 7/15/21 1:39 PM, Sean Christopherson wrote:quoted
On Thu, Jul 15, 2021, Brijesh Singh wrote:quoted
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