Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
mogasergiu committed Aug 6, 2023
1 parent 722de97 commit ab8624f
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 2 deletions.
29 changes: 29 additions & 0 deletions arch/arm/arm64/include/uk/asm/paging.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ struct ukarch_pagetable {
#define PAGE_ATTR_SHAREABLE_IS (1 << PAGE_ATTR_SHAREABLE_SHIFT)
#define PAGE_ATTR_SHAREABLE_OS (2 << PAGE_ATTR_SHAREABLE_SHIFT)

/* Page fault error code bits */
#define ARM64_PF_ESR_WnR 0x0000040UL
#define ARM64_PF_ESR_ISV 0x1000000UL

#define ARM64_PADDR_BITS 48
#define ARM64_VADDR_BITS 48

Expand Down Expand Up @@ -173,6 +177,31 @@ static inline __paddr_t PT_Lx_PTE_PADDR(__pte_t pte, unsigned int lvl)
return paddr;
}

static inline __paddr_t PT_Lx_PTE_SET_PADDR(__pte_t pte, unsigned int lvl,
__paddr_t paddr)
{
static __u64 pte_lx_map_paddr_mask[] = {
PTE_L0_PAGE_PADDR_MASK,
PTE_L1_BLOCK_PADDR_MASK,
PTE_L2_BLOCK_PADDR_MASK
};

if (PAGE_Lx_IS(pte, lvl)) {
#ifdef CONFIG_LIBUKDEBUG
UK_ASSERT(lvl <= PT_MAP_LEVEL_MAX);
#endif /* CONFIG_LIBUKDEBUG */
paddr &= pte_lx_map_paddr_mask[lvl];
pte &= ~pte_lx_map_paddr_mask[lvl];
} else {
#ifdef CONFIG_LIBUKDEBUG
UK_ASSERT(lvl > PAGE_LEVEL && lvl < PT_LEVELS);
#endif /* CONFIG_LIBUKDEBUG */
paddr &= PTE_Lx_TABLE_PADDR_MASK;
pte &= ~PTE_Lx_TABLE_PADDR_MASK;
}
return pte | paddr;
}

static inline int ukarch_paddr_range_isvalid(__paddr_t start, __paddr_t end)
{
#ifdef CONFIG_LIBUKDEBUG
Expand Down
3 changes: 1 addition & 2 deletions lib/ukvmem/Config.uk
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ menuconfig LIBUKVMEM
select LIBUKDEBUG
select LIBUKALLOC
select LIBISRLIB
# ARM architecture is not yet compatible
depends on ARCH_X86_64
select PAGING
help
This library implements virtual address management by
providing methods for working with virtual address space
Expand Down
2 changes: 2 additions & 0 deletions lib/ukvmem/Makefile.uk
Original file line number Diff line number Diff line change
Expand Up @@ -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)),)
Expand Down
54 changes: 54 additions & 0 deletions lib/ukvmem/arch/arm/pagefault64.c
Original file line number Diff line number Diff line change
@@ -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);

0 comments on commit ab8624f

Please sign in to comment.