diff options
Diffstat (limited to 'arch/powerpc/kvm/booke.c')
-rw-r--r-- | arch/powerpc/kvm/booke.c | 93 |
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 | ||
85 | void kvmppc_core_queue_program(struct kvm_vcpu *vcpu) | 86 | static 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 | |||
94 | static 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 | |||
102 | static 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 | |||
109 | void 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 | ||
125 | void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu) | ||
126 | { | ||
127 | clear_bit(BOOKE_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions); | ||
128 | } | ||
129 | |||
100 | void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, | 130 | void 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 | ||
559 | int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) | ||
560 | { | ||
561 | return -ENOTSUPP; | ||
562 | } | ||
563 | |||
523 | int __init kvmppc_booke_init(void) | 564 | int __init kvmppc_booke_init(void) |
524 | { | 565 | { |
525 | unsigned long ivor[16]; | 566 | unsigned long ivor[16]; |