hv:use spinlock_irqsave_obtain api for vpic

replace spinlock_obtain/spinlock_release with spinlock_irqsave_obtain
and spinlock_irqrestore_release to avoid dead lock for vpic module.

this vpic lock may be accessed in ISR context like this path:
  dispatch_interrupt->do_softirq->softirq_handlers
  ->ptirq_softirq->ptirq_handle_intx->vpic_set_irqline

Tracked-On: #4958
Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com>
This commit is contained in:
Mingqiang Chi 2020-06-30 21:39:43 +08:00 committed by wenlingz
parent aee4515ff0
commit 7b32fce06f

View File

@ -548,7 +548,6 @@ void vpic_set_irqline(struct acrn_vpic *vpic, uint32_t vgsi, uint32_t operation)
uint32_t pin; uint32_t pin;
uint64_t rflags; uint64_t rflags;
if (vgsi < NR_VPIC_PINS_TOTAL) { if (vgsi < NR_VPIC_PINS_TOTAL) {
i8259 = &vpic->i8259[vgsi >> 3U]; i8259 = &vpic->i8259[vgsi >> 3U];
@ -619,10 +618,11 @@ void vpic_pending_intr(struct acrn_vpic *vpic, uint32_t *vecptr)
{ {
struct i8259_reg_state *i8259; struct i8259_reg_state *i8259;
uint32_t pin; uint32_t pin;
uint64_t rflags;
i8259 = &vpic->i8259[0]; i8259 = &vpic->i8259[0];
spinlock_obtain(&(vpic->lock)); spinlock_irqsave_obtain(&(vpic->lock), &rflags);
pin = vpic_get_highest_irrpin(i8259); pin = vpic_get_highest_irrpin(i8259);
if (pin == 2U) { if (pin == 2U) {
@ -642,7 +642,7 @@ void vpic_pending_intr(struct acrn_vpic *vpic, uint32_t *vecptr)
dev_dbg(DBG_LEVEL_PIC, "Got pending vector 0x%x\n", *vecptr); dev_dbg(DBG_LEVEL_PIC, "Got pending vector 0x%x\n", *vecptr);
} }
spinlock_release(&(vpic->lock)); spinlock_irqrestore_release(&(vpic->lock), rflags);
} }
static void vpic_pin_accepted(struct i8259_reg_state *i8259, uint32_t pin) static void vpic_pin_accepted(struct i8259_reg_state *i8259, uint32_t pin)
@ -677,8 +677,9 @@ static void vpic_pin_accepted(struct i8259_reg_state *i8259, uint32_t pin)
void vpic_intr_accepted(struct acrn_vpic *vpic, uint32_t vector) void vpic_intr_accepted(struct acrn_vpic *vpic, uint32_t vector)
{ {
uint32_t pin; uint32_t pin;
uint64_t rflags;
spinlock_obtain(&(vpic->lock)); spinlock_irqsave_obtain(&(vpic->lock), &rflags);
pin = (vector & 0x7U); pin = (vector & 0x7U);
@ -695,15 +696,16 @@ void vpic_intr_accepted(struct acrn_vpic *vpic, uint32_t vector)
vpic_notify_intr(vpic); vpic_notify_intr(vpic);
spinlock_release(&(vpic->lock)); spinlock_irqrestore_release(&(vpic->lock), rflags);
} }
static int32_t vpic_read(struct acrn_vpic *vpic, struct i8259_reg_state *i8259, static int32_t vpic_read(struct acrn_vpic *vpic, struct i8259_reg_state *i8259,
uint16_t port, uint32_t *eax) uint16_t port, uint32_t *eax)
{ {
uint32_t pin; uint32_t pin;
uint64_t rflags;
spinlock_obtain(&(vpic->lock)); spinlock_irqsave_obtain(&(vpic->lock), &rflags);
if (i8259->poll) { if (i8259->poll) {
i8259->poll = false; i8259->poll = false;
@ -729,7 +731,7 @@ static int32_t vpic_read(struct acrn_vpic *vpic, struct i8259_reg_state *i8259,
} }
} }
spinlock_release(&(vpic->lock)); spinlock_irqrestore_release(&(vpic->lock), rflags);
return 0; return 0;
} }
@ -739,11 +741,12 @@ static int32_t vpic_write(struct acrn_vpic *vpic, struct i8259_reg_state *i8259,
{ {
int32_t error; int32_t error;
uint8_t val; uint8_t val;
uint64_t rflags;
error = 0; error = 0;
val = (uint8_t)*eax; val = (uint8_t)*eax;
spinlock_obtain(&(vpic->lock)); spinlock_irqsave_obtain(&(vpic->lock), &rflags);
if ((port & ICU_IMR_OFFSET) != 0U) { if ((port & ICU_IMR_OFFSET) != 0U) {
switch (i8259->icw_num) { switch (i8259->icw_num) {
@ -778,7 +781,7 @@ static int32_t vpic_write(struct acrn_vpic *vpic, struct i8259_reg_state *i8259,
vpic_notify_intr(vpic); vpic_notify_intr(vpic);
} }
spinlock_release(&(vpic->lock)); spinlock_irqrestore_release(&(vpic->lock), rflags);
return error; return error;
} }
@ -895,7 +898,9 @@ static int32_t vpic_elc_handler(struct acrn_vpic *vpic, bool in, uint16_t port,
is_master = (port == IO_ELCR1); is_master = (port == IO_ELCR1);
if (bytes == 1U) { if (bytes == 1U) {
spinlock_obtain(&(vpic->lock)); uint64_t rflags;
spinlock_irqsave_obtain(&(vpic->lock), &rflags);
if (in) { if (in) {
if (is_master) { if (is_master) {
@ -921,7 +926,7 @@ static int32_t vpic_elc_handler(struct acrn_vpic *vpic, bool in, uint16_t port,
} }
} }
spinlock_release(&(vpic->lock)); spinlock_irqrestore_release(&(vpic->lock), rflags);
ret = 0; ret = 0;
} else { } else {
ret = -1; ret = -1;