Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: PPC: Book3S 64: Move interrupt early register setup to KVM

Like the earlier patch for hcalls, KVM interrupt entry requires a
different calling convention than the Linux interrupt handlers
set up. Move the code that converts from one to the other into KVM.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Reviewed-by: Fabiano Rosas <farosas@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210528090752.3542186-6-npiggin@gmail.com

authored by

Nicholas Piggin and committed by
Michael Ellerman
69fdd674 04ece7b6

+71 -110
+23 -108
arch/powerpc/kernel/exceptions-64s.S
··· 187 187 .endif 188 188 .endm 189 189 190 - #ifdef CONFIG_KVM_BOOK3S_64_HANDLER 191 190 /* 192 191 * All interrupts which set HSRR registers, as well as SRESET and MCE and 193 192 * syscall when invoked with "sc 1" switch to MSR[HV]=1 (HVMODE) to be taken, ··· 219 220 * to KVM to handle. 220 221 */ 221 222 222 - .macro KVMTEST name 223 + .macro KVMTEST name handler 224 + #ifdef CONFIG_KVM_BOOK3S_64_HANDLER 223 225 lbz r10,HSTATE_IN_GUEST(r13) 224 226 cmpwi r10,0 225 - bne \name\()_kvm 226 - .endm 227 - 228 - .macro GEN_KVM name 229 - .balign IFETCH_ALIGN_BYTES 230 - \name\()_kvm: 231 - 232 - BEGIN_FTR_SECTION 233 - ld r10,IAREA+EX_CFAR(r13) 234 - std r10,HSTATE_CFAR(r13) 235 - END_FTR_SECTION_IFSET(CPU_FTR_CFAR) 236 - 237 - ld r10,IAREA+EX_CTR(r13) 238 - mtctr r10 239 - BEGIN_FTR_SECTION 240 - ld r10,IAREA+EX_PPR(r13) 241 - std r10,HSTATE_PPR(r13) 242 - END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) 243 - ld r11,IAREA+EX_R11(r13) 244 - ld r12,IAREA+EX_R12(r13) 245 - std r12,HSTATE_SCRATCH0(r13) 246 - sldi r12,r9,32 247 - ld r9,IAREA+EX_R9(r13) 248 - ld r10,IAREA+EX_R10(r13) 249 227 /* HSRR variants have the 0x2 bit added to their trap number */ 250 228 .if IHSRR_IF_HVMODE 251 229 BEGIN_FTR_SECTION 252 - ori r12,r12,(IVEC + 0x2) 230 + li r10,(IVEC + 0x2) 253 231 FTR_SECTION_ELSE 254 - ori r12,r12,(IVEC) 232 + li r10,(IVEC) 255 233 ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) 256 234 .elseif IHSRR 257 - ori r12,r12,(IVEC+ 0x2) 235 + li r10,(IVEC + 0x2) 258 236 .else 259 - ori r12,r12,(IVEC) 237 + li r10,(IVEC) 260 238 .endif 261 - b kvmppc_interrupt 262 - .endm 263 - 264 - #else 265 - .macro KVMTEST name 266 - .endm 267 - .macro GEN_KVM name 268 - .endm 239 + bne \handler 269 240 #endif 241 + .endm 270 242 271 243 /* 272 244 * This is the BOOK3S interrupt entry code macro. ··· 379 409 DEFINE_FIXED_SYMBOL(\name\()_common_real) 380 410 \name\()_common_real: 381 411 .if IKVM_REAL 382 - KVMTEST \name 412 + KVMTEST \name kvm_interrupt 383 413 .endif 384 414 385 415 ld r10,PACAKMSR(r13) /* get MSR value for kernel */ ··· 402 432 DEFINE_FIXED_SYMBOL(\name\()_common_virt) 403 433 \name\()_common_virt: 404 434 .if IKVM_VIRT 405 - KVMTEST \name 435 + KVMTEST \name kvm_interrupt 406 436 1: 407 437 .endif 408 438 .endif /* IVIRT */ ··· 416 446 DEFINE_FIXED_SYMBOL(\name\()_common_real) 417 447 \name\()_common_real: 418 448 .if IKVM_REAL 419 - KVMTEST \name 449 + KVMTEST \name kvm_interrupt 420 450 .endif 421 451 .endm 422 452 ··· 918 948 EXCEPTION_RESTORE_REGS 919 949 RFI_TO_USER_OR_KERNEL 920 950 921 - GEN_KVM system_reset 922 - 923 951 924 952 /** 925 953 * Interrupt 0x200 - Machine Check Interrupt (MCE). ··· 1081 1113 /* 1082 1114 * Check if we are coming from guest. If yes, then run the normal 1083 1115 * exception handler which will take the 1084 - * machine_check_kvm->kvmppc_interrupt branch to deliver the MC event 1116 + * machine_check_kvm->kvm_interrupt branch to deliver the MC event 1085 1117 * to guest. 1086 1118 */ 1087 1119 lbz r11,HSTATE_IN_GUEST(r13) ··· 1150 1182 addi r3,r1,STACK_FRAME_OVERHEAD 1151 1183 bl machine_check_exception 1152 1184 b interrupt_return 1153 - 1154 - GEN_KVM machine_check 1155 1185 1156 1186 1157 1187 #ifdef CONFIG_PPC_P7_NAP ··· 1285 1319 REST_NVGPRS(r1) 1286 1320 b interrupt_return 1287 1321 1288 - GEN_KVM data_access 1289 - 1290 1322 1291 1323 /** 1292 1324 * Interrupt 0x380 - Data Segment Interrupt (DSLB). ··· 1334 1370 bl do_bad_slb_fault 1335 1371 b interrupt_return 1336 1372 1337 - GEN_KVM data_access_slb 1338 - 1339 1373 1340 1374 /** 1341 1375 * Interrupt 0x400 - Instruction Storage Interrupt (ISI). ··· 1369 1407 bl do_page_fault 1370 1408 ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) 1371 1409 b interrupt_return 1372 - 1373 - GEN_KVM instruction_access 1374 1410 1375 1411 1376 1412 /** ··· 1414 1454 bl do_bad_slb_fault 1415 1455 b interrupt_return 1416 1456 1417 - GEN_KVM instruction_access_slb 1418 - 1419 1457 1420 1458 /** 1421 1459 * Interrupt 0x500 - External Interrupt. ··· 1458 1500 bl do_IRQ 1459 1501 b interrupt_return 1460 1502 1461 - GEN_KVM hardware_interrupt 1462 - 1463 1503 1464 1504 /** 1465 1505 * Interrupt 0x600 - Alignment Interrupt ··· 1484 1528 bl alignment_exception 1485 1529 REST_NVGPRS(r1) /* instruction emulation may change GPRs */ 1486 1530 b interrupt_return 1487 - 1488 - GEN_KVM alignment 1489 1531 1490 1532 1491 1533 /** ··· 1592 1638 REST_NVGPRS(r1) /* instruction emulation may change GPRs */ 1593 1639 b interrupt_return 1594 1640 1595 - GEN_KVM program_check 1596 - 1597 1641 1598 1642 /* 1599 1643 * Interrupt 0x800 - Floating-Point Unavailable Interrupt. ··· 1641 1689 b interrupt_return 1642 1690 #endif 1643 1691 1644 - GEN_KVM fp_unavailable 1645 - 1646 1692 1647 1693 /** 1648 1694 * Interrupt 0x900 - Decrementer Interrupt. ··· 1678 1728 addi r3,r1,STACK_FRAME_OVERHEAD 1679 1729 bl timer_interrupt 1680 1730 b interrupt_return 1681 - 1682 - GEN_KVM decrementer 1683 1731 1684 1732 1685 1733 /** ··· 1724 1776 ld r13,PACA_EXGEN+EX_R13(r13) 1725 1777 HRFI_TO_KERNEL 1726 1778 1727 - GEN_KVM hdecrementer 1728 - 1729 1779 1730 1780 /** 1731 1781 * Interrupt 0xa00 - Directed Privileged Doorbell Interrupt. ··· 1762 1816 bl unknown_async_exception 1763 1817 #endif 1764 1818 b interrupt_return 1765 - 1766 - GEN_KVM doorbell_super 1767 1819 1768 1820 1769 1821 EXC_REAL_NONE(0xb00, 0x100) ··· 1812 1868 GET_PACA(r13) 1813 1869 std r10,PACA_EXGEN+EX_R10(r13) 1814 1870 INTERRUPT_TO_KERNEL 1815 - KVMTEST system_call /* uses r10, branch to system_call_kvm */ 1871 + KVMTEST system_call kvm_hcall /* uses r10, branch to kvm_hcall */ 1816 1872 mfctr r9 1817 1873 #else 1818 1874 mr r9,r13 ··· 1868 1924 EXC_VIRT_END(system_call, 0x4c00, 0x100) 1869 1925 1870 1926 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER 1871 - TRAMP_REAL_BEGIN(system_call_kvm) 1927 + TRAMP_REAL_BEGIN(kvm_hcall) 1872 1928 mfctr r10 1873 1929 SET_SCRATCH0(r10) /* Save r13 in SCRATCH0 */ 1874 1930 #ifdef CONFIG_RELOCATABLE ··· 1908 1964 bl single_step_exception 1909 1965 b interrupt_return 1910 1966 1911 - GEN_KVM single_step 1912 - 1913 1967 1914 1968 /** 1915 1969 * Interrupt 0xe00 - Hypervisor Data Storage Interrupt (HDSI). ··· 1946 2004 ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_TYPE_RADIX) 1947 2005 b interrupt_return 1948 2006 1949 - GEN_KVM h_data_storage 1950 - 1951 2007 1952 2008 /** 1953 2009 * Interrupt 0xe20 - Hypervisor Instruction Storage Interrupt (HISI). ··· 1971 2031 bl unknown_exception 1972 2032 b interrupt_return 1973 2033 1974 - GEN_KVM h_instr_storage 1975 - 1976 2034 1977 2035 /** 1978 2036 * Interrupt 0xe40 - Hypervisor Emulation Assistance Interrupt. ··· 1994 2056 bl emulation_assist_interrupt 1995 2057 REST_NVGPRS(r1) /* instruction emulation may change GPRs */ 1996 2058 b interrupt_return 1997 - 1998 - GEN_KVM emulation_assist 1999 2059 2000 2060 2001 2061 /** ··· 2066 2130 EXCEPTION_RESTORE_REGS hsrr=1 2067 2131 GEN_INT_ENTRY hmi_exception, virt=0 2068 2132 2069 - GEN_KVM hmi_exception_early 2070 - 2071 2133 EXC_COMMON_BEGIN(hmi_exception_common) 2072 2134 GEN_COMMON hmi_exception 2073 2135 addi r3,r1,STACK_FRAME_OVERHEAD 2074 2136 bl handle_hmi_exception 2075 2137 b interrupt_return 2076 - 2077 - GEN_KVM hmi_exception 2078 2138 2079 2139 2080 2140 /** ··· 2102 2170 #endif 2103 2171 b interrupt_return 2104 2172 2105 - GEN_KVM h_doorbell 2106 - 2107 2173 2108 2174 /** 2109 2175 * Interrupt 0xea0 - Hypervisor Virtualization Interrupt. ··· 2127 2197 addi r3,r1,STACK_FRAME_OVERHEAD 2128 2198 bl do_IRQ 2129 2199 b interrupt_return 2130 - 2131 - GEN_KVM h_virt_irq 2132 2200 2133 2201 2134 2202 EXC_REAL_NONE(0xec0, 0x20) ··· 2170 2242 addi r3,r1,STACK_FRAME_OVERHEAD 2171 2243 bl performance_monitor_exception 2172 2244 b interrupt_return 2173 - 2174 - GEN_KVM performance_monitor 2175 2245 2176 2246 2177 2247 /** ··· 2220 2294 bl altivec_unavailable_exception 2221 2295 b interrupt_return 2222 2296 2223 - GEN_KVM altivec_unavailable 2224 - 2225 2297 2226 2298 /** 2227 2299 * Interrupt 0xf40 - VSX Unavailable Interrupt. ··· 2268 2344 bl vsx_unavailable_exception 2269 2345 b interrupt_return 2270 2346 2271 - GEN_KVM vsx_unavailable 2272 - 2273 2347 2274 2348 /** 2275 2349 * Interrupt 0xf60 - Facility Unavailable Interrupt. ··· 2295 2373 bl facility_unavailable_exception 2296 2374 REST_NVGPRS(r1) /* instruction emulation may change GPRs */ 2297 2375 b interrupt_return 2298 - 2299 - GEN_KVM facility_unavailable 2300 2376 2301 2377 2302 2378 /** ··· 2324 2404 REST_NVGPRS(r1) /* XXX Shouldn't be necessary in practice */ 2325 2405 b interrupt_return 2326 2406 2327 - GEN_KVM h_facility_unavailable 2328 - 2329 2407 2330 2408 EXC_REAL_NONE(0xfa0, 0x20) 2331 2409 EXC_VIRT_NONE(0x4fa0, 0x20) ··· 2352 2434 addi r3,r1,STACK_FRAME_OVERHEAD 2353 2435 bl cbe_system_error_exception 2354 2436 b interrupt_return 2355 - 2356 - GEN_KVM cbe_system_error 2357 2437 2358 2438 #else /* CONFIG_CBE_RAS */ 2359 2439 EXC_REAL_NONE(0x1200, 0x100) ··· 2383 2467 addi r3,r1,STACK_FRAME_OVERHEAD 2384 2468 bl instruction_breakpoint_exception 2385 2469 b interrupt_return 2386 - 2387 - GEN_KVM instruction_breakpoint 2388 2470 2389 2471 2390 2472 EXC_REAL_NONE(0x1400, 0x100) ··· 2504 2590 bl unknown_exception 2505 2591 b interrupt_return 2506 2592 2507 - GEN_KVM denorm_exception 2508 - 2509 2593 2510 2594 #ifdef CONFIG_CBE_RAS 2511 2595 INT_DEFINE_BEGIN(cbe_maintenance) ··· 2520 2608 addi r3,r1,STACK_FRAME_OVERHEAD 2521 2609 bl cbe_maintenance_exception 2522 2610 b interrupt_return 2523 - 2524 - GEN_KVM cbe_maintenance 2525 2611 2526 2612 #else /* CONFIG_CBE_RAS */ 2527 2613 EXC_REAL_NONE(0x1600, 0x100) ··· 2551 2641 #endif 2552 2642 b interrupt_return 2553 2643 2554 - GEN_KVM altivec_assist 2555 - 2556 2644 2557 2645 #ifdef CONFIG_CBE_RAS 2558 2646 INT_DEFINE_BEGIN(cbe_thermal) ··· 2567 2659 addi r3,r1,STACK_FRAME_OVERHEAD 2568 2660 bl cbe_thermal_exception 2569 2661 b interrupt_return 2570 - 2571 - GEN_KVM cbe_thermal 2572 2662 2573 2663 #else /* CONFIG_CBE_RAS */ 2574 2664 EXC_REAL_NONE(0x1800, 0x100) ··· 2819 2913 RFSCV 2820 2914 2821 2915 USE_TEXT_SECTION() 2916 + 2917 + #ifdef CONFIG_KVM_BOOK3S_64_HANDLER 2918 + kvm_interrupt: 2919 + /* 2920 + * The conditional branch in KVMTEST can't reach all the way, 2921 + * make a stub. 2922 + */ 2923 + b kvmppc_interrupt 2924 + #endif 2822 2925 2823 2926 _GLOBAL(do_uaccess_flush) 2824 2927 UACCESS_FLUSH_FIXUP_SECTION
+48 -2
arch/powerpc/kvm/book3s_64_entry.S
··· 44 44 sldi r12,r10,32 45 45 ori r12,r12,0xc00 46 46 ld r10,PACA_EXGEN+EX_R10(r13) 47 + b do_kvm_interrupt 47 48 49 + /* 50 + * KVM interrupt entry occurs after GEN_INT_ENTRY runs, and follows that 51 + * call convention: 52 + * 53 + * guest R9-R13, CTR, CFAR, PPR saved in PACA EX_xxx save area 54 + * guest (H)DAR, (H)DSISR are also in the save area for relevant interrupts 55 + * guest R13 also saved in SCRATCH0 56 + * R13 = PACA 57 + * R11 = (H)SRR0 58 + * R12 = (H)SRR1 59 + * R9 = guest CR 60 + * PPR is set to medium 61 + * 62 + * With the addition for KVM: 63 + * R10 = trap vector 64 + */ 48 65 .global kvmppc_interrupt 49 66 .balign IFETCH_ALIGN_BYTES 50 67 kvmppc_interrupt: 68 + li r11,PACA_EXGEN 69 + cmpdi r10,0x200 70 + bgt+ 1f 71 + li r11,PACA_EXMC 72 + beq 1f 73 + li r11,PACA_EXNMI 74 + 1: add r11,r11,r13 75 + 76 + BEGIN_FTR_SECTION 77 + ld r12,EX_CFAR(r11) 78 + std r12,HSTATE_CFAR(r13) 79 + END_FTR_SECTION_IFSET(CPU_FTR_CFAR) 80 + ld r12,EX_CTR(r11) 81 + mtctr r12 82 + BEGIN_FTR_SECTION 83 + ld r12,EX_PPR(r11) 84 + std r12,HSTATE_PPR(r13) 85 + END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) 86 + ld r12,EX_R12(r11) 87 + std r12,HSTATE_SCRATCH0(r13) 88 + sldi r12,r9,32 89 + or r12,r12,r10 90 + ld r9,EX_R9(r11) 91 + ld r10,EX_R10(r11) 92 + ld r11,EX_R11(r11) 93 + 94 + do_kvm_interrupt: 51 95 /* 52 - * Register contents: 96 + * Hcalls and other interrupts come here after normalising register 97 + * contents and save locations: 98 + * 53 99 * R12 = (guest CR << 32) | interrupt vector 54 100 * R13 = PACA 55 - * guest R12 saved in shadow VCPU SCRATCH0 101 + * guest R12 saved in shadow HSTATE_SCRATCH0 56 102 * guest R13 saved in SPRN_SCRATCH0 57 103 */ 58 104 std r9,HSTATE_SCRATCH2(r13)