]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'upstream/core' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 13 Nov 2010 00:01:55 +0000 (16:01 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 13 Nov 2010 00:01:55 +0000 (16:01 -0800)
* 'upstream/core' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen:
  xen: do not release any memory under 1M in domain 0
  xen: events: do not unmask event channels on resume
  xen: correct size of level2_kernel_pgt

arch/x86/xen/mmu.c
arch/x86/xen/setup.c
drivers/xen/events.c

index c237b810b03ff8871e1291f149b3ca379b2af48c..21ed8d7f75a5aa6fa85970d177979457d6b94d5c 100644 (file)
@@ -2126,7 +2126,7 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
 {
        pmd_t *kernel_pmd;
 
-       level2_kernel_pgt = extend_brk(sizeof(pmd_t *) * PTRS_PER_PMD, PAGE_SIZE);
+       level2_kernel_pgt = 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 +
index b1dbdaa23ecc2a632003382c0c9e4e1d6819e386..769c4b01fa32e11f01e3a77a37d42f4c8ab13207 100644 (file)
@@ -118,16 +118,18 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn,
                                                     const struct e820map *e820)
 {
        phys_addr_t max_addr = PFN_PHYS(max_pfn);
-       phys_addr_t last_end = 0;
+       phys_addr_t last_end = ISA_END_ADDRESS;
        unsigned long released = 0;
        int i;
 
+       /* Free any unused memory above the low 1Mbyte. */
        for (i = 0; i < e820->nr_map && last_end < max_addr; i++) {
                phys_addr_t end = e820->map[i].addr;
                end = min(max_addr, end);
 
-               released += xen_release_chunk(last_end, end);
-               last_end = e820->map[i].addr + e820->map[i].size;
+               if (last_end < end)
+                       released += xen_release_chunk(last_end, end);
+               last_end = max(last_end, e820->map[i].addr + e820->map[i].size);
        }
 
        if (last_end < max_addr)
@@ -164,6 +166,7 @@ char * __init xen_memory_setup(void)
                XENMEM_memory_map;
        rc = HYPERVISOR_memory_op(op, &memmap);
        if (rc == -ENOSYS) {
+               BUG_ON(xen_initial_domain());
                memmap.nr_entries = 1;
                map[0].addr = 0ULL;
                map[0].size = mem_end;
@@ -201,12 +204,13 @@ char * __init xen_memory_setup(void)
        }
 
        /*
-        * Even though this is normal, usable memory under Xen, reserve
-        * ISA memory anyway because too many things think they can poke
+        * In domU, the ISA region is normal, usable memory, but we
+        * reserve ISA memory anyway because too many things poke
         * about in there.
         *
-        * In a dom0 kernel, this region is identity mapped with the
-        * hardware ISA area, so it really is out of bounds.
+        * In Dom0, the host E820 information can leave gaps in the
+        * ISA range, which would cause us to release those pages.  To
+        * avoid this, we unconditionally reserve them here.
         */
        e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS,
                        E820_RESERVED);
index 97612f548a8e821c82821cb84218917dce136d03..321a0c8346e581bc3504ac0891b7b4883d98589c 100644 (file)
@@ -1299,9 +1299,6 @@ static void restore_cpu_virqs(unsigned int cpu)
                evtchn_to_irq[evtchn] = irq;
                irq_info[irq] = mk_virq_info(evtchn, virq);
                bind_evtchn_to_cpu(evtchn, cpu);
-
-               /* Ready for use. */
-               unmask_evtchn(evtchn);
        }
 }
 
@@ -1327,10 +1324,6 @@ static void restore_cpu_ipis(unsigned int cpu)
                evtchn_to_irq[evtchn] = irq;
                irq_info[irq] = mk_ipi_info(evtchn, ipi);
                bind_evtchn_to_cpu(evtchn, cpu);
-
-               /* Ready for use. */
-               unmask_evtchn(evtchn);
-
        }
 }
 
@@ -1390,6 +1383,7 @@ void xen_poll_irq(int irq)
 void xen_irq_resume(void)
 {
        unsigned int cpu, irq, evtchn;
+       struct irq_desc *desc;
 
        init_evtchn_cpu_bindings();
 
@@ -1408,6 +1402,23 @@ void xen_irq_resume(void)
                restore_cpu_virqs(cpu);
                restore_cpu_ipis(cpu);
        }
+
+       /*
+        * Unmask any IRQF_NO_SUSPEND IRQs which are enabled. These
+        * are not handled by the IRQ core.
+        */
+       for_each_irq_desc(irq, desc) {
+               if (!desc->action || !(desc->action->flags & IRQF_NO_SUSPEND))
+                       continue;
+               if (desc->status & IRQ_DISABLED)
+                       continue;
+
+               evtchn = evtchn_from_irq(irq);
+               if (evtchn == -1)
+                       continue;
+
+               unmask_evtchn(evtchn);
+       }
 }
 
 static struct irq_chip xen_dynamic_chip __read_mostly = {