Merge tag 'stable/for-linus-3.9-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 10 Apr 2013 22:57:33 +0000 (15:57 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 10 Apr 2013 22:57:33 +0000 (15:57 -0700)
Pull Xen fixes from Konrad Rzeszutek Wilk:
 "Two bug-fixes:
   - Early bootup issue found on DL380 machines
   - Fix for the timer interrupt not being processed right awaym leading
     to quite delayed time skew on certain workloads"

* tag 'stable/for-linus-3.9-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
  xen/mmu: On early bootup, flush the TLB when changing RO->RW bits Xen provided pagetables.
  xen/events: Handle VIRQ_TIMER before any other hardirq in event loop.

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

index 6afbb2c..a4ea924 100644 (file)
@@ -1748,14 +1748,18 @@ static void *m2v(phys_addr_t maddr)
 }
 
 /* Set the page permissions on an identity-mapped pages */
-static void set_page_prot(void *addr, pgprot_t prot)
+static void set_page_prot_flags(void *addr, pgprot_t prot, unsigned long flags)
 {
        unsigned long pfn = __pa(addr) >> PAGE_SHIFT;
        pte_t pte = pfn_pte(pfn, prot);
 
-       if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, 0))
+       if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, flags))
                BUG();
 }
+static void set_page_prot(void *addr, pgprot_t prot)
+{
+       return set_page_prot_flags(addr, prot, UVMF_NONE);
+}
 #ifdef CONFIG_X86_32
 static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
 {
@@ -1839,12 +1843,12 @@ static void __init check_pt_base(unsigned long *pt_base, unsigned long *pt_end,
                                 unsigned long addr)
 {
        if (*pt_base == PFN_DOWN(__pa(addr))) {
-               set_page_prot((void *)addr, PAGE_KERNEL);
+               set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG);
                clear_page((void *)addr);
                (*pt_base)++;
        }
        if (*pt_end == PFN_DOWN(__pa(addr))) {
-               set_page_prot((void *)addr, PAGE_KERNEL);
+               set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG);
                clear_page((void *)addr);
                (*pt_end)--;
        }
index aa85881..2647ad8 100644 (file)
@@ -1316,7 +1316,7 @@ static void __xen_evtchn_do_upcall(void)
 {
        int start_word_idx, start_bit_idx;
        int word_idx, bit_idx;
-       int i;
+       int i, irq;
        int cpu = get_cpu();
        struct shared_info *s = HYPERVISOR_shared_info;
        struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
@@ -1324,6 +1324,8 @@ static void __xen_evtchn_do_upcall(void)
 
        do {
                xen_ulong_t pending_words;
+               xen_ulong_t pending_bits;
+               struct irq_desc *desc;
 
                vcpu_info->evtchn_upcall_pending = 0;
 
@@ -1335,6 +1337,17 @@ static void __xen_evtchn_do_upcall(void)
                 * selector flag. xchg_xen_ulong must contain an
                 * appropriate barrier.
                 */
+               if ((irq = per_cpu(virq_to_irq, cpu)[VIRQ_TIMER]) != -1) {
+                       int evtchn = evtchn_from_irq(irq);
+                       word_idx = evtchn / BITS_PER_LONG;
+                       pending_bits = evtchn % BITS_PER_LONG;
+                       if (active_evtchns(cpu, s, word_idx) & (1ULL << pending_bits)) {
+                               desc = irq_to_desc(irq);
+                               if (desc)
+                                       generic_handle_irq_desc(irq, desc);
+                       }
+               }
+
                pending_words = xchg_xen_ulong(&vcpu_info->evtchn_pending_sel, 0);
 
                start_word_idx = __this_cpu_read(current_word_idx);
@@ -1343,7 +1356,6 @@ static void __xen_evtchn_do_upcall(void)
                word_idx = start_word_idx;
 
                for (i = 0; pending_words != 0; i++) {
-                       xen_ulong_t pending_bits;
                        xen_ulong_t words;
 
                        words = MASK_LSBS(pending_words, word_idx);
@@ -1372,8 +1384,7 @@ static void __xen_evtchn_do_upcall(void)
 
                        do {
                                xen_ulong_t bits;
-                               int port, irq;
-                               struct irq_desc *desc;
+                               int port;
 
                                bits = MASK_LSBS(pending_bits, bit_idx);