Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 467701e2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'stable/bug.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
  xen: off by one errors in multicalls.c
  xen: use the trigger info we already have to choose the irq handler
parents 33726bf2 f124c6ae
Loading
Loading
Loading
Loading
+6 −6
Original line number Original line Diff line number Diff line
@@ -189,10 +189,10 @@ struct multicall_space __xen_mc_entry(size_t args)
	unsigned argidx = roundup(b->argidx, sizeof(u64));
	unsigned argidx = roundup(b->argidx, sizeof(u64));


	BUG_ON(preemptible());
	BUG_ON(preemptible());
	BUG_ON(b->argidx > MC_ARGS);
	BUG_ON(b->argidx >= MC_ARGS);


	if (b->mcidx == MC_BATCH ||
	if (b->mcidx == MC_BATCH ||
	    (argidx + args) > MC_ARGS) {
	    (argidx + args) >= MC_ARGS) {
		mc_stats_flush(b->mcidx == MC_BATCH ? FL_SLOTS : FL_ARGS);
		mc_stats_flush(b->mcidx == MC_BATCH ? FL_SLOTS : FL_ARGS);
		xen_mc_flush();
		xen_mc_flush();
		argidx = roundup(b->argidx, sizeof(u64));
		argidx = roundup(b->argidx, sizeof(u64));
@@ -206,7 +206,7 @@ struct multicall_space __xen_mc_entry(size_t args)
	ret.args = &b->args[argidx];
	ret.args = &b->args[argidx];
	b->argidx = argidx + args;
	b->argidx = argidx + args;


	BUG_ON(b->argidx > MC_ARGS);
	BUG_ON(b->argidx >= MC_ARGS);
	return ret;
	return ret;
}
}


@@ -216,7 +216,7 @@ struct multicall_space xen_mc_extend_args(unsigned long op, size_t size)
	struct multicall_space ret = { NULL, NULL };
	struct multicall_space ret = { NULL, NULL };


	BUG_ON(preemptible());
	BUG_ON(preemptible());
	BUG_ON(b->argidx > MC_ARGS);
	BUG_ON(b->argidx >= MC_ARGS);


	if (b->mcidx == 0)
	if (b->mcidx == 0)
		return ret;
		return ret;
@@ -224,14 +224,14 @@ struct multicall_space xen_mc_extend_args(unsigned long op, size_t size)
	if (b->entries[b->mcidx - 1].op != op)
	if (b->entries[b->mcidx - 1].op != op)
		return ret;
		return ret;


	if ((b->argidx + size) > MC_ARGS)
	if ((b->argidx + size) >= MC_ARGS)
		return ret;
		return ret;


	ret.mc = &b->entries[b->mcidx - 1];
	ret.mc = &b->entries[b->mcidx - 1];
	ret.args = &b->args[b->argidx];
	ret.args = &b->args[b->argidx];
	b->argidx += size;
	b->argidx += size;


	BUG_ON(b->argidx > MC_ARGS);
	BUG_ON(b->argidx >= MC_ARGS);
	return ret;
	return ret;
}
}


+9 −9
Original line number Original line Diff line number Diff line
@@ -626,6 +626,9 @@ int xen_allocate_pirq_gsi(unsigned gsi)
 *
 *
 * Note: We don't assign an event channel until the irq actually started
 * Note: We don't assign an event channel until the irq actually started
 * up.  Return an existing irq if we've already got one for the gsi.
 * up.  Return an existing irq if we've already got one for the gsi.
 *
 * Shareable implies level triggered, not shareable implies edge
 * triggered here.
 */
 */
int xen_bind_pirq_gsi_to_irq(unsigned gsi,
int xen_bind_pirq_gsi_to_irq(unsigned gsi,
			     unsigned pirq, int shareable, char *name)
			     unsigned pirq, int shareable, char *name)
@@ -664,16 +667,13 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,


	pirq_query_unmask(irq);
	pirq_query_unmask(irq);
	/* We try to use the handler with the appropriate semantic for the
	/* We try to use the handler with the appropriate semantic for the
	 * type of interrupt: if the interrupt doesn't need an eoi
	 * type of interrupt: if the interrupt is an edge triggered
	 * (pirq_needs_eoi returns false), we treat it like an edge
	 * interrupt we use handle_edge_irq.
	 * triggered interrupt so we use handle_edge_irq.
	 * As a matter of fact this only happens when the corresponding
	 * physical interrupt is edge triggered or an msi.
	 *
	 *
	 * On the other hand if the interrupt needs an eoi (pirq_needs_eoi
	 * On the other hand if the interrupt is level triggered we use
	 * returns true) we treat it like a level triggered interrupt so we
	 * handle_fasteoi_irq like the native code does for this kind of
	 * use handle_fasteoi_irq like the native code does for this kind of
	 * interrupts.
	 * interrupts.
	 *
	 * Depending on the Xen version, pirq_needs_eoi might return true
	 * Depending on the Xen version, pirq_needs_eoi might return true
	 * not only for level triggered interrupts but for edge triggered
	 * not only for level triggered interrupts but for edge triggered
	 * interrupts too. In any case Xen always honors the eoi mechanism,
	 * interrupts too. In any case Xen always honors the eoi mechanism,
@@ -681,7 +681,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
	 * hasn't received an eoi yet. Therefore using the fasteoi handler
	 * hasn't received an eoi yet. Therefore using the fasteoi handler
	 * is the right choice either way.
	 * is the right choice either way.
	 */
	 */
	if (pirq_needs_eoi(irq))
	if (shareable)
		irq_set_chip_and_handler_name(irq, &xen_pirq_chip,
		irq_set_chip_and_handler_name(irq, &xen_pirq_chip,
				handle_fasteoi_irq, name);
				handle_fasteoi_irq, name);
	else
	else