Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 308078
b: refs/heads/master
c: 621b195
h: refs/heads/master
v: v3
  • Loading branch information
Chris Metcalf committed May 25, 2012
1 parent 45c6ca5 commit fcf8b06
Show file tree
Hide file tree
Showing 16 changed files with 457 additions and 159 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d9ed9faac283a3be73f0e11a2ef49ee55aece4db
refs/heads/master: 621b19551507c8fd9d721f4038509c5bb155a983
8 changes: 8 additions & 0 deletions trunk/arch/tile/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ config NEED_PER_CPU_PAGE_FIRST_CHUNK
config SYS_SUPPORTS_HUGETLBFS
def_bool y

# Support for additional huge page sizes besides HPAGE_SIZE.
# The software support is currently only present in the TILE-Gx
# hypervisor. TILEPro in any case does not support page sizes
# larger than the default HPAGE_SIZE.
config HUGETLB_SUPER_PAGES
depends on HUGETLB_PAGE && TILEGX
def_bool y

config GENERIC_CLOCKEVENTS
def_bool y

Expand Down
21 changes: 21 additions & 0 deletions trunk/arch/tile/include/asm/hugetlb.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,25 @@ static inline void arch_release_hugepage(struct page *page)
{
}

#ifdef CONFIG_HUGETLB_SUPER_PAGES
static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
struct page *page, int writable)
{
size_t pagesize = huge_page_size(hstate_vma(vma));
if (pagesize != PUD_SIZE && pagesize != PMD_SIZE)
entry = pte_mksuper(entry);
return entry;
}
#define arch_make_huge_pte arch_make_huge_pte

/* Sizes to scale up page size for PTEs with HV_PTE_SUPER bit. */
enum {
HUGE_SHIFT_PGDIR = 0,
HUGE_SHIFT_PMD = 1,
HUGE_SHIFT_PAGE = 2,
HUGE_SHIFT_ENTRIES
};
extern int huge_shift[HUGE_SHIFT_ENTRIES];
#endif

#endif /* _ASM_TILE_HUGETLB_H */
5 changes: 2 additions & 3 deletions trunk/arch/tile/include/asm/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ typedef HV_PTE pgprot_t;
/*
* User L2 page tables are managed as one L2 page table per page,
* because we use the page allocator for them. This keeps the allocation
* simple and makes it potentially useful to implement HIGHPTE at some point.
* However, it's also inefficient, since L2 page tables are much smaller
* simple, but it's also inefficient, since L2 page tables are much smaller
* than pages (currently 2KB vs 64KB). So we should revisit this.
*/
typedef struct page *pgtable_t;
Expand Down Expand Up @@ -137,7 +136,7 @@ static inline __attribute_const__ int get_order(unsigned long size)

#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)

#define HUGE_MAX_HSTATE 2
#define HUGE_MAX_HSTATE 6

#ifdef CONFIG_HUGETLB_PAGE
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
Expand Down
12 changes: 6 additions & 6 deletions trunk/arch/tile/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ extern void set_page_homes(void);

#define _PAGE_PRESENT HV_PTE_PRESENT
#define _PAGE_HUGE_PAGE HV_PTE_PAGE
#define _PAGE_SUPER_PAGE HV_PTE_SUPER
#define _PAGE_READABLE HV_PTE_READABLE
#define _PAGE_WRITABLE HV_PTE_WRITABLE
#define _PAGE_EXECUTABLE HV_PTE_EXECUTABLE
Expand All @@ -87,6 +88,7 @@ extern void set_page_homes(void);
#define _PAGE_ALL (\
_PAGE_PRESENT | \
_PAGE_HUGE_PAGE | \
_PAGE_SUPER_PAGE | \
_PAGE_READABLE | \
_PAGE_WRITABLE | \
_PAGE_EXECUTABLE | \
Expand Down Expand Up @@ -197,6 +199,7 @@ static inline void __pte_clear(pte_t *ptep)
#define pte_write hv_pte_get_writable
#define pte_exec hv_pte_get_executable
#define pte_huge hv_pte_get_page
#define pte_super hv_pte_get_super
#define pte_rdprotect hv_pte_clear_readable
#define pte_exprotect hv_pte_clear_executable
#define pte_mkclean hv_pte_clear_dirty
Expand All @@ -209,6 +212,7 @@ static inline void __pte_clear(pte_t *ptep)
#define pte_mkyoung hv_pte_set_accessed
#define pte_mkwrite hv_pte_set_writable
#define pte_mkhuge hv_pte_set_page
#define pte_mksuper hv_pte_set_super

#define pte_special(pte) 0
#define pte_mkspecial(pte) (pte)
Expand Down Expand Up @@ -338,13 +342,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
*/
#define pgd_offset_k(address) pgd_offset(&init_mm, address)

#if defined(CONFIG_HIGHPTE)
extern pte_t *pte_offset_map(pmd_t *, unsigned long address);
#define pte_unmap(pte) kunmap_atomic(pte)
#else
#define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
#define pte_unmap(pte) do { } while (0)
#endif

/* Clear a non-executable kernel PTE and flush it from the TLB. */
#define kpte_clear_flush(ptep, vaddr) \
Expand Down Expand Up @@ -537,7 +536,8 @@ static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address)
/* Support /proc/NN/pgtable API. */
struct seq_file;
int arch_proc_pgtable_show(struct seq_file *m, struct mm_struct *mm,
unsigned long vaddr, pte_t *ptep, void **datap);
unsigned long vaddr, unsigned long pagesize,
pte_t *ptep, void **datap);

#endif /* !__ASSEMBLY__ */

Expand Down
17 changes: 6 additions & 11 deletions trunk/arch/tile/include/asm/tlbflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,11 @@ DECLARE_PER_CPU(int, current_asid);
/* The hypervisor tells us what ASIDs are available to us. */
extern int min_asid, max_asid;

static inline unsigned long hv_page_size(const struct vm_area_struct *vma)
{
return (vma->vm_flags & VM_HUGETLB) ? HPAGE_SIZE : PAGE_SIZE;
}

/* Pass as vma pointer for non-executable mapping, if no vma available. */
#define FLUSH_NONEXEC ((const struct vm_area_struct *)-1UL)
#define FLUSH_NONEXEC ((struct vm_area_struct *)-1UL)

/* Flush a single user page on this cpu. */
static inline void local_flush_tlb_page(const struct vm_area_struct *vma,
static inline void local_flush_tlb_page(struct vm_area_struct *vma,
unsigned long addr,
unsigned long page_size)
{
Expand All @@ -60,7 +55,7 @@ static inline void local_flush_tlb_page(const struct vm_area_struct *vma,
}

/* Flush range of user pages on this cpu. */
static inline void local_flush_tlb_pages(const struct vm_area_struct *vma,
static inline void local_flush_tlb_pages(struct vm_area_struct *vma,
unsigned long addr,
unsigned long page_size,
unsigned long len)
Expand Down Expand Up @@ -117,10 +112,10 @@ extern void flush_tlb_all(void);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
extern void flush_tlb_current_task(void);
extern void flush_tlb_mm(struct mm_struct *);
extern void flush_tlb_page(const struct vm_area_struct *, unsigned long);
extern void flush_tlb_page_mm(const struct vm_area_struct *,
extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
extern void flush_tlb_page_mm(struct vm_area_struct *,
struct mm_struct *, unsigned long);
extern void flush_tlb_range(const struct vm_area_struct *,
extern void flush_tlb_range(struct vm_area_struct *,
unsigned long start, unsigned long end);

#define flush_tlb() flush_tlb_current_task()
Expand Down
70 changes: 67 additions & 3 deletions trunk/arch/tile/include/hv/hypervisor.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,22 @@
#define HV_DEFAULT_PAGE_SIZE_LARGE \
(__HV_SIZE_ONE << HV_LOG2_DEFAULT_PAGE_SIZE_LARGE)

#if CHIP_VA_WIDTH() > 32

/** The log2 of the initial size of jumbo pages, in bytes.
* See HV_DEFAULT_PAGE_SIZE_JUMBO.
*/
#define HV_LOG2_DEFAULT_PAGE_SIZE_JUMBO 32

/** The initial size of jumbo pages, in bytes. This value should
* be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_JUMBO).
* It may also be modified when installing a new context.
*/
#define HV_DEFAULT_PAGE_SIZE_JUMBO \
(__HV_SIZE_ONE << HV_LOG2_DEFAULT_PAGE_SIZE_JUMBO)

#endif

/** The log2 of the granularity at which page tables must be aligned;
* in other words, the CPA for a page table must have this many zero
* bits at the bottom of the address.
Expand Down Expand Up @@ -284,8 +300,11 @@
#define HV_DISPATCH_GET_IPI_PTE 56
#endif

/** hv_set_pte_super_shift */
#define HV_DISPATCH_SET_PTE_SUPER_SHIFT 57

/** One more than the largest dispatch value */
#define _HV_DISPATCH_END 57
#define _HV_DISPATCH_END 58


#ifndef __ASSEMBLER__
Expand Down Expand Up @@ -413,6 +432,11 @@ typedef enum {
*/
HV_SYSCONF_VALID_PAGE_SIZES = 7,

/** The size of jumbo pages, in bytes.
* If no jumbo pages are available, zero will be returned.
*/
HV_SYSCONF_PAGE_SIZE_JUMBO = 8,

} HV_SysconfQuery;

/** Offset to subtract from returned Kelvin temperature to get degrees
Expand Down Expand Up @@ -695,6 +719,29 @@ int hv_install_context(HV_PhysAddr page_table, HV_PTE access, HV_ASID asid,

#ifndef __ASSEMBLER__


/** Set the number of pages ganged together by HV_PTE_SUPER at a
* particular level of the page table.
*
* The current TILE-Gx hardware only supports powers of four
* (i.e. log2_count must be a multiple of two), and the requested
* "super" page size must be less than the span of the next level in
* the page table. The largest size that can be requested is 64GB.
*
* The shift value is initially "0" for all page table levels,
* indicating that the HV_PTE_SUPER bit is effectively ignored.
*
* If you change the count from one non-zero value to another, the
* hypervisor will flush the entire TLB and TSB to avoid confusion.
*
* @param level Page table level (0, 1, or 2)
* @param log2_count Base-2 log of the number of pages to gang together,
* i.e. how much to shift left the base page size for the super page size.
* @return Zero on success, or a hypervisor error code on failure.
*/
int hv_set_pte_super_shift(int level, int log2_count);


/** Value returned from hv_inquire_context(). */
typedef struct
{
Expand Down Expand Up @@ -1891,8 +1938,9 @@ int hv_flush_remote(HV_PhysAddr cache_pa, unsigned long cache_control,
#define HV_PTE_INDEX_USER 10 /**< Page is user-accessible */
#define HV_PTE_INDEX_ACCESSED 11 /**< Page has been accessed */
#define HV_PTE_INDEX_DIRTY 12 /**< Page has been written */
/* Bits 13-15 are reserved for
/* Bits 13-14 are reserved for
future use. */
#define HV_PTE_INDEX_SUPER 15 /**< Pages ganged together for TLB */
#define HV_PTE_INDEX_MODE 16 /**< Page mode; see HV_PTE_MODE_xxx */
#define HV_PTE_MODE_BITS 3 /**< Number of bits in mode */
#define HV_PTE_INDEX_CLIENT2 19 /**< Page client state 2 */
Expand Down Expand Up @@ -1987,7 +2035,10 @@ int hv_flush_remote(HV_PhysAddr cache_pa, unsigned long cache_control,

/** Does this PTE map a page?
*
* If this bit is set in the level-1 page table, the entry should be
* If this bit is set in a level-0 page table, the entry should be
* interpreted as a level-2 page table entry mapping a jumbo page.
*
* If this bit is set in a level-1 page table, the entry should be
* interpreted as a level-2 page table entry mapping a large page.
*
* This bit should not be modified by the client while PRESENT is set, as
Expand All @@ -1997,6 +2048,18 @@ int hv_flush_remote(HV_PhysAddr cache_pa, unsigned long cache_control,
*/
#define HV_PTE_PAGE (__HV_PTE_ONE << HV_PTE_INDEX_PAGE)

/** Does this PTE implicitly reference multiple pages?
*
* If this bit is set in the page table (either in the level-2 page table,
* or in a higher level page table in conjunction with the PAGE bit)
* then the PTE specifies a range of contiguous pages, not a single page.
* The hv_set_pte_super_shift() allows you to specify the count for
* each level of the page table.
*
* Note: this bit is not supported on TILEPro systems.
*/
#define HV_PTE_SUPER (__HV_PTE_ONE << HV_PTE_INDEX_SUPER)

/** Is this a global (non-ASID) mapping?
*
* If this bit is set, the translations established by this PTE will
Expand Down Expand Up @@ -2215,6 +2278,7 @@ hv_pte_clear_##name(HV_PTE pte) \
*/
_HV_BIT(present, PRESENT)
_HV_BIT(page, PAGE)
_HV_BIT(super, SUPER)
_HV_BIT(client0, CLIENT0)
_HV_BIT(client1, CLIENT1)
_HV_BIT(client2, CLIENT2)
Expand Down
3 changes: 2 additions & 1 deletion trunk/arch/tile/kernel/hvglue.lds
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,5 @@ hv_store_mapping = TEXT_OFFSET + 0x106a0;
hv_inquire_realpa = TEXT_OFFSET + 0x106c0;
hv_flush_all = TEXT_OFFSET + 0x106e0;
hv_get_ipi_pte = TEXT_OFFSET + 0x10700;
hv_glue_internals = TEXT_OFFSET + 0x10720;
hv_set_pte_super_shift = TEXT_OFFSET + 0x10720;
hv_glue_internals = TEXT_OFFSET + 0x10740;
1 change: 1 addition & 0 deletions trunk/arch/tile/kernel/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/proc_fs.h>
#include <linux/sysctl.h>
#include <linux/hardirq.h>
#include <linux/hugetlb.h>
#include <linux/mman.h>
#include <asm/unaligned.h>
#include <asm/pgtable.h>
Expand Down
Loading

0 comments on commit fcf8b06

Please sign in to comment.