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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch kvm-arm64/dump-instr into kvmarm-master/next

* kvm-arm64/dump-instr:
: .
: Dump the isntruction stream on panic, just like the rest of the kernel
: already does.
:
: Patches courtesy of Mostafa Saleh (20250909133631.3844423-1-smostafa@google.com)
: .
KVM: arm64: Map hyp text as RO and dump instr on panic
KVM: arm64: Dump instruction on hyp panic

Signed-off-by: Marc Zyngier <maz@kernel.org>

+23 -8
+1
arch/arm64/include/asm/traps.h
··· 36 36 int ubsan_brk_handler(struct pt_regs *regs, unsigned long esr); 37 37 38 38 int early_brk64(unsigned long addr, unsigned long esr, struct pt_regs *regs); 39 + void dump_kernel_instr(unsigned long kaddr); 39 40 40 41 /* 41 42 * Move regs->pc to next instruction and do necessary setup before it
+9 -6
arch/arm64/kernel/traps.c
··· 149 149 150 150 int show_unhandled_signals = 0; 151 151 152 - static void dump_kernel_instr(const char *lvl, struct pt_regs *regs) 152 + void dump_kernel_instr(unsigned long kaddr) 153 153 { 154 - unsigned long addr = instruction_pointer(regs); 155 154 char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str; 156 155 int i; 157 156 158 - if (user_mode(regs)) 157 + if (!is_ttbr1_addr(kaddr)) 159 158 return; 160 159 161 160 for (i = -4; i < 1; i++) { 162 161 unsigned int val, bad; 163 162 164 - bad = aarch64_insn_read(&((u32 *)addr)[i], &val); 163 + bad = aarch64_insn_read(&((u32 *)kaddr)[i], &val); 165 164 166 165 if (!bad) 167 166 p += sprintf(p, i == 0 ? "(%08x) " : "%08x ", val); ··· 168 169 p += sprintf(p, i == 0 ? "(????????) " : "???????? "); 169 170 } 170 171 171 - printk("%sCode: %s\n", lvl, str); 172 + printk(KERN_EMERG "Code: %s\n", str); 172 173 } 173 174 174 175 #define S_SMP " SMP" ··· 177 178 { 178 179 static int die_counter; 179 180 int ret; 181 + unsigned long addr = instruction_pointer(regs); 180 182 181 183 pr_emerg("Internal error: %s: %016lx [#%d] " S_SMP "\n", 182 184 str, err, ++die_counter); ··· 190 190 print_modules(); 191 191 show_regs(regs); 192 192 193 - dump_kernel_instr(KERN_EMERG, regs); 193 + if (user_mode(regs)) 194 + return ret; 195 + 196 + dump_kernel_instr(addr); 194 197 195 198 return ret; 196 199 }
+3
arch/arm64/kvm/handle_exit.c
··· 559 559 /* Dump the nVHE hypervisor backtrace */ 560 560 kvm_nvhe_dump_backtrace(hyp_offset); 561 561 562 + /* Dump the faulting instruction */ 563 + dump_kernel_instr(panic_addr + kaslr_offset()); 564 + 562 565 /* 563 566 * Hyp has panicked and we're going to handle that by panicking the 564 567 * kernel. The kernel offset will be revealed in the panic so we're
+10 -2
arch/arm64/kvm/hyp/nvhe/setup.c
··· 192 192 enum pkvm_page_state state; 193 193 struct hyp_page *page; 194 194 phys_addr_t phys; 195 + enum kvm_pgtable_prot prot; 195 196 196 197 if (!kvm_pte_valid(ctx->old)) 197 198 return 0; ··· 211 210 * configured in the hypervisor stage-1, and make sure to propagate them 212 211 * to the hyp_vmemmap state. 213 212 */ 214 - state = pkvm_getstate(kvm_pgtable_hyp_pte_prot(ctx->old)); 213 + prot = kvm_pgtable_hyp_pte_prot(ctx->old); 214 + state = pkvm_getstate(prot); 215 215 switch (state) { 216 216 case PKVM_PAGE_OWNED: 217 217 set_hyp_state(page, PKVM_PAGE_OWNED); 218 - return host_stage2_set_owner_locked(phys, PAGE_SIZE, PKVM_ID_HYP); 218 + /* hyp text is RO in the host stage-2 to be inspected on panic. */ 219 + if (prot == PAGE_HYP_EXEC) { 220 + set_host_state(page, PKVM_NOPAGE); 221 + return host_stage2_idmap_locked(phys, PAGE_SIZE, KVM_PGTABLE_PROT_R); 222 + } else { 223 + return host_stage2_set_owner_locked(phys, PAGE_SIZE, PKVM_ID_HYP); 224 + } 219 225 case PKVM_PAGE_SHARED_OWNED: 220 226 set_hyp_state(page, PKVM_PAGE_SHARED_OWNED); 221 227 set_host_state(page, PKVM_PAGE_SHARED_BORROWED);