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
21static 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 (be32_to_cpu(args->nargs) != 3 || be32_to_cpu(args->nret) != 1) {
27		rc = -3;
28		goto out;
29	}
30
31	irq = be32_to_cpu(args->args[0]);
32	server = be32_to_cpu(args->args[1]);
33	priority = be32_to_cpu(args->args[2]);
34
35	rc = kvmppc_xics_set_xive(vcpu->kvm, irq, server, priority);
36	if (rc)
37		rc = -3;
38out:
39	args->rets[0] = cpu_to_be32(rc);
40}
41
42static 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 (be32_to_cpu(args->nargs) != 1 || be32_to_cpu(args->nret) != 3) {
48		rc = -3;
49		goto out;
50	}
51
52	irq = be32_to_cpu(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] = cpu_to_be32(server);
62	args->rets[2] = cpu_to_be32(priority);
63out:
64	args->rets[0] = cpu_to_be32(rc);
65}
66
67static void kvm_rtas_int_off(struct kvm_vcpu *vcpu, struct rtas_args *args)
68{
69	u32 irq;
70	int rc;
71
72	if (be32_to_cpu(args->nargs) != 1 || be32_to_cpu(args->nret) != 1) {
73		rc = -3;
74		goto out;
75	}
76
77	irq = be32_to_cpu(args->args[0]);
78
79	rc = kvmppc_xics_int_off(vcpu->kvm, irq);
80	if (rc)
81		rc = -3;
82out:
83	args->rets[0] = cpu_to_be32(rc);
84}
85
86static void kvm_rtas_int_on(struct kvm_vcpu *vcpu, struct rtas_args *args)
87{
88	u32 irq;
89	int rc;
90
91	if (be32_to_cpu(args->nargs) != 1 || be32_to_cpu(args->nret) != 1) {
92		rc = -3;
93		goto out;
94	}
95
96	irq = be32_to_cpu(args->args[0]);
97
98	rc = kvmppc_xics_int_on(vcpu->kvm, irq);
99	if (rc)
100		rc = -3;
101out:
102	args->rets[0] = cpu_to_be32(rc);
103}
104#endif /* CONFIG_KVM_XICS */
105
106struct rtas_handler {
107	void (*handler)(struct kvm_vcpu *vcpu, struct rtas_args *args);
108	char *name;
109};
110
111static 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
120struct rtas_token_definition {
121	struct list_head list;
122	struct rtas_handler *handler;
123	u64 token;
124};
125
126static 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
132static 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
150static 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
188int 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
208int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
209{
210	struct rtas_token_definition *d;
211	struct rtas_args args;
212	rtas_arg_t *orig_rets;
213	gpa_t args_phys;
214	int rc;
215
216	/*
217	 * r4 contains the guest physical address of the RTAS args
218	 * Mask off the top 4 bits since this is a guest real address
219	 */
220	args_phys = kvmppc_get_gpr(vcpu, 4) & KVM_PAM;
221
222	rc = kvm_read_guest(vcpu->kvm, args_phys, &args, sizeof(args));
223	if (rc)
224		goto fail;
225
226	/*
227	 * args->rets is a pointer into args->args. Now that we've
228	 * copied args we need to fix it up to point into our copy,
229	 * not the guest args. We also need to save the original
230	 * value so we can restore it on the way out.
231	 */
232	orig_rets = args.rets;
233	args.rets = &args.args[be32_to_cpu(args.nargs)];
234
235	mutex_lock(&vcpu->kvm->lock);
236
237	rc = -ENOENT;
238	list_for_each_entry(d, &vcpu->kvm->arch.rtas_tokens, list) {
239		if (d->token == be32_to_cpu(args.token)) {
240			d->handler->handler(vcpu, &args);
241			rc = 0;
242			break;
243		}
244	}
245
246	mutex_unlock(&vcpu->kvm->lock);
247
248	if (rc == 0) {
249		args.rets = orig_rets;
250		rc = kvm_write_guest(vcpu->kvm, args_phys, &args, sizeof(args));
251		if (rc)
252			goto fail;
253	}
254
255	return rc;
256
257fail:
258	/*
259	 * We only get here if the guest has called RTAS with a bogus
260	 * args pointer. That means we can't get to the args, and so we
261	 * can't fail the RTAS call. So fail right out to userspace,
262	 * which should kill the guest.
263	 */
264	return rc;
265}
266EXPORT_SYMBOL_GPL(kvmppc_rtas_hcall);
267
268void kvmppc_rtas_tokens_free(struct kvm *kvm)
269{
270	struct rtas_token_definition *d, *tmp;
271
272	lockdep_assert_held(&kvm->lock);
273
274	list_for_each_entry_safe(d, tmp, &kvm->arch.rtas_tokens, list) {
275		list_del(&d->list);
276		kfree(d);
277	}
278}
279