| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: pmap.c,v 1.157 2012/01/28 08:57:09 cherry Exp $ */ | | 1 | /* $NetBSD: pmap.c,v 1.158 2012/01/29 11:37:08 cherry Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2008, 2010 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. | | 8 | * by Andrew Doran. |
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.157 2012/01/28 08:57:09 cherry Exp $"); | | 174 | __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.158 2012/01/29 11:37:08 cherry 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 | #if !defined(__x86_64__) | | 180 | #if !defined(__x86_64__) |
181 | #include "opt_kstack_dr0.h" | | 181 | #include "opt_kstack_dr0.h" |
182 | #endif /* !defined(__x86_64__) */ | | 182 | #endif /* !defined(__x86_64__) */ |
183 | | | 183 | |
184 | #include <sys/param.h> | | 184 | #include <sys/param.h> |
185 | #include <sys/systm.h> | | 185 | #include <sys/systm.h> |
186 | #include <sys/proc.h> | | 186 | #include <sys/proc.h> |
187 | #include <sys/pool.h> | | 187 | #include <sys/pool.h> |
| @@ -1859,68 +1859,54 @@ pmap_freepage(struct pmap *pmap, struct | | | @@ -1859,68 +1859,54 @@ pmap_freepage(struct pmap *pmap, struct |
1859 | l->l_md.md_gc_ptp = ptp; | | 1859 | l->l_md.md_gc_ptp = ptp; |
1860 | if (lidx != 0) | | 1860 | if (lidx != 0) |
1861 | mutex_exit(obj->vmobjlock); | | 1861 | mutex_exit(obj->vmobjlock); |
1862 | } | | 1862 | } |
1863 | | | 1863 | |
1864 | static void | | 1864 | static void |
1865 | pmap_free_ptp(struct pmap *pmap, struct vm_page *ptp, vaddr_t va, | | 1865 | pmap_free_ptp(struct pmap *pmap, struct vm_page *ptp, vaddr_t va, |
1866 | pt_entry_t *ptes, pd_entry_t * const *pdes) | | 1866 | pt_entry_t *ptes, pd_entry_t * const *pdes) |
1867 | { | | 1867 | { |
1868 | unsigned long index; | | 1868 | unsigned long index; |
1869 | int level; | | 1869 | int level; |
1870 | vaddr_t invaladdr; | | 1870 | vaddr_t invaladdr; |
1871 | pd_entry_t opde; | | 1871 | pd_entry_t opde; |
1872 | #ifdef XEN | | | |
1873 | struct pmap *curpmap = vm_map_pmap(&curlwp->l_proc->p_vmspace->vm_map); | | | |
1874 | #ifdef MULTIPROCESSOR | | | |
1875 | vaddr_t invaladdr2; | | | |
1876 | #endif | | | |
1877 | #endif | | | |
1878 | | | 1872 | |
1879 | KASSERT(pmap != pmap_kernel()); | | 1873 | KASSERT(pmap != pmap_kernel()); |
1880 | KASSERT(mutex_owned(pmap->pm_lock)); | | 1874 | KASSERT(mutex_owned(pmap->pm_lock)); |
1881 | KASSERT(kpreempt_disabled()); | | 1875 | KASSERT(kpreempt_disabled()); |
1882 | | | 1876 | |
1883 | level = 1; | | 1877 | level = 1; |
1884 | do { | | 1878 | do { |
1885 | index = pl_i(va, level + 1); | | 1879 | index = pl_i(va, level + 1); |
1886 | opde = pmap_pte_testset(&pdes[level - 1][index], 0); | | 1880 | opde = pmap_pte_testset(&pdes[level - 1][index], 0); |
1887 | #if defined(XEN) | | 1881 | #if defined(XEN) |
1888 | # if defined(__x86_64__) | | 1882 | # if defined(__x86_64__) |
1889 | /* | | 1883 | /* |
1890 | * If ptp is a L3 currently mapped in kernel space, | | 1884 | * If ptp is a L3 currently mapped in kernel space, |
1891 | * on any cpu, clear it before freeing | | 1885 | * on any cpu, clear it before freeing |
1892 | */ | | 1886 | */ |
1893 | if (level == PTP_LEVELS - 1) { | | 1887 | if (level == PTP_LEVELS - 1) { |
1894 | /* | | 1888 | /* |
1895 | * Update the per-cpu PD on all cpus the current | | 1889 | * Update the per-cpu PD on all cpus the current |
1896 | * pmap is active on | | 1890 | * pmap is active on |
1897 | */ | | 1891 | */ |
1898 | xen_kpm_sync(pmap, index); | | 1892 | xen_kpm_sync(pmap, index); |
1899 | | | 1893 | |
1900 | } | | 1894 | } |
1901 | # endif /*__x86_64__ */ | | 1895 | # endif /*__x86_64__ */ |
1902 | invaladdr = level == 1 ? (vaddr_t)ptes : | | 1896 | invaladdr = level == 1 ? (vaddr_t)ptes : |
1903 | (vaddr_t)pdes[level - 2]; | | 1897 | (vaddr_t)pdes[level - 2]; |
1904 | pmap_tlb_shootdown(curpmap, invaladdr + index * PAGE_SIZE, | | 1898 | pmap_tlb_shootdown(pmap, invaladdr + index * PAGE_SIZE, |
1905 | opde, TLBSHOOT_FREE_PTP1); | | 1899 | opde, TLBSHOOT_FREE_PTP1); |
1906 | # if defined(MULTIPROCESSOR) | | | |
1907 | invaladdr2 = level == 1 ? (vaddr_t)PTE_BASE : | | | |
1908 | (vaddr_t)normal_pdes[level - 2]; | | | |
1909 | if (pmap != curpmap || invaladdr != invaladdr2) { | | | |
1910 | pmap_tlb_shootdown(pmap, invaladdr2 + index * PAGE_SIZE, | | | |
1911 | opde, TLBSHOOT_FREE_PTP2); | | | |
1912 | } | | | |
1913 | # endif /* MULTIPROCESSOR */ | | | |
1914 | #else /* XEN */ | | 1900 | #else /* XEN */ |
1915 | invaladdr = level == 1 ? (vaddr_t)ptes : | | 1901 | invaladdr = level == 1 ? (vaddr_t)ptes : |
1916 | (vaddr_t)pdes[level - 2]; | | 1902 | (vaddr_t)pdes[level - 2]; |
1917 | pmap_tlb_shootdown(pmap, invaladdr + index * PAGE_SIZE, | | 1903 | pmap_tlb_shootdown(pmap, invaladdr + index * PAGE_SIZE, |
1918 | opde, TLBSHOOT_FREE_PTP1); | | 1904 | opde, TLBSHOOT_FREE_PTP1); |
1919 | #endif /* XEN */ | | 1905 | #endif /* XEN */ |
1920 | pmap_freepage(pmap, ptp, level); | | 1906 | pmap_freepage(pmap, ptp, level); |
1921 | if (level < PTP_LEVELS - 1) { | | 1907 | if (level < PTP_LEVELS - 1) { |
1922 | ptp = pmap_find_ptp(pmap, va, (paddr_t)-1, level + 1); | | 1908 | ptp = pmap_find_ptp(pmap, va, (paddr_t)-1, level + 1); |
1923 | ptp->wire_count--; | | 1909 | ptp->wire_count--; |
1924 | if (ptp->wire_count > 1) | | 1910 | if (ptp->wire_count > 1) |
1925 | break; | | 1911 | break; |
1926 | } | | 1912 | } |