mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
b24413180f
Many source files in the tree are missing licensing information, which makes it harder for compliance tools to determine the correct license. By default all files without license information are under the default license of the kernel, which is GPL version 2. Update the files which contain no license information with the 'GPL-2.0' SPDX license identifier. The SPDX identifier is a legally binding shorthand, which can be used instead of the full boiler plate text. This patch is based on work done by Thomas Gleixner and Kate Stewart and Philippe Ombredanne. How this work was done: Patches were generated and checked against linux-4.14-rc6 for a subset of the use cases: - file had no licensing information it it. - file was a */uapi/* one with no licensing information in it, - file was a */uapi/* one with existing licensing information, Further patches will be generated in subsequent months to fix up cases where non-standard license headers were used, and references to license had to be inferred by heuristics based on keywords. The analysis to determine which SPDX License Identifier to be applied to a file was done in a spreadsheet of side by side results from of the output of two independent scanners (ScanCode & Windriver) producing SPDX tag:value files created by Philippe Ombredanne. Philippe prepared the base worksheet, and did an initial spot review of a few 1000 files. The 4.13 kernel was the starting point of the analysis with 60,537 files assessed. Kate Stewart did a file by file comparison of the scanner results in the spreadsheet to determine which SPDX license identifier(s) to be applied to the file. She confirmed any determination that was not immediately clear with lawyers working with the Linux Foundation. Criteria used to select files for SPDX license identifier tagging was: - Files considered eligible had to be source code files. - Make and config files were included as candidates if they contained >5 lines of source - File already had some variant of a license header in it (even if <5 lines). All documentation files were explicitly excluded. The following heuristics were used to determine which SPDX license identifiers to apply. - when both scanners couldn't find any license traces, file was considered to have no license information in it, and the top level COPYING file license applied. For non */uapi/* files that summary was: SPDX license identifier # files ---------------------------------------------------|------- GPL-2.0 11139 and resulted in the first patch in this series. If that file was a */uapi/* path one, it was "GPL-2.0 WITH Linux-syscall-note" otherwise it was "GPL-2.0". Results of that was: SPDX license identifier # files ---------------------------------------------------|------- GPL-2.0 WITH Linux-syscall-note 930 and resulted in the second patch in this series. - if a file had some form of licensing information in it, and was one of the */uapi/* ones, it was denoted with the Linux-syscall-note if any GPL family license was found in the file or had no licensing in it (per prior point). Results summary: SPDX license identifier # files ---------------------------------------------------|------ GPL-2.0 WITH Linux-syscall-note 270 GPL-2.0+ WITH Linux-syscall-note 169 ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21 ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17 LGPL-2.1+ WITH Linux-syscall-note 15 GPL-1.0+ WITH Linux-syscall-note 14 ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5 LGPL-2.0+ WITH Linux-syscall-note 4 LGPL-2.1 WITH Linux-syscall-note 3 ((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3 ((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1 and that resulted in the third patch in this series. - when the two scanners agreed on the detected license(s), that became the concluded license(s). - when there was disagreement between the two scanners (one detected a license but the other didn't, or they both detected different licenses) a manual inspection of the file occurred. - In most cases a manual inspection of the information in the file resulted in a clear resolution of the license that should apply (and which scanner probably needed to revisit its heuristics). - When it was not immediately clear, the license identifier was confirmed with lawyers working with the Linux Foundation. - If there was any question as to the appropriate license identifier, the file was flagged for further research and to be revisited later in time. In total, over 70 hours of logged manual review was done on the spreadsheet to determine the SPDX license identifiers to apply to the source files by Kate, Philippe, Thomas and, in some cases, confirmation by lawyers working with the Linux Foundation. Kate also obtained a third independent scan of the 4.13 code base from FOSSology, and compared selected files where the other two scanners disagreed against that SPDX file, to see if there was new insights. The Windriver scanner is based on an older version of FOSSology in part, so they are related. Thomas did random spot checks in about 500 files from the spreadsheets for the uapi headers and agreed with SPDX license identifier in the files he inspected. For the non-uapi files Thomas did random spot checks in about 15000 files. In initial set of patches against 4.14-rc6, 3 files were found to have copy/paste license identifier errors, and have been fixed to reflect the correct identifier. Additionally Philippe spent 10 hours this week doing a detailed manual inspection and review of the 12,461 patched files from the initial patch version early this week with: - a full scancode scan run, collecting the matched texts, detected license ids and scores - reviewing anything where there was a license detected (about 500+ files) to ensure that the applied SPDX license was correct - reviewing anything where there was no detection but the patch license was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied SPDX license was correct This produced a worksheet with 20 files needing minor correction. This worksheet was then exported into 3 different .csv files for the different types of files to be modified. These .csv files were then reviewed by Greg. Thomas wrote a script to parse the csv files and add the proper SPDX tag to the file, in the format that the file expected. This script was further refined by Greg based on the output to detect more types of files automatically and to distinguish between header and source .c files (which need different comment types.) Finally Greg ran the script using the .csv files to generate the patches. Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org> Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
298 lines
9.6 KiB
C
298 lines
9.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* CRIS pgtable.h - macros and functions to manipulate page tables.
|
|
*/
|
|
|
|
#ifndef _CRIS_PGTABLE_H
|
|
#define _CRIS_PGTABLE_H
|
|
|
|
#include <asm/page.h>
|
|
#define __ARCH_USE_5LEVEL_HACK
|
|
#include <asm-generic/pgtable-nopmd.h>
|
|
|
|
#ifndef __ASSEMBLY__
|
|
#include <linux/sched/mm.h>
|
|
#include <asm/mmu.h>
|
|
#endif
|
|
#include <arch/pgtable.h>
|
|
|
|
/*
|
|
* The Linux memory management assumes a three-level page table setup. On
|
|
* CRIS, we use that, but "fold" the mid level into the top-level page
|
|
* table. Since the MMU TLB is software loaded through an interrupt, it
|
|
* supports any page table structure, so we could have used a three-level
|
|
* setup, but for the amounts of memory we normally use, a two-level is
|
|
* probably more efficient.
|
|
*
|
|
* This file contains the functions and defines necessary to modify and use
|
|
* the CRIS page table tree.
|
|
*/
|
|
#ifndef __ASSEMBLY__
|
|
extern void paging_init(void);
|
|
#endif
|
|
|
|
/* Certain architectures need to do special things when pte's
|
|
* within a page table are directly modified. Thus, the following
|
|
* hook is made available.
|
|
*/
|
|
#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
|
|
#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
|
|
|
|
/*
|
|
* (pmds are folded into pgds so this doesn't get actually called,
|
|
* but the define is needed for a generic inline function.)
|
|
*/
|
|
#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
|
|
#define set_pgu(pudptr, pudval) (*(pudptr) = pudval)
|
|
|
|
/* PGDIR_SHIFT determines the size of the area a second-level page table can
|
|
* map. It is equal to the page size times the number of PTE's that fit in
|
|
* a PMD page. A PTE is 4-bytes in CRIS. Hence the following number.
|
|
*/
|
|
|
|
#define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-2))
|
|
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
|
|
#define PGDIR_MASK (~(PGDIR_SIZE-1))
|
|
|
|
/*
|
|
* entries per page directory level: we use a two-level, so
|
|
* we don't really have any PMD directory physically.
|
|
* pointers are 4 bytes so we can use the page size and
|
|
* divide it by 4 (shift by 2).
|
|
*/
|
|
#define PTRS_PER_PTE (1UL << (PAGE_SHIFT-2))
|
|
#define PTRS_PER_PGD (1UL << (PAGE_SHIFT-2))
|
|
|
|
/* calculate how many PGD entries a user-level program can use
|
|
* the first mappable virtual address is 0
|
|
* (TASK_SIZE is the maximum virtual address space)
|
|
*/
|
|
|
|
#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
|
|
#define FIRST_USER_ADDRESS 0UL
|
|
|
|
/* zero page used for uninitialized stuff */
|
|
#ifndef __ASSEMBLY__
|
|
extern unsigned long empty_zero_page;
|
|
#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
|
|
#endif
|
|
|
|
/* number of bits that fit into a memory pointer */
|
|
#define BITS_PER_PTR (8*sizeof(unsigned long))
|
|
|
|
/* to align the pointer to a pointer address */
|
|
#define PTR_MASK (~(sizeof(void*)-1))
|
|
|
|
/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
|
|
/* 64-bit machines, beware! SRB. */
|
|
#define SIZEOF_PTR_LOG2 2
|
|
|
|
/* to find an entry in a page-table */
|
|
#define PAGE_PTR(address) \
|
|
((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
|
|
|
|
/* to set the page-dir */
|
|
#define SET_PAGE_DIR(tsk,pgdir)
|
|
|
|
#define pte_none(x) (!pte_val(x))
|
|
#define pte_present(x) (pte_val(x) & _PAGE_PRESENT)
|
|
#define pte_clear(mm,addr,xp) do { pte_val(*(xp)) = 0; } while (0)
|
|
|
|
#define pmd_none(x) (!pmd_val(x))
|
|
/* by removing the _PAGE_KERNEL bit from the comparison, the same pmd_bad
|
|
* works for both _PAGE_TABLE and _KERNPG_TABLE pmd entries.
|
|
*/
|
|
#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_KERNEL)) != _PAGE_TABLE)
|
|
#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
|
|
#define pmd_clear(xp) do { pmd_val(*(xp)) = 0; } while (0)
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
/*
|
|
* The following only work if pte_present() is true.
|
|
* Undefined behaviour if not..
|
|
*/
|
|
|
|
static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
|
|
static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; }
|
|
static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
|
|
static inline int pte_special(pte_t pte) { return 0; }
|
|
|
|
static inline pte_t pte_wrprotect(pte_t pte)
|
|
{
|
|
pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
|
|
return pte;
|
|
}
|
|
|
|
static inline pte_t pte_mkclean(pte_t pte)
|
|
{
|
|
pte_val(pte) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE);
|
|
return pte;
|
|
}
|
|
|
|
static inline pte_t pte_mkold(pte_t pte)
|
|
{
|
|
pte_val(pte) &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ);
|
|
return pte;
|
|
}
|
|
|
|
static inline pte_t pte_mkwrite(pte_t pte)
|
|
{
|
|
pte_val(pte) |= _PAGE_WRITE;
|
|
if (pte_val(pte) & _PAGE_MODIFIED)
|
|
pte_val(pte) |= _PAGE_SILENT_WRITE;
|
|
return pte;
|
|
}
|
|
|
|
static inline pte_t pte_mkdirty(pte_t pte)
|
|
{
|
|
pte_val(pte) |= _PAGE_MODIFIED;
|
|
if (pte_val(pte) & _PAGE_WRITE)
|
|
pte_val(pte) |= _PAGE_SILENT_WRITE;
|
|
return pte;
|
|
}
|
|
|
|
static inline pte_t pte_mkyoung(pte_t pte)
|
|
{
|
|
pte_val(pte) |= _PAGE_ACCESSED;
|
|
if (pte_val(pte) & _PAGE_READ)
|
|
{
|
|
pte_val(pte) |= _PAGE_SILENT_READ;
|
|
if ((pte_val(pte) & (_PAGE_WRITE | _PAGE_MODIFIED)) ==
|
|
(_PAGE_WRITE | _PAGE_MODIFIED))
|
|
pte_val(pte) |= _PAGE_SILENT_WRITE;
|
|
}
|
|
return pte;
|
|
}
|
|
static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
|
|
|
|
/*
|
|
* Conversion functions: convert a page and protection to a page entry,
|
|
* and a page entry and page directory to the page they refer to.
|
|
*/
|
|
|
|
/* What actually goes as arguments to the various functions is less than
|
|
* obvious, but a rule of thumb is that struct page's goes as struct page *,
|
|
* really physical DRAM addresses are unsigned long's, and DRAM "virtual"
|
|
* addresses (the 0xc0xxxxxx's) goes as void *'s.
|
|
*/
|
|
|
|
static inline pte_t __mk_pte(void * page, pgprot_t pgprot)
|
|
{
|
|
pte_t pte;
|
|
/* the PTE needs a physical address */
|
|
pte_val(pte) = __pa(page) | pgprot_val(pgprot);
|
|
return pte;
|
|
}
|
|
|
|
#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot))
|
|
|
|
#define mk_pte_phys(physpage, pgprot) \
|
|
({ \
|
|
pte_t __pte; \
|
|
\
|
|
pte_val(__pte) = (physpage) + pgprot_val(pgprot); \
|
|
__pte; \
|
|
})
|
|
|
|
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
|
{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
|
|
|
|
#define pgprot_noncached(prot) __pgprot((pgprot_val(prot) | _PAGE_NO_CACHE))
|
|
|
|
|
|
/* pte_val refers to a page in the 0x4xxxxxxx physical DRAM interval
|
|
* __pte_page(pte_val) refers to the "virtual" DRAM interval
|
|
* pte_pagenr refers to the page-number counted starting from the virtual DRAM start
|
|
*/
|
|
|
|
static inline unsigned long __pte_page(pte_t pte)
|
|
{
|
|
/* the PTE contains a physical address */
|
|
return (unsigned long)__va(pte_val(pte) & PAGE_MASK);
|
|
}
|
|
|
|
#define pte_pagenr(pte) ((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)
|
|
|
|
/* permanent address of a page */
|
|
|
|
#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
|
|
#define pte_page(pte) (mem_map+pte_pagenr(pte))
|
|
|
|
/* only the pte's themselves need to point to physical DRAM (see above)
|
|
* the pagetable links are purely handled within the kernel SW and thus
|
|
* don't need the __pa and __va transformations.
|
|
*/
|
|
|
|
static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
|
|
{ pmd_val(*pmdp) = _PAGE_TABLE | (unsigned long) ptep; }
|
|
|
|
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
|
|
#define pmd_page_vaddr(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
|
|
|
|
/* to find an entry in a page-table-directory. */
|
|
#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
|
|
|
|
/* to find an entry in a page-table-directory */
|
|
static inline pgd_t * pgd_offset(const struct mm_struct *mm, unsigned long address)
|
|
{
|
|
return mm->pgd + pgd_index(address);
|
|
}
|
|
|
|
/* to find an entry in a kernel page-table-directory */
|
|
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
|
|
|
|
/* Find an entry in the third-level page table.. */
|
|
#define __pte_offset(address) \
|
|
(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
|
|
#define pte_offset_kernel(dir, address) \
|
|
((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address))
|
|
#define pte_offset_map(dir, address) \
|
|
((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
|
|
|
|
#define pte_unmap(pte) do { } while (0)
|
|
#define pte_pfn(x) ((unsigned long)(__va((x).pte)) >> PAGE_SHIFT)
|
|
#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
|
|
|
|
#define pte_ERROR(e) \
|
|
printk("%s:%d: bad pte %p(%08lx).\n", __FILE__, __LINE__, &(e), pte_val(e))
|
|
#define pgd_ERROR(e) \
|
|
printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
|
|
|
|
|
|
extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* defined in head.S */
|
|
|
|
/*
|
|
* CRIS doesn't have any external MMU info: the kernel page
|
|
* tables contain all the necessary information.
|
|
*
|
|
* Actually I am not sure on what this could be used for.
|
|
*/
|
|
static inline void update_mmu_cache(struct vm_area_struct * vma,
|
|
unsigned long address, pte_t *ptep)
|
|
{
|
|
}
|
|
|
|
/* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */
|
|
/* Since the PAGE_PRESENT bit is bit 4, we can use the bits above */
|
|
|
|
#define __swp_type(x) (((x).val >> 5) & 0x7f)
|
|
#define __swp_offset(x) ((x).val >> 12)
|
|
#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 5) | ((offset) << 12) })
|
|
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
|
|
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
|
|
|
|
#define kern_addr_valid(addr) (1)
|
|
|
|
#include <asm-generic/pgtable.h>
|
|
|
|
/*
|
|
* No page table caches to initialise
|
|
*/
|
|
#define pgtable_cache_init() do { } while (0)
|
|
|
|
typedef pte_t *pte_addr_t;
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
#endif /* _CRIS_PGTABLE_H */
|