diff options
author | Shaun Ruffell <sruffell@digium.com> | 2011-08-30 16:38:06 +0000 |
---|---|---|
committer | Shaun Ruffell <sruffell@digium.com> | 2011-08-30 16:38:06 +0000 |
commit | 9a2b7e411b40effb6bcd89b7ceb6dea73cb58e86 (patch) | |
tree | 1386d6cf93e011cdbd5861c0891b9ea2c820f92f /drivers/dahdi/wctdm24xxp | |
parent | 45e3c5c351593b2336f29b9c0b72b231dc016ccf (diff) |
wctdm24xxp: Protect creation / destruction of VPM instance.
Closes a small window of opportunity where one CPU might free a VPM
instance that the interrupt handler may currently be using.
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Acked-by: Russ Meyerriecks <rmeyerriecks@digium.com>
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10162 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/wctdm24xxp')
-rw-r--r-- | drivers/dahdi/wctdm24xxp/base.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c index 50cc618..494c62b 100644 --- a/drivers/dahdi/wctdm24xxp/base.c +++ b/drivers/dahdi/wctdm24xxp/base.c @@ -4518,6 +4518,8 @@ static int wctdm_initialize_vpmadt032(struct wctdm *wc) { int res; struct vpmadt032_options options; + struct vpmadt032 *vpm; + unsigned long flags; options.debug = debug; options.vpmnlptype = vpmnlptype; @@ -4537,8 +4539,11 @@ static int wctdm_initialize_vpmadt032(struct wctdm *wc) if (!res) res = vpmadt032_init(wc->vpmadt032); if (res) { - vpmadt032_free(wc->vpmadt032); + vpm = wc->vpmadt032; + spin_lock_irqsave(&wc->reglock, flags); wc->vpmadt032 = NULL; + spin_unlock_irqrestore(&wc->reglock, flags); + vpmadt032_free(vpm); return res; } @@ -4546,8 +4551,11 @@ static int wctdm_initialize_vpmadt032(struct wctdm *wc) * particular board. */ res = config_vpmadt032(wc->vpmadt032, wc); if (res) { - vpmadt032_free(wc->vpmadt032); + vpm = wc->vpmadt032; + spin_lock_irqsave(&wc->reglock, flags); wc->vpmadt032 = NULL; + spin_unlock_irqrestore(&wc->reglock, flags); + vpmadt032_free(vpm); return res; } @@ -5866,8 +5874,10 @@ static void __devexit wctdm_remove_one(struct pci_dev *pdev) voicebus_stop(&wc->vb); if (vpmadt032) { - vpmadt032_free(vpmadt032); + spin_lock_irqsave(&wc->reglock, flags); wc->vpmadt032 = NULL; + spin_unlock_irqrestore(&wc->reglock, flags); + vpmadt032_free(vpmadt032); } else if (vpmoct) { spin_lock_irqsave(&wc->reglock, flags); wc->vpmoct = NULL; |