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 (args
->nargs
!= 3 || args
->nret
!= 1) {
32 server
= args
->args
[1];
33 priority
= args
->args
[2];
35 rc
= kvmppc_xics_set_xive(vcpu
->kvm
, irq
, server
, priority
);
42 static void kvm_rtas_get_xive(struct kvm_vcpu
*vcpu
, struct rtas_args
*args
)
44 u32 irq
, server
, priority
;
47 if (args
->nargs
!= 1 || args
->nret
!= 3) {
54 server
= priority
= 0;
55 rc
= kvmppc_xics_get_xive(vcpu
->kvm
, irq
, &server
, &priority
);
61 args
->rets
[1] = server
;
62 args
->rets
[2] = priority
;
67 static void kvm_rtas_int_off(struct kvm_vcpu
*vcpu
, struct rtas_args
*args
)
72 if (args
->nargs
!= 1 || args
->nret
!= 1) {
79 rc
= kvmppc_xics_int_off(vcpu
->kvm
, irq
);
86 static void kvm_rtas_int_on(struct kvm_vcpu
*vcpu
, struct rtas_args
*args
)
91 if (args
->nargs
!= 1 || args
->nret
!= 1) {
98 rc
= kvmppc_xics_int_on(vcpu
->kvm
, irq
);
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
;
216 /* r4 contains the guest physical address of the RTAS args */
217 args_phys
= kvmppc_get_gpr(vcpu
, 4);
219 rc
= kvm_read_guest(vcpu
->kvm
, args_phys
, &args
, sizeof(args
));
224 * args->rets is a pointer into args->args. Now that we've
225 * copied args we need to fix it up to point into our copy,
226 * not the guest args. We also need to save the original
227 * value so we can restore it on the way out.
229 orig_rets
= args
.rets
;
230 args
.rets
= &args
.args
[args
.nargs
];
232 mutex_lock(&vcpu
->kvm
->lock
);
235 list_for_each_entry(d
, &vcpu
->kvm
->arch
.rtas_tokens
, list
) {
236 if (d
->token
== args
.token
) {
237 d
->handler
->handler(vcpu
, &args
);
243 mutex_unlock(&vcpu
->kvm
->lock
);
246 args
.rets
= orig_rets
;
247 rc
= kvm_write_guest(vcpu
->kvm
, args_phys
, &args
, sizeof(args
));
256 * We only get here if the guest has called RTAS with a bogus
257 * args pointer. That means we can't get to the args, and so we
258 * can't fail the RTAS call. So fail right out to userspace,
259 * which should kill the guest.
263 EXPORT_SYMBOL_GPL(kvmppc_rtas_hcall
);
265 void kvmppc_rtas_tokens_free(struct kvm
*kvm
)
267 struct rtas_token_definition
*d
, *tmp
;
269 lockdep_assert_held(&kvm
->lock
);
271 list_for_each_entry_safe(d
, tmp
, &kvm
->arch
.rtas_tokens
, list
) {