sparc64: Oracle DAX infrastructure
authorRob Gardner <rob.gardner@oracle.com>
Wed, 6 Dec 2017 02:40:42 +0000 (19:40 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 22 Jan 2018 16:17:15 +0000 (08:17 -0800)
This patch adds hypercall function stubs and C templates for
ccb_submit/info/kill which provide coprocessor services for the Oracle
Data Analytics Accelerator, registration for the DAX api group, and
all the various associated constants.

Signed-off-by: Rob Gardner <rob.gardner@oracle.com>
Signed-off-by: Jonathan Helman <jonathan.helman@oracle.com>
Signed-off-by: Sanath Kumar <sanath099@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc/include/asm/hypervisor.h
arch/sparc/kernel/hvapi.c
arch/sparc/kernel/hvcalls.S

index 89a0c57..ab9c6b0 100644 (file)
 #define HV_ETOOMANY                    15 /* Too many items specified     */
 #define HV_ECHANNEL                    16 /* Invalid LDC channel          */
 #define HV_EBUSY                       17 /* Resource busy                */
+#define HV_EUNAVAILABLE                        23 /* Resource or operation not
+                                           * currently available, but may
+                                           * become available in the future
+                                           */
 
 /* mach_exit()
  * TRAP:       HV_FAST_TRAP
@@ -941,6 +945,139 @@ unsigned long sun4v_mmu_map_perm_addr(unsigned long vaddr,
  */
 #define HV_FAST_MEM_SYNC               0x32
 
+/* Coprocessor services
+ *
+ * M7 and later processors provide an on-chip coprocessor which
+ * accelerates database operations, and is known internally as
+ * DAX.
+ */
+
+/* ccb_submit()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_CCB_SUBMIT
+ * 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:       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_CCB_SUBMIT               0x34
+#ifndef __ASSEMBLY__
+unsigned long sun4v_ccb_submit(unsigned long ccb_buf,
+                              unsigned long len,
+                              unsigned long flags,
+                              unsigned long reserved,
+                              void *submitted_len,
+                              void *status_data);
+#endif
+
+/* flags (ARG2) */
+#define HV_CCB_QUERY_CMD               BIT(1)
+#define HV_CCB_ARG0_TYPE_REAL          0UL
+#define HV_CCB_ARG0_TYPE_PRIMARY       BIT(4)
+#define HV_CCB_ARG0_TYPE_SECONDARY     BIT(5)
+#define HV_CCB_ARG0_TYPE_NUCLEUS       GENMASK(5, 4)
+#define HV_CCB_ARG0_PRIVILEGED         BIT(6)
+#define HV_CCB_ALL_OR_NOTHING          BIT(7)
+#define HV_CCB_QUEUE_INFO              BIT(8)
+#define HV_CCB_VA_REJECT               0UL
+#define HV_CCB_VA_SECONDARY            BIT(13)
+#define HV_CCB_VA_NUCLEUS              GENMASK(13, 12)
+#define HV_CCB_VA_PRIVILEGED           BIT(14)
+#define HV_CCB_VA_READ_ADI_DISABLE     BIT(15) /* DAX2 only */
+
+/* ccb_info()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_CCB_INFO
+ * ARG0:       real address of CCB completion area
+ * RET0:       status (success or error code)
+ * RET1:       info array
+ *                     - RET1[0]: CCB state
+ *                     - RET1[1]: dax unit
+ *                     - RET1[2]: queue number
+ *                     - RET1[3]: queue position
+ *
+ * ERRORS:     EOK             operation successful
+ *             EBADALIGN       address not 64B aligned
+ *             ENORADDR        RA in address not valid
+ *             EINVAL          CA not valid
+ *             EWOULDBLOCK     info not available for this CCB currently, try
+ *                             again
+ *             ENOACCESS       guest cannot use dax
+ */
+
+#define HV_CCB_INFO                 0x35
+#ifndef __ASSEMBLY__
+unsigned long sun4v_ccb_info(unsigned long ca,
+                            void *info_arr);
+#endif
+
+/* info array byte offsets (RET1) */
+#define CCB_INFO_OFFSET_CCB_STATE      0
+#define CCB_INFO_OFFSET_DAX_UNIT       2
+#define CCB_INFO_OFFSET_QUEUE_NUM      4
+#define CCB_INFO_OFFSET_QUEUE_POS      6
+
+/* CCB state (RET1[0]) */
+#define HV_CCB_STATE_COMPLETED      0
+#define HV_CCB_STATE_ENQUEUED       1
+#define HV_CCB_STATE_INPROGRESS     2
+#define HV_CCB_STATE_NOTFOUND       3
+
+/* ccb_kill()
+ * TRAP:       HV_FAST_TRAP
+ * FUNCTION:   HV_CCB_KILL
+ * ARG0:       real address of CCB completion area
+ * RET0:       status (success or error code)
+ * RET1:       CCB kill status
+ *
+ * ERRORS:     EOK             operation successful
+ *             EBADALIGN       address not 64B aligned
+ *             ENORADDR        RA in address not valid
+ *             EINVAL          CA not valid
+ *             EWOULDBLOCK     kill not available for this CCB currently, try
+ *                             again
+ *             ENOACCESS       guest cannot use dax
+ */
+
+#define HV_CCB_KILL                 0x36
+#ifndef __ASSEMBLY__
+unsigned long sun4v_ccb_kill(unsigned long ca,
+                            void *kill_status);
+#endif
+
+/* CCB kill status (RET1) */
+#define HV_CCB_KILL_COMPLETED       0
+#define HV_CCB_KILL_DEQUEUED        1
+#define HV_CCB_KILL_KILLED          2
+#define HV_CCB_KILL_NOTFOUND        3
+
 /* Time of day services.
  *
  * The hypervisor maintains the time of day on a per-domain basis.
@@ -3355,6 +3492,7 @@ unsigned long sun4v_m7_set_perfreg(unsigned long reg_num,
 #define HV_GRP_SDIO_ERR                        0x0109
 #define HV_GRP_REBOOT_DATA             0x0110
 #define HV_GRP_ATU                     0x0111
+#define HV_GRP_DAX                     0x0113
 #define HV_GRP_M7_PERF                 0x0114
 #define HV_GRP_NIAG_PERF               0x0200
 #define HV_GRP_FIRE_PERF               0x0201
index a2bc1b2..717ec7e 100644 (file)
@@ -41,6 +41,7 @@ static struct api_info api_table[] = {
        { .group = HV_GRP_SDIO_ERR,                             },
        { .group = HV_GRP_REBOOT_DATA,                          },
        { .group = HV_GRP_ATU,          .flags = FLAG_PRE_API   },
+       { .group = HV_GRP_DAX,                                  },
        { .group = HV_GRP_NIAG_PERF,    .flags = FLAG_PRE_API   },
        { .group = HV_GRP_FIRE_PERF,                            },
        { .group = HV_GRP_N2_CPU,                               },
index bdfd3d8..2f865a4 100644 (file)
@@ -871,3 +871,60 @@ ENTRY(sun4v_m7_set_perfreg)
        retl
        nop
 ENDPROC(sun4v_m7_set_perfreg)
+
+       /* %o0: address of CCB array
+        * %o1: size (in bytes) of CCB array
+        * %o2: flags
+        * %o3: reserved
+        *
+        * returns:
+        * %o0: status
+        * %o1: size (in bytes) of the CCB array that was accepted
+        * %o2: status data
+        * %o3: reserved
+        */
+ENTRY(sun4v_ccb_submit)
+       mov     %o5, %g1
+       mov     HV_CCB_SUBMIT, %o5
+       ta      HV_FAST_TRAP
+       stx     %o1, [%o4]
+       retl
+        stx    %o2, [%g1]
+ENDPROC(sun4v_ccb_submit)
+EXPORT_SYMBOL(sun4v_ccb_submit)
+
+       /* %o0: completion area ra for the ccb to get info
+        *
+        * returns:
+        * %o0: status
+        * %o1: CCB state
+        * %o2: position
+        * %o3: dax unit
+        * %o4: queue
+        */
+ENTRY(sun4v_ccb_info)
+       mov     %o1, %g1
+       mov     HV_CCB_INFO, %o5
+       ta      HV_FAST_TRAP
+       sth     %o1, [%g1 + CCB_INFO_OFFSET_CCB_STATE]
+       sth     %o2, [%g1 + CCB_INFO_OFFSET_QUEUE_POS]
+       sth     %o3, [%g1 + CCB_INFO_OFFSET_DAX_UNIT]
+       retl
+        sth    %o4, [%g1 + CCB_INFO_OFFSET_QUEUE_NUM]
+ENDPROC(sun4v_ccb_info)
+EXPORT_SYMBOL(sun4v_ccb_info)
+
+       /* %o0: completion area ra for the ccb to kill
+        *
+        * returns:
+        * %o0: status
+        * %o1: result of the kill
+        */
+ENTRY(sun4v_ccb_kill)
+       mov     %o1, %g1
+       mov     HV_CCB_KILL, %o5
+       ta      HV_FAST_TRAP
+       retl
+        sth    %o1, [%g1]
+ENDPROC(sun4v_ccb_kill)
+EXPORT_SYMBOL(sun4v_ccb_kill)