// SPDX-License-Identifier: GPL-2.0 /* * PPC64 Huge TLB Page Support for hash based MMUs (POWER4 and later) * * Copyright (C) 2003 David Gibson, IBM Corporation. * * Based on the IA-32 version: * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
*/
/* Search the Linux page table for a match with va */
vpn = hpt_vpn(ea, vsid, ssize);
/* * At this point, we have a pte (old_pte) which can be used to build * or update an HPTE. There are 2 cases: * * 1. There is a valid (present) pte with no associated HPTE (this is * the most common case) * 2. There is a valid (present) pte with an associated HPTE. The * current values of the pp bits in the HPTE prevent access * because we are doing software DIRTY bit management and the * page is currently not DIRTY.
*/
do {
old_pte = pte_val(*ptep); /* If PTE busy, retry the access */ if (unlikely(old_pte & H_PAGE_BUSY)) return 0; /* If PTE permissions don't match, take page fault */ if (unlikely(!check_pte_access(access, old_pte))) return 1; /* * If hash-4k, hugepages use seeral contiguous PxD entries * so bail out and let mm make the page young or dirty
*/ if (IS_ENABLED(CONFIG_PPC_4K_PAGES)) { if (!(old_pte & _PAGE_ACCESSED)) return 1; if ((access & _PAGE_WRITE) && !(old_pte & _PAGE_DIRTY)) return 1;
}
/* * Try to lock the PTE, add ACCESSED and DIRTY if it was * a write access
*/
new_pte = old_pte | H_PAGE_BUSY | _PAGE_ACCESSED; if (access & _PAGE_WRITE)
new_pte |= _PAGE_DIRTY;
} while(!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
/* Make sure this is a hugetlb entry */ if (old_pte & H_PAGE_THP_HUGE) return 0;
if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) /* * No CPU has hugepages but lacks no execute, so we * don't need to worry about that case
*/
rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
/* Check if pte already has an hpte (case 2) */ if (unlikely(old_pte & H_PAGE_HASHPTE)) { /* There MIGHT be an HPTE for this pte */ unsignedlong gslot;
/* * No need to use ldarx/stdcx here
*/
*ptep = __pte(new_pte & ~H_PAGE_BUSY); return 0;
} #endif
pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma, unsignedlong addr, pte_t *ptep)
{ unsignedlong pte_val; /* * Clear the _PAGE_PRESENT so that no hardware parallel update is * possible. Also keep the pte_present true so that we don't take * wrong fault.
*/
pte_val = pte_update(vma->vm_mm, addr, ptep,
_PAGE_PRESENT, _PAGE_INVALID, 1);
void __init hugetlbpage_init_defaultsize(void)
{ /* Set default large page size. Currently, we pick 16M or 1M * depending on what is available
*/ if (mmu_psize_defs[MMU_PAGE_16M].shift)
hpage_shift = mmu_psize_defs[MMU_PAGE_16M].shift; elseif (mmu_psize_defs[MMU_PAGE_1M].shift)
hpage_shift = mmu_psize_defs[MMU_PAGE_1M].shift; elseif (mmu_psize_defs[MMU_PAGE_2M].shift)
hpage_shift = mmu_psize_defs[MMU_PAGE_2M].shift;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.0 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.