Skip to content

Commit c6a597f

Browse files
committed
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
2 parents 603c04e + f0f5c48 commit c6a597f

File tree

5 files changed

+113
-98
lines changed

5 files changed

+113
-98
lines changed

arch/loongarch/boot/dts/loongson-2k0500-ref.dts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060

6161
#address-cells = <1>;
6262
#size-cells = <0>;
63-
eeprom@57{
63+
eeprom@57 {
6464
compatible = "atmel,24c16";
6565
reg = <0x57>;
6666
pagesize = <16>;

arch/loongarch/boot/dts/loongson-2k1000-ref.dts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878

7979
#address-cells = <1>;
8080
#size-cells = <0>;
81-
eeprom@57{
81+
eeprom@57 {
8282
compatible = "atmel,24c16";
8383
reg = <0x57>;
8484
pagesize = <16>;

arch/loongarch/kernel/setup.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,8 @@ void __init platform_init(void)
357357
acpi_gbl_use_default_register_widths = false;
358358
acpi_boot_table_init();
359359
#endif
360+
361+
early_init_fdt_scan_reserved_mem();
360362
unflatten_and_copy_device_tree();
361363

362364
#ifdef CONFIG_NUMA
@@ -390,8 +392,6 @@ static void __init arch_mem_init(char **cmdline_p)
390392

391393
check_kernel_sections_mem();
392394

393-
early_init_fdt_scan_reserved_mem();
394-
395395
/*
396396
* In order to reduce the possibility of kernel panic when failed to
397397
* get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate

arch/loongarch/kernel/smp.c

Lines changed: 69 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,73 @@ void show_ipi_list(struct seq_file *p, int prec)
8888
}
8989
}
9090

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+
91158
/* Send mailbox buffer via Mail_Send */
92159
static void csr_mail_send(uint64_t data, int cpu, int mailbox)
93160
{
@@ -303,6 +370,7 @@ int loongson_cpu_disable(void)
303370
numa_remove_cpu(cpu);
304371
#endif
305372
set_cpu_online(cpu, false);
373+
clear_cpu_sibling_map(cpu);
306374
calculate_cpu_foreign_map();
307375
local_irq_save(flags);
308376
irq_migrate_all_off_this_cpu();
@@ -337,6 +405,7 @@ void __noreturn arch_cpu_idle_dead(void)
337405
addr = iocsr_read64(LOONGARCH_IOCSR_MBUF0);
338406
} while (addr == 0);
339407

408+
local_irq_disable();
340409
init_fn = (void *)TO_CACHE(addr);
341410
iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_CLEAR);
342411

@@ -379,59 +448,6 @@ static int __init ipi_pm_init(void)
379448
core_initcall(ipi_pm_init);
380449
#endif
381450

382-
static inline void set_cpu_sibling_map(int cpu)
383-
{
384-
int i;
385-
386-
cpumask_set_cpu(cpu, &cpu_sibling_setup_map);
387-
388-
for_each_cpu(i, &cpu_sibling_setup_map) {
389-
if (cpus_are_siblings(cpu, i)) {
390-
cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
391-
cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
392-
}
393-
}
394-
}
395-
396-
static inline void set_cpu_core_map(int cpu)
397-
{
398-
int i;
399-
400-
cpumask_set_cpu(cpu, &cpu_core_setup_map);
401-
402-
for_each_cpu(i, &cpu_core_setup_map) {
403-
if (cpu_data[cpu].package == cpu_data[i].package) {
404-
cpumask_set_cpu(i, &cpu_core_map[cpu]);
405-
cpumask_set_cpu(cpu, &cpu_core_map[i]);
406-
}
407-
}
408-
}
409-
410-
/*
411-
* Calculate a new cpu_foreign_map mask whenever a
412-
* new cpu appears or disappears.
413-
*/
414-
void calculate_cpu_foreign_map(void)
415-
{
416-
int i, k, core_present;
417-
cpumask_t temp_foreign_map;
418-
419-
/* Re-calculate the mask */
420-
cpumask_clear(&temp_foreign_map);
421-
for_each_online_cpu(i) {
422-
core_present = 0;
423-
for_each_cpu(k, &temp_foreign_map)
424-
if (cpus_are_siblings(i, k))
425-
core_present = 1;
426-
if (!core_present)
427-
cpumask_set_cpu(i, &temp_foreign_map);
428-
}
429-
430-
for_each_online_cpu(i)
431-
cpumask_andnot(&cpu_foreign_map[i],
432-
&temp_foreign_map, &cpu_sibling_map[i]);
433-
}
434-
435451
/* Preload SMP state for boot cpu */
436452
void smp_prepare_boot_cpu(void)
437453
{

arch/loongarch/kvm/vcpu.c

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -298,74 +298,73 @@ static int _kvm_setcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 val)
298298
return ret;
299299
}
300300

301-
static int _kvm_get_cpucfg(int id, u64 *v)
301+
static int _kvm_get_cpucfg_mask(int id, u64 *v)
302302
{
303-
int ret = 0;
304-
305-
if (id < 0 && id >= KVM_MAX_CPUCFG_REGS)
303+
if (id < 0 || id >= KVM_MAX_CPUCFG_REGS)
306304
return -EINVAL;
307305

308306
switch (id) {
309307
case 2:
310-
/* Return CPUCFG2 features which have been supported by KVM */
308+
/* CPUCFG2 features unconditionally supported by KVM */
311309
*v = CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP |
312310
CPUCFG2_FPVERS | CPUCFG2_LLFTP | CPUCFG2_LLFTPREV |
313311
CPUCFG2_LAM;
314312
/*
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.
317315
*/
318316
if (cpu_has_lsx)
319317
*v |= CPUCFG2_LSX;
320-
/*
321-
* if LASX is supported by CPU, it is also supported by KVM,
322-
* as we implement it.
323-
*/
324318
if (cpu_has_lasx)
325319
*v |= CPUCFG2_LASX;
326320

327-
break;
321+
return 0;
328322
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;
331330
}
332-
return ret;
333331
}
334332

335333
static int kvm_check_cpucfg(int id, u64 val)
336334
{
337-
u64 mask;
338-
int ret = 0;
339-
340-
if (id < 0 && id >= KVM_MAX_CPUCFG_REGS)
341-
return -EINVAL;
335+
int ret;
336+
u64 mask = 0;
342337

343-
if (_kvm_get_cpucfg(id, &mask))
338+
ret = _kvm_get_cpucfg_mask(id, &mask);
339+
if (ret)
344340
return ret;
345341

342+
if (val & ~mask)
343+
/* Unsupported features and/or the higher 32 bits should not be set */
344+
return -EINVAL;
345+
346346
switch (id) {
347347
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;
365361
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;
367367
}
368-
return ret;
369368
}
370369

371370
static int kvm_get_one_reg(struct kvm_vcpu *vcpu,
@@ -566,7 +565,7 @@ static int kvm_loongarch_get_cpucfg_attr(struct kvm_vcpu *vcpu,
566565
uint64_t val;
567566
uint64_t __user *uaddr = (uint64_t __user *)attr->addr;
568567

569-
ret = _kvm_get_cpucfg(attr->attr, &val);
568+
ret = _kvm_get_cpucfg_mask(attr->attr, &val);
570569
if (ret)
571570
return ret;
572571

0 commit comments

Comments
 (0)