Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec594c47 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge branch 'kvm-ppc-next' of...

Merge branch 'kvm-ppc-next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc into HEAD
parents 8afd74c2 feafd13c
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -16,7 +16,21 @@ Groups:

KVM_DEV_VFIO_GROUP attributes:
  KVM_DEV_VFIO_GROUP_ADD: Add a VFIO group to VFIO-KVM device tracking
	kvm_device_attr.addr points to an int32_t file descriptor
	for the VFIO group.
  KVM_DEV_VFIO_GROUP_DEL: Remove a VFIO group from VFIO-KVM device tracking

For each, kvm_device_attr.addr points to an int32_t file descriptor
	kvm_device_attr.addr points to an int32_t file descriptor
	for the VFIO group.
  KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE: attaches a guest visible TCE table
	allocated by sPAPR KVM.
	kvm_device_attr.addr points to a struct:

	struct kvm_vfio_spapr_tce {
		__s32	groupfd;
		__s32	tablefd;
	};

	where
	@groupfd is a file descriptor for a VFIO group;
	@tablefd is a file descriptor for a TCE table allocated via
		KVM_CREATE_SPAPR_TCE.
+5 −0
Original line number Diff line number Diff line
@@ -87,6 +87,11 @@ static inline unsigned int get_oc(u32 inst)
	return (inst >> 11) & 0x7fff;
}

static inline unsigned int get_tx_or_sx(u32 inst)
{
	return (inst) & 0x1;
}

#define IS_XFORM(inst)	(get_op(inst)  == 31)
#define IS_DSFORM(inst)	(get_op(inst) >= 56)

+25 −7
Original line number Diff line number Diff line
@@ -64,6 +64,11 @@ struct iommu_table_ops {
			long index,
			unsigned long *hpa,
			enum dma_data_direction *direction);
	/* Real mode */
	int (*exchange_rm)(struct iommu_table *tbl,
			long index,
			unsigned long *hpa,
			enum dma_data_direction *direction);
#endif
	void (*clear)(struct iommu_table *tbl,
			long index, long npages);
@@ -114,6 +119,7 @@ struct iommu_table {
	struct list_head it_group_list;/* List of iommu_table_group_link */
	unsigned long *it_userspace; /* userspace view of the table */
	struct iommu_table_ops *it_ops;
	struct kref    it_kref;
};

#define IOMMU_TABLE_USERSPACE_ENTRY(tbl, entry) \
@@ -146,8 +152,8 @@ static inline void *get_iommu_table_base(struct device *dev)

extern int dma_iommu_dma_supported(struct device *dev, u64 mask);

/* Frees table for an individual device node */
extern void iommu_free_table(struct iommu_table *tbl, const char *node_name);
extern struct iommu_table *iommu_tce_table_get(struct iommu_table *tbl);
extern int iommu_tce_table_put(struct iommu_table *tbl);

/* Initializes an iommu_table based in values set in the passed-in
 * structure
@@ -208,6 +214,8 @@ extern void iommu_del_device(struct device *dev);
extern int __init tce_iommu_bus_notifier_init(void);
extern long iommu_tce_xchg(struct iommu_table *tbl, unsigned long entry,
		unsigned long *hpa, enum dma_data_direction *direction);
extern long iommu_tce_xchg_rm(struct iommu_table *tbl, unsigned long entry,
		unsigned long *hpa, enum dma_data_direction *direction);
#else
static inline void iommu_register_group(struct iommu_table_group *table_group,
					int pci_domain_number,
@@ -288,11 +296,21 @@ static inline void iommu_restore(void)
#endif

/* The API to support IOMMU operations for VFIO */
extern int iommu_tce_clear_param_check(struct iommu_table *tbl,
		unsigned long ioba, unsigned long tce_value,
		unsigned long npages);
extern int iommu_tce_put_param_check(struct iommu_table *tbl,
		unsigned long ioba, unsigned long tce);
extern int iommu_tce_check_ioba(unsigned long page_shift,
		unsigned long offset, unsigned long size,
		unsigned long ioba, unsigned long npages);
extern int iommu_tce_check_gpa(unsigned long page_shift,
		unsigned long gpa);

#define iommu_tce_clear_param_check(tbl, ioba, tce_value, npages) \
		(iommu_tce_check_ioba((tbl)->it_page_shift,       \
				(tbl)->it_offset, (tbl)->it_size, \
				(ioba), (npages)) || (tce_value))
#define iommu_tce_put_param_check(tbl, ioba, gpa)                 \
		(iommu_tce_check_ioba((tbl)->it_page_shift,       \
				(tbl)->it_offset, (tbl)->it_size, \
				(ioba), 1) ||                     \
		iommu_tce_check_gpa((tbl)->it_page_shift, (gpa)))

extern void iommu_flush_tce(struct iommu_table *tbl);
extern int iommu_take_ownership(struct iommu_table *tbl);
+32 −0
Original line number Diff line number Diff line
@@ -188,6 +188,13 @@ struct kvmppc_pginfo {
	atomic_t refcnt;
};

struct kvmppc_spapr_tce_iommu_table {
	struct rcu_head rcu;
	struct list_head next;
	struct iommu_table *tbl;
	struct kref kref;
};

struct kvmppc_spapr_tce_table {
	struct list_head list;
	struct kvm *kvm;
@@ -196,6 +203,7 @@ struct kvmppc_spapr_tce_table {
	u32 page_shift;
	u64 offset;		/* in pages */
	u64 size;		/* window size in pages */
	struct list_head iommu_tables;
	struct page *pages[0];
};

@@ -342,6 +350,7 @@ struct kvmppc_pte {
	bool may_read		: 1;
	bool may_write		: 1;
	bool may_execute	: 1;
	unsigned long wimg;
	u8 page_size;		/* MMU_PAGE_xxx */
};

@@ -438,6 +447,11 @@ struct mmio_hpte_cache {
	unsigned int index;
};

#define KVMPPC_VSX_COPY_NONE		0
#define KVMPPC_VSX_COPY_WORD		1
#define KVMPPC_VSX_COPY_DWORD		2
#define KVMPPC_VSX_COPY_DWORD_LOAD_DUMP	3

struct openpic;

struct kvm_vcpu_arch {
@@ -641,6 +655,21 @@ struct kvm_vcpu_arch {
	u8 io_gpr; /* GPR used as IO source/target */
	u8 mmio_host_swabbed;
	u8 mmio_sign_extend;
	/* conversion between single and double precision */
	u8 mmio_sp64_extend;
	/*
	 * Number of simulations for vsx.
	 * If we use 2*8bytes to simulate 1*16bytes,
	 * then the number should be 2 and
	 * mmio_vsx_copy_type=KVMPPC_VSX_COPY_DWORD.
	 * If we use 4*4bytes to simulate 1*16bytes,
	 * the number should be 4 and
	 * mmio_vsx_copy_type=KVMPPC_VSX_COPY_WORD.
	 */
	u8 mmio_vsx_copy_nums;
	u8 mmio_vsx_offset;
	u8 mmio_vsx_copy_type;
	u8 mmio_vsx_tx_sx_enabled;
	u8 osi_needed;
	u8 osi_enabled;
	u8 papr_enabled;
@@ -729,6 +758,8 @@ struct kvm_vcpu_arch {
};

#define VCPU_FPR(vcpu, i)	(vcpu)->arch.fp.fpr[i][TS_FPROFFSET]
#define VCPU_VSX_FPR(vcpu, i, j)	((vcpu)->arch.fp.fpr[i][j])
#define VCPU_VSX_VR(vcpu, i)		((vcpu)->arch.vr.vr[i])

/* Values for vcpu->arch.state */
#define KVMPPC_VCPU_NOTREADY		0
@@ -742,6 +773,7 @@ struct kvm_vcpu_arch {
#define KVM_MMIO_REG_FPR	0x0020
#define KVM_MMIO_REG_QPR	0x0040
#define KVM_MMIO_REG_FQPR	0x0060
#define KVM_MMIO_REG_VSX	0x0080

#define __KVM_HAVE_ARCH_WQP
#define __KVM_HAVE_CREATE_DEVICE
+19 −3
Original line number Diff line number Diff line
@@ -78,9 +78,15 @@ extern int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
extern int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu,
                               unsigned int rt, unsigned int bytes,
			       int is_default_endian);
extern int kvmppc_handle_vsx_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
				unsigned int rt, unsigned int bytes,
			int is_default_endian, int mmio_sign_extend);
extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
			       u64 val, unsigned int bytes,
			       int is_default_endian);
extern int kvmppc_handle_vsx_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
				int rs, unsigned int bytes,
				int is_default_endian);

extern int kvmppc_load_last_inst(struct kvm_vcpu *vcpu,
				 enum instruction_type type, u32 *inst);
@@ -132,6 +138,9 @@ extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu);
extern int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu);
extern int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu);
extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags);
extern void kvmppc_core_queue_fpunavail(struct kvm_vcpu *vcpu);
extern void kvmppc_core_queue_vec_unavail(struct kvm_vcpu *vcpu);
extern void kvmppc_core_queue_vsx_unavail(struct kvm_vcpu *vcpu);
extern void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu);
extern void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu);
extern void kvmppc_core_queue_external(struct kvm_vcpu *vcpu,
@@ -164,13 +173,19 @@ extern long kvmppc_prepare_vrma(struct kvm *kvm,
extern void kvmppc_map_vrma(struct kvm_vcpu *vcpu,
			struct kvm_memory_slot *memslot, unsigned long porder);
extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu);
extern long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
		struct iommu_group *grp);
extern void kvm_spapr_tce_release_iommu_group(struct kvm *kvm,
		struct iommu_group *grp);

extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
				struct kvm_create_spapr_tce_64 *args);
extern struct kvmppc_spapr_tce_table *kvmppc_find_table(
		struct kvm_vcpu *vcpu, unsigned long liobn);
extern long kvmppc_ioba_validate(struct kvmppc_spapr_tce_table *stt,
		unsigned long ioba, unsigned long npages);
		struct kvm *kvm, unsigned long liobn);
#define kvmppc_ioba_validate(stt, ioba, npages)                         \
		(iommu_tce_check_ioba((stt)->page_shift, (stt)->offset, \
				(stt)->size, (ioba), (npages)) ?        \
				H_PARAMETER : H_SUCCESS)
extern long kvmppc_tce_validate(struct kvmppc_spapr_tce_table *tt,
		unsigned long tce);
extern long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long gpa,
@@ -240,6 +255,7 @@ union kvmppc_one_reg {
	u64	dval;
	vector128 vval;
	u64	vsxval[2];
	u32	vsx32val[4];
	struct {
		u64	addr;
		u64	length;
Loading