| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * 64-bit pSeries and RS/6000 setup code. |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * Adapted from 'alpha' version by Gary Thomas |
|---|
| 6 | 7 | * Modified by Cort Dougan (cort@cs.nmt.edu) |
|---|
| 7 | 8 | * Modified by PPC64 Team, IBM Corp |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or |
|---|
| 10 | | - * modify it under the terms of the GNU General Public License |
|---|
| 11 | | - * as published by the Free Software Foundation; either version |
|---|
| 12 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 13 | 9 | */ |
|---|
| 14 | 10 | |
|---|
| 15 | 11 | /* |
|---|
| .. | .. |
|---|
| 42 | 38 | #include <linux/of.h> |
|---|
| 43 | 39 | #include <linux/of_pci.h> |
|---|
| 44 | 40 | #include <linux/memblock.h> |
|---|
| 41 | +#include <linux/swiotlb.h> |
|---|
| 45 | 42 | |
|---|
| 46 | 43 | #include <asm/mmu.h> |
|---|
| 47 | 44 | #include <asm/processor.h> |
|---|
| 48 | 45 | #include <asm/io.h> |
|---|
| 49 | | -#include <asm/pgtable.h> |
|---|
| 50 | 46 | #include <asm/prom.h> |
|---|
| 51 | 47 | #include <asm/rtas.h> |
|---|
| 52 | 48 | #include <asm/pci-bridge.h> |
|---|
| .. | .. |
|---|
| 71 | 67 | #include <asm/isa-bridge.h> |
|---|
| 72 | 68 | #include <asm/security_features.h> |
|---|
| 73 | 69 | #include <asm/asm-const.h> |
|---|
| 70 | +#include <asm/idle.h> |
|---|
| 71 | +#include <asm/swiotlb.h> |
|---|
| 72 | +#include <asm/svm.h> |
|---|
| 73 | +#include <asm/dtl.h> |
|---|
| 74 | 74 | |
|---|
| 75 | 75 | #include "pseries.h" |
|---|
| 76 | 76 | #include "../../../../drivers/pci/pci.h" |
|---|
| .. | .. |
|---|
| 84 | 84 | EXPORT_SYMBOL(CMO_PageSize); |
|---|
| 85 | 85 | |
|---|
| 86 | 86 | int fwnmi_active; /* TRUE if an FWNMI handler is present */ |
|---|
| 87 | +int ibm_nmi_interlock_token; |
|---|
| 87 | 88 | |
|---|
| 88 | 89 | static void pSeries_show_cpuinfo(struct seq_file *m) |
|---|
| 89 | 90 | { |
|---|
| .. | .. |
|---|
| 110 | 111 | u8 *mce_data_buf; |
|---|
| 111 | 112 | unsigned int i; |
|---|
| 112 | 113 | int nr_cpus = num_possible_cpus(); |
|---|
| 114 | +#ifdef CONFIG_PPC_BOOK3S_64 |
|---|
| 115 | + struct slb_entry *slb_ptr; |
|---|
| 116 | + size_t size; |
|---|
| 117 | +#endif |
|---|
| 118 | + int ibm_nmi_register_token; |
|---|
| 113 | 119 | |
|---|
| 114 | | - int ibm_nmi_register = rtas_token("ibm,nmi-register"); |
|---|
| 115 | | - if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE) |
|---|
| 120 | + ibm_nmi_register_token = rtas_token("ibm,nmi-register"); |
|---|
| 121 | + if (ibm_nmi_register_token == RTAS_UNKNOWN_SERVICE) |
|---|
| 122 | + return; |
|---|
| 123 | + |
|---|
| 124 | + ibm_nmi_interlock_token = rtas_token("ibm,nmi-interlock"); |
|---|
| 125 | + if (WARN_ON(ibm_nmi_interlock_token == RTAS_UNKNOWN_SERVICE)) |
|---|
| 116 | 126 | return; |
|---|
| 117 | 127 | |
|---|
| 118 | 128 | /* If the kernel's not linked at zero we point the firmware at low |
|---|
| .. | .. |
|---|
| 120 | 130 | system_reset_addr = __pa(system_reset_fwnmi) - PHYSICAL_START; |
|---|
| 121 | 131 | machine_check_addr = __pa(machine_check_fwnmi) - PHYSICAL_START; |
|---|
| 122 | 132 | |
|---|
| 123 | | - if (0 == rtas_call(ibm_nmi_register, 2, 1, NULL, system_reset_addr, |
|---|
| 124 | | - machine_check_addr)) |
|---|
| 133 | + if (0 == rtas_call(ibm_nmi_register_token, 2, 1, NULL, |
|---|
| 134 | + system_reset_addr, machine_check_addr)) |
|---|
| 125 | 135 | fwnmi_active = 1; |
|---|
| 126 | 136 | |
|---|
| 127 | 137 | /* |
|---|
| .. | .. |
|---|
| 129 | 139 | * It will be used in real mode mce handler, hence it needs to be |
|---|
| 130 | 140 | * below RMA. |
|---|
| 131 | 141 | */ |
|---|
| 132 | | - mce_data_buf = __va(memblock_alloc_base(RTAS_ERROR_LOG_MAX * nr_cpus, |
|---|
| 133 | | - RTAS_ERROR_LOG_MAX, ppc64_rma_size)); |
|---|
| 142 | + mce_data_buf = memblock_alloc_try_nid_raw(RTAS_ERROR_LOG_MAX * nr_cpus, |
|---|
| 143 | + RTAS_ERROR_LOG_MAX, MEMBLOCK_LOW_LIMIT, |
|---|
| 144 | + ppc64_rma_size, NUMA_NO_NODE); |
|---|
| 145 | + if (!mce_data_buf) |
|---|
| 146 | + panic("Failed to allocate %d bytes below %pa for MCE buffer\n", |
|---|
| 147 | + RTAS_ERROR_LOG_MAX * nr_cpus, &ppc64_rma_size); |
|---|
| 148 | + |
|---|
| 134 | 149 | for_each_possible_cpu(i) { |
|---|
| 135 | 150 | paca_ptrs[i]->mce_data_buf = mce_data_buf + |
|---|
| 136 | 151 | (RTAS_ERROR_LOG_MAX * i); |
|---|
| 137 | 152 | } |
|---|
| 153 | + |
|---|
| 154 | +#ifdef CONFIG_PPC_BOOK3S_64 |
|---|
| 155 | + if (!radix_enabled()) { |
|---|
| 156 | + /* Allocate per cpu area to save old slb contents during MCE */ |
|---|
| 157 | + size = sizeof(struct slb_entry) * mmu_slb_size * nr_cpus; |
|---|
| 158 | + slb_ptr = memblock_alloc_try_nid_raw(size, |
|---|
| 159 | + sizeof(struct slb_entry), MEMBLOCK_LOW_LIMIT, |
|---|
| 160 | + ppc64_rma_size, NUMA_NO_NODE); |
|---|
| 161 | + if (!slb_ptr) |
|---|
| 162 | + panic("Failed to allocate %zu bytes below %pa for slb area\n", |
|---|
| 163 | + size, &ppc64_rma_size); |
|---|
| 164 | + |
|---|
| 165 | + for_each_possible_cpu(i) |
|---|
| 166 | + paca_ptrs[i]->mce_faulty_slbs = slb_ptr + (mmu_slb_size * i); |
|---|
| 167 | + } |
|---|
| 168 | +#endif |
|---|
| 138 | 169 | } |
|---|
| 139 | 170 | |
|---|
| 140 | 171 | static void pseries_8259_cascade(struct irq_desc *desc) |
|---|
| .. | .. |
|---|
| 180 | 211 | of_node_put(old); |
|---|
| 181 | 212 | if (np == NULL) |
|---|
| 182 | 213 | break; |
|---|
| 183 | | - if (strcmp(np->name, "pci") != 0) |
|---|
| 214 | + if (!of_node_name_eq(np, "pci")) |
|---|
| 184 | 215 | continue; |
|---|
| 185 | 216 | addrp = of_get_property(np, "8259-interrupt-acknowledge", NULL); |
|---|
| 186 | 217 | if (addrp == NULL) |
|---|
| .. | .. |
|---|
| 257 | 288 | */ |
|---|
| 258 | 289 | static int alloc_dispatch_logs(void) |
|---|
| 259 | 290 | { |
|---|
| 260 | | - int cpu, ret; |
|---|
| 261 | | - struct paca_struct *pp; |
|---|
| 262 | | - struct dtl_entry *dtl; |
|---|
| 263 | | - |
|---|
| 264 | 291 | if (!firmware_has_feature(FW_FEATURE_SPLPAR)) |
|---|
| 265 | 292 | return 0; |
|---|
| 266 | 293 | |
|---|
| 267 | 294 | if (!dtl_cache) |
|---|
| 268 | 295 | return 0; |
|---|
| 269 | 296 | |
|---|
| 270 | | - for_each_possible_cpu(cpu) { |
|---|
| 271 | | - pp = paca_ptrs[cpu]; |
|---|
| 272 | | - dtl = kmem_cache_alloc(dtl_cache, GFP_KERNEL); |
|---|
| 273 | | - if (!dtl) { |
|---|
| 274 | | - pr_warn("Failed to allocate dispatch trace log for cpu %d\n", |
|---|
| 275 | | - cpu); |
|---|
| 276 | | - pr_warn("Stolen time statistics will be unreliable\n"); |
|---|
| 277 | | - break; |
|---|
| 278 | | - } |
|---|
| 279 | | - |
|---|
| 280 | | - pp->dtl_ridx = 0; |
|---|
| 281 | | - pp->dispatch_log = dtl; |
|---|
| 282 | | - pp->dispatch_log_end = dtl + N_DISPATCH_LOG; |
|---|
| 283 | | - pp->dtl_curr = dtl; |
|---|
| 284 | | - } |
|---|
| 297 | + alloc_dtl_buffers(0); |
|---|
| 285 | 298 | |
|---|
| 286 | 299 | /* Register the DTL for the current (boot) cpu */ |
|---|
| 287 | | - dtl = get_paca()->dispatch_log; |
|---|
| 288 | | - get_paca()->dtl_ridx = 0; |
|---|
| 289 | | - get_paca()->dtl_curr = dtl; |
|---|
| 290 | | - get_paca()->lppaca_ptr->dtl_idx = 0; |
|---|
| 291 | | - |
|---|
| 292 | | - /* hypervisor reads buffer length from this field */ |
|---|
| 293 | | - dtl->enqueue_to_dispatch_time = cpu_to_be32(DISPATCH_LOG_BYTES); |
|---|
| 294 | | - ret = register_dtl(hard_smp_processor_id(), __pa(dtl)); |
|---|
| 295 | | - if (ret) |
|---|
| 296 | | - pr_err("WARNING: DTL registration of cpu %d (hw %d) failed " |
|---|
| 297 | | - "with %d\n", smp_processor_id(), |
|---|
| 298 | | - hard_smp_processor_id(), ret); |
|---|
| 299 | | - get_paca()->lppaca_ptr->dtl_enable_mask = 2; |
|---|
| 300 | + register_dtl_buffer(smp_processor_id()); |
|---|
| 300 | 301 | |
|---|
| 301 | 302 | return 0; |
|---|
| 302 | 303 | } |
|---|
| .. | .. |
|---|
| 309 | 310 | |
|---|
| 310 | 311 | static int alloc_dispatch_log_kmem_cache(void) |
|---|
| 311 | 312 | { |
|---|
| 313 | + void (*ctor)(void *) = get_dtl_cache_ctor(); |
|---|
| 314 | + |
|---|
| 312 | 315 | dtl_cache = kmem_cache_create("dtl", DISPATCH_LOG_BYTES, |
|---|
| 313 | | - DISPATCH_LOG_BYTES, 0, NULL); |
|---|
| 316 | + DISPATCH_LOG_BYTES, 0, ctor); |
|---|
| 314 | 317 | if (!dtl_cache) { |
|---|
| 315 | 318 | pr_warn("Failed to create dispatch trace log buffer cache\n"); |
|---|
| 316 | 319 | pr_warn("Stolen time statistics will be unreliable\n"); |
|---|
| .. | .. |
|---|
| 321 | 324 | } |
|---|
| 322 | 325 | machine_early_initcall(pseries, alloc_dispatch_log_kmem_cache); |
|---|
| 323 | 326 | |
|---|
| 327 | +DEFINE_PER_CPU(u64, idle_spurr_cycles); |
|---|
| 328 | +DEFINE_PER_CPU(u64, idle_entry_purr_snap); |
|---|
| 329 | +DEFINE_PER_CPU(u64, idle_entry_spurr_snap); |
|---|
| 324 | 330 | static void pseries_lpar_idle(void) |
|---|
| 325 | 331 | { |
|---|
| 326 | 332 | /* |
|---|
| .. | .. |
|---|
| 332 | 338 | return; |
|---|
| 333 | 339 | |
|---|
| 334 | 340 | /* Indicate to hypervisor that we are idle. */ |
|---|
| 335 | | - get_lppaca()->idle = 1; |
|---|
| 341 | + pseries_idle_prolog(); |
|---|
| 336 | 342 | |
|---|
| 337 | 343 | /* |
|---|
| 338 | 344 | * Yield the processor to the hypervisor. We return if |
|---|
| .. | .. |
|---|
| 343 | 349 | */ |
|---|
| 344 | 350 | cede_processor(); |
|---|
| 345 | 351 | |
|---|
| 346 | | - get_lppaca()->idle = 0; |
|---|
| 352 | + pseries_idle_epilog(); |
|---|
| 347 | 353 | } |
|---|
| 348 | 354 | |
|---|
| 349 | 355 | /* |
|---|
| .. | .. |
|---|
| 353 | 359 | * to ever be a problem in practice we can move this into a kernel thread to |
|---|
| 354 | 360 | * finish off the process later in boot. |
|---|
| 355 | 361 | */ |
|---|
| 356 | | -void pseries_enable_reloc_on_exc(void) |
|---|
| 362 | +bool pseries_enable_reloc_on_exc(void) |
|---|
| 357 | 363 | { |
|---|
| 358 | 364 | long rc; |
|---|
| 359 | 365 | unsigned int delay, total_delay = 0; |
|---|
| .. | .. |
|---|
| 364 | 370 | if (rc == H_P2) { |
|---|
| 365 | 371 | pr_info("Relocation on exceptions not" |
|---|
| 366 | 372 | " supported\n"); |
|---|
| 373 | + return false; |
|---|
| 367 | 374 | } else if (rc != H_SUCCESS) { |
|---|
| 368 | 375 | pr_warn("Unable to enable relocation" |
|---|
| 369 | 376 | " on exceptions: %ld\n", rc); |
|---|
| 377 | + return false; |
|---|
| 370 | 378 | } |
|---|
| 371 | | - break; |
|---|
| 379 | + return true; |
|---|
| 372 | 380 | } |
|---|
| 373 | 381 | |
|---|
| 374 | 382 | delay = get_longbusy_msecs(rc); |
|---|
| .. | .. |
|---|
| 377 | 385 | pr_warn("Warning: Giving up waiting to enable " |
|---|
| 378 | 386 | "relocation on exceptions (%u msec)!\n", |
|---|
| 379 | 387 | total_delay); |
|---|
| 380 | | - return; |
|---|
| 388 | + return false; |
|---|
| 381 | 389 | } |
|---|
| 382 | 390 | |
|---|
| 383 | 391 | mdelay(delay); |
|---|
| .. | .. |
|---|
| 462 | 470 | struct device_node *root = of_find_node_by_path("/"); |
|---|
| 463 | 471 | |
|---|
| 464 | 472 | for_each_child_of_node(root, node) { |
|---|
| 465 | | - if (node->type == NULL || (strcmp(node->type, "pci") != 0 && |
|---|
| 466 | | - strcmp(node->type, "pciex") != 0)) |
|---|
| 473 | + if (!of_node_is_type(node, "pci") && |
|---|
| 474 | + !of_node_is_type(node, "pciex")) |
|---|
| 467 | 475 | continue; |
|---|
| 468 | 476 | |
|---|
| 469 | 477 | phb = pcibios_alloc_controller(node); |
|---|
| .. | .. |
|---|
| 511 | 519 | if (result->character & H_CPU_CHAR_BCCTR_FLUSH_ASSIST) |
|---|
| 512 | 520 | security_ftr_set(SEC_FTR_BCCTR_FLUSH_ASSIST); |
|---|
| 513 | 521 | |
|---|
| 522 | + if (result->character & H_CPU_CHAR_BCCTR_LINK_FLUSH_ASSIST) |
|---|
| 523 | + security_ftr_set(SEC_FTR_BCCTR_LINK_FLUSH_ASSIST); |
|---|
| 524 | + |
|---|
| 514 | 525 | if (result->behaviour & H_CPU_BEHAV_FLUSH_COUNT_CACHE) |
|---|
| 515 | 526 | security_ftr_set(SEC_FTR_FLUSH_COUNT_CACHE); |
|---|
| 527 | + |
|---|
| 528 | + if (result->behaviour & H_CPU_BEHAV_FLUSH_LINK_STACK) |
|---|
| 529 | + security_ftr_set(SEC_FTR_FLUSH_LINK_STACK); |
|---|
| 516 | 530 | |
|---|
| 517 | 531 | /* |
|---|
| 518 | 532 | * The features below are enabled by default, so we instead look to see |
|---|
| .. | .. |
|---|
| 524 | 538 | if (!(result->behaviour & H_CPU_BEHAV_L1D_FLUSH_PR)) |
|---|
| 525 | 539 | security_ftr_clear(SEC_FTR_L1D_FLUSH_PR); |
|---|
| 526 | 540 | |
|---|
| 541 | + if (result->behaviour & H_CPU_BEHAV_NO_L1D_FLUSH_ENTRY) |
|---|
| 542 | + security_ftr_clear(SEC_FTR_L1D_FLUSH_ENTRY); |
|---|
| 543 | + |
|---|
| 544 | + if (result->behaviour & H_CPU_BEHAV_NO_L1D_FLUSH_UACCESS) |
|---|
| 545 | + security_ftr_clear(SEC_FTR_L1D_FLUSH_UACCESS); |
|---|
| 546 | + |
|---|
| 527 | 547 | if (!(result->behaviour & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR)) |
|---|
| 528 | 548 | security_ftr_clear(SEC_FTR_BNDS_CHK_SPEC_BAR); |
|---|
| 529 | 549 | } |
|---|
| 530 | 550 | |
|---|
| 531 | | -void pseries_setup_rfi_flush(void) |
|---|
| 551 | +void pseries_setup_security_mitigations(void) |
|---|
| 532 | 552 | { |
|---|
| 533 | 553 | struct h_cpu_char_result result; |
|---|
| 534 | 554 | enum l1d_flush_type types; |
|---|
| .. | .. |
|---|
| 573 | 593 | enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && |
|---|
| 574 | 594 | security_ftr_enabled(SEC_FTR_L1D_FLUSH_UACCESS); |
|---|
| 575 | 595 | setup_uaccess_flush(enable); |
|---|
| 596 | + |
|---|
| 597 | + setup_stf_barrier(); |
|---|
| 576 | 598 | } |
|---|
| 577 | 599 | |
|---|
| 578 | 600 | #ifdef CONFIG_PCI_IOV |
|---|
| .. | .. |
|---|
| 748 | 770 | smp_init_pseries(); |
|---|
| 749 | 771 | |
|---|
| 750 | 772 | |
|---|
| 773 | + if (radix_enabled() && !mmu_has_feature(MMU_FTR_GTSE)) |
|---|
| 774 | + if (!firmware_has_feature(FW_FEATURE_RPT_INVALIDATE)) |
|---|
| 775 | + panic("BUG: Radix support requires either GTSE or RPT_INVALIDATE\n"); |
|---|
| 776 | + |
|---|
| 777 | + |
|---|
| 751 | 778 | /* openpic global configuration register (64-bit format). */ |
|---|
| 752 | 779 | /* openpic Interrupt Source Unit pointer (64-bit format). */ |
|---|
| 753 | 780 | /* python0 facility area (mmio) (64-bit format) REAL address. */ |
|---|
| .. | .. |
|---|
| 757 | 784 | |
|---|
| 758 | 785 | fwnmi_init(); |
|---|
| 759 | 786 | |
|---|
| 760 | | - pseries_setup_rfi_flush(); |
|---|
| 761 | | - setup_stf_barrier(); |
|---|
| 787 | + pseries_setup_security_mitigations(); |
|---|
| 788 | + pseries_lpar_read_hblkrm_characteristics(); |
|---|
| 762 | 789 | |
|---|
| 763 | 790 | /* By default, only probe PCI (can be overridden by rtas_pci) */ |
|---|
| 764 | 791 | pci_add_flags(PCI_PROBE_ONLY); |
|---|
| .. | .. |
|---|
| 773 | 800 | if (firmware_has_feature(FW_FEATURE_LPAR)) { |
|---|
| 774 | 801 | vpa_init(boot_cpuid); |
|---|
| 775 | 802 | |
|---|
| 776 | | - if (lppaca_shared_proc(get_lppaca())) |
|---|
| 803 | + if (lppaca_shared_proc()) { |
|---|
| 777 | 804 | static_branch_enable(&shared_processor); |
|---|
| 805 | + pv_spinlocks_init(); |
|---|
| 806 | + } |
|---|
| 778 | 807 | |
|---|
| 779 | 808 | ppc_md.power_save = pseries_lpar_idle; |
|---|
| 780 | 809 | ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; |
|---|
| .. | .. |
|---|
| 792 | 821 | } |
|---|
| 793 | 822 | |
|---|
| 794 | 823 | ppc_md.pcibios_root_bridge_prepare = pseries_root_bridge_prepare; |
|---|
| 824 | + |
|---|
| 825 | + if (swiotlb_force == SWIOTLB_FORCE) |
|---|
| 826 | + ppc_swiotlb_enable = 1; |
|---|
| 827 | + |
|---|
| 828 | + pseries_rng_init(); |
|---|
| 795 | 829 | } |
|---|
| 796 | 830 | |
|---|
| 797 | 831 | static void pseries_panic(char *str) |
|---|
| .. | .. |
|---|
| 830 | 864 | return plpar_hcall_norets(H_SET_XDABR, dabr, dabrx); |
|---|
| 831 | 865 | } |
|---|
| 832 | 866 | |
|---|
| 833 | | -static int pseries_set_dawr(unsigned long dawr, unsigned long dawrx) |
|---|
| 867 | +static int pseries_set_dawr(int nr, unsigned long dawr, unsigned long dawrx) |
|---|
| 834 | 868 | { |
|---|
| 835 | 869 | /* PAPR says we can't set HYP */ |
|---|
| 836 | 870 | dawrx &= ~DAWRX_HYP; |
|---|
| 837 | 871 | |
|---|
| 838 | | - return plpar_set_watchpoint0(dawr, dawrx); |
|---|
| 872 | + if (nr == 0) |
|---|
| 873 | + return plpar_set_watchpoint0(dawr, dawrx); |
|---|
| 874 | + else |
|---|
| 875 | + return plpar_set_watchpoint1(dawr, dawrx); |
|---|
| 839 | 876 | } |
|---|
| 840 | 877 | |
|---|
| 841 | 878 | #define CMO_CHARACTERISTICS_TOKEN 44 |
|---|
| .. | .. |
|---|
| 983 | 1020 | |
|---|
| 984 | 1021 | static int __init pSeries_probe(void) |
|---|
| 985 | 1022 | { |
|---|
| 986 | | - const char *dtype = of_get_property(of_root, "device_type", NULL); |
|---|
| 987 | | - |
|---|
| 988 | | - if (dtype == NULL) |
|---|
| 989 | | - return 0; |
|---|
| 990 | | - if (strcmp(dtype, "chrp")) |
|---|
| 1023 | + if (!of_node_is_type(of_root, "chrp")) |
|---|
| 991 | 1024 | return 0; |
|---|
| 992 | 1025 | |
|---|
| 993 | 1026 | /* Cell blades firmware claims to be chrp while it's not. Until this |
|---|
| .. | .. |
|---|
| 1035 | 1068 | .calibrate_decr = generic_calibrate_decr, |
|---|
| 1036 | 1069 | .progress = rtas_progress, |
|---|
| 1037 | 1070 | .system_reset_exception = pSeries_system_reset_exception, |
|---|
| 1071 | + .machine_check_early = pseries_machine_check_realmode, |
|---|
| 1038 | 1072 | .machine_check_exception = pSeries_machine_check_exception, |
|---|
| 1039 | 1073 | #ifdef CONFIG_KEXEC_CORE |
|---|
| 1040 | 1074 | .machine_kexec = pSeries_machine_kexec, |
|---|