xref: /kvmtool/powerpc/kvm-cpu.c (revision df4239fb27a9670b554d71fb4a79bacfb804d477)
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 "spapr.h"
18 #include "spapr_pci.h"
19 #include "xics.h"
20 
21 #include <sys/ioctl.h>
22 #include <sys/mman.h>
23 #include <signal.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <stdio.h>
28 #include <assert.h>
29 
30 static int debug_fd;
31 
32 void kvm_cpu__set_debug_fd(int fd)
33 {
34 	debug_fd = fd;
35 }
36 
37 int kvm_cpu__get_debug_fd(void)
38 {
39 	return debug_fd;
40 }
41 
42 static struct kvm_cpu *kvm_cpu__new(struct kvm *kvm)
43 {
44 	struct kvm_cpu *vcpu;
45 
46 	vcpu		= calloc(1, sizeof *vcpu);
47 	if (!vcpu)
48 		return NULL;
49 
50 	vcpu->kvm	= kvm;
51 
52 	return vcpu;
53 }
54 
55 void kvm_cpu__delete(struct kvm_cpu *vcpu)
56 {
57 	free(vcpu);
58 }
59 
60 struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
61 {
62 	struct kvm_cpu *vcpu;
63 	int mmap_size;
64 	struct kvm_enable_cap papr_cap = { .cap = KVM_CAP_PPC_PAPR };
65 
66 	vcpu		= kvm_cpu__new(kvm);
67 	if (!vcpu)
68 		return NULL;
69 
70 	vcpu->cpu_id	= cpu_id;
71 
72 	vcpu->vcpu_fd = ioctl(vcpu->kvm->vm_fd, KVM_CREATE_VCPU, cpu_id);
73 	if (vcpu->vcpu_fd < 0)
74 		die_perror("KVM_CREATE_VCPU ioctl");
75 
76 	mmap_size = ioctl(vcpu->kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0);
77 	if (mmap_size < 0)
78 		die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl");
79 
80 	vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED, vcpu->vcpu_fd, 0);
81 	if (vcpu->kvm_run == MAP_FAILED)
82 		die("unable to mmap vcpu fd");
83 
84 	if (ioctl(vcpu->vcpu_fd, KVM_ENABLE_CAP, &papr_cap) < 0)
85 		die("unable to enable PAPR capability");
86 
87 	/*
88 	 * We start all CPUs, directing non-primary threads into the kernel's
89 	 * secondary start point.  When we come to support SLOF, we will start
90 	 * only one and SLOF will RTAS call us to ask for others to be
91 	 * started.  (FIXME: make more generic & interface with whichever
92 	 * firmware a platform may be using.)
93 	 */
94 	vcpu->is_running = true;
95 
96 	/* Register with IRQ controller (FIXME, assumes XICS) */
97 	xics_cpu_register(vcpu);
98 
99 	return vcpu;
100 }
101 
102 static void kvm_cpu__setup_fpu(struct kvm_cpu *vcpu)
103 {
104 	/* Don't have to do anything, there's no expected FPU state. */
105 }
106 
107 static void kvm_cpu__setup_regs(struct kvm_cpu *vcpu)
108 {
109 	/*
110 	 * FIXME: This assumes PPC64 and Linux guest.  It doesn't use the
111 	 * OpenFirmware entry method, but instead the "embedded" entry which
112 	 * passes the FDT address directly.
113 	 */
114 	struct kvm_regs *r = &vcpu->regs;
115 
116 	if (vcpu->cpu_id == 0) {
117 		r->pc = KERNEL_START_ADDR;
118 		r->gpr[3] = vcpu->kvm->arch.fdt_gra;
119 		r->gpr[5] = 0;
120 	} else {
121 		r->pc = KERNEL_SECONDARY_START_ADDR;
122 		r->gpr[3] = vcpu->cpu_id;
123 	}
124 	r->msr = 0x8000000000001000UL; /* 64bit, non-HV, ME */
125 
126 	if (ioctl(vcpu->vcpu_fd, KVM_SET_REGS, &vcpu->regs) < 0)
127 		die_perror("KVM_SET_REGS failed");
128 }
129 
130 static void kvm_cpu__setup_sregs(struct kvm_cpu *vcpu)
131 {
132 	/*
133 	 * Some sregs setup to initialise SDR1/PVR/HIOR on PPC64 SPAPR
134 	 * platforms using PR KVM.  (Technically, this is all ignored on
135 	 * SPAPR HV KVM.)  Different setup is required for non-PV non-SPAPR
136 	 * platforms!  (FIXME.)
137 	 */
138 	struct kvm_sregs sregs;
139 	struct kvm_one_reg reg = {};
140 	u64 value;
141 
142 	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &sregs) < 0)
143 		die("KVM_GET_SREGS failed");
144 
145 	sregs.u.s.sdr1 = vcpu->kvm->arch.sdr1;
146 	sregs.pvr = vcpu->kvm->arch.pvr;
147 
148 	if (ioctl(vcpu->vcpu_fd, KVM_SET_SREGS, &sregs) < 0)
149 		die("KVM_SET_SREGS failed");
150 
151 	reg.id = KVM_REG_PPC_HIOR;
152 	value = 0;
153 	reg.addr = (u64)&value;
154 	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
155 		die("KVM_SET_ONE_REG failed");
156 }
157 
158 /**
159  * kvm_cpu__reset_vcpu - reset virtual CPU to a known state
160  */
161 void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
162 {
163 	kvm_cpu__setup_regs(vcpu);
164 	kvm_cpu__setup_sregs(vcpu);
165 	kvm_cpu__setup_fpu(vcpu);
166 }
167 
168 /* kvm_cpu__irq - set KVM's IRQ flag on this vcpu */
169 void kvm_cpu__irq(struct kvm_cpu *vcpu, int pin, int level)
170 {
171 	unsigned int virq = level ? KVM_INTERRUPT_SET_LEVEL : KVM_INTERRUPT_UNSET;
172 
173 	/* FIXME: POWER-specific */
174 	if (pin != POWER7_EXT_IRQ)
175 		return;
176 	if (ioctl(vcpu->vcpu_fd, KVM_INTERRUPT, &virq) < 0)
177 		pr_warning("Could not KVM_INTERRUPT.");
178 }
179 
180 void kvm_cpu__arch_nmi(struct kvm_cpu *cpu)
181 {
182 }
183 
184 bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
185 {
186 	bool ret = true;
187 	struct kvm_run *run = vcpu->kvm_run;
188 	switch(run->exit_reason) {
189 	case KVM_EXIT_PAPR_HCALL:
190 		run->papr_hcall.ret = spapr_hypercall(vcpu, run->papr_hcall.nr,
191 						      (target_ulong*)run->papr_hcall.args);
192 		break;
193 	default:
194 		ret = false;
195 	}
196 	return ret;
197 }
198 
199 bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write)
200 {
201 	/*
202 	 * FIXME: This function will need to be split in order to support
203 	 * various PowerPC platforms/PHB types, etc.  It currently assumes SPAPR
204 	 * PPC64 guest.
205 	 */
206 	bool ret = false;
207 
208 	if ((phys_addr >= SPAPR_PCI_WIN_START) &&
209 	    (phys_addr < SPAPR_PCI_WIN_END)) {
210 		ret = spapr_phb_mmio(kvm, phys_addr, data, len, is_write);
211 	} else {
212 		pr_warning("MMIO %s unknown address %llx (size %d)!\n",
213 			   is_write ? "write to" : "read from",
214 			   phys_addr, len);
215 	}
216 	return ret;
217 }
218 
219 #define CONDSTR_BIT(m, b) (((m) & MSR_##b) ? #b" " : "")
220 
221 void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
222 {
223 	struct kvm_regs regs;
224 	struct kvm_sregs sregs;
225 	int r;
226 
227 	if (ioctl(vcpu->vcpu_fd, KVM_GET_REGS, &regs) < 0)
228 		die("KVM_GET_REGS failed");
229         if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &sregs) < 0)
230 		die("KVM_GET_SREGS failed");
231 
232 	dprintf(debug_fd, "\n Registers:\n");
233 	dprintf(debug_fd, " NIP:   %016llx  MSR:   %016llx "
234 		"( %s%s%s%s%s%s%s%s%s%s%s%s)\n",
235 		regs.pc, regs.msr,
236 		CONDSTR_BIT(regs.msr, SF),
237 		CONDSTR_BIT(regs.msr, HV), /* ! */
238 		CONDSTR_BIT(regs.msr, VEC),
239 		CONDSTR_BIT(regs.msr, VSX),
240 		CONDSTR_BIT(regs.msr, EE),
241 		CONDSTR_BIT(regs.msr, PR),
242 		CONDSTR_BIT(regs.msr, FP),
243 		CONDSTR_BIT(regs.msr, ME),
244 		CONDSTR_BIT(regs.msr, IR),
245 		CONDSTR_BIT(regs.msr, DR),
246 		CONDSTR_BIT(regs.msr, RI),
247 		CONDSTR_BIT(regs.msr, LE));
248 	dprintf(debug_fd, " CTR:   %016llx  LR:    %016llx  CR:   %08llx\n",
249 		regs.ctr, regs.lr, regs.cr);
250 	dprintf(debug_fd, " SRR0:  %016llx  SRR1:  %016llx  XER:  %016llx\n",
251 		regs.srr0, regs.srr1, regs.xer);
252 	dprintf(debug_fd, " SPRG0: %016llx  SPRG1: %016llx\n",
253 		regs.sprg0, regs.sprg1);
254 	dprintf(debug_fd, " SPRG2: %016llx  SPRG3: %016llx\n",
255 		regs.sprg2, regs.sprg3);
256 	dprintf(debug_fd, " SPRG4: %016llx  SPRG5: %016llx\n",
257 		regs.sprg4, regs.sprg5);
258 	dprintf(debug_fd, " SPRG6: %016llx  SPRG7: %016llx\n",
259 		regs.sprg6, regs.sprg7);
260 	dprintf(debug_fd, " GPRs:\n ");
261 	for (r = 0; r < 32; r++) {
262 		dprintf(debug_fd, "%016llx  ", regs.gpr[r]);
263 		if ((r & 3) == 3)
264 			dprintf(debug_fd, "\n ");
265 	}
266 	dprintf(debug_fd, "\n");
267 
268 	/* FIXME: Assumes SLB-based (book3s) guest */
269 	for (r = 0; r < 32; r++) {
270 		dprintf(debug_fd, " SLB%02d  %016llx %016llx\n", r,
271 			sregs.u.s.ppc64.slb[r].slbe,
272 			sregs.u.s.ppc64.slb[r].slbv);
273 	}
274 	dprintf(debug_fd, "----------\n");
275 }
276 
277 void kvm_cpu__show_code(struct kvm_cpu *vcpu)
278 {
279 	if (ioctl(vcpu->vcpu_fd, KVM_GET_REGS, &vcpu->regs) < 0)
280 		die("KVM_GET_REGS failed");
281 
282 	/* FIXME: Dump/disassemble some code...! */
283 
284 	dprintf(debug_fd, "\n Stack:\n");
285 	dprintf(debug_fd,   " ------\n");
286 	/* Only works in real mode: */
287 	kvm__dump_mem(vcpu->kvm, vcpu->regs.gpr[1], 32);
288 }
289 
290 void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu)
291 {
292 	/* Does nothing yet */
293 }
294