diff options
-rw-r--r-- | Documentation/virtual/kvm/api.txt | 32 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kvm.h | 5 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kvm_book3s.h | 8 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kvm_host.h | 15 | ||||
-rw-r--r-- | arch/powerpc/include/asm/kvm_ppc.h | 10 | ||||
-rw-r--r-- | arch/powerpc/include/asm/reg.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kvm/Makefile | 3 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_64_mmu_hv.c | 97 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv.c | 259 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv_builtin.c | 152 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv_rmhandlers.S | 19 | ||||
-rw-r--r-- | arch/powerpc/kvm/powerpc.c | 13 | ||||
-rw-r--r-- | include/linux/kvm.h | 3 |
15 files changed, 505 insertions, 119 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 681871311d3e..b0e4b9cd6a66 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt | |||
@@ -1398,6 +1398,38 @@ the entries written by kernel-handled H_PUT_TCE calls, and also lets | |||
1398 | userspace update the TCE table directly which is useful in some | 1398 | userspace update the TCE table directly which is useful in some |
1399 | circumstances. | 1399 | circumstances. |
1400 | 1400 | ||
1401 | 4.63 KVM_ALLOCATE_RMA | ||
1402 | |||
1403 | Capability: KVM_CAP_PPC_RMA | ||
1404 | Architectures: powerpc | ||
1405 | Type: vm ioctl | ||
1406 | Parameters: struct kvm_allocate_rma (out) | ||
1407 | Returns: file descriptor for mapping the allocated RMA | ||
1408 | |||
1409 | This allocates a Real Mode Area (RMA) from the pool allocated at boot | ||
1410 | time by the kernel. An RMA is a physically-contiguous, aligned region | ||
1411 | of memory used on older POWER processors to provide the memory which | ||
1412 | will be accessed by real-mode (MMU off) accesses in a KVM guest. | ||
1413 | POWER processors support a set of sizes for the RMA that usually | ||
1414 | includes 64MB, 128MB, 256MB and some larger powers of two. | ||
1415 | |||
1416 | /* for KVM_ALLOCATE_RMA */ | ||
1417 | struct kvm_allocate_rma { | ||
1418 | __u64 rma_size; | ||
1419 | }; | ||
1420 | |||
1421 | The return value is a file descriptor which can be passed to mmap(2) | ||
1422 | to map the allocated RMA into userspace. The mapped area can then be | ||
1423 | passed to the KVM_SET_USER_MEMORY_REGION ioctl to establish it as the | ||
1424 | RMA for a virtual machine. The size of the RMA in bytes (which is | ||
1425 | fixed at host kernel boot time) is returned in the rma_size field of | ||
1426 | the argument structure. | ||
1427 | |||
1428 | The KVM_CAP_PPC_RMA capability is 1 or 2 if the KVM_ALLOCATE_RMA ioctl | ||
1429 | is supported; 2 if the processor requires all virtual machines to have | ||
1430 | an RMA, or 1 if the processor can use an RMA but doesn't require it, | ||
1431 | because it supports the Virtual RMA (VRMA) facility. | ||
1432 | |||
1401 | 5. The kvm_run structure | 1433 | 5. The kvm_run structure |
1402 | 1434 | ||
1403 | Application code obtains a pointer to the kvm_run structure by | 1435 | Application code obtains a pointer to the kvm_run structure by |
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h index 471bb3d85e0b..a4f6c85431f8 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h | |||
@@ -282,4 +282,9 @@ struct kvm_create_spapr_tce { | |||
282 | __u32 window_size; | 282 | __u32 window_size; |
283 | }; | 283 | }; |
284 | 284 | ||
285 | /* for KVM_ALLOCATE_RMA */ | ||
286 | struct kvm_allocate_rma { | ||
287 | __u64 rma_size; | ||
288 | }; | ||
289 | |||
285 | #endif /* __LINUX_KVM_POWERPC_H */ | 290 | #endif /* __LINUX_KVM_POWERPC_H */ |
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 5537c45d626c..3f91ebd4ae43 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h | |||
@@ -298,14 +298,6 @@ static inline unsigned long kvmppc_interrupt_offset(struct kvm_vcpu *vcpu) | |||
298 | static inline void kvmppc_update_int_pending(struct kvm_vcpu *vcpu, | 298 | static inline void kvmppc_update_int_pending(struct kvm_vcpu *vcpu, |
299 | unsigned long pending_now, unsigned long old_pending) | 299 | unsigned long pending_now, unsigned long old_pending) |
300 | { | 300 | { |
301 | /* Recalculate LPCR:MER based on the presence of | ||
302 | * a pending external interrupt | ||
303 | */ | ||
304 | if (test_bit(BOOK3S_IRQPRIO_EXTERNAL, &pending_now) || | ||
305 | test_bit(BOOK3S_IRQPRIO_EXTERNAL_LEVEL, &pending_now)) | ||
306 | vcpu->arch.lpcr |= LPCR_MER; | ||
307 | else | ||
308 | vcpu->arch.lpcr &= ~((u64)LPCR_MER); | ||
309 | } | 301 | } |
310 | 302 | ||
311 | static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) | 303 | static inline void kvmppc_set_gpr(struct kvm_vcpu *vcpu, int num, ulong val) |
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 0d6d569e19c7..f572d9cc31bd 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/threads.h> | 28 | #include <linux/threads.h> |
29 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
30 | #include <linux/kvm_para.h> | 30 | #include <linux/kvm_para.h> |
31 | #include <linux/list.h> | ||
32 | #include <linux/atomic.h> | ||
31 | #include <asm/kvm_asm.h> | 33 | #include <asm/kvm_asm.h> |
32 | #include <asm/processor.h> | 34 | #include <asm/processor.h> |
33 | 35 | ||
@@ -156,6 +158,14 @@ struct kvmppc_spapr_tce_table { | |||
156 | struct page *pages[0]; | 158 | struct page *pages[0]; |
157 | }; | 159 | }; |
158 | 160 | ||
161 | struct kvmppc_rma_info { | ||
162 | void *base_virt; | ||
163 | unsigned long base_pfn; | ||
164 | unsigned long npages; | ||
165 | struct list_head list; | ||
166 | atomic_t use_count; | ||
167 | }; | ||
168 | |||
159 | struct kvm_arch { | 169 | struct kvm_arch { |
160 | #ifdef CONFIG_KVM_BOOK3S_64_HV | 170 | #ifdef CONFIG_KVM_BOOK3S_64_HV |
161 | unsigned long hpt_virt; | 171 | unsigned long hpt_virt; |
@@ -169,6 +179,10 @@ struct kvm_arch { | |||
169 | unsigned long sdr1; | 179 | unsigned long sdr1; |
170 | unsigned long host_sdr1; | 180 | unsigned long host_sdr1; |
171 | int tlbie_lock; | 181 | int tlbie_lock; |
182 | int n_rma_pages; | ||
183 | unsigned long lpcr; | ||
184 | unsigned long rmor; | ||
185 | struct kvmppc_rma_info *rma; | ||
172 | struct list_head spapr_tce_tables; | 186 | struct list_head spapr_tce_tables; |
173 | unsigned short last_vcpu[NR_CPUS]; | 187 | unsigned short last_vcpu[NR_CPUS]; |
174 | struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; | 188 | struct kvmppc_vcore *vcores[KVM_MAX_VCORES]; |
@@ -295,7 +309,6 @@ struct kvm_vcpu_arch { | |||
295 | ulong guest_owned_ext; | 309 | ulong guest_owned_ext; |
296 | ulong purr; | 310 | ulong purr; |
297 | ulong spurr; | 311 | ulong spurr; |
298 | ulong lpcr; | ||
299 | ulong dscr; | 312 | ulong dscr; |
300 | ulong amr; | 313 | ulong amr; |
301 | ulong uamor; | 314 | ulong uamor; |
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 6ef734428634..d121f49d62b8 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
@@ -124,6 +124,10 @@ extern void kvmppc_map_vrma(struct kvm *kvm, | |||
124 | extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu); | 124 | extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu); |
125 | extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, | 125 | extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, |
126 | struct kvm_create_spapr_tce *args); | 126 | struct kvm_create_spapr_tce *args); |
127 | extern long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, | ||
128 | struct kvm_allocate_rma *rma); | ||
129 | extern struct kvmppc_rma_info *kvm_alloc_rma(void); | ||
130 | extern void kvm_release_rma(struct kvmppc_rma_info *ri); | ||
127 | extern int kvmppc_core_init_vm(struct kvm *kvm); | 131 | extern int kvmppc_core_init_vm(struct kvm *kvm); |
128 | extern void kvmppc_core_destroy_vm(struct kvm *kvm); | 132 | extern void kvmppc_core_destroy_vm(struct kvm *kvm); |
129 | extern int kvmppc_core_prepare_memory_region(struct kvm *kvm, | 133 | extern int kvmppc_core_prepare_memory_region(struct kvm *kvm, |
@@ -177,9 +181,15 @@ static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) | |||
177 | { | 181 | { |
178 | paca[cpu].kvm_hstate.xics_phys = addr; | 182 | paca[cpu].kvm_hstate.xics_phys = addr; |
179 | } | 183 | } |
184 | |||
185 | extern void kvm_rma_init(void); | ||
186 | |||
180 | #else | 187 | #else |
181 | static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) | 188 | static inline void kvmppc_set_xics_phys(int cpu, unsigned long addr) |
182 | {} | 189 | {} |
190 | |||
191 | static inline void kvm_rma_init(void) | ||
192 | {} | ||
183 | #endif | 193 | #endif |
184 | 194 | ||
185 | #endif /* __POWERPC_KVM_PPC_H__ */ | 195 | #endif /* __POWERPC_KVM_PPC_H__ */ |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 36a611b398c5..20a053c14270 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -242,6 +242,7 @@ | |||
242 | #define LPCR_VRMA_LP1 (1ul << (63-16)) | 242 | #define LPCR_VRMA_LP1 (1ul << (63-16)) |
243 | #define LPCR_VRMASD_SH (63-16) | 243 | #define LPCR_VRMASD_SH (63-16) |
244 | #define LPCR_RMLS 0x1C000000 /* impl dependent rmo limit sel */ | 244 | #define LPCR_RMLS 0x1C000000 /* impl dependent rmo limit sel */ |
245 | #define LPCR_RMLS_SH (63-37) | ||
245 | #define LPCR_ILE 0x02000000 /* !HV irqs set MSR:LE */ | 246 | #define LPCR_ILE 0x02000000 /* !HV irqs set MSR:LE */ |
246 | #define LPCR_PECE 0x00007000 /* powersave exit cause enable */ | 247 | #define LPCR_PECE 0x00007000 /* powersave exit cause enable */ |
247 | #define LPCR_PECE0 0x00004000 /* ext. exceptions can cause exit */ | 248 | #define LPCR_PECE0 0x00004000 /* ext. exceptions can cause exit */ |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index d0f2387fd792..f4aba938166b 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -437,6 +437,8 @@ int main(void) | |||
437 | DEFINE(KVM_TLBIE_LOCK, offsetof(struct kvm, arch.tlbie_lock)); | 437 | DEFINE(KVM_TLBIE_LOCK, offsetof(struct kvm, arch.tlbie_lock)); |
438 | DEFINE(KVM_ONLINE_CPUS, offsetof(struct kvm, online_vcpus.counter)); | 438 | DEFINE(KVM_ONLINE_CPUS, offsetof(struct kvm, online_vcpus.counter)); |
439 | DEFINE(KVM_LAST_VCPU, offsetof(struct kvm, arch.last_vcpu)); | 439 | DEFINE(KVM_LAST_VCPU, offsetof(struct kvm, arch.last_vcpu)); |
440 | DEFINE(KVM_LPCR, offsetof(struct kvm, arch.lpcr)); | ||
441 | DEFINE(KVM_RMOR, offsetof(struct kvm, arch.rmor)); | ||
440 | DEFINE(VCPU_DSISR, offsetof(struct kvm_vcpu, arch.shregs.dsisr)); | 442 | DEFINE(VCPU_DSISR, offsetof(struct kvm_vcpu, arch.shregs.dsisr)); |
441 | DEFINE(VCPU_DAR, offsetof(struct kvm_vcpu, arch.shregs.dar)); | 443 | DEFINE(VCPU_DAR, offsetof(struct kvm_vcpu, arch.shregs.dar)); |
442 | #endif | 444 | #endif |
@@ -459,7 +461,7 @@ int main(void) | |||
459 | DEFINE(VCPU_HFLAGS, offsetof(struct kvm_vcpu, arch.hflags)); | 461 | DEFINE(VCPU_HFLAGS, offsetof(struct kvm_vcpu, arch.hflags)); |
460 | DEFINE(VCPU_DEC, offsetof(struct kvm_vcpu, arch.dec)); | 462 | DEFINE(VCPU_DEC, offsetof(struct kvm_vcpu, arch.dec)); |
461 | DEFINE(VCPU_DEC_EXPIRES, offsetof(struct kvm_vcpu, arch.dec_expires)); | 463 | DEFINE(VCPU_DEC_EXPIRES, offsetof(struct kvm_vcpu, arch.dec_expires)); |
462 | DEFINE(VCPU_LPCR, offsetof(struct kvm_vcpu, arch.lpcr)); | 464 | DEFINE(VCPU_PENDING_EXC, offsetof(struct kvm_vcpu, arch.pending_exceptions)); |
463 | DEFINE(VCPU_VPA, offsetof(struct kvm_vcpu, arch.vpa)); | 465 | DEFINE(VCPU_VPA, offsetof(struct kvm_vcpu, arch.vpa)); |
464 | DEFINE(VCPU_MMCR, offsetof(struct kvm_vcpu, arch.mmcr)); | 466 | DEFINE(VCPU_MMCR, offsetof(struct kvm_vcpu, arch.mmcr)); |
465 | DEFINE(VCPU_PMC, offsetof(struct kvm_vcpu, arch.pmc)); | 467 | DEFINE(VCPU_PMC, offsetof(struct kvm_vcpu, arch.pmc)); |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index a88bf2713d41..532054f24ecb 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -63,6 +63,7 @@ | |||
63 | #include <asm/kexec.h> | 63 | #include <asm/kexec.h> |
64 | #include <asm/mmu_context.h> | 64 | #include <asm/mmu_context.h> |
65 | #include <asm/code-patching.h> | 65 | #include <asm/code-patching.h> |
66 | #include <asm/kvm_ppc.h> | ||
66 | 67 | ||
67 | #include "setup.h" | 68 | #include "setup.h" |
68 | 69 | ||
@@ -580,6 +581,8 @@ void __init setup_arch(char **cmdline_p) | |||
580 | /* Initialize the MMU context management stuff */ | 581 | /* Initialize the MMU context management stuff */ |
581 | mmu_context_init(); | 582 | mmu_context_init(); |
582 | 583 | ||
584 | kvm_rma_init(); | ||
585 | |||
583 | ppc64_boot_msg(0x15, "Setup Done"); | 586 | ppc64_boot_msg(0x15, "Setup Done"); |
584 | } | 587 | } |
585 | 588 | ||
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 1de3d54901d4..08428e2c188d 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile | |||
@@ -56,7 +56,8 @@ kvm-book3s_64-objs-$(CONFIG_KVM_BOOK3S_64_HV) := \ | |||
56 | book3s_64_mmu_hv.o | 56 | book3s_64_mmu_hv.o |
57 | kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HV) := \ | 57 | kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HV) := \ |
58 | book3s_hv_rm_mmu.o \ | 58 | book3s_hv_rm_mmu.o \ |
59 | book3s_64_vio_hv.o | 59 | book3s_64_vio_hv.o \ |
60 | book3s_hv_builtin.o | ||
60 | 61 | ||
61 | kvm-book3s_64-module-objs := \ | 62 | kvm-book3s_64-module-objs := \ |
62 | ../../../virt/kvm/kvm_main.o \ | 63 | ../../../virt/kvm/kvm_main.o \ |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index 4a4fbec61a17..96ba96a16abf 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
@@ -79,103 +79,8 @@ long kvmppc_alloc_hpt(struct kvm *kvm) | |||
79 | 79 | ||
80 | void kvmppc_free_hpt(struct kvm *kvm) | 80 | void kvmppc_free_hpt(struct kvm *kvm) |
81 | { | 81 | { |
82 | unsigned long i; | ||
83 | struct kvmppc_pginfo *pginfo; | ||
84 | |||
85 | clear_bit(kvm->arch.lpid, lpid_inuse); | 82 | clear_bit(kvm->arch.lpid, lpid_inuse); |
86 | free_pages(kvm->arch.hpt_virt, HPT_ORDER - PAGE_SHIFT); | 83 | free_pages(kvm->arch.hpt_virt, HPT_ORDER - PAGE_SHIFT); |
87 | |||
88 | if (kvm->arch.ram_pginfo) { | ||
89 | pginfo = kvm->arch.ram_pginfo; | ||
90 | kvm->arch.ram_pginfo = NULL; | ||
91 | for (i = 0; i < kvm->arch.ram_npages; ++i) | ||
92 | put_page(pfn_to_page(pginfo[i].pfn)); | ||
93 | kfree(pginfo); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | static unsigned long user_page_size(unsigned long addr) | ||
98 | { | ||
99 | struct vm_area_struct *vma; | ||
100 | unsigned long size = PAGE_SIZE; | ||
101 | |||
102 | down_read(¤t->mm->mmap_sem); | ||
103 | vma = find_vma(current->mm, addr); | ||
104 | if (vma) | ||
105 | size = vma_kernel_pagesize(vma); | ||
106 | up_read(¤t->mm->mmap_sem); | ||
107 | return size; | ||
108 | } | ||
109 | |||
110 | static pfn_t hva_to_pfn(unsigned long addr) | ||
111 | { | ||
112 | struct page *page[1]; | ||
113 | int npages; | ||
114 | |||
115 | might_sleep(); | ||
116 | |||
117 | npages = get_user_pages_fast(addr, 1, 1, page); | ||
118 | |||
119 | if (unlikely(npages != 1)) | ||
120 | return 0; | ||
121 | |||
122 | return page_to_pfn(page[0]); | ||
123 | } | ||
124 | |||
125 | long kvmppc_prepare_vrma(struct kvm *kvm, | ||
126 | struct kvm_userspace_memory_region *mem) | ||
127 | { | ||
128 | unsigned long psize, porder; | ||
129 | unsigned long i, npages; | ||
130 | struct kvmppc_pginfo *pginfo; | ||
131 | pfn_t pfn; | ||
132 | unsigned long hva; | ||
133 | |||
134 | /* First see what page size we have */ | ||
135 | psize = user_page_size(mem->userspace_addr); | ||
136 | /* For now, only allow 16MB pages */ | ||
137 | if (psize != 1ul << VRMA_PAGE_ORDER || (mem->memory_size & (psize - 1))) { | ||
138 | pr_err("bad psize=%lx memory_size=%llx @ %llx\n", | ||
139 | psize, mem->memory_size, mem->userspace_addr); | ||
140 | return -EINVAL; | ||
141 | } | ||
142 | porder = __ilog2(psize); | ||
143 | |||
144 | npages = mem->memory_size >> porder; | ||
145 | pginfo = kzalloc(npages * sizeof(struct kvmppc_pginfo), GFP_KERNEL); | ||
146 | if (!pginfo) { | ||
147 | pr_err("kvmppc_prepare_vrma: couldn't alloc %lu bytes\n", | ||
148 | npages * sizeof(struct kvmppc_pginfo)); | ||
149 | return -ENOMEM; | ||
150 | } | ||
151 | |||
152 | for (i = 0; i < npages; ++i) { | ||
153 | hva = mem->userspace_addr + (i << porder); | ||
154 | if (user_page_size(hva) != psize) | ||
155 | goto err; | ||
156 | pfn = hva_to_pfn(hva); | ||
157 | if (pfn == 0) { | ||
158 | pr_err("oops, no pfn for hva %lx\n", hva); | ||
159 | goto err; | ||
160 | } | ||
161 | if (pfn & ((1ul << (porder - PAGE_SHIFT)) - 1)) { | ||
162 | pr_err("oops, unaligned pfn %llx\n", pfn); | ||
163 | put_page(pfn_to_page(pfn)); | ||
164 | goto err; | ||
165 | } | ||
166 | pginfo[i].pfn = pfn; | ||
167 | } | ||
168 | |||
169 | kvm->arch.ram_npages = npages; | ||
170 | kvm->arch.ram_psize = psize; | ||
171 | kvm->arch.ram_porder = porder; | ||
172 | kvm->arch.ram_pginfo = pginfo; | ||
173 | |||
174 | return 0; | ||
175 | |||
176 | err: | ||
177 | kfree(pginfo); | ||
178 | return -EINVAL; | ||
179 | } | 84 | } |
180 | 85 | ||
181 | void kvmppc_map_vrma(struct kvm *kvm, struct kvm_userspace_memory_region *mem) | 86 | void kvmppc_map_vrma(struct kvm *kvm, struct kvm_userspace_memory_region *mem) |
@@ -199,6 +104,8 @@ void kvmppc_map_vrma(struct kvm *kvm, struct kvm_userspace_memory_region *mem) | |||
199 | 104 | ||
200 | for (i = 0; i < npages; ++i) { | 105 | for (i = 0; i < npages; ++i) { |
201 | pfn = pginfo[i].pfn; | 106 | pfn = pginfo[i].pfn; |
107 | if (!pfn) | ||
108 | break; | ||
202 | /* can't use hpt_hash since va > 64 bits */ | 109 | /* can't use hpt_hash since va > 64 bits */ |
203 | hash = (i ^ (VRMA_VSID ^ (VRMA_VSID << 25))) & HPT_HASH_MASK; | 110 | hash = (i ^ (VRMA_VSID ^ (VRMA_VSID << 25))) & HPT_HASH_MASK; |
204 | /* | 111 | /* |
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 36b6d98f1197..04da135cae61 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
28 | #include <linux/anon_inodes.h> | 28 | #include <linux/anon_inodes.h> |
29 | #include <linux/cpumask.h> | 29 | #include <linux/cpumask.h> |
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/page-flags.h> | ||
30 | 32 | ||
31 | #include <asm/reg.h> | 33 | #include <asm/reg.h> |
32 | #include <asm/cputable.h> | 34 | #include <asm/cputable.h> |
@@ -40,11 +42,22 @@ | |||
40 | #include <asm/lppaca.h> | 42 | #include <asm/lppaca.h> |
41 | #include <asm/processor.h> | 43 | #include <asm/processor.h> |
42 | #include <asm/cputhreads.h> | 44 | #include <asm/cputhreads.h> |
45 | #include <asm/page.h> | ||
43 | #include <linux/gfp.h> | 46 | #include <linux/gfp.h> |
44 | #include <linux/sched.h> | 47 | #include <linux/sched.h> |
45 | #include <linux/vmalloc.h> | 48 | #include <linux/vmalloc.h> |
46 | #include <linux/highmem.h> | 49 | #include <linux/highmem.h> |
47 | 50 | ||
51 | /* | ||
52 | * For now, limit memory to 64GB and require it to be large pages. | ||
53 | * This value is chosen because it makes the ram_pginfo array be | ||
54 | * 64kB in size, which is about as large as we want to be trying | ||
55 | * to allocate with kmalloc. | ||
56 | */ | ||
57 | #define MAX_MEM_ORDER 36 | ||
58 | |||
59 | #define LARGE_PAGE_ORDER 24 /* 16MB pages */ | ||
60 | |||
48 | /* #define EXIT_DEBUG */ | 61 | /* #define EXIT_DEBUG */ |
49 | /* #define EXIT_DEBUG_SIMPLE */ | 62 | /* #define EXIT_DEBUG_SIMPLE */ |
50 | /* #define EXIT_DEBUG_INT */ | 63 | /* #define EXIT_DEBUG_INT */ |
@@ -129,7 +142,7 @@ void kvmppc_dump_regs(struct kvm_vcpu *vcpu) | |||
129 | pr_err(" ESID = %.16llx VSID = %.16llx\n", | 142 | pr_err(" ESID = %.16llx VSID = %.16llx\n", |
130 | vcpu->arch.slb[r].orige, vcpu->arch.slb[r].origv); | 143 | vcpu->arch.slb[r].orige, vcpu->arch.slb[r].origv); |
131 | pr_err("lpcr = %.16lx sdr1 = %.16lx last_inst = %.8x\n", | 144 | pr_err("lpcr = %.16lx sdr1 = %.16lx last_inst = %.8x\n", |
132 | vcpu->arch.lpcr, vcpu->kvm->arch.sdr1, | 145 | vcpu->kvm->arch.lpcr, vcpu->kvm->arch.sdr1, |
133 | vcpu->arch.last_inst); | 146 | vcpu->arch.last_inst); |
134 | } | 147 | } |
135 | 148 | ||
@@ -441,7 +454,6 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) | |||
441 | int err = -EINVAL; | 454 | int err = -EINVAL; |
442 | int core; | 455 | int core; |
443 | struct kvmppc_vcore *vcore; | 456 | struct kvmppc_vcore *vcore; |
444 | unsigned long lpcr; | ||
445 | 457 | ||
446 | core = id / threads_per_core; | 458 | core = id / threads_per_core; |
447 | if (core >= KVM_MAX_VCORES) | 459 | if (core >= KVM_MAX_VCORES) |
@@ -464,10 +476,6 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) | |||
464 | vcpu->arch.pvr = mfspr(SPRN_PVR); | 476 | vcpu->arch.pvr = mfspr(SPRN_PVR); |
465 | kvmppc_set_pvr(vcpu, vcpu->arch.pvr); | 477 | kvmppc_set_pvr(vcpu, vcpu->arch.pvr); |
466 | 478 | ||
467 | lpcr = kvm->arch.host_lpcr & (LPCR_PECE | LPCR_LPES); | ||
468 | lpcr |= LPCR_VPM0 | LPCR_VRMA_L | (4UL << LPCR_DPFD_SH) | LPCR_HDICE; | ||
469 | vcpu->arch.lpcr = lpcr; | ||
470 | |||
471 | kvmppc_mmu_book3s_hv_init(vcpu); | 479 | kvmppc_mmu_book3s_hv_init(vcpu); |
472 | 480 | ||
473 | /* | 481 | /* |
@@ -910,24 +918,216 @@ fail: | |||
910 | return ret; | 918 | return ret; |
911 | } | 919 | } |
912 | 920 | ||
921 | /* Work out RMLS (real mode limit selector) field value for a given RMA size. | ||
922 | Assumes POWER7. */ | ||
923 | static inline int lpcr_rmls(unsigned long rma_size) | ||
924 | { | ||
925 | switch (rma_size) { | ||
926 | case 32ul << 20: /* 32 MB */ | ||
927 | return 8; | ||
928 | case 64ul << 20: /* 64 MB */ | ||
929 | return 3; | ||
930 | case 128ul << 20: /* 128 MB */ | ||
931 | return 7; | ||
932 | case 256ul << 20: /* 256 MB */ | ||
933 | return 4; | ||
934 | case 1ul << 30: /* 1 GB */ | ||
935 | return 2; | ||
936 | case 16ul << 30: /* 16 GB */ | ||
937 | return 1; | ||
938 | case 256ul << 30: /* 256 GB */ | ||
939 | return 0; | ||
940 | default: | ||
941 | return -1; | ||
942 | } | ||
943 | } | ||
944 | |||
945 | static int kvm_rma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | ||
946 | { | ||
947 | struct kvmppc_rma_info *ri = vma->vm_file->private_data; | ||
948 | struct page *page; | ||
949 | |||
950 | if (vmf->pgoff >= ri->npages) | ||
951 | return VM_FAULT_SIGBUS; | ||
952 | |||
953 | page = pfn_to_page(ri->base_pfn + vmf->pgoff); | ||
954 | get_page(page); | ||
955 | vmf->page = page; | ||
956 | return 0; | ||
957 | } | ||
958 | |||
959 | static const struct vm_operations_struct kvm_rma_vm_ops = { | ||
960 | .fault = kvm_rma_fault, | ||
961 | }; | ||
962 | |||
963 | static int kvm_rma_mmap(struct file *file, struct vm_area_struct *vma) | ||
964 | { | ||
965 | vma->vm_flags |= VM_RESERVED; | ||
966 | vma->vm_ops = &kvm_rma_vm_ops; | ||
967 | return 0; | ||
968 | } | ||
969 | |||
970 | static int kvm_rma_release(struct inode *inode, struct file *filp) | ||
971 | { | ||
972 | struct kvmppc_rma_info *ri = filp->private_data; | ||
973 | |||
974 | kvm_release_rma(ri); | ||
975 | return 0; | ||
976 | } | ||
977 | |||
978 | static struct file_operations kvm_rma_fops = { | ||
979 | .mmap = kvm_rma_mmap, | ||
980 | .release = kvm_rma_release, | ||
981 | }; | ||
982 | |||
983 | long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *ret) | ||
984 | { | ||
985 | struct kvmppc_rma_info *ri; | ||
986 | long fd; | ||
987 | |||
988 | ri = kvm_alloc_rma(); | ||
989 | if (!ri) | ||
990 | return -ENOMEM; | ||
991 | |||
992 | fd = anon_inode_getfd("kvm-rma", &kvm_rma_fops, ri, O_RDWR); | ||
993 | if (fd < 0) | ||
994 | kvm_release_rma(ri); | ||
995 | |||
996 | ret->rma_size = ri->npages << PAGE_SHIFT; | ||
997 | return fd; | ||
998 | } | ||
999 | |||
1000 | static struct page *hva_to_page(unsigned long addr) | ||
1001 | { | ||
1002 | struct page *page[1]; | ||
1003 | int npages; | ||
1004 | |||
1005 | might_sleep(); | ||
1006 | |||
1007 | npages = get_user_pages_fast(addr, 1, 1, page); | ||
1008 | |||
1009 | if (unlikely(npages != 1)) | ||
1010 | return 0; | ||
1011 | |||
1012 | return page[0]; | ||
1013 | } | ||
1014 | |||
913 | int kvmppc_core_prepare_memory_region(struct kvm *kvm, | 1015 | int kvmppc_core_prepare_memory_region(struct kvm *kvm, |
914 | struct kvm_userspace_memory_region *mem) | 1016 | struct kvm_userspace_memory_region *mem) |
915 | { | 1017 | { |
916 | if (mem->guest_phys_addr == 0 && mem->memory_size != 0) | 1018 | unsigned long psize, porder; |
917 | return kvmppc_prepare_vrma(kvm, mem); | 1019 | unsigned long i, npages, totalpages; |
1020 | unsigned long pg_ix; | ||
1021 | struct kvmppc_pginfo *pginfo; | ||
1022 | unsigned long hva; | ||
1023 | struct kvmppc_rma_info *ri = NULL; | ||
1024 | struct page *page; | ||
1025 | |||
1026 | /* For now, only allow 16MB pages */ | ||
1027 | porder = LARGE_PAGE_ORDER; | ||
1028 | psize = 1ul << porder; | ||
1029 | if ((mem->memory_size & (psize - 1)) || | ||
1030 | (mem->guest_phys_addr & (psize - 1))) { | ||
1031 | pr_err("bad memory_size=%llx @ %llx\n", | ||
1032 | mem->memory_size, mem->guest_phys_addr); | ||
1033 | return -EINVAL; | ||
1034 | } | ||
1035 | |||
1036 | npages = mem->memory_size >> porder; | ||
1037 | totalpages = (mem->guest_phys_addr + mem->memory_size) >> porder; | ||
1038 | |||
1039 | /* More memory than we have space to track? */ | ||
1040 | if (totalpages > (1ul << (MAX_MEM_ORDER - LARGE_PAGE_ORDER))) | ||
1041 | return -EINVAL; | ||
1042 | |||
1043 | /* Do we already have an RMA registered? */ | ||
1044 | if (mem->guest_phys_addr == 0 && kvm->arch.rma) | ||
1045 | return -EINVAL; | ||
1046 | |||
1047 | if (totalpages > kvm->arch.ram_npages) | ||
1048 | kvm->arch.ram_npages = totalpages; | ||
1049 | |||
1050 | /* Is this one of our preallocated RMAs? */ | ||
1051 | if (mem->guest_phys_addr == 0) { | ||
1052 | struct vm_area_struct *vma; | ||
1053 | |||
1054 | down_read(¤t->mm->mmap_sem); | ||
1055 | vma = find_vma(current->mm, mem->userspace_addr); | ||
1056 | if (vma && vma->vm_file && | ||
1057 | vma->vm_file->f_op == &kvm_rma_fops && | ||
1058 | mem->userspace_addr == vma->vm_start) | ||
1059 | ri = vma->vm_file->private_data; | ||
1060 | up_read(¤t->mm->mmap_sem); | ||
1061 | } | ||
1062 | |||
1063 | if (ri) { | ||
1064 | unsigned long rma_size; | ||
1065 | unsigned long lpcr; | ||
1066 | long rmls; | ||
1067 | |||
1068 | rma_size = ri->npages << PAGE_SHIFT; | ||
1069 | if (rma_size > mem->memory_size) | ||
1070 | rma_size = mem->memory_size; | ||
1071 | rmls = lpcr_rmls(rma_size); | ||
1072 | if (rmls < 0) { | ||
1073 | pr_err("Can't use RMA of 0x%lx bytes\n", rma_size); | ||
1074 | return -EINVAL; | ||
1075 | } | ||
1076 | atomic_inc(&ri->use_count); | ||
1077 | kvm->arch.rma = ri; | ||
1078 | kvm->arch.n_rma_pages = rma_size >> porder; | ||
1079 | lpcr = kvm->arch.lpcr & ~(LPCR_VPM0 | LPCR_VRMA_L); | ||
1080 | lpcr |= rmls << LPCR_RMLS_SH; | ||
1081 | kvm->arch.lpcr = lpcr; | ||
1082 | kvm->arch.rmor = kvm->arch.rma->base_pfn << PAGE_SHIFT; | ||
1083 | pr_info("Using RMO at %lx size %lx (LPCR = %lx)\n", | ||
1084 | ri->base_pfn << PAGE_SHIFT, rma_size, lpcr); | ||
1085 | } | ||
1086 | |||
1087 | pg_ix = mem->guest_phys_addr >> porder; | ||
1088 | pginfo = kvm->arch.ram_pginfo + pg_ix; | ||
1089 | for (i = 0; i < npages; ++i, ++pg_ix) { | ||
1090 | if (ri && pg_ix < kvm->arch.n_rma_pages) { | ||
1091 | pginfo[i].pfn = ri->base_pfn + | ||
1092 | (pg_ix << (porder - PAGE_SHIFT)); | ||
1093 | continue; | ||
1094 | } | ||
1095 | hva = mem->userspace_addr + (i << porder); | ||
1096 | page = hva_to_page(hva); | ||
1097 | if (!page) { | ||
1098 | pr_err("oops, no pfn for hva %lx\n", hva); | ||
1099 | goto err; | ||
1100 | } | ||
1101 | /* Check it's a 16MB page */ | ||
1102 | if (!PageHead(page) || | ||
1103 | compound_order(page) != (LARGE_PAGE_ORDER - PAGE_SHIFT)) { | ||
1104 | pr_err("page at %lx isn't 16MB (o=%d)\n", | ||
1105 | hva, compound_order(page)); | ||
1106 | goto err; | ||
1107 | } | ||
1108 | pginfo[i].pfn = page_to_pfn(page); | ||
1109 | } | ||
1110 | |||
918 | return 0; | 1111 | return 0; |
1112 | |||
1113 | err: | ||
1114 | return -EINVAL; | ||
919 | } | 1115 | } |
920 | 1116 | ||
921 | void kvmppc_core_commit_memory_region(struct kvm *kvm, | 1117 | void kvmppc_core_commit_memory_region(struct kvm *kvm, |
922 | struct kvm_userspace_memory_region *mem) | 1118 | struct kvm_userspace_memory_region *mem) |
923 | { | 1119 | { |
924 | if (mem->guest_phys_addr == 0 && mem->memory_size != 0) | 1120 | if (mem->guest_phys_addr == 0 && mem->memory_size != 0 && |
1121 | !kvm->arch.rma) | ||
925 | kvmppc_map_vrma(kvm, mem); | 1122 | kvmppc_map_vrma(kvm, mem); |
926 | } | 1123 | } |
927 | 1124 | ||
928 | int kvmppc_core_init_vm(struct kvm *kvm) | 1125 | int kvmppc_core_init_vm(struct kvm *kvm) |
929 | { | 1126 | { |
930 | long r; | 1127 | long r; |
1128 | unsigned long npages = 1ul << (MAX_MEM_ORDER - LARGE_PAGE_ORDER); | ||
1129 | long err = -ENOMEM; | ||
1130 | unsigned long lpcr; | ||
931 | 1131 | ||
932 | /* Allocate hashed page table */ | 1132 | /* Allocate hashed page table */ |
933 | r = kvmppc_alloc_hpt(kvm); | 1133 | r = kvmppc_alloc_hpt(kvm); |
@@ -935,11 +1135,52 @@ int kvmppc_core_init_vm(struct kvm *kvm) | |||
935 | return r; | 1135 | return r; |
936 | 1136 | ||
937 | INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); | 1137 | INIT_LIST_HEAD(&kvm->arch.spapr_tce_tables); |
1138 | |||
1139 | kvm->arch.ram_pginfo = kzalloc(npages * sizeof(struct kvmppc_pginfo), | ||
1140 | GFP_KERNEL); | ||
1141 | if (!kvm->arch.ram_pginfo) { | ||
1142 | pr_err("kvmppc_core_init_vm: couldn't alloc %lu bytes\n", | ||
1143 | npages * sizeof(struct kvmppc_pginfo)); | ||
1144 | goto out_free; | ||
1145 | } | ||
1146 | |||
1147 | kvm->arch.ram_npages = 0; | ||
1148 | kvm->arch.ram_psize = 1ul << LARGE_PAGE_ORDER; | ||
1149 | kvm->arch.ram_porder = LARGE_PAGE_ORDER; | ||
1150 | kvm->arch.rma = NULL; | ||
1151 | kvm->arch.n_rma_pages = 0; | ||
1152 | |||
1153 | lpcr = kvm->arch.host_lpcr & (LPCR_PECE | LPCR_LPES); | ||
1154 | lpcr |= (4UL << LPCR_DPFD_SH) | LPCR_HDICE | | ||
1155 | LPCR_VPM0 | LPCR_VRMA_L; | ||
1156 | kvm->arch.lpcr = lpcr; | ||
1157 | |||
1158 | |||
938 | return 0; | 1159 | return 0; |
1160 | |||
1161 | out_free: | ||
1162 | kvmppc_free_hpt(kvm); | ||
1163 | return err; | ||
939 | } | 1164 | } |
940 | 1165 | ||
941 | void kvmppc_core_destroy_vm(struct kvm *kvm) | 1166 | void kvmppc_core_destroy_vm(struct kvm *kvm) |
942 | { | 1167 | { |
1168 | struct kvmppc_pginfo *pginfo; | ||
1169 | unsigned long i; | ||
1170 | |||
1171 | if (kvm->arch.ram_pginfo) { | ||
1172 | pginfo = kvm->arch.ram_pginfo; | ||
1173 | kvm->arch.ram_pginfo = NULL; | ||
1174 | for (i = kvm->arch.n_rma_pages; i < kvm->arch.ram_npages; ++i) | ||
1175 | if (pginfo[i].pfn) | ||
1176 | put_page(pfn_to_page(pginfo[i].pfn)); | ||
1177 | kfree(pginfo); | ||
1178 | } | ||
1179 | if (kvm->arch.rma) { | ||
1180 | kvm_release_rma(kvm->arch.rma); | ||
1181 | kvm->arch.rma = NULL; | ||
1182 | } | ||
1183 | |||
943 | kvmppc_free_hpt(kvm); | 1184 | kvmppc_free_hpt(kvm); |
944 | WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables)); | 1185 | WARN_ON(!list_empty(&kvm->arch.spapr_tce_tables)); |
945 | } | 1186 | } |
diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c new file mode 100644 index 000000000000..736df3cbbc55 --- /dev/null +++ b/arch/powerpc/kvm/book3s_hv_builtin.c | |||
@@ -0,0 +1,152 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com> | ||
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 | |||
9 | #include <linux/kvm_host.h> | ||
10 | #include <linux/preempt.h> | ||
11 | #include <linux/sched.h> | ||
12 | #include <linux/spinlock.h> | ||
13 | #include <linux/bootmem.h> | ||
14 | #include <linux/init.h> | ||
15 | |||
16 | #include <asm/cputable.h> | ||
17 | #include <asm/kvm_ppc.h> | ||
18 | #include <asm/kvm_book3s.h> | ||
19 | |||
20 | /* | ||
21 | * This maintains a list of RMAs (real mode areas) for KVM guests to use. | ||
22 | * Each RMA has to be physically contiguous and of a size that the | ||
23 | * hardware supports. PPC970 and POWER7 support 64MB, 128MB and 256MB, | ||
24 | * and other larger sizes. Since we are unlikely to be allocate that | ||
25 | * much physically contiguous memory after the system is up and running, | ||
26 | * we preallocate a set of RMAs in early boot for KVM to use. | ||
27 | */ | ||
28 | static unsigned long kvm_rma_size = 64 << 20; /* 64MB */ | ||
29 | static unsigned long kvm_rma_count; | ||
30 | |||
31 | static int __init early_parse_rma_size(char *p) | ||
32 | { | ||
33 | if (!p) | ||
34 | return 1; | ||
35 | |||
36 | kvm_rma_size = memparse(p, &p); | ||
37 | |||
38 | return 0; | ||
39 | } | ||
40 | early_param("kvm_rma_size", early_parse_rma_size); | ||
41 | |||
42 | static int __init early_parse_rma_count(char *p) | ||
43 | { | ||
44 | if (!p) | ||
45 | return 1; | ||
46 | |||
47 | kvm_rma_count = simple_strtoul(p, NULL, 0); | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | early_param("kvm_rma_count", early_parse_rma_count); | ||
52 | |||
53 | static struct kvmppc_rma_info *rma_info; | ||
54 | static LIST_HEAD(free_rmas); | ||
55 | static DEFINE_SPINLOCK(rma_lock); | ||
56 | |||
57 | /* Work out RMLS (real mode limit selector) field value for a given RMA size. | ||
58 | Assumes POWER7. */ | ||
59 | static inline int lpcr_rmls(unsigned long rma_size) | ||
60 | { | ||
61 | switch (rma_size) { | ||
62 | case 32ul << 20: /* 32 MB */ | ||
63 | return 8; | ||
64 | case 64ul << 20: /* 64 MB */ | ||
65 | return 3; | ||
66 | case 128ul << 20: /* 128 MB */ | ||
67 | return 7; | ||
68 | case 256ul << 20: /* 256 MB */ | ||
69 | return 4; | ||
70 | case 1ul << 30: /* 1 GB */ | ||
71 | return 2; | ||
72 | case 16ul << 30: /* 16 GB */ | ||
73 | return 1; | ||
74 | case 256ul << 30: /* 256 GB */ | ||
75 | return 0; | ||
76 | default: | ||
77 | return -1; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * Called at boot time while the bootmem allocator is active, | ||
83 | * to allocate contiguous physical memory for the real memory | ||
84 | * areas for guests. | ||
85 | */ | ||
86 | void kvm_rma_init(void) | ||
87 | { | ||
88 | unsigned long i; | ||
89 | unsigned long j, npages; | ||
90 | void *rma; | ||
91 | struct page *pg; | ||
92 | |||
93 | /* Only do this on POWER7 in HV mode */ | ||
94 | if (!cpu_has_feature(CPU_FTR_HVMODE_206)) | ||
95 | return; | ||
96 | |||
97 | if (!kvm_rma_size || !kvm_rma_count) | ||
98 | return; | ||
99 | |||
100 | /* Check that the requested size is one supported in hardware */ | ||
101 | if (lpcr_rmls(kvm_rma_size) < 0) { | ||
102 | pr_err("RMA size of 0x%lx not supported\n", kvm_rma_size); | ||
103 | return; | ||
104 | } | ||
105 | |||
106 | npages = kvm_rma_size >> PAGE_SHIFT; | ||
107 | rma_info = alloc_bootmem(kvm_rma_count * sizeof(struct kvmppc_rma_info)); | ||
108 | for (i = 0; i < kvm_rma_count; ++i) { | ||
109 | rma = alloc_bootmem_align(kvm_rma_size, kvm_rma_size); | ||
110 | pr_info("Allocated KVM RMA at %p (%ld MB)\n", rma, | ||
111 | kvm_rma_size >> 20); | ||
112 | rma_info[i].base_virt = rma; | ||
113 | rma_info[i].base_pfn = __pa(rma) >> PAGE_SHIFT; | ||
114 | rma_info[i].npages = npages; | ||
115 | list_add_tail(&rma_info[i].list, &free_rmas); | ||
116 | atomic_set(&rma_info[i].use_count, 0); | ||
117 | |||
118 | pg = pfn_to_page(rma_info[i].base_pfn); | ||
119 | for (j = 0; j < npages; ++j) { | ||
120 | atomic_inc(&pg->_count); | ||
121 | ++pg; | ||
122 | } | ||
123 | } | ||
124 | } | ||
125 | |||
126 | struct kvmppc_rma_info *kvm_alloc_rma(void) | ||
127 | { | ||
128 | struct kvmppc_rma_info *ri; | ||
129 | |||
130 | ri = NULL; | ||
131 | spin_lock(&rma_lock); | ||
132 | if (!list_empty(&free_rmas)) { | ||
133 | ri = list_first_entry(&free_rmas, struct kvmppc_rma_info, list); | ||
134 | list_del(&ri->list); | ||
135 | atomic_inc(&ri->use_count); | ||
136 | } | ||
137 | spin_unlock(&rma_lock); | ||
138 | return ri; | ||
139 | } | ||
140 | EXPORT_SYMBOL_GPL(kvm_alloc_rma); | ||
141 | |||
142 | void kvm_release_rma(struct kvmppc_rma_info *ri) | ||
143 | { | ||
144 | if (atomic_dec_and_test(&ri->use_count)) { | ||
145 | spin_lock(&rma_lock); | ||
146 | list_add_tail(&ri->list, &free_rmas); | ||
147 | spin_unlock(&rma_lock); | ||
148 | |||
149 | } | ||
150 | } | ||
151 | EXPORT_SYMBOL_GPL(kvm_release_rma); | ||
152 | |||
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index c9bf177b7cf2..9ee223c35285 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S | |||
@@ -235,10 +235,10 @@ kvmppc_hv_entry: | |||
235 | bne 21b | 235 | bne 21b |
236 | 236 | ||
237 | /* Primary thread switches to guest partition. */ | 237 | /* Primary thread switches to guest partition. */ |
238 | ld r9,VCPU_KVM(r4) /* pointer to struct kvm */ | ||
238 | lwz r6,VCPU_PTID(r4) | 239 | lwz r6,VCPU_PTID(r4) |
239 | cmpwi r6,0 | 240 | cmpwi r6,0 |
240 | bne 20f | 241 | bne 20f |
241 | ld r9,VCPU_KVM(r4) /* pointer to struct kvm */ | ||
242 | ld r6,KVM_SDR1(r9) | 242 | ld r6,KVM_SDR1(r9) |
243 | lwz r7,KVM_LPID(r9) | 243 | lwz r7,KVM_LPID(r9) |
244 | li r0,LPID_RSVD /* switch to reserved LPID */ | 244 | li r0,LPID_RSVD /* switch to reserved LPID */ |
@@ -255,8 +255,18 @@ kvmppc_hv_entry: | |||
255 | 20: lbz r0,VCORE_IN_GUEST(r5) | 255 | 20: lbz r0,VCORE_IN_GUEST(r5) |
256 | cmpwi r0,0 | 256 | cmpwi r0,0 |
257 | beq 20b | 257 | beq 20b |
258 | 10: ld r8,VCPU_LPCR(r4) | 258 | |
259 | mtspr SPRN_LPCR,r8 | 259 | /* Set LPCR. Set the MER bit if there is a pending external irq. */ |
260 | 10: ld r8,KVM_LPCR(r9) | ||
261 | ld r0,VCPU_PENDING_EXC(r4) | ||
262 | li r7,(1 << BOOK3S_IRQPRIO_EXTERNAL) | ||
263 | oris r7,r7,(1 << BOOK3S_IRQPRIO_EXTERNAL_LEVEL)@h | ||
264 | and. r0,r0,r7 | ||
265 | beq 11f | ||
266 | ori r8,r8,LPCR_MER | ||
267 | 11: mtspr SPRN_LPCR,r8 | ||
268 | ld r8,KVM_RMOR(r9) | ||
269 | mtspr SPRN_RMOR,r8 | ||
260 | isync | 270 | isync |
261 | 271 | ||
262 | /* Check if HDEC expires soon */ | 272 | /* Check if HDEC expires soon */ |
@@ -464,7 +474,8 @@ hcall_real_cont: | |||
464 | /* Check for mediated interrupts (could be done earlier really ...) */ | 474 | /* Check for mediated interrupts (could be done earlier really ...) */ |
465 | cmpwi r12,BOOK3S_INTERRUPT_EXTERNAL | 475 | cmpwi r12,BOOK3S_INTERRUPT_EXTERNAL |
466 | bne+ 1f | 476 | bne+ 1f |
467 | ld r5,VCPU_LPCR(r9) | 477 | ld r5,VCPU_KVM(r9) |
478 | ld r5,KVM_LPCR(r5) | ||
468 | andi. r0,r11,MSR_EE | 479 | andi. r0,r11,MSR_EE |
469 | beq 1f | 480 | beq 1f |
470 | andi. r0,r5,LPCR_MER | 481 | andi. r0,r5,LPCR_MER |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 4c549664c987..72c506505fa4 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -211,6 +211,9 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
211 | case KVM_CAP_PPC_SMT: | 211 | case KVM_CAP_PPC_SMT: |
212 | r = threads_per_core; | 212 | r = threads_per_core; |
213 | break; | 213 | break; |
214 | case KVM_CAP_PPC_RMA: | ||
215 | r = 1; | ||
216 | break; | ||
214 | #endif | 217 | #endif |
215 | default: | 218 | default: |
216 | r = 0; | 219 | r = 0; |
@@ -673,6 +676,16 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
673 | r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce); | 676 | r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce); |
674 | goto out; | 677 | goto out; |
675 | } | 678 | } |
679 | |||
680 | case KVM_ALLOCATE_RMA: { | ||
681 | struct kvm *kvm = filp->private_data; | ||
682 | struct kvm_allocate_rma rma; | ||
683 | |||
684 | r = kvm_vm_ioctl_allocate_rma(kvm, &rma); | ||
685 | if (r >= 0 && copy_to_user(argp, &rma, sizeof(rma))) | ||
686 | r = -EFAULT; | ||
687 | break; | ||
688 | } | ||
676 | #endif /* CONFIG_KVM_BOOK3S_64_HV */ | 689 | #endif /* CONFIG_KVM_BOOK3S_64_HV */ |
677 | 690 | ||
678 | default: | 691 | default: |
diff --git a/include/linux/kvm.h b/include/linux/kvm.h index e2a378d97160..2c366b52f505 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h | |||
@@ -552,6 +552,7 @@ struct kvm_ppc_pvinfo { | |||
552 | #define KVM_CAP_PPC_BOOKE_SREGS 62 | 552 | #define KVM_CAP_PPC_BOOKE_SREGS 62 |
553 | #define KVM_CAP_SPAPR_TCE 63 | 553 | #define KVM_CAP_SPAPR_TCE 63 |
554 | #define KVM_CAP_PPC_SMT 64 | 554 | #define KVM_CAP_PPC_SMT 64 |
555 | #define KVM_CAP_PPC_RMA 65 | ||
555 | 556 | ||
556 | #ifdef KVM_CAP_IRQ_ROUTING | 557 | #ifdef KVM_CAP_IRQ_ROUTING |
557 | 558 | ||
@@ -755,6 +756,8 @@ struct kvm_clock_data { | |||
755 | #define KVM_GET_XCRS _IOR(KVMIO, 0xa6, struct kvm_xcrs) | 756 | #define KVM_GET_XCRS _IOR(KVMIO, 0xa6, struct kvm_xcrs) |
756 | #define KVM_SET_XCRS _IOW(KVMIO, 0xa7, struct kvm_xcrs) | 757 | #define KVM_SET_XCRS _IOW(KVMIO, 0xa7, struct kvm_xcrs) |
757 | #define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce) | 758 | #define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce) |
759 | /* Available with KVM_CAP_RMA */ | ||
760 | #define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma) | ||
758 | 761 | ||
759 | #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) | 762 | #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) |
760 | 763 | ||