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 "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 31 enum RAS_DEBUG_MASK { 32 RAS_DEBUG_DISABLE_RAS_CE_LOG = 9, 33 }; 34 35 static const char * const ras_block_name[] = { 36 "umc", 37 "sdma", 38 "gfx", 39 "mmhub", 40 "athub", 41 "pcie_bif", 42 "hdp", 43 "xgmi_wafl", 44 "df", 45 "smn", 46 "sem", 47 "mp0", 48 "mp1", 49 "fuse", 50 "mca", 51 "vcn", 52 "jpeg", 53 "ih", 54 "mpio", 55 }; 56 57 const char *ras_core_get_ras_block_name(enum ras_block_id block_id) 58 { 59 if (block_id >= ARRAY_SIZE(ras_block_name)) 60 return ""; 61 62 return ras_block_name[block_id]; 63 } 64 65 int ras_core_convert_timestamp_to_time(struct ras_core_context *ras_core, 66 uint64_t timestamp, struct ras_time *tm) 67 { 68 int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 69 uint64_t month = 0, day = 0, hour = 0, minute = 0, second = 0, remainder; 70 uint32_t year = 0; 71 int seconds_per_day = 24 * 60 * 60; 72 int seconds_per_hour = 60 * 60; 73 int seconds_per_minute = 60; 74 int days, remaining_seconds; 75 76 if (!tm) 77 return -EINVAL; 78 79 days = div64_u64_rem(timestamp, seconds_per_day, &remainder); 80 /* remainder will always be less than seconds_per_day. */ 81 remaining_seconds = remainder; 82 83 /* utc_timestamp follows the Unix epoch */ 84 year = 1970; 85 while (days >= 365) { 86 if (IS_LEAP_YEAR(year)) { 87 if (days < 366) 88 break; 89 days -= 366; 90 } else { 91 days -= 365; 92 } 93 year++; 94 } 95 96 days_in_month[1] += IS_LEAP_YEAR(year); 97 98 month = 0; 99 while (days >= days_in_month[month]) { 100 days -= days_in_month[month]; 101 month++; 102 } 103 month++; 104 day = days + 1; 105 106 if (remaining_seconds) { 107 hour = remaining_seconds / seconds_per_hour; 108 minute = (remaining_seconds % seconds_per_hour) / seconds_per_minute; 109 second = remaining_seconds % seconds_per_minute; 110 } 111 112 tm->tm_year = year; 113 tm->tm_mon = month; 114 tm->tm_mday = day; 115 tm->tm_hour = hour; 116 tm->tm_min = minute; 117 tm->tm_sec = second; 118 119 return 0; 120 } 121 122 bool ras_core_gpu_in_reset(struct ras_core_context *ras_core) 123 { 124 uint32_t status = 0; 125 126 if (!ras_core) 127 return false; 128 129 if (ras_core->sys_fn && 130 ras_core->sys_fn->check_gpu_status) 131 ras_core->sys_fn->check_gpu_status(ras_core, &status); 132 133 return (status & RAS_GPU_STATUS__IN_RESET) ? true : false; 134 } 135 136 bool ras_core_gpu_is_vf(struct ras_core_context *ras_core) 137 { 138 uint32_t status = 0; 139 140 if (!ras_core) 141 return false; 142 143 if (ras_core->sys_fn && 144 ras_core->sys_fn->check_gpu_status) 145 ras_core->sys_fn->check_gpu_status(ras_core, &status); 146 147 return (status & RAS_GPU_STATUS__IS_VF) ? true : false; 148 } 149 150 bool ras_core_gpu_device_lost(struct ras_core_context *ras_core) 151 { 152 uint32_t status = 0; 153 154 if (!ras_core) 155 return false; 156 157 if (ras_core->sys_fn && 158 ras_core->sys_fn->check_gpu_status) 159 ras_core->sys_fn->check_gpu_status(ras_core, &status); 160 161 return (status & RAS_GPU_STATUS__DEVICE_LOST) ? true : false; 162 } 163 164 bool ras_core_gpu_is_rma(struct ras_core_context *ras_core) 165 { 166 if (!ras_core) 167 return false; 168 169 return ras_core->is_rma; 170 } 171 172 int ras_core_set_debug_mode(struct ras_core_context *ras_core, bool enable) 173 { 174 return ras_mp1_set_debug_mode(ras_core, enable); 175 } 176 177 static int ras_core_seqno_fifo_write(struct ras_core_context *ras_core, 178 enum ras_seqno_fifo fifo_type, uint64_t seqno) 179 { 180 int ret = 0; 181 struct kfifo *seqno_fifo = NULL; 182 183 if (fifo_type == SEQNO_FIFO_POISON_CREATION) 184 seqno_fifo = &ras_core->de_seqno_fifo; 185 else if (fifo_type == SEQNO_FIFO_POISON_CONSUMPTION) 186 seqno_fifo = &ras_core->consumption_seqno_fifo; 187 188 if (seqno_fifo) 189 ret = kfifo_in_spinlocked(seqno_fifo, 190 &seqno, sizeof(seqno), &ras_core->seqno_lock); 191 192 return ret ? 0 : -EINVAL; 193 } 194 195 static int ras_core_seqno_fifo_read(struct ras_core_context *ras_core, 196 enum ras_seqno_fifo fifo_type, uint64_t *seqno, bool pop) 197 { 198 int ret = 0; 199 struct kfifo *seqno_fifo = NULL; 200 201 if (fifo_type == SEQNO_FIFO_POISON_CREATION) 202 seqno_fifo = &ras_core->de_seqno_fifo; 203 else if (fifo_type == SEQNO_FIFO_POISON_CONSUMPTION) 204 seqno_fifo = &ras_core->consumption_seqno_fifo; 205 206 if (seqno_fifo) { 207 if (pop) 208 ret = kfifo_out_spinlocked(seqno_fifo, 209 seqno, sizeof(*seqno), &ras_core->seqno_lock); 210 else 211 ret = kfifo_out_peek(seqno_fifo, seqno, sizeof(*seqno)); 212 } 213 214 return ret ? 0 : -EINVAL; 215 } 216 217 uint64_t ras_core_gen_seqno(struct ras_core_context *ras_core, 218 enum ras_seqno_type type) 219 { 220 uint64_t seqno = 0; 221 222 if (ras_core->sys_fn && ras_core->sys_fn->gen_seqno && 223 ras_core->sys_fn->gen_seqno(ras_core, type, &seqno)) 224 return 0; 225 226 return seqno; 227 } 228 229 int ras_core_put_seqno(struct ras_core_context *ras_core, 230 enum ras_seqno_type seqno_type, uint64_t seqno) 231 { 232 int ret = 0; 233 234 if (seqno_type >= RAS_SEQNO_TYPE_COUNT_MAX) 235 return -EINVAL; 236 237 if (seqno_type == RAS_SEQNO_TYPE_DE) 238 ret = ras_core_seqno_fifo_write(ras_core, 239 SEQNO_FIFO_POISON_CREATION, seqno); 240 else if (seqno_type == RAS_SEQNO_TYPE_POISON_CONSUMPTION) 241 ret = ras_core_seqno_fifo_write(ras_core, 242 SEQNO_FIFO_POISON_CONSUMPTION, seqno); 243 else 244 ret = -EINVAL; 245 246 return ret; 247 } 248 249 uint64_t ras_core_get_seqno(struct ras_core_context *ras_core, 250 enum ras_seqno_type seqno_type, bool pop) 251 { 252 uint64_t seq_no; 253 int ret = -ENODATA; 254 255 if (seqno_type >= RAS_SEQNO_TYPE_COUNT_MAX) 256 return 0; 257 258 if (seqno_type == RAS_SEQNO_TYPE_DE) 259 ret = ras_core_seqno_fifo_read(ras_core, 260 SEQNO_FIFO_POISON_CREATION, &seq_no, pop); 261 else if (seqno_type == RAS_SEQNO_TYPE_POISON_CONSUMPTION) 262 ret = ras_core_seqno_fifo_read(ras_core, 263 SEQNO_FIFO_POISON_CONSUMPTION, &seq_no, pop); 264 265 if (ret) 266 seq_no = ras_core_gen_seqno(ras_core, seqno_type); 267 268 return seq_no; 269 } 270 271 static int ras_core_eeprom_recovery(struct ras_core_context *ras_core) 272 { 273 int count; 274 int ret; 275 276 if (ras_fw_eeprom_supported(ras_core)) 277 count = ras_fw_eeprom_get_record_count(ras_core); 278 else 279 count = ras_eeprom_get_record_count(ras_core); 280 if (!count) 281 return 0; 282 283 /* Avoid bad page to be loaded again after gpu reset */ 284 if (ras_umc_get_saved_eeprom_count(ras_core) >= count) 285 return 0; 286 287 ret = ras_umc_load_bad_pages(ras_core); 288 if (ret) { 289 RAS_DEV_ERR(ras_core->dev, "ras_umc_load_bad_pages failed: %d\n", ret); 290 return ret; 291 } 292 293 if (ras_fw_eeprom_supported(ras_core)) 294 ras_fw_eeprom_sync_info(ras_core); 295 else 296 ras_eeprom_sync_info(ras_core); 297 298 return ret; 299 } 300 301 struct ras_core_context *ras_core_create(struct ras_core_config *init_config) 302 { 303 struct ras_core_context *ras_core; 304 struct ras_core_config *config; 305 306 if (!init_config) 307 return NULL; 308 309 ras_core = kzalloc_obj(*ras_core); 310 if (!ras_core) 311 return NULL; 312 313 config = kzalloc_obj(*config); 314 if (!config) { 315 kfree(ras_core); 316 return NULL; 317 } 318 319 memcpy(config, init_config, sizeof(*config)); 320 ras_core->config = config; 321 322 return ras_core; 323 } 324 325 void ras_core_destroy(struct ras_core_context *ras_core) 326 { 327 if (ras_core) 328 kfree(ras_core->config); 329 330 kfree(ras_core); 331 } 332 333 int ras_core_sw_init(struct ras_core_context *ras_core) 334 { 335 int ret; 336 337 if (!ras_core->config) { 338 RAS_DEV_ERR(ras_core->dev, "No ras core config!\n"); 339 return -EINVAL; 340 } 341 342 ras_core->sys_fn = ras_core->config->sys_fn; 343 if (!ras_core->sys_fn) 344 return -EINVAL; 345 346 ret = kfifo_alloc(&ras_core->de_seqno_fifo, 347 RAS_SEQNO_FIFO_SIZE, GFP_KERNEL); 348 if (ret) 349 return ret; 350 351 ret = kfifo_alloc(&ras_core->consumption_seqno_fifo, 352 RAS_SEQNO_FIFO_SIZE, GFP_KERNEL); 353 if (ret) 354 return ret; 355 356 spin_lock_init(&ras_core->seqno_lock); 357 358 ret = ras_aca_sw_init(ras_core); 359 if (ret) 360 return ret; 361 362 ret = ras_umc_sw_init(ras_core); 363 if (ret) 364 return ret; 365 366 ret = ras_cmd_init(ras_core); 367 if (ret) 368 return ret; 369 370 ret = ras_log_ring_sw_init(ras_core); 371 if (ret) 372 return ret; 373 374 ret = ras_psp_sw_init(ras_core); 375 if (ret) 376 return ret; 377 378 return 0; 379 } 380 381 int ras_core_sw_fini(struct ras_core_context *ras_core) 382 { 383 kfifo_free(&ras_core->de_seqno_fifo); 384 kfifo_free(&ras_core->consumption_seqno_fifo); 385 386 ras_psp_sw_fini(ras_core); 387 ras_log_ring_sw_fini(ras_core); 388 ras_cmd_fini(ras_core); 389 ras_umc_sw_fini(ras_core); 390 ras_aca_sw_fini(ras_core); 391 392 return 0; 393 } 394 395 int ras_core_hw_init(struct ras_core_context *ras_core) 396 { 397 int ret; 398 399 ras_core->ras_eeprom_supported = 400 ras_core->config->ras_eeprom_supported; 401 402 ras_core->poison_supported = ras_core->config->poison_supported; 403 404 ret = ras_psp_hw_init(ras_core); 405 if (ret) 406 return ret; 407 408 ret = ras_aca_hw_init(ras_core); 409 if (ret) 410 goto init_err1; 411 412 ret = ras_mp1_hw_init(ras_core); 413 if (ret) 414 goto init_err2; 415 416 ret = ras_nbio_hw_init(ras_core); 417 if (ret) 418 goto init_err3; 419 420 ret = ras_umc_hw_init(ras_core); 421 if (ret) 422 goto init_err4; 423 424 ret = ras_gfx_hw_init(ras_core); 425 if (ret) 426 goto init_err5; 427 428 ras_fw_init_feature_flags(ras_core); 429 430 if (ras_fw_eeprom_supported(ras_core)) 431 ret = ras_fw_eeprom_hw_init(ras_core); 432 else 433 ret = ras_eeprom_hw_init(ras_core); 434 if (ret) 435 goto init_err6; 436 437 ret = ras_core_eeprom_recovery(ras_core); 438 if (ret) { 439 RAS_DEV_ERR(ras_core->dev, 440 "Failed to recovery ras core, ret:%d\n", ret); 441 goto init_err6; 442 } 443 444 if (ras_fw_eeprom_supported(ras_core)) 445 ret = ras_fw_eeprom_check_storage_status(ras_core); 446 else 447 ret = ras_eeprom_check_storage_status(ras_core); 448 if (ret) 449 goto init_err6; 450 451 ret = ras_process_init(ras_core); 452 if (ret) 453 goto init_err7; 454 455 ras_core->is_initialized = true; 456 457 return 0; 458 459 init_err7: 460 if (ras_fw_eeprom_supported(ras_core)) 461 ras_fw_eeprom_hw_fini(ras_core); 462 else 463 ras_eeprom_hw_fini(ras_core); 464 init_err6: 465 ras_gfx_hw_fini(ras_core); 466 init_err5: 467 ras_umc_hw_fini(ras_core); 468 init_err4: 469 ras_nbio_hw_fini(ras_core); 470 init_err3: 471 ras_mp1_hw_fini(ras_core); 472 init_err2: 473 ras_aca_hw_fini(ras_core); 474 init_err1: 475 ras_psp_hw_fini(ras_core); 476 return ret; 477 } 478 479 int ras_core_hw_fini(struct ras_core_context *ras_core) 480 { 481 ras_core->is_initialized = false; 482 483 ras_process_fini(ras_core); 484 if (ras_fw_eeprom_supported(ras_core)) 485 ras_fw_eeprom_hw_fini(ras_core); 486 else 487 ras_eeprom_hw_fini(ras_core); 488 ras_gfx_hw_fini(ras_core); 489 ras_nbio_hw_fini(ras_core); 490 ras_umc_hw_fini(ras_core); 491 ras_mp1_hw_fini(ras_core); 492 ras_aca_hw_fini(ras_core); 493 ras_psp_hw_fini(ras_core); 494 495 return 0; 496 } 497 498 bool ras_core_handle_nbio_irq(struct ras_core_context *ras_core, void *data) 499 { 500 return ras_nbio_handle_irq_error(ras_core, data); 501 } 502 503 int ras_core_handle_fatal_error(struct ras_core_context *ras_core) 504 { 505 int ret = 0; 506 507 ras_aca_mark_fatal_flag(ras_core); 508 509 ret = ras_core_event_notify(ras_core, 510 RAS_EVENT_ID__FATAL_ERROR_DETECTED, NULL); 511 512 return ret; 513 } 514 515 uint32_t ras_core_get_curr_nps_mode(struct ras_core_context *ras_core) 516 { 517 if (!ras_core) 518 return 0; 519 520 if (ras_core->ras_nbio.ip_func && 521 ras_core->ras_nbio.ip_func->get_memory_partition_mode) 522 return ras_core->ras_nbio.ip_func->get_memory_partition_mode(ras_core); 523 524 RAS_DEV_ERR(ras_core->dev, "Failed to get gpu memory nps mode!\n"); 525 return 0; 526 } 527 528 int ras_core_update_ecc_info(struct ras_core_context *ras_core) 529 { 530 int ret; 531 532 ret = ras_aca_update_ecc(ras_core, RAS_ERR_TYPE__CE, NULL); 533 if (!ret) 534 ret = ras_aca_update_ecc(ras_core, RAS_ERR_TYPE__UE, NULL); 535 536 return ret; 537 } 538 539 int ras_core_query_block_ecc_data(struct ras_core_context *ras_core, 540 enum ras_block_id block, struct ras_ecc_count *ecc_count) 541 { 542 int ret; 543 544 if (!ecc_count || (block >= RAS_BLOCK_ID__LAST) || !ras_core) 545 return -EINVAL; 546 547 ret = ras_aca_get_block_ecc_count(ras_core, block, ecc_count); 548 if (!ret) 549 ras_aca_clear_block_new_ecc_count(ras_core, block); 550 551 return ret; 552 } 553 554 int ras_core_set_status(struct ras_core_context *ras_core, bool enable) 555 { 556 ras_core->ras_core_enabled = enable; 557 558 return 0; 559 } 560 561 bool ras_core_is_enabled(struct ras_core_context *ras_core) 562 { 563 return ras_core->ras_core_enabled; 564 } 565 566 bool ras_core_is_ce_log_disabled(struct ras_core_context *ras_core) 567 { 568 return !!(ras_core->config->ras_debug_mask & BIT(RAS_DEBUG_DISABLE_RAS_CE_LOG)); 569 } 570 571 uint64_t ras_core_get_utc_second_timestamp(struct ras_core_context *ras_core) 572 { 573 if (!ras_core) 574 return 0; 575 576 if (ras_core->sys_fn && 577 ras_core->sys_fn->get_utc_second_timestamp) 578 return ras_core->sys_fn->get_utc_second_timestamp(ras_core); 579 580 RAS_DEV_ERR(ras_core->dev, "Failed to get system timestamp!\n"); 581 return 0; 582 } 583 584 int ras_core_translate_soc_pa_and_bank(struct ras_core_context *ras_core, 585 uint64_t *soc_pa, struct umc_bank_addr *bank_addr, bool bank_to_pa) 586 { 587 if (!ras_core || !soc_pa || !bank_addr) 588 return -EINVAL; 589 590 return ras_umc_translate_soc_pa_and_bank(ras_core, soc_pa, bank_addr, bank_to_pa); 591 } 592 593 bool ras_core_ras_interrupt_detected(struct ras_core_context *ras_core) 594 { 595 if (ras_core && ras_core->sys_fn && 596 ras_core->sys_fn->detect_ras_interrupt) 597 return ras_core->sys_fn->detect_ras_interrupt(ras_core); 598 599 if (ras_core && ras_core->dev) 600 RAS_DEV_ERR(ras_core->dev, "Failed to detect ras interrupt!\n"); 601 602 return false; 603 } 604 605 int ras_core_get_gpu_mem(struct ras_core_context *ras_core, 606 enum gpu_mem_type mem_type, struct gpu_mem_block *gpu_mem) 607 { 608 if (!ras_core || !gpu_mem) 609 return -EINVAL; 610 if (ras_core->sys_fn && ras_core->sys_fn->get_gpu_mem) 611 return ras_core->sys_fn->get_gpu_mem(ras_core, mem_type, gpu_mem); 612 613 RAS_DEV_ERR(ras_core->dev, "Not config get gpu memory API!\n"); 614 return -EACCES; 615 } 616 617 int ras_core_put_gpu_mem(struct ras_core_context *ras_core, 618 enum gpu_mem_type mem_type, struct gpu_mem_block *gpu_mem) 619 { 620 if (!ras_core || !gpu_mem) 621 return -EINVAL; 622 if (ras_core->sys_fn && ras_core->sys_fn->put_gpu_mem) 623 return ras_core->sys_fn->put_gpu_mem(ras_core, mem_type, gpu_mem); 624 625 RAS_DEV_ERR(ras_core->dev, "Not config put gpu memory API!!\n"); 626 return -EACCES; 627 } 628 629 bool ras_core_is_ready(struct ras_core_context *ras_core) 630 { 631 return ras_core ? ras_core->is_initialized : false; 632 } 633 634 bool ras_core_check_safety_watermark(struct ras_core_context *ras_core) 635 { 636 if (ras_fw_eeprom_supported(ras_core)) 637 return ras_fw_eeprom_check_safety_watermark(ras_core); 638 639 return ras_eeprom_check_safety_watermark(ras_core); 640 } 641 642 int ras_core_down_trylock_gpu_reset_lock(struct ras_core_context *ras_core) 643 { 644 if (ras_core->sys_fn && ras_core->sys_fn->gpu_reset_lock) 645 return ras_core->sys_fn->gpu_reset_lock(ras_core, true, true); 646 647 return 1; 648 } 649 650 void ras_core_down_gpu_reset_lock(struct ras_core_context *ras_core) 651 { 652 if (ras_core->sys_fn && ras_core->sys_fn->gpu_reset_lock) 653 ras_core->sys_fn->gpu_reset_lock(ras_core, true, false); 654 } 655 656 void ras_core_up_gpu_reset_lock(struct ras_core_context *ras_core) 657 { 658 if (ras_core->sys_fn && ras_core->sys_fn->gpu_reset_lock) 659 ras_core->sys_fn->gpu_reset_lock(ras_core, false, false); 660 } 661 662 int ras_core_event_notify(struct ras_core_context *ras_core, 663 enum ras_notify_event event_id, void *data) 664 { 665 if (ras_core && ras_core->sys_fn && 666 ras_core->sys_fn->ras_notifier) 667 return ras_core->sys_fn->ras_notifier(ras_core, event_id, data); 668 669 return -RAS_CORE_NOT_SUPPORTED; 670 } 671 672 int ras_core_get_device_system_info(struct ras_core_context *ras_core, 673 struct device_system_info *dev_info) 674 { 675 if (!dev_info) 676 return -EINVAL; 677 678 if (ras_core && ras_core->sys_fn && 679 ras_core->sys_fn->get_device_system_info) 680 return ras_core->sys_fn->get_device_system_info(ras_core, dev_info); 681 682 return -RAS_CORE_NOT_SUPPORTED; 683 } 684 685 int ras_core_convert_soc_pa_to_cur_nps_pages(struct ras_core_context *ras_core, 686 uint64_t soc_pa, uint64_t *page_pfn, uint32_t max_pages) 687 { 688 struct eeprom_umc_record record; 689 uint32_t cur_nps_mode; 690 int count = 0; 691 692 if (!ras_core || !page_pfn || !max_pages) 693 return -EINVAL; 694 695 cur_nps_mode = ras_core_get_curr_nps_mode(ras_core); 696 if (!cur_nps_mode || cur_nps_mode > UMC_MEMORY_PARTITION_MODE_NPS8) 697 return -EINVAL; 698 699 memset(&record, 0, sizeof(record)); 700 record.cur_nps_retired_row_pfn = RAS_ADDR_TO_PFN(soc_pa); 701 702 count = ras_umc_convert_record_to_nps_pages(ras_core, 703 &record, cur_nps_mode, page_pfn, max_pages); 704 705 return count; 706 } 707 708 int ras_core_check_address_sanity(struct ras_core_context *ras_core, 709 uint64_t addr) 710 { 711 if (ras_core && ras_core->sys_fn && 712 ras_core->sys_fn->check_address_sanity) 713 return ras_core->sys_fn->check_address_sanity(ras_core, addr); 714 715 return 0; 716 } 717