Commit cfdfaf4a authored by Radim Krčmář's avatar Radim Krčmář
Browse files
PPC KVM update for 4.21 from Paul Mackerras

The main new feature this time is support in HV nested KVM for passing
a device that is emulated by a level 0 hypervisor and presented to
level 1 as a PCI device through to a level 2 guest using VFIO.

Apart from that there are improvements for migration of radix guests
under HV KVM and some other fixes and cleanups.
parents e9f2e05a 95d386c2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -335,6 +335,7 @@
#define H_SET_PARTITION_TABLE	0xF800
#define H_ENTER_NESTED		0xF804
#define H_TLB_INVALIDATE	0xF808
#define H_COPY_TOFROM_GUEST	0xF80C

/* Values for 2nd argument to H_SET_MODE */
#define H_SET_MODE_RESOURCE_SET_CIABR		1
+14 −7
Original line number Diff line number Diff line
@@ -188,6 +188,13 @@ extern int kvmppc_book3s_hcall_implemented(struct kvm *kvm, unsigned long hc);
extern int kvmppc_book3s_radix_page_fault(struct kvm_run *run,
			struct kvm_vcpu *vcpu,
			unsigned long ea, unsigned long dsisr);
extern unsigned long __kvmhv_copy_tofrom_guest_radix(int lpid, int pid,
					gva_t eaddr, void *to, void *from,
					unsigned long n);
extern long kvmhv_copy_from_guest_radix(struct kvm_vcpu *vcpu, gva_t eaddr,
					void *to, unsigned long n);
extern long kvmhv_copy_to_guest_radix(struct kvm_vcpu *vcpu, gva_t eaddr,
				      void *from, unsigned long n);
extern int kvmppc_mmu_walk_radix_tree(struct kvm_vcpu *vcpu, gva_t eaddr,
				      struct kvmppc_pte *gpte, u64 root,
				      u64 *pte_ret_p);
@@ -197,7 +204,8 @@ extern int kvmppc_mmu_radix_translate_table(struct kvm_vcpu *vcpu, gva_t eaddr,
extern int kvmppc_mmu_radix_xlate(struct kvm_vcpu *vcpu, gva_t eaddr,
			struct kvmppc_pte *gpte, bool data, bool iswrite);
extern void kvmppc_unmap_pte(struct kvm *kvm, pte_t *pte, unsigned long gpa,
			unsigned int shift, struct kvm_memory_slot *memslot,
			unsigned int shift,
			const struct kvm_memory_slot *memslot,
			unsigned int lpid);
extern bool kvmppc_hv_handle_set_rc(struct kvm *kvm, pgd_t *pgtable,
				    bool writing, unsigned long gpa,
@@ -215,16 +223,14 @@ extern int kvmppc_radix_init(void);
extern void kvmppc_radix_exit(void);
extern int kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
			unsigned long gfn);
extern void kvmppc_unmap_pte(struct kvm *kvm, pte_t *pte,
			     unsigned long gpa, unsigned int shift,
			     struct kvm_memory_slot *memslot,
			     unsigned int lpid);
extern int kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
			unsigned long gfn);
extern int kvm_test_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
			unsigned long gfn);
extern long kvmppc_hv_get_dirty_log_radix(struct kvm *kvm,
			struct kvm_memory_slot *memslot, unsigned long *map);
extern void kvmppc_radix_flush_memslot(struct kvm *kvm,
			const struct kvm_memory_slot *memslot);
extern int kvmhv_get_rmmu_info(struct kvm *kvm, struct kvm_ppc_rmmu_info *info);

/* XXX remove this export when load_last_inst() is generic */
@@ -242,7 +248,7 @@ extern kvm_pfn_t kvmppc_gpa_to_pfn(struct kvm_vcpu *vcpu, gpa_t gpa,
			bool writing, bool *writable);
extern void kvmppc_add_revmap_chain(struct kvm *kvm, struct revmap_entry *rev,
			unsigned long *rmap, long pte_index, int realmode);
extern void kvmppc_update_dirty_map(struct kvm_memory_slot *memslot,
extern void kvmppc_update_dirty_map(const struct kvm_memory_slot *memslot,
			unsigned long gfn, unsigned long psize);
extern void kvmppc_invalidate_hpte(struct kvm *kvm, __be64 *hptep,
			unsigned long pte_index);
@@ -298,6 +304,7 @@ long kvmhv_nested_init(void);
void kvmhv_nested_exit(void);
void kvmhv_vm_nested_init(struct kvm *kvm);
long kvmhv_set_partition_table(struct kvm_vcpu *vcpu);
long kvmhv_copy_tofrom_guest_nested(struct kvm_vcpu *vcpu);
void kvmhv_set_ptbl_entry(unsigned int lpid, u64 dw0, u64 dw1);
void kvmhv_release_all_nested(struct kvm *kvm);
long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu);
@@ -307,7 +314,7 @@ int kvmhv_run_single_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu,
void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr);
void kvmhv_restore_hv_return_state(struct kvm_vcpu *vcpu,
				   struct hv_guest_state *hr);
long int kvmhv_nested_page_fault(struct kvm_vcpu *vcpu);
long int kvmhv_nested_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu);

void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac);

+14 −1
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ struct kvm_nested_guest {
	cpumask_t need_tlb_flush;
	cpumask_t cpu_in_guest;
	short prev_cpu[NR_CPUS];
	u8 radix;			/* is this nested guest radix */
};

/*
@@ -150,6 +151,18 @@ static inline bool kvm_is_radix(struct kvm *kvm)
	return kvm->arch.radix;
}

static inline bool kvmhv_vcpu_is_radix(struct kvm_vcpu *vcpu)
{
	bool radix;

	if (vcpu->arch.nested)
		radix = vcpu->arch.nested->radix;
	else
		radix = kvm_is_radix(vcpu->kvm);

	return radix;
}

#define KVM_DEFAULT_HPT_ORDER	24	/* 16MB HPT by default */
#endif

@@ -625,7 +638,7 @@ extern int kvmppc_create_pte(struct kvm *kvm, pgd_t *pgtable, pte_t pte,
extern void kvmhv_insert_nest_rmap(struct kvm *kvm, unsigned long *rmapp,
				   struct rmap_nested **n_rmap);
extern void kvmhv_remove_nest_rmap_range(struct kvm *kvm,
				struct kvm_memory_slot *memslot,
				const struct kvm_memory_slot *memslot,
				unsigned long gpa, unsigned long hpa,
				unsigned long nbytes);

+3 −0
Original line number Diff line number Diff line
@@ -793,6 +793,7 @@ struct kvm_vcpu_arch {
	/* For support of nested guests */
	struct kvm_nested_guest *nested;
	u32 nested_vcpu_id;
	gpa_t nested_io_gpr;
#endif

#ifdef CONFIG_KVM_BOOK3S_HV_EXIT_TIMING
@@ -827,6 +828,8 @@ struct kvm_vcpu_arch {
#define KVM_MMIO_REG_FQPR	0x00c0
#define KVM_MMIO_REG_VSX	0x0100
#define KVM_MMIO_REG_VMX	0x0180
#define KVM_MMIO_REG_NESTED_GPR	0xffc0


#define __KVM_HAVE_ARCH_WQP
#define __KVM_HAVE_CREATE_DEVICE
+8 −2
Original line number Diff line number Diff line
@@ -224,7 +224,8 @@ extern int kvmppc_core_prepare_memory_region(struct kvm *kvm,
extern void kvmppc_core_commit_memory_region(struct kvm *kvm,
				const struct kvm_userspace_memory_region *mem,
				const struct kvm_memory_slot *old,
				const struct kvm_memory_slot *new);
				const struct kvm_memory_slot *new,
				enum kvm_mr_change change);
extern int kvm_vm_ioctl_get_smmu_info(struct kvm *kvm,
				      struct kvm_ppc_smmu_info *info);
extern void kvmppc_core_flush_memslot(struct kvm *kvm,
@@ -294,7 +295,8 @@ struct kvmppc_ops {
	void (*commit_memory_region)(struct kvm *kvm,
				     const struct kvm_userspace_memory_region *mem,
				     const struct kvm_memory_slot *old,
				     const struct kvm_memory_slot *new);
				     const struct kvm_memory_slot *new,
				     enum kvm_mr_change change);
	int (*unmap_hva_range)(struct kvm *kvm, unsigned long start,
			   unsigned long end);
	int (*age_hva)(struct kvm *kvm, unsigned long start, unsigned long end);
@@ -326,6 +328,10 @@ struct kvmppc_ops {
			    unsigned long flags);
	void (*giveup_ext)(struct kvm_vcpu *vcpu, ulong msr);
	int (*enable_nested)(struct kvm *kvm);
	int (*load_from_eaddr)(struct kvm_vcpu *vcpu, ulong *eaddr, void *ptr,
			       int size);
	int (*store_to_eaddr)(struct kvm_vcpu *vcpu, ulong *eaddr, void *ptr,
			      int size);
};

extern struct kvmppc_ops *kvmppc_hv_ops;
Loading