aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc
diff options
context:
space:
mode:
authorJohn David Anglin <dave.anglin@bell.net>2013-05-10 19:21:38 -0400
committerHelge Deller <deller@gmx.de>2013-05-11 15:13:04 -0400
commitf0a18819e261afc5fdbd8c5c6f9943123c5461ba (patch)
treed931ef9634976eec903b87de8c2b2dc029918db8 /arch/parisc
parent416821d3d68164909b2cbcf398e4ba0797f5f8a2 (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')
-rw-r--r--arch/parisc/kernel/entry.S155
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
4601: LDCW 0(\tmp),\tmp1
461 cmpib,COND(=) 0,\tmp1,1b
462 nop
4632:
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
1514dbit_spin_20w:
1515 LDCW 0(t0),t1
1516 cmpib,COND(=) 0,t1,dbit_spin_20w
1517 nop
1518
1519dbit_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
1531dbit_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
1550dbit_spin_11:
1551 LDCW 0(t0),t1
1552 cmpib,= 0,t1,dbit_spin_11
1553 nop
1554
1555dbit_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
1573dbit_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
1590dbit_spin_20:
1591 LDCW 0(t0),t1
1592 cmpib,= 0,t1,dbit_spin_20
1593 nop
1594
1595dbit_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
1610dbit_nounlock_20:
1611#endif
1612 1623
1613 rfir 1624 rfir
1614 nop 1625 nop