| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: pmap.c,v 1.245.6.2 2018/02/27 09:07:33 martin Exp $ */ | | 1 | /* $NetBSD: pmap.c,v 1.245.6.3 2018/03/06 08:45:59 martin Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2008, 2010, 2016, 2017 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2008, 2010, 2016, 2017 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Andrew Doran, and by Maxime Villard. | | 8 | * by Andrew Doran, and by Maxime Villard. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -161,27 +161,27 @@ | | | @@ -161,27 +161,27 @@ |
161 | * Hibler/Jolitz pmap, as modified for FreeBSD by John S. Dyson | | 161 | * Hibler/Jolitz pmap, as modified for FreeBSD by John S. Dyson |
162 | * and David Greenman. | | 162 | * and David Greenman. |
163 | * | | 163 | * |
164 | * [3] the Mach pmap. this pmap, from CMU, seems to have migrated | | 164 | * [3] the Mach pmap. this pmap, from CMU, seems to have migrated |
165 | * between several processors. the VAX version was done by | | 165 | * between several processors. the VAX version was done by |
166 | * Avadis Tevanian, Jr., and Michael Wayne Young. the i386 | | 166 | * Avadis Tevanian, Jr., and Michael Wayne Young. the i386 |
167 | * version was done by Lance Berc, Mike Kupfer, Bob Baron, | | 167 | * version was done by Lance Berc, Mike Kupfer, Bob Baron, |
168 | * David Golub, and Richard Draves. the alpha version was | | 168 | * David Golub, and Richard Draves. the alpha version was |
169 | * done by Alessandro Forin (CMU/Mach) and Chris Demetriou | | 169 | * done by Alessandro Forin (CMU/Mach) and Chris Demetriou |
170 | * (NetBSD/alpha). | | 170 | * (NetBSD/alpha). |
171 | */ | | 171 | */ |
172 | | | 172 | |
173 | #include <sys/cdefs.h> | | 173 | #include <sys/cdefs.h> |
174 | __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.245.6.2 2018/02/27 09:07:33 martin Exp $"); | | 174 | __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.245.6.3 2018/03/06 08:45:59 martin Exp $"); |
175 | | | 175 | |
176 | #include "opt_user_ldt.h" | | 176 | #include "opt_user_ldt.h" |
177 | #include "opt_lockdebug.h" | | 177 | #include "opt_lockdebug.h" |
178 | #include "opt_multiprocessor.h" | | 178 | #include "opt_multiprocessor.h" |
179 | #include "opt_xen.h" | | 179 | #include "opt_xen.h" |
180 | | | 180 | |
181 | #include <sys/param.h> | | 181 | #include <sys/param.h> |
182 | #include <sys/systm.h> | | 182 | #include <sys/systm.h> |
183 | #include <sys/proc.h> | | 183 | #include <sys/proc.h> |
184 | #include <sys/pool.h> | | 184 | #include <sys/pool.h> |
185 | #include <sys/kernel.h> | | 185 | #include <sys/kernel.h> |
186 | #include <sys/atomic.h> | | 186 | #include <sys/atomic.h> |
187 | #include <sys/cpu.h> | | 187 | #include <sys/cpu.h> |
| @@ -1727,28 +1727,28 @@ pmap_vpage_cpu_init(struct cpu_info *ci) | | | @@ -1727,28 +1727,28 @@ pmap_vpage_cpu_init(struct cpu_info *ci) |
1727 | * p v _ e n t r y f u n c t i o n s | | 1727 | * p v _ e n t r y f u n c t i o n s |
1728 | */ | | 1728 | */ |
1729 | | | 1729 | |
1730 | static bool | | 1730 | static bool |
1731 | pmap_pp_needs_pve(struct pmap_page *pp) | | 1731 | pmap_pp_needs_pve(struct pmap_page *pp) |
1732 | { | | 1732 | { |
1733 | | | 1733 | |
1734 | /* | | 1734 | /* |
1735 | * Adding a pv entry for this page only needs to allocate a pv_entry | | 1735 | * Adding a pv entry for this page only needs to allocate a pv_entry |
1736 | * structure if the page already has at least one pv entry, | | 1736 | * structure if the page already has at least one pv entry, |
1737 | * since the first pv entry is stored in the pmap_page. | | 1737 | * since the first pv entry is stored in the pmap_page. |
1738 | */ | | 1738 | */ |
1739 | | | 1739 | |
1740 | return (pp->pp_flags & PP_EMBEDDED) != 0 || | | 1740 | return pp && ((pp->pp_flags & PP_EMBEDDED) != 0 || |
1741 | !LIST_EMPTY(&pp->pp_head.pvh_list); | | 1741 | !LIST_EMPTY(&pp->pp_head.pvh_list)); |
1742 | } | | 1742 | } |
1743 | | | 1743 | |
1744 | /* | | 1744 | /* |
1745 | * pmap_free_pvs: free a list of pv_entrys | | 1745 | * pmap_free_pvs: free a list of pv_entrys |
1746 | */ | | 1746 | */ |
1747 | | | 1747 | |
1748 | static void | | 1748 | static void |
1749 | pmap_free_pvs(struct pv_entry *pve) | | 1749 | pmap_free_pvs(struct pv_entry *pve) |
1750 | { | | 1750 | { |
1751 | struct pv_entry *next; | | 1751 | struct pv_entry *next; |
1752 | | | 1752 | |
1753 | for ( /* null */ ; pve != NULL ; pve = next) { | | 1753 | for ( /* null */ ; pve != NULL ; pve = next) { |
1754 | next = pve->pve_next; | | 1754 | next = pve->pve_next; |
| @@ -4113,27 +4113,27 @@ pmap_enter_ma(struct pmap *pmap, vaddr_t | | | @@ -4113,27 +4113,27 @@ pmap_enter_ma(struct pmap *pmap, vaddr_t |
4113 | npte |= PG_PVLIST; | | 4113 | npte |= PG_PVLIST; |
4114 | } else { | | 4114 | } else { |
4115 | new_pp = NULL; | | 4115 | new_pp = NULL; |
4116 | } | | 4116 | } |
4117 | | | 4117 | |
4118 | /* | | 4118 | /* |
4119 | * Try to get pves now if we might need them. | | 4119 | * Try to get pves now if we might need them. |
4120 | * Keep going even if we fail, since we will not actually need them | | 4120 | * Keep going even if we fail, since we will not actually need them |
4121 | * if we are just changing the permissions on an existing mapping, | | 4121 | * if we are just changing the permissions on an existing mapping, |
4122 | * but we won't know if that's the case until later. | | 4122 | * but we won't know if that's the case until later. |
4123 | */ | | 4123 | */ |
4124 | | | 4124 | |
4125 | bool needpves = pmap_pp_needs_pve(new_pp); | | 4125 | bool needpves = pmap_pp_needs_pve(new_pp); |
4126 | if (new_pp && needpves) { | | 4126 | if (needpves) { |
4127 | new_pve = pool_cache_get(&pmap_pv_cache, PR_NOWAIT); | | 4127 | new_pve = pool_cache_get(&pmap_pv_cache, PR_NOWAIT); |
4128 | new_sparepve = pool_cache_get(&pmap_pv_cache, PR_NOWAIT); | | 4128 | new_sparepve = pool_cache_get(&pmap_pv_cache, PR_NOWAIT); |
4129 | } else { | | 4129 | } else { |
4130 | new_pve = NULL; | | 4130 | new_pve = NULL; |
4131 | new_sparepve = NULL; | | 4131 | new_sparepve = NULL; |
4132 | } | | 4132 | } |
4133 | | | 4133 | |
4134 | kpreempt_disable(); | | 4134 | kpreempt_disable(); |
4135 | pmap_map_ptes(pmap, &pmap2, &ptes, &pdes); /* locks pmap */ | | 4135 | pmap_map_ptes(pmap, &pmap2, &ptes, &pdes); /* locks pmap */ |
4136 | if (pmap == pmap_kernel()) { | | 4136 | if (pmap == pmap_kernel()) { |
4137 | ptp = NULL; | | 4137 | ptp = NULL; |
4138 | } else { | | 4138 | } else { |
4139 | ptp = pmap_get_ptp(pmap, va, pdes, flags); | | 4139 | ptp = pmap_get_ptp(pmap, va, pdes, flags); |