Determine whether the MMU hardware is capable of updating a page table
entry's access flag and dirty state, and enable this feature when it's available. Ensure that we don't overlook a dirty state update that is concurrent with a call to pmap_enter(). (Previously, all dirty state updates would have occurred with the containing pmap's lock held, so a page table entry's dirty state could not have changed while pmap_enter() held that same lock.) Reviewed by: andrew, markj MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D22907
This commit is contained in:
parent
54666dffa8
commit
b0a0152ab9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=356207
@ -683,7 +683,8 @@ start_mmu:
|
||||
|
||||
/*
|
||||
* Setup TCR according to the PARange and ASIDBits fields
|
||||
* from ID_AA64MMFR0_EL1. More precisely, set TCR_EL1.AS
|
||||
* from ID_AA64MMFR0_EL1 and the HAFDBS field from the
|
||||
* ID_AA64MMFR1_EL1. More precisely, set TCR_EL1.AS
|
||||
* to 1 only if the ASIDBits field equals 0b0010.
|
||||
*/
|
||||
ldr x2, tcr
|
||||
@ -700,6 +701,21 @@ start_mmu:
|
||||
/* Set TCR.AS with x3 */
|
||||
bfi x2, x3, #(TCR_ASID_SHIFT), #(TCR_ASID_WIDTH)
|
||||
|
||||
/*
|
||||
* Check if the HW supports access flag and dirty state updates,
|
||||
* and set TCR_EL1.HA and TCR_EL1.HD accordingly.
|
||||
*/
|
||||
mrs x3, id_aa64mmfr1_el1
|
||||
and x3, x3, #(ID_AA64MMFR1_HAFDBS_MASK)
|
||||
cmp x3, #1
|
||||
b.ne 1f
|
||||
orr x2, x2, #(TCR_HA)
|
||||
b 2f
|
||||
1:
|
||||
cmp x3, #2
|
||||
b.ne 2f
|
||||
orr x2, x2, #(TCR_HA | TCR_HD)
|
||||
2:
|
||||
msr tcr_el1, x2
|
||||
|
||||
/*
|
||||
|
@ -3510,8 +3510,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
|
||||
KASSERT(opa == pa, ("pmap_enter: invalid update"));
|
||||
if ((orig_l3 & ~ATTR_AF) != (new_l3 & ~ATTR_AF)) {
|
||||
/* same PA, different attributes */
|
||||
/* XXXMJ need to reload orig_l3 for hardware DBM. */
|
||||
pmap_load_store(l3, new_l3);
|
||||
orig_l3 = pmap_load_store(l3, new_l3);
|
||||
pmap_invalidate_page(pmap, va);
|
||||
if ((orig_l3 & ATTR_SW_MANAGED) != 0 &&
|
||||
pmap_pte_dirty(orig_l3))
|
||||
|
@ -619,6 +619,11 @@
|
||||
#define PSR_FLAGS 0xf0000000
|
||||
|
||||
/* TCR_EL1 - Translation Control Register */
|
||||
#define TCR_HD_SHIFT 40
|
||||
#define TCR_HD (0x1UL << TCR_HD_SHIFT)
|
||||
#define TCR_HA_SHIFT 39
|
||||
#define TCR_HA (0x1UL << TCR_HA_SHIFT)
|
||||
|
||||
#define TCR_ASID_SHIFT 36
|
||||
#define TCR_ASID_WIDTH 1
|
||||
#define TCR_ASID_16 (0x1UL << TCR_ASID_SHIFT)
|
||||
|
Loading…
Reference in New Issue
Block a user