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 v3.1-rc8 177 lines 4.1 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/slab.h> 22#include <linux/err.h> 23 24#include <asm/reg.h> 25#include <asm/cputable.h> 26#include <asm/tlbflush.h> 27#include <asm/kvm_44x.h> 28#include <asm/kvm_ppc.h> 29 30#include "44x_tlb.h" 31 32void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) 33{ 34 kvmppc_44x_tlb_load(vcpu); 35} 36 37void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu) 38{ 39 kvmppc_44x_tlb_put(vcpu); 40} 41 42int kvmppc_core_check_processor_compat(void) 43{ 44 int r; 45 46 if (strncmp(cur_cpu_spec->platform, "ppc440", 6) == 0) 47 r = 0; 48 else 49 r = -ENOTSUPP; 50 51 return r; 52} 53 54int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu) 55{ 56 struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); 57 struct kvmppc_44x_tlbe *tlbe = &vcpu_44x->guest_tlb[0]; 58 int i; 59 60 tlbe->tid = 0; 61 tlbe->word0 = PPC44x_TLB_16M | PPC44x_TLB_VALID; 62 tlbe->word1 = 0; 63 tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR; 64 65 tlbe++; 66 tlbe->tid = 0; 67 tlbe->word0 = 0xef600000 | PPC44x_TLB_4K | PPC44x_TLB_VALID; 68 tlbe->word1 = 0xef600000; 69 tlbe->word2 = PPC44x_TLB_SX | PPC44x_TLB_SW | PPC44x_TLB_SR 70 | PPC44x_TLB_I | PPC44x_TLB_G; 71 72 /* Since the guest can directly access the timebase, it must know the 73 * real timebase frequency. Accordingly, it must see the state of 74 * CCR1[TCS]. */ 75 /* XXX CCR1 doesn't exist on all 440 SoCs. */ 76 vcpu->arch.ccr1 = mfspr(SPRN_CCR1); 77 78 for (i = 0; i < ARRAY_SIZE(vcpu_44x->shadow_refs); i++) 79 vcpu_44x->shadow_refs[i].gtlb_index = -1; 80 81 return 0; 82} 83 84/* 'linear_address' is actually an encoding of AS|PID|EADDR . */ 85int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu, 86 struct kvm_translation *tr) 87{ 88 int index; 89 gva_t eaddr; 90 u8 pid; 91 u8 as; 92 93 eaddr = tr->linear_address; 94 pid = (tr->linear_address >> 32) & 0xff; 95 as = (tr->linear_address >> 40) & 0x1; 96 97 index = kvmppc_44x_tlb_index(vcpu, eaddr, pid, as); 98 if (index == -1) { 99 tr->valid = 0; 100 return 0; 101 } 102 103 tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr); 104 /* XXX what does "writeable" and "usermode" even mean? */ 105 tr->valid = 1; 106 107 return 0; 108} 109 110void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 111{ 112 kvmppc_get_sregs_ivor(vcpu, sregs); 113} 114 115int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) 116{ 117 return kvmppc_set_sregs_ivor(vcpu, sregs); 118} 119 120struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) 121{ 122 struct kvmppc_vcpu_44x *vcpu_44x; 123 struct kvm_vcpu *vcpu; 124 int err; 125 126 vcpu_44x = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); 127 if (!vcpu_44x) { 128 err = -ENOMEM; 129 goto out; 130 } 131 132 vcpu = &vcpu_44x->vcpu; 133 err = kvm_vcpu_init(vcpu, kvm, id); 134 if (err) 135 goto free_vcpu; 136 137 vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO); 138 if (!vcpu->arch.shared) 139 goto uninit_vcpu; 140 141 return vcpu; 142 143uninit_vcpu: 144 kvm_vcpu_uninit(vcpu); 145free_vcpu: 146 kmem_cache_free(kvm_vcpu_cache, vcpu_44x); 147out: 148 return ERR_PTR(err); 149} 150 151void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) 152{ 153 struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu); 154 155 free_page((unsigned long)vcpu->arch.shared); 156 kvm_vcpu_uninit(vcpu); 157 kmem_cache_free(kvm_vcpu_cache, vcpu_44x); 158} 159 160static int __init kvmppc_44x_init(void) 161{ 162 int r; 163 164 r = kvmppc_booke_init(); 165 if (r) 166 return r; 167 168 return kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), 0, THIS_MODULE); 169} 170 171static void __exit kvmppc_44x_exit(void) 172{ 173 kvmppc_booke_exit(); 174} 175 176module_init(kvmppc_44x_init); 177module_exit(kvmppc_44x_exit);