UserOrKernelBuffer.cpp 2.2 KB

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