root/arch/powerpc/kvm/book3s_rtas.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. kvm_rtas_set_xive
  2. kvm_rtas_get_xive
  3. kvm_rtas_int_off
  4. kvm_rtas_int_on
  5. rtas_name_matches
  6. rtas_token_undefine
  7. rtas_token_define
  8. kvm_vm_ioctl_rtas_define_token
  9. kvmppc_rtas_hcall
  10. kvmppc_rtas_tokens_free

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

/* [<][>][^][v][top][bottom][index][help] */