Commit 722aacb2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'stable/for-linus-3.9-rc6-tag' of...

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.
parents 9baba666 b2222794
...@@ -1748,14 +1748,18 @@ static void *m2v(phys_addr_t maddr) ...@@ -1748,14 +1748,18 @@ static void *m2v(phys_addr_t maddr)
} }
/* Set the page permissions on an identity-mapped pages */ /* 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; unsigned long pfn = __pa(addr) >> PAGE_SHIFT;
pte_t pte = pfn_pte(pfn, prot); 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(); BUG();
} }
static void set_page_prot(void *addr, pgprot_t prot)
{
return set_page_prot_flags(addr, prot, UVMF_NONE);
}
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) 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, ...@@ -1839,12 +1843,12 @@ static void __init check_pt_base(unsigned long *pt_base, unsigned long *pt_end,
unsigned long addr) unsigned long addr)
{ {
if (*pt_base == PFN_DOWN(__pa(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); clear_page((void *)addr);
(*pt_base)++; (*pt_base)++;
} }
if (*pt_end == PFN_DOWN(__pa(addr))) { 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); clear_page((void *)addr);
(*pt_end)--; (*pt_end)--;
} }
......
...@@ -1316,7 +1316,7 @@ static void __xen_evtchn_do_upcall(void) ...@@ -1316,7 +1316,7 @@ static void __xen_evtchn_do_upcall(void)
{ {
int start_word_idx, start_bit_idx; int start_word_idx, start_bit_idx;
int word_idx, bit_idx; int word_idx, bit_idx;
int i; int i, irq;
int cpu = get_cpu(); int cpu = get_cpu();
struct shared_info *s = HYPERVISOR_shared_info; struct shared_info *s = HYPERVISOR_shared_info;
struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
...@@ -1324,6 +1324,8 @@ static void __xen_evtchn_do_upcall(void) ...@@ -1324,6 +1324,8 @@ static void __xen_evtchn_do_upcall(void)
do { do {
xen_ulong_t pending_words; xen_ulong_t pending_words;
xen_ulong_t pending_bits;
struct irq_desc *desc;
vcpu_info->evtchn_upcall_pending = 0; vcpu_info->evtchn_upcall_pending = 0;
...@@ -1335,6 +1337,17 @@ static void __xen_evtchn_do_upcall(void) ...@@ -1335,6 +1337,17 @@ static void __xen_evtchn_do_upcall(void)
* selector flag. xchg_xen_ulong must contain an * selector flag. xchg_xen_ulong must contain an
* appropriate barrier. * 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); pending_words = xchg_xen_ulong(&vcpu_info->evtchn_pending_sel, 0);
start_word_idx = __this_cpu_read(current_word_idx); start_word_idx = __this_cpu_read(current_word_idx);
...@@ -1343,7 +1356,6 @@ static void __xen_evtchn_do_upcall(void) ...@@ -1343,7 +1356,6 @@ static void __xen_evtchn_do_upcall(void)
word_idx = start_word_idx; word_idx = start_word_idx;
for (i = 0; pending_words != 0; i++) { for (i = 0; pending_words != 0; i++) {
xen_ulong_t pending_bits;
xen_ulong_t words; xen_ulong_t words;
words = MASK_LSBS(pending_words, word_idx); words = MASK_LSBS(pending_words, word_idx);
...@@ -1372,8 +1384,7 @@ static void __xen_evtchn_do_upcall(void) ...@@ -1372,8 +1384,7 @@ static void __xen_evtchn_do_upcall(void)
do { do {
xen_ulong_t bits; xen_ulong_t bits;
int port, irq; int port;
struct irq_desc *desc;
bits = MASK_LSBS(pending_bits, bit_idx); bits = MASK_LSBS(pending_bits, bit_idx);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment