1 /* 2 * Copyright 2012 Michael Ellerman, IBM Corporation. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License, version 2, as 6 * published by the Free Software Foundation. 7 */ 8 9 #include <linux/kernel.h> 10 #include <linux/kvm_host.h> 11 #include <linux/kvm.h> 12 #include <linux/err.h> 13 14 #include <asm/uaccess.h> 15 #include <asm/kvm_book3s.h> 16 #include <asm/kvm_ppc.h> 17 #include <asm/hvcall.h> 18 #include <asm/rtas.h> 19 20 #ifdef CONFIG_KVM_XICS 21 static void kvm_rtas_set_xive(struct kvm_vcpu *vcpu, struct rtas_args *args) 22 { 23 u32 irq, server, priority; 24 int rc; 25 26 if (args->nargs != 3 || args->nret != 1) { 27 rc = -3; 28 goto out; 29 } 30 31 irq = args->args[0]; 32 server = args->args[1]; 33 priority = args->args[2]; 34 35 rc = kvmppc_xics_set_xive(vcpu->kvm, irq, server, priority); 36 if (rc) 37 rc = -3; 38 out: 39 args->rets[0] = rc; 40 } 41 42 static void kvm_rtas_get_xive(struct kvm_vcpu *vcpu, struct rtas_args *args) 43 { 44 u32 irq, server, priority; 45 int rc; 46 47 if (args->nargs != 1 || args->nret != 3) { 48 rc = -3; 49 goto out; 50 } 51 52 irq = args->args[0]; 53 54 server = priority = 0; 55 rc = kvmppc_xics_get_xive(vcpu->kvm, irq, &server, &priority); 56 if (rc) { 57 rc = -3; 58 goto out; 59 } 60 61 args->rets[1] = server; 62 args->rets[2] = priority; 63 out: 64 args->rets[0] = rc; 65 } 66 67 static void kvm_rtas_int_off(struct kvm_vcpu *vcpu, struct rtas_args *args) 68 { 69 u32 irq; 70 int rc; 71 72 if (args->nargs != 1 || args->nret != 1) { 73 rc = -3; 74 goto out; 75 } 76 77 irq = args->args[0]; 78 79 rc = kvmppc_xics_int_off(vcpu->kvm, irq); 80 if (rc) 81 rc = -3; 82 out: 83 args->rets[0] = rc; 84 } 85 86 static void kvm_rtas_int_on(struct kvm_vcpu *vcpu, struct rtas_args *args) 87 { 88 u32 irq; 89 int rc; 90 91 if (args->nargs != 1 || args->nret != 1) { 92 rc = -3; 93 goto out; 94 } 95 96 irq = args->args[0]; 97 98 rc = kvmppc_xics_int_on(vcpu->kvm, irq); 99 if (rc) 100 rc = -3; 101 out: 102 args->rets[0] = rc; 103 } 104 #endif /* CONFIG_KVM_XICS */ 105 106 struct rtas_handler { 107 void (*handler)(struct kvm_vcpu *vcpu, struct rtas_args *args); 108 char *name; 109 }; 110 111 static struct rtas_handler rtas_handlers[] = { 112 #ifdef CONFIG_KVM_XICS 113 { .name = "ibm,set-xive", .handler = kvm_rtas_set_xive }, 114 { .name = "ibm,get-xive", .handler = kvm_rtas_get_xive }, 115 { .name = "ibm,int-off", .handler = kvm_rtas_int_off }, 116 { .name = "ibm,int-on", .handler = kvm_rtas_int_on }, 117 #endif 118 }; 119 120 struct rtas_token_definition { 121 struct list_head list; 122 struct rtas_handler *handler; 123 u64 token; 124 }; 125 126 static int rtas_name_matches(char *s1, char *s2) 127 { 128 struct kvm_rtas_token_args args; 129 return !strncmp(s1, s2, sizeof(args.name)); 130 } 131 132 static int rtas_token_undefine(struct kvm *kvm, char *name) 133 { 134 struct rtas_token_definition *d, *tmp; 135 136 lockdep_assert_held(&kvm->lock); 137 138 list_for_each_entry_safe(d, tmp, &kvm->arch.rtas_tokens, list) { 139 if (rtas_name_matches(d->handler->name, name)) { 140 list_del(&d->list); 141 kfree(d); 142 return 0; 143 } 144 } 145 146 /* It's not an error to undefine an undefined token */ 147 return 0; 148 } 149 150 static int rtas_token_define(struct kvm *kvm, char *name, u64 token) 151 { 152 struct rtas_token_definition *d; 153 struct rtas_handler *h = NULL; 154 bool found; 155 int i; 156 157 lockdep_assert_held(&kvm->lock); 158 159 list_for_each_entry(d, &kvm->arch.rtas_tokens, list) { 160 if (d->token == token) 161 return -EEXIST; 162 } 163 164 found = false; 165 for (i = 0; i < ARRAY_SIZE(rtas_handlers); i++) { 166 h = &rtas_handlers[i]; 167 if (rtas_name_matches(h->name, name)) { 168 found = true; 169 break; 170 } 171 } 172 173 if (!found) 174 return -ENOENT; 175 176 d = kzalloc(sizeof(*d), GFP_KERNEL); 177 if (!d) 178 return -ENOMEM; 179 180 d->handler = h; 181 d->token = token; 182 183 list_add_tail(&d->list, &kvm->arch.rtas_tokens); 184 185 return 0; 186 } 187 188 int kvm_vm_ioctl_rtas_define_token(struct kvm *kvm, void __user *argp) 189 { 190 struct kvm_rtas_token_args args; 191 int rc; 192 193 if (copy_from_user(&args, argp, sizeof(args))) 194 return -EFAULT; 195 196 mutex_lock(&kvm->lock); 197 198 if (args.token) 199 rc = rtas_token_define(kvm, args.name, args.token); 200 else 201 rc = rtas_token_undefine(kvm, args.name); 202 203 mutex_unlock(&kvm->lock); 204 205 return rc; 206 } 207 208 static void kvmppc_rtas_swap_endian_in(struct rtas_args *args) 209 { 210 #ifdef __LITTLE_ENDIAN__ 211 int i; 212 213 args->token = be32_to_cpu(args->token); 214 args->nargs = be32_to_cpu(args->nargs); 215 args->nret = be32_to_cpu(args->nret); 216 for (i = 0; i < args->nargs; i++) 217 args->args[i] = be32_to_cpu(args->args[i]); 218 #endif 219 } 220 221 static void kvmppc_rtas_swap_endian_out(struct rtas_args *args) 222 { 223 #ifdef __LITTLE_ENDIAN__ 224 int i; 225 226 for (i = 0; i < args->nret; i++) 227 args->args[i] = cpu_to_be32(args->args[i]); 228 args->token = cpu_to_be32(args->token); 229 args->nargs = cpu_to_be32(args->nargs); 230 args->nret = cpu_to_be32(args->nret); 231 #endif 232 } 233 234 int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu) 235 { 236 struct rtas_token_definition *d; 237 struct rtas_args args; 238 rtas_arg_t *orig_rets; 239 gpa_t args_phys; 240 int rc; 241 242 /* 243 * r4 contains the guest physical address of the RTAS args 244 * Mask off the top 4 bits since this is a guest real address 245 */ 246 args_phys = kvmppc_get_gpr(vcpu, 4) & KVM_PAM; 247 248 rc = kvm_read_guest(vcpu->kvm, args_phys, &args, sizeof(args)); 249 if (rc) 250 goto fail; 251 252 kvmppc_rtas_swap_endian_in(&args); 253 254 /* 255 * args->rets is a pointer into args->args. Now that we've 256 * copied args we need to fix it up to point into our copy, 257 * not the guest args. We also need to save the original 258 * value so we can restore it on the way out. 259 */ 260 orig_rets = args.rets; 261 args.rets = &args.args[args.nargs]; 262 263 mutex_lock(&vcpu->kvm->lock); 264 265 rc = -ENOENT; 266 list_for_each_entry(d, &vcpu->kvm->arch.rtas_tokens, list) { 267 if (d->token == args.token) { 268 d->handler->handler(vcpu, &args); 269 rc = 0; 270 break; 271 } 272 } 273 274 mutex_unlock(&vcpu->kvm->lock); 275 276 if (rc == 0) { 277 args.rets = orig_rets; 278 kvmppc_rtas_swap_endian_out(&args); 279 rc = kvm_write_guest(vcpu->kvm, args_phys, &args, sizeof(args)); 280 if (rc) 281 goto fail; 282 } 283 284 return rc; 285 286 fail: 287 /* 288 * We only get here if the guest has called RTAS with a bogus 289 * args pointer. That means we can't get to the args, and so we 290 * can't fail the RTAS call. So fail right out to userspace, 291 * which should kill the guest. 292 */ 293 return rc; 294 } 295 EXPORT_SYMBOL_GPL(kvmppc_rtas_hcall); 296 297 void kvmppc_rtas_tokens_free(struct kvm *kvm) 298 { 299 struct rtas_token_definition *d, *tmp; 300 301 lockdep_assert_held(&kvm->lock); 302 303 list_for_each_entry_safe(d, tmp, &kvm->arch.rtas_tokens, list) { 304 list_del(&d->list); 305 kfree(d); 306 } 307 } 308