On 5/6/25 2:52 PM, Alexander Gordeev wrote:
On Wed, Apr 30, 2025 at 08:04:40AM +0900, Harry Yoo wrote:
+struct vmalloc_populate_data {
- unsigned long start;
- struct page **pages;
+};
static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr,
void *unused)
void *_data)
{
- unsigned long page;
- struct vmalloc_populate_data *data = _data;
- struct page *page;
- unsigned long pfn; pte_t pte;
if (likely(!pte_none(ptep_get(ptep)))) return 0;
- page = __get_free_page(GFP_KERNEL);
- if (!page)
return -ENOMEM;
- __memset((void *)page, KASAN_VMALLOC_INVALID, PAGE_SIZE);
- pte = pfn_pte(PFN_DOWN(__pa(page)), PAGE_KERNEL);
- page = data->pages[PFN_DOWN(addr - data->start)];
- pfn = page_to_pfn(page);
- __memset(pfn_to_virt(pfn), KASAN_VMALLOC_INVALID, PAGE_SIZE);
- pte = pfn_pte(pfn, PAGE_KERNEL);
spin_lock(&init_mm.page_table_lock);
- if (likely(pte_none(ptep_get(ptep)))) {
- if (likely(pte_none(ptep_get(ptep)))) set_pte_at(&init_mm, addr, ptep, pte);
page = 0;
With this patch, now if the pte is already set, the page is leaked?
Yes. But currently it is leaked for previously allocated pages anyway, so no change in behaviour (unless I misread the code).
Current code doesn't even allocate page if pte set, and if set pte discovered only after taking spinlock, the page will be freed, not leaked.
Whereas, this patch leaks page for every single !pte_none case. This will build up over time as long as vmalloc called.
Should we set data->pages[PFN_DOWN(addr - data->start)] = NULL and free non-null elements later in __kasan_populate_vmalloc()?
Should the allocation fail on boot, the kernel would not fly anyway.
This is not boot code, it's called from vmalloc() code path.
If for whatever reason we want to free, that should be a follow-up change, as far as I am concerned.
We want to free it, because we don't want unbound memory leak.