The patch doesn't fix the bug on Cortex A7.

cpu0 at mainbus0: ARM Cortex A7 rev 4 (ARMv7 core)
cpu0: DC enabled IC enabled WB disabled EABT branch prediction enabled
cpu0: 32KB(32b/l,2way) I-cache, 32KB(64b/l,4way) wr-back D-cache



Scanning scsi 0:1...
reading /sun7i-a20-olinuxino-lime2.dtb
29895 bytes read in 8 ms (3.6 MiB/s)
Found EFI removable media binary efi/boot/bootarm.efi
reading efi/boot/bootarm.efi
65196 bytes read in 9 ms (6.9 MiB/s)
## Starting EFI application at 0x42000000 ...
Scanning disks on scsi...
Scanning disks on usb...
Scanning disks on mmc...
MMC Device 1 not found
MMC Device 2 not found
MMC Device 3 not found
Found 2 disks
>> OpenBSD/armv7 BOOTARM 0.1
boot> 
booting sd0a:/bsd: 3504220+97840+476376 [64+464640+214774]=0x48a2b4

OpenBSD/armv7 booting ...
arg0 0x40000000 arg1 0x10bb arg2 0x48000000
Allocating page tables
freestart = 0x4078b000, free_pages = 260213 (0x0003f875)
IRQ stack: p0x407b9000 v0xc07b9000
ABT stack: p0x407ba000 v0xc07ba000
UND stack: p0x407bb000 v0xc07bb000
SVC stack: p0x407bc000 v0xc07bc000
Creating L1 page table at 0x4078c000
Mapping kernel
Constructing L2 page tables
undefined page pmap [ using 679852 bytes of bsd ELF symbol table ]
board type: 4283
Copyright (c) 1982, 1986, 1989, 1991, 1993
        The Regents of the University of California.  All rights
        reserved.
        Copyright (c) 1995-2016 OpenBSD. All rights reserved.
        http://www.OpenBSD.org

        OpenBSD 6.0-current (GENERIC) #1: Mon Aug  1 02:40:31 CEST 2016
            [email protected]:/usr/src/sys/arch/armv7/compile/GENERIC
            real mem  = 1073741824 (1024MB)
            avail mem = 1044840448 (996MB)
            mainbus0 at root: Olimex A20-OLinuXino-LIME2
            cpu0 at mainbus0: ARM Cortex A7 rev 4 (ARMv7 core)
            cpu0: DC enabled IC enabled WB disabled EABT branch
            prediction enabled
            cpu0: 32KB(32b/l,2way) I-cache, 32KB(64b/l,4way) wr-back
            D-cache
            cortex0 at mainbus0
            ampintc0 at cortex0 nirq 160
            agtimer0 at cortex0: tick rate 24000 KHz
            sunxi0 at mainbus0
            sxipio0 at sunxi0
            sxiccmu0 at sunxi0
            sxidog0 at sunxi0
            sxirtc0 at sunxi0
            ahci0 at sunxi0 AHCI 1.1
            ahci0: port 0: 1.5Gb/s
            scsibus0 at ahci0: 32 targets
            sd0 at scsibus0 targ 0 lun 0: <ATA, HTS721010G9SA00, MCZI>
            SCSI3 0/direct fixed t10.ATA_HTS721010G9SA00_MPCZN7Y0J9XTDL
            sd0: 95396MB, 512 bytes/sector, 195371568 sectors
            ehci0 at sunxi0
            usb0 at ehci0: USB revision 2.0
            uhub0 at usb0 "Allwinner EHCI root hub" rev 2.00/1.00 addr 1
            ehci1 at sunxi0
            usb1 at ehci1: USB revision 2.0
            uhub1 at usb1 "Allwinner EHCI root hub" rev 2.00/1.00 addr 1
            gpio0 at sxipio0: 18 pins
            gpio1 at sxipio0: 24 pins
            gpio2 at sxipio0: 25 pins
            gpio3 at sxipio0: 28 pins
            gpio4 at sxipio0: 12 pins
            gpio5 at sxipio0: 6 pins
            gpio6 at sxipio0: 12 pins
            gpio7 at sxipio0: 28 pins
            gpio8 at sxipio0: 22 pins
            simplebus0 at mainbus0: "soc"
            sxiuart0 at simplebus0: console
            run0 at uhub1 port 1 configuration 1 interface 0 "Ralink
            802.11 n WLAN" rev 2.00/1.01 addr 2
            run0: MAC/BBP RT5390 (rev 0x0502), RF RT5370 (MIMO 1T1R),
            address 7c:dd:90:02:47:50
            vscsi0 at root
            scsibus1 at vscsi0: 256 targets
            softraid0 at root
            scsibus2 at softraid0: 256 targets
            boot device: sd0
            root on sd0a (5e1e16eae3186591.a) swap on sd0b dump on sd0b
            Automatic boot in progress: starting file system checks.
            /dev/sd0a (5e1e16eae3186591.a): file system is clean; not
            checking
            setting tty flags
            pf enabled
            pmap_fault_fixup: va 00008000 ftype 5 u pte 7efaf02e
            pmap_fault_fixup: va 00008000 ftype 5 u pte 7efaf02e
            pmap_fault_fixup: va 00008000 ftype 5 u pte 7efaf02e

On Sun, Jul 31, 2016 at 08:03:58PM +0200, Mark Kettenis wrote:
> The ARMv7 ARM says in B3.9 that
> 
>   The architecture guarantees that a translation table entry that
>   generates a Translation fault or an Access flag fault is not held in
>   the TLB. However a translation table entry that generates a Domain
>   fault or a Permission fault might be held in the TLB.
> 
> and that
> 
>   Any translation table entry that does not generate a Translation or
>   Access flag fault and is not out of context might be allocated to an
>   enabled TLB at any time. The only translation table entries guaranteed
>   not to be held in the TLB are those that generate a Translation or
>   Access flag fault.
> 
> So the CPU might speculatively load TLB entries.  The upshot from this
> is that we always have to perform a TLB flush if we modify a valid
> entry.  So we can't rely on PV_BEEN_REFD() to decide whether we should
> flush or not.  The diff below fixes thi.  The diff seems to fix the
> pmap_fault_fixup() messages on a Cortex A53 system.  It's very likely
> that this will fix them on Cortex A7 as well.
> 
> 
> Index: arch/arm/arm/pmap7.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/arm/arm/pmap7.c,v
> retrieving revision 1.29
> diff -u -p -r1.29 pmap7.c
> --- arch/arm/arm/pmap7.c      29 Jul 2016 06:46:15 -0000      1.29
> +++ arch/arm/arm/pmap7.c      31 Jul 2016 17:55:27 -0000
> @@ -373,13 +373,7 @@ struct pv_entry {
>   * Macro to determine if a mapping might be resident in the
>   * instruction cache and/or TLB
>   */
> -#define      PV_BEEN_EXECD(f)  (((f) & (PVF_REF | PVF_EXEC)) == (PVF_REF | 
> PVF_EXEC))
> -
> -/*
> - * Macro to determine if a mapping might be resident in the
> - * data cache and/or TLB
> - */
> -#define      PV_BEEN_REFD(f)   (((f) & PVF_REF) != 0)
> +#define      PV_BEEN_EXECD(f)  (((f) & PVF_EXEC) != 0)
>  
>  /*
>   * Local prototypes
> @@ -1034,11 +1028,12 @@ pmap_clearbit(struct vm_page *pg, u_int 
>                       *ptep = npte;
>                       PTE_SYNC(ptep);
>                       /* Flush the TLB entry if a current pmap. */
> -                     if (PV_BEEN_EXECD(oflags))
> -                             pmap_tlb_flushID_SE(pm, pv->pv_va);
> -                     else
> -                     if (PV_BEEN_REFD(oflags))
> -                             pmap_tlb_flushD_SE(pm, pv->pv_va);
> +                     if (l2pte_valid(opte)) {
> +                             if (PV_BEEN_EXECD(oflags))
> +                                     pmap_tlb_flushID_SE(pm, pv->pv_va);
> +                             else
> +                                     pmap_tlb_flushD_SE(pm, pv->pv_va);
> +                     }
>               }
>  
>               NPDEBUG(PDB_BITS,
> @@ -1454,11 +1449,12 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
>                       }
>               }
>  
> -             if (PV_BEEN_EXECD(oflags))
> -                     pmap_tlb_flushID_SE(pm, va);
> -             else
> -             if (PV_BEEN_REFD(oflags))
> -                     pmap_tlb_flushD_SE(pm, va);
> +             if (l2pte_valid(opte)) {
> +                     if (PV_BEEN_EXECD(oflags))
> +                             pmap_tlb_flushID_SE(pm, va);
> +                     else
> +                             pmap_tlb_flushD_SE(pm, va);
> +             }
>       }
>  
>       /*
> @@ -1484,7 +1480,7 @@ pmap_remove(pmap_t pm, vaddr_t sva, vadd
>       struct l2_bucket *l2b;
>       vaddr_t next_bucket;
>       pt_entry_t *ptep;
> -     u_int mappings, is_exec, is_refd;
> +     u_int mappings, is_exec;
>  
>       NPDEBUG(PDB_REMOVE, printf("pmap_remove: pmap=%p sva=%08lx eva=%08lx\n",
>           pm, sva, eva));
> @@ -1525,7 +1521,6 @@ pmap_remove(pmap_t pm, vaddr_t sva, vadd
>                       pm->pm_stats.resident_count--;
>                       pa = l2pte_pa(pte);
>                       is_exec = 0;
> -                     is_refd = l2pte_valid(pte);
>  
>                       /*
>                        * Update flags. In a number of circumstances,
> @@ -1538,7 +1533,6 @@ pmap_remove(pmap_t pm, vaddr_t sva, vadd
>                               pve = pmap_remove_pv(pg, pm, sva);
>                               if (pve != NULL) {
>                                       is_exec = PV_BEEN_EXECD(pve->pv_flags);
> -                                     is_refd = PV_BEEN_REFD(pve->pv_flags);
>                                       pool_put(&pmap_pv_pool, pve);
>                               }
>                       }
> @@ -1553,11 +1547,12 @@ pmap_remove(pmap_t pm, vaddr_t sva, vadd
>  
>                       *ptep = L2_TYPE_INV;
>                       PTE_SYNC(ptep);
> -                     if (is_exec)
> -                             pmap_tlb_flushID_SE(pm, sva);
> -                     else
> -                     if (is_refd)
> -                             pmap_tlb_flushD_SE(pm, sva);
> +                     if (l2pte_valid(pte)) {
> +                             if (is_exec)
> +                                     pmap_tlb_flushID_SE(pm, sva);
> +                             else
> +                                     pmap_tlb_flushD_SE(pm, sva);
> +                     }
>  
>                       sva += PAGE_SIZE;
>                       ptep++;
> @@ -1732,7 +1727,7 @@ void
>  pmap_protect(pmap_t pm, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
>  {
>       struct l2_bucket *l2b;
> -     pt_entry_t *ptep, pte;
> +     pt_entry_t *ptep, pte, opte;
>       vaddr_t next_bucket;
>       u_int flags;
>       int flush;
> @@ -1782,19 +1777,19 @@ NPDEBUG(PDB_PROTECT, printf("\n"));
>               ptep = &l2b->l2b_kva[l2pte_index(sva)];
>  
>               while (sva < next_bucket) {
> -                     pte = *ptep;
> +                     opte = *ptep;
>                       /* !!! not l2pte_valid */
>  /* XXX actually would only matter if really valid ??? */
> -                     if (pte != 0 && l2pte_is_writeable(pte, pm)) {
> +                     if (opte != 0 && l2pte_is_writeable(opte, pm)) {
>                               struct vm_page *pg;
>                               u_int f;
>  
> -                             pg = PHYS_TO_VM_PAGE(l2pte_pa(pte));
> +                             pg = PHYS_TO_VM_PAGE(l2pte_pa(opte));
>                               if (pg != NULL)
>                                       pmap_clean_page(pg, FALSE);
> -                             pte = (pte & ~L2_S_PROT_MASK) |
> +                             pte = (opte & ~L2_S_PROT_MASK) |
>                                   L2_S_PROT(pm == pmap_kernel() ? PTE_KERNEL 
> : PTE_USER,
> -                                   pte & L2_V7_S_XN ? PROT_READ : PROT_READ 
> | PROT_EXEC);
> +                                   opte & L2_V7_S_XN ? PROT_READ : PROT_READ 
> | PROT_EXEC);
>                               *ptep = pte;
>                               PTE_SYNC(ptep);
>  
> @@ -1802,15 +1797,16 @@ NPDEBUG(PDB_PROTECT, printf("\n"));
>                                       f = pmap_modify_pv(pg, pm, sva,
>                                           PVF_WRITE, 0);
>                               } else
> -                                     f = PVF_REF | PVF_EXEC;
> +                                     f = PVF_EXEC;
>  
>                               if (flush >= 0) {
>                                       flush++;
> -                                     if (PV_BEEN_EXECD(f))
> -                                             cpu_tlb_flushID_SE(sva);
> -                                     else
> -                                     if (PV_BEEN_REFD(f))
> -                                             cpu_tlb_flushD_SE(sva);
> +                                     if (l2pte_valid(opte)) {
> +                                             if (PV_BEEN_EXECD(f))
> +                                                     cpu_tlb_flushID_SE(sva);
> +                                             else
> +                                                     cpu_tlb_flushD_SE(sva);
> +                                     }
>                               } else
>                                       flags |= f;
>                       }
> @@ -1824,7 +1820,6 @@ NPDEBUG(PDB_PROTECT, printf("\n"));
>               if (PV_BEEN_EXECD(flags))
>                       pmap_tlb_flushID(pm);
>               else
> -             if (PV_BEEN_REFD(flags))
>                       pmap_tlb_flushD(pm);
>       }
>  NPDEBUG(PDB_PROTECT, printf("\n"));
> 

-- 
Juan Francisco Cantero Hurtado http://juanfra.info

Reply via email to