mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-18 19:16:20 +07:00
Merge branch 'stable/bug.fixes' of git://git.kernel.org/pub/scm/linux/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
This commit is contained in:
commit
467701e286
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user