From 589d03e93f6cd595f68891e48f0804f2c8f38aae Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:18 +0000 Subject: xen: Use the proper irq functions generic_handler_irq() already tests for !desc so use this instead of generic_handle_irq_desc(). Use irq_get_irq_data() instead of desc->irq_data. Signed-off-by: Thomas Gleixner Reviewed-by: David Vrabel Cc: Peter Zijlstra Cc: Konrad Rzeszutek Wilk Cc: Xen Link: http://lkml.kernel.org/r/20140223212738.222412125@linutronix.de Signed-off-by: Thomas Gleixner --- drivers/xen/events/events_2l.c | 15 ++++----------- drivers/xen/events/events_base.c | 7 ++----- drivers/xen/events/events_fifo.c | 8 ++------ 3 files changed, 8 insertions(+), 22 deletions(-) (limited to 'drivers/xen') diff --git a/drivers/xen/events/events_2l.c b/drivers/xen/events/events_2l.c index d7ff91757307..5db43fc100a4 100644 --- a/drivers/xen/events/events_2l.c +++ b/drivers/xen/events/events_2l.c @@ -166,7 +166,6 @@ static void evtchn_2l_handle_events(unsigned cpu) int start_word_idx, start_bit_idx; int word_idx, bit_idx; int i; - struct irq_desc *desc; struct shared_info *s = HYPERVISOR_shared_info; struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); @@ -176,11 +175,8 @@ static void evtchn_2l_handle_events(unsigned cpu) unsigned int evtchn = evtchn_from_irq(irq); word_idx = evtchn / BITS_PER_LONG; bit_idx = evtchn % BITS_PER_LONG; - if (active_evtchns(cpu, s, word_idx) & (1ULL << bit_idx)) { - desc = irq_to_desc(irq); - if (desc) - generic_handle_irq_desc(irq, desc); - } + if (active_evtchns(cpu, s, word_idx) & (1ULL << bit_idx)) + generic_handle_irq(irq); } /* @@ -245,11 +241,8 @@ static void evtchn_2l_handle_events(unsigned cpu) port = (word_idx * BITS_PER_EVTCHN_WORD) + bit_idx; irq = get_evtchn_to_irq(port); - if (irq != -1) { - desc = irq_to_desc(irq); - if (desc) - generic_handle_irq_desc(irq, desc); - } + if (irq != -1) + generic_handle_irq(irq); bit_idx = (bit_idx + 1) % BITS_PER_EVTCHN_WORD; diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index f4a9e3311297..7fea02c143ba 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -336,9 +336,8 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) BUG_ON(irq == -1); #ifdef CONFIG_SMP - cpumask_copy(irq_to_desc(irq)->irq_data.affinity, cpumask_of(cpu)); + cpumask_copy(irq_get_irq_data(irq)->affinity, cpumask_of(cpu)); #endif - xen_evtchn_port_bind_to_cpu(info, cpu); info->cpu = cpu; @@ -373,10 +372,8 @@ static void xen_irq_init(unsigned irq) { struct irq_info *info; #ifdef CONFIG_SMP - struct irq_desc *desc = irq_to_desc(irq); - /* By default all event channels notify CPU#0. */ - cpumask_copy(desc->irq_data.affinity, cpumask_of(0)); + cpumask_copy(irq_get_irq_data(irq)->affinity, cpumask_of(0)); #endif info = kzalloc(sizeof(*info), GFP_KERNEL); diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c index 1de2a191b395..96109a9972b6 100644 --- a/drivers/xen/events/events_fifo.c +++ b/drivers/xen/events/events_fifo.c @@ -235,14 +235,10 @@ static uint32_t clear_linked(volatile event_word_t *word) static void handle_irq_for_port(unsigned port) { int irq; - struct irq_desc *desc; irq = get_evtchn_to_irq(port); - if (irq != -1) { - desc = irq_to_desc(irq); - if (desc) - generic_handle_irq_desc(irq, desc); - } + if (irq != -1) + generic_handle_irq(irq); } static void consume_one_event(unsigned cpu, -- cgit v1.2.3-59-g8ed1b From 02893afdd310fab8f41f6afbe5233c6609ec19ed Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:20 +0000 Subject: xen: Get rid of the last irq_desc abuse Warn if any PIRQ cannot be bound to an event channel. Remove the check for irq_desc->action. This hypercall never fails in practice so we can emit a warning unconditionally. Remove a check for a valid irq desc. The only caller of xen_destroy_irq() will only do so if the irq was previously fully setup, which means the descriptor has been allocated as well. Signed-off-by: Thomas Gleixner Cc: Peter Zijlstra Cc: Konrad Rzeszutek Wilk Cc: Xen Cc: David Vrabel Link: http://lkml.kernel.org/r/20140223212738.579581220@linutronix.de Signed-off-by: Thomas Gleixner --- drivers/xen/events/events_base.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers/xen') diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index 7fea02c143ba..5dd2ddf634fb 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -487,13 +487,6 @@ static void pirq_query_unmask(int irq) info->u.pirq.flags |= PIRQ_NEEDS_EOI; } -static bool probing_irq(int irq) -{ - struct irq_desc *desc = irq_to_desc(irq); - - return desc && desc->action == NULL; -} - static void eoi_pirq(struct irq_data *data) { int evtchn = evtchn_from_irq(data->irq); @@ -535,8 +528,7 @@ static unsigned int __startup_pirq(unsigned int irq) BIND_PIRQ__WILL_SHARE : 0; rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq); if (rc != 0) { - if (!probing_irq(irq)) - pr_info("Failed to obtain physical IRQ %d\n", irq); + pr_warn("Failed to obtain physical IRQ %d\n", irq); return 0; } evtchn = bind_pirq.port; @@ -769,17 +761,12 @@ error_irq: int xen_destroy_irq(int irq) { - struct irq_desc *desc; struct physdev_unmap_pirq unmap_irq; struct irq_info *info = info_for_irq(irq); int rc = -ENOENT; mutex_lock(&irq_mapping_update_lock); - desc = irq_to_desc(irq); - if (!desc) - goto out; - if (xen_initial_domain()) { unmap_irq.pirq = info->u.pirq.pirq; unmap_irq.domid = info->u.pirq.domid; -- cgit v1.2.3-59-g8ed1b From 99c8b79d3c165f8e2a6247c14bfa1429e7efe51f Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 23 Feb 2014 21:40:21 +0000 Subject: xen: Add proper irq accounting for HYPERCALL vector Signed-off-by: Thomas Gleixner Reviewed-by: David Vrabel Cc: Peter Zijlstra Cc: Konrad Rzeszutek Wilk Cc: Xen Link: http://lkml.kernel.org/r/20140223212738.808648133@linutronix.de Signed-off-by: Thomas Gleixner --- drivers/xen/events/events_base.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/xen') diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index 5dd2ddf634fb..8b91c2561b68 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -1235,6 +1235,7 @@ void xen_evtchn_do_upcall(struct pt_regs *regs) #ifdef CONFIG_X86 exit_idle(); #endif + inc_irq_stat(irq_hv_callback_count); __xen_evtchn_do_upcall(); -- cgit v1.2.3-59-g8ed1b From 753fbd23f5e59ea9dc0cabe0a684d32100a4af02 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 4 Mar 2014 20:43:40 +0000 Subject: xen: Validate online cpus in set_affinity The user space interface does not filter out offline cpus. It merily verifies that the mask contains at least one online cpu. So the selector in the irq chip implementation needs to make sure to pick only an online cpu because otherwise: Offline Core 1 Set affinity to 0xe Selector will pick first set bit, i.e. core 1 Signed-off-by: Thomas Gleixner Reviewed-by: David Vrabel Cc: Peter Zijlstra Cc: Konrad Rzeszutek Wilk Cc: Xen Link: http://lkml.kernel.org/r/20140304203100.978031089@linutronix.de Signed-off-by: Thomas Gleixner --- drivers/xen/events/events_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/xen') diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index 8b91c2561b68..c3458f58de90 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -1324,7 +1324,7 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu) static int set_affinity_irq(struct irq_data *data, const struct cpumask *dest, bool force) { - unsigned tcpu = cpumask_first(dest); + unsigned tcpu = cpumask_first_and(dest, cpu_online_mask); return rebind_irq_to_cpu(data->irq, tcpu); } -- cgit v1.2.3-59-g8ed1b From 09ed3d5ba06137913960f9c9385f71fc384193ab Mon Sep 17 00:00:00 2001 From: Wei Liu Date: Sat, 15 Mar 2014 16:11:47 +0000 Subject: xen/balloon: flush persistent kmaps in correct position Xen balloon driver will update ballooned out pages' P2M entries to point to scratch page for PV guests. In 24f69373e2 ("xen/balloon: don't alloc page while non-preemptible", kmap_flush_unused was moved after updating P2M table. In that case for 32 bit PV guest we might end up with P2M X -----> S (S is mfn of balloon scratch page) M2P Y -----> X (Y is mfn in persistent kmap entry) kmap_flush_unused() iterates through all the PTEs in the kmap address space, using pte_to_page() to obtain the page. If the p2m and the m2p are inconsistent the incorrect page is returned. This will clear page->address on the wrong page which may cause subsequent oopses if that page is currently kmap'ed. Move the flush back between get_page and __set_phys_to_machine to fix this. Signed-off-by: Wei Liu Signed-off-by: David Vrabel Cc: stable@vger.kernel.org # 3.12+ --- drivers/xen/balloon.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'drivers/xen') diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 37d06ea624aa..61a6ac8fa8fc 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -399,11 +399,25 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) state = BP_EAGAIN; break; } + scrub_page(page); - pfn = page_to_pfn(page); - frame_list[i] = pfn_to_mfn(pfn); + frame_list[i] = page_to_pfn(page); + } - scrub_page(page); + /* + * Ensure that ballooned highmem pages don't have kmaps. + * + * Do this before changing the p2m as kmap_flush_unused() + * reads PTEs to obtain pages (and hence needs the original + * p2m entry). + */ + kmap_flush_unused(); + + /* Update direct mapping, invalidate P2M, and add to balloon. */ + for (i = 0; i < nr_pages; i++) { + pfn = frame_list[i]; + frame_list[i] = pfn_to_mfn(pfn); + page = pfn_to_page(pfn); #ifdef CONFIG_XEN_HAVE_PVMMU /* @@ -429,11 +443,9 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) } #endif - balloon_append(pfn_to_page(pfn)); + balloon_append(page); } - /* Ensure that ballooned highmem pages don't have kmaps. */ - kmap_flush_unused(); flush_tlb_all(); set_xen_guest_handle(reservation.extent_start, frame_list); -- cgit v1.2.3-59-g8ed1b