Merge tag 'x86_urgent_for_v6.16_rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Borislav Petkov:

- Make sure DR6 and DR7 are initialized to their architectural values
and not accidentally cleared, leading to misconfigurations

* tag 'x86_urgent_for_v6.16_rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/traps: Initialize DR7 by writing its architectural reset value
x86/traps: Initialize DR6 by writing its architectural reset value

Changed files
+72 -38
arch
+15 -4
arch/x86/include/asm/debugreg.h
··· 9 9 #include <asm/cpufeature.h> 10 10 #include <asm/msr.h> 11 11 12 + /* 13 + * Define bits that are always set to 1 in DR7, only bit 10 is 14 + * architecturally reserved to '1'. 15 + * 16 + * This is also the init/reset value for DR7. 17 + */ 18 + #define DR7_FIXED_1 0x00000400 19 + 12 20 DECLARE_PER_CPU(unsigned long, cpu_dr7); 13 21 14 22 #ifndef CONFIG_PARAVIRT_XXL ··· 108 100 109 101 static inline void hw_breakpoint_disable(void) 110 102 { 111 - /* Zero the control register for HW Breakpoint */ 112 - set_debugreg(0UL, 7); 103 + /* Reset the control register for HW Breakpoint */ 104 + set_debugreg(DR7_FIXED_1, 7); 113 105 114 106 /* Zero-out the individual HW breakpoint address registers */ 115 107 set_debugreg(0UL, 0); ··· 133 125 return 0; 134 126 135 127 get_debugreg(dr7, 7); 136 - dr7 &= ~0x400; /* architecturally set bit */ 128 + 129 + /* Architecturally set bit */ 130 + dr7 &= ~DR7_FIXED_1; 137 131 if (dr7) 138 - set_debugreg(0, 7); 132 + set_debugreg(DR7_FIXED_1, 7); 133 + 139 134 /* 140 135 * Ensure the compiler doesn't lower the above statements into 141 136 * the critical section; disabling breakpoints late would not
+1 -1
arch/x86/include/asm/kvm_host.h
··· 31 31 32 32 #include <asm/apic.h> 33 33 #include <asm/pvclock-abi.h> 34 + #include <asm/debugreg.h> 34 35 #include <asm/desc.h> 35 36 #include <asm/mtrr.h> 36 37 #include <asm/msr-index.h> ··· 250 249 #define DR7_BP_EN_MASK 0x000000ff 251 250 #define DR7_GE (1 << 9) 252 251 #define DR7_GD (1 << 13) 253 - #define DR7_FIXED_1 0x00000400 254 252 #define DR7_VOLATILE 0xffff2bff 255 253 256 254 #define KVM_GUESTDBG_VALID_MASK \
+20 -1
arch/x86/include/uapi/asm/debugreg.h
··· 15 15 which debugging register was responsible for the trap. The other bits 16 16 are either reserved or not of interest to us. */ 17 17 18 - /* Define reserved bits in DR6 which are always set to 1 */ 18 + /* 19 + * Define bits in DR6 which are set to 1 by default. 20 + * 21 + * This is also the DR6 architectural value following Power-up, Reset or INIT. 22 + * 23 + * Note, with the introduction of Bus Lock Detection (BLD) and Restricted 24 + * Transactional Memory (RTM), the DR6 register has been modified: 25 + * 26 + * 1) BLD flag (bit 11) is no longer reserved to 1 if the CPU supports 27 + * Bus Lock Detection. The assertion of a bus lock could clear it. 28 + * 29 + * 2) RTM flag (bit 16) is no longer reserved to 1 if the CPU supports 30 + * restricted transactional memory. #DB occurred inside an RTM region 31 + * could clear it. 32 + * 33 + * Apparently, DR6.BLD and DR6.RTM are active low bits. 34 + * 35 + * As a result, DR6_RESERVED is an incorrect name now, but it is kept for 36 + * compatibility. 37 + */ 19 38 #define DR6_RESERVED (0xFFFF0FF0) 20 39 21 40 #define DR_TRAP0 (0x1) /* db0 */
+10 -14
arch/x86/kernel/cpu/common.c
··· 2243 2243 #endif 2244 2244 #endif 2245 2245 2246 - /* 2247 - * Clear all 6 debug registers: 2248 - */ 2249 - static void clear_all_debug_regs(void) 2246 + static void initialize_debug_regs(void) 2250 2247 { 2251 - int i; 2252 - 2253 - for (i = 0; i < 8; i++) { 2254 - /* Ignore db4, db5 */ 2255 - if ((i == 4) || (i == 5)) 2256 - continue; 2257 - 2258 - set_debugreg(0, i); 2259 - } 2248 + /* Control register first -- to make sure everything is disabled. */ 2249 + set_debugreg(DR7_FIXED_1, 7); 2250 + set_debugreg(DR6_RESERVED, 6); 2251 + /* dr5 and dr4 don't exist */ 2252 + set_debugreg(0, 3); 2253 + set_debugreg(0, 2); 2254 + set_debugreg(0, 1); 2255 + set_debugreg(0, 0); 2260 2256 } 2261 2257 2262 2258 #ifdef CONFIG_KGDB ··· 2413 2417 2414 2418 load_mm_ldt(&init_mm); 2415 2419 2416 - clear_all_debug_regs(); 2420 + initialize_debug_regs(); 2417 2421 dbg_restore_debug_regs(); 2418 2422 2419 2423 doublefault_init_cpu_tss();
+1 -1
arch/x86/kernel/kgdb.c
··· 385 385 struct perf_event *bp; 386 386 387 387 /* Disable hardware debugging while we are in kgdb: */ 388 - set_debugreg(0UL, 7); 388 + set_debugreg(DR7_FIXED_1, 7); 389 389 for (i = 0; i < HBP_NUM; i++) { 390 390 if (!breakinfo[i].enabled) 391 391 continue;
+1 -1
arch/x86/kernel/process_32.c
··· 93 93 94 94 /* Only print out debug registers if they are in their non-default state. */ 95 95 if ((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) && 96 - (d6 == DR6_RESERVED) && (d7 == 0x400)) 96 + (d6 == DR6_RESERVED) && (d7 == DR7_FIXED_1)) 97 97 return; 98 98 99 99 printk("%sDR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
+1 -1
arch/x86/kernel/process_64.c
··· 133 133 134 134 /* Only print out debug registers if they are in their non-default state. */ 135 135 if (!((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) && 136 - (d6 == DR6_RESERVED) && (d7 == 0x400))) { 136 + (d6 == DR6_RESERVED) && (d7 == DR7_FIXED_1))) { 137 137 printk("%sDR0: %016lx DR1: %016lx DR2: %016lx\n", 138 138 log_lvl, d0, d1, d2); 139 139 printk("%sDR3: %016lx DR6: %016lx DR7: %016lx\n",
+21 -13
arch/x86/kernel/traps.c
··· 1022 1022 #endif 1023 1023 } 1024 1024 1025 - static __always_inline unsigned long debug_read_clear_dr6(void) 1025 + static __always_inline unsigned long debug_read_reset_dr6(void) 1026 1026 { 1027 1027 unsigned long dr6; 1028 + 1029 + get_debugreg(dr6, 6); 1030 + dr6 ^= DR6_RESERVED; /* Flip to positive polarity */ 1028 1031 1029 1032 /* 1030 1033 * The Intel SDM says: 1031 1034 * 1032 - * Certain debug exceptions may clear bits 0-3. The remaining 1033 - * contents of the DR6 register are never cleared by the 1034 - * processor. To avoid confusion in identifying debug 1035 - * exceptions, debug handlers should clear the register before 1036 - * returning to the interrupted task. 1035 + * Certain debug exceptions may clear bits 0-3 of DR6. 1037 1036 * 1038 - * Keep it simple: clear DR6 immediately. 1037 + * BLD induced #DB clears DR6.BLD and any other debug 1038 + * exception doesn't modify DR6.BLD. 1039 + * 1040 + * RTM induced #DB clears DR6.RTM and any other debug 1041 + * exception sets DR6.RTM. 1042 + * 1043 + * To avoid confusion in identifying debug exceptions, 1044 + * debug handlers should set DR6.BLD and DR6.RTM, and 1045 + * clear other DR6 bits before returning. 1046 + * 1047 + * Keep it simple: write DR6 with its architectural reset 1048 + * value 0xFFFF0FF0, defined as DR6_RESERVED, immediately. 1039 1049 */ 1040 - get_debugreg(dr6, 6); 1041 1050 set_debugreg(DR6_RESERVED, 6); 1042 - dr6 ^= DR6_RESERVED; /* Flip to positive polarity */ 1043 1051 1044 1052 return dr6; 1045 1053 } ··· 1247 1239 /* IST stack entry */ 1248 1240 DEFINE_IDTENTRY_DEBUG(exc_debug) 1249 1241 { 1250 - exc_debug_kernel(regs, debug_read_clear_dr6()); 1242 + exc_debug_kernel(regs, debug_read_reset_dr6()); 1251 1243 } 1252 1244 1253 1245 /* User entry, runs on regular task stack */ 1254 1246 DEFINE_IDTENTRY_DEBUG_USER(exc_debug) 1255 1247 { 1256 - exc_debug_user(regs, debug_read_clear_dr6()); 1248 + exc_debug_user(regs, debug_read_reset_dr6()); 1257 1249 } 1258 1250 1259 1251 #ifdef CONFIG_X86_FRED ··· 1272 1264 { 1273 1265 /* 1274 1266 * FRED #DB stores DR6 on the stack in the format which 1275 - * debug_read_clear_dr6() returns for the IDT entry points. 1267 + * debug_read_reset_dr6() returns for the IDT entry points. 1276 1268 */ 1277 1269 unsigned long dr6 = fred_event_data(regs); 1278 1270 ··· 1287 1279 /* 32 bit does not have separate entry points. */ 1288 1280 DEFINE_IDTENTRY_RAW(exc_debug) 1289 1281 { 1290 - unsigned long dr6 = debug_read_clear_dr6(); 1282 + unsigned long dr6 = debug_read_reset_dr6(); 1291 1283 1292 1284 if (user_mode(regs)) 1293 1285 exc_debug_user(regs, dr6);
+2 -2
arch/x86/kvm/x86.c
··· 11035 11035 11036 11036 if (unlikely(vcpu->arch.switch_db_regs && 11037 11037 !(vcpu->arch.switch_db_regs & KVM_DEBUGREG_AUTO_SWITCH))) { 11038 - set_debugreg(0, 7); 11038 + set_debugreg(DR7_FIXED_1, 7); 11039 11039 set_debugreg(vcpu->arch.eff_db[0], 0); 11040 11040 set_debugreg(vcpu->arch.eff_db[1], 1); 11041 11041 set_debugreg(vcpu->arch.eff_db[2], 2); ··· 11044 11044 if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) 11045 11045 kvm_x86_call(set_dr6)(vcpu, vcpu->arch.dr6); 11046 11046 } else if (unlikely(hw_breakpoint_active())) { 11047 - set_debugreg(0, 7); 11047 + set_debugreg(DR7_FIXED_1, 7); 11048 11048 } 11049 11049 11050 11050 vcpu->arch.host_debugctl = get_debugctlmsr();