diff options
author | Avi Kivity <avi@redhat.com> | 2012-06-06 08:31:34 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2012-06-06 08:31:34 -0400 |
commit | 25e531a988ea5a64bd97a72dc9d3c65ad5850120 (patch) | |
tree | 5e5b7450fe08e4818a49b4248c9400a08b4cc463 /arch/powerpc | |
parent | 79f702a6d18c75760c68202007265b2310d6f44e (diff) | |
parent | d35b1075afc0172caa44b57b56a2b9b57e06d32e (diff) |
Merge branch 'for-upstream' of git://github.com/agraf/linux-2.6 into next
Alex says:
"Changes this time include:
- Generalize KVM_GUEST support to overall ePAPR code
- Fix reset for Book3S HV
- Fix machine check deferral when CONFIG_KVM_GUEST=y
- Add support for BookE register DECAR"
* 'for-upstream' of git://github.com/agraf/linux-2.6:
KVM: PPC: Not optimizing MSR_CE and MSR_ME with paravirt.
KVM: PPC: booke: Added DECAR support
KVM: PPC: Book3S HV: Make the guest hash table size configurable
KVM: PPC: Factor out guest epapr initialization
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/epapr_hcalls.h | 2 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kvm_book3s_64.h | 7 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kvm_host.h | 6 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kvm_ppc.h | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/epapr_hcalls.S | 25 | ||||
-rw-r--r-- | arch/powerpc/kernel/epapr_paravirt.c | 52 | ||||
-rw-r--r-- | arch/powerpc/kernel/kvm.c | 28 | ||||
-rw-r--r-- | arch/powerpc/kernel/kvm_emul.S | 12 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_64_mmu_hv.c | 123 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv.c | 40 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv_builtin.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv_rm_mmu.c | 15 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kvm/booke_emulate.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kvm/e500_emulate.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 18 | ||||
-rw-r--r-- | arch/powerpc/platforms/Kconfig | 9 |
18 files changed, 267 insertions, 90 deletions
diff --git a/arch/powerpc/include/asm/epapr_hcalls.h b/arch/powerpc/include/asm/epapr_hcalls.h index 976835d8f22e..bf2c06c33871 100644 --- a/arch/powerpc/include/asm/epapr_hcalls.h +++ b/arch/powerpc/include/asm/epapr_hcalls.h | |||
@@ -153,6 +153,8 @@ | |||
153 | #define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5" | 153 | #define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5" |
154 | #define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4" | 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 | * We use "uintptr_t" to define a register because it's guaranteed to be a | 160 | * We use "uintptr_t" to define a register because it's guaranteed to be a |
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index b0c08b142770..0dd1d86d3e31 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h | |||
@@ -36,11 +36,8 @@ static inline void svcpu_put(struct kvmppc_book3s_shadow_vcpu *svcpu) | |||
36 | #define SPAPR_TCE_SHIFT 12 | 36 | #define SPAPR_TCE_SHIFT 12 |
37 | 37 | ||
38 | #ifdef CONFIG_KVM_BOOK3S_64_HV | 38 | #ifdef CONFIG_KVM_BOOK3S_64_HV |
39 | /* For now use fixed-size 16MB page table */ | 39 | #define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */ |
40 | #define HPT_ORDER 24 | 40 | extern int kvm_hpt_order; /* order of preallocated HPTs */ |
41 | #define HPT_NPTEG (1ul << (HPT_ORDER - 7)) /* 128B per pteg */ | ||
42 | #define HPT_NPTE (HPT_NPTEG << 3) /* 8 PTEs per PTEG */ | ||
43 | #define HPT_HASH_MASK (HPT_NPTEG - 1) | ||
44 | #endif | 41 | #endif |
45 | 42 | ||
46 | #define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */ | 43 | #define VRMA_VSID 0x1ffffffUL /* 1TB VSID reserved for VRMA */ |
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index d848cdc49715..50ea12fd7bf5 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
@@ -237,6 +237,10 @@ struct kvm_arch { | |||
237 | unsigned long vrma_slb_v; | 237 | unsigned long vrma_slb_v; |
238 | int rma_setup_done; | 238 | int rma_setup_done; |
239 | int using_mmu_notifiers; | 239 | int using_mmu_notifiers; |
240 | u32 hpt_order; | ||
241 | atomic_t vcpus_running; | ||
242 | unsigned long hpt_npte; | ||
243 | unsigned long hpt_mask; | ||
240 | spinlock_t slot_phys_lock; | 244 | spinlock_t slot_phys_lock; |
241 | unsigned long *slot_phys[KVM_MEM_SLOTS_NUM]; | 245 | unsigned long *slot_phys[KVM_MEM_SLOTS_NUM]; |
242 | int slot_npages[KVM_MEM_SLOTS_NUM]; | 246 | int slot_npages[KVM_MEM_SLOTS_NUM]; |
@@ -414,7 +418,9 @@ struct kvm_vcpu_arch { | |||
414 | ulong mcsrr1; | 418 | ulong mcsrr1; |
415 | ulong mcsr; | 419 | ulong mcsr; |
416 | u32 dec; | 420 | u32 dec; |
421 | #ifdef CONFIG_BOOKE | ||
417 | u32 decar; | 422 | u32 decar; |
423 | #endif | ||
418 | u32 tbl; | 424 | u32 tbl; |
419 | u32 tbu; | 425 | u32 tbu; |
420 | u32 tcr; | 426 | u32 tcr; |
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index f68c22fa2fce..0124937a23b9 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
@@ -119,7 +119,8 @@ extern void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu); | |||
119 | extern int kvmppc_kvm_pv(struct kvm_vcpu *vcpu); | 119 | extern int kvmppc_kvm_pv(struct kvm_vcpu *vcpu); |
120 | extern void kvmppc_map_magic(struct kvm_vcpu *vcpu); | 120 | extern void kvmppc_map_magic(struct kvm_vcpu *vcpu); |
121 | 121 | ||
122 | extern long kvmppc_alloc_hpt(struct kvm *kvm); | 122 | extern long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp); |
123 | extern long kvmppc_alloc_reset_hpt(struct kvm *kvm, u32 *htab_orderp); | ||
123 | extern void kvmppc_free_hpt(struct kvm *kvm); | 124 | extern void kvmppc_free_hpt(struct kvm *kvm); |
124 | extern long kvmppc_prepare_vrma(struct kvm *kvm, | 125 | extern long kvmppc_prepare_vrma(struct kvm *kvm, |
125 | struct kvm_userspace_memory_region *mem); | 126 | struct kvm_userspace_memory_region *mem); |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 83afacd3ba7b..bb282dd81612 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -128,6 +128,7 @@ ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC),) | |||
128 | obj-y += ppc_save_regs.o | 128 | obj-y += ppc_save_regs.o |
129 | endif | 129 | endif |
130 | 130 | ||
131 | obj-$(CONFIG_EPAPR_PARAVIRT) += epapr_paravirt.o epapr_hcalls.o | ||
131 | obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o | 132 | obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o |
132 | 133 | ||
133 | # Disable GCOV in odd or sensitive code | 134 | # Disable GCOV in odd or sensitive code |
diff --git a/arch/powerpc/kernel/epapr_hcalls.S b/arch/powerpc/kernel/epapr_hcalls.S new file mode 100644 index 000000000000..697b390ebfd8 --- /dev/null +++ b/arch/powerpc/kernel/epapr_hcalls.S | |||
@@ -0,0 +1,25 @@ | |||
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 | ||
diff --git a/arch/powerpc/kernel/epapr_paravirt.c b/arch/powerpc/kernel/epapr_paravirt.c new file mode 100644 index 000000000000..028aeae370b6 --- /dev/null +++ b/arch/powerpc/kernel/epapr_paravirt.c | |||
@@ -0,0 +1,52 @@ | |||
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); | ||
diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index 62bdf2389669..1c13307e0308 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/cacheflush.h> | 31 | #include <asm/cacheflush.h> |
32 | #include <asm/disassemble.h> | 32 | #include <asm/disassemble.h> |
33 | #include <asm/ppc-opcode.h> | 33 | #include <asm/ppc-opcode.h> |
34 | #include <asm/epapr_hcalls.h> | ||
34 | 35 | ||
35 | #define KVM_MAGIC_PAGE (-4096L) | 36 | #define KVM_MAGIC_PAGE (-4096L) |
36 | #define magic_var(x) KVM_MAGIC_PAGE + offsetof(struct kvm_vcpu_arch_shared, x) | 37 | #define magic_var(x) KVM_MAGIC_PAGE + offsetof(struct kvm_vcpu_arch_shared, x) |
@@ -726,7 +727,7 @@ unsigned long kvm_hypercall(unsigned long *in, | |||
726 | unsigned long register r11 asm("r11") = nr; | 727 | unsigned long register r11 asm("r11") = nr; |
727 | unsigned long register r12 asm("r12"); | 728 | unsigned long register r12 asm("r12"); |
728 | 729 | ||
729 | asm volatile("bl kvm_hypercall_start" | 730 | asm volatile("bl epapr_hypercall_start" |
730 | : "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), | 731 | : "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), |
731 | "=r"(r7), "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11), | 732 | "=r"(r7), "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11), |
732 | "=r"(r12) | 733 | "=r"(r12) |
@@ -747,29 +748,6 @@ unsigned long kvm_hypercall(unsigned long *in, | |||
747 | } | 748 | } |
748 | EXPORT_SYMBOL_GPL(kvm_hypercall); | 749 | EXPORT_SYMBOL_GPL(kvm_hypercall); |
749 | 750 | ||
750 | static int kvm_para_setup(void) | ||
751 | { | ||
752 | extern u32 kvm_hypercall_start; | ||
753 | struct device_node *hyper_node; | ||
754 | u32 *insts; | ||
755 | int len, i; | ||
756 | |||
757 | hyper_node = of_find_node_by_path("/hypervisor"); | ||
758 | if (!hyper_node) | ||
759 | return -1; | ||
760 | |||
761 | insts = (u32*)of_get_property(hyper_node, "hcall-instructions", &len); | ||
762 | if (len % 4) | ||
763 | return -1; | ||
764 | if (len > (4 * 4)) | ||
765 | return -1; | ||
766 | |||
767 | for (i = 0; i < (len / 4); i++) | ||
768 | kvm_patch_ins(&(&kvm_hypercall_start)[i], insts[i]); | ||
769 | |||
770 | return 0; | ||
771 | } | ||
772 | |||
773 | static __init void kvm_free_tmp(void) | 751 | static __init void kvm_free_tmp(void) |
774 | { | 752 | { |
775 | unsigned long start, end; | 753 | unsigned long start, end; |
@@ -791,7 +769,7 @@ static int __init kvm_guest_init(void) | |||
791 | if (!kvm_para_available()) | 769 | if (!kvm_para_available()) |
792 | goto free_tmp; | 770 | goto free_tmp; |
793 | 771 | ||
794 | if (kvm_para_setup()) | 772 | if (!epapr_paravirt_enabled) |
795 | goto free_tmp; | 773 | goto free_tmp; |
796 | 774 | ||
797 | if (kvm_para_has_feature(KVM_FEATURE_MAGIC_PAGE)) | 775 | if (kvm_para_has_feature(KVM_FEATURE_MAGIC_PAGE)) |
diff --git a/arch/powerpc/kernel/kvm_emul.S b/arch/powerpc/kernel/kvm_emul.S index e291cf3cf954..e100ff324a85 100644 --- a/arch/powerpc/kernel/kvm_emul.S +++ b/arch/powerpc/kernel/kvm_emul.S | |||
@@ -24,16 +24,6 @@ | |||
24 | #include <asm/page.h> | 24 | #include <asm/page.h> |
25 | #include <asm/asm-offsets.h> | 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 | #define KVM_MAGIC_PAGE (-4096) | 27 | #define KVM_MAGIC_PAGE (-4096) |
38 | 28 | ||
39 | #ifdef CONFIG_64BIT | 29 | #ifdef CONFIG_64BIT |
@@ -132,7 +122,7 @@ kvm_emulate_mtmsrd_len: | |||
132 | .long (kvm_emulate_mtmsrd_end - kvm_emulate_mtmsrd) / 4 | 122 | .long (kvm_emulate_mtmsrd_end - kvm_emulate_mtmsrd) / 4 |
133 | 123 | ||
134 | 124 | ||
135 | #define MSR_SAFE_BITS (MSR_EE | MSR_CE | MSR_ME | MSR_RI) | 125 | #define MSR_SAFE_BITS (MSR_EE | MSR_RI) |
136 | #define MSR_CRITICAL_BITS ~MSR_SAFE_BITS | 126 | #define MSR_CRITICAL_BITS ~MSR_SAFE_BITS |
137 | 127 | ||
138 | .global kvm_emulate_mtmsr | 128 | .global kvm_emulate_mtmsr |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 80a577517584..d03eb6f7b058 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
@@ -37,56 +37,121 @@ | |||
37 | /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */ | 37 | /* POWER7 has 10-bit LPIDs, PPC970 has 6-bit LPIDs */ |
38 | #define MAX_LPID_970 63 | 38 | #define MAX_LPID_970 63 |
39 | 39 | ||
40 | long kvmppc_alloc_hpt(struct kvm *kvm) | 40 | /* Power architecture requires HPT is at least 256kB */ |
41 | #define PPC_MIN_HPT_ORDER 18 | ||
42 | |||
43 | long kvmppc_alloc_hpt(struct kvm *kvm, u32 *htab_orderp) | ||
41 | { | 44 | { |
42 | unsigned long hpt; | 45 | unsigned long hpt; |
43 | long lpid; | ||
44 | struct revmap_entry *rev; | 46 | struct revmap_entry *rev; |
45 | struct kvmppc_linear_info *li; | 47 | struct kvmppc_linear_info *li; |
48 | long order = kvm_hpt_order; | ||
46 | 49 | ||
47 | /* Allocate guest's hashed page table */ | 50 | if (htab_orderp) { |
48 | li = kvm_alloc_hpt(); | 51 | order = *htab_orderp; |
49 | if (li) { | 52 | if (order < PPC_MIN_HPT_ORDER) |
50 | /* using preallocated memory */ | 53 | order = PPC_MIN_HPT_ORDER; |
51 | hpt = (ulong)li->base_virt; | 54 | } |
52 | kvm->arch.hpt_li = li; | 55 | |
53 | } else { | 56 | /* |
54 | /* using dynamic memory */ | 57 | * If the user wants a different size from default, |
58 | * try first to allocate it from the kernel page allocator. | ||
59 | */ | ||
60 | hpt = 0; | ||
61 | if (order != kvm_hpt_order) { | ||
55 | hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT| | 62 | hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT| |
56 | __GFP_NOWARN, HPT_ORDER - PAGE_SHIFT); | 63 | __GFP_NOWARN, order - PAGE_SHIFT); |
64 | if (!hpt) | ||
65 | --order; | ||
57 | } | 66 | } |
58 | 67 | ||
68 | /* Next try to allocate from the preallocated pool */ | ||
59 | if (!hpt) { | 69 | if (!hpt) { |
60 | pr_err("kvm_alloc_hpt: Couldn't alloc HPT\n"); | 70 | li = kvm_alloc_hpt(); |
61 | return -ENOMEM; | 71 | if (li) { |
72 | hpt = (ulong)li->base_virt; | ||
73 | kvm->arch.hpt_li = li; | ||
74 | order = kvm_hpt_order; | ||
75 | } | ||
62 | } | 76 | } |
77 | |||
78 | /* Lastly try successively smaller sizes from the page allocator */ | ||
79 | while (!hpt && order > PPC_MIN_HPT_ORDER) { | ||
80 | hpt = __get_free_pages(GFP_KERNEL|__GFP_ZERO|__GFP_REPEAT| | ||
81 | __GFP_NOWARN, order - PAGE_SHIFT); | ||
82 | if (!hpt) | ||
83 | --order; | ||
84 | } | ||
85 | |||
86 | if (!hpt) | ||
87 | return -ENOMEM; | ||
88 | |||
63 | kvm->arch.hpt_virt = hpt; | 89 | kvm->arch.hpt_virt = hpt; |
90 | kvm->arch.hpt_order = order; | ||
91 | /* HPTEs are 2**4 bytes long */ | ||
92 | kvm->arch.hpt_npte = 1ul << (order - 4); | ||
93 | /* 128 (2**7) bytes in each HPTEG */ | ||
94 | kvm->arch.hpt_mask = (1ul << (order - 7)) - 1; | ||
64 | 95 | ||
65 | /* Allocate reverse map array */ | 96 | /* Allocate reverse map array */ |
66 | rev = vmalloc(sizeof(struct revmap_entry) * HPT_NPTE); | 97 | rev = vmalloc(sizeof(struct revmap_entry) * kvm->arch.hpt_npte); |
67 | if (!rev) { | 98 | if (!rev) { |
68 | pr_err("kvmppc_alloc_hpt: Couldn't alloc reverse map array\n"); | 99 | pr_err("kvmppc_alloc_hpt: Couldn't alloc reverse map array\n"); |
69 | goto out_freehpt; | 100 | goto out_freehpt; |
70 | } | 101 | } |
71 | kvm->arch.revmap = rev; | 102 | kvm->arch.revmap = rev; |
103 | kvm->arch.sdr1 = __pa(hpt) | (order - 18); | ||
72 | 104 | ||
73 | lpid = kvmppc_alloc_lpid(); | 105 | pr_info("KVM guest htab at %lx (order %ld), LPID %x\n", |
74 | if (lpid < 0) | 106 | hpt, order, kvm->arch.lpid); |
75 | goto out_freeboth; | ||
76 | 107 | ||
77 | kvm->arch.sdr1 = __pa(hpt) | (HPT_ORDER - 18); | 108 | if (htab_orderp) |
78 | kvm->arch.lpid = lpid; | 109 | *htab_orderp = order; |
79 | |||
80 | pr_info("KVM guest htab at %lx, LPID %lx\n", hpt, lpid); | ||
81 | return 0; | 110 | return 0; |
82 | 111 | ||
83 | out_freeboth: | ||
84 | vfree(rev); | ||
85 | out_freehpt: | 112 | out_freehpt: |
86 | free_pages(hpt, HPT_ORDER - PAGE_SHIFT); | 113 | if (kvm->arch.hpt_li) |
114 | kvm_release_hpt(kvm->arch.hpt_li); | ||
115 | else | ||
116 | free_pages(hpt, order - PAGE_SHIFT); | ||
87 | return -ENOMEM; | 117 | return -ENOMEM; |
88 | } | 118 | } |
89 | 119 | ||
120 | long kvmppc_alloc_reset_hpt(struct kvm *kvm, u32 *htab_orderp) | ||
121 | { | ||
122 | long err = -EBUSY; | ||
123 | long order; | ||
124 | |||
125 | mutex_lock(&kvm->lock); | ||
126 | if (kvm->arch.rma_setup_done) { | ||
127 | kvm->arch.rma_setup_done = 0; | ||
128 | /* order rma_setup_done vs. vcpus_running */ | ||
129 | smp_mb(); | ||
130 | if (atomic_read(&kvm->arch.vcpus_running)) { | ||
131 | kvm->arch.rma_setup_done = 1; | ||
132 | goto out; | ||
133 | } | ||
134 | } | ||
135 | if (kvm->arch.hpt_virt) { | ||
136 | order = kvm->arch.hpt_order; | ||
137 | /* Set the entire HPT to 0, i.e. invalid HPTEs */ | ||
138 | memset((void *)kvm->arch.hpt_virt, 0, 1ul << order); | ||
139 | /* | ||
140 | * Set the whole last_vcpu array to an invalid vcpu number. | ||
141 | * This ensures that each vcpu will flush its TLB on next entry. | ||
142 | */ | ||
143 | memset(kvm->arch.last_vcpu, 0xff, sizeof(kvm->arch.last_vcpu)); | ||
144 | *htab_orderp = order; | ||
145 | err = 0; | ||
146 | } else { | ||
147 | err = kvmppc_alloc_hpt(kvm, htab_orderp); | ||
148 | order = *htab_orderp; | ||
149 | } | ||
150 | out: | ||
151 | mutex_unlock(&kvm->lock); | ||
152 | return err; | ||
153 | } | ||
154 | |||
90 | void kvmppc_free_hpt(struct kvm *kvm) | 155 | void kvmppc_free_hpt(struct kvm *kvm) |
91 | { | 156 | { |
92 | kvmppc_free_lpid(kvm->arch.lpid); | 157 | kvmppc_free_lpid(kvm->arch.lpid); |
@@ -94,7 +159,8 @@ void kvmppc_free_hpt(struct kvm *kvm) | |||
94 | if (kvm->arch.hpt_li) | 159 | if (kvm->arch.hpt_li) |
95 | kvm_release_hpt(kvm->arch.hpt_li); | 160 | kvm_release_hpt(kvm->arch.hpt_li); |
96 | else | 161 | else |
97 | free_pages(kvm->arch.hpt_virt, HPT_ORDER - PAGE_SHIFT); | 162 | free_pages(kvm->arch.hpt_virt, |
163 | kvm->arch.hpt_order - PAGE_SHIFT); | ||
98 | } | 164 | } |
99 | 165 | ||
100 | /* Bits in first HPTE dword for pagesize 4k, 64k or 16M */ | 166 | /* Bits in first HPTE dword for pagesize 4k, 64k or 16M */ |
@@ -119,6 +185,7 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, | |||
119 | unsigned long psize; | 185 | unsigned long psize; |
120 | unsigned long hp0, hp1; | 186 | unsigned long hp0, hp1; |
121 | long ret; | 187 | long ret; |
188 | struct kvm *kvm = vcpu->kvm; | ||
122 | 189 | ||
123 | psize = 1ul << porder; | 190 | psize = 1ul << porder; |
124 | npages = memslot->npages >> (porder - PAGE_SHIFT); | 191 | npages = memslot->npages >> (porder - PAGE_SHIFT); |
@@ -127,8 +194,8 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, | |||
127 | if (npages > 1ul << (40 - porder)) | 194 | if (npages > 1ul << (40 - porder)) |
128 | npages = 1ul << (40 - porder); | 195 | npages = 1ul << (40 - porder); |
129 | /* Can't use more than 1 HPTE per HPTEG */ | 196 | /* Can't use more than 1 HPTE per HPTEG */ |
130 | if (npages > HPT_NPTEG) | 197 | if (npages > kvm->arch.hpt_mask + 1) |
131 | npages = HPT_NPTEG; | 198 | npages = kvm->arch.hpt_mask + 1; |
132 | 199 | ||
133 | hp0 = HPTE_V_1TB_SEG | (VRMA_VSID << (40 - 16)) | | 200 | hp0 = HPTE_V_1TB_SEG | (VRMA_VSID << (40 - 16)) | |
134 | HPTE_V_BOLTED | hpte0_pgsize_encoding(psize); | 201 | HPTE_V_BOLTED | hpte0_pgsize_encoding(psize); |
@@ -138,7 +205,7 @@ void kvmppc_map_vrma(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, | |||
138 | for (i = 0; i < npages; ++i) { | 205 | for (i = 0; i < npages; ++i) { |
139 | addr = i << porder; | 206 | addr = i << porder; |
140 | /* can't use hpt_hash since va > 64 bits */ | 207 | /* can't use hpt_hash since va > 64 bits */ |
141 | hash = (i ^ (VRMA_VSID ^ (VRMA_VSID << 25))) & HPT_HASH_MASK; | 208 | hash = (i ^ (VRMA_VSID ^ (VRMA_VSID << 25))) & kvm->arch.hpt_mask; |
142 | /* | 209 | /* |
143 | * We assume that the hash table is empty and no | 210 | * We assume that the hash table is empty and no |
144 | * vcpus are using it at this stage. Since we create | 211 | * vcpus are using it at this stage. Since we create |
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index c6af1d623839..d084e412b3c5 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -56,7 +56,7 @@ | |||
56 | /* #define EXIT_DEBUG_INT */ | 56 | /* #define EXIT_DEBUG_INT */ |
57 | 57 | ||
58 | static void kvmppc_end_cede(struct kvm_vcpu *vcpu); | 58 | static void kvmppc_end_cede(struct kvm_vcpu *vcpu); |
59 | static int kvmppc_hv_setup_rma(struct kvm_vcpu *vcpu); | 59 | static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu); |
60 | 60 | ||
61 | void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | 61 | void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
62 | { | 62 | { |
@@ -1068,11 +1068,15 @@ int kvmppc_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1068 | return -EINTR; | 1068 | return -EINTR; |
1069 | } | 1069 | } |
1070 | 1070 | ||
1071 | /* On the first time here, set up VRMA or RMA */ | 1071 | atomic_inc(&vcpu->kvm->arch.vcpus_running); |
1072 | /* Order vcpus_running vs. rma_setup_done, see kvmppc_alloc_reset_hpt */ | ||
1073 | smp_mb(); | ||
1074 | |||
1075 | /* On the first time here, set up HTAB and VRMA or RMA */ | ||
1072 | if (!vcpu->kvm->arch.rma_setup_done) { | 1076 | if (!vcpu->kvm->arch.rma_setup_done) { |
1073 | r = kvmppc_hv_setup_rma(vcpu); | 1077 | r = kvmppc_hv_setup_htab_rma(vcpu); |
1074 | if (r) | 1078 | if (r) |
1075 | return r; | 1079 | goto out; |
1076 | } | 1080 | } |
1077 | 1081 | ||
1078 | flush_fp_to_thread(current); | 1082 | flush_fp_to_thread(current); |
@@ -1090,6 +1094,9 @@ int kvmppc_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
1090 | kvmppc_core_prepare_to_enter(vcpu); | 1094 | kvmppc_core_prepare_to_enter(vcpu); |
1091 | } | 1095 | } |
1092 | } while (r == RESUME_GUEST); | 1096 | } while (r == RESUME_GUEST); |
1097 | |||
1098 | out: | ||
1099 | atomic_dec(&vcpu->kvm->arch.vcpus_running); | ||
1093 | return r; | 1100 | return r; |
1094 | } | 1101 | } |
1095 | 1102 | ||
@@ -1305,7 +1312,7 @@ void kvmppc_core_commit_memory_region(struct kvm *kvm, | |||
1305 | { | 1312 | { |
1306 | } | 1313 | } |
1307 | 1314 | ||
1308 | static int kvmppc_hv_setup_rma(struct kvm_vcpu *vcpu) | 1315 | static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) |
1309 | { | 1316 | { |
1310 | int err = 0; | 1317 | int err = 0; |
1311 | struct kvm *kvm = vcpu->kvm; | 1318 | struct kvm *kvm = vcpu->kvm; |
@@ -1324,6 +1331,15 @@ static int kvmppc_hv_setup_rma(struct kvm_vcpu *vcpu) | |||
1324 | if (kvm->arch.rma_setup_done) | 1331 | if (kvm->arch.rma_setup_done) |
1325 | goto out; /* another vcpu beat us to it */ | 1332 | goto out; /* another vcpu beat us to it */ |
1326 | 1333 | ||
1334 | /* Allocate hashed page table (if not done already) and reset it */ | ||
1335 | if (!kvm->arch.hpt_virt) { | ||
1336 | err = kvmppc_alloc_hpt(kvm, NULL); | ||
1337 | if (err) { | ||
1338 | pr_err("KVM: Couldn't alloc HPT\n"); | ||
1339 | goto out; | ||
1340 | } | ||
1341 | } | ||
1342 | |||
1327 | /* Look up the memslot for guest physical address 0 */ | 1343 | /* Look up the memslot for guest physical address 0 */ |
1328 | memslot = gfn_to_memslot(kvm, 0); | 1344 | memslot = gfn_to_memslot(kvm, 0); |
1329 | 1345 | ||
@@ -1435,13 +1451,14 @@ static int kvmppc_hv_setup_rma(struct kvm_vcpu *vcpu) | |||
1435 | 1451 | ||
1436 | int kvmppc_core_init_vm(struct kvm *kvm) | 1452 | int kvmppc_core_init_vm(struct kvm *kvm) |
1437 | { | 1453 | { |
1438 | long r; | 1454 | unsigned long lpcr, lpid; |
1439 | unsigned long lpcr; | ||
1440 | 1455 | ||
1441 | /* Allocate hashed page table */ | 1456 | /* Allocate the guest's logical partition ID */ |
1442 | r = kvmppc_alloc_hpt(kvm); | 1457 | |
1443 | if (r) | 1458 | lpid = kvmppc_alloc_lpid(); |
1444 | return r; | 1459 | if (lpid < 0) |
1460 | return -ENOMEM; | ||
1461 | kvm->arch.lpid = lpid; | ||
1445 | 1462 | ||
1446 | INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); | 1463 | INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); |
1447 | 1464 | ||
@@ -1451,7 +1468,6 @@ int kvmppc_core_init_vm(struct kvm *kvm) | |||
1451 | 1468 | ||
1452 | if (cpu_has_feature(CPU_FTR_ARCH_201)) { | 1469 | if (cpu_has_feature(CPU_FTR_ARCH_201)) { |
1453 | /* PPC970; HID4 is effectively the LPCR */ | 1470 | /* PPC970; HID4 is effectively the LPCR */ |
1454 | unsigned long lpid = kvm->arch.lpid; | ||
1455 | kvm->arch.host_lpid = 0; | 1471 | kvm->arch.host_lpid = 0; |
1456 | kvm->arch.host_lpcr = lpcr = mfspr(SPRN_HID4); | 1472 | kvm->arch.host_lpcr = lpcr = mfspr(SPRN_HID4); |
1457 | lpcr &= ~((3 << HID4_LPID1_SH) | (0xful << HID4_LPID5_SH)); | 1473 | lpcr &= ~((3 << HID4_LPID1_SH) | (0xful << HID4_LPID5_SH)); |
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index e1b60f56f2a1..fb4eac290fef 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c | |||
@@ -25,6 +25,9 @@ static void __init kvm_linear_init_one(ulong size, int count, int type); | |||
25 | static struct kvmppc_linear_info *kvm_alloc_linear(int type); | 25 | static struct kvmppc_linear_info *kvm_alloc_linear(int type); |
26 | static void kvm_release_linear(struct kvmppc_linear_info *ri); | 26 | static void kvm_release_linear(struct kvmppc_linear_info *ri); |
27 | 27 | ||
28 | int kvm_hpt_order = KVM_DEFAULT_HPT_ORDER; | ||
29 | EXPORT_SYMBOL_GPL(kvm_hpt_order); | ||
30 | |||
28 | /*************** RMA *************/ | 31 | /*************** RMA *************/ |
29 | 32 | ||
30 | /* | 33 | /* |
@@ -209,7 +212,7 @@ static void kvm_release_linear(struct kvmppc_linear_info *ri) | |||
209 | void __init kvm_linear_init(void) | 212 | void __init kvm_linear_init(void) |
210 | { | 213 | { |
211 | /* HPT */ | 214 | /* HPT */ |
212 | kvm_linear_init_one(1 << HPT_ORDER, kvm_hpt_count, KVM_LINEAR_HPT); | 215 | kvm_linear_init_one(1 << kvm_hpt_order, kvm_hpt_count, KVM_LINEAR_HPT); |
213 | 216 | ||
214 | /* RMA */ | 217 | /* RMA */ |
215 | /* Only do this on PPC970 in HV mode */ | 218 | /* Only do this on PPC970 in HV mode */ |
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index cec4daddbf31..5c70d19494f9 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c | |||
@@ -237,7 +237,7 @@ long kvmppc_h_enter(struct kvm_vcpu *vcpu, unsigned long flags, | |||
237 | 237 | ||
238 | /* Find and lock the HPTEG slot to use */ | 238 | /* Find and lock the HPTEG slot to use */ |
239 | do_insert: | 239 | do_insert: |
240 | if (pte_index >= HPT_NPTE) | 240 | if (pte_index >= kvm->arch.hpt_npte) |
241 | return H_PARAMETER; | 241 | return H_PARAMETER; |
242 | if (likely((flags & H_EXACT) == 0)) { | 242 | if (likely((flags & H_EXACT) == 0)) { |
243 | pte_index &= ~7UL; | 243 | pte_index &= ~7UL; |
@@ -352,7 +352,7 @@ long kvmppc_h_remove(struct kvm_vcpu *vcpu, unsigned long flags, | |||
352 | unsigned long v, r, rb; | 352 | unsigned long v, r, rb; |
353 | struct revmap_entry *rev; | 353 | struct revmap_entry *rev; |
354 | 354 | ||
355 | if (pte_index >= HPT_NPTE) | 355 | if (pte_index >= kvm->arch.hpt_npte) |
356 | return H_PARAMETER; | 356 | return H_PARAMETER; |
357 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 357 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); |
358 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) | 358 | while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) |
@@ -419,7 +419,8 @@ long kvmppc_h_bulk_remove(struct kvm_vcpu *vcpu) | |||
419 | i = 4; | 419 | i = 4; |
420 | break; | 420 | break; |
421 | } | 421 | } |
422 | if (req != 1 || flags == 3 || pte_index >= HPT_NPTE) { | 422 | if (req != 1 || flags == 3 || |
423 | pte_index >= kvm->arch.hpt_npte) { | ||
423 | /* parameter error */ | 424 | /* parameter error */ |
424 | args[j] = ((0xa0 | flags) << 56) + pte_index; | 425 | args[j] = ((0xa0 | flags) << 56) + pte_index; |
425 | ret = H_PARAMETER; | 426 | ret = H_PARAMETER; |
@@ -521,7 +522,7 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags, | |||
521 | struct revmap_entry *rev; | 522 | struct revmap_entry *rev; |
522 | unsigned long v, r, rb, mask, bits; | 523 | unsigned long v, r, rb, mask, bits; |
523 | 524 | ||
524 | if (pte_index >= HPT_NPTE) | 525 | if (pte_index >= kvm->arch.hpt_npte) |
525 | return H_PARAMETER; | 526 | return H_PARAMETER; |
526 | 527 | ||
527 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); | 528 | hpte = (unsigned long *)(kvm->arch.hpt_virt + (pte_index << 4)); |
@@ -583,7 +584,7 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long flags, | |||
583 | int i, n = 1; | 584 | int i, n = 1; |
584 | struct revmap_entry *rev = NULL; | 585 | struct revmap_entry *rev = NULL; |
585 | 586 | ||
586 | if (pte_index >= HPT_NPTE) | 587 | if (pte_index >= kvm->arch.hpt_npte) |
587 | return H_PARAMETER; | 588 | return H_PARAMETER; |
588 | if (flags & H_READ_4) { | 589 | if (flags & H_READ_4) { |
589 | pte_index &= ~3; | 590 | pte_index &= ~3; |
@@ -678,7 +679,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, | |||
678 | somask = (1UL << 28) - 1; | 679 | somask = (1UL << 28) - 1; |
679 | vsid = (slb_v & ~SLB_VSID_B) >> SLB_VSID_SHIFT; | 680 | vsid = (slb_v & ~SLB_VSID_B) >> SLB_VSID_SHIFT; |
680 | } | 681 | } |
681 | hash = (vsid ^ ((eaddr & somask) >> pshift)) & HPT_HASH_MASK; | 682 | hash = (vsid ^ ((eaddr & somask) >> pshift)) & kvm->arch.hpt_mask; |
682 | avpn = slb_v & ~(somask >> 16); /* also includes B */ | 683 | avpn = slb_v & ~(somask >> 16); /* also includes B */ |
683 | avpn |= (eaddr & somask) >> 16; | 684 | avpn |= (eaddr & somask) >> 16; |
684 | 685 | ||
@@ -723,7 +724,7 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v, | |||
723 | if (val & HPTE_V_SECONDARY) | 724 | if (val & HPTE_V_SECONDARY) |
724 | break; | 725 | break; |
725 | val |= HPTE_V_SECONDARY; | 726 | val |= HPTE_V_SECONDARY; |
726 | hash = hash ^ HPT_HASH_MASK; | 727 | hash = hash ^ kvm->arch.hpt_mask; |
727 | } | 728 | } |
728 | return -1; | 729 | return -1; |
729 | } | 730 | } |
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 72f13f4a06e0..86681eec60b1 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
@@ -1267,6 +1267,11 @@ void kvmppc_decrementer_func(unsigned long data) | |||
1267 | { | 1267 | { |
1268 | struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data; | 1268 | struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data; |
1269 | 1269 | ||
1270 | if (vcpu->arch.tcr & TCR_ARE) { | ||
1271 | vcpu->arch.dec = vcpu->arch.decar; | ||
1272 | kvmppc_emulate_dec(vcpu); | ||
1273 | } | ||
1274 | |||
1270 | kvmppc_set_tsr_bits(vcpu, TSR_DIS); | 1275 | kvmppc_set_tsr_bits(vcpu, TSR_DIS); |
1271 | } | 1276 | } |
1272 | 1277 | ||
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c index 6c76397f2af4..9eb9809eb13e 100644 --- a/arch/powerpc/kvm/booke_emulate.c +++ b/arch/powerpc/kvm/booke_emulate.c | |||
@@ -129,6 +129,9 @@ int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) | |||
129 | kvmppc_set_tcr(vcpu, spr_val); | 129 | kvmppc_set_tcr(vcpu, spr_val); |
130 | break; | 130 | break; |
131 | 131 | ||
132 | case SPRN_DECAR: | ||
133 | vcpu->arch.decar = spr_val; | ||
134 | break; | ||
132 | /* | 135 | /* |
133 | * Note: SPRG4-7 are user-readable. | 136 | * Note: SPRG4-7 are user-readable. |
134 | * These values are loaded into the real SPRGs when resuming the | 137 | * These values are loaded into the real SPRGs when resuming the |
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c index 8b99e076dc81..e04b0ef55ce0 100644 --- a/arch/powerpc/kvm/e500_emulate.c +++ b/arch/powerpc/kvm/e500_emulate.c | |||
@@ -269,6 +269,9 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) | |||
269 | *spr_val = vcpu->arch.shared->mas7_3 >> 32; | 269 | *spr_val = vcpu->arch.shared->mas7_3 >> 32; |
270 | break; | 270 | break; |
271 | #endif | 271 | #endif |
272 | case SPRN_DECAR: | ||
273 | *spr_val = vcpu->arch.decar; | ||
274 | break; | ||
272 | case SPRN_TLB0CFG: | 275 | case SPRN_TLB0CFG: |
273 | *spr_val = vcpu->arch.tlbcfg[0]; | 276 | *spr_val = vcpu->arch.tlbcfg[0]; |
274 | break; | 277 | break; |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 1493c8de947b..87f4dc886076 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -246,6 +246,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
246 | #endif | 246 | #endif |
247 | #ifdef CONFIG_PPC_BOOK3S_64 | 247 | #ifdef CONFIG_PPC_BOOK3S_64 |
248 | case KVM_CAP_SPAPR_TCE: | 248 | case KVM_CAP_SPAPR_TCE: |
249 | case KVM_CAP_PPC_ALLOC_HTAB: | ||
249 | r = 1; | 250 | r = 1; |
250 | break; | 251 | break; |
251 | #endif /* CONFIG_PPC_BOOK3S_64 */ | 252 | #endif /* CONFIG_PPC_BOOK3S_64 */ |
@@ -802,6 +803,23 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
802 | r = -EFAULT; | 803 | r = -EFAULT; |
803 | break; | 804 | break; |
804 | } | 805 | } |
806 | |||
807 | case KVM_PPC_ALLOCATE_HTAB: { | ||
808 | struct kvm *kvm = filp->private_data; | ||
809 | u32 htab_order; | ||
810 | |||
811 | r = -EFAULT; | ||
812 | if (get_user(htab_order, (u32 __user *)argp)) | ||
813 | break; | ||
814 | r = kvmppc_alloc_reset_hpt(kvm, &htab_order); | ||
815 | if (r) | ||
816 | break; | ||
817 | r = -EFAULT; | ||
818 | if (put_user(htab_order, (u32 __user *)argp)) | ||
819 | break; | ||
820 | r = 0; | ||
821 | break; | ||
822 | } | ||
805 | #endif /* CONFIG_KVM_BOOK3S_64_HV */ | 823 | #endif /* CONFIG_KVM_BOOK3S_64_HV */ |
806 | 824 | ||
807 | #ifdef CONFIG_PPC_BOOK3S_64 | 825 | #ifdef CONFIG_PPC_BOOK3S_64 |
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index a35ca44ade66..e7a896acd982 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig | |||
@@ -25,6 +25,7 @@ source "arch/powerpc/platforms/wsp/Kconfig" | |||
25 | config KVM_GUEST | 25 | config KVM_GUEST |
26 | bool "KVM Guest support" | 26 | bool "KVM Guest support" |
27 | default n | 27 | default n |
28 | select EPAPR_PARAVIRT | ||
28 | ---help--- | 29 | ---help--- |
29 | This option enables various optimizations for running under the KVM | 30 | This option enables various optimizations for running under the KVM |
30 | hypervisor. Overhead for the kernel when not running inside KVM should | 31 | hypervisor. Overhead for the kernel when not running inside KVM should |
@@ -32,6 +33,14 @@ config KVM_GUEST | |||
32 | 33 | ||
33 | In case of doubt, say Y | 34 | In case of doubt, say Y |
34 | 35 | ||
36 | config EPAPR_PARAVIRT | ||
37 | bool "ePAPR para-virtualization support" | ||
38 | default n | ||
39 | help | ||
40 | Enables ePAPR para-virtualization support for guests. | ||
41 | |||
42 | In case of doubt, say Y | ||
43 | |||
35 | config PPC_NATIVE | 44 | config PPC_NATIVE |
36 | bool | 45 | bool |
37 | depends on 6xx || PPC64 | 46 | depends on 6xx || PPC64 |