2
0

hostmem-file.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * QEMU Host Memory Backend for hugetlbfs
  3. *
  4. * Copyright (C) 2013-2014 Red Hat Inc
  5. *
  6. * Authors:
  7. * Paolo Bonzini <pbonzini@redhat.com>
  8. *
  9. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  10. * See the COPYING file in the top-level directory.
  11. */
  12. #include "qemu-common.h"
  13. #include "sysemu/hostmem.h"
  14. #include "sysemu/sysemu.h"
  15. #include "qom/object_interfaces.h"
  16. /* hostmem-file.c */
  17. /**
  18. * @TYPE_MEMORY_BACKEND_FILE:
  19. * name of backend that uses mmap on a file descriptor
  20. */
  21. #define TYPE_MEMORY_BACKEND_FILE "memory-backend-file"
  22. #define MEMORY_BACKEND_FILE(obj) \
  23. OBJECT_CHECK(HostMemoryBackendFile, (obj), TYPE_MEMORY_BACKEND_FILE)
  24. typedef struct HostMemoryBackendFile HostMemoryBackendFile;
  25. struct HostMemoryBackendFile {
  26. HostMemoryBackend parent_obj;
  27. bool share;
  28. char *mem_path;
  29. };
  30. static void
  31. file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
  32. {
  33. HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(backend);
  34. if (!backend->size) {
  35. error_setg(errp, "can't create backend with size 0");
  36. return;
  37. }
  38. if (!fb->mem_path) {
  39. error_setg(errp, "mem_path property not set");
  40. return;
  41. }
  42. #ifndef CONFIG_LINUX
  43. error_setg(errp, "-mem-path not supported on this host");
  44. #else
  45. if (!memory_region_size(&backend->mr)) {
  46. backend->force_prealloc = mem_prealloc;
  47. memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
  48. object_get_canonical_path(OBJECT(backend)),
  49. backend->size, fb->share,
  50. fb->mem_path, errp);
  51. }
  52. #endif
  53. }
  54. static void
  55. file_backend_class_init(ObjectClass *oc, void *data)
  56. {
  57. HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
  58. bc->alloc = file_backend_memory_alloc;
  59. }
  60. static char *get_mem_path(Object *o, Error **errp)
  61. {
  62. HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
  63. return g_strdup(fb->mem_path);
  64. }
  65. static void set_mem_path(Object *o, const char *str, Error **errp)
  66. {
  67. HostMemoryBackend *backend = MEMORY_BACKEND(o);
  68. HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
  69. if (memory_region_size(&backend->mr)) {
  70. error_setg(errp, "cannot change property value");
  71. return;
  72. }
  73. if (fb->mem_path) {
  74. g_free(fb->mem_path);
  75. }
  76. fb->mem_path = g_strdup(str);
  77. }
  78. static bool file_memory_backend_get_share(Object *o, Error **errp)
  79. {
  80. HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
  81. return fb->share;
  82. }
  83. static void file_memory_backend_set_share(Object *o, bool value, Error **errp)
  84. {
  85. HostMemoryBackend *backend = MEMORY_BACKEND(o);
  86. HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
  87. if (memory_region_size(&backend->mr)) {
  88. error_setg(errp, "cannot change property value");
  89. return;
  90. }
  91. fb->share = value;
  92. }
  93. static void
  94. file_backend_instance_init(Object *o)
  95. {
  96. object_property_add_bool(o, "share",
  97. file_memory_backend_get_share,
  98. file_memory_backend_set_share, NULL);
  99. object_property_add_str(o, "mem-path", get_mem_path,
  100. set_mem_path, NULL);
  101. }
  102. static const TypeInfo file_backend_info = {
  103. .name = TYPE_MEMORY_BACKEND_FILE,
  104. .parent = TYPE_MEMORY_BACKEND,
  105. .class_init = file_backend_class_init,
  106. .instance_init = file_backend_instance_init,
  107. .instance_size = sizeof(HostMemoryBackendFile),
  108. };
  109. static void register_types(void)
  110. {
  111. type_register_static(&file_backend_info);
  112. }
  113. type_init(register_types);