[PATCH v5 3/4] kvm: decode the argument for KVM_{SET, GET}_SREGS ioctl command

Dmitry V. Levin ldv at altlinux.org
Fri Dec 8 02:54:20 UTC 2017


On Thu, Dec 07, 2017 at 11:03:34PM +0900, Masatake YAMATO wrote:
> * configure.ac (AC_CHECK_TYPES): Add struct kvm_sregs.
> * kvm.c (kvm_ioctl_decode_regs_segment): New function.
> (kvm_ioctl) <KVM_SET_SREGS, KVM_GET_SREGS>: Use it.
> * linux/arch_kvm.c (arch_print_kvm_sregs): New function.
> * linux/x86_64/arch_kvm.c (PRINT_FIELD_KVM_SREGS_STRUCT): New macro.
> (arch_print_kvm_sregs): New function.
> (kvm_ioctl_decode_regs_dtable): Ditto.
> (kvm_ioctl_decode_regs_segment): Ditto.
> 
> Changes in v2:
> * Decode only if struct kvm_sregs is available.
> * Put arch-specific and generic stub decoders to arch_kvm.c.
> * Use umove_or_printaddr instead of umove.
> 
>     Above 3 items are suggested by ldv.
> 
> * Use more const modifiers.
> 
> Change in v3:
> * Put ifdef guards around codes using kvm_sregs.
>   Suggested by ldv.
> 
> Highlights in v4:
> * Guards the case label with ifdef HAVE_STRUCT_KVM_SREGS.
> * Fix a critical typo s/HAVE_STRUCT_KVM_REGS/HAVE_STRUCT_KVM_SREGS/.
> * Fix a critical typo s/kvm_regs/kvm_sregs/.
> * Introduce PRINT_FIELD_KVM_SREGS_STRUCT macro for simplifying
>   the code for decoding sregs.
> 
> Changes in v5:
> * Don't return RVAL_DECODED if the decoder prints something.
>   Suggested by ldv.
> 
> Signed-off-by: Masatake YAMATO <yamato at redhat.com>
> ---
>  configure.ac            |  5 ++--
>  kvm.c                   | 23 ++++++++++++++++
>  linux/arch_kvm.c        | 11 ++++++++
>  linux/x86_64/arch_kvm.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 109 insertions(+), 2 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 5103d479..729ef3f7 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -542,8 +542,9 @@ AC_CHECK_TYPES([struct statfs64], [
>  AC_CHECK_TYPES([struct blk_user_trace_setup],,, [#include <linux/blktrace_api.h>])
>  
>  AC_CHECK_TYPES(m4_normalize([
> -	struct kvm_regs
> -	struct kvm_userspace_memory_region,
> +	struct kvm_regs,
> +	struct kvm_sregs,
> +	struct kvm_userspace_memory_region
>  ]),,, [#include <linux/kvm.h>])
>  
>  AC_CHECK_HEADERS([linux/btrfs.h], [
> diff --git a/kvm.c b/kvm.c
> index 5731cc25..987e7815 100644
> --- a/kvm.c
> +++ b/kvm.c
> @@ -84,6 +84,23 @@ kvm_ioctl_decode_regs(struct tcb *const tcp, const unsigned int code, const kern
>  }
>  # endif /* HAVE_STRUCT_KVM_REGS */
>  
> +# ifdef HAVE_STRUCT_KVM_SREGS
> +static int
> +kvm_ioctl_decode_sregs(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
> +{
> +	struct kvm_sregs sregs;
> +
> +	if (code == KVM_GET_SREGS && entering(tcp))
> +		return 0;
> +
> +	tprints(", ");
> +	if (!umove_or_printaddr(tcp, arg, &sregs))
> +		arch_print_kvm_sregs(tcp, arg, &sregs);
> +
> +	return RVAL_IOCTL_DECODED;
> +}
> +# endif	/* HAVE_STRUCT_KVM_SREGS */
> +
>  int
>  kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
>  {
> @@ -102,6 +119,12 @@ kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t a
>  		return kvm_ioctl_decode_regs(tcp, code, arg);
>  # endif
>  
> +# ifdef HAVE_STRUCT_KVM_SREGS
> +	case KVM_SET_SREGS:
> +	case KVM_GET_SREGS:
> +		return kvm_ioctl_decode_sregs(tcp, code, arg);
> +# endif
> +
>  	case KVM_CREATE_VM:
>  		return RVAL_DECODED | RVAL_FD;
>  	case KVM_RUN:
> diff --git a/linux/arch_kvm.c b/linux/arch_kvm.c
> index d1292a5b..bb1119a4 100644
> --- a/linux/arch_kvm.c
> +++ b/linux/arch_kvm.c
> @@ -7,3 +7,14 @@ arch_print_kvm_regs(struct tcb *const tcp,
>  	printaddr(addr);
>  }
>  #endif	/* HAVE_STRUCT_KVM_REGS */
> +
> +#ifdef HAVE_STRUCT_KVM_SREGS
> +static void
> +arch_print_kvm_sregs(struct tcb *const tcp,
> +		    const kernel_ulong_t addr,
> +		    const struct kvm_sregs *const sregs)
> +{
> +	printaddr(addr);
> +}
> +#endif	/* HAVE_STRUCT_KVM_SREGS */
> +

My .git/config contains the following two lines

[apply]
        whitespace = error-all

I removed the empty line at EOF to fix this whitespace error.

> diff --git a/linux/x86_64/arch_kvm.c b/linux/x86_64/arch_kvm.c
> index f5ade5d8..d76ca034 100644
> --- a/linux/x86_64/arch_kvm.c
> +++ b/linux/x86_64/arch_kvm.c
> @@ -36,3 +36,75 @@ arch_print_kvm_regs(struct tcb *const tcp,
>  	tprints("}");
>  }
>  #endif	/* HAVE_STRUCT_KVM_REGS */
> +
> +#ifdef HAVE_STRUCT_KVM_SREGS
> +static void
> +kvm_ioctl_decode_regs_segment(const char *prefix,
> +			      const struct kvm_segment *const segment)
> +{
> +	tprints(prefix);
> +	PRINT_FIELD_X("={", *segment, base);
> +	PRINT_FIELD_U(", ", *segment, limit);
> +	PRINT_FIELD_U(", ", *segment, selector);
> +	PRINT_FIELD_U(", ", *segment, type);
> +	PRINT_FIELD_U(", ", *segment, present);
> +	PRINT_FIELD_U(", ", *segment, dpl);
> +	PRINT_FIELD_U(", ", *segment, db);
> +	PRINT_FIELD_U(", ", *segment, s);
> +	PRINT_FIELD_U(", ", *segment, l);
> +	PRINT_FIELD_U(", ", *segment, g);
> +	PRINT_FIELD_U(", ", *segment, avl);
> +	tprints("}");
> +}
> +
> +static void
> +kvm_ioctl_decode_regs_dtable(const char *prefix,
> +			     const struct kvm_dtable *const dtable)
> +{
> +	tprints(prefix);
> +	PRINT_FIELD_X("={", *dtable, base);
> +	PRINT_FIELD_U(", ", *dtable, limit);
> +	tprints("}");
> +}
> +
> +# define PRINT_FIELD_KVM_SREGS_STRUCT(prefix_, where_, type_, field_)	\
> +  kvm_ioctl_decode_regs_ ## type_(prefix_ #field_, &(where_)->field_)
> +
> +static void
> +arch_print_kvm_sregs(struct tcb *const tcp,
> +		     const kernel_ulong_t addr,
> +		     const struct kvm_sregs *const sregs)
> +{
> +	PRINT_FIELD_KVM_SREGS_STRUCT("{", sregs, segment, cs);
> +	if (abbrev(tcp)) {
> +		tprints(", ...}");
> +		return;
> +	}
> +
> +	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, ds);
> +	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, es);
> +	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, fs);
> +	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, gs);
> +	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, ss);
> +	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, tr);
> +	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, segment, ldt);
> +	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, dtable, gdt);
> +	PRINT_FIELD_KVM_SREGS_STRUCT(", ", sregs, dtable, idt);
> +	PRINT_FIELD_U(", ", *sregs, cr0);
> +	PRINT_FIELD_U(", ", *sregs, cr2);
> +	PRINT_FIELD_U(", ", *sregs, cr3);
> +	PRINT_FIELD_U(", ", *sregs, cr4);
> +	PRINT_FIELD_U(", ", *sregs, cr8);
> +	PRINT_FIELD_U(", ", *sregs, efer);
> +	PRINT_FIELD_X(", ", *sregs, apic_base);
> +	tprints(", interrupt_bitmap=[");
> +
> +	unsigned int i;
> +	for (i = 0; i < ARRAY_SIZE(sregs->interrupt_bitmap); i++) {
> +		if (i != 0)
> +			tprints(", ");
> +		tprintf("%#" PRI__x64, sregs->interrupt_bitmap[i]);
> +	}
> +	tprints("]}");
> +}
> +#endif	/* HAVE_STRUCT_KVM_SREGS */

Applied, thanks.


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20171208/d182db8f/attachment.bin>


More information about the Strace-devel mailing list