|
40 | 40 |
|
41 | 41 | #include "head_32.h"
|
42 | 42 |
|
43 |
| -.macro compare_to_kernel_boundary scratch, addr |
44 |
| -#if CONFIG_TASK_SIZE <= 0x80000000 && MODULES_VADDR >= 0x80000000 |
45 |
| -/* By simply checking Address >= 0x80000000, we know if its a kernel address */ |
46 |
| - not. \scratch, \addr |
47 |
| -#else |
48 |
| - rlwinm \scratch, \addr, 16, 0xfff8 |
49 |
| - cmpli cr0, \scratch, TASK_SIZE@h |
50 |
| -#endif |
51 |
| -.endm |
52 |
| - |
53 | 43 | #define PAGE_SHIFT_512K 19
|
54 | 44 | #define PAGE_SHIFT_8M 23
|
55 | 45 |
|
@@ -237,19 +227,12 @@ instruction_counter:
|
237 | 227 | START_EXCEPTION(INTERRUPT_DATA_TLB_MISS_8xx, DataStoreTLBMiss)
|
238 | 228 | mtspr SPRN_SPRG_SCRATCH2, r10
|
239 | 229 | mtspr SPRN_M_TW, r11
|
240 |
| - mfcr r11 |
241 | 230 |
|
242 | 231 | /* If we are faulting a kernel address, we have to use the
|
243 | 232 | * kernel page tables.
|
244 | 233 | */
|
245 | 234 | mfspr r10, SPRN_MD_EPN
|
246 |
| - compare_to_kernel_boundary r10, r10 |
247 | 235 | mfspr r10, SPRN_M_TWB /* Get level 1 table */
|
248 |
| - blt+ 3f |
249 |
| - rlwinm r10, r10, 0, 20, 31 |
250 |
| - oris r10, r10, (swapper_pg_dir - PAGE_OFFSET)@ha |
251 |
| -3: |
252 |
| - mtcr r11 |
253 | 236 | lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r10) /* Get level 1 entry */
|
254 | 237 |
|
255 | 238 | mtspr SPRN_MD_TWC, r11
|
@@ -321,15 +304,19 @@ instruction_counter:
|
321 | 304 | cmpwi cr1, r11, RPN_PATTERN
|
322 | 305 | beq- cr1, FixupDAR /* must be a buggy dcbX, icbi insn. */
|
323 | 306 | DARFixed:/* Return from dcbx instruction bug workaround */
|
| 307 | + mfspr r11, SPRN_DSISR |
| 308 | + rlwinm r11, r11, 0, DSISR_NOHPTE |
| 309 | + cmpwi cr1, r11, 0 |
| 310 | + beq+ cr1, .Ldtlbie |
| 311 | + mfspr r11, SPRN_DAR |
| 312 | + tlbie r11 |
| 313 | + rlwinm r11, r11, 16, 0xffff |
| 314 | + cmplwi cr1, r11, TASK_SIZE@h |
| 315 | + bge- cr1, FixupPGD |
| 316 | +.Ldtlbie: |
324 | 317 | EXCEPTION_PROLOG_1
|
325 | 318 | /* 0x300 is DataAccess exception, needed by bad_page_fault() */
|
326 | 319 | EXCEPTION_PROLOG_2 INTERRUPT_DATA_STORAGE DataTLBError handle_dar_dsisr=1
|
327 |
| - lwz r4, _DAR(r11) |
328 |
| - lwz r5, _DSISR(r11) |
329 |
| - andis. r10,r5,DSISR_NOHPTE@h |
330 |
| - beq+ .Ldtlbie |
331 |
| - tlbie r4 |
332 |
| -.Ldtlbie: |
333 | 320 | prepare_transfer_to_handler
|
334 | 321 | bl do_page_fault
|
335 | 322 | b interrupt_return
|
@@ -383,6 +370,30 @@ DARFixed:/* Return from dcbx instruction bug workaround */
|
383 | 370 | __HEAD
|
384 | 371 | . = 0x2000
|
385 | 372 |
|
| 373 | +FixupPGD: |
| 374 | + mtspr SPRN_M_TW, r10 |
| 375 | + mfspr r10, SPRN_DAR |
| 376 | + mtspr SPRN_MD_EPN, r10 |
| 377 | + mfspr r11, SPRN_M_TWB /* Get level 1 table */ |
| 378 | + lwz r10, (swapper_pg_dir - PAGE_OFFSET)@l(r11) /* Get the level 1 entry */ |
| 379 | + cmpwi cr1, r10, 0 |
| 380 | + bne cr1, 1f |
| 381 | + |
| 382 | + rlwinm r10, r11, 0, 20, 31 |
| 383 | + oris r10, r10, (swapper_pg_dir - PAGE_OFFSET)@ha |
| 384 | + lwz r10, (swapper_pg_dir - PAGE_OFFSET)@l(r10) /* Get the level 1 entry */ |
| 385 | + cmpwi cr1, r10, 0 |
| 386 | + beq cr1, 1f |
| 387 | + stw r10, (swapper_pg_dir - PAGE_OFFSET)@l(r11) /* Set the level 1 entry */ |
| 388 | + mfspr r10, SPRN_M_TW |
| 389 | + mtcr r10 |
| 390 | + mfspr r10, SPRN_SPRG_SCRATCH0 |
| 391 | + mfspr r11, SPRN_SPRG_SCRATCH1 |
| 392 | + rfi |
| 393 | +1: |
| 394 | + mfspr r10, SPRN_M_TW |
| 395 | + b .Ldtlbie |
| 396 | + |
386 | 397 | /* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
|
387 | 398 | * by decoding the registers used by the dcbx instruction and adding them.
|
388 | 399 | * DAR is set to the calculated address.
|
|
0 commit comments