mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-27 14:43:58 +08:00
d9232a3da8
userspace programs using cxl currently have to use two strategies for dealing with MMIO errors simultaneously. They have to check every read for a return of all Fs in case the adapter has gone away and the kernel has not yet noticed, and they have to deal with SIGBUS in case the kernel has already noticed, invalidated the mapping and marked the context as failed. In order to simplify things, this patch adds an alternative approach where the kernel will return a page filled with Fs instead of delivering a SIGBUS. This allows userspace to only need to deal with one of these two error paths, and is intended for use in libraries that use cxl transparently and may not be able to safely install a signal handler. This approach will only work if certain constraints are met. Namely, if the application is both reading and writing to an address in the problem state area it cannot assume that a non-FF read is OK, as it may just be reading out a value it has previously written. Further - since only one page is used per context a write to a given offset would be visible when reading the same offset from a different page in the mapping (this only applies within a single context, not between contexts). An application could deal with this by e.g. making sure it also reads from a read-only offset after any reads to a read/write offset. Due to these constraints, this functionality must be explicitly requested by userspace when starting the context by passing in the CXL_START_WORK_ERR_FF flag. Signed-off-by: Ian Munsie <imunsie@au1.ibm.com> Acked-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
113 lines
2.5 KiB
C
113 lines
2.5 KiB
C
/*
|
|
* Copyright 2014 IBM Corp.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version
|
|
* 2 of the License, or (at your option) any later version.
|
|
*/
|
|
|
|
#ifndef _UAPI_MISC_CXL_H
|
|
#define _UAPI_MISC_CXL_H
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/ioctl.h>
|
|
|
|
|
|
struct cxl_ioctl_start_work {
|
|
__u64 flags;
|
|
__u64 work_element_descriptor;
|
|
__u64 amr;
|
|
__s16 num_interrupts;
|
|
__s16 reserved1;
|
|
__s32 reserved2;
|
|
__u64 reserved3;
|
|
__u64 reserved4;
|
|
__u64 reserved5;
|
|
__u64 reserved6;
|
|
};
|
|
|
|
#define CXL_START_WORK_AMR 0x0000000000000001ULL
|
|
#define CXL_START_WORK_NUM_IRQS 0x0000000000000002ULL
|
|
#define CXL_START_WORK_ERR_FF 0x0000000000000004ULL
|
|
#define CXL_START_WORK_ALL (CXL_START_WORK_AMR |\
|
|
CXL_START_WORK_NUM_IRQS |\
|
|
CXL_START_WORK_ERR_FF)
|
|
|
|
|
|
/* Possible modes that an afu can be in */
|
|
#define CXL_MODE_DEDICATED 0x1
|
|
#define CXL_MODE_DIRECTED 0x2
|
|
|
|
/* possible flags for the cxl_afu_id flags field */
|
|
#define CXL_AFUID_FLAG_SLAVE 0x1 /* In directed-mode afu is in slave mode */
|
|
|
|
struct cxl_afu_id {
|
|
__u64 flags; /* One of CXL_AFUID_FLAG_X */
|
|
__u32 card_id;
|
|
__u32 afu_offset;
|
|
__u32 afu_mode; /* one of the CXL_MODE_X */
|
|
__u32 reserved1;
|
|
__u64 reserved2;
|
|
__u64 reserved3;
|
|
__u64 reserved4;
|
|
__u64 reserved5;
|
|
__u64 reserved6;
|
|
};
|
|
|
|
/* ioctl numbers */
|
|
#define CXL_MAGIC 0xCA
|
|
#define CXL_IOCTL_START_WORK _IOW(CXL_MAGIC, 0x00, struct cxl_ioctl_start_work)
|
|
#define CXL_IOCTL_GET_PROCESS_ELEMENT _IOR(CXL_MAGIC, 0x01, __u32)
|
|
#define CXL_IOCTL_GET_AFU_ID _IOR(CXL_MAGIC, 0x02, struct cxl_afu_id)
|
|
|
|
#define CXL_READ_MIN_SIZE 0x1000 /* 4K */
|
|
|
|
/* Events from read() */
|
|
enum cxl_event_type {
|
|
CXL_EVENT_RESERVED = 0,
|
|
CXL_EVENT_AFU_INTERRUPT = 1,
|
|
CXL_EVENT_DATA_STORAGE = 2,
|
|
CXL_EVENT_AFU_ERROR = 3,
|
|
};
|
|
|
|
struct cxl_event_header {
|
|
__u16 type;
|
|
__u16 size;
|
|
__u16 process_element;
|
|
__u16 reserved1;
|
|
};
|
|
|
|
struct cxl_event_afu_interrupt {
|
|
__u16 flags;
|
|
__u16 irq; /* Raised AFU interrupt number */
|
|
__u32 reserved1;
|
|
};
|
|
|
|
struct cxl_event_data_storage {
|
|
__u16 flags;
|
|
__u16 reserved1;
|
|
__u32 reserved2;
|
|
__u64 addr;
|
|
__u64 dsisr;
|
|
__u64 reserved3;
|
|
};
|
|
|
|
struct cxl_event_afu_error {
|
|
__u16 flags;
|
|
__u16 reserved1;
|
|
__u32 reserved2;
|
|
__u64 error;
|
|
};
|
|
|
|
struct cxl_event {
|
|
struct cxl_event_header header;
|
|
union {
|
|
struct cxl_event_afu_interrupt irq;
|
|
struct cxl_event_data_storage fault;
|
|
struct cxl_event_afu_error afu_error;
|
|
};
|
|
};
|
|
|
|
#endif /* _UAPI_MISC_CXL_H */
|