[prev in list] [next in list] [prev in thread] [next in thread] 

List:       git-commits-head
Subject:    ASoC: Intel: Fix audio crash due to negative address offset
From:       "Linux Kernel Mailing List" <linux-kernel () vger ! kernel ! org>
Date:       2014-04-30 15:36:28
Message-ID: 20140430153628.5F141660E02 () gitolite ! kernel ! org
[Download RAW message or body]

Gitweb:     http://git.kernel.org/linus/;a=commit;h=95e9ee92e20162681e9f65c25962e0606db9d149
Commit:     95e9ee92e20162681e9f65c25962e0606db9d149
Parent:     bf657d2479d179a03668cd7ab8aec96415592f02
Author:     Wenkai Du <wenkai.du@intel.com>
AuthorDate: Tue Apr 22 16:38:54 2014 +0300
Committer:  Mark Brown <broonie@linaro.org>
CommitDate: Tue Apr 22 19:22:53 2014 +0100

    ASoC: Intel: Fix audio crash due to negative address offset
    
    There were occasional ADSP crash during reboot testing:
    
    [   11.883364] BUG: unable to handle kernel paging request at ffffc90121700000
    [   11.883380] IP: [<ffffffffc024d8bc>] sst_module_insert_fixed_block+0x24f/0x26d [snd_soc_sst_dsp]
    [   11.883397] PGD 7800b067 PUD 0
    [   11.883405] Oops: 0002 [#1] SMP
    [   11.886418] gsmi: Log Shutdown Reason 0x03
    
    The virtual address, ffffc90121700000, was out of range. The virtual
    address is calculated by adding LPE base address with an offset:
    
    sst_memcpy32(dsp->addr.lpe + data->offset, data->data, data->size);
    
    The offset is calculated in sst_byt_parse_module, by subtraction of
    two virtual addresses dsp->addr.fw_ext and dsp->addr.lpe:
    
    block_data.offset = block->ram_offset + (dsp->addr.fw_ext - dsp->addr.lpe);
    
    These virtual addresses are assigned by kernel from ioremap:
    
    sst->addr.lpe = ioremap(pdata->lpe_base, pdata->lpe_size);
    sst->addr.fw_ext = ioremap(pdata->fw_base, pdata->fw_size);
    
    In current driver code, offset is defined as unsigned int32:
    
    struct sst_module_data {
    ...
    	u32 offset;		/* offset in FW file */
    };
    
    Most of the time kernel assigned virtual addresses with addr.fw_ext
    greater than addr.lpe. But sometimes it was the other way round.
    
    Fix the problem by declaring offset as signed int32_t.
    
    Signed-off-by: Wenkai Du <wenkai.du@intel.com>
    Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
    Signed-off-by: Mark Brown <broonie@linaro.org>
---
 sound/soc/intel/sst-dsp-priv.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/sound/soc/intel/sst-dsp-priv.h b/sound/soc/intel/sst-dsp-priv.h
index fe8e81a..30ca14a 100644
--- a/sound/soc/intel/sst-dsp-priv.h
+++ b/sound/soc/intel/sst-dsp-priv.h
@@ -136,7 +136,7 @@ struct sst_module_data {
 	enum sst_data_type data_type;	/* type of module data */
 
 	u32 size;		/* size in bytes */
-	u32 offset;		/* offset in FW file */
+	int32_t offset;		/* offset in FW file */
 	u32 data_offset;	/* offset in ADSP memory space */
 	void *data;		/* module data */
 };
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic