[COMMIT master] api: add memory map management

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Avi Kivity <avi@xxxxxxxxxx>

Add a class to manage the memory map and a class to represent
a memory slot.

Signed-off-by: Avi Kivity <avi@xxxxxxxxxx>
Signed-off-by: Marcelo Tosatti <mtosatti@xxxxxxxxxx>

diff --git a/api/memmap.cc b/api/memmap.cc
new file mode 100644
index 0000000..c625852
--- /dev/null
+++ b/api/memmap.cc
@@ -0,0 +1,76 @@
+
+#include "memmap.hh"
+
+mem_slot::mem_slot(mem_map& map, uint64_t gpa, uint64_t size, void* hva)
+    : _map(map)
+    , _slot(map._free_slots.top())
+    , _gpa(gpa)
+    , _size(size)
+    , _hva(hva)
+    , _dirty_log_enabled(false)
+    , _log()
+{
+    map._free_slots.pop();
+    update();
+}
+
+mem_slot::~mem_slot()
+{
+    _size = 0;
+    try {
+        update();
+        _map._free_slots.push(_slot);
+    } catch (...) {
+        // can't do much if we can't undo slot registration - leak the slot
+    }
+}
+
+void mem_slot::set_dirty_logging(bool enabled)
+{
+    if (_dirty_log_enabled != enabled) {
+        _dirty_log_enabled = enabled;
+        if (enabled) {
+            int logsize = ((_size >> 12) + bits_per_word - 1) / bits_per_word;
+            _log.resize(logsize);
+        } else {
+            _log.resize(0);
+        }
+        update();
+    }
+}
+
+void mem_slot::update()
+{
+    uint32_t flags = 0;
+    if (_dirty_log_enabled) {
+        flags |= KVM_MEM_LOG_DIRTY_PAGES;
+    }
+    _map._vm.set_memory_region(_slot, _hva, _gpa, _size, flags);
+}
+
+bool mem_slot::dirty_logging() const
+{
+    return _dirty_log_enabled;
+}
+
+void mem_slot::update_dirty_log()
+{
+    _map._vm.get_dirty_log(_slot, &_log[0]);
+}
+
+bool mem_slot::is_dirty(uint64_t gpa) const
+{
+    uint64_t pagenr = (gpa - _gpa) >> 12;
+    ulong wordnr = pagenr / bits_per_word;
+    ulong bit = 1ULL << (pagenr % bits_per_word);
+    return _log[wordnr] & bit;
+}
+
+mem_map::mem_map(kvm::vm& vm)
+    : _vm(vm)
+{
+    int nr_slots = vm.sys().get_extension_int(KVM_CAP_NR_MEMSLOTS);
+    for (int i = 0; i < nr_slots; ++i) {
+        _free_slots.push(i);
+    }
+}
diff --git a/api/memmap.hh b/api/memmap.hh
new file mode 100644
index 0000000..59ec619
--- /dev/null
+++ b/api/memmap.hh
@@ -0,0 +1,43 @@
+#ifndef MEMMAP_HH
+#define MEMMAP_HH
+
+#include "kvmxx.hh"
+#include <stdint.h>
+#include <vector>
+#include <stack>
+
+class mem_map;
+class mem_slot;
+
+class mem_slot {
+public:
+    mem_slot(mem_map& map, uint64_t gpa, uint64_t size, void *hva);
+    ~mem_slot();
+    void set_dirty_logging(bool enabled);
+    bool dirty_logging() const;
+    void update_dirty_log();
+    bool is_dirty(uint64_t gpa) const;
+private:
+    void update();
+private:
+    typedef unsigned long ulong;
+    static const int bits_per_word = sizeof(ulong) * 8;
+    mem_map& _map;
+    int _slot;
+    uint64_t _gpa;
+    uint64_t _size;
+    void *_hva;
+    bool _dirty_log_enabled;
+    std::vector<ulong> _log;
+};
+
+class mem_map {
+public:
+    mem_map(kvm::vm& vm);
+private:
+    kvm::vm& _vm;
+    std::stack<int> _free_slots;
+    friend class mem_slot;
+};
+
+#endif
--
To unsubscribe from this list: send the line "unsubscribe kvm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM Development]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Walks]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux