Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'stable/for-linus-3.9-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen

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.

+23 -8
+8 -4
arch/x86/xen/mmu.c
··· 1748 1748 } 1749 1749 1750 1750 /* Set the page permissions on an identity-mapped pages */ 1751 - static void set_page_prot(void *addr, pgprot_t prot) 1751 + static void set_page_prot_flags(void *addr, pgprot_t prot, unsigned long flags) 1752 1752 { 1753 1753 unsigned long pfn = __pa(addr) >> PAGE_SHIFT; 1754 1754 pte_t pte = pfn_pte(pfn, prot); 1755 1755 1756 - if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, 0)) 1756 + if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, flags)) 1757 1757 BUG(); 1758 + } 1759 + static void set_page_prot(void *addr, pgprot_t prot) 1760 + { 1761 + return set_page_prot_flags(addr, prot, UVMF_NONE); 1758 1762 } 1759 1763 #ifdef CONFIG_X86_32 1760 1764 static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) ··· 1843 1839 unsigned long addr) 1844 1840 { 1845 1841 if (*pt_base == PFN_DOWN(__pa(addr))) { 1846 - set_page_prot((void *)addr, PAGE_KERNEL); 1842 + set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG); 1847 1843 clear_page((void *)addr); 1848 1844 (*pt_base)++; 1849 1845 } 1850 1846 if (*pt_end == PFN_DOWN(__pa(addr))) { 1851 - set_page_prot((void *)addr, PAGE_KERNEL); 1847 + set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG); 1852 1848 clear_page((void *)addr); 1853 1849 (*pt_end)--; 1854 1850 }
+15 -4
drivers/xen/events.c
··· 1316 1316 { 1317 1317 int start_word_idx, start_bit_idx; 1318 1318 int word_idx, bit_idx; 1319 - int i; 1319 + int i, irq; 1320 1320 int cpu = get_cpu(); 1321 1321 struct shared_info *s = HYPERVISOR_shared_info; 1322 1322 struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); ··· 1324 1324 1325 1325 do { 1326 1326 xen_ulong_t pending_words; 1327 + xen_ulong_t pending_bits; 1328 + struct irq_desc *desc; 1327 1329 1328 1330 vcpu_info->evtchn_upcall_pending = 0; 1329 1331 ··· 1337 1335 * selector flag. xchg_xen_ulong must contain an 1338 1336 * appropriate barrier. 1339 1337 */ 1338 + if ((irq = per_cpu(virq_to_irq, cpu)[VIRQ_TIMER]) != -1) { 1339 + int evtchn = evtchn_from_irq(irq); 1340 + word_idx = evtchn / BITS_PER_LONG; 1341 + pending_bits = evtchn % BITS_PER_LONG; 1342 + if (active_evtchns(cpu, s, word_idx) & (1ULL << pending_bits)) { 1343 + desc = irq_to_desc(irq); 1344 + if (desc) 1345 + generic_handle_irq_desc(irq, desc); 1346 + } 1347 + } 1348 + 1340 1349 pending_words = xchg_xen_ulong(&vcpu_info->evtchn_pending_sel, 0); 1341 1350 1342 1351 start_word_idx = __this_cpu_read(current_word_idx); ··· 1356 1343 word_idx = start_word_idx; 1357 1344 1358 1345 for (i = 0; pending_words != 0; i++) { 1359 - xen_ulong_t pending_bits; 1360 1346 xen_ulong_t words; 1361 1347 1362 1348 words = MASK_LSBS(pending_words, word_idx); ··· 1384 1372 1385 1373 do { 1386 1374 xen_ulong_t bits; 1387 - int port, irq; 1388 - struct irq_desc *desc; 1375 + int port; 1389 1376 1390 1377 bits = MASK_LSBS(pending_bits, bit_idx); 1391 1378