x86/platform/uv/BAU: Add payload descriptor qualifier
authorAndrew Banman <abanman@hpe.com>
Thu, 9 Mar 2017 16:42:10 +0000 (10:42 -0600)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 13 Mar 2017 13:26:28 +0000 (14:26 +0100)
On UV4, the destination agent verifies each message by checking the
descriptor qualifier field of the message payload. Messages without this
field set to 0x534749 will cause a hub error to assert. Split
bau_message_payload into uv1_2_3 and uv4 versions to account for the
different payload formats.

Enforce the size of each field by using the appropriate u** integer type.
Replace extraneous comments with KernelDoc comment.

Signed-off-by: Andrew Banman <abanman@hpe.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Mike Travis <mike.travis@hpe.com>
Cc: sivanich@hpe.com
Cc: rja@hpe.com
Cc: akpm@linux-foundation.org
Link: http://lkml.kernel.org/r/1489077734-111753-3-git-send-email-abanman@hpe.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
arch/x86/include/asm/uv/uv_bau.h
arch/x86/platform/uv/tlb_uv.c

index 768093f49354c3ec6da481ac07439eebfb7a5c09..dcd63ed69162d48d17f036d233c46e2ae42a07ff 100644 (file)
 #define MSG_REGULAR                    1
 #define MSG_RETRY                      2
 
+#define BAU_DESC_QUALIFIER             0x534749
+
 enum uv_bau_version {
        UV_BAU_V1 = 1,
        UV_BAU_V2,
@@ -229,20 +231,32 @@ struct bau_local_cpumask {
  *   the s/w ack bit vector  ]
  */
 
-/*
- * The payload is software-defined for INTD transactions
+/**
+ * struct uv1_2_3_bau_msg_payload - defines payload for INTD transactions
+ * @address:           Signifies a page or all TLB's of the cpu
+ * @sending_cpu:       CPU from which the message originates
+ * @acknowledge_count: CPUs on the destination Hub that received the interrupt
  */
-struct bau_msg_payload {
-       unsigned long   address;                /* signifies a page or all
-                                                  TLB's of the cpu */
-       /* 64 bits */
-       unsigned short  sending_cpu;            /* filled in by sender */
-       /* 16 bits */
-       unsigned short  acknowledge_count;      /* filled in by destination */
-       /* 16 bits */
-       unsigned int    reserved1:32;           /* not usable */
+struct uv1_2_3_bau_msg_payload {
+       u64 address;
+       u16 sending_cpu;
+       u16 acknowledge_count;
 };
 
+/**
+ * struct uv4_bau_msg_payload - defines payload for INTD transactions
+ * @address:           Signifies a page or all TLB's of the cpu
+ * @sending_cpu:       CPU from which the message originates
+ * @acknowledge_count: CPUs on the destination Hub that received the interrupt
+ * @qualifier:         Set by source to verify origin of INTD broadcast
+ */
+struct uv4_bau_msg_payload {
+       u64 address;
+       u16 sending_cpu;
+       u16 acknowledge_count;
+       u32 reserved:8;
+       u32 qualifier:24;
+};
 
 /*
  * UV1 Message header:  16 bytes (128 bits) (bytes 0x30-0x3f of descriptor)
@@ -418,7 +432,10 @@ struct bau_desc {
                struct uv2_3_bau_msg_header     uv2_3_hdr;
        } header;
 
-       struct bau_msg_payload                  payload;
+       union bau_payload_header {
+               struct uv1_2_3_bau_msg_payload  uv1_2_3;
+               struct uv4_bau_msg_payload      uv4;
+       } payload;
 };
 /* UV1:
  *   -payload--    ---------header------
index f4f5aa61755b0c1c4ddfabec9cf9c53e32db93ba..70721c493291a6651d39817f9d49952238c44499 100644 (file)
@@ -1114,15 +1114,12 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
                                                unsigned long end,
                                                unsigned int cpu)
 {
-       int locals = 0;
-       int remotes = 0;
-       int hubs = 0;
+       int locals = 0, remotes = 0, hubs = 0;
        struct bau_desc *bau_desc;
        struct cpumask *flush_mask;
        struct ptc_stats *stat;
        struct bau_control *bcp;
-       unsigned long descriptor_status;
-       unsigned long status;
+       unsigned long descriptor_status, status, address;
 
        bcp = &per_cpu(bau_control, cpu);
 
@@ -1171,10 +1168,24 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
        record_send_statistics(stat, locals, hubs, remotes, bau_desc);
 
        if (!end || (end - start) <= PAGE_SIZE)
-               bau_desc->payload.address = start;
+               address = start;
        else
-               bau_desc->payload.address = TLB_FLUSH_ALL;
-       bau_desc->payload.sending_cpu = cpu;
+               address = TLB_FLUSH_ALL;
+
+       switch (bcp->uvhub_version) {
+       case UV_BAU_V1:
+       case UV_BAU_V2:
+       case UV_BAU_V3:
+               bau_desc->payload.uv1_2_3.address = address;
+               bau_desc->payload.uv1_2_3.sending_cpu = cpu;
+               break;
+       case UV_BAU_V4:
+               bau_desc->payload.uv4.address = address;
+               bau_desc->payload.uv4.sending_cpu = cpu;
+               bau_desc->payload.uv4.qualifier = BAU_DESC_QUALIFIER;
+               break;
+       }
+
        /*
         * uv_flush_send_and_wait returns 0 if all cpu's were messaged,
         * or 1 if it gave up and the original cpumask should be returned.