-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 133699 b: refs/heads/master c: bc8080c h: refs/heads/master i: 133697: 5bacc33 133695: 3286118 v: v3
- Loading branch information
Hollis Blanchard
authored and
Avi Kivity
committed
Mar 24, 2009
1 parent
e943104
commit 9dfc3e8
Showing
8 changed files
with
1,331 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 17c885eb5c38f39a2bb3143a67687bd905dcd0fa | ||
refs/heads/master: bc8080cbcc8870178f0910edd537d0cb5706d703 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved. | ||
* | ||
* Author: Yu Liu, <yu.liu@freescale.com> | ||
* | ||
* Description: | ||
* This file is derived from arch/powerpc/include/asm/kvm_44x.h, | ||
* by Hollis Blanchard <hollisb@us.ibm.com>. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License, version 2, as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#ifndef __ASM_KVM_E500_H__ | ||
#define __ASM_KVM_E500_H__ | ||
|
||
#include <linux/kvm_host.h> | ||
|
||
#define BOOKE_INTERRUPT_SIZE 36 | ||
|
||
#define E500_PID_NUM 3 | ||
#define E500_TLB_NUM 2 | ||
|
||
struct tlbe{ | ||
u32 mas1; | ||
u32 mas2; | ||
u32 mas3; | ||
u32 mas7; | ||
}; | ||
|
||
struct kvmppc_vcpu_e500 { | ||
/* Unmodified copy of the guest's TLB. */ | ||
struct tlbe *guest_tlb[E500_TLB_NUM]; | ||
/* TLB that's actually used when the guest is running. */ | ||
struct tlbe *shadow_tlb[E500_TLB_NUM]; | ||
/* Pages which are referenced in the shadow TLB. */ | ||
struct page **shadow_pages[E500_TLB_NUM]; | ||
|
||
unsigned int guest_tlb_size[E500_TLB_NUM]; | ||
unsigned int shadow_tlb_size[E500_TLB_NUM]; | ||
unsigned int guest_tlb_nv[E500_TLB_NUM]; | ||
|
||
u32 host_pid[E500_PID_NUM]; | ||
u32 pid[E500_PID_NUM]; | ||
|
||
u32 mas0; | ||
u32 mas1; | ||
u32 mas2; | ||
u32 mas3; | ||
u32 mas4; | ||
u32 mas5; | ||
u32 mas6; | ||
u32 mas7; | ||
u32 l1csr1; | ||
u32 hid0; | ||
u32 hid1; | ||
|
||
struct kvm_vcpu vcpu; | ||
}; | ||
|
||
static inline struct kvmppc_vcpu_e500 *to_e500(struct kvm_vcpu *vcpu) | ||
{ | ||
return container_of(vcpu, struct kvmppc_vcpu_e500, vcpu); | ||
} | ||
|
||
#endif /* __ASM_KVM_E500_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
/* | ||
* Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved. | ||
* | ||
* Author: Yu Liu, <yu.liu@freescale.com> | ||
* | ||
* Description: | ||
* This file is derived from arch/powerpc/kvm/44x.c, | ||
* by Hollis Blanchard <hollisb@us.ibm.com>. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License, version 2, as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#include <linux/kvm_host.h> | ||
#include <linux/err.h> | ||
|
||
#include <asm/reg.h> | ||
#include <asm/cputable.h> | ||
#include <asm/tlbflush.h> | ||
#include <asm/kvm_e500.h> | ||
#include <asm/kvm_ppc.h> | ||
|
||
#include "e500_tlb.h" | ||
|
||
void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu) | ||
{ | ||
} | ||
|
||
void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu) | ||
{ | ||
} | ||
|
||
void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | ||
{ | ||
kvmppc_e500_tlb_load(vcpu, cpu); | ||
} | ||
|
||
void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) | ||
{ | ||
kvmppc_e500_tlb_put(vcpu); | ||
} | ||
|
||
int kvmppc_core_check_processor_compat(void) | ||
{ | ||
int r; | ||
|
||
if (strcmp(cur_cpu_spec->cpu_name, "e500v2") == 0) | ||
r = 0; | ||
else | ||
r = -ENOTSUPP; | ||
|
||
return r; | ||
} | ||
|
||
int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu) | ||
{ | ||
struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); | ||
|
||
kvmppc_e500_tlb_setup(vcpu_e500); | ||
|
||
/* Use the same core vertion as host's */ | ||
vcpu->arch.pvr = mfspr(SPRN_PVR); | ||
|
||
return 0; | ||
} | ||
|
||
/* 'linear_address' is actually an encoding of AS|PID|EADDR . */ | ||
int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu, | ||
struct kvm_translation *tr) | ||
{ | ||
int index; | ||
gva_t eaddr; | ||
u8 pid; | ||
u8 as; | ||
|
||
eaddr = tr->linear_address; | ||
pid = (tr->linear_address >> 32) & 0xff; | ||
as = (tr->linear_address >> 40) & 0x1; | ||
|
||
index = kvmppc_e500_tlb_search(vcpu, eaddr, pid, as); | ||
if (index < 0) { | ||
tr->valid = 0; | ||
return 0; | ||
} | ||
|
||
tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr); | ||
/* XXX what does "writeable" and "usermode" even mean? */ | ||
tr->valid = 1; | ||
|
||
return 0; | ||
} | ||
|
||
struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) | ||
{ | ||
struct kvmppc_vcpu_e500 *vcpu_e500; | ||
struct kvm_vcpu *vcpu; | ||
int err; | ||
|
||
vcpu_e500 = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); | ||
if (!vcpu_e500) { | ||
err = -ENOMEM; | ||
goto out; | ||
} | ||
|
||
vcpu = &vcpu_e500->vcpu; | ||
err = kvm_vcpu_init(vcpu, kvm, id); | ||
if (err) | ||
goto free_vcpu; | ||
|
||
err = kvmppc_e500_tlb_init(vcpu_e500); | ||
if (err) | ||
goto uninit_vcpu; | ||
|
||
return vcpu; | ||
|
||
uninit_vcpu: | ||
kvm_vcpu_uninit(vcpu); | ||
free_vcpu: | ||
kmem_cache_free(kvm_vcpu_cache, vcpu_e500); | ||
out: | ||
return ERR_PTR(err); | ||
} | ||
|
||
void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) | ||
{ | ||
struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); | ||
|
||
kvmppc_e500_tlb_uninit(vcpu_e500); | ||
kvm_vcpu_uninit(vcpu); | ||
kmem_cache_free(kvm_vcpu_cache, vcpu_e500); | ||
} | ||
|
||
static int kvmppc_e500_init(void) | ||
{ | ||
int r; | ||
|
||
r = kvmppc_booke_init(); | ||
if (r) | ||
return r; | ||
|
||
return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE); | ||
} | ||
|
||
static void kvmppc_e500_exit(void) | ||
{ | ||
kvmppc_booke_exit(); | ||
} | ||
|
||
module_init(kvmppc_e500_init); | ||
module_exit(kvmppc_e500_exit); |
Oops, something went wrong.