mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
Revert "ANDROID: GKI: arm64: add support for NO_KERNEL_MAPPING and STRONGLY_ORDERED"
This reverts commit 4ac42c4404.
DMA_ATTR_NO_KERNEL_MAPPING is not well supported on apply_to_page_range(),
which causes the following error:
[ 2.268586] nvme nvme0: pci function 0002:21:00.0
[ 2.268649] nvme 0002:21:00.0: enabling device (0000 -> 0002)
[ 2.376361] nvme nvme0: missing or invalid SUBNQN field.
[ 2.378661] Unable to handle kernel paging request at virtual address ffffffc400000000
[ 2.379360] Mem abort info:
[ 2.379616] ESR = 0x96000045
[ 2.379895] Exception class = DABT (current EL), IL = 32 bits
[ 2.380414] SET = 0, FnV = 0
[ 2.380691] EA = 0, S1PTW = 0
[ 2.380970] Data abort info:
[ 2.381237] ISV = 0, ISS = 0x00000045
[ 2.381575] CM = 0, WnR = 1
[ 2.381846] swapper pgtable: 4k pages, 39-bit VAs, pgdp = 000000005a0c0862
[ 2.382446] [ffffffc400000000] pgd=0000000000000000, pud=0000000000000000
[ 2.383049] Internal error: Oops: 96000045 [#1] PREEMPT SMP
[ 2.383546] Modules linked in:
[ 2.383827] Process kworker/u8:0 (pid: 7, stack limit = 0x00000000b285d686)
[ 2.384441] CPU: 3 PID: 7 Comm: kworker/u8:0 Not tainted 4.19.172 #134
[ 2.385017] Hardware name: Rockchip RK3568 EVB1 DDR4 V10 Board (DT)
[ 2.385580] Workqueue: nvme-reset-wq nvme_reset_work
[ 2.386022] pstate: 60c00009 (nZCv daif +PAN +UAO)
[ 2.386453] pc : __dma_clear_pte+0x0/0xc
[ 2.386804] lr : apply_to_page_range+0x1bc/0x274
[ 2.519225]
[ 2.519366] Call trace:
[ 2.519593] __dma_clear_pte+0x0/0xc
[ 2.519908] __dma_alloc+0x240/0x3f0
[ 2.520224] nvme_reset_work+0xaf4/0xf14
[ 2.520575] process_one_work+0x26c/0x438
[ 2.520935] worker_thread+0x260/0x4a8
[ 2.521272] kthread+0x13c/0x14c
[ 2.521564] ret_from_fork+0x10/0x18
Signed-off-by: Tao Huang <huangtao@rock-chips.com>
Change-Id: Ifb10b05af6b9778990cad23e3d45cc440bbecb2f
This commit is contained in:
@@ -45,9 +45,7 @@ static int swiotlb __ro_after_init;
|
||||
static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot,
|
||||
bool coherent)
|
||||
{
|
||||
if (attrs & DMA_ATTR_STRONGLY_ORDERED)
|
||||
return pgprot_noncached(prot);
|
||||
else if (!coherent || (attrs & DMA_ATTR_WRITE_COMBINE))
|
||||
if (!coherent || (attrs & DMA_ATTR_WRITE_COMBINE))
|
||||
return pgprot_writecombine(prot);
|
||||
return prot;
|
||||
}
|
||||
@@ -66,7 +64,6 @@ static bool is_dma_coherent(struct device *dev, unsigned long attrs)
|
||||
}
|
||||
static struct gen_pool *atomic_pool __ro_after_init;
|
||||
|
||||
#define NO_KERNEL_MAPPING_DUMMY 0x2222
|
||||
#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K
|
||||
static size_t atomic_pool_size __initdata = DEFAULT_DMA_COHERENT_POOL_SIZE;
|
||||
|
||||
@@ -114,43 +111,6 @@ static int __free_from_pool(void *start, size_t size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr,
|
||||
void *data)
|
||||
{
|
||||
struct page *page = virt_to_page(addr);
|
||||
pgprot_t prot = *(pgprot_t *)data;
|
||||
|
||||
set_pte(pte, mk_pte(page, prot));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __dma_clear_pte(pte_t *pte, pgtable_t token, unsigned long addr,
|
||||
void *data)
|
||||
{
|
||||
pte_clear(&init_mm, addr, pte);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __dma_remap(struct page *page, size_t size, pgprot_t prot,
|
||||
bool no_kernel_map)
|
||||
{
|
||||
unsigned long start = (unsigned long) page_address(page);
|
||||
unsigned long end = start + size;
|
||||
int (*func)(pte_t *pte, pgtable_t token, unsigned long addr,
|
||||
void *data);
|
||||
|
||||
if (no_kernel_map)
|
||||
func = __dma_clear_pte;
|
||||
else
|
||||
func = __dma_update_pte;
|
||||
|
||||
apply_to_page_range(&init_mm, start, size, func, &prot);
|
||||
/* ensure prot is applied before returning */
|
||||
mb();
|
||||
flush_tlb_kernel_range(start, end);
|
||||
}
|
||||
|
||||
|
||||
static void *__dma_alloc(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flags,
|
||||
unsigned long attrs)
|
||||
@@ -181,31 +141,19 @@ static void *__dma_alloc(struct device *dev, size_t size,
|
||||
if (coherent)
|
||||
return ptr;
|
||||
|
||||
/* remove any dirty cache lines on the kernel alias */
|
||||
__dma_flush_area(ptr, size);
|
||||
|
||||
if (attrs & DMA_ATTR_NO_KERNEL_MAPPING) {
|
||||
coherent_ptr = (void *)NO_KERNEL_MAPPING_DUMMY;
|
||||
__dma_remap(virt_to_page(ptr), size, __pgprot(0), true);
|
||||
} else {
|
||||
if ((attrs & DMA_ATTR_STRONGLY_ORDERED))
|
||||
__dma_remap(virt_to_page(ptr), size, __pgprot(0), true);
|
||||
/* create a coherent mapping */
|
||||
page = virt_to_page(ptr);
|
||||
coherent_ptr = dma_common_contiguous_remap(page, size, VM_USERMAP,
|
||||
prot, __builtin_return_address(0));
|
||||
if (!coherent_ptr)
|
||||
goto no_map;
|
||||
|
||||
/* create a coherent mapping */
|
||||
page = virt_to_page(ptr);
|
||||
coherent_ptr = dma_common_contiguous_remap(
|
||||
page, size, VM_USERMAP, prot,
|
||||
__builtin_return_address(0));
|
||||
if (!coherent_ptr)
|
||||
goto no_map;
|
||||
}
|
||||
return coherent_ptr;
|
||||
|
||||
no_map:
|
||||
if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) ||
|
||||
(attrs & DMA_ATTR_STRONGLY_ORDERED))
|
||||
__dma_remap(phys_to_page(dma_to_phys(dev, *dma_handle)),
|
||||
size, PAGE_KERNEL, false);
|
||||
|
||||
swiotlb_free(dev, size, ptr, *dma_handle, attrs);
|
||||
no_mem:
|
||||
return NULL;
|
||||
@@ -219,17 +167,11 @@ static void __dma_free(struct device *dev, size_t size,
|
||||
|
||||
size = PAGE_ALIGN(size);
|
||||
|
||||
if (!is_dma_coherent(dev, attrs)) {
|
||||
if (!is_device_dma_coherent(dev)) {
|
||||
if (__free_from_pool(vaddr, size))
|
||||
return;
|
||||
if (!(attrs & DMA_ATTR_NO_KERNEL_MAPPING))
|
||||
vunmap(vaddr);
|
||||
vunmap(vaddr);
|
||||
}
|
||||
if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) ||
|
||||
(attrs & DMA_ATTR_STRONGLY_ORDERED))
|
||||
__dma_remap(phys_to_page(dma_to_phys(dev, dma_handle)),
|
||||
size, PAGE_KERNEL, false);
|
||||
|
||||
swiotlb_free(dev, size, swiotlb_addr, dma_handle, attrs);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user