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