blob: 03df28b964314a81d9a6ecc7a5ba042f367c309e [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <assert.h>
#include <string.h>
#include <trace.h>
#include <arch/user_copy.h>
#include <arch/arm64/user_copy.h>
#include <kernel/thread.h>
#include <kernel/vm.h>
#define LOCAL_TRACE 0
status_t arch_copy_from_user(void *dst, const void *src, size_t len)
{
// We check if the address is a user pointer, since when ldtr/sttr
// cause a data fault, they do not indicate if the fault was caused
// by an access attempt to a privileged address. Because of this, we
// don't know if the user copy failed due to being a bad address or
// if we just need to run the page fault handler and try again. This
// check lets us skip the ambiguity and always try to run the page fault
// handler (since the fault will always be from trying to access an
// unprivileged page).
if (!is_user_address_range((vaddr_t)src, len)) {
return ZX_ERR_INVALID_ARGS;
}
thread_t *thr = get_current_thread();
status_t status =
_arm64_copy_from_user(dst, src, len, &thr->arch.data_fault_resume);
return status;
}
status_t arch_copy_to_user(void *dst, const void *src, size_t len)
{
if (!is_user_address_range((vaddr_t)dst, len)) {
return ZX_ERR_INVALID_ARGS;
}
thread_t *thr = get_current_thread();
status_t status =
_arm64_copy_to_user(dst, src, len, &thr->arch.data_fault_resume);
return status;
}