Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/amd64/amd64 The GDT needs to be grown on each CPU, ...



details:   https://anonhg.NetBSD.org/src/rev/73fd2d0c74e9
branches:  trunk
changeset: 347312:73fd2d0c74e9
user:      maxv <maxv%NetBSD.org@localhost>
date:      Sat Aug 20 18:04:04 2016 +0000

description:
The GDT needs to be grown on each CPU, and not just gdtstore (cpu0).
Otherwise, if the caller gets switched to another CPU, the kernel will
end up accessing unallocated memory.

Currently, it never happens. The same is done in i386.

diffstat:

 sys/arch/amd64/amd64/gdt.c |  26 ++++++++++++++++----------
 1 files changed, 16 insertions(+), 10 deletions(-)

diffs (61 lines):

diff -r bafc64b83a16 -r 73fd2d0c74e9 sys/arch/amd64/amd64/gdt.c
--- a/sys/arch/amd64/amd64/gdt.c        Sat Aug 20 17:34:23 2016 +0000
+++ b/sys/arch/amd64/amd64/gdt.c        Sat Aug 20 18:04:04 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: gdt.c,v 1.28 2016/08/20 17:34:23 christos Exp $        */
+/*     $NetBSD: gdt.c,v 1.29 2016/08/20 18:04:04 maxv Exp $    */
 
 /*-
  * Copyright (c) 1996, 1997, 2009 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.28 2016/08/20 17:34:23 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gdt.c,v 1.29 2016/08/20 18:04:04 maxv Exp $");
 
 #include "opt_multiprocessor.h"
 #include "opt_xen.h"
@@ -206,12 +206,14 @@
 #endif
 
 /*
- * Grow or shrink the GDT.
+ * Grow the GDT.
  */
 static void
 gdt_grow(void)
 {
        size_t old_len, new_len;
+       CPU_INFO_ITERATOR cii;
+       struct cpu_info *ci;
        struct vm_page *pg;
        vaddr_t va;
 
@@ -221,15 +223,19 @@
        gdt_dynavail =
            (gdt_size - DYNSEL_START) / sizeof(struct sys_segment_descriptor);
 
-       for (va = (vaddr_t)gdtstore + old_len; va < (vaddr_t)gdtstore + new_len;
-           va += PAGE_SIZE) {
-               while ((pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO)) ==
-                      NULL) {
-                       uvm_wait("gdt_grow");
+       for (CPU_INFO_FOREACH(cii, ci)) {
+               for (va = (vaddr_t)(ci->ci_gdt) + old_len;
+                    va < (vaddr_t)(ci->ci_gdt) + new_len;
+                    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, 0);
                }
-               pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg),
-                   VM_PROT_READ | VM_PROT_WRITE, 0);
        }
+
        pmap_update(pmap_kernel());
 }
 



Home | Main Index | Thread Index | Old Index