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 tag 'loongarch-fixes-6.8-3' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson

Pull LoongArch fixes from Huacai Chen:
"Fix two cpu-hotplug issues, fix the init sequence about FDT system,
fix the coding style of dts, and fix the wrong CPUCFG ID handling of
KVM"

* tag 'loongarch-fixes-6.8-3' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
LoongArch: KVM: Streamline kvm_check_cpucfg() and improve comments
LoongArch: KVM: Rename _kvm_get_cpucfg() to _kvm_get_cpucfg_mask()
LoongArch: KVM: Fix input validation of _kvm_get_cpucfg() & kvm_check_cpucfg()
LoongArch: dts: Minor whitespace cleanup
LoongArch: Call early_init_fdt_scan_reserved_mem() earlier
LoongArch: Update cpu_sibling_map when disabling nonboot CPUs
LoongArch: Disable IRQ before init_fn() for nonboot CPUs

+113 -98
+1 -1
arch/loongarch/boot/dts/loongson-2k0500-ref.dts
··· 60 60 61 61 #address-cells = <1>; 62 62 #size-cells = <0>; 63 - eeprom@57{ 63 + eeprom@57 { 64 64 compatible = "atmel,24c16"; 65 65 reg = <0x57>; 66 66 pagesize = <16>;
+1 -1
arch/loongarch/boot/dts/loongson-2k1000-ref.dts
··· 78 78 79 79 #address-cells = <1>; 80 80 #size-cells = <0>; 81 - eeprom@57{ 81 + eeprom@57 { 82 82 compatible = "atmel,24c16"; 83 83 reg = <0x57>; 84 84 pagesize = <16>;
+2 -2
arch/loongarch/kernel/setup.c
··· 357 357 acpi_gbl_use_default_register_widths = false; 358 358 acpi_boot_table_init(); 359 359 #endif 360 + 361 + early_init_fdt_scan_reserved_mem(); 360 362 unflatten_and_copy_device_tree(); 361 363 362 364 #ifdef CONFIG_NUMA ··· 391 389 pr_info("User-defined physical RAM map overwrite\n"); 392 390 393 391 check_kernel_sections_mem(); 394 - 395 - early_init_fdt_scan_reserved_mem(); 396 392 397 393 /* 398 394 * In order to reduce the possibility of kernel panic when failed to
+69 -53
arch/loongarch/kernel/smp.c
··· 88 88 } 89 89 } 90 90 91 + static inline void set_cpu_core_map(int cpu) 92 + { 93 + int i; 94 + 95 + cpumask_set_cpu(cpu, &cpu_core_setup_map); 96 + 97 + for_each_cpu(i, &cpu_core_setup_map) { 98 + if (cpu_data[cpu].package == cpu_data[i].package) { 99 + cpumask_set_cpu(i, &cpu_core_map[cpu]); 100 + cpumask_set_cpu(cpu, &cpu_core_map[i]); 101 + } 102 + } 103 + } 104 + 105 + static inline void set_cpu_sibling_map(int cpu) 106 + { 107 + int i; 108 + 109 + cpumask_set_cpu(cpu, &cpu_sibling_setup_map); 110 + 111 + for_each_cpu(i, &cpu_sibling_setup_map) { 112 + if (cpus_are_siblings(cpu, i)) { 113 + cpumask_set_cpu(i, &cpu_sibling_map[cpu]); 114 + cpumask_set_cpu(cpu, &cpu_sibling_map[i]); 115 + } 116 + } 117 + } 118 + 119 + static inline void clear_cpu_sibling_map(int cpu) 120 + { 121 + int i; 122 + 123 + for_each_cpu(i, &cpu_sibling_setup_map) { 124 + if (cpus_are_siblings(cpu, i)) { 125 + cpumask_clear_cpu(i, &cpu_sibling_map[cpu]); 126 + cpumask_clear_cpu(cpu, &cpu_sibling_map[i]); 127 + } 128 + } 129 + 130 + cpumask_clear_cpu(cpu, &cpu_sibling_setup_map); 131 + } 132 + 133 + /* 134 + * Calculate a new cpu_foreign_map mask whenever a 135 + * new cpu appears or disappears. 136 + */ 137 + void calculate_cpu_foreign_map(void) 138 + { 139 + int i, k, core_present; 140 + cpumask_t temp_foreign_map; 141 + 142 + /* Re-calculate the mask */ 143 + cpumask_clear(&temp_foreign_map); 144 + for_each_online_cpu(i) { 145 + core_present = 0; 146 + for_each_cpu(k, &temp_foreign_map) 147 + if (cpus_are_siblings(i, k)) 148 + core_present = 1; 149 + if (!core_present) 150 + cpumask_set_cpu(i, &temp_foreign_map); 151 + } 152 + 153 + for_each_online_cpu(i) 154 + cpumask_andnot(&cpu_foreign_map[i], 155 + &temp_foreign_map, &cpu_sibling_map[i]); 156 + } 157 + 91 158 /* Send mailbox buffer via Mail_Send */ 92 159 static void csr_mail_send(uint64_t data, int cpu, int mailbox) 93 160 { ··· 370 303 numa_remove_cpu(cpu); 371 304 #endif 372 305 set_cpu_online(cpu, false); 306 + clear_cpu_sibling_map(cpu); 373 307 calculate_cpu_foreign_map(); 374 308 local_irq_save(flags); 375 309 irq_migrate_all_off_this_cpu(); ··· 405 337 addr = iocsr_read64(LOONGARCH_IOCSR_MBUF0); 406 338 } while (addr == 0); 407 339 340 + local_irq_disable(); 408 341 init_fn = (void *)TO_CACHE(addr); 409 342 iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_CLEAR); 410 343 ··· 447 378 448 379 core_initcall(ipi_pm_init); 449 380 #endif 450 - 451 - static inline void set_cpu_sibling_map(int cpu) 452 - { 453 - int i; 454 - 455 - cpumask_set_cpu(cpu, &cpu_sibling_setup_map); 456 - 457 - for_each_cpu(i, &cpu_sibling_setup_map) { 458 - if (cpus_are_siblings(cpu, i)) { 459 - cpumask_set_cpu(i, &cpu_sibling_map[cpu]); 460 - cpumask_set_cpu(cpu, &cpu_sibling_map[i]); 461 - } 462 - } 463 - } 464 - 465 - static inline void set_cpu_core_map(int cpu) 466 - { 467 - int i; 468 - 469 - cpumask_set_cpu(cpu, &cpu_core_setup_map); 470 - 471 - for_each_cpu(i, &cpu_core_setup_map) { 472 - if (cpu_data[cpu].package == cpu_data[i].package) { 473 - cpumask_set_cpu(i, &cpu_core_map[cpu]); 474 - cpumask_set_cpu(cpu, &cpu_core_map[i]); 475 - } 476 - } 477 - } 478 - 479 - /* 480 - * Calculate a new cpu_foreign_map mask whenever a 481 - * new cpu appears or disappears. 482 - */ 483 - void calculate_cpu_foreign_map(void) 484 - { 485 - int i, k, core_present; 486 - cpumask_t temp_foreign_map; 487 - 488 - /* Re-calculate the mask */ 489 - cpumask_clear(&temp_foreign_map); 490 - for_each_online_cpu(i) { 491 - core_present = 0; 492 - for_each_cpu(k, &temp_foreign_map) 493 - if (cpus_are_siblings(i, k)) 494 - core_present = 1; 495 - if (!core_present) 496 - cpumask_set_cpu(i, &temp_foreign_map); 497 - } 498 - 499 - for_each_online_cpu(i) 500 - cpumask_andnot(&cpu_foreign_map[i], 501 - &temp_foreign_map, &cpu_sibling_map[i]); 502 - } 503 381 504 382 /* Preload SMP state for boot cpu */ 505 383 void smp_prepare_boot_cpu(void)
+40 -41
arch/loongarch/kvm/vcpu.c
··· 298 298 return ret; 299 299 } 300 300 301 - static int _kvm_get_cpucfg(int id, u64 *v) 301 + static int _kvm_get_cpucfg_mask(int id, u64 *v) 302 302 { 303 - int ret = 0; 304 - 305 - if (id < 0 && id >= KVM_MAX_CPUCFG_REGS) 303 + if (id < 0 || id >= KVM_MAX_CPUCFG_REGS) 306 304 return -EINVAL; 307 305 308 306 switch (id) { 309 307 case 2: 310 - /* Return CPUCFG2 features which have been supported by KVM */ 308 + /* CPUCFG2 features unconditionally supported by KVM */ 311 309 *v = CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP | 312 310 CPUCFG2_FPVERS | CPUCFG2_LLFTP | CPUCFG2_LLFTPREV | 313 311 CPUCFG2_LAM; 314 312 /* 315 - * If LSX is supported by CPU, it is also supported by KVM, 316 - * as we implement it. 313 + * For the ISA extensions listed below, if one is supported 314 + * by the host, then it is also supported by KVM. 317 315 */ 318 316 if (cpu_has_lsx) 319 317 *v |= CPUCFG2_LSX; 320 - /* 321 - * if LASX is supported by CPU, it is also supported by KVM, 322 - * as we implement it. 323 - */ 324 318 if (cpu_has_lasx) 325 319 *v |= CPUCFG2_LASX; 326 320 327 - break; 321 + return 0; 328 322 default: 329 - ret = -EINVAL; 330 - break; 323 + /* 324 + * No restrictions on other valid CPUCFG IDs' values, but 325 + * CPUCFG data is limited to 32 bits as the LoongArch ISA 326 + * manual says (Volume 1, Section 2.2.10.5 "CPUCFG"). 327 + */ 328 + *v = U32_MAX; 329 + return 0; 331 330 } 332 - return ret; 333 331 } 334 332 335 333 static int kvm_check_cpucfg(int id, u64 val) 336 334 { 337 - u64 mask; 338 - int ret = 0; 335 + int ret; 336 + u64 mask = 0; 339 337 340 - if (id < 0 && id >= KVM_MAX_CPUCFG_REGS) 341 - return -EINVAL; 342 - 343 - if (_kvm_get_cpucfg(id, &mask)) 338 + ret = _kvm_get_cpucfg_mask(id, &mask); 339 + if (ret) 344 340 return ret; 341 + 342 + if (val & ~mask) 343 + /* Unsupported features and/or the higher 32 bits should not be set */ 344 + return -EINVAL; 345 345 346 346 switch (id) { 347 347 case 2: 348 - /* CPUCFG2 features checking */ 349 - if (val & ~mask) 350 - /* The unsupported features should not be set */ 351 - ret = -EINVAL; 352 - else if (!(val & CPUCFG2_LLFTP)) 353 - /* The LLFTP must be set, as guest must has a constant timer */ 354 - ret = -EINVAL; 355 - else if ((val & CPUCFG2_FP) && (!(val & CPUCFG2_FPSP) || !(val & CPUCFG2_FPDP))) 356 - /* Single and double float point must both be set when enable FP */ 357 - ret = -EINVAL; 358 - else if ((val & CPUCFG2_LSX) && !(val & CPUCFG2_FP)) 359 - /* FP should be set when enable LSX */ 360 - ret = -EINVAL; 361 - else if ((val & CPUCFG2_LASX) && !(val & CPUCFG2_LSX)) 362 - /* LSX, FP should be set when enable LASX, and FP has been checked before. */ 363 - ret = -EINVAL; 364 - break; 348 + if (!(val & CPUCFG2_LLFTP)) 349 + /* Guests must have a constant timer */ 350 + return -EINVAL; 351 + if ((val & CPUCFG2_FP) && (!(val & CPUCFG2_FPSP) || !(val & CPUCFG2_FPDP))) 352 + /* Single and double float point must both be set when FP is enabled */ 353 + return -EINVAL; 354 + if ((val & CPUCFG2_LSX) && !(val & CPUCFG2_FP)) 355 + /* LSX architecturally implies FP but val does not satisfy that */ 356 + return -EINVAL; 357 + if ((val & CPUCFG2_LASX) && !(val & CPUCFG2_LSX)) 358 + /* LASX architecturally implies LSX and FP but val does not satisfy that */ 359 + return -EINVAL; 360 + return 0; 365 361 default: 366 - break; 362 + /* 363 + * Values for the other CPUCFG IDs are not being further validated 364 + * besides the mask check above. 365 + */ 366 + return 0; 367 367 } 368 - return ret; 369 368 } 370 369 371 370 static int kvm_get_one_reg(struct kvm_vcpu *vcpu, ··· 565 566 uint64_t val; 566 567 uint64_t __user *uaddr = (uint64_t __user *)attr->addr; 567 568 568 - ret = _kvm_get_cpucfg(attr->attr, &val); 569 + ret = _kvm_get_cpucfg_mask(attr->attr, &val); 569 570 if (ret) 570 571 return ret; 571 572