Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm64/arm64/pmap.c
Show First 20 Lines • Show All 5,737 Lines • ▼ Show 20 Lines | while (sz != 0) { | ||||
len = imin(PAGE_SIZE, sz); | len = imin(PAGE_SIZE, sz); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
int | int | ||||
pmap_fault(pmap_t pmap, uint64_t esr, uint64_t far) | pmap_fault(pmap_t pmap, uint64_t esr, uint64_t far) | ||||
{ | { | ||||
pt_entry_t *pte; | pt_entry_t pte, *ptep; | ||||
register_t intr; | register_t intr; | ||||
uint64_t ec, par; | uint64_t ec, par; | ||||
int lvl, rv; | int lvl, rv; | ||||
rv = KERN_FAILURE; | rv = KERN_FAILURE; | ||||
ec = ESR_ELx_EXCEPTION(esr); | ec = ESR_ELx_EXCEPTION(esr); | ||||
switch (ec) { | switch (ec) { | ||||
case EXCP_INSN_ABORT_L: | case EXCP_INSN_ABORT_L: | ||||
case EXCP_INSN_ABORT: | case EXCP_INSN_ABORT: | ||||
case EXCP_DATA_ABORT_L: | case EXCP_DATA_ABORT_L: | ||||
case EXCP_DATA_ABORT: | case EXCP_DATA_ABORT: | ||||
break; | break; | ||||
default: | default: | ||||
return (rv); | return (rv); | ||||
} | } | ||||
/* Data and insn aborts use same encoding for FSC field. */ | /* Data and insn aborts use same encoding for FSC field. */ | ||||
switch (esr & ISS_DATA_DFSC_MASK) { | switch (esr & ISS_DATA_DFSC_MASK) { | ||||
case ISS_DATA_DFSC_AFF_L1: | case ISS_DATA_DFSC_AFF_L1: | ||||
case ISS_DATA_DFSC_AFF_L2: | case ISS_DATA_DFSC_AFF_L2: | ||||
case ISS_DATA_DFSC_AFF_L3: | case ISS_DATA_DFSC_AFF_L3: | ||||
PMAP_LOCK(pmap); | PMAP_LOCK(pmap); | ||||
pte = pmap_pte(pmap, far, &lvl); | ptep = pmap_pte(pmap, far, &lvl); | ||||
if (pte != NULL) { | if (ptep != NULL) { | ||||
pmap_set_bits(pte, ATTR_AF); | pmap_set_bits(ptep, ATTR_AF); | ||||
rv = KERN_SUCCESS; | rv = KERN_SUCCESS; | ||||
/* | /* | ||||
* XXXMJ as an optimization we could mark the entry | * XXXMJ as an optimization we could mark the entry | ||||
* dirty if this is a write fault. | * dirty if this is a write fault. | ||||
*/ | */ | ||||
} | } | ||||
PMAP_UNLOCK(pmap); | PMAP_UNLOCK(pmap); | ||||
break; | break; | ||||
case ISS_DATA_DFSC_PF_L1: | case ISS_DATA_DFSC_PF_L1: | ||||
case ISS_DATA_DFSC_PF_L2: | case ISS_DATA_DFSC_PF_L2: | ||||
case ISS_DATA_DFSC_PF_L3: | case ISS_DATA_DFSC_PF_L3: | ||||
if ((ec != EXCP_DATA_ABORT_L && ec != EXCP_DATA_ABORT) || | if ((ec != EXCP_DATA_ABORT_L && ec != EXCP_DATA_ABORT) || | ||||
(esr & ISS_DATA_WnR) == 0) | (esr & ISS_DATA_WnR) == 0) | ||||
return (rv); | return (rv); | ||||
PMAP_LOCK(pmap); | PMAP_LOCK(pmap); | ||||
pte = pmap_pte(pmap, far, &lvl); | ptep = pmap_pte(pmap, far, &lvl); | ||||
if (pte != NULL && | if (ptep != NULL && | ||||
(pmap_load(pte) & (ATTR_AP_RW_BIT | ATTR_SW_DBM)) == | ((pte = pmap_load(ptep)) & ATTR_SW_DBM) != 0) { | ||||
(ATTR_AP(ATTR_AP_RO) | ATTR_SW_DBM)) { | if ((pte & ATTR_AP_RW_BIT) == ATTR_AP(ATTR_AP_RO)) { | ||||
pmap_clear_bits(pte, ATTR_AP_RW_BIT); | pmap_clear_bits(ptep, ATTR_AP_RW_BIT); | ||||
pmap_invalidate_page(pmap, far); | pmap_invalidate_page(pmap, far); | ||||
} | |||||
rv = KERN_SUCCESS; | rv = KERN_SUCCESS; | ||||
} | } | ||||
PMAP_UNLOCK(pmap); | PMAP_UNLOCK(pmap); | ||||
break; | break; | ||||
case ISS_DATA_DFSC_TF_L0: | case ISS_DATA_DFSC_TF_L0: | ||||
case ISS_DATA_DFSC_TF_L1: | case ISS_DATA_DFSC_TF_L1: | ||||
case ISS_DATA_DFSC_TF_L2: | case ISS_DATA_DFSC_TF_L2: | ||||
case ISS_DATA_DFSC_TF_L3: | case ISS_DATA_DFSC_TF_L3: | ||||
▲ Show 20 Lines • Show All 129 Lines • Show Last 20 Lines |