]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
lib/ukvmem: Add `AArch64` equivalent page fault intermediary handler
authorSergiu Moga <sergiu.moga@protonmail.com>
Tue, 18 Apr 2023 10:44:02 +0000 (13:44 +0300)
committerUnikraft <monkey@unikraft.io>
Fri, 11 Aug 2023 10:12:32 +0000 (10:12 +0000)
Implement the equivalent page fault intermediary handler of the x86
one, by using the `AArch64` specific equivalent bitfields to check
for the type of the fault.

Signed-off-by: Sergiu Moga <sergiu.moga@protonmail.com>
Reviewed-by: Michalis Pappas <michalis@unikraft.io>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Closes: #908

lib/ukvmem/Config.uk
lib/ukvmem/Makefile.uk
lib/ukvmem/arch/arm/pagefault64.c [new file with mode: 0644]

index fbb99ed156ec87d831c6fc238bc1d16645bdda95..c577013b4de6652d0602adc119ee7a855e854782 100644 (file)
@@ -4,8 +4,6 @@ menuconfig LIBUKVMEM
        select LIBUKDEBUG
        select LIBUKALLOC
        select LIBISRLIB
-       # ARM architecture is not yet compatible
-       depends on ARCH_X86_64
        help
                This library implements virtual address management by
                providing methods for working with virtual address space
index e5db7368ffbfbc8c11abd5611a99b9cd919c509e..2b981e24829df257cfc84eaf496ca23ee74d7581 100644 (file)
@@ -15,6 +15,8 @@ endif
 ifeq ($(CONFIG_HAVE_PAGING),y)
 LIBUKVMEM_SRCS-$(CONFIG_ARCH_X86_64) += \
        $(LIBUKVMEM_BASE)/arch/x86_64/pagefault.c|isr
+LIBUKVMEM_SRCS-$(CONFIG_ARCH_ARM_64) += \
+       $(LIBUKVMEM_BASE)/arch/arm/pagefault64.c|isr
 endif
 
 ifneq ($(filter y,$(CONFIG_LIBUKVMEM_TEST) $(CONFIG_LIBUKTEST_ALL)),)
diff --git a/lib/ukvmem/arch/arm/pagefault64.c b/lib/ukvmem/arch/arm/pagefault64.c
new file mode 100644 (file)
index 0000000..6e3d56b
--- /dev/null
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright (c) 2023, Unikraft GmbH and The Unikraft Authors.
+ * Licensed under the BSD-3-Clause License (the "License").
+ * You may not use this file except in compliance with the License.
+ */
+
+#include "../../vmem.h"
+
+#include <uk/assert.h>
+#include <uk/arch/traps.h>
+#include <uk/arch/types.h>
+#include <uk/print.h>
+#include <uk/config.h>
+
+static int vmem_arch_pagefault(void *data)
+{
+       struct ukarch_trap_ctx *ctx = (struct ukarch_trap_ctx *)data;
+       __vaddr_t vaddr = (__vaddr_t)ctx->far;
+       const char *faultstr[] __maybe_unused = {
+               "read", "write", "exec"
+       };
+       unsigned int faulttype;
+       unsigned long dfsc;
+       int rc;
+
+       if (ctx->esr & ARM64_PF_ESR_WnR)
+               faulttype = UK_VMA_FAULT_WRITE;
+       else if (ctx->esr & ARM64_PF_ESR_ISV)
+               faulttype = UK_VMA_FAULT_EXEC;
+       else
+               faulttype = UK_VMA_FAULT_READ;
+
+       dfsc = ctx->esr & ESR_ISS_ABRT_FSC_MASK;
+       if (dfsc >= ESR_ISS_ABRT_FSC_TRANS_L0 &&
+           dfsc <= ESR_ISS_ABRT_FSC_TRANS_L3)
+               faulttype |= UK_VMA_FAULT_NONPRESENT;
+       else
+               faulttype |= UK_VMA_FAULT_MISCONFIG;
+
+       rc = vmem_pagefault(vaddr, faulttype, ctx->regs);
+       if (unlikely(rc < 0)) {
+               uk_pr_debug("Cannot handle %s page fault at 0x%"__PRIvaddr
+                           " (ec: 0x%x): %d\n",
+                           faultstr[faulttype & UK_VMA_FAULT_ACCESSTYPE],
+                           vaddr, ctx->esr, rc);
+
+               return UK_EVENT_NOT_HANDLED;
+       }
+
+       return UK_EVENT_HANDLED;
+}
+
+UK_EVENT_HANDLER_PRIO(UKARCH_TRAP_PAGE_FAULT, vmem_arch_pagefault,
+                     CONFIG_LIBUKVMEM_PAGEFAULT_HANDLER_PRIO);