]> bbs.cooldavid.org Git - net-next-2.6.git/blame - arch/powerpc/kvm/e500.c
KVM: ppc: distinguish between interrupts and priorities
[net-next-2.6.git] / arch / powerpc / kvm / e500.c
CommitLineData
bc8080cb
HB
1/*
2 * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: Yu Liu, <yu.liu@freescale.com>
5 *
6 * Description:
7 * This file is derived from arch/powerpc/kvm/44x.c,
8 * by Hollis Blanchard <hollisb@us.ibm.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 */
14
15#include <linux/kvm_host.h>
16#include <linux/err.h>
17
18#include <asm/reg.h>
19#include <asm/cputable.h>
20#include <asm/tlbflush.h>
21#include <asm/kvm_e500.h>
22#include <asm/kvm_ppc.h>
23
24#include "e500_tlb.h"
25
26void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu)
27{
28}
29
30void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu)
31{
32}
33
34void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
35{
36 kvmppc_e500_tlb_load(vcpu, cpu);
37}
38
39void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
40{
41 kvmppc_e500_tlb_put(vcpu);
42}
43
44int kvmppc_core_check_processor_compat(void)
45{
46 int r;
47
48 if (strcmp(cur_cpu_spec->cpu_name, "e500v2") == 0)
49 r = 0;
50 else
51 r = -ENOTSUPP;
52
53 return r;
54}
55
56int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
57{
58 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
59
60 kvmppc_e500_tlb_setup(vcpu_e500);
61
62 /* Use the same core vertion as host's */
63 vcpu->arch.pvr = mfspr(SPRN_PVR);
64
65 return 0;
66}
67
68/* 'linear_address' is actually an encoding of AS|PID|EADDR . */
69int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
70 struct kvm_translation *tr)
71{
72 int index;
73 gva_t eaddr;
74 u8 pid;
75 u8 as;
76
77 eaddr = tr->linear_address;
78 pid = (tr->linear_address >> 32) & 0xff;
79 as = (tr->linear_address >> 40) & 0x1;
80
81 index = kvmppc_e500_tlb_search(vcpu, eaddr, pid, as);
82 if (index < 0) {
83 tr->valid = 0;
84 return 0;
85 }
86
87 tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr);
88 /* XXX what does "writeable" and "usermode" even mean? */
89 tr->valid = 1;
90
91 return 0;
92}
93
94struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
95{
96 struct kvmppc_vcpu_e500 *vcpu_e500;
97 struct kvm_vcpu *vcpu;
98 int err;
99
100 vcpu_e500 = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
101 if (!vcpu_e500) {
102 err = -ENOMEM;
103 goto out;
104 }
105
106 vcpu = &vcpu_e500->vcpu;
107 err = kvm_vcpu_init(vcpu, kvm, id);
108 if (err)
109 goto free_vcpu;
110
111 err = kvmppc_e500_tlb_init(vcpu_e500);
112 if (err)
113 goto uninit_vcpu;
114
115 return vcpu;
116
117uninit_vcpu:
118 kvm_vcpu_uninit(vcpu);
119free_vcpu:
120 kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
121out:
122 return ERR_PTR(err);
123}
124
125void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
126{
127 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
128
129 kvmppc_e500_tlb_uninit(vcpu_e500);
130 kvm_vcpu_uninit(vcpu);
131 kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
132}
133
134static int kvmppc_e500_init(void)
135{
136 int r;
137
138 r = kvmppc_booke_init();
139 if (r)
140 return r;
141
142 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE);
143}
144
145static void kvmppc_e500_exit(void)
146{
147 kvmppc_booke_exit();
148}
149
150module_init(kvmppc_e500_init);
151module_exit(kvmppc_e500_exit);