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 <aban...@hpe.com>
Acked-by: Mike Travis <mike.tra...@hpe.com>
---
 arch/x86/include/asm/uv/uv_bau.h | 40 ++++++++++++++++++++++++++++------------
 arch/x86/platform/uv/tlb_uv.c    | 27 +++++++++++++++++++--------
 2 files changed, 47 insertions(+), 20 deletions(-)

diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h
index 768093f..1ed0574 100644
--- a/arch/x86/include/asm/uv/uv_bau.h
+++ b/arch/x86/include/asm/uv/uv_bau.h
@@ -185,6 +185,8 @@
 #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,31 @@ 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
+ * @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;
+       u32 reserved1;
 };
 
+/**
+ * struct uv4_bau_msg_payload - defines payload for INTD transactions
+ * @address: signifies a page or all TLB's of the cpu
+ * @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 reserved1:8;
+       u32 qualifier:24;
+};
 
 /*
  * UV1 Message header:  16 bytes (128 bits) (bytes 0x30-0x3f of descriptor)
@@ -418,7 +431,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------
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c
index f4f5aa6..70721c4 100644
--- a/arch/x86/platform/uv/tlb_uv.c
+++ b/arch/x86/platform/uv/tlb_uv.c
@@ -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.
-- 
1.8.2.1

Reply via email to