Skip to content

Commit

Permalink
xive: Fix xive reset corrupting EQ allocation bitmap
Browse files Browse the repository at this point in the history
This causes us to hand out the physical processor EQs again to
VPs when KVM uses the XIVE, thus causing loss of host interrupts.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
  • Loading branch information
ozbenh authored and stewartsmith committed Mar 9, 2017
1 parent 0cdfe0b commit 40f50bd
Showing 1 changed file with 21 additions and 6 deletions.
27 changes: 21 additions & 6 deletions hw/xive.c
Original file line number Diff line number Diff line change
Expand Up @@ -3649,6 +3649,7 @@ static void xive_cleanup_cpu_cam(struct cpu_thread *c)
static void xive_reset_one(struct xive *x)
{
struct cpu_thread *c;
bool eq_firmware;
int i = 0;

/* Mask all interrupt sources */
Expand All @@ -3666,15 +3667,29 @@ static void xive_reset_one(struct xive *x)
bitmap_for_each_one(*x->eq_map, MAX_EQ_COUNT >> 3, i) {
struct xive_eq eq0 = {0};
struct xive_eq *eq;
int j;

if (i == 0)
continue;
eq = xive_get_eq(x, i);
if (!eq)
continue;
xive_eqc_cache_update(x, x->block_id,
i, 0, 4, &eq0, false, true);
if (!(eq->w0 & EQ_W0_FIRMWARE))
eq_firmware = false;
for (j = 0; j < 8; j++) {
uint32_t idx = (i << 3) | j;

eq = xive_get_eq(x, idx);
if (!eq)
continue;

/* We need to preserve the firmware bit, otherwise
* we will incorrectly free the EQs that are reserved
* for the physical CPUs
*/
eq0.w0 = eq->w0 & EQ_W0_FIRMWARE;
xive_eqc_cache_update(x, x->block_id,
idx, 0, 4, &eq0, false, true);
if (eq->w0 & EQ_W0_FIRMWARE)
eq_firmware = true;
}
if (!eq_firmware)
bitmap_clr_bit(*x->eq_map, i);
}

Expand Down

0 comments on commit 40f50bd

Please sign in to comment.