1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
22f4cf5e4SAlexander Graf /*
32f4cf5e4SAlexander Graf * Copyright (C) 2009. SUSE Linux Products GmbH. All rights reserved.
42f4cf5e4SAlexander Graf *
52f4cf5e4SAlexander Graf * Authors:
62f4cf5e4SAlexander Graf * Alexander Graf <agraf@suse.de>
72f4cf5e4SAlexander Graf * Kevin Wolf <mail@kevin-wolf.de>
82f4cf5e4SAlexander Graf *
92f4cf5e4SAlexander Graf * Description:
102f4cf5e4SAlexander Graf * This file is derived from arch/powerpc/kvm/44x.c,
112f4cf5e4SAlexander Graf * by Hollis Blanchard <hollisb@us.ibm.com>.
122f4cf5e4SAlexander Graf */
132f4cf5e4SAlexander Graf
142f4cf5e4SAlexander Graf #include <linux/kvm_host.h>
152f4cf5e4SAlexander Graf #include <linux/err.h>
1666b15db6SPaul Gortmaker #include <linux/export.h>
17329d20baSStephen Rothwell #include <linux/slab.h>
18398a76c6SAlexander Graf #include <linux/module.h>
19398a76c6SAlexander Graf #include <linux/miscdevice.h>
20d3989143SBenjamin Herrenschmidt #include <linux/gfp.h>
21d3989143SBenjamin Herrenschmidt #include <linux/sched.h>
22d3989143SBenjamin Herrenschmidt #include <linux/vmalloc.h>
23d3989143SBenjamin Herrenschmidt #include <linux/highmem.h>
242f4cf5e4SAlexander Graf
252f4cf5e4SAlexander Graf #include <asm/reg.h>
262f4cf5e4SAlexander Graf #include <asm/cputable.h>
272f4cf5e4SAlexander Graf #include <asm/cacheflush.h>
287c0f6ba6SLinus Torvalds #include <linux/uaccess.h>
292f4cf5e4SAlexander Graf #include <asm/io.h>
302f4cf5e4SAlexander Graf #include <asm/kvm_ppc.h>
312f4cf5e4SAlexander Graf #include <asm/kvm_book3s.h>
322f4cf5e4SAlexander Graf #include <asm/mmu_context.h>
33149dbdb1SPaul Mackerras #include <asm/page.h>
345af50993SBenjamin Herrenschmidt #include <asm/xive.h>
352f4cf5e4SAlexander Graf
36cbbc58d4SAneesh Kumar K.V #include "book3s.h"
37c4befc58SPaul Mackerras #include "trace.h"
38c4befc58SPaul Mackerras
392f4cf5e4SAlexander Graf /* #define EXIT_DEBUG */
4007b0907dSAlexander Graf
41fcfe1baeSJing Zhang const struct _kvm_stats_desc kvm_vm_stats_desc[] = {
42fcfe1baeSJing Zhang KVM_GENERIC_VM_STATS(),
43fcfe1baeSJing Zhang STATS_DESC_ICOUNTER(VM, num_2M_pages),
44fcfe1baeSJing Zhang STATS_DESC_ICOUNTER(VM, num_1G_pages)
45fcfe1baeSJing Zhang };
46fcfe1baeSJing Zhang
47fcfe1baeSJing Zhang const struct kvm_stats_header kvm_vm_stats_header = {
48fcfe1baeSJing Zhang .name_size = KVM_STATS_NAME_SIZE,
49fcfe1baeSJing Zhang .num_desc = ARRAY_SIZE(kvm_vm_stats_desc),
50fcfe1baeSJing Zhang .id_offset = sizeof(struct kvm_stats_header),
51fcfe1baeSJing Zhang .desc_offset = sizeof(struct kvm_stats_header) + KVM_STATS_NAME_SIZE,
52fcfe1baeSJing Zhang .data_offset = sizeof(struct kvm_stats_header) + KVM_STATS_NAME_SIZE +
53fcfe1baeSJing Zhang sizeof(kvm_vm_stats_desc),
54fcfe1baeSJing Zhang };
55fcfe1baeSJing Zhang
56ce55c049SJing Zhang const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
57ce55c049SJing Zhang KVM_GENERIC_VCPU_STATS(),
58ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, sum_exits),
59ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, mmio_exits),
60ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, signal_exits),
61ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, light_exits),
62ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, itlb_real_miss_exits),
63ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, itlb_virt_miss_exits),
64ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, dtlb_real_miss_exits),
65ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, dtlb_virt_miss_exits),
66ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, syscall_exits),
67ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, isi_exits),
68ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, dsi_exits),
69ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, emulated_inst_exits),
70ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, dec_exits),
71ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, ext_intr_exits),
72ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, halt_successful_wait),
73ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, dbell_exits),
74ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, gdbell_exits),
75ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, ld),
76ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, st),
77ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, pf_storage),
78ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, pf_instruc),
79ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, sp_storage),
80ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, sp_instruc),
81ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, queue_intr),
82ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, ld_slow),
83ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, st_slow),
84ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, pthru_all),
85ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, pthru_host),
86ce55c049SJing Zhang STATS_DESC_COUNTER(VCPU, pthru_bad_aff)
87ce55c049SJing Zhang };
88ce55c049SJing Zhang
89ce55c049SJing Zhang const struct kvm_stats_header kvm_vcpu_stats_header = {
90ce55c049SJing Zhang .name_size = KVM_STATS_NAME_SIZE,
91ce55c049SJing Zhang .num_desc = ARRAY_SIZE(kvm_vcpu_stats_desc),
92ce55c049SJing Zhang .id_offset = sizeof(struct kvm_stats_header),
93ce55c049SJing Zhang .desc_offset = sizeof(struct kvm_stats_header) + KVM_STATS_NAME_SIZE,
94ce55c049SJing Zhang .data_offset = sizeof(struct kvm_stats_header) + KVM_STATS_NAME_SIZE +
95ce55c049SJing Zhang sizeof(kvm_vcpu_stats_desc),
96ce55c049SJing Zhang };
97ce55c049SJing Zhang
kvmppc_update_int_pending(struct kvm_vcpu * vcpu,unsigned long pending_now,unsigned long old_pending)98699cc876SAneesh Kumar K.V static inline void kvmppc_update_int_pending(struct kvm_vcpu *vcpu,
99699cc876SAneesh Kumar K.V unsigned long pending_now, unsigned long old_pending)
100699cc876SAneesh Kumar K.V {
101a78b55d1SAneesh Kumar K.V if (is_kvmppc_hv_enabled(vcpu->kvm))
102699cc876SAneesh Kumar K.V return;
103699cc876SAneesh Kumar K.V if (pending_now)
1045deb8e7aSAlexander Graf kvmppc_set_int_pending(vcpu, 1);
105699cc876SAneesh Kumar K.V else if (old_pending)
1065deb8e7aSAlexander Graf kvmppc_set_int_pending(vcpu, 0);
107699cc876SAneesh Kumar K.V }
108699cc876SAneesh Kumar K.V
kvmppc_critical_section(struct kvm_vcpu * vcpu)109699cc876SAneesh Kumar K.V static inline bool kvmppc_critical_section(struct kvm_vcpu *vcpu)
110699cc876SAneesh Kumar K.V {
111699cc876SAneesh Kumar K.V ulong crit_raw;
112699cc876SAneesh Kumar K.V ulong crit_r1;
113699cc876SAneesh Kumar K.V bool crit;
114699cc876SAneesh Kumar K.V
115a78b55d1SAneesh Kumar K.V if (is_kvmppc_hv_enabled(vcpu->kvm))
116699cc876SAneesh Kumar K.V return false;
117699cc876SAneesh Kumar K.V
1185deb8e7aSAlexander Graf crit_raw = kvmppc_get_critical(vcpu);
119699cc876SAneesh Kumar K.V crit_r1 = kvmppc_get_gpr(vcpu, 1);
120699cc876SAneesh Kumar K.V
121699cc876SAneesh Kumar K.V /* Truncate crit indicators in 32 bit mode */
1225deb8e7aSAlexander Graf if (!(kvmppc_get_msr(vcpu) & MSR_SF)) {
123699cc876SAneesh Kumar K.V crit_raw &= 0xffffffff;
124699cc876SAneesh Kumar K.V crit_r1 &= 0xffffffff;
125699cc876SAneesh Kumar K.V }
126699cc876SAneesh Kumar K.V
127699cc876SAneesh Kumar K.V /* Critical section when crit == r1 */
128699cc876SAneesh Kumar K.V crit = (crit_raw == crit_r1);
129699cc876SAneesh Kumar K.V /* ... and we're in supervisor mode */
1305deb8e7aSAlexander Graf crit = crit && !(kvmppc_get_msr(vcpu) & MSR_PR);
131699cc876SAneesh Kumar K.V
132699cc876SAneesh Kumar K.V return crit;
133699cc876SAneesh Kumar K.V }
134699cc876SAneesh Kumar K.V
kvmppc_inject_interrupt(struct kvm_vcpu * vcpu,int vec,u64 flags)1352f4cf5e4SAlexander Graf void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags)
1362f4cf5e4SAlexander Graf {
13787a45e07SNicholas Piggin vcpu->kvm->arch.kvm_ops->inject_interrupt(vcpu, vec, flags);
1382f4cf5e4SAlexander Graf }
1392f4cf5e4SAlexander Graf
kvmppc_book3s_vec2irqprio(unsigned int vec)140583617b7SAlexander Graf static int kvmppc_book3s_vec2irqprio(unsigned int vec)
1412f4cf5e4SAlexander Graf {
1422f4cf5e4SAlexander Graf unsigned int prio;
1432f4cf5e4SAlexander Graf
1442f4cf5e4SAlexander Graf switch (vec) {
1452f4cf5e4SAlexander Graf case 0x100: prio = BOOK3S_IRQPRIO_SYSTEM_RESET; break;
1462f4cf5e4SAlexander Graf case 0x200: prio = BOOK3S_IRQPRIO_MACHINE_CHECK; break;
1472f4cf5e4SAlexander Graf case 0x300: prio = BOOK3S_IRQPRIO_DATA_STORAGE; break;
1482f4cf5e4SAlexander Graf case 0x380: prio = BOOK3S_IRQPRIO_DATA_SEGMENT; break;
1492f4cf5e4SAlexander Graf case 0x400: prio = BOOK3S_IRQPRIO_INST_STORAGE; break;
1502f4cf5e4SAlexander Graf case 0x480: prio = BOOK3S_IRQPRIO_INST_SEGMENT; break;
1512f4cf5e4SAlexander Graf case 0x500: prio = BOOK3S_IRQPRIO_EXTERNAL; break;
1522f4cf5e4SAlexander Graf case 0x600: prio = BOOK3S_IRQPRIO_ALIGNMENT; break;
1532f4cf5e4SAlexander Graf case 0x700: prio = BOOK3S_IRQPRIO_PROGRAM; break;
1542f4cf5e4SAlexander Graf case 0x800: prio = BOOK3S_IRQPRIO_FP_UNAVAIL; break;
1552f4cf5e4SAlexander Graf case 0x900: prio = BOOK3S_IRQPRIO_DECREMENTER; break;
1562f4cf5e4SAlexander Graf case 0xc00: prio = BOOK3S_IRQPRIO_SYSCALL; break;
1572f4cf5e4SAlexander Graf case 0xd00: prio = BOOK3S_IRQPRIO_DEBUG; break;
1582f4cf5e4SAlexander Graf case 0xf20: prio = BOOK3S_IRQPRIO_ALTIVEC; break;
1592f4cf5e4SAlexander Graf case 0xf40: prio = BOOK3S_IRQPRIO_VSX; break;
160616dff86SAlexander Graf case 0xf60: prio = BOOK3S_IRQPRIO_FAC_UNAVAIL; break;
1612f4cf5e4SAlexander Graf default: prio = BOOK3S_IRQPRIO_MAX; break;
1622f4cf5e4SAlexander Graf }
1632f4cf5e4SAlexander Graf
164583617b7SAlexander Graf return prio;
165583617b7SAlexander Graf }
166583617b7SAlexander Graf
kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu * vcpu,unsigned int vec)167bc5ad3f3SBenjamin Herrenschmidt void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu,
1687706664dSAlexander Graf unsigned int vec)
1697706664dSAlexander Graf {
170f05ed4d5SPaul Mackerras unsigned long old_pending = vcpu->arch.pending_exceptions;
171f05ed4d5SPaul Mackerras
1727706664dSAlexander Graf clear_bit(kvmppc_book3s_vec2irqprio(vec),
1737706664dSAlexander Graf &vcpu->arch.pending_exceptions);
1749ee18b1eSAlexander Graf
175f05ed4d5SPaul Mackerras kvmppc_update_int_pending(vcpu, vcpu->arch.pending_exceptions,
176f05ed4d5SPaul Mackerras old_pending);
1777706664dSAlexander Graf }
1787706664dSAlexander Graf
kvmppc_book3s_queue_irqprio(struct kvm_vcpu * vcpu,unsigned int vec)179583617b7SAlexander Graf void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
180583617b7SAlexander Graf {
181583617b7SAlexander Graf vcpu->stat.queue_intr++;
182583617b7SAlexander Graf
183583617b7SAlexander Graf set_bit(kvmppc_book3s_vec2irqprio(vec),
184583617b7SAlexander Graf &vcpu->arch.pending_exceptions);
1852f4cf5e4SAlexander Graf #ifdef EXIT_DEBUG
1862f4cf5e4SAlexander Graf printk(KERN_INFO "Queueing interrupt %x\n", vec);
1872f4cf5e4SAlexander Graf #endif
1882f4cf5e4SAlexander Graf }
1892ba9f0d8SAneesh Kumar K.V EXPORT_SYMBOL_GPL(kvmppc_book3s_queue_irqprio);
1902f4cf5e4SAlexander Graf
kvmppc_core_queue_machine_check(struct kvm_vcpu * vcpu,ulong srr1_flags)191460ba21dSNicholas Piggin void kvmppc_core_queue_machine_check(struct kvm_vcpu *vcpu, ulong srr1_flags)
192884dfb72SPaul Mackerras {
193884dfb72SPaul Mackerras /* might as well deliver this straight away */
194460ba21dSNicholas Piggin kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_MACHINE_CHECK, srr1_flags);
195884dfb72SPaul Mackerras }
196884dfb72SPaul Mackerras EXPORT_SYMBOL_GPL(kvmppc_core_queue_machine_check);
197884dfb72SPaul Mackerras
kvmppc_core_queue_syscall(struct kvm_vcpu * vcpu)1989dc2babcSNicholas Piggin void kvmppc_core_queue_syscall(struct kvm_vcpu *vcpu)
1999dc2babcSNicholas Piggin {
2009dc2babcSNicholas Piggin kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_SYSCALL, 0);
2019dc2babcSNicholas Piggin }
2029dc2babcSNicholas Piggin EXPORT_SYMBOL(kvmppc_core_queue_syscall);
2039dc2babcSNicholas Piggin
kvmppc_core_queue_program(struct kvm_vcpu * vcpu,ulong srr1_flags)204460ba21dSNicholas Piggin void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong srr1_flags)
2052f4cf5e4SAlexander Graf {
2063cf658b6SPaul Mackerras /* might as well deliver this straight away */
207460ba21dSNicholas Piggin kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_PROGRAM, srr1_flags);
2082f4cf5e4SAlexander Graf }
2092ba9f0d8SAneesh Kumar K.V EXPORT_SYMBOL_GPL(kvmppc_core_queue_program);
2102f4cf5e4SAlexander Graf
kvmppc_core_queue_fpunavail(struct kvm_vcpu * vcpu,ulong srr1_flags)211460ba21dSNicholas Piggin void kvmppc_core_queue_fpunavail(struct kvm_vcpu *vcpu, ulong srr1_flags)
212307d9279SPaul Mackerras {
213307d9279SPaul Mackerras /* might as well deliver this straight away */
214460ba21dSNicholas Piggin kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_FP_UNAVAIL, srr1_flags);
215307d9279SPaul Mackerras }
216307d9279SPaul Mackerras
kvmppc_core_queue_vec_unavail(struct kvm_vcpu * vcpu,ulong srr1_flags)217460ba21dSNicholas Piggin void kvmppc_core_queue_vec_unavail(struct kvm_vcpu *vcpu, ulong srr1_flags)
218307d9279SPaul Mackerras {
219307d9279SPaul Mackerras /* might as well deliver this straight away */
220460ba21dSNicholas Piggin kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_ALTIVEC, srr1_flags);
221307d9279SPaul Mackerras }
222307d9279SPaul Mackerras
kvmppc_core_queue_vsx_unavail(struct kvm_vcpu * vcpu,ulong srr1_flags)223460ba21dSNicholas Piggin void kvmppc_core_queue_vsx_unavail(struct kvm_vcpu *vcpu, ulong srr1_flags)
224307d9279SPaul Mackerras {
225307d9279SPaul Mackerras /* might as well deliver this straight away */
226460ba21dSNicholas Piggin kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_VSX, srr1_flags);
227307d9279SPaul Mackerras }
228307d9279SPaul Mackerras
kvmppc_core_queue_dec(struct kvm_vcpu * vcpu)2292f4cf5e4SAlexander Graf void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu)
2302f4cf5e4SAlexander Graf {
2312f4cf5e4SAlexander Graf kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER);
2322f4cf5e4SAlexander Graf }
2332ba9f0d8SAneesh Kumar K.V EXPORT_SYMBOL_GPL(kvmppc_core_queue_dec);
2342f4cf5e4SAlexander Graf
kvmppc_core_pending_dec(struct kvm_vcpu * vcpu)2352f4cf5e4SAlexander Graf int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
2362f4cf5e4SAlexander Graf {
23744075d95SPaul Mackerras return test_bit(BOOK3S_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions);
2382f4cf5e4SAlexander Graf }
2392ba9f0d8SAneesh Kumar K.V EXPORT_SYMBOL_GPL(kvmppc_core_pending_dec);
2402f4cf5e4SAlexander Graf
kvmppc_core_dequeue_dec(struct kvm_vcpu * vcpu)2417706664dSAlexander Graf void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
2427706664dSAlexander Graf {
2437706664dSAlexander Graf kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER);
2447706664dSAlexander Graf }
2452ba9f0d8SAneesh Kumar K.V EXPORT_SYMBOL_GPL(kvmppc_core_dequeue_dec);
2467706664dSAlexander Graf
kvmppc_core_queue_external(struct kvm_vcpu * vcpu,struct kvm_interrupt * irq)2472f4cf5e4SAlexander Graf void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
2482f4cf5e4SAlexander Graf struct kvm_interrupt *irq)
2492f4cf5e4SAlexander Graf {
250d24ea8a7SPaul Mackerras /*
251d24ea8a7SPaul Mackerras * This case (KVM_INTERRUPT_SET) should never actually arise for
252d24ea8a7SPaul Mackerras * a pseries guest (because pseries guests expect their interrupt
253d24ea8a7SPaul Mackerras * controllers to continue asserting an external interrupt request
254d24ea8a7SPaul Mackerras * until it is acknowledged at the interrupt controller), but is
255d24ea8a7SPaul Mackerras * included to avoid ABI breakage and potentially for other
256d24ea8a7SPaul Mackerras * sorts of guest.
257d24ea8a7SPaul Mackerras *
258d24ea8a7SPaul Mackerras * There is a subtlety here: HV KVM does not test the
259d24ea8a7SPaul Mackerras * external_oneshot flag in the code that synthesizes
260d24ea8a7SPaul Mackerras * external interrupts for the guest just before entering
261d24ea8a7SPaul Mackerras * the guest. That is OK even if userspace did do a
262d24ea8a7SPaul Mackerras * KVM_INTERRUPT_SET on a pseries guest vcpu, because the
263d24ea8a7SPaul Mackerras * caller (kvm_vcpu_ioctl_interrupt) does a kvm_vcpu_kick()
264d24ea8a7SPaul Mackerras * which ends up doing a smp_send_reschedule(), which will
265d24ea8a7SPaul Mackerras * pull the guest all the way out to the host, meaning that
266d24ea8a7SPaul Mackerras * we will call kvmppc_core_prepare_to_enter() before entering
267d24ea8a7SPaul Mackerras * the guest again, and that will handle the external_oneshot
268d24ea8a7SPaul Mackerras * flag correctly.
269d24ea8a7SPaul Mackerras */
270d24ea8a7SPaul Mackerras if (irq->irq == KVM_INTERRUPT_SET)
271d24ea8a7SPaul Mackerras vcpu->arch.external_oneshot = 1;
27217bd1580SAlexander Graf
273d24ea8a7SPaul Mackerras kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL);
2742f4cf5e4SAlexander Graf }
2752f4cf5e4SAlexander Graf
kvmppc_core_dequeue_external(struct kvm_vcpu * vcpu)2764fe27d2aSPaul Mackerras void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu)
27718978768SAlexander Graf {
27818978768SAlexander Graf kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL);
27918978768SAlexander Graf }
28018978768SAlexander Graf
kvmppc_core_queue_data_storage(struct kvm_vcpu * vcpu,ulong srr1_flags,ulong dar,ulong dsisr)281460ba21dSNicholas Piggin void kvmppc_core_queue_data_storage(struct kvm_vcpu *vcpu, ulong srr1_flags,
282460ba21dSNicholas Piggin ulong dar, ulong dsisr)
2838de12015SAlexander Graf {
2848de12015SAlexander Graf kvmppc_set_dar(vcpu, dar);
285460ba21dSNicholas Piggin kvmppc_set_dsisr(vcpu, dsisr);
286460ba21dSNicholas Piggin kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_DATA_STORAGE, srr1_flags);
2878de12015SAlexander Graf }
288916ccadcSPaul Mackerras EXPORT_SYMBOL_GPL(kvmppc_core_queue_data_storage);
2898de12015SAlexander Graf
kvmppc_core_queue_inst_storage(struct kvm_vcpu * vcpu,ulong srr1_flags)290460ba21dSNicholas Piggin void kvmppc_core_queue_inst_storage(struct kvm_vcpu *vcpu, ulong srr1_flags)
2918de12015SAlexander Graf {
292460ba21dSNicholas Piggin kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_INST_STORAGE, srr1_flags);
2938de12015SAlexander Graf }
294916ccadcSPaul Mackerras EXPORT_SYMBOL_GPL(kvmppc_core_queue_inst_storage);
2958de12015SAlexander Graf
kvmppc_book3s_irqprio_deliver(struct kvm_vcpu * vcpu,unsigned int priority)2965358a963SThomas Huth static int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu,
2975358a963SThomas Huth unsigned int priority)
2982f4cf5e4SAlexander Graf {
2992f4cf5e4SAlexander Graf int deliver = 1;
3002f4cf5e4SAlexander Graf int vec = 0;
301f05ed4d5SPaul Mackerras bool crit = kvmppc_critical_section(vcpu);
3022f4cf5e4SAlexander Graf
3032f4cf5e4SAlexander Graf switch (priority) {
3042f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_DECREMENTER:
3055deb8e7aSAlexander Graf deliver = (kvmppc_get_msr(vcpu) & MSR_EE) && !crit;
3062f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_DECREMENTER;
3072f4cf5e4SAlexander Graf break;
3082f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_EXTERNAL:
3095deb8e7aSAlexander Graf deliver = (kvmppc_get_msr(vcpu) & MSR_EE) && !crit;
3102f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_EXTERNAL;
3112f4cf5e4SAlexander Graf break;
3122f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_SYSTEM_RESET:
3132f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_SYSTEM_RESET;
3142f4cf5e4SAlexander Graf break;
3152f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_MACHINE_CHECK:
3162f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_MACHINE_CHECK;
3172f4cf5e4SAlexander Graf break;
3182f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_DATA_STORAGE:
3192f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_DATA_STORAGE;
3202f4cf5e4SAlexander Graf break;
3212f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_INST_STORAGE:
3222f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_INST_STORAGE;
3232f4cf5e4SAlexander Graf break;
3242f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_DATA_SEGMENT:
3252f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_DATA_SEGMENT;
3262f4cf5e4SAlexander Graf break;
3272f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_INST_SEGMENT:
3282f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_INST_SEGMENT;
3292f4cf5e4SAlexander Graf break;
3302f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_ALIGNMENT:
3312f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_ALIGNMENT;
3322f4cf5e4SAlexander Graf break;
3332f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_PROGRAM:
3342f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_PROGRAM;
3352f4cf5e4SAlexander Graf break;
3362f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_VSX:
3372f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_VSX;
3382f4cf5e4SAlexander Graf break;
3392f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_ALTIVEC:
3402f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_ALTIVEC;
3412f4cf5e4SAlexander Graf break;
3422f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_FP_UNAVAIL:
3432f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_FP_UNAVAIL;
3442f4cf5e4SAlexander Graf break;
3452f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_SYSCALL:
3462f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_SYSCALL;
3472f4cf5e4SAlexander Graf break;
3482f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_DEBUG:
3492f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_TRACE;
3502f4cf5e4SAlexander Graf break;
3512f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_PERFORMANCE_MONITOR:
3522f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_PERFMON;
3532f4cf5e4SAlexander Graf break;
354616dff86SAlexander Graf case BOOK3S_IRQPRIO_FAC_UNAVAIL:
355616dff86SAlexander Graf vec = BOOK3S_INTERRUPT_FAC_UNAVAIL;
356616dff86SAlexander Graf break;
3572f4cf5e4SAlexander Graf default:
3582f4cf5e4SAlexander Graf deliver = 0;
3592f4cf5e4SAlexander Graf printk(KERN_ERR "KVM: Unknown interrupt: 0x%x\n", priority);
3602f4cf5e4SAlexander Graf break;
3612f4cf5e4SAlexander Graf }
3622f4cf5e4SAlexander Graf
3632f4cf5e4SAlexander Graf #if 0
3642f4cf5e4SAlexander Graf printk(KERN_INFO "Deliver interrupt 0x%x? %x\n", vec, deliver);
3652f4cf5e4SAlexander Graf #endif
3662f4cf5e4SAlexander Graf
3672f4cf5e4SAlexander Graf if (deliver)
3683cf658b6SPaul Mackerras kvmppc_inject_interrupt(vcpu, vec, 0);
3692f4cf5e4SAlexander Graf
3702f4cf5e4SAlexander Graf return deliver;
3712f4cf5e4SAlexander Graf }
3722f4cf5e4SAlexander Graf
37317bd1580SAlexander Graf /*
37417bd1580SAlexander Graf * This function determines if an irqprio should be cleared once issued.
37517bd1580SAlexander Graf */
clear_irqprio(struct kvm_vcpu * vcpu,unsigned int priority)37617bd1580SAlexander Graf static bool clear_irqprio(struct kvm_vcpu *vcpu, unsigned int priority)
37717bd1580SAlexander Graf {
37817bd1580SAlexander Graf switch (priority) {
37917bd1580SAlexander Graf case BOOK3S_IRQPRIO_DECREMENTER:
38017bd1580SAlexander Graf /* DEC interrupts get cleared by mtdec */
38117bd1580SAlexander Graf return false;
382d24ea8a7SPaul Mackerras case BOOK3S_IRQPRIO_EXTERNAL:
383d24ea8a7SPaul Mackerras /*
384d24ea8a7SPaul Mackerras * External interrupts get cleared by userspace
385d24ea8a7SPaul Mackerras * except when set by the KVM_INTERRUPT ioctl with
386d24ea8a7SPaul Mackerras * KVM_INTERRUPT_SET (not KVM_INTERRUPT_SET_LEVEL).
387d24ea8a7SPaul Mackerras */
388d24ea8a7SPaul Mackerras if (vcpu->arch.external_oneshot) {
389d24ea8a7SPaul Mackerras vcpu->arch.external_oneshot = 0;
390d24ea8a7SPaul Mackerras return true;
391d24ea8a7SPaul Mackerras }
39217bd1580SAlexander Graf return false;
39317bd1580SAlexander Graf }
39417bd1580SAlexander Graf
39517bd1580SAlexander Graf return true;
39617bd1580SAlexander Graf }
39717bd1580SAlexander Graf
kvmppc_core_prepare_to_enter(struct kvm_vcpu * vcpu)398a8e4ef84SAlexander Graf int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
3992f4cf5e4SAlexander Graf {
4002f4cf5e4SAlexander Graf unsigned long *pending = &vcpu->arch.pending_exceptions;
40190bba358SAlexander Graf unsigned long old_pending = vcpu->arch.pending_exceptions;
4022f4cf5e4SAlexander Graf unsigned int priority;
4032f4cf5e4SAlexander Graf
4042f4cf5e4SAlexander Graf #ifdef EXIT_DEBUG
4052f4cf5e4SAlexander Graf if (vcpu->arch.pending_exceptions)
4062f4cf5e4SAlexander Graf printk(KERN_EMERG "KVM: Check pending: %lx\n", vcpu->arch.pending_exceptions);
4072f4cf5e4SAlexander Graf #endif
4082f4cf5e4SAlexander Graf priority = __ffs(*pending);
409ada7ba17SAlexander Graf while (priority < BOOK3S_IRQPRIO_MAX) {
4107706664dSAlexander Graf if (kvmppc_book3s_irqprio_deliver(vcpu, priority) &&
41117bd1580SAlexander Graf clear_irqprio(vcpu, priority)) {
4122f4cf5e4SAlexander Graf clear_bit(priority, &vcpu->arch.pending_exceptions);
4132f4cf5e4SAlexander Graf break;
4142f4cf5e4SAlexander Graf }
4152f4cf5e4SAlexander Graf
4162f4cf5e4SAlexander Graf priority = find_next_bit(pending,
4172f4cf5e4SAlexander Graf BITS_PER_BYTE * sizeof(*pending),
4182f4cf5e4SAlexander Graf priority + 1);
4192f4cf5e4SAlexander Graf }
42090bba358SAlexander Graf
42190bba358SAlexander Graf /* Tell the guest about our interrupt status */
422f05ed4d5SPaul Mackerras kvmppc_update_int_pending(vcpu, *pending, old_pending);
423a8e4ef84SAlexander Graf
424a8e4ef84SAlexander Graf return 0;
4252f4cf5e4SAlexander Graf }
4262ba9f0d8SAneesh Kumar K.V EXPORT_SYMBOL_GPL(kvmppc_core_prepare_to_enter);
4272f4cf5e4SAlexander Graf
kvmppc_gpa_to_pfn(struct kvm_vcpu * vcpu,gpa_t gpa,bool writing,bool * writable)428ba049e93SDan Williams kvm_pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa, bool writing,
42993b159b4SPaul Mackerras bool *writable)
430e8508940SAlexander Graf {
43189b68c96SAlexander Graf ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM;
43289b68c96SAlexander Graf gfn_t gfn = gpa >> PAGE_SHIFT;
433e8508940SAlexander Graf
4345deb8e7aSAlexander Graf if (!(kvmppc_get_msr(vcpu) & MSR_SF))
435bbcc9c06SBenjamin Herrenschmidt mp_pa = (uint32_t)mp_pa;
436bbcc9c06SBenjamin Herrenschmidt
437e8508940SAlexander Graf /* Magic page override */
43889b68c96SAlexander Graf gpa &= ~0xFFFULL;
43989b68c96SAlexander Graf if (unlikely(mp_pa) && unlikely((gpa & KVM_PAM) == mp_pa)) {
440e8508940SAlexander Graf ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK;
441ba049e93SDan Williams kvm_pfn_t pfn;
442e8508940SAlexander Graf
443ba049e93SDan Williams pfn = (kvm_pfn_t)virt_to_phys((void*)shared_page) >> PAGE_SHIFT;
444e8508940SAlexander Graf get_page(pfn_to_page(pfn));
44593b159b4SPaul Mackerras if (writable)
44693b159b4SPaul Mackerras *writable = true;
447e8508940SAlexander Graf return pfn;
448e8508940SAlexander Graf }
449e8508940SAlexander Graf
45093b159b4SPaul Mackerras return gfn_to_pfn_prot(vcpu->kvm, gfn, writing, writable);
451e8508940SAlexander Graf }
45289b68c96SAlexander Graf EXPORT_SYMBOL_GPL(kvmppc_gpa_to_pfn);
453e8508940SAlexander Graf
kvmppc_xlate(struct kvm_vcpu * vcpu,ulong eaddr,enum xlate_instdata xlid,enum xlate_readwrite xlrw,struct kvmppc_pte * pte)4547d15c06fSAlexander Graf int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, enum xlate_instdata xlid,
4557d15c06fSAlexander Graf enum xlate_readwrite xlrw, struct kvmppc_pte *pte)
4562f4cf5e4SAlexander Graf {
4577d15c06fSAlexander Graf bool data = (xlid == XLATE_DATA);
4587d15c06fSAlexander Graf bool iswrite = (xlrw == XLATE_WRITE);
4595deb8e7aSAlexander Graf int relocated = (kvmppc_get_msr(vcpu) & (data ? MSR_DR : MSR_IR));
4602f4cf5e4SAlexander Graf int r;
4612f4cf5e4SAlexander Graf
4622f4cf5e4SAlexander Graf if (relocated) {
46393b159b4SPaul Mackerras r = vcpu->arch.mmu.xlate(vcpu, eaddr, pte, data, iswrite);
4642f4cf5e4SAlexander Graf } else {
4652f4cf5e4SAlexander Graf pte->eaddr = eaddr;
46628e83b4fSAlexander Graf pte->raddr = eaddr & KVM_PAM;
4673eeafd7dSAlexander Graf pte->vpage = VSID_REAL | eaddr >> 12;
4682f4cf5e4SAlexander Graf pte->may_read = true;
4692f4cf5e4SAlexander Graf pte->may_write = true;
4702f4cf5e4SAlexander Graf pte->may_execute = true;
4712f4cf5e4SAlexander Graf r = 0;
472c01e3f66SAlexander Graf
473c01e3f66SAlexander Graf if ((kvmppc_get_msr(vcpu) & (MSR_IR | MSR_DR)) == MSR_DR &&
474c01e3f66SAlexander Graf !data) {
475c01e3f66SAlexander Graf if ((vcpu->arch.hflags & BOOK3S_HFLAG_SPLIT_HACK) &&
476c01e3f66SAlexander Graf ((eaddr & SPLIT_HACK_MASK) == SPLIT_HACK_OFFS))
477c01e3f66SAlexander Graf pte->raddr &= ~SPLIT_HACK_MASK;
478c01e3f66SAlexander Graf }
4792f4cf5e4SAlexander Graf }
4802f4cf5e4SAlexander Graf
4812f4cf5e4SAlexander Graf return r;
4822f4cf5e4SAlexander Graf }
4832f4cf5e4SAlexander Graf
484*953e3739SPaul Mackerras /*
485*953e3739SPaul Mackerras * Returns prefixed instructions with the prefix in the high 32 bits
486*953e3739SPaul Mackerras * of *inst and suffix in the low 32 bits. This is the same convention
487*953e3739SPaul Mackerras * as used in HEIR, vcpu->arch.last_inst and vcpu->arch.emul_inst.
488*953e3739SPaul Mackerras * Like vcpu->arch.last_inst but unlike vcpu->arch.emul_inst, each
489*953e3739SPaul Mackerras * half of the value needs byte-swapping if the guest endianness is
490*953e3739SPaul Mackerras * different from the host endianness.
491*953e3739SPaul Mackerras */
kvmppc_load_last_inst(struct kvm_vcpu * vcpu,enum instruction_fetch_type type,unsigned long * inst)49270923603SSimon Guo int kvmppc_load_last_inst(struct kvm_vcpu *vcpu,
493*953e3739SPaul Mackerras enum instruction_fetch_type type, unsigned long *inst)
49451f04726SMihai Caraman {
49551f04726SMihai Caraman ulong pc = kvmppc_get_pc(vcpu);
49651f04726SMihai Caraman int r;
497*953e3739SPaul Mackerras u32 iw;
49851f04726SMihai Caraman
49951f04726SMihai Caraman if (type == INST_SC)
50051f04726SMihai Caraman pc -= 4;
50151f04726SMihai Caraman
502*953e3739SPaul Mackerras r = kvmppc_ld(vcpu, &pc, sizeof(u32), &iw, false);
503*953e3739SPaul Mackerras if (r != EMULATE_DONE)
50451f04726SMihai Caraman return EMULATE_AGAIN;
505*953e3739SPaul Mackerras /*
506*953e3739SPaul Mackerras * If [H]SRR1 indicates that the instruction that caused the
507*953e3739SPaul Mackerras * current interrupt is a prefixed instruction, get the suffix.
508*953e3739SPaul Mackerras */
509*953e3739SPaul Mackerras if (kvmppc_get_msr(vcpu) & SRR1_PREFIXED) {
510*953e3739SPaul Mackerras u32 suffix;
511*953e3739SPaul Mackerras pc += 4;
512*953e3739SPaul Mackerras r = kvmppc_ld(vcpu, &pc, sizeof(u32), &suffix, false);
513*953e3739SPaul Mackerras if (r != EMULATE_DONE)
514*953e3739SPaul Mackerras return EMULATE_AGAIN;
515*953e3739SPaul Mackerras *inst = ((u64)iw << 32) | suffix;
516*953e3739SPaul Mackerras } else {
517*953e3739SPaul Mackerras *inst = iw;
518*953e3739SPaul Mackerras }
519*953e3739SPaul Mackerras return r;
52051f04726SMihai Caraman }
52151f04726SMihai Caraman EXPORT_SYMBOL_GPL(kvmppc_load_last_inst);
52251f04726SMihai Caraman
kvmppc_subarch_vcpu_init(struct kvm_vcpu * vcpu)523f61c94bbSBharat Bhushan int kvmppc_subarch_vcpu_init(struct kvm_vcpu *vcpu)
524f61c94bbSBharat Bhushan {
525f61c94bbSBharat Bhushan return 0;
526f61c94bbSBharat Bhushan }
527f61c94bbSBharat Bhushan
kvmppc_subarch_vcpu_uninit(struct kvm_vcpu * vcpu)528f61c94bbSBharat Bhushan void kvmppc_subarch_vcpu_uninit(struct kvm_vcpu *vcpu)
529f61c94bbSBharat Bhushan {
530f61c94bbSBharat Bhushan }
531f61c94bbSBharat Bhushan
kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu * vcpu,struct kvm_sregs * sregs)5323a167beaSAneesh Kumar K.V int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
5333a167beaSAneesh Kumar K.V struct kvm_sregs *sregs)
5343a167beaSAneesh Kumar K.V {
535bcdec41cSChristoffer Dall int ret;
536bcdec41cSChristoffer Dall
537bcdec41cSChristoffer Dall vcpu_load(vcpu);
538bcdec41cSChristoffer Dall ret = vcpu->kvm->arch.kvm_ops->get_sregs(vcpu, sregs);
539bcdec41cSChristoffer Dall vcpu_put(vcpu);
540bcdec41cSChristoffer Dall
541bcdec41cSChristoffer Dall return ret;
5423a167beaSAneesh Kumar K.V }
5433a167beaSAneesh Kumar K.V
kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu * vcpu,struct kvm_sregs * sregs)5443a167beaSAneesh Kumar K.V int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
5453a167beaSAneesh Kumar K.V struct kvm_sregs *sregs)
5463a167beaSAneesh Kumar K.V {
547b4ef9d4eSChristoffer Dall int ret;
548b4ef9d4eSChristoffer Dall
549b4ef9d4eSChristoffer Dall vcpu_load(vcpu);
550b4ef9d4eSChristoffer Dall ret = vcpu->kvm->arch.kvm_ops->set_sregs(vcpu, sregs);
551b4ef9d4eSChristoffer Dall vcpu_put(vcpu);
552b4ef9d4eSChristoffer Dall
553b4ef9d4eSChristoffer Dall return ret;
5543a167beaSAneesh Kumar K.V }
5553a167beaSAneesh Kumar K.V
kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu * vcpu,struct kvm_regs * regs)5562f4cf5e4SAlexander Graf int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
5572f4cf5e4SAlexander Graf {
5582f4cf5e4SAlexander Graf int i;
5592f4cf5e4SAlexander Graf
560c7f38f46SAlexander Graf regs->pc = kvmppc_get_pc(vcpu);
561992b5b29SAlexander Graf regs->cr = kvmppc_get_cr(vcpu);
562c7f38f46SAlexander Graf regs->ctr = kvmppc_get_ctr(vcpu);
563c7f38f46SAlexander Graf regs->lr = kvmppc_get_lr(vcpu);
564992b5b29SAlexander Graf regs->xer = kvmppc_get_xer(vcpu);
5655deb8e7aSAlexander Graf regs->msr = kvmppc_get_msr(vcpu);
5665deb8e7aSAlexander Graf regs->srr0 = kvmppc_get_srr0(vcpu);
5675deb8e7aSAlexander Graf regs->srr1 = kvmppc_get_srr1(vcpu);
5682f4cf5e4SAlexander Graf regs->pid = vcpu->arch.pid;
5695deb8e7aSAlexander Graf regs->sprg0 = kvmppc_get_sprg0(vcpu);
5705deb8e7aSAlexander Graf regs->sprg1 = kvmppc_get_sprg1(vcpu);
5715deb8e7aSAlexander Graf regs->sprg2 = kvmppc_get_sprg2(vcpu);
5725deb8e7aSAlexander Graf regs->sprg3 = kvmppc_get_sprg3(vcpu);
5735deb8e7aSAlexander Graf regs->sprg4 = kvmppc_get_sprg4(vcpu);
5745deb8e7aSAlexander Graf regs->sprg5 = kvmppc_get_sprg5(vcpu);
5755deb8e7aSAlexander Graf regs->sprg6 = kvmppc_get_sprg6(vcpu);
5765deb8e7aSAlexander Graf regs->sprg7 = kvmppc_get_sprg7(vcpu);
5772f4cf5e4SAlexander Graf
5782f4cf5e4SAlexander Graf for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
5798e5b26b5SAlexander Graf regs->gpr[i] = kvmppc_get_gpr(vcpu, i);
5802f4cf5e4SAlexander Graf
5812f4cf5e4SAlexander Graf return 0;
5822f4cf5e4SAlexander Graf }
5832f4cf5e4SAlexander Graf
kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu * vcpu,struct kvm_regs * regs)5842f4cf5e4SAlexander Graf int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
5852f4cf5e4SAlexander Graf {
5862f4cf5e4SAlexander Graf int i;
5872f4cf5e4SAlexander Graf
588c7f38f46SAlexander Graf kvmppc_set_pc(vcpu, regs->pc);
589992b5b29SAlexander Graf kvmppc_set_cr(vcpu, regs->cr);
590c7f38f46SAlexander Graf kvmppc_set_ctr(vcpu, regs->ctr);
591c7f38f46SAlexander Graf kvmppc_set_lr(vcpu, regs->lr);
592992b5b29SAlexander Graf kvmppc_set_xer(vcpu, regs->xer);
5932f4cf5e4SAlexander Graf kvmppc_set_msr(vcpu, regs->msr);
5945deb8e7aSAlexander Graf kvmppc_set_srr0(vcpu, regs->srr0);
5955deb8e7aSAlexander Graf kvmppc_set_srr1(vcpu, regs->srr1);
5965deb8e7aSAlexander Graf kvmppc_set_sprg0(vcpu, regs->sprg0);
5975deb8e7aSAlexander Graf kvmppc_set_sprg1(vcpu, regs->sprg1);
5985deb8e7aSAlexander Graf kvmppc_set_sprg2(vcpu, regs->sprg2);
5995deb8e7aSAlexander Graf kvmppc_set_sprg3(vcpu, regs->sprg3);
6005deb8e7aSAlexander Graf kvmppc_set_sprg4(vcpu, regs->sprg4);
6015deb8e7aSAlexander Graf kvmppc_set_sprg5(vcpu, regs->sprg5);
6025deb8e7aSAlexander Graf kvmppc_set_sprg6(vcpu, regs->sprg6);
6035deb8e7aSAlexander Graf kvmppc_set_sprg7(vcpu, regs->sprg7);
6042f4cf5e4SAlexander Graf
6058e5b26b5SAlexander Graf for (i = 0; i < ARRAY_SIZE(regs->gpr); i++)
6068e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, i, regs->gpr[i]);
6072f4cf5e4SAlexander Graf
6082f4cf5e4SAlexander Graf return 0;
6092f4cf5e4SAlexander Graf }
6102f4cf5e4SAlexander Graf
kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu * vcpu,struct kvm_fpu * fpu)6112f4cf5e4SAlexander Graf int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
6122f4cf5e4SAlexander Graf {
6134e1b2ab7SGreg Kurz return -EOPNOTSUPP;
6142f4cf5e4SAlexander Graf }
6152f4cf5e4SAlexander Graf
kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu * vcpu,struct kvm_fpu * fpu)6162f4cf5e4SAlexander Graf int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
6172f4cf5e4SAlexander Graf {
6184e1b2ab7SGreg Kurz return -EOPNOTSUPP;
6192f4cf5e4SAlexander Graf }
6202f4cf5e4SAlexander Graf
kvmppc_get_one_reg(struct kvm_vcpu * vcpu,u64 id,union kvmppc_one_reg * val)6218a41ea53SMihai Caraman int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id,
6228a41ea53SMihai Caraman union kvmppc_one_reg *val)
623a136a8bdSPaul Mackerras {
6248a41ea53SMihai Caraman int r = 0;
625a8bd19efSPaul Mackerras long int i;
626a136a8bdSPaul Mackerras
6278a41ea53SMihai Caraman r = vcpu->kvm->arch.kvm_ops->get_one_reg(vcpu, id, val);
628a136a8bdSPaul Mackerras if (r == -EINVAL) {
629a136a8bdSPaul Mackerras r = 0;
6308a41ea53SMihai Caraman switch (id) {
631a136a8bdSPaul Mackerras case KVM_REG_PPC_DAR:
6328a41ea53SMihai Caraman *val = get_reg_val(id, kvmppc_get_dar(vcpu));
633a136a8bdSPaul Mackerras break;
634a136a8bdSPaul Mackerras case KVM_REG_PPC_DSISR:
6358a41ea53SMihai Caraman *val = get_reg_val(id, kvmppc_get_dsisr(vcpu));
636a136a8bdSPaul Mackerras break;
637a8bd19efSPaul Mackerras case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
6388a41ea53SMihai Caraman i = id - KVM_REG_PPC_FPR0;
6398a41ea53SMihai Caraman *val = get_reg_val(id, VCPU_FPR(vcpu, i));
640a8bd19efSPaul Mackerras break;
641a8bd19efSPaul Mackerras case KVM_REG_PPC_FPSCR:
6428a41ea53SMihai Caraman *val = get_reg_val(id, vcpu->arch.fp.fpscr);
643a8bd19efSPaul Mackerras break;
644efff1912SPaul Mackerras #ifdef CONFIG_VSX
645efff1912SPaul Mackerras case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
646efff1912SPaul Mackerras if (cpu_has_feature(CPU_FTR_VSX)) {
6478a41ea53SMihai Caraman i = id - KVM_REG_PPC_VSR0;
6488a41ea53SMihai Caraman val->vsxval[0] = vcpu->arch.fp.fpr[i][0];
6498a41ea53SMihai Caraman val->vsxval[1] = vcpu->arch.fp.fpr[i][1];
650efff1912SPaul Mackerras } else {
651efff1912SPaul Mackerras r = -ENXIO;
652efff1912SPaul Mackerras }
653efff1912SPaul Mackerras break;
654efff1912SPaul Mackerras #endif /* CONFIG_VSX */
6558a41ea53SMihai Caraman case KVM_REG_PPC_DEBUG_INST:
6568a41ea53SMihai Caraman *val = get_reg_val(id, INS_TW);
6578c32a2eaSBharat Bhushan break;
6588b78645cSPaul Mackerras #ifdef CONFIG_KVM_XICS
6598b78645cSPaul Mackerras case KVM_REG_PPC_ICP_STATE:
6605af50993SBenjamin Herrenschmidt if (!vcpu->arch.icp && !vcpu->arch.xive_vcpu) {
6618b78645cSPaul Mackerras r = -ENXIO;
6628b78645cSPaul Mackerras break;
6638b78645cSPaul Mackerras }
66403f95332SPaul Mackerras if (xics_on_xive())
6655af50993SBenjamin Herrenschmidt *val = get_reg_val(id, kvmppc_xive_get_icp(vcpu));
6665af50993SBenjamin Herrenschmidt else
6678a41ea53SMihai Caraman *val = get_reg_val(id, kvmppc_xics_get_icp(vcpu));
6688b78645cSPaul Mackerras break;
6698b78645cSPaul Mackerras #endif /* CONFIG_KVM_XICS */
670e4945b9dSCédric Le Goater #ifdef CONFIG_KVM_XIVE
671e4945b9dSCédric Le Goater case KVM_REG_PPC_VP_STATE:
672e4945b9dSCédric Le Goater if (!vcpu->arch.xive_vcpu) {
673e4945b9dSCédric Le Goater r = -ENXIO;
674e4945b9dSCédric Le Goater break;
675e4945b9dSCédric Le Goater }
676e4945b9dSCédric Le Goater if (xive_enabled())
677e4945b9dSCédric Le Goater r = kvmppc_xive_native_get_vp(vcpu, val);
678e4945b9dSCédric Le Goater else
679e4945b9dSCédric Le Goater r = -ENXIO;
680e4945b9dSCédric Le Goater break;
681e4945b9dSCédric Le Goater #endif /* CONFIG_KVM_XIVE */
682616dff86SAlexander Graf case KVM_REG_PPC_FSCR:
6838a41ea53SMihai Caraman *val = get_reg_val(id, vcpu->arch.fscr);
684616dff86SAlexander Graf break;
685e14e7a1eSAlexander Graf case KVM_REG_PPC_TAR:
6868a41ea53SMihai Caraman *val = get_reg_val(id, vcpu->arch.tar);
687e14e7a1eSAlexander Graf break;
6882e23f544SAlexander Graf case KVM_REG_PPC_EBBHR:
6898a41ea53SMihai Caraman *val = get_reg_val(id, vcpu->arch.ebbhr);
6902e23f544SAlexander Graf break;
6912e23f544SAlexander Graf case KVM_REG_PPC_EBBRR:
6928a41ea53SMihai Caraman *val = get_reg_val(id, vcpu->arch.ebbrr);
6932e23f544SAlexander Graf break;
6942e23f544SAlexander Graf case KVM_REG_PPC_BESCR:
6958a41ea53SMihai Caraman *val = get_reg_val(id, vcpu->arch.bescr);
6962e23f544SAlexander Graf break;
69706da28e7SAneesh Kumar K.V case KVM_REG_PPC_IC:
6988a41ea53SMihai Caraman *val = get_reg_val(id, vcpu->arch.ic);
69906da28e7SAneesh Kumar K.V break;
700a136a8bdSPaul Mackerras default:
701a136a8bdSPaul Mackerras r = -EINVAL;
702a136a8bdSPaul Mackerras break;
703a136a8bdSPaul Mackerras }
704a136a8bdSPaul Mackerras }
705a136a8bdSPaul Mackerras
706a136a8bdSPaul Mackerras return r;
707a136a8bdSPaul Mackerras }
708a136a8bdSPaul Mackerras
kvmppc_set_one_reg(struct kvm_vcpu * vcpu,u64 id,union kvmppc_one_reg * val)7098a41ea53SMihai Caraman int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id,
7108a41ea53SMihai Caraman union kvmppc_one_reg *val)
711a136a8bdSPaul Mackerras {
7128a41ea53SMihai Caraman int r = 0;
713a8bd19efSPaul Mackerras long int i;
714a136a8bdSPaul Mackerras
7158a41ea53SMihai Caraman r = vcpu->kvm->arch.kvm_ops->set_one_reg(vcpu, id, val);
716a136a8bdSPaul Mackerras if (r == -EINVAL) {
717a136a8bdSPaul Mackerras r = 0;
7188a41ea53SMihai Caraman switch (id) {
719a136a8bdSPaul Mackerras case KVM_REG_PPC_DAR:
7208a41ea53SMihai Caraman kvmppc_set_dar(vcpu, set_reg_val(id, *val));
721a136a8bdSPaul Mackerras break;
722a136a8bdSPaul Mackerras case KVM_REG_PPC_DSISR:
7238a41ea53SMihai Caraman kvmppc_set_dsisr(vcpu, set_reg_val(id, *val));
724a136a8bdSPaul Mackerras break;
725a8bd19efSPaul Mackerras case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31:
7268a41ea53SMihai Caraman i = id - KVM_REG_PPC_FPR0;
7278a41ea53SMihai Caraman VCPU_FPR(vcpu, i) = set_reg_val(id, *val);
728a8bd19efSPaul Mackerras break;
729a8bd19efSPaul Mackerras case KVM_REG_PPC_FPSCR:
7308a41ea53SMihai Caraman vcpu->arch.fp.fpscr = set_reg_val(id, *val);
731a8bd19efSPaul Mackerras break;
732efff1912SPaul Mackerras #ifdef CONFIG_VSX
733efff1912SPaul Mackerras case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31:
734efff1912SPaul Mackerras if (cpu_has_feature(CPU_FTR_VSX)) {
7358a41ea53SMihai Caraman i = id - KVM_REG_PPC_VSR0;
7368a41ea53SMihai Caraman vcpu->arch.fp.fpr[i][0] = val->vsxval[0];
7378a41ea53SMihai Caraman vcpu->arch.fp.fpr[i][1] = val->vsxval[1];
738efff1912SPaul Mackerras } else {
739efff1912SPaul Mackerras r = -ENXIO;
740efff1912SPaul Mackerras }
741efff1912SPaul Mackerras break;
742efff1912SPaul Mackerras #endif /* CONFIG_VSX */
7438b78645cSPaul Mackerras #ifdef CONFIG_KVM_XICS
7448b78645cSPaul Mackerras case KVM_REG_PPC_ICP_STATE:
7455af50993SBenjamin Herrenschmidt if (!vcpu->arch.icp && !vcpu->arch.xive_vcpu) {
7468b78645cSPaul Mackerras r = -ENXIO;
7478b78645cSPaul Mackerras break;
7488b78645cSPaul Mackerras }
74903f95332SPaul Mackerras if (xics_on_xive())
7505af50993SBenjamin Herrenschmidt r = kvmppc_xive_set_icp(vcpu, set_reg_val(id, *val));
7515af50993SBenjamin Herrenschmidt else
7525af50993SBenjamin Herrenschmidt r = kvmppc_xics_set_icp(vcpu, set_reg_val(id, *val));
7538b78645cSPaul Mackerras break;
7548b78645cSPaul Mackerras #endif /* CONFIG_KVM_XICS */
755e4945b9dSCédric Le Goater #ifdef CONFIG_KVM_XIVE
756e4945b9dSCédric Le Goater case KVM_REG_PPC_VP_STATE:
757e4945b9dSCédric Le Goater if (!vcpu->arch.xive_vcpu) {
758e4945b9dSCédric Le Goater r = -ENXIO;
759e4945b9dSCédric Le Goater break;
760e4945b9dSCédric Le Goater }
761e4945b9dSCédric Le Goater if (xive_enabled())
762e4945b9dSCédric Le Goater r = kvmppc_xive_native_set_vp(vcpu, val);
763e4945b9dSCédric Le Goater else
764e4945b9dSCédric Le Goater r = -ENXIO;
765e4945b9dSCédric Le Goater break;
766e4945b9dSCédric Le Goater #endif /* CONFIG_KVM_XIVE */
767616dff86SAlexander Graf case KVM_REG_PPC_FSCR:
7688a41ea53SMihai Caraman vcpu->arch.fscr = set_reg_val(id, *val);
769616dff86SAlexander Graf break;
770e14e7a1eSAlexander Graf case KVM_REG_PPC_TAR:
7718a41ea53SMihai Caraman vcpu->arch.tar = set_reg_val(id, *val);
772e14e7a1eSAlexander Graf break;
7732e23f544SAlexander Graf case KVM_REG_PPC_EBBHR:
7748a41ea53SMihai Caraman vcpu->arch.ebbhr = set_reg_val(id, *val);
7752e23f544SAlexander Graf break;
7762e23f544SAlexander Graf case KVM_REG_PPC_EBBRR:
7778a41ea53SMihai Caraman vcpu->arch.ebbrr = set_reg_val(id, *val);
7782e23f544SAlexander Graf break;
7792e23f544SAlexander Graf case KVM_REG_PPC_BESCR:
7808a41ea53SMihai Caraman vcpu->arch.bescr = set_reg_val(id, *val);
7812e23f544SAlexander Graf break;
78206da28e7SAneesh Kumar K.V case KVM_REG_PPC_IC:
7838a41ea53SMihai Caraman vcpu->arch.ic = set_reg_val(id, *val);
78406da28e7SAneesh Kumar K.V break;
785a136a8bdSPaul Mackerras default:
786a136a8bdSPaul Mackerras r = -EINVAL;
787a136a8bdSPaul Mackerras break;
788a136a8bdSPaul Mackerras }
789a136a8bdSPaul Mackerras }
790a136a8bdSPaul Mackerras
791a136a8bdSPaul Mackerras return r;
792a136a8bdSPaul Mackerras }
793a136a8bdSPaul Mackerras
kvmppc_core_vcpu_load(struct kvm_vcpu * vcpu,int cpu)7943a167beaSAneesh Kumar K.V void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
7953a167beaSAneesh Kumar K.V {
796cbbc58d4SAneesh Kumar K.V vcpu->kvm->arch.kvm_ops->vcpu_load(vcpu, cpu);
7973a167beaSAneesh Kumar K.V }
7983a167beaSAneesh Kumar K.V
kvmppc_core_vcpu_put(struct kvm_vcpu * vcpu)7993a167beaSAneesh Kumar K.V void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
8003a167beaSAneesh Kumar K.V {
801cbbc58d4SAneesh Kumar K.V vcpu->kvm->arch.kvm_ops->vcpu_put(vcpu);
8023a167beaSAneesh Kumar K.V }
8033a167beaSAneesh Kumar K.V
kvmppc_set_msr(struct kvm_vcpu * vcpu,u64 msr)8043a167beaSAneesh Kumar K.V void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
8053a167beaSAneesh Kumar K.V {
806cbbc58d4SAneesh Kumar K.V vcpu->kvm->arch.kvm_ops->set_msr(vcpu, msr);
8073a167beaSAneesh Kumar K.V }
8082ba9f0d8SAneesh Kumar K.V EXPORT_SYMBOL_GPL(kvmppc_set_msr);
8093a167beaSAneesh Kumar K.V
kvmppc_vcpu_run(struct kvm_vcpu * vcpu)8108c99d345STianjia Zhang int kvmppc_vcpu_run(struct kvm_vcpu *vcpu)
8113a167beaSAneesh Kumar K.V {
8128c99d345STianjia Zhang return vcpu->kvm->arch.kvm_ops->vcpu_run(vcpu);
8133a167beaSAneesh Kumar K.V }
8143a167beaSAneesh Kumar K.V
kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu * vcpu,struct kvm_translation * tr)8152f4cf5e4SAlexander Graf int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
8162f4cf5e4SAlexander Graf struct kvm_translation *tr)
8172f4cf5e4SAlexander Graf {
8182f4cf5e4SAlexander Graf return 0;
8192f4cf5e4SAlexander Graf }
8202f4cf5e4SAlexander Graf
kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu * vcpu,struct kvm_guest_debug * dbg)821092d62eeSBharat Bhushan int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
822092d62eeSBharat Bhushan struct kvm_guest_debug *dbg)
823092d62eeSBharat Bhushan {
82466b56562SChristoffer Dall vcpu_load(vcpu);
825a59c1d9eSMadhavan Srinivasan vcpu->guest_debug = dbg->control;
82666b56562SChristoffer Dall vcpu_put(vcpu);
827a59c1d9eSMadhavan Srinivasan return 0;
828092d62eeSBharat Bhushan }
829092d62eeSBharat Bhushan
kvmppc_decrementer_func(struct kvm_vcpu * vcpu)830d02d4d15SMihai Caraman void kvmppc_decrementer_func(struct kvm_vcpu *vcpu)
831dfd4d47eSScott Wood {
832dfd4d47eSScott Wood kvmppc_core_queue_dec(vcpu);
833dfd4d47eSScott Wood kvm_vcpu_kick(vcpu);
834dfd4d47eSScott Wood }
8353a167beaSAneesh Kumar K.V
kvmppc_core_vcpu_create(struct kvm_vcpu * vcpu)836ff030fdfSSean Christopherson int kvmppc_core_vcpu_create(struct kvm_vcpu *vcpu)
8373a167beaSAneesh Kumar K.V {
838ff030fdfSSean Christopherson return vcpu->kvm->arch.kvm_ops->vcpu_create(vcpu);
8393a167beaSAneesh Kumar K.V }
8403a167beaSAneesh Kumar K.V
kvmppc_core_vcpu_free(struct kvm_vcpu * vcpu)8413a167beaSAneesh Kumar K.V void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
8423a167beaSAneesh Kumar K.V {
843cbbc58d4SAneesh Kumar K.V vcpu->kvm->arch.kvm_ops->vcpu_free(vcpu);
8443a167beaSAneesh Kumar K.V }
8453a167beaSAneesh Kumar K.V
kvmppc_core_check_requests(struct kvm_vcpu * vcpu)8463a167beaSAneesh Kumar K.V int kvmppc_core_check_requests(struct kvm_vcpu *vcpu)
8473a167beaSAneesh Kumar K.V {
848cbbc58d4SAneesh Kumar K.V return vcpu->kvm->arch.kvm_ops->check_requests(vcpu);
8493a167beaSAneesh Kumar K.V }
8503a167beaSAneesh Kumar K.V
kvm_arch_sync_dirty_log(struct kvm * kvm,struct kvm_memory_slot * memslot)8510dff0846SSean Christopherson void kvm_arch_sync_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot)
8520dff0846SSean Christopherson {
8530dff0846SSean Christopherson
8540dff0846SSean Christopherson }
8550dff0846SSean Christopherson
kvm_vm_ioctl_get_dirty_log(struct kvm * kvm,struct kvm_dirty_log * log)8563a167beaSAneesh Kumar K.V int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
8573a167beaSAneesh Kumar K.V {
858cbbc58d4SAneesh Kumar K.V return kvm->arch.kvm_ops->get_dirty_log(kvm, log);
8593a167beaSAneesh Kumar K.V }
8603a167beaSAneesh Kumar K.V
kvmppc_core_free_memslot(struct kvm * kvm,struct kvm_memory_slot * slot)861e96c81eeSSean Christopherson void kvmppc_core_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot)
8623a167beaSAneesh Kumar K.V {
863e96c81eeSSean Christopherson kvm->arch.kvm_ops->free_memslot(slot);
8643a167beaSAneesh Kumar K.V }
8653a167beaSAneesh Kumar K.V
kvmppc_core_flush_memslot(struct kvm * kvm,struct kvm_memory_slot * memslot)8663a167beaSAneesh Kumar K.V void kvmppc_core_flush_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot)
8673a167beaSAneesh Kumar K.V {
868cbbc58d4SAneesh Kumar K.V kvm->arch.kvm_ops->flush_memslot(kvm, memslot);
8693a167beaSAneesh Kumar K.V }
8703a167beaSAneesh Kumar K.V
kvmppc_core_prepare_memory_region(struct kvm * kvm,const struct kvm_memory_slot * old,struct kvm_memory_slot * new,enum kvm_mr_change change)8713a167beaSAneesh Kumar K.V int kvmppc_core_prepare_memory_region(struct kvm *kvm,
872537a17b3SSean Christopherson const struct kvm_memory_slot *old,
873537a17b3SSean Christopherson struct kvm_memory_slot *new,
87482307e67SSean Christopherson enum kvm_mr_change change)
8753a167beaSAneesh Kumar K.V {
876eaaaed13SSean Christopherson return kvm->arch.kvm_ops->prepare_memory_region(kvm, old, new, change);
8773a167beaSAneesh Kumar K.V }
8783a167beaSAneesh Kumar K.V
kvmppc_core_commit_memory_region(struct kvm * kvm,struct kvm_memory_slot * old,const struct kvm_memory_slot * new,enum kvm_mr_change change)8793a167beaSAneesh Kumar K.V void kvmppc_core_commit_memory_region(struct kvm *kvm,
880537a17b3SSean Christopherson struct kvm_memory_slot *old,
881f032b734SBharata B Rao const struct kvm_memory_slot *new,
882f032b734SBharata B Rao enum kvm_mr_change change)
8833a167beaSAneesh Kumar K.V {
884eaaaed13SSean Christopherson kvm->arch.kvm_ops->commit_memory_region(kvm, old, new, change);
8853a167beaSAneesh Kumar K.V }
8863a167beaSAneesh Kumar K.V
kvm_unmap_gfn_range(struct kvm * kvm,struct kvm_gfn_range * range)887b1c5356eSSean Christopherson bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
8883a167beaSAneesh Kumar K.V {
889b1c5356eSSean Christopherson return kvm->arch.kvm_ops->unmap_gfn_range(kvm, range);
8903a167beaSAneesh Kumar K.V }
8913a167beaSAneesh Kumar K.V
kvm_age_gfn(struct kvm * kvm,struct kvm_gfn_range * range)892b1c5356eSSean Christopherson bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
8933a167beaSAneesh Kumar K.V {
894b1c5356eSSean Christopherson return kvm->arch.kvm_ops->age_gfn(kvm, range);
8953a167beaSAneesh Kumar K.V }
8963a167beaSAneesh Kumar K.V
kvm_test_age_gfn(struct kvm * kvm,struct kvm_gfn_range * range)897b1c5356eSSean Christopherson bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
8983a167beaSAneesh Kumar K.V {
899b1c5356eSSean Christopherson return kvm->arch.kvm_ops->test_age_gfn(kvm, range);
9003a167beaSAneesh Kumar K.V }
9013a167beaSAneesh Kumar K.V
kvm_set_spte_gfn(struct kvm * kvm,struct kvm_gfn_range * range)902b1c5356eSSean Christopherson bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
9033a167beaSAneesh Kumar K.V {
904b1c5356eSSean Christopherson return kvm->arch.kvm_ops->set_spte_gfn(kvm, range);
9053a167beaSAneesh Kumar K.V }
9063a167beaSAneesh Kumar K.V
kvmppc_core_init_vm(struct kvm * kvm)9073a167beaSAneesh Kumar K.V int kvmppc_core_init_vm(struct kvm *kvm)
9083a167beaSAneesh Kumar K.V {
9093a167beaSAneesh Kumar K.V
9103a167beaSAneesh Kumar K.V #ifdef CONFIG_PPC64
911366baf28SAlexey Kardashevskiy INIT_LIST_HEAD_RCU(&kvm->arch.spapr_tce_tables);
9123a167beaSAneesh Kumar K.V INIT_LIST_HEAD(&kvm->arch.rtas_tokens);
9131659e27dSPaul Mackerras mutex_init(&kvm->arch.rtas_token_lock);
9143a167beaSAneesh Kumar K.V #endif
9153a167beaSAneesh Kumar K.V
916cbbc58d4SAneesh Kumar K.V return kvm->arch.kvm_ops->init_vm(kvm);
9173a167beaSAneesh Kumar K.V }
9183a167beaSAneesh Kumar K.V
kvmppc_core_destroy_vm(struct kvm * kvm)9193a167beaSAneesh Kumar K.V void kvmppc_core_destroy_vm(struct kvm *kvm)
9203a167beaSAneesh Kumar K.V {
921cbbc58d4SAneesh Kumar K.V kvm->arch.kvm_ops->destroy_vm(kvm);
9223a167beaSAneesh Kumar K.V
9233a167beaSAneesh Kumar K.V #ifdef CONFIG_PPC64
9243a167beaSAneesh Kumar K.V kvmppc_rtas_tokens_free(kvm);
9253a167beaSAneesh Kumar K.V WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables));
9263a167beaSAneesh Kumar K.V #endif
9275422e951SCédric Le Goater
9285422e951SCédric Le Goater #ifdef CONFIG_KVM_XICS
9295422e951SCédric Le Goater /*
9305706d14dSGreg Kurz * Free the XIVE and XICS devices which are not directly freed by the
9315422e951SCédric Le Goater * device 'release' method
9325422e951SCédric Le Goater */
9335422e951SCédric Le Goater kfree(kvm->arch.xive_devices.native);
9345422e951SCédric Le Goater kvm->arch.xive_devices.native = NULL;
9355422e951SCédric Le Goater kfree(kvm->arch.xive_devices.xics_on_xive);
9365422e951SCédric Le Goater kvm->arch.xive_devices.xics_on_xive = NULL;
9375706d14dSGreg Kurz kfree(kvm->arch.xics_device);
9385706d14dSGreg Kurz kvm->arch.xics_device = NULL;
9395422e951SCédric Le Goater #endif /* CONFIG_KVM_XICS */
9403a167beaSAneesh Kumar K.V }
9413a167beaSAneesh Kumar K.V
kvmppc_h_logical_ci_load(struct kvm_vcpu * vcpu)94299342cf8SDavid Gibson int kvmppc_h_logical_ci_load(struct kvm_vcpu *vcpu)
94399342cf8SDavid Gibson {
94499342cf8SDavid Gibson unsigned long size = kvmppc_get_gpr(vcpu, 4);
94599342cf8SDavid Gibson unsigned long addr = kvmppc_get_gpr(vcpu, 5);
94699342cf8SDavid Gibson u64 buf;
9473eb4ee68SThomas Huth int srcu_idx;
94899342cf8SDavid Gibson int ret;
94999342cf8SDavid Gibson
95099342cf8SDavid Gibson if (!is_power_of_2(size) || (size > sizeof(buf)))
95199342cf8SDavid Gibson return H_TOO_HARD;
95299342cf8SDavid Gibson
9533eb4ee68SThomas Huth srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
95499342cf8SDavid Gibson ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, addr, size, &buf);
9553eb4ee68SThomas Huth srcu_read_unlock(&vcpu->kvm->srcu, srcu_idx);
95699342cf8SDavid Gibson if (ret != 0)
95799342cf8SDavid Gibson return H_TOO_HARD;
95899342cf8SDavid Gibson
95999342cf8SDavid Gibson switch (size) {
96099342cf8SDavid Gibson case 1:
96199342cf8SDavid Gibson kvmppc_set_gpr(vcpu, 4, *(u8 *)&buf);
96299342cf8SDavid Gibson break;
96399342cf8SDavid Gibson
96499342cf8SDavid Gibson case 2:
96599342cf8SDavid Gibson kvmppc_set_gpr(vcpu, 4, be16_to_cpu(*(__be16 *)&buf));
96699342cf8SDavid Gibson break;
96799342cf8SDavid Gibson
96899342cf8SDavid Gibson case 4:
96999342cf8SDavid Gibson kvmppc_set_gpr(vcpu, 4, be32_to_cpu(*(__be32 *)&buf));
97099342cf8SDavid Gibson break;
97199342cf8SDavid Gibson
97299342cf8SDavid Gibson case 8:
97399342cf8SDavid Gibson kvmppc_set_gpr(vcpu, 4, be64_to_cpu(*(__be64 *)&buf));
97499342cf8SDavid Gibson break;
97599342cf8SDavid Gibson
97699342cf8SDavid Gibson default:
97799342cf8SDavid Gibson BUG();
97899342cf8SDavid Gibson }
97999342cf8SDavid Gibson
98099342cf8SDavid Gibson return H_SUCCESS;
98199342cf8SDavid Gibson }
98299342cf8SDavid Gibson EXPORT_SYMBOL_GPL(kvmppc_h_logical_ci_load);
98399342cf8SDavid Gibson
kvmppc_h_logical_ci_store(struct kvm_vcpu * vcpu)98499342cf8SDavid Gibson int kvmppc_h_logical_ci_store(struct kvm_vcpu *vcpu)
98599342cf8SDavid Gibson {
98699342cf8SDavid Gibson unsigned long size = kvmppc_get_gpr(vcpu, 4);
98799342cf8SDavid Gibson unsigned long addr = kvmppc_get_gpr(vcpu, 5);
98899342cf8SDavid Gibson unsigned long val = kvmppc_get_gpr(vcpu, 6);
98999342cf8SDavid Gibson u64 buf;
9903eb4ee68SThomas Huth int srcu_idx;
99199342cf8SDavid Gibson int ret;
99299342cf8SDavid Gibson
99399342cf8SDavid Gibson switch (size) {
99499342cf8SDavid Gibson case 1:
99599342cf8SDavid Gibson *(u8 *)&buf = val;
99699342cf8SDavid Gibson break;
99799342cf8SDavid Gibson
99899342cf8SDavid Gibson case 2:
99999342cf8SDavid Gibson *(__be16 *)&buf = cpu_to_be16(val);
100099342cf8SDavid Gibson break;
100199342cf8SDavid Gibson
100299342cf8SDavid Gibson case 4:
100399342cf8SDavid Gibson *(__be32 *)&buf = cpu_to_be32(val);
100499342cf8SDavid Gibson break;
100599342cf8SDavid Gibson
100699342cf8SDavid Gibson case 8:
100799342cf8SDavid Gibson *(__be64 *)&buf = cpu_to_be64(val);
100899342cf8SDavid Gibson break;
100999342cf8SDavid Gibson
101099342cf8SDavid Gibson default:
101199342cf8SDavid Gibson return H_TOO_HARD;
101299342cf8SDavid Gibson }
101399342cf8SDavid Gibson
10143eb4ee68SThomas Huth srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
101599342cf8SDavid Gibson ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, addr, size, &buf);
10163eb4ee68SThomas Huth srcu_read_unlock(&vcpu->kvm->srcu, srcu_idx);
101799342cf8SDavid Gibson if (ret != 0)
101899342cf8SDavid Gibson return H_TOO_HARD;
101999342cf8SDavid Gibson
102099342cf8SDavid Gibson return H_SUCCESS;
102199342cf8SDavid Gibson }
102299342cf8SDavid Gibson EXPORT_SYMBOL_GPL(kvmppc_h_logical_ci_store);
102399342cf8SDavid Gibson
kvmppc_book3s_hcall_implemented(struct kvm * kvm,unsigned long hcall)1024ae2113a4SPaul Mackerras int kvmppc_book3s_hcall_implemented(struct kvm *kvm, unsigned long hcall)
1025ae2113a4SPaul Mackerras {
1026ae2113a4SPaul Mackerras return kvm->arch.kvm_ops->hcall_implemented(hcall);
1027ae2113a4SPaul Mackerras }
1028ae2113a4SPaul Mackerras
10295af50993SBenjamin Herrenschmidt #ifdef CONFIG_KVM_XICS
kvm_set_irq(struct kvm * kvm,int irq_source_id,u32 irq,int level,bool line_status)10305af50993SBenjamin Herrenschmidt int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
10315af50993SBenjamin Herrenschmidt bool line_status)
10325af50993SBenjamin Herrenschmidt {
103303f95332SPaul Mackerras if (xics_on_xive())
10345af50993SBenjamin Herrenschmidt return kvmppc_xive_set_irq(kvm, irq_source_id, irq, level,
10355af50993SBenjamin Herrenschmidt line_status);
10365af50993SBenjamin Herrenschmidt else
10375af50993SBenjamin Herrenschmidt return kvmppc_xics_set_irq(kvm, irq_source_id, irq, level,
10385af50993SBenjamin Herrenschmidt line_status);
10395af50993SBenjamin Herrenschmidt }
10405af50993SBenjamin Herrenschmidt
kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry * irq_entry,struct kvm * kvm,int irq_source_id,int level,bool line_status)10415af50993SBenjamin Herrenschmidt int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *irq_entry,
10425af50993SBenjamin Herrenschmidt struct kvm *kvm, int irq_source_id,
10435af50993SBenjamin Herrenschmidt int level, bool line_status)
10445af50993SBenjamin Herrenschmidt {
10455af50993SBenjamin Herrenschmidt return kvm_set_irq(kvm, irq_source_id, irq_entry->gsi,
10465af50993SBenjamin Herrenschmidt level, line_status);
10475af50993SBenjamin Herrenschmidt }
kvmppc_book3s_set_irq(struct kvm_kernel_irq_routing_entry * e,struct kvm * kvm,int irq_source_id,int level,bool line_status)10485af50993SBenjamin Herrenschmidt static int kvmppc_book3s_set_irq(struct kvm_kernel_irq_routing_entry *e,
10495af50993SBenjamin Herrenschmidt struct kvm *kvm, int irq_source_id, int level,
10505af50993SBenjamin Herrenschmidt bool line_status)
10515af50993SBenjamin Herrenschmidt {
10525af50993SBenjamin Herrenschmidt return kvm_set_irq(kvm, irq_source_id, e->gsi, level, line_status);
10535af50993SBenjamin Herrenschmidt }
10545af50993SBenjamin Herrenschmidt
kvm_irq_map_gsi(struct kvm * kvm,struct kvm_kernel_irq_routing_entry * entries,int gsi)10555af50993SBenjamin Herrenschmidt int kvm_irq_map_gsi(struct kvm *kvm,
10565af50993SBenjamin Herrenschmidt struct kvm_kernel_irq_routing_entry *entries, int gsi)
10575af50993SBenjamin Herrenschmidt {
10585af50993SBenjamin Herrenschmidt entries->gsi = gsi;
10595af50993SBenjamin Herrenschmidt entries->type = KVM_IRQ_ROUTING_IRQCHIP;
10605af50993SBenjamin Herrenschmidt entries->set = kvmppc_book3s_set_irq;
10615af50993SBenjamin Herrenschmidt entries->irqchip.irqchip = 0;
10625af50993SBenjamin Herrenschmidt entries->irqchip.pin = gsi;
10635af50993SBenjamin Herrenschmidt return 1;
10645af50993SBenjamin Herrenschmidt }
10655af50993SBenjamin Herrenschmidt
kvm_irq_map_chip_pin(struct kvm * kvm,unsigned irqchip,unsigned pin)10665af50993SBenjamin Herrenschmidt int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
10675af50993SBenjamin Herrenschmidt {
10685af50993SBenjamin Herrenschmidt return pin;
10695af50993SBenjamin Herrenschmidt }
10705af50993SBenjamin Herrenschmidt
10715af50993SBenjamin Herrenschmidt #endif /* CONFIG_KVM_XICS */
10725af50993SBenjamin Herrenschmidt
kvmppc_book3s_init(void)1073cbbc58d4SAneesh Kumar K.V static int kvmppc_book3s_init(void)
1074cbbc58d4SAneesh Kumar K.V {
1075cbbc58d4SAneesh Kumar K.V int r;
1076cbbc58d4SAneesh Kumar K.V
107781a1cf9fSSean Christopherson r = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
1078cbbc58d4SAneesh Kumar K.V if (r)
1079cbbc58d4SAneesh Kumar K.V return r;
1080ab78475cSAlexander Graf #ifdef CONFIG_KVM_BOOK3S_32_HANDLER
1081cbbc58d4SAneesh Kumar K.V r = kvmppc_book3s_init_pr();
1082cbbc58d4SAneesh Kumar K.V #endif
1083cbbc58d4SAneesh Kumar K.V
10845af50993SBenjamin Herrenschmidt #ifdef CONFIG_KVM_XICS
10855af50993SBenjamin Herrenschmidt #ifdef CONFIG_KVM_XIVE
108603f95332SPaul Mackerras if (xics_on_xive()) {
10875af50993SBenjamin Herrenschmidt kvm_register_device_ops(&kvm_xive_ops, KVM_DEV_TYPE_XICS);
1088dcbac73aSNicholas Piggin if (kvmppc_xive_native_supported())
108990c73795SCédric Le Goater kvm_register_device_ops(&kvm_xive_native_ops,
109090c73795SCédric Le Goater KVM_DEV_TYPE_XIVE);
10915af50993SBenjamin Herrenschmidt } else
10925af50993SBenjamin Herrenschmidt #endif
10935af50993SBenjamin Herrenschmidt kvm_register_device_ops(&kvm_xics_ops, KVM_DEV_TYPE_XICS);
10945af50993SBenjamin Herrenschmidt #endif
10955af50993SBenjamin Herrenschmidt return r;
1096cbbc58d4SAneesh Kumar K.V }
1097cbbc58d4SAneesh Kumar K.V
kvmppc_book3s_exit(void)1098cbbc58d4SAneesh Kumar K.V static void kvmppc_book3s_exit(void)
1099cbbc58d4SAneesh Kumar K.V {
1100ab78475cSAlexander Graf #ifdef CONFIG_KVM_BOOK3S_32_HANDLER
1101cbbc58d4SAneesh Kumar K.V kvmppc_book3s_exit_pr();
1102cbbc58d4SAneesh Kumar K.V #endif
1103cbbc58d4SAneesh Kumar K.V kvm_exit();
1104cbbc58d4SAneesh Kumar K.V }
1105cbbc58d4SAneesh Kumar K.V
1106cbbc58d4SAneesh Kumar K.V module_init(kvmppc_book3s_init);
1107cbbc58d4SAneesh Kumar K.V module_exit(kvmppc_book3s_exit);
1108398a76c6SAlexander Graf
1109398a76c6SAlexander Graf /* On 32bit this is our one and only kernel module */
1110ab78475cSAlexander Graf #ifdef CONFIG_KVM_BOOK3S_32_HANDLER
1111398a76c6SAlexander Graf MODULE_ALIAS_MISCDEV(KVM_MINOR);
1112398a76c6SAlexander Graf MODULE_ALIAS("devname:kvm");
1113398a76c6SAlexander Graf #endif
1114