Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Dec 2011 13:32:30 -0600
From:      Alan Cox <alc@rice.edu>
To:        xen@freebsd.org
Cc:        Alan Cox <alc@cs.rice.edu>
Subject:   PV i386 patch
Message-ID:  <4EEB9CCE.6090701@rice.edu>

next in thread | raw e-mail | index | archive | help
Is anyone here actively working on fixing problems with SMP support 
under PV i386?  While doing some other maintenance on the 
vm_page_alloc() callers in the source tree, I happened to take a look at 
cpu_initialize_context() in mp_machdep.c.  This function is involved in 
bringing up the 2nd, 3rd, etc. CPUs on an SMP system.  I spotted a 
couple obvious errors.  First, the size parameter given to kmem_*() 
functions is expected to be in terms of bytes and not pages.  Second, I 
believe that PV i386 requires PAE to be used.  If so, there are out of 
range accesses to the array m[].

Index: i386/xen/mp_machdep.c
===================================================================
--- i386/xen/mp_machdep.c       (revision 228561)
+++ i386/xen/mp_machdep.c       (working copy)
@@ -810,7 +810,7 @@ cpu_initialize_context(unsigned int cpu)
  {
         /* vcpu_guest_context_t is too large to allocate on the stack.
          * Hence we allocate statically and protect it with a lock */
-       vm_page_t m[4];
+       vm_page_t m[NPGPTD + 2];
         static vcpu_guest_context_t ctxt;
         vm_offset_t boot_stack;
         vm_offset_t newPTD;
@@ -831,8 +831,8 @@ cpu_initialize_context(unsigned int cpu)
                 pmap_zero_page(m[i]);

         }
-       boot_stack = kmem_alloc_nofault(kernel_map, 1);
-       newPTD = kmem_alloc_nofault(kernel_map, NPGPTD);
+       boot_stack = kmem_alloc_nofault(kernel_map, PAGE_SIZE);
+       newPTD = kmem_alloc_nofault(kernel_map, NPGPTD * PAGE_SIZE);
         ma[0] = VM_PAGE_TO_MACH(m[0])|PG_V;

  #ifdef PAE
@@ -854,7 +854,7 @@ cpu_initialize_context(unsigned int cpu)
             nkpt*sizeof(vm_paddr_t));

         pmap_qremove(newPTD, 4);
-       kmem_free(kernel_map, newPTD, 4);
+       kmem_free(kernel_map, newPTD, 4 * PAGE_SIZE);
         /*
          * map actual idle stack to boot_stack
          */




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4EEB9CCE.6090701>