tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: pmap nocache



Andrew Doran wrote:
> On Thu, Apr 16, 2009 at 10:53:20PM +0200, Christoph Egger wrote:
> 
>> Attached x86_nocache.diff removes the TLB flush
>> when mapping dma-safe memory.
>>
>> Attached pmap_md.diff adds a PMAP_MD_MASK.
>> For x86 PAT feature you need six MD PMAP types.
>>
>> Comments?
> 
> Looks good to me, thanks for doing this - that bit of code has caused me
> a lot of headaches recently.

Committed.

> IIRC bus_space does something similar but uses pmap_kenter_pa().

You're asking for attached patch? :)

> I think it would be worthwhile adding a flags argument to handle it.

I'm (ab)using the prot argument for this. Either we add a flags argument
or we change change the type of the prot argument.

Christoph
Index: bus_space.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/bus_space.c,v
retrieving revision 1.22
diff -u -p -r1.22 bus_space.c
--- bus_space.c 10 Mar 2009 18:56:18 -0000      1.22
+++ bus_space.c 18 Apr 2009 11:55:10 -0000
@@ -303,11 +303,14 @@ x86_mem_add_mapping(bus_addr_t bpa, bus_
 {
        paddr_t pa, endpa;
        vaddr_t va, sva;
-       pt_entry_t *pte, xpte;
+       int pmapflags = VM_PROT_READ | VM_PROT_WRITE;
 
        pa = x86_trunc_page(bpa);
        endpa = x86_round_page(bpa + size);
 
+       if (!cacheable)
+               pmapflags |= PMAP_NOCACHE;
+
 #ifdef DIAGNOSTIC
        if (endpa <= pa)
                panic("x86_mem_add_mapping: overflow");
@@ -327,7 +330,6 @@ x86_mem_add_mapping(bus_addr_t bpa, bus_
 
        *bshp = (bus_space_handle_t)(sva + (bpa & PGOFSET));
        va = sva;
-       xpte = 0;
 
        for (; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
                /*
@@ -339,22 +341,12 @@ x86_mem_add_mapping(bus_addr_t bpa, bus_
                 * save the extra invalidate!
                 */
 #ifdef XEN
-               pmap_kenter_ma(va, pa, VM_PROT_READ | VM_PROT_WRITE);
+               pmap_kenter_ma(va, pa, pmapflags);
 #else
-               pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE);
+               pmap_kenter_pa(va, pa, pmapflags);
 #endif /* XEN */
-
-               pte = kvtopte(va);
-               if (cacheable)
-                       pmap_pte_clearbits(pte, PG_N);
-               else
-                       pmap_pte_setbits(pte, PG_N);
-               xpte |= *pte;
        }
-       kpreempt_disable();
-       pmap_tlb_shootdown(pmap_kernel(), sva, sva + (endpa - pa), xpte);
-       pmap_tlb_shootwait();
-       kpreempt_enable();
+       pmap_update(pmap_kernel());
 
        return 0;
 }
Index: pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/pmap.c,v
retrieving revision 1.83
diff -u -p -r1.83 pmap.c
--- pmap.c      18 Apr 2009 08:51:45 -0000      1.83
+++ pmap.c      18 Apr 2009 11:55:11 -0000
@@ -1042,6 +1042,8 @@ pmap_kenter_pa(vaddr_t va, paddr_t pa, v
 #endif /* DOM0OPS */
                npte = pmap_pa2pte(pa);
        npte |= protection_codes[prot] | PG_k | PG_V | pmap_pg_g;
+       if (prot & PMAP_NOCACHE)
+               npte |= PG_N;
        opte = pmap_pte_testset(pte, npte); /* zap! */
 #if defined(DIAGNOSTIC)
        /* XXX For now... */
@@ -1077,6 +1079,9 @@ pmap_kenter_ma(vaddr_t va, paddr_t ma, v
 
        npte = ma | ((prot & VM_PROT_WRITE) ? PG_RW : PG_RO) |
             PG_V | PG_k;
+       if (prot & PMAP_NOCACHE)
+               npte |= PG_N;
+
 #ifndef XEN
        if ((cpu_feature & CPUID_NOX) && !(prot & VM_PROT_EXECUTE))
                npte |= PG_NX;


Home | Main Index | Thread Index | Old Index