Skip to content

Commit 17dc73a

Browse files
Simon Xuerkhuangtao
authored andcommitted
drm/rockchip: logo: fix rockchip_free_loader_memory
Add "mem=0x40000000" to COMMAND LINE, kernel will crash: [ 18.379633][ T35] Unable to handle kernel paging request at virtual address ffffffff01d7c000 [ 18.380412][ T35] Mem abort info: [ 18.380726][ T35] ESR = 0x96000006 [ 18.381060][ T35] EC = 0x25: DABT (current EL), IL = 32 bits [ 18.381587][ T35] SET = 0, FnV = 0 [ 18.381920][ T35] EA = 0, S1PTW = 0 [ 18.382264][ T35] Data abort info: [ 18.382585][ T35] ISV = 0, ISS = 0x00000006 [ 18.383029][ T35] CM = 0, WnR = 0 [ 18.383360][ T35] swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000001c47000 [ 18.384014][ T35] [ffffffff01d7c000] pgd=0000000040f2f003, p4d=0000000040f2f003, pud=0000000040f2f003, pmd=0000000000000000 [ 18.385299][ T35] Internal error: Oops: 96000006 [#1] PREEMPT SMP [ 18.385862][ T35] Modules linked in: [ 18.386205][ T35] CPU: 2 PID: 35 Comm: kworker/2:1 Not tainted 5.10.110 torvalds#324 [ 18.386843][ T35] Hardware name: Rockchip RK3568 EVB1 DDR4 V10 Board (DT) [ 18.387470][ T35] Workqueue: events rockchip_drm_fb_destroy_work [ 18.388026][ T35] pstate: 80c00009 (Nzcv daif +PAN +UAO -TCO BTYPE=--) [ 18.388626][ T35] pc : rockchip_free_loader_memory+0x100/0x1a0 [ 18.389156][ T35] lr : rockchip_free_loader_memory+0xc8/0x1a0 [ 18.389683][ T35] sp : ffffffc0125abd00 [ 18.390039][ T35] x29: ffffffc0125abd00 x28: 0000000000001000 [ 18.390570][ T35] x27: ffffff807df00000 x26: 0000008000000000 [ 18.391099][ T35] x25: fffffffeffe00000 x24: 0000000000000001 [ 18.391628][ T35] x23: ffffff80043d6300 x22: ffffff807df00000 [ 18.392157][ T35] x21: ffffff807dfb7000 x20: ffffff80043a8480 [ 18.392686][ T35] x19: ffffffff01d7c000 x18: 0000000000000000 [ 18.393215][ T35] x17: 0000000000000000 x16: 0000000000000000 [ 18.393744][ T35] x15: 00000072e03fbb78 x14: 0000000000000000 [ 18.394273][ T35] x13: 000000000000003d x12: 0000000000000000 [ 18.394802][ T35] x11: 00000000fffffff6 x10: ffffffc0122f8000 [ 18.395330][ T35] x9 : 0000000000010000 x8 : 0000000000000008 [ 18.395859][ T35] x7 : 0000000000818000 x6 : ffffff801ad909f0 [ 18.396387][ T35] x5 : 0000000000000039 x4 : ffffffc0122d01b8 [ 18.396917][ T35] x3 : 0000000000000000 x2 : 0000000000000000 [ 18.397445][ T35] x1 : ffffff80032622d8 x0 : 0000000000001000 [ 18.397975][ T35] Call trace: [ 18.398255][ T35] rockchip_free_loader_memory+0x100/0x1a0 [ 18.398762][ T35] __rockchip_drm_fb_destroy+0xa4/0xc8 [ 18.399233][ T35] rockchip_drm_fb_destroy_work+0x14/0x20 [ 18.399728][ T35] process_one_work+0x1b0/0x490 [ 18.400142][ T35] worker_thread+0x4c/0x3f8 [ 18.400534][ T35] kthread+0x140/0x160 [ 18.400882][ T35] ret_from_fork+0x10/0x30 Logo buffer allocated from Uboot which may removed in kernel for any purpose such as "debug". So, before freeing to the buddy system, we must check if the buffer are valid. Change-Id: I9a27c4552a3c7f450b034d2a6c6c3a321bb2fc54 Signed-off-by: Simon Xue <[email protected]>
1 parent 5151d57 commit 17dc73a

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

drivers/gpu/drm/rockchip/rockchip_drm_logo.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -148,17 +148,19 @@ static int rockchip_drm_reserve_vm(struct drm_device *drm, struct drm_mm *mm,
148148
}
149149

150150
static unsigned long
151-
rockchip_drm_free_reserved_area(void *start, void *end, int poison, const char *s)
151+
rockchip_drm_free_reserved_area(phys_addr_t start, phys_addr_t end, int poison, const char *s)
152152
{
153-
void *pos;
154153
unsigned long pages = 0;
155154

156-
start = (void *)PAGE_ALIGN((unsigned long)start);
157-
end = (void *)((unsigned long)end & PAGE_MASK);
158-
for (pos = start; pos < end; pos += PAGE_SIZE, pages++) {
159-
struct page *page = virt_to_page(pos);
155+
start = ALIGN_DOWN(start, PAGE_SIZE);
156+
end = PAGE_ALIGN(end);
157+
for (; start < end; start += PAGE_SIZE) {
158+
struct page *page = phys_to_page(start);
160159
void *direct_map_addr;
161160

161+
if (!pfn_valid(__phys_to_pfn(start)))
162+
continue;
163+
162164
/*
163165
* 'direct_map_addr' might be different from 'pos'
164166
* because some architectures' virt_to_page()
@@ -176,6 +178,7 @@ rockchip_drm_free_reserved_area(void *start, void *end, int poison, const char *
176178
memset(direct_map_addr, poison, PAGE_SIZE);
177179

178180
free_reserved_page(page);
181+
pages++;
179182
}
180183

181184
if (pages && s)
@@ -188,14 +191,11 @@ void rockchip_free_loader_memory(struct drm_device *drm)
188191
{
189192
struct rockchip_drm_private *private = drm->dev_private;
190193
struct rockchip_logo *logo;
191-
void *start, *end;
192194

193195
if (!private || !private->logo || --private->logo->count)
194196
return;
195197

196198
logo = private->logo;
197-
start = phys_to_virt(logo->dma_addr);
198-
end = phys_to_virt(logo->dma_addr + logo->size);
199199

200200
if (private->domain) {
201201
u32 pg_size = 1UL << __ffs(private->domain->pgsize_bitmap);
@@ -205,7 +205,8 @@ void rockchip_free_loader_memory(struct drm_device *drm)
205205
}
206206

207207
memblock_free(logo->start, logo->size);
208-
rockchip_drm_free_reserved_area(start, end, -1, "drm_logo");
208+
rockchip_drm_free_reserved_area(logo->dma_addr, logo->dma_addr + logo->size,
209+
-1, "drm_logo");
209210
kfree(logo);
210211
private->logo = NULL;
211212
private->loader_protect = false;

0 commit comments

Comments
 (0)