]> granicus.if.org Git - strace/blob - kvm.c
nlattr: add UID/GID netlink attribute decoders
[strace] / kvm.c
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
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
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
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
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
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 */