2 * Copyright 2012 Michael Ellerman, IBM Corporation.
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.
9 #include <linux/kernel.h>
10 #include <linux/kvm_host.h>
11 #include <linux/kvm.h>
12 #include <linux/err.h>
14 #include <asm/uaccess.h>
15 #include <asm/kvm_book3s.h>
16 #include <asm/kvm_ppc.h>
17 #include <asm/hvcall.h>
20 #ifdef CONFIG_KVM_XICS
21 static void kvm_rtas_set_xive(struct kvm_vcpu
*vcpu
, struct rtas_args
*args
)
23 u32 irq
, server
, priority
;
26 if (be32_to_cpu(args
->nargs
) != 3 || be32_to_cpu(args
->nret
) != 1) {
31 irq
= be32_to_cpu(args
->args
[0]);
32 server
= be32_to_cpu(args
->args
[1]);
33 priority
= be32_to_cpu(args
->args
[2]);
35 rc
= kvmppc_xics_set_xive(vcpu
->kvm
, irq
, server
, priority
);
39 args
->rets
[0] = cpu_to_be32(rc
);
42 static void kvm_rtas_get_xive(struct kvm_vcpu
*vcpu
, struct rtas_args
*args
)
44 u32 irq
, server
, priority
;
47 if (be32_to_cpu(args
->nargs
) != 1 || be32_to_cpu(args
->nret
) != 3) {
52 irq
= be32_to_cpu(args
->args
[0]);
54 server
= priority
= 0;
55 rc
= kvmppc_xics_get_xive(vcpu
->kvm
, irq
, &server
, &priority
);
61 args
->rets
[1] = cpu_to_be32(server
);
62 args
->rets
[2] = cpu_to_be32(priority
);
64 args
->rets
[0] = cpu_to_be32(rc
);
67 static void kvm_rtas_int_off(struct kvm_vcpu
*vcpu
, struct rtas_args
*args
)
72 if (be32_to_cpu(args
->nargs
) != 1 || be32_to_cpu(args
->nret
) != 1) {
77 irq
= be32_to_cpu(args
->args
[0]);
79 rc
= kvmppc_xics_int_off(vcpu
->kvm
, irq
);
83 args
->rets
[0] = cpu_to_be32(rc
);
86 static void kvm_rtas_int_on(struct kvm_vcpu
*vcpu
, struct rtas_args
*args
)
91 if (be32_to_cpu(args
->nargs
) != 1 || be32_to_cpu(args
->nret
) != 1) {
96 irq
= be32_to_cpu(args
->args
[0]);
98 rc
= kvmppc_xics_int_on(vcpu
->kvm
, irq
);
102 args
->rets
[0] = cpu_to_be32(rc
);
104 #endif /* CONFIG_KVM_XICS */
106 struct rtas_handler
{
107 void (*handler
)(struct kvm_vcpu
*vcpu
, struct rtas_args
*args
);
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
},
120 struct rtas_token_definition
{
121 struct list_head list
;
122 struct rtas_handler
*handler
;
126 static int rtas_name_matches(char *s1
, char *s2
)
128 struct kvm_rtas_token_args args
;
129 return !strncmp(s1
, s2
, sizeof(args
.name
));
132 static int rtas_token_undefine(struct kvm
*kvm
, char *name
)
134 struct rtas_token_definition
*d
, *tmp
;
136 lockdep_assert_held(&kvm
->lock
);
138 list_for_each_entry_safe(d
, tmp
, &kvm
->arch
.rtas_tokens
, list
) {
139 if (rtas_name_matches(d
->handler
->name
, name
)) {
146 /* It's not an error to undefine an undefined token */
150 static int rtas_token_define(struct kvm
*kvm
, char *name
, u64 token
)
152 struct rtas_token_definition
*d
;
153 struct rtas_handler
*h
= NULL
;
157 lockdep_assert_held(&kvm
->lock
);
159 list_for_each_entry(d
, &kvm
->arch
.rtas_tokens
, list
) {
160 if (d
->token
== token
)
165 for (i
= 0; i
< ARRAY_SIZE(rtas_handlers
); i
++) {
166 h
= &rtas_handlers
[i
];
167 if (rtas_name_matches(h
->name
, name
)) {
176 d
= kzalloc(sizeof(*d
), GFP_KERNEL
);
183 list_add_tail(&d
->list
, &kvm
->arch
.rtas_tokens
);
188 int kvm_vm_ioctl_rtas_define_token(struct kvm
*kvm
, void __user
*argp
)
190 struct kvm_rtas_token_args args
;
193 if (copy_from_user(&args
, argp
, sizeof(args
)))
196 mutex_lock(&kvm
->lock
);
199 rc
= rtas_token_define(kvm
, args
.name
, args
.token
);
201 rc
= rtas_token_undefine(kvm
, args
.name
);
203 mutex_unlock(&kvm
->lock
);
208 int kvmppc_rtas_hcall(struct kvm_vcpu
*vcpu
)
210 struct rtas_token_definition
*d
;
211 struct rtas_args args
;
212 rtas_arg_t
*orig_rets
;
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
220 args_phys
= kvmppc_get_gpr(vcpu
, 4) & KVM_PAM
;
222 rc
= kvm_read_guest(vcpu
->kvm
, args_phys
, &args
, sizeof(args
));
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.
232 orig_rets
= args
.rets
;
233 args
.rets
= &args
.args
[be32_to_cpu(args
.nargs
)];
235 mutex_lock(&vcpu
->kvm
->lock
);
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
);
246 mutex_unlock(&vcpu
->kvm
->lock
);
249 args
.rets
= orig_rets
;
250 rc
= kvm_write_guest(vcpu
->kvm
, args_phys
, &args
, sizeof(args
));
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.
266 EXPORT_SYMBOL_GPL(kvmppc_rtas_hcall
);
268 void kvmppc_rtas_tokens_free(struct kvm
*kvm
)
270 struct rtas_token_definition
*d
, *tmp
;
272 lockdep_assert_held(&kvm
->lock
);
274 list_for_each_entry_safe(d
, tmp
, &kvm
->arch
.rtas_tokens
, list
) {