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

Commit 5be587b1 authored by Frederic Barrat's avatar Frederic Barrat Committed by Michael Ellerman
Browse files

cxl: Introduce implementation-specific API



The backend API (in cxl.h) lists some low-level functions whose
implementation is different on bare-metal and in a guest. Each
environment implements its own functions, and the common code uses
them through function pointers, defined in cxl_backend_ops

Co-authored-by: default avatarChristophe Lombard <clombard@linux.vnet.ibm.com>
Signed-off-by: default avatarFrederic Barrat <fbarrat@linux.vnet.ibm.com>
Signed-off-by: default avatarChristophe Lombard <clombard@linux.vnet.ibm.com>
Reviewed-by: default avatarManoj Kumar <manoj@linux.vnet.ibm.com>
Acked-by: default avatarIan Munsie <imunsie@au1.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent cca44c01
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
void cxl_free_afu_irqs(struct cxl_context *ctx)
void cxl_free_afu_irqs(struct cxl_context *ctx)
{
{
	afu_irq_name_free(ctx);
	afu_irq_name_free(ctx);
	cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
	cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
}
}
EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);


@@ -176,7 +176,7 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed,


	cxl_ctx_get();
	cxl_ctx_get();


	if ((rc = cxl_attach_process(ctx, kernel, wed , 0))) {
	if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
		put_pid(ctx->pid);
		put_pid(ctx->pid);
		cxl_ctx_put();
		cxl_ctx_put();
		goto out;
		goto out;
@@ -342,11 +342,11 @@ int cxl_afu_reset(struct cxl_context *ctx)
	struct cxl_afu *afu = ctx->afu;
	struct cxl_afu *afu = ctx->afu;
	int rc;
	int rc;


	rc = __cxl_afu_reset(afu);
	rc = cxl_ops->afu_reset(afu);
	if (rc)
	if (rc)
		return rc;
		return rc;


	return cxl_afu_check_and_enable(afu);
	return cxl_ops->afu_check_and_enable(afu);
}
}
EXPORT_SYMBOL_GPL(cxl_afu_reset);
EXPORT_SYMBOL_GPL(cxl_afu_reset);


+2 −2
Original line number Original line Diff line number Diff line
@@ -214,8 +214,8 @@ int __detach_context(struct cxl_context *ctx)
	/* Only warn if we detached while the link was OK.
	/* Only warn if we detached while the link was OK.
	 * If detach fails when hw is down, we don't care.
	 * If detach fails when hw is down, we don't care.
	 */
	 */
	WARN_ON(cxl_detach_process(ctx) &&
	WARN_ON(cxl_ops->detach_process(ctx) &&
		cxl_adapter_link_ok(ctx->afu->adapter));
		cxl_ops->link_ok(ctx->afu->adapter));
	flush_work(&ctx->fault_work); /* Only needed for dedicated process */
	flush_work(&ctx->fault_work); /* Only needed for dedicated process */


	/* release the reference to the group leader and mm handling pid */
	/* release the reference to the group leader and mm handling pid */
+34 −19
Original line number Original line Diff line number Diff line
@@ -623,11 +623,6 @@ static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg)
		return ~0ULL;
		return ~0ULL;
}
}


u64 cxl_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off);
u32 cxl_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off);
u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off);
u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off);

ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
				loff_t off, size_t count);
				loff_t off, size_t count);


@@ -666,10 +661,6 @@ void cxl_sysfs_afu_m_remove(struct cxl_afu *afu);


struct cxl *cxl_alloc_adapter(void);
struct cxl *cxl_alloc_adapter(void);
struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice);
struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice);

int cxl_afu_activate_mode(struct cxl_afu *afu, int mode);
int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode);
int cxl_afu_deactivate_mode(struct cxl_afu *afu);
int cxl_afu_select_best_mode(struct cxl_afu *afu);
int cxl_afu_select_best_mode(struct cxl_afu *afu);


int cxl_register_psl_irq(struct cxl_afu *afu);
int cxl_register_psl_irq(struct cxl_afu *afu);
@@ -681,8 +672,6 @@ void cxl_release_serr_irq(struct cxl_afu *afu);
int afu_register_irqs(struct cxl_context *ctx, u32 count);
int afu_register_irqs(struct cxl_context *ctx, u32 count);
void afu_release_irqs(struct cxl_context *ctx, void *cookie);
void afu_release_irqs(struct cxl_context *ctx, void *cookie);
void afu_irq_name_free(struct cxl_context *ctx);
void afu_irq_name_free(struct cxl_context *ctx);
irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr,
				u64 errstat);


int cxl_debugfs_init(void);
int cxl_debugfs_init(void);
void cxl_debugfs_exit(void);
void cxl_debugfs_exit(void);
@@ -727,18 +716,10 @@ int cxl_register_one_irq(struct cxl *adapter, irq_handler_t handler,
			void *cookie, irq_hw_number_t *dest_hwirq,
			void *cookie, irq_hw_number_t *dest_hwirq,
			unsigned int *dest_virq, const char *name);
			unsigned int *dest_virq, const char *name);


int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed,
			    u64 amr);
int cxl_detach_process(struct cxl_context *ctx);

int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);

int cxl_check_error(struct cxl_afu *afu);
int cxl_check_error(struct cxl_afu *afu);
int cxl_afu_slbia(struct cxl_afu *afu);
int cxl_afu_slbia(struct cxl_afu *afu);
int cxl_tlb_slb_invalidate(struct cxl *adapter);
int cxl_tlb_slb_invalidate(struct cxl *adapter);
int cxl_afu_disable(struct cxl_afu *afu);
int cxl_afu_disable(struct cxl_afu *afu);
int __cxl_afu_reset(struct cxl_afu *afu);
int cxl_afu_check_and_enable(struct cxl_afu *afu);
int cxl_psl_purge(struct cxl_afu *afu);
int cxl_psl_purge(struct cxl_afu *afu);


void cxl_stop_trace(struct cxl *cxl);
void cxl_stop_trace(struct cxl *cxl);
@@ -757,4 +738,38 @@ unsigned int afu_poll(struct file *file, struct poll_table_struct *poll);
ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t *off);
ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t *off);
extern const struct file_operations afu_fops;
extern const struct file_operations afu_fops;


struct cxl_backend_ops {
	struct module *module;
	int (*adapter_reset)(struct cxl *adapter);
	int (*alloc_one_irq)(struct cxl *adapter);
	void (*release_one_irq)(struct cxl *adapter, int hwirq);
	int (*alloc_irq_ranges)(struct cxl_irq_ranges *irqs,
				struct cxl *adapter, unsigned int num);
	void (*release_irq_ranges)(struct cxl_irq_ranges *irqs,
				struct cxl *adapter);
	int (*setup_irq)(struct cxl *adapter, unsigned int hwirq,
			unsigned int virq);
	irqreturn_t (*handle_psl_slice_error)(struct cxl_context *ctx,
					u64 dsisr, u64 errstat);
	irqreturn_t (*psl_interrupt)(int irq, void *data);
	int (*ack_irq)(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);
	int (*attach_process)(struct cxl_context *ctx, bool kernel,
			u64 wed, u64 amr);
	int (*detach_process)(struct cxl_context *ctx);
	bool (*link_ok)(struct cxl *cxl);
	void (*release_afu)(struct device *dev);
	ssize_t (*afu_read_err_buffer)(struct cxl_afu *afu, char *buf,
				loff_t off, size_t count);
	int (*afu_check_and_enable)(struct cxl_afu *afu);
	int (*afu_activate_mode)(struct cxl_afu *afu, int mode);
	int (*afu_deactivate_mode)(struct cxl_afu *afu, int mode);
	int (*afu_reset)(struct cxl_afu *afu);
	int (*afu_cr_read8)(struct cxl_afu *afu, int cr_idx, u64 offset, u8 *val);
	int (*afu_cr_read16)(struct cxl_afu *afu, int cr_idx, u64 offset, u16 *val);
	int (*afu_cr_read32)(struct cxl_afu *afu, int cr_idx, u64 offset, u32 *val);
	int (*afu_cr_read64)(struct cxl_afu *afu, int cr_idx, u64 offset, u64 *val);
};
extern const struct cxl_backend_ops cxl_native_ops;
extern const struct cxl_backend_ops *cxl_ops;

#endif
#endif
+3 −3
Original line number Original line Diff line number Diff line
@@ -101,7 +101,7 @@ static void cxl_ack_ae(struct cxl_context *ctx)
{
{
	unsigned long flags;
	unsigned long flags;


	cxl_ack_irq(ctx, CXL_PSL_TFC_An_AE, 0);
	cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_AE, 0);


	spin_lock_irqsave(&ctx->lock, flags);
	spin_lock_irqsave(&ctx->lock, flags);
	ctx->pending_fault = true;
	ctx->pending_fault = true;
@@ -125,7 +125,7 @@ static int cxl_handle_segment_miss(struct cxl_context *ctx,
	else {
	else {


		mb(); /* Order seg table write to TFC MMIO write */
		mb(); /* Order seg table write to TFC MMIO write */
		cxl_ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
		cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
	}
	}


	return IRQ_HANDLED;
	return IRQ_HANDLED;
@@ -163,7 +163,7 @@ static void cxl_handle_page_fault(struct cxl_context *ctx,
	local_irq_restore(flags);
	local_irq_restore(flags);


	pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe);
	pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe);
	cxl_ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
	cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
}
}


/*
/*
+8 −7
Original line number Original line Diff line number Diff line
@@ -79,7 +79,7 @@ static int __afu_open(struct inode *inode, struct file *file, bool master)
	if (!afu->current_mode)
	if (!afu->current_mode)
		goto err_put_afu;
		goto err_put_afu;


	if (!cxl_adapter_link_ok(adapter)) {
	if (!cxl_ops->link_ok(adapter)) {
		rc = -EIO;
		rc = -EIO;
		goto err_put_afu;
		goto err_put_afu;
	}
	}
@@ -210,7 +210,7 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,


	trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
	trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);


	if ((rc = cxl_attach_process(ctx, false, work.work_element_descriptor,
	if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor,
							amr))) {
							amr))) {
		afu_release_irqs(ctx, ctx);
		afu_release_irqs(ctx, ctx);
		goto out;
		goto out;
@@ -222,6 +222,7 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
	mutex_unlock(&ctx->status_mutex);
	mutex_unlock(&ctx->status_mutex);
	return rc;
	return rc;
}
}

static long afu_ioctl_process_element(struct cxl_context *ctx,
static long afu_ioctl_process_element(struct cxl_context *ctx,
				      int __user *upe)
				      int __user *upe)
{
{
@@ -259,7 +260,7 @@ long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
	if (ctx->status == CLOSED)
	if (ctx->status == CLOSED)
		return -EIO;
		return -EIO;


	if (!cxl_adapter_link_ok(ctx->afu->adapter))
	if (!cxl_ops->link_ok(ctx->afu->adapter))
		return -EIO;
		return -EIO;


	pr_devel("afu_ioctl\n");
	pr_devel("afu_ioctl\n");
@@ -289,7 +290,7 @@ int afu_mmap(struct file *file, struct vm_area_struct *vm)
	if (ctx->status != STARTED)
	if (ctx->status != STARTED)
		return -EIO;
		return -EIO;


	if (!cxl_adapter_link_ok(ctx->afu->adapter))
	if (!cxl_ops->link_ok(ctx->afu->adapter))
		return -EIO;
		return -EIO;


	return cxl_context_iomap(ctx, vm);
	return cxl_context_iomap(ctx, vm);
@@ -336,7 +337,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count,
	int rc;
	int rc;
	DEFINE_WAIT(wait);
	DEFINE_WAIT(wait);


	if (!cxl_adapter_link_ok(ctx->afu->adapter))
	if (!cxl_ops->link_ok(ctx->afu->adapter))
		return -EIO;
		return -EIO;


	if (count < CXL_READ_MIN_SIZE)
	if (count < CXL_READ_MIN_SIZE)
@@ -349,7 +350,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count,
		if (ctx_event_pending(ctx))
		if (ctx_event_pending(ctx))
			break;
			break;


		if (!cxl_adapter_link_ok(ctx->afu->adapter)) {
		if (!cxl_ops->link_ok(ctx->afu->adapter)) {
			rc = -EIO;
			rc = -EIO;
			goto out;
			goto out;
		}
		}
Loading