From: Avi Kivity <avi@redhat.com>
To: Marcelo Tosatti <mtosatti@redhat.com>, kvm@vger.kernel.org
Subject: [PATCH kvm-unit-tests v2 10/14] api: add memory map management
Date: Wed, 15 Dec 2010 18:09:39 +0200 [thread overview]
Message-ID: <1292429383-15326-11-git-send-email-avi@redhat.com> (raw)
In-Reply-To: <1292429383-15326-1-git-send-email-avi@redhat.com>
Add a class to manage the memory map and a class to represent
a memory slot.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
api/memmap.cc | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
api/memmap.hh | 43 ++++++++++++++++++++++++++++++++
2 files changed, 119 insertions(+), 0 deletions(-)
create mode 100644 api/memmap.cc
create mode 100644 api/memmap.hh
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
--
1.7.1
next prev parent reply other threads:[~2010-12-15 16:10 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-15 16:09 [PATCH kvm-unit-tests v2 00/14] API test framework Avi Kivity
2010-12-15 16:09 ` [PATCH kvm-unit-tests v2 01/14] Makefile: add support for C++ Avi Kivity
2010-12-15 16:09 ` [PATCH kvm-unit-tests v2 02/14] Improve autodepend includes Avi Kivity
2010-12-15 16:09 ` [PATCH kvm-unit-tests v2 03/14] Add exception class for kernel errors (errno) Avi Kivity
2010-12-15 16:09 ` [PATCH kvm-unit-tests v2 04/14] Add try_main() for running a program under an exception handler Avi Kivity
2010-12-15 16:09 ` [PATCH kvm-unit-tests v2 05/14] Introduce a C++ wrapper for the kvm APIs Avi Kivity
2010-12-15 16:09 ` [PATCH kvm-unit-tests v2 06/14] Add support for calling a function in guest mode Avi Kivity
2010-12-15 16:09 ` [PATCH kvm-unit-tests v2 07/14] Add sample test using the api test harness Avi Kivity
2010-12-15 16:09 ` [PATCH kvm-unit-tests v2 08/14] api: add support for KVM_SET_USER_MEMORY_REGION flags field Avi Kivity
2010-12-15 16:09 ` [PATCH kvm-unit-tests v2 09/14] api: support KVM_GET_DIRTY_LOG ioctl Avi Kivity
2010-12-15 16:09 ` Avi Kivity [this message]
2010-12-15 16:09 ` [PATCH kvm-unit-tests v2 11/14] Build tests with debug information Avi Kivity
2010-12-15 16:09 ` [PATCH kvm-unit-tests v2 12/14] api: Add support for creating an identity map with a hole Avi Kivity
2010-12-15 16:09 ` [PATCH kvm-unit-tests v2 13/14] Introduce libapi.a to avoid long Makefile recipes Avi Kivity
2010-12-15 16:09 ` [PATCH kvm-unit-tests v2 14/14] Add dirty log test Avi Kivity
2010-12-22 13:14 ` [PATCH kvm-unit-tests v2 00/14] API test framework Marcelo Tosatti
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1292429383-15326-11-git-send-email-avi@redhat.com \
--to=avi@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=mtosatti@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox