Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
s390
include
asm
hugetlb.h
Go to the documentation of this file.
1
/*
2
* IBM System z Huge TLB Page Support for Kernel.
3
*
4
* Copyright IBM Corp. 2008
5
* Author(s): Gerald Schaefer <
[email protected]
>
6
*/
7
8
#ifndef _ASM_S390_HUGETLB_H
9
#define _ASM_S390_HUGETLB_H
10
11
#include <asm/page.h>
12
#include <asm/pgtable.h>
13
14
15
#define is_hugepage_only_range(mm, addr, len) 0
16
#define hugetlb_free_pgd_range free_pgd_range
17
18
void
set_huge_pte_at
(
struct
mm_struct
*mm,
unsigned
long
addr
,
19
pte_t
*ptep,
pte_t
pte
);
20
21
/*
22
* If the arch doesn't supply something else, assume that hugepage
23
* size aligned regions are ok without further preparation.
24
*/
25
static
inline
int
prepare_hugepage_range
(
struct
file
*
file
,
26
unsigned
long
addr
,
unsigned
long
len)
27
{
28
if
(len & ~
HPAGE_MASK
)
29
return
-
EINVAL
;
30
if
(addr & ~
HPAGE_MASK
)
31
return
-
EINVAL
;
32
return
0;
33
}
34
35
#define hugetlb_prefault_arch_hook(mm) do { } while (0)
36
#define arch_clear_hugepage_flags(page) do { } while (0)
37
38
int
arch_prepare_hugepage
(
struct
page
*
page
);
39
void
arch_release_hugepage
(
struct
page
*
page
);
40
41
static
inline
pte_t
huge_pte_wrprotect(
pte_t
pte
)
42
{
43
pte_val
(pte) |=
_PAGE_RO
;
44
return
pte
;
45
}
46
47
static
inline
int
huge_pte_none(
pte_t
pte
)
48
{
49
return
(
pte_val
(pte) &
_SEGMENT_ENTRY_INV
) &&
50
!(
pte_val
(pte) &
_SEGMENT_ENTRY_RO
);
51
}
52
53
static
inline
pte_t
huge_ptep_get(
pte_t
*ptep)
54
{
55
pte_t
pte = *ptep;
56
unsigned
long
mask
;
57
58
if
(!
MACHINE_HAS_HPAGE
) {
59
ptep = (
pte_t
*) (
pte_val
(pte) &
_SEGMENT_ENTRY_ORIGIN
);
60
if
(ptep) {
61
mask =
pte_val
(pte) &
62
(
_SEGMENT_ENTRY_INV
|
_SEGMENT_ENTRY_RO
);
63
pte =
pte_mkhuge
(*ptep);
64
pte_val
(pte) |=
mask
;
65
}
66
}
67
return
pte
;
68
}
69
70
static
inline
void
__pmd_csp(
pmd_t
*pmdp)
71
{
72
register
unsigned
long
reg2
asm
(
"2"
) =
pmd_val
(*pmdp);
73
register
unsigned
long
reg3
asm
(
"3"
) =
pmd_val
(*pmdp) |
74
_SEGMENT_ENTRY_INV
;
75
register
unsigned
long
reg4
asm
(
"4"
) = ((
unsigned
long
) pmdp) + 5;
76
77
asm
volatile
(
78
" csp %1,%3"
79
:
"=m"
(*pmdp)
80
:
"d"
(
reg2
),
"d"
(
reg3
),
"d"
(
reg4
),
"m"
(*pmdp) :
"cc"
);
81
}
82
83
static
inline
void
huge_ptep_invalidate(
struct
mm_struct
*mm,
84
unsigned
long
address
,
pte_t
*ptep)
85
{
86
pmd_t
*pmdp = (
pmd_t
*) ptep;
87
88
if
(
MACHINE_HAS_IDTE
)
89
__pmd_idte(address, pmdp);
90
else
91
__pmd_csp(pmdp);
92
pmd_val
(*pmdp) =
_SEGMENT_ENTRY_INV
|
_SEGMENT_ENTRY
;
93
}
94
95
static
inline
pte_t
huge_ptep_get_and_clear(
struct
mm_struct
*mm,
96
unsigned
long
addr,
pte_t
*ptep)
97
{
98
pte_t
pte = huge_ptep_get(ptep);
99
100
huge_ptep_invalidate(mm, addr, ptep);
101
return
pte
;
102
}
103
104
#define huge_ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \
105
({ \
106
int __changed = !pte_same(huge_ptep_get(__ptep), __entry); \
107
if (__changed) { \
108
huge_ptep_invalidate((__vma)->vm_mm, __addr, __ptep); \
109
set_huge_pte_at((__vma)->vm_mm, __addr, __ptep, __entry); \
110
} \
111
__changed; \
112
})
113
114
#define huge_ptep_set_wrprotect(__mm, __addr, __ptep) \
115
({ \
116
pte_t __pte = huge_ptep_get(__ptep); \
117
if (pte_write(__pte)) { \
118
huge_ptep_invalidate(__mm, __addr, __ptep); \
119
set_huge_pte_at(__mm, __addr, __ptep, \
120
huge_pte_wrprotect(__pte)); \
121
} \
122
})
123
124
static
inline
void
huge_ptep_clear_flush(
struct
vm_area_struct
*vma,
125
unsigned
long
address,
pte_t
*ptep)
126
{
127
huge_ptep_invalidate(vma->
vm_mm
, address, ptep);
128
}
129
130
#endif
/* _ASM_S390_HUGETLB_H */
Generated on Thu Jan 10 2013 13:06:10 for Linux Kernel by
1.8.2