mailweb.openeuler.org
Manage this list

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

Kernel

Threads by month
  • ----- 2025 -----
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
kernel@openeuler.org

  • 47 participants
  • 18244 discussions
[PATCH openEuler-1.0-LTS] Driver for Zhaoxin CPU core temperature monitoring
by LeoLiu-oc 30 Aug '22

30 Aug '22
zhaoxin inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I5J763 CVE: NA -------------------------------------------- Add support for the temperature sensor inside CPU. Supported are all known variants of the Zhaoxin processors. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> --- drivers/hwmon/Kconfig | 9 + drivers/hwmon/Makefile | 1 + drivers/hwmon/via-cputemp.c | 1 - drivers/hwmon/zhaoxin-cputemp.c | 319 ++++++++++++++++++++++++++++++++ 4 files changed, 329 insertions(+), 1 deletion(-) create mode 100644 drivers/hwmon/zhaoxin-cputemp.c diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index c7adaca2ab01..1ef7c384d652 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1720,6 +1720,15 @@ config SENSORS_VIA_CPUTEMP sensor inside your CPU. Supported are all known variants of the VIA C7 and Nano. +config SENSORS_ZHAOXIN_CPUTEMP + tristate "Zhaoxin CPU temperature sensor" + depends on X86 + select HWMON_VID + help + If you say yes here you get support for the temperature + sensor inside your CPU. Supported are all known variants of + the Zhaoxin processors. + config SENSORS_VIA686A tristate "VIA686A" depends on PCI diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 93f7f41ea4ad..4fe7d2f76f0d 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -168,6 +168,7 @@ obj-$(CONFIG_SENSORS_TMP401) += tmp401.o obj-$(CONFIG_SENSORS_TMP421) += tmp421.o obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress-hwmon.o obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o +obj-$(CONFIG_SENSORS_ZHAOXIN_CPUTEMP)+= zhaoxin-cputemp.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o obj-$(CONFIG_SENSORS_VT1211) += vt1211.o obj-$(CONFIG_SENSORS_VT8231) += vt8231.o diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c index 0e81f287d305..3c960b999958 100644 --- a/drivers/hwmon/via-cputemp.c +++ b/drivers/hwmon/via-cputemp.c @@ -287,7 +287,6 @@ static const struct x86_cpu_id __initconst cputemp_ids[] = { { X86_VENDOR_CENTAUR, 6, 0xa, }, /* C7 A */ { X86_VENDOR_CENTAUR, 6, 0xd, }, /* C7 D */ { X86_VENDOR_CENTAUR, 6, 0xf, }, /* Nano */ - { X86_VENDOR_CENTAUR, 7, X86_MODEL_ANY, }, {} }; MODULE_DEVICE_TABLE(x86cpu, cputemp_ids); diff --git a/drivers/hwmon/zhaoxin-cputemp.c b/drivers/hwmon/zhaoxin-cputemp.c new file mode 100644 index 000000000000..4bfde378b0fb --- /dev/null +++ b/drivers/hwmon/zhaoxin-cputemp.c @@ -0,0 +1,319 @@ +/* + * zhaoxin-cputemp.c - Driver for Zhaoxin CPU core temperature monitoring + * + * based on existing coretemp.c, which is + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/hwmon.h> +#include <linux/hwmon-vid.h> +#include <linux/sysfs.h> +#include <linux/hwmon-sysfs.h> +#include <linux/err.h> +#include <linux/mutex.h> +#include <linux/list.h> +#include <linux/platform_device.h> +#include <linux/cpu.h> +#include <asm/msr.h> +#include <asm/processor.h> +#include <asm/cpu_device_id.h> + +#define DRVNAME "zhaoxin_cputemp" + +enum { SHOW_TEMP, SHOW_LABEL, SHOW_NAME }; + +/* + * Functions declaration + */ + +struct zhaoxin_cputemp_data { + struct device *hwmon_dev; + const char *name; + u8 vrm; + u32 id; + u32 msr_temp; + u32 msr_vid; +}; + +/* + * Sysfs stuff + */ + +static ssize_t show_name(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + int ret; + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev); + + if (attr->index == SHOW_NAME) + ret = sprintf(buf, "%s\n", data->name); + else /* show label */ + ret = sprintf(buf, "Core %d\n", data->id); + return ret; +} + +static ssize_t show_temp(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev); + u32 eax, edx; + int err; + + err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx); + if (err) + return -EAGAIN; + + return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000); +} + +static ssize_t cpu0_vid_show(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct zhaoxin_cputemp_data *data = dev_get_drvdata(dev); + u32 eax, edx; + int err; + + err = rdmsr_safe_on_cpu(data->id, data->msr_vid, &eax, &edx); + if (err) + return -EAGAIN; + + return sprintf(buf, "%d\n", vid_from_reg(~edx & 0x7f, data->vrm)); +} + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, + SHOW_TEMP); +static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL); +static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME); + +static struct attribute *zhaoxin_cputemp_attributes[] = { + &sensor_dev_attr_name.dev_attr.attr, + &sensor_dev_attr_temp1_label.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + NULL +}; + +static const struct attribute_group zhaoxin_cputemp_group = { + .attrs = zhaoxin_cputemp_attributes, +}; + +/* Optional attributes */ +static DEVICE_ATTR_RO(cpu0_vid); + +static int zhaoxin_cputemp_probe(struct platform_device *pdev) +{ + struct zhaoxin_cputemp_data *data; + int err; + u32 eax, edx; + + data = devm_kzalloc(&pdev->dev, sizeof(struct zhaoxin_cputemp_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->id = pdev->id; + data->name = "zhaoxin_cputemp"; + + data->msr_temp = 0x1423; + + /* test if we can access the TEMPERATURE MSR */ + err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx); + if (err) { + dev_err(&pdev->dev, + "Unable to access TEMPERATURE MSR, giving up\n"); + return err; + } + + platform_set_drvdata(pdev, data); + + err = sysfs_create_group(&pdev->dev.kobj, &zhaoxin_cputemp_group); + if (err) + return err; + + if (data->msr_vid) + data->vrm = vid_which_vrm(); + + if (data->vrm) { + err = device_create_file(&pdev->dev, &dev_attr_cpu0_vid); + if (err) + goto exit_remove; + } + + data->hwmon_dev = hwmon_device_register(&pdev->dev); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + dev_err(&pdev->dev, "Class registration failed (%d)\n", + err); + goto exit_remove; + } + + return 0; + +exit_remove: + if (data->vrm) + device_remove_file(&pdev->dev, &dev_attr_cpu0_vid); + sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group); + return err; +} + +static int zhaoxin_cputemp_remove(struct platform_device *pdev) +{ + struct zhaoxin_cputemp_data *data = platform_get_drvdata(pdev); + + hwmon_device_unregister(data->hwmon_dev); + if (data->vrm) + device_remove_file(&pdev->dev, &dev_attr_cpu0_vid); + sysfs_remove_group(&pdev->dev.kobj, &zhaoxin_cputemp_group); + return 0; +} + +static struct platform_driver zhaoxin_cputemp_driver = { + .driver = { + .name = DRVNAME, + }, + .probe = zhaoxin_cputemp_probe, + .remove = zhaoxin_cputemp_remove, +}; + +struct pdev_entry { + struct list_head list; + struct platform_device *pdev; + unsigned int cpu; +}; + +static LIST_HEAD(pdev_list); +static DEFINE_MUTEX(pdev_list_mutex); + +static int zhaoxin_cputemp_online(unsigned int cpu) +{ + int err; + struct platform_device *pdev; + struct pdev_entry *pdev_entry; + + pdev = platform_device_alloc(DRVNAME, cpu); + if (!pdev) { + err = -ENOMEM; + pr_err("Device allocation failed\n"); + goto exit; + } + + pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL); + if (!pdev_entry) { + err = -ENOMEM; + goto exit_device_put; + } + + err = platform_device_add(pdev); + if (err) { + pr_err("Device addition failed (%d)\n", err); + goto exit_device_free; + } + + pdev_entry->pdev = pdev; + pdev_entry->cpu = cpu; + mutex_lock(&pdev_list_mutex); + list_add_tail(&pdev_entry->list, &pdev_list); + mutex_unlock(&pdev_list_mutex); + + return 0; + +exit_device_free: + kfree(pdev_entry); +exit_device_put: + platform_device_put(pdev); +exit: + return err; +} + +static int zhaoxin_cputemp_down_prep(unsigned int cpu) +{ + struct pdev_entry *p; + + mutex_lock(&pdev_list_mutex); + list_for_each_entry(p, &pdev_list, list) { + if (p->cpu == cpu) { + platform_device_unregister(p->pdev); + list_del(&p->list); + mutex_unlock(&pdev_list_mutex); + kfree(p); + return 0; + } + } + mutex_unlock(&pdev_list_mutex); + return 0; +} + +static const struct x86_cpu_id __initconst cputemp_ids[] = { + { X86_VENDOR_CENTAUR, 7, X86_MODEL_ANY, }, + { X86_VENDOR_ZHAOXIN, 7, X86_MODEL_ANY, }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, cputemp_ids); + +static enum cpuhp_state zhaoxin_temp_online; + +static int __init zhaoxin_cputemp_init(void) +{ + int err; + + if (!x86_match_cpu(cputemp_ids)) + return -ENODEV; + + err = platform_driver_register(&zhaoxin_cputemp_driver); + if (err) + goto exit; + + err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/zhaoxin:online", + zhaoxin_cputemp_online, zhaoxin_cputemp_down_prep); + if (err < 0) + goto exit_driver_unreg; + zhaoxin_temp_online = err; + +#ifndef CONFIG_HOTPLUG_CPU + if (list_empty(&pdev_list)) { + err = -ENODEV; + goto exit_hp_unreg; + } +#endif + return 0; + +#ifndef CONFIG_HOTPLUG_CPU +exit_hp_unreg: + cpuhp_remove_state_nocalls(zhaoxin_temp_online); +#endif +exit_driver_unreg: + platform_driver_unregister(&zhaoxin_cputemp_driver); +exit: + return err; +} + +static void __exit zhaoxin_cputemp_exit(void) +{ + cpuhp_remove_state(zhaoxin_temp_online); + platform_driver_unregister(&zhaoxin_cputemp_driver); +} + +MODULE_DESCRIPTION("Zhaoxin CPU temperature monitor"); +MODULE_LICENSE("GPL"); + +module_init(zhaoxin_cputemp_init) +module_exit(zhaoxin_cputemp_exit) -- 2.25.1
1 0
0 0
[PATCH openEuler-1.0-LTS] x86/tsc: Make cur->adjusted values in package#1 to be the same
by LeoLiu-oc 29 Aug '22

29 Aug '22
zhaoxin inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I54V2W CVE: NA ---------------------------------------------------------------- When resume from S4 on Zhaoxin 2 packages platform that support X86_FEATURE_TSC_ADJUST, the following warning messages appear: [ 327.445302] [Firmware Bug]: TSC ADJUST differs: CPU15 45960750 --> 78394770. Restoring [ 329.209120] [Firmware Bug]: TSC ADJUST differs: CPU14 45960750 --> 78394770. Restoring [ 329.209128] [Firmware Bug]: TSC ADJUST differs: CPU13 45960750 --> 78394770. Restoring [ 329.209138] [Firmware Bug]: TSC ADJUST differs: CPU12 45960750 --> 78394770. Restoring [ 329.209151] [Firmware Bug]: TSC ADJUST differs: CPU11 45960750 --> 78394770. Restoring [ 329.209160] [Firmware Bug]: TSC ADJUST differs: CPU10 45960750 --> 78394770. Restoring [ 329.209169] [Firmware Bug]: TSC ADJUST differs: CPU9 45960750 --> 78394770. Restoring The reason is: Step 1: Bring up. TSC is sync after bring up with following settings: MSR 0x3b cur->adjusted Package#0 CPU 0-7 0 0 Package#1 first CPU value1 value1 Package#1 non-first CPU value1 value1 Step 2: Suspend to S4. Settings in Step 1 are not changed in this Step. Step 3: Bring up caused by S4 wake up event. TSC is sync when bring up with following settings: MSR 0x3b cur->adjusted Package#0 CPU 0-7 0 0 Package#1 first CPU value2 value2 Package#1 non-first CPU value2 value2 Step 4: Resume from S4. When resuming from S4, Current TSC synchronous mechanism cause following settings: MSR 0x3b cur->adjusted Package#0 CPU 0-7 0 0 Package#1 first CPU value2 value2 Package#1 non-first CPU value2 value1 In these Steps, value1 != 0 and value2 != value1. In Step4, as function tsc_store_and_check_tsc_adjust() do, when the value of MSR 0x3b on the non-first online CPU in package#1 is equal to the value of cur->adjusted on the first online CPU in the same package, the cur->adjusted value on this non-first online CPU will hold the old value1. This cause function tsc_verify_tsc_adjust() set the value of MSR 0x3b on the non-first online CPUs in the package#1 to the old value1 and print the beginning warning messages. Fix it by setting cur->adjusted value on the non-first online CPU in a package to the value of MSR 0x3b on the same CPU when they are not equal. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> --- arch/x86/kernel/tsc_sync.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c index ec534f978867..e0cc4170325c 100644 --- a/arch/x86/kernel/tsc_sync.c +++ b/arch/x86/kernel/tsc_sync.c @@ -190,6 +190,11 @@ bool tsc_store_and_check_tsc_adjust(bool bootcpu) if (bootval != ref->adjusted) { cur->adjusted = ref->adjusted; wrmsrl(MSR_IA32_TSC_ADJUST, ref->adjusted); + } else if (cur->adjusted != bootval) { + if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR || + boot_cpu_data.x86_vendor == X86_VENDOR_ZHAOXIN) { + cur->adjusted = bootval; + } } /* * We have the TSCs forced to be in sync on this package. Skip sync -- 2.25.1
1 0
0 0
[PATCH openEuler-1.0-LTS] Add support for PxSCT.LPM set based on actual LPM circumstances
by LeoLiu-oc 29 Aug '22

29 Aug '22
zhaoxin inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I54V2K CVE: NA ---------------------------------------------------------------- AHCI Spec shows that the PxSCTL.IPM field in each port must be programmed to disallow device initiated LPM requests when HBA can not support transitions to the LPM state. The current LPM driver has no restrictions on LPM transitions when enabling device initiated LPM. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> --- drivers/ata/libata-core.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 0bcdc5261480..e685162a188e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3975,6 +3975,9 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, bool spm_wakeup) { struct ata_eh_context *ehc = &link->eh_context; + struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL; + struct device *dev = ap ? ap->host->dev : NULL; + struct pci_dev *pdev = (!dev || !dev_is_pci(dev)) ? NULL : to_pci_dev(dev); bool woken_up = false; u32 scontrol; int rc; @@ -4001,10 +4004,20 @@ int sata_link_scr_lpm(struct ata_link *link, enum ata_lpm_policy policy, case ATA_LPM_MED_POWER_WITH_DIPM: case ATA_LPM_MIN_POWER_WITH_PARTIAL: case ATA_LPM_MIN_POWER: - if (ata_link_nr_enabled(link) > 0) + if (ata_link_nr_enabled(link) > 0) { /* no restrictions on LPM transitions */ scontrol &= ~(0x7 << 8); - else { + /* + * If Host does not support partial, then disallows it, + * the same for slumber. + */ + if (pdev && pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) { + if (!(link->ap->host->flags & ATA_HOST_PART)) + scontrol |= (0x1 << 8); + if (!(link->ap->host->flags & ATA_HOST_SSC)) + scontrol |= (0x2 << 8); + } + } else { /* empty port, power off */ scontrol &= ~0xf; scontrol |= (0x1 << 2); -- 2.25.1
1 0
0 0
[PATCH openEuler-1.0-LTS] Add support for disabling PhyRdy Change Interrupt based on actual LPM capability
by LeoLiu-oc 29 Aug '22

29 Aug '22
zhaoxin inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I54V27 CVE: NA ---------------------------------------------------------------- The ahci spec mentions that PhyRdy Change Interrupt and Link Power Management (LPM) do not coexist. However, before enabling LPM, the driver did not check whether the host supports LPM, but directly disabled PhyRdy Change Interrupt. Increase the judgment on the actual support of LPM, and disable PhyRdy Change Interrupt only when it is supported. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> --- drivers/ata/ahci.c | 11 +++++++++++ drivers/ata/libata-eh.c | 7 +++++++ include/linux/libata.h | 3 +++ 3 files changed, 21 insertions(+) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index ebb2bfd4ab0a..8ed2f42b85fd 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1855,6 +1855,17 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) else dev_info(&pdev->dev, "SSS flag set, parallel bus scan disabled\n"); + if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) { + if (hpriv->cap & HOST_CAP_PART) + host->flags |= ATA_HOST_PART; + + if (hpriv->cap & HOST_CAP_SSC) + host->flags |= ATA_HOST_SSC; + + if (hpriv->cap2 & HOST_CAP2_SDS) + host->flags |= ATA_HOST_DEVSLP; + } + if (pi.flags & ATA_FLAG_EM) ahci_reset_em(host); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index ccc80ff57eb2..e4e0e6d94741 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3448,6 +3448,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, struct ata_device **r_failed_dev) { struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL; + struct device *device = ap->host->dev; + struct pci_dev *pdev = (!device || !dev_is_pci(device)) ? NULL : to_pci_dev(device); struct ata_eh_context *ehc = &link->eh_context; struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; enum ata_lpm_policy old_policy = link->lpm_policy; @@ -3456,6 +3458,11 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, unsigned int err_mask; int rc; + /* if controller does not support lpm, then sets no LPM flags */ + if ((pdev && pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) && + !(ap->host->flags & (ATA_HOST_PART | ATA_HOST_SSC | ATA_HOST_DEVSLP))) + link->flags |= ATA_LFLAG_NO_LPM; + /* if the link or host doesn't do LPM, noop */ if ((link->flags & ATA_LFLAG_NO_LPM) || (ap && !ap->ops->set_lpm)) return 0; diff --git a/include/linux/libata.h b/include/linux/libata.h index dc164b7ebbb0..1cec68e5b104 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -276,6 +276,9 @@ enum { ATA_HOST_STARTED = (1 << 1), /* Host started */ ATA_HOST_PARALLEL_SCAN = (1 << 2), /* Ports on this host can be scanned in parallel */ ATA_HOST_IGNORE_ATA = (1 << 3), /* Ignore ATA devices on this host. */ + ATA_HOST_PART = (1 << 4), /* Host support partial. */ + ATA_HOST_SSC = (1 << 5), /* Host support slumber. */ + ATA_HOST_DEVSLP = (1 << 6), /* Host support devslp. */ /* bits 24:31 of host->flags are reserved for LLD specific flags */ -- 2.25.1
1 0
0 0
[PATCH openEuler-1.0-LTS] EHCI: Clear wakeup signal locked in S0 state when device plug in
by LeoLiu-oc 29 Aug '22

29 Aug '22
zhaoxin inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I54V1P CVE: NA ---------------------------------------------------------------- If we plug in a LS/FS device on USB2 port of EHCI, it will latch a wakeup signal in EHCI internal. This is a bug of EHCI for Some project of ZhaoXin. If enable EHCI runtime suspend and no device attach. PM core will let EHCI go to D3 to save power. However, once EHCI go to D3, it will release wakeup signal that latched on device connect to port during S0. Which will generate a SCI interrupt and bring EHCI to D0. But without device connect, EHCI will go to D3 again. So, there is suspend-resume loop and generate SCI interrupt Continuously. In order to fix this issues, we need to clear the wakeup signal latched in EHCI when EHCI suspend function is called. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> --- drivers/pci/pci-driver.c | 6 +++++- drivers/usb/host/ehci-hcd.c | 21 +++++++++++++++++++++ drivers/usb/host/ehci-pci.c | 4 ++++ drivers/usb/host/ehci.h | 1 + 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 45c3a78d6004..9329f4881d42 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -513,7 +513,11 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev) } pci_restore_state(pci_dev); - pci_pme_restore(pci_dev); + if (!(pci_dev->vendor == PCI_VENDOR_ID_ZHAOXIN && + pci_dev->device == 0x3104 && + (pci_dev->revision & 0xf0) == 0x90 && + pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI)) + pci_pme_restore(pci_dev); return 0; } diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 8608ac513fb7..0daa6d98f9b9 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1110,6 +1110,27 @@ int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup) return -EBUSY; } + /* Clear wakeup signal locked in S0 state when device plug in */ + if (ehci->zx_wakeup_clear == 1) { + u32 __iomem *reg = &ehci->regs->port_status[4]; + u32 t1 = ehci_readl(ehci, reg); + + t1 &= (u32)~0xf0000; + t1 |= PORT_TEST_FORCE; + ehci_writel(ehci, t1, reg); + t1 = ehci_readl(ehci, reg); + usleep_range(1000, 2000); + t1 &= (u32)~0xf0000; + ehci_writel(ehci, t1, reg); + usleep_range(1000, 2000); + t1 = ehci_readl(ehci, reg); + ehci_writel(ehci, t1 | PORT_CSC, reg); + udelay(500); + t1 = ehci_readl(ehci, &ehci->regs->status); + ehci_writel(ehci, t1 & STS_PCD, &ehci->regs->status); + ehci_readl(ehci, &ehci->regs->status); + } + return 0; } EXPORT_SYMBOL_GPL(ehci_suspend); diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index baae879dbddd..357dc140e914 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -216,6 +216,10 @@ static int ehci_pci_setup(struct usb_hcd *hcd) ehci_info(ehci, "applying MosChip frame-index workaround\n"); ehci->frame_index_bug = 1; break; + case PCI_VENDOR_ID_ZHAOXIN: + if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x90) + ehci->zx_wakeup_clear = 1; + break; } /* optional debug port, normally in the first BAR */ diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index c8e9a48e1d51..9625b6030757 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -218,6 +218,7 @@ struct ehci_hcd { /* one per controller */ unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */ unsigned need_oc_pp_cycle:1; /* MPC834X port power */ unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ + unsigned zx_wakeup_clear:1; /* required for usb32 quirk */ #define OHCI_CTRL_HCFS (3 << 6) -- 2.25.1
1 0
0 0
[PATCH openEuler-1.0-LTS 1/5] tty: drivers/tty/, stop using tty_schedule_flip()
by Yongqiang Liu 29 Aug '22

29 Aug '22
From: Jiri Slaby <jslaby(a)suse.cz> stable inclusion from stable-v4.19.254 commit 6935c7650015e664642556a7e6c9cf23c7dc01ce category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5A5Y1 CVE: CVE-2022-1462 -------------------------------- commit 5f6a85158ccacc3f09744b3aafe8b11ab3b6c6f6 upstream. Since commit a9c3f68f3cd8d (tty: Fix low_latency BUG) in 2014, tty_flip_buffer_push() is only a wrapper to tty_schedule_flip(). We are going to remove the latter (as it is used less), so call the former in drivers/tty/. Cc: Vladimir Zapolskiy <vz(a)mleia.com> Reviewed-by: Johan Hovold <johan(a)kernel.org> Signed-off-by: Jiri Slaby <jslaby(a)suse.cz> Link: https://lore.kernel.org/r/20211122111648.30379-2-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Signed-off-by: Yi Yang <yiyang13(a)huawei.com> Reviewed-by: Xiu Jianfeng <xiujianfeng(a)huawei.com> Reviewed-by: Wang Weiyang <wangweiyang2(a)huawei.com> Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com> --- drivers/tty/cyclades.c | 6 +++--- drivers/tty/goldfish.c | 2 +- drivers/tty/moxa.c | 4 ++-- drivers/tty/serial/lpc32xx_hs.c | 2 +- drivers/tty/vt/keyboard.c | 6 +++--- drivers/tty/vt/vt.c | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index 6d3c58051ce3..db048dbe9f78 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c @@ -556,7 +556,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, } info->idle_stats.recv_idle = jiffies; } - tty_schedule_flip(port); + tty_flip_buffer_push(port); /* end of service */ cyy_writeb(info, CyRIR, save_xir & 0x3f); @@ -996,7 +996,7 @@ static void cyz_handle_rx(struct cyclades_port *info) mod_timer(&info->rx_full_timer, jiffies + 1); #endif info->idle_stats.recv_idle = jiffies; - tty_schedule_flip(&info->port); + tty_flip_buffer_push(&info->port); /* Update rx_get */ cy_writel(&buf_ctrl->rx_get, new_rx_get); @@ -1172,7 +1172,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) if (delta_count) wake_up_interruptible(&info->port.delta_msr_wait); if (special_count) - tty_schedule_flip(&info->port); + tty_flip_buffer_push(&info->port); } } diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index c8c5cdfc5e19..ed0f3a7b8fe5 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -151,7 +151,7 @@ static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) address = (unsigned long)(void *)buf; goldfish_tty_rw(qtty, address, count, 0); - tty_schedule_flip(&qtty->port); + tty_flip_buffer_push(&qtty->port); return IRQ_HANDLED; } diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 250a19f042d7..181381fa5126 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -1393,7 +1393,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, if (inited && !tty_throttled(tty) && MoxaPortRxQueue(p) > 0) { /* RX */ MoxaPortReadData(p); - tty_schedule_flip(&p->port); + tty_flip_buffer_push(&p->port); } } else { clear_bit(EMPTYWAIT, &p->statusflags); @@ -1418,7 +1418,7 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle, if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */ tty_insert_flip_char(&p->port, 0, TTY_BREAK); - tty_schedule_flip(&p->port); + tty_flip_buffer_push(&p->port); } if (intr & IntrLine) diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c index d1d73261575b..9c145ed0dcf7 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c @@ -341,7 +341,7 @@ static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) LPC32XX_HSUART_IIR(port->membase)); port->icount.overrun++; tty_insert_flip_char(tport, 0, TTY_OVERRUN); - tty_schedule_flip(tport); + tty_flip_buffer_push(tport); } /* Data received? */ diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 94cad9f86ff9..e3aac11d770f 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -310,7 +310,7 @@ int kbd_rate(struct kbd_repeat *rpt) static void put_queue(struct vc_data *vc, int ch) { tty_insert_flip_char(&vc->port, ch, 0); - tty_schedule_flip(&vc->port); + tty_flip_buffer_push(&vc->port); } static void puts_queue(struct vc_data *vc, char *cp) @@ -319,7 +319,7 @@ static void puts_queue(struct vc_data *vc, char *cp) tty_insert_flip_char(&vc->port, *cp, 0); cp++; } - tty_schedule_flip(&vc->port); + tty_flip_buffer_push(&vc->port); } static void applkey(struct vc_data *vc, int key, char mode) @@ -564,7 +564,7 @@ static void fn_inc_console(struct vc_data *vc) static void fn_send_intr(struct vc_data *vc) { tty_insert_flip_char(&vc->port, 0, TTY_BREAK); - tty_schedule_flip(&vc->port); + tty_flip_buffer_push(&vc->port); } static void fn_scroll_forw(struct vc_data *vc) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index dca627ccece5..20565603a365 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1838,7 +1838,7 @@ static void respond_string(const char *p, struct tty_port *port) tty_insert_flip_char(port, *p, 0); p++; } - tty_schedule_flip(port); + tty_flip_buffer_push(port); } static void cursor_report(struct vc_data *vc, struct tty_struct *tty) -- 2.25.1
1 4
0 0
[PATCH openEuler-1.0-LTS] XHCI:Fix some device identify fail when enable xHCI runtime suspend
by LeoLiu-oc 29 Aug '22

29 Aug '22
zhaoxin inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I54V16 CVE: NA ---------------------------------------------------------------- If plug out device form xhci with runtime suspend enabled. On the one hand, driver will disconnect this device and send disabled slot command to xhci. On the other hand, without no device connect to xhci, PM core will call xhci suspend function to let xhci go to D3 to save power. However there is a temporal competition to get xhci lock between disable slot command interrupt and xhci suspend. If xhci suspend function get xhci lock first, then this function will clear xhci command ring. It will get error command trb when driver to handle disable slot command interrupt. This is a serious error for driver and driver will cleanup xhci. So,any device connect to this xhci port again will not be recognized. In order to fix this issues, we let disable slot command interrupt ISR to get xhci lock first. So, add a delay in xhci suspend function before to get xhci lock. Signed-off-by: LeoLiu-oc <LeoLiu-oc(a)zhaoxin.com> --- drivers/usb/host/xhci-pci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 238a32cc311c..4c2376a4c1d6 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -223,6 +223,9 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_ZHAOXIN_HOST; } + if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) + xhci->quirks |= XHCI_SUSPEND_DELAY; + /* See https://bugzilla.kernel.org/show_bug.cgi?id=79511 */ if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3432) -- 2.25.1
1 0
0 0
[PATCH openEuler-1.0-LTS] can: bcm/raw/isotp: use per module netdevice notifier
by Yongqiang Liu 27 Aug '22

27 Aug '22
From: Tetsuo Handa <penguin-kernel(a)i-love.sakura.ne.jp> stable inclusion from stable-v4.19.196 commit d42c3ebb315618ca536ef764e3f929ce1d5c3485 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5O0T8 CVE: NA -------------------------------- commit 8d0caedb759683041d9db82069937525999ada53 upstream. syzbot is reporting hung task at register_netdevice_notifier() [1] and unregister_netdevice_notifier() [2], for cleanup_net() might perform time consuming operations while CAN driver's raw/bcm/isotp modules are calling {register,unregister}_netdevice_notifier() on each socket. Change raw/bcm/isotp modules to call register_netdevice_notifier() from module's __init function and call unregister_netdevice_notifier() from module's __exit function, as with gw/j1939 modules are doing. Link: https://syzkaller.appspot.com/bug?id=391b9498827788b3cc6830226d4ff5be87107c… [1] Link: https://syzkaller.appspot.com/bug?id=1724d278c83ca6e6df100a2e320c10d991cf2b… [2] Link: https://lore.kernel.org/r/54a5f451-05ed-f977-8534-79e7aa2bcc8f@i-love.sakur… Cc: linux-stable <stable(a)vger.kernel.org> Reported-by: syzbot <syzbot+355f8edb2ff45d5f95fa(a)syzkaller.appspotmail.com> Reported-by: syzbot <syzbot+0f1827363a305f74996f(a)syzkaller.appspotmail.com> Reviewed-by: Kirill Tkhai <ktkhai(a)virtuozzo.com> Tested-by: syzbot <syzbot+355f8edb2ff45d5f95fa(a)syzkaller.appspotmail.com> Tested-by: Oliver Hartkopp <socketcan(a)hartkopp.net> Signed-off-by: Tetsuo Handa <penguin-kernel(a)I-love.SAKURA.ne.jp> Signed-off-by: Marc Kleine-Budde <mkl(a)pengutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org> Signed-off-by: Ziyang Xuan <william.xuanziyang(a)huawei.com> Reviewed-by: Yue Haibing <yuehaibing(a)huawei.com> Reviewed-by: Wei Yongjun <weiyongjun1(a)huawei.com> Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com> --- net/can/bcm.c | 59 +++++++++++++++++++++++++++++++++++++----------- net/can/raw.c | 62 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 94 insertions(+), 27 deletions(-) diff --git a/net/can/bcm.c b/net/can/bcm.c index ffc34e911808..db987a1567ba 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -124,7 +124,7 @@ struct bcm_sock { struct sock sk; int bound; int ifindex; - struct notifier_block notifier; + struct list_head notifier; struct list_head rx_ops; struct list_head tx_ops; unsigned long dropped_usr_msgs; @@ -132,6 +132,10 @@ struct bcm_sock { char procname [32]; /* inode number in decimal with \0 */ }; +static LIST_HEAD(bcm_notifier_list); +static DEFINE_SPINLOCK(bcm_notifier_lock); +static struct bcm_sock *bcm_busy_notifier; + static inline struct bcm_sock *bcm_sk(const struct sock *sk) { return (struct bcm_sock *)sk; @@ -1381,20 +1385,15 @@ static int bcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) /* * notification handler for netdevice status changes */ -static int bcm_notifier(struct notifier_block *nb, unsigned long msg, - void *ptr) +static void bcm_notify(struct bcm_sock *bo, unsigned long msg, + struct net_device *dev) { - struct net_device *dev = netdev_notifier_info_to_dev(ptr); - struct bcm_sock *bo = container_of(nb, struct bcm_sock, notifier); struct sock *sk = &bo->sk; struct bcm_op *op; int notify_enodev = 0; if (!net_eq(dev_net(dev), sock_net(sk))) - return NOTIFY_DONE; - - if (dev->type != ARPHRD_CAN) - return NOTIFY_DONE; + return; switch (msg) { @@ -1429,7 +1428,28 @@ static int bcm_notifier(struct notifier_block *nb, unsigned long msg, sk->sk_error_report(sk); } } +} +static int bcm_notifier(struct notifier_block *nb, unsigned long msg, + void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + + if (dev->type != ARPHRD_CAN) + return NOTIFY_DONE; + if (msg != NETDEV_UNREGISTER && msg != NETDEV_DOWN) + return NOTIFY_DONE; + if (unlikely(bcm_busy_notifier)) /* Check for reentrant bug. */ + return NOTIFY_DONE; + + spin_lock(&bcm_notifier_lock); + list_for_each_entry(bcm_busy_notifier, &bcm_notifier_list, notifier) { + spin_unlock(&bcm_notifier_lock); + bcm_notify(bcm_busy_notifier, msg, dev); + spin_lock(&bcm_notifier_lock); + } + bcm_busy_notifier = NULL; + spin_unlock(&bcm_notifier_lock); return NOTIFY_DONE; } @@ -1449,9 +1469,9 @@ static int bcm_init(struct sock *sk) INIT_LIST_HEAD(&bo->rx_ops); /* set notifier */ - bo->notifier.notifier_call = bcm_notifier; - - register_netdevice_notifier(&bo->notifier); + spin_lock(&bcm_notifier_lock); + list_add_tail(&bo->notifier, &bcm_notifier_list); + spin_unlock(&bcm_notifier_lock); return 0; } @@ -1474,7 +1494,14 @@ static int bcm_release(struct socket *sock) /* remove bcm_ops, timer, rx_unregister(), etc. */ - unregister_netdevice_notifier(&bo->notifier); + spin_lock(&bcm_notifier_lock); + while (bcm_busy_notifier == bo) { + spin_unlock(&bcm_notifier_lock); + schedule_timeout_uninterruptible(1); + spin_lock(&bcm_notifier_lock); + } + list_del(&bo->notifier); + spin_unlock(&bcm_notifier_lock); lock_sock(sk); @@ -1693,6 +1720,10 @@ static struct pernet_operations canbcm_pernet_ops __read_mostly = { .exit = canbcm_pernet_exit, }; +static struct notifier_block canbcm_notifier = { + .notifier_call = bcm_notifier +}; + static int __init bcm_module_init(void) { int err; @@ -1706,12 +1737,14 @@ static int __init bcm_module_init(void) } register_pernet_subsys(&canbcm_pernet_ops); + register_netdevice_notifier(&canbcm_notifier); return 0; } static void __exit bcm_module_exit(void) { can_proto_unregister(&bcm_can_proto); + unregister_netdevice_notifier(&canbcm_notifier); unregister_pernet_subsys(&canbcm_pernet_ops); } diff --git a/net/can/raw.c b/net/can/raw.c index 8d9c6c64e027..6963293e59fd 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -84,7 +84,7 @@ struct raw_sock { struct sock sk; int bound; int ifindex; - struct notifier_block notifier; + struct list_head notifier; int loopback; int recv_own_msgs; int fd_frames; @@ -96,6 +96,10 @@ struct raw_sock { struct uniqframe __percpu *uniq; }; +static LIST_HEAD(raw_notifier_list); +static DEFINE_SPINLOCK(raw_notifier_lock); +static struct raw_sock *raw_busy_notifier; + /* * Return pointer to store the extra msg flags for raw_recvmsg(). * We use the space of one unsigned int beyond the 'struct sockaddr_can' @@ -266,21 +270,16 @@ static int raw_enable_allfilters(struct net *net, struct net_device *dev, return err; } -static int raw_notifier(struct notifier_block *nb, - unsigned long msg, void *ptr) +static void raw_notify(struct raw_sock *ro, unsigned long msg, + struct net_device *dev) { - struct net_device *dev = netdev_notifier_info_to_dev(ptr); - struct raw_sock *ro = container_of(nb, struct raw_sock, notifier); struct sock *sk = &ro->sk; if (!net_eq(dev_net(dev), sock_net(sk))) - return NOTIFY_DONE; - - if (dev->type != ARPHRD_CAN) - return NOTIFY_DONE; + return; if (ro->ifindex != dev->ifindex) - return NOTIFY_DONE; + return; switch (msg) { @@ -309,7 +308,28 @@ static int raw_notifier(struct notifier_block *nb, sk->sk_error_report(sk); break; } +} + +static int raw_notifier(struct notifier_block *nb, unsigned long msg, + void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + + if (dev->type != ARPHRD_CAN) + return NOTIFY_DONE; + if (msg != NETDEV_UNREGISTER && msg != NETDEV_DOWN) + return NOTIFY_DONE; + if (unlikely(raw_busy_notifier)) /* Check for reentrant bug. */ + return NOTIFY_DONE; + spin_lock(&raw_notifier_lock); + list_for_each_entry(raw_busy_notifier, &raw_notifier_list, notifier) { + spin_unlock(&raw_notifier_lock); + raw_notify(raw_busy_notifier, msg, dev); + spin_lock(&raw_notifier_lock); + } + raw_busy_notifier = NULL; + spin_unlock(&raw_notifier_lock); return NOTIFY_DONE; } @@ -338,9 +358,9 @@ static int raw_init(struct sock *sk) return -ENOMEM; /* set notifier */ - ro->notifier.notifier_call = raw_notifier; - - register_netdevice_notifier(&ro->notifier); + spin_lock(&raw_notifier_lock); + list_add_tail(&ro->notifier, &raw_notifier_list); + spin_unlock(&raw_notifier_lock); return 0; } @@ -355,7 +375,14 @@ static int raw_release(struct socket *sock) ro = raw_sk(sk); - unregister_netdevice_notifier(&ro->notifier); + spin_lock(&raw_notifier_lock); + while (raw_busy_notifier == ro) { + spin_unlock(&raw_notifier_lock); + schedule_timeout_uninterruptible(1); + spin_lock(&raw_notifier_lock); + } + list_del(&ro->notifier); + spin_unlock(&raw_notifier_lock); lock_sock(sk); @@ -886,6 +913,10 @@ static const struct can_proto raw_can_proto = { .prot = &raw_proto, }; +static struct notifier_block canraw_notifier = { + .notifier_call = raw_notifier +}; + static __init int raw_module_init(void) { int err; @@ -895,6 +926,8 @@ static __init int raw_module_init(void) err = can_proto_register(&raw_can_proto); if (err < 0) printk(KERN_ERR "can: registration of raw protocol failed\n"); + else + register_netdevice_notifier(&canraw_notifier); return err; } @@ -902,6 +935,7 @@ static __init int raw_module_init(void) static __exit void raw_module_exit(void) { can_proto_unregister(&raw_can_proto); + unregister_netdevice_notifier(&canraw_notifier); } module_init(raw_module_init); -- 2.25.1
1 0
0 0
[PATCH openEuler-22.09 0/9] backport upstream patches for intel v8 SPR
by Zheng Zengkai 27 Aug '22

27 Aug '22
This PR is to add KVM support for SPR new CPU feature, which include bus_lock_detect,bus lock debug exception, avx_vnni and avx512_fp16. Test Boot host with kernel that having KVM support for SPR new instructions and launch a guest VM with kernel that also have the support for SPR new instructions. Then in the guest VM, we can find "bus_lock_detect" "avx_vnni" and "avx512_fp16" in /proc/cpuinfo. And, bus lock debug exception is an ability to notify the kernel by an #DB trap after the instruction acquires a bus lock and is executed when CPL>0. This allows the kernel to enforce user application throttling or mitigations. Existence of bus lock debug exception is enumerated via CPUID.(EAX=7,ECX=0).ECX[24] Known Issue N/A Default config change N/A Arnaldo Carvalho de Melo (1): tools headers UAPI: Sync KVM's kvm.h and vmx.h headers with the kernel sources Cathy Zhang (1): KVM: x86: Expose AVX512_FP16 for supported CPUID Chenyi Qiang (5): KVM: X86: Reset the vcpu->run->flags at the beginning of vcpu_run KVM: VMX: Enable bus lock VM exit KVM: X86: Rename DR6_INIT to DR6_ACTIVE_LOW KVM: X86: Add support for the emulation of DR6_BUS_LOCK bit KVM: nVMX: Fix nested bus lock VM exit Paolo Bonzini (1): KVM: X86: Expose bus lock debug exception to guest Yang Zhong (1): KVM: Expose AVX_VNNI instruction to guset arch/x86/include/asm/kvm_host.h | 20 +++++++-- arch/x86/include/asm/vmx.h | 1 + arch/x86/include/asm/vmxfeatures.h | 1 + arch/x86/include/uapi/asm/kvm.h | 1 + arch/x86/include/uapi/asm/vmx.h | 4 +- arch/x86/kvm/cpuid.c | 6 +-- arch/x86/kvm/emulate.c | 2 +- arch/x86/kvm/svm/nested.c | 2 +- arch/x86/kvm/svm/svm.c | 6 +-- arch/x86/kvm/vmx/capabilities.h | 9 ++++ arch/x86/kvm/vmx/nested.c | 10 ++++- arch/x86/kvm/vmx/vmx.c | 44 ++++++++++++++++-- arch/x86/kvm/vmx/vmx.h | 2 +- arch/x86/kvm/x86.c | 64 ++++++++++++++++++++------- include/uapi/linux/kvm.h | 5 +++ tools/arch/x86/include/uapi/asm/kvm.h | 1 + tools/arch/x86/include/uapi/asm/vmx.h | 4 +- 17 files changed, 147 insertions(+), 35 deletions(-) -- 2.20.1
1 9
0 0
[PATCH openEuler-1.0-LTS] CIFS: Fix retry mid list corruption on reconnects
by Yongqiang Liu 27 Aug '22

27 Aug '22
From: Pavel Shilovsky <pshilov(a)microsoft.com> mainline inclusion from mainline-v5.4-rc5 commit abe57073d08c13b95a46ccf48cc9dc957d5c6fdb category: bugfix bugzilla: 24367, https://gitee.com/openeuler/kernel/issues/I5OE1W CVE: NA -------------------------------- When the client hits reconnect it iterates over the mid pending queue marking entries for retry and moving them to a temporary list to issue callbacks later without holding GlobalMid_Lock. In the same time there is no guarantee that mids can't be removed from the temporary list or even freed completely by another thread. It may cause a temporary list corruption: [ 430.454897] list_del corruption. prev->next should be ffff98d3a8f316c0, but was 2e885cb266355469 [ 430.464668] ------------[ cut here ]------------ [ 430.466569] kernel BUG at lib/list_debug.c:51! [ 430.468476] invalid opcode: 0000 [#1] SMP PTI [ 430.470286] CPU: 0 PID: 13267 Comm: cifsd Kdump: loaded Not tainted 5.4.0-rc3+ #19 [ 430.473472] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 [ 430.475872] RIP: 0010:__list_del_entry_valid.cold+0x31/0x55 ... [ 430.510426] Call Trace: [ 430.511500] cifs_reconnect+0x25e/0x610 [cifs] [ 430.513350] cifs_readv_from_socket+0x220/0x250 [cifs] [ 430.515464] cifs_read_from_socket+0x4a/0x70 [cifs] [ 430.517452] ? try_to_wake_up+0x212/0x650 [ 430.519122] ? cifs_small_buf_get+0x16/0x30 [cifs] [ 430.521086] ? allocate_buffers+0x66/0x120 [cifs] [ 430.523019] cifs_demultiplex_thread+0xdc/0xc30 [cifs] [ 430.525116] kthread+0xfb/0x130 [ 430.526421] ? cifs_handle_standard+0x190/0x190 [cifs] [ 430.528514] ? kthread_park+0x90/0x90 [ 430.530019] ret_from_fork+0x35/0x40 Fix this by obtaining extra references for mids being retried and marking them as MID_DELETED which indicates that such a mid has been dequeued from the pending list. Also move mid cleanup logic from DeleteMidQEntry to _cifs_mid_q_entry_release which is called when the last reference to a particular mid is put. This allows to avoid any use-after-free of response buffers. The patch needs to be backported to stable kernels. A stable tag is not mentioned below because the patch doesn't apply cleanly to any actively maintained stable kernel. Reviewed-by: Ronnie Sahlberg <lsahlber(a)redhat.com> Reviewed-and-tested-by: David Wysochanski <dwysocha(a)redhat.com> Signed-off-by: Pavel Shilovsky <pshilov(a)microsoft.com> Signed-off-by: Steve French <stfrench(a)microsoft.com> conflicts: fs/cifs/connect.c fs/cifs/transport.c Signed-off-by: ChenXiaoSong <chenxiaosong2(a)huawei.com> Reviewed-by: Zhang Yi <yi.zhang(a)huawei.com> Reviewed-by: Jason Yan <yanaijie(a)huawei.com> Signed-off-by: Yongqiang Liu <liuyongqiang13(a)huawei.com> --- fs/cifs/connect.c | 10 +++++++++- fs/cifs/transport.c | 42 +++++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 36104dd8eb4d..976aae1eaf73 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -443,9 +443,11 @@ cifs_reconnect(struct TCP_Server_Info *server) spin_lock(&GlobalMid_Lock); list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { mid_entry = list_entry(tmp, struct mid_q_entry, qhead); + kref_get(&mid_entry->refcount); if (mid_entry->mid_state == MID_REQUEST_SUBMITTED) mid_entry->mid_state = MID_RETRY_NEEDED; list_move(&mid_entry->qhead, &retry_list); + mid_entry->mid_flags |= MID_DELETED; } spin_unlock(&GlobalMid_Lock); mutex_unlock(&server->srv_mutex); @@ -455,6 +457,7 @@ cifs_reconnect(struct TCP_Server_Info *server) mid_entry = list_entry(tmp, struct mid_q_entry, qhead); list_del_init(&mid_entry->qhead); mid_entry->callback(mid_entry); + cifs_mid_q_entry_release(mid_entry); } do { @@ -743,8 +746,10 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed) if (mid->mid_flags & MID_DELETED) printk_once(KERN_WARNING "trying to dequeue a deleted mid\n"); - else + else { list_del_init(&mid->qhead); + mid->mid_flags |= MID_DELETED; + } spin_unlock(&GlobalMid_Lock); } @@ -818,8 +823,10 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { mid_entry = list_entry(tmp, struct mid_q_entry, qhead); cifs_dbg(FYI, "Clearing mid 0x%llx\n", mid_entry->mid); + kref_get(&mid_entry->refcount); mid_entry->mid_state = MID_SHUTDOWN; list_move(&mid_entry->qhead, &dispose_list); + mid_entry->mid_flags |= MID_DELETED; } spin_unlock(&GlobalMid_Lock); @@ -829,6 +836,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) cifs_dbg(FYI, "Callback mid 0x%llx\n", mid_entry->mid); list_del_init(&mid_entry->qhead); mid_entry->callback(mid_entry); + cifs_mid_q_entry_release(mid_entry); } /* 1/8th of sec is more than enough time for them to exit */ msleep(125); diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 59643acb6d67..eb76f7a59e50 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -85,22 +85,8 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server) static void _cifs_mid_q_entry_release(struct kref *refcount) { - struct mid_q_entry *mid = container_of(refcount, struct mid_q_entry, - refcount); - - mempool_free(mid, cifs_mid_poolp); -} - -void cifs_mid_q_entry_release(struct mid_q_entry *midEntry) -{ - spin_lock(&GlobalMid_Lock); - kref_put(&midEntry->refcount, _cifs_mid_q_entry_release); - spin_unlock(&GlobalMid_Lock); -} - -void -DeleteMidQEntry(struct mid_q_entry *midEntry) -{ + struct mid_q_entry *midEntry = + container_of(refcount, struct mid_q_entry, refcount); #ifdef CONFIG_CIFS_STATS2 __le16 command = midEntry->server->vals->lock_cmd; unsigned long now; @@ -135,6 +121,19 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) } } #endif + + mempool_free(midEntry, cifs_mid_poolp); +} + +void cifs_mid_q_entry_release(struct mid_q_entry *midEntry) +{ + spin_lock(&GlobalMid_Lock); + kref_put(&midEntry->refcount, _cifs_mid_q_entry_release); + spin_unlock(&GlobalMid_Lock); +} + +void DeleteMidQEntry(struct mid_q_entry *midEntry) +{ cifs_mid_q_entry_release(midEntry); } @@ -142,8 +141,10 @@ void cifs_delete_mid(struct mid_q_entry *mid) { spin_lock(&GlobalMid_Lock); - list_del_init(&mid->qhead); - mid->mid_flags |= MID_DELETED; + if (!(mid->mid_flags & MID_DELETED)) { + list_del_init(&mid->qhead); + mid->mid_flags |= MID_DELETED; + } spin_unlock(&GlobalMid_Lock); DeleteMidQEntry(mid); @@ -711,7 +712,10 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) rc = -EHOSTDOWN; break; default: - list_del_init(&mid->qhead); + if (!(mid->mid_flags & MID_DELETED)) { + list_del_init(&mid->qhead); + mid->mid_flags |= MID_DELETED; + } cifs_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n", __func__, mid->mid, mid->mid_state); rc = -EIO; -- 2.25.1
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 1583
  • 1584
  • 1585
  • 1586
  • 1587
  • 1588
  • 1589
  • ...
  • 1825
  • Older →

HyperKitty Powered by HyperKitty