FILE
ras_core.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/amd/ras/rascore/ras_core.c
1// SPDX-License-Identifier: MIT 2/* 3 * Copyright 2025 Advanced Micro Devices, Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21 * OTHER DEALINGS IN THE SOFTWARE. 22 * 23 */ 24#include "ras.h" 25#include "ras_core_status.h" 26 27#define RAS_SEQNO_FIFO_SIZE (128 * sizeof(uint64_t)) 28 29#define IS_LEAP_YEAR(x) ((x % 4 == 0 && x % 100 != 0) || x % 400 == 0) 30 31static const char * const ras_block_name[] = { 32 "umc", 33 "sdma", 34 "gfx", 35 "mmhub", 36 "athub", 37 "pcie_bif", 38 "hdp", 39 "xgmi_wafl", 40 "df", 41 "smn", 42 "sem", 43 "mp0", 44 "mp1", 45 "fuse", 46 "mca", 47 "vcn", 48 "jpeg", 49 "ih", 50 "mpio", 51}; 52 53const char *ras_core_get_ras_block_name(enum ras_block_id block_id) 54{ 55 if (block_id >= ARRAY_SIZE(ras_block_name)) 56 return ""; 57 58 return ras_block_name[block_id]; 59} 60 61int ras_core_convert_timestamp_to_time(struct ras_core_context *ras_core, 62 uint64_t timestamp, struct ras_time *tm) 63{ 64 int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 65 uint64_t month = 0, day = 0, hour = 0, minute = 0, second = 0; 66 uint32_t year = 0; 67 int seconds_per_day = 24 * 60 * 60; 68 int seconds_per_hour = 60 * 60; 69 int seconds_per_minute = 60; 70 int days, remaining_seconds; 71 72 days = div64_u64_rem(timestamp, seconds_per_day, (uint64_t *)&remaining_seconds); 73 74 /* utc_timestamp follows the Unix epoch */ 75 year = 1970; 76 while (days >= 365) { 77 if (IS_LEAP_YEAR(year)) { 78 if (days < 366) 79 break; 80 days -= 366; 81 } else { 82 days -= 365; 83 } 84 year++; 85 } 86 87 days_in_month[1] += IS_LEAP_YEAR(year); 88 89 month = 0; 90 while (days >= days_in_month[month]) { 91 days -= days_in_month[month]; 92 month++; 93 } 94 month++; 95 day = days + 1; 96 97 if (remaining_seconds) { 98 hour = remaining_seconds / seconds_per_hour; 99 minute = (remaining_seconds % seconds_per_hour) / seconds_per_minute; 100 second = remaining_seconds % seconds_per_minute; 101 } 102 103 tm->tm_year = year; 104 tm->tm_mon = month; 105 tm->tm_mday = day; 106 tm->tm_hour = hour; 107 tm->tm_min = minute; 108 tm->tm_sec = second; 109 110 return 0; 111} 112 113bool ras_core_gpu_in_reset(struct ras_core_context *ras_core) 114{ 115 uint32_t status = 0; 116 117 if (ras_core->sys_fn && 118 ras_core->sys_fn->check_gpu_status) 119 ras_core->sys_fn->check_gpu_status(ras_core, &status); 120 121 return (status & RAS_GPU_STATUS__IN_RESET) ? true : false; 122} 123 124bool ras_core_gpu_is_vf(struct ras_core_context *ras_core) 125{ 126 uint32_t status = 0; 127 128 if (ras_core->sys_fn && 129 ras_core->sys_fn->check_gpu_status) 130 ras_core->sys_fn->check_gpu_status(ras_core, &status); 131 132 return (status & RAS_GPU_STATUS__IS_VF) ? true : false; 133} 134 135bool ras_core_gpu_is_rma(struct ras_core_context *ras_core) 136{ 137 if (!ras_core) 138 return false; 139 140 return ras_core->is_rma; 141} 142 143static int ras_core_seqno_fifo_write(struct ras_core_context *ras_core, 144 enum ras_seqno_fifo fifo_type, uint64_t seqno) 145{ 146 int ret = 0; 147 struct kfifo *seqno_fifo = NULL; 148 149 if (fifo_type == SEQNO_FIFO_POISON_CREATION) 150 seqno_fifo = &ras_core->de_seqno_fifo; 151 else if (fifo_type == SEQNO_FIFO_POISON_CONSUMPTION) 152 seqno_fifo = &ras_core->consumption_seqno_fifo; 153 154 if (seqno_fifo) 155 ret = kfifo_in_spinlocked(seqno_fifo, 156 &seqno, sizeof(seqno), &ras_core->seqno_lock); 157 158 return ret ? 0 : -EINVAL; 159} 160 161static int ras_core_seqno_fifo_read(struct ras_core_context *ras_core, 162 enum ras_seqno_fifo fifo_type, uint64_t *seqno, bool pop) 163{ 164 int ret = 0; 165 struct kfifo *seqno_fifo = NULL; 166 167 if (fifo_type == SEQNO_FIFO_POISON_CREATION) 168 seqno_fifo = &ras_core->de_seqno_fifo; 169 else if (fifo_type == SEQNO_FIFO_POISON_CONSUMPTION) 170 seqno_fifo = &ras_core->consumption_seqno_fifo; 171 172 if (seqno_fifo) { 173 if (pop) 174 ret = kfifo_out_spinlocked(seqno_fifo, 175 seqno, sizeof(*seqno), &ras_core->seqno_lock); 176 else 177 ret = kfifo_out_peek(seqno_fifo, seqno, sizeof(*seqno)); 178 } 179 180 return ret ? 0 : -EINVAL; 181} 182 183uint64_t ras_core_gen_seqno(struct ras_core_context *ras_core, 184 enum ras_seqno_type type) 185{ 186 uint64_t seqno = 0; 187 188 if (ras_core->sys_fn && 189 ras_core->sys_fn->gen_seqno) 190 ras_core->sys_fn->gen_seqno(ras_core, type, &seqno); 191 192 return seqno; 193} 194 195int ras_core_put_seqno(struct ras_core_context *ras_core, 196 enum ras_seqno_type seqno_type, uint64_t seqno) 197{ 198 int ret = 0; 199 200 if (seqno_type >= RAS_SEQNO_TYPE_COUNT_MAX) 201 return -EINVAL; 202 203 if (seqno_type == RAS_SEQNO_TYPE_DE) 204 ret = ras_core_seqno_fifo_write(ras_core, 205 SEQNO_FIFO_POISON_CREATION, seqno); 206 else if (seqno_type == RAS_SEQNO_TYPE_POISON_CONSUMPTION) 207 ret = ras_core_seqno_fifo_write(ras_core, 208 SEQNO_FIFO_POISON_CONSUMPTION, seqno); 209 else 210 ret = -EINVAL; 211 212 return ret; 213} 214 215uint64_t ras_core_get_seqno(struct ras_core_context *ras_core, 216 enum ras_seqno_type seqno_type, bool pop) 217{ 218 uint64_t seq_no; 219 int ret = -ENODATA; 220 221 if (seqno_type >= RAS_SEQNO_TYPE_COUNT_MAX) 222 return 0; 223 224 if (seqno_type == RAS_SEQNO_TYPE_DE) 225 ret = ras_core_seqno_fifo_read(ras_core, 226 SEQNO_FIFO_POISON_CREATION, &seq_no, pop); 227 else if (seqno_type == RAS_SEQNO_TYPE_POISON_CONSUMPTION) 228 ret = ras_core_seqno_fifo_read(ras_core, 229 SEQNO_FIFO_POISON_CONSUMPTION, &seq_no, pop); 230 231 if (ret) 232 seq_no = ras_core_gen_seqno(ras_core, seqno_type); 233 234 return seq_no; 235} 236 237static int ras_core_eeprom_recovery(struct ras_core_context *ras_core) 238{ 239 int count; 240 int ret; 241 242 count = ras_eeprom_get_record_count(ras_core); 243 if (!count) 244 return 0; 245 246 /* Avoid bad page to be loaded again after gpu reset */ 247 if (ras_umc_get_saved_eeprom_count(ras_core) >= count) 248 return 0; 249 250 ret = ras_umc_load_bad_pages(ras_core); 251 if (ret) { 252 RAS_DEV_ERR(ras_core->dev, "ras_umc_load_bad_pages failed: %d\n", ret); 253 return ret; 254 } 255 256 ras_eeprom_sync_info(ras_core); 257 258 return ret; 259} 260 261struct ras_core_context *ras_core_create(struct ras_core_config *init_config) 262{ 263 struct ras_core_context *ras_core; 264 struct ras_core_config *config; 265 266 ras_core = kzalloc(sizeof(*ras_core), GFP_KERNEL); 267 if (!ras_core) 268 return NULL; 269 270 config = kzalloc(sizeof(*config), GFP_KERNEL); 271 if (!config) { 272 kfree(ras_core); 273 return NULL; 274 } 275 276 memcpy(config, init_config, sizeof(*config)); 277 ras_core->config = config; 278 279 return ras_core; 280} 281 282void ras_core_destroy(struct ras_core_context *ras_core) 283{ 284 if (ras_core) 285 kfree(ras_core->config); 286 287 kfree(ras_core); 288} 289 290int ras_core_sw_init(struct ras_core_context *ras_core) 291{ 292 int ret; 293 294 if (!ras_core->config) { 295 RAS_DEV_ERR(ras_core->dev, "No ras core config!\n"); 296 return -EINVAL; 297 } 298 299 ras_core->sys_fn = ras_core->config->sys_fn; 300 if (!ras_core->sys_fn) 301 return -EINVAL; 302 303 ret = kfifo_alloc(&ras_core->de_seqno_fifo, 304 RAS_SEQNO_FIFO_SIZE, GFP_KERNEL); 305 if (ret) 306 return ret; 307 308 ret = kfifo_alloc(&ras_core->consumption_seqno_fifo, 309 RAS_SEQNO_FIFO_SIZE, GFP_KERNEL); 310 if (ret) 311 return ret; 312 313 spin_lock_init(&ras_core->seqno_lock); 314 315 ret = ras_aca_sw_init(ras_core); 316 if (ret) 317 return ret; 318 319 ret = ras_umc_sw_init(ras_core); 320 if (ret) 321 return ret; 322 323 ret = ras_cmd_init(ras_core); 324 if (ret) 325 return ret; 326 327 ret = ras_log_ring_sw_init(ras_core); 328 if (ret) 329 return ret; 330 331 ret = ras_psp_sw_init(ras_core); 332 if (ret) 333 return ret; 334 335 return 0; 336} 337 338int ras_core_sw_fini(struct ras_core_context *ras_core) 339{ 340 kfifo_free(&ras_core->de_seqno_fifo); 341 kfifo_free(&ras_core->consumption_seqno_fifo); 342 343 ras_psp_sw_fini(ras_core); 344 ras_log_ring_sw_fini(ras_core); 345 ras_cmd_fini(ras_core); 346 ras_umc_sw_fini(ras_core); 347 ras_aca_sw_fini(ras_core); 348 349 return 0; 350} 351 352int ras_core_hw_init(struct ras_core_context *ras_core) 353{ 354 int ret; 355 356 ras_core->ras_eeprom_supported = 357 ras_core->config->ras_eeprom_supported; 358 359 ras_core->poison_supported = ras_core->config->poison_supported; 360 361 ret = ras_psp_hw_init(ras_core); 362 if (ret) 363 return ret; 364 365 ret = ras_aca_hw_init(ras_core); 366 if (ret) 367 goto init_err1; 368 369 ret = ras_mp1_hw_init(ras_core); 370 if (ret) 371 goto init_err2; 372 373 ret = ras_nbio_hw_init(ras_core); 374 if (ret) 375 goto init_err3; 376 377 ret = ras_umc_hw_init(ras_core); 378 if (ret) 379 goto init_err4; 380 381 ret = ras_gfx_hw_init(ras_core); 382 if (ret) 383 goto init_err5; 384 385 ret = ras_eeprom_hw_init(ras_core); 386 if (ret) 387 goto init_err6; 388 389 ret = ras_core_eeprom_recovery(ras_core); 390 if (ret) { 391 RAS_DEV_ERR(ras_core->dev, 392 "Failed to recovery ras core, ret:%d\n", ret); 393 goto init_err6; 394 } 395 396 ret = ras_eeprom_check_storage_status(ras_core); 397 if (ret) 398 goto init_err6; 399 400 ret = ras_process_init(ras_core); 401 if (ret) 402 goto init_err7; 403 404 ras_core->is_initialized = true; 405 406 return 0; 407 408init_err7: 409 ras_eeprom_hw_fini(ras_core); 410init_err6: 411 ras_gfx_hw_fini(ras_core); 412init_err5: 413 ras_umc_hw_fini(ras_core); 414init_err4: 415 ras_nbio_hw_fini(ras_core); 416init_err3: 417 ras_mp1_hw_fini(ras_core); 418init_err2: 419 ras_aca_hw_fini(ras_core); 420init_err1: 421 ras_psp_hw_fini(ras_core); 422 return ret; 423} 424 425int ras_core_hw_fini(struct ras_core_context *ras_core) 426{ 427 ras_core->is_initialized = false; 428 429 ras_process_fini(ras_core); 430 ras_eeprom_hw_fini(ras_core); 431 ras_gfx_hw_fini(ras_core); 432 ras_nbio_hw_fini(ras_core); 433 ras_umc_hw_fini(ras_core); 434 ras_mp1_hw_fini(ras_core); 435 ras_aca_hw_fini(ras_core); 436 ras_psp_hw_fini(ras_core); 437 438 return 0; 439} 440 441bool ras_core_handle_nbio_irq(struct ras_core_context *ras_core, void *data) 442{ 443 return ras_nbio_handle_irq_error(ras_core, data); 444} 445 446int ras_core_handle_fatal_error(struct ras_core_context *ras_core) 447{ 448 int ret = 0; 449 450 ras_aca_mark_fatal_flag(ras_core); 451 452 ret = ras_core_event_notify(ras_core, 453 RAS_EVENT_ID__FATAL_ERROR_DETECTED, NULL); 454 455 return ret; 456} 457 458uint32_t ras_core_get_curr_nps_mode(struct ras_core_context *ras_core) 459{ 460 if (ras_core->ras_nbio.ip_func && 461 ras_core->ras_nbio.ip_func->get_memory_partition_mode) 462 return ras_core->ras_nbio.ip_func->get_memory_partition_mode(ras_core); 463 464 RAS_DEV_ERR(ras_core->dev, "Failed to get gpu memory nps mode!\n"); 465 return 0; 466} 467 468int ras_core_update_ecc_info(struct ras_core_context *ras_core) 469{ 470 int ret; 471 472 ret = ras_aca_update_ecc(ras_core, RAS_ERR_TYPE__CE, NULL); 473 if (!ret) 474 ret = ras_aca_update_ecc(ras_core, RAS_ERR_TYPE__UE, NULL); 475 476 return ret; 477} 478 479int ras_core_query_block_ecc_data(struct ras_core_context *ras_core, 480 enum ras_block_id block, struct ras_ecc_count *ecc_count) 481{ 482 int ret; 483 484 if (!ecc_count || (block >= RAS_BLOCK_ID__LAST) || !ras_core) 485 return -EINVAL; 486 487 ret = ras_aca_get_block_ecc_count(ras_core, block, ecc_count); 488 if (!ret) 489 ras_aca_clear_block_new_ecc_count(ras_core, block); 490 491 return ret; 492} 493 494int ras_core_set_status(struct ras_core_context *ras_core, bool enable) 495{ 496 ras_core->ras_core_enabled = enable; 497 498 return 0; 499} 500 501bool ras_core_is_enabled(struct ras_core_context *ras_core) 502{ 503 return ras_core->ras_core_enabled; 504} 505 506uint64_t ras_core_get_utc_second_timestamp(struct ras_core_context *ras_core) 507{ 508 if (ras_core && ras_core->sys_fn && 509 ras_core->sys_fn->get_utc_second_timestamp) 510 return ras_core->sys_fn->get_utc_second_timestamp(ras_core); 511 512 RAS_DEV_ERR(ras_core->dev, "Failed to get system timestamp!\n"); 513 return 0; 514} 515 516int ras_core_translate_soc_pa_and_bank(struct ras_core_context *ras_core, 517 uint64_t *soc_pa, struct umc_bank_addr *bank_addr, bool bank_to_pa) 518{ 519 if (!ras_core || !soc_pa || !bank_addr) 520 return -EINVAL; 521 522 return ras_umc_translate_soc_pa_and_bank(ras_core, soc_pa, bank_addr, bank_to_pa); 523} 524 525bool ras_core_ras_interrupt_detected(struct ras_core_context *ras_core) 526{ 527 if (ras_core && ras_core->sys_fn && 528 ras_core->sys_fn->detect_ras_interrupt) 529 return ras_core->sys_fn->detect_ras_interrupt(ras_core); 530 531 RAS_DEV_ERR(ras_core->dev, "Failed to detect ras interrupt!\n"); 532 return false; 533} 534 535int ras_core_get_gpu_mem(struct ras_core_context *ras_core, 536 enum gpu_mem_type mem_type, struct gpu_mem_block *gpu_mem) 537{ 538 if (ras_core->sys_fn && ras_core->sys_fn->get_gpu_mem) 539 return ras_core->sys_fn->get_gpu_mem(ras_core, mem_type, gpu_mem); 540 541 RAS_DEV_ERR(ras_core->dev, "Not config get gpu memory API!\n"); 542 return -EACCES; 543} 544 545int ras_core_put_gpu_mem(struct ras_core_context *ras_core, 546 enum gpu_mem_type mem_type, struct gpu_mem_block *gpu_mem) 547{ 548 if (ras_core->sys_fn && ras_core->sys_fn->put_gpu_mem) 549 return ras_core->sys_fn->put_gpu_mem(ras_core, mem_type, gpu_mem); 550 551 RAS_DEV_ERR(ras_core->dev, "Not config put gpu memory API!!\n"); 552 return -EACCES; 553} 554 555bool ras_core_is_ready(struct ras_core_context *ras_core) 556{ 557 return ras_core ? ras_core->is_initialized : false; 558} 559 560bool ras_core_check_safety_watermark(struct ras_core_context *ras_core) 561{ 562 return ras_eeprom_check_safety_watermark(ras_core); 563} 564 565int ras_core_down_trylock_gpu_reset_lock(struct ras_core_context *ras_core) 566{ 567 if (ras_core->sys_fn && ras_core->sys_fn->gpu_reset_lock) 568 return ras_core->sys_fn->gpu_reset_lock(ras_core, true, true); 569 570 return 1; 571} 572 573void ras_core_down_gpu_reset_lock(struct ras_core_context *ras_core) 574{ 575 if (ras_core->sys_fn && ras_core->sys_fn->gpu_reset_lock) 576 ras_core->sys_fn->gpu_reset_lock(ras_core, true, false); 577} 578 579void ras_core_up_gpu_reset_lock(struct ras_core_context *ras_core) 580{ 581 if (ras_core->sys_fn && ras_core->sys_fn->gpu_reset_lock) 582 ras_core->sys_fn->gpu_reset_lock(ras_core, false, false); 583} 584 585int ras_core_event_notify(struct ras_core_context *ras_core, 586 enum ras_notify_event event_id, void *data) 587{ 588 if (ras_core && ras_core->sys_fn && 589 ras_core->sys_fn->ras_notifier) 590 return ras_core->sys_fn->ras_notifier(ras_core, event_id, data); 591 592 return -RAS_CORE_NOT_SUPPORTED; 593} 594 595int ras_core_get_device_system_info(struct ras_core_context *ras_core, 596 struct device_system_info *dev_info) 597{ 598 if (ras_core && ras_core->sys_fn && 599 ras_core->sys_fn->get_device_system_info) 600 return ras_core->sys_fn->get_device_system_info(ras_core, dev_info); 601 602 return -RAS_CORE_NOT_SUPPORTED; 603}
~/
Read-only file preview.