Commit e9be3644 authored by Andrew Banman's avatar Andrew Banman Committed by Thomas Gleixner

x86/platform/uv/BAU: Add payload descriptor qualifier

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: default avatarAndrew Banman <abanman@hpe.com>
Acked-by: default avatarIngo Molnar <mingo@kernel.org>
Acked-by: default avatarMike 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.comSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 491bd88c
...@@ -185,6 +185,8 @@ ...@@ -185,6 +185,8 @@
#define MSG_REGULAR 1 #define MSG_REGULAR 1
#define MSG_RETRY 2 #define MSG_RETRY 2
#define BAU_DESC_QUALIFIER 0x534749
enum uv_bau_version { enum uv_bau_version {
UV_BAU_V1 = 1, UV_BAU_V1 = 1,
UV_BAU_V2, UV_BAU_V2,
...@@ -229,20 +231,32 @@ struct bau_local_cpumask { ...@@ -229,20 +231,32 @@ struct bau_local_cpumask {
* the s/w ack bit vector ] * 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 { struct uv1_2_3_bau_msg_payload {
unsigned long address; /* signifies a page or all u64 address;
TLB's of the cpu */ u16 sending_cpu;
/* 64 bits */ u16 acknowledge_count;
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 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) * UV1 Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor)
...@@ -418,7 +432,10 @@ struct bau_desc { ...@@ -418,7 +432,10 @@ struct bau_desc {
struct uv2_3_bau_msg_header uv2_3_hdr; struct uv2_3_bau_msg_header uv2_3_hdr;
} header; } 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: /* UV1:
* -payload-- ---------header------ * -payload-- ---------header------
......
...@@ -1114,15 +1114,12 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, ...@@ -1114,15 +1114,12 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
unsigned long end, unsigned long end,
unsigned int cpu) unsigned int cpu)
{ {
int locals = 0; int locals = 0, remotes = 0, hubs = 0;
int remotes = 0;
int hubs = 0;
struct bau_desc *bau_desc; struct bau_desc *bau_desc;
struct cpumask *flush_mask; struct cpumask *flush_mask;
struct ptc_stats *stat; struct ptc_stats *stat;
struct bau_control *bcp; struct bau_control *bcp;
unsigned long descriptor_status; unsigned long descriptor_status, status, address;
unsigned long status;
bcp = &per_cpu(bau_control, cpu); bcp = &per_cpu(bau_control, cpu);
...@@ -1171,10 +1168,24 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, ...@@ -1171,10 +1168,24 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
record_send_statistics(stat, locals, hubs, remotes, bau_desc); record_send_statistics(stat, locals, hubs, remotes, bau_desc);
if (!end || (end - start) <= PAGE_SIZE) if (!end || (end - start) <= PAGE_SIZE)
bau_desc->payload.address = start; address = start;
else else
bau_desc->payload.address = TLB_FLUSH_ALL; address = TLB_FLUSH_ALL;
bau_desc->payload.sending_cpu = cpu;
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, * 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. * or 1 if it gave up and the original cpumask should be returned.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment