Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: PPC: Factor out guest epapr initialization

epapr paravirtualization support is now a Kconfig
selectable option

Signed-off-by: Liu Yu <yu.liu@freescale.com>
[stuart.yoder@freescale.com: misc minor fixes, description update]
Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>

authored by

Liu Yu-B13201 and committed by
Alexander Graf
2e1ae9c0 b48b2c3e

+92 -35
+2
arch/powerpc/include/asm/epapr_hcalls.h
··· 153 153 #define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5" 154 154 #define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4" 155 155 156 + extern bool epapr_paravirt_enabled; 157 + extern u32 epapr_hypercall_start[]; 156 158 157 159 /* 158 160 * We use "uintptr_t" to define a register because it's guaranteed to be a
+1
arch/powerpc/kernel/Makefile
··· 128 128 obj-y += ppc_save_regs.o 129 129 endif 130 130 131 + obj-$(CONFIG_EPAPR_PARAVIRT) += epapr_paravirt.o epapr_hcalls.o 131 132 obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o 132 133 133 134 # Disable GCOV in odd or sensitive code
+25
arch/powerpc/kernel/epapr_hcalls.S
··· 1 + /* 2 + * Copyright (C) 2012 Freescale Semiconductor, Inc. 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of the GNU General Public License 6 + * as published by the Free Software Foundation; either version 7 + * 2 of the License, or (at your option) any later version. 8 + */ 9 + 10 + #include <linux/threads.h> 11 + #include <asm/reg.h> 12 + #include <asm/page.h> 13 + #include <asm/cputable.h> 14 + #include <asm/thread_info.h> 15 + #include <asm/ppc_asm.h> 16 + #include <asm/asm-offsets.h> 17 + 18 + /* Hypercall entry point. Will be patched with device tree instructions. */ 19 + .global epapr_hypercall_start 20 + epapr_hypercall_start: 21 + li r3, -1 22 + nop 23 + nop 24 + nop 25 + blr
+52
arch/powerpc/kernel/epapr_paravirt.c
··· 1 + /* 2 + * ePAPR para-virtualization support. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License, version 2, as 6 + * published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + * 13 + * You should have received a copy of the GNU General Public License 14 + * along with this program; if not, write to the Free Software 15 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 + * 17 + * Copyright (C) 2012 Freescale Semiconductor, Inc. 18 + */ 19 + 20 + #include <linux/of.h> 21 + #include <asm/epapr_hcalls.h> 22 + #include <asm/cacheflush.h> 23 + #include <asm/code-patching.h> 24 + 25 + bool epapr_paravirt_enabled; 26 + 27 + static int __init epapr_paravirt_init(void) 28 + { 29 + struct device_node *hyper_node; 30 + const u32 *insts; 31 + int len, i; 32 + 33 + hyper_node = of_find_node_by_path("/hypervisor"); 34 + if (!hyper_node) 35 + return -ENODEV; 36 + 37 + insts = of_get_property(hyper_node, "hcall-instructions", &len); 38 + if (!insts) 39 + return -ENODEV; 40 + 41 + if (len % 4 || len > (4 * 4)) 42 + return -ENODEV; 43 + 44 + for (i = 0; i < (len / 4); i++) 45 + patch_instruction(epapr_hypercall_start + i, insts[i]); 46 + 47 + epapr_paravirt_enabled = true; 48 + 49 + return 0; 50 + } 51 + 52 + early_initcall(epapr_paravirt_init);
+3 -25
arch/powerpc/kernel/kvm.c
··· 31 31 #include <asm/cacheflush.h> 32 32 #include <asm/disassemble.h> 33 33 #include <asm/ppc-opcode.h> 34 + #include <asm/epapr_hcalls.h> 34 35 35 36 #define KVM_MAGIC_PAGE (-4096L) 36 37 #define magic_var(x) KVM_MAGIC_PAGE + offsetof(struct kvm_vcpu_arch_shared, x) ··· 727 726 unsigned long register r11 asm("r11") = nr; 728 727 unsigned long register r12 asm("r12"); 729 728 730 - asm volatile("bl kvm_hypercall_start" 729 + asm volatile("bl epapr_hypercall_start" 731 730 : "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), 732 731 "=r"(r7), "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11), 733 732 "=r"(r12) ··· 747 746 return r3; 748 747 } 749 748 EXPORT_SYMBOL_GPL(kvm_hypercall); 750 - 751 - static int kvm_para_setup(void) 752 - { 753 - extern u32 kvm_hypercall_start; 754 - struct device_node *hyper_node; 755 - u32 *insts; 756 - int len, i; 757 - 758 - hyper_node = of_find_node_by_path("/hypervisor"); 759 - if (!hyper_node) 760 - return -1; 761 - 762 - insts = (u32*)of_get_property(hyper_node, "hcall-instructions", &len); 763 - if (len % 4) 764 - return -1; 765 - if (len > (4 * 4)) 766 - return -1; 767 - 768 - for (i = 0; i < (len / 4); i++) 769 - kvm_patch_ins(&(&kvm_hypercall_start)[i], insts[i]); 770 - 771 - return 0; 772 - } 773 749 774 750 static __init void kvm_free_tmp(void) 775 751 { ··· 769 791 if (!kvm_para_available()) 770 792 goto free_tmp; 771 793 772 - if (kvm_para_setup()) 794 + if (!epapr_paravirt_enabled) 773 795 goto free_tmp; 774 796 775 797 if (kvm_para_has_feature(KVM_FEATURE_MAGIC_PAGE))
-10
arch/powerpc/kernel/kvm_emul.S
··· 24 24 #include <asm/page.h> 25 25 #include <asm/asm-offsets.h> 26 26 27 - /* Hypercall entry point. Will be patched with device tree instructions. */ 28 - 29 - .global kvm_hypercall_start 30 - kvm_hypercall_start: 31 - li r3, -1 32 - nop 33 - nop 34 - nop 35 - blr 36 - 37 27 #define KVM_MAGIC_PAGE (-4096) 38 28 39 29 #ifdef CONFIG_64BIT
+9
arch/powerpc/platforms/Kconfig
··· 25 25 config KVM_GUEST 26 26 bool "KVM Guest support" 27 27 default n 28 + select EPAPR_PARAVIRT 28 29 ---help--- 29 30 This option enables various optimizations for running under the KVM 30 31 hypervisor. Overhead for the kernel when not running inside KVM should 31 32 be minimal. 33 + 34 + In case of doubt, say Y 35 + 36 + config EPAPR_PARAVIRT 37 + bool "ePAPR para-virtualization support" 38 + default n 39 + help 40 + Enables ePAPR para-virtualization support for guests. 32 41 33 42 In case of doubt, say Y 34 43