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

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.32-rc8 158 lines 3.6 kB view raw
1/* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of the GNU General Public License, version 2, as 4 * published by the Free Software Foundation. 5 * 6 * This program is distributed in the hope that it will be useful, 7 * but WITHOUT ANY WARRANTY; without even the implied warranty of 8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 * GNU General Public License for more details. 10 * 11 * You should have received a copy of the GNU General Public License 12 * along with this program; if not, write to the Free Software 13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 14 * 15 * Copyright IBM Corp. 2008 16 * 17 * Authors: Hollis Blanchard <hollisb@us.ibm.com> 18 */ 19 20#include <linux/kvm_host.h> 21#include <linux/err.h> 22 23#include <asm/reg.h> 24#include <asm/cputable.h> 25#include <asm/tlbflush.h> 26#include <asm/kvm_44x.h> 27#include <asm/kvm_ppc.h> 28 29#include "44x_tlb.h" 30 31void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) 32{ 33 kvmppc_44x_tlb_load(vcpu); 34} 35 36void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) 37{ 38 kvmppc_44x_tlb_put(vcpu); 39} 40 41int kvmppc_core_check_processor_compat(void) 42{ 43 int r; 44 45 if (strcmp(cur_cpu_spec->platform, "ppc440") == 0) 46 r = 0; 47 else 48 r = -ENOTSUPP; 49 50 return r; 51} 52 53int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu) 54{ 55 struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); 56 struct kvmppc_44x_tlbe *tlbe = &vcpu_44x->guest_tlb[0]; 57 int i; 58 59 tlbe->tid = 0; 60 tlbe->word0 = PPC44x_TLB_16M | PPC44x_TLB_VALID; 61 tlbe->word1 = 0; 62 tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR; 63 64 tlbe++; 65 tlbe->tid = 0; 66 tlbe->word0 = 0xef600000 | PPC44x_TLB_4K | PPC44x_TLB_VALID; 67 tlbe->word1 = 0xef600000; 68 tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR 69 | PPC44x_TLB_I | PPC44x_TLB_G; 70 71 /* Since the guest can directly access the timebase, it must know the 72 * real timebase frequency. Accordingly, it must see the state of 73 * CCR1[TCS]. */ 74 vcpu->arch.ccr1 = mfspr(SPRN_CCR1); 75 76 for (i = 0; i < ARRAY_SIZE(vcpu_44x->shadow_refs); i++) 77 vcpu_44x->shadow_refs[i].gtlb_index = -1; 78 79 return 0; 80} 81 82/* 'linear_address' is actually an encoding of AS|PID|EADDR . */ 83int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu, 84 struct kvm_translation *tr) 85{ 86 int index; 87 gva_t eaddr; 88 u8 pid; 89 u8 as; 90 91 eaddr = tr->linear_address; 92 pid = (tr->linear_address >> 32) & 0xff; 93 as = (tr->linear_address >> 40) & 0x1; 94 95 index = kvmppc_44x_tlb_index(vcpu, eaddr, pid, as); 96 if (index == -1) { 97 tr->valid = 0; 98 return 0; 99 } 100 101 tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr); 102 /* XXX what does "writeable" and "usermode" even mean? */ 103 tr->valid = 1; 104 105 return 0; 106} 107 108struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) 109{ 110 struct kvmppc_vcpu_44x *vcpu_44x; 111 struct kvm_vcpu *vcpu; 112 int err; 113 114 vcpu_44x = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); 115 if (!vcpu_44x) { 116 err = -ENOMEM; 117 goto out; 118 } 119 120 vcpu = &vcpu_44x->vcpu; 121 err = kvm_vcpu_init(vcpu, kvm, id); 122 if (err) 123 goto free_vcpu; 124 125 return vcpu; 126 127free_vcpu: 128 kmem_cache_free(kvm_vcpu_cache, vcpu_44x); 129out: 130 return ERR_PTR(err); 131} 132 133void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) 134{ 135 struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); 136 137 kvm_vcpu_uninit(vcpu); 138 kmem_cache_free(kvm_vcpu_cache, vcpu_44x); 139} 140 141static int __init kvmppc_44x_init(void) 142{ 143 int r; 144 145 r = kvmppc_booke_init(); 146 if (r) 147 return r; 148 149 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), THIS_MODULE); 150} 151 152static void __exit kvmppc_44x_exit(void) 153{ 154 kvmppc_booke_exit(); 155} 156 157module_init(kvmppc_44x_init); 158module_exit(kvmppc_44x_exit);