static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr,
		unsigned long end, int write, struct page **pages, int *nr)
{
	struct page *head, *page;
	int refs;

	if (!pmd_access_permitted(orig, write))
		return 0;

	if (pmd_devmap(orig))
		return __gup_device_huge_pmd(orig, pmdp, addr, end, pages, nr);

	refs = 0;
	page = pmd_page(orig) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
	do {
		pages[*nr] = page;
		(*nr)++;
		page++;
		refs++;
	} while (addr += PAGE_SIZE, addr != end);

	head = compound_head(pmd_page(orig));
	if (!page_cache_add_speculative(head, refs)) {
		*nr -= refs;
		return 0;
	}

	if (unlikely(pmd_val(orig) != pmd_val(*pmdp))) {
		*nr -= refs;
		while (refs--)
			put_page(head);
		return 0;
	}

	SetPageReferenced(head);
	return 1;
}
Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code.