• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Support for decoding of KVM_* ioctl commands.
3  *
4  * Copyright (c) 2017 Masatake YAMATO <yamato@redhat.com>
5  * Copyright (c) 2017 Red Hat, Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "defs.h"
32 
33 #ifdef HAVE_LINUX_KVM_H
34 # include <linux/kvm.h>
35 # include "print_fields.h"
36 # include "arch_kvm.c"
37 
38 static int
kvm_ioctl_create_vcpu(struct tcb * const tcp,const kernel_ulong_t arg)39 kvm_ioctl_create_vcpu(struct tcb *const tcp, const kernel_ulong_t arg)
40 {
41 	uint32_t cpuid = arg;
42 
43 	tprintf(", %u", cpuid);
44 	return RVAL_IOCTL_DECODED | RVAL_FD;
45 }
46 
47 # ifdef HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION
48 #  include "xlat/kvm_mem_flags.h"
49 static int
kvm_ioctl_set_user_memory_region(struct tcb * const tcp,const kernel_ulong_t arg)50 kvm_ioctl_set_user_memory_region(struct tcb *const tcp, const kernel_ulong_t arg)
51 {
52 	struct kvm_userspace_memory_region u_memory_region;
53 
54 	tprints(", ");
55 	if (umove_or_printaddr(tcp, arg, &u_memory_region))
56 		return RVAL_IOCTL_DECODED;
57 
58 	PRINT_FIELD_U("{", u_memory_region, slot);
59 	PRINT_FIELD_FLAGS(", ", u_memory_region, flags, kvm_mem_flags,
60 			  "KVM_MEM_???");
61 	PRINT_FIELD_X(", ", u_memory_region, guest_phys_addr);
62 	PRINT_FIELD_U(", ", u_memory_region, memory_size);
63 	PRINT_FIELD_X(", ", u_memory_region, userspace_addr);
64 	tprints("}");
65 
66 	return RVAL_IOCTL_DECODED;
67 }
68 # endif /* HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION */
69 
70 # ifdef HAVE_STRUCT_KVM_REGS
71 static int
kvm_ioctl_decode_regs(struct tcb * const tcp,const unsigned int code,const kernel_ulong_t arg)72 kvm_ioctl_decode_regs(struct tcb *const tcp, const unsigned int code,
73 		      const kernel_ulong_t arg)
74 {
75 	struct kvm_regs regs;
76 
77 	if (code == KVM_GET_REGS && entering(tcp))
78 		return 0;
79 
80 	tprints(", ");
81 	if (!umove_or_printaddr(tcp, arg, &regs))
82 		arch_print_kvm_regs(tcp, arg, &regs);
83 
84 	return RVAL_IOCTL_DECODED;
85 }
86 # endif /* HAVE_STRUCT_KVM_REGS */
87 
88 # ifdef HAVE_STRUCT_KVM_SREGS
89 static int
kvm_ioctl_decode_sregs(struct tcb * const tcp,const unsigned int code,const kernel_ulong_t arg)90 kvm_ioctl_decode_sregs(struct tcb *const tcp, const unsigned int code,
91 		       const kernel_ulong_t arg)
92 {
93 	struct kvm_sregs sregs;
94 
95 	if (code == KVM_GET_SREGS && entering(tcp))
96 		return 0;
97 
98 	tprints(", ");
99 	if (!umove_or_printaddr(tcp, arg, &sregs))
100 		arch_print_kvm_sregs(tcp, arg, &sregs);
101 
102 	return RVAL_IOCTL_DECODED;
103 }
104 # endif /* HAVE_STRUCT_KVM_SREGS */
105 
106 int
kvm_ioctl(struct tcb * const tcp,const unsigned int code,const kernel_ulong_t arg)107 kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t arg)
108 {
109 	switch (code) {
110 	case KVM_CREATE_VCPU:
111 		return kvm_ioctl_create_vcpu(tcp, arg);
112 
113 # ifdef HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION
114 	case KVM_SET_USER_MEMORY_REGION:
115 		return kvm_ioctl_set_user_memory_region(tcp, arg);
116 # endif
117 
118 # ifdef HAVE_STRUCT_KVM_REGS
119 	case KVM_SET_REGS:
120 	case KVM_GET_REGS:
121 		return kvm_ioctl_decode_regs(tcp, code, arg);
122 # endif
123 
124 # ifdef HAVE_STRUCT_KVM_SREGS
125 	case KVM_SET_SREGS:
126 	case KVM_GET_SREGS:
127 		return kvm_ioctl_decode_sregs(tcp, code, arg);
128 # endif
129 
130 	case KVM_CREATE_VM:
131 		return RVAL_DECODED | RVAL_FD;
132 	case KVM_RUN:
133 	case KVM_GET_VCPU_MMAP_SIZE:
134 	case KVM_GET_API_VERSION:
135 	default:
136 		return RVAL_DECODED;
137 	}
138 }
139 
140 #endif /* HAVE_LINUX_KVM_H */
141