Skip to content

Commit

Permalink
cxl: Introduce implementation-specific API
Browse files Browse the repository at this point in the history
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: Christophe Lombard <clombard@linux.vnet.ibm.com>
Signed-off-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com>
Reviewed-by: Manoj Kumar <manoj@linux.vnet.ibm.com>
Acked-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
2 people authored and Michael Ellerman committed Mar 9, 2016
1 parent cca44c0 commit 5be587b
Show file tree
Hide file tree
Showing 11 changed files with 185 additions and 120 deletions.
8 changes: 4 additions & 4 deletions drivers/misc/cxl/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
void cxl_free_afu_irqs(struct cxl_context *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);

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

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);
cxl_ctx_put();
goto out;
Expand Down Expand Up @@ -342,11 +342,11 @@ int cxl_afu_reset(struct cxl_context *ctx)
struct cxl_afu *afu = ctx->afu;
int rc;

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

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

Expand Down
4 changes: 2 additions & 2 deletions drivers/misc/cxl/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ int __detach_context(struct cxl_context *ctx)
/* Only warn if we detached while the link was OK.
* If detach fails when hw is down, we don't care.
*/
WARN_ON(cxl_detach_process(ctx) &&
cxl_adapter_link_ok(ctx->afu->adapter));
WARN_ON(cxl_ops->detach_process(ctx) &&
cxl_ops->link_ok(ctx->afu->adapter));
flush_work(&ctx->fault_work); /* Only needed for dedicated process */

/* release the reference to the group leader and mm handling pid */
Expand Down
53 changes: 34 additions & 19 deletions drivers/misc/cxl/cxl.h
Original file line number Diff line number Diff line change
Expand Up @@ -623,11 +623,6 @@ static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg)
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,
loff_t off, size_t count);

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

struct cxl *cxl_alloc_adapter(void);
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_register_psl_irq(struct cxl_afu *afu);
Expand All @@ -681,8 +672,6 @@ void cxl_release_serr_irq(struct cxl_afu *afu);
int afu_register_irqs(struct cxl_context *ctx, u32 count);
void afu_release_irqs(struct cxl_context *ctx, void *cookie);
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);
void cxl_debugfs_exit(void);
Expand Down Expand Up @@ -727,18 +716,10 @@ int cxl_register_one_irq(struct cxl *adapter, irq_handler_t handler,
void *cookie, irq_hw_number_t *dest_hwirq,
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_afu_slbia(struct cxl_afu *afu);
int cxl_tlb_slb_invalidate(struct cxl *adapter);
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);

void cxl_stop_trace(struct cxl *cxl);
Expand All @@ -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);
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
6 changes: 3 additions & 3 deletions drivers/misc/cxl/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ static void cxl_ack_ae(struct cxl_context *ctx)
{
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);
ctx->pending_fault = true;
Expand All @@ -125,7 +125,7 @@ static int cxl_handle_segment_miss(struct cxl_context *ctx,
else {

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;
Expand Down Expand Up @@ -163,7 +163,7 @@ static void cxl_handle_page_fault(struct cxl_context *ctx,
local_irq_restore(flags);

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);
}

/*
Expand Down
15 changes: 8 additions & 7 deletions drivers/misc/cxl/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static int __afu_open(struct inode *inode, struct file *file, bool master)
if (!afu->current_mode)
goto err_put_afu;

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

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

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

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

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

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

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

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

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

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

if (!cxl_adapter_link_ok(ctx->afu->adapter)) {
if (!cxl_ops->link_ok(ctx->afu->adapter)) {
rc = -EIO;
goto out;
}
Expand Down
19 changes: 11 additions & 8 deletions drivers/misc/cxl/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info)
if (dsisr & CXL_PSL_DSISR_An_UR)
pr_devel("CXL interrupt: AURP PTE not found\n");
if (dsisr & CXL_PSL_DSISR_An_PE)
return handle_psl_slice_error(ctx, dsisr, irq_info->errstat);
return cxl_ops->handle_psl_slice_error(ctx, dsisr,
irq_info->errstat);
if (dsisr & CXL_PSL_DSISR_An_AE) {
pr_devel("CXL interrupt: AFU Error 0x%016llx\n", irq_info->afu_err);

Expand All @@ -103,7 +104,7 @@ irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info)
wake_up_all(&ctx->wq);
}

cxl_ack_irq(ctx, CXL_PSL_TFC_An_A, 0);
cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_A, 0);
return IRQ_HANDLED;
}
if (dsisr & CXL_PSL_DSISR_An_OC)
Expand Down Expand Up @@ -167,7 +168,8 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq,
return 0;
}

cxl_setup_irq(adapter, hwirq, virq);
if (cxl_ops->setup_irq)
cxl_ops->setup_irq(adapter, hwirq, virq);

pr_devel("hwirq %#lx mapped to virq %u\n", hwirq, virq);

Expand Down Expand Up @@ -195,7 +197,7 @@ int cxl_register_one_irq(struct cxl *adapter,
{
int hwirq, virq;

if ((hwirq = cxl_alloc_one_irq(adapter)) < 0)
if ((hwirq = cxl_ops->alloc_one_irq(adapter)) < 0)
return hwirq;

if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie, name)))
Expand All @@ -207,7 +209,7 @@ int cxl_register_one_irq(struct cxl *adapter,
return 0;

err:
cxl_release_one_irq(adapter, hwirq);
cxl_ops->release_one_irq(adapter, hwirq);
return -ENOMEM;
}

Expand All @@ -230,7 +232,8 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count)
/* Initialize the list head to hold irq names */
INIT_LIST_HEAD(&ctx->irq_names);

if ((rc = cxl_alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter, count)))
if ((rc = cxl_ops->alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter,
count)))
return rc;

/* Multiplexed PSL Interrupt */
Expand Down Expand Up @@ -268,7 +271,7 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count)
return 0;

out:
cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
afu_irq_name_free(ctx);
return -ENOMEM;
}
Expand Down Expand Up @@ -319,7 +322,7 @@ void afu_release_irqs(struct cxl_context *ctx, void *cookie)
}

afu_irq_name_free(ctx);
cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);

ctx->irq_count = 0;
}
11 changes: 7 additions & 4 deletions drivers/misc/cxl/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ uint cxl_verbose;
module_param_named(verbose, cxl_verbose, uint, 0600);
MODULE_PARM_DESC(verbose, "Enable verbose dmesg output");

const struct cxl_backend_ops *cxl_ops;

int cxl_afu_slbia(struct cxl_afu *afu)
{
unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
Expand All @@ -46,7 +48,7 @@ int cxl_afu_slbia(struct cxl_afu *afu)
/* If the adapter has gone down, we can assume that we
* will PERST it and that will invalidate everything.
*/
if (!cxl_adapter_link_ok(afu->adapter))
if (!cxl_ops->link_ok(afu->adapter))
return -EIO;
cpu_relax();
}
Expand Down Expand Up @@ -228,7 +230,7 @@ struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)

afu->adapter = adapter;
afu->dev.parent = &adapter->dev;
afu->dev.release = cxl_release_afu;
afu->dev.release = cxl_ops->release_afu;
afu->slice = slice;
idr_init(&afu->contexts_idr);
mutex_init(&afu->contexts_lock);
Expand All @@ -244,10 +246,10 @@ struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)
int cxl_afu_select_best_mode(struct cxl_afu *afu)
{
if (afu->modes_supported & CXL_MODE_DIRECTED)
return cxl_afu_activate_mode(afu, CXL_MODE_DIRECTED);
return cxl_ops->afu_activate_mode(afu, CXL_MODE_DIRECTED);

if (afu->modes_supported & CXL_MODE_DEDICATED)
return cxl_afu_activate_mode(afu, CXL_MODE_DEDICATED);
return cxl_ops->afu_activate_mode(afu, CXL_MODE_DEDICATED);

dev_warn(&afu->dev, "No supported programming modes available\n");
/* We don't fail this so the user can inspect sysfs */
Expand All @@ -269,6 +271,7 @@ static int __init init_cxl(void)
if ((rc = register_cxl_calls(&cxl_calls)))
goto err;

cxl_ops = &cxl_native_ops;
if ((rc = pci_register_driver(&cxl_pci_driver)))
goto err1;

Expand Down
Loading

0 comments on commit 5be587b

Please sign in to comment.