1 /* 2 * PPC64 processor support 3 * 4 * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 as published 8 * by the Free Software Foundation. 9 */ 10 11 #include "kvm/kvm-cpu.h" 12 13 #include "kvm/symbol.h" 14 #include "kvm/util.h" 15 #include "kvm/kvm.h" 16 17 #include <sys/ioctl.h> 18 #include <sys/mman.h> 19 #include <signal.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <errno.h> 23 #include <stdio.h> 24 25 static int debug_fd; 26 27 void kvm_cpu__set_debug_fd(int fd) 28 { 29 debug_fd = fd; 30 } 31 32 int kvm_cpu__get_debug_fd(void) 33 { 34 return debug_fd; 35 } 36 37 static struct kvm_cpu *kvm_cpu__new(struct kvm *kvm) 38 { 39 struct kvm_cpu *vcpu; 40 41 vcpu = calloc(1, sizeof *vcpu); 42 if (!vcpu) 43 return NULL; 44 45 vcpu->kvm = kvm; 46 47 return vcpu; 48 } 49 50 void kvm_cpu__delete(struct kvm_cpu *vcpu) 51 { 52 free(vcpu); 53 } 54 55 struct kvm_cpu *kvm_cpu__init(struct kvm *kvm, unsigned long cpu_id) 56 { 57 struct kvm_cpu *vcpu; 58 int mmap_size; 59 struct kvm_enable_cap papr_cap = { .cap = KVM_CAP_PPC_PAPR }; 60 61 vcpu = kvm_cpu__new(kvm); 62 if (!vcpu) 63 return NULL; 64 65 vcpu->cpu_id = cpu_id; 66 67 vcpu->vcpu_fd = ioctl(vcpu->kvm->vm_fd, KVM_CREATE_VCPU, cpu_id); 68 if (vcpu->vcpu_fd < 0) 69 die_perror("KVM_CREATE_VCPU ioctl"); 70 71 mmap_size = ioctl(vcpu->kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0); 72 if (mmap_size < 0) 73 die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl"); 74 75 vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED, vcpu->vcpu_fd, 0); 76 if (vcpu->kvm_run == MAP_FAILED) 77 die("unable to mmap vcpu fd"); 78 79 if (ioctl(vcpu->vcpu_fd, KVM_ENABLE_CAP, &papr_cap) < 0) 80 die("unable to enable PAPR capability"); 81 82 /* 83 * We start all CPUs, directing non-primary threads into the kernel's 84 * secondary start point. When we come to support SLOF, we will start 85 * only one and SLOF will RTAS call us to ask for others to be 86 * started. (FIXME: make more generic & interface with whichever 87 * firmware a platform may be using.) 88 */ 89 vcpu->is_running = true; 90 91 return vcpu; 92 } 93 94 static void kvm_cpu__setup_fpu(struct kvm_cpu *vcpu) 95 { 96 /* Don't have to do anything, there's no expected FPU state. */ 97 } 98 99 static void kvm_cpu__setup_regs(struct kvm_cpu *vcpu) 100 { 101 /* 102 * FIXME: This assumes PPC64 and Linux guest. It doesn't use the 103 * OpenFirmware entry method, but instead the "embedded" entry which 104 * passes the FDT address directly. 105 */ 106 struct kvm_regs *r = &vcpu->regs; 107 108 if (vcpu->cpu_id == 0) { 109 r->pc = KERNEL_START_ADDR; 110 r->gpr[3] = vcpu->kvm->fdt_gra; 111 r->gpr[5] = 0; 112 } else { 113 r->pc = KERNEL_SECONDARY_START_ADDR; 114 r->gpr[3] = vcpu->cpu_id; 115 } 116 r->msr = 0x8000000000001000UL; /* 64bit, non-HV, ME */ 117 118 if (ioctl(vcpu->vcpu_fd, KVM_SET_REGS, &vcpu->regs) < 0) 119 die_perror("KVM_SET_REGS failed"); 120 } 121 122 static void kvm_cpu__setup_sregs(struct kvm_cpu *vcpu) 123 { 124 /* 125 * Some sregs setup to initialise SDR1/PVR/HIOR on PPC64 SPAPR 126 * platforms using PR KVM. (Technically, this is all ignored on 127 * SPAPR HV KVM.) Different setup is required for non-PV non-SPAPR 128 * platforms! (FIXME.) 129 */ 130 struct kvm_sregs sregs; 131 struct kvm_one_reg reg = {}; 132 133 if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &sregs) < 0) 134 die("KVM_GET_SREGS failed"); 135 136 sregs.u.s.sdr1 = vcpu->kvm->sdr1; 137 sregs.pvr = vcpu->kvm->pvr; 138 139 if (ioctl(vcpu->vcpu_fd, KVM_SET_SREGS, &sregs) < 0) 140 die("KVM_SET_SREGS failed"); 141 142 reg.id = KVM_ONE_REG_PPC_HIOR; 143 reg.u.reg64 = 0; 144 if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0) 145 die("KVM_SET_ONE_REG failed"); 146 } 147 148 /** 149 * kvm_cpu__reset_vcpu - reset virtual CPU to a known state 150 */ 151 void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu) 152 { 153 kvm_cpu__setup_regs(vcpu); 154 kvm_cpu__setup_sregs(vcpu); 155 kvm_cpu__setup_fpu(vcpu); 156 } 157 158 /* kvm_cpu__irq - set KVM's IRQ flag on this vcpu */ 159 void kvm_cpu__irq(struct kvm_cpu *vcpu, int pin, int level) 160 { 161 } 162 163 void kvm_cpu__arch_nmi(struct kvm_cpu *cpu) 164 { 165 } 166 167 bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu) 168 { 169 bool ret = true; 170 struct kvm_run *run = vcpu->kvm_run; 171 switch(run->exit_reason) { 172 default: 173 ret = false; 174 } 175 return ret; 176 } 177 178 #define CONDSTR_BIT(m, b) (((m) & MSR_##b) ? #b" " : "") 179 180 void kvm_cpu__show_registers(struct kvm_cpu *vcpu) 181 { 182 struct kvm_regs regs; 183 struct kvm_sregs sregs; 184 int r; 185 186 if (ioctl(vcpu->vcpu_fd, KVM_GET_REGS, ®s) < 0) 187 die("KVM_GET_REGS failed"); 188 if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &sregs) < 0) 189 die("KVM_GET_SREGS failed"); 190 191 dprintf(debug_fd, "\n Registers:\n"); 192 dprintf(debug_fd, " NIP: %016llx MSR: %016llx " 193 "( %s%s%s%s%s%s%s%s%s%s%s%s)\n", 194 regs.pc, regs.msr, 195 CONDSTR_BIT(regs.msr, SF), 196 CONDSTR_BIT(regs.msr, HV), /* ! */ 197 CONDSTR_BIT(regs.msr, VEC), 198 CONDSTR_BIT(regs.msr, VSX), 199 CONDSTR_BIT(regs.msr, EE), 200 CONDSTR_BIT(regs.msr, PR), 201 CONDSTR_BIT(regs.msr, FP), 202 CONDSTR_BIT(regs.msr, ME), 203 CONDSTR_BIT(regs.msr, IR), 204 CONDSTR_BIT(regs.msr, DR), 205 CONDSTR_BIT(regs.msr, RI), 206 CONDSTR_BIT(regs.msr, LE)); 207 dprintf(debug_fd, " CTR: %016llx LR: %016llx CR: %08llx\n", 208 regs.ctr, regs.lr, regs.cr); 209 dprintf(debug_fd, " SRR0: %016llx SRR1: %016llx XER: %016llx\n", 210 regs.srr0, regs.srr1, regs.xer); 211 dprintf(debug_fd, " SPRG0: %016llx SPRG1: %016llx\n", 212 regs.sprg0, regs.sprg1); 213 dprintf(debug_fd, " SPRG2: %016llx SPRG3: %016llx\n", 214 regs.sprg2, regs.sprg3); 215 dprintf(debug_fd, " SPRG4: %016llx SPRG5: %016llx\n", 216 regs.sprg4, regs.sprg5); 217 dprintf(debug_fd, " SPRG6: %016llx SPRG7: %016llx\n", 218 regs.sprg6, regs.sprg7); 219 dprintf(debug_fd, " GPRs:\n "); 220 for (r = 0; r < 32; r++) { 221 dprintf(debug_fd, "%016llx ", regs.gpr[r]); 222 if ((r & 3) == 3) 223 dprintf(debug_fd, "\n "); 224 } 225 dprintf(debug_fd, "\n"); 226 227 /* FIXME: Assumes SLB-based (book3s) guest */ 228 for (r = 0; r < 32; r++) { 229 dprintf(debug_fd, " SLB%02d %016llx %016llx\n", r, 230 sregs.u.s.ppc64.slb[r].slbe, 231 sregs.u.s.ppc64.slb[r].slbv); 232 } 233 dprintf(debug_fd, "----------\n"); 234 } 235 236 void kvm_cpu__show_code(struct kvm_cpu *vcpu) 237 { 238 if (ioctl(vcpu->vcpu_fd, KVM_GET_REGS, &vcpu->regs) < 0) 239 die("KVM_GET_REGS failed"); 240 241 /* FIXME: Dump/disassemble some code...! */ 242 243 dprintf(debug_fd, "\n Stack:\n"); 244 dprintf(debug_fd, " ------\n"); 245 /* Only works in real mode: */ 246 kvm__dump_mem(vcpu->kvm, vcpu->regs.gpr[1], 32); 247 } 248 249 void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu) 250 { 251 /* Does nothing yet */ 252 } 253