mirror of https://gitee.com/openkylin/linux.git
xtensa: make __pa work with uncached KSEG addresses
When __pa is applied to virtual address in uncached KSEG region the result is incorrect. Fix it by checking if the original address is in the uncached KSEG and adjusting the result. It looks better than masking off bits because pfn_valid would correctly work with new __pa results and it may be made working in noMMU case, once we get definition for uncached memory view. This is required for the dma_common_mmap and DMA debug code to work correctly: they both indirectly use __pa with coherent DMA addresses. In case of DMA debug the visible effect is false reports that an address mapped for DMA is accessed by CPU. Cc: stable@vger.kernel.org Tested-by: Boris Brezillon <boris.brezillon@free-electrons.com> Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com> Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
parent
c02ed2e75e
commit
2b83878dd7
|
@ -164,8 +164,21 @@ void copy_user_highpage(struct page *to, struct page *from,
|
|||
|
||||
#define ARCH_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT)
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
static inline unsigned long ___pa(unsigned long va)
|
||||
{
|
||||
unsigned long off = va - PAGE_OFFSET;
|
||||
|
||||
if (off >= XCHAL_KSEG_SIZE)
|
||||
off -= XCHAL_KSEG_SIZE;
|
||||
|
||||
return off + PHYS_OFFSET;
|
||||
}
|
||||
#define __pa(x) ___pa((unsigned long)(x))
|
||||
#else
|
||||
#define __pa(x) \
|
||||
((unsigned long) (x) - PAGE_OFFSET + PHYS_OFFSET)
|
||||
#endif
|
||||
#define __va(x) \
|
||||
((void *)((unsigned long) (x) - PHYS_OFFSET + PAGE_OFFSET))
|
||||
#define pfn_valid(pfn) \
|
||||
|
|
Loading…
Reference in New Issue