]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 24 Nov 2010 23:35:53 +0000 (08:35 +0900)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 24 Nov 2010 23:35:53 +0000 (08:35 +0900)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
  xen: remove duplicated #include
  xen: x86/32: perform initial startup on initial_page_table

1  2 
arch/x86/xen/enlighten.c
arch/x86/xen/mmu.c
arch/x86/xen/setup.c

diff --combined arch/x86/xen/enlighten.c
index 7250bef7f49eb0105063862443d1a5d9ba1c6118,ff82909801b609e824983a3e43b776fc18a96a5e..02c710bebf7a3d911b639c07e17bb1187fd719eb
@@@ -75,11 -75,6 +75,11 @@@ DEFINE_PER_CPU(struct vcpu_info, xen_vc
  enum xen_domain_type xen_domain_type = XEN_NATIVE;
  EXPORT_SYMBOL_GPL(xen_domain_type);
  
 +unsigned long *machine_to_phys_mapping = (void *)MACH2PHYS_VIRT_START;
 +EXPORT_SYMBOL(machine_to_phys_mapping);
 +unsigned int   machine_to_phys_order;
 +EXPORT_SYMBOL(machine_to_phys_order);
 +
  struct start_info *xen_start_info;
  EXPORT_SYMBOL_GPL(xen_start_info);
  
@@@ -1095,8 -1090,6 +1095,8 @@@ static void __init xen_setup_stackprote
  /* First C function to be called on Xen boot */
  asmlinkage void __init xen_start_kernel(void)
  {
 +      struct physdev_set_iopl set_iopl;
 +      int rc;
        pgd_t *pgd;
  
        if (!xen_start_info)
  
        xen_domain_type = XEN_PV_DOMAIN;
  
 +      xen_setup_machphys_mapping();
 +
        /* Install Xen paravirt ops */
        pv_info = xen_info;
        pv_init_ops = xen_init_ops;
        /* Allocate and initialize top and mid mfn levels for p2m structure */
        xen_build_mfn_list_list();
  
-       init_mm.pgd = pgd;
        /* keep using Xen gdt for now; no urgent need to change it */
  
  #ifdef CONFIG_X86_32
  #else
        pv_info.kernel_rpl = 0;
  #endif
 -
        /* set the limit of our address space */
        xen_reserve_top();
  
 +      /* We used to do this in xen_arch_setup, but that is too late on AMD
 +       * were early_cpu_init (run before ->arch_setup()) calls early_amd_init
 +       * which pokes 0xcf8 port.
 +       */
 +      set_iopl.iopl = 1;
 +      rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
 +      if (rc != 0)
 +              xen_raw_printk("physdev_op failed %d\n", rc);
 +
  #ifdef CONFIG_X86_32
        /* set up basic CPUID stuff */
        cpu_detect(&new_cpu_data);
diff --combined arch/x86/xen/mmu.c
index 790af908284e56424ce3c3b0c851b53eb1443b63,c9cf23e1744004a2cb43f82a2c499fdea696ded3..a1feff9e59b6cb7d7eaa937039884eb7ab6847f5
@@@ -2034,20 -2034,6 +2034,20 @@@ static __init void xen_map_identity_ear
        set_page_prot(pmd, PAGE_KERNEL_RO);
  }
  
 +void __init xen_setup_machphys_mapping(void)
 +{
 +      struct xen_machphys_mapping mapping;
 +      unsigned long machine_to_phys_nr_ents;
 +
 +      if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) {
 +              machine_to_phys_mapping = (unsigned long *)mapping.v_start;
 +              machine_to_phys_nr_ents = mapping.max_mfn + 1;
 +      } else {
 +              machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
 +      }
 +      machine_to_phys_order = fls(machine_to_phys_nr_ents - 1);
 +}
 +
  #ifdef CONFIG_X86_64
  static void convert_pfn_mfn(void *v)
  {
@@@ -2133,44 -2119,83 +2133,83 @@@ __init pgd_t *xen_setup_kernel_pagetabl
        return pgd;
  }
  #else /* !CONFIG_X86_64 */
- static RESERVE_BRK_ARRAY(pmd_t, level2_kernel_pgt, PTRS_PER_PMD);
+ static RESERVE_BRK_ARRAY(pmd_t, initial_kernel_pmd, PTRS_PER_PMD);
+ static RESERVE_BRK_ARRAY(pmd_t, swapper_kernel_pmd, PTRS_PER_PMD);
+ static __init void xen_write_cr3_init(unsigned long cr3)
+ {
+       unsigned long pfn = PFN_DOWN(__pa(swapper_pg_dir));
+       BUG_ON(read_cr3() != __pa(initial_page_table));
+       BUG_ON(cr3 != __pa(swapper_pg_dir));
+       /*
+        * We are switching to swapper_pg_dir for the first time (from
+        * initial_page_table) and therefore need to mark that page
+        * read-only and then pin it.
+        *
+        * Xen disallows sharing of kernel PMDs for PAE
+        * guests. Therefore we must copy the kernel PMD from
+        * initial_page_table into a new kernel PMD to be used in
+        * swapper_pg_dir.
+        */
+       swapper_kernel_pmd =
+               extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE);
+       memcpy(swapper_kernel_pmd, initial_kernel_pmd,
+              sizeof(pmd_t) * PTRS_PER_PMD);
+       swapper_pg_dir[KERNEL_PGD_BOUNDARY] =
+               __pgd(__pa(swapper_kernel_pmd) | _PAGE_PRESENT);
+       set_page_prot(swapper_kernel_pmd, PAGE_KERNEL_RO);
+       set_page_prot(swapper_pg_dir, PAGE_KERNEL_RO);
+       xen_write_cr3(cr3);
+       pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, pfn);
+       pin_pagetable_pfn(MMUEXT_UNPIN_TABLE,
+                         PFN_DOWN(__pa(initial_page_table)));
+       set_page_prot(initial_page_table, PAGE_KERNEL);
+       set_page_prot(initial_kernel_pmd, PAGE_KERNEL);
+       pv_mmu_ops.write_cr3 = &xen_write_cr3;
+ }
  
  __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
                                         unsigned long max_pfn)
  {
        pmd_t *kernel_pmd;
  
-       level2_kernel_pgt = extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE);
+       initial_kernel_pmd =
+               extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE);
  
        max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) +
                                  xen_start_info->nr_pt_frames * PAGE_SIZE +
                                  512*1024);
  
        kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd);
-       memcpy(level2_kernel_pgt, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD);
+       memcpy(initial_kernel_pmd, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD);
  
-       xen_map_identity_early(level2_kernel_pgt, max_pfn);
+       xen_map_identity_early(initial_kernel_pmd, max_pfn);
  
-       memcpy(swapper_pg_dir, pgd, sizeof(pgd_t) * PTRS_PER_PGD);
-       set_pgd(&swapper_pg_dir[KERNEL_PGD_BOUNDARY],
-                       __pgd(__pa(level2_kernel_pgt) | _PAGE_PRESENT));
+       memcpy(initial_page_table, pgd, sizeof(pgd_t) * PTRS_PER_PGD);
+       initial_page_table[KERNEL_PGD_BOUNDARY] =
+               __pgd(__pa(initial_kernel_pmd) | _PAGE_PRESENT);
  
-       set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
-       set_page_prot(swapper_pg_dir, PAGE_KERNEL_RO);
+       set_page_prot(initial_kernel_pmd, PAGE_KERNEL_RO);
+       set_page_prot(initial_page_table, PAGE_KERNEL_RO);
        set_page_prot(empty_zero_page, PAGE_KERNEL_RO);
  
        pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
  
-       xen_write_cr3(__pa(swapper_pg_dir));
-       pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(swapper_pg_dir)));
+       pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE,
+                         PFN_DOWN(__pa(initial_page_table)));
+       xen_write_cr3(__pa(initial_page_table));
  
        memblock_x86_reserve_range(__pa(xen_start_info->pt_base),
                      __pa(xen_start_info->pt_base +
                           xen_start_info->nr_pt_frames * PAGE_SIZE),
                      "XEN PAGETABLES");
  
-       return swapper_pg_dir;
+       return initial_page_table;
  }
  #endif        /* CONFIG_X86_64 */
  
@@@ -2304,7 -2329,11 +2343,11 @@@ static const struct pv_mmu_ops xen_mmu_
        .write_cr2 = xen_write_cr2,
  
        .read_cr3 = xen_read_cr3,
+ #ifdef CONFIG_X86_32
+       .write_cr3 = xen_write_cr3_init,
+ #else
        .write_cr3 = xen_write_cr3,
+ #endif
  
        .flush_tlb_user = xen_flush_tlb,
        .flush_tlb_kernel = xen_flush_tlb,
@@@ -2641,8 -2670,7 +2684,8 @@@ int xen_remap_domain_mfn_range(struct v
  
        prot = __pgprot(pgprot_val(prot) | _PAGE_IOMAP);
  
 -      vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
 +      BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_RESERVED | VM_IO)) ==
 +                              (VM_PFNMAP | VM_RESERVED | VM_IO)));
  
        rmd.mfn = mfn;
        rmd.prot = prot;
diff --combined arch/x86/xen/setup.c
index 38fdffaa71d3347defe9fc871f7cc29acf374d3b,d392486179e7b234849536f3917dfc2c8ff174d7..01afd8a9460765375fe7569bdba0ddcb65089347
@@@ -23,7 -23,6 +23,6 @@@
  #include <xen/interface/callback.h>
  #include <xen/interface/memory.h>
  #include <xen/interface/physdev.h>
- #include <xen/interface/memory.h>
  #include <xen/features.h>
  
  #include "xen-ops.h"
@@@ -248,7 -247,8 +247,7 @@@ char * __init xen_memory_setup(void
        else
                extra_pages = 0;
  
 -      if (!xen_initial_domain())
 -              xen_add_extra_mem(extra_pages);
 +      xen_add_extra_mem(extra_pages);
  
        return "Xen";
  }
@@@ -336,6 -336,9 +335,6 @@@ void __cpuinit xen_enable_syscall(void
  
  void __init xen_arch_setup(void)
  {
 -      struct physdev_set_iopl set_iopl;
 -      int rc;
 -
        xen_panic_handler_init();
  
        HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments);
        xen_enable_sysenter();
        xen_enable_syscall();
  
 -      set_iopl.iopl = 1;
 -      rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
 -      if (rc != 0)
 -              printk(KERN_INFO "physdev_op failed %d\n", rc);
 -
  #ifdef CONFIG_ACPI
        if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
                printk(KERN_INFO "ACPI in unprivileged domain disabled\n");