summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2008-07-25 15:01:34 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2008-07-25 15:01:34 +0000
commit9839e44c59e63c413a9faeaae4d0e48a8da2b3a5 (patch)
treee291707b0fd628e3fa4ff7aa73bd6b294a046eeb /sys/arch
parent4488a21781d1010ab7c4833b8ddcc42bb02c2a5f (diff)
In gdt_grow, always map the gdt on the secondary cpus too. This far
we depended on the pageability of the kernel_map to map them which worked most of the time, until we hit the most improbable case - when cpu_switchto wanted to fault in the missing gdt page, which at this moment is Verboten. kettenis@ ok
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/amd64/amd64/gdt.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/sys/arch/amd64/amd64/gdt.c b/sys/arch/amd64/amd64/gdt.c
index 699e8666fa6..0f178eede25 100644
--- a/sys/arch/amd64/amd64/gdt.c
+++ b/sys/arch/amd64/amd64/gdt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gdt.c,v 1.11 2008/06/26 05:42:09 ray Exp $ */
+/* $OpenBSD: gdt.c,v 1.12 2008/07/25 15:01:33 art Exp $ */
/* $NetBSD: gdt.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */
/*-
@@ -206,8 +206,10 @@ gdt_reload_cpu(struct cpu_info *ci)
void
gdt_grow(void)
{
- size_t old_len;
+ CPU_INFO_ITERATOR cii;
+ struct cpu_info *ci;
struct vm_page *pg;
+ size_t old_len;
vaddr_t va;
old_len = gdt_size;
@@ -215,15 +217,18 @@ gdt_grow(void)
gdt_dynavail =
(gdt_size - DYNSEL_START) / sizeof (struct sys_segment_descriptor);
- for (va = (vaddr_t)gdtstore + old_len;
- va < (vaddr_t)gdtstore + gdt_size;
- va += PAGE_SIZE) {
- while ((pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO)) ==
- NULL) {
- uvm_wait("gdt_grow");
+ CPU_INFO_FOREACH(cii, ci) {
+ for (va = (vaddr_t)(ci->ci_gdt) + old_len;
+ va < (vaddr_t)(ci->ci_gdt) + gdt_size;
+ va += PAGE_SIZE) {
+ while ((pg =
+ uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO)) ==
+ NULL) {
+ uvm_wait("gdt_grow");
+ }
+ pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg),
+ VM_PROT_READ | VM_PROT_WRITE);
}
- pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg),
- VM_PROT_READ | VM_PROT_WRITE);
}
}