12f4cf5e4SAlexander Graf /* 22f4cf5e4SAlexander Graf * Copyright (C) 2009. SUSE Linux Products GmbH. All rights reserved. 32f4cf5e4SAlexander Graf * 42f4cf5e4SAlexander Graf * Authors: 52f4cf5e4SAlexander Graf * Alexander Graf <agraf@suse.de> 62f4cf5e4SAlexander Graf * Kevin Wolf <mail@kevin-wolf.de> 72f4cf5e4SAlexander Graf * 82f4cf5e4SAlexander Graf * Description: 92f4cf5e4SAlexander Graf * This file is derived from arch/powerpc/kvm/44x.c, 102f4cf5e4SAlexander Graf * by Hollis Blanchard <hollisb@us.ibm.com>. 112f4cf5e4SAlexander Graf * 122f4cf5e4SAlexander Graf * This program is free software; you can redistribute it and/or modify 132f4cf5e4SAlexander Graf * it under the terms of the GNU General Public License, version 2, as 142f4cf5e4SAlexander Graf * published by the Free Software Foundation. 152f4cf5e4SAlexander Graf */ 162f4cf5e4SAlexander Graf 172f4cf5e4SAlexander Graf #include <linux/kvm_host.h> 182f4cf5e4SAlexander Graf #include <linux/err.h> 19329d20baSStephen Rothwell #include <linux/slab.h> 202f4cf5e4SAlexander Graf 212f4cf5e4SAlexander Graf #include <asm/reg.h> 222f4cf5e4SAlexander Graf #include <asm/cputable.h> 232f4cf5e4SAlexander Graf #include <asm/cacheflush.h> 242f4cf5e4SAlexander Graf #include <asm/tlbflush.h> 252f4cf5e4SAlexander Graf #include <asm/uaccess.h> 262f4cf5e4SAlexander Graf #include <asm/io.h> 272f4cf5e4SAlexander Graf #include <asm/kvm_ppc.h> 282f4cf5e4SAlexander Graf #include <asm/kvm_book3s.h> 292f4cf5e4SAlexander Graf #include <asm/mmu_context.h> 30149dbdb1SPaul Mackerras #include <asm/page.h> 315a0e3ad6STejun Heo #include <linux/gfp.h> 322f4cf5e4SAlexander Graf #include <linux/sched.h> 332f4cf5e4SAlexander Graf #include <linux/vmalloc.h> 349fb244a2SAlexander Graf #include <linux/highmem.h> 352f4cf5e4SAlexander Graf 36c4befc58SPaul Mackerras #include "trace.h" 37c4befc58SPaul Mackerras 382f4cf5e4SAlexander Graf #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU 392f4cf5e4SAlexander Graf 402f4cf5e4SAlexander Graf /* #define EXIT_DEBUG */ 4107b0907dSAlexander Graf 422f4cf5e4SAlexander Graf struct kvm_stats_debugfs_item debugfs_entries[] = { 432f4cf5e4SAlexander Graf { "exits", VCPU_STAT(sum_exits) }, 442f4cf5e4SAlexander Graf { "mmio", VCPU_STAT(mmio_exits) }, 452f4cf5e4SAlexander Graf { "sig", VCPU_STAT(signal_exits) }, 462f4cf5e4SAlexander Graf { "sysc", VCPU_STAT(syscall_exits) }, 472f4cf5e4SAlexander Graf { "inst_emu", VCPU_STAT(emulated_inst_exits) }, 482f4cf5e4SAlexander Graf { "dec", VCPU_STAT(dec_exits) }, 492f4cf5e4SAlexander Graf { "ext_intr", VCPU_STAT(ext_intr_exits) }, 502f4cf5e4SAlexander Graf { "queue_intr", VCPU_STAT(queue_intr) }, 512f4cf5e4SAlexander Graf { "halt_wakeup", VCPU_STAT(halt_wakeup) }, 522f4cf5e4SAlexander Graf { "pf_storage", VCPU_STAT(pf_storage) }, 532f4cf5e4SAlexander Graf { "sp_storage", VCPU_STAT(sp_storage) }, 542f4cf5e4SAlexander Graf { "pf_instruc", VCPU_STAT(pf_instruc) }, 552f4cf5e4SAlexander Graf { "sp_instruc", VCPU_STAT(sp_instruc) }, 562f4cf5e4SAlexander Graf { "ld", VCPU_STAT(ld) }, 572f4cf5e4SAlexander Graf { "ld_slow", VCPU_STAT(ld_slow) }, 582f4cf5e4SAlexander Graf { "st", VCPU_STAT(st) }, 592f4cf5e4SAlexander Graf { "st_slow", VCPU_STAT(st_slow) }, 602f4cf5e4SAlexander Graf { NULL } 612f4cf5e4SAlexander Graf }; 622f4cf5e4SAlexander Graf 632f4cf5e4SAlexander Graf void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu) 642f4cf5e4SAlexander Graf { 652f4cf5e4SAlexander Graf } 662f4cf5e4SAlexander Graf 672f4cf5e4SAlexander Graf void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu) 682f4cf5e4SAlexander Graf { 692f4cf5e4SAlexander Graf } 702f4cf5e4SAlexander Graf 712f4cf5e4SAlexander Graf void kvmppc_inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 flags) 722f4cf5e4SAlexander Graf { 73de7906c3SAlexander Graf vcpu->arch.shared->srr0 = kvmppc_get_pc(vcpu); 74de7906c3SAlexander Graf vcpu->arch.shared->srr1 = vcpu->arch.shared->msr | flags; 75f05ed4d5SPaul Mackerras kvmppc_set_pc(vcpu, kvmppc_interrupt_offset(vcpu) + vec); 762f4cf5e4SAlexander Graf vcpu->arch.mmu.reset_msr(vcpu); 772f4cf5e4SAlexander Graf } 782f4cf5e4SAlexander Graf 79583617b7SAlexander Graf static int kvmppc_book3s_vec2irqprio(unsigned int vec) 802f4cf5e4SAlexander Graf { 812f4cf5e4SAlexander Graf unsigned int prio; 822f4cf5e4SAlexander Graf 832f4cf5e4SAlexander Graf switch (vec) { 842f4cf5e4SAlexander Graf case 0x100: prio = BOOK3S_IRQPRIO_SYSTEM_RESET; break; 852f4cf5e4SAlexander Graf case 0x200: prio = BOOK3S_IRQPRIO_MACHINE_CHECK; break; 862f4cf5e4SAlexander Graf case 0x300: prio = BOOK3S_IRQPRIO_DATA_STORAGE; break; 872f4cf5e4SAlexander Graf case 0x380: prio = BOOK3S_IRQPRIO_DATA_SEGMENT; break; 882f4cf5e4SAlexander Graf case 0x400: prio = BOOK3S_IRQPRIO_INST_STORAGE; break; 892f4cf5e4SAlexander Graf case 0x480: prio = BOOK3S_IRQPRIO_INST_SEGMENT; break; 902f4cf5e4SAlexander Graf case 0x500: prio = BOOK3S_IRQPRIO_EXTERNAL; break; 9117bd1580SAlexander Graf case 0x501: prio = BOOK3S_IRQPRIO_EXTERNAL_LEVEL; break; 922f4cf5e4SAlexander Graf case 0x600: prio = BOOK3S_IRQPRIO_ALIGNMENT; break; 932f4cf5e4SAlexander Graf case 0x700: prio = BOOK3S_IRQPRIO_PROGRAM; break; 942f4cf5e4SAlexander Graf case 0x800: prio = BOOK3S_IRQPRIO_FP_UNAVAIL; break; 952f4cf5e4SAlexander Graf case 0x900: prio = BOOK3S_IRQPRIO_DECREMENTER; break; 962f4cf5e4SAlexander Graf case 0xc00: prio = BOOK3S_IRQPRIO_SYSCALL; break; 972f4cf5e4SAlexander Graf case 0xd00: prio = BOOK3S_IRQPRIO_DEBUG; break; 982f4cf5e4SAlexander Graf case 0xf20: prio = BOOK3S_IRQPRIO_ALTIVEC; break; 992f4cf5e4SAlexander Graf case 0xf40: prio = BOOK3S_IRQPRIO_VSX; break; 1002f4cf5e4SAlexander Graf default: prio = BOOK3S_IRQPRIO_MAX; break; 1012f4cf5e4SAlexander Graf } 1022f4cf5e4SAlexander Graf 103583617b7SAlexander Graf return prio; 104583617b7SAlexander Graf } 105583617b7SAlexander Graf 1067706664dSAlexander Graf static void kvmppc_book3s_dequeue_irqprio(struct kvm_vcpu *vcpu, 1077706664dSAlexander Graf unsigned int vec) 1087706664dSAlexander Graf { 109f05ed4d5SPaul Mackerras unsigned long old_pending = vcpu->arch.pending_exceptions; 110f05ed4d5SPaul Mackerras 1117706664dSAlexander Graf clear_bit(kvmppc_book3s_vec2irqprio(vec), 1127706664dSAlexander Graf &vcpu->arch.pending_exceptions); 1139ee18b1eSAlexander Graf 114f05ed4d5SPaul Mackerras kvmppc_update_int_pending(vcpu, vcpu->arch.pending_exceptions, 115f05ed4d5SPaul Mackerras old_pending); 1167706664dSAlexander Graf } 1177706664dSAlexander Graf 118583617b7SAlexander Graf void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec) 119583617b7SAlexander Graf { 120583617b7SAlexander Graf vcpu->stat.queue_intr++; 121583617b7SAlexander Graf 122583617b7SAlexander Graf set_bit(kvmppc_book3s_vec2irqprio(vec), 123583617b7SAlexander Graf &vcpu->arch.pending_exceptions); 1242f4cf5e4SAlexander Graf #ifdef EXIT_DEBUG 1252f4cf5e4SAlexander Graf printk(KERN_INFO "Queueing interrupt %x\n", vec); 1262f4cf5e4SAlexander Graf #endif 1272f4cf5e4SAlexander Graf } 1282f4cf5e4SAlexander Graf 1292f4cf5e4SAlexander Graf 13025a8a02dSAlexander Graf void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags) 1312f4cf5e4SAlexander Graf { 132*3cf658b6SPaul Mackerras /* might as well deliver this straight away */ 133*3cf658b6SPaul Mackerras kvmppc_inject_interrupt(vcpu, BOOK3S_INTERRUPT_PROGRAM, flags); 1342f4cf5e4SAlexander Graf } 1352f4cf5e4SAlexander Graf 1362f4cf5e4SAlexander Graf void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu) 1372f4cf5e4SAlexander Graf { 1382f4cf5e4SAlexander Graf kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER); 1392f4cf5e4SAlexander Graf } 1402f4cf5e4SAlexander Graf 1412f4cf5e4SAlexander Graf int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu) 1422f4cf5e4SAlexander Graf { 14344075d95SPaul Mackerras return test_bit(BOOK3S_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions); 1442f4cf5e4SAlexander Graf } 1452f4cf5e4SAlexander Graf 1467706664dSAlexander Graf void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu) 1477706664dSAlexander Graf { 1487706664dSAlexander Graf kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_DECREMENTER); 1497706664dSAlexander Graf } 1507706664dSAlexander Graf 1512f4cf5e4SAlexander Graf void kvmppc_core_queue_external(struct kvm_vcpu *vcpu, 1522f4cf5e4SAlexander Graf struct kvm_interrupt *irq) 1532f4cf5e4SAlexander Graf { 15417bd1580SAlexander Graf unsigned int vec = BOOK3S_INTERRUPT_EXTERNAL; 15517bd1580SAlexander Graf 15617bd1580SAlexander Graf if (irq->irq == KVM_INTERRUPT_SET_LEVEL) 15717bd1580SAlexander Graf vec = BOOK3S_INTERRUPT_EXTERNAL_LEVEL; 15817bd1580SAlexander Graf 15917bd1580SAlexander Graf kvmppc_book3s_queue_irqprio(vcpu, vec); 1602f4cf5e4SAlexander Graf } 1612f4cf5e4SAlexander Graf 16218978768SAlexander Graf void kvmppc_core_dequeue_external(struct kvm_vcpu *vcpu, 16318978768SAlexander Graf struct kvm_interrupt *irq) 16418978768SAlexander Graf { 16518978768SAlexander Graf kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL); 16617bd1580SAlexander Graf kvmppc_book3s_dequeue_irqprio(vcpu, BOOK3S_INTERRUPT_EXTERNAL_LEVEL); 16718978768SAlexander Graf } 16818978768SAlexander Graf 1692f4cf5e4SAlexander Graf int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) 1702f4cf5e4SAlexander Graf { 1712f4cf5e4SAlexander Graf int deliver = 1; 1722f4cf5e4SAlexander Graf int vec = 0; 173f05ed4d5SPaul Mackerras bool crit = kvmppc_critical_section(vcpu); 1742f4cf5e4SAlexander Graf 1752f4cf5e4SAlexander Graf switch (priority) { 1762f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_DECREMENTER: 1775c6cedf4SAlexander Graf deliver = (vcpu->arch.shared->msr & MSR_EE) && !crit; 1782f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_DECREMENTER; 1792f4cf5e4SAlexander Graf break; 1802f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_EXTERNAL: 18117bd1580SAlexander Graf case BOOK3S_IRQPRIO_EXTERNAL_LEVEL: 1825c6cedf4SAlexander Graf deliver = (vcpu->arch.shared->msr & MSR_EE) && !crit; 1832f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_EXTERNAL; 1842f4cf5e4SAlexander Graf break; 1852f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_SYSTEM_RESET: 1862f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_SYSTEM_RESET; 1872f4cf5e4SAlexander Graf break; 1882f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_MACHINE_CHECK: 1892f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_MACHINE_CHECK; 1902f4cf5e4SAlexander Graf break; 1912f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_DATA_STORAGE: 1922f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_DATA_STORAGE; 1932f4cf5e4SAlexander Graf break; 1942f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_INST_STORAGE: 1952f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_INST_STORAGE; 1962f4cf5e4SAlexander Graf break; 1972f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_DATA_SEGMENT: 1982f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_DATA_SEGMENT; 1992f4cf5e4SAlexander Graf break; 2002f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_INST_SEGMENT: 2012f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_INST_SEGMENT; 2022f4cf5e4SAlexander Graf break; 2032f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_ALIGNMENT: 2042f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_ALIGNMENT; 2052f4cf5e4SAlexander Graf break; 2062f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_PROGRAM: 2072f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_PROGRAM; 2082f4cf5e4SAlexander Graf break; 2092f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_VSX: 2102f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_VSX; 2112f4cf5e4SAlexander Graf break; 2122f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_ALTIVEC: 2132f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_ALTIVEC; 2142f4cf5e4SAlexander Graf break; 2152f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_FP_UNAVAIL: 2162f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_FP_UNAVAIL; 2172f4cf5e4SAlexander Graf break; 2182f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_SYSCALL: 2192f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_SYSCALL; 2202f4cf5e4SAlexander Graf break; 2212f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_DEBUG: 2222f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_TRACE; 2232f4cf5e4SAlexander Graf break; 2242f4cf5e4SAlexander Graf case BOOK3S_IRQPRIO_PERFORMANCE_MONITOR: 2252f4cf5e4SAlexander Graf vec = BOOK3S_INTERRUPT_PERFMON; 2262f4cf5e4SAlexander Graf break; 2272f4cf5e4SAlexander Graf default: 2282f4cf5e4SAlexander Graf deliver = 0; 2292f4cf5e4SAlexander Graf printk(KERN_ERR "KVM: Unknown interrupt: 0x%x\n", priority); 2302f4cf5e4SAlexander Graf break; 2312f4cf5e4SAlexander Graf } 2322f4cf5e4SAlexander Graf 2332f4cf5e4SAlexander Graf #if 0 2342f4cf5e4SAlexander Graf printk(KERN_INFO "Deliver interrupt 0x%x? %x\n", vec, deliver); 2352f4cf5e4SAlexander Graf #endif 2362f4cf5e4SAlexander Graf 2372f4cf5e4SAlexander Graf if (deliver) 238*3cf658b6SPaul Mackerras kvmppc_inject_interrupt(vcpu, vec, 0); 2392f4cf5e4SAlexander Graf 2402f4cf5e4SAlexander Graf return deliver; 2412f4cf5e4SAlexander Graf } 2422f4cf5e4SAlexander Graf 24317bd1580SAlexander Graf /* 24417bd1580SAlexander Graf * This function determines if an irqprio should be cleared once issued. 24517bd1580SAlexander Graf */ 24617bd1580SAlexander Graf static bool clear_irqprio(struct kvm_vcpu *vcpu, unsigned int priority) 24717bd1580SAlexander Graf { 24817bd1580SAlexander Graf switch (priority) { 24917bd1580SAlexander Graf case BOOK3S_IRQPRIO_DECREMENTER: 25017bd1580SAlexander Graf /* DEC interrupts get cleared by mtdec */ 25117bd1580SAlexander Graf return false; 25217bd1580SAlexander Graf case BOOK3S_IRQPRIO_EXTERNAL_LEVEL: 25317bd1580SAlexander Graf /* External interrupts get cleared by userspace */ 25417bd1580SAlexander Graf return false; 25517bd1580SAlexander Graf } 25617bd1580SAlexander Graf 25717bd1580SAlexander Graf return true; 25817bd1580SAlexander Graf } 25917bd1580SAlexander Graf 2602f4cf5e4SAlexander Graf void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu) 2612f4cf5e4SAlexander Graf { 2622f4cf5e4SAlexander Graf unsigned long *pending = &vcpu->arch.pending_exceptions; 26390bba358SAlexander Graf unsigned long old_pending = vcpu->arch.pending_exceptions; 2642f4cf5e4SAlexander Graf unsigned int priority; 2652f4cf5e4SAlexander Graf 2662f4cf5e4SAlexander Graf #ifdef EXIT_DEBUG 2672f4cf5e4SAlexander Graf if (vcpu->arch.pending_exceptions) 2682f4cf5e4SAlexander Graf printk(KERN_EMERG "KVM: Check pending: %lx\n", vcpu->arch.pending_exceptions); 2692f4cf5e4SAlexander Graf #endif 2702f4cf5e4SAlexander Graf priority = __ffs(*pending); 271ada7ba17SAlexander Graf while (priority < BOOK3S_IRQPRIO_MAX) { 2727706664dSAlexander Graf if (kvmppc_book3s_irqprio_deliver(vcpu, priority) && 27317bd1580SAlexander Graf clear_irqprio(vcpu, priority)) { 2742f4cf5e4SAlexander Graf clear_bit(priority, &vcpu->arch.pending_exceptions); 2752f4cf5e4SAlexander Graf break; 2762f4cf5e4SAlexander Graf } 2772f4cf5e4SAlexander Graf 2782f4cf5e4SAlexander Graf priority = find_next_bit(pending, 2792f4cf5e4SAlexander Graf BITS_PER_BYTE * sizeof(*pending), 2802f4cf5e4SAlexander Graf priority + 1); 2812f4cf5e4SAlexander Graf } 28290bba358SAlexander Graf 28390bba358SAlexander Graf /* Tell the guest about our interrupt status */ 284f05ed4d5SPaul Mackerras kvmppc_update_int_pending(vcpu, *pending, old_pending); 2852f4cf5e4SAlexander Graf } 2862f4cf5e4SAlexander Graf 287e8508940SAlexander Graf pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn) 288e8508940SAlexander Graf { 289e8508940SAlexander Graf ulong mp_pa = vcpu->arch.magic_page_pa; 290e8508940SAlexander Graf 291e8508940SAlexander Graf /* Magic page override */ 292e8508940SAlexander Graf if (unlikely(mp_pa) && 293e8508940SAlexander Graf unlikely(((gfn << PAGE_SHIFT) & KVM_PAM) == 294e8508940SAlexander Graf ((mp_pa & PAGE_MASK) & KVM_PAM))) { 295e8508940SAlexander Graf ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK; 296e8508940SAlexander Graf pfn_t pfn; 297e8508940SAlexander Graf 298e8508940SAlexander Graf pfn = (pfn_t)virt_to_phys((void*)shared_page) >> PAGE_SHIFT; 299e8508940SAlexander Graf get_page(pfn_to_page(pfn)); 300e8508940SAlexander Graf return pfn; 301e8508940SAlexander Graf } 302e8508940SAlexander Graf 303e8508940SAlexander Graf return gfn_to_pfn(vcpu->kvm, gfn); 304e8508940SAlexander Graf } 305e8508940SAlexander Graf 3062f4cf5e4SAlexander Graf static int kvmppc_xlate(struct kvm_vcpu *vcpu, ulong eaddr, bool data, 3072f4cf5e4SAlexander Graf struct kvmppc_pte *pte) 3082f4cf5e4SAlexander Graf { 309666e7252SAlexander Graf int relocated = (vcpu->arch.shared->msr & (data ? MSR_DR : MSR_IR)); 3102f4cf5e4SAlexander Graf int r; 3112f4cf5e4SAlexander Graf 3122f4cf5e4SAlexander Graf if (relocated) { 3132f4cf5e4SAlexander Graf r = vcpu->arch.mmu.xlate(vcpu, eaddr, pte, data); 3142f4cf5e4SAlexander Graf } else { 3152f4cf5e4SAlexander Graf pte->eaddr = eaddr; 31628e83b4fSAlexander Graf pte->raddr = eaddr & KVM_PAM; 3173eeafd7dSAlexander Graf pte->vpage = VSID_REAL | eaddr >> 12; 3182f4cf5e4SAlexander Graf pte->may_read = true; 3192f4cf5e4SAlexander Graf pte->may_write = true; 3202f4cf5e4SAlexander Graf pte->may_execute = true; 3212f4cf5e4SAlexander Graf r = 0; 3222f4cf5e4SAlexander Graf } 3232f4cf5e4SAlexander Graf 3242f4cf5e4SAlexander Graf return r; 3252f4cf5e4SAlexander Graf } 3262f4cf5e4SAlexander Graf 3272f4cf5e4SAlexander Graf static hva_t kvmppc_bad_hva(void) 3282f4cf5e4SAlexander Graf { 3292f4cf5e4SAlexander Graf return PAGE_OFFSET; 3302f4cf5e4SAlexander Graf } 3312f4cf5e4SAlexander Graf 3322f4cf5e4SAlexander Graf static hva_t kvmppc_pte_to_hva(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte, 3332f4cf5e4SAlexander Graf bool read) 3342f4cf5e4SAlexander Graf { 3352f4cf5e4SAlexander Graf hva_t hpage; 3362f4cf5e4SAlexander Graf 3372f4cf5e4SAlexander Graf if (read && !pte->may_read) 3382f4cf5e4SAlexander Graf goto err; 3392f4cf5e4SAlexander Graf 3402f4cf5e4SAlexander Graf if (!read && !pte->may_write) 3412f4cf5e4SAlexander Graf goto err; 3422f4cf5e4SAlexander Graf 3432f4cf5e4SAlexander Graf hpage = gfn_to_hva(vcpu->kvm, pte->raddr >> PAGE_SHIFT); 3442f4cf5e4SAlexander Graf if (kvm_is_error_hva(hpage)) 3452f4cf5e4SAlexander Graf goto err; 3462f4cf5e4SAlexander Graf 3472f4cf5e4SAlexander Graf return hpage | (pte->raddr & ~PAGE_MASK); 3482f4cf5e4SAlexander Graf err: 3492f4cf5e4SAlexander Graf return kvmppc_bad_hva(); 3502f4cf5e4SAlexander Graf } 3512f4cf5e4SAlexander Graf 3525467a97dSAlexander Graf int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, 3532f4cf5e4SAlexander Graf bool data) 3542f4cf5e4SAlexander Graf { 3552f4cf5e4SAlexander Graf struct kvmppc_pte pte; 3565467a97dSAlexander Graf 3575467a97dSAlexander Graf vcpu->stat.st++; 3585467a97dSAlexander Graf 3595467a97dSAlexander Graf if (kvmppc_xlate(vcpu, *eaddr, data, &pte)) 3609fb244a2SAlexander Graf return -ENOENT; 3615467a97dSAlexander Graf 3625467a97dSAlexander Graf *eaddr = pte.raddr; 3635467a97dSAlexander Graf 3649fb244a2SAlexander Graf if (!pte.may_write) 3659fb244a2SAlexander Graf return -EPERM; 3665467a97dSAlexander Graf 3679fb244a2SAlexander Graf if (kvm_write_guest(vcpu->kvm, pte.raddr, ptr, size)) 3689fb244a2SAlexander Graf return EMULATE_DO_MMIO; 3695467a97dSAlexander Graf 3705467a97dSAlexander Graf return EMULATE_DONE; 3715467a97dSAlexander Graf } 3725467a97dSAlexander Graf 3735467a97dSAlexander Graf int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, 3745467a97dSAlexander Graf bool data) 3755467a97dSAlexander Graf { 3765467a97dSAlexander Graf struct kvmppc_pte pte; 3775467a97dSAlexander Graf hva_t hva = *eaddr; 3782f4cf5e4SAlexander Graf 3792f4cf5e4SAlexander Graf vcpu->stat.ld++; 3802f4cf5e4SAlexander Graf 3815467a97dSAlexander Graf if (kvmppc_xlate(vcpu, *eaddr, data, &pte)) 3825467a97dSAlexander Graf goto nopte; 3835467a97dSAlexander Graf 3845467a97dSAlexander Graf *eaddr = pte.raddr; 3852f4cf5e4SAlexander Graf 3862f4cf5e4SAlexander Graf hva = kvmppc_pte_to_hva(vcpu, &pte, true); 3872f4cf5e4SAlexander Graf if (kvm_is_error_hva(hva)) 3885467a97dSAlexander Graf goto mmio; 3892f4cf5e4SAlexander Graf 3902f4cf5e4SAlexander Graf if (copy_from_user(ptr, (void __user *)hva, size)) { 3912f4cf5e4SAlexander Graf printk(KERN_INFO "kvmppc_ld at 0x%lx failed\n", hva); 3925467a97dSAlexander Graf goto mmio; 3932f4cf5e4SAlexander Graf } 3942f4cf5e4SAlexander Graf 3955467a97dSAlexander Graf return EMULATE_DONE; 3962f4cf5e4SAlexander Graf 3975467a97dSAlexander Graf nopte: 3982f4cf5e4SAlexander Graf return -ENOENT; 3995467a97dSAlexander Graf mmio: 4005467a97dSAlexander Graf return EMULATE_DO_MMIO; 4012f4cf5e4SAlexander Graf } 4022f4cf5e4SAlexander Graf 4032f4cf5e4SAlexander Graf int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) 4042f4cf5e4SAlexander Graf { 4052f4cf5e4SAlexander Graf return 0; 4062f4cf5e4SAlexander Graf } 4072f4cf5e4SAlexander Graf 4082f4cf5e4SAlexander Graf int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 4092f4cf5e4SAlexander Graf { 4102f4cf5e4SAlexander Graf int i; 4112f4cf5e4SAlexander Graf 412c7f38f46SAlexander Graf regs->pc = kvmppc_get_pc(vcpu); 413992b5b29SAlexander Graf regs->cr = kvmppc_get_cr(vcpu); 414c7f38f46SAlexander Graf regs->ctr = kvmppc_get_ctr(vcpu); 415c7f38f46SAlexander Graf regs->lr = kvmppc_get_lr(vcpu); 416992b5b29SAlexander Graf regs->xer = kvmppc_get_xer(vcpu); 417666e7252SAlexander Graf regs->msr = vcpu->arch.shared->msr; 418de7906c3SAlexander Graf regs->srr0 = vcpu->arch.shared->srr0; 419de7906c3SAlexander Graf regs->srr1 = vcpu->arch.shared->srr1; 4202f4cf5e4SAlexander Graf regs->pid = vcpu->arch.pid; 421a73a9599SAlexander Graf regs->sprg0 = vcpu->arch.shared->sprg0; 422a73a9599SAlexander Graf regs->sprg1 = vcpu->arch.shared->sprg1; 423a73a9599SAlexander Graf regs->sprg2 = vcpu->arch.shared->sprg2; 424a73a9599SAlexander Graf regs->sprg3 = vcpu->arch.shared->sprg3; 425bc9c1933SPeter Tyser regs->sprg4 = vcpu->arch.sprg4; 426bc9c1933SPeter Tyser regs->sprg5 = vcpu->arch.sprg5; 427bc9c1933SPeter Tyser regs->sprg6 = vcpu->arch.sprg6; 428bc9c1933SPeter Tyser regs->sprg7 = vcpu->arch.sprg7; 4292f4cf5e4SAlexander Graf 4302f4cf5e4SAlexander Graf for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) 4318e5b26b5SAlexander Graf regs->gpr[i] = kvmppc_get_gpr(vcpu, i); 4322f4cf5e4SAlexander Graf 4332f4cf5e4SAlexander Graf return 0; 4342f4cf5e4SAlexander Graf } 4352f4cf5e4SAlexander Graf 4362f4cf5e4SAlexander Graf int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 4372f4cf5e4SAlexander Graf { 4382f4cf5e4SAlexander Graf int i; 4392f4cf5e4SAlexander Graf 440c7f38f46SAlexander Graf kvmppc_set_pc(vcpu, regs->pc); 441992b5b29SAlexander Graf kvmppc_set_cr(vcpu, regs->cr); 442c7f38f46SAlexander Graf kvmppc_set_ctr(vcpu, regs->ctr); 443c7f38f46SAlexander Graf kvmppc_set_lr(vcpu, regs->lr); 444992b5b29SAlexander Graf kvmppc_set_xer(vcpu, regs->xer); 4452f4cf5e4SAlexander Graf kvmppc_set_msr(vcpu, regs->msr); 446de7906c3SAlexander Graf vcpu->arch.shared->srr0 = regs->srr0; 447de7906c3SAlexander Graf vcpu->arch.shared->srr1 = regs->srr1; 448a73a9599SAlexander Graf vcpu->arch.shared->sprg0 = regs->sprg0; 449a73a9599SAlexander Graf vcpu->arch.shared->sprg1 = regs->sprg1; 450a73a9599SAlexander Graf vcpu->arch.shared->sprg2 = regs->sprg2; 451a73a9599SAlexander Graf vcpu->arch.shared->sprg3 = regs->sprg3; 452bc9c1933SPeter Tyser vcpu->arch.sprg4 = regs->sprg4; 453bc9c1933SPeter Tyser vcpu->arch.sprg5 = regs->sprg5; 454bc9c1933SPeter Tyser vcpu->arch.sprg6 = regs->sprg6; 455bc9c1933SPeter Tyser vcpu->arch.sprg7 = regs->sprg7; 4562f4cf5e4SAlexander Graf 4578e5b26b5SAlexander Graf for (i = 0; i < ARRAY_SIZE(regs->gpr); i++) 4588e5b26b5SAlexander Graf kvmppc_set_gpr(vcpu, i, regs->gpr[i]); 4592f4cf5e4SAlexander Graf 4602f4cf5e4SAlexander Graf return 0; 4612f4cf5e4SAlexander Graf } 4622f4cf5e4SAlexander Graf 4632f4cf5e4SAlexander Graf int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 4642f4cf5e4SAlexander Graf { 4652f4cf5e4SAlexander Graf return -ENOTSUPP; 4662f4cf5e4SAlexander Graf } 4672f4cf5e4SAlexander Graf 4682f4cf5e4SAlexander Graf int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) 4692f4cf5e4SAlexander Graf { 4702f4cf5e4SAlexander Graf return -ENOTSUPP; 4712f4cf5e4SAlexander Graf } 4722f4cf5e4SAlexander Graf 4732f4cf5e4SAlexander Graf int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, 4742f4cf5e4SAlexander Graf struct kvm_translation *tr) 4752f4cf5e4SAlexander Graf { 4762f4cf5e4SAlexander Graf return 0; 4772f4cf5e4SAlexander Graf } 4782f4cf5e4SAlexander Graf 4792f4cf5e4SAlexander Graf /* 4802f4cf5e4SAlexander Graf * Get (and clear) the dirty memory log for a memory slot. 4812f4cf5e4SAlexander Graf */ 4822f4cf5e4SAlexander Graf int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, 4832f4cf5e4SAlexander Graf struct kvm_dirty_log *log) 4842f4cf5e4SAlexander Graf { 4852f4cf5e4SAlexander Graf struct kvm_memory_slot *memslot; 4862f4cf5e4SAlexander Graf struct kvm_vcpu *vcpu; 4872f4cf5e4SAlexander Graf ulong ga, ga_end; 4882f4cf5e4SAlexander Graf int is_dirty = 0; 48987bf6e7dSTakuya Yoshikawa int r; 49087bf6e7dSTakuya Yoshikawa unsigned long n; 4912f4cf5e4SAlexander Graf 49279fac95eSMarcelo Tosatti mutex_lock(&kvm->slots_lock); 4932f4cf5e4SAlexander Graf 4942f4cf5e4SAlexander Graf r = kvm_get_dirty_log(kvm, log, &is_dirty); 4952f4cf5e4SAlexander Graf if (r) 4962f4cf5e4SAlexander Graf goto out; 4972f4cf5e4SAlexander Graf 4982f4cf5e4SAlexander Graf /* If nothing is dirty, don't bother messing with page tables. */ 4992f4cf5e4SAlexander Graf if (is_dirty) { 50046a26bf5SMarcelo Tosatti memslot = &kvm->memslots->memslots[log->slot]; 5012f4cf5e4SAlexander Graf 5022f4cf5e4SAlexander Graf ga = memslot->base_gfn << PAGE_SHIFT; 5032f4cf5e4SAlexander Graf ga_end = ga + (memslot->npages << PAGE_SHIFT); 5042f4cf5e4SAlexander Graf 5052f4cf5e4SAlexander Graf kvm_for_each_vcpu(n, vcpu, kvm) 5062f4cf5e4SAlexander Graf kvmppc_mmu_pte_pflush(vcpu, ga, ga_end); 5072f4cf5e4SAlexander Graf 50887bf6e7dSTakuya Yoshikawa n = kvm_dirty_bitmap_bytes(memslot); 5092f4cf5e4SAlexander Graf memset(memslot->dirty_bitmap, 0, n); 5102f4cf5e4SAlexander Graf } 5112f4cf5e4SAlexander Graf 5122f4cf5e4SAlexander Graf r = 0; 5132f4cf5e4SAlexander Graf out: 51479fac95eSMarcelo Tosatti mutex_unlock(&kvm->slots_lock); 5152f4cf5e4SAlexander Graf return r; 5162f4cf5e4SAlexander Graf } 517