Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszer...
[cascardo/linux.git] / drivers / misc / sgi-xp / xpc.h
index 114444c..b94d5f7 100644 (file)
@@ -90,18 +90,21 @@ struct xpc_rsvd_page {
        short max_npartitions;  /* value of XPC_MAX_PARTITIONS */
        u8 version;
        u8 pad1[3];             /* align to next u64 in 1st 64-byte cacheline */
+       unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
        union {
-               unsigned long vars_pa;  /* phys address of struct xpc_vars */
-               unsigned long activate_gru_mq_desc_gpa; /* phys addr of */
-                                                       /* activate mq's */
-                                                       /* gru mq descriptor */
+               struct {
+                       unsigned long vars_pa;  /* phys addr */
+               } sn2;
+               struct {
+                       unsigned long heartbeat_gpa; /* phys addr */
+                       unsigned long activate_gru_mq_desc_gpa; /* phys addr */
+               } uv;
        } sn;
-       unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
-       u64 pad2[10];           /* align to last u64 in 2nd 64-byte cacheline */
+       u64 pad2[9];            /* align to last u64 in 2nd 64-byte cacheline */
        u64 SAL_nasids_size;    /* SAL: size of each nasid mask in bytes */
 };
 
-#define XPC_RP_VERSION _XPC_VERSION(2, 0) /* version 2.0 of the reserved page */
+#define XPC_RP_VERSION _XPC_VERSION(3, 0) /* version 3.0 of the reserved page */
 
 /*
  * Define the structures by which XPC variables can be exported to other
@@ -182,6 +185,17 @@ struct xpc_vars_part_sn2 {
                                 (XPC_RP_MACH_NASIDS(_rp) + \
                                  xpc_nasid_mask_nlongs))
 
+
+/*
+ * The following structure describes the partition's heartbeat info which
+ * will be periodically read by other partitions to determine whether this
+ * XPC is still 'alive'.
+ */
+struct xpc_heartbeat_uv {
+       unsigned long value;
+       unsigned long offline;  /* if 0, heartbeat should be changing */
+};
+
 /*
  * Info pertinent to a GRU message queue using a watch list for irq generation.
  */
@@ -198,7 +212,7 @@ struct xpc_gru_mq_uv {
 
 /*
  * The activate_mq is used to send/receive GRU messages that affect XPC's
- * heartbeat, partition active state, and channel state. This is UV only.
+ * partition active state and channel state. This is uv only.
  */
 struct xpc_activate_mq_msghdr_uv {
        unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */
@@ -210,33 +224,27 @@ struct xpc_activate_mq_msghdr_uv {
 
 /* activate_mq defined message types */
 #define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV          0
-#define XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV           1
-#define XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV       2
-#define XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV                3
 
-#define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV            4
-#define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV          5
+#define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV            1
+#define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV          2
 
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV      6
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV                7
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV       8
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV         9
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV      3
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV                4
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV       5
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV         6
+#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV      7
 
-#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV            10
-#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV         11
+#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV            8
+#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV         9
 
 struct xpc_activate_mq_msg_uv {
        struct xpc_activate_mq_msghdr_uv hdr;
 };
 
-struct xpc_activate_mq_msg_heartbeat_req_uv {
-       struct xpc_activate_mq_msghdr_uv hdr;
-       u64 heartbeat;
-};
-
 struct xpc_activate_mq_msg_activate_req_uv {
        struct xpc_activate_mq_msghdr_uv hdr;
        unsigned long rp_gpa;
+       unsigned long heartbeat_gpa;
        unsigned long activate_gru_mq_desc_gpa;
 };
 
@@ -271,6 +279,11 @@ struct xpc_activate_mq_msg_chctl_openreply_uv {
        unsigned long notify_gru_mq_desc_gpa;
 };
 
+struct xpc_activate_mq_msg_chctl_opencomplete_uv {
+       struct xpc_activate_mq_msghdr_uv hdr;
+       short ch_number;
+};
+
 /*
  * Functions registered by add_timer() or called by kernel_thread() only
  * allow for a single 64-bit argument. The following macros can be used to
@@ -576,30 +589,32 @@ struct xpc_channel {
 
 #define        XPC_C_WASCONNECTED      0x00000001      /* channel was connected */
 
-#define        XPC_C_ROPENREPLY        0x00000002      /* remote open channel reply */
-#define        XPC_C_OPENREPLY         0x00000004      /* local open channel reply */
-#define        XPC_C_ROPENREQUEST      0x00000008     /* remote open channel request */
-#define        XPC_C_OPENREQUEST       0x00000010      /* local open channel request */
+#define XPC_C_ROPENCOMPLETE    0x00000002    /* remote open channel complete */
+#define XPC_C_OPENCOMPLETE     0x00000004     /* local open channel complete */
+#define        XPC_C_ROPENREPLY        0x00000008      /* remote open channel reply */
+#define        XPC_C_OPENREPLY         0x00000010      /* local open channel reply */
+#define        XPC_C_ROPENREQUEST      0x00000020     /* remote open channel request */
+#define        XPC_C_OPENREQUEST       0x00000040      /* local open channel request */
 
-#define        XPC_C_SETUP             0x00000020 /* channel's msgqueues are alloc'd */
-#define        XPC_C_CONNECTEDCALLOUT  0x00000040     /* connected callout initiated */
+#define        XPC_C_SETUP             0x00000080 /* channel's msgqueues are alloc'd */
+#define        XPC_C_CONNECTEDCALLOUT  0x00000100     /* connected callout initiated */
 #define        XPC_C_CONNECTEDCALLOUT_MADE \
-                               0x00000080     /* connected callout completed */
-#define        XPC_C_CONNECTED         0x00000100      /* local channel is connected */
-#define        XPC_C_CONNECTING        0x00000200      /* channel is being connected */
+                               0x00000200     /* connected callout completed */
+#define        XPC_C_CONNECTED         0x00000400      /* local channel is connected */
+#define        XPC_C_CONNECTING        0x00000800      /* channel is being connected */
 
-#define        XPC_C_RCLOSEREPLY       0x00000400      /* remote close channel reply */
-#define        XPC_C_CLOSEREPLY        0x00000800      /* local close channel reply */
-#define        XPC_C_RCLOSEREQUEST     0x00001000    /* remote close channel request */
-#define        XPC_C_CLOSEREQUEST      0x00002000     /* local close channel request */
+#define        XPC_C_RCLOSEREPLY       0x00001000      /* remote close channel reply */
+#define        XPC_C_CLOSEREPLY        0x00002000      /* local close channel reply */
+#define        XPC_C_RCLOSEREQUEST     0x00004000    /* remote close channel request */
+#define        XPC_C_CLOSEREQUEST      0x00008000     /* local close channel request */
 
-#define        XPC_C_DISCONNECTED      0x00004000      /* channel is disconnected */
-#define        XPC_C_DISCONNECTING     0x00008000   /* channel is being disconnected */
+#define        XPC_C_DISCONNECTED      0x00010000      /* channel is disconnected */
+#define        XPC_C_DISCONNECTING     0x00020000   /* channel is being disconnected */
 #define        XPC_C_DISCONNECTINGCALLOUT \
-                               0x00010000 /* disconnecting callout initiated */
+                               0x00040000 /* disconnecting callout initiated */
 #define        XPC_C_DISCONNECTINGCALLOUT_MADE \
-                               0x00020000 /* disconnecting callout completed */
-#define        XPC_C_WDISCONNECT       0x00040000  /* waiting for channel disconnect */
+                               0x00080000 /* disconnecting callout completed */
+#define        XPC_C_WDISCONNECT       0x00100000  /* waiting for channel disconnect */
 
 /*
  * The channel control flags (chctl) union consists of a 64-bit variable which
@@ -618,11 +633,13 @@ union xpc_channel_ctl_flags {
 #define        XPC_CHCTL_CLOSEREPLY    0x02
 #define        XPC_CHCTL_OPENREQUEST   0x04
 #define        XPC_CHCTL_OPENREPLY     0x08
-#define        XPC_CHCTL_MSGREQUEST    0x10
+#define XPC_CHCTL_OPENCOMPLETE 0x10
+#define        XPC_CHCTL_MSGREQUEST    0x20
 
 #define XPC_OPENCLOSE_CHCTL_FLAGS \
                        (XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \
-                        XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY)
+                        XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY | \
+                        XPC_CHCTL_OPENCOMPLETE)
 #define XPC_MSG_CHCTL_FLAGS    XPC_CHCTL_MSGREQUEST
 
 static inline int
@@ -687,6 +704,9 @@ struct xpc_partition_sn2 {
 };
 
 struct xpc_partition_uv {
+       unsigned long heartbeat_gpa; /* phys addr of partition's heartbeat */
+       struct xpc_heartbeat_uv cached_heartbeat; /* cached copy of */
+                                                 /* partition's heartbeat */
        unsigned long activate_gru_mq_desc_gpa; /* phys addr of parititon's */
                                                /* activate mq's gru mq */
                                                /* descriptor */
@@ -698,14 +718,12 @@ struct xpc_partition_uv {
        u8 remote_act_state;    /* remote partition's act_state */
        u8 act_state_req;       /* act_state request from remote partition */
        enum xp_retval reason;  /* reason for deactivate act_state request */
-       u64 heartbeat;          /* incremented by remote partition */
 };
 
 /* struct xpc_partition_uv flags */
 
-#define XPC_P_HEARTBEAT_OFFLINE_UV             0x00000001
+#define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV   0x00000001
 #define XPC_P_ENGAGED_UV                       0x00000002
-#define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV   0x00000004
 
 /* struct xpc_partition_uv act_state change requests */
 
@@ -762,6 +780,62 @@ struct xpc_partition {
 
 } ____cacheline_aligned;
 
+struct xpc_arch_operations {
+       int (*setup_partitions) (void);
+       void (*teardown_partitions) (void);
+       void (*process_activate_IRQ_rcvd) (void);
+       enum xp_retval (*get_partition_rsvd_page_pa)
+               (void *, u64 *, unsigned long *, size_t *);
+       int (*setup_rsvd_page) (struct xpc_rsvd_page *);
+
+       void (*allow_hb) (short);
+       void (*disallow_hb) (short);
+       void (*disallow_all_hbs) (void);
+       void (*increment_heartbeat) (void);
+       void (*offline_heartbeat) (void);
+       void (*online_heartbeat) (void);
+       void (*heartbeat_init) (void);
+       void (*heartbeat_exit) (void);
+       enum xp_retval (*get_remote_heartbeat) (struct xpc_partition *);
+
+       void (*request_partition_activation) (struct xpc_rsvd_page *,
+                                                unsigned long, int);
+       void (*request_partition_reactivation) (struct xpc_partition *);
+       void (*request_partition_deactivation) (struct xpc_partition *);
+       void (*cancel_partition_deactivation_request) (struct xpc_partition *);
+       enum xp_retval (*setup_ch_structures) (struct xpc_partition *);
+       void (*teardown_ch_structures) (struct xpc_partition *);
+
+       enum xp_retval (*make_first_contact) (struct xpc_partition *);
+
+       u64 (*get_chctl_all_flags) (struct xpc_partition *);
+       void (*send_chctl_closerequest) (struct xpc_channel *, unsigned long *);
+       void (*send_chctl_closereply) (struct xpc_channel *, unsigned long *);
+       void (*send_chctl_openrequest) (struct xpc_channel *, unsigned long *);
+       void (*send_chctl_openreply) (struct xpc_channel *, unsigned long *);
+       void (*send_chctl_opencomplete) (struct xpc_channel *, unsigned long *);
+       void (*process_msg_chctl_flags) (struct xpc_partition *, int);
+
+       enum xp_retval (*save_remote_msgqueue_pa) (struct xpc_channel *,
+                                                     unsigned long);
+
+       enum xp_retval (*setup_msg_structures) (struct xpc_channel *);
+       void (*teardown_msg_structures) (struct xpc_channel *);
+
+       void (*indicate_partition_engaged) (struct xpc_partition *);
+       void (*indicate_partition_disengaged) (struct xpc_partition *);
+       void (*assume_partition_disengaged) (short);
+       int (*partition_engaged) (short);
+       int (*any_partition_engaged) (void);
+
+       int (*n_of_deliverable_payloads) (struct xpc_channel *);
+       enum xp_retval (*send_payload) (struct xpc_channel *, u32, void *,
+                                          u16, u8, xpc_notify_func, void *);
+       void *(*get_deliverable_payload) (struct xpc_channel *);
+       void (*received_payload) (struct xpc_channel *, void *);
+       void (*notify_senders_of_disconnect) (struct xpc_channel *);
+};
+
 /* struct xpc_partition act_state values (for XPC HB) */
 
 #define        XPC_P_AS_INACTIVE       0x00    /* partition is not active */
@@ -802,67 +876,17 @@ extern struct xpc_registration xpc_registrations[];
 /* found in xpc_main.c */
 extern struct device *xpc_part;
 extern struct device *xpc_chan;
+extern struct xpc_arch_operations xpc_arch_ops;
 extern int xpc_disengage_timelimit;
 extern int xpc_disengage_timedout;
 extern int xpc_activate_IRQ_rcvd;
 extern spinlock_t xpc_activate_IRQ_rcvd_lock;
 extern wait_queue_head_t xpc_activate_IRQ_wq;
-extern void *xpc_heartbeating_to_mask;
 extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
 extern void xpc_activate_partition(struct xpc_partition *);
 extern void xpc_activate_kthreads(struct xpc_channel *, int);
 extern void xpc_create_kthreads(struct xpc_channel *, int, int);
 extern void xpc_disconnect_wait(int);
-extern int (*xpc_setup_partitions_sn) (void);
-extern void (*xpc_teardown_partitions_sn) (void);
-extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *, u64 *,
-                                                        unsigned long *,
-                                                        size_t *);
-extern int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *);
-extern void (*xpc_heartbeat_init) (void);
-extern void (*xpc_heartbeat_exit) (void);
-extern void (*xpc_increment_heartbeat) (void);
-extern void (*xpc_offline_heartbeat) (void);
-extern void (*xpc_online_heartbeat) (void);
-extern enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *);
-extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
-extern u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *);
-extern enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *);
-extern void (*xpc_teardown_msg_structures) (struct xpc_channel *);
-extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *);
-extern void (*xpc_process_msg_chctl_flags) (struct xpc_partition *, int);
-extern int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *);
-extern void *(*xpc_get_deliverable_payload) (struct xpc_channel *);
-extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *,
-                                                unsigned long, int);
-extern void (*xpc_request_partition_reactivation) (struct xpc_partition *);
-extern void (*xpc_request_partition_deactivation) (struct xpc_partition *);
-extern void (*xpc_cancel_partition_deactivation_request) (
-                                                       struct xpc_partition *);
-extern void (*xpc_process_activate_IRQ_rcvd) (void);
-extern enum xp_retval (*xpc_setup_ch_structures_sn) (struct xpc_partition *);
-extern void (*xpc_teardown_ch_structures_sn) (struct xpc_partition *);
-
-extern void (*xpc_indicate_partition_engaged) (struct xpc_partition *);
-extern int (*xpc_partition_engaged) (short);
-extern int (*xpc_any_partition_engaged) (void);
-extern void (*xpc_indicate_partition_disengaged) (struct xpc_partition *);
-extern void (*xpc_assume_partition_disengaged) (short);
-
-extern void (*xpc_send_chctl_closerequest) (struct xpc_channel *,
-                                           unsigned long *);
-extern void (*xpc_send_chctl_closereply) (struct xpc_channel *,
-                                         unsigned long *);
-extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *,
-                                          unsigned long *);
-extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *);
-
-extern enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *,
-                                                     unsigned long);
-
-extern enum xp_retval (*xpc_send_payload) (struct xpc_channel *, u32, void *,
-                                          u16, u8, xpc_notify_func, void *);
-extern void (*xpc_received_payload) (struct xpc_channel *, void *);
 
 /* found in xpc_sn2.c */
 extern int xpc_init_sn2(void);
@@ -909,40 +933,6 @@ extern void xpc_disconnect_channel(const int, struct xpc_channel *,
 extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
 extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
 
-static inline int
-xpc_hb_allowed(short partid, void *heartbeating_to_mask)
-{
-       return test_bit(partid, heartbeating_to_mask);
-}
-
-static inline int
-xpc_any_hbs_allowed(void)
-{
-       DBUG_ON(xpc_heartbeating_to_mask == NULL);
-       return !bitmap_empty(xpc_heartbeating_to_mask, xp_max_npartitions);
-}
-
-static inline void
-xpc_allow_hb(short partid)
-{
-       DBUG_ON(xpc_heartbeating_to_mask == NULL);
-       set_bit(partid, xpc_heartbeating_to_mask);
-}
-
-static inline void
-xpc_disallow_hb(short partid)
-{
-       DBUG_ON(xpc_heartbeating_to_mask == NULL);
-       clear_bit(partid, xpc_heartbeating_to_mask);
-}
-
-static inline void
-xpc_disallow_all_hbs(void)
-{
-       DBUG_ON(xpc_heartbeating_to_mask == NULL);
-       bitmap_zero(xpc_heartbeating_to_mask, xp_max_npartitions);
-}
-
 static inline void
 xpc_wakeup_channel_mgr(struct xpc_partition *part)
 {