From: Marc Rittinghaus Date: Wed, 12 Apr 2023 12:55:03 +0000 (+0200) Subject: lib/uksglist: Make sure buffers are mapped X-Git-Tag: RELEASE-0.13.0~148 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=7f7f84e63390aa6dd1cfb848e26bd666d1478ede;p=unikraft%2Funikraft.git lib/uksglist: Make sure buffers are mapped With ukvmem and demand-paging enabled it can happen that buffers supplied to the sglist are not fully backed by physical memory. In that case the call to ukplat_virt_to_phys() fails, which expects a valid mapping. This commit adds a call to uk_vma_advise() to make sure the entire buffer is backed by physical memory. A future optimization should integrate the address translation and backing with physical memory in a visitor pattern that traverses the page tables only once instead of doing it one time for the advise and then an extra time for each page of the buffer. Signed-off-by: Marc Rittinghaus Reviewed-by: Ioan-Teodor Teugea Reviewed-by: Razvan Deaconescu Approved-by: Razvan Deaconescu Tested-by: Unikraft CI GitHub-Closes: #834 --- diff --git a/lib/uksglist/sglist.c b/lib/uksglist/sglist.c index 65973d018..150de10a6 100644 --- a/lib/uksglist/sglist.c +++ b/lib/uksglist/sglist.c @@ -46,6 +46,10 @@ #include #endif /* CONFIG_LIBUKALLOC */ #include +#ifdef CONFIG_LIBUKVMEM +#include +#include +#endif /* CONFIG_LIBUKVMEM*/ /* * Convenience macros to save the state of an sglist so it can be restored @@ -125,9 +129,20 @@ static inline int _sglist_append_buf(struct uk_sglist *sg, void *buf, if (len == 0) return 0; - /* Do the first page. It may have an offset. */ vaddr = (__vaddr_t)buf; offset = page_off(vaddr); + +#ifdef CONFIG_LIBUKVMEM + /* Ensure the buffer is backed by physical memory */ + error = uk_vma_advise(uk_vas_get_active(), + PAGE_ALIGN_DOWN(vaddr), + PAGE_ALIGN_UP(len + offset), UK_VMA_ADV_WILLNEED, + UK_VMA_FLAG_UNINITIALIZED); + if (unlikely(error)) + return error; +#endif /* CONFIG_LIBUKVMEM */ + + /* Do the first page. It may have an offset. */ paddr = ukplat_virt_to_phys((void *)vaddr); seglen = MIN(len, __PAGE_SIZE - offset); if (sg->sg_nseg == 0) {