* Change the page size for the specified virtual address in a way that * prevents any possibility of the TLB ever having two entries that map the * same virtual address using different page sizes. This is the recommended * workaround for Erratum 383 on AMD Family 10h processors. It prevents a * machine check exception for a TLB state that is improperly diagnosed as a * hardware error. */
| 1366 | * hardware error. |
| 1367 | */ |
| 1368 | static void |
| 1369 | pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde) |
| 1370 | { |
| 1371 | struct pde_action act; |
| 1372 | cpuset_t active, other_cpus; |
| 1373 | u_int cpuid; |
| 1374 | |
| 1375 | sched_pin(); |
| 1376 | cpuid = PCPU_GET(cpuid); |
| 1377 | other_cpus = all_cpus; |
| 1378 | CPU_CLR(cpuid, &other_cpus); |
| 1379 | if (pmap == kernel_pmap) |
| 1380 | active = all_cpus; |
| 1381 | else |
| 1382 | active = pmap->pm_active; |
| 1383 | if (CPU_OVERLAP(&active, &other_cpus)) { |
| 1384 | act.store = cpuid; |
| 1385 | act.invalidate = active; |
| 1386 | act.va = va; |
| 1387 | act.pde = pde; |
| 1388 | act.newpde = newpde; |
| 1389 | CPU_SET(cpuid, &active); |
| 1390 | smp_rendezvous_cpus(active, |
| 1391 | smp_no_rendezvous_barrier, pmap == kernel_pmap ? |
| 1392 | pmap_update_pde_kernel : pmap_update_pde_user, |
| 1393 | pmap_update_pde_teardown, &act); |
| 1394 | } else { |
| 1395 | if (pmap == kernel_pmap) |
| 1396 | pmap_kenter_pde(va, newpde); |
| 1397 | else |
| 1398 | pde_store(pde, newpde); |
| 1399 | if (CPU_ISSET(cpuid, &active)) |
| 1400 | pmap_update_pde_invalidate(va, newpde); |
| 1401 | } |
| 1402 | sched_unpin(); |
| 1403 | } |
| 1404 | #else /* !SMP */ |
| 1405 | /* |
| 1406 | * Normal, non-SMP, 486+ invalidation functions. |
no test coverage detected