]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sparc64: update DAX submit to latest HV spec
authorJonathan Helman <jonathan.helman@oracle.com>
Mon, 1 May 2017 18:47:15 +0000 (11:47 -0700)
committerShannon Nelson <shannon.nelson@oracle.com>
Wed, 31 May 2017 23:43:48 +0000 (16:43 -0700)
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 <jonathan.helman@oracle.com>
Reviewed-by: Rob Gardner <rob.gardner@oracle.com>
Signed-off-by: Allen Pais <allen.pais@oracle.com>
arch/sparc/dax/dax_main.c
arch/sparc/dax/dax_misc.c
arch/sparc/include/asm/hypervisor.h
arch/sparc/kernel/hvcalls.S

index 0c3536e1e86c73ee574a6fee5d8074cb54fbc614..696e0276fba574e119e17132c33003c17c86d4bd 100644 (file)
@@ -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;
index 1928df9b423c8aff0b8706381482502b54e2ec3a..9a533463ac57369a570c67ed3bf84c3f65b9f7a0 100644 (file)
@@ -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)
index d2b29427036dd771b85784c31f9ebf9d563460b5..b4996e679c0b45cba83c2634f85dde0c08935f3b 100644 (file)
@@ -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
index 143994e75a25d4603dd4f9085fb9fdcd1151d86d..a5388b4b79df056bc5c57c5166064291e8259aa1 100644 (file)
@@ -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