diff options
author | John David Anglin <dave.anglin@bell.net> | 2013-05-10 19:21:38 -0400 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2013-05-11 15:13:04 -0400 |
commit | f0a18819e261afc5fdbd8c5c6f9943123c5461ba (patch) | |
tree | d931ef9634976eec903b87de8c2b2dc029918db8 /arch/parisc/kernel/entry.S | |
parent | 416821d3d68164909b2cbcf398e4ba0797f5f8a2 (diff) |
parisc: fix SMP races when updating PTE and TLB entries in entry.S
Currently, race conditions exist in the handling of TLB interruptions in
entry.S. In particular, dirty bit updates can be lost if an accessed
interruption occurs just after the dirty bit interruption on a different
cpu. Lost dirty bit updates result in user pages not being flushed and
general system instability. This change adds lock and unlock macros to
synchronize all PTE and TLB updates done in entry.S. As a result,
userspace stability is significantly improved.
Signed-off-by: John David Anglin <dave.anglin@bell.net>
Signed-off-by: Helge Deller <deller@gmx.de>
Diffstat (limited to 'arch/parisc/kernel/entry.S')
-rw-r--r-- | arch/parisc/kernel/entry.S | 155 |
1 files changed, 83 insertions, 72 deletions
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 4bb96ad9b0b1..ae27cb6ce19a 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
@@ -452,9 +452,41 @@ | |||
452 | L2_ptep \pgd,\pte,\index,\va,\fault | 452 | L2_ptep \pgd,\pte,\index,\va,\fault |
453 | .endm | 453 | .endm |
454 | 454 | ||
455 | /* Acquire pa_dbit_lock lock. */ | ||
456 | .macro dbit_lock spc,tmp,tmp1 | ||
457 | #ifdef CONFIG_SMP | ||
458 | cmpib,COND(=),n 0,\spc,2f | ||
459 | load32 PA(pa_dbit_lock),\tmp | ||
460 | 1: LDCW 0(\tmp),\tmp1 | ||
461 | cmpib,COND(=) 0,\tmp1,1b | ||
462 | nop | ||
463 | 2: | ||
464 | #endif | ||
465 | .endm | ||
466 | |||
467 | /* Release pa_dbit_lock lock without reloading lock address. */ | ||
468 | .macro dbit_unlock0 spc,tmp | ||
469 | #ifdef CONFIG_SMP | ||
470 | or,COND(=) %r0,\spc,%r0 | ||
471 | stw \spc,0(\tmp) | ||
472 | #endif | ||
473 | .endm | ||
474 | |||
475 | /* Release pa_dbit_lock lock. */ | ||
476 | .macro dbit_unlock1 spc,tmp | ||
477 | #ifdef CONFIG_SMP | ||
478 | load32 PA(pa_dbit_lock),\tmp | ||
479 | dbit_unlock0 \spc,\tmp | ||
480 | #endif | ||
481 | .endm | ||
482 | |||
455 | /* Set the _PAGE_ACCESSED bit of the PTE. Be clever and | 483 | /* Set the _PAGE_ACCESSED bit of the PTE. Be clever and |
456 | * don't needlessly dirty the cache line if it was already set */ | 484 | * don't needlessly dirty the cache line if it was already set */ |
457 | .macro update_ptep ptep,pte,tmp,tmp1 | 485 | .macro update_ptep spc,ptep,pte,tmp,tmp1 |
486 | #ifdef CONFIG_SMP | ||
487 | or,COND(=) %r0,\spc,%r0 | ||
488 | LDREG 0(\ptep),\pte | ||
489 | #endif | ||
458 | ldi _PAGE_ACCESSED,\tmp1 | 490 | ldi _PAGE_ACCESSED,\tmp1 |
459 | or \tmp1,\pte,\tmp | 491 | or \tmp1,\pte,\tmp |
460 | and,COND(<>) \tmp1,\pte,%r0 | 492 | and,COND(<>) \tmp1,\pte,%r0 |
@@ -463,7 +495,11 @@ | |||
463 | 495 | ||
464 | /* Set the dirty bit (and accessed bit). No need to be | 496 | /* Set the dirty bit (and accessed bit). No need to be |
465 | * clever, this is only used from the dirty fault */ | 497 | * clever, this is only used from the dirty fault */ |
466 | .macro update_dirty ptep,pte,tmp | 498 | .macro update_dirty spc,ptep,pte,tmp |
499 | #ifdef CONFIG_SMP | ||
500 | or,COND(=) %r0,\spc,%r0 | ||
501 | LDREG 0(\ptep),\pte | ||
502 | #endif | ||
467 | ldi _PAGE_ACCESSED|_PAGE_DIRTY,\tmp | 503 | ldi _PAGE_ACCESSED|_PAGE_DIRTY,\tmp |
468 | or \tmp,\pte,\pte | 504 | or \tmp,\pte,\pte |
469 | STREG \pte,0(\ptep) | 505 | STREG \pte,0(\ptep) |
@@ -1111,11 +1147,13 @@ dtlb_miss_20w: | |||
1111 | 1147 | ||
1112 | L3_ptep ptp,pte,t0,va,dtlb_check_alias_20w | 1148 | L3_ptep ptp,pte,t0,va,dtlb_check_alias_20w |
1113 | 1149 | ||
1114 | update_ptep ptp,pte,t0,t1 | 1150 | dbit_lock spc,t0,t1 |
1151 | update_ptep spc,ptp,pte,t0,t1 | ||
1115 | 1152 | ||
1116 | make_insert_tlb spc,pte,prot | 1153 | make_insert_tlb spc,pte,prot |
1117 | 1154 | ||
1118 | idtlbt pte,prot | 1155 | idtlbt pte,prot |
1156 | dbit_unlock1 spc,t0 | ||
1119 | 1157 | ||
1120 | rfir | 1158 | rfir |
1121 | nop | 1159 | nop |
@@ -1135,11 +1173,13 @@ nadtlb_miss_20w: | |||
1135 | 1173 | ||
1136 | L3_ptep ptp,pte,t0,va,nadtlb_check_alias_20w | 1174 | L3_ptep ptp,pte,t0,va,nadtlb_check_alias_20w |
1137 | 1175 | ||
1138 | update_ptep ptp,pte,t0,t1 | 1176 | dbit_lock spc,t0,t1 |
1177 | update_ptep spc,ptp,pte,t0,t1 | ||
1139 | 1178 | ||
1140 | make_insert_tlb spc,pte,prot | 1179 | make_insert_tlb spc,pte,prot |
1141 | 1180 | ||
1142 | idtlbt pte,prot | 1181 | idtlbt pte,prot |
1182 | dbit_unlock1 spc,t0 | ||
1143 | 1183 | ||
1144 | rfir | 1184 | rfir |
1145 | nop | 1185 | nop |
@@ -1161,7 +1201,8 @@ dtlb_miss_11: | |||
1161 | 1201 | ||
1162 | L2_ptep ptp,pte,t0,va,dtlb_check_alias_11 | 1202 | L2_ptep ptp,pte,t0,va,dtlb_check_alias_11 |
1163 | 1203 | ||
1164 | update_ptep ptp,pte,t0,t1 | 1204 | dbit_lock spc,t0,t1 |
1205 | update_ptep spc,ptp,pte,t0,t1 | ||
1165 | 1206 | ||
1166 | make_insert_tlb_11 spc,pte,prot | 1207 | make_insert_tlb_11 spc,pte,prot |
1167 | 1208 | ||
@@ -1172,6 +1213,7 @@ dtlb_miss_11: | |||
1172 | idtlbp prot,(%sr1,va) | 1213 | idtlbp prot,(%sr1,va) |
1173 | 1214 | ||
1174 | mtsp t0, %sr1 /* Restore sr1 */ | 1215 | mtsp t0, %sr1 /* Restore sr1 */ |
1216 | dbit_unlock1 spc,t0 | ||
1175 | 1217 | ||
1176 | rfir | 1218 | rfir |
1177 | nop | 1219 | nop |
@@ -1192,7 +1234,8 @@ nadtlb_miss_11: | |||
1192 | 1234 | ||
1193 | L2_ptep ptp,pte,t0,va,nadtlb_check_alias_11 | 1235 | L2_ptep ptp,pte,t0,va,nadtlb_check_alias_11 |
1194 | 1236 | ||
1195 | update_ptep ptp,pte,t0,t1 | 1237 | dbit_lock spc,t0,t1 |
1238 | update_ptep spc,ptp,pte,t0,t1 | ||
1196 | 1239 | ||
1197 | make_insert_tlb_11 spc,pte,prot | 1240 | make_insert_tlb_11 spc,pte,prot |
1198 | 1241 | ||
@@ -1204,6 +1247,7 @@ nadtlb_miss_11: | |||
1204 | idtlbp prot,(%sr1,va) | 1247 | idtlbp prot,(%sr1,va) |
1205 | 1248 | ||
1206 | mtsp t0, %sr1 /* Restore sr1 */ | 1249 | mtsp t0, %sr1 /* Restore sr1 */ |
1250 | dbit_unlock1 spc,t0 | ||
1207 | 1251 | ||
1208 | rfir | 1252 | rfir |
1209 | nop | 1253 | nop |
@@ -1224,13 +1268,15 @@ dtlb_miss_20: | |||
1224 | 1268 | ||
1225 | L2_ptep ptp,pte,t0,va,dtlb_check_alias_20 | 1269 | L2_ptep ptp,pte,t0,va,dtlb_check_alias_20 |
1226 | 1270 | ||
1227 | update_ptep ptp,pte,t0,t1 | 1271 | dbit_lock spc,t0,t1 |
1272 | update_ptep spc,ptp,pte,t0,t1 | ||
1228 | 1273 | ||
1229 | make_insert_tlb spc,pte,prot | 1274 | make_insert_tlb spc,pte,prot |
1230 | 1275 | ||
1231 | f_extend pte,t0 | 1276 | f_extend pte,t0 |
1232 | 1277 | ||
1233 | idtlbt pte,prot | 1278 | idtlbt pte,prot |
1279 | dbit_unlock1 spc,t0 | ||
1234 | 1280 | ||
1235 | rfir | 1281 | rfir |
1236 | nop | 1282 | nop |
@@ -1250,13 +1296,15 @@ nadtlb_miss_20: | |||
1250 | 1296 | ||
1251 | L2_ptep ptp,pte,t0,va,nadtlb_check_alias_20 | 1297 | L2_ptep ptp,pte,t0,va,nadtlb_check_alias_20 |
1252 | 1298 | ||
1253 | update_ptep ptp,pte,t0,t1 | 1299 | dbit_lock spc,t0,t1 |
1300 | update_ptep spc,ptp,pte,t0,t1 | ||
1254 | 1301 | ||
1255 | make_insert_tlb spc,pte,prot | 1302 | make_insert_tlb spc,pte,prot |
1256 | 1303 | ||
1257 | f_extend pte,t0 | 1304 | f_extend pte,t0 |
1258 | 1305 | ||
1259 | idtlbt pte,prot | 1306 | idtlbt pte,prot |
1307 | dbit_unlock1 spc,t0 | ||
1260 | 1308 | ||
1261 | rfir | 1309 | rfir |
1262 | nop | 1310 | nop |
@@ -1357,11 +1405,13 @@ itlb_miss_20w: | |||
1357 | 1405 | ||
1358 | L3_ptep ptp,pte,t0,va,itlb_fault | 1406 | L3_ptep ptp,pte,t0,va,itlb_fault |
1359 | 1407 | ||
1360 | update_ptep ptp,pte,t0,t1 | 1408 | dbit_lock spc,t0,t1 |
1409 | update_ptep spc,ptp,pte,t0,t1 | ||
1361 | 1410 | ||
1362 | make_insert_tlb spc,pte,prot | 1411 | make_insert_tlb spc,pte,prot |
1363 | 1412 | ||
1364 | iitlbt pte,prot | 1413 | iitlbt pte,prot |
1414 | dbit_unlock1 spc,t0 | ||
1365 | 1415 | ||
1366 | rfir | 1416 | rfir |
1367 | nop | 1417 | nop |
@@ -1379,11 +1429,13 @@ naitlb_miss_20w: | |||
1379 | 1429 | ||
1380 | L3_ptep ptp,pte,t0,va,naitlb_check_alias_20w | 1430 | L3_ptep ptp,pte,t0,va,naitlb_check_alias_20w |
1381 | 1431 | ||
1382 | update_ptep ptp,pte,t0,t1 | 1432 | dbit_lock spc,t0,t1 |
1433 | update_ptep spc,ptp,pte,t0,t1 | ||
1383 | 1434 | ||
1384 | make_insert_tlb spc,pte,prot | 1435 | make_insert_tlb spc,pte,prot |
1385 | 1436 | ||
1386 | iitlbt pte,prot | 1437 | iitlbt pte,prot |
1438 | dbit_unlock1 spc,t0 | ||
1387 | 1439 | ||
1388 | rfir | 1440 | rfir |
1389 | nop | 1441 | nop |
@@ -1405,7 +1457,8 @@ itlb_miss_11: | |||
1405 | 1457 | ||
1406 | L2_ptep ptp,pte,t0,va,itlb_fault | 1458 | L2_ptep ptp,pte,t0,va,itlb_fault |
1407 | 1459 | ||
1408 | update_ptep ptp,pte,t0,t1 | 1460 | dbit_lock spc,t0,t1 |
1461 | update_ptep spc,ptp,pte,t0,t1 | ||
1409 | 1462 | ||
1410 | make_insert_tlb_11 spc,pte,prot | 1463 | make_insert_tlb_11 spc,pte,prot |
1411 | 1464 | ||
@@ -1416,6 +1469,7 @@ itlb_miss_11: | |||
1416 | iitlbp prot,(%sr1,va) | 1469 | iitlbp prot,(%sr1,va) |
1417 | 1470 | ||
1418 | mtsp t0, %sr1 /* Restore sr1 */ | 1471 | mtsp t0, %sr1 /* Restore sr1 */ |
1472 | dbit_unlock1 spc,t0 | ||
1419 | 1473 | ||
1420 | rfir | 1474 | rfir |
1421 | nop | 1475 | nop |
@@ -1427,7 +1481,8 @@ naitlb_miss_11: | |||
1427 | 1481 | ||
1428 | L2_ptep ptp,pte,t0,va,naitlb_check_alias_11 | 1482 | L2_ptep ptp,pte,t0,va,naitlb_check_alias_11 |
1429 | 1483 | ||
1430 | update_ptep ptp,pte,t0,t1 | 1484 | dbit_lock spc,t0,t1 |
1485 | update_ptep spc,ptp,pte,t0,t1 | ||
1431 | 1486 | ||
1432 | make_insert_tlb_11 spc,pte,prot | 1487 | make_insert_tlb_11 spc,pte,prot |
1433 | 1488 | ||
@@ -1438,6 +1493,7 @@ naitlb_miss_11: | |||
1438 | iitlbp prot,(%sr1,va) | 1493 | iitlbp prot,(%sr1,va) |
1439 | 1494 | ||
1440 | mtsp t0, %sr1 /* Restore sr1 */ | 1495 | mtsp t0, %sr1 /* Restore sr1 */ |
1496 | dbit_unlock1 spc,t0 | ||
1441 | 1497 | ||
1442 | rfir | 1498 | rfir |
1443 | nop | 1499 | nop |
@@ -1459,13 +1515,15 @@ itlb_miss_20: | |||
1459 | 1515 | ||
1460 | L2_ptep ptp,pte,t0,va,itlb_fault | 1516 | L2_ptep ptp,pte,t0,va,itlb_fault |
1461 | 1517 | ||
1462 | update_ptep ptp,pte,t0,t1 | 1518 | dbit_lock spc,t0,t1 |
1519 | update_ptep spc,ptp,pte,t0,t1 | ||
1463 | 1520 | ||
1464 | make_insert_tlb spc,pte,prot | 1521 | make_insert_tlb spc,pte,prot |
1465 | 1522 | ||
1466 | f_extend pte,t0 | 1523 | f_extend pte,t0 |
1467 | 1524 | ||
1468 | iitlbt pte,prot | 1525 | iitlbt pte,prot |
1526 | dbit_unlock1 spc,t0 | ||
1469 | 1527 | ||
1470 | rfir | 1528 | rfir |
1471 | nop | 1529 | nop |
@@ -1477,13 +1535,15 @@ naitlb_miss_20: | |||
1477 | 1535 | ||
1478 | L2_ptep ptp,pte,t0,va,naitlb_check_alias_20 | 1536 | L2_ptep ptp,pte,t0,va,naitlb_check_alias_20 |
1479 | 1537 | ||
1480 | update_ptep ptp,pte,t0,t1 | 1538 | dbit_lock spc,t0,t1 |
1539 | update_ptep spc,ptp,pte,t0,t1 | ||
1481 | 1540 | ||
1482 | make_insert_tlb spc,pte,prot | 1541 | make_insert_tlb spc,pte,prot |
1483 | 1542 | ||
1484 | f_extend pte,t0 | 1543 | f_extend pte,t0 |
1485 | 1544 | ||
1486 | iitlbt pte,prot | 1545 | iitlbt pte,prot |
1546 | dbit_unlock1 spc,t0 | ||
1487 | 1547 | ||
1488 | rfir | 1548 | rfir |
1489 | nop | 1549 | nop |
@@ -1507,29 +1567,13 @@ dbit_trap_20w: | |||
1507 | 1567 | ||
1508 | L3_ptep ptp,pte,t0,va,dbit_fault | 1568 | L3_ptep ptp,pte,t0,va,dbit_fault |
1509 | 1569 | ||
1510 | #ifdef CONFIG_SMP | 1570 | dbit_lock spc,t0,t1 |
1511 | cmpib,COND(=),n 0,spc,dbit_nolock_20w | 1571 | update_dirty spc,ptp,pte,t1 |
1512 | load32 PA(pa_dbit_lock),t0 | ||
1513 | |||
1514 | dbit_spin_20w: | ||
1515 | LDCW 0(t0),t1 | ||
1516 | cmpib,COND(=) 0,t1,dbit_spin_20w | ||
1517 | nop | ||
1518 | |||
1519 | dbit_nolock_20w: | ||
1520 | #endif | ||
1521 | update_dirty ptp,pte,t1 | ||
1522 | 1572 | ||
1523 | make_insert_tlb spc,pte,prot | 1573 | make_insert_tlb spc,pte,prot |
1524 | 1574 | ||
1525 | idtlbt pte,prot | 1575 | idtlbt pte,prot |
1526 | #ifdef CONFIG_SMP | 1576 | dbit_unlock0 spc,t0 |
1527 | cmpib,COND(=),n 0,spc,dbit_nounlock_20w | ||
1528 | ldi 1,t1 | ||
1529 | stw t1,0(t0) | ||
1530 | |||
1531 | dbit_nounlock_20w: | ||
1532 | #endif | ||
1533 | 1577 | ||
1534 | rfir | 1578 | rfir |
1535 | nop | 1579 | nop |
@@ -1543,18 +1587,8 @@ dbit_trap_11: | |||
1543 | 1587 | ||
1544 | L2_ptep ptp,pte,t0,va,dbit_fault | 1588 | L2_ptep ptp,pte,t0,va,dbit_fault |
1545 | 1589 | ||
1546 | #ifdef CONFIG_SMP | 1590 | dbit_lock spc,t0,t1 |
1547 | cmpib,COND(=),n 0,spc,dbit_nolock_11 | 1591 | update_dirty spc,ptp,pte,t1 |
1548 | load32 PA(pa_dbit_lock),t0 | ||
1549 | |||
1550 | dbit_spin_11: | ||
1551 | LDCW 0(t0),t1 | ||
1552 | cmpib,= 0,t1,dbit_spin_11 | ||
1553 | nop | ||
1554 | |||
1555 | dbit_nolock_11: | ||
1556 | #endif | ||
1557 | update_dirty ptp,pte,t1 | ||
1558 | 1592 | ||
1559 | make_insert_tlb_11 spc,pte,prot | 1593 | make_insert_tlb_11 spc,pte,prot |
1560 | 1594 | ||
@@ -1565,13 +1599,7 @@ dbit_nolock_11: | |||
1565 | idtlbp prot,(%sr1,va) | 1599 | idtlbp prot,(%sr1,va) |
1566 | 1600 | ||
1567 | mtsp t1, %sr1 /* Restore sr1 */ | 1601 | mtsp t1, %sr1 /* Restore sr1 */ |
1568 | #ifdef CONFIG_SMP | 1602 | dbit_unlock0 spc,t0 |
1569 | cmpib,COND(=),n 0,spc,dbit_nounlock_11 | ||
1570 | ldi 1,t1 | ||
1571 | stw t1,0(t0) | ||
1572 | |||
1573 | dbit_nounlock_11: | ||
1574 | #endif | ||
1575 | 1603 | ||
1576 | rfir | 1604 | rfir |
1577 | nop | 1605 | nop |
@@ -1583,32 +1611,15 @@ dbit_trap_20: | |||
1583 | 1611 | ||
1584 | L2_ptep ptp,pte,t0,va,dbit_fault | 1612 | L2_ptep ptp,pte,t0,va,dbit_fault |
1585 | 1613 | ||
1586 | #ifdef CONFIG_SMP | 1614 | dbit_lock spc,t0,t1 |
1587 | cmpib,COND(=),n 0,spc,dbit_nolock_20 | 1615 | update_dirty spc,ptp,pte,t1 |
1588 | load32 PA(pa_dbit_lock),t0 | ||
1589 | |||
1590 | dbit_spin_20: | ||
1591 | LDCW 0(t0),t1 | ||
1592 | cmpib,= 0,t1,dbit_spin_20 | ||
1593 | nop | ||
1594 | |||
1595 | dbit_nolock_20: | ||
1596 | #endif | ||
1597 | update_dirty ptp,pte,t1 | ||
1598 | 1616 | ||
1599 | make_insert_tlb spc,pte,prot | 1617 | make_insert_tlb spc,pte,prot |
1600 | 1618 | ||
1601 | f_extend pte,t1 | 1619 | f_extend pte,t1 |
1602 | 1620 | ||
1603 | idtlbt pte,prot | 1621 | idtlbt pte,prot |
1604 | 1622 | dbit_unlock0 spc,t0 | |
1605 | #ifdef CONFIG_SMP | ||
1606 | cmpib,COND(=),n 0,spc,dbit_nounlock_20 | ||
1607 | ldi 1,t1 | ||
1608 | stw t1,0(t0) | ||
1609 | |||
1610 | dbit_nounlock_20: | ||
1611 | #endif | ||
1612 | 1623 | ||
1613 | rfir | 1624 | rfir |
1614 | nop | 1625 | nop |