| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2010,2012 Freescale Semiconductor, Inc. All rights reserved. |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * Description: |
|---|
| 7 | 8 | * This file is derived from arch/powerpc/kvm/e500.c, |
|---|
| 8 | 9 | * by Yu Liu <yu.liu@freescale.com>. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 11 | | - * it under the terms of the GNU General Public License, version 2, as |
|---|
| 12 | | - * published by the Free Software Foundation. |
|---|
| 13 | 10 | */ |
|---|
| 14 | 11 | |
|---|
| 15 | 12 | #include <linux/kvm_host.h> |
|---|
| .. | .. |
|---|
| 304 | 301 | return r; |
|---|
| 305 | 302 | } |
|---|
| 306 | 303 | |
|---|
| 307 | | -static struct kvm_vcpu *kvmppc_core_vcpu_create_e500mc(struct kvm *kvm, |
|---|
| 308 | | - unsigned int id) |
|---|
| 304 | +static int kvmppc_core_vcpu_create_e500mc(struct kvm_vcpu *vcpu) |
|---|
| 309 | 305 | { |
|---|
| 310 | 306 | struct kvmppc_vcpu_e500 *vcpu_e500; |
|---|
| 311 | | - struct kvm_vcpu *vcpu; |
|---|
| 312 | 307 | int err; |
|---|
| 313 | 308 | |
|---|
| 314 | | - vcpu_e500 = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); |
|---|
| 315 | | - if (!vcpu_e500) { |
|---|
| 316 | | - err = -ENOMEM; |
|---|
| 317 | | - goto out; |
|---|
| 318 | | - } |
|---|
| 319 | | - vcpu = &vcpu_e500->vcpu; |
|---|
| 309 | + BUILD_BUG_ON(offsetof(struct kvmppc_vcpu_e500, vcpu) != 0); |
|---|
| 310 | + vcpu_e500 = to_e500(vcpu); |
|---|
| 320 | 311 | |
|---|
| 321 | 312 | /* Invalid PIR value -- this LPID dosn't have valid state on any cpu */ |
|---|
| 322 | 313 | vcpu->arch.oldpir = 0xffffffff; |
|---|
| 323 | 314 | |
|---|
| 324 | | - err = kvm_vcpu_init(vcpu, kvm, id); |
|---|
| 325 | | - if (err) |
|---|
| 326 | | - goto free_vcpu; |
|---|
| 327 | | - |
|---|
| 328 | 315 | err = kvmppc_e500_tlb_init(vcpu_e500); |
|---|
| 329 | 316 | if (err) |
|---|
| 330 | | - goto uninit_vcpu; |
|---|
| 317 | + return err; |
|---|
| 331 | 318 | |
|---|
| 332 | 319 | vcpu->arch.shared = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); |
|---|
| 333 | 320 | if (!vcpu->arch.shared) { |
|---|
| .. | .. |
|---|
| 335 | 322 | goto uninit_tlb; |
|---|
| 336 | 323 | } |
|---|
| 337 | 324 | |
|---|
| 338 | | - return vcpu; |
|---|
| 325 | + return 0; |
|---|
| 339 | 326 | |
|---|
| 340 | 327 | uninit_tlb: |
|---|
| 341 | 328 | kvmppc_e500_tlb_uninit(vcpu_e500); |
|---|
| 342 | | -uninit_vcpu: |
|---|
| 343 | | - kvm_vcpu_uninit(vcpu); |
|---|
| 344 | | - |
|---|
| 345 | | -free_vcpu: |
|---|
| 346 | | - kmem_cache_free(kvm_vcpu_cache, vcpu_e500); |
|---|
| 347 | | -out: |
|---|
| 348 | | - return ERR_PTR(err); |
|---|
| 329 | + return err; |
|---|
| 349 | 330 | } |
|---|
| 350 | 331 | |
|---|
| 351 | 332 | static void kvmppc_core_vcpu_free_e500mc(struct kvm_vcpu *vcpu) |
|---|
| .. | .. |
|---|
| 354 | 335 | |
|---|
| 355 | 336 | free_page((unsigned long)vcpu->arch.shared); |
|---|
| 356 | 337 | kvmppc_e500_tlb_uninit(vcpu_e500); |
|---|
| 357 | | - kvm_vcpu_uninit(vcpu); |
|---|
| 358 | | - kmem_cache_free(kvm_vcpu_cache, vcpu_e500); |
|---|
| 359 | 338 | } |
|---|
| 360 | 339 | |
|---|
| 361 | 340 | static int kvmppc_core_init_vm_e500mc(struct kvm *kvm) |
|---|
| .. | .. |
|---|
| 397 | 376 | .vcpu_put = kvmppc_core_vcpu_put_e500mc, |
|---|
| 398 | 377 | .vcpu_create = kvmppc_core_vcpu_create_e500mc, |
|---|
| 399 | 378 | .vcpu_free = kvmppc_core_vcpu_free_e500mc, |
|---|
| 400 | | - .mmu_destroy = kvmppc_mmu_destroy_e500, |
|---|
| 401 | 379 | .init_vm = kvmppc_core_init_vm_e500mc, |
|---|
| 402 | 380 | .destroy_vm = kvmppc_core_destroy_vm_e500mc, |
|---|
| 403 | 381 | .emulate_op = kvmppc_core_emulate_op_e500, |
|---|