diff options
-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 | } |