Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932429AbdCIQmZ (ORCPT ); Thu, 9 Mar 2017 11:42:25 -0500 Received: from relay2.sgi.com ([192.48.180.65]:52792 "EHLO relay.sgi.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753196AbdCIQmY (ORCPT ); Thu, 9 Mar 2017 11:42:24 -0500 From: Andrew Banman To: mingo@redhat.com Cc: akpm@linux-foundation.org, tglx@linutronix.de, hpa@zytor.com, mike.travis@hpe.com, rja@hpe.com, sivanich@hpe.com, x86@kernel.org, linux-kernel@vger.kernel.org, abanman@hpe.com Subject: [PATCH 2/6] x86/platform/uv/BAU: Add payload descriptor qualifier Date: Thu, 9 Mar 2017 10:42:10 -0600 Message-Id: <1489077734-111753-3-git-send-email-abanman@hpe.com> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1489077734-111753-1-git-send-email-abanman@hpe.com> References: <1489077734-111753-1-git-send-email-abanman@hpe.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4284 Lines: 136 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 Acked-by: Mike Travis --- 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