From e36ca7533dce9818f600ca286086fdf0cb348f90 Mon Sep 17 00:00:00 2001 From: Allen Pais Date: Thu, 22 Jun 2017 12:36:21 +0530 Subject: [PATCH] sparc64: add DAX2 support to dax driver Orabug: 25904994 Introduce DAX2 support in the driver. This involves negotiating the right version with hypervisor as well as exposing a new INIT_V2 ioctl. This new ioctl will return failure if DAX2 is not present on the system, otherwise it will attempt to initialize the DAX2. A user should first call INIT_V2 and on failure call INIT_V1. See Documentation/sparc/dax.txt for more detail. Signed-off-by: Jonathan Helman Reviewed-by: Sanath Kumar Signed-off-by: Allen Pais --- Documentation/sparc/dax.txt | 13 ++++++++++++ arch/sparc/dax/dax_impl.h | 2 ++ arch/sparc/dax/dax_main.c | 33 ++++++++++++++++++++++------- arch/sparc/dax/sys_dax.h | 3 ++- arch/sparc/include/asm/hypervisor.h | 3 ++- arch/sparc/kernel/hvapi.c | 2 +- 6 files changed, 45 insertions(+), 11 deletions(-) diff --git a/Documentation/sparc/dax.txt b/Documentation/sparc/dax.txt index 877d37f36c9e..9156f9a4f77d 100644 --- a/Documentation/sparc/dax.txt +++ b/Documentation/sparc/dax.txt @@ -82,6 +82,19 @@ needed for the mmap() call so that the user can get access to the completion area buffer. Another value returned is the maximum length of the CCB array that may be submitted. +CCB_THR_INIT_V2 + +Initializes the DAX driver for DAX2 if available. If DAX2 is not available, +returns an error. The user should do the following to determine the DAX version +on their system: + +if (ioctl(CCB_THR_INIT_V2) == SUCCESS) + /* DAX2 available on system */ +else if (ioctl(CCB_THR_INIT) == SUCCESS) + /* DAX1 available on system */ +else + /* no DAX available on system */ + CCB_THR_FINI Destroys a context for a thread. After doing this, the thread can no longer diff --git a/arch/sparc/dax/dax_impl.h b/arch/sparc/dax/dax_impl.h index 894dfe5ea359..51eb93eaf611 100644 --- a/arch/sparc/dax/dax_impl.h +++ b/arch/sparc/dax/dax_impl.h @@ -108,6 +108,8 @@ extern const struct vm_operations_struct dax_vm_ops; #define DAX_NAME "dax" #define DAX_MINOR 1UL #define DAX_MAJOR 1UL +#define DAX2_MINOR 0UL +#define DAX2_MAJOR 2UL #define DAX1_STR "ORCL,sun4v-dax" #define DAX1_FC_STR "ORCL,sun4v-dax-fc" diff --git a/arch/sparc/dax/dax_main.c b/arch/sparc/dax/dax_main.c index 98e046a21114..3a15be27965f 100644 --- a/arch/sparc/dax/dax_main.c +++ b/arch/sparc/dax/dax_main.c @@ -73,7 +73,7 @@ static int hv_get_hwqueue_size(unsigned long *qsize) static int __init dax_attach(void) { - unsigned long minor = DAX_MINOR; + unsigned long major, minor, minor_requested; unsigned long max_ccbs; int ret = 0, found_dax = 0; struct mdesc_handle *hp = mdesc_grab(); @@ -106,14 +106,22 @@ static int __init dax_attach(void) if (!strncmp(prop, DAX1_FC_STR, strlen(DAX1_FC_STR))) { msg = "dax1-flow-control"; dax_type = DAX1; + major = DAX_MAJOR; + minor_requested = DAX_MINOR; } else if (!strncmp(prop, DAX2_STR, strlen(DAX2_STR))) { msg = "dax2"; dax_type = DAX2; + major = DAX2_MAJOR; + minor_requested = DAX2_MINOR; } else if (!strncmp(prop, DAX1_STR, strlen(DAX1_STR))) { msg = "dax1-no-flow-control"; dax_no_flow_ctl = true; dax_type = DAX1; + major = DAX_MAJOR; + minor_requested = DAX_MINOR; } else { + major = DAX_MAJOR; + minor_requested = DAX_MINOR; break; } found_dax = 1; @@ -129,21 +137,23 @@ static int __init dax_attach(void) } } - dax_dbg("Registering DAX HV api with minor %ld", minor); - if (sun4v_hvapi_register(HV_GRP_M7_DAX, DAX_MAJOR, &minor)) { + minor = minor_requested; + dax_dbg("Registering DAX HV api with major %ld minor %ld", major, + minor); + if (sun4v_hvapi_register(HV_GRP_DAX, major, &minor)) { dax_err("hvapi_register failed"); if ((force & FORCE_LOAD_ON_ERROR) == 0) { ret = -ENODEV; goto done; } } else { - dax_dbg("Max minor supported by HV = %ld", minor); - minor = min(minor, DAX_MINOR); - dax_dbg("registered DAX major %ld minor %ld ", - DAX_MAJOR, minor); + dax_dbg("Max minor supported by HV = %ld (major %ld)", minor, + major); + minor = min(minor, minor_requested); + dax_dbg("registered DAX major %ld minor %ld", major, minor); } - dax_no_ra_pgsz = (DAX_MAJOR == 1) && (minor == 0) && !dax_has_ra_pgsz(); + dax_no_ra_pgsz = (major == 1) && (minor == 0) && !dax_has_ra_pgsz(); dax_dbg("RA pagesize feature %spresent", dax_no_ra_pgsz ? "not " : ""); ret = hv_get_hwqueue_size(&max_ccbs); @@ -287,6 +297,13 @@ static long dax_ioctl(struct file *f, unsigned int cmd, unsigned long arg) { dax_dbg("cmd=0x%x, f=%p, priv=%p", cmd, f, f->private_data); switch (cmd) { + case DAXIOC_CCB_THR_INIT_V2: + if (dax_type != DAX2) + return -ENXIO; + /* + * fall-through: INIT_V2 is just to test if DAX2 is available, + * but initializing DAX1 and DAX2 is the same + */ case DAXIOC_CCB_THR_INIT: return dax_ioctl_ccb_thr_init((void *)arg, f); case DAXIOC_CCB_THR_FINI: diff --git a/arch/sparc/dax/sys_dax.h b/arch/sparc/dax/sys_dax.h index fb0a985237c8..40b00843f9a6 100644 --- a/arch/sparc/dax/sys_dax.h +++ b/arch/sparc/dax/sys_dax.h @@ -56,6 +56,7 @@ /* CCB thread initialization */ #define DAXIOC_CCB_THR_INIT _IOWR(DAXIOC, 6, struct dax_ccb_thr_init_arg) +#define DAXIOC_CCB_THR_INIT_V2 _IOWR(DAXIOC, 11, struct dax_ccb_thr_init_arg) /* free CCB thread resources */ #define DAXIOC_CCB_THR_FINI _IO(DAXIOC, 2) /* CCB CA dequeue */ @@ -78,7 +79,7 @@ #define DAXIOC_PERF_CLEAR_COUNTERS _IOW(DAXIOC, 0xBC, void *) /* - * DAXIOC_CCB_THR_INIT + * DAXIOC_CCB_THR_INIT, DAXIOC_CCB_THR_INIT_V2 * dcti_ccb_buf_maxlen - return u32 length * dcti_compl_maplen - return u64 mmap length * dcti_compl_mapoff - return u64 mmap offset diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h index 86e357d18f10..b0bbdd6f5954 100644 --- a/arch/sparc/include/asm/hypervisor.h +++ b/arch/sparc/include/asm/hypervisor.h @@ -998,6 +998,7 @@ unsigned long sun4v_dax_ccb_submit(void *ccb, int len, long flags, #define HV_DAX_CCB_VA_SECONDARY BIT_FIELD(2UL, 12) #define HV_DAX_CCB_VA_NUCLEUS BIT_FIELD(3UL, 12) #define HV_DAX_CCB_VA_PRIVILEGED BIT(14) +#define HV_DAX_VA_READ_ADI_DISABLE BIT(15) /* defined in API 2.0 */ /* dax_ccb_info() * TRAP: HV_FAST_TRAP @@ -3823,7 +3824,7 @@ struct hv_pci_priq_intx_info { #define HV_GRP_SDIO 0x0108 #define HV_GRP_SDIO_ERR 0x0109 #define HV_GRP_REBOOT_DATA 0x0110 -#define HV_GRP_M7_DAX 0x0113 +#define HV_GRP_DAX 0x0113 #define HV_GRP_M7_PERF 0x0114 #define HV_GRP_PRIQ 0x011b #define HV_GRP_PRIQ_PCI 0x011c diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c index 19b3ca1cddfd..7a873ba5103a 100644 --- a/arch/sparc/kernel/hvapi.c +++ b/arch/sparc/kernel/hvapi.c @@ -39,7 +39,7 @@ static struct api_info api_table[] = { { .group = HV_GRP_SDIO, }, { .group = HV_GRP_SDIO_ERR, }, { .group = HV_GRP_REBOOT_DATA, }, - { .group = HV_GRP_M7_DAX, }, + { .group = HV_GRP_DAX, }, { .group = HV_GRP_PRIQ, }, { .group = HV_GRP_PRIQ_PCI, }, { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API }, -- 2.50.1