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