diff options
author | Paul Mundt <lethal@linux-sh.org> | 2012-05-14 04:46:49 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2012-05-14 04:46:49 -0400 |
commit | fd37e75ed56e3f9ddde15c57a9cbde8256221404 (patch) | |
tree | 6ae537e09c4cfd8f73e2f34d403b7a3a081c60fc /arch/sh/mm/tlbex_64.c | |
parent | 392c3822a6fc247c0708c9e52c0818d1fbc9d7d7 (diff) |
sh64: Set additional fault code values.
The SSR.MD status amongst other things are already made available, which
can be used for encoding a more precise fault code value.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/mm/tlbex_64.c')
-rw-r--r-- | arch/sh/mm/tlbex_64.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/arch/sh/mm/tlbex_64.c b/arch/sh/mm/tlbex_64.c index 24dd4ab33dec..8557548fc53e 100644 --- a/arch/sh/mm/tlbex_64.c +++ b/arch/sh/mm/tlbex_64.c | |||
@@ -108,6 +108,17 @@ static struct expevt_lookup expevt_lookup_table = { | |||
108 | .is_text_access = {1, 1, 0, 0, 0, 0, 0, 0} | 108 | .is_text_access = {1, 1, 0, 0, 0, 0, 0, 0} |
109 | }; | 109 | }; |
110 | 110 | ||
111 | static inline unsigned int | ||
112 | expevt_to_fault_code(unsigned long expevt) | ||
113 | { | ||
114 | if (expevt == 0xa40) | ||
115 | return FAULT_CODE_ITLB; | ||
116 | else if (expevt == 0x060) | ||
117 | return FAULT_CODE_WRITE; | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
111 | /* | 122 | /* |
112 | This routine handles page faults that can be serviced just by refilling a | 123 | This routine handles page faults that can be serviced just by refilling a |
113 | TLB entry from an existing page table entry. (This case represents a very | 124 | TLB entry from an existing page table entry. (This case represents a very |
@@ -123,6 +134,7 @@ do_fast_page_fault(unsigned long long ssr_md, unsigned long long expevt, | |||
123 | unsigned long long protection_flags; | 134 | unsigned long long protection_flags; |
124 | unsigned long long index; | 135 | unsigned long long index; |
125 | unsigned long long expevt4; | 136 | unsigned long long expevt4; |
137 | unsigned int fault_code; | ||
126 | 138 | ||
127 | /* The next few lines implement a way of hashing EXPEVT into a | 139 | /* The next few lines implement a way of hashing EXPEVT into a |
128 | * small array index which can be used to lookup parameters | 140 | * small array index which can be used to lookup parameters |
@@ -139,10 +151,16 @@ do_fast_page_fault(unsigned long long ssr_md, unsigned long long expevt, | |||
139 | index = expevt4 ^ (expevt4 >> 5); | 151 | index = expevt4 ^ (expevt4 >> 5); |
140 | index &= 7; | 152 | index &= 7; |
141 | 153 | ||
154 | fault_code = expevt_to_fault_code(expevt); | ||
155 | |||
142 | protection_flags = expevt_lookup_table.protection_flags[index]; | 156 | protection_flags = expevt_lookup_table.protection_flags[index]; |
143 | 157 | ||
144 | if (expevt_lookup_table.is_text_access[index]) | 158 | if (expevt_lookup_table.is_text_access[index]) |
145 | set_thread_fault_code(FAULT_CODE_ITLB); | 159 | fault_code |= FAULT_CODE_ITLB; |
160 | if (!ssr_md) | ||
161 | fault_code |= FAULT_CODE_USER; | ||
162 | |||
163 | set_thread_fault_code(fault_code); | ||
146 | 164 | ||
147 | return handle_tlbmiss(protection_flags, address); | 165 | return handle_tlbmiss(protection_flags, address); |
148 | } | 166 | } |