diff options
Diffstat (limited to 'arch/powerpc')
35 files changed, 665 insertions, 176 deletions
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 8a2ce14d68d0..854199c9ab7e 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -228,10 +228,6 @@ KBUILD_CFLAGS += $(call cc-option,-mno-vsx) | |||
228 | KBUILD_CFLAGS += $(call cc-option,-mno-spe) | 228 | KBUILD_CFLAGS += $(call cc-option,-mno-spe) |
229 | KBUILD_CFLAGS += $(call cc-option,-mspe=no) | 229 | KBUILD_CFLAGS += $(call cc-option,-mspe=no) |
230 | 230 | ||
231 | # Enable unit-at-a-time mode when possible. It shrinks the | ||
232 | # kernel considerably. | ||
233 | KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time) | ||
234 | |||
235 | # FIXME: the module load should be taught about the additional relocs | 231 | # FIXME: the module load should be taught about the additional relocs |
236 | # generated by this. | 232 | # generated by this. |
237 | # revert to pre-gcc-4.4 behaviour of .eh_frame | 233 | # revert to pre-gcc-4.4 behaviour of .eh_frame |
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 39354365f54a..ed9883169190 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile | |||
@@ -197,7 +197,7 @@ $(obj)/empty.c: | |||
197 | $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S | 197 | $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S |
198 | $(Q)cp $< $@ | 198 | $(Q)cp $< $@ |
199 | 199 | ||
200 | $(obj)/serial.c: $(obj)/autoconf.h | 200 | $(srctree)/$(src)/serial.c: $(obj)/autoconf.h |
201 | 201 | ||
202 | $(obj)/autoconf.h: $(obj)/%: $(objtree)/include/generated/% | 202 | $(obj)/autoconf.h: $(obj)/%: $(objtree)/include/generated/% |
203 | $(Q)cp $< $@ | 203 | $(Q)cp $< $@ |
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S index 32dfe6d083f3..9b9d17437373 100644 --- a/arch/powerpc/boot/crt0.S +++ b/arch/powerpc/boot/crt0.S | |||
@@ -15,7 +15,7 @@ | |||
15 | RELA = 7 | 15 | RELA = 7 |
16 | RELACOUNT = 0x6ffffff9 | 16 | RELACOUNT = 0x6ffffff9 |
17 | 17 | ||
18 | .text | 18 | .data |
19 | /* A procedure descriptor used when booting this as a COFF file. | 19 | /* A procedure descriptor used when booting this as a COFF file. |
20 | * When making COFF, this comes first in the link and we're | 20 | * When making COFF, this comes first in the link and we're |
21 | * linked at 0x500000. | 21 | * linked at 0x500000. |
@@ -23,6 +23,8 @@ RELACOUNT = 0x6ffffff9 | |||
23 | .globl _zimage_start_opd | 23 | .globl _zimage_start_opd |
24 | _zimage_start_opd: | 24 | _zimage_start_opd: |
25 | .long 0x500000, 0, 0, 0 | 25 | .long 0x500000, 0, 0, 0 |
26 | .text | ||
27 | b _zimage_start | ||
26 | 28 | ||
27 | #ifdef __powerpc64__ | 29 | #ifdef __powerpc64__ |
28 | .balign 8 | 30 | .balign 8 |
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index 33a4fc891947..463c63a9fcf1 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h | |||
@@ -335,6 +335,7 @@ | |||
335 | #define H_SET_PARTITION_TABLE 0xF800 | 335 | #define H_SET_PARTITION_TABLE 0xF800 |
336 | #define H_ENTER_NESTED 0xF804 | 336 | #define H_ENTER_NESTED 0xF804 |
337 | #define H_TLB_INVALIDATE 0xF808 | 337 | #define H_TLB_INVALIDATE 0xF808 |
338 | #define H_COPY_TOFROM_GUEST 0xF80C | ||
338 | 339 | ||
339 | /* Values for 2nd argument to H_SET_MODE */ | 340 | /* Values for 2nd argument to H_SET_MODE */ |
340 | #define H_SET_MODE_RESOURCE_SET_CIABR 1 | 341 | #define H_SET_MODE_RESOURCE_SET_CIABR 1 |
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index 09f8e9ba69bc..38f1b879f569 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h | |||
@@ -188,6 +188,13 @@ extern int kvmppc_book3s_hcall_implemented(struct kvm *kvm, unsigned long hc); | |||
188 | extern int kvmppc_book3s_radix_page_fault(struct kvm_run *run, | 188 | extern int kvmppc_book3s_radix_page_fault(struct kvm_run *run, |
189 | struct kvm_vcpu *vcpu, | 189 | struct kvm_vcpu *vcpu, |
190 | unsigned long ea, unsigned long dsisr); | 190 | unsigned long ea, unsigned long dsisr); |
191 | extern unsigned long __kvmhv_copy_tofrom_guest_radix(int lpid, int pid, | ||
192 | gva_t eaddr, void *to, void *from, | ||
193 | unsigned long n); | ||
194 | extern long kvmhv_copy_from_guest_radix(struct kvm_vcpu *vcpu, gva_t eaddr, | ||
195 | void *to, unsigned long n); | ||
196 | extern long kvmhv_copy_to_guest_radix(struct kvm_vcpu *vcpu, gva_t eaddr, | ||
197 | void *from, unsigned long n); | ||
191 | extern int kvmppc_mmu_walk_radix_tree(struct kvm_vcpu *vcpu, gva_t eaddr, | 198 | extern int kvmppc_mmu_walk_radix_tree(struct kvm_vcpu *vcpu, gva_t eaddr, |
192 | struct kvmppc_pte *gpte, u64 root, | 199 | struct kvmppc_pte *gpte, u64 root, |
193 | u64 *pte_ret_p); | 200 | u64 *pte_ret_p); |
@@ -196,8 +203,11 @@ extern int kvmppc_mmu_radix_translate_table(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
196 | int table_index, u64 *pte_ret_p); | 203 | int table_index, u64 *pte_ret_p); |
197 | extern int kvmppc_mmu_radix_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | 204 | extern int kvmppc_mmu_radix_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, |
198 | struct kvmppc_pte *gpte, bool data, bool iswrite); | 205 | struct kvmppc_pte *gpte, bool data, bool iswrite); |
206 | extern void kvmppc_radix_tlbie_page(struct kvm *kvm, unsigned long addr, | ||
207 | unsigned int pshift, unsigned int lpid); | ||
199 | extern void kvmppc_unmap_pte(struct kvm *kvm, pte_t *pte, unsigned long gpa, | 208 | extern void kvmppc_unmap_pte(struct kvm *kvm, pte_t *pte, unsigned long gpa, |
200 | unsigned int shift, struct kvm_memory_slot *memslot, | 209 | unsigned int shift, |
210 | const struct kvm_memory_slot *memslot, | ||
201 | unsigned int lpid); | 211 | unsigned int lpid); |
202 | extern bool kvmppc_hv_handle_set_rc(struct kvm *kvm, pgd_t *pgtable, | 212 | extern bool kvmppc_hv_handle_set_rc(struct kvm *kvm, pgd_t *pgtable, |
203 | bool writing, unsigned long gpa, | 213 | bool writing, unsigned long gpa, |
@@ -215,16 +225,14 @@ extern int kvmppc_radix_init(void); | |||
215 | extern void kvmppc_radix_exit(void); | 225 | extern void kvmppc_radix_exit(void); |
216 | extern int kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, | 226 | extern int kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, |
217 | unsigned long gfn); | 227 | unsigned long gfn); |
218 | extern void kvmppc_unmap_pte(struct kvm *kvm, pte_t *pte, | ||
219 | unsigned long gpa, unsigned int shift, | ||
220 | struct kvm_memory_slot *memslot, | ||
221 | unsigned int lpid); | ||
222 | extern int kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, | 228 | extern int kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, |
223 | unsigned long gfn); | 229 | unsigned long gfn); |
224 | extern int kvm_test_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, | 230 | extern int kvm_test_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, |
225 | unsigned long gfn); | 231 | unsigned long gfn); |
226 | extern long kvmppc_hv_get_dirty_log_radix(struct kvm *kvm, | 232 | extern long kvmppc_hv_get_dirty_log_radix(struct kvm *kvm, |
227 | struct kvm_memory_slot *memslot, unsigned long *map); | 233 | struct kvm_memory_slot *memslot, unsigned long *map); |
234 | extern void kvmppc_radix_flush_memslot(struct kvm *kvm, | ||
235 | const struct kvm_memory_slot *memslot); | ||
228 | extern int kvmhv_get_rmmu_info(struct kvm *kvm, struct kvm_ppc_rmmu_info *info); | 236 | extern int kvmhv_get_rmmu_info(struct kvm *kvm, struct kvm_ppc_rmmu_info *info); |
229 | 237 | ||
230 | /* XXX remove this export when load_last_inst() is generic */ | 238 | /* XXX remove this export when load_last_inst() is generic */ |
@@ -242,7 +250,7 @@ extern kvm_pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
242 | bool writing, bool *writable); | 250 | bool writing, bool *writable); |
243 | extern void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev, | 251 | extern void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev, |
244 | unsigned long *rmap, long pte_index, int realmode); | 252 | unsigned long *rmap, long pte_index, int realmode); |
245 | extern void kvmppc_update_dirty_map(struct kvm_memory_slot *memslot, | 253 | extern void kvmppc_update_dirty_map(const struct kvm_memory_slot *memslot, |
246 | unsigned long gfn, unsigned long psize); | 254 | unsigned long gfn, unsigned long psize); |
247 | extern void kvmppc_invalidate_hpte(struct kvm *kvm, __be64 *hptep, | 255 | extern void kvmppc_invalidate_hpte(struct kvm *kvm, __be64 *hptep, |
248 | unsigned long pte_index); | 256 | unsigned long pte_index); |
@@ -298,6 +306,7 @@ long kvmhv_nested_init(void); | |||
298 | void kvmhv_nested_exit(void); | 306 | void kvmhv_nested_exit(void); |
299 | void kvmhv_vm_nested_init(struct kvm *kvm); | 307 | void kvmhv_vm_nested_init(struct kvm *kvm); |
300 | long kvmhv_set_partition_table(struct kvm_vcpu *vcpu); | 308 | long kvmhv_set_partition_table(struct kvm_vcpu *vcpu); |
309 | long kvmhv_copy_tofrom_guest_nested(struct kvm_vcpu *vcpu); | ||
301 | void kvmhv_set_ptbl_entry(unsigned int lpid, u64 dw0, u64 dw1); | 310 | void kvmhv_set_ptbl_entry(unsigned int lpid, u64 dw0, u64 dw1); |
302 | void kvmhv_release_all_nested(struct kvm *kvm); | 311 | void kvmhv_release_all_nested(struct kvm *kvm); |
303 | long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu); | 312 | long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu); |
@@ -307,7 +316,7 @@ int kvmhv_run_single_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu, | |||
307 | void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr); | 316 | void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr); |
308 | void kvmhv_restore_hv_return_state(struct kvm_vcpu *vcpu, | 317 | void kvmhv_restore_hv_return_state(struct kvm_vcpu *vcpu, |
309 | struct hv_guest_state *hr); | 318 | struct hv_guest_state *hr); |
310 | long int kvmhv_nested_page_fault(struct kvm_vcpu *vcpu); | 319 | long int kvmhv_nested_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu); |
311 | 320 | ||
312 | void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac); | 321 | void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac); |
313 | 322 | ||
diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h b/arch/powerpc/include/asm/kvm_book3s_64.h index 6d298145d564..21b1ed5df888 100644 --- a/arch/powerpc/include/asm/kvm_book3s_64.h +++ b/arch/powerpc/include/asm/kvm_book3s_64.h | |||
@@ -55,6 +55,7 @@ struct kvm_nested_guest { | |||
55 | cpumask_t need_tlb_flush; | 55 | cpumask_t need_tlb_flush; |
56 | cpumask_t cpu_in_guest; | 56 | cpumask_t cpu_in_guest; |
57 | short prev_cpu[NR_CPUS]; | 57 | short prev_cpu[NR_CPUS]; |
58 | u8 radix; /* is this nested guest radix */ | ||
58 | }; | 59 | }; |
59 | 60 | ||
60 | /* | 61 | /* |
@@ -150,6 +151,18 @@ static inline bool kvm_is_radix(struct kvm *kvm) | |||
150 | return kvm->arch.radix; | 151 | return kvm->arch.radix; |
151 | } | 152 | } |
152 | 153 | ||
154 | static inline bool kvmhv_vcpu_is_radix(struct kvm_vcpu *vcpu) | ||
155 | { | ||
156 | bool radix; | ||
157 | |||
158 | if (vcpu->arch.nested) | ||
159 | radix = vcpu->arch.nested->radix; | ||
160 | else | ||
161 | radix = kvm_is_radix(vcpu->kvm); | ||
162 | |||
163 | return radix; | ||
164 | } | ||
165 | |||
153 | #define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */ | 166 | #define KVM_DEFAULT_HPT_ORDER 24 /* 16MB HPT by default */ |
154 | #endif | 167 | #endif |
155 | 168 | ||
@@ -624,8 +637,11 @@ extern int kvmppc_create_pte(struct kvm *kvm, pgd_t *pgtable, pte_t pte, | |||
624 | unsigned long *rmapp, struct rmap_nested **n_rmap); | 637 | unsigned long *rmapp, struct rmap_nested **n_rmap); |
625 | extern void kvmhv_insert_nest_rmap(struct kvm *kvm, unsigned long *rmapp, | 638 | extern void kvmhv_insert_nest_rmap(struct kvm *kvm, unsigned long *rmapp, |
626 | struct rmap_nested **n_rmap); | 639 | struct rmap_nested **n_rmap); |
640 | extern void kvmhv_update_nest_rmap_rc_list(struct kvm *kvm, unsigned long *rmapp, | ||
641 | unsigned long clr, unsigned long set, | ||
642 | unsigned long hpa, unsigned long nbytes); | ||
627 | extern void kvmhv_remove_nest_rmap_range(struct kvm *kvm, | 643 | extern void kvmhv_remove_nest_rmap_range(struct kvm *kvm, |
628 | struct kvm_memory_slot *memslot, | 644 | const struct kvm_memory_slot *memslot, |
629 | unsigned long gpa, unsigned long hpa, | 645 | unsigned long gpa, unsigned long hpa, |
630 | unsigned long nbytes); | 646 | unsigned long nbytes); |
631 | 647 | ||
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index fac6f631ed29..0f98f00da2ea 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h | |||
@@ -72,7 +72,7 @@ extern int kvm_unmap_hva_range(struct kvm *kvm, | |||
72 | unsigned long start, unsigned long end); | 72 | unsigned long start, unsigned long end); |
73 | extern int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); | 73 | extern int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); |
74 | extern int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); | 74 | extern int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); |
75 | extern void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); | 75 | extern int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); |
76 | 76 | ||
77 | #define HPTEG_CACHE_NUM (1 << 15) | 77 | #define HPTEG_CACHE_NUM (1 << 15) |
78 | #define HPTEG_HASH_BITS_PTE 13 | 78 | #define HPTEG_HASH_BITS_PTE 13 |
@@ -793,6 +793,7 @@ struct kvm_vcpu_arch { | |||
793 | /* For support of nested guests */ | 793 | /* For support of nested guests */ |
794 | struct kvm_nested_guest *nested; | 794 | struct kvm_nested_guest *nested; |
795 | u32 nested_vcpu_id; | 795 | u32 nested_vcpu_id; |
796 | gpa_t nested_io_gpr; | ||
796 | #endif | 797 | #endif |
797 | 798 | ||
798 | #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING | 799 | #ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING |
@@ -827,6 +828,8 @@ struct kvm_vcpu_arch { | |||
827 | #define KVM_MMIO_REG_FQPR 0x00c0 | 828 | #define KVM_MMIO_REG_FQPR 0x00c0 |
828 | #define KVM_MMIO_REG_VSX 0x0100 | 829 | #define KVM_MMIO_REG_VSX 0x0100 |
829 | #define KVM_MMIO_REG_VMX 0x0180 | 830 | #define KVM_MMIO_REG_VMX 0x0180 |
831 | #define KVM_MMIO_REG_NESTED_GPR 0xffc0 | ||
832 | |||
830 | 833 | ||
831 | #define __KVM_HAVE_ARCH_WQP | 834 | #define __KVM_HAVE_ARCH_WQP |
832 | #define __KVM_HAVE_CREATE_DEVICE | 835 | #define __KVM_HAVE_CREATE_DEVICE |
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 9b89b1918dfc..eb0d79f0ca45 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h | |||
@@ -224,7 +224,8 @@ extern int kvmppc_core_prepare_memory_region(struct kvm *kvm, | |||
224 | extern void kvmppc_core_commit_memory_region(struct kvm *kvm, | 224 | extern void kvmppc_core_commit_memory_region(struct kvm *kvm, |
225 | const struct kvm_userspace_memory_region *mem, | 225 | const struct kvm_userspace_memory_region *mem, |
226 | const struct kvm_memory_slot *old, | 226 | const struct kvm_memory_slot *old, |
227 | const struct kvm_memory_slot *new); | 227 | const struct kvm_memory_slot *new, |
228 | enum kvm_mr_change change); | ||
228 | extern int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm, | 229 | extern int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm, |
229 | struct kvm_ppc_smmu_info *info); | 230 | struct kvm_ppc_smmu_info *info); |
230 | extern void kvmppc_core_flush_memslot(struct kvm *kvm, | 231 | extern void kvmppc_core_flush_memslot(struct kvm *kvm, |
@@ -294,7 +295,8 @@ struct kvmppc_ops { | |||
294 | void (*commit_memory_region)(struct kvm *kvm, | 295 | void (*commit_memory_region)(struct kvm *kvm, |
295 | const struct kvm_userspace_memory_region *mem, | 296 | const struct kvm_userspace_memory_region *mem, |
296 | const struct kvm_memory_slot *old, | 297 | const struct kvm_memory_slot *old, |
297 | const struct kvm_memory_slot *new); | 298 | const struct kvm_memory_slot *new, |
299 | enum kvm_mr_change change); | ||
298 | int (*unmap_hva_range)(struct kvm *kvm, unsigned long start, | 300 | int (*unmap_hva_range)(struct kvm *kvm, unsigned long start, |
299 | unsigned long end); | 301 | unsigned long end); |
300 | int (*age_hva)(struct kvm *kvm, unsigned long start, unsigned long end); | 302 | int (*age_hva)(struct kvm *kvm, unsigned long start, unsigned long end); |
@@ -326,6 +328,10 @@ struct kvmppc_ops { | |||
326 | unsigned long flags); | 328 | unsigned long flags); |
327 | void (*giveup_ext)(struct kvm_vcpu *vcpu, ulong msr); | 329 | void (*giveup_ext)(struct kvm_vcpu *vcpu, ulong msr); |
328 | int (*enable_nested)(struct kvm *kvm); | 330 | int (*enable_nested)(struct kvm *kvm); |
331 | int (*load_from_eaddr)(struct kvm_vcpu *vcpu, ulong *eaddr, void *ptr, | ||
332 | int size); | ||
333 | int (*store_to_eaddr)(struct kvm_vcpu *vcpu, ulong *eaddr, void *ptr, | ||
334 | int size); | ||
329 | }; | 335 | }; |
330 | 336 | ||
331 | extern struct kvmppc_ops *kvmppc_hv_ops; | 337 | extern struct kvmppc_ops *kvmppc_hv_ops; |
diff --git a/arch/powerpc/include/asm/perf_event.h b/arch/powerpc/include/asm/perf_event.h index 8bf1b6351716..16a49819da9a 100644 --- a/arch/powerpc/include/asm/perf_event.h +++ b/arch/powerpc/include/asm/perf_event.h | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <asm/ptrace.h> | 26 | #include <asm/ptrace.h> |
27 | #include <asm/reg.h> | 27 | #include <asm/reg.h> |
28 | 28 | ||
29 | #define perf_arch_bpf_user_pt_regs(regs) ®s->user_regs | ||
30 | |||
29 | /* | 31 | /* |
30 | * Overload regs->result to specify whether we should use the MSR (result | 32 | * Overload regs->result to specify whether we should use the MSR (result |
31 | * is zero) or the SIAR (result is non zero). | 33 | * is zero) or the SIAR (result is non zero). |
diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild index a658091a19f9..3712152206f3 100644 --- a/arch/powerpc/include/uapi/asm/Kbuild +++ b/arch/powerpc/include/uapi/asm/Kbuild | |||
@@ -1,7 +1,6 @@ | |||
1 | # UAPI Header export list | 1 | # UAPI Header export list |
2 | include include/uapi/asm-generic/Kbuild.asm | 2 | include include/uapi/asm-generic/Kbuild.asm |
3 | 3 | ||
4 | generic-y += bpf_perf_event.h | ||
5 | generic-y += param.h | 4 | generic-y += param.h |
6 | generic-y += poll.h | 5 | generic-y += poll.h |
7 | generic-y += resource.h | 6 | generic-y += resource.h |
diff --git a/arch/powerpc/include/uapi/asm/bpf_perf_event.h b/arch/powerpc/include/uapi/asm/bpf_perf_event.h new file mode 100644 index 000000000000..b551b741653d --- /dev/null +++ b/arch/powerpc/include/uapi/asm/bpf_perf_event.h | |||
@@ -0,0 +1,9 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | #ifndef _UAPI__ASM_BPF_PERF_EVENT_H__ | ||
3 | #define _UAPI__ASM_BPF_PERF_EVENT_H__ | ||
4 | |||
5 | #include <asm/ptrace.h> | ||
6 | |||
7 | typedef struct user_pt_regs bpf_user_pt_regs_t; | ||
8 | |||
9 | #endif /* _UAPI__ASM_BPF_PERF_EVENT_H__ */ | ||
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 89d32bb79d5e..db2691ff4c0b 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -995,7 +995,16 @@ EXC_COMMON_BEGIN(h_data_storage_common) | |||
995 | bl save_nvgprs | 995 | bl save_nvgprs |
996 | RECONCILE_IRQ_STATE(r10, r11) | 996 | RECONCILE_IRQ_STATE(r10, r11) |
997 | addi r3,r1,STACK_FRAME_OVERHEAD | 997 | addi r3,r1,STACK_FRAME_OVERHEAD |
998 | BEGIN_MMU_FTR_SECTION | ||
999 | ld r4,PACA_EXGEN+EX_DAR(r13) | ||
1000 | lwz r5,PACA_EXGEN+EX_DSISR(r13) | ||
1001 | std r4,_DAR(r1) | ||
1002 | std r5,_DSISR(r1) | ||
1003 | li r5,SIGSEGV | ||
1004 | bl bad_page_fault | ||
1005 | MMU_FTR_SECTION_ELSE | ||
998 | bl unknown_exception | 1006 | bl unknown_exception |
1007 | ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_TYPE_RADIX) | ||
999 | b ret_from_except | 1008 | b ret_from_except |
1000 | 1009 | ||
1001 | 1010 | ||
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 33b34a58fc62..5b9dce17f0c9 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c | |||
@@ -372,6 +372,8 @@ void __init find_legacy_serial_ports(void) | |||
372 | 372 | ||
373 | /* Now find out if one of these is out firmware console */ | 373 | /* Now find out if one of these is out firmware console */ |
374 | path = of_get_property(of_chosen, "linux,stdout-path", NULL); | 374 | path = of_get_property(of_chosen, "linux,stdout-path", NULL); |
375 | if (path == NULL) | ||
376 | path = of_get_property(of_chosen, "stdout-path", NULL); | ||
375 | if (path != NULL) { | 377 | if (path != NULL) { |
376 | stdout = of_find_node_by_path(path); | 378 | stdout = of_find_node_by_path(path); |
377 | if (stdout) | 379 | if (stdout) |
@@ -595,8 +597,10 @@ static int __init check_legacy_serial_console(void) | |||
595 | /* We are getting a weird phandle from OF ... */ | 597 | /* We are getting a weird phandle from OF ... */ |
596 | /* ... So use the full path instead */ | 598 | /* ... So use the full path instead */ |
597 | name = of_get_property(of_chosen, "linux,stdout-path", NULL); | 599 | name = of_get_property(of_chosen, "linux,stdout-path", NULL); |
600 | if (name == NULL) | ||
601 | name = of_get_property(of_chosen, "stdout-path", NULL); | ||
598 | if (name == NULL) { | 602 | if (name == NULL) { |
599 | DBG(" no linux,stdout-path !\n"); | 603 | DBG(" no stdout-path !\n"); |
600 | return -ENODEV; | 604 | return -ENODEV; |
601 | } | 605 | } |
602 | prom_stdout = of_find_node_by_path(name); | 606 | prom_stdout = of_find_node_by_path(name); |
diff --git a/arch/powerpc/kernel/machine_kexec_file_64.c b/arch/powerpc/kernel/machine_kexec_file_64.c index c77e95e9b384..0d20c7ad40fa 100644 --- a/arch/powerpc/kernel/machine_kexec_file_64.c +++ b/arch/powerpc/kernel/machine_kexec_file_64.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/kexec.h> | 26 | #include <linux/kexec.h> |
27 | #include <linux/memblock.h> | ||
28 | #include <linux/of_fdt.h> | 27 | #include <linux/of_fdt.h> |
29 | #include <linux/libfdt.h> | 28 | #include <linux/libfdt.h> |
30 | #include <asm/ima.h> | 29 | #include <asm/ima.h> |
@@ -47,59 +46,6 @@ int arch_kexec_kernel_image_probe(struct kimage *image, void *buf, | |||
47 | } | 46 | } |
48 | 47 | ||
49 | /** | 48 | /** |
50 | * arch_kexec_walk_mem - call func(data) for each unreserved memory block | ||
51 | * @kbuf: Context info for the search. Also passed to @func. | ||
52 | * @func: Function to call for each memory block. | ||
53 | * | ||
54 | * This function is used by kexec_add_buffer and kexec_locate_mem_hole | ||
55 | * to find unreserved memory to load kexec segments into. | ||
56 | * | ||
57 | * Return: The memory walk will stop when func returns a non-zero value | ||
58 | * and that value will be returned. If all free regions are visited without | ||
59 | * func returning non-zero, then zero will be returned. | ||
60 | */ | ||
61 | int arch_kexec_walk_mem(struct kexec_buf *kbuf, | ||
62 | int (*func)(struct resource *, void *)) | ||
63 | { | ||
64 | int ret = 0; | ||
65 | u64 i; | ||
66 | phys_addr_t mstart, mend; | ||
67 | struct resource res = { }; | ||
68 | |||
69 | if (kbuf->top_down) { | ||
70 | for_each_free_mem_range_reverse(i, NUMA_NO_NODE, 0, | ||
71 | &mstart, &mend, NULL) { | ||
72 | /* | ||
73 | * In memblock, end points to the first byte after the | ||
74 | * range while in kexec, end points to the last byte | ||
75 | * in the range. | ||
76 | */ | ||
77 | res.start = mstart; | ||
78 | res.end = mend - 1; | ||
79 | ret = func(&res, kbuf); | ||
80 | if (ret) | ||
81 | break; | ||
82 | } | ||
83 | } else { | ||
84 | for_each_free_mem_range(i, NUMA_NO_NODE, 0, &mstart, &mend, | ||
85 | NULL) { | ||
86 | /* | ||
87 | * In memblock, end points to the first byte after the | ||
88 | * range while in kexec, end points to the last byte | ||
89 | * in the range. | ||
90 | */ | ||
91 | res.start = mstart; | ||
92 | res.end = mend - 1; | ||
93 | ret = func(&res, kbuf); | ||
94 | if (ret) | ||
95 | break; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * setup_purgatory - initialize the purgatory's global variables | 49 | * setup_purgatory - initialize the purgatory's global variables |
104 | * @image: kexec image. | 50 | * @image: kexec image. |
105 | * @slave_code: Slave code for the purgatory. | 51 | * @slave_code: Slave code for the purgatory. |
diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c index dab616a33b8d..f2197654be07 100644 --- a/arch/powerpc/kernel/msi.c +++ b/arch/powerpc/kernel/msi.c | |||
@@ -34,5 +34,10 @@ void arch_teardown_msi_irqs(struct pci_dev *dev) | |||
34 | { | 34 | { |
35 | struct pci_controller *phb = pci_bus_to_host(dev->bus); | 35 | struct pci_controller *phb = pci_bus_to_host(dev->bus); |
36 | 36 | ||
37 | phb->controller_ops.teardown_msi_irqs(dev); | 37 | /* |
38 | * We can be called even when arch_setup_msi_irqs() returns -ENOSYS, | ||
39 | * so check the pointer again. | ||
40 | */ | ||
41 | if (phb->controller_ops.teardown_msi_irqs) | ||
42 | phb->controller_ops.teardown_msi_irqs(dev); | ||
38 | } | 43 | } |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index afb819f4ca68..714c3480c52d 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -3266,12 +3266,17 @@ long do_syscall_trace_enter(struct pt_regs *regs) | |||
3266 | user_exit(); | 3266 | user_exit(); |
3267 | 3267 | ||
3268 | if (test_thread_flag(TIF_SYSCALL_EMU)) { | 3268 | if (test_thread_flag(TIF_SYSCALL_EMU)) { |
3269 | ptrace_report_syscall(regs); | ||
3270 | /* | 3269 | /* |
3270 | * A nonzero return code from tracehook_report_syscall_entry() | ||
3271 | * tells us to prevent the syscall execution, but we are not | ||
3272 | * going to execute it anyway. | ||
3273 | * | ||
3271 | * Returning -1 will skip the syscall execution. We want to | 3274 | * Returning -1 will skip the syscall execution. We want to |
3272 | * avoid clobbering any register also, thus, not 'gotoing' | 3275 | * avoid clobbering any register also, thus, not 'gotoing' |
3273 | * skip label. | 3276 | * skip label. |
3274 | */ | 3277 | */ |
3278 | if (tracehook_report_syscall_entry(regs)) | ||
3279 | ; | ||
3275 | return -1; | 3280 | return -1; |
3276 | } | 3281 | } |
3277 | 3282 | ||
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index fd9893bc7aa1..bd1a677dd9e4 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
@@ -830,9 +830,10 @@ int kvmppc_core_prepare_memory_region(struct kvm *kvm, | |||
830 | void kvmppc_core_commit_memory_region(struct kvm *kvm, | 830 | void kvmppc_core_commit_memory_region(struct kvm *kvm, |
831 | const struct kvm_userspace_memory_region *mem, | 831 | const struct kvm_userspace_memory_region *mem, |
832 | const struct kvm_memory_slot *old, | 832 | const struct kvm_memory_slot *old, |
833 | const struct kvm_memory_slot *new) | 833 | const struct kvm_memory_slot *new, |
834 | enum kvm_mr_change change) | ||
834 | { | 835 | { |
835 | kvm->arch.kvm_ops->commit_memory_region(kvm, mem, old, new); | 836 | kvm->arch.kvm_ops->commit_memory_region(kvm, mem, old, new, change); |
836 | } | 837 | } |
837 | 838 | ||
838 | int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) | 839 | int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) |
@@ -850,9 +851,10 @@ int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) | |||
850 | return kvm->arch.kvm_ops->test_age_hva(kvm, hva); | 851 | return kvm->arch.kvm_ops->test_age_hva(kvm, hva); |
851 | } | 852 | } |
852 | 853 | ||
853 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) | 854 | int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) |
854 | { | 855 | { |
855 | kvm->arch.kvm_ops->set_spte_hva(kvm, hva, pte); | 856 | kvm->arch.kvm_ops->set_spte_hva(kvm, hva, pte); |
857 | return 0; | ||
856 | } | 858 | } |
857 | 859 | ||
858 | void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) | 860 | void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu) |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index c615617e78ac..6f2d2fb4e098 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
@@ -743,12 +743,15 @@ void kvmppc_rmap_reset(struct kvm *kvm) | |||
743 | srcu_idx = srcu_read_lock(&kvm->srcu); | 743 | srcu_idx = srcu_read_lock(&kvm->srcu); |
744 | slots = kvm_memslots(kvm); | 744 | slots = kvm_memslots(kvm); |
745 | kvm_for_each_memslot(memslot, slots) { | 745 | kvm_for_each_memslot(memslot, slots) { |
746 | /* Mutual exclusion with kvm_unmap_hva_range etc. */ | ||
747 | spin_lock(&kvm->mmu_lock); | ||
746 | /* | 748 | /* |
747 | * This assumes it is acceptable to lose reference and | 749 | * This assumes it is acceptable to lose reference and |
748 | * change bits across a reset. | 750 | * change bits across a reset. |
749 | */ | 751 | */ |
750 | memset(memslot->arch.rmap, 0, | 752 | memset(memslot->arch.rmap, 0, |
751 | memslot->npages * sizeof(*memslot->arch.rmap)); | 753 | memslot->npages * sizeof(*memslot->arch.rmap)); |
754 | spin_unlock(&kvm->mmu_lock); | ||
752 | } | 755 | } |
753 | srcu_read_unlock(&kvm->srcu, srcu_idx); | 756 | srcu_read_unlock(&kvm->srcu, srcu_idx); |
754 | } | 757 | } |
@@ -896,11 +899,12 @@ void kvmppc_core_flush_memslot_hv(struct kvm *kvm, | |||
896 | 899 | ||
897 | gfn = memslot->base_gfn; | 900 | gfn = memslot->base_gfn; |
898 | rmapp = memslot->arch.rmap; | 901 | rmapp = memslot->arch.rmap; |
902 | if (kvm_is_radix(kvm)) { | ||
903 | kvmppc_radix_flush_memslot(kvm, memslot); | ||
904 | return; | ||
905 | } | ||
906 | |||
899 | for (n = memslot->npages; n; --n, ++gfn) { | 907 | for (n = memslot->npages; n; --n, ++gfn) { |
900 | if (kvm_is_radix(kvm)) { | ||
901 | kvm_unmap_radix(kvm, memslot, gfn); | ||
902 | continue; | ||
903 | } | ||
904 | /* | 908 | /* |
905 | * Testing the present bit without locking is OK because | 909 | * Testing the present bit without locking is OK because |
906 | * the memslot has been marked invalid already, and hence | 910 | * the memslot has been marked invalid already, and hence |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index d68162ee159b..fb88167a402a 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c | |||
@@ -29,6 +29,103 @@ | |||
29 | */ | 29 | */ |
30 | static int p9_supported_radix_bits[4] = { 5, 9, 9, 13 }; | 30 | static int p9_supported_radix_bits[4] = { 5, 9, 9, 13 }; |
31 | 31 | ||
32 | unsigned long __kvmhv_copy_tofrom_guest_radix(int lpid, int pid, | ||
33 | gva_t eaddr, void *to, void *from, | ||
34 | unsigned long n) | ||
35 | { | ||
36 | unsigned long quadrant, ret = n; | ||
37 | int old_pid, old_lpid; | ||
38 | bool is_load = !!to; | ||
39 | |||
40 | /* Can't access quadrants 1 or 2 in non-HV mode, call the HV to do it */ | ||
41 | if (kvmhv_on_pseries()) | ||
42 | return plpar_hcall_norets(H_COPY_TOFROM_GUEST, lpid, pid, eaddr, | ||
43 | __pa(to), __pa(from), n); | ||
44 | |||
45 | quadrant = 1; | ||
46 | if (!pid) | ||
47 | quadrant = 2; | ||
48 | if (is_load) | ||
49 | from = (void *) (eaddr | (quadrant << 62)); | ||
50 | else | ||
51 | to = (void *) (eaddr | (quadrant << 62)); | ||
52 | |||
53 | preempt_disable(); | ||
54 | |||
55 | /* switch the lpid first to avoid running host with unallocated pid */ | ||
56 | old_lpid = mfspr(SPRN_LPID); | ||
57 | if (old_lpid != lpid) | ||
58 | mtspr(SPRN_LPID, lpid); | ||
59 | if (quadrant == 1) { | ||
60 | old_pid = mfspr(SPRN_PID); | ||
61 | if (old_pid != pid) | ||
62 | mtspr(SPRN_PID, pid); | ||
63 | } | ||
64 | isync(); | ||
65 | |||
66 | pagefault_disable(); | ||
67 | if (is_load) | ||
68 | ret = raw_copy_from_user(to, from, n); | ||
69 | else | ||
70 | ret = raw_copy_to_user(to, from, n); | ||
71 | pagefault_enable(); | ||
72 | |||
73 | /* switch the pid first to avoid running host with unallocated pid */ | ||
74 | if (quadrant == 1 && pid != old_pid) | ||
75 | mtspr(SPRN_PID, old_pid); | ||
76 | if (lpid != old_lpid) | ||
77 | mtspr(SPRN_LPID, old_lpid); | ||
78 | isync(); | ||
79 | |||
80 | preempt_enable(); | ||
81 | |||
82 | return ret; | ||
83 | } | ||
84 | EXPORT_SYMBOL_GPL(__kvmhv_copy_tofrom_guest_radix); | ||
85 | |||
86 | static long kvmhv_copy_tofrom_guest_radix(struct kvm_vcpu *vcpu, gva_t eaddr, | ||
87 | void *to, void *from, unsigned long n) | ||
88 | { | ||
89 | int lpid = vcpu->kvm->arch.lpid; | ||
90 | int pid = vcpu->arch.pid; | ||
91 | |||
92 | /* This would cause a data segment intr so don't allow the access */ | ||
93 | if (eaddr & (0x3FFUL << 52)) | ||
94 | return -EINVAL; | ||
95 | |||
96 | /* Should we be using the nested lpid */ | ||
97 | if (vcpu->arch.nested) | ||
98 | lpid = vcpu->arch.nested->shadow_lpid; | ||
99 | |||
100 | /* If accessing quadrant 3 then pid is expected to be 0 */ | ||
101 | if (((eaddr >> 62) & 0x3) == 0x3) | ||
102 | pid = 0; | ||
103 | |||
104 | eaddr &= ~(0xFFFUL << 52); | ||
105 | |||
106 | return __kvmhv_copy_tofrom_guest_radix(lpid, pid, eaddr, to, from, n); | ||
107 | } | ||
108 | |||
109 | long kvmhv_copy_from_guest_radix(struct kvm_vcpu *vcpu, gva_t eaddr, void *to, | ||
110 | unsigned long n) | ||
111 | { | ||
112 | long ret; | ||
113 | |||
114 | ret = kvmhv_copy_tofrom_guest_radix(vcpu, eaddr, to, NULL, n); | ||
115 | if (ret > 0) | ||
116 | memset(to + (n - ret), 0, ret); | ||
117 | |||
118 | return ret; | ||
119 | } | ||
120 | EXPORT_SYMBOL_GPL(kvmhv_copy_from_guest_radix); | ||
121 | |||
122 | long kvmhv_copy_to_guest_radix(struct kvm_vcpu *vcpu, gva_t eaddr, void *from, | ||
123 | unsigned long n) | ||
124 | { | ||
125 | return kvmhv_copy_tofrom_guest_radix(vcpu, eaddr, NULL, from, n); | ||
126 | } | ||
127 | EXPORT_SYMBOL_GPL(kvmhv_copy_to_guest_radix); | ||
128 | |||
32 | int kvmppc_mmu_walk_radix_tree(struct kvm_vcpu *vcpu, gva_t eaddr, | 129 | int kvmppc_mmu_walk_radix_tree(struct kvm_vcpu *vcpu, gva_t eaddr, |
33 | struct kvmppc_pte *gpte, u64 root, | 130 | struct kvmppc_pte *gpte, u64 root, |
34 | u64 *pte_ret_p) | 131 | u64 *pte_ret_p) |
@@ -197,8 +294,8 @@ int kvmppc_mmu_radix_xlate(struct kvm_vcpu *vcpu, gva_t eaddr, | |||
197 | return 0; | 294 | return 0; |
198 | } | 295 | } |
199 | 296 | ||
200 | static void kvmppc_radix_tlbie_page(struct kvm *kvm, unsigned long addr, | 297 | void kvmppc_radix_tlbie_page(struct kvm *kvm, unsigned long addr, |
201 | unsigned int pshift, unsigned int lpid) | 298 | unsigned int pshift, unsigned int lpid) |
202 | { | 299 | { |
203 | unsigned long psize = PAGE_SIZE; | 300 | unsigned long psize = PAGE_SIZE; |
204 | int psi; | 301 | int psi; |
@@ -284,7 +381,8 @@ static void kvmppc_pmd_free(pmd_t *pmdp) | |||
284 | 381 | ||
285 | /* Called with kvm->mmu_lock held */ | 382 | /* Called with kvm->mmu_lock held */ |
286 | void kvmppc_unmap_pte(struct kvm *kvm, pte_t *pte, unsigned long gpa, | 383 | void kvmppc_unmap_pte(struct kvm *kvm, pte_t *pte, unsigned long gpa, |
287 | unsigned int shift, struct kvm_memory_slot *memslot, | 384 | unsigned int shift, |
385 | const struct kvm_memory_slot *memslot, | ||
288 | unsigned int lpid) | 386 | unsigned int lpid) |
289 | 387 | ||
290 | { | 388 | { |
@@ -683,6 +781,7 @@ int kvmppc_book3s_instantiate_page(struct kvm_vcpu *vcpu, | |||
683 | pte_t pte, *ptep; | 781 | pte_t pte, *ptep; |
684 | unsigned int shift, level; | 782 | unsigned int shift, level; |
685 | int ret; | 783 | int ret; |
784 | bool large_enable; | ||
686 | 785 | ||
687 | /* used to check for invalidations in progress */ | 786 | /* used to check for invalidations in progress */ |
688 | mmu_seq = kvm->mmu_notifier_seq; | 787 | mmu_seq = kvm->mmu_notifier_seq; |
@@ -732,12 +831,15 @@ int kvmppc_book3s_instantiate_page(struct kvm_vcpu *vcpu, | |||
732 | pte = *ptep; | 831 | pte = *ptep; |
733 | local_irq_enable(); | 832 | local_irq_enable(); |
734 | 833 | ||
834 | /* If we're logging dirty pages, always map single pages */ | ||
835 | large_enable = !(memslot->flags & KVM_MEM_LOG_DIRTY_PAGES); | ||
836 | |||
735 | /* Get pte level from shift/size */ | 837 | /* Get pte level from shift/size */ |
736 | if (shift == PUD_SHIFT && | 838 | if (large_enable && shift == PUD_SHIFT && |
737 | (gpa & (PUD_SIZE - PAGE_SIZE)) == | 839 | (gpa & (PUD_SIZE - PAGE_SIZE)) == |
738 | (hva & (PUD_SIZE - PAGE_SIZE))) { | 840 | (hva & (PUD_SIZE - PAGE_SIZE))) { |
739 | level = 2; | 841 | level = 2; |
740 | } else if (shift == PMD_SHIFT && | 842 | } else if (large_enable && shift == PMD_SHIFT && |
741 | (gpa & (PMD_SIZE - PAGE_SIZE)) == | 843 | (gpa & (PMD_SIZE - PAGE_SIZE)) == |
742 | (hva & (PMD_SIZE - PAGE_SIZE))) { | 844 | (hva & (PMD_SIZE - PAGE_SIZE))) { |
743 | level = 1; | 845 | level = 1; |
@@ -857,7 +959,7 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
857 | return ret; | 959 | return ret; |
858 | } | 960 | } |
859 | 961 | ||
860 | /* Called with kvm->lock held */ | 962 | /* Called with kvm->mmu_lock held */ |
861 | int kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, | 963 | int kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, |
862 | unsigned long gfn) | 964 | unsigned long gfn) |
863 | { | 965 | { |
@@ -872,7 +974,7 @@ int kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, | |||
872 | return 0; | 974 | return 0; |
873 | } | 975 | } |
874 | 976 | ||
875 | /* Called with kvm->lock held */ | 977 | /* Called with kvm->mmu_lock held */ |
876 | int kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, | 978 | int kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, |
877 | unsigned long gfn) | 979 | unsigned long gfn) |
878 | { | 980 | { |
@@ -880,18 +982,24 @@ int kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, | |||
880 | unsigned long gpa = gfn << PAGE_SHIFT; | 982 | unsigned long gpa = gfn << PAGE_SHIFT; |
881 | unsigned int shift; | 983 | unsigned int shift; |
882 | int ref = 0; | 984 | int ref = 0; |
985 | unsigned long old, *rmapp; | ||
883 | 986 | ||
884 | ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift); | 987 | ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift); |
885 | if (ptep && pte_present(*ptep) && pte_young(*ptep)) { | 988 | if (ptep && pte_present(*ptep) && pte_young(*ptep)) { |
886 | kvmppc_radix_update_pte(kvm, ptep, _PAGE_ACCESSED, 0, | 989 | old = kvmppc_radix_update_pte(kvm, ptep, _PAGE_ACCESSED, 0, |
887 | gpa, shift); | 990 | gpa, shift); |
888 | /* XXX need to flush tlb here? */ | 991 | /* XXX need to flush tlb here? */ |
992 | /* Also clear bit in ptes in shadow pgtable for nested guests */ | ||
993 | rmapp = &memslot->arch.rmap[gfn - memslot->base_gfn]; | ||
994 | kvmhv_update_nest_rmap_rc_list(kvm, rmapp, _PAGE_ACCESSED, 0, | ||
995 | old & PTE_RPN_MASK, | ||
996 | 1UL << shift); | ||
889 | ref = 1; | 997 | ref = 1; |
890 | } | 998 | } |
891 | return ref; | 999 | return ref; |
892 | } | 1000 | } |
893 | 1001 | ||
894 | /* Called with kvm->lock held */ | 1002 | /* Called with kvm->mmu_lock held */ |
895 | int kvm_test_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, | 1003 | int kvm_test_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, |
896 | unsigned long gfn) | 1004 | unsigned long gfn) |
897 | { | 1005 | { |
@@ -915,15 +1023,23 @@ static int kvm_radix_test_clear_dirty(struct kvm *kvm, | |||
915 | pte_t *ptep; | 1023 | pte_t *ptep; |
916 | unsigned int shift; | 1024 | unsigned int shift; |
917 | int ret = 0; | 1025 | int ret = 0; |
1026 | unsigned long old, *rmapp; | ||
918 | 1027 | ||
919 | ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift); | 1028 | ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift); |
920 | if (ptep && pte_present(*ptep) && pte_dirty(*ptep)) { | 1029 | if (ptep && pte_present(*ptep) && pte_dirty(*ptep)) { |
921 | ret = 1; | 1030 | ret = 1; |
922 | if (shift) | 1031 | if (shift) |
923 | ret = 1 << (shift - PAGE_SHIFT); | 1032 | ret = 1 << (shift - PAGE_SHIFT); |
924 | kvmppc_radix_update_pte(kvm, ptep, _PAGE_DIRTY, 0, | 1033 | spin_lock(&kvm->mmu_lock); |
925 | gpa, shift); | 1034 | old = kvmppc_radix_update_pte(kvm, ptep, _PAGE_DIRTY, 0, |
1035 | gpa, shift); | ||
926 | kvmppc_radix_tlbie_page(kvm, gpa, shift, kvm->arch.lpid); | 1036 | kvmppc_radix_tlbie_page(kvm, gpa, shift, kvm->arch.lpid); |
1037 | /* Also clear bit in ptes in shadow pgtable for nested guests */ | ||
1038 | rmapp = &memslot->arch.rmap[gfn - memslot->base_gfn]; | ||
1039 | kvmhv_update_nest_rmap_rc_list(kvm, rmapp, _PAGE_DIRTY, 0, | ||
1040 | old & PTE_RPN_MASK, | ||
1041 | 1UL << shift); | ||
1042 | spin_unlock(&kvm->mmu_lock); | ||
927 | } | 1043 | } |
928 | return ret; | 1044 | return ret; |
929 | } | 1045 | } |
@@ -953,6 +1069,26 @@ long kvmppc_hv_get_dirty_log_radix(struct kvm *kvm, | |||
953 | return 0; | 1069 | return 0; |
954 | } | 1070 | } |
955 | 1071 | ||
1072 | void kvmppc_radix_flush_memslot(struct kvm *kvm, | ||
1073 | const struct kvm_memory_slot *memslot) | ||
1074 | { | ||
1075 | unsigned long n; | ||
1076 | pte_t *ptep; | ||
1077 | unsigned long gpa; | ||
1078 | unsigned int shift; | ||
1079 | |||
1080 | gpa = memslot->base_gfn << PAGE_SHIFT; | ||
1081 | spin_lock(&kvm->mmu_lock); | ||
1082 | for (n = memslot->npages; n; --n) { | ||
1083 | ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift); | ||
1084 | if (ptep && pte_present(*ptep)) | ||
1085 | kvmppc_unmap_pte(kvm, ptep, gpa, shift, memslot, | ||
1086 | kvm->arch.lpid); | ||
1087 | gpa += PAGE_SIZE; | ||
1088 | } | ||
1089 | spin_unlock(&kvm->mmu_lock); | ||
1090 | } | ||
1091 | |||
956 | static void add_rmmu_ap_encoding(struct kvm_ppc_rmmu_info *info, | 1092 | static void add_rmmu_ap_encoding(struct kvm_ppc_rmmu_info *info, |
957 | int psize, int *indexp) | 1093 | int psize, int *indexp) |
958 | { | 1094 | { |
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index a56f8413758a..5a066fc299e1 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -985,6 +985,10 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | |||
985 | kvmppc_set_gpr(vcpu, 3, 0); | 985 | kvmppc_set_gpr(vcpu, 3, 0); |
986 | vcpu->arch.hcall_needed = 0; | 986 | vcpu->arch.hcall_needed = 0; |
987 | return -EINTR; | 987 | return -EINTR; |
988 | } else if (ret == H_TOO_HARD) { | ||
989 | kvmppc_set_gpr(vcpu, 3, 0); | ||
990 | vcpu->arch.hcall_needed = 0; | ||
991 | return RESUME_HOST; | ||
988 | } | 992 | } |
989 | break; | 993 | break; |
990 | case H_TLB_INVALIDATE: | 994 | case H_TLB_INVALIDATE: |
@@ -992,7 +996,11 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) | |||
992 | if (nesting_enabled(vcpu->kvm)) | 996 | if (nesting_enabled(vcpu->kvm)) |
993 | ret = kvmhv_do_nested_tlbie(vcpu); | 997 | ret = kvmhv_do_nested_tlbie(vcpu); |
994 | break; | 998 | break; |
995 | 999 | case H_COPY_TOFROM_GUEST: | |
1000 | ret = H_FUNCTION; | ||
1001 | if (nesting_enabled(vcpu->kvm)) | ||
1002 | ret = kvmhv_copy_tofrom_guest_nested(vcpu); | ||
1003 | break; | ||
996 | default: | 1004 | default: |
997 | return RESUME_HOST; | 1005 | return RESUME_HOST; |
998 | } | 1006 | } |
@@ -1336,7 +1344,7 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
1336 | return r; | 1344 | return r; |
1337 | } | 1345 | } |
1338 | 1346 | ||
1339 | static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu) | 1347 | static int kvmppc_handle_nested_exit(struct kvm_run *run, struct kvm_vcpu *vcpu) |
1340 | { | 1348 | { |
1341 | int r; | 1349 | int r; |
1342 | int srcu_idx; | 1350 | int srcu_idx; |
@@ -1394,7 +1402,7 @@ static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu) | |||
1394 | */ | 1402 | */ |
1395 | case BOOK3S_INTERRUPT_H_DATA_STORAGE: | 1403 | case BOOK3S_INTERRUPT_H_DATA_STORAGE: |
1396 | srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); | 1404 | srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); |
1397 | r = kvmhv_nested_page_fault(vcpu); | 1405 | r = kvmhv_nested_page_fault(run, vcpu); |
1398 | srcu_read_unlock(&vcpu->kvm->srcu, srcu_idx); | 1406 | srcu_read_unlock(&vcpu->kvm->srcu, srcu_idx); |
1399 | break; | 1407 | break; |
1400 | case BOOK3S_INTERRUPT_H_INST_STORAGE: | 1408 | case BOOK3S_INTERRUPT_H_INST_STORAGE: |
@@ -1404,7 +1412,7 @@ static int kvmppc_handle_nested_exit(struct kvm_vcpu *vcpu) | |||
1404 | if (vcpu->arch.shregs.msr & HSRR1_HISI_WRITE) | 1412 | if (vcpu->arch.shregs.msr & HSRR1_HISI_WRITE) |
1405 | vcpu->arch.fault_dsisr |= DSISR_ISSTORE; | 1413 | vcpu->arch.fault_dsisr |= DSISR_ISSTORE; |
1406 | srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); | 1414 | srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); |
1407 | r = kvmhv_nested_page_fault(vcpu); | 1415 | r = kvmhv_nested_page_fault(run, vcpu); |
1408 | srcu_read_unlock(&vcpu->kvm->srcu, srcu_idx); | 1416 | srcu_read_unlock(&vcpu->kvm->srcu, srcu_idx); |
1409 | break; | 1417 | break; |
1410 | 1418 | ||
@@ -4059,7 +4067,7 @@ int kvmhv_run_single_vcpu(struct kvm_run *kvm_run, | |||
4059 | if (!nested) | 4067 | if (!nested) |
4060 | r = kvmppc_handle_exit_hv(kvm_run, vcpu, current); | 4068 | r = kvmppc_handle_exit_hv(kvm_run, vcpu, current); |
4061 | else | 4069 | else |
4062 | r = kvmppc_handle_nested_exit(vcpu); | 4070 | r = kvmppc_handle_nested_exit(kvm_run, vcpu); |
4063 | } | 4071 | } |
4064 | vcpu->arch.ret = r; | 4072 | vcpu->arch.ret = r; |
4065 | 4073 | ||
@@ -4371,7 +4379,8 @@ static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm, | |||
4371 | static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm, | 4379 | static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm, |
4372 | const struct kvm_userspace_memory_region *mem, | 4380 | const struct kvm_userspace_memory_region *mem, |
4373 | const struct kvm_memory_slot *old, | 4381 | const struct kvm_memory_slot *old, |
4374 | const struct kvm_memory_slot *new) | 4382 | const struct kvm_memory_slot *new, |
4383 | enum kvm_mr_change change) | ||
4375 | { | 4384 | { |
4376 | unsigned long npages = mem->memory_size >> PAGE_SHIFT; | 4385 | unsigned long npages = mem->memory_size >> PAGE_SHIFT; |
4377 | 4386 | ||
@@ -4383,6 +4392,23 @@ static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm, | |||
4383 | */ | 4392 | */ |
4384 | if (npages) | 4393 | if (npages) |
4385 | atomic64_inc(&kvm->arch.mmio_update); | 4394 | atomic64_inc(&kvm->arch.mmio_update); |
4395 | |||
4396 | /* | ||
4397 | * For change == KVM_MR_MOVE or KVM_MR_DELETE, higher levels | ||
4398 | * have already called kvm_arch_flush_shadow_memslot() to | ||
4399 | * flush shadow mappings. For KVM_MR_CREATE we have no | ||
4400 | * previous mappings. So the only case to handle is | ||
4401 | * KVM_MR_FLAGS_ONLY when the KVM_MEM_LOG_DIRTY_PAGES bit | ||
4402 | * has been changed. | ||
4403 | * For radix guests, we flush on setting KVM_MEM_LOG_DIRTY_PAGES | ||
4404 | * to get rid of any THP PTEs in the partition-scoped page tables | ||
4405 | * so we can track dirtiness at the page level; we flush when | ||
4406 | * clearing KVM_MEM_LOG_DIRTY_PAGES so that we can go back to | ||
4407 | * using THP PTEs. | ||
4408 | */ | ||
4409 | if (change == KVM_MR_FLAGS_ONLY && kvm_is_radix(kvm) && | ||
4410 | ((new->flags ^ old->flags) & KVM_MEM_LOG_DIRTY_PAGES)) | ||
4411 | kvmppc_radix_flush_memslot(kvm, old); | ||
4386 | } | 4412 | } |
4387 | 4413 | ||
4388 | /* | 4414 | /* |
@@ -4532,12 +4558,15 @@ int kvmppc_switch_mmu_to_hpt(struct kvm *kvm) | |||
4532 | { | 4558 | { |
4533 | if (nesting_enabled(kvm)) | 4559 | if (nesting_enabled(kvm)) |
4534 | kvmhv_release_all_nested(kvm); | 4560 | kvmhv_release_all_nested(kvm); |
4561 | kvmppc_rmap_reset(kvm); | ||
4562 | kvm->arch.process_table = 0; | ||
4563 | /* Mutual exclusion with kvm_unmap_hva_range etc. */ | ||
4564 | spin_lock(&kvm->mmu_lock); | ||
4565 | kvm->arch.radix = 0; | ||
4566 | spin_unlock(&kvm->mmu_lock); | ||
4535 | kvmppc_free_radix(kvm); | 4567 | kvmppc_free_radix(kvm); |
4536 | kvmppc_update_lpcr(kvm, LPCR_VPM1, | 4568 | kvmppc_update_lpcr(kvm, LPCR_VPM1, |
4537 | LPCR_VPM1 | LPCR_UPRT | LPCR_GTSE | LPCR_HR); | 4569 | LPCR_VPM1 | LPCR_UPRT | LPCR_GTSE | LPCR_HR); |
4538 | kvmppc_rmap_reset(kvm); | ||
4539 | kvm->arch.radix = 0; | ||
4540 | kvm->arch.process_table = 0; | ||
4541 | return 0; | 4570 | return 0; |
4542 | } | 4571 | } |
4543 | 4572 | ||
@@ -4549,12 +4578,14 @@ int kvmppc_switch_mmu_to_radix(struct kvm *kvm) | |||
4549 | err = kvmppc_init_vm_radix(kvm); | 4578 | err = kvmppc_init_vm_radix(kvm); |
4550 | if (err) | 4579 | if (err) |
4551 | return err; | 4580 | return err; |
4552 | 4581 | kvmppc_rmap_reset(kvm); | |
4582 | /* Mutual exclusion with kvm_unmap_hva_range etc. */ | ||
4583 | spin_lock(&kvm->mmu_lock); | ||
4584 | kvm->arch.radix = 1; | ||
4585 | spin_unlock(&kvm->mmu_lock); | ||
4553 | kvmppc_free_hpt(&kvm->arch.hpt); | 4586 | kvmppc_free_hpt(&kvm->arch.hpt); |
4554 | kvmppc_update_lpcr(kvm, LPCR_UPRT | LPCR_GTSE | LPCR_HR, | 4587 | kvmppc_update_lpcr(kvm, LPCR_UPRT | LPCR_GTSE | LPCR_HR, |
4555 | LPCR_VPM1 | LPCR_UPRT | LPCR_GTSE | LPCR_HR); | 4588 | LPCR_VPM1 | LPCR_UPRT | LPCR_GTSE | LPCR_HR); |
4556 | kvmppc_rmap_reset(kvm); | ||
4557 | kvm->arch.radix = 1; | ||
4558 | return 0; | 4589 | return 0; |
4559 | } | 4590 | } |
4560 | 4591 | ||
@@ -5214,6 +5245,44 @@ static int kvmhv_enable_nested(struct kvm *kvm) | |||
5214 | return 0; | 5245 | return 0; |
5215 | } | 5246 | } |
5216 | 5247 | ||
5248 | static int kvmhv_load_from_eaddr(struct kvm_vcpu *vcpu, ulong *eaddr, void *ptr, | ||
5249 | int size) | ||
5250 | { | ||
5251 | int rc = -EINVAL; | ||
5252 | |||
5253 | if (kvmhv_vcpu_is_radix(vcpu)) { | ||
5254 | rc = kvmhv_copy_from_guest_radix(vcpu, *eaddr, ptr, size); | ||
5255 | |||
5256 | if (rc > 0) | ||
5257 | rc = -EINVAL; | ||
5258 | } | ||
5259 | |||
5260 | /* For now quadrants are the only way to access nested guest memory */ | ||
5261 | if (rc && vcpu->arch.nested) | ||
5262 | rc = -EAGAIN; | ||
5263 | |||
5264 | return rc; | ||
5265 | } | ||
5266 | |||
5267 | static int kvmhv_store_to_eaddr(struct kvm_vcpu *vcpu, ulong *eaddr, void *ptr, | ||
5268 | int size) | ||
5269 | { | ||
5270 | int rc = -EINVAL; | ||
5271 | |||
5272 | if (kvmhv_vcpu_is_radix(vcpu)) { | ||
5273 | rc = kvmhv_copy_to_guest_radix(vcpu, *eaddr, ptr, size); | ||
5274 | |||
5275 | if (rc > 0) | ||
5276 | rc = -EINVAL; | ||
5277 | } | ||
5278 | |||
5279 | /* For now quadrants are the only way to access nested guest memory */ | ||
5280 | if (rc && vcpu->arch.nested) | ||
5281 | rc = -EAGAIN; | ||
5282 | |||
5283 | return rc; | ||
5284 | } | ||
5285 | |||
5217 | static struct kvmppc_ops kvm_ops_hv = { | 5286 | static struct kvmppc_ops kvm_ops_hv = { |
5218 | .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv, | 5287 | .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv, |
5219 | .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv, | 5288 | .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv, |
@@ -5254,6 +5323,8 @@ static struct kvmppc_ops kvm_ops_hv = { | |||
5254 | .get_rmmu_info = kvmhv_get_rmmu_info, | 5323 | .get_rmmu_info = kvmhv_get_rmmu_info, |
5255 | .set_smt_mode = kvmhv_set_smt_mode, | 5324 | .set_smt_mode = kvmhv_set_smt_mode, |
5256 | .enable_nested = kvmhv_enable_nested, | 5325 | .enable_nested = kvmhv_enable_nested, |
5326 | .load_from_eaddr = kvmhv_load_from_eaddr, | ||
5327 | .store_to_eaddr = kvmhv_store_to_eaddr, | ||
5257 | }; | 5328 | }; |
5258 | 5329 | ||
5259 | static int kvm_init_subcore_bitmap(void) | 5330 | static int kvm_init_subcore_bitmap(void) |
diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c index 401d2ecbebc5..735e0ac6f5b2 100644 --- a/arch/powerpc/kvm/book3s_hv_nested.c +++ b/arch/powerpc/kvm/book3s_hv_nested.c | |||
@@ -195,6 +195,26 @@ void kvmhv_restore_hv_return_state(struct kvm_vcpu *vcpu, | |||
195 | vcpu->arch.ppr = hr->ppr; | 195 | vcpu->arch.ppr = hr->ppr; |
196 | } | 196 | } |
197 | 197 | ||
198 | static void kvmhv_nested_mmio_needed(struct kvm_vcpu *vcpu, u64 regs_ptr) | ||
199 | { | ||
200 | /* No need to reflect the page fault to L1, we've handled it */ | ||
201 | vcpu->arch.trap = 0; | ||
202 | |||
203 | /* | ||
204 | * Since the L2 gprs have already been written back into L1 memory when | ||
205 | * we complete the mmio, store the L1 memory location of the L2 gpr | ||
206 | * being loaded into by the mmio so that the loaded value can be | ||
207 | * written there in kvmppc_complete_mmio_load() | ||
208 | */ | ||
209 | if (((vcpu->arch.io_gpr & KVM_MMIO_REG_EXT_MASK) == KVM_MMIO_REG_GPR) | ||
210 | && (vcpu->mmio_is_write == 0)) { | ||
211 | vcpu->arch.nested_io_gpr = (gpa_t) regs_ptr + | ||
212 | offsetof(struct pt_regs, | ||
213 | gpr[vcpu->arch.io_gpr]); | ||
214 | vcpu->arch.io_gpr = KVM_MMIO_REG_NESTED_GPR; | ||
215 | } | ||
216 | } | ||
217 | |||
198 | long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu) | 218 | long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu) |
199 | { | 219 | { |
200 | long int err, r; | 220 | long int err, r; |
@@ -316,6 +336,11 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu) | |||
316 | if (r == -EINTR) | 336 | if (r == -EINTR) |
317 | return H_INTERRUPT; | 337 | return H_INTERRUPT; |
318 | 338 | ||
339 | if (vcpu->mmio_needed) { | ||
340 | kvmhv_nested_mmio_needed(vcpu, regs_ptr); | ||
341 | return H_TOO_HARD; | ||
342 | } | ||
343 | |||
319 | return vcpu->arch.trap; | 344 | return vcpu->arch.trap; |
320 | } | 345 | } |
321 | 346 | ||
@@ -437,6 +462,81 @@ long kvmhv_set_partition_table(struct kvm_vcpu *vcpu) | |||
437 | } | 462 | } |
438 | 463 | ||
439 | /* | 464 | /* |
465 | * Handle the H_COPY_TOFROM_GUEST hcall. | ||
466 | * r4 = L1 lpid of nested guest | ||
467 | * r5 = pid | ||
468 | * r6 = eaddr to access | ||
469 | * r7 = to buffer (L1 gpa) | ||
470 | * r8 = from buffer (L1 gpa) | ||
471 | * r9 = n bytes to copy | ||
472 | */ | ||
473 | long kvmhv_copy_tofrom_guest_nested(struct kvm_vcpu *vcpu) | ||
474 | { | ||
475 | struct kvm_nested_guest *gp; | ||
476 | int l1_lpid = kvmppc_get_gpr(vcpu, 4); | ||
477 | int pid = kvmppc_get_gpr(vcpu, 5); | ||
478 | gva_t eaddr = kvmppc_get_gpr(vcpu, 6); | ||
479 | gpa_t gp_to = (gpa_t) kvmppc_get_gpr(vcpu, 7); | ||
480 | gpa_t gp_from = (gpa_t) kvmppc_get_gpr(vcpu, 8); | ||
481 | void *buf; | ||
482 | unsigned long n = kvmppc_get_gpr(vcpu, 9); | ||
483 | bool is_load = !!gp_to; | ||
484 | long rc; | ||
485 | |||
486 | if (gp_to && gp_from) /* One must be NULL to determine the direction */ | ||
487 | return H_PARAMETER; | ||
488 | |||
489 | if (eaddr & (0xFFFUL << 52)) | ||
490 | return H_PARAMETER; | ||
491 | |||
492 | buf = kzalloc(n, GFP_KERNEL); | ||
493 | if (!buf) | ||
494 | return H_NO_MEM; | ||
495 | |||
496 | gp = kvmhv_get_nested(vcpu->kvm, l1_lpid, false); | ||
497 | if (!gp) { | ||
498 | rc = H_PARAMETER; | ||
499 | goto out_free; | ||
500 | } | ||
501 | |||
502 | mutex_lock(&gp->tlb_lock); | ||
503 | |||
504 | if (is_load) { | ||
505 | /* Load from the nested guest into our buffer */ | ||
506 | rc = __kvmhv_copy_tofrom_guest_radix(gp->shadow_lpid, pid, | ||
507 | eaddr, buf, NULL, n); | ||
508 | if (rc) | ||
509 | goto not_found; | ||
510 | |||
511 | /* Write what was loaded into our buffer back to the L1 guest */ | ||
512 | rc = kvm_vcpu_write_guest(vcpu, gp_to, buf, n); | ||
513 | if (rc) | ||
514 | goto not_found; | ||
515 | } else { | ||
516 | /* Load the data to be stored from the L1 guest into our buf */ | ||
517 | rc = kvm_vcpu_read_guest(vcpu, gp_from, buf, n); | ||
518 | if (rc) | ||
519 | goto not_found; | ||
520 | |||
521 | /* Store from our buffer into the nested guest */ | ||
522 | rc = __kvmhv_copy_tofrom_guest_radix(gp->shadow_lpid, pid, | ||
523 | eaddr, NULL, buf, n); | ||
524 | if (rc) | ||
525 | goto not_found; | ||
526 | } | ||
527 | |||
528 | out_unlock: | ||
529 | mutex_unlock(&gp->tlb_lock); | ||
530 | kvmhv_put_nested(gp); | ||
531 | out_free: | ||
532 | kfree(buf); | ||
533 | return rc; | ||
534 | not_found: | ||
535 | rc = H_NOT_FOUND; | ||
536 | goto out_unlock; | ||
537 | } | ||
538 | |||
539 | /* | ||
440 | * Reload the partition table entry for a guest. | 540 | * Reload the partition table entry for a guest. |
441 | * Caller must hold gp->tlb_lock. | 541 | * Caller must hold gp->tlb_lock. |
442 | */ | 542 | */ |
@@ -480,6 +580,7 @@ struct kvm_nested_guest *kvmhv_alloc_nested(struct kvm *kvm, unsigned int lpid) | |||
480 | if (shadow_lpid < 0) | 580 | if (shadow_lpid < 0) |
481 | goto out_free2; | 581 | goto out_free2; |
482 | gp->shadow_lpid = shadow_lpid; | 582 | gp->shadow_lpid = shadow_lpid; |
583 | gp->radix = 1; | ||
483 | 584 | ||
484 | memset(gp->prev_cpu, -1, sizeof(gp->prev_cpu)); | 585 | memset(gp->prev_cpu, -1, sizeof(gp->prev_cpu)); |
485 | 586 | ||
@@ -687,6 +788,57 @@ void kvmhv_insert_nest_rmap(struct kvm *kvm, unsigned long *rmapp, | |||
687 | *n_rmap = NULL; | 788 | *n_rmap = NULL; |
688 | } | 789 | } |
689 | 790 | ||
791 | static void kvmhv_update_nest_rmap_rc(struct kvm *kvm, u64 n_rmap, | ||
792 | unsigned long clr, unsigned long set, | ||
793 | unsigned long hpa, unsigned long mask) | ||
794 | { | ||
795 | struct kvm_nested_guest *gp; | ||
796 | unsigned long gpa; | ||
797 | unsigned int shift, lpid; | ||
798 | pte_t *ptep; | ||
799 | |||
800 | gpa = n_rmap & RMAP_NESTED_GPA_MASK; | ||
801 | lpid = (n_rmap & RMAP_NESTED_LPID_MASK) >> RMAP_NESTED_LPID_SHIFT; | ||
802 | gp = kvmhv_find_nested(kvm, lpid); | ||
803 | if (!gp) | ||
804 | return; | ||
805 | |||
806 | /* Find the pte */ | ||
807 | ptep = __find_linux_pte(gp->shadow_pgtable, gpa, NULL, &shift); | ||
808 | /* | ||
809 | * If the pte is present and the pfn is still the same, update the pte. | ||
810 | * If the pfn has changed then this is a stale rmap entry, the nested | ||
811 | * gpa actually points somewhere else now, and there is nothing to do. | ||
812 | * XXX A future optimisation would be to remove the rmap entry here. | ||
813 | */ | ||
814 | if (ptep && pte_present(*ptep) && ((pte_val(*ptep) & mask) == hpa)) { | ||
815 | __radix_pte_update(ptep, clr, set); | ||
816 | kvmppc_radix_tlbie_page(kvm, gpa, shift, lpid); | ||
817 | } | ||
818 | } | ||
819 | |||
820 | /* | ||
821 | * For a given list of rmap entries, update the rc bits in all ptes in shadow | ||
822 | * page tables for nested guests which are referenced by the rmap list. | ||
823 | */ | ||
824 | void kvmhv_update_nest_rmap_rc_list(struct kvm *kvm, unsigned long *rmapp, | ||
825 | unsigned long clr, unsigned long set, | ||
826 | unsigned long hpa, unsigned long nbytes) | ||
827 | { | ||
828 | struct llist_node *entry = ((struct llist_head *) rmapp)->first; | ||
829 | struct rmap_nested *cursor; | ||
830 | unsigned long rmap, mask; | ||
831 | |||
832 | if ((clr | set) & ~(_PAGE_DIRTY | _PAGE_ACCESSED)) | ||
833 | return; | ||
834 | |||
835 | mask = PTE_RPN_MASK & ~(nbytes - 1); | ||
836 | hpa &= mask; | ||
837 | |||
838 | for_each_nest_rmap_safe(cursor, entry, &rmap) | ||
839 | kvmhv_update_nest_rmap_rc(kvm, rmap, clr, set, hpa, mask); | ||
840 | } | ||
841 | |||
690 | static void kvmhv_remove_nest_rmap(struct kvm *kvm, u64 n_rmap, | 842 | static void kvmhv_remove_nest_rmap(struct kvm *kvm, u64 n_rmap, |
691 | unsigned long hpa, unsigned long mask) | 843 | unsigned long hpa, unsigned long mask) |
692 | { | 844 | { |
@@ -723,7 +875,7 @@ static void kvmhv_remove_nest_rmap_list(struct kvm *kvm, unsigned long *rmapp, | |||
723 | 875 | ||
724 | /* called with kvm->mmu_lock held */ | 876 | /* called with kvm->mmu_lock held */ |
725 | void kvmhv_remove_nest_rmap_range(struct kvm *kvm, | 877 | void kvmhv_remove_nest_rmap_range(struct kvm *kvm, |
726 | struct kvm_memory_slot *memslot, | 878 | const struct kvm_memory_slot *memslot, |
727 | unsigned long gpa, unsigned long hpa, | 879 | unsigned long gpa, unsigned long hpa, |
728 | unsigned long nbytes) | 880 | unsigned long nbytes) |
729 | { | 881 | { |
@@ -1049,7 +1201,7 @@ static long kvmhv_handle_nested_set_rc(struct kvm_vcpu *vcpu, | |||
1049 | struct kvm *kvm = vcpu->kvm; | 1201 | struct kvm *kvm = vcpu->kvm; |
1050 | bool writing = !!(dsisr & DSISR_ISSTORE); | 1202 | bool writing = !!(dsisr & DSISR_ISSTORE); |
1051 | u64 pgflags; | 1203 | u64 pgflags; |
1052 | bool ret; | 1204 | long ret; |
1053 | 1205 | ||
1054 | /* Are the rc bits set in the L1 partition scoped pte? */ | 1206 | /* Are the rc bits set in the L1 partition scoped pte? */ |
1055 | pgflags = _PAGE_ACCESSED; | 1207 | pgflags = _PAGE_ACCESSED; |
@@ -1062,16 +1214,22 @@ static long kvmhv_handle_nested_set_rc(struct kvm_vcpu *vcpu, | |||
1062 | /* Set the rc bit in the pte of our (L0) pgtable for the L1 guest */ | 1214 | /* Set the rc bit in the pte of our (L0) pgtable for the L1 guest */ |
1063 | ret = kvmppc_hv_handle_set_rc(kvm, kvm->arch.pgtable, writing, | 1215 | ret = kvmppc_hv_handle_set_rc(kvm, kvm->arch.pgtable, writing, |
1064 | gpte.raddr, kvm->arch.lpid); | 1216 | gpte.raddr, kvm->arch.lpid); |
1065 | spin_unlock(&kvm->mmu_lock); | 1217 | if (!ret) { |
1066 | if (!ret) | 1218 | ret = -EINVAL; |
1067 | return -EINVAL; | 1219 | goto out_unlock; |
1220 | } | ||
1068 | 1221 | ||
1069 | /* Set the rc bit in the pte of the shadow_pgtable for the nest guest */ | 1222 | /* Set the rc bit in the pte of the shadow_pgtable for the nest guest */ |
1070 | ret = kvmppc_hv_handle_set_rc(kvm, gp->shadow_pgtable, writing, n_gpa, | 1223 | ret = kvmppc_hv_handle_set_rc(kvm, gp->shadow_pgtable, writing, n_gpa, |
1071 | gp->shadow_lpid); | 1224 | gp->shadow_lpid); |
1072 | if (!ret) | 1225 | if (!ret) |
1073 | return -EINVAL; | 1226 | ret = -EINVAL; |
1074 | return 0; | 1227 | else |
1228 | ret = 0; | ||
1229 | |||
1230 | out_unlock: | ||
1231 | spin_unlock(&kvm->mmu_lock); | ||
1232 | return ret; | ||
1075 | } | 1233 | } |
1076 | 1234 | ||
1077 | static inline int kvmppc_radix_level_to_shift(int level) | 1235 | static inline int kvmppc_radix_level_to_shift(int level) |
@@ -1099,7 +1257,8 @@ static inline int kvmppc_radix_shift_to_level(int shift) | |||
1099 | } | 1257 | } |
1100 | 1258 | ||
1101 | /* called with gp->tlb_lock held */ | 1259 | /* called with gp->tlb_lock held */ |
1102 | static long int __kvmhv_nested_page_fault(struct kvm_vcpu *vcpu, | 1260 | static long int __kvmhv_nested_page_fault(struct kvm_run *run, |
1261 | struct kvm_vcpu *vcpu, | ||
1103 | struct kvm_nested_guest *gp) | 1262 | struct kvm_nested_guest *gp) |
1104 | { | 1263 | { |
1105 | struct kvm *kvm = vcpu->kvm; | 1264 | struct kvm *kvm = vcpu->kvm; |
@@ -1180,9 +1339,9 @@ static long int __kvmhv_nested_page_fault(struct kvm_vcpu *vcpu, | |||
1180 | kvmppc_core_queue_data_storage(vcpu, ea, dsisr); | 1339 | kvmppc_core_queue_data_storage(vcpu, ea, dsisr); |
1181 | return RESUME_GUEST; | 1340 | return RESUME_GUEST; |
1182 | } | 1341 | } |
1183 | /* passthrough of emulated MMIO case... */ | 1342 | |
1184 | pr_err("emulated MMIO passthrough?\n"); | 1343 | /* passthrough of emulated MMIO case */ |
1185 | return -EINVAL; | 1344 | return kvmppc_hv_emulate_mmio(run, vcpu, gpa, ea, writing); |
1186 | } | 1345 | } |
1187 | if (memslot->flags & KVM_MEM_READONLY) { | 1346 | if (memslot->flags & KVM_MEM_READONLY) { |
1188 | if (writing) { | 1347 | if (writing) { |
@@ -1220,6 +1379,8 @@ static long int __kvmhv_nested_page_fault(struct kvm_vcpu *vcpu, | |||
1220 | return ret; | 1379 | return ret; |
1221 | shift = kvmppc_radix_level_to_shift(level); | 1380 | shift = kvmppc_radix_level_to_shift(level); |
1222 | } | 1381 | } |
1382 | /* Align gfn to the start of the page */ | ||
1383 | gfn = (gpa & ~((1UL << shift) - 1)) >> PAGE_SHIFT; | ||
1223 | 1384 | ||
1224 | /* 3. Compute the pte we need to insert for nest_gpa -> host r_addr */ | 1385 | /* 3. Compute the pte we need to insert for nest_gpa -> host r_addr */ |
1225 | 1386 | ||
@@ -1227,6 +1388,9 @@ static long int __kvmhv_nested_page_fault(struct kvm_vcpu *vcpu, | |||
1227 | perm |= gpte.may_read ? 0UL : _PAGE_READ; | 1388 | perm |= gpte.may_read ? 0UL : _PAGE_READ; |
1228 | perm |= gpte.may_write ? 0UL : _PAGE_WRITE; | 1389 | perm |= gpte.may_write ? 0UL : _PAGE_WRITE; |
1229 | perm |= gpte.may_execute ? 0UL : _PAGE_EXEC; | 1390 | perm |= gpte.may_execute ? 0UL : _PAGE_EXEC; |
1391 | /* Only set accessed/dirty (rc) bits if set in host and l1 guest ptes */ | ||
1392 | perm |= (gpte.rc & _PAGE_ACCESSED) ? 0UL : _PAGE_ACCESSED; | ||
1393 | perm |= ((gpte.rc & _PAGE_DIRTY) && writing) ? 0UL : _PAGE_DIRTY; | ||
1230 | pte = __pte(pte_val(pte) & ~perm); | 1394 | pte = __pte(pte_val(pte) & ~perm); |
1231 | 1395 | ||
1232 | /* What size pte can we insert? */ | 1396 | /* What size pte can we insert? */ |
@@ -1264,13 +1428,13 @@ static long int __kvmhv_nested_page_fault(struct kvm_vcpu *vcpu, | |||
1264 | return RESUME_GUEST; | 1428 | return RESUME_GUEST; |
1265 | } | 1429 | } |
1266 | 1430 | ||
1267 | long int kvmhv_nested_page_fault(struct kvm_vcpu *vcpu) | 1431 | long int kvmhv_nested_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu) |
1268 | { | 1432 | { |
1269 | struct kvm_nested_guest *gp = vcpu->arch.nested; | 1433 | struct kvm_nested_guest *gp = vcpu->arch.nested; |
1270 | long int ret; | 1434 | long int ret; |
1271 | 1435 | ||
1272 | mutex_lock(&gp->tlb_lock); | 1436 | mutex_lock(&gp->tlb_lock); |
1273 | ret = __kvmhv_nested_page_fault(vcpu, gp); | 1437 | ret = __kvmhv_nested_page_fault(run, vcpu, gp); |
1274 | mutex_unlock(&gp->tlb_lock); | 1438 | mutex_unlock(&gp->tlb_lock); |
1275 | return ret; | 1439 | return ret; |
1276 | } | 1440 | } |
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index a67cf1cdeda4..3b3791ed74a6 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c | |||
@@ -107,7 +107,7 @@ void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev, | |||
107 | EXPORT_SYMBOL_GPL(kvmppc_add_revmap_chain); | 107 | EXPORT_SYMBOL_GPL(kvmppc_add_revmap_chain); |
108 | 108 | ||
109 | /* Update the dirty bitmap of a memslot */ | 109 | /* Update the dirty bitmap of a memslot */ |
110 | void kvmppc_update_dirty_map(struct kvm_memory_slot *memslot, | 110 | void kvmppc_update_dirty_map(const struct kvm_memory_slot *memslot, |
111 | unsigned long gfn, unsigned long psize) | 111 | unsigned long gfn, unsigned long psize) |
112 | { | 112 | { |
113 | unsigned long npages; | 113 | unsigned long npages; |
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 4efd65d9e828..811a3c2fb0e9 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c | |||
@@ -587,6 +587,7 @@ void kvmppc_set_pvr_pr(struct kvm_vcpu *vcpu, u32 pvr) | |||
587 | case PVR_POWER8: | 587 | case PVR_POWER8: |
588 | case PVR_POWER8E: | 588 | case PVR_POWER8E: |
589 | case PVR_POWER8NVL: | 589 | case PVR_POWER8NVL: |
590 | case PVR_POWER9: | ||
590 | vcpu->arch.hflags |= BOOK3S_HFLAG_MULTI_PGSIZE | | 591 | vcpu->arch.hflags |= BOOK3S_HFLAG_MULTI_PGSIZE | |
591 | BOOK3S_HFLAG_NEW_TLBIE; | 592 | BOOK3S_HFLAG_NEW_TLBIE; |
592 | break; | 593 | break; |
@@ -1913,7 +1914,8 @@ static int kvmppc_core_prepare_memory_region_pr(struct kvm *kvm, | |||
1913 | static void kvmppc_core_commit_memory_region_pr(struct kvm *kvm, | 1914 | static void kvmppc_core_commit_memory_region_pr(struct kvm *kvm, |
1914 | const struct kvm_userspace_memory_region *mem, | 1915 | const struct kvm_userspace_memory_region *mem, |
1915 | const struct kvm_memory_slot *old, | 1916 | const struct kvm_memory_slot *old, |
1916 | const struct kvm_memory_slot *new) | 1917 | const struct kvm_memory_slot *new, |
1918 | enum kvm_mr_change change) | ||
1917 | { | 1919 | { |
1918 | return; | 1920 | return; |
1919 | } | 1921 | } |
diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index b0b2bfc2ff51..f27ee57ab46e 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c | |||
@@ -1015,17 +1015,7 @@ static int xics_debug_show(struct seq_file *m, void *private) | |||
1015 | return 0; | 1015 | return 0; |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | static int xics_debug_open(struct inode *inode, struct file *file) | 1018 | DEFINE_SHOW_ATTRIBUTE(xics_debug); |
1019 | { | ||
1020 | return single_open(file, xics_debug_show, inode->i_private); | ||
1021 | } | ||
1022 | |||
1023 | static const struct file_operations xics_debug_fops = { | ||
1024 | .open = xics_debug_open, | ||
1025 | .read = seq_read, | ||
1026 | .llseek = seq_lseek, | ||
1027 | .release = single_release, | ||
1028 | }; | ||
1029 | 1019 | ||
1030 | static void xics_debugfs_init(struct kvmppc_xics *xics) | 1020 | static void xics_debugfs_init(struct kvmppc_xics *xics) |
1031 | { | 1021 | { |
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index ad4a370703d3..f78d002f0fe0 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c | |||
@@ -1968,17 +1968,7 @@ static int xive_debug_show(struct seq_file *m, void *private) | |||
1968 | return 0; | 1968 | return 0; |
1969 | } | 1969 | } |
1970 | 1970 | ||
1971 | static int xive_debug_open(struct inode *inode, struct file *file) | 1971 | DEFINE_SHOW_ATTRIBUTE(xive_debug); |
1972 | { | ||
1973 | return single_open(file, xive_debug_show, inode->i_private); | ||
1974 | } | ||
1975 | |||
1976 | static const struct file_operations xive_debug_fops = { | ||
1977 | .open = xive_debug_open, | ||
1978 | .read = seq_read, | ||
1979 | .llseek = seq_lseek, | ||
1980 | .release = single_release, | ||
1981 | }; | ||
1982 | 1972 | ||
1983 | static void xive_debugfs_init(struct kvmppc_xive *xive) | 1973 | static void xive_debugfs_init(struct kvmppc_xive *xive) |
1984 | { | 1974 | { |
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index a9ca016da670..dbec4128bb51 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c | |||
@@ -1833,7 +1833,8 @@ int kvmppc_core_prepare_memory_region(struct kvm *kvm, | |||
1833 | void kvmppc_core_commit_memory_region(struct kvm *kvm, | 1833 | void kvmppc_core_commit_memory_region(struct kvm *kvm, |
1834 | const struct kvm_userspace_memory_region *mem, | 1834 | const struct kvm_userspace_memory_region *mem, |
1835 | const struct kvm_memory_slot *old, | 1835 | const struct kvm_memory_slot *old, |
1836 | const struct kvm_memory_slot *new) | 1836 | const struct kvm_memory_slot *new, |
1837 | enum kvm_mr_change change) | ||
1837 | { | 1838 | { |
1838 | } | 1839 | } |
1839 | 1840 | ||
diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c index 8f2985e46f6f..c3f312b2bcb3 100644 --- a/arch/powerpc/kvm/e500_mmu_host.c +++ b/arch/powerpc/kvm/e500_mmu_host.c | |||
@@ -757,10 +757,11 @@ int kvm_test_age_hva(struct kvm *kvm, unsigned long hva) | |||
757 | return 0; | 757 | return 0; |
758 | } | 758 | } |
759 | 759 | ||
760 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) | 760 | int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) |
761 | { | 761 | { |
762 | /* The page will get remapped properly on its next fault */ | 762 | /* The page will get remapped properly on its next fault */ |
763 | kvm_unmap_hva(kvm, hva); | 763 | kvm_unmap_hva(kvm, hva); |
764 | return 0; | ||
764 | } | 765 | } |
765 | 766 | ||
766 | /*****************************************/ | 767 | /*****************************************/ |
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 2869a299c4ed..b90a7d154180 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c | |||
@@ -331,10 +331,17 @@ int kvmppc_st(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | |||
331 | { | 331 | { |
332 | ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM & PAGE_MASK; | 332 | ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM & PAGE_MASK; |
333 | struct kvmppc_pte pte; | 333 | struct kvmppc_pte pte; |
334 | int r; | 334 | int r = -EINVAL; |
335 | 335 | ||
336 | vcpu->stat.st++; | 336 | vcpu->stat.st++; |
337 | 337 | ||
338 | if (vcpu->kvm->arch.kvm_ops && vcpu->kvm->arch.kvm_ops->store_to_eaddr) | ||
339 | r = vcpu->kvm->arch.kvm_ops->store_to_eaddr(vcpu, eaddr, ptr, | ||
340 | size); | ||
341 | |||
342 | if ((!r) || (r == -EAGAIN)) | ||
343 | return r; | ||
344 | |||
338 | r = kvmppc_xlate(vcpu, *eaddr, data ? XLATE_DATA : XLATE_INST, | 345 | r = kvmppc_xlate(vcpu, *eaddr, data ? XLATE_DATA : XLATE_INST, |
339 | XLATE_WRITE, &pte); | 346 | XLATE_WRITE, &pte); |
340 | if (r < 0) | 347 | if (r < 0) |
@@ -367,10 +374,17 @@ int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr, | |||
367 | { | 374 | { |
368 | ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM & PAGE_MASK; | 375 | ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM & PAGE_MASK; |
369 | struct kvmppc_pte pte; | 376 | struct kvmppc_pte pte; |
370 | int rc; | 377 | int rc = -EINVAL; |
371 | 378 | ||
372 | vcpu->stat.ld++; | 379 | vcpu->stat.ld++; |
373 | 380 | ||
381 | if (vcpu->kvm->arch.kvm_ops && vcpu->kvm->arch.kvm_ops->load_from_eaddr) | ||
382 | rc = vcpu->kvm->arch.kvm_ops->load_from_eaddr(vcpu, eaddr, ptr, | ||
383 | size); | ||
384 | |||
385 | if ((!rc) || (rc == -EAGAIN)) | ||
386 | return rc; | ||
387 | |||
374 | rc = kvmppc_xlate(vcpu, *eaddr, data ? XLATE_DATA : XLATE_INST, | 388 | rc = kvmppc_xlate(vcpu, *eaddr, data ? XLATE_DATA : XLATE_INST, |
375 | XLATE_READ, &pte); | 389 | XLATE_READ, &pte); |
376 | if (rc) | 390 | if (rc) |
@@ -518,7 +532,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | |||
518 | case KVM_CAP_PPC_UNSET_IRQ: | 532 | case KVM_CAP_PPC_UNSET_IRQ: |
519 | case KVM_CAP_PPC_IRQ_LEVEL: | 533 | case KVM_CAP_PPC_IRQ_LEVEL: |
520 | case KVM_CAP_ENABLE_CAP: | 534 | case KVM_CAP_ENABLE_CAP: |
521 | case KVM_CAP_ENABLE_CAP_VM: | ||
522 | case KVM_CAP_ONE_REG: | 535 | case KVM_CAP_ONE_REG: |
523 | case KVM_CAP_IOEVENTFD: | 536 | case KVM_CAP_IOEVENTFD: |
524 | case KVM_CAP_DEVICE_CTRL: | 537 | case KVM_CAP_DEVICE_CTRL: |
@@ -543,8 +556,11 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | |||
543 | #ifdef CONFIG_PPC_BOOK3S_64 | 556 | #ifdef CONFIG_PPC_BOOK3S_64 |
544 | case KVM_CAP_SPAPR_TCE: | 557 | case KVM_CAP_SPAPR_TCE: |
545 | case KVM_CAP_SPAPR_TCE_64: | 558 | case KVM_CAP_SPAPR_TCE_64: |
546 | /* fallthrough */ | 559 | r = 1; |
560 | break; | ||
547 | case KVM_CAP_SPAPR_TCE_VFIO: | 561 | case KVM_CAP_SPAPR_TCE_VFIO: |
562 | r = !!cpu_has_feature(CPU_FTR_HVMODE); | ||
563 | break; | ||
548 | case KVM_CAP_PPC_RTAS: | 564 | case KVM_CAP_PPC_RTAS: |
549 | case KVM_CAP_PPC_FIXUP_HCALL: | 565 | case KVM_CAP_PPC_FIXUP_HCALL: |
550 | case KVM_CAP_PPC_ENABLE_HCALL: | 566 | case KVM_CAP_PPC_ENABLE_HCALL: |
@@ -696,7 +712,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, | |||
696 | const struct kvm_memory_slot *new, | 712 | const struct kvm_memory_slot *new, |
697 | enum kvm_mr_change change) | 713 | enum kvm_mr_change change) |
698 | { | 714 | { |
699 | kvmppc_core_commit_memory_region(kvm, mem, old, new); | 715 | kvmppc_core_commit_memory_region(kvm, mem, old, new, change); |
700 | } | 716 | } |
701 | 717 | ||
702 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, | 718 | void kvm_arch_flush_shadow_memslot(struct kvm *kvm, |
@@ -1192,6 +1208,14 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu, | |||
1192 | kvmppc_set_vmx_byte(vcpu, gpr); | 1208 | kvmppc_set_vmx_byte(vcpu, gpr); |
1193 | break; | 1209 | break; |
1194 | #endif | 1210 | #endif |
1211 | #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE | ||
1212 | case KVM_MMIO_REG_NESTED_GPR: | ||
1213 | if (kvmppc_need_byteswap(vcpu)) | ||
1214 | gpr = swab64(gpr); | ||
1215 | kvm_vcpu_write_guest(vcpu, vcpu->arch.nested_io_gpr, &gpr, | ||
1216 | sizeof(gpr)); | ||
1217 | break; | ||
1218 | #endif | ||
1195 | default: | 1219 | default: |
1196 | BUG(); | 1220 | BUG(); |
1197 | } | 1221 | } |
@@ -2084,8 +2108,8 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event, | |||
2084 | } | 2108 | } |
2085 | 2109 | ||
2086 | 2110 | ||
2087 | static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, | 2111 | int kvm_vm_ioctl_enable_cap(struct kvm *kvm, |
2088 | struct kvm_enable_cap *cap) | 2112 | struct kvm_enable_cap *cap) |
2089 | { | 2113 | { |
2090 | int r; | 2114 | int r; |
2091 | 2115 | ||
@@ -2273,15 +2297,6 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
2273 | 2297 | ||
2274 | break; | 2298 | break; |
2275 | } | 2299 | } |
2276 | case KVM_ENABLE_CAP: | ||
2277 | { | ||
2278 | struct kvm_enable_cap cap; | ||
2279 | r = -EFAULT; | ||
2280 | if (copy_from_user(&cap, argp, sizeof(cap))) | ||
2281 | goto out; | ||
2282 | r = kvm_vm_ioctl_enable_cap(kvm, &cap); | ||
2283 | break; | ||
2284 | } | ||
2285 | #ifdef CONFIG_SPAPR_TCE_IOMMU | 2300 | #ifdef CONFIG_SPAPR_TCE_IOMMU |
2286 | case KVM_CREATE_SPAPR_TCE_64: { | 2301 | case KVM_CREATE_SPAPR_TCE_64: { |
2287 | struct kvm_create_spapr_tce_64 create_tce_64; | 2302 | struct kvm_create_spapr_tce_64 create_tce_64; |
diff --git a/arch/powerpc/mm/dump_linuxpagetables.c b/arch/powerpc/mm/dump_linuxpagetables.c index 2b74f8adf4d0..6aa41669ac1a 100644 --- a/arch/powerpc/mm/dump_linuxpagetables.c +++ b/arch/powerpc/mm/dump_linuxpagetables.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/hugetlb.h> | 19 | #include <linux/hugetlb.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
22 | #include <linux/highmem.h> | ||
22 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
23 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
24 | #include <asm/fixmap.h> | 25 | #include <asm/fixmap.h> |
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 1697e903bbf2..2e6fb1d758c3 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c | |||
@@ -636,6 +636,7 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) | |||
636 | switch (TRAP(regs)) { | 636 | switch (TRAP(regs)) { |
637 | case 0x300: | 637 | case 0x300: |
638 | case 0x380: | 638 | case 0x380: |
639 | case 0xe00: | ||
639 | printk(KERN_ALERT "Unable to handle kernel paging request for " | 640 | printk(KERN_ALERT "Unable to handle kernel paging request for " |
640 | "data at address 0x%08lx\n", regs->dar); | 641 | "data at address 0x%08lx\n", regs->dar); |
641 | break; | 642 | break; |
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 8cf035e68378..4c01e9a01a74 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c | |||
@@ -289,7 +289,7 @@ static void hugepd_free(struct mmu_gather *tlb, void *hugepte) | |||
289 | 289 | ||
290 | (*batchp)->ptes[(*batchp)->index++] = hugepte; | 290 | (*batchp)->ptes[(*batchp)->index++] = hugepte; |
291 | if ((*batchp)->index == HUGEPD_FREELIST_SIZE) { | 291 | if ((*batchp)->index == HUGEPD_FREELIST_SIZE) { |
292 | call_rcu_sched(&(*batchp)->rcu, hugepd_free_rcu_callback); | 292 | call_rcu(&(*batchp)->rcu, hugepd_free_rcu_callback); |
293 | *batchp = NULL; | 293 | *batchp = NULL; |
294 | } | 294 | } |
295 | put_cpu_var(hugepd_freelist_cur); | 295 | put_cpu_var(hugepd_freelist_cur); |
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 7a9886f98b0c..a5091c034747 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c | |||
@@ -188,15 +188,20 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, | |||
188 | pr_debug("vmemmap_populate %lx..%lx, node %d\n", start, end, node); | 188 | pr_debug("vmemmap_populate %lx..%lx, node %d\n", start, end, node); |
189 | 189 | ||
190 | for (; start < end; start += page_size) { | 190 | for (; start < end; start += page_size) { |
191 | void *p; | 191 | void *p = NULL; |
192 | int rc; | 192 | int rc; |
193 | 193 | ||
194 | if (vmemmap_populated(start, page_size)) | 194 | if (vmemmap_populated(start, page_size)) |
195 | continue; | 195 | continue; |
196 | 196 | ||
197 | /* | ||
198 | * Allocate from the altmap first if we have one. This may | ||
199 | * fail due to alignment issues when using 16MB hugepages, so | ||
200 | * fall back to system memory if the altmap allocation fail. | ||
201 | */ | ||
197 | if (altmap) | 202 | if (altmap) |
198 | p = altmap_alloc_block_buf(page_size, altmap); | 203 | p = altmap_alloc_block_buf(page_size, altmap); |
199 | else | 204 | if (!p) |
200 | p = vmemmap_alloc_block_buf(page_size, node); | 205 | p = vmemmap_alloc_block_buf(page_size, node); |
201 | if (!p) | 206 | if (!p) |
202 | return -ENOMEM; | 207 | return -ENOMEM; |
@@ -255,8 +260,15 @@ void __ref vmemmap_free(unsigned long start, unsigned long end, | |||
255 | { | 260 | { |
256 | unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift; | 261 | unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift; |
257 | unsigned long page_order = get_order(page_size); | 262 | unsigned long page_order = get_order(page_size); |
263 | unsigned long alt_start = ~0, alt_end = ~0; | ||
264 | unsigned long base_pfn; | ||
258 | 265 | ||
259 | start = _ALIGN_DOWN(start, page_size); | 266 | start = _ALIGN_DOWN(start, page_size); |
267 | if (altmap) { | ||
268 | alt_start = altmap->base_pfn; | ||
269 | alt_end = altmap->base_pfn + altmap->reserve + | ||
270 | altmap->free + altmap->alloc + altmap->align; | ||
271 | } | ||
260 | 272 | ||
261 | pr_debug("vmemmap_free %lx...%lx\n", start, end); | 273 | pr_debug("vmemmap_free %lx...%lx\n", start, end); |
262 | 274 | ||
@@ -280,8 +292,9 @@ void __ref vmemmap_free(unsigned long start, unsigned long end, | |||
280 | page = pfn_to_page(addr >> PAGE_SHIFT); | 292 | page = pfn_to_page(addr >> PAGE_SHIFT); |
281 | section_base = pfn_to_page(vmemmap_section_start(start)); | 293 | section_base = pfn_to_page(vmemmap_section_start(start)); |
282 | nr_pages = 1 << page_order; | 294 | nr_pages = 1 << page_order; |
295 | base_pfn = PHYS_PFN(addr); | ||
283 | 296 | ||
284 | if (altmap) { | 297 | if (base_pfn >= alt_start && base_pfn < alt_end) { |
285 | vmem_altmap_free(altmap, nr_pages); | 298 | vmem_altmap_free(altmap, nr_pages); |
286 | } else if (PageReserved(page)) { | 299 | } else if (PageReserved(page)) { |
287 | /* allocated from bootmem */ | 300 | /* allocated from bootmem */ |
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c index 17482f5de3e2..9393e231cbc2 100644 --- a/arch/powerpc/net/bpf_jit_comp64.c +++ b/arch/powerpc/net/bpf_jit_comp64.c | |||
@@ -891,6 +891,55 @@ cond_branch: | |||
891 | return 0; | 891 | return 0; |
892 | } | 892 | } |
893 | 893 | ||
894 | /* Fix the branch target addresses for subprog calls */ | ||
895 | static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image, | ||
896 | struct codegen_context *ctx, u32 *addrs) | ||
897 | { | ||
898 | const struct bpf_insn *insn = fp->insnsi; | ||
899 | bool func_addr_fixed; | ||
900 | u64 func_addr; | ||
901 | u32 tmp_idx; | ||
902 | int i, ret; | ||
903 | |||
904 | for (i = 0; i < fp->len; i++) { | ||
905 | /* | ||
906 | * During the extra pass, only the branch target addresses for | ||
907 | * the subprog calls need to be fixed. All other instructions | ||
908 | * can left untouched. | ||
909 | * | ||
910 | * The JITed image length does not change because we already | ||
911 | * ensure that the JITed instruction sequence for these calls | ||
912 | * are of fixed length by padding them with NOPs. | ||
913 | */ | ||
914 | if (insn[i].code == (BPF_JMP | BPF_CALL) && | ||
915 | insn[i].src_reg == BPF_PSEUDO_CALL) { | ||
916 | ret = bpf_jit_get_func_addr(fp, &insn[i], true, | ||
917 | &func_addr, | ||
918 | &func_addr_fixed); | ||
919 | if (ret < 0) | ||
920 | return ret; | ||
921 | |||
922 | /* | ||
923 | * Save ctx->idx as this would currently point to the | ||
924 | * end of the JITed image and set it to the offset of | ||
925 | * the instruction sequence corresponding to the | ||
926 | * subprog call temporarily. | ||
927 | */ | ||
928 | tmp_idx = ctx->idx; | ||
929 | ctx->idx = addrs[i] / 4; | ||
930 | bpf_jit_emit_func_call_rel(image, ctx, func_addr); | ||
931 | |||
932 | /* | ||
933 | * Restore ctx->idx here. This is safe as the length | ||
934 | * of the JITed sequence remains unchanged. | ||
935 | */ | ||
936 | ctx->idx = tmp_idx; | ||
937 | } | ||
938 | } | ||
939 | |||
940 | return 0; | ||
941 | } | ||
942 | |||
894 | struct powerpc64_jit_data { | 943 | struct powerpc64_jit_data { |
895 | struct bpf_binary_header *header; | 944 | struct bpf_binary_header *header; |
896 | u32 *addrs; | 945 | u32 *addrs; |
@@ -989,6 +1038,22 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) | |||
989 | skip_init_ctx: | 1038 | skip_init_ctx: |
990 | code_base = (u32 *)(image + FUNCTION_DESCR_SIZE); | 1039 | code_base = (u32 *)(image + FUNCTION_DESCR_SIZE); |
991 | 1040 | ||
1041 | if (extra_pass) { | ||
1042 | /* | ||
1043 | * Do not touch the prologue and epilogue as they will remain | ||
1044 | * unchanged. Only fix the branch target address for subprog | ||
1045 | * calls in the body. | ||
1046 | * | ||
1047 | * This does not change the offsets and lengths of the subprog | ||
1048 | * call instruction sequences and hence, the size of the JITed | ||
1049 | * image as well. | ||
1050 | */ | ||
1051 | bpf_jit_fixup_subprog_calls(fp, code_base, &cgctx, addrs); | ||
1052 | |||
1053 | /* There is no need to perform the usual passes. */ | ||
1054 | goto skip_codegen_passes; | ||
1055 | } | ||
1056 | |||
992 | /* Code generation passes 1-2 */ | 1057 | /* Code generation passes 1-2 */ |
993 | for (pass = 1; pass < 3; pass++) { | 1058 | for (pass = 1; pass < 3; pass++) { |
994 | /* Now build the prologue, body code & epilogue for real. */ | 1059 | /* Now build the prologue, body code & epilogue for real. */ |
@@ -1002,6 +1067,7 @@ skip_init_ctx: | |||
1002 | proglen - (cgctx.idx * 4), cgctx.seen); | 1067 | proglen - (cgctx.idx * 4), cgctx.seen); |
1003 | } | 1068 | } |
1004 | 1069 | ||
1070 | skip_codegen_passes: | ||
1005 | if (bpf_jit_enable > 1) | 1071 | if (bpf_jit_enable > 1) |
1006 | /* | 1072 | /* |
1007 | * Note that we output the base address of the code_base | 1073 | * Note that we output the base address of the code_base |
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 2e4bd32154b5..472b784f01eb 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig | |||
@@ -140,8 +140,7 @@ config IBMEBUS | |||
140 | Bus device driver for GX bus based adapters. | 140 | Bus device driver for GX bus based adapters. |
141 | 141 | ||
142 | config PAPR_SCM | 142 | config PAPR_SCM |
143 | depends on PPC_PSERIES && MEMORY_HOTPLUG | 143 | depends on PPC_PSERIES && MEMORY_HOTPLUG && LIBNVDIMM |
144 | select LIBNVDIMM | ||
145 | tristate "Support for the PAPR Storage Class Memory interface" | 144 | tristate "Support for the PAPR Storage Class Memory interface" |
146 | help | 145 | help |
147 | Enable access to hypervisor provided storage class memory. | 146 | Enable access to hypervisor provided storage class memory. |
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index ee9372b65ca5..7d6457ab5d34 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c | |||
@@ -55,7 +55,7 @@ static int drc_pmem_bind(struct papr_scm_priv *p) | |||
55 | do { | 55 | do { |
56 | rc = plpar_hcall(H_SCM_BIND_MEM, ret, p->drc_index, 0, | 56 | rc = plpar_hcall(H_SCM_BIND_MEM, ret, p->drc_index, 0, |
57 | p->blocks, BIND_ANY_ADDR, token); | 57 | p->blocks, BIND_ANY_ADDR, token); |
58 | token = be64_to_cpu(ret[0]); | 58 | token = ret[0]; |
59 | cond_resched(); | 59 | cond_resched(); |
60 | } while (rc == H_BUSY); | 60 | } while (rc == H_BUSY); |
61 | 61 | ||
@@ -64,7 +64,7 @@ static int drc_pmem_bind(struct papr_scm_priv *p) | |||
64 | return -ENXIO; | 64 | return -ENXIO; |
65 | } | 65 | } |
66 | 66 | ||
67 | p->bound_addr = be64_to_cpu(ret[1]); | 67 | p->bound_addr = ret[1]; |
68 | 68 | ||
69 | dev_dbg(&p->pdev->dev, "bound drc %x to %pR\n", p->drc_index, &p->res); | 69 | dev_dbg(&p->pdev->dev, "bound drc %x to %pR\n", p->drc_index, &p->res); |
70 | 70 | ||
@@ -82,7 +82,7 @@ static int drc_pmem_unbind(struct papr_scm_priv *p) | |||
82 | do { | 82 | do { |
83 | rc = plpar_hcall(H_SCM_UNBIND_MEM, ret, p->drc_index, | 83 | rc = plpar_hcall(H_SCM_UNBIND_MEM, ret, p->drc_index, |
84 | p->bound_addr, p->blocks, token); | 84 | p->bound_addr, p->blocks, token); |
85 | token = be64_to_cpu(ret); | 85 | token = ret[0]; |
86 | cond_resched(); | 86 | cond_resched(); |
87 | } while (rc == H_BUSY); | 87 | } while (rc == H_BUSY); |
88 | 88 | ||
@@ -223,6 +223,9 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p) | |||
223 | goto err; | 223 | goto err; |
224 | } | 224 | } |
225 | 225 | ||
226 | if (nvdimm_bus_check_dimm_count(p->bus, 1)) | ||
227 | goto err; | ||
228 | |||
226 | /* now add the region */ | 229 | /* now add the region */ |
227 | 230 | ||
228 | memset(&mapping, 0, sizeof(mapping)); | 231 | memset(&mapping, 0, sizeof(mapping)); |
@@ -257,9 +260,12 @@ err: nvdimm_bus_unregister(p->bus); | |||
257 | 260 | ||
258 | static int papr_scm_probe(struct platform_device *pdev) | 261 | static int papr_scm_probe(struct platform_device *pdev) |
259 | { | 262 | { |
260 | uint32_t drc_index, metadata_size, unit_cap[2]; | ||
261 | struct device_node *dn = pdev->dev.of_node; | 263 | struct device_node *dn = pdev->dev.of_node; |
264 | u32 drc_index, metadata_size; | ||
265 | u64 blocks, block_size; | ||
262 | struct papr_scm_priv *p; | 266 | struct papr_scm_priv *p; |
267 | const char *uuid_str; | ||
268 | u64 uuid[2]; | ||
263 | int rc; | 269 | int rc; |
264 | 270 | ||
265 | /* check we have all the required DT properties */ | 271 | /* check we have all the required DT properties */ |
@@ -268,8 +274,18 @@ static int papr_scm_probe(struct platform_device *pdev) | |||
268 | return -ENODEV; | 274 | return -ENODEV; |
269 | } | 275 | } |
270 | 276 | ||
271 | if (of_property_read_u32_array(dn, "ibm,unit-capacity", unit_cap, 2)) { | 277 | if (of_property_read_u64(dn, "ibm,block-size", &block_size)) { |
272 | dev_err(&pdev->dev, "%pOF: missing unit-capacity!\n", dn); | 278 | dev_err(&pdev->dev, "%pOF: missing block-size!\n", dn); |
279 | return -ENODEV; | ||
280 | } | ||
281 | |||
282 | if (of_property_read_u64(dn, "ibm,number-of-blocks", &blocks)) { | ||
283 | dev_err(&pdev->dev, "%pOF: missing number-of-blocks!\n", dn); | ||
284 | return -ENODEV; | ||
285 | } | ||
286 | |||
287 | if (of_property_read_string(dn, "ibm,unit-guid", &uuid_str)) { | ||
288 | dev_err(&pdev->dev, "%pOF: missing unit-guid!\n", dn); | ||
273 | return -ENODEV; | 289 | return -ENODEV; |
274 | } | 290 | } |
275 | 291 | ||
@@ -282,8 +298,13 @@ static int papr_scm_probe(struct platform_device *pdev) | |||
282 | 298 | ||
283 | p->dn = dn; | 299 | p->dn = dn; |
284 | p->drc_index = drc_index; | 300 | p->drc_index = drc_index; |
285 | p->block_size = unit_cap[0]; | 301 | p->block_size = block_size; |
286 | p->blocks = unit_cap[1]; | 302 | p->blocks = blocks; |
303 | |||
304 | /* We just need to ensure that set cookies are unique across */ | ||
305 | uuid_parse(uuid_str, (uuid_t *) uuid); | ||
306 | p->nd_set.cookie1 = uuid[0]; | ||
307 | p->nd_set.cookie2 = uuid[1]; | ||
287 | 308 | ||
288 | /* might be zero */ | 309 | /* might be zero */ |
289 | p->metadata_size = metadata_size; | 310 | p->metadata_size = metadata_size; |
@@ -296,7 +317,7 @@ static int papr_scm_probe(struct platform_device *pdev) | |||
296 | 317 | ||
297 | /* setup the resource for the newly bound range */ | 318 | /* setup the resource for the newly bound range */ |
298 | p->res.start = p->bound_addr; | 319 | p->res.start = p->bound_addr; |
299 | p->res.end = p->bound_addr + p->blocks * p->block_size; | 320 | p->res.end = p->bound_addr + p->blocks * p->block_size - 1; |
300 | p->res.name = pdev->name; | 321 | p->res.name = pdev->name; |
301 | p->res.flags = IORESOURCE_MEM; | 322 | p->res.flags = IORESOURCE_MEM; |
302 | 323 | ||