kvm: decode the argument of KVM_{SET, GET}_REGS ioctl command

* configure.ac (AC_CHECK_TYPES): Add struct kvm_regs.
* linux/arck_kvm.c: New file.
* linux/x86_64/arch_kvm.c: Likewise.
* linux/i386/arch_kvm.c: Likewise.
* linux/x32/arch_kvm.c: Likewise.
* Makefile.am (EXTRA_DIST): Add them.
* kvm.c: Include "arch_kvm.c".
[HAVE_STRUCT_KVM_REGS] (kvm_ioctl_decode_regs): New function.
(kvm_ioctl) [HAVE_STRUCT_KVM_REGS] <KVM_SET_REGS, KVM_GET_REGS>: Use it.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
This commit is contained in:
Masatake YAMATO 2017-12-04 22:08:15 +09:00 committed by Dmitry V. Levin
parent d3cc998a05
commit 1d3b9b2c94
7 changed files with 82 additions and 1 deletions

View File

@ -424,6 +424,7 @@ EXTRA_DIST = \
linux/arc/set_error.c \
linux/arc/set_scno.c \
linux/arc/syscallent.h \
linux/arch_kvm.c \
linux/arch_regs.h \
linux/arch_sigreturn.c \
linux/arm/arch_regs.c \
@ -506,6 +507,7 @@ EXTRA_DIST = \
linux/hppa/set_scno.c \
linux/hppa/signalent.h \
linux/hppa/syscallent.h \
linux/i386/arch_kvm.c \
linux/i386/arch_regs.c \
linux/i386/arch_regs.h \
linux/i386/arch_rt_sigframe.c \
@ -805,6 +807,7 @@ EXTRA_DIST = \
linux/unix_diag.h \
linux/userent.h \
linux/userent0.h \
linux/x32/arch_kvm.c \
linux/x32/arch_regs.c \
linux/x32/arch_regs.h \
linux/x32/arch_rt_sigframe.c \
@ -824,6 +827,7 @@ EXTRA_DIST = \
linux/x32/syscallent.h \
linux/x32/syscallent1.h \
linux/x32/userent.h \
linux/x86_64/arch_kvm.c \
linux/x86_64/arch_regs.c \
linux/x86_64/arch_regs.h \
linux/x86_64/arch_rt_sigframe.c \

View File

@ -541,7 +541,10 @@ AC_CHECK_TYPES([struct statfs64], [
AC_CHECK_TYPES([struct blk_user_trace_setup],,, [#include <linux/blktrace_api.h>])
AC_CHECK_TYPES([struct kvm_userspace_memory_region],,, [#include <linux/kvm.h>])
AC_CHECK_TYPES(m4_normalize([
struct kvm_regs,
struct kvm_userspace_memory_region
]),,, [#include <linux/kvm.h>])
AC_CHECK_HEADERS([linux/btrfs.h], [
AC_CHECK_MEMBERS(m4_normalize([

25
kvm.c
View File

@ -33,6 +33,7 @@
#ifdef HAVE_LINUX_KVM_H
# include <linux/kvm.h>
# include "print_fields.h"
# include "arch_kvm.c"
static int
kvm_ioctl_create_vcpu(struct tcb *const tcp, const kernel_ulong_t arg)
@ -66,6 +67,24 @@ kvm_ioctl_set_user_memory_region(struct tcb *const tcp, const kernel_ulong_t arg
}
# endif /* HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION */
# ifdef HAVE_STRUCT_KVM_REGS
static int
kvm_ioctl_decode_regs(struct tcb *const tcp, const unsigned int code,
const kernel_ulong_t arg)
{
struct kvm_regs regs;
if (code == KVM_GET_REGS && entering(tcp))
return 0;
tprints(", ");
if (!umove_or_printaddr(tcp, arg, &regs))
arch_print_kvm_regs(tcp, arg, &regs);
return RVAL_IOCTL_DECODED;
}
# endif /* HAVE_STRUCT_KVM_REGS */
int
kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
{
@ -78,6 +97,12 @@ kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t a
return kvm_ioctl_set_user_memory_region(tcp, arg);
# endif
# ifdef HAVE_STRUCT_KVM_REGS
case KVM_SET_REGS:
case KVM_GET_REGS:
return kvm_ioctl_decode_regs(tcp, code, arg);
# endif
case KVM_CREATE_VM:
return RVAL_DECODED | RVAL_FD;
case KVM_RUN:

9
linux/arch_kvm.c Normal file
View File

@ -0,0 +1,9 @@
#ifdef HAVE_STRUCT_KVM_REGS
static void
arch_print_kvm_regs(struct tcb *const tcp,
const kernel_ulong_t addr,
const struct kvm_regs *const regs)
{
printaddr(addr);
}
#endif /* HAVE_STRUCT_KVM_REGS */

1
linux/i386/arch_kvm.c Normal file
View File

@ -0,0 +1 @@
#include "x86_64/arch_kvm.c"

1
linux/x32/arch_kvm.c Normal file
View File

@ -0,0 +1 @@
#include "x86_64/arch_kvm.c"

38
linux/x86_64/arch_kvm.c Normal file
View File

@ -0,0 +1,38 @@
#ifdef HAVE_STRUCT_KVM_REGS
static void
arch_print_kvm_regs(struct tcb *const tcp,
const kernel_ulong_t addr,
const struct kvm_regs *const regs)
{
PRINT_FIELD_X("{", *regs, rax);
if (abbrev(tcp))
tprints(", ...");
else {
PRINT_FIELD_X(", ", *regs, rbx);
PRINT_FIELD_X(", ", *regs, rcx);
PRINT_FIELD_X(", ", *regs, rdx);
PRINT_FIELD_X(", ", *regs, rsi);
PRINT_FIELD_X(", ", *regs, rdi);
}
PRINT_FIELD_X(", ", *regs, rsp);
PRINT_FIELD_X(", ", *regs, rbp);
if (abbrev(tcp))
tprints(", ...");
else {
PRINT_FIELD_X(", ", *regs, r8);
PRINT_FIELD_X(", ", *regs, r9);
PRINT_FIELD_X(", ", *regs, r10);
PRINT_FIELD_X(", ", *regs, r11);
PRINT_FIELD_X(", ", *regs, r12);
PRINT_FIELD_X(", ", *regs, r13);
PRINT_FIELD_X(", ", *regs, r14);
PRINT_FIELD_X(", ", *regs, r15);
}
PRINT_FIELD_X(", ", *regs, rip);
/* TODO: we can decode this more */
PRINT_FIELD_X(", ", *regs, rflags);
tprints("}");
}
#endif /* HAVE_STRUCT_KVM_REGS */