diff options
| -rw-r--r-- | arch/powerpc/kvm/book3s_rtas.c | 65 |
1 files changed, 18 insertions, 47 deletions
diff --git a/arch/powerpc/kvm/book3s_rtas.c b/arch/powerpc/kvm/book3s_rtas.c index edb14ba992b3..ef27fbd5d9c5 100644 --- a/arch/powerpc/kvm/book3s_rtas.c +++ b/arch/powerpc/kvm/book3s_rtas.c | |||
| @@ -23,20 +23,20 @@ static void kvm_rtas_set_xive(struct kvm_vcpu *vcpu, struct rtas_args *args) | |||
| 23 | u32 irq, server, priority; | 23 | u32 irq, server, priority; |
| 24 | int rc; | 24 | int rc; |
| 25 | 25 | ||
| 26 | if (args->nargs != 3 || args->nret != 1) { | 26 | if (be32_to_cpu(args->nargs) != 3 || be32_to_cpu(args->nret) != 1) { |
| 27 | rc = -3; | 27 | rc = -3; |
| 28 | goto out; | 28 | goto out; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | irq = args->args[0]; | 31 | irq = be32_to_cpu(args->args[0]); |
| 32 | server = args->args[1]; | 32 | server = be32_to_cpu(args->args[1]); |
| 33 | priority = args->args[2]; | 33 | priority = be32_to_cpu(args->args[2]); |
| 34 | 34 | ||
| 35 | rc = kvmppc_xics_set_xive(vcpu->kvm, irq, server, priority); | 35 | rc = kvmppc_xics_set_xive(vcpu->kvm, irq, server, priority); |
| 36 | if (rc) | 36 | if (rc) |
| 37 | rc = -3; | 37 | rc = -3; |
| 38 | out: | 38 | out: |
| 39 | args->rets[0] = rc; | 39 | args->rets[0] = cpu_to_be32(rc); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | static void kvm_rtas_get_xive(struct kvm_vcpu *vcpu, struct rtas_args *args) | 42 | static void kvm_rtas_get_xive(struct kvm_vcpu *vcpu, struct rtas_args *args) |
| @@ -44,12 +44,12 @@ static void kvm_rtas_get_xive(struct kvm_vcpu *vcpu, struct rtas_args *args) | |||
| 44 | u32 irq, server, priority; | 44 | u32 irq, server, priority; |
| 45 | int rc; | 45 | int rc; |
| 46 | 46 | ||
| 47 | if (args->nargs != 1 || args->nret != 3) { | 47 | if (be32_to_cpu(args->nargs) != 1 || be32_to_cpu(args->nret) != 3) { |
| 48 | rc = -3; | 48 | rc = -3; |
| 49 | goto out; | 49 | goto out; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | irq = args->args[0]; | 52 | irq = be32_to_cpu(args->args[0]); |
| 53 | 53 | ||
| 54 | server = priority = 0; | 54 | server = priority = 0; |
| 55 | rc = kvmppc_xics_get_xive(vcpu->kvm, irq, &server, &priority); | 55 | rc = kvmppc_xics_get_xive(vcpu->kvm, irq, &server, &priority); |
| @@ -58,10 +58,10 @@ static void kvm_rtas_get_xive(struct kvm_vcpu *vcpu, struct rtas_args *args) | |||
| 58 | goto out; | 58 | goto out; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | args->rets[1] = server; | 61 | args->rets[1] = cpu_to_be32(server); |
| 62 | args->rets[2] = priority; | 62 | args->rets[2] = cpu_to_be32(priority); |
| 63 | out: | 63 | out: |
| 64 | args->rets[0] = rc; | 64 | args->rets[0] = cpu_to_be32(rc); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | static void kvm_rtas_int_off(struct kvm_vcpu *vcpu, struct rtas_args *args) | 67 | static void kvm_rtas_int_off(struct kvm_vcpu *vcpu, struct rtas_args *args) |
| @@ -69,18 +69,18 @@ static void kvm_rtas_int_off(struct kvm_vcpu *vcpu, struct rtas_args *args) | |||
| 69 | u32 irq; | 69 | u32 irq; |
| 70 | int rc; | 70 | int rc; |
| 71 | 71 | ||
| 72 | if (args->nargs != 1 || args->nret != 1) { | 72 | if (be32_to_cpu(args->nargs) != 1 || be32_to_cpu(args->nret) != 1) { |
| 73 | rc = -3; | 73 | rc = -3; |
| 74 | goto out; | 74 | goto out; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | irq = args->args[0]; | 77 | irq = be32_to_cpu(args->args[0]); |
| 78 | 78 | ||
| 79 | rc = kvmppc_xics_int_off(vcpu->kvm, irq); | 79 | rc = kvmppc_xics_int_off(vcpu->kvm, irq); |
| 80 | if (rc) | 80 | if (rc) |
| 81 | rc = -3; | 81 | rc = -3; |
| 82 | out: | 82 | out: |
| 83 | args->rets[0] = rc; | 83 | args->rets[0] = cpu_to_be32(rc); |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | static void kvm_rtas_int_on(struct kvm_vcpu *vcpu, struct rtas_args *args) | 86 | static void kvm_rtas_int_on(struct kvm_vcpu *vcpu, struct rtas_args *args) |
| @@ -88,18 +88,18 @@ static void kvm_rtas_int_on(struct kvm_vcpu *vcpu, struct rtas_args *args) | |||
| 88 | u32 irq; | 88 | u32 irq; |
| 89 | int rc; | 89 | int rc; |
| 90 | 90 | ||
| 91 | if (args->nargs != 1 || args->nret != 1) { | 91 | if (be32_to_cpu(args->nargs) != 1 || be32_to_cpu(args->nret) != 1) { |
| 92 | rc = -3; | 92 | rc = -3; |
| 93 | goto out; | 93 | goto out; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | irq = args->args[0]; | 96 | irq = be32_to_cpu(args->args[0]); |
| 97 | 97 | ||
| 98 | rc = kvmppc_xics_int_on(vcpu->kvm, irq); | 98 | rc = kvmppc_xics_int_on(vcpu->kvm, irq); |
| 99 | if (rc) | 99 | if (rc) |
| 100 | rc = -3; | 100 | rc = -3; |
| 101 | out: | 101 | out: |
| 102 | args->rets[0] = rc; | 102 | args->rets[0] = cpu_to_be32(rc); |
| 103 | } | 103 | } |
| 104 | #endif /* CONFIG_KVM_XICS */ | 104 | #endif /* CONFIG_KVM_XICS */ |
| 105 | 105 | ||
| @@ -205,32 +205,6 @@ int kvm_vm_ioctl_rtas_define_token(struct kvm *kvm, void __user *argp) | |||
| 205 | return rc; | 205 | return rc; |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | static void kvmppc_rtas_swap_endian_in(struct rtas_args *args) | ||
| 209 | { | ||
| 210 | #ifdef __LITTLE_ENDIAN__ | ||
| 211 | int i; | ||
| 212 | |||
| 213 | args->token = be32_to_cpu(args->token); | ||
| 214 | args->nargs = be32_to_cpu(args->nargs); | ||
| 215 | args->nret = be32_to_cpu(args->nret); | ||
| 216 | for (i = 0; i < args->nargs; i++) | ||
| 217 | args->args[i] = be32_to_cpu(args->args[i]); | ||
| 218 | #endif | ||
| 219 | } | ||
| 220 | |||
| 221 | static void kvmppc_rtas_swap_endian_out(struct rtas_args *args) | ||
| 222 | { | ||
| 223 | #ifdef __LITTLE_ENDIAN__ | ||
| 224 | int i; | ||
| 225 | |||
| 226 | for (i = 0; i < args->nret; i++) | ||
| 227 | args->args[i] = cpu_to_be32(args->args[i]); | ||
| 228 | args->token = cpu_to_be32(args->token); | ||
| 229 | args->nargs = cpu_to_be32(args->nargs); | ||
| 230 | args->nret = cpu_to_be32(args->nret); | ||
| 231 | #endif | ||
| 232 | } | ||
| 233 | |||
| 234 | int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu) | 208 | int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu) |
| 235 | { | 209 | { |
| 236 | struct rtas_token_definition *d; | 210 | struct rtas_token_definition *d; |
| @@ -249,8 +223,6 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu) | |||
| 249 | if (rc) | 223 | if (rc) |
| 250 | goto fail; | 224 | goto fail; |
| 251 | 225 | ||
| 252 | kvmppc_rtas_swap_endian_in(&args); | ||
| 253 | |||
| 254 | /* | 226 | /* |
| 255 | * args->rets is a pointer into args->args. Now that we've | 227 | * args->rets is a pointer into args->args. Now that we've |
| 256 | * copied args we need to fix it up to point into our copy, | 228 | * copied args we need to fix it up to point into our copy, |
| @@ -258,13 +230,13 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu) | |||
| 258 | * value so we can restore it on the way out. | 230 | * value so we can restore it on the way out. |
| 259 | */ | 231 | */ |
| 260 | orig_rets = args.rets; | 232 | orig_rets = args.rets; |
| 261 | args.rets = &args.args[args.nargs]; | 233 | args.rets = &args.args[be32_to_cpu(args.nargs)]; |
| 262 | 234 | ||
| 263 | mutex_lock(&vcpu->kvm->lock); | 235 | mutex_lock(&vcpu->kvm->lock); |
| 264 | 236 | ||
| 265 | rc = -ENOENT; | 237 | rc = -ENOENT; |
| 266 | list_for_each_entry(d, &vcpu->kvm->arch.rtas_tokens, list) { | 238 | list_for_each_entry(d, &vcpu->kvm->arch.rtas_tokens, list) { |
| 267 | if (d->token == args.token) { | 239 | if (d->token == be32_to_cpu(args.token)) { |
| 268 | d->handler->handler(vcpu, &args); | 240 | d->handler->handler(vcpu, &args); |
| 269 | rc = 0; | 241 | rc = 0; |
| 270 | break; | 242 | break; |
| @@ -275,7 +247,6 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu) | |||
| 275 | 247 | ||
| 276 | if (rc == 0) { | 248 | if (rc == 0) { |
| 277 | args.rets = orig_rets; | 249 | args.rets = orig_rets; |
| 278 | kvmppc_rtas_swap_endian_out(&args); | ||
| 279 | rc = kvm_write_guest(vcpu->kvm, args_phys, &args, sizeof(args)); | 250 | rc = kvm_write_guest(vcpu->kvm, args_phys, &args, sizeof(args)); |
| 280 | if (rc) | 251 | if (rc) |
| 281 | goto fail; | 252 | goto fail; |
