aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2010-07-29 08:47:42 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:50:42 -0400
commit96bc451a153297bf1f99ef2d633d512ea349ae7a (patch)
tree75ab4d40387ea1295a23b180e4c8719ce7053d00 /arch/powerpc
parent34698d8c61bd3fc86b2e99c3d1ad9ef140b3eb0d (diff)
KVM: PPC: Introduce shared page
For transparent variable sharing between the hypervisor and guest, I introduce a shared page. This shared page will contain all the registers the guest can read and write safely without exiting guest context. This patch only implements the stubs required for the basic structure of the shared page. The actual register moving follows. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/kvm_host.h2
-rw-r--r--arch/powerpc/include/asm/kvm_para.h5
-rw-r--r--arch/powerpc/kernel/asm-offsets.c1
-rw-r--r--arch/powerpc/kvm/44x.c7
-rw-r--r--arch/powerpc/kvm/book3s.c9
-rw-r--r--arch/powerpc/kvm/e500.c7
6 files changed, 30 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index b0b23c007d6e..53edacdf6940 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -25,6 +25,7 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/kvm_types.h> 27#include <linux/kvm_types.h>
28#include <linux/kvm_para.h>
28#include <asm/kvm_asm.h> 29#include <asm/kvm_asm.h>
29 30
30#define KVM_MAX_VCPUS 1 31#define KVM_MAX_VCPUS 1
@@ -290,6 +291,7 @@ struct kvm_vcpu_arch {
290 struct tasklet_struct tasklet; 291 struct tasklet_struct tasklet;
291 u64 dec_jiffies; 292 u64 dec_jiffies;
292 unsigned long pending_exceptions; 293 unsigned long pending_exceptions;
294 struct kvm_vcpu_arch_shared *shared;
293 295
294#ifdef CONFIG_PPC_BOOK3S 296#ifdef CONFIG_PPC_BOOK3S
295 struct hlist_head hpte_hash_pte[HPTEG_HASH_NUM_PTE]; 297 struct hlist_head hpte_hash_pte[HPTEG_HASH_NUM_PTE];
diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h
index 2d48f6a63d0b..1485ba87a52a 100644
--- a/arch/powerpc/include/asm/kvm_para.h
+++ b/arch/powerpc/include/asm/kvm_para.h
@@ -20,6 +20,11 @@
20#ifndef __POWERPC_KVM_PARA_H__ 20#ifndef __POWERPC_KVM_PARA_H__
21#define __POWERPC_KVM_PARA_H__ 21#define __POWERPC_KVM_PARA_H__
22 22
23#include <linux/types.h>
24
25struct kvm_vcpu_arch_shared {
26};
27
23#ifdef __KERNEL__ 28#ifdef __KERNEL__
24 29
25static inline int kvm_para_available(void) 30static inline int kvm_para_available(void)
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 1c0607ddccc0..60e7db4c13af 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -400,6 +400,7 @@ int main(void)
400 DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6)); 400 DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6));
401 DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7)); 401 DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7));
402 DEFINE(VCPU_SHADOW_PID, offsetof(struct kvm_vcpu, arch.shadow_pid)); 402 DEFINE(VCPU_SHADOW_PID, offsetof(struct kvm_vcpu, arch.shadow_pid));
403 DEFINE(VCPU_SHARED, offsetof(struct kvm_vcpu, arch.shared));
403 404
404 /* book3s */ 405 /* book3s */
405#ifdef CONFIG_PPC_BOOK3S 406#ifdef CONFIG_PPC_BOOK3S
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index 73c0a3f64ed1..e7b1f3fca5dc 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -123,8 +123,14 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
123 if (err) 123 if (err)
124 goto free_vcpu; 124 goto free_vcpu;
125 125
126 vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO);
127 if (!vcpu->arch.shared)
128 goto uninit_vcpu;
129
126 return vcpu; 130 return vcpu;
127 131
132uninit_vcpu:
133 kvm_vcpu_uninit(vcpu);
128free_vcpu: 134free_vcpu:
129 kmem_cache_free(kvm_vcpu_cache, vcpu_44x); 135 kmem_cache_free(kvm_vcpu_cache, vcpu_44x);
130out: 136out:
@@ -135,6 +141,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
135{ 141{
136 struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); 142 struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
137 143
144 free_page((unsigned long)vcpu->arch.shared);
138 kvm_vcpu_uninit(vcpu); 145 kvm_vcpu_uninit(vcpu);
139 kmem_cache_free(kvm_vcpu_cache, vcpu_44x); 146 kmem_cache_free(kvm_vcpu_cache, vcpu_44x);
140} 147}
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index a3cef30d1d42..b3385dd6f28d 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -1242,6 +1242,10 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
1242 if (err) 1242 if (err)
1243 goto free_shadow_vcpu; 1243 goto free_shadow_vcpu;
1244 1244
1245 vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO);
1246 if (!vcpu->arch.shared)
1247 goto uninit_vcpu;
1248
1245 vcpu->arch.host_retip = kvm_return_point; 1249 vcpu->arch.host_retip = kvm_return_point;
1246 vcpu->arch.host_msr = mfmsr(); 1250 vcpu->arch.host_msr = mfmsr();
1247#ifdef CONFIG_PPC_BOOK3S_64 1251#ifdef CONFIG_PPC_BOOK3S_64
@@ -1268,10 +1272,12 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
1268 1272
1269 err = kvmppc_mmu_init(vcpu); 1273 err = kvmppc_mmu_init(vcpu);
1270 if (err < 0) 1274 if (err < 0)
1271 goto free_shadow_vcpu; 1275 goto uninit_vcpu;
1272 1276
1273 return vcpu; 1277 return vcpu;
1274 1278
1279uninit_vcpu:
1280 kvm_vcpu_uninit(vcpu);
1275free_shadow_vcpu: 1281free_shadow_vcpu:
1276 kfree(vcpu_book3s->shadow_vcpu); 1282 kfree(vcpu_book3s->shadow_vcpu);
1277free_vcpu: 1283free_vcpu:
@@ -1284,6 +1290,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
1284{ 1290{
1285 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); 1291 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
1286 1292
1293 free_page((unsigned long)vcpu->arch.shared);
1287 kvm_vcpu_uninit(vcpu); 1294 kvm_vcpu_uninit(vcpu);
1288 kfree(vcpu_book3s->shadow_vcpu); 1295 kfree(vcpu_book3s->shadow_vcpu);
1289 vfree(vcpu_book3s); 1296 vfree(vcpu_book3s);
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index e8a00b0c4449..71750f2dd5d3 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -117,8 +117,14 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
117 if (err) 117 if (err)
118 goto uninit_vcpu; 118 goto uninit_vcpu;
119 119
120 vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO);
121 if (!vcpu->arch.shared)
122 goto uninit_tlb;
123
120 return vcpu; 124 return vcpu;
121 125
126uninit_tlb:
127 kvmppc_e500_tlb_uninit(vcpu_e500);
122uninit_vcpu: 128uninit_vcpu:
123 kvm_vcpu_uninit(vcpu); 129 kvm_vcpu_uninit(vcpu);
124free_vcpu: 130free_vcpu:
@@ -131,6 +137,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
131{ 137{
132 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 138 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
133 139
140 free_page((unsigned long)vcpu->arch.shared);
134 kvmppc_e500_tlb_uninit(vcpu_e500); 141 kvmppc_e500_tlb_uninit(vcpu_e500);
135 kvm_vcpu_uninit(vcpu); 142 kvm_vcpu_uninit(vcpu);
136 kmem_cache_free(kvm_vcpu_cache, vcpu_e500); 143 kmem_cache_free(kvm_vcpu_cache, vcpu_e500);