--- zzzz-none-000/linux-3.10.107/arch/mips/mm/highmem.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/arch/mips/mm/highmem.c 2021-11-10 11:53:54.000000000 +0000 @@ -9,6 +9,7 @@ static pte_t *kmap_pte; unsigned long highstart_pfn, highend_pfn; +unsigned int last_pkmap_nr_arr[FIX_N_COLOURS] = { 0, 1, 2, 3, 4, 5, 6, 7 }; void *kmap(struct page *page) { @@ -53,8 +54,12 @@ return page_address(page); type = kmap_atomic_idx_push(); - idx = type + KM_TYPE_NR*smp_processor_id(); - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); + + idx = (((unsigned long)lowmem_page_address(page)) >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); + idx = (FIX_N_COLOURS - idx); + idx = idx + FIX_N_COLOURS * (smp_processor_id() + NR_CPUS * type); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN - 1 + idx); /* actually - FIX_CMAP_END */ + #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(!pte_none(*(kmap_pte - idx))); #endif @@ -75,12 +80,16 @@ return; } - type = kmap_atomic_idx(); #ifdef CONFIG_DEBUG_HIGHMEM { - int idx = type + KM_TYPE_NR * smp_processor_id(); + int idx; + type = kmap_atomic_idx(); - BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); + idx = ((unsigned long)kvaddr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); + idx = (FIX_N_COLOURS - idx); + idx = idx + FIX_N_COLOURS * (smp_processor_id() + NR_CPUS * type); + + BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN -1 + idx)); /* * force other mappings to Oops if they'll try to access @@ -95,26 +104,6 @@ } EXPORT_SYMBOL(__kunmap_atomic); -/* - * This is the same as kmap_atomic() but can map memory that doesn't - * have a struct page associated with it. - */ -void *kmap_atomic_pfn(unsigned long pfn) -{ - unsigned long vaddr; - int idx, type; - - pagefault_disable(); - - type = kmap_atomic_idx_push(); - idx = type + KM_TYPE_NR*smp_processor_id(); - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); - set_pte(kmap_pte-idx, pfn_pte(pfn, PAGE_KERNEL)); - flush_tlb_one(vaddr); - - return (void*) vaddr; -} - struct page *kmap_atomic_to_page(void *ptr) { unsigned long idx, vaddr = (unsigned long)ptr; @@ -124,7 +113,7 @@ return virt_to_page(ptr); idx = virt_to_fix(vaddr); - pte = kmap_pte - (idx - FIX_KMAP_BEGIN); + pte = kmap_pte - (idx - FIX_KMAP_BEGIN + 1); return pte_page(*pte); } @@ -133,6 +122,6 @@ unsigned long kmap_vstart; /* cache the first kmap pte */ - kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN - 1); /* actually - FIX_CMAP_END */ kmap_pte = kmap_get_fixmap_pte(kmap_vstart); }