Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Alexander Graf and committed by
Avi Kivity
96bc451a 34698d8c

+30 -1
+2
arch/powerpc/include/asm/kvm_host.h
··· 25 25 #include <linux/interrupt.h> 26 26 #include <linux/types.h> 27 27 #include <linux/kvm_types.h> 28 + #include <linux/kvm_para.h> 28 29 #include <asm/kvm_asm.h> 29 30 30 31 #define KVM_MAX_VCPUS 1 ··· 291 290 struct tasklet_struct tasklet; 292 291 u64 dec_jiffies; 293 292 unsigned long pending_exceptions; 293 + struct kvm_vcpu_arch_shared *shared; 294 294 295 295 #ifdef CONFIG_PPC_BOOK3S 296 296 struct hlist_head hpte_hash_pte[HPTEG_HASH_NUM_PTE];
+5
arch/powerpc/include/asm/kvm_para.h
··· 20 20 #ifndef __POWERPC_KVM_PARA_H__ 21 21 #define __POWERPC_KVM_PARA_H__ 22 22 23 + #include <linux/types.h> 24 + 25 + struct kvm_vcpu_arch_shared { 26 + }; 27 + 23 28 #ifdef __KERNEL__ 24 29 25 30 static inline int kvm_para_available(void)
+1
arch/powerpc/kernel/asm-offsets.c
··· 400 400 DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6)); 401 401 DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7)); 402 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 405 /* book3s */ 405 406 #ifdef CONFIG_PPC_BOOK3S
+7
arch/powerpc/kvm/44x.c
··· 123 123 if (err) 124 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 130 return vcpu; 127 131 132 + uninit_vcpu: 133 + kvm_vcpu_uninit(vcpu); 128 134 free_vcpu: 129 135 kmem_cache_free(kvm_vcpu_cache, vcpu_44x); 130 136 out: ··· 141 135 { 142 136 struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); 143 137 138 + free_page((unsigned long)vcpu->arch.shared); 144 139 kvm_vcpu_uninit(vcpu); 145 140 kmem_cache_free(kvm_vcpu_cache, vcpu_44x); 146 141 }
+8 -1
arch/powerpc/kvm/book3s.c
··· 1242 1242 if (err) 1243 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 1249 vcpu->arch.host_retip = kvm_return_point; 1246 1250 vcpu->arch.host_msr = mfmsr(); 1247 1251 #ifdef CONFIG_PPC_BOOK3S_64 ··· 1272 1268 1273 1269 err = kvmppc_mmu_init(vcpu); 1274 1270 if (err < 0) 1275 - goto free_shadow_vcpu; 1271 + goto uninit_vcpu; 1276 1272 1277 1273 return vcpu; 1278 1274 1275 + uninit_vcpu: 1276 + kvm_vcpu_uninit(vcpu); 1279 1277 free_shadow_vcpu: 1280 1278 kfree(vcpu_book3s->shadow_vcpu); 1281 1279 free_vcpu: ··· 1290 1284 { 1291 1285 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); 1292 1286 1287 + free_page((unsigned long)vcpu->arch.shared); 1293 1288 kvm_vcpu_uninit(vcpu); 1294 1289 kfree(vcpu_book3s->shadow_vcpu); 1295 1290 vfree(vcpu_book3s);
+7
arch/powerpc/kvm/e500.c
··· 117 117 if (err) 118 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 124 return vcpu; 121 125 126 + uninit_tlb: 127 + kvmppc_e500_tlb_uninit(vcpu_e500); 122 128 uninit_vcpu: 123 129 kvm_vcpu_uninit(vcpu); 124 130 free_vcpu: ··· 137 131 { 138 132 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 139 133 134 + free_page((unsigned long)vcpu->arch.shared); 140 135 kvmppc_e500_tlb_uninit(vcpu_e500); 141 136 kvm_vcpu_uninit(vcpu); 142 137 kmem_cache_free(kvm_vcpu_cache, vcpu_e500);