cregit-Linux how code gets into the kernel

Release 4.14 arch/parisc/mm/hugetlbpage.c

Directory: arch/parisc/mm
// SPDX-License-Identifier: GPL-2.0
/*
 * PARISC64 Huge TLB page support.
 *
 * This parisc implementation is heavily based on the SPARC and x86 code.
 *
 * Copyright (C) 2015 Helge Deller <deller@gmx.de>
 */

#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/sched/mm.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
#include <linux/sysctl.h>

#include <asm/mman.h>
#include <asm/pgalloc.h>
#include <asm/tlb.h>
#include <asm/tlbflush.h>
#include <asm/cacheflush.h>
#include <asm/mmu_context.h>



unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) { struct hstate *h = hstate_file(file); if (len & ~huge_page_mask(h)) return -EINVAL; if (len > TASK_SIZE) return -ENOMEM; if (flags & MAP_FIXED) if (prepare_hugepage_range(file, addr, len)) return -EINVAL; if (addr) addr = ALIGN(addr, huge_page_size(h)); /* we need to make sure the colouring is OK */ return arch_get_unmapped_area(file, addr, len, pgoff, flags); }

Contributors

PersonTokensPropCommitsCommitProp
Helge Deller113100.00%1100.00%
Total113100.00%1100.00%


pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *pte = NULL; /* We must align the address, because our caller will run * set_huge_pte_at() on whatever we return, which writes out * all of the sub-ptes for the hugepage range. So we have * to give it the first such sub-pte. */ addr &= HPAGE_MASK; pgd = pgd_offset(mm, addr); pud = pud_alloc(mm, pgd, addr); if (pud) { pmd = pmd_alloc(mm, pud, addr); if (pmd) pte = pte_alloc_map(mm, pmd, addr); } return pte; }

Contributors

PersonTokensPropCommitsCommitProp
Helge Deller97100.00%1100.00%
Total97100.00%1100.00%


pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *pte = NULL; addr &= HPAGE_MASK; pgd = pgd_offset(mm, addr); if (!pgd_none(*pgd)) { pud = pud_offset(pgd, addr); if (!pud_none(*pud)) { pmd = pmd_offset(pud, addr); if (!pmd_none(*pmd)) pte = pte_offset_map(pmd, addr); } } return pte; }

Contributors

PersonTokensPropCommitsCommitProp
Helge Deller10796.40%150.00%
Punit Agrawal43.60%150.00%
Total111100.00%2100.00%

/* Purge data and instruction TLB entries. Must be called holding * the pa_tlb_lock. The TLB purge instructions are slow on SMP * machines since the purge must be broadcast to all CPUs. */
static inline void purge_tlb_entries_huge(struct mm_struct *mm, unsigned long addr) { int i; /* We may use multiple physical huge pages (e.g. 2x1 MB) to emulate * Linux standard huge pages (e.g. 2 MB) */ BUILD_BUG_ON(REAL_HPAGE_SHIFT > HPAGE_SHIFT); addr &= HPAGE_MASK; addr |= _HUGE_PAGE_SIZE_ENCODING_DEFAULT; for (i = 0; i < (1 << (HPAGE_SHIFT-REAL_HPAGE_SHIFT)); i++) { purge_tlb_entries(mm, addr); addr += (1UL << REAL_HPAGE_SHIFT); } }

Contributors

PersonTokensPropCommitsCommitProp
Helge Deller73100.00%2100.00%
Total73100.00%2100.00%

/* __set_huge_pte_at() must be called holding the pa_tlb_lock. */
static void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t entry) { unsigned long addr_start; int i; addr &= HPAGE_MASK; addr_start = addr; for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { set_pte(ptep, entry); ptep++; addr += PAGE_SIZE; pte_val(entry) += PAGE_SIZE; } purge_tlb_entries_huge(mm, addr_start); }

Contributors

PersonTokensPropCommitsCommitProp
Helge Deller84100.00%2100.00%
Total84100.00%2100.00%


void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t entry) { unsigned long flags; purge_tlb_start(flags); __set_huge_pte_at(mm, addr, ptep, entry); purge_tlb_end(flags); }

Contributors

PersonTokensPropCommitsCommitProp
Helge Deller46100.00%1100.00%
Total46100.00%1100.00%


pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { unsigned long flags; pte_t entry; purge_tlb_start(flags); entry = *ptep; __set_huge_pte_at(mm, addr, ptep, __pte(0)); purge_tlb_end(flags); return entry; }

Contributors

PersonTokensPropCommitsCommitProp
Helge Deller57100.00%2100.00%
Total57100.00%2100.00%


void huge_ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { unsigned long flags; pte_t old_pte; purge_tlb_start(flags); old_pte = *ptep; __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); purge_tlb_end(flags); }

Contributors

PersonTokensPropCommitsCommitProp
Helge Deller54100.00%1100.00%
Total54100.00%1100.00%


int huge_ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte, int dirty) { unsigned long flags; int changed; purge_tlb_start(flags); changed = !pte_same(*ptep, pte); if (changed) { __set_huge_pte_at(vma->vm_mm, addr, ptep, pte); } purge_tlb_end(flags); return changed; }

Contributors

PersonTokensPropCommitsCommitProp
Helge Deller74100.00%1100.00%
Total74100.00%1100.00%


int pmd_huge(pmd_t pmd) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Helge Deller11100.00%1100.00%
Total11100.00%1100.00%


int pud_huge(pud_t pud) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Helge Deller11100.00%1100.00%
Total11100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Helge Deller76398.96%240.00%
Punit Agrawal40.52%120.00%
Ingo Molnar30.39%120.00%
Greg Kroah-Hartman10.13%120.00%
Total771100.00%5100.00%
Directory: arch/parisc/mm
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.