Skip to content

Commit

Permalink
Merge branch 'stable/bug.fixes' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/konrad/xen

* '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
  • Loading branch information
torvalds committed Jun 8, 2011
2 parents 33726bf + f124c6a commit 467701e
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 15 deletions.
12 changes: 6 additions & 6 deletions arch/x86/xen/multicalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,10 @@ struct multicall_space __xen_mc_entry(size_t args)
unsigned argidx = roundup(b->argidx, sizeof(u64));

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

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

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

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

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

if (b->mcidx == 0)
return ret;

if (b->entries[b->mcidx - 1].op != op)
return ret;

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

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

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

Expand Down
18 changes: 9 additions & 9 deletions drivers/xen/events.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,9 @@ int xen_allocate_pirq_gsi(unsigned gsi)
*
* 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.
*
* Shareable implies level triggered, not shareable implies edge
* triggered here.
*/
int xen_bind_pirq_gsi_to_irq(unsigned gsi,
unsigned pirq, int shareable, char *name)
Expand Down Expand Up @@ -664,24 +667,21 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,

pirq_query_unmask(irq);
/* We try to use the handler with the appropriate semantic for the
* type of interrupt: if the interrupt doesn't need an eoi
* (pirq_needs_eoi returns false), we treat it like an edge
* 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.
* type of interrupt: if the interrupt is an edge triggered
* interrupt we use handle_edge_irq.
*
* On the other hand if the interrupt needs an eoi (pirq_needs_eoi
* returns true) we treat it like a level triggered interrupt so we
* use handle_fasteoi_irq like the native code does for this kind of
* On the other hand if the interrupt is level triggered we use
* handle_fasteoi_irq like the native code does for this kind of
* interrupts.
*
* Depending on the Xen version, pirq_needs_eoi might return true
* not only for level triggered interrupts but for edge triggered
* interrupts too. In any case Xen always honors the eoi mechanism,
* not injecting any more pirqs of the same kind if the first one
* hasn't received an eoi yet. Therefore using the fasteoi handler
* is the right choice either way.
*/
if (pirq_needs_eoi(irq))
if (shareable)
irq_set_chip_and_handler_name(irq, &xen_pirq_chip,
handle_fasteoi_irq, name);
else
Expand Down

0 comments on commit 467701e

Please sign in to comment.