aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/booke.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/booke.c')
-rw-r--r--arch/powerpc/kvm/booke.c93
1 files changed, 67 insertions, 26 deletions
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index e7bf4d029484..2a3a1953d4bd 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -21,6 +21,7 @@
21#include <linux/errno.h> 21#include <linux/errno.h>
22#include <linux/err.h> 22#include <linux/err.h>
23#include <linux/kvm_host.h> 23#include <linux/kvm_host.h>
24#include <linux/gfp.h>
24#include <linux/module.h> 25#include <linux/module.h>
25#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
26#include <linux/fs.h> 27#include <linux/fs.h>
@@ -69,10 +70,10 @@ void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu)
69 70
70 for (i = 0; i < 32; i += 4) { 71 for (i = 0; i < 32; i += 4) {
71 printk("gpr%02d: %08lx %08lx %08lx %08lx\n", i, 72 printk("gpr%02d: %08lx %08lx %08lx %08lx\n", i,
72 vcpu->arch.gpr[i], 73 kvmppc_get_gpr(vcpu, i),
73 vcpu->arch.gpr[i+1], 74 kvmppc_get_gpr(vcpu, i+1),
74 vcpu->arch.gpr[i+2], 75 kvmppc_get_gpr(vcpu, i+2),
75 vcpu->arch.gpr[i+3]); 76 kvmppc_get_gpr(vcpu, i+3));
76 } 77 }
77} 78}
78 79
@@ -82,8 +83,32 @@ static void kvmppc_booke_queue_irqprio(struct kvm_vcpu *vcpu,
82 set_bit(priority, &vcpu->arch.pending_exceptions); 83 set_bit(priority, &vcpu->arch.pending_exceptions);
83} 84}
84 85
85void kvmppc_core_queue_program(struct kvm_vcpu *vcpu) 86static void kvmppc_core_queue_dtlb_miss(struct kvm_vcpu *vcpu,
87 ulong dear_flags, ulong esr_flags)
86{ 88{
89 vcpu->arch.queued_dear = dear_flags;
90 vcpu->arch.queued_esr = esr_flags;
91 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS);
92}
93
94static void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu,
95 ulong dear_flags, ulong esr_flags)
96{
97 vcpu->arch.queued_dear = dear_flags;
98 vcpu->arch.queued_esr = esr_flags;
99 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE);
100}
101
102static void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu,
103 ulong esr_flags)
104{
105 vcpu->arch.queued_esr = esr_flags;
106 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE);
107}
108
109void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong esr_flags)
110{
111 vcpu->arch.queued_esr = esr_flags;
87 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM); 112 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM);
88} 113}
89 114
@@ -97,6 +122,11 @@ int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
97 return test_bit(BOOKE_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions); 122 return test_bit(BOOKE_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions);
98} 123}
99 124
125void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
126{
127 clear_bit(BOOKE_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions);
128}
129
100void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, 130void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
101 struct kvm_interrupt *irq) 131 struct kvm_interrupt *irq)
102{ 132{
@@ -109,14 +139,19 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
109{ 139{
110 int allowed = 0; 140 int allowed = 0;
111 ulong msr_mask; 141 ulong msr_mask;
142 bool update_esr = false, update_dear = false;
112 143
113 switch (priority) { 144 switch (priority) {
114 case BOOKE_IRQPRIO_PROGRAM:
115 case BOOKE_IRQPRIO_DTLB_MISS: 145 case BOOKE_IRQPRIO_DTLB_MISS:
116 case BOOKE_IRQPRIO_ITLB_MISS:
117 case BOOKE_IRQPRIO_SYSCALL:
118 case BOOKE_IRQPRIO_DATA_STORAGE: 146 case BOOKE_IRQPRIO_DATA_STORAGE:
147 update_dear = true;
148 /* fall through */
119 case BOOKE_IRQPRIO_INST_STORAGE: 149 case BOOKE_IRQPRIO_INST_STORAGE:
150 case BOOKE_IRQPRIO_PROGRAM:
151 update_esr = true;
152 /* fall through */
153 case BOOKE_IRQPRIO_ITLB_MISS:
154 case BOOKE_IRQPRIO_SYSCALL:
120 case BOOKE_IRQPRIO_FP_UNAVAIL: 155 case BOOKE_IRQPRIO_FP_UNAVAIL:
121 case BOOKE_IRQPRIO_SPE_UNAVAIL: 156 case BOOKE_IRQPRIO_SPE_UNAVAIL:
122 case BOOKE_IRQPRIO_SPE_FP_DATA: 157 case BOOKE_IRQPRIO_SPE_FP_DATA:
@@ -151,6 +186,10 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
151 vcpu->arch.srr0 = vcpu->arch.pc; 186 vcpu->arch.srr0 = vcpu->arch.pc;
152 vcpu->arch.srr1 = vcpu->arch.msr; 187 vcpu->arch.srr1 = vcpu->arch.msr;
153 vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority]; 188 vcpu->arch.pc = vcpu->arch.ivpr | vcpu->arch.ivor[priority];
189 if (update_esr == true)
190 vcpu->arch.esr = vcpu->arch.queued_esr;
191 if (update_dear == true)
192 vcpu->arch.dear = vcpu->arch.queued_dear;
154 kvmppc_set_msr(vcpu, vcpu->arch.msr & msr_mask); 193 kvmppc_set_msr(vcpu, vcpu->arch.msr & msr_mask);
155 194
156 clear_bit(priority, &vcpu->arch.pending_exceptions); 195 clear_bit(priority, &vcpu->arch.pending_exceptions);
@@ -223,8 +262,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
223 if (vcpu->arch.msr & MSR_PR) { 262 if (vcpu->arch.msr & MSR_PR) {
224 /* Program traps generated by user-level software must be handled 263 /* Program traps generated by user-level software must be handled
225 * by the guest kernel. */ 264 * by the guest kernel. */
226 vcpu->arch.esr = vcpu->arch.fault_esr; 265 kvmppc_core_queue_program(vcpu, vcpu->arch.fault_esr);
227 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_PROGRAM);
228 r = RESUME_GUEST; 266 r = RESUME_GUEST;
229 kvmppc_account_exit(vcpu, USR_PR_INST); 267 kvmppc_account_exit(vcpu, USR_PR_INST);
230 break; 268 break;
@@ -280,16 +318,14 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
280 break; 318 break;
281 319
282 case BOOKE_INTERRUPT_DATA_STORAGE: 320 case BOOKE_INTERRUPT_DATA_STORAGE:
283 vcpu->arch.dear = vcpu->arch.fault_dear; 321 kvmppc_core_queue_data_storage(vcpu, vcpu->arch.fault_dear,
284 vcpu->arch.esr = vcpu->arch.fault_esr; 322 vcpu->arch.fault_esr);
285 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DATA_STORAGE);
286 kvmppc_account_exit(vcpu, DSI_EXITS); 323 kvmppc_account_exit(vcpu, DSI_EXITS);
287 r = RESUME_GUEST; 324 r = RESUME_GUEST;
288 break; 325 break;
289 326
290 case BOOKE_INTERRUPT_INST_STORAGE: 327 case BOOKE_INTERRUPT_INST_STORAGE:
291 vcpu->arch.esr = vcpu->arch.fault_esr; 328 kvmppc_core_queue_inst_storage(vcpu, vcpu->arch.fault_esr);
292 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_INST_STORAGE);
293 kvmppc_account_exit(vcpu, ISI_EXITS); 329 kvmppc_account_exit(vcpu, ISI_EXITS);
294 r = RESUME_GUEST; 330 r = RESUME_GUEST;
295 break; 331 break;
@@ -310,9 +346,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
310 gtlb_index = kvmppc_mmu_dtlb_index(vcpu, eaddr); 346 gtlb_index = kvmppc_mmu_dtlb_index(vcpu, eaddr);
311 if (gtlb_index < 0) { 347 if (gtlb_index < 0) {
312 /* The guest didn't have a mapping for it. */ 348 /* The guest didn't have a mapping for it. */
313 kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS); 349 kvmppc_core_queue_dtlb_miss(vcpu,
314 vcpu->arch.dear = vcpu->arch.fault_dear; 350 vcpu->arch.fault_dear,
315 vcpu->arch.esr = vcpu->arch.fault_esr; 351 vcpu->arch.fault_esr);
316 kvmppc_mmu_dtlb_miss(vcpu); 352 kvmppc_mmu_dtlb_miss(vcpu);
317 kvmppc_account_exit(vcpu, DTLB_REAL_MISS_EXITS); 353 kvmppc_account_exit(vcpu, DTLB_REAL_MISS_EXITS);
318 r = RESUME_GUEST; 354 r = RESUME_GUEST;
@@ -426,7 +462,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
426{ 462{
427 vcpu->arch.pc = 0; 463 vcpu->arch.pc = 0;
428 vcpu->arch.msr = 0; 464 vcpu->arch.msr = 0;
429 vcpu->arch.gpr[1] = (16<<20) - 8; /* -8 for the callee-save LR slot */ 465 kvmppc_set_gpr(vcpu, 1, (16<<20) - 8); /* -8 for the callee-save LR slot */
430 466
431 vcpu->arch.shadow_pid = 1; 467 vcpu->arch.shadow_pid = 1;
432 468
@@ -444,10 +480,10 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
444 int i; 480 int i;
445 481
446 regs->pc = vcpu->arch.pc; 482 regs->pc = vcpu->arch.pc;
447 regs->cr = vcpu->arch.cr; 483 regs->cr = kvmppc_get_cr(vcpu);
448 regs->ctr = vcpu->arch.ctr; 484 regs->ctr = vcpu->arch.ctr;
449 regs->lr = vcpu->arch.lr; 485 regs->lr = vcpu->arch.lr;
450 regs->xer = vcpu->arch.xer; 486 regs->xer = kvmppc_get_xer(vcpu);
451 regs->msr = vcpu->arch.msr; 487 regs->msr = vcpu->arch.msr;
452 regs->srr0 = vcpu->arch.srr0; 488 regs->srr0 = vcpu->arch.srr0;
453 regs->srr1 = vcpu->arch.srr1; 489 regs->srr1 = vcpu->arch.srr1;
@@ -461,7 +497,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
461 regs->sprg7 = vcpu->arch.sprg6; 497 regs->sprg7 = vcpu->arch.sprg6;
462 498
463 for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) 499 for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
464 regs->gpr[i] = vcpu->arch.gpr[i]; 500 regs->gpr[i] = kvmppc_get_gpr(vcpu, i);
465 501
466 return 0; 502 return 0;
467} 503}
@@ -471,10 +507,10 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
471 int i; 507 int i;
472 508
473 vcpu->arch.pc = regs->pc; 509 vcpu->arch.pc = regs->pc;
474 vcpu->arch.cr = regs->cr; 510 kvmppc_set_cr(vcpu, regs->cr);
475 vcpu->arch.ctr = regs->ctr; 511 vcpu->arch.ctr = regs->ctr;
476 vcpu->arch.lr = regs->lr; 512 vcpu->arch.lr = regs->lr;
477 vcpu->arch.xer = regs->xer; 513 kvmppc_set_xer(vcpu, regs->xer);
478 kvmppc_set_msr(vcpu, regs->msr); 514 kvmppc_set_msr(vcpu, regs->msr);
479 vcpu->arch.srr0 = regs->srr0; 515 vcpu->arch.srr0 = regs->srr0;
480 vcpu->arch.srr1 = regs->srr1; 516 vcpu->arch.srr1 = regs->srr1;
@@ -486,8 +522,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
486 vcpu->arch.sprg6 = regs->sprg5; 522 vcpu->arch.sprg6 = regs->sprg5;
487 vcpu->arch.sprg7 = regs->sprg6; 523 vcpu->arch.sprg7 = regs->sprg6;
488 524
489 for (i = 0; i < ARRAY_SIZE(vcpu->arch.gpr); i++) 525 for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
490 vcpu->arch.gpr[i] = regs->gpr[i]; 526 kvmppc_set_gpr(vcpu, i, regs->gpr[i]);
491 527
492 return 0; 528 return 0;
493} 529}
@@ -520,6 +556,11 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
520 return kvmppc_core_vcpu_translate(vcpu, tr); 556 return kvmppc_core_vcpu_translate(vcpu, tr);
521} 557}
522 558
559int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
560{
561 return -ENOTSUPP;
562}
563
523int __init kvmppc_booke_init(void) 564int __init kvmppc_booke_init(void)
524{ 565{
525 unsigned long ivor[16]; 566 unsigned long ivor[16];