mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
LoongArch fixes for v6.8-rc6
-----BEGIN PGP SIGNATURE----- iQJKBAABCAA0FiEEzOlt8mkP+tbeiYy5AoYrw/LiJnoFAmXZeF4WHGNoZW5odWFj YWlAa2VybmVsLm9yZwAKCRAChivD8uImepF0D/9vFZTcp0RYeSg8ja6Hw5sPpCtO FbUepaxp7GnLzTAdCtrcNSGkKau4fWmo96fNcvs9Nshy08aemD8qLI9QH64oyLrJ K4YXk9MgU4ye5T71PHqSn5BMuVrNkeVt2Qe+2VCH15ZANTCkdComdLoxdkJa5N3M naOearhfh8qY0GHEVZFeBDkkcAU+xghi6//xwp3sd7562uUGsvXjiykog6JwNON5 Bzet22YigCkb5jSm5nyTS5DXEiNUDHd06mPp8yN6RLFPcN1nEiw1xviPGlKJZbwm dgoYgbMZCz668x7Lw/Uga2wmZm4HyxcEagcHJDZEGmnO++8a8fQUMTG00rQqEinG XvwmFHgDReaKoDaEA5R+fPEoMR7akWkXv5hbLz+ym+gfpGfyAX8fIkEd8Vh8DmgL IMJdH4AXYZhXxJbNiLOnWRB4NUjvxS86QS4o2HJMO6WsSvF8MB0ZOR17ROVM9ABP vb/EDfTdN5KYRvg6vBrUKNtw87NYm97uBjPCdwf/PfZqNGQ8wcdDQ4oiSh92cF5c Vd3T0YwAO45mW6EmzrhXgNh9JmYvNn1jqsX6pqGRY5FQ+6wZf4TfhZzCvlM8ShoX NElM1gbtT63nxDFFWVrxTQtabFQy4CVzQSjVoaCffs9Xt3ZQucGo3v6r7tnC1MqR gjM9WTQH4IK0y63fnQ== =tRG3 -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
c6a597fcc7
|
|
@ -60,7 +60,7 @@ &i2c0 {
|
|||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
eeprom@57{
|
||||
eeprom@57 {
|
||||
compatible = "atmel,24c16";
|
||||
reg = <0x57>;
|
||||
pagesize = <16>;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ &i2c2 {
|
|||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
eeprom@57{
|
||||
eeprom@57 {
|
||||
compatible = "atmel,24c16";
|
||||
reg = <0x57>;
|
||||
pagesize = <16>;
|
||||
|
|
|
|||
|
|
@ -357,6 +357,8 @@ void __init platform_init(void)
|
|||
acpi_gbl_use_default_register_widths = false;
|
||||
acpi_boot_table_init();
|
||||
#endif
|
||||
|
||||
early_init_fdt_scan_reserved_mem();
|
||||
unflatten_and_copy_device_tree();
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
|
|
@ -390,8 +392,6 @@ static void __init arch_mem_init(char **cmdline_p)
|
|||
|
||||
check_kernel_sections_mem();
|
||||
|
||||
early_init_fdt_scan_reserved_mem();
|
||||
|
||||
/*
|
||||
* In order to reduce the possibility of kernel panic when failed to
|
||||
* get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate
|
||||
|
|
|
|||
|
|
@ -88,6 +88,73 @@ void show_ipi_list(struct seq_file *p, int prec)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void set_cpu_core_map(int cpu)
|
||||
{
|
||||
int i;
|
||||
|
||||
cpumask_set_cpu(cpu, &cpu_core_setup_map);
|
||||
|
||||
for_each_cpu(i, &cpu_core_setup_map) {
|
||||
if (cpu_data[cpu].package == cpu_data[i].package) {
|
||||
cpumask_set_cpu(i, &cpu_core_map[cpu]);
|
||||
cpumask_set_cpu(cpu, &cpu_core_map[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void set_cpu_sibling_map(int cpu)
|
||||
{
|
||||
int i;
|
||||
|
||||
cpumask_set_cpu(cpu, &cpu_sibling_setup_map);
|
||||
|
||||
for_each_cpu(i, &cpu_sibling_setup_map) {
|
||||
if (cpus_are_siblings(cpu, i)) {
|
||||
cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
|
||||
cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void clear_cpu_sibling_map(int cpu)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_cpu(i, &cpu_sibling_setup_map) {
|
||||
if (cpus_are_siblings(cpu, i)) {
|
||||
cpumask_clear_cpu(i, &cpu_sibling_map[cpu]);
|
||||
cpumask_clear_cpu(cpu, &cpu_sibling_map[i]);
|
||||
}
|
||||
}
|
||||
|
||||
cpumask_clear_cpu(cpu, &cpu_sibling_setup_map);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate a new cpu_foreign_map mask whenever a
|
||||
* new cpu appears or disappears.
|
||||
*/
|
||||
void calculate_cpu_foreign_map(void)
|
||||
{
|
||||
int i, k, core_present;
|
||||
cpumask_t temp_foreign_map;
|
||||
|
||||
/* Re-calculate the mask */
|
||||
cpumask_clear(&temp_foreign_map);
|
||||
for_each_online_cpu(i) {
|
||||
core_present = 0;
|
||||
for_each_cpu(k, &temp_foreign_map)
|
||||
if (cpus_are_siblings(i, k))
|
||||
core_present = 1;
|
||||
if (!core_present)
|
||||
cpumask_set_cpu(i, &temp_foreign_map);
|
||||
}
|
||||
|
||||
for_each_online_cpu(i)
|
||||
cpumask_andnot(&cpu_foreign_map[i],
|
||||
&temp_foreign_map, &cpu_sibling_map[i]);
|
||||
}
|
||||
|
||||
/* Send mailbox buffer via Mail_Send */
|
||||
static void csr_mail_send(uint64_t data, int cpu, int mailbox)
|
||||
{
|
||||
|
|
@ -303,6 +370,7 @@ int loongson_cpu_disable(void)
|
|||
numa_remove_cpu(cpu);
|
||||
#endif
|
||||
set_cpu_online(cpu, false);
|
||||
clear_cpu_sibling_map(cpu);
|
||||
calculate_cpu_foreign_map();
|
||||
local_irq_save(flags);
|
||||
irq_migrate_all_off_this_cpu();
|
||||
|
|
@ -337,6 +405,7 @@ void __noreturn arch_cpu_idle_dead(void)
|
|||
addr = iocsr_read64(LOONGARCH_IOCSR_MBUF0);
|
||||
} while (addr == 0);
|
||||
|
||||
local_irq_disable();
|
||||
init_fn = (void *)TO_CACHE(addr);
|
||||
iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_CLEAR);
|
||||
|
||||
|
|
@ -379,59 +448,6 @@ static int __init ipi_pm_init(void)
|
|||
core_initcall(ipi_pm_init);
|
||||
#endif
|
||||
|
||||
static inline void set_cpu_sibling_map(int cpu)
|
||||
{
|
||||
int i;
|
||||
|
||||
cpumask_set_cpu(cpu, &cpu_sibling_setup_map);
|
||||
|
||||
for_each_cpu(i, &cpu_sibling_setup_map) {
|
||||
if (cpus_are_siblings(cpu, i)) {
|
||||
cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
|
||||
cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void set_cpu_core_map(int cpu)
|
||||
{
|
||||
int i;
|
||||
|
||||
cpumask_set_cpu(cpu, &cpu_core_setup_map);
|
||||
|
||||
for_each_cpu(i, &cpu_core_setup_map) {
|
||||
if (cpu_data[cpu].package == cpu_data[i].package) {
|
||||
cpumask_set_cpu(i, &cpu_core_map[cpu]);
|
||||
cpumask_set_cpu(cpu, &cpu_core_map[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate a new cpu_foreign_map mask whenever a
|
||||
* new cpu appears or disappears.
|
||||
*/
|
||||
void calculate_cpu_foreign_map(void)
|
||||
{
|
||||
int i, k, core_present;
|
||||
cpumask_t temp_foreign_map;
|
||||
|
||||
/* Re-calculate the mask */
|
||||
cpumask_clear(&temp_foreign_map);
|
||||
for_each_online_cpu(i) {
|
||||
core_present = 0;
|
||||
for_each_cpu(k, &temp_foreign_map)
|
||||
if (cpus_are_siblings(i, k))
|
||||
core_present = 1;
|
||||
if (!core_present)
|
||||
cpumask_set_cpu(i, &temp_foreign_map);
|
||||
}
|
||||
|
||||
for_each_online_cpu(i)
|
||||
cpumask_andnot(&cpu_foreign_map[i],
|
||||
&temp_foreign_map, &cpu_sibling_map[i]);
|
||||
}
|
||||
|
||||
/* Preload SMP state for boot cpu */
|
||||
void smp_prepare_boot_cpu(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -298,74 +298,73 @@ static int _kvm_setcsr(struct kvm_vcpu *vcpu, unsigned int id, u64 val)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int _kvm_get_cpucfg(int id, u64 *v)
|
||||
static int _kvm_get_cpucfg_mask(int id, u64 *v)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (id < 0 && id >= KVM_MAX_CPUCFG_REGS)
|
||||
if (id < 0 || id >= KVM_MAX_CPUCFG_REGS)
|
||||
return -EINVAL;
|
||||
|
||||
switch (id) {
|
||||
case 2:
|
||||
/* Return CPUCFG2 features which have been supported by KVM */
|
||||
/* CPUCFG2 features unconditionally supported by KVM */
|
||||
*v = CPUCFG2_FP | CPUCFG2_FPSP | CPUCFG2_FPDP |
|
||||
CPUCFG2_FPVERS | CPUCFG2_LLFTP | CPUCFG2_LLFTPREV |
|
||||
CPUCFG2_LAM;
|
||||
/*
|
||||
* If LSX is supported by CPU, it is also supported by KVM,
|
||||
* as we implement it.
|
||||
* For the ISA extensions listed below, if one is supported
|
||||
* by the host, then it is also supported by KVM.
|
||||
*/
|
||||
if (cpu_has_lsx)
|
||||
*v |= CPUCFG2_LSX;
|
||||
/*
|
||||
* if LASX is supported by CPU, it is also supported by KVM,
|
||||
* as we implement it.
|
||||
*/
|
||||
if (cpu_has_lasx)
|
||||
*v |= CPUCFG2_LASX;
|
||||
|
||||
break;
|
||||
return 0;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
/*
|
||||
* No restrictions on other valid CPUCFG IDs' values, but
|
||||
* CPUCFG data is limited to 32 bits as the LoongArch ISA
|
||||
* manual says (Volume 1, Section 2.2.10.5 "CPUCFG").
|
||||
*/
|
||||
*v = U32_MAX;
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int kvm_check_cpucfg(int id, u64 val)
|
||||
{
|
||||
u64 mask;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
u64 mask = 0;
|
||||
|
||||
if (id < 0 && id >= KVM_MAX_CPUCFG_REGS)
|
||||
return -EINVAL;
|
||||
|
||||
if (_kvm_get_cpucfg(id, &mask))
|
||||
ret = _kvm_get_cpucfg_mask(id, &mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (val & ~mask)
|
||||
/* Unsupported features and/or the higher 32 bits should not be set */
|
||||
return -EINVAL;
|
||||
|
||||
switch (id) {
|
||||
case 2:
|
||||
/* CPUCFG2 features checking */
|
||||
if (val & ~mask)
|
||||
/* The unsupported features should not be set */
|
||||
ret = -EINVAL;
|
||||
else if (!(val & CPUCFG2_LLFTP))
|
||||
/* The LLFTP must be set, as guest must has a constant timer */
|
||||
ret = -EINVAL;
|
||||
else if ((val & CPUCFG2_FP) && (!(val & CPUCFG2_FPSP) || !(val & CPUCFG2_FPDP)))
|
||||
/* Single and double float point must both be set when enable FP */
|
||||
ret = -EINVAL;
|
||||
else if ((val & CPUCFG2_LSX) && !(val & CPUCFG2_FP))
|
||||
/* FP should be set when enable LSX */
|
||||
ret = -EINVAL;
|
||||
else if ((val & CPUCFG2_LASX) && !(val & CPUCFG2_LSX))
|
||||
/* LSX, FP should be set when enable LASX, and FP has been checked before. */
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
if (!(val & CPUCFG2_LLFTP))
|
||||
/* Guests must have a constant timer */
|
||||
return -EINVAL;
|
||||
if ((val & CPUCFG2_FP) && (!(val & CPUCFG2_FPSP) || !(val & CPUCFG2_FPDP)))
|
||||
/* Single and double float point must both be set when FP is enabled */
|
||||
return -EINVAL;
|
||||
if ((val & CPUCFG2_LSX) && !(val & CPUCFG2_FP))
|
||||
/* LSX architecturally implies FP but val does not satisfy that */
|
||||
return -EINVAL;
|
||||
if ((val & CPUCFG2_LASX) && !(val & CPUCFG2_LSX))
|
||||
/* LASX architecturally implies LSX and FP but val does not satisfy that */
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
/*
|
||||
* Values for the other CPUCFG IDs are not being further validated
|
||||
* besides the mask check above.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
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,
|
|||
uint64_t val;
|
||||
uint64_t __user *uaddr = (uint64_t __user *)attr->addr;
|
||||
|
||||
ret = _kvm_get_cpucfg(attr->attr, &val);
|
||||
ret = _kvm_get_cpucfg_mask(attr->attr, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user