Messages in this thread Patch in this message | | | From | Yazen Ghannam <> | Subject | [PATCH 23/25] x86/MCE/AMD: Update CS ID calculation to match reference code | Date | Fri, 7 May 2021 15:01:38 -0400 |
| |
From: Yazen Ghannam <yazen.ghannam@amd.com>
Redo the current CS ID calculations to match the reference code. Helper functions are introduced that will be expanded for future DF versions.
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com> --- arch/x86/kernel/cpu/mce/amd.c | 50 ++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 19 deletions(-)
diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c index 01931f98c6d9..3340f8326681 100644 --- a/arch/x86/kernel/cpu/mce/amd.c +++ b/arch/x86/kernel/cpu/mce/amd.c @@ -924,45 +924,57 @@ static u8 get_socket_id_shift(struct addr_ctx *ctx) return (ctx->reg_fab_id_mask0 >> 28) & 0xF; } +static u8 get_dst_fabric_id(struct addr_ctx *ctx) +{ + return ctx->reg_limit_addr & 0xFF; +} + +static u8 get_component_id_mask(struct addr_ctx *ctx) +{ + return (~(ctx->socket_id_mask | ctx->die_id_mask)) & 0xFF; +} + +static u8 calc_level_bits(u8 id, u8 level_mask, u8 shift, u8 mask, u8 num_bits) +{ + return (((id & level_mask) >> shift) & mask) << num_bits; +} + static int calculate_cs_id(struct addr_ctx *ctx) { - u8 die_id_bit, sock_id_bit, cs_mask = 0; + u8 mask, num_intlv_bits = ctx->intlv_num_chan; + u8 dst_fabric_id = get_dst_fabric_id(ctx); if (get_cs_fabric_id(ctx)) return -EINVAL; get_masks(ctx); - die_id_bit = 0; + mask = get_component_id_mask(ctx); + ctx->cs_id = (ctx->cs_fabric_id & mask) - (dst_fabric_id & mask); - /* If interleaved over more than 1 channel: */ - if (ctx->intlv_num_chan) { - die_id_bit = ctx->intlv_num_chan; - cs_mask = (1 << die_id_bit) - 1; - ctx->cs_id = ctx->cs_fabric_id & cs_mask; - } - - /* Return early if no die interleaving and no socket interleaving. */ - if (!(ctx->intlv_num_dies || ctx->intlv_num_sockets)) - return 0; - - sock_id_bit = die_id_bit; + mask = (1 << num_intlv_bits) - 1; + ctx->cs_id &= mask; /* If interleaved over more than 1 die: */ if (ctx->intlv_num_dies) { u8 die_id_shift = get_die_id_shift(ctx); - sock_id_bit = die_id_bit + ctx->intlv_num_dies; - ctx->cs_id |= ((ctx->cs_fabric_id & ctx->die_id_mask) - >> die_id_shift) << die_id_bit; + mask = (1 << ctx->intlv_num_dies) - 1; + + ctx->cs_id |= calc_level_bits(ctx->cs_fabric_id, ctx->die_id_mask, + die_id_shift, mask, num_intlv_bits); + + num_intlv_bits += ctx->intlv_num_dies; } /* If interleaved over more than 1 socket: */ if (ctx->intlv_num_sockets) { u8 socket_id_shift = get_socket_id_shift(ctx); - ctx->cs_id |= ((ctx->cs_fabric_id & ctx->socket_id_mask) - >> socket_id_shift) << sock_id_bit; + mask = (1 << ctx->intlv_num_sockets) - 1; + + ctx->cs_id |= calc_level_bits(ctx->cs_fabric_id, ctx->socket_id_mask, + socket_id_shift, mask, num_intlv_bits); } return 0; -- 2.25.1
| |