pmap.c (033e1e35d38d38a582c4acc72e3745dbaf27ab53) pmap.c (250a44f6a22f43ad95ca119e876370e82f8cefc1)
1/*-
2 * Copyright (c) 1991 Regents of the University of California.
3 * All rights reserved.
4 * Copyright (c) 1994 John S. Dyson
5 * All rights reserved.
6 * Copyright (c) 1994 David Greenman
7 * All rights reserved.
8 * Copyright (c) 2005-2010 Alan L. Cox <alc@cs.rice.edu>

--- 918 unchanged lines hidden (view full) ---

927 *
928 * The kernel page table is exempt because its pm_active field is
929 * immutable. The kernel page table is always active on every
930 * processor.
931 */
932void
933pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
934{
1/*-
2 * Copyright (c) 1991 Regents of the University of California.
3 * All rights reserved.
4 * Copyright (c) 1994 John S. Dyson
5 * All rights reserved.
6 * Copyright (c) 1994 David Greenman
7 * All rights reserved.
8 * Copyright (c) 2005-2010 Alan L. Cox <alc@cs.rice.edu>

--- 918 unchanged lines hidden (view full) ---

927 *
928 * The kernel page table is exempt because its pm_active field is
929 * immutable. The kernel page table is always active on every
930 * processor.
931 */
932void
933pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
934{
935 cpuset_t cpumask, other_cpus;
935 cpuset_t other_cpus;
936 u_int cpuid;
936
937 sched_pin();
938 if (pmap == kernel_pmap || !CPU_CMP(&pmap->pm_active, &all_cpus)) {
939 invlpg(va);
940 smp_invlpg(va);
941 } else {
937
938 sched_pin();
939 if (pmap == kernel_pmap || !CPU_CMP(&pmap->pm_active, &all_cpus)) {
940 invlpg(va);
941 smp_invlpg(va);
942 } else {
942 cpumask = PCPU_GET(cpumask);
943 other_cpus = PCPU_GET(other_cpus);
944 if (CPU_OVERLAP(&pmap->pm_active, &cpumask))
943 cpuid = PCPU_GET(cpuid);
944 other_cpus = all_cpus;
945 CPU_CLR(cpuid, &other_cpus);
946 if (CPU_ISSET(cpuid, &pmap->pm_active))
945 invlpg(va);
946 CPU_AND(&other_cpus, &pmap->pm_active);
947 if (!CPU_EMPTY(&other_cpus))
948 smp_masked_invlpg(other_cpus, va);
949 }
950 sched_unpin();
951}
952
953void
954pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
955{
947 invlpg(va);
948 CPU_AND(&other_cpus, &pmap->pm_active);
949 if (!CPU_EMPTY(&other_cpus))
950 smp_masked_invlpg(other_cpus, va);
951 }
952 sched_unpin();
953}
954
955void
956pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
957{
956 cpuset_t cpumask, other_cpus;
958 cpuset_t other_cpus;
957 vm_offset_t addr;
959 vm_offset_t addr;
960 u_int cpuid;
958
959 sched_pin();
960 if (pmap == kernel_pmap || !CPU_CMP(&pmap->pm_active, &all_cpus)) {
961 for (addr = sva; addr < eva; addr += PAGE_SIZE)
962 invlpg(addr);
963 smp_invlpg_range(sva, eva);
964 } else {
961
962 sched_pin();
963 if (pmap == kernel_pmap || !CPU_CMP(&pmap->pm_active, &all_cpus)) {
964 for (addr = sva; addr < eva; addr += PAGE_SIZE)
965 invlpg(addr);
966 smp_invlpg_range(sva, eva);
967 } else {
965 cpumask = PCPU_GET(cpumask);
966 other_cpus = PCPU_GET(other_cpus);
967 if (CPU_OVERLAP(&pmap->pm_active, &cpumask))
968 cpuid = PCPU_GET(cpuid);
969 other_cpus = all_cpus;
970 CPU_CLR(cpuid, &other_cpus);
971 if (CPU_ISSET(cpuid, &pmap->pm_active))
968 for (addr = sva; addr < eva; addr += PAGE_SIZE)
969 invlpg(addr);
970 CPU_AND(&other_cpus, &pmap->pm_active);
971 if (!CPU_EMPTY(&other_cpus))
972 smp_masked_invlpg_range(other_cpus, sva, eva);
973 }
974 sched_unpin();
975}
976
977void
978pmap_invalidate_all(pmap_t pmap)
979{
972 for (addr = sva; addr < eva; addr += PAGE_SIZE)
973 invlpg(addr);
974 CPU_AND(&other_cpus, &pmap->pm_active);
975 if (!CPU_EMPTY(&other_cpus))
976 smp_masked_invlpg_range(other_cpus, sva, eva);
977 }
978 sched_unpin();
979}
980
981void
982pmap_invalidate_all(pmap_t pmap)
983{
980 cpuset_t cpumask, other_cpus;
984 cpuset_t other_cpus;
985 u_int cpuid;
981
982 sched_pin();
983 if (pmap == kernel_pmap || !CPU_CMP(&pmap->pm_active, &all_cpus)) {
984 invltlb();
985 smp_invltlb();
986 } else {
986
987 sched_pin();
988 if (pmap == kernel_pmap || !CPU_CMP(&pmap->pm_active, &all_cpus)) {
989 invltlb();
990 smp_invltlb();
991 } else {
987 cpumask = PCPU_GET(cpumask);
988 other_cpus = PCPU_GET(other_cpus);
989 if (CPU_OVERLAP(&pmap->pm_active, &cpumask))
992 cpuid = PCPU_GET(cpuid);
993 other_cpus = all_cpus;
994 CPU_CLR(cpuid, &other_cpus);
995 if (CPU_ISSET(cpuid, &pmap->pm_active))
990 invltlb();
991 CPU_AND(&other_cpus, &pmap->pm_active);
992 if (!CPU_EMPTY(&other_cpus))
993 smp_masked_invltlb(other_cpus);
994 }
995 sched_unpin();
996}
997

--- 52 unchanged lines hidden (view full) ---

1050 sched_unpin();
1051}
1052
1053static void
1054pmap_update_pde_teardown(void *arg)
1055{
1056 struct pde_action *act = arg;
1057
996 invltlb();
997 CPU_AND(&other_cpus, &pmap->pm_active);
998 if (!CPU_EMPTY(&other_cpus))
999 smp_masked_invltlb(other_cpus);
1000 }
1001 sched_unpin();
1002}
1003

--- 52 unchanged lines hidden (view full) ---

1056 sched_unpin();
1057}
1058
1059static void
1060pmap_update_pde_teardown(void *arg)
1061{
1062 struct pde_action *act = arg;
1063
1058 sched_pin();
1059 if (CPU_OVERLAP(&act->invalidate, PCPU_PTR(cpumask))) {
1060 sched_unpin();
1064 if (CPU_ISSET(PCPU_GET(cpuid), &act->invalidate))
1061 pmap_update_pde_invalidate(act->va, act->newpde);
1065 pmap_update_pde_invalidate(act->va, act->newpde);
1062 } else
1063 sched_unpin();
1064}
1065
1066/*
1067 * Change the page size for the specified virtual address in a way that
1068 * prevents any possibility of the TLB ever having two entries that map the
1069 * same virtual address using different page sizes. This is the recommended
1070 * workaround for Erratum 383 on AMD Family 10h processors. It prevents a
1071 * machine check exception for a TLB state that is improperly diagnosed as a
1072 * hardware error.
1073 */
1074static void
1075pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde)
1076{
1077 struct pde_action act;
1078 cpuset_t active, cpumask, other_cpus;
1079
1080 sched_pin();
1081 cpumask = PCPU_GET(cpumask);
1066}
1067
1068/*
1069 * Change the page size for the specified virtual address in a way that
1070 * prevents any possibility of the TLB ever having two entries that map the
1071 * same virtual address using different page sizes. This is the recommended
1072 * workaround for Erratum 383 on AMD Family 10h processors. It prevents a
1073 * machine check exception for a TLB state that is improperly diagnosed as a
1074 * hardware error.
1075 */
1076static void
1077pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde)
1078{
1079 struct pde_action act;
1080 cpuset_t active, cpumask, other_cpus;
1081
1082 sched_pin();
1083 cpumask = PCPU_GET(cpumask);
1082 other_cpus = PCPU_GET(other_cpus);
1084 other_cpus = all_cpus;
1085 CPU_CLR(PCPU_GET(cpuid), &other_cpus);
1083 if (pmap == kernel_pmap)
1084 active = all_cpus;
1085 else
1086 active = pmap->pm_active;
1087 if (CPU_OVERLAP(&active, &other_cpus)) {
1088 act.store = cpumask;
1089 act.invalidate = active;
1090 act.va = va;

--- 4174 unchanged lines hidden ---
1086 if (pmap == kernel_pmap)
1087 active = all_cpus;
1088 else
1089 active = pmap->pm_active;
1090 if (CPU_OVERLAP(&active, &other_cpus)) {
1091 act.store = cpumask;
1092 act.invalidate = active;
1093 act.va = va;

--- 4174 unchanged lines hidden ---