All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
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: Wed, 24 Nov 2010 08:10:14 -0600	[thread overview]
Message-ID: <4CED1CC6.20603@codemonkey.ws> (raw)
In-Reply-To: <1290595933-13122-3-git-send-email-avi@redhat.com>

On 11/24/2010 04:52 AM, Avi Kivity wrote:
> Introduce exception-safe objects for calling system, vm, and vcpu ioctls.
>
> Signed-off-by: Avi Kivity<avi@redhat.com>
> ---
>   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;
> +}
>    

It's generally nicer for exceptions to be objects and to inherit from 
std::exception.  Otherwise, you can run into nasty issues when catching 
the wrong type.

> +fd::fd(int fd)
> +    : _fd(fd)
> +{
> +}
>    

There's no need to prefix with '_'.  Every compiler has been able to do 
the right thing with : fd(fd) for a long time.

> +
> +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);
> +    munmap(_shared, mmap_size);
> +}
> +
> +void vcpu::run()
> +{
> +    _fd.ioctl(KVM_RUN, 0);
> +}
> +
> +kvm_regs vcpu::regs()
> +{
> +    kvm_regs regs;
> +    _fd.ioctlp(KVM_GET_REGS,&regs);
> +    return regs;
> +}
> +
> +void vcpu::set_regs(const kvm_regs&  regs)
> +{
> +    _fd.ioctlp(KVM_SET_REGS, const_cast<kvm_regs*>(&regs));
> +}
> +
> +kvm_sregs vcpu::sregs()
> +{
> +    kvm_sregs sregs;
> +    _fd.ioctlp(KVM_GET_SREGS,&sregs);
> +    return sregs;
> +}
>    

I think you're missing an opportunity by just returning the structures 
in their raw form as opposed to wrapping them in an object.

> +
> +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;
> +}
>    

malloc?

Mixing C and C++ allocations is nasty stuff.  Would be nicer to new an 
object and return it such that delete can be used consistently.

> +
> +std::vector<kvm_msr_entry>  vcpu::msrs(std::vector<uint32_t>  indices)
> +{
> +    std::auto_ptr<kvm_msrs>  msrs(alloc_msr_list(indices.size()));
> +    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);
> +}
>    

auto_ptr has pretty awful semantics.  tr1::shared_ptr is now available.

> +
> +void vcpu::set_msrs(const std::vector<kvm_msr_entry>&  msrs)
> +{
> +    std::auto_ptr<kvm_msrs>  _msrs(alloc_msr_list(msrs.size()));
> +    _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));
> +    }
>    

I think mixing inline definitions with declarations is bad form.

Regards,

Anthony Liguori

> +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
>    


  parent reply	other threads:[~2010-11-24 14:10 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 [this message]
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
     [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=4CED1CC6.20603@codemonkey.ws \
    --to=anthony@codemonkey.ws \
    --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.