From: "Michael S. Tsirkin" <mst@redhat.com>
To: Avi Kivity <avi@redhat.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>, kvm@vger.kernel.org
Subject: Re: [PATCH kvm-unit-tests 2/4] Introduce a C++ wrapper for the kvm APIs
Date: Fri, 26 Nov 2010 12:16:25 +0200 [thread overview]
Message-ID: <20101126101625.GA3657@redhat.com> (raw)
In-Reply-To: <1290595933-13122-3-git-send-email-avi@redhat.com>
On Wed, Nov 24, 2010 at 12:52:11PM +0200, Avi Kivity wrote:
> Introduce exception-safe objects for calling system, vm, and vcpu ioctls.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>
ioctlp calls below ignore possible errors.
Somre more comments below.
> ---
> api/kvmxx.cc | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> api/kvmxx.h | 80 +++++++++++++++++++++++++++
> 2 files changed, 248 insertions(+), 0 deletions(-)
> create mode 100644 api/kvmxx.cc
> create mode 100644 api/kvmxx.h
>
> diff --git a/api/kvmxx.cc b/api/kvmxx.cc
> new file mode 100644
> index 0000000..2f8fc27
> --- /dev/null
> +++ b/api/kvmxx.cc
> @@ -0,0 +1,168 @@
> +#include "kvmxx.h"
> +#include <fcntl.h>
> +#include <sys/ioctl.h>
> +#include <sys/mman.h>
> +#include <memory>
> +#include <algorithm>
> +
> +namespace kvm {
> +
> +static long check_error(long r)
> +{
> + if (r == -1) {
> + throw errno;
> + }
> + return r;
> +}
> +
> +fd::fd(int fd)
> + : _fd(fd)
> +{
> +}
> +
> +fd::fd(const fd& other)
> + : _fd(::dup(other._fd))
> +{
> + check_error(_fd);
> +}
> +
> +fd::fd(std::string device_node, int flags)
> + : _fd(::open(device_node.c_str(), flags))
> +{
> + check_error(_fd);
> +}
> +
> +long fd::ioctl(unsigned nr, long arg)
> +{
> + return check_error(::ioctl(_fd, nr, arg));
> +}
> +
> +vcpu::vcpu(vm& vm, int id)
> + : _vm(vm), _fd(vm._fd.ioctl(KVM_CREATE_VCPU, id)), _shared(NULL)
> +{
> + unsigned mmap_size = _vm._system._fd.ioctl(KVM_GET_VCPU_MMAP_SIZE, 0);
> + kvm_run *shared = static_cast<kvm_run*>(::mmap(NULL, mmap_size,
> + PROT_READ | PROT_WRITE,
> + MAP_SHARED,
> + _fd.get(), 0));
> + if (shared == MAP_FAILED) {
> + throw errno;
> + }
> + _shared = shared;
> +}
> +
> +vcpu::~vcpu()
> +{
> + unsigned mmap_size = _vm._system._fd.ioctl(KVM_GET_VCPU_MMAP_SIZE, 0);
This might throw an exception on destructor path, if this happens
because an exception was thrown terminate is called.
> + munmap(_shared, mmap_size);
> +}
> +
> +void vcpu::run()
> +{
> + _fd.ioctl(KVM_RUN, 0);
> +}
> +
> +kvm_regs vcpu::regs()
> +{
> + kvm_regs regs;
> + _fd.ioctlp(KVM_GET_REGS, ®s);
> + return regs;
> +}
> +
> +void vcpu::set_regs(const kvm_regs& regs)
> +{
> + _fd.ioctlp(KVM_SET_REGS, const_cast<kvm_regs*>(®s));
> +}
> +
> +kvm_sregs vcpu::sregs()
> +{
> + kvm_sregs sregs;
> + _fd.ioctlp(KVM_GET_SREGS, &sregs);
> + return sregs;
> +}
> +
> +void vcpu::set_sregs(const kvm_sregs& sregs)
> +{
> + _fd.ioctlp(KVM_SET_SREGS, const_cast<kvm_sregs*>(&sregs));
> +}
> +
> +kvm_msrs* vcpu::alloc_msr_list(size_t nmsrs)
> +{
> + size_t size = sizeof(kvm_msrs) + sizeof(kvm_msr_entry) * nmsrs;
> + kvm_msrs* ret = static_cast<kvm_msrs*>(malloc(size));
> + if (!ret) {
> + throw ENOMEM;
> + }
> + return ret;
> +}
> +
> +std::vector<kvm_msr_entry> vcpu::msrs(std::vector<uint32_t> indices)
> +{
> + std::auto_ptr<kvm_msrs> msrs(alloc_msr_list(indices.size()));
This looks wrong. auto_ptr frees memory with delete,
alloc_msr_list allocates it with malloc.
> + msrs->nmsrs = indices.size();
> + for (unsigned i = 0; i < msrs->nmsrs; ++i) {
> + msrs->entries[i].index = indices[i];
> + }
> + _fd.ioctlp(KVM_GET_MSRS, msrs.get());
> + return std::vector<kvm_msr_entry>(msrs->entries,
> + msrs->entries + msrs->nmsrs);
> +}
> +
> +void vcpu::set_msrs(const std::vector<kvm_msr_entry>& msrs)
> +{
> + std::auto_ptr<kvm_msrs> _msrs(alloc_msr_list(msrs.size()));
As above.
> + _msrs->nmsrs = msrs.size();
> + std::copy(msrs.begin(), msrs.end(), _msrs->entries);
> + _fd.ioctlp(KVM_SET_MSRS, _msrs.get());
> +}
> +
> +void vcpu::set_debug(uint64_t dr[8], bool enabled, bool singlestep)
> +{
> + kvm_guest_debug gd;
> +
> + gd.control = 0;
> + if (enabled) {
> + gd.control |= KVM_GUESTDBG_ENABLE;
> + }
> + if (singlestep) {
> + gd.control |= KVM_GUESTDBG_SINGLESTEP;
> + }
> + for (int i = 0; i < 8; ++i) {
> + gd.arch.debugreg[i] = dr[i];
> + }
> + _fd.ioctlp(KVM_SET_GUEST_DEBUG, &gd);
> +}
> +
> +vm::vm(system& system)
> + : _system(system), _fd(system._fd.ioctl(KVM_CREATE_VM, 0))
> +{
> +}
> +
> +void vm::set_memory_region(int slot, void *addr, uint64_t gpa, size_t len)
> +{
> + struct kvm_userspace_memory_region umr;
> +
> + umr.slot = slot;
> + umr.flags = 0;
> + umr.guest_phys_addr = gpa;
> + umr.memory_size = len;
> + umr.userspace_addr = reinterpret_cast<uint64_t>(addr);
> + _fd.ioctlp(KVM_SET_USER_MEMORY_REGION, &umr);
> +}
> +
> +void vm::set_tss_addr(uint32_t addr)
> +{
> + _fd.ioctl(KVM_SET_TSS_ADDR, addr);
> +}
> +
> +system::system(std::string device_node)
> + : _fd(device_node, O_RDWR)
> +{
> +}
> +
> +bool system::check_extension(int extension)
> +{
> + return _fd.ioctl(KVM_CHECK_EXTENSION, extension);
> +}
> +
> +};
> diff --git a/api/kvmxx.h b/api/kvmxx.h
> new file mode 100644
> index 0000000..716e400
> --- /dev/null
> +++ b/api/kvmxx.h
> @@ -0,0 +1,80 @@
> +#ifndef KVMXX_H
> +#define KVMXX_H
> +
> +#include <string>
> +#include <signal.h>
> +#include <unistd.h>
> +#include <vector>
> +#include <errno.h>
> +#include <linux/kvm.h>
> +#include <stdint.h>
> +
> +namespace kvm {
> +
> +class system;
> +class vm;
> +class vcpu;
> +class fd;
> +
> +class fd {
> +public:
> + explicit fd(int n);
> + explicit fd(std::string path, int flags);
> + fd(const fd& other);
> + ~fd() { ::close(_fd); }
> + int get() { return _fd; }
> + long ioctl(unsigned nr, long arg);
> + long ioctlp(unsigned nr, void *arg) {
> + return ioctl(nr, reinterpret_cast<long>(arg));
> + }
> +private:
> + int _fd;
> +};
> +
> +class vcpu {
> +public:
> + vcpu(vm& vm, int fd);
> + ~vcpu();
> + void run();
> + kvm_run *shared();
> + kvm_regs regs();
> + void set_regs(const kvm_regs& regs);
> + kvm_sregs sregs();
> + void set_sregs(const kvm_sregs& sregs);
> + std::vector<kvm_msr_entry> msrs(std::vector<uint32_t> indices);
> + void set_msrs(const std::vector<kvm_msr_entry>& msrs);
> + void set_debug(uint64_t dr[8], bool enabled, bool singlestep);
> +private:
> + static kvm_msrs* alloc_msr_list(size_t nmsrs);
> +private:
> + vm& _vm;
> + fd _fd;
> + kvm_run *_shared;
> + friend class vm;
> +};
> +
> +class vm {
> +public:
> + explicit vm(system& system);
> + void set_memory_region(int slot, void *addr, uint64_t gpa, size_t len);
> + void set_tss_addr(uint32_t addr);
> +private:
> + system& _system;
> + fd _fd;
> + friend class system;
> + friend class vcpu;
> +};
> +
> +class system {
> +public:
> + explicit system(std::string device_node = "/dev/kvm");
> + bool check_extension(int extension);
> +private:
> + fd _fd;
> + friend class vcpu;
> + friend class vm;
> +};
> +
> +};
> +
> +#endif
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2010-11-26 10:16 UTC|newest]
Thread overview: 130+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-24 10:52 [PATCH kvm-unit-tests 0/4] API test framework Avi Kivity
2010-11-24 10:52 ` [PATCH kvm-unit-tests 1/4] Makefile: add support for C++ Avi Kivity
2010-11-24 10:52 ` [PATCH kvm-unit-tests 2/4] Introduce a C++ wrapper for the kvm APIs Avi Kivity
2010-11-24 12:59 ` Alexander Graf
2010-11-24 13:33 ` Gleb Natapov
2010-11-24 14:18 ` Anthony Liguori
2010-11-24 14:24 ` Anthony Liguori
2010-11-24 14:32 ` Avi Kivity
2010-11-24 14:31 ` Avi Kivity
2010-11-24 14:41 ` Anthony Liguori
2010-11-24 15:40 ` Gleb Natapov
2010-11-24 15:50 ` Anthony Liguori
2010-11-24 16:10 ` Avi Kivity
2010-12-02 13:52 ` Mike Day
2010-11-24 16:12 ` [PATCH kvm-unit-tests 2/4] " Gleb Natapov
2010-11-24 16:14 ` Avi Kivity
2010-11-24 16:21 ` Gleb Natapov
2010-11-24 16:25 ` Avi Kivity
2010-11-24 16:29 ` Gleb Natapov
2010-11-24 16:33 ` Avi Kivity
2010-11-24 16:52 ` Gleb Natapov
2010-11-24 16:56 ` Avi Kivity
2010-11-24 17:02 ` Gleb Natapov
2010-11-24 17:07 ` Avi Kivity
2010-11-24 17:10 ` Jes Sorensen
2010-11-24 17:12 ` Avi Kivity
2010-11-24 17:14 ` Anthony Liguori
2010-11-24 16:43 ` Anthony Liguori
2010-11-24 16:48 ` Gleb Natapov
2010-11-24 16:56 ` Anthony Liguori
2010-11-24 17:04 ` Gleb Natapov
2010-11-24 16:40 ` Anthony Liguori
2010-11-24 17:33 ` Gleb Natapov
2010-11-24 17:39 ` Avi Kivity
2010-11-24 17:41 ` Gleb Natapov
2010-11-24 17:50 ` Avi Kivity
2010-11-24 18:23 ` Gleb Natapov
2010-11-24 18:50 ` Avi Kivity
2010-11-24 18:17 ` Anthony Liguori
2010-11-24 18:34 ` Gleb Natapov
2010-11-24 18:53 ` Anthony Liguori
2010-11-25 8:35 ` Gleb Natapov
2010-11-24 16:40 ` Jes Sorensen
2010-11-24 16:47 ` Avi Kivity
2010-11-24 16:51 ` Jes Sorensen
2010-11-24 16:57 ` Anthony Liguori
2010-11-24 17:29 ` Avi Kivity
2010-11-24 16:59 ` Avi Kivity
2010-11-24 17:06 ` Jes Sorensen
2010-11-24 17:11 ` Avi Kivity
2010-11-24 17:17 ` Jes Sorensen
2010-11-24 17:25 ` Avi Kivity
2010-11-24 17:28 ` Jes Sorensen
2010-11-24 17:31 ` Avi Kivity
2010-11-24 17:36 ` Gleb Natapov
2010-11-24 17:41 ` Avi Kivity
2010-11-24 17:27 ` Anthony Liguori
2010-11-24 17:35 ` Avi Kivity
2010-11-24 17:36 ` Jes Sorensen
2010-11-24 17:41 ` Avi Kivity
2010-11-24 17:43 ` Gleb Natapov
2010-11-24 17:50 ` Avi Kivity
2010-11-24 18:10 ` Gleb Natapov
2010-11-24 18:55 ` Avi Kivity
2010-11-24 19:29 ` Jes Sorensen
2010-11-24 19:33 ` Avi Kivity
2010-11-24 17:43 ` Jes Sorensen
2010-11-24 17:51 ` Avi Kivity
2010-11-24 17:43 ` Anthony Liguori
2010-11-24 17:45 ` Jes Sorensen
2010-11-24 17:51 ` Avi Kivity
2010-11-24 18:01 ` Anthony Liguori
2010-11-24 18:56 ` Avi Kivity
2010-11-24 16:55 ` Gleb Natapov
2010-11-24 17:01 ` Avi Kivity
2010-11-24 17:16 ` Gleb Natapov
2010-11-24 17:26 ` Avi Kivity
2010-11-24 16:53 ` Anthony Liguori
2010-11-24 17:03 ` Jes Sorensen
2010-11-28 12:27 ` Michael S. Tsirkin
2010-11-28 22:04 ` Anthony Liguori
2010-11-28 22:28 ` Michael S. Tsirkin
2010-11-28 23:13 ` Anthony Liguori
2010-11-29 8:04 ` Michael S. Tsirkin
2010-11-29 13:44 ` Anthony Liguori
2010-11-29 13:48 ` Avi Kivity
2010-11-24 16:29 ` Jes Sorensen
2010-11-24 16:34 ` Avi Kivity
2010-11-24 16:44 ` Jes Sorensen
2010-11-24 16:49 ` Avi Kivity
2010-11-28 11:59 ` Michael S. Tsirkin
2010-11-28 13:02 ` Avi Kivity
2010-11-28 13:57 ` Michael S. Tsirkin
2010-11-28 14:34 ` Avi Kivity
2010-11-28 16:57 ` Michael S. Tsirkin
2010-11-29 9:22 ` Avi Kivity
2010-11-29 10:47 ` Michael S. Tsirkin
2010-11-29 10:52 ` Avi Kivity
2010-11-29 11:26 ` Michael S. Tsirkin
2010-11-29 13:38 ` Anthony Liguori
2010-11-24 14:10 ` Anthony Liguori
2010-11-24 14:29 ` Avi Kivity
2010-11-24 14:45 ` Anthony Liguori
2010-11-24 14:53 ` Avi Kivity
2010-11-24 14:55 ` Anthony Liguori
2010-11-25 16:32 ` Avi Kivity
2010-11-26 10:16 ` Michael S. Tsirkin [this message]
[not found] ` <4CF0CB9A.5060403@redhat.com>
2010-11-28 8:58 ` Michael S. Tsirkin
2010-11-28 9:31 ` Avi Kivity
2010-11-28 9:50 ` Michael S. Tsirkin
2010-11-28 9:54 ` Avi Kivity
2010-11-28 11:44 ` Michael S. Tsirkin
2010-11-28 13:14 ` Avi Kivity
2010-11-28 14:40 ` Michael S. Tsirkin
2010-11-28 22:12 ` Anthony Liguori
2010-11-29 9:30 ` Avi Kivity
2010-11-28 11:49 ` Michael S. Tsirkin
2010-11-28 13:15 ` Avi Kivity
2010-11-28 14:49 ` Michael S. Tsirkin
2010-11-29 9:30 ` Avi Kivity
2010-11-24 10:52 ` [PATCH kvm-unit-tests 3/4] Add support for calling a function in guest mode Avi Kivity
2010-11-26 14:17 ` Michael S. Tsirkin
[not found] ` <4CF0CC26.8030407@redhat.com>
2010-11-28 8:59 ` Michael S. Tsirkin
2010-11-28 9:22 ` Avi Kivity
2010-11-24 10:52 ` [PATCH kvm-unit-tests 4/4] Add sample test using the api test harness Avi Kivity
2010-11-26 14:17 ` Michael S. Tsirkin
[not found] ` <4CF0CC4A.8070100@redhat.com>
2010-11-28 9:04 ` Michael S. Tsirkin
2010-11-28 9:21 ` Avi Kivity
2010-11-29 16:09 ` [PATCH kvm-unit-tests 0/4] API test framework Marcelo Tosatti
2010-12-01 10:38 ` Avi Kivity
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=20101126101625.GA3657@redhat.com \
--to=mst@redhat.com \
--cc=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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.