From 42e640112d5463db79eda91cba963b0c47fd1d8f Mon Sep 17 00:00:00 2001 From: Jonathan Helman Date: Mon, 1 May 2017 11:47:15 -0700 Subject: [PATCH] sparc64: update DAX submit to latest HV spec Orabug: 25927558 DAX submit needs to be updated to the latest HV spec. Along with a couple small updates, the biggest modification is changing nomap_va to status_data. This is mostly a cosmetic change but also adds support to return the unavailable code via the exec ioctl. Further, augment the comments and fix up a couple nits in the ccb submit hcall in hypervisor.h. Signed-off-by: Jonathan Helman Reviewed-by: Rob Gardner Signed-off-by: Allen Pais --- arch/sparc/dax/dax_main.c | 21 +++++---- arch/sparc/dax/dax_misc.c | 8 ++-- arch/sparc/include/asm/hypervisor.h | 71 ++++++++++++++++++----------- arch/sparc/kernel/hvcalls.S | 8 ++-- 4 files changed, 64 insertions(+), 44 deletions(-) diff --git a/arch/sparc/dax/dax_main.c b/arch/sparc/dax/dax_main.c index 0c3536e1e86c..696e0276fba5 100644 --- a/arch/sparc/dax/dax_main.c +++ b/arch/sparc/dax/dax_main.c @@ -873,7 +873,7 @@ static int dax_ccb_hv_submit(struct dax_ctx *dax_ctx, union ccb *ccb_buf, size_t buflen, struct dax_ccb_exec_arg *exec_arg) { unsigned long submitted_ccb_buf_len = 0; - unsigned long nomap_va = 0; + unsigned long status_data = 0; unsigned long hv_rv = HV_ENOMAP; int rv = -EIO; ptrdiff_t offset; @@ -892,7 +892,7 @@ static int dax_ccb_hv_submit(struct dax_ctx *dax_ctx, union ccb *ccb_buf, offset, buflen, HV_DAX_QUERY_CMD | HV_DAX_CCB_VA_SECONDARY, 0, - &submitted_ccb_buf_len, &nomap_va); + &submitted_ccb_buf_len, &status_data); if (dax_debug & DAX_DBG_FLG_BASIC) dax_prt_ccbs(ccb_buf, buflen); @@ -901,8 +901,8 @@ static int dax_ccb_hv_submit(struct dax_ctx *dax_ctx, union ccb *ccb_buf, exec_arg->dce_submitted_ccb_buf_len = 0; exec_arg->dce_ca_region_off = 0; - dax_dbg("hcall rv=%ld, submitted_ccb_buf_len=%ld, nomap_va=0x%lx", - hv_rv, submitted_ccb_buf_len, nomap_va); + dax_dbg("hcall rv=%ld, submitted_ccb_buf_len=%ld, status_data=0x%lx", + hv_rv, submitted_ccb_buf_len, status_data); if (submitted_ccb_buf_len % sizeof(union ccb) != 0) { dax_err("submitted_ccb_buf_len %ld not multiple of ccb size %ld", @@ -940,9 +940,8 @@ static int dax_ccb_hv_submit(struct dax_ctx *dax_ctx, union ccb *ccb_buf, * HV was unable to translate a VA. The VA it could not * translate is returned in the nomap_va param. */ - dax_err("hcall returned HV_ENOMAP nomap_va=0x%lx with %d retries", - nomap_va, DAX_NOMAP_RETRIES); - exec_arg->dce_nomap_va = nomap_va; + dax_err("hcall returned HV_ENOMAP nomap_va=0x%lx", status_data); + exec_arg->dce_nomap_va = status_data; exec_arg->dce_ccb_status = DAX_SUBMIT_ERR_NOMAP; break; case HV_EINVAL: @@ -966,17 +965,19 @@ static int dax_ccb_hv_submit(struct dax_ctx *dax_ctx, union ccb *ccb_buf, */ dax_err("hcall returned HV_ENOACCESS"); exec_arg->dce_ccb_status = DAX_SUBMIT_ERR_NOACCESS; - exec_arg->dce_nomap_va = nomap_va; + exec_arg->dce_nomap_va = status_data; break; case HV_EUNAVAILABLE: /* * The requested CCB operation could not be performed at this * time. The restrict-ed operation availability may apply only * to the first unsuccessfully submitted CCB, or may apply to a - * larger scope. + * larger scope. Return the specific unavailable code in the + * nomap_va field. */ - dax_err("hcall returned HV_EUNAVAILABLE"); + dax_err("hcall returned HV_EUNAVAILABLE code=%ld", status_data); exec_arg->dce_ccb_status = DAX_SUBMIT_ERR_UNAVAIL; + exec_arg->dce_nomap_va = status_data; break; default: exec_arg->dce_ccb_status = DAX_SUBMIT_ERR_INTERNAL; diff --git a/arch/sparc/dax/dax_misc.c b/arch/sparc/dax/dax_misc.c index 1928df9b423c..9a533463ac57 100644 --- a/arch/sparc/dax/dax_misc.c +++ b/arch/sparc/dax/dax_misc.c @@ -14,7 +14,7 @@ static int dax_has_flow_ctl_one_node(void) struct ccb_extract *ccb; struct ccb_completion_area *ca; char *mem, *dax_input, *dax_output; - unsigned long submitted_ccb_buf_len, nomap_va, hv_rv, ra, va; + unsigned long submitted_ccb_buf_len, status_data, hv_rv, ra, va; long timeout; int ret = 0; @@ -58,7 +58,7 @@ static int dax_has_flow_ctl_one_node(void) ra = virt_to_phys(ccb); hv_rv = sun4v_dax_ccb_submit((void *) ra, 64, HV_DAX_CCB_VA_PRIVILEGED | HV_DAX_QUERY_CMD, 0, - &submitted_ccb_buf_len, &nomap_va); + &submitted_ccb_buf_len, &status_data); if (hv_rv != HV_EOK) { dax_info("failed dax submit, ret=0x%lx", hv_rv); if (dax_debug & DAX_DBG_FLG_BASIC) @@ -164,7 +164,7 @@ bool dax_has_ra_pgsz(void) struct ccb_extract *ccb; struct ccb_completion_area *ca; char *mem, *dax_input, *dax_output; - unsigned long submitted_ccb_buf_len, nomap_va, hv_rv, ra, va; + unsigned long submitted_ccb_buf_len, status_data, hv_rv, ra, va; long timeout; bool ret = false; int i; @@ -214,7 +214,7 @@ bool dax_has_ra_pgsz(void) ra = virt_to_phys(ccb); hv_rv = sun4v_dax_ccb_submit((void *) ra, 64, HV_DAX_CCB_VA_PRIVILEGED | HV_DAX_QUERY_CMD, 0, - &submitted_ccb_buf_len, &nomap_va); + &submitted_ccb_buf_len, &status_data); if (hv_rv != HV_EOK) { dax_info("failed dax submit, ret=0x%lx", hv_rv); if (dax_debug & DAX_DBG_FLG_BASIC) diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h index d2b29427036d..b4996e679c0b 100644 --- a/arch/sparc/include/asm/hypervisor.h +++ b/arch/sparc/include/asm/hypervisor.h @@ -946,39 +946,58 @@ extern unsigned long sun4v_mmu_unmap_perm_addr(unsigned long vaddr, /* dax_ccb_submit() * TRAP: HV_FAST_TRAP * FUNCTION: HV_DAX_CCB_SUBMIT - * ARG0: address of CCB array - * ARG1: size (in bytes) of CCB array being submitted - * ARG2: flags - * ARG3: virtual queue token + * ARG0: address of CCB array + * ARG1: size (in bytes) of CCB array being submitted + * ARG2: flags + * ARG3: reserved * RET0: status (success or error code) - * RET1 size (in bytes) of CCB array that was accepted (might be less than arg1) - * RET2 Identifies the VA in question when status is ENOMAP or ENOACCESS - * RET3 (if using virtual message queues) new virtual queue token - * - * ERRORS: EWOULDBLOCK etc - * ENOTSUPPORTED etc - * - * Details. + * RET1: size (in bytes) of CCB array that was accepted (might be less + * than arg1) + * RET2: status data + * if status == ENOMAP or ENOACCESS, identifies the VA in question + * if status == EUNAVAILBLE, unavailable code + * RET3: reserved + * + * ERRORS: EOK successful submission (check size) + * EWOULDBLOCK could not finish submissions, try again + * EBADALIGN array not 64B aligned or size not 64B multiple + * ENORADDR invalid RA for array or in CCB + * ENOMAP could not translate address (see status data) + * EINVAL invalid ccb or arguments + * ETOOMANY too many ccbs with all-or-nothing flag + * ENOACCESS guest has no access to submit ccbs or address + * in CCB does not have correct permissions (check + * status data) + * EUNAVAILABLE ccb operation could not be performed at this + * time (check status data) + * Status data codes: + * 0 - exact CCB could not be executed + * 1 - CCB opcode cannot be executed + * 2 - CCB version cannot be executed + * 3 - vcpu cannot execute CCBs + * 4 - no CCBs can be executed */ #define HV_DAX_CCB_SUBMIT 0x34 #ifndef __ASSEMBLY__ -unsigned long sun4v_dax_ccb_submit(void *ccb, int len, long flags, long vq_token, long *submitted_len, long *error_va); +unsigned long sun4v_dax_ccb_submit(void *ccb, int len, long flags, + long reserved, long *submitted_len, + long *status_data); #endif /* flags (ARG2) */ -#define HV_DAX_MESSAGE_CMD (0) -#define HV_DAX_VIRTUAL_MESSAGE_CMD (1) -#define HV_DAX_QUERY_CMD (2) -#define HV_DAX_ARG0_TYPE_REAL (0 << 4) -#define HV_DAX_ARG0_TYPE_PRIMARY (1 << 4) -#define HV_DAX_ARG0_TYPE_SECONDARY (2 << 4) -#define HV_DAX_ARG0_TYPE_NUCLEUS (3 << 4) -#define HV_DAX_ARG0_PRIVILEGED (1 << 6) -#define HV_DAX_ALL_OR_NOTHING (1 << 7) -#define HV_DAX_CCB_VA_REJECT (0 << 12) -#define HV_DAX_CCB_VA_SECONDARY (2 << 12) -#define HV_DAX_CCB_VA_NUCLEUS (3 << 12) -#define HV_DAX_CCB_VA_PRIVILEGED (1 << 14) +#define BIT_FIELD(n, s) ((n) << (s)) +#define HV_DAX_QUERY_CMD BIT_FIELD(2UL, 0) +#define HV_DAX_ARG0_TYPE_REAL BIT_FIELD(0UL, 4) +#define HV_DAX_ARG0_TYPE_PRIMARY BIT_FIELD(1UL, 4) +#define HV_DAX_ARG0_TYPE_SECONDARY BIT_FIELD(2UL, 4) +#define HV_DAX_ARG0_TYPE_NUCLEUS BIT_FIELD(3UL, 4) +#define HV_DAX_ARG0_PRIVILEGED BIT(6) +#define HV_DAX_ALL_OR_NOTHING BIT(7) +#define HV_DAX_QUEUE_INFO BIT(8) +#define HV_DAX_CCB_VA_REJECT BIT_FIELD(0UL, 12) +#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) /* dax_ccb_info() * TRAP: HV_FAST_TRAP diff --git a/arch/sparc/kernel/hvcalls.S b/arch/sparc/kernel/hvcalls.S index 143994e75a25..a5388b4b79df 100644 --- a/arch/sparc/kernel/hvcalls.S +++ b/arch/sparc/kernel/hvcalls.S @@ -219,13 +219,13 @@ ENDPROC(sun4v_set_version) /* %o0: address of CCB array * %o1: size (in bytes) of CCB array * %o2: flags - * %o3: virtual queue token + * %o3: reserved * * returns: * %o0: status * %o1: size (in bytes) of the CCB array that was accepted - * %o2: error address - * %o3: new virtual queue token + * %o2: status data + * %o3: reserved */ ENTRY(sun4v_dax_ccb_submit) mov %o5, %g1 @@ -233,7 +233,7 @@ ENTRY(sun4v_dax_ccb_submit) ta HV_FAST_TRAP stx %o1, [%o4] retl - stx %o2, [%g1] + stx %o2, [%g1] ENDPROC(sun4v_dax_ccb_submit) /* %o0: pointer to unsigned long time -- 2.50.1