Serenity Operating System
1/*
2 * Copyright (c) 2020, the SerenityOS developers.
3 * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include <Kernel/Memory/MemoryManager.h>
9#include <Kernel/UserOrKernelBuffer.h>
10
11namespace Kernel {
12
13bool UserOrKernelBuffer::is_kernel_buffer() const
14{
15 return !Memory::is_user_address(VirtualAddress(m_buffer));
16}
17
18ErrorOr<NonnullOwnPtr<KString>> UserOrKernelBuffer::try_copy_into_kstring(size_t size) const
19{
20 if (!m_buffer)
21 return EINVAL;
22 if (Memory::is_user_address(VirtualAddress(m_buffer))) {
23 char* buffer;
24 auto kstring = TRY(KString::try_create_uninitialized(size, buffer));
25 TRY(copy_from_user(buffer, m_buffer, size));
26 return kstring;
27 }
28
29 return KString::try_create(ReadonlyBytes { m_buffer, size });
30}
31
32ErrorOr<void> UserOrKernelBuffer::write(void const* src, size_t offset, size_t len)
33{
34 if (!m_buffer)
35 return EFAULT;
36
37 if (Memory::is_user_address(VirtualAddress(m_buffer)))
38 return copy_to_user(m_buffer + offset, src, len);
39
40 memcpy(m_buffer + offset, src, len);
41 return {};
42}
43
44ErrorOr<void> UserOrKernelBuffer::read(void* dest, size_t offset, size_t len) const
45{
46 if (!m_buffer)
47 return EFAULT;
48
49 if (Memory::is_user_address(VirtualAddress(m_buffer)))
50 return copy_from_user(dest, m_buffer + offset, len);
51
52 memcpy(dest, m_buffer + offset, len);
53 return {};
54}
55
56ErrorOr<void> UserOrKernelBuffer::memset(int value, size_t offset, size_t len)
57{
58 if (!m_buffer)
59 return EFAULT;
60
61 if (Memory::is_user_address(VirtualAddress(m_buffer)))
62 return memset_user(m_buffer + offset, value, len);
63
64 ::memset(m_buffer + offset, value, len);
65 return {};
66}
67
68}