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