Page MenuHomeFreeBSD

D21685.id62206.diff
No OneTemporary

D21685.id62206.diff

Index: sys/arm64/arm64/pmap.c
===================================================================
--- sys/arm64/arm64/pmap.c
+++ sys/arm64/arm64/pmap.c
@@ -5764,11 +5764,27 @@
}
}
+static uint64_t
+pmap_fault_translate(pmap_t pmap, uint64_t far)
+{
+ register_t intr;
+ uint64_t par;
+
+ /* Ask the MMU to check the address */
+ intr = intr_disable();
+ if (pmap == kernel_pmap)
+ par = arm64_address_translate_s1e1r(far);
+ else
+ par = arm64_address_translate_s1e0r(far);
+ intr_restore(intr);
+
+ return (par);
+}
+
int
pmap_fault(pmap_t pmap, uint64_t esr, uint64_t far)
{
pt_entry_t pte, *ptep;
- register_t intr;
uint64_t ec, par;
int lvl, rv;
@@ -5824,21 +5840,26 @@
case ISS_DATA_DFSC_TF_L1:
case ISS_DATA_DFSC_TF_L2:
case ISS_DATA_DFSC_TF_L3:
- PMAP_LOCK(pmap);
- /* Ask the MMU to check the address */
- intr = intr_disable();
- if (pmap == kernel_pmap)
- par = arm64_address_translate_s1e1r(far);
- else
- par = arm64_address_translate_s1e0r(far);
- intr_restore(intr);
- PMAP_UNLOCK(pmap);
-
/*
* If the translation was successful the address was invalid
- * due to a break-before-make sequence. We can unlock and
- * return success to the trap handler.
+ * due to a break-before-make sequence. Try first unlocked
+ * as the operatin is only a few instructions long and will
+ * have interrupts disabled to stop it being interrupted.
*/
+ par = pmap_fault_translate(pmap, far);
+ if (PAR_SUCCESS(par)) {
+ rv = KERN_SUCCESS;
+ break;
+ }
+
+ /*
+ * The translation failed, try afain with the pmap lock to
+ * ensure all page table updates have completed.
+ */
+ PMAP_LOCK(pmap);
+ par = pmap_fault_translate(pmap, far);
+ PMAP_UNLOCK(pmap);
+
if (PAR_SUCCESS(par))
rv = KERN_SUCCESS;
break;

File Metadata

Mime Type
text/plain
Expires
Mon, Jun 22, 11:22 PM (1 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34218459
Default Alt Text
D21685.id62206.diff (1 KB)

Event Timeline