From 9c426b770bd088f18899f836093d810a83b59b98 Mon Sep 17 00:00:00 2001 From: Talel Shenhar Date: Mon, 9 Sep 2019 11:39:18 +0300 Subject: [PATCH 001/993] irqchip/al-fic: Add support for irq retrigger Introduce interrupts retrigger support for Amazon's Annapurna Labs Fabric Interrupt Controller. Signed-off-by: Talel Shenhar Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/1568018358-18985-1-git-send-email-talel@amazon.com --- drivers/irqchip/irq-al-fic.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/irqchip/irq-al-fic.c b/drivers/irqchip/irq-al-fic.c index 1a57cee3efab..0b0a73739756 100644 --- a/drivers/irqchip/irq-al-fic.c +++ b/drivers/irqchip/irq-al-fic.c @@ -15,6 +15,7 @@ /* FIC Registers */ #define AL_FIC_CAUSE 0x00 +#define AL_FIC_SET_CAUSE 0x08 #define AL_FIC_MASK 0x10 #define AL_FIC_CONTROL 0x28 @@ -126,6 +127,16 @@ static void al_fic_irq_handler(struct irq_desc *desc) chained_irq_exit(irqchip, desc); } +static int al_fic_irq_retrigger(struct irq_data *data) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); + struct al_fic *fic = gc->private; + + writel_relaxed(BIT(data->hwirq), fic->base + AL_FIC_SET_CAUSE); + + return 1; +} + static int al_fic_register(struct device_node *node, struct al_fic *fic) { @@ -159,6 +170,7 @@ static int al_fic_register(struct device_node *node, gc->chip_types->chip.irq_unmask = irq_gc_mask_clr_bit; gc->chip_types->chip.irq_ack = irq_gc_ack_clr_bit; gc->chip_types->chip.irq_set_type = al_fic_irq_set_type; + gc->chip_types->chip.irq_retrigger = al_fic_irq_retrigger; gc->chip_types->chip.flags = IRQCHIP_SKIP_SET_WAKE; gc->private = fic; -- GitLab From 212fbf2c9e84ceb267cadd8342156b69b54b8135 Mon Sep 17 00:00:00 2001 From: Sandeep Sheriker Mallikarjun Date: Mon, 9 Sep 2019 14:00:35 +0300 Subject: [PATCH 002/993] irqchip/atmel-aic5: Add support for sam9x60 irqchip Add support for SAM9X60 irqchip. Signed-off-by: Sandeep Sheriker Mallikarjun Signed-off-by: Claudiu Beznea Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/1568026835-6646-1-git-send-email-claudiu.beznea@microchip.com [claudiu.beznea@microchip.com: update aic5_irq_fixups[], update documentation] --- .../bindings/interrupt-controller/atmel,aic.txt | 7 +++++-- drivers/irqchip/irq-atmel-aic5.c | 10 ++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt index f4c5d34c4111..7079d44bf3ba 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt @@ -1,8 +1,11 @@ * Advanced Interrupt Controller (AIC) Required properties: -- compatible: Should be "atmel,-aic" - can be "at91rm9200", "sama5d2", "sama5d3" or "sama5d4" +- compatible: Should be: + - "atmel,-aic" where can be "at91rm9200", "sama5d2", + "sama5d3" or "sama5d4" + - "microchip,-aic" where can be "sam9x60" + - interrupt-controller: Identifies the node as an interrupt controller. - #interrupt-cells: The number of cells to define the interrupts. It should be 3. The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet). diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c index 6acad2ea0fb3..29333497ba10 100644 --- a/drivers/irqchip/irq-atmel-aic5.c +++ b/drivers/irqchip/irq-atmel-aic5.c @@ -313,6 +313,7 @@ static void __init sama5d3_aic_irq_fixup(void) static const struct of_device_id aic5_irq_fixups[] __initconst = { { .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup }, { .compatible = "atmel,sama5d4", .data = sama5d3_aic_irq_fixup }, + { .compatible = "microchip,sam9x60", .data = sama5d3_aic_irq_fixup }, { /* sentinel */ }, }; @@ -390,3 +391,12 @@ static int __init sama5d4_aic5_of_init(struct device_node *node, return aic5_of_init(node, parent, NR_SAMA5D4_IRQS); } IRQCHIP_DECLARE(sama5d4_aic5, "atmel,sama5d4-aic", sama5d4_aic5_of_init); + +#define NR_SAM9X60_IRQS 50 + +static int __init sam9x60_aic5_of_init(struct device_node *node, + struct device_node *parent) +{ + return aic5_of_init(node, parent, NR_SAM9X60_IRQS); +} +IRQCHIP_DECLARE(sam9x60_aic5, "microchip,sam9x60-aic", sam9x60_aic5_of_init); -- GitLab From 131cb1210d4b58acb0695707dad2eb90dcb50a2a Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Tue, 17 Sep 2019 17:40:20 +0200 Subject: [PATCH 003/993] regulator: of: fix suspend-min/max-voltage parsing Currently the regulator-suspend-min/max-microvolt must be within the root regulator node but the dt-bindings specifies it as subnode properties for the regulator-state-[mem/disk/standby] node. The only DT using this bindings currently is the at91-sama5d2_xplained.dts and this DT uses it correctly. I don't know if it isn't tested but it can't work without this fix. Fixes: f7efad10b5c4 ("regulator: add PM suspend and resume hooks") Signed-off-by: Marco Felsch Link: https://lore.kernel.org/r/20190917154021.14693-3-m.felsch@pengutronix.de Signed-off-by: Mark Brown --- drivers/regulator/of_regulator.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 9112faa6a9a0..38dd06fbab38 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -231,12 +231,12 @@ static int of_get_regulation_constraints(struct device *dev, "regulator-off-in-suspend")) suspend_state->enabled = DISABLE_IN_SUSPEND; - if (!of_property_read_u32(np, "regulator-suspend-min-microvolt", - &pval)) + if (!of_property_read_u32(suspend_np, + "regulator-suspend-min-microvolt", &pval)) suspend_state->min_uV = pval; - if (!of_property_read_u32(np, "regulator-suspend-max-microvolt", - &pval)) + if (!of_property_read_u32(suspend_np, + "regulator-suspend-max-microvolt", &pval)) suspend_state->max_uV = pval; if (!of_property_read_u32(suspend_np, -- GitLab From f8970d341eec73c976a3462b9ecdb02b60b84dd6 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Tue, 17 Sep 2019 17:40:21 +0200 Subject: [PATCH 004/993] regulator: core: make regulator_register() EPROBE_DEFER aware Sometimes it can happen that the regulator_of_get_init_data() can't retrieve the config due to a not probed device the regulator depends on. Fix that by checking the return value of of_parse_cb() and return EPROBE_DEFER in such cases. Signed-off-by: Marco Felsch Link: https://lore.kernel.org/r/20190917154021.14693-4-m.felsch@pengutronix.de Signed-off-by: Mark Brown --- drivers/regulator/core.c | 13 +++++++++++++ drivers/regulator/of_regulator.c | 19 ++++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index afe94470b67f..a46be221dbdc 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -5053,6 +5053,19 @@ regulator_register(const struct regulator_desc *regulator_desc, init_data = regulator_of_get_init_data(dev, regulator_desc, config, &rdev->dev.of_node); + + /* + * Sometimes not all resources are probed already so we need to take + * that into account. This happens most the time if the ena_gpiod comes + * from a gpio extender or something else. + */ + if (PTR_ERR(init_data) == -EPROBE_DEFER) { + kfree(config); + kfree(rdev); + ret = -EPROBE_DEFER; + goto rinse; + } + /* * We need to keep track of any GPIO descriptor coming from the * device tree until we have handled it over to the core. If the diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 38dd06fbab38..ef7198b76e50 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -445,11 +445,20 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev, goto error; } - if (desc->of_parse_cb && desc->of_parse_cb(child, desc, config)) { - dev_err(dev, - "driver callback failed to parse DT for regulator %pOFn\n", - child); - goto error; + if (desc->of_parse_cb) { + int ret; + + ret = desc->of_parse_cb(child, desc, config); + if (ret) { + if (ret == -EPROBE_DEFER) { + of_node_put(child); + return ERR_PTR(-EPROBE_DEFER); + } + dev_err(dev, + "driver callback failed to parse DT for regulator %pOFn\n", + child); + goto error; + } } *node = child; -- GitLab From c107d613f9204ff9c7624c229938153d7492c56e Mon Sep 17 00:00:00 2001 From: Zenghui Yu Date: Wed, 18 Sep 2019 06:57:30 +0000 Subject: [PATCH 005/993] irqchip/gic-v3: Fix GIC_LINE_NR accessor As per GIC spec, ITLinesNumber indicates the maximum SPI INTID that the GIC implementation supports. And the maximum SPI INTID an implementation might support is 1019 (field value 11111). max(GICD_TYPER_SPIS(...), 1020) is not what we actually want for GIC_LINE_NR. Fix it to min(GICD_TYPER_SPIS(...), 1020). Signed-off-by: Zenghui Yu Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/1568789850-14080-1-git-send-email-yuzenghui@huawei.com --- drivers/irqchip/irq-gic-v3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 422664ac5f53..1edc99335a94 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -59,7 +59,7 @@ static struct gic_chip_data gic_data __read_mostly; static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key); #define GIC_ID_NR (1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer)) -#define GIC_LINE_NR max(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U) +#define GIC_LINE_NR min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U) #define GIC_ESPI_NR GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer) /* -- GitLab From bb0fed1c60cccbe4063b455a7228818395dac86e Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sun, 15 Sep 2019 15:17:45 +0100 Subject: [PATCH 006/993] irqchip/sifive-plic: Switch to fasteoi flow The SiFive PLIC interrupt controller seems to have all the HW features to support the fasteoi flow, but the driver seems to be stuck in a distant past. Bring it into the 21st century. Signed-off-by: Marc Zyngier Tested-by: Palmer Dabbelt (QEMU Boot) Tested-by: Darius Rad (on 2 HW PLIC implementations) Tested-by: Paul Walmsley (HiFive Unleashed) Reviewed-by: Palmer Dabbelt Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/8636gxskmj.wl-maz@kernel.org --- drivers/irqchip/irq-sifive-plic.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c index cf755964f2f8..3e51deedbcc8 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -97,7 +97,7 @@ static inline void plic_irq_toggle(const struct cpumask *mask, } } -static void plic_irq_enable(struct irq_data *d) +static void plic_irq_unmask(struct irq_data *d) { unsigned int cpu = cpumask_any_and(irq_data_get_affinity_mask(d), cpu_online_mask); @@ -106,7 +106,7 @@ static void plic_irq_enable(struct irq_data *d) plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1); } -static void plic_irq_disable(struct irq_data *d) +static void plic_irq_mask(struct irq_data *d) { plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); } @@ -125,10 +125,8 @@ static int plic_set_affinity(struct irq_data *d, if (cpu >= nr_cpu_ids) return -EINVAL; - if (!irqd_irq_disabled(d)) { - plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); - plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1); - } + plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); + plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1); irq_data_update_effective_affinity(d, cpumask_of(cpu)); @@ -136,14 +134,18 @@ static int plic_set_affinity(struct irq_data *d, } #endif +static void plic_irq_eoi(struct irq_data *d) +{ + struct plic_handler *handler = this_cpu_ptr(&plic_handlers); + + writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); +} + static struct irq_chip plic_chip = { .name = "SiFive PLIC", - /* - * There is no need to mask/unmask PLIC interrupts. They are "masked" - * by reading claim and "unmasked" when writing it back. - */ - .irq_enable = plic_irq_enable, - .irq_disable = plic_irq_disable, + .irq_mask = plic_irq_mask, + .irq_unmask = plic_irq_unmask, + .irq_eoi = plic_irq_eoi, #ifdef CONFIG_SMP .irq_set_affinity = plic_set_affinity, #endif @@ -152,7 +154,7 @@ static struct irq_chip plic_chip = { static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq) { - irq_set_chip_and_handler(irq, &plic_chip, handle_simple_irq); + irq_set_chip_and_handler(irq, &plic_chip, handle_fasteoi_irq); irq_set_chip_data(irq, NULL); irq_set_noprobe(irq); return 0; @@ -188,7 +190,6 @@ static void plic_handle_irq(struct pt_regs *regs) hwirq); else generic_handle_irq(irq); - writel(hwirq, claim); } csr_set(sie, SIE_SEIE); } -- GitLab From fb629fa2587d0c150792d87e3053664bfc8dc78c Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 20 Sep 2019 15:02:11 +0200 Subject: [PATCH 007/993] ASoC: samsung: arndale: Add missing OF node dereferencing Ensure there is no OF node references kept when the driver is removed/unbound. Reviewed-by: Charles Keepax Signed-off-by: Sylwester Nawrocki Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20190920130218.32690-3-s.nawrocki@samsung.com Signed-off-by: Mark Brown --- sound/soc/samsung/arndale_rt5631.c | 34 ++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/sound/soc/samsung/arndale_rt5631.c b/sound/soc/samsung/arndale_rt5631.c index c213913eb984..fd8c6642fb0d 100644 --- a/sound/soc/samsung/arndale_rt5631.c +++ b/sound/soc/samsung/arndale_rt5631.c @@ -5,6 +5,7 @@ // Author: Claude #include +#include #include #include @@ -74,6 +75,17 @@ static struct snd_soc_card arndale_rt5631 = { .num_links = ARRAY_SIZE(arndale_rt5631_dai), }; +static void arndale_put_of_nodes(struct snd_soc_card *card) +{ + struct snd_soc_dai_link *dai_link; + int i; + + for_each_card_prelinks(card, i, dai_link) { + of_node_put(dai_link->cpus->of_node); + of_node_put(dai_link->codecs->of_node); + } +} + static int arndale_audio_probe(struct platform_device *pdev) { int n, ret; @@ -103,18 +115,31 @@ static int arndale_audio_probe(struct platform_device *pdev) if (!arndale_rt5631_dai[0].codecs->of_node) { dev_err(&pdev->dev, "Property 'samsung,audio-codec' missing or invalid\n"); - return -EINVAL; + ret = -EINVAL; + goto err_put_of_nodes; } } ret = devm_snd_soc_register_card(card->dev, card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); + goto err_put_of_nodes; + } + return 0; - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret); - +err_put_of_nodes: + arndale_put_of_nodes(card); return ret; } +static int arndale_audio_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + arndale_put_of_nodes(card); + return 0; +} + static const struct of_device_id samsung_arndale_rt5631_of_match[] __maybe_unused = { { .compatible = "samsung,arndale-rt5631", }, { .compatible = "samsung,arndale-alc5631", }, @@ -129,6 +154,7 @@ static struct platform_driver arndale_audio_driver = { .of_match_table = of_match_ptr(samsung_arndale_rt5631_of_match), }, .probe = arndale_audio_probe, + .remove = arndale_audio_remove, }; module_platform_driver(arndale_audio_driver); -- GitLab From ca2347190adb5e4eece73a2b16e96e651c46246b Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 20 Sep 2019 15:02:10 +0200 Subject: [PATCH 008/993] ASoC: wm8994: Do not register inapplicable controls for WM1811 In case of WM1811 device there are currently being registered controls referring to registers not existing on that device. It has been noticed when getting values of "AIF1ADC2 Volume", "AIF1DAC2 Volume" controls was failing during ALSA state restoring at boot time: "amixer: Mixer hw:0 load error: Device or resource busy" Reading some registers through I2C was failing with EBUSY error and indeed these registers were not available according to the datasheet. To fix this controls not available on WM1811 are moved to a separate array and registered only for WM8994 and WM8958. There are some further differences between WM8994 and WM1811, e.g. registers 603h, 604h, 605h, which are not covered in this patch. Acked-by: Charles Keepax Acked-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki Link: https://lore.kernel.org/r/20190920130218.32690-2-s.nawrocki@samsung.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 43 +++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index c3d06e8bc54f..d5fb7f5dd551 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -533,13 +533,10 @@ static SOC_ENUM_SINGLE_DECL(dac_osr, static SOC_ENUM_SINGLE_DECL(adc_osr, WM8994_OVERSAMPLING, 1, osr_text); -static const struct snd_kcontrol_new wm8994_snd_controls[] = { +static const struct snd_kcontrol_new wm8994_common_snd_controls[] = { SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, WM8994_AIF1_ADC1_RIGHT_VOLUME, 1, 119, 0, digital_tlv), -SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME, - WM8994_AIF1_ADC2_RIGHT_VOLUME, - 1, 119, 0, digital_tlv), SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME, WM8994_AIF2_ADC_RIGHT_VOLUME, 1, 119, 0, digital_tlv), @@ -556,8 +553,6 @@ SOC_ENUM("AIF2DACR Source", aif2dacr_src), SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME, WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv), -SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME, - WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv), SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8994_AIF2_DAC_LEFT_VOLUME, WM8994_AIF2_DAC_RIGHT_VOLUME, 1, 96, 0, digital_tlv), @@ -565,17 +560,12 @@ SOC_SINGLE_TLV("AIF1 Boost Volume", WM8994_AIF1_CONTROL_2, 10, 3, 0, aif_tlv), SOC_SINGLE_TLV("AIF2 Boost Volume", WM8994_AIF2_CONTROL_2, 10, 3, 0, aif_tlv), SOC_SINGLE("AIF1DAC1 EQ Switch", WM8994_AIF1_DAC1_EQ_GAINS_1, 0, 1, 0), -SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0), SOC_SINGLE("AIF2 EQ Switch", WM8994_AIF2_EQ_GAINS_1, 0, 1, 0), WM8994_DRC_SWITCH("AIF1DAC1 DRC Switch", WM8994_AIF1_DRC1_1, 2), WM8994_DRC_SWITCH("AIF1ADC1L DRC Switch", WM8994_AIF1_DRC1_1, 1), WM8994_DRC_SWITCH("AIF1ADC1R DRC Switch", WM8994_AIF1_DRC1_1, 0), -WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2), -WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1), -WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0), - WM8994_DRC_SWITCH("AIF2DAC DRC Switch", WM8994_AIF2_DRC_1, 2), WM8994_DRC_SWITCH("AIF2ADCL DRC Switch", WM8994_AIF2_DRC_1, 1), WM8994_DRC_SWITCH("AIF2ADCR DRC Switch", WM8994_AIF2_DRC_1, 0), @@ -594,9 +584,6 @@ SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0), SOC_ENUM("AIF1ADC1 HPF Mode", aif1adc1_hpf), SOC_DOUBLE("AIF1ADC1 HPF Switch", WM8994_AIF1_ADC1_FILTERS, 12, 11, 1, 0), -SOC_ENUM("AIF1ADC2 HPF Mode", aif1adc2_hpf), -SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0), - SOC_ENUM("AIF2ADC HPF Mode", aif2adc_hpf), SOC_DOUBLE("AIF2ADC HPF Switch", WM8994_AIF2_ADC_FILTERS, 12, 11, 1, 0), @@ -637,6 +624,24 @@ SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF2_DAC_FILTERS_2, 8, 1, 0), }; +/* Controls not available on WM1811 */ +static const struct snd_kcontrol_new wm8994_snd_controls[] = { +SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME, + WM8994_AIF1_ADC2_RIGHT_VOLUME, + 1, 119, 0, digital_tlv), +SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME, + WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv), + +SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0), + +WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2), +WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1), +WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0), + +SOC_ENUM("AIF1ADC2 HPF Mode", aif1adc2_hpf), +SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0), +}; + static const struct snd_kcontrol_new wm8994_eq_controls[] = { SOC_SINGLE_TLV("AIF1DAC1 EQ1 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 11, 31, 0, eq_tlv), @@ -4258,13 +4263,15 @@ static int wm8994_component_probe(struct snd_soc_component *component) wm8994_handle_pdata(wm8994); wm_hubs_add_analogue_controls(component); - snd_soc_add_component_controls(component, wm8994_snd_controls, - ARRAY_SIZE(wm8994_snd_controls)); + snd_soc_add_component_controls(component, wm8994_common_snd_controls, + ARRAY_SIZE(wm8994_common_snd_controls)); snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets, ARRAY_SIZE(wm8994_dapm_widgets)); switch (control->type) { case WM8994: + snd_soc_add_component_controls(component, wm8994_snd_controls, + ARRAY_SIZE(wm8994_snd_controls)); snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets, ARRAY_SIZE(wm8994_specific_dapm_widgets)); if (control->revision < 4) { @@ -4284,8 +4291,10 @@ static int wm8994_component_probe(struct snd_soc_component *component) } break; case WM8958: + snd_soc_add_component_controls(component, wm8994_snd_controls, + ARRAY_SIZE(wm8994_snd_controls)); snd_soc_add_component_controls(component, wm8958_snd_controls, - ARRAY_SIZE(wm8958_snd_controls)); + ARRAY_SIZE(wm8958_snd_controls)); snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, ARRAY_SIZE(wm8958_dapm_widgets)); if (control->revision < 1) { -- GitLab From 901e822b2e365dac4727e0ddffb444a2554b0a89 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 23 Sep 2019 17:22:57 +0300 Subject: [PATCH 009/993] ASoC: soc-component: fix a couple missing error assignments There were a couple places where the return value wasn't assigned so the error handling wouldn't trigger. Fixes: 5c0769af4caf ("ASoC: soc-dai: add snd_soc_dai_bespoke_trigger()") Fixes: 95aef3553384 ("ASoC: soc-dai: add snd_soc_dai_trigger()") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/20190923142257.GB31251@mwanda Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index e163dde5eab1..a1b99ac57d9e 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1070,7 +1070,7 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) return ret; } - snd_soc_dai_trigger(cpu_dai, substream, cmd); + ret = snd_soc_dai_trigger(cpu_dai, substream, cmd); if (ret < 0) return ret; @@ -1097,7 +1097,7 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream, return ret; } - snd_soc_dai_bespoke_trigger(cpu_dai, substream, cmd); + ret = snd_soc_dai_bespoke_trigger(cpu_dai, substream, cmd); if (ret < 0) return ret; -- GitLab From 1d6db22ff7d67a17c571543c69c63b1d261249b0 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 22 Sep 2019 10:29:28 +0800 Subject: [PATCH 010/993] regulator: fixed: Prevent NULL pointer dereference when !CONFIG_OF Use of_device_get_match_data which has NULL test for match before dereference match->data. Add NULL test for drvtype so it still works for fixed_voltage_ops when !CONFIG_OF. Signed-off-by: Axel Lin Reviewed-by: Philippe Schenker Link: https://lore.kernel.org/r/20190922022928.28355-1-axel.lin@ingics.com Signed-off-by: Mark Brown --- drivers/regulator/fixed.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index d90a6fd8cbc7..f81533070058 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -144,8 +144,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct fixed_voltage_config *config; struct fixed_voltage_data *drvdata; - const struct fixed_dev_type *drvtype = - of_match_device(dev->driver->of_match_table, dev)->data; + const struct fixed_dev_type *drvtype = of_device_get_match_data(dev); struct regulator_config cfg = { }; enum gpiod_flags gflags; int ret; @@ -177,7 +176,7 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) drvdata->desc.type = REGULATOR_VOLTAGE; drvdata->desc.owner = THIS_MODULE; - if (drvtype->has_enable_clock) { + if (drvtype && drvtype->has_enable_clock) { drvdata->desc.ops = &fixed_voltage_clkenabled_ops; drvdata->enable_clock = devm_clk_get(dev, NULL); -- GitLab From 58283636a5a03e64ad5d03bd282e3b66dcfa2c49 Mon Sep 17 00:00:00 2001 From: Philippe Schenker Date: Mon, 23 Sep 2019 08:18:49 +0000 Subject: [PATCH 011/993] dt-bindings: fixed-regulator: fix compatible enum Remove 'const:' in the compatible enum. This was breaking make dt_binding_check since it has more than one compatible string. Fixes: 9c86d003d620 ("dt-bindings: regulator: add regulator-fixed-clock binding") Signed-off-by: Philippe Schenker Link: https://lore.kernel.org/r/20190923081840.23391-1-philippe.schenker@toradex.com Signed-off-by: Mark Brown --- .../devicetree/bindings/regulator/fixed-regulator.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml b/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml index a78150c47aa2..f32416968197 100644 --- a/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/fixed-regulator.yaml @@ -30,8 +30,8 @@ if: properties: compatible: enum: - - const: regulator-fixed - - const: regulator-fixed-clock + - regulator-fixed + - regulator-fixed-clock regulator-name: true -- GitLab From a72865f057820ea9f57597915da4b651d65eb92f Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Tue, 17 Sep 2019 14:42:42 +0200 Subject: [PATCH 012/993] regulator: da9062: fix suspend_enable/disable preparation Currently the suspend reg_field maps to the pmic voltage selection bits and is used during suspend_enabe/disable() and during get_mode(). This seems to be wrong for both use cases. Use case one (suspend_enabe/disable): Those callbacks are used to mark a regulator device as enabled/disabled during suspend. Marking the regulator enabled during suspend is done by the LDOx_CONF/BUCKx_CONF bit within the LDOx_CONT/BUCKx_CONT registers. Setting this bit tells the DA9062 PMIC state machine to keep the regulator on in POWERDOWN mode and switch to suspend voltage. Use case two (get_mode): The get_mode callback is used to retrieve the active mode state. Since the regulator-setting-A is used for the active state and regulator-setting-B for the suspend state there is no need to check which regulator setting is active. Fixes: 4068e5182ada ("regulator: da9062: DA9062 regulator driver") Signed-off-by: Marco Felsch Reviewed-by: Adam Thomson Link: https://lore.kernel.org/r/20190917124246.11732-2-m.felsch@pengutronix.de Signed-off-by: Mark Brown --- drivers/regulator/da9062-regulator.c | 118 +++++++++++---------------- 1 file changed, 47 insertions(+), 71 deletions(-) diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c index 56f3f72d7707..710e67081d53 100644 --- a/drivers/regulator/da9062-regulator.c +++ b/drivers/regulator/da9062-regulator.c @@ -136,7 +136,6 @@ static int da9062_buck_set_mode(struct regulator_dev *rdev, unsigned mode) static unsigned da9062_buck_get_mode(struct regulator_dev *rdev) { struct da9062_regulator *regl = rdev_get_drvdata(rdev); - struct regmap_field *field; unsigned int val, mode = 0; int ret; @@ -158,18 +157,7 @@ static unsigned da9062_buck_get_mode(struct regulator_dev *rdev) return REGULATOR_MODE_NORMAL; } - /* Detect current regulator state */ - ret = regmap_field_read(regl->suspend, &val); - if (ret < 0) - return 0; - - /* Read regulator mode from proper register, depending on state */ - if (val) - field = regl->suspend_sleep; - else - field = regl->sleep; - - ret = regmap_field_read(field, &val); + ret = regmap_field_read(regl->sleep, &val); if (ret < 0) return 0; @@ -208,21 +196,9 @@ static int da9062_ldo_set_mode(struct regulator_dev *rdev, unsigned mode) static unsigned da9062_ldo_get_mode(struct regulator_dev *rdev) { struct da9062_regulator *regl = rdev_get_drvdata(rdev); - struct regmap_field *field; int ret, val; - /* Detect current regulator state */ - ret = regmap_field_read(regl->suspend, &val); - if (ret < 0) - return 0; - - /* Read regulator mode from proper register, depending on state */ - if (val) - field = regl->suspend_sleep; - else - field = regl->sleep; - - ret = regmap_field_read(field, &val); + ret = regmap_field_read(regl->sleep, &val); if (ret < 0) return 0; @@ -408,10 +384,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { __builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1), - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_BUCK1_CONT, + __builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1), }, { .desc.id = DA9061_ID_BUCK2, @@ -444,10 +420,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { __builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1), - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_BUCK3_CONT, + __builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1), }, { .desc.id = DA9061_ID_BUCK3, @@ -480,10 +456,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { __builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1), - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_BUCK4_CONT, + __builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1), }, { .desc.id = DA9061_ID_LDO1, @@ -509,10 +485,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1), .suspend_vsel_reg = DA9062AA_VLDO1_B, - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_LDO1_CONT, + __builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1), .oc_event = REG_FIELD(DA9062AA_STATUS_D, __builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1, sizeof(unsigned int) * 8 - @@ -542,10 +518,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1), .suspend_vsel_reg = DA9062AA_VLDO2_B, - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_LDO2_CONT, + __builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1), .oc_event = REG_FIELD(DA9062AA_STATUS_D, __builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1, sizeof(unsigned int) * 8 - @@ -575,10 +551,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1), .suspend_vsel_reg = DA9062AA_VLDO3_B, - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_LDO3_CONT, + __builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1), .oc_event = REG_FIELD(DA9062AA_STATUS_D, __builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1, sizeof(unsigned int) * 8 - @@ -608,10 +584,10 @@ static const struct da9062_regulator_info local_da9061_regulator_info[] = { sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1), .suspend_vsel_reg = DA9062AA_VLDO4_B, - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_LDO4_CONT, + __builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1), .oc_event = REG_FIELD(DA9062AA_STATUS_D, __builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1, sizeof(unsigned int) * 8 - @@ -652,10 +628,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { __builtin_ffs((int)DA9062AA_BUCK1_MODE_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_BUCK1_MODE_MASK)) - 1), - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VBUCK1_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_BUCK1_CONT, + __builtin_ffs((int)DA9062AA_BUCK1_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VBUCK1_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_BUCK1_CONF_MASK) - 1), }, { .desc.id = DA9062_ID_BUCK2, @@ -688,10 +664,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { __builtin_ffs((int)DA9062AA_BUCK2_MODE_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_BUCK2_MODE_MASK)) - 1), - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VBUCK2_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_BUCK2_CONT, + __builtin_ffs((int)DA9062AA_BUCK2_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VBUCK2_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_BUCK2_CONF_MASK) - 1), }, { .desc.id = DA9062_ID_BUCK3, @@ -724,10 +700,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { __builtin_ffs((int)DA9062AA_BUCK3_MODE_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_BUCK3_MODE_MASK)) - 1), - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VBUCK3_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_BUCK3_CONT, + __builtin_ffs((int)DA9062AA_BUCK3_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VBUCK3_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_BUCK3_CONF_MASK) - 1), }, { .desc.id = DA9062_ID_BUCK4, @@ -760,10 +736,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { __builtin_ffs((int)DA9062AA_BUCK4_MODE_MASK) - 1, sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_BUCK4_MODE_MASK)) - 1), - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VBUCK4_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_BUCK4_CONT, + __builtin_ffs((int)DA9062AA_BUCK4_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VBUCK4_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_BUCK4_CONF_MASK) - 1), }, { .desc.id = DA9062_ID_LDO1, @@ -789,10 +765,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_LDO1_SL_B_MASK)) - 1), .suspend_vsel_reg = DA9062AA_VLDO1_B, - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VLDO1_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_LDO1_CONT, + __builtin_ffs((int)DA9062AA_LDO1_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VLDO1_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_LDO1_CONF_MASK) - 1), .oc_event = REG_FIELD(DA9062AA_STATUS_D, __builtin_ffs((int)DA9062AA_LDO1_ILIM_MASK) - 1, sizeof(unsigned int) * 8 - @@ -822,10 +798,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_LDO2_SL_B_MASK)) - 1), .suspend_vsel_reg = DA9062AA_VLDO2_B, - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VLDO2_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_LDO2_CONT, + __builtin_ffs((int)DA9062AA_LDO2_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VLDO2_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_LDO2_CONF_MASK) - 1), .oc_event = REG_FIELD(DA9062AA_STATUS_D, __builtin_ffs((int)DA9062AA_LDO2_ILIM_MASK) - 1, sizeof(unsigned int) * 8 - @@ -855,10 +831,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_LDO3_SL_B_MASK)) - 1), .suspend_vsel_reg = DA9062AA_VLDO3_B, - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VLDO3_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_LDO3_CONT, + __builtin_ffs((int)DA9062AA_LDO3_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VLDO3_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_LDO3_CONF_MASK) - 1), .oc_event = REG_FIELD(DA9062AA_STATUS_D, __builtin_ffs((int)DA9062AA_LDO3_ILIM_MASK) - 1, sizeof(unsigned int) * 8 - @@ -888,10 +864,10 @@ static const struct da9062_regulator_info local_da9062_regulator_info[] = { sizeof(unsigned int) * 8 - __builtin_clz((DA9062AA_LDO4_SL_B_MASK)) - 1), .suspend_vsel_reg = DA9062AA_VLDO4_B, - .suspend = REG_FIELD(DA9062AA_DVC_1, - __builtin_ffs((int)DA9062AA_VLDO4_SEL_MASK) - 1, + .suspend = REG_FIELD(DA9062AA_LDO4_CONT, + __builtin_ffs((int)DA9062AA_LDO4_CONF_MASK) - 1, sizeof(unsigned int) * 8 - - __builtin_clz((DA9062AA_VLDO4_SEL_MASK)) - 1), + __builtin_clz(DA9062AA_LDO4_CONF_MASK) - 1), .oc_event = REG_FIELD(DA9062AA_STATUS_D, __builtin_ffs((int)DA9062AA_LDO4_ILIM_MASK) - 1, sizeof(unsigned int) * 8 - -- GitLab From 82a9ac7130cf51c2640800fb0ef19d3a05cb8fff Mon Sep 17 00:00:00 2001 From: Steffen Maier Date: Wed, 7 Aug 2019 16:49:47 +0200 Subject: [PATCH 013/993] scsi: core: fix missing .cleanup_rq for SCSI hosts without request batching This was missing from scsi_mq_ops_no_commit of linux-next commit 8930a6c20791 ("scsi: core: add support for request batching") from Martin's scsi/5.4/scsi-queue or James' scsi/misc. See also linux-next commit b7e9e1fb7a92 ("scsi: implement .cleanup_rq callback") from block/for-next. Signed-off-by: Steffen Maier Fixes: 8930a6c20791 ("scsi: core: add support for request batching") Cc: Paolo Bonzini Cc: Ming Lei Reviewed-by: Paolo Bonzini Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index dc210b9d4896..12db0c13a927 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1834,6 +1834,7 @@ static const struct blk_mq_ops scsi_mq_ops_no_commit = { .init_request = scsi_mq_init_request, .exit_request = scsi_mq_exit_request, .initialize_rq_fn = scsi_initialize_rq, + .cleanup_rq = scsi_cleanup_rq, .busy = scsi_mq_lld_busy, .map_queues = scsi_map_queues, }; -- GitLab From 6b6fa7a5c86e1269d9f0c9a5b902072351317387 Mon Sep 17 00:00:00 2001 From: Steffen Maier Date: Wed, 7 Aug 2019 16:49:48 +0200 Subject: [PATCH 014/993] scsi: core: fix dh and multipathing for SCSI hosts without request batching This was missing from scsi_device_from_queue() due to the introduction of another new scsi_mq_ops_no_commit of linux-next commit 8930a6c20791 ("scsi: core: add support for request batching") from Martin's scsi/5.4/scsi-queue or James' scsi/misc. Only devicehandler code seems to call scsi_device_from_queue(): *** drivers/scsi/scsi_dh.c: scsi_dh_activate[255] sdev = scsi_device_from_queue(q); scsi_dh_set_params[302] sdev = scsi_device_from_queue(q); scsi_dh_attach[325] sdev = scsi_device_from_queue(q); scsi_dh_attached_handler_name[363] sdev = scsi_device_from_queue(q); Fixes multipath tools follow-on errors: $ multipath -v6 ... libdevmapper: ioctl/libdm-iface.c(1887): device-mapper: reload ioctl on mpatha failed: No such device ... mpatha: failed to load map, error 19 ... showing also as kernel messages: device-mapper: table: 252:0: multipath: error attaching hardware handler device-mapper: ioctl: error adding target to table Signed-off-by: Steffen Maier Fixes: 8930a6c20791 ("scsi: core: add support for request batching") Cc: Paolo Bonzini Reviewed-by: Paolo Bonzini Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 12db0c13a927..5447738906ac 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1922,7 +1922,8 @@ struct scsi_device *scsi_device_from_queue(struct request_queue *q) { struct scsi_device *sdev = NULL; - if (q->mq_ops == &scsi_mq_ops) + if (q->mq_ops == &scsi_mq_ops_no_commit || + q->mq_ops == &scsi_mq_ops) sdev = q->queuedata; if (!sdev || !get_device(&sdev->sdev_gendev)) sdev = NULL; -- GitLab From 752c938a5c14b8cbf0ed3ffbfa637fb166255c3f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 25 Sep 2019 14:06:24 +0300 Subject: [PATCH 015/993] ASoC: topology: Fix a signedness bug in soc_tplg_dapm_widget_create() The "template.id" variable is an enum and in this context GCC will treat it as an unsigned int so it can never be less than zero. Fixes: 8a9782346dcc ("ASoC: topology: Add topology core") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/20190925110624.GR3264@mwanda Signed-off-by: Mark Brown --- sound/soc/soc-topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index b8690715abb5..c25939c5611b 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -1588,7 +1588,7 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, /* map user to kernel widget ID */ template.id = get_widget_id(le32_to_cpu(w->id)); - if (template.id < 0) + if ((int)template.id < 0) return template.id; /* strings are allocated here, but used and freed by the widget */ -- GitLab From 55d554f5d14071f7c2c5dbd88d0a2eb695c97d16 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Thu, 26 Sep 2019 19:13:44 -0600 Subject: [PATCH 016/993] tools: bpf: Use !building_out_of_srctree to determine srctree make TARGETS=bpf kselftest fails with: Makefile:127: tools/build/Makefile.include: No such file or directory When the bpf tool make is invoked from tools Makefile, srctree is cleared and the current logic check for srctree equals to empty string to determine srctree location from CURDIR. When the build in invoked from selftests/bpf Makefile, the srctree is set to "." and the same logic used for srctree equals to empty is needed to determine srctree. Check building_out_of_srctree undefined as the condition for both cases to fix "make TARGETS=bpf kselftest" build failure. Signed-off-by: Shuah Khan Signed-off-by: Daniel Borkmann Acked-by: Song Liu Link: https://lore.kernel.org/bpf/20190927011344.4695-1-skhan@linuxfoundation.org --- tools/bpf/Makefile | 6 +++++- tools/lib/bpf/Makefile | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/bpf/Makefile b/tools/bpf/Makefile index fbf5e4a0cb9c..5d1995fd369c 100644 --- a/tools/bpf/Makefile +++ b/tools/bpf/Makefile @@ -12,7 +12,11 @@ INSTALL ?= install CFLAGS += -Wall -O2 CFLAGS += -D__EXPORTED_HEADERS__ -I$(srctree)/include/uapi -I$(srctree)/include -ifeq ($(srctree),) +# This will work when bpf is built in tools env. where srctree +# isn't set and when invoked from selftests build, where srctree +# is set to ".". building_out_of_srctree is undefined for in srctree +# builds +ifndef building_out_of_srctree srctree := $(patsubst %/,%,$(dir $(CURDIR))) srctree := $(patsubst %/,%,$(dir $(srctree))) endif diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index c6f94cffe06e..20772663d3e1 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -8,7 +8,11 @@ LIBBPF_MAJOR_VERSION := $(firstword $(subst ., ,$(LIBBPF_VERSION))) MAKEFLAGS += --no-print-directory -ifeq ($(srctree),) +# This will work when bpf is built in tools env. where srctree +# isn't set and when invoked from selftests build, where srctree +# is a ".". building_out_of_srctree is undefined for in srctree +# builds +ifndef building_out_of_srctree srctree := $(patsubst %/,%,$(dir $(CURDIR))) srctree := $(patsubst %/,%,$(dir $(srctree))) srctree := $(patsubst %/,%,$(dir $(srctree))) -- GitLab From 2511366797fa6ab4a404b4b000ef7cd262aaafe8 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Mon, 9 Sep 2019 20:42:35 +0200 Subject: [PATCH 017/993] arm64: dts: allwinner: a64: pine64-plus: Add PHY regulator delay Depending on kernel and bootloader configuration, it's possible that Realtek ethernet PHY isn't powered on properly. According to the datasheet, it needs 30ms to power up and then some more time before it can be used. Fix that by adding 100ms ramp delay to regulator responsible for powering PHY. Fixes: 94dcfdc77fc5 ("arm64: allwinner: pine64-plus: Enable dwmac-sun8i") Suggested-by: Ondrej Jirman Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts index 24f1aac366d6..d5b6e8159a33 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts @@ -63,3 +63,12 @@ reg = <1>; }; }; + +®_dc1sw { + /* + * Ethernet PHY needs 30ms to properly power up and some more + * to initialize. 100ms should be plenty of time to finish + * whole process. + */ + regulator-enable-ramp-delay = <100000>; +}; -- GitLab From ed3e9406bcbc32f84dc4aa4cb4767852e5ab086c Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Tue, 6 Aug 2019 07:01:35 -0700 Subject: [PATCH 018/993] arm64: dts: allwinner: a64: Drop PMU node Looks like PMU in A64 is broken, it generates no interrupts at all and as result 'perf top' shows no events. Tested on Pine64-LTS. Fixes: 34a97fcc71c2 ("arm64: dts: allwinner: a64: Add PMU node") Cc: Harald Geyer Cc: Jared D. McNeill Signed-off-by: Vasily Khoruzhick Reviewed-by: Emmanuel Vadot Signed-off-by: Maxime Ripard --- arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 9 --------- 1 file changed, 9 deletions(-) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index 69128a6dfc46..d0028934e11c 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -142,15 +142,6 @@ clock-output-names = "ext-osc32k"; }; - pmu { - compatible = "arm,cortex-a53-pmu"; - interrupts = , - , - , - ; - interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; - }; - psci { compatible = "arm,psci-0.2"; method = "smc"; -- GitLab From ccdf3aaa27ded6db9a93eed3ca7468bb2353b8fe Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sun, 29 Sep 2019 10:52:59 +0200 Subject: [PATCH 019/993] arm64: dts: allwinner: a64: sopine-baseboard: Add PHY regulator delay It turns out that sopine-baseboard needs same fix as pine64-plus for ethernet PHY. Here too Realtek ethernet PHY chip needs additional power on delay to properly initialize. Datasheet mentions that chip needs 30 ms to be properly powered on and that it needs some more time to be initialized. Fix that by adding 100ms ramp delay to regulator responsible for powering PHY. Note that issue was found out and fix tested on pine64-lts, but it's basically the same as sopine-baseboard, only layout and connectors differ. Fixes: bdfe4cebea11 ("arm64: allwinner: a64: add Ethernet PHY regulator for several boards") Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- .../boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts index e6fb9683f213..25099202c52c 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts @@ -159,6 +159,12 @@ }; ®_dc1sw { + /* + * Ethernet PHY needs 30ms to properly power up and some more + * to initialize. 100ms should be plenty of time to finish + * whole process. + */ + regulator-enable-ramp-delay = <100000>; regulator-name = "vcc-phy"; }; -- GitLab From 1bd63524593b964934a33afd442df16b8f90e2b5 Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Mon, 30 Sep 2019 14:02:03 -0700 Subject: [PATCH 020/993] libbpf: handle symbol versioning properly for libbpf.a bcc uses libbpf repo as a submodule. It brings in libbpf source code and builds everything together to produce shared libraries. With latest libbpf, I got the following errors: /bin/ld: libbcc_bpf.so.0.10.0: version node not found for symbol xsk_umem__create@LIBBPF_0.0.2 /bin/ld: failed to set dynamic section sizes: Bad value collect2: error: ld returned 1 exit status make[2]: *** [src/cc/libbcc_bpf.so.0.10.0] Error 1 In xsk.c, we have asm(".symver xsk_umem__create_v0_0_2, xsk_umem__create@LIBBPF_0.0.2"); asm(".symver xsk_umem__create_v0_0_4, xsk_umem__create@@LIBBPF_0.0.4"); The linker thinks the built is for LIBBPF but cannot find proper version LIBBPF_0.0.2/4, so emit errors. I also confirmed that using libbpf.a to produce a shared library also has issues: -bash-4.4$ cat t.c extern void *xsk_umem__create; void * test() { return xsk_umem__create; } -bash-4.4$ gcc -c -fPIC t.c -bash-4.4$ gcc -shared t.o libbpf.a -o t.so /bin/ld: t.so: version node not found for symbol xsk_umem__create@LIBBPF_0.0.2 /bin/ld: failed to set dynamic section sizes: Bad value collect2: error: ld returned 1 exit status -bash-4.4$ Symbol versioning does happens in commonly used libraries, e.g., elfutils and glibc. For static libraries, for a versioned symbol, the old definitions will be ignored, and the symbol will be an alias to the latest definition. For example, glibc sched_setaffinity is versioned. -bash-4.4$ readelf -s /usr/lib64/libc.so.6 | grep sched_setaffinity 756: 000000000013d3d0 13 FUNC GLOBAL DEFAULT 13 sched_setaffinity@GLIBC_2.3.3 757: 00000000000e2e70 455 FUNC GLOBAL DEFAULT 13 sched_setaffinity@@GLIBC_2.3.4 1800: 0000000000000000 0 FILE LOCAL DEFAULT ABS sched_setaffinity.c 4228: 00000000000e2e70 455 FUNC LOCAL DEFAULT 13 __sched_setaffinity_new 4648: 000000000013d3d0 13 FUNC LOCAL DEFAULT 13 __sched_setaffinity_old 7338: 000000000013d3d0 13 FUNC GLOBAL DEFAULT 13 sched_setaffinity@GLIBC_2 7380: 00000000000e2e70 455 FUNC GLOBAL DEFAULT 13 sched_setaffinity@@GLIBC_ -bash-4.4$ For static library, the definition of sched_setaffinity aliases to the new definition. -bash-4.4$ readelf -s /usr/lib64/libc.a | grep sched_setaffinity File: /usr/lib64/libc.a(sched_setaffinity.o) 8: 0000000000000000 455 FUNC GLOBAL DEFAULT 1 __sched_setaffinity_new 12: 0000000000000000 455 FUNC WEAK DEFAULT 1 sched_setaffinity For both elfutils and glibc, additional macros are used to control different handling of symbol versioning w.r.t static and shared libraries. For elfutils, the macro is SYMBOL_VERSIONING (https://sourceware.org/git/?p=elfutils.git;a=blob;f=lib/eu-config.h). For glibc, the macro is SHARED (https://sourceware.org/git/?p=glibc.git;a=blob;f=include/shlib-compat.h;hb=refs/heads/master) This patch used SHARED as the macro name. After this patch, the libbpf.a has -bash-4.4$ readelf -s libbpf.a | grep xsk_umem__create 372: 0000000000017145 1190 FUNC GLOBAL DEFAULT 1 xsk_umem__create_v0_0_4 405: 0000000000017145 1190 FUNC GLOBAL DEFAULT 1 xsk_umem__create 499: 00000000000175eb 103 FUNC GLOBAL DEFAULT 1 xsk_umem__create_v0_0_2 -bash-4.4$ No versioned symbols for xsk_umem__create. The libbpf.a can be used to build a shared library succesfully. -bash-4.4$ cat t.c extern void *xsk_umem__create; void * test() { return xsk_umem__create; } -bash-4.4$ gcc -c -fPIC t.c -bash-4.4$ gcc -shared t.o libbpf.a -o t.so -bash-4.4$ Fixes: 10d30e301732 ("libbpf: add flags to umem config") Cc: Kevin Laatz Cc: Arnaldo Carvalho de Melo Cc: Andrii Nakryiko Acked-by: Andrii Nakryiko Signed-off-by: Yonghong Song Signed-off-by: Alexei Starovoitov --- tools/lib/bpf/Makefile | 27 ++++++++++++++++++--------- tools/lib/bpf/libbpf_internal.h | 16 ++++++++++++++++ tools/lib/bpf/xsk.c | 4 ++-- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 20772663d3e1..56ce6292071b 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -114,6 +114,9 @@ override CFLAGS += $(INCLUDES) override CFLAGS += -fvisibility=hidden override CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 +# flags specific for shared library +SHLIB_FLAGS := -DSHARED + ifeq ($(VERBOSE),1) Q = else @@ -130,14 +133,17 @@ all: export srctree OUTPUT CC LD CFLAGS V include $(srctree)/tools/build/Makefile.include -BPF_IN := $(OUTPUT)libbpf-in.o +SHARED_OBJDIR := $(OUTPUT)sharedobjs/ +STATIC_OBJDIR := $(OUTPUT)staticobjs/ +BPF_IN_SHARED := $(SHARED_OBJDIR)libbpf-in.o +BPF_IN_STATIC := $(STATIC_OBJDIR)libbpf-in.o VERSION_SCRIPT := libbpf.map LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET)) LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) PC_FILE := $(addprefix $(OUTPUT),$(PC_FILE)) -GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN) | \ +GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN_SHARED) | \ cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \ awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}' | \ sort -u | wc -l) @@ -159,7 +165,7 @@ all: fixdep all_cmd: $(CMD_TARGETS) check -$(BPF_IN): force elfdep bpfdep +$(BPF_IN_SHARED): force elfdep bpfdep @(test -f ../../include/uapi/linux/bpf.h -a -f ../../../include/uapi/linux/bpf.h && ( \ (diff -B ../../include/uapi/linux/bpf.h ../../../include/uapi/linux/bpf.h >/dev/null) || \ echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf.h' differs from latest version at 'include/uapi/linux/bpf.h'" >&2 )) || true @@ -175,17 +181,20 @@ $(BPF_IN): force elfdep bpfdep @(test -f ../../include/uapi/linux/if_xdp.h -a -f ../../../include/uapi/linux/if_xdp.h && ( \ (diff -B ../../include/uapi/linux/if_xdp.h ../../../include/uapi/linux/if_xdp.h >/dev/null) || \ echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_xdp.h' differs from latest version at 'include/uapi/linux/if_xdp.h'" >&2 )) || true - $(Q)$(MAKE) $(build)=libbpf + $(Q)$(MAKE) $(build)=libbpf OUTPUT=$(SHARED_OBJDIR) CFLAGS="$(CFLAGS) $(SHLIB_FLAGS)" + +$(BPF_IN_STATIC): force elfdep bpfdep + $(Q)$(MAKE) $(build)=libbpf OUTPUT=$(STATIC_OBJDIR) $(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION) -$(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN) +$(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN_SHARED) $(QUIET_LINK)$(CC) --shared -Wl,-soname,libbpf.so.$(LIBBPF_MAJOR_VERSION) \ -Wl,--version-script=$(VERSION_SCRIPT) $^ -lelf -o $@ @ln -sf $(@F) $(OUTPUT)libbpf.so @ln -sf $(@F) $(OUTPUT)libbpf.so.$(LIBBPF_MAJOR_VERSION) -$(OUTPUT)libbpf.a: $(BPF_IN) +$(OUTPUT)libbpf.a: $(BPF_IN_STATIC) $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ $(OUTPUT)test_libbpf: test_libbpf.cpp $(OUTPUT)libbpf.a @@ -201,7 +210,7 @@ check: check_abi check_abi: $(OUTPUT)libbpf.so @if [ "$(GLOBAL_SYM_COUNT)" != "$(VERSIONED_SYM_COUNT)" ]; then \ - echo "Warning: Num of global symbols in $(BPF_IN)" \ + echo "Warning: Num of global symbols in $(BPF_IN_SHARED)" \ "($(GLOBAL_SYM_COUNT)) does NOT match with num of" \ "versioned symbols in $^ ($(VERSIONED_SYM_COUNT))." \ "Please make sure all LIBBPF_API symbols are" \ @@ -259,9 +268,9 @@ config-clean: $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null clean: - $(call QUIET_CLEAN, libbpf) $(RM) $(TARGETS) $(CXX_TEST_TARGET) \ + $(call QUIET_CLEAN, libbpf) $(RM) -rf $(TARGETS) $(CXX_TEST_TARGET) \ *.o *~ *.a *.so *.so.$(LIBBPF_MAJOR_VERSION) .*.d .*.cmd \ - *.pc LIBBPF-CFLAGS + *.pc LIBBPF-CFLAGS $(SHARED_OBJDIR) $(STATIC_OBJDIR) $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h index 2e83a34f8c79..98216a69c32f 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -34,6 +34,22 @@ (offsetof(TYPE, FIELD) + sizeof(((TYPE *)0)->FIELD)) #endif +/* Symbol versioning is different between static and shared library. + * Properly versioned symbols are needed for shared library, but + * only the symbol of the new version is needed for static library. + */ +#ifdef SHARED +# define COMPAT_VERSION(internal_name, api_name, version) \ + asm(".symver " #internal_name "," #api_name "@" #version); +# define DEFAULT_VERSION(internal_name, api_name, version) \ + asm(".symver " #internal_name "," #api_name "@@" #version); +#else +# define COMPAT_VERSION(internal_name, api_name, version) +# define DEFAULT_VERSION(internal_name, api_name, version) \ + extern typeof(internal_name) api_name \ + __attribute__((alias(#internal_name))); +#endif + extern void libbpf_print(enum libbpf_print_level level, const char *format, ...) __attribute__((format(printf, 2, 3))); diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c index 24fa313524fb..a902838f9fcc 100644 --- a/tools/lib/bpf/xsk.c +++ b/tools/lib/bpf/xsk.c @@ -261,8 +261,8 @@ int xsk_umem__create_v0_0_2(struct xsk_umem **umem_ptr, void *umem_area, return xsk_umem__create_v0_0_4(umem_ptr, umem_area, size, fill, comp, &config); } -asm(".symver xsk_umem__create_v0_0_2, xsk_umem__create@LIBBPF_0.0.2"); -asm(".symver xsk_umem__create_v0_0_4, xsk_umem__create@@LIBBPF_0.0.4"); +COMPAT_VERSION(xsk_umem__create_v0_0_2, xsk_umem__create, LIBBPF_0.0.2) +DEFAULT_VERSION(xsk_umem__create_v0_0_4, xsk_umem__create, LIBBPF_0.0.4) static int xsk_load_xdp_prog(struct xsk_socket *xsk) { -- GitLab From 965f6603e3335a953f4f876792074cb36bf65f7f Mon Sep 17 00:00:00 2001 From: Rayagonda Kokatanur Date: Mon, 9 Sep 2019 14:05:27 +0530 Subject: [PATCH 021/993] arm64: dts: Fix gpio to pinmux mapping There are total of 151 non-secure gpio (0-150) and four pins of pinmux (91, 92, 93 and 94) are not mapped to any gpio pin, hence update same in DT. Fixes: 8aa428cc1e2e ("arm64: dts: Add pinctrl DT nodes for Stingray SOC") Signed-off-by: Rayagonda Kokatanur Reviewed-by: Ray Jui Signed-off-by: Florian Fainelli --- arch/arm64/boot/dts/broadcom/stingray/stingray-pinctrl.dtsi | 5 +++-- arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi | 3 +-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray-pinctrl.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray-pinctrl.dtsi index 8a3a770e8f2c..56789ccf9454 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/stingray-pinctrl.dtsi +++ b/arch/arm64/boot/dts/broadcom/stingray/stingray-pinctrl.dtsi @@ -42,13 +42,14 @@ pinmux: pinmux@14029c { compatible = "pinctrl-single"; - reg = <0x0014029c 0x250>; + reg = <0x0014029c 0x26c>; #address-cells = <1>; #size-cells = <1>; pinctrl-single,register-width = <32>; pinctrl-single,function-mask = <0xf>; pinctrl-single,gpio-range = < - &range 0 154 MODE_GPIO + &range 0 91 MODE_GPIO + &range 95 60 MODE_GPIO >; range: gpio-range { #pinctrl-single,gpio-range-cells = <3>; diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi index 71e2e34400d4..0098dfdef96c 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi +++ b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi @@ -464,8 +464,7 @@ <&pinmux 108 16 27>, <&pinmux 135 77 6>, <&pinmux 141 67 4>, - <&pinmux 145 149 6>, - <&pinmux 151 91 4>; + <&pinmux 145 149 6>; }; i2c1: i2c@e0000 { -- GitLab From 21e3d6c81179bbdfa279efc8de456c34b814cfd2 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 3 Sep 2019 12:18:39 +0200 Subject: [PATCH 022/993] scsi: sd: Ignore a failure to sync cache due to lack of authorization I've got a report about a UAS drive enclosure reporting back Sense: Logical unit access not authorized if the drive it holds is password protected. While the drive is obviously unusable in that state as a mass storage device, it still exists as a sd device and when the system is asked to perform a suspend of the drive, it will be sent a SYNCHRONIZE CACHE. If that fails due to password protection, the error must be ignored. Cc: Link: https://lore.kernel.org/r/20190903101840.16483-1-oneukum@suse.com Signed-off-by: Oliver Neukum Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 91af598f2f53..0f96eb0ddbfa 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1655,7 +1655,8 @@ static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr) /* we need to evaluate the error return */ if (scsi_sense_valid(sshdr) && (sshdr->asc == 0x3a || /* medium not present */ - sshdr->asc == 0x20)) /* invalid command */ + sshdr->asc == 0x20 || /* invalid command */ + (sshdr->asc == 0x74 && sshdr->ascq == 0x71))) /* drive is password locked */ /* this is no error here */ return 0; -- GitLab From 9bc6157f5fd0e898c94f3018d088a3419bde0d8f Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 27 Sep 2019 09:30:31 +0200 Subject: [PATCH 023/993] scsi: qla2xxx: Remove WARN_ON_ONCE in qla2x00_status_cont_entry() Commit 88263208dd23 ("scsi: qla2xxx: Complain if sp->done() is not called from the completion path") introduced the WARN_ON_ONCE in qla2x00_status_cont_entry(). The assumption was that there is only one status continuations element. According to the firmware documentation it is possible that multiple status continuations are emitted by the firmware. Fixes: 88263208dd23 ("scsi: qla2xxx: Complain if sp->done() is not called from the completion path") Link: https://lore.kernel.org/r/20190927073031.62296-1-dwagner@suse.de Cc: Bart Van Assche Reviewed-by: Hannes Reinecke Reviewed-by: Bart Van Assche Signed-off-by: Daniel Wagner Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_isr.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 4c26630c1c3e..009fd5a33fcd 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -2837,8 +2837,6 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt) if (sense_len == 0) { rsp->status_srb = NULL; sp->done(sp, cp->result); - } else { - WARN_ON_ONCE(true); } } -- GitLab From 6db7bfb431220d78e34d2d0afdb7c12683323588 Mon Sep 17 00:00:00 2001 From: Liu Xiang Date: Mon, 16 Sep 2019 21:53:00 +0800 Subject: [PATCH 024/993] iommu/arm-smmu: Free context bitmap in the err path of arm_smmu_init_domain_context When alloc_io_pgtable_ops is failed, context bitmap which is just allocated by __arm_smmu_alloc_bitmap should be freed to release the resource. Signed-off-by: Liu Xiang Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index b18aac4c105e..7c503a6bc585 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -812,6 +812,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, return 0; out_clear_smmu: + __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); smmu_domain->smmu = NULL; out_unlock: mutex_unlock(&smmu_domain->init_mutex); -- GitLab From 52f325f4eb321ea2e8a0779f49a3866be58bc694 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Mon, 30 Sep 2019 15:11:00 +0100 Subject: [PATCH 025/993] iommu/io-pgtable-arm: Correct Mali attributes Whilst Midgard's MEMATTR follows a similar principle to the VMSA MAIR, the actual attribute values differ, so although it currently appears to work to some degree, we probably shouldn't be using our standard stage 1 MAIR for that. Instead, generate a reasonable MEMATTR with attribute values borrowed from the kbase driver; at this point we'll be overriding or ignoring pretty much all of the LPAE config, so just implement these Mali details in a dedicated allocator instead of pretending to subclass the standard VMSA format. Fixes: d08d42de6432 ("iommu: io-pgtable: Add ARM Mali midgard MMU page table format") Tested-by: Neil Armstrong Reviewed-by: Steven Price Reviewed-by: Rob Herring Signed-off-by: Robin Murphy Signed-off-by: Will Deacon --- drivers/iommu/io-pgtable-arm.c | 53 +++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 4c91359057c5..90cb37af761c 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -166,6 +166,9 @@ #define ARM_MALI_LPAE_TTBR_READ_INNER BIT(2) #define ARM_MALI_LPAE_TTBR_SHARE_OUTER BIT(4) +#define ARM_MALI_LPAE_MEMATTR_IMP_DEF 0x88ULL +#define ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC 0x8DULL + /* IOPTE accessors */ #define iopte_deref(pte,d) __va(iopte_to_paddr(pte, d)) @@ -1015,27 +1018,51 @@ arm_32_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie) static struct io_pgtable * arm_mali_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie) { - struct io_pgtable *iop; + struct arm_lpae_io_pgtable *data; + + /* No quirks for Mali (hopefully) */ + if (cfg->quirks) + return NULL; if (cfg->ias != 48 || cfg->oas > 40) return NULL; cfg->pgsize_bitmap &= (SZ_4K | SZ_2M | SZ_1G); - iop = arm_64_lpae_alloc_pgtable_s1(cfg, cookie); - if (iop) { - u64 mair, ttbr; - /* Copy values as union fields overlap */ - mair = cfg->arm_lpae_s1_cfg.mair[0]; - ttbr = cfg->arm_lpae_s1_cfg.ttbr[0]; + data = arm_lpae_alloc_pgtable(cfg); + if (!data) + return NULL; - cfg->arm_mali_lpae_cfg.memattr = mair; - cfg->arm_mali_lpae_cfg.transtab = ttbr | - ARM_MALI_LPAE_TTBR_READ_INNER | - ARM_MALI_LPAE_TTBR_ADRMODE_TABLE; - } + /* + * MEMATTR: Mali has no actual notion of a non-cacheable type, so the + * best we can do is mimic the out-of-tree driver and hope that the + * "implementation-defined caching policy" is good enough. Similarly, + * we'll use it for the sake of a valid attribute for our 'device' + * index, although callers should never request that in practice. + */ + cfg->arm_mali_lpae_cfg.memattr = + (ARM_MALI_LPAE_MEMATTR_IMP_DEF + << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_NC)) | + (ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC + << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_CACHE)) | + (ARM_MALI_LPAE_MEMATTR_IMP_DEF + << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_DEV)); - return iop; + data->pgd = __arm_lpae_alloc_pages(data->pgd_size, GFP_KERNEL, cfg); + if (!data->pgd) + goto out_free_data; + + /* Ensure the empty pgd is visible before TRANSTAB can be written */ + wmb(); + + cfg->arm_mali_lpae_cfg.transtab = virt_to_phys(data->pgd) | + ARM_MALI_LPAE_TTBR_READ_INNER | + ARM_MALI_LPAE_TTBR_ADRMODE_TABLE; + return &data->iop; + +out_free_data: + kfree(data); + return NULL; } struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns = { -- GitLab From 1be08f458d1602275b02f5357ef069957058f3fd Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Mon, 30 Sep 2019 15:11:01 +0100 Subject: [PATCH 026/993] iommu/io-pgtable-arm: Support all Mali configurations In principle, Midgard GPUs supporting smaller VA sizes should only require 3-level pagetables, since level 0 only resolves bits 48:40 of the address. However, the kbase driver does not appear to have any notion of a variable start level, and empirically T720 and T820 rapidly blow up with translation faults unless given a full 4-level table, despite only supporting a 33-bit VA size. The 'real' IAS value is still valuable in terms of validating addresses on map/unmap, so tweak the allocator to allow smaller values while still forcing the resultant tables to the full 4 levels. As far as I can test, this should make all known Midgard variants happy. Fixes: d08d42de6432 ("iommu: io-pgtable: Add ARM Mali midgard MMU page table format") Tested-by: Neil Armstrong Reviewed-by: Steven Price Reviewed-by: Rob Herring Signed-off-by: Robin Murphy Signed-off-by: Will Deacon --- drivers/iommu/io-pgtable-arm.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 90cb37af761c..ca51036aa53c 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -1024,7 +1024,7 @@ arm_mali_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie) if (cfg->quirks) return NULL; - if (cfg->ias != 48 || cfg->oas > 40) + if (cfg->ias > 48 || cfg->oas > 40) return NULL; cfg->pgsize_bitmap &= (SZ_4K | SZ_2M | SZ_1G); @@ -1033,6 +1033,11 @@ arm_mali_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie) if (!data) return NULL; + /* Mali seems to need a full 4-level table regardless of IAS */ + if (data->levels < ARM_LPAE_MAX_LEVELS) { + data->levels = ARM_LPAE_MAX_LEVELS; + data->pgd_size = sizeof(arm_lpae_iopte); + } /* * MEMATTR: Mali has no actual notion of a non-cacheable type, so the * best we can do is mimic the out-of-tree driver and hope that the -- GitLab From f64db548799e0330897c3203680c2ee795ade518 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 29 Sep 2019 17:58:48 +0800 Subject: [PATCH 027/993] regulator: ti-abb: Fix timeout in ti_abb_wait_txdone/ti_abb_clear_all_txdone ti_abb_wait_txdone() may return -ETIMEDOUT when ti_abb_check_txdone() returns true in the latest iteration of the while loop because the timeout value is abb->settling_time + 1. Similarly, ti_abb_clear_all_txdone() may return -ETIMEDOUT when ti_abb_check_txdone() returns false in the latest iteration of the while loop. Fix it. Signed-off-by: Axel Lin Acked-by: Nishanth Menon Link: https://lore.kernel.org/r/20190929095848.21960-1-axel.lin@ingics.com Signed-off-by: Mark Brown --- drivers/regulator/ti-abb-regulator.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c index cced1ffb896c..89b9314d64c9 100644 --- a/drivers/regulator/ti-abb-regulator.c +++ b/drivers/regulator/ti-abb-regulator.c @@ -173,19 +173,14 @@ static int ti_abb_wait_txdone(struct device *dev, struct ti_abb *abb) while (timeout++ <= abb->settling_time) { status = ti_abb_check_txdone(abb); if (status) - break; + return 0; udelay(1); } - if (timeout > abb->settling_time) { - dev_warn_ratelimited(dev, - "%s:TRANXDONE timeout(%duS) int=0x%08x\n", - __func__, timeout, readl(abb->int_base)); - return -ETIMEDOUT; - } - - return 0; + dev_warn_ratelimited(dev, "%s:TRANXDONE timeout(%duS) int=0x%08x\n", + __func__, timeout, readl(abb->int_base)); + return -ETIMEDOUT; } /** @@ -205,19 +200,14 @@ static int ti_abb_clear_all_txdone(struct device *dev, const struct ti_abb *abb) status = ti_abb_check_txdone(abb); if (!status) - break; + return 0; udelay(1); } - if (timeout > abb->settling_time) { - dev_warn_ratelimited(dev, - "%s:TRANXDONE timeout(%duS) int=0x%08x\n", - __func__, timeout, readl(abb->int_base)); - return -ETIMEDOUT; - } - - return 0; + dev_warn_ratelimited(dev, "%s:TRANXDONE timeout(%duS) int=0x%08x\n", + __func__, timeout, readl(abb->int_base)); + return -ETIMEDOUT; } /** -- GitLab From 4bb41984bf2f4cb8ed6ec1579d317790bd941788 Mon Sep 17 00:00:00 2001 From: Sathyanarayana Nujella Date: Sat, 28 Sep 2019 13:22:30 -0700 Subject: [PATCH 028/993] ASoC: max98373: check for device node before parsing Below Oops is caused in a system which uses ACPI instead of device node: of_get_named_gpiod_flags: can't parse 'maxim,reset-gpio' property of node '(null)[0]' BUG: kernel NULL pointer dereference, address: 0000000000000010 This patch avoids NULL pointer deferencing by adding a check before parsing and initializes to make reset-gpio pin as invalid. Signed-off-by: Sathyanarayana Nujella Signed-off-by: Jairaj Arava Link: https://lore.kernel.org/r/1569702150-11976-1-git-send-email-sathyanarayana.nujella@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/max98373.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c index e609abcf3220..eb709d528259 100644 --- a/sound/soc/codecs/max98373.c +++ b/sound/soc/codecs/max98373.c @@ -901,16 +901,20 @@ static void max98373_slot_config(struct i2c_client *i2c, max98373->i_slot = value & 0xF; else max98373->i_slot = 1; - - max98373->reset_gpio = of_get_named_gpio(dev->of_node, + if (dev->of_node) { + max98373->reset_gpio = of_get_named_gpio(dev->of_node, "maxim,reset-gpio", 0); - if (!gpio_is_valid(max98373->reset_gpio)) { - dev_err(dev, "Looking up %s property in node %s failed %d\n", - "maxim,reset-gpio", dev->of_node->full_name, - max98373->reset_gpio); + if (!gpio_is_valid(max98373->reset_gpio)) { + dev_err(dev, "Looking up %s property in node %s failed %d\n", + "maxim,reset-gpio", dev->of_node->full_name, + max98373->reset_gpio); + } else { + dev_dbg(dev, "maxim,reset-gpio=%d", + max98373->reset_gpio); + } } else { - dev_dbg(dev, "maxim,reset-gpio=%d", - max98373->reset_gpio); + /* this makes reset_gpio as invalid */ + max98373->reset_gpio = -1; } if (!device_property_read_u32(dev, "maxim,spkfb-slot-no", &value)) -- GitLab From b3a81c777dcb093020680490ab970d85e2f6f04f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Date: Fri, 23 Aug 2019 21:15:27 +0200 Subject: [PATCH 029/993] HID: fix error message in hid_open_report() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On HID report descriptor parsing error the code displays bogus pointer instead of error offset (subtracts start=NULL from end). Make the message more useful by displaying correct error offset and include total buffer size for reference. This was carried over from ancient times - "Fixed" commit just promoted the message from DEBUG to ERROR. Cc: stable@vger.kernel.org Fixes: 8c3d52fc393b ("HID: make parser more verbose about parsing errors by default") Signed-off-by: Michał Mirosław Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 3eaee2c37931..63fdbf09b044 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1139,6 +1139,7 @@ int hid_open_report(struct hid_device *device) __u8 *start; __u8 *buf; __u8 *end; + __u8 *next; int ret; static int (*dispatch_type[])(struct hid_parser *parser, struct hid_item *item) = { @@ -1192,7 +1193,8 @@ int hid_open_report(struct hid_device *device) device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; ret = -EINVAL; - while ((start = fetch_item(start, end, &item)) != NULL) { + while ((next = fetch_item(start, end, &item)) != NULL) { + start = next; if (item.format != HID_ITEM_FORMAT_SHORT) { hid_err(device, "unexpected long global item\n"); @@ -1230,7 +1232,8 @@ int hid_open_report(struct hid_device *device) } } - hid_err(device, "item fetching failed at offset %d\n", (int)(end - start)); + hid_err(device, "item fetching failed at offset %u/%u\n", + size - (unsigned int)(end - start), size); err: kfree(parser->collection_stack); alloc_err: -- GitLab From fe2199cfd1516e90e03c033c52c9a28da09d9986 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 5 Sep 2019 17:54:06 +0100 Subject: [PATCH 030/993] HID: prodikeys: make array keys static const, makes object smaller Don't populate the array keys on the stack but instead make it static const. Makes the object code smaller by 166 bytes. Before: text data bss dec hex filename 18931 5872 480 25283 62c3 drivers/hid/hid-prodikeys.o After: text data bss dec hex filename 18669 5968 480 25117 621d drivers/hid/hid-prodikeys.o (gcc version 9.2.1, amd64) Signed-off-by: Colin Ian King Signed-off-by: Jiri Kosina --- drivers/hid/hid-prodikeys.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index 5a3b3d974d84..2666af02d5c1 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c @@ -516,7 +516,7 @@ static void pcmidi_setup_extra_keys( MY PICTURES => KEY_WORDPROCESSOR MY MUSIC=> KEY_SPREADSHEET */ - unsigned int keys[] = { + static const unsigned int keys[] = { KEY_FN, KEY_MESSENGER, KEY_CALENDAR, KEY_ADDRESSBOOK, KEY_DOCUMENTS, @@ -532,7 +532,7 @@ static void pcmidi_setup_extra_keys( 0 }; - unsigned int *pkeys = &keys[0]; + const unsigned int *pkeys = &keys[0]; unsigned short i; if (pm->ifnum != 1) /* only set up ONCE for interace 1 */ -- GitLab From 57ff2df1b952c7934d7b0e1d3a2ec403ec76edec Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 16 Sep 2019 17:47:51 +0300 Subject: [PATCH 031/993] pinctrl: intel: Allocate IRQ chip dynamic Keeping the IRQ chip definition static shares it with multiple instances of the GPIO chip in the system. This is bad and now we get this warning from GPIO library: "detected irqchip that is shared with multiple gpiochips: please fix the driver." Hence, move the IRQ chip definition from being driver static into the struct intel_pinctrl. So a unique IRQ chip is used for each GPIO chip instance. Fixes: ee1a6ca43dba ("pinctrl: intel: Add Intel Broxton pin controller support") Depends-on: 5ff56b015e85 ("pinctrl: intel: Disable GPIO pin interrupts in suspend") Reported-by: Federico Ricchiuto Suggested-by: Mika Westerberg Signed-off-by: Andy Shevchenko Signed-off-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-intel.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 1f13bcd0e4e1..bc013599a9a3 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -96,6 +96,7 @@ struct intel_pinctrl_context { * @pctldesc: Pin controller description * @pctldev: Pointer to the pin controller device * @chip: GPIO chip in this pin controller + * @irqchip: IRQ chip in this pin controller * @soc: SoC/PCH specific pin configuration data * @communities: All communities in this pin controller * @ncommunities: Number of communities in this pin controller @@ -108,6 +109,7 @@ struct intel_pinctrl { struct pinctrl_desc pctldesc; struct pinctrl_dev *pctldev; struct gpio_chip chip; + struct irq_chip irqchip; const struct intel_pinctrl_soc_data *soc; struct intel_community *communities; size_t ncommunities; @@ -1139,16 +1141,6 @@ static irqreturn_t intel_gpio_irq(int irq, void *data) return ret; } -static struct irq_chip intel_gpio_irqchip = { - .name = "intel-gpio", - .irq_ack = intel_gpio_irq_ack, - .irq_mask = intel_gpio_irq_mask, - .irq_unmask = intel_gpio_irq_unmask, - .irq_set_type = intel_gpio_irq_type, - .irq_set_wake = intel_gpio_irq_wake, - .flags = IRQCHIP_MASK_ON_SUSPEND, -}; - static int intel_gpio_add_pin_ranges(struct intel_pinctrl *pctrl, const struct intel_community *community) { @@ -1198,12 +1190,22 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) pctrl->chip = intel_gpio_chip; + /* Setup GPIO chip */ pctrl->chip.ngpio = intel_gpio_ngpio(pctrl); pctrl->chip.label = dev_name(pctrl->dev); pctrl->chip.parent = pctrl->dev; pctrl->chip.base = -1; pctrl->irq = irq; + /* Setup IRQ chip */ + pctrl->irqchip.name = dev_name(pctrl->dev); + pctrl->irqchip.irq_ack = intel_gpio_irq_ack; + pctrl->irqchip.irq_mask = intel_gpio_irq_mask; + pctrl->irqchip.irq_unmask = intel_gpio_irq_unmask; + pctrl->irqchip.irq_set_type = intel_gpio_irq_type; + pctrl->irqchip.irq_set_wake = intel_gpio_irq_wake; + pctrl->irqchip.flags = IRQCHIP_MASK_ON_SUSPEND; + ret = devm_gpiochip_add_data(pctrl->dev, &pctrl->chip, pctrl); if (ret) { dev_err(pctrl->dev, "failed to register gpiochip\n"); @@ -1233,15 +1235,14 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) return ret; } - ret = gpiochip_irqchip_add(&pctrl->chip, &intel_gpio_irqchip, 0, + ret = gpiochip_irqchip_add(&pctrl->chip, &pctrl->irqchip, 0, handle_bad_irq, IRQ_TYPE_NONE); if (ret) { dev_err(pctrl->dev, "failed to add irqchip\n"); return ret; } - gpiochip_set_chained_irqchip(&pctrl->chip, &intel_gpio_irqchip, irq, - NULL); + gpiochip_set_chained_irqchip(&pctrl->chip, &pctrl->irqchip, irq, NULL); return 0; } -- GitLab From 260996c30f4f3a732f45045e3e0efe27017615e4 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 23 Sep 2019 19:49:58 -0700 Subject: [PATCH 032/993] pinctrl: cherryview: restore Strago DMI workaround for all versions This is essentially a revert of: e3f72b749da2 pinctrl: cherryview: fix Strago DMI workaround 86c5dd6860a6 pinctrl: cherryview: limit Strago DMI workarounds to version 1.0 because even with 1.1 versions of BIOS there are some pins that are configured as interrupts but not claimed by any driver, and they sometimes fire up and result in interrupt storms that cause touchpad stop functioning and other issues. Given that we are unlikely to qualify another firmware version for a while it is better to keep the workaround active on all Strago boards. Reported-by: Alex Levin Fixes: 86c5dd6860a6 ("pinctrl: cherryview: limit Strago DMI workarounds to version 1.0") Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov Reviewed-by: Andy Shevchenko Tested-by: Alex Levin Signed-off-by: Mika Westerberg --- drivers/pinctrl/intel/pinctrl-cherryview.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index aae51c507f59..c6251eac8946 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1513,7 +1513,6 @@ static const struct dmi_system_id chv_no_valid_mask[] = { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_Strago"), - DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), }, }, { @@ -1521,7 +1520,6 @@ static const struct dmi_system_id chv_no_valid_mask[] = { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "HP"), DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"), - DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), }, }, { @@ -1529,7 +1527,6 @@ static const struct dmi_system_id chv_no_valid_mask[] = { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), DMI_MATCH(DMI_PRODUCT_NAME, "Cyan"), - DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), }, }, { @@ -1537,7 +1534,6 @@ static const struct dmi_system_id chv_no_valid_mask[] = { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), DMI_MATCH(DMI_PRODUCT_NAME, "Celes"), - DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), }, }, {} -- GitLab From 9daf4fd0302b2559223cf90dae7dc510c6679047 Mon Sep 17 00:00:00 2001 From: Li Xu Date: Tue, 1 Oct 2019 14:09:11 +0100 Subject: [PATCH 033/993] ASoC: wm_adsp: Fix theoretical NULL pointer for alg_region Fix potential NULL pointer dereference for alg_region in wm_adsp_buffer_parse_legacy. In practice this can never happen as loading the firmware should have failed at the wm_adsp2_setup_algs stage, however probably better for the code to be robust against future changes and this is more helpful for static analysis. Signed-off-by: Li Xu Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20191001130911.19238-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index ae28d9907c30..85396d920e0a 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -3697,11 +3697,16 @@ static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) u32 xmalg, addr, magic; int i, ret; + alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); + if (!alg_region) { + adsp_err(dsp, "No algorithm region found\n"); + return -EINVAL; + } + buf = wm_adsp_buffer_alloc(dsp); if (!buf) return -ENOMEM; - alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); xmalg = dsp->ops->sys_config_size / sizeof(__be32); addr = alg_region->base + xmalg + ALG_XM_FIELD(magic); -- GitLab From f75841aa3b4bf02fcc7941af2d3e00ff74a93bdb Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 1 Oct 2019 14:20:17 +0100 Subject: [PATCH 034/993] regulator: lochnagar: Add on_off_delay for VDDCORE The VDDCORE regulator takes a good length of time to discharge down, so add an on_off_delay to ensure DCVDD is removed before it is powered on again. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20191001132017.1785-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- drivers/regulator/lochnagar-regulator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/regulator/lochnagar-regulator.c b/drivers/regulator/lochnagar-regulator.c index ff97cc50f2eb..9b05e03ba830 100644 --- a/drivers/regulator/lochnagar-regulator.c +++ b/drivers/regulator/lochnagar-regulator.c @@ -210,6 +210,7 @@ static const struct regulator_desc lochnagar_regulators[] = { .enable_time = 3000, .ramp_delay = 1000, + .off_on_delay = 15000, .owner = THIS_MODULE, }, -- GitLab From 798614885a0e1b867ceb0197c30c2d82575c73b0 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 27 Sep 2019 15:05:26 -0500 Subject: [PATCH 035/993] ASoC: SOF: loader: fix kernel oops on firmware boot failure When we fail to boot the firmware, we encounter a kernel oops in hda_dsp_get_registers(), which is called conditionally in hda_dsp_dump() when the sdev_>boot_complete flag is set. Setting this flag _after_ dumping the data fixes the issue and does not change the programming flow. Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190927200538.660-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/loader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c index d7f32745fefe..9a9a381a908d 100644 --- a/sound/soc/sof/loader.c +++ b/sound/soc/sof/loader.c @@ -546,10 +546,10 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev) msecs_to_jiffies(sdev->boot_timeout)); if (ret == 0) { dev_err(sdev->dev, "error: firmware boot failure\n"); - /* after this point FW_READY msg should be ignored */ - sdev->boot_complete = true; snd_sof_dsp_dbg_dump(sdev, SOF_DBG_REGS | SOF_DBG_MBOX | SOF_DBG_TEXT | SOF_DBG_PCI); + /* after this point FW_READY msg should be ignored */ + sdev->boot_complete = true; return -EIO; } -- GitLab From 2e305a074061121220a2828f97a57d315cf8efba Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Fri, 27 Sep 2019 15:05:27 -0500 Subject: [PATCH 036/993] ASoC: SOF: topology: fix parse fail issue for byte/bool tuple types We are using sof_parse_word_tokens() to parse tokens with bool/byte/short/word tuple types, here add the missing check, to fix the parsing failure at byte/bool tuple types. Signed-off-by: Keyon Jie Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190927200538.660-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/topology.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index fc85efbad378..0aabb3190ddc 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -920,7 +920,9 @@ static void sof_parse_word_tokens(struct snd_soc_component *scomp, for (j = 0; j < count; j++) { /* match token type */ if (!(tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_WORD || - tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_SHORT)) + tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_SHORT || + tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BYTE || + tokens[j].type == SND_SOC_TPLG_TUPLE_TYPE_BOOL)) continue; /* match token id */ -- GitLab From e66e52c5b7422824cedf0084c0766602dea7e8a7 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Fri, 27 Sep 2019 15:05:30 -0500 Subject: [PATCH 037/993] ASoC: SOF: pcm: fix resource leak in hw_free Fix a bug in sof_pcm_hw_free() where some cleanup actions were skipped if STREAM_PCM_FREE IPC was already successfully sent to DSP when the stream was stopped or suspended. This is incorrect as hw_free should clean up also other resources, including pcm lib page allocations, period elapsed work queue and call to platform hw_free. Fixes: c29d96c3b9b4 ("ASoC: SOF: reset DMA state in prepare") Signed-off-by: Kai Vehmanen Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190927200538.660-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/pcm.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index e3f6a6dc0f36..fa7769dd825c 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -244,7 +244,7 @@ static int sof_pcm_hw_free(struct snd_pcm_substream *substream) snd_soc_rtdcom_lookup(rtd, DRV_NAME); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); struct snd_sof_pcm *spcm; - int ret; + int ret, err = 0; /* nothing to do for BE */ if (rtd->dai_link->no_pcm) @@ -254,26 +254,26 @@ static int sof_pcm_hw_free(struct snd_pcm_substream *substream) if (!spcm) return -EINVAL; - if (!spcm->prepared[substream->stream]) - return 0; - dev_dbg(sdev->dev, "pcm: free stream %d dir %d\n", spcm->pcm.pcm_id, substream->stream); - ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm); + if (spcm->prepared[substream->stream]) { + ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm); + if (ret < 0) + err = ret; + } snd_pcm_lib_free_pages(substream); cancel_work_sync(&spcm->stream[substream->stream].period_elapsed_work); - if (ret < 0) - return ret; - ret = snd_sof_pcm_platform_hw_free(sdev, substream); - if (ret < 0) + if (ret < 0) { dev_err(sdev->dev, "error: platform hw free failed\n"); + err = ret; + } - return ret; + return err; } static int sof_pcm_prepare(struct snd_pcm_substream *substream) -- GitLab From 0a1b08345bc5d9214dc701f8ec5d67c473fab735 Mon Sep 17 00:00:00 2001 From: Pan Xiuli Date: Fri, 27 Sep 2019 15:05:31 -0500 Subject: [PATCH 038/993] ASoC: SOF: pcm: harden PCM STOP sequence The old STOP sequence is: 1. stop DMA 2. send STOP ipc If delay happen before the steps 1 and 2, the DMA buffer will be empty in short time and cause pipeline xrun then stop the pipeline. Then the step 2 ipc stop will return error as pipeline is already stopped. Suggested change to avoid the issue is to switch the order of steps 1 and 2 for the stop sequence. Signed-off-by: Pan Xiuli Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190927200538.660-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/pcm.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index fa7769dd825c..2b876d497447 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -323,6 +323,7 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct sof_ipc_stream stream; struct sof_ipc_reply reply; bool reset_hw_params = false; + bool ipc_first = false; int ret; /* nothing to do for BE */ @@ -343,6 +344,7 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd) switch (cmd) { case SNDRV_PCM_TRIGGER_PAUSE_PUSH: stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_PAUSE; + ipc_first = true; break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_RELEASE; @@ -363,6 +365,7 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP; + ipc_first = true; reset_hw_params = true; break; default: @@ -370,12 +373,22 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd) return -EINVAL; } - snd_sof_pcm_platform_trigger(sdev, substream, cmd); + /* + * DMA and IPC sequence is different for start and stop. Need to send + * STOP IPC before stop DMA + */ + if (!ipc_first) + snd_sof_pcm_platform_trigger(sdev, substream, cmd); /* send IPC to the DSP */ ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream, sizeof(stream), &reply, sizeof(reply)); + /* need to STOP DMA even if STOP IPC failed */ + if (ipc_first) + snd_sof_pcm_platform_trigger(sdev, substream, cmd); + + /* free PCM if reset_hw_params is set and the STOP IPC is successful */ if (!ret && reset_hw_params) ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm); -- GitLab From 4ff5f6439fe69624e8f7d559915e9b54a6477684 Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Fri, 27 Sep 2019 15:05:35 -0500 Subject: [PATCH 039/993] ASoC: SOF: Intel: hda: fix warnings during FW load The "snd_pcm_substream" handle was not initialized properly in hda-loader.c for firmware load. When the HDA DMAs were used to load the firmware, the interrupts related to firmware load also triggered calls to snd_sof_pcm_period_elapsed() on a non-existent ALSA PCM stream. This caused runtime kernel warnings from pcm_lib.c:snd_pcm_period_elapsed(). Signed-off-by: Kai Vehmanen Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190927200538.660-11-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-loader.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 6427f0b3a2f1..65c2af3fcaab 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -44,6 +44,7 @@ static int cl_stream_prepare(struct snd_sof_dev *sdev, unsigned int format, return -ENODEV; } hstream = &dsp_stream->hstream; + hstream->substream = NULL; /* allocate DMA buffer */ ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, &pci->dev, size, dmab); -- GitLab From ff2be865633e6fa523cd2db3b73197d795dec991 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Fri, 27 Sep 2019 15:05:36 -0500 Subject: [PATCH 040/993] ASoC: SOF: Intel: initialise and verify FW crash dump data. FW mailbox offset was not set before use and HDR size was not validated. Fix this. Signed-off-by: Liam Girdwood Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190927200538.660-12-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/bdw.c | 7 +++++++ sound/soc/sof/intel/byt.c | 6 ++++++ sound/soc/sof/intel/hda.c | 7 +++++++ 3 files changed, 20 insertions(+) diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c index e282179263e8..80e2826fb447 100644 --- a/sound/soc/sof/intel/bdw.c +++ b/sound/soc/sof/intel/bdw.c @@ -37,6 +37,7 @@ #define MBOX_SIZE 0x1000 #define MBOX_DUMP_SIZE 0x30 #define EXCEPT_OFFSET 0x800 +#define EXCEPT_MAX_HDR_SIZE 0x400 /* DSP peripherals */ #define DMAC0_OFFSET 0xFE000 @@ -228,6 +229,11 @@ static void bdw_get_registers(struct snd_sof_dev *sdev, /* note: variable AR register array is not read */ /* then get panic info */ + if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) { + dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n", + xoops->arch_hdr.totalsize); + return; + } offset += xoops->arch_hdr.totalsize; sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info)); @@ -451,6 +457,7 @@ static int bdw_probe(struct snd_sof_dev *sdev) /* TODO: add offsets */ sdev->mmio_bar = BDW_DSP_BAR; sdev->mailbox_bar = BDW_DSP_BAR; + sdev->dsp_oops_offset = MBOX_OFFSET; /* PCI base */ mmio = platform_get_resource(pdev, IORESOURCE_MEM, diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c index 5e7a6aaa627a..a1e514f71739 100644 --- a/sound/soc/sof/intel/byt.c +++ b/sound/soc/sof/intel/byt.c @@ -28,6 +28,7 @@ #define MBOX_OFFSET 0x144000 #define MBOX_SIZE 0x1000 #define EXCEPT_OFFSET 0x800 +#define EXCEPT_MAX_HDR_SIZE 0x400 /* DSP peripherals */ #define DMAC0_OFFSET 0x098000 @@ -126,6 +127,11 @@ static void byt_get_registers(struct snd_sof_dev *sdev, /* note: variable AR register array is not read */ /* then get panic info */ + if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) { + dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n", + xoops->arch_hdr.totalsize); + return; + } offset += xoops->arch_hdr.totalsize; sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info)); diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index c72e9a09eee1..06e84679087b 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -35,6 +35,8 @@ #define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348) #define IS_CNL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9dc8) +#define EXCEPT_MAX_HDR_SIZE 0x400 + /* * Debug */ @@ -131,6 +133,11 @@ static void hda_dsp_get_registers(struct snd_sof_dev *sdev, /* note: variable AR register array is not read */ /* then get panic info */ + if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) { + dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n", + xoops->arch_hdr.totalsize); + return; + } offset += xoops->arch_hdr.totalsize; sof_block_read(sdev, sdev->mmio_bar, offset, panic_info, sizeof(*panic_info)); -- GitLab From 43b2ab9009b13bfff47fcc1893de9244b39bdd54 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Fri, 27 Sep 2019 15:05:38 -0500 Subject: [PATCH 041/993] ASoC: SOF: Intel: hda: Disable DMI L1 entry during capture There is a known issue on some Intel platforms which causes pause/release to run into xrun's during capture usecases. The suggested workaround to address the issue is to disable the entry of lower power L1 state in the physical DMI link when there is a capture stream open. Signed-off-by: Ranjani Sridharan Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190927200538.660-14-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/Kconfig | 10 +++++++ sound/soc/sof/intel/hda-ctrl.c | 12 +++------ sound/soc/sof/intel/hda-stream.c | 45 +++++++++++++++++++++++++++----- sound/soc/sof/intel/hda.h | 5 +++- 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig index 479ba249e219..d62f51d33be1 100644 --- a/sound/soc/sof/intel/Kconfig +++ b/sound/soc/sof/intel/Kconfig @@ -273,6 +273,16 @@ config SND_SOC_SOF_HDA_AUDIO_CODEC Say Y if you want to enable HDAudio codecs with SOF. If unsure select "N". +config SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1 + bool "SOF enable DMI Link L1" + help + This option enables DMI L1 for both playback and capture + and disables known workarounds for specific HDaudio platforms. + Only use to look into power optimizations on platforms not + affected by DMI L1 issues. This option is not recommended. + Say Y if you want to enable DMI Link L1 + If unsure, select "N". + endif ## SND_SOC_SOF_HDA_COMMON config SND_SOC_SOF_HDA_LINK_BASELINE diff --git a/sound/soc/sof/intel/hda-ctrl.c b/sound/soc/sof/intel/hda-ctrl.c index bc41028a7a01..df1909e1d950 100644 --- a/sound/soc/sof/intel/hda-ctrl.c +++ b/sound/soc/sof/intel/hda-ctrl.c @@ -139,20 +139,16 @@ void hda_dsp_ctrl_misc_clock_gating(struct snd_sof_dev *sdev, bool enable) */ int hda_dsp_ctrl_clock_power_gating(struct snd_sof_dev *sdev, bool enable) { -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - struct hdac_bus *bus = sof_to_bus(sdev); -#endif u32 val; /* enable/disable audio dsp clock gating */ val = enable ? PCI_CGCTL_ADSPDCGE : 0; snd_sof_pci_update_bits(sdev, PCI_CGCTL, PCI_CGCTL_ADSPDCGE, val); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - /* enable/disable L1 support */ - val = enable ? SOF_HDA_VS_EM2_L1SEN : 0; - snd_hdac_chip_updatel(bus, VS_EM2, SOF_HDA_VS_EM2_L1SEN, val); -#endif + /* enable/disable DMI Link L1 support */ + val = enable ? HDA_VS_INTEL_EM2_L1SEN : 0; + snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, HDA_VS_INTEL_EM2, + HDA_VS_INTEL_EM2_L1SEN, val); /* enable/disable audio dsp power gating */ val = enable ? 0 : PCI_PGCTL_ADSPPGD; diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index ad8d41f22e92..2c7447188402 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -185,6 +185,17 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction) direction == SNDRV_PCM_STREAM_PLAYBACK ? "playback" : "capture"); + /* + * Disable DMI Link L1 entry when capture stream is opened. + * Workaround to address a known issue with host DMA that results + * in xruns during pause/release in capture scenarios. + */ + if (!IS_ENABLED(SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1)) + if (stream && direction == SNDRV_PCM_STREAM_CAPTURE) + snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, + HDA_VS_INTEL_EM2, + HDA_VS_INTEL_EM2_L1SEN, 0); + return stream; } @@ -193,23 +204,43 @@ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag) { struct hdac_bus *bus = sof_to_bus(sdev); struct hdac_stream *s; + bool active_capture_stream = false; + bool found = false; spin_lock_irq(&bus->reg_lock); - /* find used stream */ + /* + * close stream matching the stream tag + * and check if there are any open capture streams. + */ list_for_each_entry(s, &bus->stream_list, list) { - if (s->direction == direction && - s->opened && s->stream_tag == stream_tag) { + if (!s->opened) + continue; + + if (s->direction == direction && s->stream_tag == stream_tag) { s->opened = false; - spin_unlock_irq(&bus->reg_lock); - return 0; + found = true; + } else if (s->direction == SNDRV_PCM_STREAM_CAPTURE) { + active_capture_stream = true; } } spin_unlock_irq(&bus->reg_lock); - dev_dbg(sdev->dev, "stream_tag %d not opened!\n", stream_tag); - return -ENODEV; + /* Enable DMI L1 entry if there are no capture streams open */ + if (!IS_ENABLED(SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1)) + if (!active_capture_stream) + snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, + HDA_VS_INTEL_EM2, + HDA_VS_INTEL_EM2_L1SEN, + HDA_VS_INTEL_EM2_L1SEN); + + if (!found) { + dev_dbg(sdev->dev, "stream_tag %d not opened!\n", stream_tag); + return -ENODEV; + } + + return 0; } int hda_dsp_stream_trigger(struct snd_sof_dev *sdev, diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 5591841a1b6f..23e430d3e056 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -39,7 +39,6 @@ #define SOF_HDA_WAKESTS 0x0E #define SOF_HDA_WAKESTS_INT_MASK ((1 << 8) - 1) #define SOF_HDA_RIRBSTS 0x5d -#define SOF_HDA_VS_EM2_L1SEN BIT(13) /* SOF_HDA_GCTL register bist */ #define SOF_HDA_GCTL_RESET BIT(0) @@ -228,6 +227,10 @@ #define HDA_DSP_REG_HIPCIE (HDA_DSP_IPC_BASE + 0x0C) #define HDA_DSP_REG_HIPCCTL (HDA_DSP_IPC_BASE + 0x10) +/* Intel Vendor Specific Registers */ +#define HDA_VS_INTEL_EM2 0x1030 +#define HDA_VS_INTEL_EM2_L1SEN BIT(13) + /* HIPCI */ #define HDA_DSP_REG_HIPCI_BUSY BIT(31) #define HDA_DSP_REG_HIPCI_MSG_MASK 0x7FFFFFFF -- GitLab From 4413adc4fd872579de87bedaecda633f999ef995 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Fri, 27 Sep 2019 15:14:06 -0500 Subject: [PATCH 042/993] ASoC: intel: sof_rt5682: use separate route map for dmic dmic map can only be added when dmic dai link is present. Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190927201408.925-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_rt5682.c | 35 +++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index a437567b8cee..57b4ef75be15 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -308,6 +308,9 @@ static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_SPK("Spk", NULL), +}; + +static const struct snd_soc_dapm_widget dmic_widgets[] = { SND_SOC_DAPM_MIC("SoC DMIC", NULL), }; @@ -318,10 +321,6 @@ static const struct snd_soc_dapm_route sof_map[] = { /* other jacks */ { "IN1P", NULL, "Headset Mic" }, - - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, - }; static const struct snd_soc_dapm_route speaker_map[] = { @@ -329,6 +328,11 @@ static const struct snd_soc_dapm_route speaker_map[] = { { "Spk", NULL, "Speaker" }, }; +static const struct snd_soc_dapm_route dmic_map[] = { + /* digital mics */ + {"DMic", NULL, "SoC DMIC"}, +}; + static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; @@ -342,6 +346,28 @@ static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } +static int dmic_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, + ARRAY_SIZE(dmic_widgets)); + if (ret) { + dev_err(card->dev, "DMic widget addition failed: %d\n", ret); + /* Don't need to add routes if widget addition failed */ + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, + ARRAY_SIZE(dmic_map)); + + if (ret) + dev_err(card->dev, "DMic map addition failed: %d\n", ret); + + return ret; +} + /* sof audio machine driver for rt5682 codec */ static struct snd_soc_card sof_audio_card_rt5682 = { .name = "sof_rt5682", @@ -445,6 +471,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].name = "dmic01"; links[id].cpus = &cpus[id]; links[id].cpus->dai_name = "DMIC01 Pin"; + links[id].init = dmic_init; if (dmic_be_num > 1) { /* set up 2 BE links at most */ links[id + 1].name = "dmic16k"; -- GitLab From a315e76fc544f09daf619530a7b2f85865e6b25e Mon Sep 17 00:00:00 2001 From: Jaska Uimonen Date: Fri, 27 Sep 2019 15:14:07 -0500 Subject: [PATCH 043/993] ASoC: rt5682: add NULL handler to set_jack function Implement NULL handler in set_jack function to disable irq's. Signed-off-by: Jaska Uimonen Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190927201408.925-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5682.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index 1ef470700ed5..c50b75ce82e0 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -995,6 +995,16 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component, { struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); + rt5682->hs_jack = hs_jack; + + if (!hs_jack) { + regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, + RT5682_JD1_EN_MASK, RT5682_JD1_DIS); + regmap_update_bits(rt5682->regmap, RT5682_RC_CLK_CTRL, + RT5682_POW_JDH | RT5682_POW_JDL, 0); + return 0; + } + switch (rt5682->pdata.jd_src) { case RT5682_JD1: snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_2, @@ -1032,8 +1042,6 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component, break; } - rt5682->hs_jack = hs_jack; - return 0; } -- GitLab From 6ba5041c23c1062d4e8287b2b76a1181538c6df1 Mon Sep 17 00:00:00 2001 From: Jaska Uimonen Date: Fri, 27 Sep 2019 15:14:08 -0500 Subject: [PATCH 044/993] ASoC: intel: sof_rt5682: add remove function to disable jack When removing sof module the rt5682 jack handler will oops if jack detection is not disabled. So add remove function, which disables the jack detection. Signed-off-by: Jaska Uimonen Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190927201408.925-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_rt5682.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 57b4ef75be15..5ce643d62faf 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -648,8 +648,24 @@ static int sof_audio_probe(struct platform_device *pdev) &sof_audio_card_rt5682); } +static int sof_rt5682_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct snd_soc_component *component = NULL; + + for_each_card_components(card, component) { + if (!strcmp(component->name, rt5682_component[0].name)) { + snd_soc_component_set_jack(component, NULL, NULL); + break; + } + } + + return 0; +} + static struct platform_driver sof_audio = { .probe = sof_audio_probe, + .remove = sof_rt5682_remove, .driver = { .name = "sof_rt5682", .pm = &snd_soc_pm_ops, -- GitLab From 2bdf194e2030fce4f2e91300817338353414ab3b Mon Sep 17 00:00:00 2001 From: Jaska Uimonen Date: Fri, 27 Sep 2019 15:14:05 -0500 Subject: [PATCH 045/993] ASoC: intel: bytcr_rt5651: add null check to support_button_press When removing sof module the support_button_press function will oops because hp_jack pointer is not checked for NULL. So add a check to fix this. Signed-off-by: Jaska Uimonen Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190927201408.925-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt5651.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index 762595de956c..c506c9305043 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -1770,6 +1770,9 @@ static int rt5651_detect_headset(struct snd_soc_component *component) static bool rt5651_support_button_press(struct rt5651_priv *rt5651) { + if (!rt5651->hp_jack) + return false; + /* Button press support only works with internal jack-detection */ return (rt5651->hp_jack->status & SND_JACK_MICROPHONE) && rt5651->gpiod_hp_det == NULL; -- GitLab From 1252b283141f03c3dffd139292c862cae10e174d Mon Sep 17 00:00:00 2001 From: Yizhuo Date: Sun, 29 Sep 2019 10:09:57 -0700 Subject: [PATCH 046/993] regulator: pfuze100-regulator: Variable "val" in pfuze100_regulator_probe() could be uninitialized In function pfuze100_regulator_probe(), variable "val" could be initialized if regmap_read() fails. However, "val" is used to decide the control flow later in the if statement, which is potentially unsafe. Signed-off-by: Yizhuo Link: https://lore.kernel.org/r/20190929170957.14775-1-yzhai003@ucr.edu Signed-off-by: Mark Brown --- drivers/regulator/pfuze100-regulator.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index df5df1c495ad..689537927f6f 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c @@ -788,7 +788,13 @@ static int pfuze100_regulator_probe(struct i2c_client *client, /* SW2~SW4 high bit check and modify the voltage value table */ if (i >= sw_check_start && i <= sw_check_end) { - regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val); + ret = regmap_read(pfuze_chip->regmap, + desc->vsel_reg, &val); + if (ret) { + dev_err(&client->dev, "Fails to read from the register.\n"); + return ret; + } + if (val & sw_hi) { if (pfuze_chip->chip_id == PFUZE3000 || pfuze_chip->chip_id == PFUZE3001) { -- GitLab From 86c1aea84b97120a6d428ce17a2ebd55be677f56 Mon Sep 17 00:00:00 2001 From: Brian Vazquez Date: Tue, 1 Oct 2019 10:37:27 -0700 Subject: [PATCH 047/993] selftests/bpf: test_progs: Don't leak server_fd in tcp_rtt server_fd needs to be closed if pthread can't be created. Fixes: 8a03222f508b ("selftests/bpf: test_progs: fix client/server race in tcp_rtt") Signed-off-by: Brian Vazquez Signed-off-by: Daniel Borkmann Reviewed-by: Stanislav Fomichev Link: https://lore.kernel.org/bpf/20191001173728.149786-2-brianvv@google.com --- tools/testing/selftests/bpf/prog_tests/tcp_rtt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c b/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c index a82da555b1b0..f4cd60d6fba2 100644 --- a/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c +++ b/tools/testing/selftests/bpf/prog_tests/tcp_rtt.c @@ -260,13 +260,14 @@ void test_tcp_rtt(void) if (CHECK_FAIL(pthread_create(&tid, NULL, server_thread, (void *)&server_fd))) - goto close_cgroup_fd; + goto close_server_fd; pthread_mutex_lock(&server_started_mtx); pthread_cond_wait(&server_started, &server_started_mtx); pthread_mutex_unlock(&server_started_mtx); CHECK_FAIL(run_test(cgroup_fd, server_fd)); +close_server_fd: close(server_fd); close_cgroup_fd: close(cgroup_fd); -- GitLab From a2d074e4c6e81ec9ab359d54f0b88273c738de37 Mon Sep 17 00:00:00 2001 From: Brian Vazquez Date: Tue, 1 Oct 2019 10:37:28 -0700 Subject: [PATCH 048/993] selftests/bpf: test_progs: Don't leak server_fd in test_sockopt_inherit server_fd needs to be closed if pthread can't be created. Fixes: e3e02e1d9c24 ("selftests/bpf: test_progs: convert test_sockopt_inherit") Signed-off-by: Brian Vazquez Signed-off-by: Daniel Borkmann Reviewed-by: Stanislav Fomichev Link: https://lore.kernel.org/bpf/20191001173728.149786-3-brianvv@google.com --- tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c b/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c index 6cbeea7b4bf1..8547ecbdc61f 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c +++ b/tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c @@ -195,7 +195,7 @@ static void run_test(int cgroup_fd) if (CHECK_FAIL(pthread_create(&tid, NULL, server_thread, (void *)&server_fd))) - goto close_bpf_object; + goto close_server_fd; pthread_mutex_lock(&server_started_mtx); pthread_cond_wait(&server_started, &server_started_mtx); -- GitLab From c91a9cfe9f6d136172a52ff6e01b3f83ba850c19 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 26 Sep 2019 10:54:33 +0200 Subject: [PATCH 049/993] rt2x00: initialize last_reset Initialize last_reset variable to INITIAL_JIFFIES, otherwise it is not possible to test H/W reset for first 5 minutes of system run. Fixes: e403fa31ed71 ("rt2x00: add restart hw") Reported-and-tested-by: Jonathan Liu Signed-off-by: Stanislaw Gruszka Signed-off-by: Kalle Valo --- drivers/net/wireless/ralink/rt2x00/rt2x00debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c index 4d4e3888ef20..f2395309ec00 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c @@ -555,7 +555,7 @@ static ssize_t rt2x00debug_write_restart_hw(struct file *file, { struct rt2x00debug_intf *intf = file->private_data; struct rt2x00_dev *rt2x00dev = intf->rt2x00dev; - static unsigned long last_reset; + static unsigned long last_reset = INITIAL_JIFFIES; if (!rt2x00_has_cap_restart_hw(rt2x00dev)) return -EOPNOTSUPP; -- GitLab From 82af5b6609673f1cc7d3453d0be3d292dfffc813 Mon Sep 17 00:00:00 2001 From: Nayna Jain Date: Tue, 1 Oct 2019 19:37:18 -0400 Subject: [PATCH 050/993] sysfs: Fixes __BIN_ATTR_WO() macro This patch fixes the size and write parameter for the macro __BIN_ATTR_WO(). Fixes: 7f905761e15a8 ("sysfs: add BIN_ATTR_WO() macro") Signed-off-by: Nayna Jain Link: https://lore.kernel.org/r/1569973038-2710-1-git-send-email-nayna@linux.ibm.com Signed-off-by: Greg Kroah-Hartman --- include/linux/sysfs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 5420817ed317..fa7ee503fb76 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -196,9 +196,9 @@ struct bin_attribute { .size = _size, \ } -#define __BIN_ATTR_WO(_name) { \ +#define __BIN_ATTR_WO(_name, _size) { \ .attr = { .name = __stringify(_name), .mode = 0200 }, \ - .store = _name##_store, \ + .write = _name##_write, \ .size = _size, \ } -- GitLab From 3ae7359c0e39f42a96284d6798fc669acff38140 Mon Sep 17 00:00:00 2001 From: Stuart Henderson Date: Wed, 2 Oct 2019 09:42:40 +0100 Subject: [PATCH 051/993] ASoC: wm_adsp: Don't generate kcontrols without READ flags User space always expects to be able to read ALSA controls, so ensure no kcontrols are generated without an appropriate READ flag. In the case of a read of such a control zeros will be returned. Signed-off-by: Stuart Henderson Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20191002084240.21589-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 85396d920e0a..9b8bb7bbe945 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -1259,8 +1259,7 @@ static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len) } if (in) { - if (in & WMFW_CTL_FLAG_READABLE) - out |= rd; + out |= rd; if (in & WMFW_CTL_FLAG_WRITEABLE) out |= wr; if (in & WMFW_CTL_FLAG_VOLATILE) -- GitLab From afce285b859cea91c182015fc9858ea58c26cd0e Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Mon, 16 Sep 2019 12:45:48 -0700 Subject: [PATCH 052/993] Input: da9063 - fix capability and drop KEY_SLEEP Since commit f889beaaab1c ("Input: da9063 - report KEY_POWER instead of KEY_SLEEP during power key-press") KEY_SLEEP isn't supported anymore. This caused input device to not generate any events if "dlg,disable-key-power" is set. Fix this by unconditionally setting KEY_POWER capability, and not declaring KEY_SLEEP. Fixes: f889beaaab1c ("Input: da9063 - report KEY_POWER instead of KEY_SLEEP during power key-press") Signed-off-by: Marco Felsch Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/misc/da9063_onkey.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/input/misc/da9063_onkey.c b/drivers/input/misc/da9063_onkey.c index dace8577fa43..79851923ee57 100644 --- a/drivers/input/misc/da9063_onkey.c +++ b/drivers/input/misc/da9063_onkey.c @@ -232,10 +232,7 @@ static int da9063_onkey_probe(struct platform_device *pdev) onkey->input->phys = onkey->phys; onkey->input->dev.parent = &pdev->dev; - if (onkey->key_power) - input_set_capability(onkey->input, EV_KEY, KEY_POWER); - - input_set_capability(onkey->input, EV_KEY, KEY_SLEEP); + input_set_capability(onkey->input, EV_KEY, KEY_POWER); INIT_DELAYED_WORK(&onkey->work, da9063_poll_on); -- GitLab From bd3b8480237680b5967aee3c814b92b2fd87a582 Mon Sep 17 00:00:00 2001 From: Yauhen Kharuzhy Date: Mon, 16 Sep 2019 16:32:24 -0700 Subject: [PATCH 053/993] Input: goodix - add support for 9-bytes reports Some variants of Goodix touchscreen firmwares use 9-bytes finger report format instead of common 8-bytes format. This report format may be present as: struct goodix_contact_data { uint8_t unknown1; uint8_t track_id; uint8_t unknown2; uint16_t x; uint16_t y; uint16_t w; }__attribute__((packed)); Add support for such format and use it for Lenovo Yoga Book notebook (which uses a Goodix touchpad as a touch keyboard). Signed-off-by: Yauhen Kharuzhy Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/goodix.c | 58 +++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 5178ea8b5f30..fb43aa708660 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -53,6 +53,7 @@ struct goodix_ts_data { const char *cfg_name; struct completion firmware_loading_complete; unsigned long irq_flags; + unsigned int contact_size; }; #define GOODIX_GPIO_INT_NAME "irq" @@ -62,6 +63,7 @@ struct goodix_ts_data { #define GOODIX_MAX_WIDTH 4096 #define GOODIX_INT_TRIGGER 1 #define GOODIX_CONTACT_SIZE 8 +#define GOODIX_MAX_CONTACT_SIZE 9 #define GOODIX_MAX_CONTACTS 10 #define GOODIX_CONFIG_MAX_LENGTH 240 @@ -144,6 +146,19 @@ static const struct dmi_system_id rotated_screen[] = { {} }; +static const struct dmi_system_id nine_bytes_report[] = { +#if defined(CONFIG_DMI) && defined(CONFIG_X86) + { + .ident = "Lenovo YogaBook", + /* YB1-X91L/F and YB1-X90L/F */ + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9") + } + }, +#endif + {} +}; + /** * goodix_i2c_read - read data from a register of the i2c slave device. * @@ -249,7 +264,7 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) max_timeout = jiffies + msecs_to_jiffies(GOODIX_BUFFER_STATUS_TIMEOUT); do { error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, - data, GOODIX_CONTACT_SIZE + 1); + data, ts->contact_size + 1); if (error) { dev_err(&ts->client->dev, "I2C transfer error: %d\n", error); @@ -262,12 +277,12 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) return -EPROTO; if (touch_num > 1) { - data += 1 + GOODIX_CONTACT_SIZE; + data += 1 + ts->contact_size; error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR + - 1 + GOODIX_CONTACT_SIZE, + 1 + ts->contact_size, data, - GOODIX_CONTACT_SIZE * + ts->contact_size * (touch_num - 1)); if (error) return error; @@ -286,7 +301,7 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) return 0; } -static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) +static void goodix_ts_report_touch_8b(struct goodix_ts_data *ts, u8 *coor_data) { int id = coor_data[0] & 0x0F; int input_x = get_unaligned_le16(&coor_data[1]); @@ -301,6 +316,21 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w); } +static void goodix_ts_report_touch_9b(struct goodix_ts_data *ts, u8 *coor_data) +{ + int id = coor_data[1] & 0x0F; + int input_x = get_unaligned_le16(&coor_data[3]); + int input_y = get_unaligned_le16(&coor_data[5]); + int input_w = get_unaligned_le16(&coor_data[7]); + + input_mt_slot(ts->input_dev, id); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); + touchscreen_report_pos(ts->input_dev, &ts->prop, + input_x, input_y, true); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w); +} + /** * goodix_process_events - Process incoming events * @@ -311,7 +341,7 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) */ static void goodix_process_events(struct goodix_ts_data *ts) { - u8 point_data[1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS]; + u8 point_data[1 + GOODIX_MAX_CONTACT_SIZE * GOODIX_MAX_CONTACTS]; int touch_num; int i; @@ -326,8 +356,12 @@ static void goodix_process_events(struct goodix_ts_data *ts) input_report_key(ts->input_dev, KEY_LEFTMETA, point_data[0] & BIT(4)); for (i = 0; i < touch_num; i++) - goodix_ts_report_touch(ts, - &point_data[1 + GOODIX_CONTACT_SIZE * i]); + if (ts->contact_size == 9) + goodix_ts_report_touch_9b(ts, + &point_data[1 + ts->contact_size * i]); + else + goodix_ts_report_touch_8b(ts, + &point_data[1 + ts->contact_size * i]); input_mt_sync_frame(ts->input_dev); input_sync(ts->input_dev); @@ -730,6 +764,13 @@ static int goodix_configure_dev(struct goodix_ts_data *ts) "Applying '180 degrees rotated screen' quirk\n"); } + if (dmi_check_system(nine_bytes_report)) { + ts->contact_size = 9; + + dev_dbg(&ts->client->dev, + "Non-standard 9-bytes report format quirk\n"); + } + error = input_mt_init_slots(ts->input_dev, ts->max_touch_num, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); if (error) { @@ -810,6 +851,7 @@ static int goodix_ts_probe(struct i2c_client *client, ts->client = client; i2c_set_clientdata(client, ts); init_completion(&ts->firmware_loading_complete); + ts->contact_size = GOODIX_CONTACT_SIZE; error = goodix_get_gpio_config(ts); if (error) -- GitLab From 35b9ad840892d979dbeffe702dae95a3cbefa07b Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 6 Aug 2019 14:24:39 +1000 Subject: [PATCH 054/993] ACPI: HMAT: ACPI_HMAT_MEMORY_PD_VALID is deprecated since ACPI-6.3 ACPI-6.3 corresponds to when HMAT revision was bumped from 1 to 2. In this version ACPI_HMAT_MEMORY_PD_VALID was deprecated and made reserved. As such in revision 2+ we shouldn't be testing this flag. This is as per ACPI-6.3, 5.2.27.3, Table 5-145 "Memory Proximity Domain Attributes Structure" for Flags. Signed-off-by: Daniel Black Reviewed-by: Tao Xu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/hmat/hmat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/hmat/hmat.c b/drivers/acpi/hmat/hmat.c index 8f9a28a870b0..8b0de8a3c647 100644 --- a/drivers/acpi/hmat/hmat.c +++ b/drivers/acpi/hmat/hmat.c @@ -403,7 +403,7 @@ static int __init hmat_parse_proximity_domain(union acpi_subtable_headers *heade pr_info("HMAT: Memory Flags:%04x Processor Domain:%d Memory Domain:%d\n", p->flags, p->processor_PD, p->memory_PD); - if (p->flags & ACPI_HMAT_MEMORY_PD_VALID) { + if (p->flags & ACPI_HMAT_MEMORY_PD_VALID && hmat_revision == 1) { target = find_mem_target(p->memory_PD); if (!target) { pr_debug("HMAT: Memory Domain missing from SRAT\n"); -- GitLab From e8307ec51efebf579da5966aa5da5ab5353c61c7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 2 Oct 2019 17:29:46 +0200 Subject: [PATCH 055/993] mmc: renesas_sdhi: Do not use platform_get_irq() to count interrupts As platform_get_irq() now prints an error when the interrupt does not exist, counting interrupts by looping until failure causes the printing of scary messages like: renesas_sdhi_internal_dmac ee140000.sd: IRQ index 1 not found Fix this by using the platform_irq_count() helper to avoid touching non-existent interrupts. Fixes: 7723f4c5ecdb8d83 ("driver core: platform: Add an error message to platform_get_irq*()") Signed-off-by: Geert Uytterhoeven Reviewed-by: Yoshihiro Shimoda Reviewed-by: Wolfram Sang Tested-by: Yoshihiro Shimoda Tested-by: Wolfram Sang Signed-off-by: Ulf Hansson --- drivers/mmc/host/renesas_sdhi_core.c | 31 +++++++++++++++++----------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index d4ada5cca2d1..234551a68739 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c @@ -646,8 +646,8 @@ int renesas_sdhi_probe(struct platform_device *pdev, struct tmio_mmc_dma *dma_priv; struct tmio_mmc_host *host; struct renesas_sdhi *priv; + int num_irqs, irq, ret, i; struct resource *res; - int irq, ret, i; u16 ver; of_data = of_device_get_match_data(&pdev->dev); @@ -825,24 +825,31 @@ int renesas_sdhi_probe(struct platform_device *pdev, host->hs400_complete = renesas_sdhi_hs400_complete; } - i = 0; - while (1) { + num_irqs = platform_irq_count(pdev); + if (num_irqs < 0) { + ret = num_irqs; + goto eirq; + } + + /* There must be at least one IRQ source */ + if (!num_irqs) { + ret = -ENXIO; + goto eirq; + } + + for (i = 0; i < num_irqs; i++) { irq = platform_get_irq(pdev, i); - if (irq < 0) - break; - i++; + if (irq < 0) { + ret = irq; + goto eirq; + } + ret = devm_request_irq(&pdev->dev, irq, tmio_mmc_irq, 0, dev_name(&pdev->dev), host); if (ret) goto eirq; } - /* There must be at least one IRQ source */ - if (!i) { - ret = irq; - goto eirq; - } - dev_info(&pdev->dev, "%s base at 0x%08lx max clock rate %u MHz\n", mmc_hostname(host->mmc), (unsigned long) (platform_get_resource(pdev, IORESOURCE_MEM, 0)->start), -- GitLab From faf97b84fa86d40eba5a30e9071dfb55133fb1b7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 1 Oct 2019 20:08:34 +0200 Subject: [PATCH 056/993] mmc: sh_mmcif: Use platform_get_irq_optional() for optional interrupt As platform_get_irq() now prints an error when the interrupt does not exist, a scary warning may be printed for an optional interrupt: sh_mmcif ee200000.mmc: IRQ index 1 not found Fix this by calling platform_get_irq_optional() instead for the second interrupt, which is optional. Remove the now superfluous error printing for the first interrupt, which is mandatory. Fixes: 7723f4c5ecdb8d83 ("driver core: platform: Add an error message to platform_get_irq*()") Signed-off-by: Geert Uytterhoeven Reviewed-by: Yoshihiro Shimoda Tested-by: Yoshihiro Shimoda Reviewed-by: Wolfram Sang Tested-by: Wolfram Sang Signed-off-by: Ulf Hansson --- drivers/mmc/host/sh_mmcif.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 81bd9afb0980..98c575de43c7 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c @@ -1393,11 +1393,9 @@ static int sh_mmcif_probe(struct platform_device *pdev) const char *name; irq[0] = platform_get_irq(pdev, 0); - irq[1] = platform_get_irq(pdev, 1); - if (irq[0] < 0) { - dev_err(dev, "Get irq error\n"); + irq[1] = platform_get_irq_optional(pdev, 1); + if (irq[0] < 0) return -ENXIO; - } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(dev, res); -- GitLab From b1e620e7d32f5aad5353cc3cfc13ed99fea65d3a Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Wed, 2 Oct 2019 16:30:37 +0100 Subject: [PATCH 057/993] ASoc: rockchip: i2s: Fix RPM imbalance If rockchip_pcm_platform_register() fails, e.g. upon deferring to wait for an absent DMA channel, we return without disabling RPM, which makes subsequent re-probe attempts scream with errors about the unbalanced enable. Don't do that. Fixes: ebb75c0bdba2 ("ASoC: rockchip: i2s: Adjust devm usage") Signed-off-by: Robin Murphy Link: https://lore.kernel.org/r/bcb12a849a05437fb18372bc7536c649b94bdf07.1570029862.git.robin.murphy@arm.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index af2d5a6124c8..61c984f10d8e 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -677,7 +677,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev) ret = rockchip_pcm_platform_register(&pdev->dev); if (ret) { dev_err(&pdev->dev, "Could not register PCM\n"); - return ret; + goto err_suspend; } return 0; -- GitLab From e55190f26f92927e95aba22b069679311d5379ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20T=C3=B6pel?= Date: Tue, 1 Oct 2019 13:22:49 +0200 Subject: [PATCH 058/993] samples/bpf: Fix build for task_fd_query_user.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add missing include for which was removed from perf-sys.h in commit 91854f9a077e ("perf tools: Move everything related to sys_perf_event_open() to perf-sys.h"). Fixes: 91854f9a077e ("perf tools: Move everything related to sys_perf_event_open() to perf-sys.h") Reported-by: KP Singh Reported-by: Florent Revest Signed-off-by: Björn Töpel Signed-off-by: Daniel Borkmann Tested-by: KP Singh Acked-by: Song Liu Link: https://lore.kernel.org/bpf/20191001112249.27341-1-bjorn.topel@gmail.com --- samples/bpf/task_fd_query_user.c | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/bpf/task_fd_query_user.c b/samples/bpf/task_fd_query_user.c index e39938058223..4c31b305e6ef 100644 --- a/samples/bpf/task_fd_query_user.c +++ b/samples/bpf/task_fd_query_user.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "libbpf.h" #include "bpf_load.h" -- GitLab From df551058f7a303bd3a17a4cef001349974962ce8 Mon Sep 17 00:00:00 2001 From: Magnus Karlsson Date: Wed, 2 Oct 2019 08:31:59 +0200 Subject: [PATCH 059/993] xsk: Fix crash in poll when device does not support ndo_xsk_wakeup Fixes a crash in poll() when an AF_XDP socket is opened in copy mode and the bound device does not have ndo_xsk_wakeup defined. Avoid trying to call the non-existing ndo and instead call the internal xsk sendmsg function to send packets in the same way (from the application's point of view) as calling sendmsg() in any mode or poll() in zero-copy mode would have done. The application should behave in the same way independent on if zero-copy mode or copy mode is used. Fixes: 77cd0d7b3f25 ("xsk: add support for need_wakeup flag in AF_XDP rings") Reported-by: syzbot+a5765ed8cdb1cca4d249@syzkaller.appspotmail.com Signed-off-by: Magnus Karlsson Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/1569997919-11541-1-git-send-email-magnus.karlsson@intel.com --- net/xdp/xsk.c | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c index fa8fbb8fa3c8..9044073fbf22 100644 --- a/net/xdp/xsk.c +++ b/net/xdp/xsk.c @@ -305,9 +305,8 @@ bool xsk_umem_consume_tx(struct xdp_umem *umem, struct xdp_desc *desc) } EXPORT_SYMBOL(xsk_umem_consume_tx); -static int xsk_zc_xmit(struct sock *sk) +static int xsk_zc_xmit(struct xdp_sock *xs) { - struct xdp_sock *xs = xdp_sk(sk); struct net_device *dev = xs->dev; return dev->netdev_ops->ndo_xsk_wakeup(dev, xs->queue_id, @@ -327,11 +326,10 @@ static void xsk_destruct_skb(struct sk_buff *skb) sock_wfree(skb); } -static int xsk_generic_xmit(struct sock *sk, struct msghdr *m, - size_t total_len) +static int xsk_generic_xmit(struct sock *sk) { - u32 max_batch = TX_BATCH_SIZE; struct xdp_sock *xs = xdp_sk(sk); + u32 max_batch = TX_BATCH_SIZE; bool sent_frame = false; struct xdp_desc desc; struct sk_buff *skb; @@ -394,6 +392,18 @@ static int xsk_generic_xmit(struct sock *sk, struct msghdr *m, return err; } +static int __xsk_sendmsg(struct sock *sk) +{ + struct xdp_sock *xs = xdp_sk(sk); + + if (unlikely(!(xs->dev->flags & IFF_UP))) + return -ENETDOWN; + if (unlikely(!xs->tx)) + return -ENOBUFS; + + return xs->zc ? xsk_zc_xmit(xs) : xsk_generic_xmit(sk); +} + static int xsk_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len) { bool need_wait = !(m->msg_flags & MSG_DONTWAIT); @@ -402,21 +412,18 @@ static int xsk_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len) if (unlikely(!xsk_is_bound(xs))) return -ENXIO; - if (unlikely(!(xs->dev->flags & IFF_UP))) - return -ENETDOWN; - if (unlikely(!xs->tx)) - return -ENOBUFS; - if (need_wait) + if (unlikely(need_wait)) return -EOPNOTSUPP; - return (xs->zc) ? xsk_zc_xmit(sk) : xsk_generic_xmit(sk, m, total_len); + return __xsk_sendmsg(sk); } static unsigned int xsk_poll(struct file *file, struct socket *sock, struct poll_table_struct *wait) { unsigned int mask = datagram_poll(file, sock, wait); - struct xdp_sock *xs = xdp_sk(sock->sk); + struct sock *sk = sock->sk; + struct xdp_sock *xs = xdp_sk(sk); struct net_device *dev; struct xdp_umem *umem; @@ -426,9 +433,14 @@ static unsigned int xsk_poll(struct file *file, struct socket *sock, dev = xs->dev; umem = xs->umem; - if (umem->need_wakeup) - dev->netdev_ops->ndo_xsk_wakeup(dev, xs->queue_id, - umem->need_wakeup); + if (umem->need_wakeup) { + if (dev->netdev_ops->ndo_xsk_wakeup) + dev->netdev_ops->ndo_xsk_wakeup(dev, xs->queue_id, + umem->need_wakeup); + else + /* Poll needs to drive Tx also in copy mode */ + __xsk_sendmsg(sk); + } if (xs->rx && !xskq_empty_desc(xs->rx)) mask |= POLLIN | POLLRDNORM; -- GitLab From 98beb3edeb974e906a81f305d88f7bc96b2ec83e Mon Sep 17 00:00:00 2001 From: KP Singh Date: Wed, 2 Oct 2019 21:16:52 +0200 Subject: [PATCH 060/993] samples/bpf: Add a workaround for asm_inline This was added in commit eb111869301e ("compiler-types.h: add asm_inline definition") and breaks samples/bpf as clang does not support asm __inline. Fixes: eb111869301e ("compiler-types.h: add asm_inline definition") Co-developed-by: Florent Revest Signed-off-by: Florent Revest Signed-off-by: KP Singh Signed-off-by: Daniel Borkmann Acked-by: Song Liu Acked-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20191002191652.11432-1-kpsingh@chromium.org --- samples/bpf/asm_goto_workaround.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/samples/bpf/asm_goto_workaround.h b/samples/bpf/asm_goto_workaround.h index 7409722727ca..7048bb3594d6 100644 --- a/samples/bpf/asm_goto_workaround.h +++ b/samples/bpf/asm_goto_workaround.h @@ -3,7 +3,8 @@ #ifndef __ASM_GOTO_WORKAROUND_H #define __ASM_GOTO_WORKAROUND_H -/* this will bring in asm_volatile_goto macro definition +/* + * This will bring in asm_volatile_goto and asm_inline macro definitions * if enabled by compiler and config options. */ #include @@ -13,5 +14,15 @@ #define asm_volatile_goto(x...) asm volatile("invalid use of asm_volatile_goto") #endif +/* + * asm_inline is defined as asm __inline in "include/linux/compiler_types.h" + * if supported by the kernel's CC (i.e CONFIG_CC_HAS_ASM_INLINE) which is not + * supported by CLANG. + */ +#ifdef asm_inline +#undef asm_inline +#define asm_inline asm +#endif + #define volatile(x...) volatile("") #endif -- GitLab From 96d49bbfe6c1a6bb43ccd00fb87aca100e32e5e2 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 3 Oct 2019 09:44:10 -0700 Subject: [PATCH 061/993] ARM: omap2plus_defconfig: Fix selected panels after generic panel changes The old omapdrm panels got removed for v5.4 in favor of generic panels, and the Kconfig options changed. Let's update omap2plus_defconfig accordingly so the same panels are still enabled. Cc: Jyri Sarha Cc: Laurent Pinchart Cc: Tomi Valkeinen Signed-off-by: Tony Lindgren --- arch/arm/configs/omap2plus_defconfig | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 64eb896907bf..b647e463b9c7 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -356,14 +356,14 @@ CONFIG_DRM_OMAP_CONNECTOR_HDMI=m CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV=m CONFIG_DRM_OMAP_PANEL_DPI=m CONFIG_DRM_OMAP_PANEL_DSI_CM=m -CONFIG_DRM_OMAP_PANEL_SONY_ACX565AKM=m -CONFIG_DRM_OMAP_PANEL_LGPHILIPS_LB035Q02=m -CONFIG_DRM_OMAP_PANEL_SHARP_LS037V7DW01=m -CONFIG_DRM_OMAP_PANEL_TPO_TD028TTEC1=m -CONFIG_DRM_OMAP_PANEL_TPO_TD043MTEA1=m -CONFIG_DRM_OMAP_PANEL_NEC_NL8048HL11=m CONFIG_DRM_TILCDC=m CONFIG_DRM_PANEL_SIMPLE=m +CONFIG_DRM_PANEL_LG_LB035Q02=m +CONFIG_DRM_PANEL_NEC_NL8048HL11=m +CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m +CONFIG_DRM_PANEL_SONY_ACX565AKM=m +CONFIG_DRM_PANEL_TPO_TD028TTEC1=m +CONFIG_DRM_PANEL_TPO_TD043MTEA1=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y -- GitLab From d9d4b1e46d9543a82c23f6df03f4ad697dab361b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 3 Oct 2019 14:53:59 -0400 Subject: [PATCH 062/993] HID: Fix assumption that devices have inputs The syzbot fuzzer found a slab-out-of-bounds write bug in the hid-gaff driver. The problem is caused by the driver's assumption that the device must have an input report. While this will be true for all normal HID input devices, a suitably malicious device can violate the assumption. The same assumption is present in over a dozen other HID drivers. This patch fixes them by checking that the list of hid_inputs for the hid_device is nonempty before allowing it to be used. Reported-and-tested-by: syzbot+403741a091bf41d4ae79@syzkaller.appspotmail.com Signed-off-by: Alan Stern CC: Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-axff.c | 11 +++++++++-- drivers/hid/hid-dr.c | 12 +++++++++--- drivers/hid/hid-emsff.c | 12 +++++++++--- drivers/hid/hid-gaff.c | 12 +++++++++--- drivers/hid/hid-holtekff.c | 12 +++++++++--- drivers/hid/hid-lg2ff.c | 12 +++++++++--- drivers/hid/hid-lg3ff.c | 11 +++++++++-- drivers/hid/hid-lg4ff.c | 11 +++++++++-- drivers/hid/hid-lgff.c | 11 +++++++++-- drivers/hid/hid-logitech-hidpp.c | 11 +++++++++-- drivers/hid/hid-microsoft.c | 12 +++++++++--- drivers/hid/hid-sony.c | 12 +++++++++--- drivers/hid/hid-tmff.c | 12 +++++++++--- drivers/hid/hid-zpff.c | 12 +++++++++--- 14 files changed, 126 insertions(+), 37 deletions(-) diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c index 6654c1550e2e..fbe4e16ab029 100644 --- a/drivers/hid/hid-axff.c +++ b/drivers/hid/hid-axff.c @@ -63,13 +63,20 @@ static int axff_init(struct hid_device *hid) { struct axff_device *axff; struct hid_report *report; - struct hid_input *hidinput = list_first_entry(&hid->inputs, struct hid_input, list); + struct hid_input *hidinput; struct list_head *report_list =&hid->report_enum[HID_OUTPUT_REPORT].report_list; - struct input_dev *dev = hidinput->input; + struct input_dev *dev; int field_count = 0; int i, j; int error; + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_first_entry(&hid->inputs, struct hid_input, list); + dev = hidinput->input; + if (list_empty(report_list)) { hid_err(hid, "no output reports found\n"); return -ENODEV; diff --git a/drivers/hid/hid-dr.c b/drivers/hid/hid-dr.c index 17e17f9a597b..947f19f8685f 100644 --- a/drivers/hid/hid-dr.c +++ b/drivers/hid/hid-dr.c @@ -75,13 +75,19 @@ static int drff_init(struct hid_device *hid) { struct drff_device *drff; struct hid_report *report; - struct hid_input *hidinput = list_first_entry(&hid->inputs, - struct hid_input, list); + struct hid_input *hidinput; struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; - struct input_dev *dev = hidinput->input; + struct input_dev *dev; int error; + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_first_entry(&hid->inputs, struct hid_input, list); + dev = hidinput->input; + if (list_empty(report_list)) { hid_err(hid, "no output reports found\n"); return -ENODEV; diff --git a/drivers/hid/hid-emsff.c b/drivers/hid/hid-emsff.c index 7cd5651872d3..c34f2e5a049f 100644 --- a/drivers/hid/hid-emsff.c +++ b/drivers/hid/hid-emsff.c @@ -47,13 +47,19 @@ static int emsff_init(struct hid_device *hid) { struct emsff_device *emsff; struct hid_report *report; - struct hid_input *hidinput = list_first_entry(&hid->inputs, - struct hid_input, list); + struct hid_input *hidinput; struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; - struct input_dev *dev = hidinput->input; + struct input_dev *dev; int error; + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_first_entry(&hid->inputs, struct hid_input, list); + dev = hidinput->input; + if (list_empty(report_list)) { hid_err(hid, "no output reports found\n"); return -ENODEV; diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c index 0f95c96b70f8..ecbd3995a4eb 100644 --- a/drivers/hid/hid-gaff.c +++ b/drivers/hid/hid-gaff.c @@ -64,14 +64,20 @@ static int gaff_init(struct hid_device *hid) { struct gaff_device *gaff; struct hid_report *report; - struct hid_input *hidinput = list_entry(hid->inputs.next, - struct hid_input, list); + struct hid_input *hidinput; struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; struct list_head *report_ptr = report_list; - struct input_dev *dev = hidinput->input; + struct input_dev *dev; int error; + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_entry(hid->inputs.next, struct hid_input, list); + dev = hidinput->input; + if (list_empty(report_list)) { hid_err(hid, "no output reports found\n"); return -ENODEV; diff --git a/drivers/hid/hid-holtekff.c b/drivers/hid/hid-holtekff.c index 10a720558830..8619b80c834c 100644 --- a/drivers/hid/hid-holtekff.c +++ b/drivers/hid/hid-holtekff.c @@ -124,13 +124,19 @@ static int holtekff_init(struct hid_device *hid) { struct holtekff_device *holtekff; struct hid_report *report; - struct hid_input *hidinput = list_entry(hid->inputs.next, - struct hid_input, list); + struct hid_input *hidinput; struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; - struct input_dev *dev = hidinput->input; + struct input_dev *dev; int error; + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_entry(hid->inputs.next, struct hid_input, list); + dev = hidinput->input; + if (list_empty(report_list)) { hid_err(hid, "no output report found\n"); return -ENODEV; diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c index dd1a6c3a7de6..73d07e35f12a 100644 --- a/drivers/hid/hid-lg2ff.c +++ b/drivers/hid/hid-lg2ff.c @@ -50,11 +50,17 @@ int lg2ff_init(struct hid_device *hid) { struct lg2ff_device *lg2ff; struct hid_report *report; - struct hid_input *hidinput = list_entry(hid->inputs.next, - struct hid_input, list); - struct input_dev *dev = hidinput->input; + struct hid_input *hidinput; + struct input_dev *dev; int error; + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_entry(hid->inputs.next, struct hid_input, list); + dev = hidinput->input; + /* Check that the report looks ok */ report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7); if (!report) diff --git a/drivers/hid/hid-lg3ff.c b/drivers/hid/hid-lg3ff.c index 9ecb6fd06203..b7e1949f3cf7 100644 --- a/drivers/hid/hid-lg3ff.c +++ b/drivers/hid/hid-lg3ff.c @@ -117,12 +117,19 @@ static const signed short ff3_joystick_ac[] = { int lg3ff_init(struct hid_device *hid) { - struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); - struct input_dev *dev = hidinput->input; + struct hid_input *hidinput; + struct input_dev *dev; const signed short *ff_bits = ff3_joystick_ac; int error; int i; + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_entry(hid->inputs.next, struct hid_input, list); + dev = hidinput->input; + /* Check that the report looks ok */ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 35)) return -ENODEV; diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index 03f0220062ca..5e6a0cef2a06 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c @@ -1253,8 +1253,8 @@ static int lg4ff_handle_multimode_wheel(struct hid_device *hid, u16 *real_produc int lg4ff_init(struct hid_device *hid) { - struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); - struct input_dev *dev = hidinput->input; + struct hid_input *hidinput; + struct input_dev *dev; struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; struct hid_report *report = list_entry(report_list->next, struct hid_report, list); const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor); @@ -1266,6 +1266,13 @@ int lg4ff_init(struct hid_device *hid) int mmode_ret, mmode_idx = -1; u16 real_product_id; + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_entry(hid->inputs.next, struct hid_input, list); + dev = hidinput->input; + /* Check that the report looks ok */ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) return -1; diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c index c79a6ec43745..aed4ddc397a9 100644 --- a/drivers/hid/hid-lgff.c +++ b/drivers/hid/hid-lgff.c @@ -115,12 +115,19 @@ static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude) int lgff_init(struct hid_device* hid) { - struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); - struct input_dev *dev = hidinput->input; + struct hid_input *hidinput; + struct input_dev *dev; const signed short *ff_bits = ff_joystick; int error; int i; + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_entry(hid->inputs.next, struct hid_input, list); + dev = hidinput->input; + /* Check that the report looks ok */ if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) return -ENODEV; diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 0179f7ed77e5..1ac1ecc1e67c 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -2084,8 +2084,8 @@ static void hidpp_ff_destroy(struct ff_device *ff) static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) { struct hid_device *hid = hidpp->hid_dev; - struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); - struct input_dev *dev = hidinput->input; + struct hid_input *hidinput; + struct input_dev *dev; const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor); const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice); struct ff_device *ff; @@ -2094,6 +2094,13 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) int error, j, num_slots; u8 version; + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_entry(hid->inputs.next, struct hid_input, list); + dev = hidinput->input; + if (!dev) { hid_err(hid, "Struct input_dev not set!\n"); return -EINVAL; diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 2cf83856f2e4..2d8b589201a4 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c @@ -328,11 +328,17 @@ static int ms_play_effect(struct input_dev *dev, void *data, static int ms_init_ff(struct hid_device *hdev) { - struct hid_input *hidinput = list_entry(hdev->inputs.next, - struct hid_input, list); - struct input_dev *input_dev = hidinput->input; + struct hid_input *hidinput; + struct input_dev *input_dev; struct ms_data *ms = hid_get_drvdata(hdev); + if (list_empty(&hdev->inputs)) { + hid_err(hdev, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_entry(hdev->inputs.next, struct hid_input, list); + input_dev = hidinput->input; + if (!(ms->quirks & MS_QUIRK_FF)) return 0; diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 73c0f7a95e2d..4c6ed6ef31f1 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -2254,9 +2254,15 @@ static int sony_play_effect(struct input_dev *dev, void *data, static int sony_init_ff(struct sony_sc *sc) { - struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, - struct hid_input, list); - struct input_dev *input_dev = hidinput->input; + struct hid_input *hidinput; + struct input_dev *input_dev; + + if (list_empty(&sc->hdev->inputs)) { + hid_err(sc->hdev, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_entry(sc->hdev->inputs.next, struct hid_input, list); + input_dev = hidinput->input; input_set_capability(input_dev, EV_FF, FF_RUMBLE); return input_ff_create_memless(input_dev, NULL, sony_play_effect); diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c index bdfc5ff3b2c5..90acef304536 100644 --- a/drivers/hid/hid-tmff.c +++ b/drivers/hid/hid-tmff.c @@ -124,12 +124,18 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits) struct tmff_device *tmff; struct hid_report *report; struct list_head *report_list; - struct hid_input *hidinput = list_entry(hid->inputs.next, - struct hid_input, list); - struct input_dev *input_dev = hidinput->input; + struct hid_input *hidinput; + struct input_dev *input_dev; int error; int i; + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_entry(hid->inputs.next, struct hid_input, list); + input_dev = hidinput->input; + tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL); if (!tmff) return -ENOMEM; diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c index f90959e94028..3abaca045869 100644 --- a/drivers/hid/hid-zpff.c +++ b/drivers/hid/hid-zpff.c @@ -54,11 +54,17 @@ static int zpff_init(struct hid_device *hid) { struct zpff_device *zpff; struct hid_report *report; - struct hid_input *hidinput = list_entry(hid->inputs.next, - struct hid_input, list); - struct input_dev *dev = hidinput->input; + struct hid_input *hidinput; + struct input_dev *dev; int i, error; + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } + hidinput = list_entry(hid->inputs.next, struct hid_input, list); + dev = hidinput->input; + for (i = 0; i < 4; i++) { report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1); if (!report) -- GitLab From deea9f5fc32040fd6f6132f2260ba410fb5cf98c Mon Sep 17 00:00:00 2001 From: Hugh Cole-Baker Date: Sat, 21 Sep 2019 14:14:57 +0100 Subject: [PATCH 063/993] arm64: dts: rockchip: fix Rockpro64 RK808 interrupt line Fix the pinctrl and interrupt specifier for RK808 to use GPIO3_B2. On the Rockpro64 schematic [1] page 16, it shows GPIO3_B2 used for the interrupt line PMIC_INT_L from the RK808, and there's a note which translates as: "PMU termination GPIO1_C5 changed to this". Tested by setting an RTC wakealarm and checking /proc/interrupts counters. Without this patch, neither the rockchip_gpio_irq counter for the RK808, nor the RTC alarm counter increment when the alarm time is reached. With this patch, both interrupt counters increment by 1 as expected. [1] http://files.pine64.org/doc/rockpro64/rockpro64_v21-SCH.pdf Fixes: e4f3fb490967 ("arm64: dts: rockchip: add initial dts support for Rockpro64") Signed-off-by: Hugh Cole-Baker Link: https://lore.kernel.org/r/20190921131457.36258-1-sigmaris@gmail.com Signed-off-by: Heiko Stuebner --- arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts index 0401d4ec1f45..c27d8a6ae1c5 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts @@ -247,8 +247,8 @@ rk808: pmic@1b { compatible = "rockchip,rk808"; reg = <0x1b>; - interrupt-parent = <&gpio1>; - interrupts = <21 IRQ_TYPE_LEVEL_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; #clock-cells = <1>; clock-output-names = "xin32k", "rk808-clkout2"; pinctrl-names = "default"; @@ -574,7 +574,7 @@ pmic { pmic_int_l: pmic-int-l { - rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; + rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; }; vsel1_gpio: vsel1-gpio { -- GitLab From cb11a90e33c04623428eccb2c693a6b81947c686 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 17 Sep 2019 10:34:53 +0200 Subject: [PATCH 064/993] dt-bindings: arm: rockchip: fix Theobroma-System board bindings The naming convention for the existing Theobroma boards is soc-q7module-baseboard, so rk3399-puma-haikou and the in-kernel devicetrees also follow that scheme. For some reason in the binding a wrong or outdated naming slipped in which does not match the used devicetrees and makes the dt-schema complain now. Fix this by using the names used in the wild by actual boards. Fixes: a323a513c712 ("dt-bindings: arm: Convert Rockchip board/soc bindings to json-schema") [although the issue was also present in the old txt file] Signed-off-by: Heiko Stuebner Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/20190917083453.25744-1-heiko@sntech.de --- Documentation/devicetree/bindings/arm/rockchip.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml index c82c5e57d44c..9c7e70335ac0 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.yaml +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml @@ -496,12 +496,12 @@ properties: - description: Theobroma Systems RK3368-uQ7 with Haikou baseboard items: - - const: tsd,rk3368-uq7-haikou + - const: tsd,rk3368-lion-haikou - const: rockchip,rk3368 - description: Theobroma Systems RK3399-Q7 with Haikou baseboard items: - - const: tsd,rk3399-q7-haikou + - const: tsd,rk3399-puma-haikou - const: rockchip,rk3399 - description: Tronsmart Orion R68 Meta -- GitLab From 8f8fed0cdbbd6cdbf28d9ebe662f45765d2f7d39 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Tue, 1 Oct 2019 16:48:39 +0900 Subject: [PATCH 065/993] scsi: core: save/restore command resid for error handling When a non-passthrough command is terminated with CHECK CONDITION, request sense is executed by hijacking the command descriptor. Since scsi_eh_prep_cmnd() and scsi_eh_restore_cmnd() do not save/restore the original command resid, the value returned on failure of the original command is lost and replaced with the value set by the execution of the request sense command. This value may in many instances be unaligned to the device sector size, causing sd_done() to print a warning message about the incorrect unaligned resid before the command is retried. Fix this problem by saving the original command residual in struct scsi_eh_save using scsi_eh_prep_cmnd() and restoring it in scsi_eh_restore_cmnd(). In addition, to make sure that the request sense command is executed with a correctly initialized command structure, also reset the residual to 0 in scsi_eh_prep_cmnd() after saving the original command value in struct scsi_eh_save. Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191001074839.1994-1-damien.lemoal@wdc.com Signed-off-by: Damien Le Moal Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_error.c | 3 +++ include/scsi/scsi_eh.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 1c470e31ae81..ae2fa170f6ad 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -967,6 +967,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, ses->data_direction = scmd->sc_data_direction; ses->sdb = scmd->sdb; ses->result = scmd->result; + ses->resid_len = scmd->req.resid_len; ses->underflow = scmd->underflow; ses->prot_op = scmd->prot_op; ses->eh_eflags = scmd->eh_eflags; @@ -977,6 +978,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, memset(scmd->cmnd, 0, BLK_MAX_CDB); memset(&scmd->sdb, 0, sizeof(scmd->sdb)); scmd->result = 0; + scmd->req.resid_len = 0; if (sense_bytes) { scmd->sdb.length = min_t(unsigned, SCSI_SENSE_BUFFERSIZE, @@ -1029,6 +1031,7 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses) scmd->sc_data_direction = ses->data_direction; scmd->sdb = ses->sdb; scmd->result = ses->result; + scmd->req.resid_len = ses->resid_len; scmd->underflow = ses->underflow; scmd->prot_op = ses->prot_op; scmd->eh_eflags = ses->eh_eflags; diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index 3810b340551c..6bd5ed695a5e 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h @@ -32,6 +32,7 @@ extern int scsi_ioctl_reset(struct scsi_device *, int __user *); struct scsi_eh_save { /* saved state */ int result; + unsigned int resid_len; int eh_eflags; enum dma_data_direction data_direction; unsigned underflow; -- GitLab From 2190168aaea42c31bff7b9a967e7b045f07df095 Mon Sep 17 00:00:00 2001 From: Steffen Maier Date: Tue, 1 Oct 2019 12:49:49 +0200 Subject: [PATCH 066/993] scsi: zfcp: fix reaction on bit error threshold notification On excessive bit errors for the FCP channel ingress fibre path, the channel notifies us. Previously, we only emitted a kernel message and a trace record. Since performance can become suboptimal with I/O timeouts due to bit errors, we now stop using an FCP device by default on channel notification so multipath on top can timely failover to other paths. A new module parameter zfcp.ber_stop can be used to get zfcp old behavior. User explanation of new kernel message: * Description: * The FCP channel reported that its bit error threshold has been exceeded. * These errors might result from a problem with the physical components * of the local fibre link into the FCP channel. * The problem might be damage or malfunction of the cable or * cable connection between the FCP channel and * the adjacent fabric switch port or the point-to-point peer. * Find details about the errors in the HBA trace for the FCP device. * The zfcp device driver closed down the FCP device * to limit the performance impact from possible I/O command timeouts. * User action: * Check for problems on the local fibre link, ensure that fibre optics are * clean and functional, and all cables are properly plugged. * After the repair action, you can manually recover the FCP device by * writing "0" into its "failed" sysfs attribute. * If recovery through sysfs is not possible, set the CHPID of the device * offline and back online on the service element. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: #2.6.30+ Link: https://lore.kernel.org/r/20191001104949.42810-1-maier@linux.ibm.com Reviewed-by: Jens Remus Reviewed-by: Benjamin Block Signed-off-by: Steffen Maier Signed-off-by: Martin K. Petersen --- drivers/s390/scsi/zfcp_fsf.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 296bbc3c4606..cf63916814cc 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -27,6 +27,11 @@ struct kmem_cache *zfcp_fsf_qtcb_cache; +static bool ber_stop = true; +module_param(ber_stop, bool, 0600); +MODULE_PARM_DESC(ber_stop, + "Shuts down FCP devices for FCP channels that report a bit-error count in excess of its threshold (default on)"); + static void zfcp_fsf_request_timeout_handler(struct timer_list *t) { struct zfcp_fsf_req *fsf_req = from_timer(fsf_req, t, timer); @@ -236,10 +241,15 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) case FSF_STATUS_READ_SENSE_DATA_AVAIL: break; case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: - dev_warn(&adapter->ccw_device->dev, - "The error threshold for checksum statistics " - "has been exceeded\n"); zfcp_dbf_hba_bit_err("fssrh_3", req); + if (ber_stop) { + dev_warn(&adapter->ccw_device->dev, + "All paths over this FCP device are disused because of excessive bit errors\n"); + zfcp_erp_adapter_shutdown(adapter, 0, "fssrh_b"); + } else { + dev_warn(&adapter->ccw_device->dev, + "The error threshold for checksum statistics has been exceeded\n"); + } break; case FSF_STATUS_READ_LINK_DOWN: zfcp_fsf_status_read_link_down(req); -- GitLab From b23f330d5145b92f90cf16f1adc5444ad06764b4 Mon Sep 17 00:00:00 2001 From: Himanshu Madhani Date: Tue, 1 Oct 2019 08:33:38 -0700 Subject: [PATCH 067/993] scsi: MAINTAINERS: Update qla2xxx driver Update maintainer entry for qla2xxx driver now that email addresses have been changed to Marvell. Link: https://lore.kernel.org/r/20191001153338.28765-1-hmadhani@marvell.com Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 783569e3c4b4..91f33522393a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13184,7 +13184,7 @@ S: Maintained F: drivers/scsi/qla1280.[ch] QLOGIC QLA2XXX FC-SCSI DRIVER -M: qla2xxx-upstream@qlogic.com +M: hmadhani@marvell.com L: linux-scsi@vger.kernel.org S: Supported F: Documentation/scsi/LICENSE.qla2xxx -- GitLab From cd24ee2a9a091432deb8da461b9b1055107460d4 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 27 Nov 2018 21:50:56 +0100 Subject: [PATCH 068/993] MAINTAINERS: Add hp_sdc drivers to parisc arch Signed-off-by: Helge Deller --- MAINTAINERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 296de2b51c83..59dd4c8f070d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12310,12 +12310,15 @@ F: arch/parisc/ F: Documentation/parisc/ F: drivers/parisc/ F: drivers/char/agp/parisc-agp.c +F: drivers/input/misc/hp_sdc_rtc.c F: drivers/input/serio/gscps2.c +F: drivers/input/serio/hp_sdc* F: drivers/parport/parport_gsc.* F: drivers/tty/serial/8250/8250_gsc.c F: drivers/video/fbdev/sti* F: drivers/video/console/sti* F: drivers/video/logo/logo_parisc* +F: include/linux/hp_sdc.h PARMAN M: Jiri Pirko -- GitLab From 313c3fe9c2348e7147eca38bb446f295b45403a0 Mon Sep 17 00:00:00 2001 From: Michael Vassernis Date: Thu, 3 Oct 2019 07:31:38 +0000 Subject: [PATCH 069/993] mac80211_hwsim: fix incorrect dev_alloc_name failure goto If dev_alloc_name fails, hwsim_mon's memory allocated in alloc_netdev needs to be freed. Change goto command in dev_alloc_name failure to out_free_mon in order to perform free_netdev. Signed-off-by: Michael Vassernis Link: https://lore.kernel.org/r/20191003073049.3760-1-michael.vassernis@tandemg.com Signed-off-by: Johannes Berg --- drivers/net/wireless/mac80211_hwsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 45c73a6f09a1..14f562cd715c 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -4026,7 +4026,7 @@ static int __init init_mac80211_hwsim(void) err = dev_alloc_name(hwsim_mon, hwsim_mon->name); if (err < 0) { rtnl_unlock(); - goto out_free_radios; + goto out_free_mon; } err = register_netdevice(hwsim_mon); -- GitLab From 4152561f5da3fca92af7179dd538ea89e248f9d0 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 4 Oct 2019 10:51:31 +0100 Subject: [PATCH 070/993] mac80211: Reject malformed SSID elements Although this shouldn't occur in practice, it's a good idea to bounds check the length field of the SSID element prior to using it for things like allocations or memcpy operations. Cc: Cc: Kees Cook Reported-by: Nicolas Waisman Signed-off-by: Will Deacon Link: https://lore.kernel.org/r/20191004095132.15777-1-will@kernel.org Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 26a2f49208b6..54dd8849d1cc 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2633,7 +2633,8 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, rcu_read_lock(); ssid = ieee80211_bss_get_ie(cbss, WLAN_EID_SSID); - if (WARN_ON_ONCE(ssid == NULL)) + if (WARN_ONCE(!ssid || ssid[1] > IEEE80211_MAX_SSID_LEN, + "invalid SSID element (len=%d)", ssid ? ssid[1] : -1)) ssid_len = 0; else ssid_len = ssid[1]; @@ -5233,7 +5234,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, rcu_read_lock(); ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); - if (!ssidie) { + if (!ssidie || ssidie[1] > sizeof(assoc_data->ssid)) { rcu_read_unlock(); kfree(assoc_data); return -EINVAL; -- GitLab From 4ac2813cc867ae563a1ba5a9414bfb554e5796fa Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 4 Oct 2019 10:51:32 +0100 Subject: [PATCH 071/993] cfg80211: wext: avoid copying malformed SSIDs Ensure the SSID element is bounds-checked prior to invoking memcpy() with its length field, when copying to userspace. Cc: Cc: Kees Cook Reported-by: Nicolas Waisman Signed-off-by: Will Deacon Link: https://lore.kernel.org/r/20191004095132.15777-2-will@kernel.org [adjust commit log a bit] Signed-off-by: Johannes Berg --- net/wireless/wext-sme.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index c67d7a82ab13..73fd0eae08ca 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -202,6 +202,7 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, struct iw_point *data, char *ssid) { struct wireless_dev *wdev = dev->ieee80211_ptr; + int ret = 0; /* call only for station! */ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) @@ -219,7 +220,10 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, if (ie) { data->flags = 1; data->length = ie[1]; - memcpy(ssid, ie + 2, data->length); + if (data->length > IW_ESSID_MAX_SIZE) + ret = -EINVAL; + else + memcpy(ssid, ie + 2, data->length); } rcu_read_unlock(); } else if (wdev->wext.connect.ssid && wdev->wext.connect.ssid_len) { @@ -229,7 +233,7 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, } wdev_unlock(wdev); - return 0; + return ret; } int cfg80211_mgd_wext_siwap(struct net_device *dev, -- GitLab From 6b512b0ee091edcb8e46218894e4c917d919d3dc Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Fri, 16 Aug 2019 17:58:12 -0500 Subject: [PATCH 072/993] ARM: dts: logicpd-torpedo-som: Remove twl_keypad The TWL4030 used on the Logit PD Torpedo SOM does not have the keypad pins routed. This patch disables the twl_keypad driver to remove some splat during boot: twl4030_keypad 48070000.i2c:twl@48:keypad: missing or malformed property linux,keymap: -22 twl4030_keypad 48070000.i2c:twl@48:keypad: Failed to build keymap twl4030_keypad: probe of 48070000.i2c:twl@48:keypad failed with error -22 Signed-off-by: Adam Ford [tony@atomide.com: removed error time stamps] Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/logicpd-torpedo-som.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi index 3fdd0a72f87f..506b118e511a 100644 --- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi +++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi @@ -192,3 +192,7 @@ &twl_gpio { ti,use-leds; }; + +&twl_keypad { + status = "disabled"; +}; -- GitLab From 77fd66c9ff3e992718a79fa6407148935d34b50f Mon Sep 17 00:00:00 2001 From: Kiran Gunda Date: Fri, 4 Oct 2019 15:46:55 +0530 Subject: [PATCH 073/993] regulator: qcom-rpmh: Fix PMIC5 BoB min voltage Correct the PMIC5 BoB min voltage from 0.3V to 3V. Also correct the voltage selector accordingly. Signed-off-by: Kiran Gunda Link: https://lore.kernel.org/r/1570184215-5355-1-git-send-email-kgunda@codeaurora.org Signed-off-by: Mark Brown --- drivers/regulator/qcom-rpmh-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c index db6c085da65e..0246b6f99fb5 100644 --- a/drivers/regulator/qcom-rpmh-regulator.c +++ b/drivers/regulator/qcom-rpmh-regulator.c @@ -735,8 +735,8 @@ static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = { static const struct rpmh_vreg_hw_data pmic5_bob = { .regulator_type = VRM, .ops = &rpmh_regulator_vrm_bypass_ops, - .voltage_range = REGULATOR_LINEAR_RANGE(300000, 0, 135, 32000), - .n_voltages = 136, + .voltage_range = REGULATOR_LINEAR_RANGE(3000000, 0, 31, 32000), + .n_voltages = 32, .pmic_mode_map = pmic_mode_map_pmic5_bob, .of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode, }; -- GitLab From 0990c5e7573098117c69651821647c228483e31b Mon Sep 17 00:00:00 2001 From: Soeren Moch Date: Thu, 3 Oct 2019 23:50:34 +0200 Subject: [PATCH 074/993] arm64: dts: rockchip: fix RockPro64 vdd-log regulator settings The RockPro64 schematic [1] page 18 states a min voltage of 0.8V and a max voltage of 1.4V for the VDD_LOG pwm regulator. However, there is an additional note that the pwm parameter needs to be modified. From the schematics a voltage range of 0.8V to 1.7V can be calculated. Additional voltage measurements on the board show that this fix indeed leads to the correct voltage, while without this fix the voltage was set too high. [1] http://files.pine64.org/doc/rockpro64/rockpro64_v21-SCH.pdf Fixes: e4f3fb490967 ("arm64: dts: rockchip: add initial dts support for Rockpro64") Signed-off-by: Soeren Moch Link: https://lore.kernel.org/r/20191003215036.15023-1-smoch@web.de Signed-off-by: Heiko Stuebner --- arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts index c27d8a6ae1c5..98a5f323bc1d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts @@ -173,7 +173,7 @@ regulator-always-on; regulator-boot-on; regulator-min-microvolt = <800000>; - regulator-max-microvolt = <1400000>; + regulator-max-microvolt = <1700000>; vin-supply = <&vcc5v0_sys>; }; }; -- GitLab From 2558b3b1b11a1b32b336be2dd0aabfa6d35ddcb5 Mon Sep 17 00:00:00 2001 From: Soeren Moch Date: Thu, 3 Oct 2019 23:50:35 +0200 Subject: [PATCH 075/993] arm64: dts: rockchip: fix RockPro64 sdhci settings The RockPro64 schematics [1], [2] show that the rk3399 EMMC_STRB pin is connected to the RESET pin instead of the DATA_STROBE pin of the eMMC module. So the data strobe cannot be used for its intended purpose on this board, and so the HS400 eMMC mode is not functional. Limit the controller to HS200. [1] http://files.pine64.org/doc/rockpro64/rockpro64_v21-SCH.pdf [2] http://files.pine64.org/doc/rock64/PINE64_eMMC_Module_20170719.pdf Fixes: e4f3fb490967 ("arm64: dts: rockchip: add initial dts support for Rockpro64") Signed-off-by: Soeren Moch Link: https://lore.kernel.org/r/20191003215036.15023-2-smoch@web.de Signed-off-by: Heiko Stuebner --- arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts index 98a5f323bc1d..aa06a6587a11 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts @@ -636,8 +636,7 @@ &sdhci { bus-width = <8>; - mmc-hs400-1_8v; - mmc-hs400-enhanced-strobe; + mmc-hs200-1_8v; non-removable; status = "okay"; }; -- GitLab From 20504fa1d2ffd5d03cdd9dc9c9dd4ed4579b97ef Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Tue, 1 Oct 2019 10:46:31 -0500 Subject: [PATCH 076/993] pinctrl: armada-37xx: fix control of pins 32 and up The 37xx configuration registers are only 32 bits long, so pins 32-35 spill over into the next register. The calculation for the register address was done, but the bitmask was not, so any configuration to pin 32 or above resulted in a bitmask that overflowed and performed no action. Fix the register / offset calculation to also adjust the offset. Fixes: 5715092a458c ("pinctrl: armada-37xx: Add gpio support") Signed-off-by: Patrick Williams Acked-by: Gregory CLEMENT Cc: Link: https://lore.kernel.org/r/20191001154634.96165-1-alpawi@amazon.com Signed-off-by: Linus Walleij --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 6462d3ca7ceb..34c1fee52cbe 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -221,11 +221,11 @@ static const struct armada_37xx_pin_data armada_37xx_pin_sb = { }; static inline void armada_37xx_update_reg(unsigned int *reg, - unsigned int offset) + unsigned int *offset) { /* We never have more than 2 registers */ - if (offset >= GPIO_PER_REG) { - offset -= GPIO_PER_REG; + if (*offset >= GPIO_PER_REG) { + *offset -= GPIO_PER_REG; *reg += sizeof(u32); } } @@ -376,7 +376,7 @@ static inline void armada_37xx_irq_update_reg(unsigned int *reg, { int offset = irqd_to_hwirq(d); - armada_37xx_update_reg(reg, offset); + armada_37xx_update_reg(reg, &offset); } static int armada_37xx_gpio_direction_input(struct gpio_chip *chip, @@ -386,7 +386,7 @@ static int armada_37xx_gpio_direction_input(struct gpio_chip *chip, unsigned int reg = OUTPUT_EN; unsigned int mask; - armada_37xx_update_reg(®, offset); + armada_37xx_update_reg(®, &offset); mask = BIT(offset); return regmap_update_bits(info->regmap, reg, mask, 0); @@ -399,7 +399,7 @@ static int armada_37xx_gpio_get_direction(struct gpio_chip *chip, unsigned int reg = OUTPUT_EN; unsigned int val, mask; - armada_37xx_update_reg(®, offset); + armada_37xx_update_reg(®, &offset); mask = BIT(offset); regmap_read(info->regmap, reg, &val); @@ -413,7 +413,7 @@ static int armada_37xx_gpio_direction_output(struct gpio_chip *chip, unsigned int reg = OUTPUT_EN; unsigned int mask, val, ret; - armada_37xx_update_reg(®, offset); + armada_37xx_update_reg(®, &offset); mask = BIT(offset); ret = regmap_update_bits(info->regmap, reg, mask, mask); @@ -434,7 +434,7 @@ static int armada_37xx_gpio_get(struct gpio_chip *chip, unsigned int offset) unsigned int reg = INPUT_VAL; unsigned int val, mask; - armada_37xx_update_reg(®, offset); + armada_37xx_update_reg(®, &offset); mask = BIT(offset); regmap_read(info->regmap, reg, &val); @@ -449,7 +449,7 @@ static void armada_37xx_gpio_set(struct gpio_chip *chip, unsigned int offset, unsigned int reg = OUTPUT_VAL; unsigned int mask, val; - armada_37xx_update_reg(®, offset); + armada_37xx_update_reg(®, &offset); mask = BIT(offset); val = value ? mask : 0; -- GitLab From f876dbff857b41b0f5c6139fb1db2361cb708279 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 2 Oct 2019 15:02:17 +0200 Subject: [PATCH 077/993] pinctrl: bcm-iproc: Use SPDX header This convert the BCM IPROC driver to use the SPDX header for indicating GPL v2.0 only licensing. Cc: Pramod Kumar Cc: Ray Jui Cc: Scott Branden Signed-off-by: Linus Walleij Acked-by: Scott Branden Link: https://lore.kernel.org/r/20191002130217.4491-1-linus.walleij@linaro.org --- drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c index 6f7d3a2f2e97..61352cc6c0d3 100644 --- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c +++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2014-2017 Broadcom - * - * 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. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* -- GitLab From 39b65fbb813089e366b376bd8acc300b6fd646dc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 26 Sep 2019 11:14:26 +0300 Subject: [PATCH 078/993] pinctrl: ns2: Fix off by one bugs in ns2_pinmux_enable() The pinctrl->functions[] array has pinctrl->num_functions elements and the pinctrl->groups[] array is the same way. These are set in ns2_pinmux_probe(). So the > comparisons should be >= so that we don't read one element beyond the end of the array. Fixes: b5aa1006e4a9 ("pinctrl: ns2: add pinmux driver support for Broadcom NS2 SoC") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/20190926081426.GB2332@mwanda Acked-by: Scott Branden Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-ns2-mux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/bcm/pinctrl-ns2-mux.c b/drivers/pinctrl/bcm/pinctrl-ns2-mux.c index 2bf6af7df7d9..9fabc451550e 100644 --- a/drivers/pinctrl/bcm/pinctrl-ns2-mux.c +++ b/drivers/pinctrl/bcm/pinctrl-ns2-mux.c @@ -640,8 +640,8 @@ static int ns2_pinmux_enable(struct pinctrl_dev *pctrl_dev, const struct ns2_pin_function *func; const struct ns2_pin_group *grp; - if (grp_select > pinctrl->num_groups || - func_select > pinctrl->num_functions) + if (grp_select >= pinctrl->num_groups || + func_select >= pinctrl->num_functions) return -EINVAL; func = &pinctrl->functions[func_select]; -- GitLab From 6abff1b9f7b8884a46b7bd80b49e7af0b5625aeb Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Wed, 2 Oct 2019 10:52:25 -0700 Subject: [PATCH 079/993] nvme: fix possible deadlock when nvme_update_formats fails nvme_update_formats may fail to revalidate the namespace and attempt to remove the namespace. This may lead to a deadlock as nvme_ns_remove will attempt to acquire the subsystem lock which is already acquired by the passthru command with effects. Move the invalid namepsace removal to after the passthru command releases the subsystem lock. Reported-by: Judy Brock Signed-off-by: Sagi Grimberg --- drivers/nvme/host/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index fd7dea36c3b6..ef1d8f81f69e 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1306,8 +1306,6 @@ static void nvme_update_formats(struct nvme_ctrl *ctrl) if (ns->disk && nvme_revalidate_disk(ns->disk)) nvme_set_queue_dying(ns); up_read(&ctrl->namespaces_rwsem); - - nvme_remove_invalid_namespaces(ctrl, NVME_NSID_ALL); } static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects) @@ -1323,6 +1321,7 @@ static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects) nvme_unfreeze(ctrl); nvme_mpath_unfreeze(ctrl->subsys); mutex_unlock(&ctrl->subsys->lock); + nvme_remove_invalid_namespaces(ctrl, NVME_NSID_ALL); mutex_unlock(&ctrl->scan_lock); } if (effects & NVME_CMD_EFFECTS_CCC) -- GitLab From 3a8ecc935efabdad106b5e06d07b150c394b4465 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 3 Oct 2019 13:57:29 +0200 Subject: [PATCH 080/993] nvme: retain split access workaround for capability reads Commit 7fd8930f26be4 "nvme: add a common helper to read Identify Controller data" has re-introduced an issue that we have attempted to work around in the past, in commit a310acd7a7ea ("NVMe: use split lo_hi_{read,write}q"). The problem is that some PCIe NVMe controllers do not implement 64-bit outbound accesses correctly, which is why the commit above switched to using lo_hi_[read|write]q for all 64-bit BAR accesses occuring in the code. In the mean time, the NVMe subsystem has been refactored, and now calls into the PCIe support layer for NVMe via a .reg_read64() method, which fails to use lo_hi_readq(), and thus reintroduces the problem that the workaround above aimed to address. Given that, at the moment, .reg_read64() is only used to read the capability register [which is known to tolerate split reads], let's switch .reg_read64() to lo_hi_readq() as well. This fixes a boot issue on some ARM boxes with NVMe behind a Synopsys DesignWare PCIe host controller. Fixes: 7fd8930f26be4 ("nvme: add a common helper to read Identify Controller data") Signed-off-by: Ard Biesheuvel Signed-off-by: Sagi Grimberg --- drivers/nvme/host/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index bb88681f4dc3..78e403823646 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -2672,7 +2672,7 @@ static int nvme_pci_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val) static int nvme_pci_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val) { - *val = readq(to_nvme_dev(ctrl)->bar + off); + *val = lo_hi_readq(to_nvme_dev(ctrl)->bar + off); return 0; } -- GitLab From 48659227e0a1d7897a4942c7b2cf925b581b6bf7 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Thu, 3 Oct 2019 13:03:09 +1300 Subject: [PATCH 081/993] pinctrl: iproc: allow for error from platform_get_irq() platform_get_irq() can return an error code. Allow for this when getting the irq. Fixes: 6f265e5d4da7 ("pinctrl: bcm-iproc: Pass irqchip when adding gpiochip") Signed-off-by: Chris Packham Link: https://lore.kernel.org/r/20191003000310.17099-2-chris.packham@alliedtelesis.co.nz Acked-by: Scott Branden Signed-off-by: Linus Walleij --- drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c index 61352cc6c0d3..42f7ab383ad9 100644 --- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c +++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c @@ -845,7 +845,7 @@ static int iproc_gpio_probe(struct platform_device *pdev) /* optional GPIO interrupt support */ irq = platform_get_irq(pdev, 0); - if (irq) { + if (irq > 0) { struct irq_chip *irqc; struct gpio_irq_chip *girq; -- GitLab From 2fd215b8fdbe4d3a609adbe3a323696393cb1e53 Mon Sep 17 00:00:00 2001 From: Amelie Delaunay Date: Fri, 4 Oct 2019 14:23:42 +0200 Subject: [PATCH 082/993] pinctrl: stmfx: fix null pointer on remove dev_get_platdata(&pdev->dev) returns a pointer on struct stmfx_pinctrl, not on struct stmfx (platform_set_drvdata(pdev, pctl); in probe). Pointer on struct stmfx is stored in driver data of pdev parent (in probe: struct stmfx *stmfx = dev_get_drvdata(pdev->dev.parent);). Fixes: 1490d9f841b1 ("pinctrl: Add STMFX GPIO expander Pinctrl/GPIO driver") Signed-off-by: Amelie Delaunay Link: https://lore.kernel.org/r/20191004122342.22018-1-amelie.delaunay@st.com Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-stmfx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index 974973777395..564660028fcc 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -705,7 +705,7 @@ static int stmfx_pinctrl_probe(struct platform_device *pdev) static int stmfx_pinctrl_remove(struct platform_device *pdev) { - struct stmfx *stmfx = dev_get_platdata(&pdev->dev); + struct stmfx *stmfx = dev_get_drvdata(pdev->dev.parent); return stmfx_function_disable(stmfx, STMFX_FUNC_GPIO | -- GitLab From 30ca9b04747ea865cbb5a7d05e10ef0a3761bf19 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 4 Sep 2019 15:13:14 -0400 Subject: [PATCH 083/993] soc: imx: imx-scu: Getting UID from SCU should have response The SCU firmware API for getting UID should have response, otherwise, the message stored in function stack could be released and then the response data received from SCU will be stored into that released stack and cause kernel NULL pointer dump. Fixes: 73feb4d0f8f1 ("soc: imx-scu: Add SoC UID(unique identifier) support") Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- drivers/soc/imx/soc-imx-scu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/imx/soc-imx-scu.c b/drivers/soc/imx/soc-imx-scu.c index 50831ebf126a..c68882eb80f7 100644 --- a/drivers/soc/imx/soc-imx-scu.c +++ b/drivers/soc/imx/soc-imx-scu.c @@ -46,7 +46,7 @@ static ssize_t soc_uid_show(struct device *dev, hdr->func = IMX_SC_MISC_FUNC_UNIQUE_ID; hdr->size = 1; - ret = imx_scu_call_rpc(soc_ipc_handle, &msg, false); + ret = imx_scu_call_rpc(soc_ipc_handle, &msg, true); if (ret) { pr_err("%s: get soc uid failed, ret %d\n", __func__, ret); return ret; -- GitLab From 21094ba5c1f4b15df096e8f6247a50b6ab57c869 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 6 Sep 2019 19:06:01 +0200 Subject: [PATCH 084/993] arm64: dts: zii-ultra: fix ARM regulator states The GPIO controlled regulator for the ARM power supply is supplying the higher voltage when the GPIO is driven high. This is opposite to the similar regulator setup on the EVK board and is impacting stability of the board as the ARM domain has been supplied with a too low voltage when to faster OPPs are in use. Fixes: 4a13b3bec3b4 (arm64: dts: imx: add Zii Ultra board support) Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi index af99473ada04..087b5b6ebe89 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi @@ -89,8 +89,8 @@ regulator-min-microvolt = <900000>; regulator-max-microvolt = <1000000>; gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; - states = <1000000 0x0 - 900000 0x1>; + states = <1000000 0x1 + 900000 0x0>; regulator-always-on; }; }; -- GitLab From c763ac436b668d7417f0979430ec0312ede4093d Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sat, 5 Oct 2019 15:05:18 -0700 Subject: [PATCH 085/993] net: dsa: b53: Do not clear existing mirrored port mask Clearing the existing bitmask of mirrored ports essentially prevents us from capturing more than one port at any given time. This is clearly wrong, do not clear the bitmask prior to setting up the new port. Reported-by: Hubert Feurstein Fixes: ed3af5fd08eb ("net: dsa: b53: Add support for port mirroring") Signed-off-by: Florian Fainelli Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/b53/b53_common.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 526ba2ab66f1..cc3536315eff 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -1845,7 +1845,6 @@ int b53_mirror_add(struct dsa_switch *ds, int port, loc = B53_EG_MIR_CTL; b53_read16(dev, B53_MGMT_PAGE, loc, ®); - reg &= ~MIRROR_MASK; reg |= BIT(port); b53_write16(dev, B53_MGMT_PAGE, loc, reg); -- GitLab From b870b0f867c77b92d7fd17ace8421904270d3c6a Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Sun, 6 Oct 2019 13:08:55 +0200 Subject: [PATCH 086/993] net: stmmac: selftests: Check if filtering is available before running We need to check if the number of available Hash Filters is enough to run the test, otherwise we will get false failures. Fixes: 091810dbded9 ("net: stmmac: Introduce selftests support") Signed-off-by: Jose Abreu Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c index cc76a42c7466..ed3926d4471d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c @@ -496,6 +496,9 @@ static int stmmac_test_hfilt(struct stmmac_priv *priv) if (ret) return ret; + if (netdev_mc_count(priv->dev) >= priv->hw->multicast_filter_bins) + return -EOPNOTSUPP; + ret = dev_mc_add(priv->dev, gd_addr); if (ret) return ret; @@ -573,6 +576,8 @@ static int stmmac_test_mcfilt(struct stmmac_priv *priv) if (stmmac_filter_check(priv)) return -EOPNOTSUPP; + if (!priv->hw->multicast_filter_bins) + return -EOPNOTSUPP; /* Remove all MC addresses */ __dev_mc_unsync(priv->dev, NULL); @@ -611,6 +616,8 @@ static int stmmac_test_ucfilt(struct stmmac_priv *priv) if (stmmac_filter_check(priv)) return -EOPNOTSUPP; + if (!priv->hw->multicast_filter_bins) + return -EOPNOTSUPP; /* Remove all UC addresses */ __dev_uc_unsync(priv->dev, NULL); -- GitLab From 25683bab09a70542b9f8e3e28f79b3369e56701f Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Sun, 6 Oct 2019 13:08:56 +0200 Subject: [PATCH 087/993] net: stmmac: gmac4+: Not all Unicast addresses may be available Some setups may not have all Unicast addresses filters available. Check the number of available filters before trying to setup it. Fixes: 477286b53f55 ("stmmac: add GMAC4 core support") Signed-off-by: Jose Abreu Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 2cb9c53f93b8..5a7b0aca1d31 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -448,7 +448,7 @@ static void dwmac4_set_filter(struct mac_device_info *hw, value |= GMAC_PACKET_FILTER_HPF; /* Handle multiple unicast addresses */ - if (netdev_uc_count(dev) > GMAC_MAX_PERFECT_ADDRESSES) { + if (netdev_uc_count(dev) > hw->unicast_filter_entries) { /* Switch to promiscuous mode if more than 128 addrs * are required */ -- GitLab From 2809fc13163f4946d7cde092807bea44bbae4478 Mon Sep 17 00:00:00 2001 From: Jose Abreu Date: Sun, 6 Oct 2019 13:08:57 +0200 Subject: [PATCH 088/993] net: stmmac: selftests: Fix L2 Hash Filter test With the current MAC addresses hard-coded in the test we can get some false positives as we use the Hash Filtering method. Let's change the MAC addresses in the tests to be unique when hashed. Fixes: 091810dbded9 ("net: stmmac: Introduce selftests support") Signed-off-by: Jose Abreu Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c index ed3926d4471d..e4ac3c401432 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c @@ -487,8 +487,8 @@ static int stmmac_filter_check(struct stmmac_priv *priv) static int stmmac_test_hfilt(struct stmmac_priv *priv) { - unsigned char gd_addr[ETH_ALEN] = {0x01, 0x00, 0xcc, 0xcc, 0xdd, 0xdd}; - unsigned char bd_addr[ETH_ALEN] = {0x09, 0x00, 0xaa, 0xaa, 0xbb, 0xbb}; + unsigned char gd_addr[ETH_ALEN] = {0x01, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}; + unsigned char bd_addr[ETH_ALEN] = {0x01, 0x01, 0x02, 0x03, 0x04, 0x05}; struct stmmac_packet_attrs attr = { }; int ret; -- GitLab From c90012ac85c24547e5c3468ef00aabf44aa7332d Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Sun, 6 Oct 2019 10:30:28 +1100 Subject: [PATCH 089/993] lib: test_user_copy: style cleanup While writing the tests for copy_struct_from_user(), I used a construct that Linus doesn't appear to be too fond of: On 2019-10-04, Linus Torvalds wrote: > Hmm. That code is ugly, both before and after the fix. > > This just doesn't make sense for so many reasons: > > if ((ret |= test(umem_src == NULL, "kmalloc failed"))) > > where the insanity comes from > > - why "|=" when you know that "ret" was zero before (and it had to > be, for the test to make sense) > > - why do this as a single line anyway? > > - don't do the stupid "double parenthesis" to hide a warning. Make it > use an actual comparison if you add a layer of parentheses. So instead, use a bog-standard check that isn't nearly as ugly. Fixes: 341115822f88 ("usercopy: Add parentheses around assignment in test_copy_struct_from_user") Fixes: f5a1a536fa14 ("lib: introduce copy_struct_from_user() helper") Signed-off-by: Aleksa Sarai Reviewed-by: Nathan Chancellor Reviewed-by: Christian Brauner Link: https://lore.kernel.org/r/20191005233028.18566-1-cyphar@cyphar.com Signed-off-by: Christian Brauner --- lib/test_user_copy.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/test_user_copy.c b/lib/test_user_copy.c index e365ace06538..ad2372727b1b 100644 --- a/lib/test_user_copy.c +++ b/lib/test_user_copy.c @@ -52,13 +52,14 @@ static int test_check_nonzero_user(char *kmem, char __user *umem, size_t size) size_t zero_end = size - zero_start; /* - * We conduct a series of check_nonzero_user() tests on a block of memory - * with the following byte-pattern (trying every possible [start,end] - * pair): + * We conduct a series of check_nonzero_user() tests on a block of + * memory with the following byte-pattern (trying every possible + * [start,end] pair): * * [ 00 ff 00 ff ... 00 00 00 00 ... ff 00 ff 00 ] * - * And we verify that check_nonzero_user() acts identically to memchr_inv(). + * And we verify that check_nonzero_user() acts identically to + * memchr_inv(). */ memset(kmem, 0x0, size); @@ -93,11 +94,13 @@ static int test_copy_struct_from_user(char *kmem, char __user *umem, size_t ksize, usize; umem_src = kmalloc(size, GFP_KERNEL); - if ((ret |= test(umem_src == NULL, "kmalloc failed"))) + ret = test(umem_src == NULL, "kmalloc failed"); + if (ret) goto out_free; expected = kmalloc(size, GFP_KERNEL); - if ((ret |= test(expected == NULL, "kmalloc failed"))) + ret = test(expected == NULL, "kmalloc failed"); + if (ret) goto out_free; /* Fill umem with a fixed byte pattern. */ -- GitLab From 1099f48457d06b816359fb43ac32a4a07e33219b Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Thu, 3 Oct 2019 12:39:19 +0800 Subject: [PATCH 090/993] ALSA: hda/realtek: Reduce the Headphone static noise on XPS 9350/9360 Headphone on XPS 9350/9360 produces a background white noise. The The noise level somehow correlates with "Headphone Mic Boost", when it sets to 1 the noise disappears. However, doing this has a side effect, which also decreases the overall headphone volume so I didn't send the patch upstream. The noise was bearable back then, but after commit 717f43d81afc ("ALSA: hda/realtek - Update headset mode for ALC256") the noise exacerbates to a point it starts hurting ears. So let's use the workaround to set "Headphone Mic Boost" to 1 and lock it so it's not touchable by userspace. Fixes: 717f43d81afc ("ALSA: hda/realtek - Update headset mode for ALC256") BugLink: https://bugs.launchpad.net/bugs/1654448 BugLink: https://bugs.launchpad.net/bugs/1845810 Signed-off-by: Kai-Heng Feng Link: https://lore.kernel.org/r/20191003043919.10960-1-kai.heng.feng@canonical.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b000b36ac3c6..b5c225a56b98 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5358,6 +5358,17 @@ static void alc271_hp_gate_mic_jack(struct hda_codec *codec, } } +static void alc256_fixup_dell_xps_13_headphone_noise2(struct hda_codec *codec, + const struct hda_fixup *fix, + int action) +{ + if (action != HDA_FIXUP_ACT_PRE_PROBE) + return; + + snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 0, HDA_AMP_VOLMASK, 1); + snd_hda_override_wcaps(codec, 0x1a, get_wcaps(codec, 0x1a) & ~AC_WCAP_IN_AMP); +} + static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec, const struct hda_fixup *fix, int action) @@ -5822,6 +5833,7 @@ enum { ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, ALC275_FIXUP_DELL_XPS, ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, + ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2, ALC293_FIXUP_LENOVO_SPK_NOISE, ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, ALC255_FIXUP_DELL_SPK_NOISE, @@ -6558,6 +6570,12 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE }, + [ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc256_fixup_dell_xps_13_headphone_noise2, + .chained = true, + .chain_id = ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE + }, [ALC293_FIXUP_LENOVO_SPK_NOISE] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_disable_aamix, @@ -7001,17 +7019,17 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), - SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), + SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2), SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER), SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE), SND_PCI_QUIRK(0x1028, 0x0738, "Dell Precision 5820", ALC269_FIXUP_NO_SHUTUP), - SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), + SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2), SND_PCI_QUIRK(0x1028, 0x075c, "Dell XPS 27 7760", ALC298_FIXUP_SPK_VOLUME), SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME), SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3), SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER), SND_PCI_QUIRK(0x1028, 0x080c, "Dell WYSE", ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), + SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE2), SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC), -- GitLab From 130bce3afbbbbe585cba8604f2124c28e8d86fb0 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Mon, 30 Sep 2019 09:29:45 -0500 Subject: [PATCH 091/993] ALSA: hdac: clear link output stream mapping Fix potential DMA hang upon starting playback on devices in HDA mode on Intel platforms (Gemini Lake/Whiskey Lake/Comet Lake/Ice Lake). It doesn't affect platforms before Gemini Lake or any Intel device in non-HDA mode. The reset value for the LOSDIV register is all output streams valid. Clear this register to invalidate non-existent streams when the bus is powered up. Signed-off-by: Rander Wang Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20190930142945.7805-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Takashi Iwai --- include/sound/hda_register.h | 3 +++ sound/hda/ext/hdac_ext_controller.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h index 0fd39295b426..057d2a2d0bd0 100644 --- a/include/sound/hda_register.h +++ b/include/sound/hda_register.h @@ -264,6 +264,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define AZX_REG_ML_LOUTPAY 0x20 #define AZX_REG_ML_LINPAY 0x30 +/* bit0 is reserved, with BIT(1) mapping to stream1 */ +#define ML_LOSIDV_STREAM_MASK 0xFFFE + #define ML_LCTL_SCF_MASK 0xF #define AZX_MLCTL_SPA (0x1 << 16) #define AZX_MLCTL_CPA (0x1 << 23) diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c index 211ca85acd8c..cfab60d88c92 100644 --- a/sound/hda/ext/hdac_ext_controller.c +++ b/sound/hda/ext/hdac_ext_controller.c @@ -270,6 +270,11 @@ int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, ret = snd_hdac_ext_bus_link_power_up(link); + /* + * clear the register to invalidate all the output streams + */ + snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, + ML_LOSIDV_STREAM_MASK, 0); /* * wait for 521usec for codec to report status * HDA spec section 4.3 - Codec Discovery -- GitLab From c48fc11b69e95007109206311b0187a3090591f3 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 7 Oct 2019 10:58:28 +0100 Subject: [PATCH 092/993] rxrpc: Fix call ref leak When sendmsg() finds a call to continue on with, if the call is in an inappropriate state, it doesn't release the ref it just got on that call before returning an error. This causes the following symptom to show up with kasan: BUG: KASAN: use-after-free in rxrpc_send_keepalive+0x8a2/0x940 net/rxrpc/output.c:635 Read of size 8 at addr ffff888064219698 by task kworker/0:3/11077 where line 635 is: whdr.epoch = htonl(peer->local->rxnet->epoch); The local endpoint (which cannot be pinned by the call) has been released, but not the peer (which is pinned by the call). Fix this by releasing the call in the error path. Fixes: 37411cad633f ("rxrpc: Fix potential NULL-pointer exception") Reported-by: syzbot+d850c266e3df14da1d31@syzkaller.appspotmail.com Signed-off-by: David Howells --- net/rxrpc/sendmsg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index 6a1547b270fe..22f51a7e356e 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c @@ -661,6 +661,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len) case RXRPC_CALL_SERVER_PREALLOC: case RXRPC_CALL_SERVER_SECURING: case RXRPC_CALL_SERVER_ACCEPTING: + rxrpc_put_call(call, rxrpc_call_put); ret = -EBUSY; goto error_release_sock; default: -- GitLab From e1056f9bbf0d79e9120dc4cbdc96ce7fee6cd15f Mon Sep 17 00:00:00 2001 From: Pragnesh Patel Date: Wed, 18 Sep 2019 17:31:00 +0530 Subject: [PATCH 093/993] media: dt-bindings: Fix building error for dt_binding_check $id doesn't match the actual filename, so update the $id Fixes: c5e8f4ccd7750 ("media: dt-bindings: media: Add Allwinner A10 CSI binding") Signed-off-by: Pragnesh Patel Signed-off-by: Maxime Ripard --- .../devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml index 27f38eed389e..5dd1cf490cd9 100644 --- a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml +++ b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2 --- -$id: http://devicetree.org/schemas/arm/allwinner,sun4i-a10-csi.yaml# +$id: http://devicetree.org/schemas/media/allwinner,sun4i-a10-csi.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: Allwinner A10 CMOS Sensor Interface (CSI) Device Tree Bindings -- GitLab From 55f6c98e3674ce16038a1949c3f9ca5a9a99f289 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 7 Oct 2019 10:58:29 +0100 Subject: [PATCH 094/993] rxrpc: Fix trace-after-put looking at the put peer record rxrpc_put_peer() calls trace_rxrpc_peer() after it has done the decrement of the refcount - which looks at the debug_id in the peer record. But unless the refcount was reduced to zero, we no longer have the right to look in the record and, indeed, it may be deleted by some other thread. Fix this by getting the debug_id out before decrementing the refcount and then passing that into the tracepoint. This can cause the following symptoms: BUG: KASAN: use-after-free in __rxrpc_put_peer net/rxrpc/peer_object.c:411 [inline] BUG: KASAN: use-after-free in rxrpc_put_peer+0x685/0x6a0 net/rxrpc/peer_object.c:435 Read of size 8 at addr ffff888097ec0058 by task syz-executor823/24216 Fixes: 1159d4b496f5 ("rxrpc: Add a tracepoint to track rxrpc_peer refcounting") Reported-by: syzbot+b9be979c55f2bea8ed30@syzkaller.appspotmail.com Signed-off-by: David Howells --- include/trace/events/rxrpc.h | 6 +++--- net/rxrpc/peer_object.c | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index edc5c887a44c..45556fe771c3 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -519,10 +519,10 @@ TRACE_EVENT(rxrpc_local, ); TRACE_EVENT(rxrpc_peer, - TP_PROTO(struct rxrpc_peer *peer, enum rxrpc_peer_trace op, + TP_PROTO(unsigned int peer_debug_id, enum rxrpc_peer_trace op, int usage, const void *where), - TP_ARGS(peer, op, usage, where), + TP_ARGS(peer_debug_id, op, usage, where), TP_STRUCT__entry( __field(unsigned int, peer ) @@ -532,7 +532,7 @@ TRACE_EVENT(rxrpc_peer, ), TP_fast_assign( - __entry->peer = peer->debug_id; + __entry->peer = peer_debug_id; __entry->op = op; __entry->usage = usage; __entry->where = where; diff --git a/net/rxrpc/peer_object.c b/net/rxrpc/peer_object.c index 9c3ac96f71cb..b700b7ecaa3d 100644 --- a/net/rxrpc/peer_object.c +++ b/net/rxrpc/peer_object.c @@ -382,7 +382,7 @@ struct rxrpc_peer *rxrpc_get_peer(struct rxrpc_peer *peer) int n; n = atomic_inc_return(&peer->usage); - trace_rxrpc_peer(peer, rxrpc_peer_got, n, here); + trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, n, here); return peer; } @@ -396,7 +396,7 @@ struct rxrpc_peer *rxrpc_get_peer_maybe(struct rxrpc_peer *peer) if (peer) { int n = atomic_fetch_add_unless(&peer->usage, 1, 0); if (n > 0) - trace_rxrpc_peer(peer, rxrpc_peer_got, n + 1, here); + trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, n + 1, here); else peer = NULL; } @@ -426,11 +426,13 @@ static void __rxrpc_put_peer(struct rxrpc_peer *peer) void rxrpc_put_peer(struct rxrpc_peer *peer) { const void *here = __builtin_return_address(0); + unsigned int debug_id; int n; if (peer) { + debug_id = peer->debug_id; n = atomic_dec_return(&peer->usage); - trace_rxrpc_peer(peer, rxrpc_peer_put, n, here); + trace_rxrpc_peer(debug_id, rxrpc_peer_put, n, here); if (n == 0) __rxrpc_put_peer(peer); } @@ -443,10 +445,11 @@ void rxrpc_put_peer(struct rxrpc_peer *peer) void rxrpc_put_peer_locked(struct rxrpc_peer *peer) { const void *here = __builtin_return_address(0); + unsigned int debug_id = peer->debug_id; int n; n = atomic_dec_return(&peer->usage); - trace_rxrpc_peer(peer, rxrpc_peer_put, n, here); + trace_rxrpc_peer(debug_id, rxrpc_peer_put, n, here); if (n == 0) { hash_del_rcu(&peer->hash_link); list_del_init(&peer->keepalive_link); -- GitLab From 4c1295dccc0afe0905b6ca4c62ade7f2406f2cfb Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 7 Oct 2019 10:58:29 +0100 Subject: [PATCH 095/993] rxrpc: Fix trace-after-put looking at the put connection record rxrpc_put_*conn() calls trace_rxrpc_conn() after they have done the decrement of the refcount - which looks at the debug_id in the connection record. But unless the refcount was reduced to zero, we no longer have the right to look in the record and, indeed, it may be deleted by some other thread. Fix this by getting the debug_id out before decrementing the refcount and then passing that into the tracepoint. Fixes: 363deeab6d0f ("rxrpc: Add connection tracepoint and client conn state tracepoint") Signed-off-by: David Howells --- include/trace/events/rxrpc.h | 6 +++--- net/rxrpc/call_accept.c | 2 +- net/rxrpc/conn_client.c | 6 ++++-- net/rxrpc/conn_object.c | 13 +++++++------ net/rxrpc/conn_service.c | 2 +- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 45556fe771c3..38a97e890cb6 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -546,10 +546,10 @@ TRACE_EVENT(rxrpc_peer, ); TRACE_EVENT(rxrpc_conn, - TP_PROTO(struct rxrpc_connection *conn, enum rxrpc_conn_trace op, + TP_PROTO(unsigned int conn_debug_id, enum rxrpc_conn_trace op, int usage, const void *where), - TP_ARGS(conn, op, usage, where), + TP_ARGS(conn_debug_id, op, usage, where), TP_STRUCT__entry( __field(unsigned int, conn ) @@ -559,7 +559,7 @@ TRACE_EVENT(rxrpc_conn, ), TP_fast_assign( - __entry->conn = conn->debug_id; + __entry->conn = conn_debug_id; __entry->op = op; __entry->usage = usage; __entry->where = where; diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c index 00c095d74145..c1b1b7dd2924 100644 --- a/net/rxrpc/call_accept.c +++ b/net/rxrpc/call_accept.c @@ -84,7 +84,7 @@ static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx, smp_store_release(&b->conn_backlog_head, (head + 1) & (size - 1)); - trace_rxrpc_conn(conn, rxrpc_conn_new_service, + trace_rxrpc_conn(conn->debug_id, rxrpc_conn_new_service, atomic_read(&conn->usage), here); } diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c index 3f1da1b49f69..700eb77173fc 100644 --- a/net/rxrpc/conn_client.c +++ b/net/rxrpc/conn_client.c @@ -212,7 +212,8 @@ rxrpc_alloc_client_connection(struct rxrpc_conn_parameters *cp, gfp_t gfp) rxrpc_get_local(conn->params.local); key_get(conn->params.key); - trace_rxrpc_conn(conn, rxrpc_conn_new_client, atomic_read(&conn->usage), + trace_rxrpc_conn(conn->debug_id, rxrpc_conn_new_client, + atomic_read(&conn->usage), __builtin_return_address(0)); trace_rxrpc_client(conn, -1, rxrpc_client_alloc); _leave(" = %p", conn); @@ -985,11 +986,12 @@ rxrpc_put_one_client_conn(struct rxrpc_connection *conn) void rxrpc_put_client_conn(struct rxrpc_connection *conn) { const void *here = __builtin_return_address(0); + unsigned int debug_id = conn->debug_id; int n; do { n = atomic_dec_return(&conn->usage); - trace_rxrpc_conn(conn, rxrpc_conn_put_client, n, here); + trace_rxrpc_conn(debug_id, rxrpc_conn_put_client, n, here); if (n > 0) return; ASSERTCMP(n, >=, 0); diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c index ed05b6922132..38d718e90dc6 100644 --- a/net/rxrpc/conn_object.c +++ b/net/rxrpc/conn_object.c @@ -269,7 +269,7 @@ bool rxrpc_queue_conn(struct rxrpc_connection *conn) if (n == 0) return false; if (rxrpc_queue_work(&conn->processor)) - trace_rxrpc_conn(conn, rxrpc_conn_queued, n + 1, here); + trace_rxrpc_conn(conn->debug_id, rxrpc_conn_queued, n + 1, here); else rxrpc_put_connection(conn); return true; @@ -284,7 +284,7 @@ void rxrpc_see_connection(struct rxrpc_connection *conn) if (conn) { int n = atomic_read(&conn->usage); - trace_rxrpc_conn(conn, rxrpc_conn_seen, n, here); + trace_rxrpc_conn(conn->debug_id, rxrpc_conn_seen, n, here); } } @@ -296,7 +296,7 @@ void rxrpc_get_connection(struct rxrpc_connection *conn) const void *here = __builtin_return_address(0); int n = atomic_inc_return(&conn->usage); - trace_rxrpc_conn(conn, rxrpc_conn_got, n, here); + trace_rxrpc_conn(conn->debug_id, rxrpc_conn_got, n, here); } /* @@ -310,7 +310,7 @@ rxrpc_get_connection_maybe(struct rxrpc_connection *conn) if (conn) { int n = atomic_fetch_add_unless(&conn->usage, 1, 0); if (n > 0) - trace_rxrpc_conn(conn, rxrpc_conn_got, n + 1, here); + trace_rxrpc_conn(conn->debug_id, rxrpc_conn_got, n + 1, here); else conn = NULL; } @@ -333,10 +333,11 @@ static void rxrpc_set_service_reap_timer(struct rxrpc_net *rxnet, void rxrpc_put_service_conn(struct rxrpc_connection *conn) { const void *here = __builtin_return_address(0); + unsigned int debug_id = conn->debug_id; int n; n = atomic_dec_return(&conn->usage); - trace_rxrpc_conn(conn, rxrpc_conn_put_service, n, here); + trace_rxrpc_conn(debug_id, rxrpc_conn_put_service, n, here); ASSERTCMP(n, >=, 0); if (n == 1) rxrpc_set_service_reap_timer(conn->params.local->rxnet, @@ -420,7 +421,7 @@ void rxrpc_service_connection_reaper(struct work_struct *work) */ if (atomic_cmpxchg(&conn->usage, 1, 0) != 1) continue; - trace_rxrpc_conn(conn, rxrpc_conn_reap_service, 0, NULL); + trace_rxrpc_conn(conn->debug_id, rxrpc_conn_reap_service, 0, NULL); if (rxrpc_conn_is_client(conn)) BUG(); diff --git a/net/rxrpc/conn_service.c b/net/rxrpc/conn_service.c index b30e13f6d95f..123d6ceab15c 100644 --- a/net/rxrpc/conn_service.c +++ b/net/rxrpc/conn_service.c @@ -134,7 +134,7 @@ struct rxrpc_connection *rxrpc_prealloc_service_connection(struct rxrpc_net *rxn list_add_tail(&conn->proc_link, &rxnet->conn_proc_list); write_unlock(&rxnet->conn_lock); - trace_rxrpc_conn(conn, rxrpc_conn_new_service, + trace_rxrpc_conn(conn->debug_id, rxrpc_conn_new_service, atomic_read(&conn->usage), __builtin_return_address(0)); } -- GitLab From 48c9e0ec7cbbb7370448f859ccc8e3b7eb69e755 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 7 Oct 2019 10:58:29 +0100 Subject: [PATCH 096/993] rxrpc: Fix trace-after-put looking at the put call record rxrpc_put_call() calls trace_rxrpc_call() after it has done the decrement of the refcount - which looks at the debug_id in the call record. But unless the refcount was reduced to zero, we no longer have the right to look in the record and, indeed, it may be deleted by some other thread. Fix this by getting the debug_id out before decrementing the refcount and then passing that into the tracepoint. Fixes: e34d4234b0b7 ("rxrpc: Trace rxrpc_call usage") Signed-off-by: David Howells --- include/trace/events/rxrpc.h | 6 +++--- net/rxrpc/call_accept.c | 2 +- net/rxrpc/call_object.c | 28 +++++++++++++++++----------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 38a97e890cb6..191fe447f990 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -606,10 +606,10 @@ TRACE_EVENT(rxrpc_client, ); TRACE_EVENT(rxrpc_call, - TP_PROTO(struct rxrpc_call *call, enum rxrpc_call_trace op, + TP_PROTO(unsigned int call_debug_id, enum rxrpc_call_trace op, int usage, const void *where, const void *aux), - TP_ARGS(call, op, usage, where, aux), + TP_ARGS(call_debug_id, op, usage, where, aux), TP_STRUCT__entry( __field(unsigned int, call ) @@ -620,7 +620,7 @@ TRACE_EVENT(rxrpc_call, ), TP_fast_assign( - __entry->call = call->debug_id; + __entry->call = call_debug_id; __entry->op = op; __entry->usage = usage; __entry->where = where; diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c index c1b1b7dd2924..1f778102ed8d 100644 --- a/net/rxrpc/call_accept.c +++ b/net/rxrpc/call_accept.c @@ -97,7 +97,7 @@ static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx, call->flags |= (1 << RXRPC_CALL_IS_SERVICE); call->state = RXRPC_CALL_SERVER_PREALLOC; - trace_rxrpc_call(call, rxrpc_call_new_service, + trace_rxrpc_call(call->debug_id, rxrpc_call_new_service, atomic_read(&call->usage), here, (const void *)user_call_ID); diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c index 32d8dc677142..6dace078971a 100644 --- a/net/rxrpc/call_object.c +++ b/net/rxrpc/call_object.c @@ -240,7 +240,8 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, if (p->intr) __set_bit(RXRPC_CALL_IS_INTR, &call->flags); call->tx_total_len = p->tx_total_len; - trace_rxrpc_call(call, rxrpc_call_new_client, atomic_read(&call->usage), + trace_rxrpc_call(call->debug_id, rxrpc_call_new_client, + atomic_read(&call->usage), here, (const void *)p->user_call_ID); /* We need to protect a partially set up call against the user as we @@ -290,8 +291,8 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, if (ret < 0) goto error; - trace_rxrpc_call(call, rxrpc_call_connected, atomic_read(&call->usage), - here, NULL); + trace_rxrpc_call(call->debug_id, rxrpc_call_connected, + atomic_read(&call->usage), here, NULL); rxrpc_start_call_timer(call); @@ -313,8 +314,8 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, error: __rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, RX_CALL_DEAD, ret); - trace_rxrpc_call(call, rxrpc_call_error, atomic_read(&call->usage), - here, ERR_PTR(ret)); + trace_rxrpc_call(call->debug_id, rxrpc_call_error, + atomic_read(&call->usage), here, ERR_PTR(ret)); rxrpc_release_call(rx, call); mutex_unlock(&call->user_mutex); rxrpc_put_call(call, rxrpc_call_put); @@ -376,7 +377,8 @@ bool rxrpc_queue_call(struct rxrpc_call *call) if (n == 0) return false; if (rxrpc_queue_work(&call->processor)) - trace_rxrpc_call(call, rxrpc_call_queued, n + 1, here, NULL); + trace_rxrpc_call(call->debug_id, rxrpc_call_queued, n + 1, + here, NULL); else rxrpc_put_call(call, rxrpc_call_put_noqueue); return true; @@ -391,7 +393,8 @@ bool __rxrpc_queue_call(struct rxrpc_call *call) int n = atomic_read(&call->usage); ASSERTCMP(n, >=, 1); if (rxrpc_queue_work(&call->processor)) - trace_rxrpc_call(call, rxrpc_call_queued_ref, n, here, NULL); + trace_rxrpc_call(call->debug_id, rxrpc_call_queued_ref, n, + here, NULL); else rxrpc_put_call(call, rxrpc_call_put_noqueue); return true; @@ -406,7 +409,8 @@ void rxrpc_see_call(struct rxrpc_call *call) if (call) { int n = atomic_read(&call->usage); - trace_rxrpc_call(call, rxrpc_call_seen, n, here, NULL); + trace_rxrpc_call(call->debug_id, rxrpc_call_seen, n, + here, NULL); } } @@ -418,7 +422,7 @@ void rxrpc_get_call(struct rxrpc_call *call, enum rxrpc_call_trace op) const void *here = __builtin_return_address(0); int n = atomic_inc_return(&call->usage); - trace_rxrpc_call(call, op, n, here, NULL); + trace_rxrpc_call(call->debug_id, op, n, here, NULL); } /* @@ -445,7 +449,8 @@ void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call) _enter("{%d,%d}", call->debug_id, atomic_read(&call->usage)); - trace_rxrpc_call(call, rxrpc_call_release, atomic_read(&call->usage), + trace_rxrpc_call(call->debug_id, rxrpc_call_release, + atomic_read(&call->usage), here, (const void *)call->flags); ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE); @@ -534,12 +539,13 @@ void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op) { struct rxrpc_net *rxnet = call->rxnet; const void *here = __builtin_return_address(0); + unsigned int debug_id = call->debug_id; int n; ASSERT(call != NULL); n = atomic_dec_return(&call->usage); - trace_rxrpc_call(call, op, n, here, NULL); + trace_rxrpc_call(debug_id, op, n, here, NULL); ASSERTCMP(n, >=, 0); if (n == 0) { _debug("call %d dead", call->debug_id); -- GitLab From 9ebeddef58c41bd700419cdcece24cf64ce32276 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 7 Oct 2019 10:58:29 +0100 Subject: [PATCH 097/993] rxrpc: rxrpc_peer needs to hold a ref on the rxrpc_local record The rxrpc_peer record needs to hold a reference on the rxrpc_local record it points as the peer is used as a base to access information in the rxrpc_local record. This can cause problems in __rxrpc_put_peer(), where we need the network namespace pointer, and in rxrpc_send_keepalive(), where we need to access the UDP socket, leading to symptoms like: BUG: KASAN: use-after-free in __rxrpc_put_peer net/rxrpc/peer_object.c:411 [inline] BUG: KASAN: use-after-free in rxrpc_put_peer+0x685/0x6a0 net/rxrpc/peer_object.c:435 Read of size 8 at addr ffff888097ec0058 by task syz-executor823/24216 Fix this by taking a ref on the local record for the peer record. Fixes: ace45bec6d77 ("rxrpc: Fix firewall route keepalive") Fixes: 2baec2c3f854 ("rxrpc: Support network namespacing") Reported-by: syzbot+b9be979c55f2bea8ed30@syzkaller.appspotmail.com Signed-off-by: David Howells --- net/rxrpc/peer_object.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/rxrpc/peer_object.c b/net/rxrpc/peer_object.c index b700b7ecaa3d..64830d8c1fdb 100644 --- a/net/rxrpc/peer_object.c +++ b/net/rxrpc/peer_object.c @@ -216,7 +216,7 @@ struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *local, gfp_t gfp) peer = kzalloc(sizeof(struct rxrpc_peer), gfp); if (peer) { atomic_set(&peer->usage, 1); - peer->local = local; + peer->local = rxrpc_get_local(local); INIT_HLIST_HEAD(&peer->error_targets); peer->service_conns = RB_ROOT; seqlock_init(&peer->service_conn_lock); @@ -307,7 +307,6 @@ void rxrpc_new_incoming_peer(struct rxrpc_sock *rx, struct rxrpc_local *local, unsigned long hash_key; hash_key = rxrpc_peer_hash_key(local, &peer->srx); - peer->local = local; rxrpc_init_peer(rx, peer, hash_key); spin_lock(&rxnet->peer_hash_lock); @@ -417,6 +416,7 @@ static void __rxrpc_put_peer(struct rxrpc_peer *peer) list_del_init(&peer->keepalive_link); spin_unlock_bh(&rxnet->peer_hash_lock); + rxrpc_put_local(peer->local); kfree_rcu(peer, rcu); } @@ -453,6 +453,7 @@ void rxrpc_put_peer_locked(struct rxrpc_peer *peer) if (n == 0) { hash_del_rcu(&peer->hash_link); list_del_init(&peer->keepalive_link); + rxrpc_put_local(peer->local); kfree_rcu(peer, rcu); } } -- GitLab From 91fcfbe8852edb929ff8702534525031a15d0aa6 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 7 Oct 2019 10:58:29 +0100 Subject: [PATCH 098/993] rxrpc: Fix call crypto state cleanup Fix the cleanup of the crypto state on a call after the call has been disconnected. As the call has been disconnected, its connection ref has been discarded and so we can't go through that to get to the security ops table. Fix this by caching the security ops pointer in the rxrpc_call struct and using that when freeing the call security state. Also use this in other places we're dealing with call-specific security. The symptoms look like: BUG: KASAN: use-after-free in rxrpc_release_call+0xb2d/0xb60 net/rxrpc/call_object.c:481 Read of size 8 at addr ffff888062ffeb50 by task syz-executor.5/4764 Fixes: 1db88c534371 ("rxrpc: Fix -Wframe-larger-than= warnings from on-stack crypto") Reported-by: syzbot+eed305768ece6682bb7f@syzkaller.appspotmail.com Signed-off-by: David Howells --- net/rxrpc/ar-internal.h | 1 + net/rxrpc/call_accept.c | 1 + net/rxrpc/call_object.c | 6 +++--- net/rxrpc/conn_client.c | 3 +++ net/rxrpc/recvmsg.c | 6 +++--- net/rxrpc/sendmsg.c | 2 +- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index 1091bf35a199..ecc17dabec8f 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -556,6 +556,7 @@ struct rxrpc_call { struct rxrpc_peer *peer; /* Peer record for remote address */ struct rxrpc_sock __rcu *socket; /* socket responsible */ struct rxrpc_net *rxnet; /* Network namespace to which call belongs */ + const struct rxrpc_security *security; /* applied security module */ struct mutex user_mutex; /* User access mutex */ unsigned long ack_at; /* When deferred ACK needs to happen */ unsigned long ack_lost_at; /* When ACK is figured as lost */ diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c index 1f778102ed8d..135bf5cd8dd5 100644 --- a/net/rxrpc/call_accept.c +++ b/net/rxrpc/call_accept.c @@ -307,6 +307,7 @@ static struct rxrpc_call *rxrpc_alloc_incoming_call(struct rxrpc_sock *rx, rxrpc_see_call(call); call->conn = conn; + call->security = conn->security; call->peer = rxrpc_get_peer(conn->params.peer); call->cong_cwnd = call->peer->cong_cwnd; return call; diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c index 6dace078971a..a31c18c09894 100644 --- a/net/rxrpc/call_object.c +++ b/net/rxrpc/call_object.c @@ -493,10 +493,10 @@ void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call) _debug("RELEASE CALL %p (%d CONN %p)", call, call->debug_id, conn); - if (conn) { + if (conn) rxrpc_disconnect_call(call); - conn->security->free_call_crypto(call); - } + if (call->security) + call->security->free_call_crypto(call); rxrpc_cleanup_ring(call); _leave(""); diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c index 700eb77173fc..376370cd9285 100644 --- a/net/rxrpc/conn_client.c +++ b/net/rxrpc/conn_client.c @@ -353,6 +353,7 @@ static int rxrpc_get_client_conn(struct rxrpc_sock *rx, if (cp->exclusive) { call->conn = candidate; + call->security = candidate->security; call->security_ix = candidate->security_ix; call->service_id = candidate->service_id; _leave(" = 0 [exclusive %d]", candidate->debug_id); @@ -404,6 +405,7 @@ static int rxrpc_get_client_conn(struct rxrpc_sock *rx, candidate_published: set_bit(RXRPC_CONN_IN_CLIENT_CONNS, &candidate->flags); call->conn = candidate; + call->security = candidate->security; call->security_ix = candidate->security_ix; call->service_id = candidate->service_id; spin_unlock(&local->client_conns_lock); @@ -426,6 +428,7 @@ static int rxrpc_get_client_conn(struct rxrpc_sock *rx, spin_lock(&conn->channel_lock); call->conn = conn; + call->security = conn->security; call->security_ix = conn->security_ix; call->service_id = conn->service_id; list_add_tail(&call->chan_wait_link, &conn->waiting_calls); diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c index 3b0becb12041..a4090797c9b2 100644 --- a/net/rxrpc/recvmsg.c +++ b/net/rxrpc/recvmsg.c @@ -251,8 +251,8 @@ static int rxrpc_verify_packet(struct rxrpc_call *call, struct sk_buff *skb, seq += subpacket; } - return call->conn->security->verify_packet(call, skb, offset, len, - seq, cksum); + return call->security->verify_packet(call, skb, offset, len, + seq, cksum); } /* @@ -291,7 +291,7 @@ static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb, *_offset = offset; *_len = len; - call->conn->security->locate_data(call, skb, _offset, _len); + call->security->locate_data(call, skb, _offset, _len); return 0; } diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index 22f51a7e356e..813fd6888142 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c @@ -419,7 +419,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, call->tx_winsize) sp->hdr.flags |= RXRPC_MORE_PACKETS; - ret = conn->security->secure_packet( + ret = call->security->secure_packet( call, skb, skb->mark, skb->head); if (ret < 0) goto out; -- GitLab From 90b32268e15c003d894e5567b7181bcc2bad6b2c Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 3 Oct 2019 17:48:41 +0200 Subject: [PATCH 099/993] dt-bindings: media: sun4i-csi: Drop the module clock It turns out that what was thought to be the module clock was actually the clock meant to be used by the sensor, and isn't playing any role with the CSI controller itself. Let's drop that clock from our binding. Fixes: c5e8f4ccd775 ("media: dt-bindings: media: Add Allwinner A10 CSI binding") Reported-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- .../devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml index 5dd1cf490cd9..d3e423fcb6c2 100644 --- a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml +++ b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml @@ -27,14 +27,12 @@ properties: clocks: items: - description: The CSI interface clock - - description: The CSI module clock - description: The CSI ISP clock - description: The CSI DRAM clock clock-names: items: - const: bus - - const: mod - const: isp - const: ram @@ -89,9 +87,8 @@ examples: compatible = "allwinner,sun7i-a20-csi0"; reg = <0x01c09000 0x1000>; interrupts = ; - clocks = <&ccu CLK_AHB_CSI0>, <&ccu CLK_CSI0>, - <&ccu CLK_CSI_SCLK>, <&ccu CLK_DRAM_CSI0>; - clock-names = "bus", "mod", "isp", "ram"; + clocks = <&ccu CLK_AHB_CSI0>, <&ccu CLK_CSI_SCLK>, <&ccu CLK_DRAM_CSI0>; + clock-names = "bus", "isp", "ram"; resets = <&ccu RST_CSI0>; port { -- GitLab From cf03c691eb959f438c16d58ffd11f150b1a95b1e Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 3 Oct 2019 17:48:42 +0200 Subject: [PATCH 100/993] ARM: dts: sun7i: Drop the module clock from the device tree What we thought would be the module clock is actually the clock meant to be used by the sensors, and play no role in the CSI controller. Now that the binding has been updated to reflect that, let's update the device tree too. Fixes: d2b9c6444301 ("ARM: dts: sun7i: Add CSI0 controller") Reported-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun7i-a20.dtsi | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 49380de754a9..31631a3504c0 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -380,9 +380,8 @@ compatible = "allwinner,sun7i-a20-csi0"; reg = <0x01c09000 0x1000>; interrupts = ; - clocks = <&ccu CLK_AHB_CSI0>, <&ccu CLK_CSI0>, - <&ccu CLK_CSI_SCLK>, <&ccu CLK_DRAM_CSI0>; - clock-names = "bus", "mod", "isp", "ram"; + clocks = <&ccu CLK_AHB_CSI0>, <&ccu CLK_CSI_SCLK>, <&ccu CLK_DRAM_CSI0>; + clock-names = "bus", "isp", "ram"; resets = <&ccu RST_CSI0>; status = "disabled"; }; -- GitLab From 0632fa042541dbb3b8b960a8cd519eb9b6b584c0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 5 Oct 2019 23:22:02 +0200 Subject: [PATCH 101/993] ASoC: core: Fix pcm code debugfs error We can have 2 dcpm-s with the same backend and frontend name (capture + playback pair), this causes the following debugfs error on Intel Bay Trail systems: [ 298.969049] debugfs: Directory 'SSP2-Codec' with parent 'Baytrail Audio Port' already present! This commit adds a ":playback" or ":capture" postfix to the debugfs dir name fixing this. Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20191005212202.5206-1-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index a1b99ac57d9e..b600d3eaaf5c 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1146,6 +1146,7 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, { struct snd_soc_dpcm *dpcm; unsigned long flags; + char *name; /* only add new dpcms */ for_each_dpcm_be(fe, stream, dpcm) { @@ -1171,9 +1172,15 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, stream ? "<-" : "->", be->dai_link->name); #ifdef CONFIG_DEBUG_FS - dpcm->debugfs_state = debugfs_create_dir(be->dai_link->name, - fe->debugfs_dpcm_root); - debugfs_create_u32("state", 0644, dpcm->debugfs_state, &dpcm->state); + name = kasprintf(GFP_KERNEL, "%s:%s", be->dai_link->name, + stream ? "capture" : "playback"); + if (name) { + dpcm->debugfs_state = debugfs_create_dir(name, + fe->debugfs_dpcm_root); + debugfs_create_u32("state", 0644, dpcm->debugfs_state, + &dpcm->state); + kfree(name); + } #endif return 1; } -- GitLab From 4b5149365faa8fddf7dc58e47cfed51b19db051e Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Sun, 6 Oct 2019 13:21:07 -0700 Subject: [PATCH 102/993] ionic: fix stats memory dereference When the netdev is down, the queues and their debug stats do not exist, so don't try using a pointer to them when when printing the ethtool stats. Fixes: e470355bd96a ("ionic: Add driver stats") Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- .../net/ethernet/pensando/ionic/ionic_lif.h | 2 ++ .../net/ethernet/pensando/ionic/ionic_stats.c | 29 ++++++++++++------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.h b/drivers/net/ethernet/pensando/ionic/ionic_lif.h index 812190e729c2..6a95b42a8d8c 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.h @@ -182,6 +182,8 @@ struct ionic_lif { #define lif_to_txqcq(lif, i) ((lif)->txqcqs[i].qcq) #define lif_to_rxqcq(lif, i) ((lif)->rxqcqs[i].qcq) +#define lif_to_txstats(lif, i) ((lif)->txqcqs[i].stats->tx) +#define lif_to_rxstats(lif, i) ((lif)->rxqcqs[i].stats->rx) #define lif_to_txq(lif, i) (&lif_to_txqcq((lif), i)->q) #define lif_to_rxq(lif, i) (&lif_to_txqcq((lif), i)->q) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_stats.c b/drivers/net/ethernet/pensando/ionic/ionic_stats.c index e2907884f843..03916b6d47f2 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_stats.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_stats.c @@ -117,7 +117,8 @@ static u64 ionic_sw_stats_get_count(struct ionic_lif *lif) /* rx stats */ total += MAX_Q(lif) * IONIC_NUM_RX_STATS; - if (test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { + if (test_bit(IONIC_LIF_UP, lif->state) && + test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { /* tx debug stats */ total += MAX_Q(lif) * (IONIC_NUM_DBG_CQ_STATS + IONIC_NUM_TX_Q_STATS + @@ -149,7 +150,8 @@ static void ionic_sw_stats_get_strings(struct ionic_lif *lif, u8 **buf) *buf += ETH_GSTRING_LEN; } - if (test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { + if (test_bit(IONIC_LIF_UP, lif->state) && + test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { for (i = 0; i < IONIC_NUM_TX_Q_STATS; i++) { snprintf(*buf, ETH_GSTRING_LEN, "txq_%d_%s", @@ -187,7 +189,8 @@ static void ionic_sw_stats_get_strings(struct ionic_lif *lif, u8 **buf) *buf += ETH_GSTRING_LEN; } - if (test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { + if (test_bit(IONIC_LIF_UP, lif->state) && + test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) { snprintf(*buf, ETH_GSTRING_LEN, "rxq_%d_cq_%s", @@ -223,6 +226,8 @@ static void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf) { struct ionic_lif_sw_stats lif_stats; struct ionic_qcq *txqcq, *rxqcq; + struct ionic_tx_stats *txstats; + struct ionic_rx_stats *rxstats; int i, q_num; ionic_get_lif_stats(lif, &lif_stats); @@ -233,15 +238,17 @@ static void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf) } for (q_num = 0; q_num < MAX_Q(lif); q_num++) { - txqcq = lif_to_txqcq(lif, q_num); + txstats = &lif_to_txstats(lif, q_num); for (i = 0; i < IONIC_NUM_TX_STATS; i++) { - **buf = IONIC_READ_STAT64(&txqcq->stats->tx, + **buf = IONIC_READ_STAT64(txstats, &ionic_tx_stats_desc[i]); (*buf)++; } - if (test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { + if (test_bit(IONIC_LIF_UP, lif->state) && + test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { + txqcq = lif_to_txqcq(lif, q_num); for (i = 0; i < IONIC_NUM_TX_Q_STATS; i++) { **buf = IONIC_READ_STAT64(&txqcq->q, &ionic_txq_stats_desc[i]); @@ -258,22 +265,24 @@ static void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf) (*buf)++; } for (i = 0; i < IONIC_MAX_NUM_SG_CNTR; i++) { - **buf = txqcq->stats->tx.sg_cntr[i]; + **buf = txstats->sg_cntr[i]; (*buf)++; } } } for (q_num = 0; q_num < MAX_Q(lif); q_num++) { - rxqcq = lif_to_rxqcq(lif, q_num); + rxstats = &lif_to_rxstats(lif, q_num); for (i = 0; i < IONIC_NUM_RX_STATS; i++) { - **buf = IONIC_READ_STAT64(&rxqcq->stats->rx, + **buf = IONIC_READ_STAT64(rxstats, &ionic_rx_stats_desc[i]); (*buf)++; } - if (test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { + if (test_bit(IONIC_LIF_UP, lif->state) && + test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { + rxqcq = lif_to_rxqcq(lif, q_num); for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) { **buf = IONIC_READ_STAT64(&rxqcq->cq, &ionic_dbg_cq_stats_desc[i]); -- GitLab From 503c9addef613c872679e24fc8a78f3febeb5a08 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 7 Oct 2019 17:43:02 +0200 Subject: [PATCH 103/993] ptp: fix typo of "mechanism" in Kconfig help text Fix typo s/mechansim/mechanism/ Signed-off-by: Antonio Borneo Signed-off-by: David S. Miller --- drivers/ptp/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig index 960961fb0d7c..0517272a268e 100644 --- a/drivers/ptp/Kconfig +++ b/drivers/ptp/Kconfig @@ -97,8 +97,8 @@ config PTP_1588_CLOCK_PCH help This driver adds support for using the PCH EG20T as a PTP clock. The hardware supports time stamping of PTP packets - when using the end-to-end delay (E2E) mechansim. The peer - delay mechansim (P2P) is not supported. + when using the end-to-end delay (E2E) mechanism. The peer + delay mechanism (P2P) is not supported. This clock is only useful if your PTP programs are getting hardware time stamps on the PTP Ethernet packets using the -- GitLab From 1399c59fa92984836db90538cf92397fe7caaa57 Mon Sep 17 00:00:00 2001 From: Navid Emamdoost Date: Fri, 4 Oct 2019 14:42:19 -0500 Subject: [PATCH 104/993] nl80211: fix memory leak in nl80211_get_ftm_responder_stats In nl80211_get_ftm_responder_stats, a new skb is created via nlmsg_new named msg. If nl80211hdr_put() fails, then msg should be released. The return statement should be replace by goto to error handling code. Fixes: 81e54d08d9d8 ("cfg80211: support FTM responder configuration/statistics") Signed-off-by: Navid Emamdoost Link: https://lore.kernel.org/r/20191004194220.19412-1-navid.emamdoost@gmail.com Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 141cdb171665..4453dd375de9 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -13682,7 +13682,7 @@ static int nl80211_get_ftm_responder_stats(struct sk_buff *skb, hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, NL80211_CMD_GET_FTM_RESPONDER_STATS); if (!hdr) - return -ENOBUFS; + goto nla_put_failure; if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) goto nla_put_failure; -- GitLab From 461c4c2b4c0731d7452bad4e77c0cdbdcea1804c Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Fri, 4 Oct 2019 15:37:06 +0300 Subject: [PATCH 105/993] cfg80211: fix a bunch of RCU issues in multi-bssid code cfg80211_update_notlisted_nontrans() leaves the RCU critical session too early, while still using nontrans_ssid which is RCU protected. In addition, it performs a bunch of RCU pointer update operations such as rcu_access_pointer and rcu_assign_pointer. The caller, cfg80211_inform_bss_frame_data(), also accesses the RCU pointer without holding the lock. Just wrap all of this with bss_lock. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/20191004123706.15768-3-luca@coelho.fi Signed-off-by: Johannes Berg --- net/wireless/scan.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index ff1016607f0b..aef240fdf8df 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -1703,8 +1703,7 @@ cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy, static void cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, struct cfg80211_bss *nontrans_bss, - struct ieee80211_mgmt *mgmt, size_t len, - gfp_t gfp) + struct ieee80211_mgmt *mgmt, size_t len) { u8 *ie, *new_ie, *pos; const u8 *nontrans_ssid, *trans_ssid, *mbssid; @@ -1715,6 +1714,8 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, const struct cfg80211_bss_ies *old; u8 cpy_len; + lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock); + ie = mgmt->u.probe_resp.variable; new_ie_len = ielen; @@ -1731,23 +1732,22 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy, if (!mbssid || mbssid < trans_ssid) return; new_ie_len -= mbssid[1]; - rcu_read_lock(); + nontrans_ssid = ieee80211_bss_get_ie(nontrans_bss, WLAN_EID_SSID); - if (!nontrans_ssid) { - rcu_read_unlock(); + if (!nontrans_ssid) return; - } + new_ie_len += nontrans_ssid[1]; - rcu_read_unlock(); /* generate new ie for nontrans BSS * 1. replace SSID with nontrans BSS' SSID * 2. skip MBSSID IE */ - new_ie = kzalloc(new_ie_len, gfp); + new_ie = kzalloc(new_ie_len, GFP_ATOMIC); if (!new_ie) return; - new_ies = kzalloc(sizeof(*new_ies) + new_ie_len, gfp); + + new_ies = kzalloc(sizeof(*new_ies) + new_ie_len, GFP_ATOMIC); if (!new_ies) goto out_free; @@ -1901,6 +1901,8 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, cfg80211_parse_mbssid_frame_data(wiphy, data, mgmt, len, &non_tx_data, gfp); + spin_lock_bh(&wiphy_to_rdev(wiphy)->bss_lock); + /* check if the res has other nontransmitting bss which is not * in MBSSID IE */ @@ -1915,8 +1917,9 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, ies2 = rcu_access_pointer(tmp_bss->ies); if (ies2->tsf < ies1->tsf) cfg80211_update_notlisted_nontrans(wiphy, tmp_bss, - mgmt, len, gfp); + mgmt, len); } + spin_unlock_bh(&wiphy_to_rdev(wiphy)->bss_lock); return res; } -- GitLab From 95697f9907bfe3eab0ef20265a766b22e27dde64 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 4 Oct 2019 15:37:05 +0300 Subject: [PATCH 106/993] mac80211: accept deauth frames in IBSS mode We can process deauth frames and all, but we drop them very early in the RX path today - this could never have worked. Fixes: 2cc59e784b54 ("mac80211: reply to AUTH with DEAUTH if sta allocation fails in IBSS") Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/20191004123706.15768-2-luca@coelho.fi Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 768d14c9a716..0e05ff037672 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -3467,9 +3467,18 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): /* process for all: mesh, mlme, ibss */ break; + case cpu_to_le16(IEEE80211_STYPE_DEAUTH): + if (is_multicast_ether_addr(mgmt->da) && + !is_broadcast_ether_addr(mgmt->da)) + return RX_DROP_MONITOR; + + /* process only for station/IBSS */ + if (sdata->vif.type != NL80211_IFTYPE_STATION && + sdata->vif.type != NL80211_IFTYPE_ADHOC) + return RX_DROP_MONITOR; + break; case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP): case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP): - case cpu_to_le16(IEEE80211_STYPE_DEAUTH): case cpu_to_le16(IEEE80211_STYPE_DISASSOC): if (is_multicast_ether_addr(mgmt->da) && !is_broadcast_ether_addr(mgmt->da)) -- GitLab From dc0c18ed229cdcca283dd78fefa38273ec37a42c Mon Sep 17 00:00:00 2001 From: Aaron Komisar Date: Wed, 2 Oct 2019 13:59:07 +0000 Subject: [PATCH 107/993] mac80211: fix scan when operating on DFS channels in ETSI domains In non-ETSI regulatory domains scan is blocked when operating channel is a DFS channel. For ETSI, however, once DFS channel is marked as available after the CAC, this channel will remain available (for some time) even after leaving this channel. Therefore a scan can be done without any impact on the availability of the DFS channel as no new CAC is required after the scan. Enable scan in mac80211 in these cases. Signed-off-by: Aaron Komisar Link: https://lore.kernel.org/r/1570024728-17284-1-git-send-email-aaron.komisar@tandemg.com Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 8 ++++++++ net/mac80211/scan.c | 30 ++++++++++++++++++++++++++++-- net/wireless/reg.c | 1 + net/wireless/reg.h | 8 -------- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ff45c3e1abff..4ab2c49423dc 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -5549,6 +5549,14 @@ const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy, */ const char *reg_initiator_name(enum nl80211_reg_initiator initiator); +/** + * regulatory_pre_cac_allowed - check if pre-CAC allowed in the current regdom + * @wiphy: wiphy for which pre-CAC capability is checked. + * + * Pre-CAC is allowed only in some regdomains (notable ETSI). + */ +bool regulatory_pre_cac_allowed(struct wiphy *wiphy); + /** * DOC: Internal regulatory db functions * diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index adf94ba1ed77..4d31d9688dc2 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -520,10 +520,33 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local, return 0; } +static bool __ieee80211_can_leave_ch(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_sub_if_data *sdata_iter; + + if (!ieee80211_is_radar_required(local)) + return true; + + if (!regulatory_pre_cac_allowed(local->hw.wiphy)) + return false; + + mutex_lock(&local->iflist_mtx); + list_for_each_entry(sdata_iter, &local->interfaces, list) { + if (sdata_iter->wdev.cac_started) { + mutex_unlock(&local->iflist_mtx); + return false; + } + } + mutex_unlock(&local->iflist_mtx); + + return true; +} + static bool ieee80211_can_scan(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata) { - if (ieee80211_is_radar_required(local)) + if (!__ieee80211_can_leave_ch(sdata)) return false; if (!list_empty(&local->roc_list)) @@ -630,7 +653,10 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, lockdep_assert_held(&local->mtx); - if (local->scan_req || ieee80211_is_radar_required(local)) + if (local->scan_req) + return -EBUSY; + + if (!__ieee80211_can_leave_ch(sdata)) return -EBUSY; if (!ieee80211_can_scan(local, sdata)) { diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 420c4207ab59..446c76d44e65 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -3883,6 +3883,7 @@ bool regulatory_pre_cac_allowed(struct wiphy *wiphy) return pre_cac_allowed; } +EXPORT_SYMBOL(regulatory_pre_cac_allowed); void regulatory_propagate_dfs_state(struct wiphy *wiphy, struct cfg80211_chan_def *chandef, diff --git a/net/wireless/reg.h b/net/wireless/reg.h index 504133d76de4..dc8f689bd469 100644 --- a/net/wireless/reg.h +++ b/net/wireless/reg.h @@ -155,14 +155,6 @@ bool regulatory_indoor_allowed(void); */ #define REG_PRE_CAC_EXPIRY_GRACE_MS 2000 -/** - * regulatory_pre_cac_allowed - if pre-CAC allowed in the current dfs domain - * @wiphy: wiphy for which pre-CAC capability is checked. - - * Pre-CAC is allowed only in ETSI domain. - */ -bool regulatory_pre_cac_allowed(struct wiphy *wiphy); - /** * regulatory_propagate_dfs_state - Propagate DFS channel state to other wiphys * @wiphy - wiphy on which radar is detected and the event will be propagated -- GitLab From d3ec3a08fa700c8b46abb137dce4e2514a6f9668 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 7 Feb 2019 16:01:21 +0000 Subject: [PATCH 108/993] arm64: KVM: Trap VM ops when ARM64_WORKAROUND_CAVIUM_TX2_219_TVM is set In order to workaround the TX2-219 erratum, it is necessary to trap TTBRx_EL1 accesses to EL2. This is done by setting HCR_EL2.TVM on guest entry, which has the side effect of trapping all the other VM-related sysregs as well. To minimize the overhead, a fast path is used so that we don't have to go all the way back to the main sysreg handling code, unless the rest of the hypervisor expects to see these accesses. Cc: Signed-off-by: Marc Zyngier Signed-off-by: Will Deacon --- arch/arm64/include/asm/cpucaps.h | 3 +- arch/arm64/kvm/hyp/switch.c | 69 +++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index f19fe4b9acc4..e81e0cbd728f 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -52,7 +52,8 @@ #define ARM64_HAS_IRQ_PRIO_MASKING 42 #define ARM64_HAS_DCPODP 43 #define ARM64_WORKAROUND_1463225 44 +#define ARM64_WORKAROUND_CAVIUM_TX2_219_TVM 45 -#define ARM64_NCAPS 45 +#define ARM64_NCAPS 46 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c index 3d3815020e36..799e84a40335 100644 --- a/arch/arm64/kvm/hyp/switch.c +++ b/arch/arm64/kvm/hyp/switch.c @@ -124,6 +124,9 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu) { u64 hcr = vcpu->arch.hcr_el2; + if (cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM)) + hcr |= HCR_TVM; + write_sysreg(hcr, hcr_el2); if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (hcr & HCR_VSE)) @@ -174,8 +177,10 @@ static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu) * the crucial bit is "On taking a vSError interrupt, * HCR_EL2.VSE is cleared to 0." */ - if (vcpu->arch.hcr_el2 & HCR_VSE) - vcpu->arch.hcr_el2 = read_sysreg(hcr_el2); + if (vcpu->arch.hcr_el2 & HCR_VSE) { + vcpu->arch.hcr_el2 &= ~HCR_VSE; + vcpu->arch.hcr_el2 |= read_sysreg(hcr_el2) & HCR_VSE; + } if (has_vhe()) deactivate_traps_vhe(); @@ -380,6 +385,61 @@ static bool __hyp_text __hyp_handle_fpsimd(struct kvm_vcpu *vcpu) return true; } +static bool __hyp_text handle_tx2_tvm(struct kvm_vcpu *vcpu) +{ + u32 sysreg = esr_sys64_to_sysreg(kvm_vcpu_get_hsr(vcpu)); + int rt = kvm_vcpu_sys_get_rt(vcpu); + u64 val = vcpu_get_reg(vcpu, rt); + + /* + * The normal sysreg handling code expects to see the traps, + * let's not do anything here. + */ + if (vcpu->arch.hcr_el2 & HCR_TVM) + return false; + + switch (sysreg) { + case SYS_SCTLR_EL1: + write_sysreg_el1(val, SYS_SCTLR); + break; + case SYS_TTBR0_EL1: + write_sysreg_el1(val, SYS_TTBR0); + break; + case SYS_TTBR1_EL1: + write_sysreg_el1(val, SYS_TTBR1); + break; + case SYS_TCR_EL1: + write_sysreg_el1(val, SYS_TCR); + break; + case SYS_ESR_EL1: + write_sysreg_el1(val, SYS_ESR); + break; + case SYS_FAR_EL1: + write_sysreg_el1(val, SYS_FAR); + break; + case SYS_AFSR0_EL1: + write_sysreg_el1(val, SYS_AFSR0); + break; + case SYS_AFSR1_EL1: + write_sysreg_el1(val, SYS_AFSR1); + break; + case SYS_MAIR_EL1: + write_sysreg_el1(val, SYS_MAIR); + break; + case SYS_AMAIR_EL1: + write_sysreg_el1(val, SYS_AMAIR); + break; + case SYS_CONTEXTIDR_EL1: + write_sysreg_el1(val, SYS_CONTEXTIDR); + break; + default: + return false; + } + + __kvm_skip_instr(vcpu); + return true; +} + /* * Return true when we were able to fixup the guest exit and should return to * the guest, false when we should restore the host state and return to the @@ -399,6 +459,11 @@ static bool __hyp_text fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) if (*exit_code != ARM_EXCEPTION_TRAP) goto exit; + if (cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM) && + kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_SYS64 && + handle_tx2_tvm(vcpu)) + return true; + /* * We trap the first access to the FP/SIMD to save the host context * and restore the guest context lazily. -- GitLab From 93916beb70143c46bf1d2bacf814be3a124b253b Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 9 Apr 2019 16:26:21 +0100 Subject: [PATCH 109/993] arm64: Enable workaround for Cavium TX2 erratum 219 when running SMT It appears that the only case where we need to apply the TX2_219_TVM mitigation is when the core is in SMT mode. So let's condition the enabling on detecting a CPU whose MPIDR_EL1.Aff0 is non-zero. Cc: Signed-off-by: Marc Zyngier Signed-off-by: Will Deacon --- arch/arm64/kernel/cpu_errata.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 1e43ba5c79b7..d999ca2dd760 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -12,6 +12,7 @@ #include #include #include +#include static bool __maybe_unused is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope) @@ -623,6 +624,30 @@ check_branch_predictor(const struct arm64_cpu_capabilities *entry, int scope) return (need_wa > 0); } +static const __maybe_unused struct midr_range tx2_family_cpus[] = { + MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN), + MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2), + {}, +}; + +static bool __maybe_unused +needs_tx2_tvm_workaround(const struct arm64_cpu_capabilities *entry, + int scope) +{ + int i; + + if (!is_affected_midr_range_list(entry, scope) || + !is_hyp_mode_available()) + return false; + + for_each_possible_cpu(i) { + if (MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 0) != 0) + return true; + } + + return false; +} + #ifdef CONFIG_HARDEN_EL2_VECTORS static const struct midr_range arm64_harden_el2_vectors[] = { @@ -851,6 +876,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .matches = has_cortex_a76_erratum_1463225, }, +#endif +#ifdef CONFIG_CAVIUM_TX2_ERRATUM_219 + { + .desc = "Cavium ThunderX2 erratum 219 (KVM guest sysreg trapping)", + .capability = ARM64_WORKAROUND_CAVIUM_TX2_219_TVM, + ERRATA_MIDR_RANGE_LIST(tx2_family_cpus), + .matches = needs_tx2_tvm_workaround, + }, #endif { } -- GitLab From 9405447ef79bc93101373e130f72e9e6cbf17dbb Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 9 Apr 2019 16:22:24 +0100 Subject: [PATCH 110/993] arm64: Avoid Cavium TX2 erratum 219 when switching TTBR As a PRFM instruction racing against a TTBR update can have undesirable effects on TX2, NOP-out such PRFM on cores that are affected by the TX2-219 erratum. Cc: Signed-off-by: Marc Zyngier Signed-off-by: Will Deacon --- arch/arm64/include/asm/cpucaps.h | 3 ++- arch/arm64/kernel/cpu_errata.c | 5 +++++ arch/arm64/kernel/entry.S | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index e81e0cbd728f..ac1dbca3d0cd 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -53,7 +53,8 @@ #define ARM64_HAS_DCPODP 43 #define ARM64_WORKAROUND_1463225 44 #define ARM64_WORKAROUND_CAVIUM_TX2_219_TVM 45 +#define ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM 46 -#define ARM64_NCAPS 46 +#define ARM64_NCAPS 47 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index d999ca2dd760..a19bb3e4bcfb 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -884,6 +884,11 @@ const struct arm64_cpu_capabilities arm64_errata[] = { ERRATA_MIDR_RANGE_LIST(tx2_family_cpus), .matches = needs_tx2_tvm_workaround, }, + { + .desc = "Cavium ThunderX2 erratum 219 (PRFM removal)", + .capability = ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM, + ERRATA_MIDR_RANGE_LIST(tx2_family_cpus), + }, #endif { } diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 84a822748c84..109894bd3194 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -1070,7 +1070,9 @@ alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003 #else ldr x30, =vectors #endif +alternative_if_not ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM prfm plil1strm, [x30, #(1b - tramp_vectors)] +alternative_else_nop_endif msr vbar_el1, x30 add x30, x30, #(1b - tramp_vectors) isb -- GitLab From 603afdc9438ac546181e843f807253d75d3dbc45 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 13 Sep 2019 10:57:50 +0100 Subject: [PATCH 111/993] arm64: Allow CAVIUM_TX2_ERRATUM_219 to be selected Allow the user to select the workaround for TX2-219, and update the silicon-errata.rst file to reflect this. Cc: Signed-off-by: Marc Zyngier Signed-off-by: Will Deacon --- Documentation/arm64/silicon-errata.rst | 2 ++ arch/arm64/Kconfig | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index 17ea3fecddaa..ab7ed2fd072f 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -107,6 +107,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Cavium | ThunderX2 SMMUv3| #126 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +| Cavium | ThunderX2 Core | #219 | CAVIUM_TX2_ERRATUM_219 | ++----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 | +----------------+-----------------+-----------------+-----------------------------+ diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 41a9b4257b72..7d36fd95ae5a 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -617,6 +617,23 @@ config CAVIUM_ERRATUM_30115 If unsure, say Y. +config CAVIUM_TX2_ERRATUM_219 + bool "Cavium ThunderX2 erratum 219: PRFM between TTBR change and ISB fails" + default y + help + On Cavium ThunderX2, a load, store or prefetch instruction between a + TTBR update and the corresponding context synchronizing operation can + cause a spurious Data Abort to be delivered to any hardware thread in + the CPU core. + + Work around the issue by avoiding the problematic code sequence and + trapping KVM guest TTBRx_EL1 writes to EL2 when SMT is enabled. The + trap handler performs the corresponding register access, skips the + instruction and ensures context synchronization by virtue of the + exception return. + + If unsure, say Y. + config QCOM_FALKOR_ERRATUM_1003 bool "Falkor E1003: Incorrect translation due to ASID change" default y -- GitLab From 734a9b21bb061acdbb0b9c08cd37f80368f381dd Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Tue, 8 Oct 2019 10:56:42 +0300 Subject: [PATCH 112/993] ARM: dts: omap5: fix gpu_cm clock provider name The clkctrl code searches for the parent clockdomain based on the name of the CM provider node. The introduction of SGX node for omap5 made the node name for the gpu_cm to be clock-controller. There is no clockdomain named like this, so the lookup fails. Fix by changing the node name properly. Fixes: 394534cb07d8 ("ARM: dts: Configure sgx for omap5") Signed-off-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap54xx-clocks.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/omap54xx-clocks.dtsi b/arch/arm/boot/dts/omap54xx-clocks.dtsi index fac2e57dcca9..4791834dacb2 100644 --- a/arch/arm/boot/dts/omap54xx-clocks.dtsi +++ b/arch/arm/boot/dts/omap54xx-clocks.dtsi @@ -1146,7 +1146,7 @@ }; }; - gpu_cm: clock-controller@1500 { + gpu_cm: gpu_cm@1500 { compatible = "ti,omap4-cm"; reg = <0x1500 0x100>; #address-cells = <1>; -- GitLab From 647c8977e111c0a62c93a489ebc4b045c833fdb4 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 3 Oct 2019 18:45:48 -0700 Subject: [PATCH 113/993] ARM: dts: am3874-iceboard: Fix 'i2c-mux-idle-disconnect' usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt, i2c-mux-idle-disconnect is a property of a parent node since it pertains to the mux/switch as a whole, so move it there and drop all of the concurrences in child nodes. Fixes: d031773169df ("ARM: dts: Adds device tree file for McGill's IceBoard, based on TI AM3874") Signed-off-by: Andrey Smirnov Cc: Benoît Cousson Cc: Tony Lindgren Cc: Graeme Smecher Cc: linux-omap@vger.kernel.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Tested-by: Graeme Smecher Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am3874-iceboard.dts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/arch/arm/boot/dts/am3874-iceboard.dts b/arch/arm/boot/dts/am3874-iceboard.dts index 883fb85135d4..1b4b2b0500e4 100644 --- a/arch/arm/boot/dts/am3874-iceboard.dts +++ b/arch/arm/boot/dts/am3874-iceboard.dts @@ -111,13 +111,13 @@ reg = <0x70>; #address-cells = <1>; #size-cells = <0>; + i2c-mux-idle-disconnect; i2c@0 { /* FMC A */ #address-cells = <1>; #size-cells = <0>; reg = <0>; - i2c-mux-idle-disconnect; }; i2c@1 { @@ -125,7 +125,6 @@ #address-cells = <1>; #size-cells = <0>; reg = <1>; - i2c-mux-idle-disconnect; }; i2c@2 { @@ -133,7 +132,6 @@ #address-cells = <1>; #size-cells = <0>; reg = <2>; - i2c-mux-idle-disconnect; }; i2c@3 { @@ -141,7 +139,6 @@ #address-cells = <1>; #size-cells = <0>; reg = <3>; - i2c-mux-idle-disconnect; }; i2c@4 { @@ -149,14 +146,12 @@ #address-cells = <1>; #size-cells = <0>; reg = <4>; - i2c-mux-idle-disconnect; }; i2c@5 { #address-cells = <1>; #size-cells = <0>; reg = <5>; - i2c-mux-idle-disconnect; ina230@40 { compatible = "ti,ina230"; reg = <0x40>; shunt-resistor = <5000>; }; ina230@41 { compatible = "ti,ina230"; reg = <0x41>; shunt-resistor = <5000>; }; @@ -182,14 +177,12 @@ #address-cells = <1>; #size-cells = <0>; reg = <6>; - i2c-mux-idle-disconnect; }; i2c@7 { #address-cells = <1>; #size-cells = <0>; reg = <7>; - i2c-mux-idle-disconnect; u41: pca9575@20 { compatible = "nxp,pca9575"; -- GitLab From 98d22b01f9f6f85eb8870290006241b316829fd3 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 2 Oct 2019 14:50:52 -0700 Subject: [PATCH 114/993] rt2x00: remove input-polldev.h header The driver does not use input subsystem so we do not need this header, and it is being removed, so stop pulling it in. Signed-off-by: Dmitry Torokhov Signed-off-by: Kalle Valo --- drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h index 2b216edd0c7d..a90a518b40d3 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include -- GitLab From 0a005856d35936e351cc20ff3de04499bd7ffbfd Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Mon, 23 Sep 2019 14:11:11 +0800 Subject: [PATCH 115/993] dm clone: Make __hash_find static drivers/md/dm-clone-target.c:594:34: warning: symbol '__hash_find' was not declared. Should it be static? Reported-by: Hulk Robot Signed-off-by: YueHaibing Signed-off-by: Mike Snitzer --- drivers/md/dm-clone-target.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm-clone-target.c b/drivers/md/dm-clone-target.c index cd6f9e9fc98e..4ca8f1977222 100644 --- a/drivers/md/dm-clone-target.c +++ b/drivers/md/dm-clone-target.c @@ -591,8 +591,8 @@ static struct hash_table_bucket *get_hash_table_bucket(struct clone *clone, * * NOTE: Must be called with the bucket lock held */ -struct dm_clone_region_hydration *__hash_find(struct hash_table_bucket *bucket, - unsigned long region_nr) +static struct dm_clone_region_hydration *__hash_find(struct hash_table_bucket *bucket, + unsigned long region_nr) { struct dm_clone_region_hydration *hd; -- GitLab From c6ee11c39fcc1fb55130748990a8f199e76263b4 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 6 Oct 2019 14:24:24 -0700 Subject: [PATCH 116/993] llc: fix sk_buff leak in llc_sap_state_process() syzbot reported: BUG: memory leak unreferenced object 0xffff888116270800 (size 224): comm "syz-executor641", pid 7047, jiffies 4294947360 (age 13.860s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 20 e1 2a 81 88 ff ff 00 40 3d 2a 81 88 ff ff . .*.....@=*.... backtrace: [<000000004d41b4cc>] kmemleak_alloc_recursive include/linux/kmemleak.h:55 [inline] [<000000004d41b4cc>] slab_post_alloc_hook mm/slab.h:439 [inline] [<000000004d41b4cc>] slab_alloc_node mm/slab.c:3269 [inline] [<000000004d41b4cc>] kmem_cache_alloc_node+0x153/0x2a0 mm/slab.c:3579 [<00000000506a5965>] __alloc_skb+0x6e/0x210 net/core/skbuff.c:198 [<000000001ba5a161>] alloc_skb include/linux/skbuff.h:1058 [inline] [<000000001ba5a161>] alloc_skb_with_frags+0x5f/0x250 net/core/skbuff.c:5327 [<0000000047d9c78b>] sock_alloc_send_pskb+0x269/0x2a0 net/core/sock.c:2225 [<000000003828fe54>] sock_alloc_send_skb+0x32/0x40 net/core/sock.c:2242 [<00000000e34d94f9>] llc_ui_sendmsg+0x10a/0x540 net/llc/af_llc.c:933 [<00000000de2de3fb>] sock_sendmsg_nosec net/socket.c:652 [inline] [<00000000de2de3fb>] sock_sendmsg+0x54/0x70 net/socket.c:671 [<000000008fe16e7a>] __sys_sendto+0x148/0x1f0 net/socket.c:1964 [...] The bug is that llc_sap_state_process() always takes an extra reference to the skb, but sometimes neither llc_sap_next_state() nor llc_sap_state_process() itself drops this reference. Fix it by changing llc_sap_next_state() to never consume a reference to the skb, rather than sometimes do so and sometimes not. Then remove the extra skb_get() and kfree_skb() from llc_sap_state_process(). Reported-by: syzbot+6bf095f9becf5efef645@syzkaller.appspotmail.com Reported-by: syzbot+31c16aa4202dace3812e@syzkaller.appspotmail.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Biggers Signed-off-by: Jakub Kicinski --- net/llc/llc_s_ac.c | 12 +++++++++--- net/llc/llc_sap.c | 23 ++++++++--------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c index a94bd56bcac6..7ae4cc684d3a 100644 --- a/net/llc/llc_s_ac.c +++ b/net/llc/llc_s_ac.c @@ -58,8 +58,10 @@ int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb) ev->daddr.lsap, LLC_PDU_CMD); llc_pdu_init_as_ui_cmd(skb); rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); - if (likely(!rc)) + if (likely(!rc)) { + skb_get(skb); rc = dev_queue_xmit(skb); + } return rc; } @@ -81,8 +83,10 @@ int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb) ev->daddr.lsap, LLC_PDU_CMD); llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0); rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); - if (likely(!rc)) + if (likely(!rc)) { + skb_get(skb); rc = dev_queue_xmit(skb); + } return rc; } @@ -135,8 +139,10 @@ int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb) ev->daddr.lsap, LLC_PDU_CMD); llc_pdu_init_as_test_cmd(skb); rc = llc_mac_hdr_init(skb, ev->saddr.mac, ev->daddr.mac); - if (likely(!rc)) + if (likely(!rc)) { + skb_get(skb); rc = dev_queue_xmit(skb); + } return rc; } diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index a7f7b8ff4729..be419062e19a 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c @@ -197,29 +197,22 @@ static int llc_sap_next_state(struct llc_sap *sap, struct sk_buff *skb) * After executing actions of the event, upper layer will be indicated * if needed(on receiving an UI frame). sk can be null for the * datalink_proto case. + * + * This function always consumes a reference to the skb. */ static void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb) { struct llc_sap_state_ev *ev = llc_sap_ev(skb); - /* - * We have to hold the skb, because llc_sap_next_state - * will kfree it in the sending path and we need to - * look at the skb->cb, where we encode llc_sap_state_ev. - */ - skb_get(skb); ev->ind_cfm_flag = 0; llc_sap_next_state(sap, skb); - if (ev->ind_cfm_flag == LLC_IND) { - if (skb->sk->sk_state == TCP_LISTEN) - kfree_skb(skb); - else { - llc_save_primitive(skb->sk, skb, ev->prim); - /* queue skb to the user. */ - if (sock_queue_rcv_skb(skb->sk, skb)) - kfree_skb(skb); - } + if (ev->ind_cfm_flag == LLC_IND && skb->sk->sk_state != TCP_LISTEN) { + llc_save_primitive(skb->sk, skb, ev->prim); + + /* queue skb to the user. */ + if (sock_queue_rcv_skb(skb->sk, skb) == 0) + return; } kfree_skb(skb); } -- GitLab From b74555de21acd791f12c4a1aeaf653dd7ac21133 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 6 Oct 2019 14:24:25 -0700 Subject: [PATCH 117/993] llc: fix sk_buff leak in llc_conn_service() syzbot reported: BUG: memory leak unreferenced object 0xffff88811eb3de00 (size 224): comm "syz-executor559", pid 7315, jiffies 4294943019 (age 10.300s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 a0 38 24 81 88 ff ff 00 c0 f2 15 81 88 ff ff ..8$............ backtrace: [<000000008d1c66a1>] kmemleak_alloc_recursive include/linux/kmemleak.h:55 [inline] [<000000008d1c66a1>] slab_post_alloc_hook mm/slab.h:439 [inline] [<000000008d1c66a1>] slab_alloc_node mm/slab.c:3269 [inline] [<000000008d1c66a1>] kmem_cache_alloc_node+0x153/0x2a0 mm/slab.c:3579 [<00000000447d9496>] __alloc_skb+0x6e/0x210 net/core/skbuff.c:198 [<000000000cdbf82f>] alloc_skb include/linux/skbuff.h:1058 [inline] [<000000000cdbf82f>] llc_alloc_frame+0x66/0x110 net/llc/llc_sap.c:54 [<000000002418b52e>] llc_conn_ac_send_sabme_cmd_p_set_x+0x2f/0x140 net/llc/llc_c_ac.c:777 [<000000001372ae17>] llc_exec_conn_trans_actions net/llc/llc_conn.c:475 [inline] [<000000001372ae17>] llc_conn_service net/llc/llc_conn.c:400 [inline] [<000000001372ae17>] llc_conn_state_process+0x1ac/0x640 net/llc/llc_conn.c:75 [<00000000f27e53c1>] llc_establish_connection+0x110/0x170 net/llc/llc_if.c:109 [<00000000291b2ca0>] llc_ui_connect+0x10e/0x370 net/llc/af_llc.c:477 [<000000000f9c740b>] __sys_connect+0x11d/0x170 net/socket.c:1840 [...] The bug is that most callers of llc_conn_send_pdu() assume it consumes a reference to the skb, when actually due to commit b85ab56c3f81 ("llc: properly handle dev_queue_xmit() return value") it doesn't. Revert most of that commit, and instead make the few places that need llc_conn_send_pdu() to *not* consume a reference call skb_get() before. Fixes: b85ab56c3f81 ("llc: properly handle dev_queue_xmit() return value") Reported-by: syzbot+6b825a6494a04cc0e3f7@syzkaller.appspotmail.com Signed-off-by: Eric Biggers Signed-off-by: Jakub Kicinski --- include/net/llc_conn.h | 2 +- net/llc/llc_c_ac.c | 8 ++++++-- net/llc/llc_conn.c | 32 +++++++++----------------------- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h index df528a623548..ea985aa7a6c5 100644 --- a/include/net/llc_conn.h +++ b/include/net/llc_conn.h @@ -104,7 +104,7 @@ void llc_sk_reset(struct sock *sk); /* Access to a connection */ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb); -int llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb); +void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb); void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb); void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit); void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit); diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c index 4d78375f9872..647c0554d04c 100644 --- a/net/llc/llc_c_ac.c +++ b/net/llc/llc_c_ac.c @@ -372,6 +372,7 @@ int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR); rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); if (likely(!rc)) { + skb_get(skb); llc_conn_send_pdu(sk, skb); llc_conn_ac_inc_vs_by_1(sk, skb); } @@ -389,7 +390,8 @@ static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb) llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR); rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); if (likely(!rc)) { - rc = llc_conn_send_pdu(sk, skb); + skb_get(skb); + llc_conn_send_pdu(sk, skb); llc_conn_ac_inc_vs_by_1(sk, skb); } return rc; @@ -406,6 +408,7 @@ int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR); rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); if (likely(!rc)) { + skb_get(skb); llc_conn_send_pdu(sk, skb); llc_conn_ac_inc_vs_by_1(sk, skb); } @@ -916,7 +919,8 @@ static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk, llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR); rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac); if (likely(!rc)) { - rc = llc_conn_send_pdu(sk, skb); + skb_get(skb); + llc_conn_send_pdu(sk, skb); llc_conn_ac_inc_vs_by_1(sk, skb); } return rc; diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 4ff89cb7c86f..ed2aca12460c 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -30,7 +30,7 @@ #endif static int llc_find_offset(int state, int ev_type); -static int llc_conn_send_pdus(struct sock *sk, struct sk_buff *skb); +static void llc_conn_send_pdus(struct sock *sk); static int llc_conn_service(struct sock *sk, struct sk_buff *skb); static int llc_exec_conn_trans_actions(struct sock *sk, struct llc_conn_state_trans *trans, @@ -193,11 +193,11 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) return rc; } -int llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb) +void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb) { /* queue PDU to send to MAC layer */ skb_queue_tail(&sk->sk_write_queue, skb); - return llc_conn_send_pdus(sk, skb); + llc_conn_send_pdus(sk); } /** @@ -255,7 +255,7 @@ void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit) if (howmany_resend > 0) llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO; /* any PDUs to re-send are queued up; start sending to MAC */ - llc_conn_send_pdus(sk, NULL); + llc_conn_send_pdus(sk); out:; } @@ -296,7 +296,7 @@ void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit) if (howmany_resend > 0) llc->vS = (llc->vS + 1) % LLC_2_SEQ_NBR_MODULO; /* any PDUs to re-send are queued up; start sending to MAC */ - llc_conn_send_pdus(sk, NULL); + llc_conn_send_pdus(sk); out:; } @@ -340,16 +340,12 @@ int llc_conn_remove_acked_pdus(struct sock *sk, u8 nr, u16 *how_many_unacked) /** * llc_conn_send_pdus - Sends queued PDUs * @sk: active connection - * @hold_skb: the skb held by caller, or NULL if does not care * - * Sends queued pdus to MAC layer for transmission. When @hold_skb is - * NULL, always return 0. Otherwise, return 0 if @hold_skb is sent - * successfully, or 1 for failure. + * Sends queued pdus to MAC layer for transmission. */ -static int llc_conn_send_pdus(struct sock *sk, struct sk_buff *hold_skb) +static void llc_conn_send_pdus(struct sock *sk) { struct sk_buff *skb; - int ret = 0; while ((skb = skb_dequeue(&sk->sk_write_queue)) != NULL) { struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); @@ -361,20 +357,10 @@ static int llc_conn_send_pdus(struct sock *sk, struct sk_buff *hold_skb) skb_queue_tail(&llc_sk(sk)->pdu_unack_q, skb); if (!skb2) break; - dev_queue_xmit(skb2); - } else { - bool is_target = skb == hold_skb; - int rc; - - if (is_target) - skb_get(skb); - rc = dev_queue_xmit(skb); - if (is_target) - ret = rc; + skb = skb2; } + dev_queue_xmit(skb); } - - return ret; } /** -- GitLab From fc8d5db10cbe1338a52ebc74e7feab9276721774 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 6 Oct 2019 14:24:26 -0700 Subject: [PATCH 118/993] llc: fix another potential sk_buff leak in llc_ui_sendmsg() All callers of llc_conn_state_process() except llc_build_and_send_pkt() (via llc_ui_sendmsg() -> llc_ui_send_data()) assume that it always consumes a reference to the skb. Fix this caller to do the same. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Biggers Signed-off-by: Jakub Kicinski --- net/llc/af_llc.c | 34 ++++++++++++++++++++-------------- net/llc/llc_conn.c | 2 ++ net/llc/llc_if.c | 12 ++++++++---- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 2017b7d780f5..c74f44dfaa22 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -113,22 +113,26 @@ static inline u8 llc_ui_header_len(struct sock *sk, struct sockaddr_llc *addr) * * Send data via reliable llc2 connection. * Returns 0 upon success, non-zero if action did not succeed. + * + * This function always consumes a reference to the skb. */ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, int noblock) { struct llc_sock* llc = llc_sk(sk); - int rc = 0; if (unlikely(llc_data_accept_state(llc->state) || llc->remote_busy_flag || llc->p_flag)) { long timeout = sock_sndtimeo(sk, noblock); + int rc; rc = llc_ui_wait_for_busy_core(sk, timeout); + if (rc) { + kfree_skb(skb); + return rc; + } } - if (unlikely(!rc)) - rc = llc_build_and_send_pkt(sk, skb); - return rc; + return llc_build_and_send_pkt(sk, skb); } static void llc_ui_sk_init(struct socket *sock, struct sock *sk) @@ -899,7 +903,7 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) DECLARE_SOCKADDR(struct sockaddr_llc *, addr, msg->msg_name); int flags = msg->msg_flags; int noblock = flags & MSG_DONTWAIT; - struct sk_buff *skb; + struct sk_buff *skb = NULL; size_t size = 0; int rc = -EINVAL, copied = 0, hdrlen; @@ -908,10 +912,10 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) lock_sock(sk); if (addr) { if (msg->msg_namelen < sizeof(*addr)) - goto release; + goto out; } else { if (llc_ui_addr_null(&llc->addr)) - goto release; + goto out; addr = &llc->addr; } /* must bind connection to sap if user hasn't done it. */ @@ -919,7 +923,7 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) /* bind to sap with null dev, exclusive. */ rc = llc_ui_autobind(sock, addr); if (rc) - goto release; + goto out; } hdrlen = llc->dev->hard_header_len + llc_ui_header_len(sk, addr); size = hdrlen + len; @@ -928,12 +932,12 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) copied = size - hdrlen; rc = -EINVAL; if (copied < 0) - goto release; + goto out; release_sock(sk); skb = sock_alloc_send_skb(sk, size, noblock, &rc); lock_sock(sk); if (!skb) - goto release; + goto out; skb->dev = llc->dev; skb->protocol = llc_proto_type(addr->sllc_arphrd); skb_reserve(skb, hdrlen); @@ -943,29 +947,31 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) { llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_mac, addr->sllc_sap); + skb = NULL; goto out; } if (addr->sllc_test) { llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_mac, addr->sllc_sap); + skb = NULL; goto out; } if (addr->sllc_xid) { llc_build_and_send_xid_pkt(llc->sap, skb, addr->sllc_mac, addr->sllc_sap); + skb = NULL; goto out; } rc = -ENOPROTOOPT; if (!(sk->sk_type == SOCK_STREAM && !addr->sllc_ua)) goto out; rc = llc_ui_send_data(sk, skb, noblock); + skb = NULL; out: - if (rc) { - kfree_skb(skb); -release: + kfree_skb(skb); + if (rc) dprintk("%s: failed sending from %02X to %02X: %d\n", __func__, llc->laddr.lsap, llc->daddr.lsap, rc); - } release_sock(sk); return rc ? : copied; } diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index ed2aca12460c..0b0c6f12153b 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -55,6 +55,8 @@ int sysctl_llc2_busy_timeout = LLC2_BUSY_TIME * HZ; * (executing it's actions and changing state), upper layer will be * indicated or confirmed, if needed. Returns 0 for success, 1 for * failure. The socket lock has to be held before calling this function. + * + * This function always consumes a reference to the skb. */ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) { diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c index 8db03c2d5440..ad6547736c21 100644 --- a/net/llc/llc_if.c +++ b/net/llc/llc_if.c @@ -38,6 +38,8 @@ * closed and -EBUSY when sending data is not permitted in this state or * LLC has send an I pdu with p bit set to 1 and is waiting for it's * response. + * + * This function always consumes a reference to the skb. */ int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb) { @@ -46,20 +48,22 @@ int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb) struct llc_sock *llc = llc_sk(sk); if (unlikely(llc->state == LLC_CONN_STATE_ADM)) - goto out; + goto out_free; rc = -EBUSY; if (unlikely(llc_data_accept_state(llc->state) || /* data_conn_refuse */ llc->p_flag)) { llc->failed_data_req = 1; - goto out; + goto out_free; } ev = llc_conn_ev(skb); ev->type = LLC_CONN_EV_TYPE_PRIM; ev->prim = LLC_DATA_PRIM; ev->prim_type = LLC_PRIM_TYPE_REQ; skb->dev = llc->dev; - rc = llc_conn_state_process(sk, skb); -out: + return llc_conn_state_process(sk, skb); + +out_free: + kfree_skb(skb); return rc; } -- GitLab From 36453c852816f19947ca482a595dffdd2efa4965 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 6 Oct 2019 14:24:27 -0700 Subject: [PATCH 119/993] llc: fix sk_buff refcounting in llc_conn_state_process() If llc_conn_state_process() sees that llc_conn_service() put the skb on a list, it will drop one fewer references to it. This is wrong because the current behavior is that llc_conn_service() never consumes a reference to the skb. The code also makes the number of skb references being dropped conditional on which of ind_prim and cfm_prim are nonzero, yet neither of these affects how many references are *acquired*. So there is extra code that tries to fix this up by sometimes taking another reference. Remove the unnecessary/broken refcounting logic and instead just add an skb_get() before the only two places where an extra reference is actually consumed. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Biggers Signed-off-by: Jakub Kicinski --- net/llc/llc_conn.c | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 0b0c6f12153b..a79b739eb223 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -64,12 +64,6 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) struct llc_sock *llc = llc_sk(skb->sk); struct llc_conn_state_ev *ev = llc_conn_ev(skb); - /* - * We have to hold the skb, because llc_conn_service will kfree it in - * the sending path and we need to look at the skb->cb, where we encode - * llc_conn_state_ev. - */ - skb_get(skb); ev->ind_prim = ev->cfm_prim = 0; /* * Send event to state machine @@ -77,21 +71,12 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) rc = llc_conn_service(skb->sk, skb); if (unlikely(rc != 0)) { printk(KERN_ERR "%s: llc_conn_service failed\n", __func__); - goto out_kfree_skb; - } - - if (unlikely(!ev->ind_prim && !ev->cfm_prim)) { - /* indicate or confirm not required */ - if (!skb->next) - goto out_kfree_skb; goto out_skb_put; } - if (unlikely(ev->ind_prim && ev->cfm_prim)) /* Paranoia */ - skb_get(skb); - switch (ev->ind_prim) { case LLC_DATA_PRIM: + skb_get(skb); llc_save_primitive(sk, skb, LLC_DATA_PRIM); if (unlikely(sock_queue_rcv_skb(sk, skb))) { /* @@ -108,6 +93,7 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) * skb->sk pointing to the newly created struct sock in * llc_conn_handler. -acme */ + skb_get(skb); skb_queue_tail(&sk->sk_receive_queue, skb); sk->sk_state_change(sk); break; @@ -123,7 +109,6 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) sk->sk_state_change(sk); } } - kfree_skb(skb); sock_put(sk); break; case LLC_RESET_PRIM: @@ -132,14 +117,11 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) * RESET is not being notified to upper layers for now */ printk(KERN_INFO "%s: received a reset ind!\n", __func__); - kfree_skb(skb); break; default: - if (ev->ind_prim) { + if (ev->ind_prim) printk(KERN_INFO "%s: received unknown %d prim!\n", __func__, ev->ind_prim); - kfree_skb(skb); - } /* No indication */ break; } @@ -181,15 +163,12 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb) printk(KERN_INFO "%s: received a reset conf!\n", __func__); break; default: - if (ev->cfm_prim) { + if (ev->cfm_prim) printk(KERN_INFO "%s: received unknown %d prim!\n", __func__, ev->cfm_prim); - break; - } - goto out_skb_put; /* No confirmation */ + /* No confirmation */ + break; } -out_kfree_skb: - kfree_skb(skb); out_skb_put: kfree_skb(skb); return rc; -- GitLab From fd418b01fe26c2430b1091675cceb3ab2b52e1e0 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Tue, 8 Oct 2019 15:10:44 +0200 Subject: [PATCH 120/993] selftests/bpf: Set rp_filter in test_flow_dissector Many distributions enable rp_filter. However, the flow dissector test generates packets that have 1.1.1.1 set as (inner) source address without this address being reachable. This causes the selftest to fail. The selftests should not assume a particular initial configuration. Switch off rp_filter. Fixes: 50b3ed57dee9 ("selftests/bpf: test bpf flow dissection") Signed-off-by: Jiri Benc Signed-off-by: Daniel Borkmann Acked-by: Petar Penkov Link: https://lore.kernel.org/bpf/513a298f53e99561d2f70b2e60e2858ea6cda754.1570539863.git.jbenc@redhat.com --- tools/testing/selftests/bpf/test_flow_dissector.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/testing/selftests/bpf/test_flow_dissector.sh b/tools/testing/selftests/bpf/test_flow_dissector.sh index d23d4da66b83..e2d06191bd35 100755 --- a/tools/testing/selftests/bpf/test_flow_dissector.sh +++ b/tools/testing/selftests/bpf/test_flow_dissector.sh @@ -63,6 +63,9 @@ fi # Setup tc qdisc add dev lo ingress +echo 0 > /proc/sys/net/ipv4/conf/default/rp_filter +echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter +echo 0 > /proc/sys/net/ipv4/conf/lo/rp_filter echo "Testing IPv4..." # Drops all IP/UDP packets coming from port 9 -- GitLab From 106c35dda32f8b63f88cad7433f1b8bb0056958a Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Tue, 8 Oct 2019 15:10:45 +0200 Subject: [PATCH 121/993] selftests/bpf: More compatible nc options in test_lwt_ip_encap Out of the three nc implementations widely in use, at least two (BSD netcat and nmap-ncat) do not support -l combined with -s. Modify the nc invocation to be accepted by all of them. Fixes: 17a90a788473 ("selftests/bpf: test that GSO works in lwt_ip_encap") Signed-off-by: Jiri Benc Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/9f177682c387f3f943bb64d849e6c6774df3c5b4.1570539863.git.jbenc@redhat.com --- tools/testing/selftests/bpf/test_lwt_ip_encap.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/bpf/test_lwt_ip_encap.sh b/tools/testing/selftests/bpf/test_lwt_ip_encap.sh index acf7a74f97cd..59ea56945e6c 100755 --- a/tools/testing/selftests/bpf/test_lwt_ip_encap.sh +++ b/tools/testing/selftests/bpf/test_lwt_ip_encap.sh @@ -314,15 +314,15 @@ test_gso() command -v nc >/dev/null 2>&1 || \ { echo >&2 "nc is not available: skipping TSO tests"; return; } - # listen on IPv*_DST, capture TCP into $TMPFILE + # listen on port 9000, capture TCP into $TMPFILE if [ "${PROTO}" == "IPv4" ] ; then IP_DST=${IPv4_DST} ip netns exec ${NS3} bash -c \ - "nc -4 -l -s ${IPv4_DST} -p 9000 > ${TMPFILE} &" + "nc -4 -l -p 9000 > ${TMPFILE} &" elif [ "${PROTO}" == "IPv6" ] ; then IP_DST=${IPv6_DST} ip netns exec ${NS3} bash -c \ - "nc -6 -l -s ${IPv6_DST} -p 9000 > ${TMPFILE} &" + "nc -6 -l -p 9000 > ${TMPFILE} &" RET=$? else echo " test_gso: unknown PROTO: ${PROTO}" -- GitLab From 0041412694eca70387aee4076254fbed8222700a Mon Sep 17 00:00:00 2001 From: Alex Vesker Date: Mon, 7 Oct 2019 16:13:25 +0300 Subject: [PATCH 122/993] net/mlx5: DR, Allow insertion of duplicate rules Duplicate rules were not allowed to be configured with SW steering. This restriction caused failures with the replace rule logic done by upper layers. This fix allows for multiple rules with the same match values, in such case the first inserted rules will match. Fixes: 41d07074154c ("net/mlx5: DR, Expose steering rule functionality") Signed-off-by: Alex Vesker Signed-off-by: Tariq Toukan Signed-off-by: Jakub Kicinski --- .../net/ethernet/mellanox/mlx5/core/steering/dr_rule.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c index 4187f2b112b8..e8b656075c6f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c @@ -788,12 +788,10 @@ dr_rule_handle_ste_branch(struct mlx5dr_rule *rule, * it means that all the previous stes are the same, * if so, this rule is duplicated. */ - if (mlx5dr_ste_is_last_in_rule(nic_matcher, - matched_ste->ste_chain_location)) { - mlx5dr_info(dmn, "Duplicate rule inserted, aborting!!\n"); - return NULL; - } - return matched_ste; + if (!mlx5dr_ste_is_last_in_rule(nic_matcher, ste_location)) + return matched_ste; + + mlx5dr_dbg(dmn, "Duplicate rule inserted\n"); } if (!skip_rehash && dr_rule_need_enlarge_hash(cur_htbl, dmn, nic_dmn)) { -- GitLab From 6f96c3c6904c26cea9ca2726d5d8a9b0b8205b3c Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Mon, 7 Oct 2019 13:26:28 -0700 Subject: [PATCH 123/993] net_sched: fix backward compatibility for TCA_KIND Marcelo noticed a backward compatibility issue of TCA_KIND after we move from NLA_STRING to NLA_NUL_STRING, so it is probably too late to change it. Instead, to make everyone happy, we can just insert a NUL to terminate the string with nla_strlcpy() like we do for TC actions. Fixes: 62794fc4fbf5 ("net_sched: add max len check for TCA_KIND") Reported-by: Marcelo Ricardo Leitner Cc: Jamal Hadi Salim Cc: Jiri Pirko Signed-off-by: Cong Wang Reviewed-by: Marcelo Ricardo Leitner Signed-off-by: Jakub Kicinski --- net/sched/cls_api.c | 36 +++++++++++++++++++++++++++++++++--- net/sched/sch_api.c | 3 +-- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 64584a1df425..8717c0b26c90 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -162,11 +162,22 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp) return TC_H_MAJ(first); } +static bool tcf_proto_check_kind(struct nlattr *kind, char *name) +{ + if (kind) + return nla_strlcpy(name, kind, IFNAMSIZ) >= IFNAMSIZ; + memset(name, 0, IFNAMSIZ); + return false; +} + static bool tcf_proto_is_unlocked(const char *kind) { const struct tcf_proto_ops *ops; bool ret; + if (strlen(kind) == 0) + return false; + ops = tcf_proto_lookup_ops(kind, false, NULL); /* On error return false to take rtnl lock. Proto lookup/create * functions will perform lookup again and properly handle errors. @@ -1843,6 +1854,7 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n, { struct net *net = sock_net(skb->sk); struct nlattr *tca[TCA_MAX + 1]; + char name[IFNAMSIZ]; struct tcmsg *t; u32 protocol; u32 prio; @@ -1899,13 +1911,19 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n, if (err) return err; + if (tcf_proto_check_kind(tca[TCA_KIND], name)) { + NL_SET_ERR_MSG(extack, "Specified TC filter name too long"); + err = -EINVAL; + goto errout; + } + /* Take rtnl mutex if rtnl_held was set to true on previous iteration, * block is shared (no qdisc found), qdisc is not unlocked, classifier * type is not specified, classifier is not unlocked. */ if (rtnl_held || (q && !(q->ops->cl_ops->flags & QDISC_CLASS_OPS_DOIT_UNLOCKED)) || - !tca[TCA_KIND] || !tcf_proto_is_unlocked(nla_data(tca[TCA_KIND]))) { + !tcf_proto_is_unlocked(name)) { rtnl_held = true; rtnl_lock(); } @@ -2063,6 +2081,7 @@ static int tc_del_tfilter(struct sk_buff *skb, struct nlmsghdr *n, { struct net *net = sock_net(skb->sk); struct nlattr *tca[TCA_MAX + 1]; + char name[IFNAMSIZ]; struct tcmsg *t; u32 protocol; u32 prio; @@ -2102,13 +2121,18 @@ static int tc_del_tfilter(struct sk_buff *skb, struct nlmsghdr *n, if (err) return err; + if (tcf_proto_check_kind(tca[TCA_KIND], name)) { + NL_SET_ERR_MSG(extack, "Specified TC filter name too long"); + err = -EINVAL; + goto errout; + } /* Take rtnl mutex if flushing whole chain, block is shared (no qdisc * found), qdisc is not unlocked, classifier type is not specified, * classifier is not unlocked. */ if (!prio || (q && !(q->ops->cl_ops->flags & QDISC_CLASS_OPS_DOIT_UNLOCKED)) || - !tca[TCA_KIND] || !tcf_proto_is_unlocked(nla_data(tca[TCA_KIND]))) { + !tcf_proto_is_unlocked(name)) { rtnl_held = true; rtnl_lock(); } @@ -2216,6 +2240,7 @@ static int tc_get_tfilter(struct sk_buff *skb, struct nlmsghdr *n, { struct net *net = sock_net(skb->sk); struct nlattr *tca[TCA_MAX + 1]; + char name[IFNAMSIZ]; struct tcmsg *t; u32 protocol; u32 prio; @@ -2252,12 +2277,17 @@ static int tc_get_tfilter(struct sk_buff *skb, struct nlmsghdr *n, if (err) return err; + if (tcf_proto_check_kind(tca[TCA_KIND], name)) { + NL_SET_ERR_MSG(extack, "Specified TC filter name too long"); + err = -EINVAL; + goto errout; + } /* Take rtnl mutex if block is shared (no qdisc found), qdisc is not * unlocked, classifier type is not specified, classifier is not * unlocked. */ if ((q && !(q->ops->cl_ops->flags & QDISC_CLASS_OPS_DOIT_UNLOCKED)) || - !tca[TCA_KIND] || !tcf_proto_is_unlocked(nla_data(tca[TCA_KIND]))) { + !tcf_proto_is_unlocked(name)) { rtnl_held = true; rtnl_lock(); } diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 81d58b280612..1047825d9f48 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -1390,8 +1390,7 @@ check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w) } const struct nla_policy rtm_tca_policy[TCA_MAX + 1] = { - [TCA_KIND] = { .type = NLA_NUL_STRING, - .len = IFNAMSIZ - 1 }, + [TCA_KIND] = { .type = NLA_STRING }, [TCA_RATE] = { .type = NLA_BINARY, .len = sizeof(struct tc_estimator) }, [TCA_STAB] = { .type = NLA_NESTED }, -- GitLab From 4b793feccae3b06764268377a4030eb774ed924e Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Mon, 7 Oct 2019 13:26:29 -0700 Subject: [PATCH 124/993] net_sched: fix backward compatibility for TCA_ACT_KIND For TCA_ACT_KIND, we have to keep the backward compatibility too, and rely on nla_strlcpy() to check and terminate the string with a NUL. Note for TC actions, nla_strcmp() is already used to compare kind strings, so we don't need to fix other places. Fixes: 199ce850ce11 ("net_sched: add policy validation for action attributes") Reported-by: Marcelo Ricardo Leitner Cc: Jamal Hadi Salim Cc: Jiri Pirko Signed-off-by: Cong Wang Reviewed-by: Marcelo Ricardo Leitner Signed-off-by: Jakub Kicinski --- net/sched/act_api.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 2558f00f6b3e..4e7429c6f864 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -832,8 +832,7 @@ static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb) } static const struct nla_policy tcf_action_policy[TCA_ACT_MAX + 1] = { - [TCA_ACT_KIND] = { .type = NLA_NUL_STRING, - .len = IFNAMSIZ - 1 }, + [TCA_ACT_KIND] = { .type = NLA_STRING }, [TCA_ACT_INDEX] = { .type = NLA_U32 }, [TCA_ACT_COOKIE] = { .type = NLA_BINARY, .len = TC_COOKIE_MAX_SIZE }, @@ -865,8 +864,10 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp, NL_SET_ERR_MSG(extack, "TC action kind must be specified"); goto err_out; } - nla_strlcpy(act_name, kind, IFNAMSIZ); - + if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) { + NL_SET_ERR_MSG(extack, "TC action name too long"); + goto err_out; + } if (tb[TCA_ACT_COOKIE]) { cookie = nla_memdup_cookie(tb); if (!cookie) { -- GitLab From bcf059578980526d6067a2b1b0cd8344b58bf2d5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 8 Oct 2019 16:40:33 -0700 Subject: [PATCH 125/993] Input: soc_button_array - partial revert of support for newer surface devices Commit c394159310d0 ("Input: soc_button_array - add support for newer surface devices") not only added support for the MSHW0040 ACPI HID, but for some reason it also makes changes to the error handling of the soc_button_lookup_gpio() call in soc_button_device_create(). Note ideally this seamingly unrelated change would have been made in a separate commit, with a message explaining the what and why of this change. I guess this change may have been added to deal with -EPROBE_DEFER errors, but in case of the existing support for PNP0C40 devices, treating -EPROBE_DEFER as any other error is deliberate, see the comment this commit adds for why. The actual returning of -EPROBE_DEFER to the caller of soc_button_probe() introduced by the new error checking causes a serious regression: On devices with so called virtual GPIOs soc_button_lookup_gpio() will always return -EPROBE_DEFER for these fake GPIOs, when this happens during the second call of soc_button_device_create() we already have successfully registered our first child. This causes the kernel to think we are making progress with probing things even though we unregister the child before again before we return the -EPROBE_DEFER. Since we are making progress the kernel will retry deferred-probes again immediately ending up stuck in a loop with the following showing in dmesg: [ 124.022697] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6537 [ 124.040764] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6538 [ 124.056967] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6539 [ 124.072143] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6540 [ 124.092373] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6541 [ 124.108065] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6542 [ 124.128483] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6543 [ 124.147141] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6544 [ 124.165070] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6545 [ 124.179775] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6546 [ 124.202726] input: gpio-keys as /devices/platform/INTCFD9:00/gpio-keys.0.auto/input/input6547 And 1 CPU core being stuck at 100% and udev hanging since it is waiting for the modprobe of soc_button_array to return. This patch reverts the soc_button_lookup_gpio() error handling changes, fixing this regression. Fixes: c394159310d0 ("Input: soc_button_array - add support for newer surface devices") BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=205031 Signed-off-by: Hans de Goede Tested-by: Maximilian Luz Acked-by: Maximilian Luz Link: https://lore.kernel.org/r/20191005105551.353273-1-hdegoede@redhat.com Signed-off-by: Dmitry Torokhov --- drivers/input/misc/soc_button_array.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c index 97e3639e99d0..08520b3a18b8 100644 --- a/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c @@ -92,11 +92,18 @@ soc_button_device_create(struct platform_device *pdev, continue; gpio = soc_button_lookup_gpio(&pdev->dev, info->acpi_index); - if (gpio < 0 && gpio != -ENOENT) { - error = gpio; - goto err_free_mem; - } else if (!gpio_is_valid(gpio)) { - /* Skip GPIO if not present */ + if (!gpio_is_valid(gpio)) { + /* + * Skip GPIO if not present. Note we deliberately + * ignore -EPROBE_DEFER errors here. On some devices + * Intel is using so called virtual GPIOs which are not + * GPIOs at all but some way for AML code to check some + * random status bits without need a custom opregion. + * In some cases the resources table we parse points to + * such a virtual GPIO, since these are not real GPIOs + * we do not have a driver for these so they will never + * show up, therefore we ignore -EPROBE_DEFER. + */ continue; } -- GitLab From 6af3aa57a0984e061f61308fe181a9a12359fecc Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 7 Oct 2019 18:40:59 +0200 Subject: [PATCH 126/993] NFC: pn533: fix use-after-free and memleaks The driver would fail to deregister and its class device and free related resources on late probe errors. Reported-by: syzbot+cb035c75c03dbe34b796@syzkaller.appspotmail.com Fixes: 32ecc75ded72 ("NFC: pn533: change order operations in dev registation") Signed-off-by: Johan Hovold Signed-off-by: Jakub Kicinski --- drivers/nfc/pn533/usb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c index c5289eaf17ee..e897e4d768ef 100644 --- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -547,18 +547,25 @@ static int pn533_usb_probe(struct usb_interface *interface, rc = pn533_finalize_setup(priv); if (rc) - goto error; + goto err_deregister; usb_set_intfdata(interface, phy); return 0; +err_deregister: + pn533_unregister_device(phy->priv); error: + usb_kill_urb(phy->in_urb); + usb_kill_urb(phy->out_urb); + usb_kill_urb(phy->ack_urb); + usb_free_urb(phy->in_urb); usb_free_urb(phy->out_urb); usb_free_urb(phy->ack_urb); usb_put_dev(phy->udev); kfree(in_buf); + kfree(phy->ack_buffer); return rc; } -- GitLab From b82316d25522e8ee748b8cc9d8aadeb3c135c6fe Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 8 Oct 2019 08:35:51 -0700 Subject: [PATCH 127/993] Doc: networking/device_drivers/pensando: fix ionic.rst warnings Fix documentation build warnings for Pensando ionic: Documentation/networking/device_drivers/pensando/ionic.rst:39: WARNING: Unexpected indentation. Documentation/networking/device_drivers/pensando/ionic.rst:43: WARNING: Unexpected indentation. Fixes: df69ba43217d ("ionic: Add basic framework for IONIC Network device driver") Signed-off-by: Randy Dunlap Acked-by: Shannon Nelson Signed-off-by: Jakub Kicinski --- Documentation/networking/device_drivers/pensando/ionic.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/networking/device_drivers/pensando/ionic.rst b/Documentation/networking/device_drivers/pensando/ionic.rst index 67b6839d516b..13935896bee6 100644 --- a/Documentation/networking/device_drivers/pensando/ionic.rst +++ b/Documentation/networking/device_drivers/pensando/ionic.rst @@ -36,8 +36,10 @@ Support ======= For general Linux networking support, please use the netdev mailing list, which is monitored by Pensando personnel:: + netdev@vger.kernel.org For more specific support needs, please use the Pensando driver support email:: - drivers@pensando.io + + drivers@pensando.io -- GitLab From 4123f637a5129470ff9d3cb00a5a4e213f2e15cc Mon Sep 17 00:00:00 2001 From: Haishuang Yan Date: Tue, 8 Oct 2019 17:56:03 +0800 Subject: [PATCH 128/993] ip6erspan: remove the incorrect mtu limit for ip6erspan ip6erspan driver calls ether_setup(), after commit 61e84623ace3 ("net: centralize net_device min/max MTU checking"), the range of mtu is [min_mtu, max_mtu], which is [68, 1500] by default. It causes the dev mtu of the erspan device to not be greater than 1500, this limit value is not correct for ip6erspan tap device. Fixes: 61e84623ace3 ("net: centralize net_device min/max MTU checking") Signed-off-by: Haishuang Yan Acked-by: William Tu Signed-off-by: Jakub Kicinski --- net/ipv6/ip6_gre.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index d5779d6a6065..787d9f2a6e99 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -2192,6 +2192,7 @@ static void ip6erspan_tap_setup(struct net_device *dev) { ether_setup(dev); + dev->max_mtu = 0; dev->netdev_ops = &ip6erspan_netdev_ops; dev->needs_free_netdev = true; dev->priv_destructor = ip6gre_dev_free; -- GitLab From 187c195ac57fbb84a84ca07e93c6f16fd8edfbe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Tue, 8 Oct 2019 16:59:44 +0200 Subject: [PATCH 129/993] arm64: dts: armada-3720-turris-mox: convert usb-phy to phy-supply MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update Turris Mox device tree to use the phy-supply property of the generic PHY framework instead of the legacy usb-phy property. This is needed since it caused a regression on Turris Mox since "usb: host: xhci-plat: Prevent an abnormally restrictive PHY init skipping". Signed-off-by: Marek Behún Fixes: eb6c2eb6c7fb ("usb: host: xhci-plat: Prevent an abnormally restrictive PHY init skipping") Reviewed-by: Miquel Raynal Cc: Andrew Lunn Signed-off-by: Gregory CLEMENT --- .../boot/dts/marvell/armada-3720-turris-mox.dts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts index d105986c6be1..5f350cc71a2f 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts @@ -60,11 +60,6 @@ gpio = <&gpiosb 0 GPIO_ACTIVE_HIGH>; }; - usb3_phy: usb3-phy { - compatible = "usb-nop-xceiv"; - vcc-supply = <&exp_usb3_vbus>; - }; - vsdc_reg: vsdc-reg { compatible = "regulator-gpio"; regulator-name = "vsdc"; @@ -255,10 +250,16 @@ status = "okay"; }; +&comphy2 { + connector { + compatible = "usb-a-connector"; + phy-supply = <&exp_usb3_vbus>; + }; +}; + &usb3 { status = "okay"; phys = <&comphy2 0>; - usb-phy = <&usb3_phy>; }; &mdio { -- GitLab From b835d6953009dc350d61402a854b5a7178d8c615 Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Tue, 1 Oct 2019 10:51:38 -0500 Subject: [PATCH 130/993] pinctrl: armada-37xx: swap polarity on LED group The configuration registers for the LED group have inverted polarity, which puts the GPIO into open-drain state when used in GPIO mode. Switch to '0' for GPIO and '1' for LED modes. Fixes: 87466ccd9401 ("pinctrl: armada-37xx: Add pin controller support for Armada 37xx") Signed-off-by: Patrick Williams Cc: Link: https://lore.kernel.org/r/20191001155154.99710-1-alpawi@amazon.com Signed-off-by: Linus Walleij --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 34c1fee52cbe..f2f5fcd9a237 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -183,10 +183,10 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = { PIN_GRP_EXTRA("uart2", 9, 2, BIT(1) | BIT(13) | BIT(14) | BIT(19), BIT(1) | BIT(13) | BIT(14), BIT(1) | BIT(19), 18, 2, "gpio", "uart"), - PIN_GRP_GPIO("led0_od", 11, 1, BIT(20), "led"), - PIN_GRP_GPIO("led1_od", 12, 1, BIT(21), "led"), - PIN_GRP_GPIO("led2_od", 13, 1, BIT(22), "led"), - PIN_GRP_GPIO("led3_od", 14, 1, BIT(23), "led"), + PIN_GRP_GPIO_2("led0_od", 11, 1, BIT(20), BIT(20), 0, "led"), + PIN_GRP_GPIO_2("led1_od", 12, 1, BIT(21), BIT(21), 0, "led"), + PIN_GRP_GPIO_2("led2_od", 13, 1, BIT(22), BIT(22), 0, "led"), + PIN_GRP_GPIO_2("led3_od", 14, 1, BIT(23), BIT(23), 0, "led"), }; -- GitLab From 19ec6bb80290e496021488084944b77f03a87dd7 Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Fri, 4 Oct 2019 15:44:52 +0200 Subject: [PATCH 131/993] mmc: sdhci-iproc: fix spurious interrupts on Multiblock reads with bcm2711 The Raspberry Pi 4 SDHCI hardware seems to automatically issue CMD12 after multiblock reads even when ACMD12 is disabled. This triggers spurious interrupts after the data transfer is done with the following message: mmc1: Got data interrupt 0x00000002 even though no data operation was in progress. mmc1: sdhci: ============ SDHCI REGISTER DUMP =========== mmc1: sdhci: Sys addr: 0x00000000 | Version: 0x00001002 mmc1: sdhci: Blk size: 0x00007200 | Blk cnt: 0x00000000 mmc1: sdhci: Argument: 0x00000000 | Trn mode: 0x00000033 mmc1: sdhci: Present: 0x1fff0000 | Host ctl: 0x00000017 mmc1: sdhci: Power: 0x0000000f | Blk gap: 0x00000080 mmc1: sdhci: Wake-up: 0x00000000 | Clock: 0x00000107 mmc1: sdhci: Timeout: 0x00000000 | Int stat: 0x00000000 mmc1: sdhci: Int enab: 0x03ff100b | Sig enab: 0x03ff100b mmc1: sdhci: ACmd stat: 0x00000000 | Slot int: 0x00000000 mmc1: sdhci: Caps: 0x45ee6432 | Caps_1: 0x0000a525 mmc1: sdhci: Cmd: 0x00000c1a | Max curr: 0x00080008 mmc1: sdhci: Resp[0]: 0x00000b00 | Resp[1]: 0x00edc87f mmc1: sdhci: Resp[2]: 0x325b5900 | Resp[3]: 0x00400e00 mmc1: sdhci: Host ctl2: 0x00000001 mmc1: sdhci: ADMA Err: 0x00000000 | ADMA Ptr: 0xf3025208 mmc1: sdhci: ============================================ Enable SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 to enable ACMD12 on multiblock reads and suppress the spurious interrupts. Fixes: f84e411c85be ("mmc: sdhci-iproc: Add support for emmc2 of the BCM2711") Signed-off-by: Nicolas Saenz Julienne Tested-by: Matthias Brugger Acked-by: Stefan Wahren Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-iproc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c index 2b9cdcd1dd9d..f4f5f0a70cda 100644 --- a/drivers/mmc/host/sdhci-iproc.c +++ b/drivers/mmc/host/sdhci-iproc.c @@ -262,6 +262,7 @@ static const struct sdhci_iproc_data bcm2835_data = { }; static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = { + .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, .ops = &sdhci_iproc_32only_ops, }; -- GitLab From 28c9fac09ab0147158db0baeec630407a5e9b892 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 5 Oct 2019 13:21:01 +0200 Subject: [PATCH 132/993] memstick: jmb38x_ms: Fix an error handling path in 'jmb38x_ms_probe()' If 'jmb38x_ms_count_slots()' returns 0, we must undo the previous 'pci_request_regions()' call. Goto 'err_out_int' to fix it. Fixes: 60fdd931d577 ("memstick: add support for JMicron jmb38x MemoryStick host controller") Cc: stable@vger.kernel.org Signed-off-by: Christophe JAILLET Signed-off-by: Ulf Hansson --- drivers/memstick/host/jmb38x_ms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c index 32747425297d..64fff6abe60e 100644 --- a/drivers/memstick/host/jmb38x_ms.c +++ b/drivers/memstick/host/jmb38x_ms.c @@ -941,7 +941,7 @@ static int jmb38x_ms_probe(struct pci_dev *pdev, if (!cnt) { rc = -ENODEV; pci_dev_busy = 1; - goto err_out; + goto err_out_int; } jm = kzalloc(sizeof(struct jmb38x_ms) -- GitLab From 1fee35d04a42290a3c44b8a4e3c66dbdd6180c42 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Thu, 8 Aug 2019 13:52:50 +0300 Subject: [PATCH 133/993] iwlwifi: don't access trans_cfg via cfg We copy cfg->trans to trans->trans_cfg at the very beginning, so don't try to access it via cfg->trans anymore, because the cfg may be unset in later cases. Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/iwl-io.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-io.h index f8e4f0f5de0c..f09e368c7040 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.h @@ -112,38 +112,38 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf); */ static inline u32 iwl_umac_prph(struct iwl_trans *trans, u32 ofs) { - return ofs + trans->cfg->trans.umac_prph_offset; + return ofs + trans->trans_cfg->umac_prph_offset; } static inline u32 iwl_read_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs) { return iwl_read_prph_no_grab(trans, ofs + - trans->cfg->trans.umac_prph_offset); + trans->trans_cfg->umac_prph_offset); } static inline u32 iwl_read_umac_prph(struct iwl_trans *trans, u32 ofs) { - return iwl_read_prph(trans, ofs + trans->cfg->trans.umac_prph_offset); + return iwl_read_prph(trans, ofs + trans->trans_cfg->umac_prph_offset); } static inline void iwl_write_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs, u32 val) { - iwl_write_prph_no_grab(trans, ofs + trans->cfg->trans.umac_prph_offset, + iwl_write_prph_no_grab(trans, ofs + trans->trans_cfg->umac_prph_offset, val); } static inline void iwl_write_umac_prph(struct iwl_trans *trans, u32 ofs, u32 val) { - iwl_write_prph(trans, ofs + trans->cfg->trans.umac_prph_offset, val); + iwl_write_prph(trans, ofs + trans->trans_cfg->umac_prph_offset, val); } static inline int iwl_poll_umac_prph_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout) { return iwl_poll_prph_bit(trans, addr + - trans->cfg->trans.umac_prph_offset, + trans->trans_cfg->umac_prph_offset, bits, mask, timeout); } -- GitLab From 3ed83da39aed275a5b74c74f77e85c839ad2efe9 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 23 Aug 2019 11:59:09 +0300 Subject: [PATCH 134/993] iwlwifi: fix ACPI table revision checks We can't check for the ACPI table revision validity in the same if where we check if the package was read correctly, because we return PTR_ERR(pkg) and if the table is not valid but the pointer is, we would return a valid pointer as an error. Fix that by moving the table checks to a separate if and return -EINVAL if it's not valid. Reported-by: Dan Carpenter Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 10 ++++---- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 24 +++++++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c index 7573af2d88ce..c2db758b9d54 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -162,12 +162,13 @@ int iwl_acpi_get_mcc(struct device *dev, char *mcc) wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data, ACPI_WRDD_WIFI_DATA_SIZE, &tbl_rev); - if (IS_ERR(wifi_pkg) || tbl_rev != 0) { + if (IS_ERR(wifi_pkg)) { ret = PTR_ERR(wifi_pkg); goto out_free; } - if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) { + if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER || + tbl_rev != 0) { ret = -EINVAL; goto out_free; } @@ -224,12 +225,13 @@ int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk) wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data, ACPI_ECKV_WIFI_DATA_SIZE, &tbl_rev); - if (IS_ERR(wifi_pkg) || tbl_rev != 0) { + if (IS_ERR(wifi_pkg)) { ret = PTR_ERR(wifi_pkg); goto out_free; } - if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) { + if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER || + tbl_rev != 0) { ret = -EINVAL; goto out_free; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 32a5e4e5461f..b2eb18eedf02 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -694,12 +694,13 @@ static int iwl_mvm_sar_get_wrds_table(struct iwl_mvm *mvm) wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data, ACPI_WRDS_WIFI_DATA_SIZE, &tbl_rev); - if (IS_ERR(wifi_pkg) || tbl_rev != 0) { + if (IS_ERR(wifi_pkg)) { ret = PTR_ERR(wifi_pkg); goto out_free; } - if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) { + if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER || + tbl_rev != 0) { ret = -EINVAL; goto out_free; } @@ -731,13 +732,14 @@ static int iwl_mvm_sar_get_ewrd_table(struct iwl_mvm *mvm) wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data, ACPI_EWRD_WIFI_DATA_SIZE, &tbl_rev); - if (IS_ERR(wifi_pkg) || tbl_rev != 0) { + if (IS_ERR(wifi_pkg)) { ret = PTR_ERR(wifi_pkg); goto out_free; } if ((wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) || - (wifi_pkg->package.elements[2].type != ACPI_TYPE_INTEGER)) { + (wifi_pkg->package.elements[2].type != ACPI_TYPE_INTEGER) || + tbl_rev != 0) { ret = -EINVAL; goto out_free; } @@ -791,11 +793,16 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm) wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data, ACPI_WGDS_WIFI_DATA_SIZE, &tbl_rev); - if (IS_ERR(wifi_pkg) || tbl_rev > 1) { + if (IS_ERR(wifi_pkg)) { ret = PTR_ERR(wifi_pkg); goto out_free; } + if (tbl_rev != 0) { + ret = -EINVAL; + goto out_free; + } + mvm->geo_rev = tbl_rev; for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) { for (j = 0; j < ACPI_GEO_TABLE_SIZE; j++) { @@ -1020,11 +1027,16 @@ static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm) wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data, ACPI_PPAG_WIFI_DATA_SIZE, &tbl_rev); - if (IS_ERR(wifi_pkg) || tbl_rev != 0) { + if (IS_ERR(wifi_pkg)) { ret = PTR_ERR(wifi_pkg); goto out_free; } + if (tbl_rev != 0) { + ret = -EINVAL; + goto out_free; + } + enabled = &wifi_pkg->package.elements[1]; if (enabled->type != ACPI_TYPE_INTEGER || (enabled->integer.value != 0 && enabled->integer.value != 1)) { -- GitLab From a4584729291c71c5c14718ff00ea6c5f971c45b2 Mon Sep 17 00:00:00 2001 From: Haim Dreyfuss Date: Mon, 12 Aug 2019 13:25:42 +0300 Subject: [PATCH 135/993] iwlwifi: mvm: force single phy init The PHY is initialized during device initialization, but devices with the tx_siso_diversity flag set need to send PHY_CONFIGURATION_CMD first, otherwise the PHY would be reinitialized, causing a SYSASSERT. To fix this, use a bit that tells the FW not to complete the PHY initialization before a PHY_CONFIGURATION_CMD is received. Signed-off-by: Haim Dreyfuss Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index b2eb18eedf02..0d2229319261 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -420,6 +420,9 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) }; int ret; + if (mvm->trans->cfg->tx_with_siso_diversity) + init_cfg.init_flags |= cpu_to_le32(BIT(IWL_INIT_PHY)); + lockdep_assert_held(&mvm->mutex); mvm->rfkill_safe_init_done = false; -- GitLab From a2113cc44d4387a7c3ef3a9082d273524f9230ac Mon Sep 17 00:00:00 2001 From: Naftali Goldstein Date: Mon, 9 Sep 2019 13:11:04 +0300 Subject: [PATCH 136/993] iwlwifi: mvm: fix race in sync rx queue notification Consider the following flow: 1. Driver starts to sync the rx queues due to a delba. mvm->queue_sync_cookie=1. This rx-queues-sync is synchronous, so it doesn't increment the cookie until all rx queues handle the notification from FW. 2. During this time, driver starts to sync rx queues due to nssn sync required. The cookie's value is still 1, but it doesn't matter since this rx-queue-sync is non-synchronous so in the notification handler the cookie is ignored. What _does_ matter is that this flow increments the cookie to 2 immediately. Remember though that the FW won't start servicing this command until it's done with the previous one. 3. FW is still handling the first command, so it sends a notification with internal_notif->sync=1, and internal_notif->cookie=0, which triggers a WARN_ONCE. The solution for this race is to only use the mvm->queue_sync_cookie in case of a synchronous sync-rx-queues. This way in step 2 the cookie's value won't change so we avoid the WARN. The commit in the "fixes" field is the first commit to introduce non-synchronous sending of this command to FW. Fixes: 3c514bf831ac ("iwlwifi: mvm: add a loose synchronization of the NSSN across Rx queues") Signed-off-by: Naftali Goldstein Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index cd1b10042fbf..d31f96c3f925 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -4881,11 +4881,11 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, if (!iwl_mvm_has_new_rx_api(mvm)) return; - notif->cookie = mvm->queue_sync_cookie; - - if (notif->sync) + if (notif->sync) { + notif->cookie = mvm->queue_sync_cookie; atomic_set(&mvm->queue_sync_counter, mvm->trans->num_rx_queues); + } ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif, size, !notif->sync); @@ -4905,7 +4905,8 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, out: atomic_set(&mvm->queue_sync_counter, 0); - mvm->queue_sync_cookie++; + if (notif->sync) + mvm->queue_sync_cookie++; } static void iwl_mvm_sync_rx_queues(struct ieee80211_hw *hw) -- GitLab From 08326a97afbe808e50e1610c2835fa2747bdb908 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 4 Sep 2019 16:23:27 +0200 Subject: [PATCH 137/993] iwlwifi: pcie: fix indexing in command dump for new HW We got a crash in iwl_trans_pcie_get_cmdlen(), while the TFD was being accessed to sum up the lengths. We want to access the TFD here, which is the information for the hardware. We always only allocate 32 buffers for the cmd queue, but on newer hardware (using TFH) we can also allocate only a shorter hardware array, also only 32 TFDs. Prior to the TFH, we had to allocate a bigger TFD array but would make those point to a smaller set of buffers. Additionally, now max_tfd_queue_size is up to 65536, so we can access *way* out of bounds of a really only 32-entry array, so it crashes. Fix this by making the TFD index depend on which hardware we are using right now. While changing the calculation, also fix it to not use void ptr arithmetic, but cast to u8 * before. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index f8a1f985a1d8..ab7480a85015 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3272,11 +3272,17 @@ static struct iwl_trans_dump_data ptr = cmdq->write_ptr; for (i = 0; i < cmdq->n_window; i++) { u8 idx = iwl_pcie_get_cmd_index(cmdq, ptr); + u8 tfdidx; u32 caplen, cmdlen; + if (trans->trans_cfg->use_tfh) + tfdidx = idx; + else + tfdidx = ptr; + cmdlen = iwl_trans_pcie_get_cmdlen(trans, - cmdq->tfds + - tfd_size * ptr); + (u8 *)cmdq->tfds + + tfd_size * tfdidx); caplen = min_t(u32, TFD_MAX_PAYLOAD_SIZE, cmdlen); if (cmdlen) { -- GitLab From 8188a18ee2e48c9a7461139838048363bfce3fef Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 19 Sep 2019 09:04:09 +0200 Subject: [PATCH 138/993] iwlwifi: pcie: fix rb_allocator workqueue allocation We don't handle failures in the rb_allocator workqueue allocation correctly. To fix that, move the code earlier so the cleanup is easier and we don't have to undo all the interrupt allocations in this case. Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index ab7480a85015..6961f00ff812 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -3456,6 +3456,15 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, spin_lock_init(&trans_pcie->reg_lock); mutex_init(&trans_pcie->mutex); init_waitqueue_head(&trans_pcie->ucode_write_waitq); + + trans_pcie->rba.alloc_wq = alloc_workqueue("rb_allocator", + WQ_HIGHPRI | WQ_UNBOUND, 1); + if (!trans_pcie->rba.alloc_wq) { + ret = -ENOMEM; + goto out_free_trans; + } + INIT_WORK(&trans_pcie->rba.rx_alloc, iwl_pcie_rx_allocator_work); + trans_pcie->tso_hdr_page = alloc_percpu(struct iwl_tso_hdr_page); if (!trans_pcie->tso_hdr_page) { ret = -ENOMEM; @@ -3590,10 +3599,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, trans_pcie->inta_mask = CSR_INI_SET_MASK; } - trans_pcie->rba.alloc_wq = alloc_workqueue("rb_allocator", - WQ_HIGHPRI | WQ_UNBOUND, 1); - INIT_WORK(&trans_pcie->rba.rx_alloc, iwl_pcie_rx_allocator_work); - #ifdef CONFIG_IWLWIFI_DEBUGFS trans_pcie->fw_mon_data.state = IWL_FW_MON_DBGFS_STATE_CLOSED; mutex_init(&trans_pcie->fw_mon_data.mutex); @@ -3605,6 +3610,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, iwl_pcie_free_ict(trans); out_no_pci: free_percpu(trans_pcie->tso_hdr_page); + destroy_workqueue(trans_pcie->rba.alloc_wq); +out_free_trans: iwl_trans_free(trans); return ERR_PTR(ret); } -- GitLab From b4b814fec1a5a849383f7b3886b654a13abbda7d Mon Sep 17 00:00:00 2001 From: Navid Emamdoost Date: Thu, 12 Sep 2019 23:23:27 -0500 Subject: [PATCH 139/993] iwlwifi: dbg_ini: fix memory leak in alloc_sgtable In alloc_sgtable if alloc_page fails, the alocated table should be released. Signed-off-by: Navid Emamdoost Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 5c8602de9168..87421807e040 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -646,6 +646,7 @@ static struct scatterlist *alloc_sgtable(int size) if (new_page) __free_page(new_page); } + kfree(table); return NULL; } alloc_size = min_t(int, size, PAGE_SIZE); -- GitLab From 0f4f199443faca715523b0659aa536251d8b978f Mon Sep 17 00:00:00 2001 From: Navid Emamdoost Date: Fri, 27 Sep 2019 15:56:04 -0500 Subject: [PATCH 140/993] iwlwifi: pcie: fix memory leaks in iwl_pcie_ctxt_info_gen3_init In iwl_pcie_ctxt_info_gen3_init there are cases that the allocated dma memory is leaked in case of error. DMA memories prph_scratch, prph_info, and ctxt_info_gen3 are allocated and initialized to be later assigned to trans_pcie. But in any error case before such assignment the allocated memories should be released. First of such error cases happens when iwl_pcie_init_fw_sec fails. Current implementation correctly releases prph_scratch. But in two sunsequent error cases where dma_alloc_coherent may fail, such releases are missing. This commit adds release for prph_scratch when allocation for prph_info fails, and adds releases for prph_scratch and prph_info when allocation for ctxt_info_gen3 fails. Fixes: 2ee824026288 ("iwlwifi: pcie: support context information for 22560 devices") Signed-off-by: Navid Emamdoost Signed-off-by: Luca Coelho --- .../intel/iwlwifi/pcie/ctxt-info-gen3.c | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c index 75fa8a6aafee..74980382e64c 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -107,13 +107,9 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, /* allocate ucode sections in dram and set addresses */ ret = iwl_pcie_init_fw_sec(trans, fw, &prph_scratch->dram); - if (ret) { - dma_free_coherent(trans->dev, - sizeof(*prph_scratch), - prph_scratch, - trans_pcie->prph_scratch_dma_addr); - return ret; - } + if (ret) + goto err_free_prph_scratch; + /* Allocate prph information * currently we don't assign to the prph info anything, but it would get @@ -121,16 +117,20 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, prph_info = dma_alloc_coherent(trans->dev, sizeof(*prph_info), &trans_pcie->prph_info_dma_addr, GFP_KERNEL); - if (!prph_info) - return -ENOMEM; + if (!prph_info) { + ret = -ENOMEM; + goto err_free_prph_scratch; + } /* Allocate context info */ ctxt_info_gen3 = dma_alloc_coherent(trans->dev, sizeof(*ctxt_info_gen3), &trans_pcie->ctxt_info_dma_addr, GFP_KERNEL); - if (!ctxt_info_gen3) - return -ENOMEM; + if (!ctxt_info_gen3) { + ret = -ENOMEM; + goto err_free_prph_info; + } ctxt_info_gen3->prph_info_base_addr = cpu_to_le64(trans_pcie->prph_info_dma_addr); @@ -186,6 +186,20 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, iwl_set_bit(trans, CSR_GP_CNTRL, CSR_AUTO_FUNC_INIT); return 0; + +err_free_prph_info: + dma_free_coherent(trans->dev, + sizeof(*prph_info), + prph_info, + trans_pcie->prph_info_dma_addr); + +err_free_prph_scratch: + dma_free_coherent(trans->dev, + sizeof(*prph_scratch), + prph_scratch, + trans_pcie->prph_scratch_dma_addr); + return ret; + } void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans) -- GitLab From 12e36d98d3e5acf5fc57774e0a15906d55f30cb9 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Tue, 8 Oct 2019 13:10:53 +0300 Subject: [PATCH 141/993] iwlwifi: exclude GEO SAR support for 3168 We currently support two NICs in FW version 29, namely 7265D and 3168. Out of these, only 7265D supports GEO SAR, so adjust the function that checks for it accordingly. Signed-off-by: Luca Coelho Fixes: f5a47fae6aa3 ("iwlwifi: mvm: fix version check for GEO_TX_POWER_LIMIT support") Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 0d2229319261..d9eb2b286438 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -899,15 +899,17 @@ static bool iwl_mvm_sar_geo_support(struct iwl_mvm *mvm) * firmware versions. Unfortunately, we don't have a TLV API * flag to rely on, so rely on the major version which is in * the first byte of ucode_ver. This was implemented - * initially on version 38 and then backported to29 and 17. - * The intention was to have it in 36 as well, but not all - * 8000 family got this feature enabled. The 8000 family is - * the only one using version 36, so skip this version - * entirely. + * initially on version 38 and then backported to 17. It was + * also backported to 29, but only for 7265D devices. The + * intention was to have it in 36 as well, but not all 8000 + * family got this feature enabled. The 8000 family is the + * only one using version 36, so skip this version entirely. */ return IWL_UCODE_SERIAL(mvm->fw->ucode_ver) >= 38 || - IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 29 || - IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 17; + IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 17 || + (IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 29 && + ((mvm->trans->hw_rev & CSR_HW_REV_TYPE_MSK) == + CSR_HW_REV_TYPE_7265D)); } int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm) -- GitLab From aa0cc7dde17bb6b8cc533bbcfe3f53d70e0dd269 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Tue, 8 Oct 2019 13:21:02 +0300 Subject: [PATCH 142/993] iwlwifi: pcie: change qu with jf devices to use qu configuration There were a bunch of devices with qu and jf that were loading the configuration with pu and jf, which is wrong. Fix them all accordingly. Additionally, remove 0x1010 and 0x1210 subsytem IDs from the list, since they are obviously wrong, and 0x0044 and 0x0244, which were duplicate. Cc: stable@vger.kernel.org # 5.1+ Signed-off-by: Luca Coelho --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 274 +++++++++--------- 1 file changed, 137 insertions(+), 137 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index e29c47744ef5..6f4bb7ce71a5 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -513,31 +513,33 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8265_2ac_cfg)}, /* 9000 Series */ - {IWL_PCI_DEVICE(0x02F0, 0x0030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x00A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x0230, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x02A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x1551, iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x1552, iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x2030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x2034, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x4030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x4034, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x40A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x4234, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, - {IWL_PCI_DEVICE(0x02F0, 0x42A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, + {IWL_PCI_DEVICE(0x02F0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x02F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x06F0, 0x0030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, {IWL_PCI_DEVICE(0x06F0, 0x0034, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, {IWL_PCI_DEVICE(0x06F0, 0x0038, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, @@ -643,34 +645,34 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2720, 0x40A4, iwl9462_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x4234, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x42A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x0030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x0034, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x0038, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x003C, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x0060, iwl9460_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x0064, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x00A0, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x00A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x0230, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x0234, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x0238, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x023C, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x0260, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x0264, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x02A0, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x02A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x1010, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x30DC, 0x1030, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x1210, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x30DC, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x1552, iwl9560_killer_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x2030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x2034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x4030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x4034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x40A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x4234, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x30DC, 0x42A4, iwl9462_2ac_cfg_soc)}, + + {IWL_PCI_DEVICE(0x30DC, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x30DC, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x31DC, 0x0030, iwl9560_2ac_160_cfg_shared_clk)}, {IWL_PCI_DEVICE(0x31DC, 0x0034, iwl9560_2ac_cfg_shared_clk)}, {IWL_PCI_DEVICE(0x31DC, 0x0038, iwl9560_2ac_160_cfg_shared_clk)}, @@ -726,62 +728,60 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x34F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, {IWL_PCI_DEVICE(0x34F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0034, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0038, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x003C, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0060, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0064, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x00A0, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x00A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0230, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0234, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0238, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x023C, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0260, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x0264, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x02A0, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x02A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x1010, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x3DF0, 0x1030, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x1210, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x3DF0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x1552, iwl9560_killer_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x2030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x2034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x4030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x4034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x40A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x4234, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x3DF0, 0x42A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x0030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x0034, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x0060, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x0064, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x00A0, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x00A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x0230, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x0234, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x0238, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x023C, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x0260, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x0264, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x02A0, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x02A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x1010, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x43F0, 0x1030, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x1210, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x43F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x1552, iwl9560_killer_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x2030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x2034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x4030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x4034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x40A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x4234, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x43F0, 0x42A4, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x3DF0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x3DF0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + + {IWL_PCI_DEVICE(0x43F0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x43F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x9DF0, 0x0000, iwl9460_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x9DF0, 0x0010, iwl9460_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x9DF0, 0x0030, iwl9560_2ac_160_cfg_soc)}, @@ -821,34 +821,34 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x9DF0, 0x40A4, iwl9462_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x9DF0, 0x4234, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x9DF0, 0x42A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0034, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0060, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0064, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x00A0, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x00A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0230, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0234, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0238, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x023C, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0260, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x0264, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x02A0, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x02A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x1010, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0xA0F0, 0x1030, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x1210, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0xA0F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x1552, iwl9560_killer_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x2030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x2034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x4030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x4034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x40A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x4234, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0xA0F0, 0x42A4, iwl9462_2ac_cfg_soc)}, + + {IWL_PCI_DEVICE(0xA0F0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA0F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0xA370, 0x0030, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0xA370, 0x0034, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0xA370, 0x0038, iwl9560_2ac_160_cfg_soc)}, -- GitLab From 598c30dbcc9434706f29a085a8eba4730573bcc2 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 2 Oct 2019 16:10:24 -0500 Subject: [PATCH 143/993] drm/amdgpu/powerplay: fix typo in mvdd table setup Polaris and vegam use count for the value rather than level. This looks like a copy paste typo from when the code was adapted from previous asics. I'm not sure that the SMU actually uses this value, so I don't know that it actually is a bug per se. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=108609 Reported-by: Robert Strube Reviewed-by: Evan Quan Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c | 2 +- drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c index dc754447f0dd..23c12018dbc1 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/polaris10_smumgr.c @@ -655,7 +655,7 @@ static int polaris10_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, count = SMU_MAX_SMIO_LEVELS; for (level = 0; level < count; level++) { table->SmioTable2.Pattern[level].Voltage = - PP_HOST_TO_SMC_US(data->mvdd_voltage_table.entries[count].value * VOLTAGE_SCALE); + PP_HOST_TO_SMC_US(data->mvdd_voltage_table.entries[level].value * VOLTAGE_SCALE); /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level.*/ table->SmioTable2.Pattern[level].Smio = (uint8_t) level; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c index 7c960b07746f..ae18fbcb26fb 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c @@ -456,7 +456,7 @@ static int vegam_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, count = SMU_MAX_SMIO_LEVELS; for (level = 0; level < count; level++) { table->SmioTable2.Pattern[level].Voltage = PP_HOST_TO_SMC_US( - data->mvdd_voltage_table.entries[count].value * VOLTAGE_SCALE); + data->mvdd_voltage_table.entries[level].value * VOLTAGE_SCALE); /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level.*/ table->SmioTable2.Pattern[level].Smio = (uint8_t) level; -- GitLab From bcab05880f9306e94531b0009c627421db110a74 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 9 Oct 2019 12:19:44 +0100 Subject: [PATCH 144/993] ASoC: msm8916-wcd-digital: add missing MIX2 path for RX1/2 This patch adds missing MIX2 path on RX1/2 which take IIR1 and IIR2 as inputs. Without this patch sound card fails to intialize with below warning: ASoC: no sink widget found for RX1 MIX2 INP1 ASoC: Failed to add route IIR1 -> IIR1 -> RX1 MIX2 INP1 ASoC: no sink widget found for RX2 MIX2 INP1 ASoC: Failed to add route IIR1 -> IIR1 -> RX2 MIX2 INP1 ASoC: no sink widget found for RX1 MIX2 INP1 ASoC: Failed to add route IIR2 -> IIR2 -> RX1 MIX2 INP1 ASoC: no sink widget found for RX2 MIX2 INP1 ASoC: Failed to add route IIR2 -> IIR2 -> RX2 MIX2 INP1 Reported-by: Stephan Gerhold Signed-off-by: Srinivas Kandagatla Tested-by: Stephan Gerhold Link: https://lore.kernel.org/r/20191009111944.28069-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/codecs/msm8916-wcd-digital.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c index 9fa5d44fdc79..58b2468fb2a7 100644 --- a/sound/soc/codecs/msm8916-wcd-digital.c +++ b/sound/soc/codecs/msm8916-wcd-digital.c @@ -243,6 +243,10 @@ static const char *const rx_mix1_text[] = { "ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3" }; +static const char * const rx_mix2_text[] = { + "ZERO", "IIR1", "IIR2" +}; + static const char *const dec_mux_text[] = { "ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2" }; @@ -270,6 +274,16 @@ static const struct soc_enum rx3_mix1_inp_enum[] = { SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B2_CTL, 0, 6, rx_mix1_text), }; +/* RX1 MIX2 */ +static const struct soc_enum rx_mix2_inp1_chain_enum = + SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX1_B3_CTL, + 0, 3, rx_mix2_text); + +/* RX2 MIX2 */ +static const struct soc_enum rx2_mix2_inp1_chain_enum = + SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B3_CTL, + 0, 3, rx_mix2_text); + /* DEC */ static const struct soc_enum dec1_mux_enum = SOC_ENUM_SINGLE( LPASS_CDC_CONN_TX_B1_CTL, 0, 6, dec_mux_text); @@ -309,6 +323,10 @@ static const struct snd_kcontrol_new rx3_mix1_inp2_mux = SOC_DAPM_ENUM( "RX3 MIX1 INP2 Mux", rx3_mix1_inp_enum[1]); static const struct snd_kcontrol_new rx3_mix1_inp3_mux = SOC_DAPM_ENUM( "RX3 MIX1 INP3 Mux", rx3_mix1_inp_enum[2]); +static const struct snd_kcontrol_new rx1_mix2_inp1_mux = SOC_DAPM_ENUM( + "RX1 MIX2 INP1 Mux", rx_mix2_inp1_chain_enum); +static const struct snd_kcontrol_new rx2_mix2_inp1_mux = SOC_DAPM_ENUM( + "RX2 MIX2 INP1 Mux", rx2_mix2_inp1_chain_enum); /* Digital Gain control -38.4 dB to +38.4 dB in 0.3 dB steps */ static const DECLARE_TLV_DB_SCALE(digital_gain, -3840, 30, 0); @@ -740,6 +758,10 @@ static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = { &rx3_mix1_inp2_mux), SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0, &rx3_mix1_inp3_mux), + SND_SOC_DAPM_MUX("RX1 MIX2 INP1", SND_SOC_NOPM, 0, 0, + &rx1_mix2_inp1_mux), + SND_SOC_DAPM_MUX("RX2 MIX2 INP1", SND_SOC_NOPM, 0, 0, + &rx2_mix2_inp1_mux), SND_SOC_DAPM_MUX("CIC1 MUX", SND_SOC_NOPM, 0, 0, &cic1_mux), SND_SOC_DAPM_MUX("CIC2 MUX", SND_SOC_NOPM, 0, 0, &cic2_mux), -- GitLab From af6219590b541418d3192e9bfa03989834ca0e78 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Wed, 9 Oct 2019 18:36:15 +0300 Subject: [PATCH 145/993] ASoC: simple_card_utils.h: Fix potential multiple redefinition error asoc_simple_debug_info and asoc_simple_debug_dai must be static otherwise we might a compilation error if the compiler decides not to inline the given function. Fixes: 0580dde59438686d ("ASoC: simple-card-utils: add asoc_simple_debug_info()") Signed-off-by: Daniel Baluta Link: https://lore.kernel.org/r/20191009153615.32105-3-daniel.baluta@nxp.com Signed-off-by: Mark Brown --- include/sound/simple_card_utils.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h index 985a5f583de4..31f76b6abf71 100644 --- a/include/sound/simple_card_utils.h +++ b/include/sound/simple_card_utils.h @@ -135,9 +135,9 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv, struct link_info *li); #ifdef DEBUG -inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv, - char *name, - struct asoc_simple_dai *dai) +static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv, + char *name, + struct asoc_simple_dai *dai) { struct device *dev = simple_priv_to_dev(priv); @@ -167,7 +167,7 @@ inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv, dev_dbg(dev, "%s clk %luHz\n", name, clk_get_rate(dai->clk)); } -inline void asoc_simple_debug_info(struct asoc_simple_priv *priv) +static inline void asoc_simple_debug_info(struct asoc_simple_priv *priv) { struct snd_soc_card *card = simple_priv_to_card(priv); struct device *dev = simple_priv_to_dev(priv); -- GitLab From e963408e8ff439e2b9da20e5399d7dca21462fcc Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 2 Oct 2019 17:45:11 +0100 Subject: [PATCH 146/993] drivers/amba: fix reset control error handling With commit 79bdcb202a35 ("ARM: 8906/1: drivers/amba: add reset control to amba bus probe") it is possible for the the amba bus driver to defer probing the device for its IDs because the reset driver may be probed later. However when a subsequent probe occurs, the call to request_resource() in the driver returns -EBUSY as the driver has not released the resource from the initial probe attempt - or cleaned up any of the preceding actions. Fix this both for the deferred probe case as well as a failure to get the reset. Fixes: 79bdcb202a35 ("ARM: 8906/1: drivers/amba: add reset control to amba bus probe") Reported-by: Dinh Nguyen Tested-by: Dinh Nguyen Signed-off-by: Russell King --- drivers/amba/bus.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index f39f075abff9..fe1523664816 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -409,9 +409,11 @@ static int amba_device_try_add(struct amba_device *dev, struct resource *parent) */ rstc = of_reset_control_array_get_optional_shared(dev->dev.of_node); if (IS_ERR(rstc)) { - if (PTR_ERR(rstc) != -EPROBE_DEFER) - dev_err(&dev->dev, "Can't get amba reset!\n"); - return PTR_ERR(rstc); + ret = PTR_ERR(rstc); + if (ret != -EPROBE_DEFER) + dev_err(&dev->dev, "can't get reset: %d\n", + ret); + goto err_reset; } reset_control_deassert(rstc); reset_control_put(rstc); @@ -472,6 +474,12 @@ static int amba_device_try_add(struct amba_device *dev, struct resource *parent) release_resource(&dev->res); err_out: return ret; + + err_reset: + amba_put_disable_pclk(dev); + iounmap(tmp); + dev_pm_domain_detach(&dev->dev, true); + goto err_release; } /* -- GitLab From 087a2b7ec973f6f30f6e7b72cb50b6f7734ffdd2 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 9 Oct 2019 15:11:27 -0700 Subject: [PATCH 147/993] ARM: dts: Use level interrupt for omap4 & 5 wlcore Commit 572cf7d7b07d ("ARM: dts: Improve omap l4per idling with wlcore edge sensitive interrupt") changed wlcore interrupts to use edge interrupt based on what's specified in the wl1835mod.pdf data sheet. However, there are still cases where we can have lost interrupts as described in omap_gpio_unidle(). And using a level interrupt instead of edge interrupt helps as we avoid the check for untriggered GPIO interrupts in omap_gpio_unidle(). And with commit e6818d29ea15 ("gpio: gpio-omap: configure edge detection for level IRQs for idle wakeup") GPIOs idle just fine with level interrupts. Let's change omap4 and 5 wlcore users back to using level interrupt instead of edge interrupt. Let's not change the others as I've only seen this on omap4 and 5, probably because the other SoCs don't have l4per idle independent of the CPUs. Fixes: 572cf7d7b07d ("ARM: dts: Improve omap l4per idling with wlcore edge sensitive interrupt") Depends-on: e6818d29ea15 ("gpio: gpio-omap: configure edge detection for level IRQs for idle wakeup") Cc: Anders Roxell Cc: Eyal Reizer Cc: Guy Mishol Cc: John Stultz Cc: Ulf Hansson Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap4-droid4-xt894.dts | 2 +- arch/arm/boot/dts/omap4-panda-common.dtsi | 2 +- arch/arm/boot/dts/omap4-sdp.dts | 2 +- arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi | 2 +- arch/arm/boot/dts/omap5-board-common.dtsi | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/omap4-droid4-xt894.dts b/arch/arm/boot/dts/omap4-droid4-xt894.dts index 4454449de00c..a40fe8d49da6 100644 --- a/arch/arm/boot/dts/omap4-droid4-xt894.dts +++ b/arch/arm/boot/dts/omap4-droid4-xt894.dts @@ -369,7 +369,7 @@ compatible = "ti,wl1285", "ti,wl1283"; reg = <2>; /* gpio_100 with gpmc_wait2 pad as wakeirq */ - interrupts-extended = <&gpio4 4 IRQ_TYPE_EDGE_RISING>, + interrupts-extended = <&gpio4 4 IRQ_TYPE_LEVEL_HIGH>, <&omap4_pmx_core 0x4e>; interrupt-names = "irq", "wakeup"; ref-clock-frequency = <26000000>; diff --git a/arch/arm/boot/dts/omap4-panda-common.dtsi b/arch/arm/boot/dts/omap4-panda-common.dtsi index 14be2ecb62b1..55ea8b6189af 100644 --- a/arch/arm/boot/dts/omap4-panda-common.dtsi +++ b/arch/arm/boot/dts/omap4-panda-common.dtsi @@ -474,7 +474,7 @@ compatible = "ti,wl1271"; reg = <2>; /* gpio_53 with gpmc_ncs3 pad as wakeup */ - interrupts-extended = <&gpio2 21 IRQ_TYPE_EDGE_RISING>, + interrupts-extended = <&gpio2 21 IRQ_TYPE_LEVEL_HIGH>, <&omap4_pmx_core 0x3a>; interrupt-names = "irq", "wakeup"; ref-clock-frequency = <38400000>; diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts index 3c274965ff40..91480ac1f328 100644 --- a/arch/arm/boot/dts/omap4-sdp.dts +++ b/arch/arm/boot/dts/omap4-sdp.dts @@ -512,7 +512,7 @@ compatible = "ti,wl1281"; reg = <2>; interrupt-parent = <&gpio1>; - interrupts = <21 IRQ_TYPE_EDGE_RISING>; /* gpio 53 */ + interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; /* gpio 53 */ ref-clock-frequency = <26000000>; tcxo-clock-frequency = <26000000>; }; diff --git a/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi b/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi index 6dbbc9b3229c..d0032213101e 100644 --- a/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi +++ b/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi @@ -69,7 +69,7 @@ compatible = "ti,wl1271"; reg = <2>; interrupt-parent = <&gpio2>; - interrupts = <9 IRQ_TYPE_EDGE_RISING>; /* gpio 41 */ + interrupts = <9 IRQ_TYPE_LEVEL_HIGH>; /* gpio 41 */ ref-clock-frequency = <38400000>; }; }; diff --git a/arch/arm/boot/dts/omap5-board-common.dtsi b/arch/arm/boot/dts/omap5-board-common.dtsi index 7fff555ee394..68ac04641bdb 100644 --- a/arch/arm/boot/dts/omap5-board-common.dtsi +++ b/arch/arm/boot/dts/omap5-board-common.dtsi @@ -362,7 +362,7 @@ pinctrl-names = "default"; pinctrl-0 = <&wlcore_irq_pin>; interrupt-parent = <&gpio1>; - interrupts = <14 IRQ_TYPE_EDGE_RISING>; /* gpio 14 */ + interrupts = <14 IRQ_TYPE_LEVEL_HIGH>; /* gpio 14 */ ref-clock-frequency = <26000000>; }; }; -- GitLab From 67e15fa5b487adb9b78a92789eeff2d6ec8f5cee Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 31 Aug 2019 17:01:58 +0100 Subject: [PATCH 148/993] ARM: mm: fix alignment handler faults under memory pressure When the system has high memory pressure, the page containing the instruction may be paged out. Using probe_kernel_address() means that if the page is swapped out, the resulting page fault will not be handled because page faults are disabled by this function. Use get_user() to read the instruction instead. Reported-by: Jing Xiangfeng Fixes: b255188f90e2 ("ARM: fix scheduling while atomic warning in alignment handling code") Signed-off-by: Russell King --- arch/arm/mm/alignment.c | 44 +++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 04b36436cbc0..6587432faf05 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -767,6 +767,36 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs, return NULL; } +static int alignment_get_arm(struct pt_regs *regs, u32 *ip, unsigned long *inst) +{ + u32 instr = 0; + int fault; + + if (user_mode(regs)) + fault = get_user(instr, ip); + else + fault = probe_kernel_address(ip, instr); + + *inst = __mem_to_opcode_arm(instr); + + return fault; +} + +static int alignment_get_thumb(struct pt_regs *regs, u16 *ip, u16 *inst) +{ + u16 instr = 0; + int fault; + + if (user_mode(regs)) + fault = get_user(instr, ip); + else + fault = probe_kernel_address(ip, instr); + + *inst = __mem_to_opcode_thumb16(instr); + + return fault; +} + static int do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { @@ -774,10 +804,10 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) unsigned long instr = 0, instrptr; int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs); unsigned int type; - unsigned int fault; u16 tinstr = 0; int isize = 4; int thumb2_32b = 0; + int fault; if (interrupts_enabled(regs)) local_irq_enable(); @@ -786,15 +816,14 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (thumb_mode(regs)) { u16 *ptr = (u16 *)(instrptr & ~1); - fault = probe_kernel_address(ptr, tinstr); - tinstr = __mem_to_opcode_thumb16(tinstr); + + fault = alignment_get_thumb(regs, ptr, &tinstr); if (!fault) { if (cpu_architecture() >= CPU_ARCH_ARMv7 && IS_T32(tinstr)) { /* Thumb-2 32-bit */ - u16 tinst2 = 0; - fault = probe_kernel_address(ptr + 1, tinst2); - tinst2 = __mem_to_opcode_thumb16(tinst2); + u16 tinst2; + fault = alignment_get_thumb(regs, ptr + 1, &tinst2); instr = __opcode_thumb32_compose(tinstr, tinst2); thumb2_32b = 1; } else { @@ -803,8 +832,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) } } } else { - fault = probe_kernel_address((void *)instrptr, instr); - instr = __mem_to_opcode_arm(instr); + fault = alignment_get_arm(regs, (void *)instrptr, &instr); } if (fault) { -- GitLab From 1bb9fb0a147f9db11a34b2469ba5a52fc70b0349 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 6 Sep 2019 16:07:54 +0100 Subject: [PATCH 149/993] ARM: mm: alignment: use "u32" for 32-bit instructions Rather than using "unsigned long", use "u32" for 32-bit instructions in the alignment fault handler. Signed-off-by: Russell King --- arch/arm/mm/alignment.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 6587432faf05..788c5cf46de5 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -324,7 +324,7 @@ union offset_union { __put32_unaligned_check("strbt", val, addr) static void -do_alignment_finish_ldst(unsigned long addr, unsigned long instr, struct pt_regs *regs, union offset_union offset) +do_alignment_finish_ldst(unsigned long addr, u32 instr, struct pt_regs *regs, union offset_union offset) { if (!LDST_U_BIT(instr)) offset.un = -offset.un; @@ -337,7 +337,7 @@ do_alignment_finish_ldst(unsigned long addr, unsigned long instr, struct pt_regs } static int -do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *regs) +do_alignment_ldrhstrh(unsigned long addr, u32 instr, struct pt_regs *regs) { unsigned int rd = RD_BITS(instr); @@ -386,8 +386,7 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r } static int -do_alignment_ldrdstrd(unsigned long addr, unsigned long instr, - struct pt_regs *regs) +do_alignment_ldrdstrd(unsigned long addr, u32 instr, struct pt_regs *regs) { unsigned int rd = RD_BITS(instr); unsigned int rd2; @@ -449,7 +448,7 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr, } static int -do_alignment_ldrstr(unsigned long addr, unsigned long instr, struct pt_regs *regs) +do_alignment_ldrstr(unsigned long addr, u32 instr, struct pt_regs *regs) { unsigned int rd = RD_BITS(instr); @@ -498,7 +497,7 @@ do_alignment_ldrstr(unsigned long addr, unsigned long instr, struct pt_regs *reg * PU = 10 A B */ static int -do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *regs) +do_alignment_ldmstm(unsigned long addr, u32 instr, struct pt_regs *regs) { unsigned int rd, rn, correction, nr_regs, regbits; unsigned long eaddr, newaddr; @@ -539,7 +538,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg * processor for us. */ if (addr != eaddr) { - pr_err("LDMSTM: PC = %08lx, instr = %08lx, " + pr_err("LDMSTM: PC = %08lx, instr = %08x, " "addr = %08lx, eaddr = %08lx\n", instruction_pointer(regs), instr, addr, eaddr); show_regs(regs); @@ -716,10 +715,10 @@ thumb2arm(u16 tinstr) * 2. Register name Rt from ARMv7 is same as Rd from ARMv6 (Rd is Rt) */ static void * -do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs, +do_alignment_t32_to_handler(u32 *pinstr, struct pt_regs *regs, union offset_union *poffset) { - unsigned long instr = *pinstr; + u32 instr = *pinstr; u16 tinst1 = (instr >> 16) & 0xffff; u16 tinst2 = instr & 0xffff; @@ -767,7 +766,7 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs, return NULL; } -static int alignment_get_arm(struct pt_regs *regs, u32 *ip, unsigned long *inst) +static int alignment_get_arm(struct pt_regs *regs, u32 *ip, u32 *inst) { u32 instr = 0; int fault; @@ -801,9 +800,10 @@ static int do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { union offset_union uninitialized_var(offset); - unsigned long instr = 0, instrptr; - int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs); + unsigned long instrptr; + int (*handler)(unsigned long addr, u32 instr, struct pt_regs *regs); unsigned int type; + u32 instr = 0; u16 tinstr = 0; int isize = 4; int thumb2_32b = 0; @@ -954,7 +954,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) * Oops, we didn't handle the instruction. */ pr_err("Alignment trap: not handling instruction " - "%0*lx at [<%08lx>]\n", + "%0*x at [<%08lx>]\n", isize << 1, isize == 2 ? tinstr : instr, instrptr); ai_skipped += 1; @@ -964,7 +964,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) ai_user += 1; if (ai_usermode & UM_WARN) - printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx " + printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*x " "Address=0x%08lx FSR 0x%03x\n", current->comm, task_pid_nr(current), instrptr, isize << 1, -- GitLab From 5da202c88f8c355ad79bc2e8eb582e6d433060e7 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 7 Oct 2019 17:43:04 +0200 Subject: [PATCH 150/993] net: stmmac: fix length of PTP clock's name string The field "name" in struct ptp_clock_info has a fixed size of 16 chars and is used as zero terminated string by clock_name_show() in drivers/ptp/ptp_sysfs.c The current initialization value requires 17 chars to fit also the null termination, and this causes overflow to the next bytes in the struct when the string is read as null terminated: hexdump -C /sys/class/ptp/ptp0/clock_name 00000000 73 74 6d 6d 61 63 5f 70 74 70 5f 63 6c 6f 63 6b |stmmac_ptp_clock| 00000010 a0 ac b9 03 0a |.....| where the extra 4 bytes (excluding the newline) after the string represent the integer 0x03b9aca0 = 62500000 assigned to the field "max_adj" that follows "name" in the same struct. There is no strict requirement for the "name" content and in the comment in ptp_clock_kernel.h it's reported it should just be 'A short "friendly name" to identify the clock'. Replace it with "stmmac ptp". Signed-off-by: Antonio Borneo Fixes: 92ba6888510c ("stmmac: add the support for PTP hw clock driver") Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c index 173493db038c..df638b18b72c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c @@ -164,7 +164,7 @@ static int stmmac_enable(struct ptp_clock_info *ptp, /* structure describing a PTP hardware clock */ static struct ptp_clock_info stmmac_ptp_clock_ops = { .owner = THIS_MODULE, - .name = "stmmac_ptp_clock", + .name = "stmmac ptp", .max_adj = 62500000, .n_alarm = 0, .n_ext_ts = 0, -- GitLab From 520cf6002147281d1e7b522bb338416b623dcb93 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 7 Oct 2019 17:43:05 +0200 Subject: [PATCH 151/993] net: stmmac: fix disabling flexible PPS output Accordingly to Synopsys documentation [1] and [2], when bit PPSEN0 in register MAC_PPS_CONTROL is set it selects the functionality command in the same register, otherwise selects the functionality control. Command functionality is required to either enable (command 0x2) and disable (command 0x5) the flexible PPS output, but the bit PPSEN0 is currently set only for enabling. Set the bit PPSEN0 to properly disable flexible PPS output. Tested on STM32MP15x, based on dwmac 4.10a. [1] DWC Ethernet QoS Databook 4.10a October 2014 [2] DWC Ethernet QoS Databook 5.00a September 2017 Signed-off-by: Antonio Borneo Fixes: 9a8a02c9d46d ("net: stmmac: Add Flexible PPS support") Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c index 3f4f3132e16b..e436fa160c7d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c @@ -515,6 +515,7 @@ int dwmac5_flex_pps_config(void __iomem *ioaddr, int index, if (!enable) { val |= PPSCMDx(index, 0x5); + val |= PPSEN0; writel(val, ioaddr + MAC_PPS_CONTROL); return 0; } -- GitLab From a7137534b597b7c303203e6bc3ed87e87a273bb8 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 7 Oct 2019 15:43:01 -0700 Subject: [PATCH 152/993] bonding: fix potential NULL deref in bond_update_slave_arr syzbot got a NULL dereference in bond_update_slave_arr() [1], happening after a failure to allocate bond->slave_arr A workqueue (bond_slave_arr_handler) is supposed to retry the allocation later, but if the slave is removed before the workqueue had a chance to complete, bond->slave_arr can still be NULL. [1] Failed to build slave-array. kasan: CONFIG_KASAN_INLINE enabled kasan: GPF could be caused by NULL-ptr deref or user memory access general protection fault: 0000 [#1] SMP KASAN PTI Modules linked in: Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:bond_update_slave_arr.cold+0xc6/0x198 drivers/net/bonding/bond_main.c:4039 RSP: 0018:ffff88018fe33678 EFLAGS: 00010246 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffc9000290b000 RDX: 0000000000000000 RSI: ffffffff82b63037 RDI: ffff88019745ea20 RBP: ffff88018fe33760 R08: ffff880170754280 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: ffff88019745ea00 R14: 0000000000000000 R15: ffff88018fe338b0 FS: 00007febd837d700(0000) GS:ffff8801dad00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000004540a0 CR3: 00000001c242e005 CR4: 00000000001626f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: [] __bond_release_one+0x43e/0x500 drivers/net/bonding/bond_main.c:1923 [] bond_release drivers/net/bonding/bond_main.c:2039 [inline] [] bond_do_ioctl+0x416/0x870 drivers/net/bonding/bond_main.c:3562 [] dev_ifsioc+0x6f4/0x940 net/core/dev_ioctl.c:328 [] dev_ioctl+0x1b8/0xc70 net/core/dev_ioctl.c:495 [] sock_do_ioctl+0x1bd/0x300 net/socket.c:1088 [] sock_ioctl+0x300/0x5d0 net/socket.c:1196 [] vfs_ioctl fs/ioctl.c:47 [inline] [] file_ioctl fs/ioctl.c:501 [inline] [] do_vfs_ioctl+0xacb/0x1300 fs/ioctl.c:688 [] SYSC_ioctl fs/ioctl.c:705 [inline] [] SyS_ioctl+0xb6/0xe0 fs/ioctl.c:696 [] do_syscall_64+0x528/0x770 arch/x86/entry/common.c:305 [] entry_SYSCALL_64_after_hwframe+0x42/0xb7 Fixes: ee6377147409 ("bonding: Simplify the xmit function for modes that use xmit_hash") Signed-off-by: Eric Dumazet Reported-by: syzbot Cc: Mahesh Bandewar Signed-off-by: Jakub Kicinski --- drivers/net/bonding/bond_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 931d9d935686..21d8fcc83c9c 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4039,7 +4039,7 @@ int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave) * this to-be-skipped slave to send a packet out. */ old_arr = rtnl_dereference(bond->slave_arr); - for (idx = 0; idx < old_arr->count; idx++) { + for (idx = 0; old_arr != NULL && idx < old_arr->count; idx++) { if (skipslave == old_arr->arr[idx]) { old_arr->arr[idx] = old_arr->arr[old_arr->count-1]; -- GitLab From 819be8108fded0b9e710bbbf81193e52f7bab2f7 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Tue, 8 Oct 2019 19:09:23 +0800 Subject: [PATCH 153/993] sctp: add chunks to sk_backlog when the newsk sk_socket is not set This patch is to fix a NULL-ptr deref in selinux_socket_connect_helper: [...] kasan: GPF could be caused by NULL-ptr deref or user memory access [...] RIP: 0010:selinux_socket_connect_helper+0x94/0x460 [...] Call Trace: [...] selinux_sctp_bind_connect+0x16a/0x1d0 [...] security_sctp_bind_connect+0x58/0x90 [...] sctp_process_asconf+0xa52/0xfd0 [sctp] [...] sctp_sf_do_asconf+0x785/0x980 [sctp] [...] sctp_do_sm+0x175/0x5a0 [sctp] [...] sctp_assoc_bh_rcv+0x285/0x5b0 [sctp] [...] sctp_backlog_rcv+0x482/0x910 [sctp] [...] __release_sock+0x11e/0x310 [...] release_sock+0x4f/0x180 [...] sctp_accept+0x3f9/0x5a0 [sctp] [...] inet_accept+0xe7/0x720 It was caused by that the 'newsk' sk_socket was not set before going to security sctp hook when processing asconf chunk with SCTP_PARAM_ADD_IP or SCTP_PARAM_SET_PRIMARY: inet_accept()-> sctp_accept(): lock_sock(): lock listening 'sk' do_softirq(): sctp_rcv(): <-- [1] asconf chunk arrives and enqueued in 'sk' backlog sctp_sock_migrate(): set asoc's sk to 'newsk' release_sock(): sctp_backlog_rcv(): lock 'newsk' sctp_process_asconf() <-- [2] unlock 'newsk' sock_graft(): set sk_socket <-- [3] As it shows, at [1] the asconf chunk would be put into the listening 'sk' backlog, as accept() was holding its sock lock. Then at [2] asconf would get processed with 'newsk' as asoc's sk had been set to 'newsk'. However, 'newsk' sk_socket is not set until [3], while selinux_sctp_bind_connect() would deref it, then kernel crashed. Here to fix it by adding the chunk to sk_backlog until newsk sk_socket is set when .accept() is done. Note that sk->sk_socket can be NULL when the sock is closed, so SOCK_DEAD flag is also needed to check in sctp_newsk_ready(). Thanks to Ondrej for reviewing the code. Fixes: d452930fd3b9 ("selinux: Add SCTP support") Reported-by: Ying Xu Suggested-by: Marcelo Ricardo Leitner Signed-off-by: Xin Long Acked-by: Marcelo Ricardo Leitner Acked-by: Neil Horman Signed-off-by: Jakub Kicinski --- include/net/sctp/sctp.h | 5 +++++ net/sctp/input.c | 12 +++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 5d60f13d2347..3ab5c6bbb90b 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -610,4 +610,9 @@ static inline __u32 sctp_min_frag_point(struct sctp_sock *sp, __u16 datasize) return sctp_mtu_payload(sp, SCTP_DEFAULT_MINSEGMENT, datasize); } +static inline bool sctp_newsk_ready(const struct sock *sk) +{ + return sock_flag(sk, SOCK_DEAD) || sk->sk_socket; +} + #endif /* __net_sctp_h__ */ diff --git a/net/sctp/input.c b/net/sctp/input.c index 5a070fb5b278..f2771375bfc0 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -243,7 +243,7 @@ int sctp_rcv(struct sk_buff *skb) bh_lock_sock(sk); } - if (sock_owned_by_user(sk)) { + if (sock_owned_by_user(sk) || !sctp_newsk_ready(sk)) { if (sctp_add_backlog(sk, skb)) { bh_unlock_sock(sk); sctp_chunk_free(chunk); @@ -321,7 +321,7 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) local_bh_disable(); bh_lock_sock(sk); - if (sock_owned_by_user(sk)) { + if (sock_owned_by_user(sk) || !sctp_newsk_ready(sk)) { if (sk_add_backlog(sk, skb, sk->sk_rcvbuf)) sctp_chunk_free(chunk); else @@ -336,7 +336,13 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) if (backloged) return 0; } else { - sctp_inq_push(inqueue, chunk); + if (!sctp_newsk_ready(sk)) { + if (!sk_add_backlog(sk, skb, sk->sk_rcvbuf)) + return 0; + sctp_chunk_free(chunk); + } else { + sctp_inq_push(inqueue, chunk); + } } done: -- GitLab From 9db74e51ec08d75c3e97f851299bc25e645cc5ad Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 8 Oct 2019 08:39:04 -0700 Subject: [PATCH 154/993] phylink: fix kernel-doc warnings Fix kernel-doc warnings in phylink.c: ../drivers/net/phy/phylink.c:595: warning: Function parameter or member 'config' not described in 'phylink_create' ../drivers/net/phy/phylink.c:595: warning: Excess function parameter 'ndev' description in 'phylink_create' Fixes: 8796c8923d9c ("phylink: add documentation for kernel APIs") Signed-off-by: Randy Dunlap Cc: Russell King Signed-off-by: Jakub Kicinski --- drivers/net/phy/phylink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index a5a57ca94c1a..20e2ebe458f2 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -576,7 +576,7 @@ static int phylink_register_sfp(struct phylink *pl, /** * phylink_create() - create a phylink instance - * @ndev: a pointer to the &struct net_device + * @config: a pointer to the target &struct phylink_config * @fwnode: a pointer to a &struct fwnode_handle describing the network * interface * @iface: the desired link mode defined by &typedef phy_interface_t -- GitLab From b528965bcc827dad32a8d21745feaacfc76c9703 Mon Sep 17 00:00:00 2001 From: Alexandra Winter Date: Tue, 8 Oct 2019 18:21:06 +0200 Subject: [PATCH 155/993] s390/qeth: Fix error handling during VNICC initialization Smatch discovered the use of uninitialized variable sup_cmds in error paths. Fixes: caa1f0b10d18 ("s390/qeth: add VNICC enable/disable support") Signed-off-by: Alexandra Winter Signed-off-by: Julian Wiedmann Signed-off-by: Jakub Kicinski --- drivers/s390/net/qeth_l2_main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index b8799cd3e7aa..de62a9ccc882 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -2021,10 +2021,10 @@ static bool qeth_l2_vnicc_recover_char(struct qeth_card *card, u32 vnicc, static void qeth_l2_vnicc_init(struct qeth_card *card) { u32 *timeout = &card->options.vnicc.learning_timeout; + bool enable, error = false; unsigned int chars_len, i; unsigned long chars_tmp; u32 sup_cmds, vnicc; - bool enable, error; QETH_CARD_TEXT(card, 2, "vniccini"); /* reset rx_bcast */ @@ -2045,7 +2045,10 @@ static void qeth_l2_vnicc_init(struct qeth_card *card) chars_len = sizeof(card->options.vnicc.sup_chars) * BITS_PER_BYTE; for_each_set_bit(i, &chars_tmp, chars_len) { vnicc = BIT(i); - qeth_l2_vnicc_query_cmds(card, vnicc, &sup_cmds); + if (qeth_l2_vnicc_query_cmds(card, vnicc, &sup_cmds)) { + sup_cmds = 0; + error = true; + } if (!(sup_cmds & IPA_VNICC_SET_TIMEOUT) || !(sup_cmds & IPA_VNICC_GET_TIMEOUT)) card->options.vnicc.getset_timeout_sup &= ~vnicc; @@ -2054,8 +2057,8 @@ static void qeth_l2_vnicc_init(struct qeth_card *card) card->options.vnicc.set_char_sup &= ~vnicc; } /* enforce assumed default values and recover settings, if changed */ - error = qeth_l2_vnicc_recover_timeout(card, QETH_VNICC_LEARNING, - timeout); + error |= qeth_l2_vnicc_recover_timeout(card, QETH_VNICC_LEARNING, + timeout); chars_tmp = card->options.vnicc.wanted_chars ^ QETH_VNICC_DEFAULT; chars_tmp |= QETH_VNICC_BRIDGE_INVISIBLE; chars_len = sizeof(card->options.vnicc.wanted_chars) * BITS_PER_BYTE; -- GitLab From be40a86c319706f90caca144343c64743c32b953 Mon Sep 17 00:00:00 2001 From: Alexandra Winter Date: Tue, 8 Oct 2019 18:21:07 +0200 Subject: [PATCH 156/993] s390/qeth: Fix initialization of vnicc cmd masks during set online Without this patch, a command bit in the supported commands mask is only ever set to unsupported during set online. If a command is ever marked as unsupported (e.g. because of error during qeth_l2_vnicc_query_cmds), subsequent successful initialization (offline/online) would not bring it back. Fixes: caa1f0b10d18 ("s390/qeth: add VNICC enable/disable support") Signed-off-by: Alexandra Winter Signed-off-by: Julian Wiedmann Signed-off-by: Jakub Kicinski --- drivers/s390/net/qeth_l2_main.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index de62a9ccc882..bd8143e51747 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -2049,11 +2049,15 @@ static void qeth_l2_vnicc_init(struct qeth_card *card) sup_cmds = 0; error = true; } - if (!(sup_cmds & IPA_VNICC_SET_TIMEOUT) || - !(sup_cmds & IPA_VNICC_GET_TIMEOUT)) + if ((sup_cmds & IPA_VNICC_SET_TIMEOUT) && + (sup_cmds & IPA_VNICC_GET_TIMEOUT)) + card->options.vnicc.getset_timeout_sup |= vnicc; + else card->options.vnicc.getset_timeout_sup &= ~vnicc; - if (!(sup_cmds & IPA_VNICC_ENABLE) || - !(sup_cmds & IPA_VNICC_DISABLE)) + if ((sup_cmds & IPA_VNICC_ENABLE) && + (sup_cmds & IPA_VNICC_DISABLE)) + card->options.vnicc.set_char_sup |= vnicc; + else card->options.vnicc.set_char_sup &= ~vnicc; } /* enforce assumed default values and recover settings, if changed */ -- GitLab From a954380acde6adf584de76c41e1d520097820dd5 Mon Sep 17 00:00:00 2001 From: Vinicius Costa Gomes Date: Tue, 8 Oct 2019 16:20:07 -0700 Subject: [PATCH 157/993] net: taprio: Fix returning EINVAL when configuring without flags When configuring a taprio instance if "flags" is not specified (or it's zero), taprio currently replies with an "Invalid argument" error. So, set the return value to zero after we are done with all the checks. Fixes: 9c66d1564676 ("taprio: Add support for hardware offloading") Signed-off-by: Vinicius Costa Gomes Acked-by: Vladimir Oltean Signed-off-by: Jakub Kicinski --- net/sched/sch_taprio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 68b543f85a96..6719a65169d4 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -1341,6 +1341,10 @@ static int taprio_parse_clockid(struct Qdisc *sch, struct nlattr **tb, NL_SET_ERR_MSG(extack, "Specifying a 'clockid' is mandatory"); goto out; } + + /* Everything went ok, return success. */ + err = 0; + out: return err; } -- GitLab From 11c9a7d38af524217efb7a176ad322b97ac2f163 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Wed, 9 Oct 2019 11:10:52 +0800 Subject: [PATCH 158/993] act_mirred: Fix mirred_init_module error handling If tcf_register_action failed, mirred_device_notifier should be unregistered. Fixes: 3b87956ea645 ("net sched: fix race in mirred device removal") Signed-off-by: YueHaibing Signed-off-by: Jakub Kicinski --- net/sched/act_mirred.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 9ce073a05414..08923b21e566 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -484,7 +484,11 @@ static int __init mirred_init_module(void) return err; pr_info("Mirror/redirect action on\n"); - return tcf_register_action(&act_mirred_ops, &mirred_net_ops); + err = tcf_register_action(&act_mirred_ops, &mirred_net_ops); + if (err) + unregister_netdevice_notifier(&mirred_device_notifier); + + return err; } static void __exit mirred_cleanup_module(void) -- GitLab From e0ae2c578d3909e60e9448207f5d83f785f1129f Mon Sep 17 00:00:00 2001 From: Daniele Palmas Date: Wed, 9 Oct 2019 11:07:18 +0200 Subject: [PATCH 159/993] net: usb: qmi_wwan: add Telit 0x1050 composition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds support for Telit FN980 0x1050 composition 0x1050: tty, adb, rmnet, tty, tty, tty, tty Signed-off-by: Daniele Palmas Acked-by: Bjørn Mork Signed-off-by: Jakub Kicinski --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 3d77cd402ba9..596428ec71df 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1327,6 +1327,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */ {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */ {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */ {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ -- GitLab From 35a79a63517981a8aea395497c548776347deda8 Mon Sep 17 00:00:00 2001 From: Allen Pais Date: Wed, 18 Sep 2019 22:06:58 +0530 Subject: [PATCH 160/993] scsi: qla2xxx: fix a potential NULL pointer dereference alloc_workqueue is not checked for errors and as a result a potential NULL dereference could occur. Link: https://lore.kernel.org/r/1568824618-4366-1-git-send-email-allen.pais@oracle.com Signed-off-by: Allen Pais Reviewed-by: Martin Wilck Acked-by: Himanshu Madhani Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index ee47de9fbc05..e4d765fc03ea 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3224,6 +3224,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) req->req_q_in, req->req_q_out, rsp->rsp_q_in, rsp->rsp_q_out); ha->wq = alloc_workqueue("qla2xxx_wq", 0, 0); + if (unlikely(!ha->wq)) { + ret = -ENOMEM; + goto probe_failed; + } if (ha->isp_ops->initialize_adapter(base_vha)) { ql_log(ql_log_fatal, base_vha, 0x00d6, -- GitLab From b6ce6fb121a655aefe41dccc077141c102145a37 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 7 Oct 2019 15:57:01 +0200 Subject: [PATCH 161/993] scsi: scsi_dh_alua: handle RTPG sense code correctly during state transitions Some arrays are not capable of returning RTPG data during state transitioning, but rather return an 'LUN not accessible, asymmetric access state transition' sense code. In these cases we can set the state to 'transitioning' directly and don't need to evaluate the RTPG data (which we won't have anyway). Link: https://lore.kernel.org/r/20191007135701.32389-1-hare@suse.de Reviewed-by: Laurence Oberman Reviewed-by: Ewan D. Milne Reviewed-by: Bart Van Assche Signed-off-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index f0066f8a1786..c6437a442ffc 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -511,6 +511,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) unsigned int tpg_desc_tbl_off; unsigned char orig_transition_tmo; unsigned long flags; + bool transitioning_sense = false; if (!pg->expiry) { unsigned long transition_tmo = ALUA_FAILOVER_TIMEOUT * HZ; @@ -571,13 +572,19 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) goto retry; } /* - * Retry on ALUA state transition or if any - * UNIT ATTENTION occurred. + * If the array returns with 'ALUA state transition' + * sense code here it cannot return RTPG data during + * transition. So set the state to 'transitioning' directly. */ if (sense_hdr.sense_key == NOT_READY && - sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) - err = SCSI_DH_RETRY; - else if (sense_hdr.sense_key == UNIT_ATTENTION) + sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) { + transitioning_sense = true; + goto skip_rtpg; + } + /* + * Retry on any other UNIT ATTENTION occurred. + */ + if (sense_hdr.sense_key == UNIT_ATTENTION) err = SCSI_DH_RETRY; if (err == SCSI_DH_RETRY && pg->expiry != 0 && time_before(jiffies, pg->expiry)) { @@ -665,7 +672,11 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) off = 8 + (desc[7] * 4); } + skip_rtpg: spin_lock_irqsave(&pg->lock, flags); + if (transitioning_sense) + pg->state = SCSI_ACCESS_STATE_TRANSITIONING; + sdev_printk(KERN_INFO, sdev, "%s: port group %02x state %c %s supports %c%c%c%c%c%c%c\n", ALUA_DH_NAME, pg->group_id, print_alua_state(pg->state), -- GitLab From 0ee6211408a8e939428f662833c7301394125b80 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Wed, 9 Oct 2019 17:11:18 +0200 Subject: [PATCH 162/993] scsi: sni_53c710: fix compilation error Drop out memory dev_printk() with wrong device pointer argument. [mkp: typo] Link: https://lore.kernel.org/r/20191009151118.32350-1-tbogendoerfer@suse.de Signed-off-by: Thomas Bogendoerfer Signed-off-by: Martin K. Petersen --- drivers/scsi/sni_53c710.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c index aef4881d8e21..a85d52b5dc32 100644 --- a/drivers/scsi/sni_53c710.c +++ b/drivers/scsi/sni_53c710.c @@ -66,10 +66,8 @@ static int snirm710_probe(struct platform_device *dev) base = res->start; hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL); - if (!hostdata) { - dev_printk(KERN_ERR, dev, "Failed to allocate host data\n"); + if (!hostdata) return -ENOMEM; - } hostdata->dev = &dev->dev; dma_set_mask(&dev->dev, DMA_BIT_MASK(32)); -- GitLab From 8cbf0c173aa096dda526d1ccd66fc751c31da346 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Wed, 9 Oct 2019 17:11:28 +0200 Subject: [PATCH 163/993] scsi: fix kconfig dependency warning related to 53C700_LE_ON_BE When building a kernel with SCSI_SNI_53C710 enabled, Kconfig warns: WARNING: unmet direct dependencies detected for 53C700_LE_ON_BE Depends on [n]: SCSI_LOWLEVEL [=y] && SCSI [=y] && SCSI_LASI700 [=n] Selected by [y]: - SCSI_SNI_53C710 [=y] && SCSI_LOWLEVEL [=y] && SNI_RM [=y] && SCSI [=y] Add the missing depends SCSI_SNI_53C710 to 53C700_LE_ON_BE to fix it. Link: https://lore.kernel.org/r/20191009151128.32411-1-tbogendoerfer@suse.de Signed-off-by: Thomas Bogendoerfer Signed-off-by: Martin K. Petersen --- drivers/scsi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 75f66f8ad3ea..d00e1ee09af3 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -898,7 +898,7 @@ config SCSI_SNI_53C710 config 53C700_LE_ON_BE bool - depends on SCSI_LASI700 + depends on SCSI_LASI700 || SCSI_SNI_53C710 default y config SCSI_STEX -- GitLab From 6a0990eaa768dfb7064f06777743acc6d392084b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 9 Oct 2019 10:35:36 -0700 Subject: [PATCH 164/993] scsi: ch: Make it possible to open a ch device multiple times again Clearing ch->device in ch_release() is wrong because that pointer must remain valid until ch_remove() is called. This patch fixes the following crash the second time a ch device is opened: BUG: kernel NULL pointer dereference, address: 0000000000000790 RIP: 0010:scsi_device_get+0x5/0x60 Call Trace: ch_open+0x4c/0xa0 [ch] chrdev_open+0xa2/0x1c0 do_dentry_open+0x13a/0x380 path_openat+0x591/0x1470 do_filp_open+0x91/0x100 do_sys_open+0x184/0x220 do_syscall_64+0x5f/0x1a0 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Fixes: 085e56766f74 ("scsi: ch: add refcounting") Cc: Hannes Reinecke Cc: Link: https://lore.kernel.org/r/20191009173536.247889-1-bvanassche@acm.org Reported-by: Rob Turk Suggested-by: Rob Turk Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/ch.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index 5f8153c37f77..76751d6c7f0d 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -579,7 +579,6 @@ ch_release(struct inode *inode, struct file *file) scsi_changer *ch = file->private_data; scsi_device_put(ch->device); - ch->device = NULL; file->private_data = NULL; kref_put(&ch->ref, ch_destroy); return 0; -- GitLab From 993e4c929a073595d22c85f59082f0c387e31c21 Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Wed, 9 Oct 2019 11:19:10 +0200 Subject: [PATCH 165/993] netns: fix NLM_F_ECHO mechanism for RTM_NEWNSID The flag NLM_F_ECHO aims to reply to the user the message notified to all listeners. It was not the case with the command RTM_NEWNSID, let's fix this. Fixes: 0c7aecd4bde4 ("netns: add rtnl cmd to add and get peer netns ids") Reported-by: Guillaume Nault Signed-off-by: Nicolas Dichtel Acked-by: Guillaume Nault Tested-by: Guillaume Nault Signed-off-by: Jakub Kicinski --- net/core/net_namespace.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index a0e0d298c991..6d3e4821b02d 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -245,7 +245,8 @@ static int __peernet2id(struct net *net, struct net *peer) return __peernet2id_alloc(net, peer, &no); } -static void rtnl_net_notifyid(struct net *net, int cmd, int id); +static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid, + struct nlmsghdr *nlh); /* This function returns the id of a peer netns. If no id is assigned, one will * be allocated and returned. */ @@ -268,7 +269,7 @@ int peernet2id_alloc(struct net *net, struct net *peer) id = __peernet2id_alloc(net, peer, &alloc); spin_unlock_bh(&net->nsid_lock); if (alloc && id >= 0) - rtnl_net_notifyid(net, RTM_NEWNSID, id); + rtnl_net_notifyid(net, RTM_NEWNSID, id, 0, NULL); if (alive) put_net(peer); return id; @@ -532,7 +533,7 @@ static void unhash_nsid(struct net *net, struct net *last) idr_remove(&tmp->netns_ids, id); spin_unlock_bh(&tmp->nsid_lock); if (id >= 0) - rtnl_net_notifyid(tmp, RTM_DELNSID, id); + rtnl_net_notifyid(tmp, RTM_DELNSID, id, 0, NULL); if (tmp == last) break; } @@ -764,7 +765,8 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh, err = alloc_netid(net, peer, nsid); spin_unlock_bh(&net->nsid_lock); if (err >= 0) { - rtnl_net_notifyid(net, RTM_NEWNSID, err); + rtnl_net_notifyid(net, RTM_NEWNSID, err, NETLINK_CB(skb).portid, + nlh); err = 0; } else if (err == -ENOSPC && nsid >= 0) { err = -EEXIST; @@ -1051,9 +1053,12 @@ static int rtnl_net_dumpid(struct sk_buff *skb, struct netlink_callback *cb) return err < 0 ? err : skb->len; } -static void rtnl_net_notifyid(struct net *net, int cmd, int id) +static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid, + struct nlmsghdr *nlh) { struct net_fill_args fillargs = { + .portid = portid, + .seq = nlh ? nlh->nlmsg_seq : 0, .cmd = cmd, .nsid = id, }; @@ -1068,7 +1073,7 @@ static void rtnl_net_notifyid(struct net *net, int cmd, int id) if (err < 0) goto err_out; - rtnl_notify(msg, net, 0, RTNLGRP_NSID, NULL, 0); + rtnl_notify(msg, net, portid, RTNLGRP_NSID, nlh, 0); return; err_out: -- GitLab From e37542ba111f3974dc622ae0a21c1787318de500 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 9 Oct 2019 09:19:13 -0700 Subject: [PATCH 166/993] netfilter: conntrack: avoid possible false sharing As hinted by KCSAN, we need at least one READ_ONCE() to prevent a compiler optimization. More details on : https://github.com/google/ktsan/wiki/READ_ONCE-and-WRITE_ONCE#it-may-improve-performance sysbot report : BUG: KCSAN: data-race in __nf_ct_refresh_acct / __nf_ct_refresh_acct read to 0xffff888123eb4f08 of 4 bytes by interrupt on cpu 0: __nf_ct_refresh_acct+0xd4/0x1b0 net/netfilter/nf_conntrack_core.c:1796 nf_ct_refresh_acct include/net/netfilter/nf_conntrack.h:201 [inline] nf_conntrack_tcp_packet+0xd40/0x3390 net/netfilter/nf_conntrack_proto_tcp.c:1161 nf_conntrack_handle_packet net/netfilter/nf_conntrack_core.c:1633 [inline] nf_conntrack_in+0x410/0xaa0 net/netfilter/nf_conntrack_core.c:1727 ipv4_conntrack_in+0x27/0x40 net/netfilter/nf_conntrack_proto.c:178 nf_hook_entry_hookfn include/linux/netfilter.h:135 [inline] nf_hook_slow+0x83/0x160 net/netfilter/core.c:512 nf_hook include/linux/netfilter.h:260 [inline] NF_HOOK include/linux/netfilter.h:303 [inline] ip_rcv+0x12f/0x1a0 net/ipv4/ip_input.c:523 __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5004 __netif_receive_skb+0x37/0xf0 net/core/dev.c:5118 netif_receive_skb_internal+0x59/0x190 net/core/dev.c:5208 napi_skb_finish net/core/dev.c:5671 [inline] napi_gro_receive+0x28f/0x330 net/core/dev.c:5704 receive_buf+0x284/0x30b0 drivers/net/virtio_net.c:1061 virtnet_receive drivers/net/virtio_net.c:1323 [inline] virtnet_poll+0x436/0x7d0 drivers/net/virtio_net.c:1428 napi_poll net/core/dev.c:6352 [inline] net_rx_action+0x3ae/0xa50 net/core/dev.c:6418 __do_softirq+0x115/0x33f kernel/softirq.c:292 write to 0xffff888123eb4f08 of 4 bytes by task 7191 on cpu 1: __nf_ct_refresh_acct+0xfb/0x1b0 net/netfilter/nf_conntrack_core.c:1797 nf_ct_refresh_acct include/net/netfilter/nf_conntrack.h:201 [inline] nf_conntrack_tcp_packet+0xd40/0x3390 net/netfilter/nf_conntrack_proto_tcp.c:1161 nf_conntrack_handle_packet net/netfilter/nf_conntrack_core.c:1633 [inline] nf_conntrack_in+0x410/0xaa0 net/netfilter/nf_conntrack_core.c:1727 ipv4_conntrack_local+0xbe/0x130 net/netfilter/nf_conntrack_proto.c:200 nf_hook_entry_hookfn include/linux/netfilter.h:135 [inline] nf_hook_slow+0x83/0x160 net/netfilter/core.c:512 nf_hook include/linux/netfilter.h:260 [inline] __ip_local_out+0x1f7/0x2b0 net/ipv4/ip_output.c:114 ip_local_out+0x31/0x90 net/ipv4/ip_output.c:123 __ip_queue_xmit+0x3a8/0xa40 net/ipv4/ip_output.c:532 ip_queue_xmit+0x45/0x60 include/net/ip.h:236 __tcp_transmit_skb+0xdeb/0x1cd0 net/ipv4/tcp_output.c:1158 __tcp_send_ack+0x246/0x300 net/ipv4/tcp_output.c:3685 tcp_send_ack+0x34/0x40 net/ipv4/tcp_output.c:3691 tcp_cleanup_rbuf+0x130/0x360 net/ipv4/tcp.c:1575 Reported by Kernel Concurrency Sanitizer on: CPU: 1 PID: 7191 Comm: syz-fuzzer Not tainted 5.3.0+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Fixes: cc16921351d8 ("netfilter: conntrack: avoid same-timeout update") Signed-off-by: Eric Dumazet Reported-by: syzbot Cc: Jozsef Kadlecsik Cc: Florian Westphal Acked-by: Pablo Neira Ayuso Signed-off-by: Jakub Kicinski --- net/netfilter/nf_conntrack_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 0c63120b2db2..5cd610b547e0 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1792,8 +1792,8 @@ void __nf_ct_refresh_acct(struct nf_conn *ct, if (nf_ct_is_confirmed(ct)) extra_jiffies += nfct_time_stamp; - if (ct->timeout != extra_jiffies) - ct->timeout = extra_jiffies; + if (READ_ONCE(ct->timeout) != extra_jiffies) + WRITE_ONCE(ct->timeout, extra_jiffies); acct: if (do_acct) nf_ct_acct_update(ct, ctinfo, skb->len); -- GitLab From 4ffdd22e49f47db543906d75453a0048a53071ab Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 9 Oct 2019 09:20:02 -0700 Subject: [PATCH 167/993] tun: remove possible false sharing in tun_flow_update() As mentioned in https://github.com/google/ktsan/wiki/READ_ONCE-and-WRITE_ONCE#it-may-improve-performance a C compiler can legally transform if (e->queue_index != queue_index) e->queue_index = queue_index; to : e->queue_index = queue_index; Note that the code using jiffies has no issue, since jiffies has volatile attribute. if (e->updated != jiffies) e->updated = jiffies; Fixes: 83b1bc122cab ("tun: align write-heavy flow entry members to a cache line") Signed-off-by: Eric Dumazet Cc: Zhang Yu Cc: Wang Li Cc: Li RongQing Acked-by: Jason Wang Signed-off-by: Jakub Kicinski --- drivers/net/tun.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 812dc3a65efb..a8d3141582a5 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -526,8 +526,8 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash, e = tun_flow_find(head, rxhash); if (likely(e)) { /* TODO: keep queueing to old queue until it's empty? */ - if (e->queue_index != queue_index) - e->queue_index = queue_index; + if (READ_ONCE(e->queue_index) != queue_index) + WRITE_ONCE(e->queue_index, queue_index); if (e->updated != jiffies) e->updated = jiffies; sock_rps_record_flow_hash(e->rps_rxhash); -- GitLab From 503978aca46124cd714703e180b9c8292ba50ba7 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 9 Oct 2019 12:55:53 -0700 Subject: [PATCH 168/993] net: avoid possible false sharing in sk_leave_memory_pressure() As mentioned in https://github.com/google/ktsan/wiki/READ_ONCE-and-WRITE_ONCE#it-may-improve-performance a C compiler can legally transform : if (memory_pressure && *memory_pressure) *memory_pressure = 0; to : if (memory_pressure) *memory_pressure = 0; Fixes: 0604475119de ("tcp: add TCPMemoryPressuresChrono counter") Fixes: 180d8cd942ce ("foundations of per-cgroup memory pressure controlling.") Fixes: 3ab224be6d69 ("[NET] CORE: Introducing new memory accounting interface.") Signed-off-by: Eric Dumazet Signed-off-by: Jakub Kicinski --- net/core/sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/core/sock.c b/net/core/sock.c index fac2b4d80de5..50647a10fdb7 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2334,8 +2334,8 @@ static void sk_leave_memory_pressure(struct sock *sk) } else { unsigned long *memory_pressure = sk->sk_prot->memory_pressure; - if (memory_pressure && *memory_pressure) - *memory_pressure = 0; + if (memory_pressure && READ_ONCE(*memory_pressure)) + WRITE_ONCE(*memory_pressure, 0); } } -- GitLab From 60b173ca3d1cd1782bd0096dc17298ec242f6fb1 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 9 Oct 2019 14:51:20 -0700 Subject: [PATCH 169/993] net: add {READ|WRITE}_ONCE() annotations on ->rskq_accept_head reqsk_queue_empty() is called from inet_csk_listen_poll() while other cpus might write ->rskq_accept_head value. Use {READ|WRITE}_ONCE() to avoid compiler tricks and potential KCSAN splats. Fixes: fff1f3001cc5 ("tcp: add a spinlock to protect struct request_sock_queue") Signed-off-by: Eric Dumazet Signed-off-by: Jakub Kicinski --- drivers/xen/pvcalls-back.c | 2 +- include/net/request_sock.h | 4 ++-- net/ipv4/inet_connection_sock.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/xen/pvcalls-back.c b/drivers/xen/pvcalls-back.c index 69a626b0e594..c57c71b7d53d 100644 --- a/drivers/xen/pvcalls-back.c +++ b/drivers/xen/pvcalls-back.c @@ -775,7 +775,7 @@ static int pvcalls_back_poll(struct xenbus_device *dev, mappass->reqcopy = *req; icsk = inet_csk(mappass->sock->sk); queue = &icsk->icsk_accept_queue; - data = queue->rskq_accept_head != NULL; + data = READ_ONCE(queue->rskq_accept_head) != NULL; if (data) { mappass->reqcopy.cmd = 0; ret = 0; diff --git a/include/net/request_sock.h b/include/net/request_sock.h index fd178d58fa84..cf8b33213bbc 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h @@ -185,7 +185,7 @@ void reqsk_fastopen_remove(struct sock *sk, struct request_sock *req, static inline bool reqsk_queue_empty(const struct request_sock_queue *queue) { - return queue->rskq_accept_head == NULL; + return READ_ONCE(queue->rskq_accept_head) == NULL; } static inline struct request_sock *reqsk_queue_remove(struct request_sock_queue *queue, @@ -197,7 +197,7 @@ static inline struct request_sock *reqsk_queue_remove(struct request_sock_queue req = queue->rskq_accept_head; if (req) { sk_acceptq_removed(parent); - queue->rskq_accept_head = req->dl_next; + WRITE_ONCE(queue->rskq_accept_head, req->dl_next); if (queue->rskq_accept_head == NULL) queue->rskq_accept_tail = NULL; } diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index a9183543ca30..dbcf34ec8dd2 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -934,7 +934,7 @@ struct sock *inet_csk_reqsk_queue_add(struct sock *sk, req->sk = child; req->dl_next = NULL; if (queue->rskq_accept_head == NULL) - queue->rskq_accept_head = req; + WRITE_ONCE(queue->rskq_accept_head, req); else queue->rskq_accept_tail->dl_next = req; queue->rskq_accept_tail = req; -- GitLab From 1f142c17d19a5618d5a633195a46f2c8be9bf232 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 9 Oct 2019 15:10:15 -0700 Subject: [PATCH 170/993] tcp: annotate lockless access to tcp_memory_pressure tcp_memory_pressure is read without holding any lock, and its value could be changed on other cpus. Use READ_ONCE() to annotate these lockless reads. The write side is already using atomic ops. Fixes: b8da51ebb1aa ("tcp: introduce tcp_under_memory_pressure()") Signed-off-by: Eric Dumazet Signed-off-by: Jakub Kicinski --- include/net/tcp.h | 2 +- net/ipv4/tcp.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index c9a3f9688223..88e63d64c698 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -258,7 +258,7 @@ static inline bool tcp_under_memory_pressure(const struct sock *sk) mem_cgroup_under_socket_pressure(sk->sk_memcg)) return true; - return tcp_memory_pressure; + return READ_ONCE(tcp_memory_pressure); } /* * The next routines deal with comparing 32 bit unsigned ints diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f98a1882e537..888c92b63f5a 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -326,7 +326,7 @@ void tcp_enter_memory_pressure(struct sock *sk) { unsigned long val; - if (tcp_memory_pressure) + if (READ_ONCE(tcp_memory_pressure)) return; val = jiffies; @@ -341,7 +341,7 @@ void tcp_leave_memory_pressure(struct sock *sk) { unsigned long val; - if (!tcp_memory_pressure) + if (!READ_ONCE(tcp_memory_pressure)) return; val = xchg(&tcp_memory_pressure, 0); if (val) -- GitLab From 8265792bf8871acc2d00fd03883d830e2249d395 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 9 Oct 2019 15:21:13 -0700 Subject: [PATCH 171/993] net: silence KCSAN warnings around sk_add_backlog() calls sk_add_backlog() callers usually read sk->sk_rcvbuf without owning the socket lock. This means sk_rcvbuf value can be changed by other cpus, and KCSAN complains. Add READ_ONCE() annotations to document the lockless nature of these reads. Note that writes over sk_rcvbuf should also use WRITE_ONCE(), but this will be done in separate patches to ease stable backports (if we decide this is relevant for stable trees). BUG: KCSAN: data-race in tcp_add_backlog / tcp_recvmsg write to 0xffff88812ab369f8 of 8 bytes by interrupt on cpu 1: __sk_add_backlog include/net/sock.h:902 [inline] sk_add_backlog include/net/sock.h:933 [inline] tcp_add_backlog+0x45a/0xcc0 net/ipv4/tcp_ipv4.c:1737 tcp_v4_rcv+0x1aba/0x1bf0 net/ipv4/tcp_ipv4.c:1925 ip_protocol_deliver_rcu+0x51/0x470 net/ipv4/ip_input.c:204 ip_local_deliver_finish+0x110/0x140 net/ipv4/ip_input.c:231 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_local_deliver+0x133/0x210 net/ipv4/ip_input.c:252 dst_input include/net/dst.h:442 [inline] ip_rcv_finish+0x121/0x160 net/ipv4/ip_input.c:413 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_rcv+0x18f/0x1a0 net/ipv4/ip_input.c:523 __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5004 __netif_receive_skb+0x37/0xf0 net/core/dev.c:5118 netif_receive_skb_internal+0x59/0x190 net/core/dev.c:5208 napi_skb_finish net/core/dev.c:5671 [inline] napi_gro_receive+0x28f/0x330 net/core/dev.c:5704 receive_buf+0x284/0x30b0 drivers/net/virtio_net.c:1061 virtnet_receive drivers/net/virtio_net.c:1323 [inline] virtnet_poll+0x436/0x7d0 drivers/net/virtio_net.c:1428 napi_poll net/core/dev.c:6352 [inline] net_rx_action+0x3ae/0xa50 net/core/dev.c:6418 read to 0xffff88812ab369f8 of 8 bytes by task 7271 on cpu 0: tcp_recvmsg+0x470/0x1a30 net/ipv4/tcp.c:2047 inet_recvmsg+0xbb/0x250 net/ipv4/af_inet.c:838 sock_recvmsg_nosec net/socket.c:871 [inline] sock_recvmsg net/socket.c:889 [inline] sock_recvmsg+0x92/0xb0 net/socket.c:885 sock_read_iter+0x15f/0x1e0 net/socket.c:967 call_read_iter include/linux/fs.h:1864 [inline] new_sync_read+0x389/0x4f0 fs/read_write.c:414 __vfs_read+0xb1/0xc0 fs/read_write.c:427 vfs_read fs/read_write.c:461 [inline] vfs_read+0x143/0x2c0 fs/read_write.c:446 ksys_read+0xd5/0x1b0 fs/read_write.c:587 __do_sys_read fs/read_write.c:597 [inline] __se_sys_read fs/read_write.c:595 [inline] __x64_sys_read+0x4c/0x60 fs/read_write.c:595 do_syscall_64+0xcf/0x2f0 arch/x86/entry/common.c:296 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Reported by Kernel Concurrency Sanitizer on: CPU: 0 PID: 7271 Comm: syz-fuzzer Not tainted 5.3.0+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: Jakub Kicinski --- net/core/sock.c | 2 +- net/ipv4/tcp_ipv4.c | 2 +- net/llc/llc_conn.c | 2 +- net/sctp/input.c | 6 +++--- net/tipc/socket.c | 6 +++--- net/x25/x25_dev.c | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/net/core/sock.c b/net/core/sock.c index 50647a10fdb7..1cf06934da50 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -522,7 +522,7 @@ int __sk_receive_skb(struct sock *sk, struct sk_buff *skb, rc = sk_backlog_rcv(sk, skb); mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_); - } else if (sk_add_backlog(sk, skb, sk->sk_rcvbuf)) { + } else if (sk_add_backlog(sk, skb, READ_ONCE(sk->sk_rcvbuf))) { bh_unlock_sock(sk); atomic_inc(&sk->sk_drops); goto discard_and_relse; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index bf124b1742df..492bf6a6b023 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1644,7 +1644,7 @@ int tcp_v4_early_demux(struct sk_buff *skb) bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb) { - u32 limit = sk->sk_rcvbuf + sk->sk_sndbuf; + u32 limit = READ_ONCE(sk->sk_rcvbuf) + READ_ONCE(sk->sk_sndbuf); struct skb_shared_info *shinfo; const struct tcphdr *th; struct tcphdr *thtail; diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index a79b739eb223..7b620acaca9e 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -813,7 +813,7 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb) else { dprintk("%s: adding to backlog...\n", __func__); llc_set_backlog_type(skb, LLC_PACKET); - if (sk_add_backlog(sk, skb, sk->sk_rcvbuf)) + if (sk_add_backlog(sk, skb, READ_ONCE(sk->sk_rcvbuf))) goto drop_unlock; } out: diff --git a/net/sctp/input.c b/net/sctp/input.c index f2771375bfc0..2277981559d0 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -322,7 +322,7 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) bh_lock_sock(sk); if (sock_owned_by_user(sk) || !sctp_newsk_ready(sk)) { - if (sk_add_backlog(sk, skb, sk->sk_rcvbuf)) + if (sk_add_backlog(sk, skb, READ_ONCE(sk->sk_rcvbuf))) sctp_chunk_free(chunk); else backloged = 1; @@ -337,7 +337,7 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) return 0; } else { if (!sctp_newsk_ready(sk)) { - if (!sk_add_backlog(sk, skb, sk->sk_rcvbuf)) + if (!sk_add_backlog(sk, skb, READ_ONCE(sk->sk_rcvbuf))) return 0; sctp_chunk_free(chunk); } else { @@ -364,7 +364,7 @@ static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb) struct sctp_ep_common *rcvr = chunk->rcvr; int ret; - ret = sk_add_backlog(sk, skb, sk->sk_rcvbuf); + ret = sk_add_backlog(sk, skb, READ_ONCE(sk->sk_rcvbuf)); if (!ret) { /* Hold the assoc/ep while hanging on the backlog queue. * This way, we know structures we need will not disappear diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 3b9f8cc328f5..7c736cfec57f 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -2119,13 +2119,13 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *skb) struct tipc_msg *hdr = buf_msg(skb); if (unlikely(msg_in_group(hdr))) - return sk->sk_rcvbuf; + return READ_ONCE(sk->sk_rcvbuf); if (unlikely(!msg_connected(hdr))) - return sk->sk_rcvbuf << msg_importance(hdr); + return READ_ONCE(sk->sk_rcvbuf) << msg_importance(hdr); if (likely(tsk->peer_caps & TIPC_BLOCK_FLOWCTL)) - return sk->sk_rcvbuf; + return READ_ONCE(sk->sk_rcvbuf); return FLOWCTL_MSG_LIM; } diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c index 5c111bc3c8ea..00e782335cb0 100644 --- a/net/x25/x25_dev.c +++ b/net/x25/x25_dev.c @@ -55,7 +55,7 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb) if (!sock_owned_by_user(sk)) { queued = x25_process_rx_frame(sk, skb); } else { - queued = !sk_add_backlog(sk, skb, sk->sk_rcvbuf); + queued = !sk_add_backlog(sk, skb, READ_ONCE(sk->sk_rcvbuf)); } bh_unlock_sock(sk); sock_put(sk); -- GitLab From eac66402d1c342f07ff38f8d631ff95eb7ad3220 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 9 Oct 2019 15:32:35 -0700 Subject: [PATCH 172/993] net: annotate sk->sk_rcvlowat lockless reads sock_rcvlowat() or int_sk_rcvlowat() might be called without the socket lock for example from tcp_poll(). Use READ_ONCE() to document the fact that other cpus might change sk->sk_rcvlowat under us and avoid KCSAN splats. Use WRITE_ONCE() on write sides too. Signed-off-by: Eric Dumazet Signed-off-by: Jakub Kicinski --- include/net/sock.h | 4 +++- net/core/filter.c | 2 +- net/core/sock.c | 2 +- net/ipv4/tcp.c | 2 +- net/sched/em_meta.c | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 2c53f1a1d905..79f54e1f8827 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2271,7 +2271,9 @@ static inline long sock_sndtimeo(const struct sock *sk, bool noblock) static inline int sock_rcvlowat(const struct sock *sk, int waitall, int len) { - return (waitall ? len : min_t(int, sk->sk_rcvlowat, len)) ? : 1; + int v = waitall ? len : min_t(int, READ_ONCE(sk->sk_rcvlowat), len); + + return v ?: 1; } /* Alas, with timeout socket operations are not restartable. diff --git a/net/core/filter.c b/net/core/filter.c index ed6563622ce3..a50c0b6846f2 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -4274,7 +4274,7 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock, case SO_RCVLOWAT: if (val < 0) val = INT_MAX; - sk->sk_rcvlowat = val ? : 1; + WRITE_ONCE(sk->sk_rcvlowat, val ? : 1); break; case SO_MARK: if (sk->sk_mark != val) { diff --git a/net/core/sock.c b/net/core/sock.c index 1cf06934da50..b7c5c6ea51ba 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -974,7 +974,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, if (sock->ops->set_rcvlowat) ret = sock->ops->set_rcvlowat(sk, val); else - sk->sk_rcvlowat = val ? : 1; + WRITE_ONCE(sk->sk_rcvlowat, val ? : 1); break; case SO_RCVTIMEO_OLD: diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 888c92b63f5a..8781a92ea4b6 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1699,7 +1699,7 @@ int tcp_set_rcvlowat(struct sock *sk, int val) else cap = sock_net(sk)->ipv4.sysctl_tcp_rmem[2] >> 1; val = min(val, cap); - sk->sk_rcvlowat = val ? : 1; + WRITE_ONCE(sk->sk_rcvlowat, val ? : 1); /* Check if we need to signal EPOLLIN right now */ tcp_data_ready(sk); diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 82bd14e7ac93..4c9122fc35c9 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -554,7 +554,7 @@ META_COLLECTOR(int_sk_rcvlowat) *err = -1; return; } - dst->value = sk->sk_rcvlowat; + dst->value = READ_ONCE(sk->sk_rcvlowat); } META_COLLECTOR(int_sk_rcvtimeo) -- GitLab From 70c2655849a25431f31b505a07fe0c861e5e41fb Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 9 Oct 2019 15:41:03 -0700 Subject: [PATCH 173/993] net: silence KCSAN warnings about sk->sk_backlog.len reads sk->sk_backlog.len can be written by BH handlers, and read from process contexts in a lockless way. Note the write side should also use WRITE_ONCE() or a variant. We need some agreement about the best way to do this. syzbot reported : BUG: KCSAN: data-race in tcp_add_backlog / tcp_grow_window.isra.0 write to 0xffff88812665f32c of 4 bytes by interrupt on cpu 1: sk_add_backlog include/net/sock.h:934 [inline] tcp_add_backlog+0x4a0/0xcc0 net/ipv4/tcp_ipv4.c:1737 tcp_v4_rcv+0x1aba/0x1bf0 net/ipv4/tcp_ipv4.c:1925 ip_protocol_deliver_rcu+0x51/0x470 net/ipv4/ip_input.c:204 ip_local_deliver_finish+0x110/0x140 net/ipv4/ip_input.c:231 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_local_deliver+0x133/0x210 net/ipv4/ip_input.c:252 dst_input include/net/dst.h:442 [inline] ip_rcv_finish+0x121/0x160 net/ipv4/ip_input.c:413 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_rcv+0x18f/0x1a0 net/ipv4/ip_input.c:523 __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5004 __netif_receive_skb+0x37/0xf0 net/core/dev.c:5118 netif_receive_skb_internal+0x59/0x190 net/core/dev.c:5208 napi_skb_finish net/core/dev.c:5671 [inline] napi_gro_receive+0x28f/0x330 net/core/dev.c:5704 receive_buf+0x284/0x30b0 drivers/net/virtio_net.c:1061 virtnet_receive drivers/net/virtio_net.c:1323 [inline] virtnet_poll+0x436/0x7d0 drivers/net/virtio_net.c:1428 napi_poll net/core/dev.c:6352 [inline] net_rx_action+0x3ae/0xa50 net/core/dev.c:6418 read to 0xffff88812665f32c of 4 bytes by task 7292 on cpu 0: tcp_space include/net/tcp.h:1373 [inline] tcp_grow_window.isra.0+0x6b/0x480 net/ipv4/tcp_input.c:413 tcp_event_data_recv+0x68f/0x990 net/ipv4/tcp_input.c:717 tcp_rcv_established+0xbfe/0xf50 net/ipv4/tcp_input.c:5618 tcp_v4_do_rcv+0x381/0x4e0 net/ipv4/tcp_ipv4.c:1542 sk_backlog_rcv include/net/sock.h:945 [inline] __release_sock+0x135/0x1e0 net/core/sock.c:2427 release_sock+0x61/0x160 net/core/sock.c:2943 tcp_recvmsg+0x63b/0x1a30 net/ipv4/tcp.c:2181 inet_recvmsg+0xbb/0x250 net/ipv4/af_inet.c:838 sock_recvmsg_nosec net/socket.c:871 [inline] sock_recvmsg net/socket.c:889 [inline] sock_recvmsg+0x92/0xb0 net/socket.c:885 sock_read_iter+0x15f/0x1e0 net/socket.c:967 call_read_iter include/linux/fs.h:1864 [inline] new_sync_read+0x389/0x4f0 fs/read_write.c:414 __vfs_read+0xb1/0xc0 fs/read_write.c:427 vfs_read fs/read_write.c:461 [inline] vfs_read+0x143/0x2c0 fs/read_write.c:446 Reported by Kernel Concurrency Sanitizer on: CPU: 0 PID: 7292 Comm: syz-fuzzer Not tainted 5.3.0+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: Jakub Kicinski --- include/net/tcp.h | 3 ++- net/core/sock.c | 2 +- net/sctp/diag.c | 2 +- net/tipc/socket.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 88e63d64c698..35f6f7e0fdc2 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1380,7 +1380,8 @@ static inline int tcp_win_from_space(const struct sock *sk, int space) /* Note: caller must be prepared to deal with negative returns */ static inline int tcp_space(const struct sock *sk) { - return tcp_win_from_space(sk, sk->sk_rcvbuf - sk->sk_backlog.len - + return tcp_win_from_space(sk, sk->sk_rcvbuf - + READ_ONCE(sk->sk_backlog.len) - atomic_read(&sk->sk_rmem_alloc)); } diff --git a/net/core/sock.c b/net/core/sock.c index b7c5c6ea51ba..2a053999df11 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -3210,7 +3210,7 @@ void sk_get_meminfo(const struct sock *sk, u32 *mem) mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc; mem[SK_MEMINFO_WMEM_QUEUED] = sk->sk_wmem_queued; mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc); - mem[SK_MEMINFO_BACKLOG] = sk->sk_backlog.len; + mem[SK_MEMINFO_BACKLOG] = READ_ONCE(sk->sk_backlog.len); mem[SK_MEMINFO_DROPS] = atomic_read(&sk->sk_drops); } diff --git a/net/sctp/diag.c b/net/sctp/diag.c index fc9a4c6629ce..0851166b9175 100644 --- a/net/sctp/diag.c +++ b/net/sctp/diag.c @@ -175,7 +175,7 @@ static int inet_sctp_diag_fill(struct sock *sk, struct sctp_association *asoc, mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc; mem[SK_MEMINFO_WMEM_QUEUED] = sk->sk_wmem_queued; mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc); - mem[SK_MEMINFO_BACKLOG] = sk->sk_backlog.len; + mem[SK_MEMINFO_BACKLOG] = READ_ONCE(sk->sk_backlog.len); mem[SK_MEMINFO_DROPS] = atomic_read(&sk->sk_drops); if (nla_put(skb, INET_DIAG_SKMEMINFO, sizeof(mem), &mem) < 0) diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 7c736cfec57f..f8bbc4aab213 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -3790,7 +3790,7 @@ int tipc_sk_dump(struct sock *sk, u16 dqueues, char *buf) i += scnprintf(buf + i, sz - i, " %d", sk->sk_sndbuf); i += scnprintf(buf + i, sz - i, " | %d", sk_rmem_alloc_get(sk)); i += scnprintf(buf + i, sz - i, " %d", sk->sk_rcvbuf); - i += scnprintf(buf + i, sz - i, " | %d\n", sk->sk_backlog.len); + i += scnprintf(buf + i, sz - i, " | %d\n", READ_ONCE(sk->sk_backlog.len)); if (dqueues & TIPC_DUMP_SK_SNDQ) { i += scnprintf(buf + i, sz - i, "sk_write_queue: "); -- GitLab From 2189624b3c5a6fb03416129e35c09aa5151b7392 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 26 Sep 2019 11:08:57 -0500 Subject: [PATCH 174/993] ACPI: PM: Drop Dell XPS13 9360 from LPS0 Idle _DSM blacklist This reverts part of commit 71630b7a832f ("ACPI / PM: Blacklist Low Power S0 Idle _DSM for Dell XPS13 9360") to remove the S0ix blacklist for the XPS 9360. The problems with this system occurred in one possible NVME SSD when putting system into s0ix. As the NVME sleep behavior has been adjusted in commit d916b1be94b6 ("nvme-pci: use host managed power state for suspend") this is expected to be now resolved. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=196907 Signed-off-by: Mario Limonciello Tested-by: Paul Menzel Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sleep.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 9fa77d72ef27..2af937a8b1c5 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -361,19 +361,6 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "80E3"), }, }, - /* - * https://bugzilla.kernel.org/show_bug.cgi?id=196907 - * Some Dell XPS13 9360 cannot do suspend-to-idle using the Low Power - * S0 Idle firmware interface. - */ - { - .callback = init_default_s3, - .ident = "Dell XPS13 9360", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9360"), - }, - }, /* * ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using * the Low Power S0 Idle firmware interface (see -- GitLab From 65650b35133ff20f0c9ef0abd5c3c66dbce3ae57 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 9 Oct 2019 01:29:10 +0200 Subject: [PATCH 175/993] cpufreq: Avoid cpufreq_suspend() deadlock on system shutdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is incorrect to set the cpufreq syscore shutdown callback pointer to cpufreq_suspend(), because that function cannot be run in the syscore stage of system shutdown for two reasons: (a) it may attempt to carry out actions depending on devices that have already been shut down at that point and (b) the RCU synchronization carried out by it may not be able to make progress then. The latter issue has been present since commit 45975c7d21a1 ("rcu: Define RCU-sched API in terms of RCU for Tree RCU PREEMPT builds"), but the former one has been there since commit 90de2a4aa9f3 ("cpufreq: suspend cpufreq governors on shutdown") regardless. Fix that by dropping cpufreq_syscore_ops altogether and making device_shutdown() call cpufreq_suspend() directly before shutting down devices, which is along the lines of what system-wide power management does. Fixes: 45975c7d21a1 ("rcu: Define RCU-sched API in terms of RCU for Tree RCU PREEMPT builds") Fixes: 90de2a4aa9f3 ("cpufreq: suspend cpufreq governors on shutdown") Reported-by: Ville Syrjälä Tested-by: Ville Syrjälä Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar Cc: 4.0+ # 4.0+ --- drivers/base/core.c | 3 +++ drivers/cpufreq/cpufreq.c | 10 ---------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 2db62d98e395..7bd9cd366d41 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -3179,6 +3180,8 @@ void device_shutdown(void) wait_for_device_probe(); device_block_probing(); + cpufreq_suspend(); + spin_lock(&devices_kset->list_lock); /* * Walk the devices list backward, shutting down each in turn. diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index c52d6fa32aac..bffc11b87247 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2737,14 +2737,6 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver) } EXPORT_SYMBOL_GPL(cpufreq_unregister_driver); -/* - * Stop cpufreq at shutdown to make sure it isn't holding any locks - * or mutexes when secondary CPUs are halted. - */ -static struct syscore_ops cpufreq_syscore_ops = { - .shutdown = cpufreq_suspend, -}; - struct kobject *cpufreq_global_kobject; EXPORT_SYMBOL(cpufreq_global_kobject); @@ -2756,8 +2748,6 @@ static int __init cpufreq_core_init(void) cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj); BUG_ON(!cpufreq_global_kobject); - register_syscore_ops(&cpufreq_syscore_ops); - return 0; } module_param(off, int, 0444); -- GitLab From f49249d58abdc12067d69f15d509487171148b30 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 8 Oct 2019 11:46:46 +0100 Subject: [PATCH 176/993] PM: sleep: include for pm_wq Include the for the definition of pm_wq to avoid the following warning: kernel/power/main.c:890:25: warning: symbol 'pm_wq' was not declared. Should it be static? Signed-off-by: Ben Dooks Signed-off-by: Rafael J. Wysocki --- kernel/power/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/power/main.c b/kernel/power/main.c index e8710d179b35..e26de7af520b 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "power.h" -- GitLab From f2edbb6699b0bc6e4f789846b99007200546c6c2 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 10 Oct 2019 15:55:33 +0530 Subject: [PATCH 177/993] opp: of: drop incorrect lockdep_assert_held() _find_opp_of_np() doesn't traverse the list of OPP tables but instead just the entries within an OPP table and so only requires to lock the OPP table itself. The lockdep_assert_held() was added there by mistake and isn't really required. Fixes: 5d6d106fa455 ("OPP: Populate required opp tables from "required-opps" property") Cc: v5.0+ # v5.0+ Reported-by: Niklas Cassel Signed-off-by: Viresh Kumar --- drivers/opp/of.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 1813f5ad5fa2..6dc41faf74b5 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -77,8 +77,6 @@ static struct dev_pm_opp *_find_opp_of_np(struct opp_table *opp_table, { struct dev_pm_opp *opp; - lockdep_assert_held(&opp_table_lock); - mutex_lock(&opp_table->lock); list_for_each_entry(opp, &opp_table->opp_list, node) { -- GitLab From 18380f52dbac230032a16545e67a6d90b548cf18 Mon Sep 17 00:00:00 2001 From: yu kuai Date: Sun, 29 Sep 2019 21:42:49 +0800 Subject: [PATCH 178/993] platform/x86: classmate-laptop: remove unused variable Fixes gcc '-Wunused-but-set-variable' warning: drivers/platform/x86/classmate-laptop.c: In function cmpc_accel_remove_v4: drivers/platform/x86/classmate-laptop.c:424:21: warning: variable accel set but not used [-Wunused-but-set-variable] drivers/platform/x86/classmate-laptop.c: In function cmpc_accel_remove: drivers/platform/x86/classmate-laptop.c:660:21: warning: variable accel set but not used [-Wunused-but-set-variable] In function cmpc_accel_remove_v4 and cmpc_accel_remove, variable accel is set but not used, so it can be removed. In that case, variable inputdev is set but not used and can be removed. Fixes: 7125587df4e8 ("classmate-laptop: Add support for Classmate V4 accelerometer.") Reported-by: Hulk Robot Signed-off-by: yu kuai Signed-off-by: Andy Shevchenko --- drivers/platform/x86/classmate-laptop.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index 86cc2cc68fb5..af063f690846 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c @@ -420,12 +420,6 @@ static int cmpc_accel_add_v4(struct acpi_device *acpi) static int cmpc_accel_remove_v4(struct acpi_device *acpi) { - struct input_dev *inputdev; - struct cmpc_accel *accel; - - inputdev = dev_get_drvdata(&acpi->dev); - accel = dev_get_drvdata(&inputdev->dev); - device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4); device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4); return cmpc_remove_acpi_notify_device(acpi); @@ -656,12 +650,6 @@ static int cmpc_accel_add(struct acpi_device *acpi) static int cmpc_accel_remove(struct acpi_device *acpi) { - struct input_dev *inputdev; - struct cmpc_accel *accel; - - inputdev = dev_get_drvdata(&acpi->dev); - accel = dev_get_drvdata(&inputdev->dev); - device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr); return cmpc_remove_acpi_notify_device(acpi); } -- GitLab From 71eea7071583b04e9b796ee1d6f7a07334426495 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 10 Oct 2019 11:15:20 +0300 Subject: [PATCH 179/993] platform/x86: intel_punit_ipc: Avoid error message when retrieving IRQ Since the commit 7723f4c5ecdb ("driver core: platform: Add an error message to platform_get_irq*()") the platform_get_irq() started issuing an error message which is not what we want here. Switch to platform_get_irq_optional() to have only warning message provided by the driver. Fixes: 7723f4c5ecdb ("driver core: platform: Add an error message to platform_get_irq*()") Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_punit_ipc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/platform/x86/intel_punit_ipc.c b/drivers/platform/x86/intel_punit_ipc.c index ab7ae1950867..fa97834fdb78 100644 --- a/drivers/platform/x86/intel_punit_ipc.c +++ b/drivers/platform/x86/intel_punit_ipc.c @@ -293,9 +293,8 @@ static int intel_punit_ipc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, punit_ipcdev); - irq = platform_get_irq(pdev, 0); + irq = platform_get_irq_optional(pdev, 0); if (irq < 0) { - punit_ipcdev->irq = 0; dev_warn(&pdev->dev, "Invalid IRQ, using polling mode\n"); } else { ret = devm_request_irq(&pdev->dev, irq, intel_punit_ioc, -- GitLab From b33a654a5bd6bba0052ca2d86098826b309f27b8 Mon Sep 17 00:00:00 2001 From: Ulf Magnusson Date: Fri, 27 Sep 2019 19:42:32 +0200 Subject: [PATCH 180/993] drm/tiny: Kconfig: Remove always-y THERMAL dep. from TINYDRM_REPAPER MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [cherry-picked to drm-misc-fixes: drm-misc-next commit dfef959803c7] Commit 554b3529fe01 ("thermal/drivers/core: Remove the module Kconfig's option") changed the type of THERMAL from tristate to bool, so THERMAL || !THERMAL is now always y. Remove the redundant dependency. Discovered through Kconfiglib detecting a dependency loop. The C tools simplify the expression to y before running dependency loop detection, and so don't see it. Changing the type of THERMAL back to tristate makes the C tools detect the same loop. Not sure if running dep. loop detection after simplification can be called a bug. Fixing this nit unbreaks Kconfiglib on the kernel at least. Signed-off-by: Ulf Magnusson Signed-off-by: Noralf Trønnes Link: https://patchwork.freedesktop.org/patch/msgid/20190927174218.GA32085@huvuddator --- drivers/gpu/drm/tiny/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/tiny/Kconfig b/drivers/gpu/drm/tiny/Kconfig index 504763423d46..a46ac284dd5e 100644 --- a/drivers/gpu/drm/tiny/Kconfig +++ b/drivers/gpu/drm/tiny/Kconfig @@ -63,7 +63,6 @@ config TINYDRM_REPAPER depends on DRM && SPI select DRM_KMS_HELPER select DRM_KMS_CMA_HELPER - depends on THERMAL || !THERMAL help DRM driver for the following Pervasive Displays panels: 1.44" TFT EPD Panel (E1144CS021) -- GitLab From a2f83e8b0c82c9500421a26c49eb198b25fcdea3 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 2 Oct 2019 06:14:17 -0400 Subject: [PATCH 181/993] dm snapshot: introduce account_start_copy() and account_end_copy() This simple refactoring moves code for modifying the semaphore cow_count into separate functions to prepare for changes that will extend these methods to provide for a more sophisticated mechanism for COW throttling. Signed-off-by: Mikulas Patocka Reviewed-by: Nikos Tsironis Signed-off-by: Mike Snitzer --- drivers/md/dm-snap.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index f150f5c5492b..da3bd1794ee0 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -1512,6 +1512,16 @@ static void snapshot_dtr(struct dm_target *ti) kfree(s); } +static void account_start_copy(struct dm_snapshot *s) +{ + down(&s->cow_count); +} + +static void account_end_copy(struct dm_snapshot *s) +{ + up(&s->cow_count); +} + /* * Flush a list of buffers. */ @@ -1732,7 +1742,7 @@ static void copy_callback(int read_err, unsigned long write_err, void *context) rb_link_node(&pe->out_of_order_node, parent, p); rb_insert_color(&pe->out_of_order_node, &s->out_of_order_tree); } - up(&s->cow_count); + account_end_copy(s); } /* @@ -1756,7 +1766,7 @@ static void start_copy(struct dm_snap_pending_exception *pe) dest.count = src.count; /* Hand over to kcopyd */ - down(&s->cow_count); + account_start_copy(s); dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, copy_callback, pe); } @@ -1776,7 +1786,7 @@ static void start_full_bio(struct dm_snap_pending_exception *pe, pe->full_bio = bio; pe->full_bio_end_io = bio->bi_end_io; - down(&s->cow_count); + account_start_copy(s); callback_data = dm_kcopyd_prepare_callback(s->kcopyd_client, copy_callback, pe); @@ -1866,7 +1876,7 @@ static void zero_callback(int read_err, unsigned long write_err, void *context) struct bio *bio = context; struct dm_snapshot *s = bio->bi_private; - up(&s->cow_count); + account_end_copy(s); bio->bi_status = write_err ? BLK_STS_IOERR : 0; bio_endio(bio); } @@ -1880,7 +1890,7 @@ static void zero_exception(struct dm_snapshot *s, struct dm_exception *e, dest.sector = bio->bi_iter.bi_sector; dest.count = s->store->chunk_size; - down(&s->cow_count); + account_start_copy(s); WARN_ON_ONCE(bio->bi_private); bio->bi_private = s; dm_kcopyd_zero(s->kcopyd_client, 1, &dest, 0, zero_callback, bio); -- GitLab From b21555786f18cd77f2311ad89074533109ae3ffa Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 2 Oct 2019 06:15:53 -0400 Subject: [PATCH 182/993] dm snapshot: rework COW throttling to fix deadlock Commit 721b1d98fb517a ("dm snapshot: Fix excessive memory usage and workqueue stalls") introduced a semaphore to limit the maximum number of in-flight kcopyd (COW) jobs. The implementation of this throttling mechanism is prone to a deadlock: 1. One or more threads write to the origin device causing COW, which is performed by kcopyd. 2. At some point some of these threads might reach the s->cow_count semaphore limit and block in down(&s->cow_count), holding a read lock on _origins_lock. 3. Someone tries to acquire a write lock on _origins_lock, e.g., snapshot_ctr(), which blocks because the threads at step (2) already hold a read lock on it. 4. A COW operation completes and kcopyd runs dm-snapshot's completion callback, which ends up calling pending_complete(). pending_complete() tries to resubmit any deferred origin bios. This requires acquiring a read lock on _origins_lock, which blocks. This happens because the read-write semaphore implementation gives priority to writers, meaning that as soon as a writer tries to enter the critical section, no readers will be allowed in, until all writers have completed their work. So, pending_complete() waits for the writer at step (3) to acquire and release the lock. This writer waits for the readers at step (2) to release the read lock and those readers wait for pending_complete() (the kcopyd thread) to signal the s->cow_count semaphore: DEADLOCK. The above was thoroughly analyzed and documented by Nikos Tsironis as part of his initial proposal for fixing this deadlock, see: https://www.redhat.com/archives/dm-devel/2019-October/msg00001.html Fix this deadlock by reworking COW throttling so that it waits without holding any locks. Add a variable 'in_progress' that counts how many kcopyd jobs are running. A function wait_for_in_progress() will sleep if 'in_progress' is over the limit. It drops _origins_lock in order to avoid the deadlock. Reported-by: Guruswamy Basavaiah Reported-by: Nikos Tsironis Reviewed-by: Nikos Tsironis Tested-by: Nikos Tsironis Fixes: 721b1d98fb51 ("dm snapshot: Fix excessive memory usage and workqueue stalls") Cc: stable@vger.kernel.org # v5.0+ Depends-on: 4a3f111a73a8c ("dm snapshot: introduce account_start_copy() and account_end_copy()") Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer --- drivers/md/dm-snap.c | 78 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 14 deletions(-) diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index da3bd1794ee0..4fb1a40e68a0 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "dm.h" @@ -107,8 +106,8 @@ struct dm_snapshot { /* The on disk metadata handler */ struct dm_exception_store *store; - /* Maximum number of in-flight COW jobs. */ - struct semaphore cow_count; + unsigned in_progress; + struct wait_queue_head in_progress_wait; struct dm_kcopyd_client *kcopyd_client; @@ -162,8 +161,8 @@ struct dm_snapshot { */ #define DEFAULT_COW_THRESHOLD 2048 -static int cow_threshold = DEFAULT_COW_THRESHOLD; -module_param_named(snapshot_cow_threshold, cow_threshold, int, 0644); +static unsigned cow_threshold = DEFAULT_COW_THRESHOLD; +module_param_named(snapshot_cow_threshold, cow_threshold, uint, 0644); MODULE_PARM_DESC(snapshot_cow_threshold, "Maximum number of chunks being copied on write"); DECLARE_DM_KCOPYD_THROTTLE_WITH_MODULE_PARM(snapshot_copy_throttle, @@ -1327,7 +1326,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto bad_hash_tables; } - sema_init(&s->cow_count, (cow_threshold > 0) ? cow_threshold : INT_MAX); + init_waitqueue_head(&s->in_progress_wait); s->kcopyd_client = dm_kcopyd_client_create(&dm_kcopyd_throttle); if (IS_ERR(s->kcopyd_client)) { @@ -1509,17 +1508,54 @@ static void snapshot_dtr(struct dm_target *ti) dm_put_device(ti, s->origin); + WARN_ON(s->in_progress); + kfree(s); } static void account_start_copy(struct dm_snapshot *s) { - down(&s->cow_count); + spin_lock(&s->in_progress_wait.lock); + s->in_progress++; + spin_unlock(&s->in_progress_wait.lock); } static void account_end_copy(struct dm_snapshot *s) { - up(&s->cow_count); + spin_lock(&s->in_progress_wait.lock); + BUG_ON(!s->in_progress); + s->in_progress--; + if (likely(s->in_progress <= cow_threshold) && + unlikely(waitqueue_active(&s->in_progress_wait))) + wake_up_locked(&s->in_progress_wait); + spin_unlock(&s->in_progress_wait.lock); +} + +static bool wait_for_in_progress(struct dm_snapshot *s, bool unlock_origins) +{ + if (unlikely(s->in_progress > cow_threshold)) { + spin_lock(&s->in_progress_wait.lock); + if (likely(s->in_progress > cow_threshold)) { + /* + * NOTE: this throttle doesn't account for whether + * the caller is servicing an IO that will trigger a COW + * so excess throttling may result for chunks not required + * to be COW'd. But if cow_threshold was reached, extra + * throttling is unlikely to negatively impact performance. + */ + DECLARE_WAITQUEUE(wait, current); + __add_wait_queue(&s->in_progress_wait, &wait); + __set_current_state(TASK_UNINTERRUPTIBLE); + spin_unlock(&s->in_progress_wait.lock); + if (unlock_origins) + up_read(&_origins_lock); + io_schedule(); + remove_wait_queue(&s->in_progress_wait, &wait); + return false; + } + spin_unlock(&s->in_progress_wait.lock); + } + return true; } /* @@ -1537,7 +1573,7 @@ static void flush_bios(struct bio *bio) } } -static int do_origin(struct dm_dev *origin, struct bio *bio); +static int do_origin(struct dm_dev *origin, struct bio *bio, bool limit); /* * Flush a list of buffers. @@ -1550,7 +1586,7 @@ static void retry_origin_bios(struct dm_snapshot *s, struct bio *bio) while (bio) { n = bio->bi_next; bio->bi_next = NULL; - r = do_origin(s->origin, bio); + r = do_origin(s->origin, bio, false); if (r == DM_MAPIO_REMAPPED) generic_make_request(bio); bio = n; @@ -1926,6 +1962,11 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio) if (!s->valid) return DM_MAPIO_KILL; + if (bio_data_dir(bio) == WRITE) { + while (unlikely(!wait_for_in_progress(s, false))) + ; /* wait_for_in_progress() has slept */ + } + down_read(&s->lock); dm_exception_table_lock(&lock); @@ -2122,7 +2163,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio) if (bio_data_dir(bio) == WRITE) { up_write(&s->lock); - return do_origin(s->origin, bio); + return do_origin(s->origin, bio, false); } out_unlock: @@ -2497,15 +2538,24 @@ static int __origin_write(struct list_head *snapshots, sector_t sector, /* * Called on a write from the origin driver. */ -static int do_origin(struct dm_dev *origin, struct bio *bio) +static int do_origin(struct dm_dev *origin, struct bio *bio, bool limit) { struct origin *o; int r = DM_MAPIO_REMAPPED; +again: down_read(&_origins_lock); o = __lookup_origin(origin->bdev); - if (o) + if (o) { + if (limit) { + struct dm_snapshot *s; + list_for_each_entry(s, &o->snapshots, list) + if (unlikely(!wait_for_in_progress(s, true))) + goto again; + } + r = __origin_write(&o->snapshots, bio->bi_iter.bi_sector, bio); + } up_read(&_origins_lock); return r; @@ -2618,7 +2668,7 @@ static int origin_map(struct dm_target *ti, struct bio *bio) dm_accept_partial_bio(bio, available_sectors); /* Only tell snapshots if this is a write */ - return do_origin(o->dev, bio); + return do_origin(o->dev, bio, true); } /* -- GitLab From 11bcf5f78905b90baae8fb01e16650664ed0cb00 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Tue, 2 Apr 2019 11:30:37 +0800 Subject: [PATCH 183/993] drm/edid: Add 6 bpc quirk for SDC panel in Lenovo G50 Another panel that needs 6BPC quirk. BugLink: https://bugs.launchpad.net/bugs/1819968 Cc: # v4.8+ Reviewed-by: Alex Deucher Signed-off-by: Kai-Heng Feng Signed-off-by: Alex Deucher Link: https://patchwork.freedesktop.org/patch/msgid/20190402033037.21877-1-kai.heng.feng@canonical.com --- drivers/gpu/drm/drm_edid.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 82a4ceed3fcf..6b0177112e18 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -159,6 +159,9 @@ static const struct edid_quirk { /* Medion MD 30217 PG */ { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 }, + /* Lenovo G50 */ + { "SDC", 18514, EDID_QUIRK_FORCE_6BPC }, + /* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */ { "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC }, -- GitLab From c3d79a83ca10d2026fd1cce096cde2d8e316592e Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Sun, 22 Sep 2019 15:49:00 +0800 Subject: [PATCH 184/993] dma-buf/resv: fix exclusive fence get MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This causes kernel crash when testing lima driver. Cc: Christian König Fixes: b8c036dfc66f ("dma-buf: simplify reservation_object_get_fences_rcu a bit") Signed-off-by: Qiang Yu Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190922074900.853-1-yuq825@gmail.com Signed-off-by: Christian König --- drivers/dma-buf/dma-resv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c index 42a8f3f11681..709002515550 100644 --- a/drivers/dma-buf/dma-resv.c +++ b/drivers/dma-buf/dma-resv.c @@ -471,7 +471,7 @@ int dma_resv_get_fences_rcu(struct dma_resv *obj, if (pfence_excl) *pfence_excl = fence_excl; else if (fence_excl) - shared[++shared_count] = fence_excl; + shared[shared_count++] = fence_excl; if (!shared_count) { kfree(shared); -- GitLab From f1e5aa6c13feb8ee47ff5d116bed0a10007686f1 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sun, 21 Jul 2019 18:10:31 +0200 Subject: [PATCH 185/993] MAINTAINERS: Add BCM2711 to BCM2835 ARCH Clarify that BCM2711 belongs to the BCM2835 ARCH. Signed-off-by: Stefan Wahren Acked-by: Eric Anholt --- MAINTAINERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 296de2b51c83..14a939a9e1e7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3187,7 +3187,7 @@ N: bcm216* N: kona F: arch/arm/mach-bcm/ -BROADCOM BCM2835 ARM ARCHITECTURE +BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE M: Eric Anholt M: Stefan Wahren L: bcm-kernel-feedback-list@broadcom.com @@ -3195,6 +3195,7 @@ L: linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) T: git git://github.com/anholt/linux S: Maintained +N: bcm2711 N: bcm2835 F: drivers/staging/vc04_services -- GitLab From 9e4dbc4646a84b2562ea7c64a542740687ff7daf Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Thu, 3 Oct 2019 11:17:59 +0800 Subject: [PATCH 186/993] HID: google: add magnemite/masterball USB ids Add 2 additional hammer-like devices. Signed-off-by: Nicolas Boichat Signed-off-by: Jiri Kosina --- drivers/hid/hid-google-hammer.c | 4 ++++ drivers/hid/hid-ids.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/hid/hid-google-hammer.c b/drivers/hid/hid-google-hammer.c index 84f8c127ebdc..d86a9189e88f 100644 --- a/drivers/hid/hid-google-hammer.c +++ b/drivers/hid/hid-google-hammer.c @@ -469,6 +469,10 @@ static int hammer_probe(struct hid_device *hdev, static const struct hid_device_id hammer_devices[] = { { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) }, { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) }, { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 76969a22b0f2..447e8db21174 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -476,6 +476,8 @@ #define USB_DEVICE_ID_GOOGLE_STAFF 0x502b #define USB_DEVICE_ID_GOOGLE_WAND 0x502d #define USB_DEVICE_ID_GOOGLE_WHISKERS 0x5030 +#define USB_DEVICE_ID_GOOGLE_MASTERBALL 0x503c +#define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d #define USB_VENDOR_ID_GOTOP 0x08f2 #define USB_DEVICE_ID_SUPER_Q2 0x007f -- GitLab From 851140ab0d083c78e5723a8b1cbd258f567a7aff Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 2 Oct 2019 11:28:02 +0100 Subject: [PATCH 187/993] ARM: 8908/1: add __always_inline to functions called from __get_user_check() KernelCI reports that bcm2835_defconfig is no longer booting since commit ac7c3e4ff401 ("compiler: enable CONFIG_OPTIMIZE_INLINING forcibly") (https://lkml.org/lkml/2019/9/26/825). I also received a regression report from Nicolas Saenz Julienne (https://lkml.org/lkml/2019/9/27/263). This problem has cropped up on bcm2835_defconfig because it enables CONFIG_CC_OPTIMIZE_FOR_SIZE. The compiler tends to prefer not inlining functions with -Os. I was able to reproduce it with other boards and defconfig files by manually enabling CONFIG_CC_OPTIMIZE_FOR_SIZE. The __get_user_check() specifically uses r0, r1, r2 registers. So, uaccess_save_and_enable() and uaccess_restore() must be inlined. Otherwise, those register assignments would be entirely dropped, according to my analysis of the disassembly. Prior to commit 9012d011660e ("compiler: allow all arches to enable CONFIG_OPTIMIZE_INLINING"), the 'inline' marker was always enough for inlining functions, except on x86. Since that commit, all architectures can enable CONFIG_OPTIMIZE_INLINING. So, __always_inline is now the only guaranteed way of forcible inlining. I added __always_inline to 4 functions in the call-graph from the __get_user_check() macro. Fixes: 9012d011660e ("compiler: allow all arches to enable CONFIG_OPTIMIZE_INLINING") Reported-by: "kernelci.org bot" Reported-by: Nicolas Saenz Julienne Signed-off-by: Masahiro Yamada Tested-by: Nicolas Saenz Julienne Signed-off-by: Russell King --- arch/arm/include/asm/domain.h | 8 ++++---- arch/arm/include/asm/uaccess.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h index 567dbede4785..f1d0a7807cd0 100644 --- a/arch/arm/include/asm/domain.h +++ b/arch/arm/include/asm/domain.h @@ -82,7 +82,7 @@ #ifndef __ASSEMBLY__ #ifdef CONFIG_CPU_CP15_MMU -static inline unsigned int get_domain(void) +static __always_inline unsigned int get_domain(void) { unsigned int domain; @@ -94,7 +94,7 @@ static inline unsigned int get_domain(void) return domain; } -static inline void set_domain(unsigned val) +static __always_inline void set_domain(unsigned int val) { asm volatile( "mcr p15, 0, %0, c3, c0 @ set domain" @@ -102,12 +102,12 @@ static inline void set_domain(unsigned val) isb(); } #else -static inline unsigned int get_domain(void) +static __always_inline unsigned int get_domain(void) { return 0; } -static inline void set_domain(unsigned val) +static __always_inline void set_domain(unsigned int val) { } #endif diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 303248e5b990..98c6b91be4a8 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -22,7 +22,7 @@ * perform such accesses (eg, via list poison values) which could then * be exploited for priviledge escalation. */ -static inline unsigned int uaccess_save_and_enable(void) +static __always_inline unsigned int uaccess_save_and_enable(void) { #ifdef CONFIG_CPU_SW_DOMAIN_PAN unsigned int old_domain = get_domain(); @@ -37,7 +37,7 @@ static inline unsigned int uaccess_save_and_enable(void) #endif } -static inline void uaccess_restore(unsigned int flags) +static __always_inline void uaccess_restore(unsigned int flags) { #ifdef CONFIG_CPU_SW_DOMAIN_PAN /* Restore the user access mask */ -- GitLab From 4c0742f65b4ee466546fd24b71b56516cacd4613 Mon Sep 17 00:00:00 2001 From: Vladimir Murzin Date: Thu, 10 Oct 2019 10:12:20 +0100 Subject: [PATCH 188/993] ARM: 8914/1: NOMMU: Fix exc_ret for XIP It was reported that 72cd4064fcca "NOMMU: Toggle only bits in EXC_RETURN we are really care of" breaks NOMMU+XIP combination. It happens because saved EXC_RETURN gets overwritten when data section is relocated. The fix is to propagate EXC_RETURN via register and let relocation code to commit that value into memory. Fixes: 72cd4064fcca ("ARM: 8830/1: NOMMU: Toggle only bits in EXC_RETURN we are really care of") Reported-by: afzal mohammed Tested-by: afzal mohammed Signed-off-by: Vladimir Murzin Signed-off-by: Russell King --- arch/arm/kernel/head-common.S | 5 +++-- arch/arm/kernel/head-nommu.S | 2 ++ arch/arm/mm/proc-v7m.S | 5 ++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index a7810be07da1..4a3982812a40 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -68,7 +68,7 @@ ENDPROC(__vet_atags) * The following fragment of code is executed with the MMU on in MMU mode, * and uses absolute addresses; this is not position independent. * - * r0 = cp#15 control register + * r0 = cp#15 control register (exc_ret for M-class) * r1 = machine ID * r2 = atags/dtb pointer * r9 = processor ID @@ -137,7 +137,8 @@ __mmap_switched_data: #ifdef CONFIG_CPU_CP15 .long cr_alignment @ r3 #else - .long 0 @ r3 +M_CLASS(.long exc_ret) @ r3 +AR_CLASS(.long 0) @ r3 #endif .size __mmap_switched_data, . - __mmap_switched_data diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index afa350f44dea..0fc814bbc34b 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -201,6 +201,8 @@ M_CLASS(streq r3, [r12, #PMSAv8_MAIR1]) bic r0, r0, #V7M_SCB_CCR_IC #endif str r0, [r12, V7M_SCB_CCR] + /* Pass exc_ret to __mmap_switched */ + mov r0, r10 #endif /* CONFIG_CPU_CP15 elif CONFIG_CPU_V7M */ ret lr ENDPROC(__after_proc_init) diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S index 1448f144e7fb..efebf4120a0c 100644 --- a/arch/arm/mm/proc-v7m.S +++ b/arch/arm/mm/proc-v7m.S @@ -136,9 +136,8 @@ __v7m_setup_cont: cpsie i svc #0 1: cpsid i - ldr r0, =exc_ret - orr lr, lr, #EXC_RET_THREADMODE_PROCESSSTACK - str lr, [r0] + /* Calculate exc_ret */ + orr r10, lr, #EXC_RET_THREADMODE_PROCESSSTACK ldmia sp, {r0-r3, r12} str r5, [r12, #11 * 4] @ restore the original SVC vector entry mov lr, r6 @ restore LR -- GitLab From 5234c14531152702a9f3e575cb552b7e9cea9f94 Mon Sep 17 00:00:00 2001 From: Soeren Moch Date: Fri, 4 Oct 2019 22:32:13 +0200 Subject: [PATCH 189/993] arm64: dts: rockchip: fix RockPro64 sdmmc settings According to the RockPro64 schematic [1] the rk3399 sdmmc controller is connected to a microSD (TF card) slot. Remove the cap-mmc-highspeed property of the sdmmc controller, since no mmc card can be connected here. [1] http://files.pine64.org/doc/rockpro64/rockpro64_v21-SCH.pdf Fixes: e4f3fb490967 ("arm64: dts: rockchip: add initial dts support for Rockpro64") Signed-off-by: Soeren Moch Link: https://lore.kernel.org/r/20191004203213.4995-1-smoch@web.de Signed-off-by: Heiko Stuebner --- arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts index aa06a6587a11..e544deb61d28 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts @@ -624,7 +624,6 @@ &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>; disable-wp; -- GitLab From 389206e806d892d36de0df6e7b07721432957801 Mon Sep 17 00:00:00 2001 From: Vivek Unune Date: Sat, 28 Sep 2019 23:22:30 -0400 Subject: [PATCH 190/993] arm64: dts: rockchip: Fix usb-c on Hugsun X99 TV Box Fix usb-c on X99 TV Box. Tested with armbian w/ kernel 5.3 Signed-off-by: Vivek Unune Link: https://lore.kernel.org/r/20190929032230.24628-1-npcomplete13@gmail.com Signed-off-by: Heiko Stuebner --- arch/arm64/boot/dts/rockchip/rk3399-hugsun-x99.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-hugsun-x99.dts b/arch/arm64/boot/dts/rockchip/rk3399-hugsun-x99.dts index 0d1f5f9a0de9..c133e8d64b2a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-hugsun-x99.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-hugsun-x99.dts @@ -644,7 +644,7 @@ status = "okay"; u2phy0_host: host-port { - phy-supply = <&vcc5v0_host>; + phy-supply = <&vcc5v0_typec>; status = "okay"; }; @@ -712,7 +712,7 @@ &usbdrd_dwc3_0 { status = "okay"; - dr_mode = "otg"; + dr_mode = "host"; }; &usbdrd3_1 { -- GitLab From a9082575f8d09a3a55f300d04f46ef5243e99688 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 8 Oct 2019 12:49:54 -0700 Subject: [PATCH 191/993] arm64: dts: rockchip: Fix override mode for rk3399-kevin panel When I re-posted Sean's original commit to add the override mode for the kevin panel, for some reason I didn't notice that the pixel clock wasn't quite right. Looking at /sys/kernel/debug/clk/clk_summary on downstream kernels it can be seen that the VOP clock is supposed to be 266,666,667 Hz achieved by dividing the 800 MHz PLL by 3. Looking at history, it seems that even Sean's first patch [1] had this funny clock rate. I'm not sure where it came from since the commit message specifically mentioned 26666 kHz and the Chrome OS tree [2] can be seen to request 266667 kHz. In any case, let's fix it up. This together with my patch [3] to do the proper rounding when setting the clock rate makes the VOP clock more proper as seen in /sys/kernel/debug/clk/clk_summary. [1] https://lore.kernel.org/r/20180206165626.37692-4-seanpaul@chromium.org [2] https://chromium.googlesource.com/chromiumos/third_party/kernel/+/chromeos-4.4/drivers/gpu/drm/panel/panel-simple.c#1172 [3] https://lkml.kernel.org/r/20191003114726.v2.1.Ib233b3e706cf6317858384264d5b0ed35657456e@changeid Fixes: 84ebd2da6d04 ("arm64: dts: rockchip: Specify override mode for kevin panel") Cc: Sean Paul Signed-off-by: Douglas Anderson Link: https://lore.kernel.org/r/20191008124949.1.I674acd441997dd0690c86c9003743aacda1cf5dd@changeid Signed-off-by: Heiko Stuebner --- arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts b/arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts index e152b0ca0290..b8066868a3fe 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts @@ -44,7 +44,7 @@ power-supply = <&pp3300_disp>; panel-timing { - clock-frequency = <266604720>; + clock-frequency = <266666667>; hactive = <2400>; hfront-porch = <48>; hback-porch = <84>; -- GitLab From 4ebcb113edcc498888394821bca2e60ef89c6ff3 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 9 Oct 2019 20:55:48 +0200 Subject: [PATCH 192/993] r8169: fix jumbo packet handling on resume from suspend Mariusz reported that invalid packets are sent after resume from suspend if jumbo packets are active. It turned out that his BIOS resets chip settings to non-jumbo on resume. Most chip settings are re-initialized on resume from suspend by calling rtl_hw_start(), so let's add configuring jumbo to this function. There's nothing wrong with the commit marked as fixed, it's just the first one where the patch applies cleanly. Fixes: 7366016d2d4c ("r8169: read common register for PCI commit") Reported-by: Mariusz Bialonczyk Tested-by: Mariusz Bialonczyk Signed-off-by: Heiner Kallweit Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/realtek/r8169_main.c | 35 +++++++---------------- 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 74f81fe03810..350b0d949611 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -4146,6 +4146,14 @@ static void rtl_hw_jumbo_disable(struct rtl8169_private *tp) rtl_lock_config_regs(tp); } +static void rtl_jumbo_config(struct rtl8169_private *tp, int mtu) +{ + if (mtu > ETH_DATA_LEN) + rtl_hw_jumbo_enable(tp); + else + rtl_hw_jumbo_disable(tp); +} + DECLARE_RTL_COND(rtl_chipcmd_cond) { return RTL_R8(tp, ChipCmd) & CmdReset; @@ -4442,11 +4450,6 @@ static void rtl8168g_set_pause_thresholds(struct rtl8169_private *tp, static void rtl_hw_start_8168bb(struct rtl8169_private *tp) { RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); - - if (tp->dev->mtu <= ETH_DATA_LEN) { - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B | - PCI_EXP_DEVCTL_NOSNOOP_EN); - } } static void rtl_hw_start_8168bef(struct rtl8169_private *tp) @@ -4462,9 +4465,6 @@ static void __rtl_hw_start_8168cp(struct rtl8169_private *tp) RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - rtl_disable_clock_request(tp); } @@ -4490,9 +4490,6 @@ static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp) rtl_set_def_aspm_entry_latency(tp); RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); - - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); } static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp) @@ -4503,9 +4500,6 @@ static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp) /* Magic. */ RTL_W8(tp, DBG_REG, 0x20); - - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); } static void rtl_hw_start_8168c_1(struct rtl8169_private *tp) @@ -4611,9 +4605,6 @@ static void rtl_hw_start_8168e_1(struct rtl8169_private *tp) rtl_ephy_init(tp, e_info_8168e_1); - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - rtl_disable_clock_request(tp); /* Reset tx FIFO pointer */ @@ -4636,9 +4627,6 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) rtl_ephy_init(tp, e_info_8168e_2); - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); rtl_set_fifo_size(tp, 0x10, 0x10, 0x02, 0x06); @@ -5485,6 +5473,8 @@ static void rtl_hw_start(struct rtl8169_private *tp) rtl_set_rx_tx_desc_registers(tp); rtl_lock_config_regs(tp); + rtl_jumbo_config(tp, tp->dev->mtu); + /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ RTL_R16(tp, CPlusCmd); RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb); @@ -5498,10 +5488,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) { struct rtl8169_private *tp = netdev_priv(dev); - if (new_mtu > ETH_DATA_LEN) - rtl_hw_jumbo_enable(tp); - else - rtl_hw_jumbo_disable(tp); + rtl_jumbo_config(tp, new_mtu); dev->mtu = new_mtu; netdev_update_features(dev); -- GitLab From 2168da4594040529f6a6cb413c22668a4402f83c Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Wed, 9 Oct 2019 12:18:31 -0700 Subject: [PATCH 193/993] net: update net_dim documentation after rename Commit 8960b38932be ("linux/dim: Rename externally used net_dim members") renamed the net_dim API, removing the "net_" prefix from the structures and functions. The patch didn't update the net_dim.txt documentation file. Fix the documentation so that its examples match the current code. Fixes: 8960b38932be ("linux/dim: Rename externally used net_dim members", 2019-06-25) Fixes: c002bd529d71 ("linux/dim: Rename externally exposed macros", 2019-06-25) Fixes: 4f75da3666c0 ("linux/dim: Move implementation to .c files") Cc: Tal Gilboa Signed-off-by: Jacob Keller Signed-off-by: Jakub Kicinski --- Documentation/networking/net_dim.txt | 36 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Documentation/networking/net_dim.txt b/Documentation/networking/net_dim.txt index 9cb31c5e2dcd..9bdb7d5a3ba3 100644 --- a/Documentation/networking/net_dim.txt +++ b/Documentation/networking/net_dim.txt @@ -92,16 +92,16 @@ under some conditions. Part III: Registering a Network Device to DIM ============================================== -Net DIM API exposes the main function net_dim(struct net_dim *dim, -struct net_dim_sample end_sample). This function is the entry point to the Net +Net DIM API exposes the main function net_dim(struct dim *dim, +struct dim_sample end_sample). This function is the entry point to the Net DIM algorithm and has to be called every time the driver would like to check if it should change interrupt moderation parameters. The driver should provide two -data structures: struct net_dim and struct net_dim_sample. Struct net_dim +data structures: struct dim and struct dim_sample. Struct dim describes the state of DIM for a specific object (RX queue, TX queue, other queues, etc.). This includes the current selected profile, previous data samples, the callback function provided by the driver and more. -Struct net_dim_sample describes a data sample, which will be compared to the -data sample stored in struct net_dim in order to decide on the algorithm's next +Struct dim_sample describes a data sample, which will be compared to the +data sample stored in struct dim in order to decide on the algorithm's next step. The sample should include bytes, packets and interrupts, measured by the driver. @@ -110,9 +110,9 @@ main net_dim() function. The recommended method is to call net_dim() on each interrupt. Since Net DIM has a built-in moderation and it might decide to skip iterations under certain conditions, there is no need to moderate the net_dim() calls as well. As mentioned above, the driver needs to provide an object of type -struct net_dim to the net_dim() function call. It is advised for each entity -using Net DIM to hold a struct net_dim as part of its data structure and use it -as the main Net DIM API object. The struct net_dim_sample should hold the latest +struct dim to the net_dim() function call. It is advised for each entity +using Net DIM to hold a struct dim as part of its data structure and use it +as the main Net DIM API object. The struct dim_sample should hold the latest bytes, packets and interrupts count. No need to perform any calculations, just include the raw data. @@ -132,19 +132,19 @@ usage is not complete but it should make the outline of the usage clear. my_driver.c: -#include +#include /* Callback for net DIM to schedule on a decision to change moderation */ void my_driver_do_dim_work(struct work_struct *work) { - /* Get struct net_dim from struct work_struct */ - struct net_dim *dim = container_of(work, struct net_dim, - work); + /* Get struct dim from struct work_struct */ + struct dim *dim = container_of(work, struct dim, + work); /* Do interrupt moderation related stuff */ ... /* Signal net DIM work is done and it should move to next iteration */ - dim->state = NET_DIM_START_MEASURE; + dim->state = DIM_START_MEASURE; } /* My driver's interrupt handler */ @@ -152,13 +152,13 @@ int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...) { ... /* A struct to hold current measured data */ - struct net_dim_sample dim_sample; + struct dim_sample dim_sample; ... /* Initiate data sample struct with current data */ - net_dim_sample(my_entity->events, - my_entity->packets, - my_entity->bytes, - &dim_sample); + dim_update_sample(my_entity->events, + my_entity->packets, + my_entity->bytes, + &dim_sample); /* Call net DIM */ net_dim(&my_entity->dim, dim_sample); ... -- GitLab From 29ee2701529e1905c0e948688f9688c68c8d4ea4 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Thu, 10 Oct 2019 10:16:09 +0200 Subject: [PATCH 194/993] net/smc: fix SMCD link group creation with VLAN id If creation of an SMCD link group with VLAN id fails, the initial smc_ism_get_vlan() step has to be reverted as well. Fixes: c6ba7c9ba43d ("net/smc: add base infrastructure for SMC-D and ISM") Signed-off-by: Ursula Braun Signed-off-by: Karsten Graul Signed-off-by: Jakub Kicinski --- net/smc/smc_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index 4ca50ddf8d16..88556f0251ab 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -213,7 +213,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini) lgr = kzalloc(sizeof(*lgr), GFP_KERNEL); if (!lgr) { rc = SMC_CLC_DECL_MEM; - goto out; + goto ism_put_vlan; } lgr->is_smcd = ini->is_smcd; lgr->sync_err = 0; @@ -289,6 +289,9 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini) smc_llc_link_clear(lnk); free_lgr: kfree(lgr); +ism_put_vlan: + if (ini->is_smcd && ini->vlan_id) + smc_ism_put_vlan(ini->ism_dev, ini->vlan_id); out: if (rc < 0) { if (rc == -ENOMEM) -- GitLab From 882dcfe5a1785c20f45820cbe6fec4b8b647c946 Mon Sep 17 00:00:00 2001 From: Karsten Graul Date: Thu, 10 Oct 2019 10:16:10 +0200 Subject: [PATCH 195/993] net/smc: receive returns without data smc_cdc_rxed_any_close_or_senddone() is used as an end condition for the receive loop. This conflicts with smc_cdc_msg_recv_action() which could run in parallel and set the bits checked by smc_cdc_rxed_any_close_or_senddone() before the receive is processed. In that case we could return from receive with no data, although data is available. The same applies to smc_rx_wait(). Fix this by checking for RCV_SHUTDOWN only, which is set in smc_cdc_msg_recv_action() after the receive was actually processed. Fixes: 952310ccf2d8 ("smc: receive data from RMBE") Reviewed-by: Ursula Braun Signed-off-by: Karsten Graul Signed-off-by: Jakub Kicinski --- net/smc/smc_rx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c index 413a6abf227e..000002642288 100644 --- a/net/smc/smc_rx.c +++ b/net/smc/smc_rx.c @@ -211,8 +211,7 @@ int smc_rx_wait(struct smc_sock *smc, long *timeo, rc = sk_wait_event(sk, timeo, sk->sk_err || sk->sk_shutdown & RCV_SHUTDOWN || - fcrit(conn) || - smc_cdc_rxed_any_close_or_senddone(conn), + fcrit(conn), &wait); remove_wait_queue(sk_sleep(sk), &wait); sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk); @@ -310,7 +309,6 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, smc_rx_update_cons(smc, 0); if (sk->sk_shutdown & RCV_SHUTDOWN || - smc_cdc_rxed_any_close_or_senddone(conn) || conn->local_tx_ctrl.conn_state_flags.peer_conn_abort) break; -- GitLab From 107529e31a87acd475ff6a0f82745821b8f70fec Mon Sep 17 00:00:00 2001 From: Karsten Graul Date: Thu, 10 Oct 2019 10:16:11 +0200 Subject: [PATCH 196/993] net/smc: receive pending data after RCV_SHUTDOWN smc_rx_recvmsg() first checks if data is available, and then if RCV_SHUTDOWN is set. There is a race when smc_cdc_msg_recv_action() runs in between these 2 checks, receives data and sets RCV_SHUTDOWN. In that case smc_rx_recvmsg() would return from receive without to process the available data. Fix that with a final check for data available if RCV_SHUTDOWN is set. Move the check for data into a function and call it twice. And use the existing helper smc_rx_data_available(). Fixes: 952310ccf2d8 ("smc: receive data from RMBE") Reviewed-by: Ursula Braun Signed-off-by: Karsten Graul Signed-off-by: Jakub Kicinski --- net/smc/smc_rx.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c index 000002642288..97e8369002d7 100644 --- a/net/smc/smc_rx.c +++ b/net/smc/smc_rx.c @@ -261,6 +261,18 @@ static int smc_rx_recv_urg(struct smc_sock *smc, struct msghdr *msg, int len, return -EAGAIN; } +static bool smc_rx_recvmsg_data_available(struct smc_sock *smc) +{ + struct smc_connection *conn = &smc->conn; + + if (smc_rx_data_available(conn)) + return true; + else if (conn->urg_state == SMC_URG_VALID) + /* we received a single urgent Byte - skip */ + smc_rx_update_cons(smc, 0); + return false; +} + /* smc_rx_recvmsg - receive data from RMBE * @msg: copy data to receive buffer * @pipe: copy data to pipe if set - indicates splice() call @@ -302,15 +314,18 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg, if (read_done >= target || (pipe && read_done)) break; - if (atomic_read(&conn->bytes_to_rcv)) + if (smc_rx_recvmsg_data_available(smc)) goto copy; - else if (conn->urg_state == SMC_URG_VALID) - /* we received a single urgent Byte - skip */ - smc_rx_update_cons(smc, 0); if (sk->sk_shutdown & RCV_SHUTDOWN || - conn->local_tx_ctrl.conn_state_flags.peer_conn_abort) + conn->local_tx_ctrl.conn_state_flags.peer_conn_abort) { + /* smc_cdc_msg_recv_action() could have run after + * above smc_rx_recvmsg_data_available() + */ + if (smc_rx_recvmsg_data_available(smc)) + goto copy; break; + } if (read_done) { if (sk->sk_err || -- GitLab From c461e8df0c9bc46b3696dfb5d1df2f09d755af53 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 26 Sep 2019 13:43:10 -0400 Subject: [PATCH 197/993] tools/virtio: more stubs fix test module build. Signed-off-by: Michael S. Tsirkin --- tools/virtio/crypto/hash.h | 0 tools/virtio/linux/dma-mapping.h | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 tools/virtio/crypto/hash.h diff --git a/tools/virtio/crypto/hash.h b/tools/virtio/crypto/hash.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tools/virtio/linux/dma-mapping.h b/tools/virtio/linux/dma-mapping.h index f91aeb5fe571..8f41cd6bd5c0 100644 --- a/tools/virtio/linux/dma-mapping.h +++ b/tools/virtio/linux/dma-mapping.h @@ -29,4 +29,6 @@ enum dma_data_direction { #define dma_unmap_single(...) do { } while (0) #define dma_unmap_page(...) do { } while (0) +#define dma_max_mapping_size(...) SIZE_MAX + #endif -- GitLab From 86109a691a454e08cbe0356400268cb2a81f1997 Mon Sep 17 00:00:00 2001 From: Chris von Recklinghausen Date: Thu, 10 Oct 2019 13:22:47 -0400 Subject: [PATCH 198/993] arm64: Fix kcore macros after 52-bit virtual addressing fallout We export the entire kernel address space (i.e. the whole of the TTBR1 address range) via /proc/kcore. The kc_vaddr_to_offset() and kc_offset_to_vaddr() macros are intended to convert between a kernel virtual address and its offset relative to the start of the TTBR1 address space. Prior to commit: 14c127c957c1c607 ("arm64: mm: Flip kernel VA space") ... the offset was calculated relative to VA_START, which at the time was the start of the TTBR1 address space. At this time, PAGE_OFFSET pointed to the high half of the TTBR1 address space where arm64's linear map lived. That commit swapped the position of VA_START and PAGE_OFFSET, but failed to update kc_vaddr_to_offset() or kc_offset_to_vaddr(), so since then the two macros behave incorrectly. Note that VA_START was subsequently renamed to PAGE_END in commit: 77ad4ce69321abbe ("arm64: memory: rename VA_START to PAGE_END") As the generic implementations of the two macros calculate the offset relative to PAGE_OFFSET (which is now the start of the TTBR1 address space), we can delete the arm64 implementation and use those. Fixes: 14c127c957c1c607 ("arm64: mm: Flip kernel VA space") Reviewed-by: James Morse Reviewed-by: Mark Rutland Signed-off-by: Chris von Recklinghausen Signed-off-by: Will Deacon --- arch/arm64/include/asm/pgtable.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 7576df00eb50..8330810f699e 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -876,9 +876,6 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, #define update_mmu_cache_pmd(vma, address, pmd) do { } while (0) -#define kc_vaddr_to_offset(v) ((v) & ~PAGE_END) -#define kc_offset_to_vaddr(o) ((o) | PAGE_END) - #ifdef CONFIG_ARM64_PA_BITS_52 #define phys_to_ttbr(addr) (((addr) | ((addr) >> 46)) & TTBR_BADDR_MASK_52) #else -- GitLab From 2aa85f246c181b1fa89f27e8e20c5636426be624 Mon Sep 17 00:00:00 2001 From: Steve Wahl Date: Tue, 24 Sep 2019 16:03:55 -0500 Subject: [PATCH 199/993] x86/boot/64: Make level2_kernel_pgt pages invalid outside kernel area Our hardware (UV aka Superdome Flex) has address ranges marked reserved by the BIOS. Access to these ranges is caught as an error, causing the BIOS to halt the system. Initial page tables mapped a large range of physical addresses that were not checked against the list of BIOS reserved addresses, and sometimes included reserved addresses in part of the mapped range. Including the reserved range in the map allowed processor speculative accesses to the reserved range, triggering a BIOS halt. Used early in booting, the page table level2_kernel_pgt addresses 1 GiB divided into 2 MiB pages, and it was set up to linearly map a full 1 GiB of physical addresses that included the physical address range of the kernel image, as chosen by KASLR. But this also included a large range of unused addresses on either side of the kernel image. And unlike the kernel image's physical address range, this extra mapped space was not checked against the BIOS tables of usable RAM addresses. So there were times when the addresses chosen by KASLR would result in processor accessible mappings of BIOS reserved physical addresses. The kernel code did not directly access any of this extra mapped space, but having it mapped allowed the processor to issue speculative accesses into reserved memory, causing system halts. This was encountered somewhat rarely on a normal system boot, and much more often when starting the crash kernel if "crashkernel=512M,high" was specified on the command line (this heavily restricts the physical address of the crash kernel, in our case usually within 1 GiB of reserved space). The solution is to invalidate the pages of this table outside the kernel image's space before the page table is activated. It fixes this problem on our hardware. [ bp: Touchups. ] Signed-off-by: Steve Wahl Signed-off-by: Borislav Petkov Acked-by: Dave Hansen Acked-by: Kirill A. Shutemov Cc: Baoquan He Cc: Brijesh Singh Cc: dimitri.sivanich@hpe.com Cc: Feng Tang Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Jordan Borgner Cc: Juergen Gross Cc: mike.travis@hpe.com Cc: russ.anderson@hpe.com Cc: stable@vger.kernel.org Cc: Thomas Gleixner Cc: x86-ml Cc: Zhenzhong Duan Link: https://lkml.kernel.org/r/9c011ee51b081534a7a15065b1681d200298b530.1569358539.git.steve.wahl@hpe.com --- arch/x86/kernel/head64.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 29ffa495bd1c..206a4b6144c2 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -222,13 +222,31 @@ unsigned long __head __startup_64(unsigned long physaddr, * we might write invalid pmds, when the kernel is relocated * cleanup_highmap() fixes this up along with the mappings * beyond _end. + * + * Only the region occupied by the kernel image has so far + * been checked against the table of usable memory regions + * provided by the firmware, so invalidate pages outside that + * region. A page table entry that maps to a reserved area of + * memory would allow processor speculation into that area, + * and on some hardware (particularly the UV platform) even + * speculative access to some reserved areas is caught as an + * error, causing the BIOS to halt the system. */ pmd = fixup_pointer(level2_kernel_pgt, physaddr); - for (i = 0; i < PTRS_PER_PMD; i++) { + + /* invalidate pages before the kernel image */ + for (i = 0; i < pmd_index((unsigned long)_text); i++) + pmd[i] &= ~_PAGE_PRESENT; + + /* fixup pages that are part of the kernel image */ + for (; i <= pmd_index((unsigned long)_end); i++) if (pmd[i] & _PAGE_PRESENT) pmd[i] += load_delta; - } + + /* invalidate pages after the kernel image */ + for (; i < PTRS_PER_PMD; i++) + pmd[i] &= ~_PAGE_PRESENT; /* * Fixup phys_base - remove the memory encryption mask to obtain -- GitLab From 1869dbe87cb94dc9a218ae1d9301dea3678bd4ff Mon Sep 17 00:00:00 2001 From: Steve Wahl Date: Tue, 24 Sep 2019 16:04:31 -0500 Subject: [PATCH 200/993] x86/boot/64: Round memory hole size up to next PMD page The kernel image map is created using PMD pages, which can include some extra space beyond what's actually needed. Round the size of the memory hole we search for up to the next PMD boundary, to be certain all of the space to be mapped is usable RAM and includes no reserved areas. Signed-off-by: Steve Wahl Signed-off-by: Borislav Petkov Acked-by: Dave Hansen Acked-by: Kirill A. Shutemov Cc: Baoquan He Cc: Brijesh Singh Cc: dimitri.sivanich@hpe.com Cc: Feng Tang Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Jordan Borgner Cc: Juergen Gross Cc: mike.travis@hpe.com Cc: russ.anderson@hpe.com Cc: Thomas Gleixner Cc: x86-ml Cc: Zhenzhong Duan Link: https://lkml.kernel.org/r/df4f49f05c0c27f108234eb93db5c613d09ea62e.1569358539.git.steve.wahl@hpe.com --- arch/x86/boot/compressed/misc.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 53ac0cb2396d..9652d5c2afda 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -345,6 +345,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, { const unsigned long kernel_total_size = VO__end - VO__text; unsigned long virt_addr = LOAD_PHYSICAL_ADDR; + unsigned long needed_size; /* Retain x86 boot parameters pointer passed from startup_32/64. */ boot_params = rmode; @@ -379,26 +380,38 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, free_mem_ptr = heap; /* Heap */ free_mem_end_ptr = heap + BOOT_HEAP_SIZE; + /* + * The memory hole needed for the kernel is the larger of either + * the entire decompressed kernel plus relocation table, or the + * entire decompressed kernel plus .bss and .brk sections. + * + * On X86_64, the memory is mapped with PMD pages. Round the + * size up so that the full extent of PMD pages mapped is + * included in the check against the valid memory table + * entries. This ensures the full mapped area is usable RAM + * and doesn't include any reserved areas. + */ + needed_size = max(output_len, kernel_total_size); +#ifdef CONFIG_X86_64 + needed_size = ALIGN(needed_size, MIN_KERNEL_ALIGN); +#endif + /* Report initial kernel position details. */ debug_putaddr(input_data); debug_putaddr(input_len); debug_putaddr(output); debug_putaddr(output_len); debug_putaddr(kernel_total_size); + debug_putaddr(needed_size); #ifdef CONFIG_X86_64 /* Report address of 32-bit trampoline */ debug_putaddr(trampoline_32bit); #endif - /* - * The memory hole needed for the kernel is the larger of either - * the entire decompressed kernel plus relocation table, or the - * entire decompressed kernel plus .bss and .brk sections. - */ choose_random_location((unsigned long)input_data, input_len, (unsigned long *)&output, - max(output_len, kernel_total_size), + needed_size, &virt_addr); /* Validate memory location choices. */ -- GitLab From 44db1216efe37bf670f8d1019cdc41658d84baf5 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Wed, 9 Oct 2019 17:43:45 +0100 Subject: [PATCH 201/993] Btrfs: add missing extents release on file extent cluster relocation error If we error out when finding a page at relocate_file_extent_cluster(), we need to release the outstanding extents counter on the relocation inode, set by the previous call to btrfs_delalloc_reserve_metadata(), otherwise the inode's block reserve size can never decrease to zero and metadata space is leaked. Therefore add a call to btrfs_delalloc_release_extents() in case we can't find the target page. Fixes: 8b62f87bad9c ("Btrfs: rework outstanding_extents") CC: stable@vger.kernel.org # 4.19+ Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/relocation.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 00504657b602..7b883239fa7e 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -3277,6 +3277,8 @@ static int relocate_file_extent_cluster(struct inode *inode, if (!page) { btrfs_delalloc_release_metadata(BTRFS_I(inode), PAGE_SIZE, true); + btrfs_delalloc_release_extents(BTRFS_I(inode), + PAGE_SIZE, true); ret = -ENOMEM; goto out; } -- GitLab From 78e31c42261779a01bc73472d0f65f15378e9de3 Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Fri, 11 Oct 2019 06:39:39 -0700 Subject: [PATCH 202/993] drm/msm/dsi: Implement reset correctly On msm8998, vblank timeouts are observed because the DSI controller is not reset properly, which ends up stalling the MDP. This is because the reset logic is not correct per the hardware documentation. The documentation states that after asserting reset, software should wait some time (no indication of how long), or poll the status register until it returns 0 before deasserting reset. wmb() is insufficient for this purpose since it just ensures ordering, not timing between writes. Since asserting and deasserting reset occurs on the same register, ordering is already guaranteed by the architecture, making the wmb extraneous. Since we would define a timeout for polling the status register to avoid a possible infinite loop, lets just use a static delay of 20 ms, since 16.666 ms is the time available to process one frame at 60 fps. Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support") Cc: Hai Li Cc: Rob Clark Signed-off-by: Jeffrey Hugo Reviewed-by: Sean Paul [seanpaul renamed RESET_DELAY to DSI_RESET_TOGGLE_DELAY_MS] Signed-off-by: Sean Paul Link: https://patchwork.freedesktop.org/patch/msgid/20191011133939.16551-1-jeffrey.l.hugo@gmail.com --- drivers/gpu/drm/msm/dsi/dsi_host.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 663ff9f4fac9..1e7b1be25bb0 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -26,6 +26,8 @@ #include "dsi_cfg.h" #include "msm_kms.h" +#define DSI_RESET_TOGGLE_DELAY_MS 20 + static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor) { u32 ver; @@ -986,7 +988,7 @@ static void dsi_sw_reset(struct msm_dsi_host *msm_host) wmb(); /* clocks need to be enabled before reset */ dsi_write(msm_host, REG_DSI_RESET, 1); - wmb(); /* make sure reset happen */ + msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */ dsi_write(msm_host, REG_DSI_RESET, 0); } @@ -1396,7 +1398,7 @@ static void dsi_sw_reset_restore(struct msm_dsi_host *msm_host) /* dsi controller can only be reset while clocks are running */ dsi_write(msm_host, REG_DSI_RESET, 1); - wmb(); /* make sure reset happen */ + msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */ dsi_write(msm_host, REG_DSI_RESET, 0); wmb(); /* controller out of reset */ dsi_write(msm_host, REG_DSI_CTRL, data0); -- GitLab From 4b654acdae850f48b8250b9a578a4eaa518c7a6f Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Thu, 10 Oct 2019 10:39:26 +0800 Subject: [PATCH 203/993] btrfs: block-group: Fix a memory leak due to missing btrfs_put_block_group() In btrfs_read_block_groups(), if we have an invalid block group which has mixed type (DATA|METADATA) while the fs doesn't have MIXED_GROUPS feature, we error out without freeing the block group cache. This patch will add the missing btrfs_put_block_group() to prevent memory leak. Note for stable backports: the file to patch in versions <= 5.3 is fs/btrfs/extent-tree.c Fixes: 49303381f19a ("Btrfs: bail out if block group has different mixed flag") CC: stable@vger.kernel.org # 4.9+ Reviewed-by: Anand Jain Reviewed-by: Johannes Thumshirn Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/block-group.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c index bf7e3f23bba7..670700cb1110 100644 --- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -1761,6 +1761,7 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info) btrfs_err(info, "bg %llu is a mixed block group but filesystem hasn't enabled mixed block groups", cache->key.objectid); + btrfs_put_block_group(cache); ret = -EINVAL; goto error; } -- GitLab From 363c53875aef8fce69d4a2d0873919ccc7d9e2ad Mon Sep 17 00:00:00 2001 From: Evan Green Date: Fri, 11 Oct 2019 17:22:09 -0700 Subject: [PATCH 204/993] Input: synaptics-rmi4 - avoid processing unknown IRQs rmi_process_interrupt_requests() calls handle_nested_irq() for each interrupt status bit it finds. If the irq domain mapping for this bit had not yet been set up, then it ends up calling handle_nested_irq(0), which causes a NULL pointer dereference. There's already code that masks the irq_status bits coming out of the hardware with current_irq_mask, presumably to avoid this situation. However current_irq_mask seems to more reflect the actual mask set in the hardware rather than the IRQs software has set up and registered for. For example, in rmi_driver_reset_handler(), the current_irq_mask is initialized based on what is read from the hardware. If the reset value of this mask enables IRQs that Linux has not set up yet, then we end up in this situation. There appears to be a third unused bitmask that used to serve this purpose, fn_irq_bits. Use that bitmask instead of current_irq_mask to avoid calling handle_nested_irq() on IRQs that have not yet been set up. Signed-off-by: Evan Green Reviewed-by: Andrew Duggan Link: https://lore.kernel.org/r/20191008223657.163366-1-evgreen@chromium.org Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/rmi4/rmi_driver.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index 772493b1f665..190b9974526b 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c @@ -146,7 +146,7 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev) } mutex_lock(&data->irq_mutex); - bitmap_and(data->irq_status, data->irq_status, data->current_irq_mask, + bitmap_and(data->irq_status, data->irq_status, data->fn_irq_bits, data->irq_count); /* * At this point, irq_status has all bits that are set in the @@ -385,6 +385,8 @@ static int rmi_driver_set_irq_bits(struct rmi_device *rmi_dev, bitmap_copy(data->current_irq_mask, data->new_irq_mask, data->num_of_irq_regs); + bitmap_or(data->fn_irq_bits, data->fn_irq_bits, mask, data->irq_count); + error_unlock: mutex_unlock(&data->irq_mutex); return error; @@ -398,6 +400,8 @@ static int rmi_driver_clear_irq_bits(struct rmi_device *rmi_dev, struct device *dev = &rmi_dev->dev; mutex_lock(&data->irq_mutex); + bitmap_andnot(data->fn_irq_bits, + data->fn_irq_bits, mask, data->irq_count); bitmap_andnot(data->new_irq_mask, data->current_irq_mask, mask, data->irq_count); -- GitLab From 8d13c187c42e110625d60094668a8f778c092879 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 9 Oct 2019 13:12:37 -0500 Subject: [PATCH 205/993] Revert "drm/radeon: Fix EEH during kexec" This reverts commit 6f7fe9a93e6c09bf988c5059403f5f88e17e21e6. This breaks some boards. Maybe just enable this on PPC for now? Bug: https://bugzilla.kernel.org/show_bug.cgi?id=205147 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_drv.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index d0bc91ed7c90..9e55076578c6 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -379,19 +379,11 @@ radeon_pci_remove(struct pci_dev *pdev) static void radeon_pci_shutdown(struct pci_dev *pdev) { - struct drm_device *ddev = pci_get_drvdata(pdev); - /* if we are running in a VM, make sure the device * torn down properly on reboot/shutdown */ if (radeon_device_is_virtual()) radeon_pci_remove(pdev); - - /* Some adapters need to be suspended before a - * shutdown occurs in order to prevent an error - * during kexec. - */ - radeon_suspend_kms(ddev, true, true, false); } static int radeon_pmops_suspend(struct device *dev) -- GitLab From 984d7a929ad68b7be9990fc9c5cfa5d5c9fc7942 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 10 Oct 2019 18:28:17 +0200 Subject: [PATCH 206/993] drm/amdgpu: Bail earlier when amdgpu.cik_/si_support is not set to 1 Bail from the pci_driver probe function instead of from the drm_driver load function. This avoid /dev/dri/card0 temporarily getting registered and then unregistered again, sending unwanted add / remove udev events to userspace. Specifically this avoids triggering the (userspace) bug fixed by this plymouth merge-request: https://gitlab.freedesktop.org/plymouth/plymouth/merge_requests/59 Note that despite that being a userspace bug, not sending unnecessary udev events is a good idea in general. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1490490 Reviewed-by: Daniel Vetter Signed-off-by: Hans de Goede Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 35 +++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 35 ------------------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 6f8aaf655a9f..2a00a36106b2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -1048,6 +1048,41 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, return -ENODEV; } +#ifdef CONFIG_DRM_AMDGPU_SI + if (!amdgpu_si_support) { + switch (flags & AMD_ASIC_MASK) { + case CHIP_TAHITI: + case CHIP_PITCAIRN: + case CHIP_VERDE: + case CHIP_OLAND: + case CHIP_HAINAN: + dev_info(&pdev->dev, + "SI support provided by radeon.\n"); + dev_info(&pdev->dev, + "Use radeon.si_support=0 amdgpu.si_support=1 to override.\n" + ); + return -ENODEV; + } + } +#endif +#ifdef CONFIG_DRM_AMDGPU_CIK + if (!amdgpu_cik_support) { + switch (flags & AMD_ASIC_MASK) { + case CHIP_KAVERI: + case CHIP_BONAIRE: + case CHIP_HAWAII: + case CHIP_KABINI: + case CHIP_MULLINS: + dev_info(&pdev->dev, + "CIK support provided by radeon.\n"); + dev_info(&pdev->dev, + "Use radeon.cik_support=0 amdgpu.cik_support=1 to override.\n" + ); + return -ENODEV; + } + } +#endif + /* Get rid of things like offb */ ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 0, "amdgpudrmfb"); if (ret) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index f2c097983f48..d55f5baa83d3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -144,41 +144,6 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags) struct amdgpu_device *adev; int r, acpi_status; -#ifdef CONFIG_DRM_AMDGPU_SI - if (!amdgpu_si_support) { - switch (flags & AMD_ASIC_MASK) { - case CHIP_TAHITI: - case CHIP_PITCAIRN: - case CHIP_VERDE: - case CHIP_OLAND: - case CHIP_HAINAN: - dev_info(dev->dev, - "SI support provided by radeon.\n"); - dev_info(dev->dev, - "Use radeon.si_support=0 amdgpu.si_support=1 to override.\n" - ); - return -ENODEV; - } - } -#endif -#ifdef CONFIG_DRM_AMDGPU_CIK - if (!amdgpu_cik_support) { - switch (flags & AMD_ASIC_MASK) { - case CHIP_KAVERI: - case CHIP_BONAIRE: - case CHIP_HAWAII: - case CHIP_KABINI: - case CHIP_MULLINS: - dev_info(dev->dev, - "CIK support provided by radeon.\n"); - dev_info(dev->dev, - "Use radeon.cik_support=0 amdgpu.cik_support=1 to override.\n" - ); - return -ENODEV; - } - } -#endif - adev = kzalloc(sizeof(struct amdgpu_device), GFP_KERNEL); if (adev == NULL) { return -ENOMEM; -- GitLab From d12c50857c6edc1d18aa7a60c5a4d6d943137bc0 Mon Sep 17 00:00:00 2001 From: Xiaojie Yuan Date: Thu, 10 Oct 2019 01:01:23 +0800 Subject: [PATCH 207/993] drm/amdgpu/sdma5: fix mask value of POLL_REGMEM packet for pipe sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sdma will hang once sequence number to be polled reaches 0x1000_0000 Reviewed-by: Christian König Signed-off-by: Xiaojie Yuan Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c index fa2f70ce2e2b..f6e81680dd7e 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c @@ -1129,7 +1129,7 @@ static void sdma_v5_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring) amdgpu_ring_write(ring, addr & 0xfffffffc); amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff); amdgpu_ring_write(ring, seq); /* reference */ - amdgpu_ring_write(ring, 0xfffffff); /* mask */ + amdgpu_ring_write(ring, 0xffffffff); /* mask */ amdgpu_ring_write(ring, SDMA_PKT_POLL_REGMEM_DW5_RETRY_COUNT(0xfff) | SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(4)); /* retry count, poll interval */ } -- GitLab From f0308fb0708078d6c1d8a4d533941a7a191af634 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 10 Oct 2019 15:52:34 +0100 Subject: [PATCH 208/993] rxrpc: Fix possible NULL pointer access in ICMP handling If an ICMP packet comes in on the UDP socket backing an AF_RXRPC socket as the UDP socket is being shut down, rxrpc_error_report() may get called to deal with it after sk_user_data on the UDP socket has been cleared, leading to a NULL pointer access when this local endpoint record gets accessed. Fix this by just returning immediately if sk_user_data was NULL. The oops looks like the following: #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page ... RIP: 0010:rxrpc_error_report+0x1bd/0x6a9 ... Call Trace: ? sock_queue_err_skb+0xbd/0xde ? __udp4_lib_err+0x313/0x34d __udp4_lib_err+0x313/0x34d icmp_unreach+0x1ee/0x207 icmp_rcv+0x25b/0x28f ip_protocol_deliver_rcu+0x95/0x10e ip_local_deliver+0xe9/0x148 __netif_receive_skb_one_core+0x52/0x6e process_backlog+0xdc/0x177 net_rx_action+0xf9/0x270 __do_softirq+0x1b6/0x39a ? smpboot_register_percpu_thread+0xce/0xce run_ksoftirqd+0x1d/0x42 smpboot_thread_fn+0x19e/0x1b3 kthread+0xf1/0xf6 ? kthread_delayed_work_timer_fn+0x83/0x83 ret_from_fork+0x24/0x30 Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both") Reported-by: syzbot+611164843bd48cc2190c@syzkaller.appspotmail.com Signed-off-by: David Howells Signed-off-by: David S. Miller --- net/rxrpc/peer_event.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/rxrpc/peer_event.c b/net/rxrpc/peer_event.c index c97ebdc043e4..61451281d74a 100644 --- a/net/rxrpc/peer_event.c +++ b/net/rxrpc/peer_event.c @@ -151,6 +151,9 @@ void rxrpc_error_report(struct sock *sk) struct rxrpc_peer *peer; struct sk_buff *skb; + if (unlikely(!local)) + return; + _enter("%p{%d}", sk, local->debug_id); /* Clear the outstanding error value on the socket so that it doesn't -- GitLab From a91f757bda1a48317f692487addf832ebf8e93aa Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Thu, 22 Aug 2019 20:01:56 +0100 Subject: [PATCH 209/993] mailmap: Add Simon Arlott (replacement for expired email address) Add replacement email address for the one on my expired domain. Signed-off-by: Simon Arlott Signed-off-by: Stefan Wahren --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index edcac87e76c8..f652f3725772 100644 --- a/.mailmap +++ b/.mailmap @@ -229,6 +229,7 @@ Shuah Khan Shuah Khan Shuah Khan Shuah Khan +Simon Arlott Simon Kelley Stéphane Witzmann Stephen Hemminger -- GitLab From edc5774c097f6463e9fb2373832e7db726247809 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 13 Oct 2019 09:37:16 -0400 Subject: [PATCH 210/993] tools/virtio: xen stub Fixes test module build. Reported-by: Jan Kiszka Signed-off-by: Michael S. Tsirkin --- tools/virtio/xen/xen.h | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tools/virtio/xen/xen.h diff --git a/tools/virtio/xen/xen.h b/tools/virtio/xen/xen.h new file mode 100644 index 000000000000..f569387d1403 --- /dev/null +++ b/tools/virtio/xen/xen.h @@ -0,0 +1,6 @@ +#ifndef XEN_XEN_STUB_H +#define XEN_XEN_STUB_H + +#define xen_domain() 0 + +#endif -- GitLab From 245cdd9fbd396483d501db83047116e2530f245f Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 7 Oct 2019 13:56:59 -0400 Subject: [PATCH 211/993] vhost/test: stop device before reset When device stop was moved out of reset, test device wasn't updated to stop before reset, this resulted in a use after free. Fix by invoking stop appropriately. Fixes: b211616d7125 ("vhost: move -net specific code out") Signed-off-by: Michael S. Tsirkin --- drivers/vhost/test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c index 7804869c6a31..056308008288 100644 --- a/drivers/vhost/test.c +++ b/drivers/vhost/test.c @@ -161,6 +161,7 @@ static int vhost_test_release(struct inode *inode, struct file *f) vhost_test_stop(n, &private); vhost_test_flush(n); + vhost_dev_stop(&n->dev); vhost_dev_cleanup(&n->dev); /* We do an extra flush before freeing memory, * since jobs can re-queue themselves. */ @@ -237,6 +238,7 @@ static long vhost_test_reset_owner(struct vhost_test *n) } vhost_test_stop(n, &priv); vhost_test_flush(n); + vhost_dev_stop(&n->dev); vhost_dev_reset_owner(&n->dev, umem); done: mutex_unlock(&n->dev.mutex); -- GitLab From d983ea6f16b835dcde2ee9a58a1e764ce68bfccc Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 10 Oct 2019 20:17:38 -0700 Subject: [PATCH 212/993] tcp: add rcu protection around tp->fastopen_rsk Both tcp_v4_err() and tcp_v6_err() do the following operations while they do not own the socket lock : fastopen = tp->fastopen_rsk; snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; The problem is that without appropriate barrier, the compiler might reload tp->fastopen_rsk and trigger a NULL deref. request sockets are protected by RCU, we can simply add the missing annotations and barriers to solve the issue. Fixes: 168a8f58059a ("tcp: TCP Fast Open Server - main code path") Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/tcp.h | 6 +++--- net/core/request_sock.c | 2 +- net/ipv4/inet_connection_sock.c | 4 ++-- net/ipv4/tcp.c | 11 ++++++++--- net/ipv4/tcp_fastopen.c | 2 +- net/ipv4/tcp_input.c | 13 +++++++++---- net/ipv4/tcp_ipv4.c | 4 ++-- net/ipv4/tcp_minisocks.c | 2 +- net/ipv4/tcp_output.c | 2 +- net/ipv4/tcp_timer.c | 11 ++++++----- net/ipv6/tcp_ipv6.c | 2 +- 11 files changed, 35 insertions(+), 24 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 99617e528ea2..668e25a76d69 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -393,7 +393,7 @@ struct tcp_sock { /* fastopen_rsk points to request_sock that resulted in this big * socket. Used to retransmit SYNACKs etc. */ - struct request_sock *fastopen_rsk; + struct request_sock __rcu *fastopen_rsk; u32 *saved_syn; }; @@ -447,8 +447,8 @@ static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) static inline bool tcp_passive_fastopen(const struct sock *sk) { - return (sk->sk_state == TCP_SYN_RECV && - tcp_sk(sk)->fastopen_rsk != NULL); + return sk->sk_state == TCP_SYN_RECV && + rcu_access_pointer(tcp_sk(sk)->fastopen_rsk) != NULL; } static inline void fastopen_queue_tune(struct sock *sk, int backlog) diff --git a/net/core/request_sock.c b/net/core/request_sock.c index c9bb00008528..f35c2e998406 100644 --- a/net/core/request_sock.c +++ b/net/core/request_sock.c @@ -96,7 +96,7 @@ void reqsk_fastopen_remove(struct sock *sk, struct request_sock *req, fastopenq = &inet_csk(lsk)->icsk_accept_queue.fastopenq; - tcp_sk(sk)->fastopen_rsk = NULL; + RCU_INIT_POINTER(tcp_sk(sk)->fastopen_rsk, NULL); spin_lock_bh(&fastopenq->lock); fastopenq->qlen--; tcp_rsk(req)->tfo_listener = false; diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index dbcf34ec8dd2..eb30fc1770de 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -906,7 +906,7 @@ static void inet_child_forget(struct sock *sk, struct request_sock *req, percpu_counter_inc(sk->sk_prot->orphan_count); if (sk->sk_protocol == IPPROTO_TCP && tcp_rsk(req)->tfo_listener) { - BUG_ON(tcp_sk(child)->fastopen_rsk != req); + BUG_ON(rcu_access_pointer(tcp_sk(child)->fastopen_rsk) != req); BUG_ON(sk != req->rsk_listener); /* Paranoid, to prevent race condition if @@ -915,7 +915,7 @@ static void inet_child_forget(struct sock *sk, struct request_sock *req, * Also to satisfy an assertion in * tcp_v4_destroy_sock(). */ - tcp_sk(child)->fastopen_rsk = NULL; + RCU_INIT_POINTER(tcp_sk(child)->fastopen_rsk, NULL); } inet_csk_destroy_sock(child); } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 8781a92ea4b6..c59d0bd29c5c 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -543,7 +543,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait) /* Connected or passive Fast Open socket? */ if (state != TCP_SYN_SENT && - (state != TCP_SYN_RECV || tp->fastopen_rsk)) { + (state != TCP_SYN_RECV || rcu_access_pointer(tp->fastopen_rsk))) { int target = sock_rcvlowat(sk, 0, INT_MAX); if (tp->urg_seq == tp->copied_seq && @@ -2487,7 +2487,10 @@ void tcp_close(struct sock *sk, long timeout) } if (sk->sk_state == TCP_CLOSE) { - struct request_sock *req = tcp_sk(sk)->fastopen_rsk; + struct request_sock *req; + + req = rcu_dereference_protected(tcp_sk(sk)->fastopen_rsk, + lockdep_sock_is_held(sk)); /* We could get here with a non-NULL req if the socket is * aborted (e.g., closed with unread data) before 3WHS * finishes. @@ -3831,8 +3834,10 @@ EXPORT_SYMBOL(tcp_md5_hash_key); void tcp_done(struct sock *sk) { - struct request_sock *req = tcp_sk(sk)->fastopen_rsk; + struct request_sock *req; + req = rcu_dereference_protected(tcp_sk(sk)->fastopen_rsk, + lockdep_sock_is_held(sk)); if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index 3fd451271a70..a915ade0c818 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c @@ -253,7 +253,7 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk, */ tp = tcp_sk(child); - tp->fastopen_rsk = req; + rcu_assign_pointer(tp->fastopen_rsk, req); tcp_rsk(req)->tfo_listener = true; /* RFC1323: The window in SYN & SYN/ACK segments is never diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 3578357abe30..5f9b102c3b55 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2666,7 +2666,7 @@ static void tcp_process_loss(struct sock *sk, int flag, int num_dupack, struct tcp_sock *tp = tcp_sk(sk); bool recovered = !before(tp->snd_una, tp->high_seq); - if ((flag & FLAG_SND_UNA_ADVANCED || tp->fastopen_rsk) && + if ((flag & FLAG_SND_UNA_ADVANCED || rcu_access_pointer(tp->fastopen_rsk)) && tcp_try_undo_loss(sk, false)) return; @@ -2990,7 +2990,7 @@ void tcp_rearm_rto(struct sock *sk) /* If the retrans timer is currently being used by Fast Open * for SYN-ACK retrans purpose, stay put. */ - if (tp->fastopen_rsk) + if (rcu_access_pointer(tp->fastopen_rsk)) return; if (!tp->packets_out) { @@ -6087,6 +6087,8 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, static void tcp_rcv_synrecv_state_fastopen(struct sock *sk) { + struct request_sock *req; + tcp_try_undo_loss(sk, false); /* Reset rtx states to prevent spurious retransmits_timed_out() */ @@ -6096,7 +6098,9 @@ static void tcp_rcv_synrecv_state_fastopen(struct sock *sk) /* Once we leave TCP_SYN_RECV or TCP_FIN_WAIT_1, * we no longer need req so release it. */ - reqsk_fastopen_remove(sk, tcp_sk(sk)->fastopen_rsk, false); + req = rcu_dereference_protected(tcp_sk(sk)->fastopen_rsk, + lockdep_sock_is_held(sk)); + reqsk_fastopen_remove(sk, req, false); /* Re-arm the timer because data may have been sent out. * This is similar to the regular data transmission case @@ -6171,7 +6175,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) tcp_mstamp_refresh(tp); tp->rx_opt.saw_tstamp = 0; - req = tp->fastopen_rsk; + req = rcu_dereference_protected(tp->fastopen_rsk, + lockdep_sock_is_held(sk)); if (req) { bool req_stolen; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 492bf6a6b023..ffa366099eb2 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -478,7 +478,7 @@ int tcp_v4_err(struct sk_buff *icmp_skb, u32 info) icsk = inet_csk(sk); tp = tcp_sk(sk); /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ - fastopen = tp->fastopen_rsk; + fastopen = rcu_dereference(tp->fastopen_rsk); snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; if (sk->sk_state != TCP_LISTEN && !between(seq, snd_una, tp->snd_nxt)) { @@ -2121,7 +2121,7 @@ void tcp_v4_destroy_sock(struct sock *sk) if (inet_csk(sk)->icsk_bind_hash) inet_put_port(sk); - BUG_ON(tp->fastopen_rsk); + BUG_ON(rcu_access_pointer(tp->fastopen_rsk)); /* If socket is aborted during connect operation */ tcp_free_fastopen_req(tp); diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index bb140a5db8c0..5401dbd39c8f 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -541,7 +541,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, newtp->rx_opt.mss_clamp = req->mss; tcp_ecn_openreq_child(newtp, req); newtp->fastopen_req = NULL; - newtp->fastopen_rsk = NULL; + RCU_INIT_POINTER(newtp->fastopen_rsk, NULL); __TCP_INC_STATS(sock_net(sk), TCP_MIB_PASSIVEOPENS); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index fec6d67bfd14..84ae4d1449ea 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2482,7 +2482,7 @@ bool tcp_schedule_loss_probe(struct sock *sk, bool advancing_rto) /* Don't do any loss probe on a Fast Open connection before 3WHS * finishes. */ - if (tp->fastopen_rsk) + if (rcu_access_pointer(tp->fastopen_rsk)) return false; early_retrans = sock_net(sk)->ipv4.sysctl_tcp_early_retrans; diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 05be564414e9..dd5a6317a801 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -386,15 +386,13 @@ abort: tcp_write_err(sk); * Timer for Fast Open socket to retransmit SYNACK. Note that the * sk here is the child socket, not the parent (listener) socket. */ -static void tcp_fastopen_synack_timer(struct sock *sk) +static void tcp_fastopen_synack_timer(struct sock *sk, struct request_sock *req) { struct inet_connection_sock *icsk = inet_csk(sk); int max_retries = icsk->icsk_syn_retries ? : sock_net(sk)->ipv4.sysctl_tcp_synack_retries + 1; /* add one more retry for fastopen */ struct tcp_sock *tp = tcp_sk(sk); - struct request_sock *req; - req = tcp_sk(sk)->fastopen_rsk; req->rsk_ops->syn_ack_timeout(req); if (req->num_timeout >= max_retries) { @@ -435,11 +433,14 @@ void tcp_retransmit_timer(struct sock *sk) struct tcp_sock *tp = tcp_sk(sk); struct net *net = sock_net(sk); struct inet_connection_sock *icsk = inet_csk(sk); + struct request_sock *req; - if (tp->fastopen_rsk) { + req = rcu_dereference_protected(tp->fastopen_rsk, + lockdep_sock_is_held(sk)); + if (req) { WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV && sk->sk_state != TCP_FIN_WAIT1); - tcp_fastopen_synack_timer(sk); + tcp_fastopen_synack_timer(sk, req); /* Before we receive ACK to our SYN-ACK don't retransmit * anything else (e.g., data or FIN segments). */ diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index e3d9f4559c99..45a95e032bdf 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -406,7 +406,7 @@ static int tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, tp = tcp_sk(sk); /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ - fastopen = tp->fastopen_rsk; + fastopen = rcu_dereference(tp->fastopen_rsk); snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; if (sk->sk_state != TCP_LISTEN && !between(seq, snd_una, tp->snd_nxt)) { -- GitLab From dba7d9b8c739df27ff3a234c81d6c6b23e3986fa Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 10 Oct 2019 20:17:39 -0700 Subject: [PATCH 213/993] tcp: annotate tp->rcv_nxt lockless reads There are few places where we fetch tp->rcv_nxt while this field can change from IRQ or other cpu. We need to add READ_ONCE() annotations, and also make sure write sides use corresponding WRITE_ONCE() to avoid store-tearing. Note that tcp_inq_hint() was already using READ_ONCE(tp->rcv_nxt) syzbot reported : BUG: KCSAN: data-race in tcp_poll / tcp_queue_rcv write to 0xffff888120425770 of 4 bytes by interrupt on cpu 0: tcp_rcv_nxt_update net/ipv4/tcp_input.c:3365 [inline] tcp_queue_rcv+0x180/0x380 net/ipv4/tcp_input.c:4638 tcp_rcv_established+0xbf1/0xf50 net/ipv4/tcp_input.c:5616 tcp_v4_do_rcv+0x381/0x4e0 net/ipv4/tcp_ipv4.c:1542 tcp_v4_rcv+0x1a03/0x1bf0 net/ipv4/tcp_ipv4.c:1923 ip_protocol_deliver_rcu+0x51/0x470 net/ipv4/ip_input.c:204 ip_local_deliver_finish+0x110/0x140 net/ipv4/ip_input.c:231 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_local_deliver+0x133/0x210 net/ipv4/ip_input.c:252 dst_input include/net/dst.h:442 [inline] ip_rcv_finish+0x121/0x160 net/ipv4/ip_input.c:413 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_rcv+0x18f/0x1a0 net/ipv4/ip_input.c:523 __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5004 __netif_receive_skb+0x37/0xf0 net/core/dev.c:5118 netif_receive_skb_internal+0x59/0x190 net/core/dev.c:5208 napi_skb_finish net/core/dev.c:5671 [inline] napi_gro_receive+0x28f/0x330 net/core/dev.c:5704 receive_buf+0x284/0x30b0 drivers/net/virtio_net.c:1061 read to 0xffff888120425770 of 4 bytes by task 7254 on cpu 1: tcp_stream_is_readable net/ipv4/tcp.c:480 [inline] tcp_poll+0x204/0x6b0 net/ipv4/tcp.c:554 sock_poll+0xed/0x250 net/socket.c:1256 vfs_poll include/linux/poll.h:90 [inline] ep_item_poll.isra.0+0x90/0x190 fs/eventpoll.c:892 ep_send_events_proc+0x113/0x5c0 fs/eventpoll.c:1749 ep_scan_ready_list.constprop.0+0x189/0x500 fs/eventpoll.c:704 ep_send_events fs/eventpoll.c:1793 [inline] ep_poll+0xe3/0x900 fs/eventpoll.c:1930 do_epoll_wait+0x162/0x180 fs/eventpoll.c:2294 __do_sys_epoll_pwait fs/eventpoll.c:2325 [inline] __se_sys_epoll_pwait fs/eventpoll.c:2311 [inline] __x64_sys_epoll_pwait+0xcd/0x170 fs/eventpoll.c:2311 do_syscall_64+0xcf/0x2f0 arch/x86/entry/common.c:296 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Reported by Kernel Concurrency Sanitizer on: CPU: 1 PID: 7254 Comm: syz-fuzzer Not tainted 5.3.0+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 4 ++-- net/ipv4/tcp_diag.c | 2 +- net/ipv4/tcp_input.c | 6 +++--- net/ipv4/tcp_ipv4.c | 3 ++- net/ipv4/tcp_minisocks.c | 7 +++++-- net/ipv6/tcp_ipv6.c | 3 ++- 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index c59d0bd29c5c..883ee863db43 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -477,7 +477,7 @@ static void tcp_tx_timestamp(struct sock *sk, u16 tsflags) static inline bool tcp_stream_is_readable(const struct tcp_sock *tp, int target, struct sock *sk) { - return (tp->rcv_nxt - tp->copied_seq >= target) || + return (READ_ONCE(tp->rcv_nxt) - tp->copied_seq >= target) || (sk->sk_prot->stream_memory_read ? sk->sk_prot->stream_memory_read(sk) : false); } @@ -2935,7 +2935,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, else if (tp->repair_queue == TCP_SEND_QUEUE) tp->write_seq = val; else if (tp->repair_queue == TCP_RECV_QUEUE) - tp->rcv_nxt = val; + WRITE_ONCE(tp->rcv_nxt, val); else err = -EINVAL; break; diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index 81a8221d650a..cd219161f106 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c @@ -26,7 +26,7 @@ static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, } else if (sk->sk_type == SOCK_STREAM) { const struct tcp_sock *tp = tcp_sk(sk); - r->idiag_rqueue = max_t(int, tp->rcv_nxt - tp->copied_seq, 0); + r->idiag_rqueue = max_t(int, READ_ONCE(tp->rcv_nxt) - tp->copied_seq, 0); r->idiag_wqueue = tp->write_seq - tp->snd_una; } if (info) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 5f9b102c3b55..5b7c8768ed5f 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3362,7 +3362,7 @@ static void tcp_rcv_nxt_update(struct tcp_sock *tp, u32 seq) sock_owned_by_me((struct sock *)tp); tp->bytes_received += delta; - tp->rcv_nxt = seq; + WRITE_ONCE(tp->rcv_nxt, seq); } /* Update our send window. @@ -5932,7 +5932,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, /* Ok.. it's good. Set up sequence numbers and * move to established. */ - tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; + WRITE_ONCE(tp->rcv_nxt, TCP_SKB_CB(skb)->seq + 1); tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; /* RFC1323: The window in SYN & SYN/ACK segments is @@ -6035,7 +6035,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, tp->tcp_header_len = sizeof(struct tcphdr); } - tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; + WRITE_ONCE(tp->rcv_nxt, TCP_SKB_CB(skb)->seq + 1); tp->copied_seq = tp->rcv_nxt; tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index ffa366099eb2..5089dd6bee0f 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2455,7 +2455,8 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i) /* Because we don't lock the socket, * we might find a transient negative value. */ - rx_queue = max_t(int, tp->rcv_nxt - tp->copied_seq, 0); + rx_queue = max_t(int, READ_ONCE(tp->rcv_nxt) - + tp->copied_seq, 0); seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " "%08X %5u %8d %lu %d %pK %lu %lu %u %u %d", diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 5401dbd39c8f..adc6ce486a38 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -462,6 +462,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, struct tcp_request_sock *treq = tcp_rsk(req); struct inet_connection_sock *newicsk; struct tcp_sock *oldtp, *newtp; + u32 seq; if (!newsk) return NULL; @@ -475,8 +476,10 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, /* Now setup tcp_sock */ newtp->pred_flags = 0; - newtp->rcv_wup = newtp->copied_seq = - newtp->rcv_nxt = treq->rcv_isn + 1; + seq = treq->rcv_isn + 1; + newtp->rcv_wup = seq; + newtp->copied_seq = seq; + WRITE_ONCE(newtp->rcv_nxt, seq); newtp->segs_in = 1; newtp->snd_sml = newtp->snd_una = diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 45a95e032bdf..89ea0a7018b5 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1895,7 +1895,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) /* Because we don't lock the socket, * we might find a transient negative value. */ - rx_queue = max_t(int, tp->rcv_nxt - tp->copied_seq, 0); + rx_queue = max_t(int, READ_ONCE(tp->rcv_nxt) - + tp->copied_seq, 0); seq_printf(seq, "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " -- GitLab From 7db48e983930285b765743ebd665aecf9850582b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 10 Oct 2019 20:17:40 -0700 Subject: [PATCH 214/993] tcp: annotate tp->copied_seq lockless reads There are few places where we fetch tp->copied_seq while this field can change from IRQ or other cpu. We need to add READ_ONCE() annotations, and also make sure write sides use corresponding WRITE_ONCE() to avoid store-tearing. Note that tcp_inq_hint() was already using READ_ONCE(tp->copied_seq) Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 20 ++++++++++---------- net/ipv4/tcp_diag.c | 3 ++- net/ipv4/tcp_input.c | 6 +++--- net/ipv4/tcp_ipv4.c | 2 +- net/ipv4/tcp_minisocks.c | 2 +- net/ipv4/tcp_output.c | 2 +- net/ipv6/tcp_ipv6.c | 2 +- 7 files changed, 19 insertions(+), 18 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 883ee863db43..c322ad071e17 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -477,7 +477,7 @@ static void tcp_tx_timestamp(struct sock *sk, u16 tsflags) static inline bool tcp_stream_is_readable(const struct tcp_sock *tp, int target, struct sock *sk) { - return (READ_ONCE(tp->rcv_nxt) - tp->copied_seq >= target) || + return (READ_ONCE(tp->rcv_nxt) - READ_ONCE(tp->copied_seq) >= target) || (sk->sk_prot->stream_memory_read ? sk->sk_prot->stream_memory_read(sk) : false); } @@ -546,7 +546,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait) (state != TCP_SYN_RECV || rcu_access_pointer(tp->fastopen_rsk))) { int target = sock_rcvlowat(sk, 0, INT_MAX); - if (tp->urg_seq == tp->copied_seq && + if (tp->urg_seq == READ_ONCE(tp->copied_seq) && !sock_flag(sk, SOCK_URGINLINE) && tp->urg_data) target++; @@ -607,7 +607,7 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) unlock_sock_fast(sk, slow); break; case SIOCATMARK: - answ = tp->urg_data && tp->urg_seq == tp->copied_seq; + answ = tp->urg_data && tp->urg_seq == READ_ONCE(tp->copied_seq); break; case SIOCOUTQ: if (sk->sk_state == TCP_LISTEN) @@ -1668,9 +1668,9 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, sk_eat_skb(sk, skb); if (!desc->count) break; - tp->copied_seq = seq; + WRITE_ONCE(tp->copied_seq, seq); } - tp->copied_seq = seq; + WRITE_ONCE(tp->copied_seq, seq); tcp_rcv_space_adjust(sk); @@ -1819,7 +1819,7 @@ static int tcp_zerocopy_receive(struct sock *sk, out: up_read(¤t->mm->mmap_sem); if (length) { - tp->copied_seq = seq; + WRITE_ONCE(tp->copied_seq, seq); tcp_rcv_space_adjust(sk); /* Clean up data we have read: This will do ACK frames. */ @@ -2117,7 +2117,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, if (urg_offset < used) { if (!urg_offset) { if (!sock_flag(sk, SOCK_URGINLINE)) { - ++*seq; + WRITE_ONCE(*seq, *seq + 1); urg_hole++; offset++; used--; @@ -2139,7 +2139,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, } } - *seq += used; + WRITE_ONCE(*seq, *seq + used); copied += used; len -= used; @@ -2166,7 +2166,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, found_fin_ok: /* Process the FIN. */ - ++*seq; + WRITE_ONCE(*seq, *seq + 1); if (!(flags & MSG_PEEK)) sk_eat_skb(sk, skb); break; @@ -2588,7 +2588,7 @@ int tcp_disconnect(struct sock *sk, int flags) __kfree_skb(sk->sk_rx_skb_cache); sk->sk_rx_skb_cache = NULL; } - tp->copied_seq = tp->rcv_nxt; + WRITE_ONCE(tp->copied_seq, tp->rcv_nxt); tp->urg_data = 0; tcp_write_queue_purge(sk); tcp_fastopen_active_disable_ofo_check(sk); diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index cd219161f106..66273c8a55c2 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c @@ -26,7 +26,8 @@ static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, } else if (sk->sk_type == SOCK_STREAM) { const struct tcp_sock *tp = tcp_sk(sk); - r->idiag_rqueue = max_t(int, READ_ONCE(tp->rcv_nxt) - tp->copied_seq, 0); + r->idiag_rqueue = max_t(int, READ_ONCE(tp->rcv_nxt) - + READ_ONCE(tp->copied_seq), 0); r->idiag_wqueue = tp->write_seq - tp->snd_una; } if (info) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 5b7c8768ed5f..a30aae3a6a18 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5961,7 +5961,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, /* Remember, tcp_poll() does not lock socket! * Change state from SYN-SENT only after copied_seq * is initialized. */ - tp->copied_seq = tp->rcv_nxt; + WRITE_ONCE(tp->copied_seq, tp->rcv_nxt); smc_check_reset_syn(tp); @@ -6036,7 +6036,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, } WRITE_ONCE(tp->rcv_nxt, TCP_SKB_CB(skb)->seq + 1); - tp->copied_seq = tp->rcv_nxt; + WRITE_ONCE(tp->copied_seq, tp->rcv_nxt); tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; /* RFC1323: The window in SYN & SYN/ACK segments is @@ -6216,7 +6216,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb) tcp_try_undo_spurious_syn(sk); tp->retrans_stamp = 0; tcp_init_transfer(sk, BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB); - tp->copied_seq = tp->rcv_nxt; + WRITE_ONCE(tp->copied_seq, tp->rcv_nxt); } smp_mb(); tcp_set_state(sk, TCP_ESTABLISHED); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 5089dd6bee0f..39560f482e0b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2456,7 +2456,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i) * we might find a transient negative value. */ rx_queue = max_t(int, READ_ONCE(tp->rcv_nxt) - - tp->copied_seq, 0); + READ_ONCE(tp->copied_seq), 0); seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " "%08X %5u %8d %lu %d %pK %lu %lu %u %u %d", diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index adc6ce486a38..c4731d26ab4a 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -478,7 +478,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, seq = treq->rcv_isn + 1; newtp->rcv_wup = seq; - newtp->copied_seq = seq; + WRITE_ONCE(newtp->copied_seq, seq); WRITE_ONCE(newtp->rcv_nxt, seq); newtp->segs_in = 1; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 84ae4d1449ea..7dda12720169 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -3433,7 +3433,7 @@ static void tcp_connect_init(struct sock *sk) else tp->rcv_tstamp = tcp_jiffies32; tp->rcv_wup = tp->rcv_nxt; - tp->copied_seq = tp->rcv_nxt; + WRITE_ONCE(tp->copied_seq, tp->rcv_nxt); inet_csk(sk)->icsk_rto = tcp_timeout_init(sk); inet_csk(sk)->icsk_retransmits = 0; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 89ea0a7018b5..a62c7042fc4a 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1896,7 +1896,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) * we might find a transient negative value. */ rx_queue = max_t(int, READ_ONCE(tp->rcv_nxt) - - tp->copied_seq, 0); + READ_ONCE(tp->copied_seq), 0); seq_printf(seq, "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " -- GitLab From 0f31746452e6793ad6271337438af8f4defb8940 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 10 Oct 2019 20:17:41 -0700 Subject: [PATCH 215/993] tcp: annotate tp->write_seq lockless reads There are few places where we fetch tp->write_seq while this field can change from IRQ or other cpu. We need to add READ_ONCE() annotations, and also make sure write sides use corresponding WRITE_ONCE() to avoid store-tearing. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/tcp.h | 2 +- net/ipv4/tcp.c | 20 ++++++++++++-------- net/ipv4/tcp_diag.c | 2 +- net/ipv4/tcp_ipv4.c | 21 ++++++++++++--------- net/ipv4/tcp_minisocks.c | 2 +- net/ipv4/tcp_output.c | 4 ++-- net/ipv6/tcp_ipv6.c | 13 +++++++------ 7 files changed, 36 insertions(+), 28 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 35f6f7e0fdc2..8e7c3f6801a9 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1917,7 +1917,7 @@ static inline u32 tcp_notsent_lowat(const struct tcp_sock *tp) static inline bool tcp_stream_memory_free(const struct sock *sk, int wake) { const struct tcp_sock *tp = tcp_sk(sk); - u32 notsent_bytes = tp->write_seq - tp->snd_nxt; + u32 notsent_bytes = READ_ONCE(tp->write_seq) - tp->snd_nxt; return (notsent_bytes << wake) < tcp_notsent_lowat(tp); } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index c322ad071e17..96dd65cbeb85 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -616,7 +616,7 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) answ = 0; else - answ = tp->write_seq - tp->snd_una; + answ = READ_ONCE(tp->write_seq) - tp->snd_una; break; case SIOCOUTQNSD: if (sk->sk_state == TCP_LISTEN) @@ -625,7 +625,7 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) answ = 0; else - answ = tp->write_seq - tp->snd_nxt; + answ = READ_ONCE(tp->write_seq) - tp->snd_nxt; break; default: return -ENOIOCTLCMD; @@ -1035,7 +1035,7 @@ ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, sk->sk_wmem_queued += copy; sk_mem_charge(sk, copy); skb->ip_summed = CHECKSUM_PARTIAL; - tp->write_seq += copy; + WRITE_ONCE(tp->write_seq, tp->write_seq + copy); TCP_SKB_CB(skb)->end_seq += copy; tcp_skb_pcount_set(skb, 0); @@ -1362,7 +1362,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) if (!copied) TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH; - tp->write_seq += copy; + WRITE_ONCE(tp->write_seq, tp->write_seq + copy); TCP_SKB_CB(skb)->end_seq += copy; tcp_skb_pcount_set(skb, 0); @@ -2562,6 +2562,7 @@ int tcp_disconnect(struct sock *sk, int flags) struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); int old_state = sk->sk_state; + u32 seq; if (old_state != TCP_CLOSE) tcp_set_state(sk, TCP_CLOSE); @@ -2604,9 +2605,12 @@ int tcp_disconnect(struct sock *sk, int flags) tp->srtt_us = 0; tp->mdev_us = jiffies_to_usecs(TCP_TIMEOUT_INIT); tp->rcv_rtt_last_tsecr = 0; - tp->write_seq += tp->max_window + 2; - if (tp->write_seq == 0) - tp->write_seq = 1; + + seq = tp->write_seq + tp->max_window + 2; + if (!seq) + seq = 1; + WRITE_ONCE(tp->write_seq, seq); + icsk->icsk_backoff = 0; tp->snd_cwnd = 2; icsk->icsk_probes_out = 0; @@ -2933,7 +2937,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, if (sk->sk_state != TCP_CLOSE) err = -EPERM; else if (tp->repair_queue == TCP_SEND_QUEUE) - tp->write_seq = val; + WRITE_ONCE(tp->write_seq, val); else if (tp->repair_queue == TCP_RECV_QUEUE) WRITE_ONCE(tp->rcv_nxt, val); else diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index 66273c8a55c2..549506162dde 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c @@ -28,7 +28,7 @@ static void tcp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, r->idiag_rqueue = max_t(int, READ_ONCE(tp->rcv_nxt) - READ_ONCE(tp->copied_seq), 0); - r->idiag_wqueue = tp->write_seq - tp->snd_una; + r->idiag_wqueue = READ_ONCE(tp->write_seq) - tp->snd_una; } if (info) tcp_get_info(sk, info); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 39560f482e0b..6be568334848 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -164,9 +164,11 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp) * without appearing to create any others. */ if (likely(!tp->repair)) { - tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2; - if (tp->write_seq == 0) - tp->write_seq = 1; + u32 seq = tcptw->tw_snd_nxt + 65535 + 2; + + if (!seq) + seq = 1; + WRITE_ONCE(tp->write_seq, seq); tp->rx_opt.ts_recent = tcptw->tw_ts_recent; tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp; } @@ -253,7 +255,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) tp->rx_opt.ts_recent = 0; tp->rx_opt.ts_recent_stamp = 0; if (likely(!tp->repair)) - tp->write_seq = 0; + WRITE_ONCE(tp->write_seq, 0); } inet->inet_dport = usin->sin_port; @@ -291,10 +293,11 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) if (likely(!tp->repair)) { if (!tp->write_seq) - tp->write_seq = secure_tcp_seq(inet->inet_saddr, - inet->inet_daddr, - inet->inet_sport, - usin->sin_port); + WRITE_ONCE(tp->write_seq, + secure_tcp_seq(inet->inet_saddr, + inet->inet_daddr, + inet->inet_sport, + usin->sin_port)); tp->tsoffset = secure_tcp_ts_off(sock_net(sk), inet->inet_saddr, inet->inet_daddr); @@ -2461,7 +2464,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i) seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " "%08X %5u %8d %lu %d %pK %lu %lu %u %u %d", i, src, srcp, dest, destp, state, - tp->write_seq - tp->snd_una, + READ_ONCE(tp->write_seq) - tp->snd_una, rx_queue, timer_active, jiffies_delta_to_clock_t(timer_expires - jiffies), diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index c4731d26ab4a..339944690329 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -498,7 +498,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, newtp->total_retrans = req->num_retrans; tcp_init_xmit_timers(newsk); - newtp->write_seq = newtp->pushed_seq = treq->snt_isn + 1; + WRITE_ONCE(newtp->write_seq, newtp->pushed_seq = treq->snt_isn + 1); if (sock_flag(newsk, SOCK_KEEPOPEN)) inet_csk_reset_keepalive_timer(newsk, diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 7dda12720169..c17c2a78809d 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1196,7 +1196,7 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) struct tcp_sock *tp = tcp_sk(sk); /* Advance write_seq and place onto the write_queue. */ - tp->write_seq = TCP_SKB_CB(skb)->end_seq; + WRITE_ONCE(tp->write_seq, TCP_SKB_CB(skb)->end_seq); __skb_header_release(skb); tcp_add_write_queue_tail(sk, skb); sk->sk_wmem_queued += skb->truesize; @@ -3449,7 +3449,7 @@ static void tcp_connect_queue_skb(struct sock *sk, struct sk_buff *skb) __skb_header_release(skb); sk->sk_wmem_queued += skb->truesize; sk_mem_charge(sk, skb->truesize); - tp->write_seq = tcb->end_seq; + WRITE_ONCE(tp->write_seq, tcb->end_seq); tp->packets_out += tcp_skb_pcount(skb); } diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index a62c7042fc4a..4804b6dc5e65 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -215,7 +215,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, !ipv6_addr_equal(&sk->sk_v6_daddr, &usin->sin6_addr)) { tp->rx_opt.ts_recent = 0; tp->rx_opt.ts_recent_stamp = 0; - tp->write_seq = 0; + WRITE_ONCE(tp->write_seq, 0); } sk->sk_v6_daddr = usin->sin6_addr; @@ -311,10 +311,11 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, if (likely(!tp->repair)) { if (!tp->write_seq) - tp->write_seq = secure_tcpv6_seq(np->saddr.s6_addr32, - sk->sk_v6_daddr.s6_addr32, - inet->inet_sport, - inet->inet_dport); + WRITE_ONCE(tp->write_seq, + secure_tcpv6_seq(np->saddr.s6_addr32, + sk->sk_v6_daddr.s6_addr32, + inet->inet_sport, + inet->inet_dport)); tp->tsoffset = secure_tcpv6_ts_off(sock_net(sk), np->saddr.s6_addr32, sk->sk_v6_daddr.s6_addr32); @@ -1907,7 +1908,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) dest->s6_addr32[0], dest->s6_addr32[1], dest->s6_addr32[2], dest->s6_addr32[3], destp, state, - tp->write_seq - tp->snd_una, + READ_ONCE(tp->write_seq) - tp->snd_una, rx_queue, timer_active, jiffies_delta_to_clock_t(timer_expires - jiffies), -- GitLab From e0d694d638dba768b47be31c22e1a9b4f862f561 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 10 Oct 2019 20:17:42 -0700 Subject: [PATCH 216/993] tcp: annotate tp->snd_nxt lockless reads There are few places where we fetch tp->snd_nxt while this field can change from IRQ or other cpu. We need to add READ_ONCE() annotations, and also make sure write sides use corresponding WRITE_ONCE() to avoid store-tearing. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/tcp.h | 3 ++- net/ipv4/tcp.c | 3 ++- net/ipv4/tcp_minisocks.c | 6 ++++-- net/ipv4/tcp_output.c | 10 +++++----- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 8e7c3f6801a9..e1d08f69fd39 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1917,7 +1917,8 @@ static inline u32 tcp_notsent_lowat(const struct tcp_sock *tp) static inline bool tcp_stream_memory_free(const struct sock *sk, int wake) { const struct tcp_sock *tp = tcp_sk(sk); - u32 notsent_bytes = READ_ONCE(tp->write_seq) - tp->snd_nxt; + u32 notsent_bytes = READ_ONCE(tp->write_seq) - + READ_ONCE(tp->snd_nxt); return (notsent_bytes << wake) < tcp_notsent_lowat(tp); } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 96dd65cbeb85..652568750cb1 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -625,7 +625,8 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) answ = 0; else - answ = READ_ONCE(tp->write_seq) - tp->snd_nxt; + answ = READ_ONCE(tp->write_seq) - + READ_ONCE(tp->snd_nxt); break; default: return -ENOIOCTLCMD; diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 339944690329..c802bc80c400 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -482,8 +482,10 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, WRITE_ONCE(newtp->rcv_nxt, seq); newtp->segs_in = 1; - newtp->snd_sml = newtp->snd_una = - newtp->snd_nxt = newtp->snd_up = treq->snt_isn + 1; + seq = treq->snt_isn + 1; + newtp->snd_sml = newtp->snd_una = seq; + WRITE_ONCE(newtp->snd_nxt, seq); + newtp->snd_up = seq; INIT_LIST_HEAD(&newtp->tsq_node); INIT_LIST_HEAD(&newtp->tsorted_sent_queue); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index c17c2a78809d..a115a991dfb5 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -67,7 +67,7 @@ static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb) struct tcp_sock *tp = tcp_sk(sk); unsigned int prior_packets = tp->packets_out; - tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; + WRITE_ONCE(tp->snd_nxt, TCP_SKB_CB(skb)->end_seq); __skb_unlink(skb, &sk->sk_write_queue); tcp_rbtree_insert(&sk->tcp_rtx_queue, skb); @@ -3142,7 +3142,7 @@ void tcp_send_fin(struct sock *sk) * if FIN had been sent. This is because retransmit path * does not change tp->snd_nxt. */ - tp->snd_nxt++; + WRITE_ONCE(tp->snd_nxt, tp->snd_nxt + 1); return; } } else { @@ -3426,7 +3426,7 @@ static void tcp_connect_init(struct sock *sk) tp->snd_una = tp->write_seq; tp->snd_sml = tp->write_seq; tp->snd_up = tp->write_seq; - tp->snd_nxt = tp->write_seq; + WRITE_ONCE(tp->snd_nxt, tp->write_seq); if (likely(!tp->repair)) tp->rcv_nxt = 0; @@ -3586,11 +3586,11 @@ int tcp_connect(struct sock *sk) /* We change tp->snd_nxt after the tcp_transmit_skb() call * in order to make this packet get counted in tcpOutSegs. */ - tp->snd_nxt = tp->write_seq; + WRITE_ONCE(tp->snd_nxt, tp->write_seq); tp->pushed_seq = tp->write_seq; buff = tcp_send_head(sk); if (unlikely(buff)) { - tp->snd_nxt = TCP_SKB_CB(buff)->seq; + WRITE_ONCE(tp->snd_nxt, TCP_SKB_CB(buff)->seq); tp->pushed_seq = TCP_SKB_CB(buff)->seq; } TCP_INC_STATS(sock_net(sk), TCP_MIB_ACTIVEOPENS); -- GitLab From d9b55bf7b6788ec0bd1db1acefbc4feb1399144a Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 10 Oct 2019 20:17:43 -0700 Subject: [PATCH 217/993] tcp: annotate tp->urg_seq lockless reads There two places where we fetch tp->urg_seq while this field can change from IRQ or other cpu. We need to add READ_ONCE() annotations, and also make sure write side use corresponding WRITE_ONCE() to avoid store-tearing. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 5 +++-- net/ipv4/tcp_input.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 652568750cb1..577a8c6eef9f 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -546,7 +546,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait) (state != TCP_SYN_RECV || rcu_access_pointer(tp->fastopen_rsk))) { int target = sock_rcvlowat(sk, 0, INT_MAX); - if (tp->urg_seq == READ_ONCE(tp->copied_seq) && + if (READ_ONCE(tp->urg_seq) == READ_ONCE(tp->copied_seq) && !sock_flag(sk, SOCK_URGINLINE) && tp->urg_data) target++; @@ -607,7 +607,8 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) unlock_sock_fast(sk, slow); break; case SIOCATMARK: - answ = tp->urg_data && tp->urg_seq == READ_ONCE(tp->copied_seq); + answ = tp->urg_data && + READ_ONCE(tp->urg_seq) == READ_ONCE(tp->copied_seq); break; case SIOCOUTQ: if (sk->sk_state == TCP_LISTEN) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index a30aae3a6a18..16342e043ab3 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5356,7 +5356,7 @@ static void tcp_check_urg(struct sock *sk, const struct tcphdr *th) } tp->urg_data = TCP_URG_NOTYET; - tp->urg_seq = ptr; + WRITE_ONCE(tp->urg_seq, ptr); /* Disable header prediction. */ tp->pred_flags = 0; -- GitLab From ebb3b78db7bf842270a46fd4fe7cc45c78fa5ed6 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 10 Oct 2019 20:17:44 -0700 Subject: [PATCH 218/993] tcp: annotate sk->sk_rcvbuf lockless reads For the sake of tcp_poll(), there are few places where we fetch sk->sk_rcvbuf while this field can change from IRQ or other cpu. We need to add READ_ONCE() annotations, and also make sure write sides use corresponding WRITE_ONCE() to avoid store-tearing. Note that other transports probably need similar fixes. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/tcp.h | 4 ++-- include/trace/events/sock.h | 2 +- net/core/filter.c | 3 ++- net/core/skbuff.c | 2 +- net/core/sock.c | 5 +++-- net/ipv4/tcp.c | 4 ++-- net/ipv4/tcp_input.c | 7 ++++--- 7 files changed, 15 insertions(+), 12 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index e1d08f69fd39..ab4eb5eb5d07 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1380,14 +1380,14 @@ static inline int tcp_win_from_space(const struct sock *sk, int space) /* Note: caller must be prepared to deal with negative returns */ static inline int tcp_space(const struct sock *sk) { - return tcp_win_from_space(sk, sk->sk_rcvbuf - + return tcp_win_from_space(sk, READ_ONCE(sk->sk_rcvbuf) - READ_ONCE(sk->sk_backlog.len) - atomic_read(&sk->sk_rmem_alloc)); } static inline int tcp_full_space(const struct sock *sk) { - return tcp_win_from_space(sk, sk->sk_rcvbuf); + return tcp_win_from_space(sk, READ_ONCE(sk->sk_rcvbuf)); } extern void tcp_openreq_init_rwin(struct request_sock *req, diff --git a/include/trace/events/sock.h b/include/trace/events/sock.h index a0c4b8a30966..f720c32e7dfd 100644 --- a/include/trace/events/sock.h +++ b/include/trace/events/sock.h @@ -82,7 +82,7 @@ TRACE_EVENT(sock_rcvqueue_full, TP_fast_assign( __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc); __entry->truesize = skb->truesize; - __entry->sk_rcvbuf = sk->sk_rcvbuf; + __entry->sk_rcvbuf = READ_ONCE(sk->sk_rcvbuf); ), TP_printk("rmem_alloc=%d truesize=%u sk_rcvbuf=%d", diff --git a/net/core/filter.c b/net/core/filter.c index a50c0b6846f2..7deceaeeed7b 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -4252,7 +4252,8 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock, case SO_RCVBUF: val = min_t(u32, val, sysctl_rmem_max); sk->sk_userlocks |= SOCK_RCVBUF_LOCK; - sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF); + WRITE_ONCE(sk->sk_rcvbuf, + max_t(int, val * 2, SOCK_MIN_RCVBUF)); break; case SO_SNDBUF: val = min_t(u32, val, sysctl_wmem_max); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 529133611ea2..8c178703467b 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4415,7 +4415,7 @@ static void skb_set_err_queue(struct sk_buff *skb) int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) { if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= - (unsigned int)sk->sk_rcvbuf) + (unsigned int)READ_ONCE(sk->sk_rcvbuf)) return -ENOMEM; skb_orphan(skb); diff --git a/net/core/sock.c b/net/core/sock.c index 2a053999df11..8c8f61e70141 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -831,7 +831,8 @@ int sock_setsockopt(struct socket *sock, int level, int optname, * returning the value we actually used in getsockopt * is the most desirable behavior. */ - sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF); + WRITE_ONCE(sk->sk_rcvbuf, + max_t(int, val * 2, SOCK_MIN_RCVBUF)); break; case SO_RCVBUFFORCE: @@ -3204,7 +3205,7 @@ void sk_get_meminfo(const struct sock *sk, u32 *mem) memset(mem, 0, sizeof(*mem) * SK_MEMINFO_VARS); mem[SK_MEMINFO_RMEM_ALLOC] = sk_rmem_alloc_get(sk); - mem[SK_MEMINFO_RCVBUF] = sk->sk_rcvbuf; + mem[SK_MEMINFO_RCVBUF] = READ_ONCE(sk->sk_rcvbuf); mem[SK_MEMINFO_WMEM_ALLOC] = sk_wmem_alloc_get(sk); mem[SK_MEMINFO_SNDBUF] = sk->sk_sndbuf; mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 577a8c6eef9f..bc0481aa6633 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -451,7 +451,7 @@ void tcp_init_sock(struct sock *sk) icsk->icsk_sync_mss = tcp_sync_mss; sk->sk_sndbuf = sock_net(sk)->ipv4.sysctl_tcp_wmem[1]; - sk->sk_rcvbuf = sock_net(sk)->ipv4.sysctl_tcp_rmem[1]; + WRITE_ONCE(sk->sk_rcvbuf, sock_net(sk)->ipv4.sysctl_tcp_rmem[1]); sk_sockets_allocated_inc(sk); sk->sk_route_forced_caps = NETIF_F_GSO; @@ -1711,7 +1711,7 @@ int tcp_set_rcvlowat(struct sock *sk, int val) val <<= 1; if (val > sk->sk_rcvbuf) { - sk->sk_rcvbuf = val; + WRITE_ONCE(sk->sk_rcvbuf, val); tcp_sk(sk)->window_clamp = tcp_win_from_space(sk, val); } return 0; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 16342e043ab3..6995df20710a 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -483,8 +483,9 @@ static void tcp_clamp_window(struct sock *sk) !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && !tcp_under_memory_pressure(sk) && sk_memory_allocated(sk) < sk_prot_mem_limits(sk, 0)) { - sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), - net->ipv4.sysctl_tcp_rmem[2]); + WRITE_ONCE(sk->sk_rcvbuf, + min(atomic_read(&sk->sk_rmem_alloc), + net->ipv4.sysctl_tcp_rmem[2])); } if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf) tp->rcv_ssthresh = min(tp->window_clamp, 2U * tp->advmss); @@ -648,7 +649,7 @@ void tcp_rcv_space_adjust(struct sock *sk) rcvbuf = min_t(u64, rcvwin * rcvmem, sock_net(sk)->ipv4.sysctl_tcp_rmem[2]); if (rcvbuf > sk->sk_rcvbuf) { - sk->sk_rcvbuf = rcvbuf; + WRITE_ONCE(sk->sk_rcvbuf, rcvbuf); /* Make the window clamp follow along. */ tp->window_clamp = tcp_win_from_space(sk, rcvbuf); -- GitLab From e292f05e0df73f9fcc93329663936e1ded97a988 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 10 Oct 2019 20:17:45 -0700 Subject: [PATCH 219/993] tcp: annotate sk->sk_sndbuf lockless reads For the sake of tcp_poll(), there are few places where we fetch sk->sk_sndbuf while this field can change from IRQ or other cpu. We need to add READ_ONCE() annotations, and also make sure write sides use corresponding WRITE_ONCE() to avoid store-tearing. Note that other transports probably need similar fixes. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/sock.h | 18 +++++++++++------- net/core/filter.c | 3 ++- net/core/sock.c | 15 +++++++++------ net/ipv4/tcp.c | 2 +- net/ipv4/tcp_input.c | 3 ++- 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 79f54e1f8827..3d1e7502333e 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -883,7 +883,7 @@ static inline int sk_stream_min_wspace(const struct sock *sk) static inline int sk_stream_wspace(const struct sock *sk) { - return sk->sk_sndbuf - sk->sk_wmem_queued; + return READ_ONCE(sk->sk_sndbuf) - sk->sk_wmem_queued; } void sk_stream_write_space(struct sock *sk); @@ -1207,7 +1207,7 @@ static inline void sk_refcnt_debug_release(const struct sock *sk) static inline bool __sk_stream_memory_free(const struct sock *sk, int wake) { - if (sk->sk_wmem_queued >= sk->sk_sndbuf) + if (sk->sk_wmem_queued >= READ_ONCE(sk->sk_sndbuf)) return false; return sk->sk_prot->stream_memory_free ? @@ -2220,10 +2220,14 @@ static inline void sk_wake_async(const struct sock *sk, int how, int band) static inline void sk_stream_moderate_sndbuf(struct sock *sk) { - if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) { - sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued >> 1); - sk->sk_sndbuf = max_t(u32, sk->sk_sndbuf, SOCK_MIN_SNDBUF); - } + u32 val; + + if (sk->sk_userlocks & SOCK_SNDBUF_LOCK) + return; + + val = min(sk->sk_sndbuf, sk->sk_wmem_queued >> 1); + + WRITE_ONCE(sk->sk_sndbuf, max_t(u32, val, SOCK_MIN_SNDBUF)); } struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp, @@ -2251,7 +2255,7 @@ bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag); */ static inline bool sock_writeable(const struct sock *sk) { - return refcount_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf >> 1); + return refcount_read(&sk->sk_wmem_alloc) < (READ_ONCE(sk->sk_sndbuf) >> 1); } static inline gfp_t gfp_any(void) diff --git a/net/core/filter.c b/net/core/filter.c index 7deceaeeed7b..3fed5755494b 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -4258,7 +4258,8 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock, case SO_SNDBUF: val = min_t(u32, val, sysctl_wmem_max); sk->sk_userlocks |= SOCK_SNDBUF_LOCK; - sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF); + WRITE_ONCE(sk->sk_sndbuf, + max_t(int, val * 2, SOCK_MIN_SNDBUF)); break; case SO_MAX_PACING_RATE: /* 32bit version */ if (val != ~0U) diff --git a/net/core/sock.c b/net/core/sock.c index 8c8f61e70141..cd075bc86407 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -785,7 +785,8 @@ int sock_setsockopt(struct socket *sock, int level, int optname, */ val = min_t(int, val, INT_MAX / 2); sk->sk_userlocks |= SOCK_SNDBUF_LOCK; - sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF); + WRITE_ONCE(sk->sk_sndbuf, + max_t(int, val * 2, SOCK_MIN_SNDBUF)); /* Wake up sending tasks if we upped the value. */ sk->sk_write_space(sk); break; @@ -2089,8 +2090,10 @@ EXPORT_SYMBOL(sock_i_ino); struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, gfp_t priority) { - if (force || refcount_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { + if (force || + refcount_read(&sk->sk_wmem_alloc) < READ_ONCE(sk->sk_sndbuf)) { struct sk_buff *skb = alloc_skb(size, priority); + if (skb) { skb_set_owner_w(skb, sk); return skb; @@ -2191,7 +2194,7 @@ static long sock_wait_for_wmem(struct sock *sk, long timeo) break; set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); - if (refcount_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) + if (refcount_read(&sk->sk_wmem_alloc) < READ_ONCE(sk->sk_sndbuf)) break; if (sk->sk_shutdown & SEND_SHUTDOWN) break; @@ -2226,7 +2229,7 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, if (sk->sk_shutdown & SEND_SHUTDOWN) goto failure; - if (sk_wmem_alloc_get(sk) < sk->sk_sndbuf) + if (sk_wmem_alloc_get(sk) < READ_ONCE(sk->sk_sndbuf)) break; sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk); @@ -2807,7 +2810,7 @@ static void sock_def_write_space(struct sock *sk) /* Do not wake up a writer until he can make "significant" * progress. --DaveM */ - if ((refcount_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) { + if ((refcount_read(&sk->sk_wmem_alloc) << 1) <= READ_ONCE(sk->sk_sndbuf)) { wq = rcu_dereference(sk->sk_wq); if (skwq_has_sleeper(wq)) wake_up_interruptible_sync_poll(&wq->wait, EPOLLOUT | @@ -3207,7 +3210,7 @@ void sk_get_meminfo(const struct sock *sk, u32 *mem) mem[SK_MEMINFO_RMEM_ALLOC] = sk_rmem_alloc_get(sk); mem[SK_MEMINFO_RCVBUF] = READ_ONCE(sk->sk_rcvbuf); mem[SK_MEMINFO_WMEM_ALLOC] = sk_wmem_alloc_get(sk); - mem[SK_MEMINFO_SNDBUF] = sk->sk_sndbuf; + mem[SK_MEMINFO_SNDBUF] = READ_ONCE(sk->sk_sndbuf); mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc; mem[SK_MEMINFO_WMEM_QUEUED] = sk->sk_wmem_queued; mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index bc0481aa6633..111853262972 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -450,7 +450,7 @@ void tcp_init_sock(struct sock *sk) icsk->icsk_sync_mss = tcp_sync_mss; - sk->sk_sndbuf = sock_net(sk)->ipv4.sysctl_tcp_wmem[1]; + WRITE_ONCE(sk->sk_sndbuf, sock_net(sk)->ipv4.sysctl_tcp_wmem[1]); WRITE_ONCE(sk->sk_rcvbuf, sock_net(sk)->ipv4.sysctl_tcp_rmem[1]); sk_sockets_allocated_inc(sk); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 6995df20710a..a2e52ad7cdab 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -359,7 +359,8 @@ static void tcp_sndbuf_expand(struct sock *sk) sndmem *= nr_segs * per_mss; if (sk->sk_sndbuf < sndmem) - sk->sk_sndbuf = min(sndmem, sock_net(sk)->ipv4.sysctl_tcp_wmem[2]); + WRITE_ONCE(sk->sk_sndbuf, + min(sndmem, sock_net(sk)->ipv4.sysctl_tcp_wmem[2])); } /* 2. Tuning advertised window (window_clamp, rcv_ssthresh) -- GitLab From ab4e846a82d0ae00176de19f2db3c5c64f8eb5f2 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 10 Oct 2019 20:17:46 -0700 Subject: [PATCH 220/993] tcp: annotate sk->sk_wmem_queued lockless reads For the sake of tcp_poll(), there are few places where we fetch sk->sk_wmem_queued while this field can change from IRQ or other cpu. We need to add READ_ONCE() annotations, and also make sure write sides use corresponding WRITE_ONCE() to avoid store-tearing. sk_wmem_queued_add() helper is added so that we can in the future convert to ADD_ONCE() or equivalent if/when available. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/sock.h | 15 ++++++++++----- include/trace/events/sock.h | 2 +- net/core/datagram.c | 2 +- net/core/sock.c | 2 +- net/ipv4/inet_diag.c | 2 +- net/ipv4/tcp.c | 4 ++-- net/ipv4/tcp_output.c | 14 +++++++------- net/sched/em_meta.c | 2 +- 8 files changed, 24 insertions(+), 19 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 3d1e7502333e..f69b58bff7e5 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -878,12 +878,17 @@ static inline bool sk_acceptq_is_full(const struct sock *sk) */ static inline int sk_stream_min_wspace(const struct sock *sk) { - return sk->sk_wmem_queued >> 1; + return READ_ONCE(sk->sk_wmem_queued) >> 1; } static inline int sk_stream_wspace(const struct sock *sk) { - return READ_ONCE(sk->sk_sndbuf) - sk->sk_wmem_queued; + return READ_ONCE(sk->sk_sndbuf) - READ_ONCE(sk->sk_wmem_queued); +} + +static inline void sk_wmem_queued_add(struct sock *sk, int val) +{ + WRITE_ONCE(sk->sk_wmem_queued, sk->sk_wmem_queued + val); } void sk_stream_write_space(struct sock *sk); @@ -1207,7 +1212,7 @@ static inline void sk_refcnt_debug_release(const struct sock *sk) static inline bool __sk_stream_memory_free(const struct sock *sk, int wake) { - if (sk->sk_wmem_queued >= READ_ONCE(sk->sk_sndbuf)) + if (READ_ONCE(sk->sk_wmem_queued) >= READ_ONCE(sk->sk_sndbuf)) return false; return sk->sk_prot->stream_memory_free ? @@ -1467,7 +1472,7 @@ DECLARE_STATIC_KEY_FALSE(tcp_tx_skb_cache_key); static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb) { sock_set_flag(sk, SOCK_QUEUE_SHRUNK); - sk->sk_wmem_queued -= skb->truesize; + sk_wmem_queued_add(sk, -skb->truesize); sk_mem_uncharge(sk, skb->truesize); if (static_branch_unlikely(&tcp_tx_skb_cache_key) && !sk->sk_tx_skb_cache && !skb_cloned(skb)) { @@ -2014,7 +2019,7 @@ static inline int skb_copy_to_page_nocache(struct sock *sk, struct iov_iter *fro skb->len += copy; skb->data_len += copy; skb->truesize += copy; - sk->sk_wmem_queued += copy; + sk_wmem_queued_add(sk, copy); sk_mem_charge(sk, copy); return 0; } diff --git a/include/trace/events/sock.h b/include/trace/events/sock.h index f720c32e7dfd..51fe9f6719eb 100644 --- a/include/trace/events/sock.h +++ b/include/trace/events/sock.h @@ -115,7 +115,7 @@ TRACE_EVENT(sock_exceed_buf_limit, __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc); __entry->sysctl_wmem = sk_get_wmem0(sk, prot); __entry->wmem_alloc = refcount_read(&sk->sk_wmem_alloc); - __entry->wmem_queued = sk->sk_wmem_queued; + __entry->wmem_queued = READ_ONCE(sk->sk_wmem_queued); __entry->kind = kind; ), diff --git a/net/core/datagram.c b/net/core/datagram.c index 4cc8dc5db2b7..c210fc116103 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -640,7 +640,7 @@ int __zerocopy_sg_from_iter(struct sock *sk, struct sk_buff *skb, skb->len += copied; skb->truesize += truesize; if (sk && sk->sk_type == SOCK_STREAM) { - sk->sk_wmem_queued += truesize; + sk_wmem_queued_add(sk, truesize); sk_mem_charge(sk, truesize); } else { refcount_add(truesize, &skb->sk->sk_wmem_alloc); diff --git a/net/core/sock.c b/net/core/sock.c index cd075bc86407..a515392ba84b 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -3212,7 +3212,7 @@ void sk_get_meminfo(const struct sock *sk, u32 *mem) mem[SK_MEMINFO_WMEM_ALLOC] = sk_wmem_alloc_get(sk); mem[SK_MEMINFO_SNDBUF] = READ_ONCE(sk->sk_sndbuf); mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc; - mem[SK_MEMINFO_WMEM_QUEUED] = sk->sk_wmem_queued; + mem[SK_MEMINFO_WMEM_QUEUED] = READ_ONCE(sk->sk_wmem_queued); mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc); mem[SK_MEMINFO_BACKLOG] = READ_ONCE(sk->sk_backlog.len); mem[SK_MEMINFO_DROPS] = atomic_read(&sk->sk_drops); diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index bbb005eb5218..7dc79b973e6e 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -193,7 +193,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, if (ext & (1 << (INET_DIAG_MEMINFO - 1))) { struct inet_diag_meminfo minfo = { .idiag_rmem = sk_rmem_alloc_get(sk), - .idiag_wmem = sk->sk_wmem_queued, + .idiag_wmem = READ_ONCE(sk->sk_wmem_queued), .idiag_fmem = sk->sk_forward_alloc, .idiag_tmem = sk_wmem_alloc_get(sk), }; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 111853262972..b2ac4f074e2d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -659,7 +659,7 @@ static void skb_entail(struct sock *sk, struct sk_buff *skb) tcb->sacked = 0; __skb_header_release(skb); tcp_add_write_queue_tail(sk, skb); - sk->sk_wmem_queued += skb->truesize; + sk_wmem_queued_add(sk, skb->truesize); sk_mem_charge(sk, skb->truesize); if (tp->nonagle & TCP_NAGLE_PUSH) tp->nonagle &= ~TCP_NAGLE_PUSH; @@ -1034,7 +1034,7 @@ ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset, skb->len += copy; skb->data_len += copy; skb->truesize += copy; - sk->sk_wmem_queued += copy; + sk_wmem_queued_add(sk, copy); sk_mem_charge(sk, copy); skb->ip_summed = CHECKSUM_PARTIAL; WRITE_ONCE(tp->write_seq, tp->write_seq + copy); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index a115a991dfb5..0488607c5cd3 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1199,7 +1199,7 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) WRITE_ONCE(tp->write_seq, TCP_SKB_CB(skb)->end_seq); __skb_header_release(skb); tcp_add_write_queue_tail(sk, skb); - sk->sk_wmem_queued += skb->truesize; + sk_wmem_queued_add(sk, skb->truesize); sk_mem_charge(sk, skb->truesize); } @@ -1333,7 +1333,7 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue, return -ENOMEM; /* We'll just try again later. */ skb_copy_decrypted(buff, skb); - sk->sk_wmem_queued += buff->truesize; + sk_wmem_queued_add(sk, buff->truesize); sk_mem_charge(sk, buff->truesize); nlen = skb->len - len - nsize; buff->truesize += nlen; @@ -1443,7 +1443,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) if (delta_truesize) { skb->truesize -= delta_truesize; - sk->sk_wmem_queued -= delta_truesize; + sk_wmem_queued_add(sk, -delta_truesize); sk_mem_uncharge(sk, delta_truesize); sock_set_flag(sk, SOCK_QUEUE_SHRUNK); } @@ -1888,7 +1888,7 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len, return -ENOMEM; skb_copy_decrypted(buff, skb); - sk->sk_wmem_queued += buff->truesize; + sk_wmem_queued_add(sk, buff->truesize); sk_mem_charge(sk, buff->truesize); buff->truesize += nlen; skb->truesize -= nlen; @@ -2152,7 +2152,7 @@ static int tcp_mtu_probe(struct sock *sk) nskb = sk_stream_alloc_skb(sk, probe_size, GFP_ATOMIC, false); if (!nskb) return -1; - sk->sk_wmem_queued += nskb->truesize; + sk_wmem_queued_add(sk, nskb->truesize); sk_mem_charge(sk, nskb->truesize); skb = tcp_send_head(sk); @@ -3222,7 +3222,7 @@ int tcp_send_synack(struct sock *sk) tcp_rtx_queue_unlink_and_free(skb, sk); __skb_header_release(nskb); tcp_rbtree_insert(&sk->tcp_rtx_queue, nskb); - sk->sk_wmem_queued += nskb->truesize; + sk_wmem_queued_add(sk, nskb->truesize); sk_mem_charge(sk, nskb->truesize); skb = nskb; } @@ -3447,7 +3447,7 @@ static void tcp_connect_queue_skb(struct sock *sk, struct sk_buff *skb) tcb->end_seq += skb->len; __skb_header_release(skb); - sk->sk_wmem_queued += skb->truesize; + sk_wmem_queued_add(sk, skb->truesize); sk_mem_charge(sk, skb->truesize); WRITE_ONCE(tp->write_seq, tcb->end_seq); tp->packets_out += tcp_skb_pcount(skb); diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 4c9122fc35c9..3177dcb17316 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -446,7 +446,7 @@ META_COLLECTOR(int_sk_wmem_queued) *err = -1; return; } - dst->value = sk->sk_wmem_queued; + dst->value = READ_ONCE(sk->sk_wmem_queued); } META_COLLECTOR(int_sk_fwd_alloc) -- GitLab From c23936fad79ea2bea749db19b8921bb4dc524905 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 10 Oct 2019 22:46:06 +0200 Subject: [PATCH 221/993] net: lpc_eth: avoid resetting twice __lpc_eth_shutdown is called after __lpc_eth_reset but it is already calling __lpc_eth_reset. Avoid resetting the IP twice. Signed-off-by: Alexandre Belloni Signed-off-by: David S. Miller --- drivers/net/ethernet/nxp/lpc_eth.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index 141571e2ec11..544012a67221 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c @@ -1356,9 +1356,6 @@ static int lpc_eth_drv_probe(struct platform_device *pdev) if (!is_valid_ether_addr(ndev->dev_addr)) eth_hw_addr_random(ndev); - /* Reset the ethernet controller */ - __lpc_eth_reset(pldat); - /* then shut everything down to save power */ __lpc_eth_shutdown(pldat); -- GitLab From 11d49ce9f7946dfed4dcf5dbde865c78058b50ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Fri, 11 Oct 2019 07:52:54 +0200 Subject: [PATCH 222/993] net/ibmvnic: Fix EOI when running in XIVE mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pSeries machines on POWER9 processors can run with the XICS (legacy) interrupt mode or with the XIVE exploitation interrupt mode. These interrupt contollers have different interfaces for interrupt management : XICS uses hcalls and XIVE loads and stores on a page. H_EOI being a XICS interface the enable_scrq_irq() routine can fail when the machine runs in XIVE mode. Fix that by calling the EOI handler of the interrupt chip. Fixes: f23e0643cd0b ("ibmvnic: Clear pending interrupt after device reset") Signed-off-by: Cédric Le Goater Signed-off-by: David S. Miller --- drivers/net/ethernet/ibm/ibmvnic.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 2b073a3c0b84..f59d9a8e35e2 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -2878,12 +2878,10 @@ static int enable_scrq_irq(struct ibmvnic_adapter *adapter, if (test_bit(0, &adapter->resetting) && adapter->reset_reason == VNIC_RESET_MOBILITY) { - u64 val = (0xff000000) | scrq->hw_irq; + struct irq_desc *desc = irq_to_desc(scrq->irq); + struct irq_chip *chip = irq_desc_get_chip(desc); - rc = plpar_hcall_norets(H_EOI, val); - if (rc) - dev_err(dev, "H_EOI FAILED irq 0x%llx. rc=%ld\n", - val, rc); + chip->irq_eoi(&desc->irq_data); } rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address, -- GitLab From 33902b4a4227877896dd9368ac10f4ca0d100de5 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Fri, 11 Oct 2019 17:46:53 +0800 Subject: [PATCH 223/993] netdevsim: Fix error handling in nsim_fib_init and nsim_fib_exit In nsim_fib_init(), if register_fib_notifier failed, nsim_fib_net_ops should be unregistered before return. In nsim_fib_exit(), unregister_fib_notifier should be called before nsim_fib_net_ops be unregistered, otherwise may cause use-after-free: BUG: KASAN: use-after-free in nsim_fib_event_nb+0x342/0x570 [netdevsim] Read of size 8 at addr ffff8881daaf4388 by task kworker/0:3/3499 CPU: 0 PID: 3499 Comm: kworker/0:3 Not tainted 5.3.0-rc7+ #30 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 Workqueue: ipv6_addrconf addrconf_dad_work [ipv6] Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xa9/0x10e lib/dump_stack.c:113 print_address_description+0x65/0x380 mm/kasan/report.c:351 __kasan_report+0x149/0x18d mm/kasan/report.c:482 kasan_report+0xe/0x20 mm/kasan/common.c:618 nsim_fib_event_nb+0x342/0x570 [netdevsim] notifier_call_chain+0x52/0xf0 kernel/notifier.c:95 __atomic_notifier_call_chain+0x78/0x140 kernel/notifier.c:185 call_fib_notifiers+0x30/0x60 net/core/fib_notifier.c:30 call_fib6_entry_notifiers+0xc1/0x100 [ipv6] fib6_add+0x92e/0x1b10 [ipv6] __ip6_ins_rt+0x40/0x60 [ipv6] ip6_ins_rt+0x84/0xb0 [ipv6] __ipv6_ifa_notify+0x4b6/0x550 [ipv6] ipv6_ifa_notify+0xa5/0x180 [ipv6] addrconf_dad_completed+0xca/0x640 [ipv6] addrconf_dad_work+0x296/0x960 [ipv6] process_one_work+0x5c0/0xc00 kernel/workqueue.c:2269 worker_thread+0x5c/0x670 kernel/workqueue.c:2415 kthread+0x1d7/0x200 kernel/kthread.c:255 ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:352 Allocated by task 3388: save_stack+0x19/0x80 mm/kasan/common.c:69 set_track mm/kasan/common.c:77 [inline] __kasan_kmalloc.constprop.3+0xa0/0xd0 mm/kasan/common.c:493 kmalloc include/linux/slab.h:557 [inline] kzalloc include/linux/slab.h:748 [inline] ops_init+0xa9/0x220 net/core/net_namespace.c:127 __register_pernet_operations net/core/net_namespace.c:1135 [inline] register_pernet_operations+0x1d4/0x420 net/core/net_namespace.c:1212 register_pernet_subsys+0x24/0x40 net/core/net_namespace.c:1253 nsim_fib_init+0x12/0x70 [netdevsim] veth_get_link_ksettings+0x2b/0x50 [veth] do_one_initcall+0xd4/0x454 init/main.c:939 do_init_module+0xe0/0x330 kernel/module.c:3490 load_module+0x3c2f/0x4620 kernel/module.c:3841 __do_sys_finit_module+0x163/0x190 kernel/module.c:3931 do_syscall_64+0x72/0x2e0 arch/x86/entry/common.c:296 entry_SYSCALL_64_after_hwframe+0x49/0xbe Freed by task 3534: save_stack+0x19/0x80 mm/kasan/common.c:69 set_track mm/kasan/common.c:77 [inline] __kasan_slab_free+0x130/0x180 mm/kasan/common.c:455 slab_free_hook mm/slub.c:1423 [inline] slab_free_freelist_hook mm/slub.c:1474 [inline] slab_free mm/slub.c:3016 [inline] kfree+0xe9/0x2d0 mm/slub.c:3957 ops_free net/core/net_namespace.c:151 [inline] ops_free_list.part.7+0x156/0x220 net/core/net_namespace.c:184 ops_free_list net/core/net_namespace.c:182 [inline] __unregister_pernet_operations net/core/net_namespace.c:1165 [inline] unregister_pernet_operations+0x221/0x2a0 net/core/net_namespace.c:1224 unregister_pernet_subsys+0x1d/0x30 net/core/net_namespace.c:1271 nsim_fib_exit+0x11/0x20 [netdevsim] nsim_module_exit+0x16/0x21 [netdevsim] __do_sys_delete_module kernel/module.c:1015 [inline] __se_sys_delete_module kernel/module.c:958 [inline] __x64_sys_delete_module+0x244/0x330 kernel/module.c:958 do_syscall_64+0x72/0x2e0 arch/x86/entry/common.c:296 entry_SYSCALL_64_after_hwframe+0x49/0xbe Reported-by: Hulk Robot Fixes: 59c84b9fcf42 ("netdevsim: Restore per-network namespace accounting for fib entries") Signed-off-by: YueHaibing Acked-by: Jakub Kicinski Signed-off-by: David S. Miller --- drivers/net/netdevsim/fib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/netdevsim/fib.c b/drivers/net/netdevsim/fib.c index f61d094746c0..1a251f76d09b 100644 --- a/drivers/net/netdevsim/fib.c +++ b/drivers/net/netdevsim/fib.c @@ -241,8 +241,8 @@ static struct pernet_operations nsim_fib_net_ops = { void nsim_fib_exit(void) { - unregister_pernet_subsys(&nsim_fib_net_ops); unregister_fib_notifier(&nsim_fib_nb); + unregister_pernet_subsys(&nsim_fib_net_ops); } int nsim_fib_init(void) @@ -258,6 +258,7 @@ int nsim_fib_init(void) err = register_fib_notifier(&nsim_fib_nb, nsim_fib_dump_inconsistent); if (err < 0) { pr_err("Failed to register fib notifier\n"); + unregister_pernet_subsys(&nsim_fib_net_ops); goto err_out; } -- GitLab From a8d23cbbf6c9f515ed678204ad2962be7c336344 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Thu, 3 Oct 2019 17:02:01 +0200 Subject: [PATCH 224/993] batman-adv: Avoid free/alloc race when handling OGM2 buffer A B.A.T.M.A.N. V virtual interface has an OGM2 packet buffer which is initialized using data from the netdevice notifier and other rtnetlink related hooks. It is sent regularly via various slave interfaces of the batadv virtual interface and in this process also modified (realloced) to integrate additional state information via TVLV containers. It must be avoided that the worker item is executed without a common lock with the netdevice notifier/rtnetlink helpers. Otherwise it can either happen that half modified data is sent out or the functions modifying the OGM2 buffer try to access already freed memory regions. Fixes: 0da0035942d4 ("batman-adv: OGMv2 - add basic infrastructure") Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich --- net/batman-adv/bat_v_ogm.c | 41 ++++++++++++++++++++++++++++++-------- net/batman-adv/types.h | 4 ++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index dc4f7430cb5a..8033f24f506c 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -256,14 +257,12 @@ static void batadv_v_ogm_queue_on_if(struct sk_buff *skb, } /** - * batadv_v_ogm_send() - periodic worker broadcasting the own OGM - * @work: work queue item + * batadv_v_ogm_send_softif() - periodic worker broadcasting the own OGM + * @bat_priv: the bat priv with all the soft interface information */ -static void batadv_v_ogm_send(struct work_struct *work) +static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv) { struct batadv_hard_iface *hard_iface; - struct batadv_priv_bat_v *bat_v; - struct batadv_priv *bat_priv; struct batadv_ogm2_packet *ogm_packet; struct sk_buff *skb, *skb_tmp; unsigned char *ogm_buff; @@ -271,8 +270,7 @@ static void batadv_v_ogm_send(struct work_struct *work) u16 tvlv_len = 0; int ret; - bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work); - bat_priv = container_of(bat_v, struct batadv_priv, bat_v); + lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex); if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) goto out; @@ -363,6 +361,23 @@ static void batadv_v_ogm_send(struct work_struct *work) return; } +/** + * batadv_v_ogm_send() - periodic worker broadcasting the own OGM + * @work: work queue item + */ +static void batadv_v_ogm_send(struct work_struct *work) +{ + struct batadv_priv_bat_v *bat_v; + struct batadv_priv *bat_priv; + + bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work); + bat_priv = container_of(bat_v, struct batadv_priv, bat_v); + + mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); + batadv_v_ogm_send_softif(bat_priv); + mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); +} + /** * batadv_v_ogm_aggr_work() - OGM queue periodic task per interface * @work: work queue item @@ -424,11 +439,15 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface) struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface); struct batadv_ogm2_packet *ogm_packet; + mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); if (!bat_priv->bat_v.ogm_buff) - return; + goto unlock; ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff; ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr); + +unlock: + mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); } /** @@ -1050,6 +1069,8 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv) atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno); INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send); + mutex_init(&bat_priv->bat_v.ogm_buff_mutex); + return 0; } @@ -1061,7 +1082,11 @@ void batadv_v_ogm_free(struct batadv_priv *bat_priv) { cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq); + mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); + kfree(bat_priv->bat_v.ogm_buff); bat_priv->bat_v.ogm_buff = NULL; bat_priv->bat_v.ogm_buff_len = 0; + + mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); } diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index be7c02aa91e2..a9fb7b17f557 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include /* for linux/wait.h */ @@ -1539,6 +1540,9 @@ struct batadv_priv_bat_v { /** @ogm_seqno: OGM sequence number - used to identify each OGM */ atomic_t ogm_seqno; + /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */ + struct mutex ogm_buff_mutex; + /** @ogm_wq: workqueue used to schedule OGM transmissions */ struct delayed_work ogm_wq; }; -- GitLab From 40e220b4218bb3d278e5e8cc04ccdfd1c7ff8307 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Thu, 3 Oct 2019 17:02:01 +0200 Subject: [PATCH 225/993] batman-adv: Avoid free/alloc race when handling OGM buffer Each slave interface of an B.A.T.M.A.N. IV virtual interface has an OGM packet buffer which is initialized using data from netdevice notifier and other rtnetlink related hooks. It is sent regularly via various slave interfaces of the batadv virtual interface and in this process also modified (realloced) to integrate additional state information via TVLV containers. It must be avoided that the worker item is executed without a common lock with the netdevice notifier/rtnetlink helpers. Otherwise it can either happen that half modified/freed data is sent out or functions modifying the OGM buffer try to access already freed memory regions. Reported-by: syzbot+0cc629f19ccb8534935b@syzkaller.appspotmail.com Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol") Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich --- net/batman-adv/bat_iv_ogm.c | 61 ++++++++++++++++++++++++++++----- net/batman-adv/hard-interface.c | 2 ++ net/batman-adv/types.h | 3 ++ 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index d78938e3e008..5b0b20e6da95 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include #include @@ -193,14 +195,18 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) unsigned char *ogm_buff; u32 random_seqno; + mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); + /* randomize initial seqno to avoid collision */ get_random_bytes(&random_seqno, sizeof(random_seqno)); atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno); hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN; ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC); - if (!ogm_buff) + if (!ogm_buff) { + mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); return -ENOMEM; + } hard_iface->bat_iv.ogm_buff = ogm_buff; @@ -212,35 +218,59 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) batadv_ogm_packet->reserved = 0; batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE; + mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); + return 0; } static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) { + mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); + kfree(hard_iface->bat_iv.ogm_buff); hard_iface->bat_iv.ogm_buff = NULL; + + mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); } static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface) { struct batadv_ogm_packet *batadv_ogm_packet; - unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; + void *ogm_buff; - batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; + mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); + + ogm_buff = hard_iface->bat_iv.ogm_buff; + if (!ogm_buff) + goto unlock; + + batadv_ogm_packet = ogm_buff; ether_addr_copy(batadv_ogm_packet->orig, hard_iface->net_dev->dev_addr); ether_addr_copy(batadv_ogm_packet->prev_sender, hard_iface->net_dev->dev_addr); + +unlock: + mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); } static void batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface) { struct batadv_ogm_packet *batadv_ogm_packet; - unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; + void *ogm_buff; - batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; + mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); + + ogm_buff = hard_iface->bat_iv.ogm_buff; + if (!ogm_buff) + goto unlock; + + batadv_ogm_packet = ogm_buff; batadv_ogm_packet->ttl = BATADV_TTL; + +unlock: + mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); } /* when do we schedule our own ogm to be sent */ @@ -742,7 +772,11 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface) } } -static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) +/** + * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer + * @hard_iface: interface whose ogm buffer should be transmitted + */ +static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface) { struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff; @@ -753,9 +787,7 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) u16 tvlv_len = 0; unsigned long send_time; - if (hard_iface->if_status == BATADV_IF_NOT_IN_USE || - hard_iface->if_status == BATADV_IF_TO_BE_REMOVED) - return; + lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex); /* the interface gets activated here to avoid race conditions between * the moment of activating the interface in @@ -823,6 +855,17 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) batadv_hardif_put(primary_if); } +static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) +{ + if (hard_iface->if_status == BATADV_IF_NOT_IN_USE || + hard_iface->if_status == BATADV_IF_TO_BE_REMOVED) + return; + + mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); + batadv_iv_ogm_schedule_buff(hard_iface); + mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); +} + /** * batadv_iv_orig_ifinfo_sum() - Get bcast_own sum for originator over iterface * @orig_node: originator which reproadcasted the OGMs directly diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index c90e47342bb0..afb52282d5bd 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -929,6 +930,7 @@ batadv_hardif_add_interface(struct net_device *net_dev) INIT_LIST_HEAD(&hard_iface->list); INIT_HLIST_HEAD(&hard_iface->neigh_list); + mutex_init(&hard_iface->bat_iv.ogm_buff_mutex); spin_lock_init(&hard_iface->neigh_list_lock); kref_init(&hard_iface->refcount); diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index a9fb7b17f557..4d7f1baee7b7 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -82,6 +82,9 @@ struct batadv_hard_iface_bat_iv { /** @ogm_seqno: OGM sequence number - used to identify each OGM */ atomic_t ogm_seqno; + + /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */ + struct mutex ogm_buff_mutex; }; /** -- GitLab From 8b6bc5fd71e677864d1a3b896b3069a6e0c5e214 Mon Sep 17 00:00:00 2001 From: Zhenfang Wang Date: Thu, 12 Sep 2019 13:47:18 +0800 Subject: [PATCH 226/993] dmaengine: sprd: Fix the link-list pointer register configuration issue We will set the link-list pointer register point to next link-list configuration's physical address, which can load DMA configuration from the link-list node automatically. But the link-list node's physical address can be larger than 32bits, and now Spreadtrum DMA driver only supports 32bits physical address, which may cause loading a incorrect DMA configuration when starting the link-list transfer mode. According to the DMA datasheet, we can use SRC_BLK_STEP register (bit28 - bit31) to save the high bits of the link-list node's physical address to fix this issue. Fixes: 4ac695464763 ("dmaengine: sprd: Support DMA link-list mode") Signed-off-by: Zhenfang Wang Signed-off-by: Baolin Wang Link: https://lore.kernel.org/r/eadfe9295499efa003e1c344e67e2890f9d1d780.1568267061.git.baolin.wang@linaro.org Signed-off-by: Vinod Koul --- drivers/dma/sprd-dma.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c index 525dc7338fe3..a4a91f233121 100644 --- a/drivers/dma/sprd-dma.c +++ b/drivers/dma/sprd-dma.c @@ -134,6 +134,10 @@ #define SPRD_DMA_SRC_TRSF_STEP_OFFSET 0 #define SPRD_DMA_TRSF_STEP_MASK GENMASK(15, 0) +/* SPRD DMA_SRC_BLK_STEP register definition */ +#define SPRD_DMA_LLIST_HIGH_MASK GENMASK(31, 28) +#define SPRD_DMA_LLIST_HIGH_SHIFT 28 + /* define DMA channel mode & trigger mode mask */ #define SPRD_DMA_CHN_MODE_MASK GENMASK(7, 0) #define SPRD_DMA_TRG_MODE_MASK GENMASK(7, 0) @@ -717,6 +721,7 @@ static int sprd_dma_fill_desc(struct dma_chan *chan, u32 int_mode = flags & SPRD_DMA_INT_MASK; int src_datawidth, dst_datawidth, src_step, dst_step; u32 temp, fix_mode = 0, fix_en = 0; + phys_addr_t llist_ptr; if (dir == DMA_MEM_TO_DEV) { src_step = sprd_dma_get_step(slave_cfg->src_addr_width); @@ -814,13 +819,16 @@ static int sprd_dma_fill_desc(struct dma_chan *chan, * Set the link-list pointer point to next link-list * configuration's physical address. */ - hw->llist_ptr = schan->linklist.phy_addr + temp; + llist_ptr = schan->linklist.phy_addr + temp; + hw->llist_ptr = lower_32_bits(llist_ptr); + hw->src_blk_step = (upper_32_bits(llist_ptr) << SPRD_DMA_LLIST_HIGH_SHIFT) & + SPRD_DMA_LLIST_HIGH_MASK; } else { hw->llist_ptr = 0; + hw->src_blk_step = 0; } hw->frg_step = 0; - hw->src_blk_step = 0; hw->des_blk_step = 0; return 0; } -- GitLab From 07159f67c77134dfdfdbdf3d8f657f5890de5b7f Mon Sep 17 00:00:00 2001 From: Ran Wang Date: Tue, 17 Sep 2019 15:33:56 +0800 Subject: [PATCH 227/993] arm64: dts: lx2160a: Correct CPU core idle state name lx2160a support PW15 but not PW20, correct name to avoid confusing. Signed-off-by: Ran Wang Fixes: 00c5ce8ac023 ("arm64: dts: lx2160a: add cpu idle support") Acked-by: Li Yang Signed-off-by: Shawn Guo --- .../arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi index 408e0ecdce6a..b032f3890c8c 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi @@ -33,7 +33,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster0_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@1 { @@ -49,7 +49,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster0_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@100 { @@ -65,7 +65,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster1_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@101 { @@ -81,7 +81,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster1_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@200 { @@ -97,7 +97,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster2_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@201 { @@ -113,7 +113,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster2_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@300 { @@ -129,7 +129,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster3_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@301 { @@ -145,7 +145,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster3_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@400 { @@ -161,7 +161,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster4_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@401 { @@ -177,7 +177,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster4_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@500 { @@ -193,7 +193,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster5_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@501 { @@ -209,7 +209,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster5_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@600 { @@ -225,7 +225,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster6_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@601 { @@ -241,7 +241,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster6_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@700 { @@ -257,7 +257,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster7_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cpu@701 { @@ -273,7 +273,7 @@ i-cache-line-size = <64>; i-cache-sets = <192>; next-level-cache = <&cluster7_l2>; - cpu-idle-states = <&cpu_pw20>; + cpu-idle-states = <&cpu_pw15>; }; cluster0_l2: l2-cache0 { @@ -340,9 +340,9 @@ cache-level = <2>; }; - cpu_pw20: cpu-pw20 { + cpu_pw15: cpu-pw15 { compatible = "arm,idle-state"; - idle-state-name = "PW20"; + idle-state-name = "PW15"; arm,psci-suspend-param = <0x0>; entry-latency-us = <2000>; exit-latency-us = <2000>; -- GitLab From 9ec691f48b5ef741a48af8932ccaec859c67e8f1 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Mon, 16 Sep 2019 15:05:13 +0530 Subject: [PATCH 228/993] dmaengine: tegra210-adma: fix transfer failure >From Tegra186 onwards OUTSTANDING_REQUESTS field is added in channel configuration register(bits 7:4) which defines the maximum number of reads from the source and writes to the destination that may be outstanding at any given point of time. This field must be programmed with a value between 1 and 8. A value of 0 will prevent any transfers from happening. Thus added 'has_outstanding_reqs' bool member in chip data structure and is set to false for Tegra210, since the field is not applicable. For Tegra186 it is set to true and channel configuration is updated with maximum outstanding requests. Fixes: 433de642a76c ("dmaengine: tegra210-adma: add support for Tegra186/Tegra194") Cc: stable@vger.kernel.org Signed-off-by: Sameer Pujar Acked-by: Jon Hunter Link: https://lore.kernel.org/r/1568626513-16541-1-git-send-email-spujar@nvidia.com Signed-off-by: Vinod Koul --- drivers/dma/tegra210-adma.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c index 5f8adf5c1f20..6e1268552f74 100644 --- a/drivers/dma/tegra210-adma.c +++ b/drivers/dma/tegra210-adma.c @@ -40,6 +40,7 @@ #define ADMA_CH_CONFIG_MAX_BURST_SIZE 16 #define ADMA_CH_CONFIG_WEIGHT_FOR_WRR(val) ((val) & 0xf) #define ADMA_CH_CONFIG_MAX_BUFS 8 +#define TEGRA186_ADMA_CH_CONFIG_OUTSTANDING_REQS(reqs) (reqs << 4) #define ADMA_CH_FIFO_CTRL 0x2c #define TEGRA210_ADMA_CH_FIFO_CTRL_TXSIZE(val) (((val) & 0xf) << 8) @@ -77,6 +78,7 @@ struct tegra_adma; * @ch_req_tx_shift: Register offset for AHUB transmit channel select. * @ch_req_rx_shift: Register offset for AHUB receive channel select. * @ch_base_offset: Register offset of DMA channel registers. + * @has_outstanding_reqs: If DMA channel can have outstanding requests. * @ch_fifo_ctrl: Default value for channel FIFO CTRL register. * @ch_req_mask: Mask for Tx or Rx channel select. * @ch_req_max: Maximum number of Tx or Rx channels available. @@ -95,6 +97,7 @@ struct tegra_adma_chip_data { unsigned int ch_req_max; unsigned int ch_reg_size; unsigned int nr_channels; + bool has_outstanding_reqs; }; /* @@ -594,6 +597,8 @@ static int tegra_adma_set_xfer_params(struct tegra_adma_chan *tdc, ADMA_CH_CTRL_FLOWCTRL_EN; ch_regs->config |= cdata->adma_get_burst_config(burst_size); ch_regs->config |= ADMA_CH_CONFIG_WEIGHT_FOR_WRR(1); + if (cdata->has_outstanding_reqs) + ch_regs->config |= TEGRA186_ADMA_CH_CONFIG_OUTSTANDING_REQS(8); ch_regs->fifo_ctrl = cdata->ch_fifo_ctrl; ch_regs->tc = desc->period_len & ADMA_CH_TC_COUNT_MASK; @@ -778,6 +783,7 @@ static const struct tegra_adma_chip_data tegra210_chip_data = { .ch_req_tx_shift = 28, .ch_req_rx_shift = 24, .ch_base_offset = 0, + .has_outstanding_reqs = false, .ch_fifo_ctrl = TEGRA210_FIFO_CTRL_DEFAULT, .ch_req_mask = 0xf, .ch_req_max = 10, @@ -792,6 +798,7 @@ static const struct tegra_adma_chip_data tegra186_chip_data = { .ch_req_tx_shift = 27, .ch_req_rx_shift = 22, .ch_base_offset = 0x10000, + .has_outstanding_reqs = true, .ch_fifo_ctrl = TEGRA186_FIFO_CTRL_DEFAULT, .ch_req_mask = 0x1f, .ch_req_max = 20, -- GitLab From bd73dfabdda280fc5f05bdec79b6721b4b2f035f Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Tue, 24 Sep 2019 09:49:18 +0000 Subject: [PATCH 229/993] dmaengine: imx-sdma: fix size check for sdma script_number Illegal memory will be touch if SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3 (41) exceed the size of structure sdma_script_start_addrs(40), thus cause memory corrupt such as slob block header so that kernel trap into while() loop forever in slob_free(). Please refer to below code piece in imx-sdma.c: for (i = 0; i < sdma->script_number; i++) if (addr_arr[i] > 0) saddr_arr[i] = addr_arr[i]; /* memory corrupt here */ That issue was brought by commit a572460be9cf ("dmaengine: imx-sdma: Add support for version 3 firmware") because SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V3 (38->41 3 scripts added) not align with script number added in sdma_script_start_addrs(2 scripts). Fixes: a572460be9cf ("dmaengine: imx-sdma: Add support for version 3 firmware") Cc: stable@vger.kernel Link: https://www.spinics.net/lists/arm-kernel/msg754895.html Signed-off-by: Robin Gong Reported-by: Jurgen Lambrecht Link: https://lore.kernel.org/r/1569347584-3478-1-git-send-email-yibin.gong@nxp.com [vkoul: update the patch title] Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 8 ++++++++ include/linux/platform_data/dma-imx-sdma.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 9ba74ab7e912..c27e206a764c 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1707,6 +1707,14 @@ static void sdma_add_scripts(struct sdma_engine *sdma, if (!sdma->script_number) sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; + if (sdma->script_number > sizeof(struct sdma_script_start_addrs) + / sizeof(s32)) { + dev_err(sdma->dev, + "SDMA script number %d not match with firmware.\n", + sdma->script_number); + return; + } + for (i = 0; i < sdma->script_number; i++) if (addr_arr[i] > 0) saddr_arr[i] = addr_arr[i]; diff --git a/include/linux/platform_data/dma-imx-sdma.h b/include/linux/platform_data/dma-imx-sdma.h index 6eaa53cef0bd..30e676b36b24 100644 --- a/include/linux/platform_data/dma-imx-sdma.h +++ b/include/linux/platform_data/dma-imx-sdma.h @@ -51,7 +51,10 @@ struct sdma_script_start_addrs { /* End of v2 array */ s32 zcanfd_2_mcu_addr; s32 zqspi_2_mcu_addr; + s32 mcu_2_ecspi_addr; /* End of v3 array */ + s32 mcu_2_zqspi_addr; + /* End of v4 array */ }; /** -- GitLab From 112e72373d1f60f1e4558d0a7f0de5da39a1224d Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Fri, 11 Oct 2019 14:18:26 -0400 Subject: [PATCH 230/993] virtio-fs: Change module name to virtiofs.ko We have been calling it virtio_fs and even file name is virtio_fs.c. Module name is virtio_fs.ko but when registering file system user is supposed to specify filesystem type as "virtiofs". Masayoshi Mizuma reported that he specified filesytem type as "virtio_fs" and got this warning on console. ------------[ cut here ]------------ request_module fs-virtio_fs succeeded, but still no fs? WARNING: CPU: 1 PID: 1234 at fs/filesystems.c:274 get_fs_type+0x12c/0x138 Modules linked in: ... virtio_fs fuse virtio_net net_failover ... CPU: 1 PID: 1234 Comm: mount Not tainted 5.4.0-rc1 #1 So looks like kernel could find the module virtio_fs.ko but could not find filesystem type after that. It probably is better to rename module name to virtiofs.ko so that above warning goes away in case user ends up specifying wrong fs name. Reported-by: Masayoshi Mizuma Suggested-by: Stefan Hajnoczi Signed-off-by: Vivek Goyal Tested-by: Masayoshi Mizuma Reviewed-by: Stefan Hajnoczi Signed-off-by: Miklos Szeredi --- fs/fuse/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile index 6419a2b3510d..3e8cebfb59b7 100644 --- a/fs/fuse/Makefile +++ b/fs/fuse/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_FUSE_FS) += fuse.o obj-$(CONFIG_CUSE) += cuse.o -obj-$(CONFIG_VIRTIO_FS) += virtio_fs.o +obj-$(CONFIG_VIRTIO_FS) += virtiofs.o fuse-objs := dev.o dir.o file.o inode.o control.o xattr.o acl.o readdir.o +virtiofs-y += virtio_fs.o -- GitLab From d79749f7716d9dc32fa2d5075f6ec29aac63c76d Mon Sep 17 00:00:00 2001 From: Miaoqing Pan Date: Thu, 29 Aug 2019 10:45:12 +0800 Subject: [PATCH 231/993] ath10k: fix latency issue for QCA988x (kvalo: cherry picked from commit 1340cc631bd00431e2f174525c971f119df9efa1 in wireless-drivers-next to wireless-drivers as this a frequently reported regression) Bad latency is found on QCA988x, the issue was introduced by commit 4504f0e5b571 ("ath10k: sdio: workaround firmware UART pin configuration bug"). If uart_pin_workaround is false, this change will set uart pin even if uart_print is false. Tested HW: QCA9880 Tested FW: 10.2.4-1.0-00037 Fixes: 4504f0e5b571 ("ath10k: sdio: workaround firmware UART pin configuration bug") Signed-off-by: Miaoqing Pan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index dc45d16e8d21..383d4fa555a8 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -2118,12 +2118,15 @@ static int ath10k_init_uart(struct ath10k *ar) return ret; } - if (!uart_print && ar->hw_params.uart_pin_workaround) { - ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, - ar->hw_params.uart_pin); - if (ret) { - ath10k_warn(ar, "failed to set UART TX pin: %d", ret); - return ret; + if (!uart_print) { + if (ar->hw_params.uart_pin_workaround) { + ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, + ar->hw_params.uart_pin); + if (ret) { + ath10k_warn(ar, "failed to set UART TX pin: %d", + ret); + return ret; + } } return 0; -- GitLab From 52f4d4043d1edc4e9e66ec79cae3e32cfe0e44d6 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 1 Oct 2019 19:20:29 -0500 Subject: [PATCH 232/993] ARM: dts: imx6q-logicpd: Re-Enable SNVS power key A previous patch disabled the SNVS power key by default which breaks the ability for the imx6q-logicpd board to wake from sleep. This patch re-enables this feature for this board. Fixes: 770856f0da5d ("ARM: dts: imx6qdl: Enable SNVS power key according to board design") Signed-off-by: Adam Ford Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6-logicpd-som.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/imx6-logicpd-som.dtsi b/arch/arm/boot/dts/imx6-logicpd-som.dtsi index 7ceae3573248..547fb141ec0c 100644 --- a/arch/arm/boot/dts/imx6-logicpd-som.dtsi +++ b/arch/arm/boot/dts/imx6-logicpd-som.dtsi @@ -207,6 +207,10 @@ vin-supply = <&sw1c_reg>; }; +&snvs_poweroff { + status = "okay"; +}; + &iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hog>; -- GitLab From 73a88e4ce31055c415f1ddb55e3f08c9393cf4e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 23 Sep 2019 10:47:22 +0200 Subject: [PATCH 233/993] drm/ttm: fix busy reference in ttm_mem_evict_first MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The busy BO might actually be already deleted, so grab only a list reference. Signed-off-by: Christian König Reviewed-by: Thomas Hellström Link: https://patchwork.freedesktop.org/patch/332877/ --- drivers/gpu/drm/ttm/ttm_bo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 20ff56f27aa4..ea59459c4128 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -878,11 +878,11 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, if (!bo) { if (busy_bo) - ttm_bo_get(busy_bo); + kref_get(&busy_bo->list_kref); spin_unlock(&glob->lru_lock); ret = ttm_mem_evict_wait_busy(busy_bo, ctx, ticket); if (busy_bo) - ttm_bo_put(busy_bo); + kref_put(&busy_bo->list_kref, ttm_bo_release_list); return ret; } -- GitLab From 941f2f72dbbe0cf8c2d6e0b180a8021a0ec477fa Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 12 Sep 2019 20:38:54 +0200 Subject: [PATCH 234/993] drm/ttm: Restore ttm prefaulting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 4daa4fba3a38 ("gpu: drm: ttm: Adding new return type vm_fault_t") broke TTM prefaulting. Since vmf_insert_mixed() typically always returns VM_FAULT_NOPAGE, prefaulting stops after the second PTE. Restore (almost) the original behaviour. Unfortunately we can no longer with the new vm_fault_t return type determine whether a prefaulting PTE insertion hit an already populated PTE, and terminate the insertion loop. Instead we continue with the pre-determined number of prefaults. Fixes: 4daa4fba3a38 ("gpu: drm: ttm: Adding new return type vm_fault_t") Cc: Souptick Joarder Cc: Christian König Signed-off-by: Thomas Hellstrom Reviewed-by: Christian König Cc: stable@vger.kernel.org # v4.19+ Signed-off-by: Christian König Link: https://patchwork.freedesktop.org/patch/330387/ --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 76eedb963693..46dc3de7e81b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -278,15 +278,13 @@ static vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf) else ret = vmf_insert_pfn(&cvma, address, pfn); - /* - * Somebody beat us to this PTE or prefaulting to - * an already populated PTE, or prefaulting error. - */ - - if (unlikely((ret == VM_FAULT_NOPAGE && i > 0))) - break; - else if (unlikely(ret & VM_FAULT_ERROR)) - goto out_io_unlock; + /* Never error on prefaulted PTEs */ + if (unlikely((ret & VM_FAULT_ERROR))) { + if (i == 0) + goto out_io_unlock; + else + break; + } address += PAGE_SIZE; if (unlikely(++page_offset >= page_last)) -- GitLab From 7fbc899ddeaa9aaef0ba646529089149572c84ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 10 Oct 2019 13:24:17 +0200 Subject: [PATCH 235/993] drm/ttm: fix handling in ttm_bo_add_mem_to_lru MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should not add the BO to the swap LRU when the new mem is fixed and the TTM object about to be destroyed. Signed-off-by: Christian König Reviewed-by: Kevin Wang Link: https://patchwork.freedesktop.org/patch/335246/ --- drivers/gpu/drm/ttm/ttm_bo.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index ea59459c4128..98819462f025 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -185,8 +185,9 @@ static void ttm_bo_add_mem_to_lru(struct ttm_buffer_object *bo, list_add_tail(&bo->lru, &man->lru[bo->priority]); kref_get(&bo->list_kref); - if (bo->ttm && !(bo->ttm->page_flags & - (TTM_PAGE_FLAG_SG | TTM_PAGE_FLAG_SWAPPED))) { + if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED) && bo->ttm && + !(bo->ttm->page_flags & (TTM_PAGE_FLAG_SG | + TTM_PAGE_FLAG_SWAPPED))) { list_add_tail(&bo->swap, &bdev->glob->swap_lru[bo->priority]); kref_get(&bo->list_kref); } -- GitLab From 71936a6d18c33c63b4e9e0359fb987306cbe9fae Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 3 Oct 2019 22:41:15 -0700 Subject: [PATCH 236/993] ARM: dts: vf610-zii-scu4-aib: Specify 'i2c-mux-idle-disconnect' Specify 'i2c-mux-idle-disconnect' for both I2C switches present on the board, since both are connected to the same parent bus and all of their children have the same I2C address. Fixes: ca4b4d373fcc ("ARM: dts: vf610: Add ZII SCU4 AIB board") Signed-off-by: Andrey Smirnov Cc: Shawn Guo Cc: Chris Healy Cc: Cory Tusar Cc: Jeff White Cc: Rick Ramstetter Cc: Lucas Stach Cc: Fabio Estevam Cc: linux-arm-kernel@lists.infradead.org Cc: devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org Tested-by: Chris Healy Signed-off-by: Shawn Guo --- arch/arm/boot/dts/vf610-zii-scu4-aib.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/vf610-zii-scu4-aib.dts b/arch/arm/boot/dts/vf610-zii-scu4-aib.dts index dc8a5f37a1ef..c8ebb23c4e02 100644 --- a/arch/arm/boot/dts/vf610-zii-scu4-aib.dts +++ b/arch/arm/boot/dts/vf610-zii-scu4-aib.dts @@ -602,6 +602,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x70>; + i2c-mux-idle-disconnect; sff0_i2c: i2c@1 { #address-cells = <1>; @@ -640,6 +641,7 @@ reg = <0x71>; #address-cells = <1>; #size-cells = <0>; + i2c-mux-idle-disconnect; sff5_i2c: i2c@1 { #address-cells = <1>; -- GitLab From 252b9e21bcf46b0d16f733f2e42b21fdc60addee Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Mon, 7 Oct 2019 08:43:42 +0800 Subject: [PATCH 237/993] ARM: dts: imx7s: Correct GPT's ipg clock source i.MX7S/D's GPT ipg clock should be from GPT clock root and controlled by CCM's GPT CCGR, using correct clock source for GPT ipg clock instead of IMX7D_CLK_DUMMY. Fixes: 3ef79ca6bd1d ("ARM: dts: imx7d: use imx7s.dtsi as base device tree") Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx7s.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index 710f850e785c..e2e604d6ba0b 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi @@ -448,7 +448,7 @@ compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; reg = <0x302d0000 0x10000>; interrupts = ; - clocks = <&clks IMX7D_CLK_DUMMY>, + clocks = <&clks IMX7D_GPT1_ROOT_CLK>, <&clks IMX7D_GPT1_ROOT_CLK>; clock-names = "ipg", "per"; }; @@ -457,7 +457,7 @@ compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; reg = <0x302e0000 0x10000>; interrupts = ; - clocks = <&clks IMX7D_CLK_DUMMY>, + clocks = <&clks IMX7D_GPT2_ROOT_CLK>, <&clks IMX7D_GPT2_ROOT_CLK>; clock-names = "ipg", "per"; status = "disabled"; @@ -467,7 +467,7 @@ compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; reg = <0x302f0000 0x10000>; interrupts = ; - clocks = <&clks IMX7D_CLK_DUMMY>, + clocks = <&clks IMX7D_GPT3_ROOT_CLK>, <&clks IMX7D_GPT3_ROOT_CLK>; clock-names = "ipg", "per"; status = "disabled"; @@ -477,7 +477,7 @@ compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; reg = <0x30300000 0x10000>; interrupts = ; - clocks = <&clks IMX7D_CLK_DUMMY>, + clocks = <&clks IMX7D_GPT4_ROOT_CLK>, <&clks IMX7D_GPT4_ROOT_CLK>; clock-names = "ipg", "per"; status = "disabled"; -- GitLab From 832392db9747b9c95724d37fc6a5dadd3d4ec514 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 11 Oct 2019 13:22:58 +0300 Subject: [PATCH 238/993] platform/x86: i2c-multi-instantiate: Fail the probe if no IRQ provided For APIC case of interrupt we don't fail a ->probe() of the driver, which makes kernel to print a lot of warnings from the children. We have two options here: - switch to platform_get_irq_optional(), though it won't stop children to be probed and failed - fail the ->probe() of i2c-multi-instantiate Since the in reality we never had devices in the wild where IRQ resource is optional, the latter solution suits the best. Fixes: 799d3379a672 ("platform/x86: i2c-multi-instantiate: Introduce IOAPIC IRQ support") Reported-by: Ammy Yi Cc: Heikki Krogerus Cc: Hans de Goede Signed-off-by: Andy Shevchenko Reviewed-by: Heikki Krogerus --- drivers/platform/x86/i2c-multi-instantiate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/i2c-multi-instantiate.c b/drivers/platform/x86/i2c-multi-instantiate.c index ea68f6ed66ae..ffb8d5d1eb5f 100644 --- a/drivers/platform/x86/i2c-multi-instantiate.c +++ b/drivers/platform/x86/i2c-multi-instantiate.c @@ -108,6 +108,7 @@ static int i2c_multi_inst_probe(struct platform_device *pdev) if (ret < 0) { dev_dbg(dev, "Error requesting irq at index %d: %d\n", inst_data[i].irq_idx, ret); + goto error; } board_info.irq = ret; break; -- GitLab From b0759297f2c8dda455ff78a1d1ac95e261300ae3 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Tue, 8 Oct 2019 08:55:43 +0800 Subject: [PATCH 239/993] arm64: dts: imx8mq: Use correct clock for usdhc's ipg clk On i.MX8MQ, usdhc's ipg clock is from IMX8MQ_CLK_IPG_ROOT, assign it explicitly instead of using IMX8MQ_CLK_DUMMY. Fixes: 748f908cc882 ("arm64: add basic DTS for i.MX8MQ") Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mq.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi index 04115ca6bfb5..55a3d1c4bdf0 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi @@ -850,7 +850,7 @@ "fsl,imx7d-usdhc"; reg = <0x30b40000 0x10000>; interrupts = ; - clocks = <&clk IMX8MQ_CLK_DUMMY>, + clocks = <&clk IMX8MQ_CLK_IPG_ROOT>, <&clk IMX8MQ_CLK_NAND_USDHC_BUS>, <&clk IMX8MQ_CLK_USDHC1_ROOT>; clock-names = "ipg", "ahb", "per"; @@ -867,7 +867,7 @@ "fsl,imx7d-usdhc"; reg = <0x30b50000 0x10000>; interrupts = ; - clocks = <&clk IMX8MQ_CLK_DUMMY>, + clocks = <&clk IMX8MQ_CLK_IPG_ROOT>, <&clk IMX8MQ_CLK_NAND_USDHC_BUS>, <&clk IMX8MQ_CLK_USDHC2_ROOT>; clock-names = "ipg", "ahb", "per"; -- GitLab From a6a40d5688f2264afd40574ee1c92e5f824b34ba Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Tue, 8 Oct 2019 08:55:44 +0800 Subject: [PATCH 240/993] arm64: dts: imx8mm: Use correct clock for usdhc's ipg clk On i.MX8MM, usdhc's ipg clock is from IMX8MM_CLK_IPG_ROOT, assign it explicitly instead of using IMX8MM_CLK_DUMMY. Fixes: a05ea40eb384 ("arm64: dts: imx: Add i.mx8mm dtsi support") Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mm.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi index 5f9d0da196e1..58b8cd06cae7 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi @@ -694,7 +694,7 @@ compatible = "fsl,imx8mm-usdhc", "fsl,imx7d-usdhc"; reg = <0x30b40000 0x10000>; interrupts = ; - clocks = <&clk IMX8MM_CLK_DUMMY>, + clocks = <&clk IMX8MM_CLK_IPG_ROOT>, <&clk IMX8MM_CLK_NAND_USDHC_BUS>, <&clk IMX8MM_CLK_USDHC1_ROOT>; clock-names = "ipg", "ahb", "per"; @@ -710,7 +710,7 @@ compatible = "fsl,imx8mm-usdhc", "fsl,imx7d-usdhc"; reg = <0x30b50000 0x10000>; interrupts = ; - clocks = <&clk IMX8MM_CLK_DUMMY>, + clocks = <&clk IMX8MM_CLK_IPG_ROOT>, <&clk IMX8MM_CLK_NAND_USDHC_BUS>, <&clk IMX8MM_CLK_USDHC2_ROOT>; clock-names = "ipg", "ahb", "per"; @@ -724,7 +724,7 @@ compatible = "fsl,imx8mm-usdhc", "fsl,imx7d-usdhc"; reg = <0x30b60000 0x10000>; interrupts = ; - clocks = <&clk IMX8MM_CLK_DUMMY>, + clocks = <&clk IMX8MM_CLK_IPG_ROOT>, <&clk IMX8MM_CLK_NAND_USDHC_BUS>, <&clk IMX8MM_CLK_USDHC3_ROOT>; clock-names = "ipg", "ahb", "per"; -- GitLab From ea65aba85e8143c3854b66f40be09b6b79215006 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Tue, 8 Oct 2019 08:55:45 +0800 Subject: [PATCH 241/993] arm64: dts: imx8mn: Use correct clock for usdhc's ipg clk On i.MX8MN, usdhc's ipg clock is from IMX8MN_CLK_IPG_ROOT, assign it explicitly instead of using IMX8MN_CLK_DUMMY. Fixes: 6c3debcbae47 ("arm64: dts: freescale: Add i.MX8MN dtsi support") Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mn.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi index 785f4c420fa4..98496f570720 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi @@ -569,7 +569,7 @@ compatible = "fsl,imx8mn-usdhc", "fsl,imx7d-usdhc"; reg = <0x30b40000 0x10000>; interrupts = ; - clocks = <&clk IMX8MN_CLK_DUMMY>, + clocks = <&clk IMX8MN_CLK_IPG_ROOT>, <&clk IMX8MN_CLK_NAND_USDHC_BUS>, <&clk IMX8MN_CLK_USDHC1_ROOT>; clock-names = "ipg", "ahb", "per"; @@ -585,7 +585,7 @@ compatible = "fsl,imx8mn-usdhc", "fsl,imx7d-usdhc"; reg = <0x30b50000 0x10000>; interrupts = ; - clocks = <&clk IMX8MN_CLK_DUMMY>, + clocks = <&clk IMX8MN_CLK_IPG_ROOT>, <&clk IMX8MN_CLK_NAND_USDHC_BUS>, <&clk IMX8MN_CLK_USDHC2_ROOT>; clock-names = "ipg", "ahb", "per"; @@ -599,7 +599,7 @@ compatible = "fsl,imx8mn-usdhc", "fsl,imx7d-usdhc"; reg = <0x30b60000 0x10000>; interrupts = ; - clocks = <&clk IMX8MN_CLK_DUMMY>, + clocks = <&clk IMX8MN_CLK_IPG_ROOT>, <&clk IMX8MN_CLK_NAND_USDHC_BUS>, <&clk IMX8MN_CLK_USDHC3_ROOT>; clock-names = "ipg", "ahb", "per"; -- GitLab From 95993238b29b3f0f9a5eb9db84e0e38e5bfe76d8 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 8 Oct 2019 14:38:13 -0300 Subject: [PATCH 242/993] ARM: imx_v6_v7_defconfig: Enable CONFIG_DRM_MSM Since commit 2eba69071b4b ("drm/msm: Remove Kconfig default") the CONFIG_DRM_MSM option is no longer selected by default on i.MX5. Explicitly select CONFIG_DRM_MSM so that we can get GPU support by default on i.MX51 and i.MX53. Fixes: 2eba69071b4b ("drm/msm: Remove Kconfig default") Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/configs/imx_v6_v7_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 9bfffbe22d53..0f7381ee0c37 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -276,6 +276,7 @@ CONFIG_VIDEO_OV5640=m CONFIG_VIDEO_OV5645=m CONFIG_IMX_IPUV3_CORE=y CONFIG_DRM=y +CONFIG_DRM_MSM=y CONFIG_DRM_PANEL_LVDS=y CONFIG_DRM_PANEL_SIMPLE=y CONFIG_DRM_PANEL_SEIKO_43WVF1G=y -- GitLab From 153c5d8191c26165dbbd2646448ca7207f7796d0 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 14 Oct 2019 12:02:01 +0100 Subject: [PATCH 243/993] staging: wlan-ng: fix exit return when sme->key_idx >= NUM_WEPKEYS Currently the exit return path when sme->key_idx >= NUM_WEPKEYS is via label 'exit' and this checks if result is non-zero, however result has not been initialized and contains garbage. Fix this by replacing the goto with a return with the error code. Addresses-Coverity: ("Uninitialized scalar variable") Fixes: 0ca6d8e74489 ("Staging: wlan-ng: replace switch-case statements with macro") Signed-off-by: Colin Ian King Cc: stable Link: https://lore.kernel.org/r/20191014110201.9874-1-colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/cfg80211.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index eee1998c4b18..fac38c842ac5 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -469,10 +469,8 @@ static int prism2_connect(struct wiphy *wiphy, struct net_device *dev, /* Set the encryption - we only support wep */ if (is_wep) { if (sme->key) { - if (sme->key_idx >= NUM_WEPKEYS) { - err = -EINVAL; - goto exit; - } + if (sme->key_idx >= NUM_WEPKEYS) + return -EINVAL; result = prism2_domibset_uint32(wlandev, DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID, -- GitLab From ff229eee3d897f52bd001c841f2d3cce8853ecdc Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 8 Oct 2019 10:32:04 -0700 Subject: [PATCH 244/993] hrtimer: Annotate lockless access to timer->base Followup to commit dd2261ed45aa ("hrtimer: Protect lockless access to timer->base") lock_hrtimer_base() fetches timer->base without lock exclusion. Compiler is allowed to read timer->base twice (even if considered dumb) which could end up trying to lock migration_base and return &migration_base. base = timer->base; if (likely(base != &migration_base)) { /* compiler reads timer->base again, and now (base == &migration_base) raw_spin_lock_irqsave(&base->cpu_base->lock, *flags); if (likely(base == timer->base)) return base; /* == &migration_base ! */ Similarly the write sides must use WRITE_ONCE() to avoid store tearing. Signed-off-by: Eric Dumazet Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/20191008173204.180879-1-edumazet@google.com --- kernel/time/hrtimer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 0d4dc241c0fb..65605530ee34 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -164,7 +164,7 @@ struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer, struct hrtimer_clock_base *base; for (;;) { - base = timer->base; + base = READ_ONCE(timer->base); if (likely(base != &migration_base)) { raw_spin_lock_irqsave(&base->cpu_base->lock, *flags); if (likely(base == timer->base)) @@ -244,7 +244,7 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base, return base; /* See the comment in lock_hrtimer_base() */ - timer->base = &migration_base; + WRITE_ONCE(timer->base, &migration_base); raw_spin_unlock(&base->cpu_base->lock); raw_spin_lock(&new_base->cpu_base->lock); @@ -253,10 +253,10 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base, raw_spin_unlock(&new_base->cpu_base->lock); raw_spin_lock(&base->cpu_base->lock); new_cpu_base = this_cpu_base; - timer->base = base; + WRITE_ONCE(timer->base, base); goto again; } - timer->base = new_base; + WRITE_ONCE(timer->base, new_base); } else { if (new_cpu_base != this_cpu_base && hrtimer_check_target(timer, new_base)) { -- GitLab From 770597ecb2075390c01c425b8b1f551347f1bd70 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 5 Sep 2019 07:52:33 -0600 Subject: [PATCH 245/993] nvme-pci: Free tagset if no IO queues If a controller becomes degraded after a reset, we will not be able to perform any IO. We currently teardown previously created request queues and namespaces, but we had kept the unusable tagset. Free it after all queues using it have been released. Tested-by: Edmund Nadolski Reviewed-by: James Smart Reviewed-by: Sagi Grimberg Reviewed-by: Christoph Hellwig Signed-off-by: Keith Busch --- drivers/nvme/host/pci.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 78e403823646..5c04581899f4 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -2490,14 +2490,20 @@ static void nvme_release_prp_pools(struct nvme_dev *dev) dma_pool_destroy(dev->prp_small_pool); } +static void nvme_free_tagset(struct nvme_dev *dev) +{ + if (dev->tagset.tags) + blk_mq_free_tag_set(&dev->tagset); + dev->ctrl.tagset = NULL; +} + static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl) { struct nvme_dev *dev = to_nvme_dev(ctrl); nvme_dbbuf_dma_free(dev); put_device(dev->dev); - if (dev->tagset.tags) - blk_mq_free_tag_set(&dev->tagset); + nvme_free_tagset(dev); if (dev->ctrl.admin_q) blk_put_queue(dev->ctrl.admin_q); kfree(dev->queues); @@ -2616,6 +2622,7 @@ static void nvme_reset_work(struct work_struct *work) nvme_kill_queues(&dev->ctrl); nvme_remove_namespaces(&dev->ctrl); new_state = NVME_CTRL_ADMIN_ONLY; + nvme_free_tagset(dev); } else { nvme_start_queues(&dev->ctrl); nvme_wait_freeze(&dev->ctrl); -- GitLab From 5d02a5c1d6e14534ca4729b055c89a2cd022ca00 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 3 Sep 2019 09:22:24 -0600 Subject: [PATCH 246/993] nvme: Remove ADMIN_ONLY state The admin only state was intended to fence off actions that don't apply to a non-IO capable controller. The only actual user of this is the scan_work, and pci was the only transport to ever set this state. The consequence of having this state is placing an additional burden on every other action that applies to both live and admin only controllers. Remove the admin only state and place the admin only burden on the only place that actually cares: scan_work. This also prepares to make it easier to temporarily pause a LIVE state so that we don't need to remember which state the controller had been in prior to the pause. Tested-by: Edmund Nadolski Reviewed-by: James Smart Reviewed-by: Sagi Grimberg Reviewed-by: Christoph Hellwig Signed-off-by: Keith Busch --- drivers/nvme/host/core.c | 23 ++++------------------- drivers/nvme/host/fabrics.h | 3 +-- drivers/nvme/host/nvme.h | 1 - drivers/nvme/host/pci.c | 21 ++++++--------------- 4 files changed, 11 insertions(+), 37 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index ef1d8f81f69e..e451e77005dc 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -116,7 +116,7 @@ static void nvme_queue_scan(struct nvme_ctrl *ctrl) /* * Only new queue scan work when admin and IO queues are both alive */ - if (ctrl->state == NVME_CTRL_LIVE) + if (ctrl->state == NVME_CTRL_LIVE && ctrl->tagset) queue_work(nvme_wq, &ctrl->scan_work); } @@ -137,8 +137,7 @@ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl) ret = nvme_reset_ctrl(ctrl); if (!ret) { flush_work(&ctrl->reset_work); - if (ctrl->state != NVME_CTRL_LIVE && - ctrl->state != NVME_CTRL_ADMIN_ONLY) + if (ctrl->state != NVME_CTRL_LIVE) ret = -ENETRESET; } @@ -315,15 +314,6 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, old_state = ctrl->state; switch (new_state) { - case NVME_CTRL_ADMIN_ONLY: - switch (old_state) { - case NVME_CTRL_CONNECTING: - changed = true; - /* FALLTHRU */ - default: - break; - } - break; case NVME_CTRL_LIVE: switch (old_state) { case NVME_CTRL_NEW: @@ -339,7 +329,6 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, switch (old_state) { case NVME_CTRL_NEW: case NVME_CTRL_LIVE: - case NVME_CTRL_ADMIN_ONLY: changed = true; /* FALLTHRU */ default: @@ -359,7 +348,6 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, case NVME_CTRL_DELETING: switch (old_state) { case NVME_CTRL_LIVE: - case NVME_CTRL_ADMIN_ONLY: case NVME_CTRL_RESETTING: case NVME_CTRL_CONNECTING: changed = true; @@ -2873,7 +2861,6 @@ static int nvme_dev_open(struct inode *inode, struct file *file) switch (ctrl->state) { case NVME_CTRL_LIVE: - case NVME_CTRL_ADMIN_ONLY: break; default: return -EWOULDBLOCK; @@ -3167,7 +3154,6 @@ static ssize_t nvme_sysfs_show_state(struct device *dev, static const char *const state_name[] = { [NVME_CTRL_NEW] = "new", [NVME_CTRL_LIVE] = "live", - [NVME_CTRL_ADMIN_ONLY] = "only-admin", [NVME_CTRL_RESETTING] = "resetting", [NVME_CTRL_CONNECTING] = "connecting", [NVME_CTRL_DELETING] = "deleting", @@ -3678,11 +3664,10 @@ static void nvme_scan_work(struct work_struct *work) struct nvme_id_ctrl *id; unsigned nn; - if (ctrl->state != NVME_CTRL_LIVE) + /* No tagset on a live ctrl means IO queues could not created */ + if (ctrl->state != NVME_CTRL_LIVE || !ctrl->tagset) return; - WARN_ON_ONCE(!ctrl->tagset); - if (test_and_clear_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events)) { dev_info(ctrl->device, "rescanning namespaces.\n"); nvme_clear_changed_ns_log(ctrl); diff --git a/drivers/nvme/host/fabrics.h b/drivers/nvme/host/fabrics.h index 93f08d77c896..a0ec40ab62ee 100644 --- a/drivers/nvme/host/fabrics.h +++ b/drivers/nvme/host/fabrics.h @@ -182,8 +182,7 @@ bool nvmf_ip_options_match(struct nvme_ctrl *ctrl, static inline bool nvmf_check_ready(struct nvme_ctrl *ctrl, struct request *rq, bool queue_live) { - if (likely(ctrl->state == NVME_CTRL_LIVE || - ctrl->state == NVME_CTRL_ADMIN_ONLY)) + if (likely(ctrl->state == NVME_CTRL_LIVE)) return true; return __nvmf_check_ready(ctrl, rq, queue_live); } diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 38a83ef5bcd3..2ba577271ada 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -161,7 +161,6 @@ static inline u16 nvme_req_qid(struct request *req) enum nvme_ctrl_state { NVME_CTRL_NEW, NVME_CTRL_LIVE, - NVME_CTRL_ADMIN_ONLY, /* Only admin queue live */ NVME_CTRL_RESETTING, NVME_CTRL_CONNECTING, NVME_CTRL_DELETING, diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 5c04581899f4..e7e79d6af9ba 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -2263,10 +2263,7 @@ static bool __nvme_disable_io_queues(struct nvme_dev *dev, u8 opcode) return true; } -/* - * return error value only when tagset allocation failed - */ -static int nvme_dev_add(struct nvme_dev *dev) +static void nvme_dev_add(struct nvme_dev *dev) { int ret; @@ -2296,7 +2293,7 @@ static int nvme_dev_add(struct nvme_dev *dev) if (ret) { dev_warn(dev->ctrl.device, "IO queues tagset allocation failed %d\n", ret); - return ret; + return; } dev->ctrl.tagset = &dev->tagset; } else { @@ -2307,7 +2304,6 @@ static int nvme_dev_add(struct nvme_dev *dev) } nvme_dbbuf_set(dev); - return 0; } static int nvme_pci_enable(struct nvme_dev *dev) @@ -2527,7 +2523,6 @@ static void nvme_reset_work(struct work_struct *work) container_of(work, struct nvme_dev, ctrl.reset_work); bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL); int result; - enum nvme_ctrl_state new_state = NVME_CTRL_LIVE; if (WARN_ON(dev->ctrl.state != NVME_CTRL_RESETTING)) { result = -ENODEV; @@ -2621,14 +2616,11 @@ static void nvme_reset_work(struct work_struct *work) dev_warn(dev->ctrl.device, "IO queues not created\n"); nvme_kill_queues(&dev->ctrl); nvme_remove_namespaces(&dev->ctrl); - new_state = NVME_CTRL_ADMIN_ONLY; nvme_free_tagset(dev); } else { nvme_start_queues(&dev->ctrl); nvme_wait_freeze(&dev->ctrl); - /* hit this only when allocate tagset fails */ - if (nvme_dev_add(dev)) - new_state = NVME_CTRL_ADMIN_ONLY; + nvme_dev_add(dev); nvme_unfreeze(&dev->ctrl); } @@ -2636,9 +2628,9 @@ static void nvme_reset_work(struct work_struct *work) * If only admin queue live, keep it to do further investigation or * recovery. */ - if (!nvme_change_ctrl_state(&dev->ctrl, new_state)) { + if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_LIVE)) { dev_warn(dev->ctrl.device, - "failed to mark controller state %d\n", new_state); + "failed to mark controller live state\n"); result = -ENODEV; goto out; } @@ -2945,8 +2937,7 @@ static int nvme_suspend(struct device *dev) nvme_wait_freeze(ctrl); nvme_sync_queues(ctrl); - if (ctrl->state != NVME_CTRL_LIVE && - ctrl->state != NVME_CTRL_ADMIN_ONLY) + if (ctrl->state != NVME_CTRL_LIVE) goto unfreeze; ret = nvme_get_power_state(ctrl, &ndev->last_ps); -- GitLab From 92b98e88d59ab17e65f261fbb5db272143ccf414 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 5 Sep 2019 08:09:33 -0600 Subject: [PATCH 247/993] nvme: Restart request timers in resetting state A controller in the resetting state has not yet completed its recovery actions. The pci and fc transports were already handling this, so update the remaining transports to not attempt additional recovery in this state. Instead, just restart the request timer. Tested-by: Edmund Nadolski Reviewed-by: James Smart Reviewed-by: Sagi Grimberg Reviewed-by: Christoph Hellwig Signed-off-by: Keith Busch --- drivers/nvme/host/rdma.c | 8 ++++++++ drivers/nvme/host/tcp.c | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 4d280160dd3f..f19a28b4e997 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -1701,6 +1701,14 @@ nvme_rdma_timeout(struct request *rq, bool reserved) dev_warn(ctrl->ctrl.device, "I/O %d QID %d timeout\n", rq->tag, nvme_rdma_queue_idx(queue)); + /* + * Restart the timer if a controller reset is already scheduled. Any + * timed out commands would be handled before entering the connecting + * state. + */ + if (ctrl->ctrl.state == NVME_CTRL_RESETTING) + return BLK_EH_RESET_TIMER; + if (ctrl->ctrl.state != NVME_CTRL_LIVE) { /* * Teardown immediately if controller times out while starting diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 385a5212c10f..33de2fddfbb2 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -2044,6 +2044,14 @@ nvme_tcp_timeout(struct request *rq, bool reserved) struct nvme_tcp_ctrl *ctrl = req->queue->ctrl; struct nvme_tcp_cmd_pdu *pdu = req->pdu; + /* + * Restart the timer if a controller reset is already scheduled. Any + * timed out commands would be handled before entering the connecting + * state. + */ + if (ctrl->ctrl.state == NVME_CTRL_RESETTING) + return BLK_EH_RESET_TIMER; + dev_warn(ctrl->ctrl.device, "queue %d: timeout request %#x type %d\n", nvme_tcp_queue_id(req->queue), rq->tag, pdu->hdr.type); -- GitLab From 4c75f877853cfa81b12374a07208e07b077f39b8 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 6 Sep 2019 11:23:08 -0600 Subject: [PATCH 248/993] nvme: Prevent resets during paused controller state A paused controller is doing critical internal activation work in the background. Prevent subsequent controller resets from occurring during this period by setting the controller state to RESETTING first. A helper function, nvme_try_sched_reset_work(), is introduced for these paths so they may continue with scheduling the reset_work after they've completed their uninterruptible critical section. Tested-by: Edmund Nadolski Reviewed-by: Christoph Hellwig Signed-off-by: Keith Busch --- drivers/nvme/host/core.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index e451e77005dc..e94fa693dd4b 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -120,6 +120,21 @@ static void nvme_queue_scan(struct nvme_ctrl *ctrl) queue_work(nvme_wq, &ctrl->scan_work); } +/* + * Use this function to proceed with scheduling reset_work for a controller + * that had previously been set to the resetting state. This is intended for + * code paths that can't be interrupted by other reset attempts. A hot removal + * may prevent this from succeeding. + */ +static int nvme_try_sched_reset(struct nvme_ctrl *ctrl) +{ + if (ctrl->state != NVME_CTRL_RESETTING) + return -EBUSY; + if (!queue_work(nvme_reset_wq, &ctrl->reset_work)) + return -EBUSY; + return 0; +} + int nvme_reset_ctrl(struct nvme_ctrl *ctrl) { if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) @@ -3828,13 +3843,13 @@ static void nvme_fw_act_work(struct work_struct *work) if (time_after(jiffies, fw_act_timeout)) { dev_warn(ctrl->device, "Fw activation timeout, reset controller\n"); - nvme_reset_ctrl(ctrl); - break; + nvme_try_sched_reset(ctrl); + return; } msleep(100); } - if (ctrl->state != NVME_CTRL_LIVE) + if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE)) return; nvme_start_queues(ctrl); @@ -3854,7 +3869,13 @@ static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result) nvme_queue_scan(ctrl); break; case NVME_AER_NOTICE_FW_ACT_STARTING: - queue_work(nvme_wq, &ctrl->fw_act_work); + /* + * We are (ab)using the RESETTING state to prevent subsequent + * recovery actions from interfering with the controller's + * firmware activation. + */ + if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) + queue_work(nvme_wq, &ctrl->fw_act_work); break; #ifdef CONFIG_NVME_MULTIPATH case NVME_AER_NOTICE_ANA: -- GitLab From c1ac9a4b0797ca8bb4470f863a5f78ef1ab13bed Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 4 Sep 2019 10:06:11 -0600 Subject: [PATCH 249/993] nvme: Wait for reset state when required Prevent simultaneous controller disabling/enabling tasks from interfering with each other through a function to wait until the task successfully transitioned the controller to the RESETTING state. This ensures disabling the controller will not be interrupted by another reset path, otherwise a concurrent reset may leave the controller in the wrong state. Tested-by: Edmund Nadolski Reviewed-by: Christoph Hellwig Signed-off-by: Keith Busch --- drivers/nvme/host/core.c | 41 +++++++++++++++++++++++++++++++++-- drivers/nvme/host/nvme.h | 4 ++++ drivers/nvme/host/pci.c | 46 +++++++++++++++++++++++++++------------- 3 files changed, 74 insertions(+), 17 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index e94fa693dd4b..fa7ba09dca77 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -126,7 +126,7 @@ static void nvme_queue_scan(struct nvme_ctrl *ctrl) * code paths that can't be interrupted by other reset attempts. A hot removal * may prevent this from succeeding. */ -static int nvme_try_sched_reset(struct nvme_ctrl *ctrl) +int nvme_try_sched_reset(struct nvme_ctrl *ctrl) { if (ctrl->state != NVME_CTRL_RESETTING) return -EBUSY; @@ -134,6 +134,7 @@ static int nvme_try_sched_reset(struct nvme_ctrl *ctrl) return -EBUSY; return 0; } +EXPORT_SYMBOL_GPL(nvme_try_sched_reset); int nvme_reset_ctrl(struct nvme_ctrl *ctrl) { @@ -384,8 +385,10 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, break; } - if (changed) + if (changed) { ctrl->state = new_state; + wake_up_all(&ctrl->state_wq); + } spin_unlock_irqrestore(&ctrl->lock, flags); if (changed && ctrl->state == NVME_CTRL_LIVE) @@ -394,6 +397,39 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, } EXPORT_SYMBOL_GPL(nvme_change_ctrl_state); +/* + * Returns true for sink states that can't ever transition back to live. + */ +static bool nvme_state_terminal(struct nvme_ctrl *ctrl) +{ + switch (ctrl->state) { + case NVME_CTRL_NEW: + case NVME_CTRL_LIVE: + case NVME_CTRL_RESETTING: + case NVME_CTRL_CONNECTING: + return false; + case NVME_CTRL_DELETING: + case NVME_CTRL_DEAD: + return true; + default: + WARN_ONCE(1, "Unhandled ctrl state:%d", ctrl->state); + return true; + } +} + +/* + * Waits for the controller state to be resetting, or returns false if it is + * not possible to ever transition to that state. + */ +bool nvme_wait_reset(struct nvme_ctrl *ctrl) +{ + wait_event(ctrl->state_wq, + nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING) || + nvme_state_terminal(ctrl)); + return ctrl->state == NVME_CTRL_RESETTING; +} +EXPORT_SYMBOL_GPL(nvme_wait_reset); + static void nvme_free_ns_head(struct kref *ref) { struct nvme_ns_head *head = @@ -3998,6 +4034,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev, INIT_WORK(&ctrl->async_event_work, nvme_async_event_work); INIT_WORK(&ctrl->fw_act_work, nvme_fw_act_work); INIT_WORK(&ctrl->delete_work, nvme_delete_ctrl_work); + init_waitqueue_head(&ctrl->state_wq); INIT_DELAYED_WORK(&ctrl->ka_work, nvme_keep_alive_work); memset(&ctrl->ka_cmd, 0, sizeof(ctrl->ka_cmd)); diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 2ba577271ada..22e8401352c2 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -198,6 +199,7 @@ struct nvme_ctrl { struct cdev cdev; struct work_struct reset_work; struct work_struct delete_work; + wait_queue_head_t state_wq; struct nvme_subsystem *subsys; struct list_head subsys_entry; @@ -448,6 +450,7 @@ void nvme_complete_rq(struct request *req); bool nvme_cancel_request(struct request *req, void *data, bool reserved); bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, enum nvme_ctrl_state new_state); +bool nvme_wait_reset(struct nvme_ctrl *ctrl); int nvme_disable_ctrl(struct nvme_ctrl *ctrl); int nvme_enable_ctrl(struct nvme_ctrl *ctrl); int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl); @@ -498,6 +501,7 @@ int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count); void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); int nvme_reset_ctrl(struct nvme_ctrl *ctrl); int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl); +int nvme_try_sched_reset(struct nvme_ctrl *ctrl); int nvme_delete_ctrl(struct nvme_ctrl *ctrl); int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index e7e79d6af9ba..4b181969c432 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -2463,6 +2463,14 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) mutex_unlock(&dev->shutdown_lock); } +static int nvme_disable_prepare_reset(struct nvme_dev *dev, bool shutdown) +{ + if (!nvme_wait_reset(&dev->ctrl)) + return -EBUSY; + nvme_dev_disable(dev, shutdown); + return 0; +} + static int nvme_setup_prp_pools(struct nvme_dev *dev) { dev->prp_page_pool = dma_pool_create("prp list page", dev->dev, @@ -2510,6 +2518,11 @@ static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl) static void nvme_remove_dead_ctrl(struct nvme_dev *dev) { + /* + * Set state to deleting now to avoid blocking nvme_wait_reset(), which + * may be holding this pci_dev's device lock. + */ + nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DELETING); nvme_get_ctrl(&dev->ctrl); nvme_dev_disable(dev, false); nvme_kill_queues(&dev->ctrl); @@ -2835,19 +2848,28 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) static void nvme_reset_prepare(struct pci_dev *pdev) { struct nvme_dev *dev = pci_get_drvdata(pdev); - nvme_dev_disable(dev, false); + + /* + * We don't need to check the return value from waiting for the reset + * state as pci_dev device lock is held, making it impossible to race + * with ->remove(). + */ + nvme_disable_prepare_reset(dev, false); + nvme_sync_queues(&dev->ctrl); } static void nvme_reset_done(struct pci_dev *pdev) { struct nvme_dev *dev = pci_get_drvdata(pdev); - nvme_reset_ctrl_sync(&dev->ctrl); + + if (!nvme_try_sched_reset(&dev->ctrl)) + flush_work(&dev->ctrl.reset_work); } static void nvme_shutdown(struct pci_dev *pdev) { struct nvme_dev *dev = pci_get_drvdata(pdev); - nvme_dev_disable(dev, true); + nvme_disable_prepare_reset(dev, true); } /* @@ -2900,7 +2922,7 @@ static int nvme_resume(struct device *dev) if (ndev->last_ps == U32_MAX || nvme_set_power_state(ctrl, ndev->last_ps) != 0) - nvme_reset_ctrl(ctrl); + return nvme_try_sched_reset(&ndev->ctrl); return 0; } @@ -2928,10 +2950,8 @@ static int nvme_suspend(struct device *dev) */ if (pm_suspend_via_firmware() || !ctrl->npss || !pcie_aspm_enabled(pdev) || - (ndev->ctrl.quirks & NVME_QUIRK_SIMPLE_SUSPEND)) { - nvme_dev_disable(ndev, true); - return 0; - } + (ndev->ctrl.quirks & NVME_QUIRK_SIMPLE_SUSPEND)) + return nvme_disable_prepare_reset(ndev, true); nvme_start_freeze(ctrl); nvme_wait_freeze(ctrl); @@ -2963,9 +2983,8 @@ static int nvme_suspend(struct device *dev) * Clearing npss forces a controller reset on resume. The * correct value will be resdicovered then. */ - nvme_dev_disable(ndev, true); + ret = nvme_disable_prepare_reset(ndev, true); ctrl->npss = 0; - ret = 0; } unfreeze: nvme_unfreeze(ctrl); @@ -2975,9 +2994,7 @@ static int nvme_suspend(struct device *dev) static int nvme_simple_suspend(struct device *dev) { struct nvme_dev *ndev = pci_get_drvdata(to_pci_dev(dev)); - - nvme_dev_disable(ndev, true); - return 0; + return nvme_disable_prepare_reset(ndev, true); } static int nvme_simple_resume(struct device *dev) @@ -2985,8 +3002,7 @@ static int nvme_simple_resume(struct device *dev) struct pci_dev *pdev = to_pci_dev(dev); struct nvme_dev *ndev = pci_get_drvdata(pdev); - nvme_reset_ctrl(&ndev->ctrl); - return 0; + return nvme_try_sched_reset(&ndev->ctrl); } static const struct dev_pm_ops nvme_dev_pm_ops = { -- GitLab From ac1c4e18858cb1da6abe1932a7ca001c37f62372 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 10 Oct 2019 17:34:12 +0200 Subject: [PATCH 250/993] nvme-tcp: Initialize sk->sk_ll_usec only with NET_RX_BUSY_POLL The access to sk->sk_ll_usec should be hidden behind CONFIG_NET_RX_BUSY_POLL like the definition of sk_ll_usec. Put access to ->sk_ll_usec behind CONFIG_NET_RX_BUSY_POLL. Fixes: 1a9460cef5711 ("nvme-tcp: support simple polling") Reviewed-by: Christoph Hellwig Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Keith Busch --- drivers/nvme/host/tcp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 33de2fddfbb2..820dac10fa9e 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -1386,7 +1386,9 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, queue->sock->sk->sk_data_ready = nvme_tcp_data_ready; queue->sock->sk->sk_state_change = nvme_tcp_state_change; queue->sock->sk->sk_write_space = nvme_tcp_write_space; +#ifdef CONFIG_NET_RX_BUSY_POLL queue->sock->sk->sk_ll_usec = 1; +#endif write_unlock_bh(&queue->sock->sk->sk_callback_lock); return 0; -- GitLab From 2abd839aa7e615f2bbc50c8ba7deb9e40d186768 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 4 Oct 2019 14:46:24 +0100 Subject: [PATCH 251/993] kmemleak: Do not corrupt the object_list during clean-up In case of an error (e.g. memory pool too small), kmemleak disables itself and cleans up the already allocated metadata objects. However, if this happens early before the RCU callback mechanism is available, put_object() skips call_rcu() and frees the object directly. This is not safe with the RCU list traversal in __kmemleak_do_cleanup(). Change the list traversal in __kmemleak_do_cleanup() to list_for_each_entry_safe() and remove the rcu_read_{lock,unlock} since the kmemleak is already disabled at this point. In addition, avoid an unnecessary metadata object rb-tree look-up since it already has the struct kmemleak_object pointer. Fixes: c5665868183f ("mm: kmemleak: use the memory pool for early allocations") Reported-by: Alexey Kardashevskiy Reported-by: Marc Dionne Reported-by: Ted Ts'o Cc: Andrew Morton Signed-off-by: Catalin Marinas Signed-off-by: Linus Torvalds --- mm/kmemleak.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/mm/kmemleak.c b/mm/kmemleak.c index 03a8d84badad..244607663363 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -526,6 +526,16 @@ static struct kmemleak_object *find_and_get_object(unsigned long ptr, int alias) return object; } +/* + * Remove an object from the object_tree_root and object_list. Must be called + * with the kmemleak_lock held _if_ kmemleak is still enabled. + */ +static void __remove_object(struct kmemleak_object *object) +{ + rb_erase(&object->rb_node, &object_tree_root); + list_del_rcu(&object->object_list); +} + /* * Look up an object in the object search tree and remove it from both * object_tree_root and object_list. The returned object's use_count should be @@ -538,10 +548,8 @@ static struct kmemleak_object *find_and_remove_object(unsigned long ptr, int ali write_lock_irqsave(&kmemleak_lock, flags); object = lookup_object(ptr, alias); - if (object) { - rb_erase(&object->rb_node, &object_tree_root); - list_del_rcu(&object->object_list); - } + if (object) + __remove_object(object); write_unlock_irqrestore(&kmemleak_lock, flags); return object; @@ -1834,12 +1842,16 @@ static const struct file_operations kmemleak_fops = { static void __kmemleak_do_cleanup(void) { - struct kmemleak_object *object; + struct kmemleak_object *object, *tmp; - rcu_read_lock(); - list_for_each_entry_rcu(object, &object_list, object_list) - delete_object_full(object->pointer); - rcu_read_unlock(); + /* + * Kmemleak has already been disabled, no need for RCU list traversal + * or kmemleak_lock held. + */ + list_for_each_entry_safe(object, tmp, &object_list, object_list) { + __remove_object(object); + __delete_object(object); + } } /* -- GitLab From 6595d144decec396bf2e2efee27e50634a4b627f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 9 Oct 2019 20:21:05 +0100 Subject: [PATCH 252/993] xtensa: fix {get,put}_user() for 64bit values First of all, on short copies __copy_{to,from}_user() return the amount of bytes left uncopied, *not* -EFAULT. get_user() and put_user() are expected to return -EFAULT on failure. Another problem is get_user(v32, (__u64 __user *)p); that should fetch 64bit value and the assign it to v32, truncating it in process. Current code, OTOH, reads 8 bytes of data and stores them at the address of v32, stomping on the 4 bytes that follow v32 itself. Signed-off-by: Al Viro Signed-off-by: Max Filippov --- arch/xtensa/include/asm/uaccess.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h index 6792928ba84a..f568c00392ec 100644 --- a/arch/xtensa/include/asm/uaccess.h +++ b/arch/xtensa/include/asm/uaccess.h @@ -100,7 +100,7 @@ do { \ case 4: __put_user_asm(x, ptr, retval, 4, "s32i", __cb); break; \ case 8: { \ __typeof__(*ptr) __v64 = x; \ - retval = __copy_to_user(ptr, &__v64, 8); \ + retval = __copy_to_user(ptr, &__v64, 8) ? -EFAULT : 0; \ break; \ } \ default: __put_user_bad(); \ @@ -198,7 +198,16 @@ do { \ case 1: __get_user_asm(x, ptr, retval, 1, "l8ui", __cb); break;\ case 2: __get_user_asm(x, ptr, retval, 2, "l16ui", __cb); break;\ case 4: __get_user_asm(x, ptr, retval, 4, "l32i", __cb); break;\ - case 8: retval = __copy_from_user(&x, ptr, 8); break; \ + case 8: { \ + u64 __x; \ + if (unlikely(__copy_from_user(&__x, ptr, 8))) { \ + retval = -EFAULT; \ + (x) = 0; \ + } else { \ + (x) = *(__force __typeof__((ptr)))&__x; \ + } \ + break; \ + } \ default: (x) = __get_user_bad(); \ } \ } while (0) -- GitLab From 9e8acd9c44a0dd52b2922eeb82398c04e356c058 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Wed, 9 Oct 2019 10:31:24 +0200 Subject: [PATCH 253/993] bpf: lwtunnel: Fix reroute supplying invalid dst The dst in bpf_input() has lwtstate field set. As it is of the LWTUNNEL_ENCAP_BPF type, lwtstate->data is struct bpf_lwt. When the bpf program returns BPF_LWT_REROUTE, ip_route_input_noref is directly called on this skb. This causes invalid memory access, as ip_route_input_slow calls skb_tunnel_info(skb) that expects the dst->lwstate->data to be struct ip_tunnel_info. This results to struct bpf_lwt being accessed as struct ip_tunnel_info. Drop the dst before calling the IP route input functions (both for IPv4 and IPv6). Reported by KASAN. Fixes: 3bd0b15281af ("bpf: add handling of BPF_LWT_REROUTE to lwt_bpf.c") Signed-off-by: Jiri Benc Signed-off-by: Alexei Starovoitov Acked-by: Peter Oskolkov Link: https://lore.kernel.org/bpf/111664d58fe4e9dd9c8014bb3d0b2dab93086a9e.1570609794.git.jbenc@redhat.com --- net/core/lwt_bpf.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c index f93785e5833c..74cfb8b5ab33 100644 --- a/net/core/lwt_bpf.c +++ b/net/core/lwt_bpf.c @@ -88,11 +88,16 @@ static int bpf_lwt_input_reroute(struct sk_buff *skb) int err = -EINVAL; if (skb->protocol == htons(ETH_P_IP)) { + struct net_device *dev = skb_dst(skb)->dev; struct iphdr *iph = ip_hdr(skb); + dev_hold(dev); + skb_dst_drop(skb); err = ip_route_input_noref(skb, iph->daddr, iph->saddr, - iph->tos, skb_dst(skb)->dev); + iph->tos, dev); + dev_put(dev); } else if (skb->protocol == htons(ETH_P_IPV6)) { + skb_dst_drop(skb); err = ipv6_stub->ipv6_route_input(skb); } else { err = -EAFNOSUPPORT; -- GitLab From eda6d764ac33d9ce8d656fa381f05b3feae09085 Mon Sep 17 00:00:00 2001 From: Steven Price Date: Mon, 14 Oct 2019 16:15:15 +0100 Subject: [PATCH 254/993] drm/panfrost: Add missing GPU feature registers Three feature registers were declared but never actually read from the GPU. Add THREAD_MAX_THREADS, THREAD_MAX_WORKGROUP_SIZE and THREAD_MAX_BARRIER_SIZE so that the complete set are available. Fixes: 4bced8bea094 ("drm/panfrost: Export all GPU feature registers") Signed-off-by: Steven Price Signed-off-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/20191014151515.13839-1-steven.price@arm.com --- drivers/gpu/drm/panfrost/panfrost_gpu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c index f67ed925c0ef..8822ec13a0d6 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gpu.c +++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c @@ -208,6 +208,9 @@ static void panfrost_gpu_init_features(struct panfrost_device *pfdev) pfdev->features.mem_features = gpu_read(pfdev, GPU_MEM_FEATURES); pfdev->features.mmu_features = gpu_read(pfdev, GPU_MMU_FEATURES); pfdev->features.thread_features = gpu_read(pfdev, GPU_THREAD_FEATURES); + pfdev->features.max_threads = gpu_read(pfdev, GPU_THREAD_MAX_THREADS); + pfdev->features.thread_max_workgroup_sz = gpu_read(pfdev, GPU_THREAD_MAX_WORKGROUP_SIZE); + pfdev->features.thread_max_barrier_sz = gpu_read(pfdev, GPU_THREAD_MAX_BARRIER_SIZE); pfdev->features.coherency_features = gpu_read(pfdev, GPU_COHERENCY_FEATURES); for (i = 0; i < 4; i++) pfdev->features.texture_features[i] = gpu_read(pfdev, GPU_TEXTURE_FEATURES(i)); -- GitLab From 2f01b7864188b895e0f18250b650328da4fe3cb2 Mon Sep 17 00:00:00 2001 From: Vincent Chen Date: Mon, 23 Sep 2019 08:45:17 +0800 Subject: [PATCH 255/993] riscv: remove the switch statement in do_trap_break() To make the code more straightforward, replace the switch statement with an if statement. Suggested-by: Paul Walmsley Signed-off-by: Vincent Chen [paul.walmsley@sifive.com: cleaned up patch description; updated to apply] Link: https://lore.kernel.org/linux-riscv/20190927224711.GI4700@infradead.org/ Link: https://lore.kernel.org/linux-riscv/CABvJ_xiHJSB7P5QekuLRP=LBPzXXghAfuUpPUYb=a_HbnOQ6BA@mail.gmail.com/ Link: https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org/thread/VDCU2WOB6KQISREO4V5DTXEI2M7VOV55/ Cc: Christoph Hellwig Signed-off-by: Paul Walmsley --- arch/riscv/kernel/traps.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index 93742df9067f..1ac75f7d0bff 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -124,24 +124,24 @@ static inline unsigned long get_break_insn_length(unsigned long pc) asmlinkage void do_trap_break(struct pt_regs *regs) { - if (!user_mode(regs)) { + if (user_mode(regs)) { + force_sig_fault(SIGTRAP, TRAP_BRKPT, + (void __user *)(regs->sepc)); + return; + } +#ifdef CONFIG_GENERIC_BUG + { enum bug_trap_type type; type = report_bug(regs->sepc, regs); - switch (type) { -#ifdef CONFIG_GENERIC_BUG - case BUG_TRAP_TYPE_WARN: + if (type == BUG_TRAP_TYPE_WARN) { regs->sepc += get_break_insn_length(regs->sepc); return; - case BUG_TRAP_TYPE_BUG: -#endif /* CONFIG_GENERIC_BUG */ - default: - die(regs, "Kernel BUG"); } - } else { - force_sig_fault(SIGTRAP, TRAP_BRKPT, - (void __user *)(regs->sepc)); } +#endif /* CONFIG_GENERIC_BUG */ + + die(regs, "Kernel BUG"); } #ifdef CONFIG_GENERIC_BUG -- GitLab From 2993c9b04e616df0848b655d7202a707a70fc876 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Wed, 9 Oct 2019 12:42:44 -0700 Subject: [PATCH 256/993] riscv: dts: HiFive Unleashed: add default chosen/stdout-path Add a default "stdout-path" to the kernel DTS file, as is present in many of the board DTS files elsewhere in the kernel tree. With this line present, earlyconsole can be enabled by simply passing "earlycon" on the kernel command line. No specific device details are necessary, since the kernel will use the stdout-path as the default. Signed-off-by: Paul Walmsley Reviewed-by: Atish Patra --- arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts index 104d334511cd..88cfcb96bf23 100644 --- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts +++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts @@ -13,6 +13,7 @@ compatible = "sifive,hifive-unleashed-a00", "sifive,fu540-c000"; chosen { + stdout-path = "serial0"; }; cpus { -- GitLab From 4c8eb19cf9dc5fcc489757acbf93be90baf25848 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 10 Oct 2019 15:57:58 -0700 Subject: [PATCH 257/993] riscv: tlbflush: remove confusing comment on local_flush_tlb_all() Remove a confusing comment on our local_flush_tlb_all() implementation. Per an internal discussion with Andrew, while it's true that the fence.i is not necessary, it's not the case that an sfence.vma implies a fence.i. We also drop the section about "flush[ing] the entire local TLB" to better align with the language in section 4.2.1 "Supervisor Memory-Management Fence Instruction" of the RISC-V Privileged Specification v20190608. Fixes: c901e45a999a1 ("RISC-V: `sfence.vma` orderes the instruction cache") Reported-by: Alan Kao Cc: Palmer Dabbelt Cc: Andrew Waterman Signed-off-by: Paul Walmsley --- arch/riscv/include/asm/tlbflush.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h index 37ae4e367ad2..f02188a5b0f4 100644 --- a/arch/riscv/include/asm/tlbflush.h +++ b/arch/riscv/include/asm/tlbflush.h @@ -10,10 +10,6 @@ #include #include -/* - * Flush entire local TLB. 'sfence.vma' implicitly fences with the instruction - * cache as well, so a 'fence.i' is not necessary. - */ static inline void local_flush_tlb_all(void) { __asm__ __volatile__ ("sfence.vma" : : : "memory"); -- GitLab From 81dde26de9c08bb04c4962a15608778aaffb3cf9 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Oct 2019 21:41:24 +0200 Subject: [PATCH 258/993] firmware: dmi: Fix unlikely out-of-bounds read in save_mem_devices Before reading the Extended Size field, we should ensure it fits in the DMI record. There is already a record length check but it does not cover that field. It would take a seriously corrupted DMI table to hit that bug, so no need to worry, but we should still fix it. Signed-off-by: Jean Delvare Fixes: 6deae96b42eb ("firmware, DMI: Add function to look up a handle and return DIMM size") Cc: Tony Luck Cc: Borislav Petkov --- drivers/firmware/dmi_scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 35ed56b9c34f..1e21fc3e9851 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -408,7 +408,7 @@ static void __init save_mem_devices(const struct dmi_header *dm, void *v) bytes = ~0ull; else if (size & 0x8000) bytes = (u64)(size & 0x7fff) << 10; - else if (size != 0x7fff) + else if (size != 0x7fff || dm->length < 0x20) bytes = (u64)size << 20; else bytes = (u64)get_unaligned((u32 *)&d[0x1C]) << 20; -- GitLab From b67114db64adcb0aaff0fe0bb2a84ede0a99aaf2 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 4 Oct 2019 13:10:09 +0200 Subject: [PATCH 259/993] parisc: sysctl.c: Use CONFIG_PARISC instead of __hppa_ define Signed-off-by: Helge Deller --- kernel/sysctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 00fcea236eba..b6f2f35d0bcf 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -163,7 +163,7 @@ static unsigned long hung_task_timeout_max = (LONG_MAX/HZ); #ifdef CONFIG_SPARC #endif -#ifdef __hppa__ +#ifdef CONFIG_PARISC extern int pwrsw_enabled; #endif @@ -620,7 +620,7 @@ static struct ctl_table kern_table[] = { .proc_handler = proc_dointvec, }, #endif -#ifdef __hppa__ +#ifdef CONFIG_PARISC { .procname = "soft-power", .data = &pwrsw_enabled, -- GitLab From 0703ad217ebd441dd730af71f8d9cdbf144fbc03 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 12 Aug 2019 14:50:36 -0700 Subject: [PATCH 260/993] parisc: prefer __section from compiler_attributes.h Reported-by: Sedat Dilek Suggested-by: Josh Poimboeuf Signed-off-by: Nick Desaulniers Signed-off-by: Helge Deller --- arch/parisc/include/asm/cache.h | 2 +- arch/parisc/include/asm/ldcw.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h index 73ca89a47f49..e5de3f897633 100644 --- a/arch/parisc/include/asm/cache.h +++ b/arch/parisc/include/asm/cache.h @@ -22,7 +22,7 @@ #define ARCH_DMA_MINALIGN L1_CACHE_BYTES -#define __read_mostly __attribute__((__section__(".data..read_mostly"))) +#define __read_mostly __section(.data..read_mostly) void parisc_cache_init(void); /* initializes cache-flushing */ void disable_sr_hashing_asm(int); /* low level support for above */ diff --git a/arch/parisc/include/asm/ldcw.h b/arch/parisc/include/asm/ldcw.h index 3eb4bfc1fb36..e080143e79a3 100644 --- a/arch/parisc/include/asm/ldcw.h +++ b/arch/parisc/include/asm/ldcw.h @@ -52,7 +52,7 @@ }) #ifdef CONFIG_SMP -# define __lock_aligned __attribute__((__section__(".data..lock_aligned"))) +# define __lock_aligned __section(.data..lock_aligned) #endif #endif /* __PARISC_LDCW_H */ -- GitLab From 513f7f747e1cba81f28a436911fba0b485878ebd Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 4 Oct 2019 19:23:37 +0200 Subject: [PATCH 261/993] parisc: Fix vmap memory leak in ioremap()/iounmap() Sven noticed that calling ioremap() and iounmap() multiple times leads to a vmap memory leak: vmap allocation for size 4198400 failed: use vmalloc= to increase size It seems we missed calling vunmap() in iounmap(). Signed-off-by: Helge Deller Noticed-by: Sven Schnelle Cc: # v3.16+ --- arch/parisc/mm/ioremap.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c index 92a9b5f12f98..f29f682352f0 100644 --- a/arch/parisc/mm/ioremap.c +++ b/arch/parisc/mm/ioremap.c @@ -3,7 +3,7 @@ * arch/parisc/mm/ioremap.c * * (C) Copyright 1995 1996 Linus Torvalds - * (C) Copyright 2001-2006 Helge Deller + * (C) Copyright 2001-2019 Helge Deller * (C) Copyright 2005 Kyle McMartin */ @@ -84,7 +84,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l addr = (void __iomem *) area->addr; if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, phys_addr, pgprot)) { - vfree(addr); + vunmap(addr); return NULL; } @@ -92,9 +92,11 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l } EXPORT_SYMBOL(__ioremap); -void iounmap(const volatile void __iomem *addr) +void iounmap(const volatile void __iomem *io_addr) { - if (addr > high_memory) - return vfree((void *) (PAGE_MASK & (unsigned long __force) addr)); + unsigned long addr = (unsigned long)io_addr & PAGE_MASK; + + if (is_vmalloc_addr((void *)addr)) + vunmap((void *)addr); } EXPORT_SYMBOL(iounmap); -- GitLab From c32c47aa364096124c9c69c1a44918433832562b Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Tue, 24 Sep 2019 17:01:31 +0200 Subject: [PATCH 262/993] parisc: Remove 32-bit DMA enforcement from sba_iommu This breaks booting from sata_sil24 with the recent DMA change. According to James Bottomley this was in to improve performance by kicking the device into 32 bit descriptors, which are usually more efficient, especially with older dual descriptor format cards like we have on parisc systems. Remove it for now to make DMA working again. Fixes: dcc02c19cc06 ("sata_sil24: use dma_set_mask_and_coherent") Signed-off-by: Sven Schnelle Signed-off-by: Helge Deller --- drivers/parisc/sba_iommu.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index ed50502cc65a..de8e4e347249 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -678,14 +678,6 @@ static int sba_dma_supported( struct device *dev, u64 mask) return(0); } - /* Documentation/DMA-API-HOWTO.txt tells drivers to try 64-bit - * first, then fall back to 32-bit if that fails. - * We are just "encouraging" 32-bit DMA masks here since we can - * never allow IOMMU bypass unless we add special support for ZX1. - */ - if (mask > ~0U) - return 0; - ioc = GET_IOC(dev); if (!ioc) return 0; -- GitLab From 7a7c5e715e722c86d602c56a09e77f000364e263 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Wed, 9 Oct 2019 07:39:54 +0900 Subject: [PATCH 263/993] block: Fix elv_support_iosched() A BIO based request queue does not have a tag_set, which prevent testing for the flag BLK_MQ_F_NO_SCHED indicating that the queue does not require an elevator. This leads to an incorrect initialization of a default elevator in some cases such as BIO based null_blk (queue_mode == BIO) with zoned mode enabled as the default elevator in this case is mq-deadline instead of "none". Fix this by testing for a NULL queue mq_ops field which indicates that the queue is BIO based and should not have an elevator. Reported-by: Shinichiro Kawasaki Reviewed-by: Bob Liu Signed-off-by: Damien Le Moal Signed-off-by: Jens Axboe --- block/elevator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/block/elevator.c b/block/elevator.c index 5437059c9261..076ba7308e65 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -616,7 +616,8 @@ int elevator_switch_mq(struct request_queue *q, static inline bool elv_support_iosched(struct request_queue *q) { - if (q->tag_set && (q->tag_set->flags & BLK_MQ_F_NO_SCHED)) + if (!q->mq_ops || + (q->tag_set && (q->tag_set->flags & BLK_MQ_F_NO_SCHED))) return false; return true; } -- GitLab From c0437642966fd32b827034af6f00eecd80b89325 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 9 Oct 2019 19:41:24 -0700 Subject: [PATCH 264/993] xtensa: clean up assembly arguments in uaccess macros Numeric assembly arguments are hard to understand and assembly code that uses them is hard to modify. Use named arguments in __check_align_*, __get_user_asm and __put_user_asm. Modify macro parameter names so that they don't affect argument names. Use '+' constraint for the [err] argument instead of having it as both input and output. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/uaccess.h | 42 +++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h index f568c00392ec..da4d35445063 100644 --- a/arch/xtensa/include/asm/uaccess.h +++ b/arch/xtensa/include/asm/uaccess.h @@ -132,14 +132,14 @@ do { \ #define __check_align_1 "" #define __check_align_2 \ - " _bbci.l %3, 0, 1f \n" \ - " movi %0, %4 \n" \ + " _bbci.l %[addr], 0, 1f \n" \ + " movi %[err], %[efault] \n" \ " _j 2f \n" #define __check_align_4 \ - " _bbsi.l %3, 0, 0f \n" \ - " _bbci.l %3, 1, 1f \n" \ - "0: movi %0, %4 \n" \ + " _bbsi.l %[addr], 0, 0f \n" \ + " _bbci.l %[addr], 1, 1f \n" \ + "0: movi %[err], %[efault] \n" \ " _j 2f \n" @@ -151,24 +151,24 @@ do { \ * WARNING: If you modify this macro at all, verify that the * __check_align_* macros still work. */ -#define __put_user_asm(x, addr, err, align, insn, cb) \ +#define __put_user_asm(x_, addr_, err_, align, insn, cb)\ __asm__ __volatile__( \ __check_align_##align \ - "1: "insn" %2, %3, 0 \n" \ + "1: "insn" %[x], %[addr], 0 \n" \ "2: \n" \ " .section .fixup,\"ax\" \n" \ " .align 4 \n" \ " .literal_position \n" \ "5: \n" \ - " movi %1, 2b \n" \ - " movi %0, %4 \n" \ - " jx %1 \n" \ + " movi %[tmp], 2b \n" \ + " movi %[err], %[efault] \n" \ + " jx %[tmp] \n" \ " .previous \n" \ " .section __ex_table,\"a\" \n" \ " .long 1b, 5b \n" \ " .previous" \ - :"=r" (err), "=r" (cb) \ - :"r" ((int)(x)), "r" (addr), "i" (-EFAULT), "0" (err)) + :[err] "+r"(err_), [tmp] "=r"(cb) \ + :[x] "r"(x_), [addr] "r"(addr_), [efault] "i"(-EFAULT)) #define __get_user_nocheck(x, ptr, size) \ ({ \ @@ -217,25 +217,25 @@ do { \ * WARNING: If you modify this macro at all, verify that the * __check_align_* macros still work. */ -#define __get_user_asm(x, addr, err, align, insn, cb) \ -__asm__ __volatile__( \ +#define __get_user_asm(x_, addr_, err_, align, insn, cb) \ +__asm__ __volatile__( \ __check_align_##align \ - "1: "insn" %2, %3, 0 \n" \ + "1: "insn" %[x], %[addr], 0 \n" \ "2: \n" \ " .section .fixup,\"ax\" \n" \ " .align 4 \n" \ " .literal_position \n" \ "5: \n" \ - " movi %1, 2b \n" \ - " movi %2, 0 \n" \ - " movi %0, %4 \n" \ - " jx %1 \n" \ + " movi %[tmp], 2b \n" \ + " movi %[x], 0 \n" \ + " movi %[err], %[efault] \n" \ + " jx %[tmp] \n" \ " .previous \n" \ " .section __ex_table,\"a\" \n" \ " .long 1b, 5b \n" \ " .previous" \ - :"=r" (err), "=r" (cb), "=r" (x) \ - :"r" (addr), "i" (-EFAULT), "0" (err)) + :[err] "+r"(err_), [tmp] "=r"(cb), [x] "=r"(x_)\ + :[addr] "r"(addr_), [efault] "i"(-EFAULT)) /* -- GitLab From c9c63f3c7a9081e4768291514991d3208ae8a697 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 10 Oct 2019 20:55:35 -0700 Subject: [PATCH 265/993] xtensa: fix type conversion in __get_user_[no]check __get_user_[no]check uses temporary buffer of type long to store result of __get_user_size and do sign extension on it when necessary. This doesn't work correctly for 64-bit data. Fix it by moving temporary buffer/sign extension logic to __get_user_asm. Don't do assignment of __get_user_bad result to (x) as it may not always be integer-compatible now and issue warning even when it's going to be optimized. Instead do (x) = 0; and call __get_user_bad separately. Zero initialize __x in __get_user_asm and use '+' constraint for its assembly argument, so that its value is preserved in error cases. This may add at most 1 cycle to the fast path, but saves an instruction and two padding bytes in the fixup section for each use of this macro and works for both misaligned store and store exception. Signed-off-by: Max Filippov --- arch/xtensa/include/asm/uaccess.h | 55 ++++++++++++++++--------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h index da4d35445063..3f80386f1883 100644 --- a/arch/xtensa/include/asm/uaccess.h +++ b/arch/xtensa/include/asm/uaccess.h @@ -172,19 +172,19 @@ __asm__ __volatile__( \ #define __get_user_nocheck(x, ptr, size) \ ({ \ - long __gu_err, __gu_val; \ - __get_user_size(__gu_val, (ptr), (size), __gu_err); \ - (x) = (__force __typeof__(*(ptr)))__gu_val; \ + long __gu_err; \ + __get_user_size((x), (ptr), (size), __gu_err); \ __gu_err; \ }) #define __get_user_check(x, ptr, size) \ ({ \ - long __gu_err = -EFAULT, __gu_val = 0; \ + long __gu_err = -EFAULT; \ const __typeof__(*(ptr)) *__gu_addr = (ptr); \ - if (access_ok(__gu_addr, size)) \ - __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ - (x) = (__force __typeof__(*(ptr)))__gu_val; \ + if (access_ok(__gu_addr, size)) \ + __get_user_size((x), __gu_addr, (size), __gu_err); \ + else \ + (x) = 0; \ __gu_err; \ }) @@ -208,7 +208,7 @@ do { \ } \ break; \ } \ - default: (x) = __get_user_bad(); \ + default: (x) = 0; __get_user_bad(); \ } \ } while (0) @@ -218,24 +218,27 @@ do { \ * __check_align_* macros still work. */ #define __get_user_asm(x_, addr_, err_, align, insn, cb) \ -__asm__ __volatile__( \ - __check_align_##align \ - "1: "insn" %[x], %[addr], 0 \n" \ - "2: \n" \ - " .section .fixup,\"ax\" \n" \ - " .align 4 \n" \ - " .literal_position \n" \ - "5: \n" \ - " movi %[tmp], 2b \n" \ - " movi %[x], 0 \n" \ - " movi %[err], %[efault] \n" \ - " jx %[tmp] \n" \ - " .previous \n" \ - " .section __ex_table,\"a\" \n" \ - " .long 1b, 5b \n" \ - " .previous" \ - :[err] "+r"(err_), [tmp] "=r"(cb), [x] "=r"(x_)\ - :[addr] "r"(addr_), [efault] "i"(-EFAULT)) +do { \ + u32 __x = 0; \ + __asm__ __volatile__( \ + __check_align_##align \ + "1: "insn" %[x], %[addr], 0 \n" \ + "2: \n" \ + " .section .fixup,\"ax\" \n" \ + " .align 4 \n" \ + " .literal_position \n" \ + "5: \n" \ + " movi %[tmp], 2b \n" \ + " movi %[err], %[efault] \n" \ + " jx %[tmp] \n" \ + " .previous \n" \ + " .section __ex_table,\"a\" \n" \ + " .long 1b, 5b \n" \ + " .previous" \ + :[err] "+r"(err_), [tmp] "=r"(cb), [x] "+r"(__x) \ + :[addr] "r"(addr_), [efault] "i"(-EFAULT)); \ + (x_) = (__force __typeof__(*(addr_)))__x; \ +} while (0) /* -- GitLab From 5556cfe8d994d5e7b4d50fd91597b8dc0b3a82fd Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Mon, 14 Oct 2019 14:11:40 -0700 Subject: [PATCH 266/993] mm, page_owner: fix off-by-one error in __set_page_owner_handle() Patch series "followups to debug_pagealloc improvements through page_owner", v3. These are followups to [1] which made it to Linus meanwhile. Patches 1 and 3 are based on Kirill's review, patch 2 on KASAN request [2]. It would be nice if all of this made it to 5.4 with [1] already there (or at least Patch 1). This patch (of 3): As noted by Kirill, commit 7e2f2a0cd17c ("mm, page_owner: record page owner for each subpage") has introduced an off-by-one error in __set_page_owner_handle() when looking up page_ext for subpages. As a result, the head page page_owner info is set twice, while for the last tail page, it's not set at all. Fix this and also make the code more efficient by advancing the page_ext pointer we already have, instead of calling lookup_page_ext() for each subpage. Since the full size of struct page_ext is not known at compile time, we can't use a simple page_ext++ statement, so introduce a page_ext_next() inline function for that. Link: http://lkml.kernel.org/r/20190930122916.14969-2-vbabka@suse.cz Fixes: 7e2f2a0cd17c ("mm, page_owner: record page owner for each subpage") Signed-off-by: Vlastimil Babka Reported-by: Kirill A. Shutemov Reported-by: Miles Chen Acked-by: Kirill A. Shutemov Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: Walter Wu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/page_ext.h | 8 ++++++++ mm/page_ext.c | 23 +++++++++-------------- mm/page_owner.c | 15 +++++++-------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h index 682fd465df06..5e856512bafb 100644 --- a/include/linux/page_ext.h +++ b/include/linux/page_ext.h @@ -36,6 +36,7 @@ struct page_ext { unsigned long flags; }; +extern unsigned long page_ext_size; extern void pgdat_page_ext_init(struct pglist_data *pgdat); #ifdef CONFIG_SPARSEMEM @@ -52,6 +53,13 @@ static inline void page_ext_init(void) struct page_ext *lookup_page_ext(const struct page *page); +static inline struct page_ext *page_ext_next(struct page_ext *curr) +{ + void *next = curr; + next += page_ext_size; + return next; +} + #else /* !CONFIG_PAGE_EXTENSION */ struct page_ext; diff --git a/mm/page_ext.c b/mm/page_ext.c index 5f5769c7db3b..4ade843ff588 100644 --- a/mm/page_ext.c +++ b/mm/page_ext.c @@ -67,8 +67,9 @@ static struct page_ext_operations *page_ext_ops[] = { #endif }; +unsigned long page_ext_size = sizeof(struct page_ext); + static unsigned long total_usage; -static unsigned long extra_mem; static bool __init invoke_need_callbacks(void) { @@ -78,9 +79,8 @@ static bool __init invoke_need_callbacks(void) for (i = 0; i < entries; i++) { if (page_ext_ops[i]->need && page_ext_ops[i]->need()) { - page_ext_ops[i]->offset = sizeof(struct page_ext) + - extra_mem; - extra_mem += page_ext_ops[i]->size; + page_ext_ops[i]->offset = page_ext_size; + page_ext_size += page_ext_ops[i]->size; need = true; } } @@ -99,14 +99,9 @@ static void __init invoke_init_callbacks(void) } } -static unsigned long get_entry_size(void) -{ - return sizeof(struct page_ext) + extra_mem; -} - static inline struct page_ext *get_entry(void *base, unsigned long index) { - return base + get_entry_size() * index; + return base + page_ext_size * index; } #if !defined(CONFIG_SPARSEMEM) @@ -156,7 +151,7 @@ static int __init alloc_node_page_ext(int nid) !IS_ALIGNED(node_end_pfn(nid), MAX_ORDER_NR_PAGES)) nr_pages += MAX_ORDER_NR_PAGES; - table_size = get_entry_size() * nr_pages; + table_size = page_ext_size * nr_pages; base = memblock_alloc_try_nid( table_size, PAGE_SIZE, __pa(MAX_DMA_ADDRESS), @@ -234,7 +229,7 @@ static int __meminit init_section_page_ext(unsigned long pfn, int nid) if (section->page_ext) return 0; - table_size = get_entry_size() * PAGES_PER_SECTION; + table_size = page_ext_size * PAGES_PER_SECTION; base = alloc_page_ext(table_size, nid); /* @@ -254,7 +249,7 @@ static int __meminit init_section_page_ext(unsigned long pfn, int nid) * we need to apply a mask. */ pfn &= PAGE_SECTION_MASK; - section->page_ext = (void *)base - get_entry_size() * pfn; + section->page_ext = (void *)base - page_ext_size * pfn; total_usage += table_size; return 0; } @@ -267,7 +262,7 @@ static void free_page_ext(void *addr) struct page *page = virt_to_page(addr); size_t table_size; - table_size = get_entry_size() * PAGES_PER_SECTION; + table_size = page_ext_size * PAGES_PER_SECTION; BUG_ON(PageReserved(page)); kmemleak_free(addr); diff --git a/mm/page_owner.c b/mm/page_owner.c index dee931184788..d3cf5d336ccf 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -156,10 +156,10 @@ void __reset_page_owner(struct page *page, unsigned int order) handle = save_stack(GFP_NOWAIT | __GFP_NOWARN); #endif + page_ext = lookup_page_ext(page); + if (unlikely(!page_ext)) + return; for (i = 0; i < (1 << order); i++) { - page_ext = lookup_page_ext(page + i); - if (unlikely(!page_ext)) - continue; __clear_bit(PAGE_EXT_OWNER_ACTIVE, &page_ext->flags); #ifdef CONFIG_DEBUG_PAGEALLOC if (debug_pagealloc_enabled()) { @@ -167,6 +167,7 @@ void __reset_page_owner(struct page *page, unsigned int order) page_owner->free_handle = handle; } #endif + page_ext = page_ext_next(page_ext); } } @@ -186,7 +187,7 @@ static inline void __set_page_owner_handle(struct page *page, __set_bit(PAGE_EXT_OWNER, &page_ext->flags); __set_bit(PAGE_EXT_OWNER_ACTIVE, &page_ext->flags); - page_ext = lookup_page_ext(page + i); + page_ext = page_ext_next(page_ext); } } @@ -224,12 +225,10 @@ void __split_page_owner(struct page *page, unsigned int order) if (unlikely(!page_ext)) return; - page_owner = get_page_owner(page_ext); - page_owner->order = 0; - for (i = 1; i < (1 << order); i++) { - page_ext = lookup_page_ext(page + i); + for (i = 0; i < (1 << order); i++) { page_owner = get_page_owner(page_ext); page_owner->order = 0; + page_ext = page_ext_next(page_ext); } } -- GitLab From 0fe9a448a029a11d7211fcc2ebe9023d7fd31792 Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Mon, 14 Oct 2019 14:11:44 -0700 Subject: [PATCH 267/993] mm, page_owner: decouple freeing stack trace from debug_pagealloc Commit 8974558f49a6 ("mm, page_owner, debug_pagealloc: save and dump freeing stack trace") enhanced page_owner to also store freeing stack trace, when debug_pagealloc is also enabled. KASAN would also like to do this [1] to improve error reports to debug e.g. UAF issues. Kirill has suggested that the freeing stack trace saving should be also possible to be enabled separately from KASAN or debug_pagealloc, i.e. with an extra boot option. Qian argued that we have enough options already, and avoiding the extra overhead is not worth the complications in the case of a debugging option. Kirill noted that the extra stack handle in struct page_owner requires 0.1% of memory. This patch therefore enables free stack saving whenever page_owner is enabled, regardless of whether debug_pagealloc or KASAN is also enabled. KASAN kernels booted with page_owner=on will thus benefit from the improved error reports. [1] https://bugzilla.kernel.org/show_bug.cgi?id=203967 [vbabka@suse.cz: v3] Link: http://lkml.kernel.org/r/20191007091808.7096-3-vbabka@suse.cz Link: http://lkml.kernel.org/r/20190930122916.14969-3-vbabka@suse.cz Signed-off-by: Vlastimil Babka Reviewed-by: Qian Cai Suggested-by: Dmitry Vyukov Suggested-by: Walter Wu Suggested-by: Andrey Ryabinin Suggested-by: Kirill A. Shutemov Suggested-by: Qian Cai Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/dev-tools/kasan.rst | 3 +++ mm/page_owner.c | 28 +++++++--------------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/kasan.rst index b72d07d70239..525296121d89 100644 --- a/Documentation/dev-tools/kasan.rst +++ b/Documentation/dev-tools/kasan.rst @@ -41,6 +41,9 @@ smaller binary while the latter is 1.1 - 2 times faster. Both KASAN modes work with both SLUB and SLAB memory allocators. For better bug detection and nicer reporting, enable CONFIG_STACKTRACE. +To augment reports with last allocation and freeing stack of the physical page, +it is recommended to enable also CONFIG_PAGE_OWNER and boot with page_owner=on. + To disable instrumentation for specific files or directories, add a line similar to the following to the respective kernel Makefile: diff --git a/mm/page_owner.c b/mm/page_owner.c index d3cf5d336ccf..de1916ac3e24 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -24,12 +24,10 @@ struct page_owner { short last_migrate_reason; gfp_t gfp_mask; depot_stack_handle_t handle; -#ifdef CONFIG_DEBUG_PAGEALLOC depot_stack_handle_t free_handle; -#endif }; -static bool page_owner_disabled = true; +static bool page_owner_enabled = false; DEFINE_STATIC_KEY_FALSE(page_owner_inited); static depot_stack_handle_t dummy_handle; @@ -44,7 +42,7 @@ static int __init early_page_owner_param(char *buf) return -EINVAL; if (strcmp(buf, "on") == 0) - page_owner_disabled = false; + page_owner_enabled = true; return 0; } @@ -52,10 +50,7 @@ early_param("page_owner", early_page_owner_param); static bool need_page_owner(void) { - if (page_owner_disabled) - return false; - - return true; + return page_owner_enabled; } static __always_inline depot_stack_handle_t create_dummy_stack(void) @@ -84,7 +79,7 @@ static noinline void register_early_stack(void) static void init_page_owner(void) { - if (page_owner_disabled) + if (!page_owner_enabled) return; register_dummy_stack(); @@ -148,25 +143,18 @@ void __reset_page_owner(struct page *page, unsigned int order) { int i; struct page_ext *page_ext; -#ifdef CONFIG_DEBUG_PAGEALLOC depot_stack_handle_t handle = 0; struct page_owner *page_owner; - if (debug_pagealloc_enabled()) - handle = save_stack(GFP_NOWAIT | __GFP_NOWARN); -#endif + handle = save_stack(GFP_NOWAIT | __GFP_NOWARN); page_ext = lookup_page_ext(page); if (unlikely(!page_ext)) return; for (i = 0; i < (1 << order); i++) { __clear_bit(PAGE_EXT_OWNER_ACTIVE, &page_ext->flags); -#ifdef CONFIG_DEBUG_PAGEALLOC - if (debug_pagealloc_enabled()) { - page_owner = get_page_owner(page_ext); - page_owner->free_handle = handle; - } -#endif + page_owner = get_page_owner(page_ext); + page_owner->free_handle = handle; page_ext = page_ext_next(page_ext); } } @@ -450,7 +438,6 @@ void __dump_page_owner(struct page *page) stack_trace_print(entries, nr_entries, 0); } -#ifdef CONFIG_DEBUG_PAGEALLOC handle = READ_ONCE(page_owner->free_handle); if (!handle) { pr_alert("page_owner free stack trace missing\n"); @@ -459,7 +446,6 @@ void __dump_page_owner(struct page *page) pr_alert("page last free stack trace:\n"); stack_trace_print(entries, nr_entries, 0); } -#endif if (page_owner->last_migrate_reason != -1) pr_alert("page has been migrated, last migrate reason: %s\n", -- GitLab From fdf3bf809162592b54c278b9b0e84f3e126f8844 Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Mon, 14 Oct 2019 14:11:47 -0700 Subject: [PATCH 268/993] mm, page_owner: rename flag indicating that page is allocated Commit 37389167a281 ("mm, page_owner: keep owner info when freeing the page") has introduced a flag PAGE_EXT_OWNER_ACTIVE to indicate that page is tracked as being allocated. Kirril suggested naming it PAGE_EXT_OWNER_ALLOCATED to make it more clear, as "active is somewhat loaded term for a page". Link: http://lkml.kernel.org/r/20190930122916.14969-4-vbabka@suse.cz Signed-off-by: Vlastimil Babka Suggested-by: Kirill A. Shutemov Cc: Andrey Ryabinin Cc: Dmitry Vyukov Cc: Kirill A. Shutemov Cc: Walter Wu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/page_ext.h | 2 +- mm/page_owner.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h index 5e856512bafb..cfce186f0c4e 100644 --- a/include/linux/page_ext.h +++ b/include/linux/page_ext.h @@ -18,7 +18,7 @@ struct page_ext_operations { enum page_ext_flags { PAGE_EXT_OWNER, - PAGE_EXT_OWNER_ACTIVE, + PAGE_EXT_OWNER_ALLOCATED, #if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT) PAGE_EXT_YOUNG, PAGE_EXT_IDLE, diff --git a/mm/page_owner.c b/mm/page_owner.c index de1916ac3e24..e327bcd0380e 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -152,7 +152,7 @@ void __reset_page_owner(struct page *page, unsigned int order) if (unlikely(!page_ext)) return; for (i = 0; i < (1 << order); i++) { - __clear_bit(PAGE_EXT_OWNER_ACTIVE, &page_ext->flags); + __clear_bit(PAGE_EXT_OWNER_ALLOCATED, &page_ext->flags); page_owner = get_page_owner(page_ext); page_owner->free_handle = handle; page_ext = page_ext_next(page_ext); @@ -173,7 +173,7 @@ static inline void __set_page_owner_handle(struct page *page, page_owner->gfp_mask = gfp_mask; page_owner->last_migrate_reason = -1; __set_bit(PAGE_EXT_OWNER, &page_ext->flags); - __set_bit(PAGE_EXT_OWNER_ACTIVE, &page_ext->flags); + __set_bit(PAGE_EXT_OWNER_ALLOCATED, &page_ext->flags); page_ext = page_ext_next(page_ext); } @@ -247,7 +247,7 @@ void __copy_page_owner(struct page *oldpage, struct page *newpage) * the new page, which will be freed. */ __set_bit(PAGE_EXT_OWNER, &new_ext->flags); - __set_bit(PAGE_EXT_OWNER_ACTIVE, &new_ext->flags); + __set_bit(PAGE_EXT_OWNER_ALLOCATED, &new_ext->flags); } void pagetypeinfo_showmixedcount_print(struct seq_file *m, @@ -307,7 +307,7 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m, if (unlikely(!page_ext)) continue; - if (!test_bit(PAGE_EXT_OWNER_ACTIVE, &page_ext->flags)) + if (!test_bit(PAGE_EXT_OWNER_ALLOCATED, &page_ext->flags)) continue; page_owner = get_page_owner(page_ext); @@ -422,7 +422,7 @@ void __dump_page_owner(struct page *page) return; } - if (test_bit(PAGE_EXT_OWNER_ACTIVE, &page_ext->flags)) + if (test_bit(PAGE_EXT_OWNER_ALLOCATED, &page_ext->flags)) pr_alert("page_owner tracks the page as allocated\n"); else pr_alert("page_owner tracks the page as freed\n"); @@ -512,7 +512,7 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos) * Although we do have the info about past allocation of free * pages, it's not relevant for current memory usage. */ - if (!test_bit(PAGE_EXT_OWNER_ACTIVE, &page_ext->flags)) + if (!test_bit(PAGE_EXT_OWNER_ALLOCATED, &page_ext->flags)) continue; page_owner = get_page_owner(page_ext); -- GitLab From e4f8e513c3d353c134ad4eef9fd0bba12406c7c8 Mon Sep 17 00:00:00 2001 From: Qian Cai Date: Mon, 14 Oct 2019 14:11:51 -0700 Subject: [PATCH 269/993] mm/slub: fix a deadlock in show_slab_objects() A long time ago we fixed a similar deadlock in show_slab_objects() [1]. However, it is apparently due to the commits like 01fb58bcba63 ("slab: remove synchronous synchronize_sched() from memcg cache deactivation path") and 03afc0e25f7f ("slab: get_online_mems for kmem_cache_{create,destroy,shrink}"), this kind of deadlock is back by just reading files in /sys/kernel/slab which will generate a lockdep splat below. Since the "mem_hotplug_lock" here is only to obtain a stable online node mask while racing with NUMA node hotplug, in the worst case, the results may me miscalculated while doing NUMA node hotplug, but they shall be corrected by later reads of the same files. WARNING: possible circular locking dependency detected ------------------------------------------------------ cat/5224 is trying to acquire lock: ffff900012ac3120 (mem_hotplug_lock.rw_sem){++++}, at: show_slab_objects+0x94/0x3a8 but task is already holding lock: b8ff009693eee398 (kn->count#45){++++}, at: kernfs_seq_start+0x44/0xf0 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #2 (kn->count#45){++++}: lock_acquire+0x31c/0x360 __kernfs_remove+0x290/0x490 kernfs_remove+0x30/0x44 sysfs_remove_dir+0x70/0x88 kobject_del+0x50/0xb0 sysfs_slab_unlink+0x2c/0x38 shutdown_cache+0xa0/0xf0 kmemcg_cache_shutdown_fn+0x1c/0x34 kmemcg_workfn+0x44/0x64 process_one_work+0x4f4/0x950 worker_thread+0x390/0x4bc kthread+0x1cc/0x1e8 ret_from_fork+0x10/0x18 -> #1 (slab_mutex){+.+.}: lock_acquire+0x31c/0x360 __mutex_lock_common+0x16c/0xf78 mutex_lock_nested+0x40/0x50 memcg_create_kmem_cache+0x38/0x16c memcg_kmem_cache_create_func+0x3c/0x70 process_one_work+0x4f4/0x950 worker_thread+0x390/0x4bc kthread+0x1cc/0x1e8 ret_from_fork+0x10/0x18 -> #0 (mem_hotplug_lock.rw_sem){++++}: validate_chain+0xd10/0x2bcc __lock_acquire+0x7f4/0xb8c lock_acquire+0x31c/0x360 get_online_mems+0x54/0x150 show_slab_objects+0x94/0x3a8 total_objects_show+0x28/0x34 slab_attr_show+0x38/0x54 sysfs_kf_seq_show+0x198/0x2d4 kernfs_seq_show+0xa4/0xcc seq_read+0x30c/0x8a8 kernfs_fop_read+0xa8/0x314 __vfs_read+0x88/0x20c vfs_read+0xd8/0x10c ksys_read+0xb0/0x120 __arm64_sys_read+0x54/0x88 el0_svc_handler+0x170/0x240 el0_svc+0x8/0xc other info that might help us debug this: Chain exists of: mem_hotplug_lock.rw_sem --> slab_mutex --> kn->count#45 Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(kn->count#45); lock(slab_mutex); lock(kn->count#45); lock(mem_hotplug_lock.rw_sem); *** DEADLOCK *** 3 locks held by cat/5224: #0: 9eff00095b14b2a0 (&p->lock){+.+.}, at: seq_read+0x4c/0x8a8 #1: 0eff008997041480 (&of->mutex){+.+.}, at: kernfs_seq_start+0x34/0xf0 #2: b8ff009693eee398 (kn->count#45){++++}, at: kernfs_seq_start+0x44/0xf0 stack backtrace: Call trace: dump_backtrace+0x0/0x248 show_stack+0x20/0x2c dump_stack+0xd0/0x140 print_circular_bug+0x368/0x380 check_noncircular+0x248/0x250 validate_chain+0xd10/0x2bcc __lock_acquire+0x7f4/0xb8c lock_acquire+0x31c/0x360 get_online_mems+0x54/0x150 show_slab_objects+0x94/0x3a8 total_objects_show+0x28/0x34 slab_attr_show+0x38/0x54 sysfs_kf_seq_show+0x198/0x2d4 kernfs_seq_show+0xa4/0xcc seq_read+0x30c/0x8a8 kernfs_fop_read+0xa8/0x314 __vfs_read+0x88/0x20c vfs_read+0xd8/0x10c ksys_read+0xb0/0x120 __arm64_sys_read+0x54/0x88 el0_svc_handler+0x170/0x240 el0_svc+0x8/0xc I think it is important to mention that this doesn't expose the show_slab_objects to use-after-free. There is only a single path that might really race here and that is the slab hotplug notifier callback __kmem_cache_shrink (via slab_mem_going_offline_callback) but that path doesn't really destroy kmem_cache_node data structures. [1] http://lkml.iu.edu/hypermail/linux/kernel/1101.0/02850.html [akpm@linux-foundation.org: add comment explaining why we don't need mem_hotplug_lock] Link: http://lkml.kernel.org/r/1570192309-10132-1-git-send-email-cai@lca.pw Fixes: 01fb58bcba63 ("slab: remove synchronous synchronize_sched() from memcg cache deactivation path") Fixes: 03afc0e25f7f ("slab: get_online_mems for kmem_cache_{create,destroy,shrink}") Signed-off-by: Qian Cai Acked-by: Michal Hocko Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Cc: Tejun Heo Cc: Vladimir Davydov Cc: Roman Gushchin Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slub.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 3d63ae320d31..442f111d1e98 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -4846,7 +4846,17 @@ static ssize_t show_slab_objects(struct kmem_cache *s, } } - get_online_mems(); + /* + * It is impossible to take "mem_hotplug_lock" here with "kernfs_mutex" + * already held which will conflict with an existing lock order: + * + * mem_hotplug_lock->slab_mutex->kernfs_mutex + * + * We don't really need mem_hotplug_lock (to hold off + * slab_mem_going_offline_callback) here because slab's memory hot + * unplug code doesn't destroy the kmem_cache->node[] data. + */ + #ifdef CONFIG_SLUB_DEBUG if (flags & SO_ALL) { struct kmem_cache_node *n; @@ -4887,7 +4897,6 @@ static ssize_t show_slab_objects(struct kmem_cache *s, x += sprintf(buf + x, " N%d=%lu", node, nodes[node]); #endif - put_online_mems(); kfree(nodes); return x + sprintf(buf + x, "\n"); } -- GitLab From 3c52b0af059e11a063970aed1ad143b9284a79c7 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 14 Oct 2019 14:11:54 -0700 Subject: [PATCH 270/993] lib/generic-radix-tree.c: add kmemleak annotations Kmemleak is falsely reporting a leak of the slab allocation in sctp_stream_init_ext(): BUG: memory leak unreferenced object 0xffff8881114f5d80 (size 96): comm "syz-executor934", pid 7160, jiffies 4294993058 (age 31.950s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<00000000ce7a1326>] kmemleak_alloc_recursive include/linux/kmemleak.h:55 [inline] [<00000000ce7a1326>] slab_post_alloc_hook mm/slab.h:439 [inline] [<00000000ce7a1326>] slab_alloc mm/slab.c:3326 [inline] [<00000000ce7a1326>] kmem_cache_alloc_trace+0x13d/0x280 mm/slab.c:3553 [<000000007abb7ac9>] kmalloc include/linux/slab.h:547 [inline] [<000000007abb7ac9>] kzalloc include/linux/slab.h:742 [inline] [<000000007abb7ac9>] sctp_stream_init_ext+0x2b/0xa0 net/sctp/stream.c:157 [<0000000048ecb9c1>] sctp_sendmsg_to_asoc+0x946/0xa00 net/sctp/socket.c:1882 [<000000004483ca2b>] sctp_sendmsg+0x2a8/0x990 net/sctp/socket.c:2102 [...] But it's freed later. Kmemleak misses the allocation because its pointer is stored in the generic radix tree sctp_stream::out, and the generic radix tree uses raw pages which aren't tracked by kmemleak. Fix this by adding the kmemleak hooks to the generic radix tree code. Link: http://lkml.kernel.org/r/20191004065039.727564-1-ebiggers@kernel.org Signed-off-by: Eric Biggers Reported-by: Reviewed-by: Marcelo Ricardo Leitner Acked-by: Neil Horman Reviewed-by: Catalin Marinas Cc: Kent Overstreet Cc: Vlad Yasevich Cc: Xin Long Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/generic-radix-tree.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/generic-radix-tree.c b/lib/generic-radix-tree.c index ae25e2fa2187..f25eb111c051 100644 --- a/lib/generic-radix-tree.c +++ b/lib/generic-radix-tree.c @@ -2,6 +2,7 @@ #include #include #include +#include #define GENRADIX_ARY (PAGE_SIZE / sizeof(struct genradix_node *)) #define GENRADIX_ARY_SHIFT ilog2(GENRADIX_ARY) @@ -75,6 +76,27 @@ void *__genradix_ptr(struct __genradix *radix, size_t offset) } EXPORT_SYMBOL(__genradix_ptr); +static inline struct genradix_node *genradix_alloc_node(gfp_t gfp_mask) +{ + struct genradix_node *node; + + node = (struct genradix_node *)__get_free_page(gfp_mask|__GFP_ZERO); + + /* + * We're using pages (not slab allocations) directly for kernel data + * structures, so we need to explicitly inform kmemleak of them in order + * to avoid false positive memory leak reports. + */ + kmemleak_alloc(node, PAGE_SIZE, 1, gfp_mask); + return node; +} + +static inline void genradix_free_node(struct genradix_node *node) +{ + kmemleak_free(node); + free_page((unsigned long)node); +} + /* * Returns pointer to the specified byte @offset within @radix, allocating it if * necessary - newly allocated slots are always zeroed out: @@ -97,8 +119,7 @@ void *__genradix_ptr_alloc(struct __genradix *radix, size_t offset, break; if (!new_node) { - new_node = (void *) - __get_free_page(gfp_mask|__GFP_ZERO); + new_node = genradix_alloc_node(gfp_mask); if (!new_node) return NULL; } @@ -121,8 +142,7 @@ void *__genradix_ptr_alloc(struct __genradix *radix, size_t offset, n = READ_ONCE(*p); if (!n) { if (!new_node) { - new_node = (void *) - __get_free_page(gfp_mask|__GFP_ZERO); + new_node = genradix_alloc_node(gfp_mask); if (!new_node) return NULL; } @@ -133,7 +153,7 @@ void *__genradix_ptr_alloc(struct __genradix *radix, size_t offset, } if (new_node) - free_page((unsigned long) new_node); + genradix_free_node(new_node); return &n->data[offset]; } @@ -191,7 +211,7 @@ static void genradix_free_recurse(struct genradix_node *n, unsigned level) genradix_free_recurse(n->children[i], level - 1); } - free_page((unsigned long) n); + genradix_free_node(n); } int __genradix_prealloc(struct __genradix *radix, size_t size, -- GitLab From 0f181f9fbea8bc7ea2f7e13ae7f8c256b39e254c Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Mon, 14 Oct 2019 14:11:57 -0700 Subject: [PATCH 271/993] mm/slub.c: init_on_free=1 should wipe freelist ptr for bulk allocations slab_alloc_node() already zeroed out the freelist pointer if init_on_free was on. Thibaut Sautereau noticed that the same needs to be done for kmem_cache_alloc_bulk(), which performs the allocations separately. kmem_cache_alloc_bulk() is currently used in two places in the kernel, so this change is unlikely to have a major performance impact. SLAB doesn't require a similar change, as auto-initialization makes the allocator store the freelist pointers off-slab. Link: http://lkml.kernel.org/r/20191007091605.30530-1-glider@google.com Fixes: 6471384af2a6 ("mm: security: introduce init_on_alloc=1 and init_on_free=1 boot options") Signed-off-by: Alexander Potapenko Reported-by: Thibaut Sautereau Reported-by: Kees Cook Cc: Christoph Lameter Cc: Laura Abbott Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slub.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 442f111d1e98..b25c807a111f 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -2671,6 +2671,17 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, return p; } +/* + * If the object has been wiped upon free, make sure it's fully initialized by + * zeroing out freelist pointer. + */ +static __always_inline void maybe_wipe_obj_freeptr(struct kmem_cache *s, + void *obj) +{ + if (unlikely(slab_want_init_on_free(s)) && obj) + memset((void *)((char *)obj + s->offset), 0, sizeof(void *)); +} + /* * Inlined fastpath so that allocation functions (kmalloc, kmem_cache_alloc) * have the fastpath folded into their functions. So no function call @@ -2759,12 +2770,8 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s, prefetch_freepointer(s, next_object); stat(s, ALLOC_FASTPATH); } - /* - * If the object has been wiped upon free, make sure it's fully - * initialized by zeroing out freelist pointer. - */ - if (unlikely(slab_want_init_on_free(s)) && object) - memset(object + s->offset, 0, sizeof(void *)); + + maybe_wipe_obj_freeptr(s, object); if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object) memset(object, 0, s->object_size); @@ -3178,10 +3185,13 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size, goto error; c = this_cpu_ptr(s->cpu_slab); + maybe_wipe_obj_freeptr(s, p[i]); + continue; /* goto for-loop */ } c->freelist = get_freepointer(s, object); p[i] = object; + maybe_wipe_obj_freeptr(s, p[i]); } c->tid = next_tid(c->tid); local_irq_enable(); -- GitLab From 03a9349ac0e095dea6ef8b5b7b14f9c23e5fabe6 Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Mon, 14 Oct 2019 14:12:00 -0700 Subject: [PATCH 272/993] lib/test_meminit: add a kmem_cache_alloc_bulk() test Make sure allocations from kmem_cache_alloc_bulk() and kmem_cache_free_bulk() are properly initialized. Link: http://lkml.kernel.org/r/20191007091605.30530-2-glider@google.com Signed-off-by: Alexander Potapenko Cc: Kees Cook Cc: Christoph Lameter Cc: Laura Abbott Cc: Thibaut Sautereau Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/test_meminit.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/lib/test_meminit.c b/lib/test_meminit.c index 9729f271d150..9742e5cb853a 100644 --- a/lib/test_meminit.c +++ b/lib/test_meminit.c @@ -297,6 +297,32 @@ static int __init do_kmem_cache_rcu_persistent(int size, int *total_failures) return 1; } +static int __init do_kmem_cache_size_bulk(int size, int *total_failures) +{ + struct kmem_cache *c; + int i, iter, maxiter = 1024; + int num, bytes; + bool fail = false; + void *objects[10]; + + c = kmem_cache_create("test_cache", size, size, 0, NULL); + for (iter = 0; (iter < maxiter) && !fail; iter++) { + num = kmem_cache_alloc_bulk(c, GFP_KERNEL, ARRAY_SIZE(objects), + objects); + for (i = 0; i < num; i++) { + bytes = count_nonzero_bytes(objects[i], size); + if (bytes) + fail = true; + fill_with_garbage(objects[i], size); + } + + if (num) + kmem_cache_free_bulk(c, num, objects); + } + *total_failures += fail; + return 1; +} + /* * Test kmem_cache allocation by creating caches of different sizes, with and * without constructors, with and without SLAB_TYPESAFE_BY_RCU. @@ -318,6 +344,7 @@ static int __init test_kmemcache(int *total_failures) num_tests += do_kmem_cache_size(size, ctor, rcu, zero, &failures); } + num_tests += do_kmem_cache_size_bulk(size, &failures); } REPORT_FAILURES_IN_FN(); *total_failures += failures; -- GitLab From 3f36d8669457605910cb7a40089b485949569c41 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 14 Oct 2019 14:12:04 -0700 Subject: [PATCH 273/993] mm, hugetlb: allow hugepage allocations to reclaim as needed Commit b39d0ee2632d ("mm, page_alloc: avoid expensive reclaim when compaction may not succeed") has chnaged the allocator to bail out from the allocator early to prevent from a potentially excessive memory reclaim. __GFP_RETRY_MAYFAIL is designed to retry the allocation, reclaim and compaction loop as long as there is a reasonable chance to make forward progress. Neither COMPACT_SKIPPED nor COMPACT_DEFERRED at the INIT_COMPACT_PRIORITY compaction attempt gives this feedback. The most obvious affected subsystem is hugetlbfs which allocates huge pages based on an admin request (or via admin configured overcommit). I have done a simple test which tries to allocate half of the memory for hugetlb pages while the memory is full of a clean page cache. This is not an unusual situation because we try to cache as much of the memory as possible and sysctl/sysfs interface to allocate huge pages is there for flexibility to allocate hugetlb pages at any time. System has 1GB of RAM and we are requesting 515MB worth of hugetlb pages after the memory is prefilled by a clean page cache: root@test1:~# cat hugetlb_test.sh set -x echo 0 > /proc/sys/vm/nr_hugepages echo 3 > /proc/sys/vm/drop_caches echo 1 > /proc/sys/vm/compact_memory dd if=/mnt/data/file-1G of=/dev/null bs=$((4<<10)) TS=$(date +%s) echo 256 > /proc/sys/vm/nr_hugepages cat /proc/sys/vm/nr_hugepages The results for 2 consecutive runs on clean 5.3 root@test1:~# sh hugetlb_test.sh + echo 0 + echo 3 + echo 1 + dd if=/mnt/data/file-1G of=/dev/null bs=4096 262144+0 records in 262144+0 records out 1073741824 bytes (1.1 GB) copied, 21.0694 s, 51.0 MB/s + date +%s + TS=1569905284 + echo 256 + cat /proc/sys/vm/nr_hugepages 256 root@test1:~# sh hugetlb_test.sh + echo 0 + echo 3 + echo 1 + dd if=/mnt/data/file-1G of=/dev/null bs=4096 262144+0 records in 262144+0 records out 1073741824 bytes (1.1 GB) copied, 21.7548 s, 49.4 MB/s + date +%s + TS=1569905311 + echo 256 + cat /proc/sys/vm/nr_hugepages 256 Now with b39d0ee2632d applied root@test1:~# sh hugetlb_test.sh + echo 0 + echo 3 + echo 1 + dd if=/mnt/data/file-1G of=/dev/null bs=4096 262144+0 records in 262144+0 records out 1073741824 bytes (1.1 GB) copied, 20.1815 s, 53.2 MB/s + date +%s + TS=1569905516 + echo 256 + cat /proc/sys/vm/nr_hugepages 11 root@test1:~# sh hugetlb_test.sh + echo 0 + echo 3 + echo 1 + dd if=/mnt/data/file-1G of=/dev/null bs=4096 262144+0 records in 262144+0 records out 1073741824 bytes (1.1 GB) copied, 21.9485 s, 48.9 MB/s + date +%s + TS=1569905541 + echo 256 + cat /proc/sys/vm/nr_hugepages 12 The success rate went down by factor of 20! Although hugetlb allocation requests might fail and it is reasonable to expect them to under extremely fragmented memory or when the memory is under a heavy pressure but the above situation is not that case. Fix the regression by reverting back to the previous behavior for __GFP_RETRY_MAYFAIL requests and disable the beail out heuristic for those requests. Mike said: : hugetlbfs allocations are commonly done via sysctl/sysfs shortly after : boot where this may not be as much of an issue. However, I am aware of at : least three use cases where allocations are made after the system has been : up and running for quite some time: : : - DB reconfiguration. If sysctl/sysfs fails to get required number of : huge pages, system is rebooted to perform allocation after boot. : : - VM provisioning. If unable get required number of huge pages, fall : back to base pages. : : - An application that does not preallocate pool, but rather allocates : pages at fault time for optimal NUMA locality. : : In all cases, I would expect b39d0ee2632d to cause regressions and : noticable behavior changes. : : My quick/limited testing in : https://lkml.kernel.org/r/3468b605-a3a9-6978-9699-57c52a90bd7e@oracle.com : was insufficient. It was also mentioned that if something like : b39d0ee2632d went forward, I would like exemptions for __GFP_RETRY_MAYFAIL : requests as in this patch. [mhocko@suse.com: reworded changelog] Link: http://lkml.kernel.org/r/20191007075548.12456-1-mhocko@kernel.org Fixes: b39d0ee2632d ("mm, page_alloc: avoid expensive reclaim when compaction may not succeed") Signed-off-by: David Rientjes Signed-off-by: Michal Hocko Reviewed-by: Mike Kravetz Acked-by: Vlastimil Babka Cc: Mel Gorman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_alloc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c0b2e0306720..ecc3dbad606b 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4473,12 +4473,14 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, if (page) goto got_pg; - if (order >= pageblock_order && (gfp_mask & __GFP_IO)) { + if (order >= pageblock_order && (gfp_mask & __GFP_IO) && + !(gfp_mask & __GFP_RETRY_MAYFAIL)) { /* * If allocating entire pageblock(s) and compaction * failed because all zones are below low watermarks * or is prohibited because it recently failed at this - * order, fail immediately. + * order, fail immediately unless the allocator has + * requested compaction and reclaim retry. * * Reclaim is * - potentially very expensive because zones are far -- GitLab From a2e9a5afce080226edbf1882d63d99bf32070e9e Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Mon, 14 Oct 2019 14:12:07 -0700 Subject: [PATCH 274/993] mm, compaction: fix wrong pfn handling in __reset_isolation_pfn() Florian and Dave reported [1] a NULL pointer dereference in __reset_isolation_pfn(). While the exact cause is unclear, staring at the code revealed two bugs, which might be related. One bug is that if zone starts in the middle of pageblock, block_page might correspond to different pfn than block_pfn, and then the pfn_valid_within() checks will check different pfn's than those accessed via struct page. This might result in acessing an unitialized page in CONFIG_HOLES_IN_ZONE configs. The other bug is that end_page refers to the first page of next pageblock and not last page of current pageblock. The online and valid check is then wrong and with sections, the while (page < end_page) loop might wander off actual struct page arrays. [1] https://lore.kernel.org/linux-xfs/87o8z1fvqu.fsf@mid.deneb.enyo.de/ Link: http://lkml.kernel.org/r/20191008152915.24704-1-vbabka@suse.cz Fixes: 6b0868c820ff ("mm/compaction.c: correct zone boundary handling when resetting pageblock skip hints") Signed-off-by: Vlastimil Babka Reported-by: Florian Weimer Reported-by: Dave Chinner Acked-by: Mel Gorman Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/compaction.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mm/compaction.c b/mm/compaction.c index ce08b39d85d4..672d3c78c6ab 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -270,14 +270,15 @@ __reset_isolation_pfn(struct zone *zone, unsigned long pfn, bool check_source, /* Ensure the start of the pageblock or zone is online and valid */ block_pfn = pageblock_start_pfn(pfn); - block_page = pfn_to_online_page(max(block_pfn, zone->zone_start_pfn)); + block_pfn = max(block_pfn, zone->zone_start_pfn); + block_page = pfn_to_online_page(block_pfn); if (block_page) { page = block_page; pfn = block_pfn; } /* Ensure the end of the pageblock or zone is online and valid */ - block_pfn += pageblock_nr_pages; + block_pfn = pageblock_end_pfn(pfn) - 1; block_pfn = min(block_pfn, zone_end_pfn(zone) - 1); end_page = pfn_to_online_page(block_pfn); if (!end_page) @@ -303,7 +304,7 @@ __reset_isolation_pfn(struct zone *zone, unsigned long pfn, bool check_source, page += (1 << PAGE_ALLOC_COSTLY_ORDER); pfn += (1 << PAGE_ALLOC_COSTLY_ORDER); - } while (page < end_page); + } while (page <= end_page); return false; } -- GitLab From c70d868f272befca09081190ae477c51fcbee5dd Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 14 Oct 2019 14:12:11 -0700 Subject: [PATCH 275/993] fs/direct-io.c: fix kernel-doc warning Fix kernel-doc warning in fs/direct-io.c: fs/direct-io.c:258: warning: Excess function parameter 'offset' description in 'dio_complete' Also, don't mark this function as having kernel-doc notation since it is not exported. Link: http://lkml.kernel.org/r/97908511-4328-4a56-17fe-f43a1d7aa470@infradead.org Fixes: 6d544bb4d901 ("dio: centralize completion in dio_complete()") Signed-off-by: Randy Dunlap Cc: Zach Brown Cc: Alexander Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/direct-io.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index ae196784f487..9329ced91f1d 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -241,9 +241,8 @@ void dio_warn_stale_pagecache(struct file *filp) } } -/** +/* * dio_complete() - called when all DIO BIO I/O has been completed - * @offset: the byte offset in the file of the completed operation * * This drops i_dio_count, lets interested parties know that a DIO operation * has completed, and calculates the resulting return code for the operation. -- GitLab From 8e88bfba77eec6231c6a72076c28bbb7634a0e8c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 14 Oct 2019 14:12:14 -0700 Subject: [PATCH 276/993] fs/libfs.c: fix kernel-doc warning Fix kernel-doc warning in fs/libfs.c: fs/libfs.c:496: warning: Excess function parameter 'available' description in 'simple_write_end' Link: http://lkml.kernel.org/r/5fc9d70b-e377-0ec9-066a-970d49579041@infradead.org Fixes: ad2a722f196d ("libfs: Open code simple_commit_write into only user") Signed-off-by: Randy Dunlap Cc: Boaz Harrosh Cc: Alexander Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/libfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/libfs.c b/fs/libfs.c index 540611b99b9a..1463b038ffc4 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -473,8 +473,7 @@ EXPORT_SYMBOL(simple_write_begin); /** * simple_write_end - .write_end helper for non-block-device FSes - * @available: See .write_end of address_space_operations - * @file: " + * @file: See .write_end of address_space_operations * @mapping: " * @pos: " * @len: " -- GitLab From b46ec1da5eb7d728938c8d115c4c291c7c71a98d Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 14 Oct 2019 14:12:17 -0700 Subject: [PATCH 277/993] fs/fs-writeback.c: fix kernel-doc warning Fix kernel-doc warning in fs/fs-writeback.c: fs/fs-writeback.c:913: warning: Excess function parameter 'nr_pages' description in 'cgroup_writeback_by_id' Link: http://lkml.kernel.org/r/756645ac-0ce8-d47e-d30a-04d9e4923a4f@infradead.org Fixes: d62241c7a406 ("writeback, memcg: Implement cgroup_writeback_by_id()") Signed-off-by: Randy Dunlap Cc: Tejun Heo Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fs-writeback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index e88421d9a48d..8461a6322039 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -905,7 +905,7 @@ static void bdi_split_work_to_wbs(struct backing_dev_info *bdi, * cgroup_writeback_by_id - initiate cgroup writeback from bdi and memcg IDs * @bdi_id: target bdi id * @memcg_id: target memcg css id - * @nr_pages: number of pages to write, 0 for best-effort dirty flushing + * @nr: number of pages to write, 0 for best-effort dirty flushing * @reason: reason why some writeback work initiated * @done: target wb_completion * -- GitLab From 2a7e582f429bd983816ad366cf0f1fcf87ec6ba6 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 14 Oct 2019 14:12:20 -0700 Subject: [PATCH 278/993] bitmap.h: fix kernel-doc warning and typo Fix kernel-doc warning in : include/linux/bitmap.h:341: warning: Function parameter or member 'nbits' not described in 'bitmap_or_equal' Also fix small typo (bitnaps). Link: http://lkml.kernel.org/r/0729ea7a-2c0d-b2c5-7dd3-3629ee0803e2@infradead.org Fixes: b9fa6442f704 ("cpumask: Implement cpumask_or_equal()") Signed-off-by: Randy Dunlap Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/bitmap.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index 90528f12bdfa..29fc933df3bf 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -326,10 +326,11 @@ static inline int bitmap_equal(const unsigned long *src1, } /** - * bitmap_or_equal - Check whether the or of two bitnaps is equal to a third + * bitmap_or_equal - Check whether the or of two bitmaps is equal to a third * @src1: Pointer to bitmap 1 * @src2: Pointer to bitmap 2 will be or'ed with bitmap 1 * @src3: Pointer to bitmap 3. Compare to the result of *@src1 | *@src2 + * @nbits: number of bits in each of these bitmaps * * Returns: True if (*@src1 | *@src2) == *@src3, false otherwise */ -- GitLab From 13bea898cd9153be91baa92de68ec32ff0b99362 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 14 Oct 2019 14:12:23 -0700 Subject: [PATCH 279/993] xarray.h: fix kernel-doc warning Fix (Sphinx) kernel-doc warning in : include/linux/xarray.h:232: WARNING: Unexpected indentation. Link: http://lkml.kernel.org/r/89ba2134-ce23-7c10-5ee1-ef83b35aa984@infradead.org Fixes: a3e4d3f97ec8 ("XArray: Redesign xa_alloc API") Signed-off-by: Randy Dunlap Cc: Matthew Wilcox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/xarray.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/xarray.h b/include/linux/xarray.h index 5921599b6dc4..86eecbd98e84 100644 --- a/include/linux/xarray.h +++ b/include/linux/xarray.h @@ -230,8 +230,8 @@ static inline int xa_err(void *entry) * This structure is used either directly or via the XA_LIMIT() macro * to communicate the range of IDs that are valid for allocation. * Two common ranges are predefined for you: - * * xa_limit_32b - [0 - UINT_MAX] - * * xa_limit_31b - [0 - INT_MAX] + * * xa_limit_32b - [0 - UINT_MAX] + * * xa_limit_31b - [0 - INT_MAX] */ struct xa_limit { u32 max; -- GitLab From 87bf4f71af4fb162033fbd98b4252ec11a715dbe Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 14 Oct 2019 14:12:26 -0700 Subject: [PATCH 280/993] mm/slab.c: fix kernel-doc warning for __ksize() Fix kernel-doc warning in mm/slab.c: mm/slab.c:4215: warning: Function parameter or member 'objp' not described in '__ksize' Also add Return: documentation section for this function. Link: http://lkml.kernel.org/r/68c9fd7d-f09e-d376-e292-c7b2bdf1774d@infradead.org Fixes: 10d1f8cb3965 ("mm/slab: refactor common ksize KASAN logic into slab_common.c") Signed-off-by: Randy Dunlap Acked-by: Marco Elver Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mm/slab.c b/mm/slab.c index 9df370558e5d..66e5d8032bae 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -4206,9 +4206,12 @@ void __check_heap_object(const void *ptr, unsigned long n, struct page *page, /** * __ksize -- Uninstrumented ksize. + * @objp: pointer to the object * * Unlike ksize(), __ksize() is uninstrumented, and does not provide the same * safety checks as ksize() with KASAN instrumentation enabled. + * + * Return: size of the actual memory used by @objp in bytes */ size_t __ksize(const void *objp) { -- GitLab From 3d7fed4ad8ccb691d217efbb0f934e6a4df5ef91 Mon Sep 17 00:00:00 2001 From: Jane Chu Date: Mon, 14 Oct 2019 14:12:29 -0700 Subject: [PATCH 281/993] mm/memory-failure: poison read receives SIGKILL instead of SIGBUS if mmaped more than once Mmap /dev/dax more than once, then read the poison location using address from one of the mappings. The other mappings due to not having the page mapped in will cause SIGKILLs delivered to the process. SIGKILL succeeds over SIGBUS, so user process loses the opportunity to handle the UE. Although one may add MAP_POPULATE to mmap(2) to work around the issue, MAP_POPULATE makes mapping 128GB of pmem several magnitudes slower, so isn't always an option. Details - ndctl inject-error --block=10 --count=1 namespace6.0 ./read_poison -x dax6.0 -o 5120 -m 2 mmaped address 0x7f5bb6600000 mmaped address 0x7f3cf3600000 doing local read at address 0x7f3cf3601400 Killed Console messages in instrumented kernel - mce: Uncorrected hardware memory error in user-access at edbe201400 Memory failure: tk->addr = 7f5bb6601000 Memory failure: address edbe201: call dev_pagemap_mapping_shift dev_pagemap_mapping_shift: page edbe201: no PUD Memory failure: tk->size_shift == 0 Memory failure: Unable to find user space address edbe201 in read_poison Memory failure: tk->addr = 7f3cf3601000 Memory failure: address edbe201: call dev_pagemap_mapping_shift Memory failure: tk->size_shift = 21 Memory failure: 0xedbe201: forcibly killing read_poison:22434 because of failure to unmap corrupted page => to deliver SIGKILL Memory failure: 0xedbe201: Killing read_poison:22434 due to hardware memory corruption => to deliver SIGBUS Link: http://lkml.kernel.org/r/1565112345-28754-3-git-send-email-jane.chu@oracle.com Signed-off-by: Jane Chu Suggested-by: Naoya Horiguchi Reviewed-by: Dan Williams Acked-by: Naoya Horiguchi Cc: Michal Hocko Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory-failure.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 7ef849da8278..0ae72b6acee7 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -199,7 +199,6 @@ struct to_kill { struct task_struct *tsk; unsigned long addr; short size_shift; - char addr_valid; }; /* @@ -324,22 +323,27 @@ static void add_to_kill(struct task_struct *tsk, struct page *p, } } tk->addr = page_address_in_vma(p, vma); - tk->addr_valid = 1; if (is_zone_device_page(p)) tk->size_shift = dev_pagemap_mapping_shift(p, vma); else tk->size_shift = compound_order(compound_head(p)) + PAGE_SHIFT; /* - * In theory we don't have to kill when the page was - * munmaped. But it could be also a mremap. Since that's - * likely very rare kill anyways just out of paranoia, but use - * a SIGKILL because the error is not contained anymore. + * Send SIGKILL if "tk->addr == -EFAULT". Also, as + * "tk->size_shift" is always non-zero for !is_zone_device_page(), + * so "tk->size_shift == 0" effectively checks no mapping on + * ZONE_DEVICE. Indeed, when a devdax page is mmapped N times + * to a process' address space, it's possible not all N VMAs + * contain mappings for the page, but at least one VMA does. + * Only deliver SIGBUS with payload derived from the VMA that + * has a mapping for the page. */ - if (tk->addr == -EFAULT || tk->size_shift == 0) { + if (tk->addr == -EFAULT) { pr_info("Memory failure: Unable to find user space address %lx in %s\n", page_to_pfn(p), tsk->comm); - tk->addr_valid = 0; + } else if (tk->size_shift == 0) { + kfree(tk); + return; } get_task_struct(tsk); tk->tsk = tsk; @@ -366,7 +370,7 @@ static void kill_procs(struct list_head *to_kill, int forcekill, bool fail, * make sure the process doesn't catch the * signal and then access the memory. Just kill it. */ - if (fail || tk->addr_valid == 0) { + if (fail || tk->addr == -EFAULT) { pr_err("Memory failure: %#lx: forcibly killing %s:%d because of failure to unmap corrupted page\n", pfn, tk->tsk->comm, tk->tsk->pid); do_send_sig_info(SIGKILL, SEND_SIG_PRIV, -- GitLab From 8b39da985194aac2998dd9e3a22d00b596cebf1e Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 14 Oct 2019 15:48:19 -0700 Subject: [PATCH 282/993] xtensa: drop EXPORT_SYMBOL for outs*/ins* Custom outs*/ins* implementations are long gone from the xtensa port, remove matching EXPORT_SYMBOLs. This fixes the following build warnings issued by modpost since commit 15bfc2348d54 ("modpost: check for static EXPORT_SYMBOL* functions"): WARNING: "insb" [vmlinux] is a static EXPORT_SYMBOL WARNING: "insw" [vmlinux] is a static EXPORT_SYMBOL WARNING: "insl" [vmlinux] is a static EXPORT_SYMBOL WARNING: "outsb" [vmlinux] is a static EXPORT_SYMBOL WARNING: "outsw" [vmlinux] is a static EXPORT_SYMBOL WARNING: "outsl" [vmlinux] is a static EXPORT_SYMBOL Cc: stable@vger.kernel.org Fixes: d38efc1f150f ("xtensa: adopt generic io routines") Signed-off-by: Max Filippov --- arch/xtensa/kernel/xtensa_ksyms.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 04f19de46700..4092555828b1 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c @@ -119,13 +119,6 @@ EXPORT_SYMBOL(__invalidate_icache_range); // FIXME EXPORT_SYMBOL(screen_info); #endif -EXPORT_SYMBOL(outsb); -EXPORT_SYMBOL(outsw); -EXPORT_SYMBOL(outsl); -EXPORT_SYMBOL(insb); -EXPORT_SYMBOL(insw); -EXPORT_SYMBOL(insl); - extern long common_exception_return; EXPORT_SYMBOL(common_exception_return); -- GitLab From 6658f87f219427ee776c498e07c878eb5cad1be2 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 9 Oct 2019 18:23:27 +0300 Subject: [PATCH 283/993] gpio: merrifield: Restore use of irq_base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During conversion to internal IRQ chip initialization the commit 8f86a5b4ad67 ("gpio: merrifield: Pass irqchip when adding gpiochip") lost the irq_base assignment. drivers/gpio/gpio-merrifield.c: In function ‘mrfld_gpio_probe’: drivers/gpio/gpio-merrifield.c:405:17: warning: variable ‘irq_base’ set but not used [-Wunused-but-set-variable] Assign the girq->first to it. Fixes: 8f86a5b4ad67 ("gpio: merrifield: Pass irqchip when adding gpiochip") Signed-off-by: Andy Shevchenko Signed-off-by: Linus Walleij --- drivers/gpio/gpio-merrifield.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpio/gpio-merrifield.c b/drivers/gpio/gpio-merrifield.c index 4f27ddfe1e2f..9596024c9161 100644 --- a/drivers/gpio/gpio-merrifield.c +++ b/drivers/gpio/gpio-merrifield.c @@ -455,6 +455,7 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id if (!girq->parents) return -ENOMEM; girq->parents[0] = pdev->irq; + girq->first = irq_base; girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_bad_irq; -- GitLab From 9411e3aaa6342eb730daa55cf3377463a37d2aa7 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 9 Oct 2019 17:34:44 +0300 Subject: [PATCH 284/993] gpiolib: Initialize the hardware with a callback After changing the drivers to use GPIO core to add an IRQ chip it appears that some of them requires a hardware initialization before adding the IRQ chip. Add an optional callback ->init_hw() to allow that drivers to initialize hardware if needed. This change is a part of the fix NULL pointer dereference brought to the several drivers recently. Cc: Hans de Goede Signed-off-by: Andy Shevchenko Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 22 +++++++++++++++++++++- include/linux/gpio/driver.h | 8 ++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 5833e4f380d6..104ed299d5ea 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -86,6 +86,7 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, struct lock_class_key *lock_key, struct lock_class_key *request_key); static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); +static int gpiochip_irqchip_init_hw(struct gpio_chip *gpiochip); static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip); static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip); @@ -1406,6 +1407,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, machine_gpiochip_add(chip); + ret = gpiochip_irqchip_init_hw(chip); + if (ret) + goto err_remove_acpi_chip; + ret = gpiochip_irqchip_init_valid_mask(chip); if (ret) goto err_remove_acpi_chip; @@ -1622,6 +1627,16 @@ static struct gpio_chip *find_chip_by_name(const char *name) * The following is irqchip helper code for gpiochips. */ +static int gpiochip_irqchip_init_hw(struct gpio_chip *gc) +{ + struct gpio_irq_chip *girq = &gc->irq; + + if (!girq->init_hw) + return 0; + + return girq->init_hw(gc); +} + static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gc) { struct gpio_irq_chip *girq = &gc->irq; @@ -2446,8 +2461,13 @@ static inline int gpiochip_add_irqchip(struct gpio_chip *gpiochip, { return 0; } - static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) {} + +static inline int gpiochip_irqchip_init_hw(struct gpio_chip *gpiochip) +{ + return 0; +} + static inline int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip) { return 0; diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index f8245d67f070..5dd9c982e2cb 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -201,6 +201,14 @@ struct gpio_irq_chip { */ bool threaded; + /** + * @init_hw: optional routine to initialize hardware before + * an IRQ chip will be added. This is quite useful when + * a particular driver wants to clear IRQ related registers + * in order to avoid undesired events. + */ + int (*init_hw)(struct gpio_chip *chip); + /** * @init_valid_mask: optional routine to initialize @valid_mask, to be * used if not all GPIO lines are valid interrupts. Sometimes some -- GitLab From a752fbb4b4644d09964e76c69ccd1acc700e907a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 9 Oct 2019 18:23:27 +0300 Subject: [PATCH 285/993] gpio: intel-mid: Move hardware initialization to callback The driver wants to initialize related registers before IRQ chip will be added. That's why move it to a corresponding callback. It also fixes the NULL pointer dereference. Fixes: 8069e69a9792 ("gpio: intel-mid: Pass irqchip when adding gpiochip") Signed-off-by: Andy Shevchenko Signed-off-by: Linus Walleij --- drivers/gpio/gpio-intel-mid.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-intel-mid.c b/drivers/gpio/gpio-intel-mid.c index 4d835f9089df..86a10c808ef6 100644 --- a/drivers/gpio/gpio-intel-mid.c +++ b/drivers/gpio/gpio-intel-mid.c @@ -293,8 +293,9 @@ static void intel_mid_irq_handler(struct irq_desc *desc) chip->irq_eoi(data); } -static void intel_mid_irq_init_hw(struct intel_mid_gpio *priv) +static int intel_mid_irq_init_hw(struct gpio_chip *chip) { + struct intel_mid_gpio *priv = gpiochip_get_data(chip); void __iomem *reg; unsigned base; @@ -309,6 +310,8 @@ static void intel_mid_irq_init_hw(struct intel_mid_gpio *priv) reg = gpio_reg(&priv->chip, base, GEDR); writel(~0, reg); } + + return 0; } static int __maybe_unused intel_gpio_runtime_idle(struct device *dev) @@ -372,6 +375,7 @@ static int intel_gpio_probe(struct pci_dev *pdev, girq = &priv->chip.irq; girq->chip = &intel_mid_irqchip; + girq->init_hw = intel_mid_irq_init_hw; girq->parent_handler = intel_mid_irq_handler; girq->num_parents = 1; girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents, @@ -384,9 +388,8 @@ static int intel_gpio_probe(struct pci_dev *pdev, girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_simple_irq; - intel_mid_irq_init_hw(priv); - pci_set_drvdata(pdev, priv); + retval = devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv); if (retval) { dev_err(&pdev->dev, "gpiochip_add error %d\n", retval); -- GitLab From a33912061607979380e070af63a9adeef0a16246 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 9 Oct 2019 18:58:45 +0300 Subject: [PATCH 286/993] gpio: lynxpoint: Move hardware initialization to callback The driver wants to initialize related registers before IRQ chip will be added. That's why move it to a corresponding callback. It also fixes the NULL pointer dereference. Fixes: 7b1e889436a1 ("gpio: lynxpoint: Pass irqchip when adding gpiochip") Signed-off-by: Andy Shevchenko Signed-off-by: Linus Walleij --- drivers/gpio/gpio-lynxpoint.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c index 6bb9741ad036..082cd143f430 100644 --- a/drivers/gpio/gpio-lynxpoint.c +++ b/drivers/gpio/gpio-lynxpoint.c @@ -294,8 +294,9 @@ static struct irq_chip lp_irqchip = { .flags = IRQCHIP_SKIP_SET_WAKE, }; -static void lp_gpio_irq_init_hw(struct lp_gpio *lg) +static int lp_gpio_irq_init_hw(struct gpio_chip *chip) { + struct lp_gpio *lg = gpiochip_get_data(chip); unsigned long reg; unsigned base; @@ -307,6 +308,8 @@ static void lp_gpio_irq_init_hw(struct lp_gpio *lg) reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT); outl(0xffffffff, reg); } + + return 0; } static int lp_gpio_probe(struct platform_device *pdev) @@ -364,6 +367,7 @@ static int lp_gpio_probe(struct platform_device *pdev) girq = &gc->irq; girq->chip = &lp_irqchip; + girq->init_hw = lp_gpio_irq_init_hw; girq->parent_handler = lp_gpio_irq_handler; girq->num_parents = 1; girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents, @@ -374,8 +378,6 @@ static int lp_gpio_probe(struct platform_device *pdev) girq->parents[0] = (unsigned)irq_rc->start; girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_simple_irq; - - lp_gpio_irq_init_hw(lg); } ret = devm_gpiochip_add_data(dev, gc, lg); -- GitLab From 4c87540940cbc7ddbe9674087919c605fd5c2ef1 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 9 Oct 2019 18:23:27 +0300 Subject: [PATCH 287/993] gpio: merrifield: Move hardware initialization to callback The driver wants to initialize related registers before IRQ chip will be added. That's why move it to a corresponding callback. It also fixes the NULL pointer dereference. Fixes: 8f86a5b4ad67 ("gpio: merrifield: Pass irqchip when adding gpiochip") Signed-off-by: Andy Shevchenko Signed-off-by: Linus Walleij --- drivers/gpio/gpio-merrifield.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-merrifield.c b/drivers/gpio/gpio-merrifield.c index 9596024c9161..2f1e9da81c1e 100644 --- a/drivers/gpio/gpio-merrifield.c +++ b/drivers/gpio/gpio-merrifield.c @@ -362,8 +362,9 @@ static void mrfld_irq_handler(struct irq_desc *desc) chained_irq_exit(irqchip, desc); } -static void mrfld_irq_init_hw(struct mrfld_gpio *priv) +static int mrfld_irq_init_hw(struct gpio_chip *chip) { + struct mrfld_gpio *priv = gpiochip_get_data(chip); void __iomem *reg; unsigned int base; @@ -375,6 +376,8 @@ static void mrfld_irq_init_hw(struct mrfld_gpio *priv) reg = gpio_reg(&priv->chip, base, GFER); writel(0, reg); } + + return 0; } static const char *mrfld_gpio_get_pinctrl_dev_name(struct mrfld_gpio *priv) @@ -447,6 +450,7 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id girq = &priv->chip.irq; girq->chip = &mrfld_irqchip; + girq->init_hw = mrfld_irq_init_hw; girq->parent_handler = mrfld_irq_handler; girq->num_parents = 1; girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents, @@ -459,8 +463,6 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_bad_irq; - mrfld_irq_init_hw(priv); - pci_set_drvdata(pdev, priv); retval = devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv); if (retval) { -- GitLab From 75e99bf5ed8fa74bc80d693d8e0a24eeaa38202b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 9 Oct 2019 18:59:11 +0300 Subject: [PATCH 288/993] gpio: lynxpoint: set default handler to be handle_bad_irq() We switch the default handler to be handle_bad_irq() instead of handle_simple_irq() (which was not correct anyway). Signed-off-by: Andy Shevchenko Signed-off-by: Linus Walleij --- drivers/gpio/gpio-lynxpoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c index 082cd143f430..e9e47c0d5be7 100644 --- a/drivers/gpio/gpio-lynxpoint.c +++ b/drivers/gpio/gpio-lynxpoint.c @@ -377,7 +377,7 @@ static int lp_gpio_probe(struct platform_device *pdev) return -ENOMEM; girq->parents[0] = (unsigned)irq_rc->start; girq->default_type = IRQ_TYPE_NONE; - girq->handler = handle_simple_irq; + girq->handler = handle_bad_irq; } ret = devm_gpiochip_add_data(dev, gc, lg); -- GitLab From 06b0d7fe7e5ff3ba4c7e265ef41135e8bcc232bb Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Fri, 11 Oct 2019 13:45:19 +0000 Subject: [PATCH 289/993] net: aquantia: temperature retrieval fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Chip temperature is a two byte word, colocated internally with cable length data. We do all readouts from HW memory by dwords, thus we should clear extra high bytes, otherwise temperature output gets weird as soon as we attach a cable to the NIC. Fixes: 8f8940118654 ("net: aquantia: add infrastructure to readout chip temperature") Tested-by: Holger Hoffstätte Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- .../net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c index da726489e3c8..7bc51f8d6f2f 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c @@ -337,7 +337,7 @@ static int aq_fw2x_get_phy_temp(struct aq_hw_s *self, int *temp) /* Convert PHY temperature from 1/256 degree Celsius * to 1/1000 degree Celsius. */ - *temp = temp_res * 1000 / 256; + *temp = (temp_res & 0xFFFF) * 1000 / 256; return 0; } -- GitLab From ed4d81c4b3f28ccf624f11fd66f67aec5b58859c Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Fri, 11 Oct 2019 13:45:20 +0000 Subject: [PATCH 290/993] net: aquantia: when cleaning hw cache it should be toggled >From HW specification to correctly reset HW caches (this is a required workaround when stopping the device), register bit should actually be toggled. It was previosly always just set. Due to the way driver stops HW this never actually caused any issues, but it still may, so cleaning this up. Fixes: 7a1bb49461b1 ("net: aquantia: fix potential IOMMU fault after driver unbind") Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- .../aquantia/atlantic/hw_atl/hw_atl_b0.c | 16 ++++++++++++++-- .../aquantia/atlantic/hw_atl/hw_atl_llh.c | 17 +++++++++++++++-- .../aquantia/atlantic/hw_atl/hw_atl_llh.h | 7 +++++-- .../atlantic/hw_atl/hw_atl_llh_internal.h | 19 +++++++++++++++++++ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c index 30f7fc4c97ff..3459fadb7ddd 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c @@ -968,14 +968,26 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self) static int hw_atl_b0_hw_stop(struct aq_hw_s *self) { + int err; + u32 val; + hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK); /* Invalidate Descriptor Cache to prevent writing to the cached * descriptors and to the data pointer of those descriptors */ - hw_atl_rdm_rx_dma_desc_cache_init_set(self, 1); + hw_atl_rdm_rx_dma_desc_cache_init_tgl(self); - return aq_hw_err_from_flags(self); + err = aq_hw_err_from_flags(self); + + if (err) + goto err_exit; + + readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get, + self, val, val == 1, 1000U, 10000U); + +err_exit: + return err; } static int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c index 1149812ae463..6f340695e6bd 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c @@ -606,12 +606,25 @@ void hw_atl_rpb_rx_flow_ctl_mode_set(struct aq_hw_s *aq_hw, u32 rx_flow_ctl_mode HW_ATL_RPB_RX_FC_MODE_SHIFT, rx_flow_ctl_mode); } -void hw_atl_rdm_rx_dma_desc_cache_init_set(struct aq_hw_s *aq_hw, u32 init) +void hw_atl_rdm_rx_dma_desc_cache_init_tgl(struct aq_hw_s *aq_hw) { + u32 val; + + val = aq_hw_read_reg_bit(aq_hw, HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR, + HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK, + HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT); + aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR, HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK, HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT, - init); + val ^ 1); +} + +u32 hw_atl_rdm_rx_dma_desc_cache_init_done_get(struct aq_hw_s *aq_hw) +{ + return aq_hw_read_reg_bit(aq_hw, RDM_RX_DMA_DESC_CACHE_INIT_DONE_ADR, + RDM_RX_DMA_DESC_CACHE_INIT_DONE_MSK, + RDM_RX_DMA_DESC_CACHE_INIT_DONE_SHIFT); } void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw, diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h index 0c37abbabca5..c3ee278c3747 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h @@ -313,8 +313,11 @@ void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw, u32 rx_pkt_buff_size_per_tc, u32 buffer); -/* set rdm rx dma descriptor cache init */ -void hw_atl_rdm_rx_dma_desc_cache_init_set(struct aq_hw_s *aq_hw, u32 init); +/* toggle rdm rx dma descriptor cache init */ +void hw_atl_rdm_rx_dma_desc_cache_init_tgl(struct aq_hw_s *aq_hw); + +/* get rdm rx dma descriptor cache init done */ +u32 hw_atl_rdm_rx_dma_desc_cache_init_done_get(struct aq_hw_s *aq_hw); /* set rx xoff enable (per tc) */ void hw_atl_rpb_rx_xoff_en_per_tc_set(struct aq_hw_s *aq_hw, u32 rx_xoff_en_per_tc, diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h index c3febcdfa92e..35887ad89025 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h @@ -318,6 +318,25 @@ /* default value of bitfield rdm_desc_init_i */ #define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_DEFAULT 0x0 +/* rdm_desc_init_done_i bitfield definitions + * preprocessor definitions for the bitfield rdm_desc_init_done_i. + * port="pif_rdm_desc_init_done_i" + */ + +/* register address for bitfield rdm_desc_init_done_i */ +#define RDM_RX_DMA_DESC_CACHE_INIT_DONE_ADR 0x00005a10 +/* bitmask for bitfield rdm_desc_init_done_i */ +#define RDM_RX_DMA_DESC_CACHE_INIT_DONE_MSK 0x00000001U +/* inverted bitmask for bitfield rdm_desc_init_done_i */ +#define RDM_RX_DMA_DESC_CACHE_INIT_DONE_MSKN 0xfffffffe +/* lower bit position of bitfield rdm_desc_init_done_i */ +#define RDM_RX_DMA_DESC_CACHE_INIT_DONE_SHIFT 0U +/* width of bitfield rdm_desc_init_done_i */ +#define RDM_RX_DMA_DESC_CACHE_INIT_DONE_WIDTH 1 +/* default value of bitfield rdm_desc_init_done_i */ +#define RDM_RX_DMA_DESC_CACHE_INIT_DONE_DEFAULT 0x0 + + /* rx int_desc_wrb_en bitfield definitions * preprocessor definitions for the bitfield "int_desc_wrb_en". * port="pif_rdm_int_desc_wrb_en_i" -- GitLab From d08b9a0a3ebdf71b0aabe576c7dd48e57e80e0f0 Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Fri, 11 Oct 2019 13:45:22 +0000 Subject: [PATCH 291/993] net: aquantia: do not pass lro session with invalid tcp checksum Individual descriptors on LRO TCP session should be checked for CRC errors. It was discovered that HW recalculates L4 checksums on LRO session and does not break it up on bad L4 csum. Thus, driver should aggregate HW LRO L4 statuses from all individual buffers of LRO session and drop packet if one of the buffers has bad L4 checksum. Fixes: f38f1ee8aeb2 ("net: aquantia: check rx csum for all packets in LRO session") Signed-off-by: Dmitry Bogdanov Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c index 3901d7994ca1..76bdbe1596d6 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -313,6 +313,7 @@ int aq_ring_rx_clean(struct aq_ring_s *self, break; buff->is_error |= buff_->is_error; + buff->is_cso_err |= buff_->is_cso_err; } while (!buff_->is_eop); @@ -320,7 +321,7 @@ int aq_ring_rx_clean(struct aq_ring_s *self, err = 0; goto err_exit; } - if (buff->is_error) { + if (buff->is_error || buff->is_cso_err) { buff_ = buff; do { next_ = buff_->next, -- GitLab From 9f051db566da1e8110659ab4ab188af1c2510bb4 Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Fri, 11 Oct 2019 13:45:23 +0000 Subject: [PATCH 292/993] net: aquantia: correctly handle macvlan and multicast coexistence macvlan and multicast handling is now mixed up. The explicit issue is that macvlan interface gets broken (no traffic) after clearing MULTICAST flag on the real interface. We now do separate logic and consider both ALLMULTI and MULTICAST flags on the device. Fixes: 11ba961c9161 ("net: aquantia: Fix IFF_ALLMULTI flag functionality") Signed-off-by: Dmitry Bogdanov Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- .../net/ethernet/aquantia/atlantic/aq_main.c | 4 +-- .../net/ethernet/aquantia/atlantic/aq_nic.c | 32 +++++++++---------- .../aquantia/atlantic/hw_atl/hw_atl_b0.c | 7 ++-- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c index b4a0fb281e69..bb65dd39f847 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c @@ -194,9 +194,7 @@ static void aq_ndev_set_multicast_settings(struct net_device *ndev) { struct aq_nic_s *aq_nic = netdev_priv(ndev); - aq_nic_set_packet_filter(aq_nic, ndev->flags); - - aq_nic_set_multicast_list(aq_nic, ndev); + (void)aq_nic_set_multicast_list(aq_nic, ndev); } static int aq_ndo_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index 8f66e7817811..2a18439b36fb 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -631,9 +631,12 @@ int aq_nic_set_packet_filter(struct aq_nic_s *self, unsigned int flags) int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev) { - unsigned int packet_filter = self->packet_filter; + const struct aq_hw_ops *hw_ops = self->aq_hw_ops; + struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg; + unsigned int packet_filter = ndev->flags; struct netdev_hw_addr *ha = NULL; unsigned int i = 0U; + int err = 0; self->mc_list.count = 0; if (netdev_uc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) { @@ -641,29 +644,26 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev) } else { netdev_for_each_uc_addr(ha, ndev) { ether_addr_copy(self->mc_list.ar[i++], ha->addr); - - if (i >= AQ_HW_MULTICAST_ADDRESS_MAX) - break; } } - if (i + netdev_mc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) { - packet_filter |= IFF_ALLMULTI; - } else { - netdev_for_each_mc_addr(ha, ndev) { - ether_addr_copy(self->mc_list.ar[i++], ha->addr); - - if (i >= AQ_HW_MULTICAST_ADDRESS_MAX) - break; + cfg->is_mc_list_enabled = !!(packet_filter & IFF_MULTICAST); + if (cfg->is_mc_list_enabled) { + if (i + netdev_mc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) { + packet_filter |= IFF_ALLMULTI; + } else { + netdev_for_each_mc_addr(ha, ndev) { + ether_addr_copy(self->mc_list.ar[i++], + ha->addr); + } } } if (i > 0 && i <= AQ_HW_MULTICAST_ADDRESS_MAX) { - packet_filter |= IFF_MULTICAST; self->mc_list.count = i; - self->aq_hw_ops->hw_multicast_list_set(self->aq_hw, - self->mc_list.ar, - self->mc_list.count); + err = hw_ops->hw_multicast_list_set(self->aq_hw, + self->mc_list.ar, + self->mc_list.count); } return aq_nic_set_packet_filter(self, packet_filter); } diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c index 3459fadb7ddd..2ad3fa6316ce 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c @@ -818,14 +818,15 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self, cfg->is_vlan_force_promisc); hw_atl_rpfl2multicast_flr_en_set(self, - IS_FILTER_ENABLED(IFF_ALLMULTI), 0); + IS_FILTER_ENABLED(IFF_ALLMULTI) && + IS_FILTER_ENABLED(IFF_MULTICAST), 0); hw_atl_rpfl2_accept_all_mc_packets_set(self, - IS_FILTER_ENABLED(IFF_ALLMULTI)); + IS_FILTER_ENABLED(IFF_ALLMULTI) && + IS_FILTER_ENABLED(IFF_MULTICAST)); hw_atl_rpfl2broadcast_en_set(self, IS_FILTER_ENABLED(IFF_BROADCAST)); - cfg->is_mc_list_enabled = IS_FILTER_ENABLED(IFF_MULTICAST); for (i = HW_ATL_B0_MAC_MIN; i < HW_ATL_B0_MAC_MAX; ++i) hw_atl_rpfl2_uc_flr_en_set(self, -- GitLab From ec52c7134b1fcef0edfc56d55072fd4f261ef198 Mon Sep 17 00:00:00 2001 From: Julien Grall Date: Mon, 14 Oct 2019 11:21:13 +0100 Subject: [PATCH 293/993] arm64: cpufeature: Treat ID_AA64ZFR0_EL1 as RAZ when SVE is not enabled If CONFIG_ARM64_SVE=n then we fail to report ID_AA64ZFR0_EL1 as 0 when read by userspace, despite being required by the architecture. Although this is theoretically a change in ABI, userspace will first check for the presence of SVE via the HWCAP or the ID_AA64PFR0_EL1.SVE field before probing the ID_AA64ZFR0_EL1 register. Given that these are reported correctly for this configuration, we can safely tighten up the current behaviour. Ensure ID_AA64ZFR0_EL1 is treated as RAZ when CONFIG_ARM64_SVE=n. Signed-off-by: Julien Grall Reviewed-by: Suzuki K Poulose Reviewed-by: Mark Rutland Reviewed-by: Dave Martin Fixes: 06a916feca2b ("arm64: Expose SVE2 features for userspace") Signed-off-by: Will Deacon --- arch/arm64/kernel/cpufeature.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index cabebf1a7976..80f459ad0190 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -176,11 +176,16 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = { }; static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = { - ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SM4_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SHA3_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_BITPERM_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_AES_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SVEVER_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE), + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SM4_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE), + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SHA3_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE), + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_BITPERM_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE), + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_AES_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE), + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SVEVER_SHIFT, 4, 0), ARM64_FTR_END, }; -- GitLab From 8c551f919a73c1dfa690a70a691be1da394145e8 Mon Sep 17 00:00:00 2001 From: Pavel Tatashin Date: Mon, 14 Oct 2019 10:48:24 -0400 Subject: [PATCH 294/993] arm64: hibernate: check pgd table allocation There is a bug in create_safe_exec_page(), when page table is allocated it is not checked that table is allocated successfully: But it is dereferenced in: pgd_none(READ_ONCE(*pgdp)). Check that allocation was successful. Fixes: 82869ac57b5d ("arm64: kernel: Add support for hibernate/suspend-to-disk") Reviewed-by: James Morse Signed-off-by: Pavel Tatashin Signed-off-by: Will Deacon --- arch/arm64/kernel/hibernate.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c index e0a7fce0e01c..a96b2921d22c 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c @@ -201,6 +201,7 @@ static int create_safe_exec_page(void *src_start, size_t length, gfp_t mask) { int rc = 0; + pgd_t *trans_pgd; pgd_t *pgdp; pud_t *pudp; pmd_t *pmdp; @@ -215,7 +216,13 @@ static int create_safe_exec_page(void *src_start, size_t length, memcpy((void *)dst, src_start, length); __flush_icache_range(dst, dst + length); - pgdp = pgd_offset_raw(allocator(mask), dst_addr); + trans_pgd = allocator(mask); + if (!trans_pgd) { + rc = -ENOMEM; + goto out; + } + + pgdp = pgd_offset_raw(trans_pgd, dst_addr); if (pgd_none(READ_ONCE(*pgdp))) { pudp = allocator(mask); if (!pudp) { -- GitLab From 12ade69c1eb9958b13374edf5ef742ea20ccffde Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 27 Sep 2019 13:53:43 +0200 Subject: [PATCH 295/993] KVM: PPC: Book3S HV: XIVE: Ensure VP isn't already in use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Connecting a vCPU to a XIVE KVM device means establishing a 1:1 association between a vCPU id and the offset (VP id) of a VP structure within a fixed size block of VPs. We currently try to enforce the 1:1 relationship by checking that a vCPU with the same id isn't already connected. This is good but unfortunately not enough because we don't map VP ids to raw vCPU ids but to packed vCPU ids, and the packing function kvmppc_pack_vcpu_id() isn't bijective by design. We got away with it because QEMU passes vCPU ids that fit well in the packing pattern. But nothing prevents userspace to come up with a forged vCPU id resulting in a packed id collision which causes the KVM device to associate two vCPUs to the same VP. This greatly confuses the irq layer and ultimately crashes the kernel, as shown below. Example: a guest with 1 guest thread per core, a core stride of 8 and 300 vCPUs has vCPU ids 0,8,16...2392. If QEMU is patched to inject at some point an invalid vCPU id 348, which is the packed version of itself and 2392, we get: genirq: Flags mismatch irq 199. 00010000 (kvm-2-2392) vs. 00010000 (kvm-2-348) CPU: 24 PID: 88176 Comm: qemu-system-ppc Not tainted 5.3.0-xive-nr-servers-5.3-gku+ #38 Call Trace: [c000003f7f9937e0] [c000000000c0110c] dump_stack+0xb0/0xf4 (unreliable) [c000003f7f993820] [c0000000001cb480] __setup_irq+0xa70/0xad0 [c000003f7f9938d0] [c0000000001cb75c] request_threaded_irq+0x13c/0x260 [c000003f7f993940] [c00800000d44e7ac] kvmppc_xive_attach_escalation+0x104/0x270 [kvm] [c000003f7f9939d0] [c00800000d45013c] kvmppc_xive_connect_vcpu+0x424/0x620 [kvm] [c000003f7f993ac0] [c00800000d444428] kvm_arch_vcpu_ioctl+0x260/0x448 [kvm] [c000003f7f993b90] [c00800000d43593c] kvm_vcpu_ioctl+0x154/0x7c8 [kvm] [c000003f7f993d00] [c0000000004840f0] do_vfs_ioctl+0xe0/0xc30 [c000003f7f993db0] [c000000000484d44] ksys_ioctl+0x104/0x120 [c000003f7f993e00] [c000000000484d88] sys_ioctl+0x28/0x80 [c000003f7f993e20] [c00000000000b278] system_call+0x5c/0x68 xive-kvm: Failed to request escalation interrupt for queue 0 of VCPU 2392 ------------[ cut here ]------------ remove_proc_entry: removing non-empty directory 'irq/199', leaking at least 'kvm-2-348' WARNING: CPU: 24 PID: 88176 at /home/greg/Work/linux/kernel-kvm-ppc/fs/proc/generic.c:684 remove_proc_entry+0x1ec/0x200 Modules linked in: kvm_hv kvm dm_mod vhost_net vhost tap xt_CHECKSUM iptable_mangle xt_MASQUERADE iptable_nat nf_nat xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ipt_REJECT nf_reject_ipv4 tun bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter squashfs loop fuse i2c_dev sg ofpart ocxl powernv_flash at24 xts mtd uio_pdrv_genirq vmx_crypto opal_prd ipmi_powernv uio ipmi_devintf ipmi_msghandler ibmpowernv ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi ip_tables ext4 mbcache jbd2 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor xor async_tx raid6_pq libcrc32c raid1 raid0 linear sd_mod ast i2c_algo_bit drm_vram_helper ttm drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm ahci libahci libata tg3 drm_panel_orientation_quirks [last unloaded: kvm] CPU: 24 PID: 88176 Comm: qemu-system-ppc Not tainted 5.3.0-xive-nr-servers-5.3-gku+ #38 NIP: c00000000053b0cc LR: c00000000053b0c8 CTR: c0000000000ba3b0 REGS: c000003f7f9934b0 TRAP: 0700 Not tainted (5.3.0-xive-nr-servers-5.3-gku+) MSR: 9000000000029033 CR: 48228222 XER: 20040000 CFAR: c000000000131a50 IRQMASK: 0 GPR00: c00000000053b0c8 c000003f7f993740 c0000000015ec500 0000000000000057 GPR04: 0000000000000001 0000000000000000 000049fb98484262 0000000000001bcf GPR08: 0000000000000007 0000000000000007 0000000000000001 9000000000001033 GPR12: 0000000000008000 c000003ffffeb800 0000000000000000 000000012f4ce5a1 GPR16: 000000012ef5a0c8 0000000000000000 000000012f113bb0 0000000000000000 GPR20: 000000012f45d918 c000003f863758b0 c000003f86375870 0000000000000006 GPR24: c000003f86375a30 0000000000000007 c0002039373d9020 c0000000014c4a48 GPR28: 0000000000000001 c000003fe62a4f6b c00020394b2e9fab c000003fe62a4ec0 NIP [c00000000053b0cc] remove_proc_entry+0x1ec/0x200 LR [c00000000053b0c8] remove_proc_entry+0x1e8/0x200 Call Trace: [c000003f7f993740] [c00000000053b0c8] remove_proc_entry+0x1e8/0x200 (unreliable) [c000003f7f9937e0] [c0000000001d3654] unregister_irq_proc+0x114/0x150 [c000003f7f993880] [c0000000001c6284] free_desc+0x54/0xb0 [c000003f7f9938c0] [c0000000001c65ec] irq_free_descs+0xac/0x100 [c000003f7f993910] [c0000000001d1ff8] irq_dispose_mapping+0x68/0x80 [c000003f7f993940] [c00800000d44e8a4] kvmppc_xive_attach_escalation+0x1fc/0x270 [kvm] [c000003f7f9939d0] [c00800000d45013c] kvmppc_xive_connect_vcpu+0x424/0x620 [kvm] [c000003f7f993ac0] [c00800000d444428] kvm_arch_vcpu_ioctl+0x260/0x448 [kvm] [c000003f7f993b90] [c00800000d43593c] kvm_vcpu_ioctl+0x154/0x7c8 [kvm] [c000003f7f993d00] [c0000000004840f0] do_vfs_ioctl+0xe0/0xc30 [c000003f7f993db0] [c000000000484d44] ksys_ioctl+0x104/0x120 [c000003f7f993e00] [c000000000484d88] sys_ioctl+0x28/0x80 [c000003f7f993e20] [c00000000000b278] system_call+0x5c/0x68 Instruction dump: 2c230000 41820008 3923ff78 e8e900a0 3c82ff69 3c62ff8d 7fa6eb78 7fc5f378 3884f080 3863b948 4bbf6925 60000000 <0fe00000> 4bffff7c fba10088 4bbf6e41 ---[ end trace b925b67a74a1d8d1 ]--- BUG: Kernel NULL pointer dereference at 0x00000010 Faulting instruction address: 0xc00800000d44fc04 Oops: Kernel access of bad area, sig: 11 [#1] LE PAGE_SIZE=64K MMU=Radix MMU=Hash SMP NR_CPUS=2048 NUMA PowerNV Modules linked in: kvm_hv kvm dm_mod vhost_net vhost tap xt_CHECKSUM iptable_mangle xt_MASQUERADE iptable_nat nf_nat xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ipt_REJECT nf_reject_ipv4 tun bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter squashfs loop fuse i2c_dev sg ofpart ocxl powernv_flash at24 xts mtd uio_pdrv_genirq vmx_crypto opal_prd ipmi_powernv uio ipmi_devintf ipmi_msghandler ibmpowernv ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi ip_tables ext4 mbcache jbd2 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor xor async_tx raid6_pq libcrc32c raid1 raid0 linear sd_mod ast i2c_algo_bit drm_vram_helper ttm drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm ahci libahci libata tg3 drm_panel_orientation_quirks [last unloaded: kvm] CPU: 24 PID: 88176 Comm: qemu-system-ppc Tainted: G W 5.3.0-xive-nr-servers-5.3-gku+ #38 NIP: c00800000d44fc04 LR: c00800000d44fc00 CTR: c0000000001cd970 REGS: c000003f7f9938e0 TRAP: 0300 Tainted: G W (5.3.0-xive-nr-servers-5.3-gku+) MSR: 9000000000009033 CR: 24228882 XER: 20040000 CFAR: c0000000001cd9ac DAR: 0000000000000010 DSISR: 40000000 IRQMASK: 0 GPR00: c00800000d44fc00 c000003f7f993b70 c00800000d468300 0000000000000000 GPR04: 00000000000000c7 0000000000000000 0000000000000000 c000003ffacd06d8 GPR08: 0000000000000000 c000003ffacd0738 0000000000000000 fffffffffffffffd GPR12: 0000000000000040 c000003ffffeb800 0000000000000000 000000012f4ce5a1 GPR16: 000000012ef5a0c8 0000000000000000 000000012f113bb0 0000000000000000 GPR20: 000000012f45d918 00007ffffe0d9a80 000000012f4f5df0 000000012ef8c9f8 GPR24: 0000000000000001 0000000000000000 c000003fe4501ed0 c000003f8b1d0000 GPR28: c0000033314689c0 c000003fe4501c00 c000003fe4501e70 c000003fe4501e90 NIP [c00800000d44fc04] kvmppc_xive_cleanup_vcpu+0xfc/0x210 [kvm] LR [c00800000d44fc00] kvmppc_xive_cleanup_vcpu+0xf8/0x210 [kvm] Call Trace: [c000003f7f993b70] [c00800000d44fc00] kvmppc_xive_cleanup_vcpu+0xf8/0x210 [kvm] (unreliable) [c000003f7f993bd0] [c00800000d450bd4] kvmppc_xive_release+0xdc/0x1b0 [kvm] [c000003f7f993c30] [c00800000d436a98] kvm_device_release+0xb0/0x110 [kvm] [c000003f7f993c70] [c00000000046730c] __fput+0xec/0x320 [c000003f7f993cd0] [c000000000164ae0] task_work_run+0x150/0x1c0 [c000003f7f993d30] [c000000000025034] do_notify_resume+0x304/0x440 [c000003f7f993e20] [c00000000000dcc4] ret_from_except_lite+0x70/0x74 Instruction dump: 3bff0008 7fbfd040 419e0054 847e0004 2fa30000 419effec e93d0000 8929203c 2f890000 419effb8 4800821d e8410018 e9490008 9b2a0039 7c0004ac ---[ end trace b925b67a74a1d8d2 ]--- Kernel panic - not syncing: Fatal exception This affects both XIVE and XICS-on-XIVE devices since the beginning. Check the VP id instead of the vCPU id when a new vCPU is connected. The allocation of the XIVE CPU structure in kvmppc_xive_connect_vcpu() is moved after the check to avoid the need for rollback. Cc: stable@vger.kernel.org # v4.12+ Signed-off-by: Greg Kurz Reviewed-by: Cédric Le Goater Signed-off-by: Paul Mackerras --- arch/powerpc/kvm/book3s_xive.c | 24 ++++++++++++++++-------- arch/powerpc/kvm/book3s_xive.h | 12 ++++++++++++ arch/powerpc/kvm/book3s_xive_native.c | 6 ++++-- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 591bfb4bfd0f..a3f9c665bb5b 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -1217,6 +1217,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev, struct kvmppc_xive *xive = dev->private; struct kvmppc_xive_vcpu *xc; int i, r = -EBUSY; + u32 vp_id; pr_devel("connect_vcpu(cpu=%d)\n", cpu); @@ -1228,25 +1229,32 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev, return -EPERM; if (vcpu->arch.irq_type != KVMPPC_IRQ_DEFAULT) return -EBUSY; - if (kvmppc_xive_find_server(vcpu->kvm, cpu)) { - pr_devel("Duplicate !\n"); - return -EEXIST; - } if (cpu >= (KVM_MAX_VCPUS * vcpu->kvm->arch.emul_smt_mode)) { pr_devel("Out of bounds !\n"); return -EINVAL; } - xc = kzalloc(sizeof(*xc), GFP_KERNEL); - if (!xc) - return -ENOMEM; /* We need to synchronize with queue provisioning */ mutex_lock(&xive->lock); + + vp_id = kvmppc_xive_vp(xive, cpu); + if (kvmppc_xive_vp_in_use(xive->kvm, vp_id)) { + pr_devel("Duplicate !\n"); + r = -EEXIST; + goto bail; + } + + xc = kzalloc(sizeof(*xc), GFP_KERNEL); + if (!xc) { + r = -ENOMEM; + goto bail; + } + vcpu->arch.xive_vcpu = xc; xc->xive = xive; xc->vcpu = vcpu; xc->server_num = cpu; - xc->vp_id = kvmppc_xive_vp(xive, cpu); + xc->vp_id = vp_id; xc->mfrr = 0xff; xc->valid = true; diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index 955b820ffd6d..fe3ed50e0818 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -220,6 +220,18 @@ static inline u32 kvmppc_xive_vp(struct kvmppc_xive *xive, u32 server) return xive->vp_base + kvmppc_pack_vcpu_id(xive->kvm, server); } +static inline bool kvmppc_xive_vp_in_use(struct kvm *kvm, u32 vp_id) +{ + struct kvm_vcpu *vcpu = NULL; + int i; + + kvm_for_each_vcpu(i, vcpu, kvm) { + if (vcpu->arch.xive_vcpu && vp_id == vcpu->arch.xive_vcpu->vp_id) + return true; + } + return false; +} + /* * Mapping between guest priorities and host priorities * is as follow. diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index 248c1ea9e788..78b906ffa0d2 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -106,6 +106,7 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, struct kvmppc_xive *xive = dev->private; struct kvmppc_xive_vcpu *xc = NULL; int rc; + u32 vp_id; pr_devel("native_connect_vcpu(server=%d)\n", server_num); @@ -124,7 +125,8 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, mutex_lock(&xive->lock); - if (kvmppc_xive_find_server(vcpu->kvm, server_num)) { + vp_id = kvmppc_xive_vp(xive, server_num); + if (kvmppc_xive_vp_in_use(xive->kvm, vp_id)) { pr_devel("Duplicate !\n"); rc = -EEXIST; goto bail; @@ -141,7 +143,7 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, xc->vcpu = vcpu; xc->server_num = server_num; - xc->vp_id = kvmppc_xive_vp(xive, server_num); + xc->vp_id = vp_id; xc->valid = true; vcpu->arch.irq_type = KVMPPC_IRQ_XIVE; -- GitLab From e211288b72f15259da86eed6eca680758dbe9e74 Mon Sep 17 00:00:00 2001 From: Roman Kagan Date: Thu, 10 Oct 2019 12:33:05 +0000 Subject: [PATCH 296/993] x86/hyperv: Make vapic support x2apic mode Now that there's Hyper-V IOMMU driver, Linux can switch to x2apic mode when supported by the vcpus. However, the apic access functions for Hyper-V enlightened apic assume xapic mode only. As a result, Linux fails to bring up secondary cpus when run as a guest in QEMU/KVM with both hv_apic and x2apic enabled. According to Michael Kelley, when in x2apic mode, the Hyper-V synthetic apic MSRs behave exactly the same as the corresponding architectural x2apic MSRs, so there's no need to override the apic accessors. The only exception is hv_apic_eoi_write, which benefits from lazy EOI when available; however, its implementation works for both xapic and x2apic modes. Fixes: 29217a474683 ("iommu/hyper-v: Add Hyper-V stub IOMMU driver") Fixes: 6b48cb5f8347 ("X86/Hyper-V: Enlighten APIC access") Suggested-by: Michael Kelley Signed-off-by: Roman Kagan Signed-off-by: Thomas Gleixner Reviewed-by: Vitaly Kuznetsov Reviewed-by: Michael Kelley Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20191010123258.16919-1-rkagan@virtuozzo.com --- arch/x86/hyperv/hv_apic.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c index 5c056b8aebef..e01078e93dd3 100644 --- a/arch/x86/hyperv/hv_apic.c +++ b/arch/x86/hyperv/hv_apic.c @@ -260,11 +260,21 @@ void __init hv_apic_init(void) } if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) { - pr_info("Hyper-V: Using MSR based APIC access\n"); + pr_info("Hyper-V: Using enlightened APIC (%s mode)", + x2apic_enabled() ? "x2apic" : "xapic"); + /* + * With x2apic, architectural x2apic MSRs are equivalent to the + * respective synthetic MSRs, so there's no need to override + * the apic accessors. The only exception is + * hv_apic_eoi_write, because it benefits from lazy EOI when + * available, but it works for both xapic and x2apic modes. + */ apic_set_eoi_write(hv_apic_eoi_write); - apic->read = hv_apic_read; - apic->write = hv_apic_write; - apic->icr_write = hv_apic_icr_write; - apic->icr_read = hv_apic_icr_read; + if (!x2apic_enabled()) { + apic->read = hv_apic_read; + apic->write = hv_apic_write; + apic->icr_write = hv_apic_icr_write; + apic->icr_read = hv_apic_icr_read; + } } } -- GitLab From 7a22e03b0c02988e91003c505b34d752a51de344 Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Tue, 1 Oct 2019 13:50:19 -0700 Subject: [PATCH 297/993] x86/apic/x2apic: Fix a NULL pointer deref when handling a dying cpu Check that the per-cpu cluster mask pointer has been set prior to clearing a dying cpu's bit. The per-cpu pointer is not set until the target cpu reaches smp_callin() during CPUHP_BRINGUP_CPU, whereas the teardown function, x2apic_dead_cpu(), is associated with the earlier CPUHP_X2APIC_PREPARE. If an error occurs before the cpu is awakened, e.g. if do_boot_cpu() itself fails, x2apic_dead_cpu() will dereference the NULL pointer and cause a panic. smpboot: do_boot_cpu failed(-22) to wakeup CPU#1 BUG: kernel NULL pointer dereference, address: 0000000000000008 RIP: 0010:x2apic_dead_cpu+0x1a/0x30 Call Trace: cpuhp_invoke_callback+0x9a/0x580 _cpu_up+0x10d/0x140 do_cpu_up+0x69/0xb0 smp_init+0x63/0xa9 kernel_init_freeable+0xd7/0x229 ? rest_init+0xa0/0xa0 kernel_init+0xa/0x100 ret_from_fork+0x35/0x40 Fixes: 023a611748fd5 ("x86/apic/x2apic: Simplify cluster management") Signed-off-by: Sean Christopherson Signed-off-by: Thomas Gleixner Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20191001205019.5789-1-sean.j.christopherson@intel.com --- arch/x86/kernel/apic/x2apic_cluster.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 45e92cba92f5..b0889c48a2ac 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -156,7 +156,8 @@ static int x2apic_dead_cpu(unsigned int dead_cpu) { struct cluster_mask *cmsk = per_cpu(cluster_masks, dead_cpu); - cpumask_clear_cpu(dead_cpu, &cmsk->mask); + if (cmsk) + cpumask_clear_cpu(dead_cpu, &cmsk->mask); free_cpumask_var(per_cpu(ipi_mask, dead_cpu)); return 0; } -- GitLab From 68fe2b520cee829ed518b4b1f64d2a557bcbffe1 Mon Sep 17 00:00:00 2001 From: Radhey Shyam Pandey Date: Thu, 26 Sep 2019 16:20:57 +0530 Subject: [PATCH 298/993] dmaengine: xilinx_dma: Fix 64-bit simple AXIDMA transfer In AXI DMA simple mode also pass MSB bits of source and destination address to xilinx_write function. It fixes simple AXI DMA operation mode using 64-bit addressing. Signed-off-by: Radhey Shyam Pandey Link: https://lore.kernel.org/r/1569495060-18117-2-git-send-email-radhey.shyam.pandey@xilinx.com Signed-off-by: Vinod Koul --- drivers/dma/xilinx/xilinx_dma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index e7dc3c4dc8e0..1fbe0258578b 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -1354,7 +1354,8 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) node); hw = &segment->hw; - xilinx_write(chan, XILINX_DMA_REG_SRCDSTADDR, hw->buf_addr); + xilinx_write(chan, XILINX_DMA_REG_SRCDSTADDR, + xilinx_prep_dma_addr_t(hw->buf_addr)); /* Start the transfer */ dma_ctrl_write(chan, XILINX_DMA_REG_BTT, -- GitLab From 6c6de1ddb1be3840f2ed5cc9d009a622720940c9 Mon Sep 17 00:00:00 2001 From: Radhey Shyam Pandey Date: Thu, 26 Sep 2019 16:20:58 +0530 Subject: [PATCH 299/993] dmaengine: xilinx_dma: Fix control reg update in vdma_channel_set_config In vdma_channel_set_config clear the delay, frame count and master mask before updating their new values. It avoids programming incorrect state when input parameters are different from default. Signed-off-by: Radhey Shyam Pandey Acked-by: Appana Durga Kedareswara rao Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/1569495060-18117-3-git-send-email-radhey.shyam.pandey@xilinx.com Signed-off-by: Vinod Koul --- drivers/dma/xilinx/xilinx_dma.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 1fbe0258578b..5d56f1e4d332 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -68,6 +68,9 @@ #define XILINX_DMA_DMACR_CIRC_EN BIT(1) #define XILINX_DMA_DMACR_RUNSTOP BIT(0) #define XILINX_DMA_DMACR_FSYNCSRC_MASK GENMASK(6, 5) +#define XILINX_DMA_DMACR_DELAY_MASK GENMASK(31, 24) +#define XILINX_DMA_DMACR_FRAME_COUNT_MASK GENMASK(23, 16) +#define XILINX_DMA_DMACR_MASTER_MASK GENMASK(11, 8) #define XILINX_DMA_REG_DMASR 0x0004 #define XILINX_DMA_DMASR_EOL_LATE_ERR BIT(15) @@ -2118,8 +2121,10 @@ int xilinx_vdma_channel_set_config(struct dma_chan *dchan, chan->config.gen_lock = cfg->gen_lock; chan->config.master = cfg->master; + dmacr &= ~XILINX_DMA_DMACR_GENLOCK_EN; if (cfg->gen_lock && chan->genlock) { dmacr |= XILINX_DMA_DMACR_GENLOCK_EN; + dmacr &= ~XILINX_DMA_DMACR_MASTER_MASK; dmacr |= cfg->master << XILINX_DMA_DMACR_MASTER_SHIFT; } @@ -2135,11 +2140,13 @@ int xilinx_vdma_channel_set_config(struct dma_chan *dchan, chan->config.delay = cfg->delay; if (cfg->coalesc <= XILINX_DMA_DMACR_FRAME_COUNT_MAX) { + dmacr &= ~XILINX_DMA_DMACR_FRAME_COUNT_MASK; dmacr |= cfg->coalesc << XILINX_DMA_DMACR_FRAME_COUNT_SHIFT; chan->config.coalesc = cfg->coalesc; } if (cfg->delay <= XILINX_DMA_DMACR_DELAY_MAX) { + dmacr &= ~XILINX_DMA_DMACR_DELAY_MASK; dmacr |= cfg->delay << XILINX_DMA_DMACR_DELAY_SHIFT; chan->config.delay = cfg->delay; } -- GitLab From ec1ac309596a7bdf206743b092748205f6cd5720 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Wed, 9 Oct 2019 17:11:30 +0800 Subject: [PATCH 300/993] dmaengine: sprd: Fix the possible memory leak issue If we terminate the channel to free all descriptors associated with this channel, we will leak the memory of current descriptor if the current descriptor is not completed, since it had been deteled from the desc_issued list and have not been added into the desc_completed list. Thus we should check if current descriptor is completed or not, when freeing the descriptors associated with one channel, if not, we should free it to avoid this issue. Fixes: 9b3b8171f7f4 ("dmaengine: sprd: Add Spreadtrum DMA driver") Reported-by: Zhenfang Wang Tested-by: Zhenfang Wang Signed-off-by: Baolin Wang Link: https://lore.kernel.org/r/170dbbc6d5366b6fa974ce2d366652e23a334251.1570609788.git.baolin.wang@linaro.org Signed-off-by: Vinod Koul --- drivers/dma/sprd-dma.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c index a4a91f233121..8546ad034720 100644 --- a/drivers/dma/sprd-dma.c +++ b/drivers/dma/sprd-dma.c @@ -212,6 +212,7 @@ struct sprd_dma_dev { struct sprd_dma_chn channels[0]; }; +static void sprd_dma_free_desc(struct virt_dma_desc *vd); static bool sprd_dma_filter_fn(struct dma_chan *chan, void *param); static struct of_dma_filter_info sprd_dma_info = { .filter_fn = sprd_dma_filter_fn, @@ -613,12 +614,19 @@ static int sprd_dma_alloc_chan_resources(struct dma_chan *chan) static void sprd_dma_free_chan_resources(struct dma_chan *chan) { struct sprd_dma_chn *schan = to_sprd_dma_chan(chan); + struct virt_dma_desc *cur_vd = NULL; unsigned long flags; spin_lock_irqsave(&schan->vc.lock, flags); + if (schan->cur_desc) + cur_vd = &schan->cur_desc->vd; + sprd_dma_stop(schan); spin_unlock_irqrestore(&schan->vc.lock, flags); + if (cur_vd) + sprd_dma_free_desc(cur_vd); + vchan_free_chan_resources(&schan->vc); pm_runtime_put(chan->device->dev); } @@ -1031,15 +1039,22 @@ static int sprd_dma_resume(struct dma_chan *chan) static int sprd_dma_terminate_all(struct dma_chan *chan) { struct sprd_dma_chn *schan = to_sprd_dma_chan(chan); + struct virt_dma_desc *cur_vd = NULL; unsigned long flags; LIST_HEAD(head); spin_lock_irqsave(&schan->vc.lock, flags); + if (schan->cur_desc) + cur_vd = &schan->cur_desc->vd; + sprd_dma_stop(schan); vchan_get_all_descriptors(&schan->vc, &head); spin_unlock_irqrestore(&schan->vc.lock, flags); + if (cur_vd) + sprd_dma_free_desc(cur_vd); + vchan_dma_desc_free_list(&schan->vc, &head); return 0; } -- GitLab From f9258156c73c2b2aa96731cd78bc23c4c4aac83d Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 25 Sep 2019 20:43:46 +0200 Subject: [PATCH 301/993] iommu/rockchip: Don't use platform_get_irq to implicitly count irqs Till now the Rockchip iommu driver walked through the irq list via platform_get_irq() until it encountered an ENXIO error. With the recent change to add a central error message, this always results in such an error for each iommu on probe and shutdown. To not confuse people, switch to platform_count_irqs() to get the actual number of interrupts before walking through them. Fixes: 7723f4c5ecdb ("driver core: platform: Add an error message to platform_get_irq*()") Signed-off-by: Heiko Stuebner Tested-by: Enric Balletbo i Serra Signed-off-by: Joerg Roedel --- drivers/iommu/rockchip-iommu.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 26290f310f90..4dcbf68dfda4 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -100,6 +100,7 @@ struct rk_iommu { struct device *dev; void __iomem **bases; int num_mmu; + int num_irq; struct clk_bulk_data *clocks; int num_clocks; bool reset_disabled; @@ -1136,7 +1137,7 @@ static int rk_iommu_probe(struct platform_device *pdev) struct rk_iommu *iommu; struct resource *res; int num_res = pdev->num_resources; - int err, i, irq; + int err, i; iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL); if (!iommu) @@ -1163,6 +1164,10 @@ static int rk_iommu_probe(struct platform_device *pdev) if (iommu->num_mmu == 0) return PTR_ERR(iommu->bases[0]); + iommu->num_irq = platform_irq_count(pdev); + if (iommu->num_irq < 0) + return iommu->num_irq; + iommu->reset_disabled = device_property_read_bool(dev, "rockchip,disable-mmu-reset"); @@ -1219,8 +1224,9 @@ static int rk_iommu_probe(struct platform_device *pdev) pm_runtime_enable(dev); - i = 0; - while ((irq = platform_get_irq(pdev, i++)) != -ENXIO) { + for (i = 0; i < iommu->num_irq; i++) { + int irq = platform_get_irq(pdev, i); + if (irq < 0) return irq; @@ -1245,10 +1251,13 @@ static int rk_iommu_probe(struct platform_device *pdev) static void rk_iommu_shutdown(struct platform_device *pdev) { struct rk_iommu *iommu = platform_get_drvdata(pdev); - int i = 0, irq; + int i; + + for (i = 0; i < iommu->num_irq; i++) { + int irq = platform_get_irq(pdev, i); - while ((irq = platform_get_irq(pdev, i++)) != -ENXIO) devm_free_irq(iommu->dev, irq, iommu); + } pm_runtime_force_suspend(&pdev->dev); } -- GitLab From ec37d4e999041ae8eb507d8d444a28b338670336 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 1 Oct 2019 20:06:22 +0200 Subject: [PATCH 302/993] iommu/ipmmu-vmsa: Only call platform_get_irq() when interrupt is mandatory As platform_get_irq() now prints an error when the interrupt does not exist, calling it gratuitously causes scary messages like: ipmmu-vmsa e6740000.mmu: IRQ index 0 not found Fix this by moving the call to platform_get_irq() down, where the existence of the interrupt is mandatory. Fixes: 7723f4c5ecdb8d83 ("driver core: platform: Add an error message to platform_get_irq*()") Signed-off-by: Geert Uytterhoeven Reviewed-by: Yoshihiro Shimoda Tested-by: Yoshihiro Shimoda Reviewed-by: Stephen Boyd Signed-off-by: Joerg Roedel --- drivers/iommu/ipmmu-vmsa.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 9da8309f7170..237103465b82 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -1086,8 +1086,6 @@ static int ipmmu_probe(struct platform_device *pdev) mmu->num_ctx = min(IPMMU_CTX_MAX, mmu->features->number_of_contexts); - irq = platform_get_irq(pdev, 0); - /* * Determine if this IPMMU instance is a root device by checking for * the lack of has_cache_leaf_nodes flag or renesas,ipmmu-main property. @@ -1106,6 +1104,7 @@ static int ipmmu_probe(struct platform_device *pdev) /* Root devices have mandatory IRQs */ if (ipmmu_is_root(mmu)) { + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "no IRQ found\n"); return irq; -- GitLab From ec21f17a9437e11bb29e5fa375aa31b472793c15 Mon Sep 17 00:00:00 2001 From: "Suthikulpanit, Suravee" Date: Mon, 14 Oct 2019 20:06:05 +0000 Subject: [PATCH 303/993] iommu/amd: Fix incorrect PASID decoding from event log IOMMU Event Log encodes 20-bit PASID for events: ILLEGAL_DEV_TABLE_ENTRY IO_PAGE_FAULT PAGE_TAB_HARDWARE_ERROR INVALID_DEVICE_REQUEST as: PASID[15:0] = bit 47:32 PASID[19:16] = bit 19:16 Note that INVALID_PPR_REQUEST event has different encoding from the rest of the events as the following: PASID[15:0] = bit 31:16 PASID[19:16] = bit 45:42 So, fixes the decoding logic. Fixes: d64c0486ed50 ("iommu/amd: Update the PASID information printed to the system log") Cc: Joerg Roedel Cc: Gary R Hook Signed-off-by: Suravee Suthikulpanit Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu.c | 5 +++-- drivers/iommu/amd_iommu_types.h | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 2369b8af81f3..bcd89ea50a8b 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -583,7 +583,8 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) retry: type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; devid = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK; - pasid = PPR_PASID(*(u64 *)&event[0]); + pasid = (event[0] & EVENT_DOMID_MASK_HI) | + (event[1] & EVENT_DOMID_MASK_LO); flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK; address = (u64)(((u64)event[3]) << 32) | event[2]; @@ -616,7 +617,7 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) address, flags); break; case EVENT_TYPE_PAGE_TAB_ERR: - dev_err(dev, "Event logged [PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x domain=0x%04x address=0x%llx flags=0x%04x]\n", + dev_err(dev, "Event logged [PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x pasid=0x%04x address=0x%llx flags=0x%04x]\n", PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), pasid, address, flags); break; diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index c9c1612d52e0..17bd5a349119 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -130,8 +130,8 @@ #define EVENT_TYPE_INV_PPR_REQ 0x9 #define EVENT_DEVID_MASK 0xffff #define EVENT_DEVID_SHIFT 0 -#define EVENT_DOMID_MASK 0xffff -#define EVENT_DOMID_SHIFT 0 +#define EVENT_DOMID_MASK_LO 0xffff +#define EVENT_DOMID_MASK_HI 0xf0000 #define EVENT_FLAGS_MASK 0xfff #define EVENT_FLAGS_SHIFT 0x10 -- GitLab From 80ed4548d0711d15ca51be5dee0ff813051cfc90 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Sat, 12 Oct 2019 18:42:10 +0200 Subject: [PATCH 304/993] btrfs: don't needlessly create extent-refs kernel thread The patch 32b593bfcb58 ("Btrfs: remove no longer used function to run delayed refs asynchronously") removed the async delayed refs but the thread has been created, without any use. Remove it to avoid resource consumption. Fixes: 32b593bfcb58 ("Btrfs: remove no longer used function to run delayed refs asynchronously") CC: stable@vger.kernel.org # 5.2+ Reviewed-by: Josef Bacik Signed-off-by: David Sterba --- fs/btrfs/ctree.h | 2 -- fs/btrfs/disk-io.c | 6 ------ 2 files changed, 8 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 19d669d12ca1..c1489c229694 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -734,8 +734,6 @@ struct btrfs_fs_info { struct btrfs_workqueue *fixup_workers; struct btrfs_workqueue *delayed_workers; - /* the extent workers do delayed refs on the extent allocation tree */ - struct btrfs_workqueue *extent_workers; struct task_struct *transaction_kthread; struct task_struct *cleaner_kthread; u32 thread_pool_size; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 044981cf6df9..402b61bf345c 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2008,7 +2008,6 @@ static void btrfs_stop_all_workers(struct btrfs_fs_info *fs_info) btrfs_destroy_workqueue(fs_info->readahead_workers); btrfs_destroy_workqueue(fs_info->flush_workers); btrfs_destroy_workqueue(fs_info->qgroup_rescan_workers); - btrfs_destroy_workqueue(fs_info->extent_workers); /* * Now that all other work queues are destroyed, we can safely destroy * the queues used for metadata I/O, since tasks from those other work @@ -2214,10 +2213,6 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info, max_active, 2); fs_info->qgroup_rescan_workers = btrfs_alloc_workqueue(fs_info, "qgroup-rescan", flags, 1, 0); - fs_info->extent_workers = - btrfs_alloc_workqueue(fs_info, "extent-refs", flags, - min_t(u64, fs_devices->num_devices, - max_active), 8); if (!(fs_info->workers && fs_info->delalloc_workers && fs_info->submit_workers && fs_info->flush_workers && @@ -2228,7 +2223,6 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info, fs_info->endio_freespace_worker && fs_info->rmw_workers && fs_info->caching_workers && fs_info->readahead_workers && fs_info->fixup_workers && fs_info->delayed_workers && - fs_info->extent_workers && fs_info->qgroup_rescan_workers)) { return -ENOMEM; } -- GitLab From 5812d04c4c7455627d8722e04ab99a737cfe9713 Mon Sep 17 00:00:00 2001 From: Max Gurtovoy Date: Sun, 13 Oct 2019 19:57:37 +0300 Subject: [PATCH 305/993] nvmet-loop: fix possible leakage during error flow During nvme_loop_queue_rq error flow, one must call nvme_cleanup_cmd since it's symmetric to nvme_setup_cmd. Signed-off-by: Max Gurtovoy Reviewed-by: Christoph Hellwig Signed-off-by: Keith Busch --- drivers/nvme/target/loop.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c index 748a39fca771..11f5aea97d1b 100644 --- a/drivers/nvme/target/loop.c +++ b/drivers/nvme/target/loop.c @@ -157,8 +157,10 @@ static blk_status_t nvme_loop_queue_rq(struct blk_mq_hw_ctx *hctx, iod->sg_table.sgl = iod->first_sgl; if (sg_alloc_table_chained(&iod->sg_table, blk_rq_nr_phys_segments(req), - iod->sg_table.sgl, SG_CHUNK_SIZE)) + iod->sg_table.sgl, SG_CHUNK_SIZE)) { + nvme_cleanup_cmd(req); return BLK_STS_RESOURCE; + } iod->req.sg = iod->sg_table.sgl; iod->req.sg_cnt = blk_rq_map_sg(req->q, req, iod->sg_table.sgl); -- GitLab From 28a4cac48c7e897a0b4e7d79a53a8e4fe40337ae Mon Sep 17 00:00:00 2001 From: Max Gurtovoy Date: Sun, 13 Oct 2019 19:57:38 +0300 Subject: [PATCH 306/993] nvme-tcp: fix possible leakage during error flow During nvme_tcp_setup_cmd_pdu error flow, one must call nvme_cleanup_cmd since it's symmetric to nvme_setup_cmd. Signed-off-by: Max Gurtovoy Reviewed-by: Christoph Hellwig Signed-off-by: Keith Busch --- drivers/nvme/host/tcp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 820dac10fa9e..770dbcbc999e 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -2136,6 +2136,7 @@ static blk_status_t nvme_tcp_setup_cmd_pdu(struct nvme_ns *ns, ret = nvme_tcp_map_data(queue, rq); if (unlikely(ret)) { + nvme_cleanup_cmd(rq); dev_err(queue->ctrl->ctrl.device, "Failed to map data (%d)\n", ret); return ret; -- GitLab From 3f22c7467136adfa6d2a7baf7cd5c573f0641bd1 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 15 Oct 2019 16:11:41 +0200 Subject: [PATCH 307/993] virtio-fs: don't show mount options Virtio-fs does not accept any mount options, so it's confusing and wrong to show any in /proc/mounts. Reported-by: Stefan Hajnoczi Signed-off-by: Miklos Szeredi --- fs/fuse/fuse_i.h | 4 ++++ fs/fuse/inode.c | 4 ++++ fs/fuse/virtio_fs.c | 1 + 3 files changed, 9 insertions(+) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 956aeaf961ae..d148188cfca4 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -479,6 +479,7 @@ struct fuse_fs_context { bool destroy:1; bool no_control:1; bool no_force_umount:1; + bool no_mount_options:1; unsigned int max_read; unsigned int blksize; const char *subtype; @@ -713,6 +714,9 @@ struct fuse_conn { /** Do not allow MNT_FORCE umount */ unsigned int no_force_umount:1; + /* Do not show mount options */ + unsigned int no_mount_options:1; + /** The number of requests waiting for completion */ atomic_t num_waiting; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index e040e2a2b621..16aec32f7f3d 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -558,6 +558,9 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root) struct super_block *sb = root->d_sb; struct fuse_conn *fc = get_fuse_conn_super(sb); + if (fc->no_mount_options) + return 0; + seq_printf(m, ",user_id=%u", from_kuid_munged(fc->user_ns, fc->user_id)); seq_printf(m, ",group_id=%u", from_kgid_munged(fc->user_ns, fc->group_id)); if (fc->default_permissions) @@ -1180,6 +1183,7 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx) fc->destroy = ctx->destroy; fc->no_control = ctx->no_control; fc->no_force_umount = ctx->no_force_umount; + fc->no_mount_options = ctx->no_mount_options; err = -ENOMEM; root = fuse_get_root_inode(sb, ctx->rootmode); diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index 6af3f131e468..e22a0c003c3d 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -992,6 +992,7 @@ static int virtio_fs_fill_super(struct super_block *sb) .destroy = true, .no_control = true, .no_force_umount = true, + .no_mount_options = true, }; mutex_lock(&virtio_fs_mutex); -- GitLab From 85f0ae7e435afb261af33f9a605b973c0c8c1139 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 21 Sep 2019 22:18:46 +0900 Subject: [PATCH 308/993] kbuild: update comment about KBUILD_ALLDIRS Commit 000ec95fbe75 ("kbuild: pkg: rename scripts/package/Makefile to scripts/Makefile.package") missed to update this comment. Fixes: 000ec95fbe75 ("kbuild: pkg: rename scripts/package/Makefile to scripts/Makefile.package") Signed-off-by: Masahiro Yamada --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ffd7a912fc46..19efe04b398c 100644 --- a/Makefile +++ b/Makefile @@ -1037,7 +1037,7 @@ export KBUILD_VMLINUX_OBJS := $(head-y) $(init-y) $(core-y) $(libs-y2) \ export KBUILD_VMLINUX_LIBS := $(libs-y1) export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds export LDFLAGS_vmlinux -# used by scripts/package/Makefile +# used by scripts/Makefile.package export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) LICENSES arch include scripts tools) vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) -- GitLab From 991b78fbd2231175293bd1d7c0768fb4e4382e14 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 5 Oct 2019 08:01:59 -0700 Subject: [PATCH 309/993] scripts: setlocalversion: fix a bashism Fix bashism reported by checkbashisms by using only one '=': possible bashism in scripts/setlocalversion line 96 (should be 'b = a'): if [ "`hg log -r . --template '{latesttagdistance}'`" == "1" ]; then Fixes: 38b3439d84f4 ("setlocalversion: update mercurial tag parsing") Signed-off-by: Randy Dunlap Cc: Mike Crowe Signed-off-by: Masahiro Yamada --- scripts/setlocalversion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/setlocalversion b/scripts/setlocalversion index 220dae0db3f1..a2998b118ef9 100755 --- a/scripts/setlocalversion +++ b/scripts/setlocalversion @@ -93,7 +93,7 @@ scm_version() # Check for mercurial and a mercurial repo. if test -d .hg && hgid=`hg id 2>/dev/null`; then # Do we have an tagged version? If so, latesttagdistance == 1 - if [ "`hg log -r . --template '{latesttagdistance}'`" == "1" ]; then + if [ "`hg log -r . --template '{latesttagdistance}'`" = "1" ]; then id=`hg log -r . --template '{latesttag}'` printf '%s%s' -hg "$id" else -- GitLab From 6a6fac11b11299aa5bd8532ea863fc2f652af2b6 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Tue, 8 Oct 2019 11:38:41 +0200 Subject: [PATCH 310/993] perf jvmti: Link against tools/lib/ctype.h to have weak strlcpy() The build of file libperf-jvmti.so succeeds but the resulting object fails to load: # ~/linux/tools/perf/perf record -k mono -- java \ -XX:+PreserveFramePointer \ -agentpath:/root/linux/tools/perf/libperf-jvmti.so \ hog 100000 123450 Error occurred during initialization of VM Could not find agent library /root/linux/tools/perf/libperf-jvmti.so in absolute path, with error: /root/linux/tools/perf/libperf-jvmti.so: undefined symbol: _ctype Add the missing _ctype symbol into the build script. Fixes: 79743bc927f6 ("perf jvmti: Link against tools/lib/string.o to have weak strlcpy()") Signed-off-by: Thomas Richter Cc: Heiko Carstens Cc: Vasily Gorbik Link: http://lore.kernel.org/lkml/20191008093841.59387-1-tmricht@linux.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/jvmti/Build | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/perf/jvmti/Build b/tools/perf/jvmti/Build index 1e148bbdf820..202cadaaf097 100644 --- a/tools/perf/jvmti/Build +++ b/tools/perf/jvmti/Build @@ -2,7 +2,7 @@ jvmti-y += libjvmti.o jvmti-y += jvmti_agent.o # For strlcpy -jvmti-y += libstring.o +jvmti-y += libstring.o libctype.o CFLAGS_jvmti = -fPIC -DPIC -I$(JDIR)/include -I$(JDIR)/include/linux CFLAGS_REMOVE_jvmti = -Wmissing-declarations @@ -15,3 +15,7 @@ CFLAGS_libstring.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PE $(OUTPUT)jvmti/libstring.o: ../lib/string.c FORCE $(call rule_mkdir) $(call if_changed_dep,cc_o_c) + +$(OUTPUT)jvmti/libctype.o: ../lib/ctype.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,cc_o_c) -- GitLab From 98a8b2e60c69927b1f405c3b001a1de3f4e53901 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 11 Oct 2019 11:21:40 -0700 Subject: [PATCH 311/993] perf evlist: Fix fix for freed id arrays In the earlier fix for the memory overrun of id arrays I managed to typo the wrong event in the fix. Of course we need to close the current event in the loop, not the original failing event. The same test case as in the original patch still passes. Fixes: 7834fa948beb ("perf evlist: Fix access of freed id arrays") Signed-off-by: Andi Kleen Cc: Jiri Olsa Link: http://lore.kernel.org/lkml/20191011182140.8353-2-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index d277a98e62df..de79c735e441 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1659,7 +1659,7 @@ struct evsel *perf_evlist__reset_weak_group(struct evlist *evsel_list, is_open = false; if (c2->leader == leader) { if (is_open) - perf_evsel__close(&evsel->core); + perf_evsel__close(&c2->core); c2->leader = c2; c2->core.nr_members = 0; } -- GitLab From 6080728ff8e9c9116e52e6f840152356ac2fea56 Mon Sep 17 00:00:00 2001 From: Yunfeng Ye Date: Tue, 15 Oct 2019 16:30:08 +0800 Subject: [PATCH 312/993] perf tools: Fix resource leak of closedir() on the error paths Both build_mem_topology() and rm_rf_depth_pat() have resource leaks of closedir() on the error paths. Fix this by calling closedir() before function returns. Fixes: e2091cedd51b ("perf tools: Add MEM_TOPOLOGY feature to perf data file") Fixes: cdb6b0235f17 ("perf tools: Add pattern name checking to rm_rf") Signed-off-by: Yunfeng Ye Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Alexey Budankov Cc: Andi Kleen Cc: Daniel Borkmann Cc: Feilong Lin Cc: Hu Shiyuan Cc: Igor Lubashev Cc: Kan Liang Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Song Liu Cc: Yonghong Song Link: http://lore.kernel.org/lkml/cd5f7cd2-b80d-6add-20a1-32f4f43e0744@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/header.c | 4 +++- tools/perf/util/util.c | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 86d9396cb131..becc2d109423 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1296,8 +1296,10 @@ static int build_mem_topology(struct memory_node *nodes, u64 size, u64 *cntp) continue; if (WARN_ONCE(cnt >= size, - "failed to write MEM_TOPOLOGY, way too many nodes\n")) + "failed to write MEM_TOPOLOGY, way too many nodes\n")) { + closedir(dir); return -1; + } ret = memory_node__read(&nodes[cnt++], idx); } diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 5eda6e19c947..ae56c766eda1 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -154,8 +154,10 @@ static int rm_rf_depth_pat(const char *path, int depth, const char **pat) if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) continue; - if (!match_pat(d->d_name, pat)) - return -2; + if (!match_pat(d->d_name, pat)) { + ret = -2; + break; + } scnprintf(namebuf, sizeof(namebuf), "%s/%s", path, d->d_name); -- GitLab From 5da0fb1ab34ccfe6d49210b4f5a739c59fcbf25e Mon Sep 17 00:00:00 2001 From: yangerkun Date: Tue, 15 Oct 2019 21:59:29 +0800 Subject: [PATCH 313/993] io_uring: consider the overflow of sequence for timeout req Now we recalculate the sequence of timeout with 'req->sequence = ctx->cached_sq_head + count - 1', judge the right place to insert for timeout_list by compare the number of request we still expected for completion. But we have not consider about the situation of overflow: 1. ctx->cached_sq_head + count - 1 may overflow. And a bigger count for the new timeout req can have a small req->sequence. 2. cached_sq_head of now may overflow compare with before req. And it will lead the timeout req with small req->sequence. This overflow will lead to the misorder of timeout_list, which can lead to the wrong order of the completion of timeout_list. Fix it by reuse req->submit.sequence to store the count, and change the logic of inserting sort in io_timeout. Signed-off-by: yangerkun Signed-off-by: Jens Axboe --- fs/io_uring.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 38d274fc0f25..d2cb277da2f4 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1884,7 +1884,7 @@ static enum hrtimer_restart io_timeout_fn(struct hrtimer *timer) static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe) { - unsigned count, req_dist, tail_index; + unsigned count; struct io_ring_ctx *ctx = req->ctx; struct list_head *entry; struct timespec64 ts; @@ -1907,21 +1907,36 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe) count = 1; req->sequence = ctx->cached_sq_head + count - 1; + /* reuse it to store the count */ + req->submit.sequence = count; req->flags |= REQ_F_TIMEOUT; /* * Insertion sort, ensuring the first entry in the list is always * the one we need first. */ - tail_index = ctx->cached_cq_tail - ctx->rings->sq_dropped; - req_dist = req->sequence - tail_index; spin_lock_irq(&ctx->completion_lock); list_for_each_prev(entry, &ctx->timeout_list) { struct io_kiocb *nxt = list_entry(entry, struct io_kiocb, list); - unsigned dist; + unsigned nxt_sq_head; + long long tmp, tmp_nxt; - dist = nxt->sequence - tail_index; - if (req_dist >= dist) + /* + * Since cached_sq_head + count - 1 can overflow, use type long + * long to store it. + */ + tmp = (long long)ctx->cached_sq_head + count - 1; + nxt_sq_head = nxt->sequence - nxt->submit.sequence + 1; + tmp_nxt = (long long)nxt_sq_head + nxt->submit.sequence - 1; + + /* + * cached_sq_head may overflow, and it will never overflow twice + * once there is some timeout req still be valid. + */ + if (ctx->cached_sq_head < nxt_sq_head) + tmp_nxt += UINT_MAX; + + if (tmp >= tmp_nxt) break; } list_add(&req->list, entry); -- GitLab From f948eb45e3af9fb18a0487d0797a773897ef6929 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 14 Oct 2019 12:10:47 -0500 Subject: [PATCH 314/993] perf annotate: Fix multiple memory and file descriptor leaks Store SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF in variable *ret*, instead of returning in the middle of the function and leaking multiple resources: prog_linfo, btf, s and bfdf. Addresses-Coverity-ID: 1454832 ("Structurally dead code") Fixes: 11aad897f6d1 ("perf annotate: Don't return -1 for error when doing BPF disassembly") Signed-off-by: Gustavo A. R. Silva Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20191014171047.GA30850@embeddedor Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 4036c7f7b0fb..e42bf572358c 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1758,7 +1758,7 @@ static int symbol__disassemble_bpf(struct symbol *sym, info_node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, dso->bpf_prog.id); if (!info_node) { - return SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF; + ret = SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF; goto out; } info_linear = info_node->info_linear; -- GitLab From 5a0baf5123236362fda4e9772cc63b7faa16a0df Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 7 Oct 2019 10:02:21 +0300 Subject: [PATCH 315/993] perf tools: Fix mode setting in copyfile_mode_ns() slow_copyfile() opens the file by name, so "write" permissions must not be removed in copyfile_mode_ns() before calling slow_copyfile(). Example: Before: $ sudo chmod +r /proc/kcore $ sudo setcap "cap_sys_admin,cap_sys_ptrace,cap_syslog,cap_sys_rawio=ep" tools/perf/perf $ tools/perf/perf buildid-cache -k /proc/kcore Couldn't add /proc/kcore After: $ sudo chmod +r /proc/kcore $ sudo setcap "cap_sys_admin,cap_sys_ptrace,cap_syslog,cap_sys_rawio=ep" tools/perf/perf $ tools/perf/perf buildid-cache -v -k /proc/kcore kcore added to build-id cache directory /home/ahunter/.debug/[kernel.kcore]/37e340b1b5a7cf4f57ba8de2bc777359588a957f/2019100709562289 Signed-off-by: Adrian Hunter Acked-by: Jiri Olsa Tested-by: Arnaldo Carvalho de Melo Link: http://lore.kernel.org/lkml/20191007070221.11158-1-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/copyfile.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/copyfile.c b/tools/perf/util/copyfile.c index 3fa0db136667..47e03de7c235 100644 --- a/tools/perf/util/copyfile.c +++ b/tools/perf/util/copyfile.c @@ -101,14 +101,16 @@ static int copyfile_mode_ns(const char *from, const char *to, mode_t mode, if (tofd < 0) goto out; - if (fchmod(tofd, mode)) - goto out_close_to; - if (st.st_size == 0) { /* /proc? do it slowly... */ err = slow_copyfile(from, tmp, nsi); + if (!err && fchmod(tofd, mode)) + err = -1; goto out_close_to; } + if (fchmod(tofd, mode)) + goto out_close_to; + nsinfo__mountns_enter(nsi, &nsc); fromfd = open(from, O_RDONLY); nsinfo__mountns_exit(&nsc); -- GitLab From ae199c580da1754a2b051321eeb76d6dacd8707b Mon Sep 17 00:00:00 2001 From: Yunfeng Ye Date: Tue, 15 Oct 2019 10:54:14 +0800 Subject: [PATCH 316/993] perf c2c: Fix memory leak in build_cl_output() There is a memory leak problem in the failure paths of build_cl_output(), so fix it. Signed-off-by: Yunfeng Ye Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Feilong Lin Cc: Hu Shiyuan Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/4d3c0178-5482-c313-98e1-f82090d2d456@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-c2c.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 3542b6ab9813..e69f44941aad 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -2635,6 +2635,7 @@ static int build_cl_output(char *cl_sort, bool no_source) bool add_sym = false; bool add_dso = false; bool add_src = false; + int ret = 0; if (!buf) return -ENOMEM; @@ -2653,7 +2654,8 @@ static int build_cl_output(char *cl_sort, bool no_source) add_dso = true; } else if (strcmp(tok, "offset")) { pr_err("unrecognized sort token: %s\n", tok); - return -EINVAL; + ret = -EINVAL; + goto err; } } @@ -2676,13 +2678,15 @@ static int build_cl_output(char *cl_sort, bool no_source) add_sym ? "symbol," : "", add_dso ? "dso," : "", add_src ? "cl_srcline," : "", - "node") < 0) - return -ENOMEM; + "node") < 0) { + ret = -ENOMEM; + goto err; + } c2c.show_src = add_src; - +err: free(buf); - return 0; + return ret; } static int setup_coalesce(const char *coalesce, bool no_source) -- GitLab From 7a12f514c408cc499e61211f234858d3d4b7f4ea Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 15 Oct 2019 12:22:37 -0300 Subject: [PATCH 317/993] tools headers kvm: Sync kvm headers with the kernel sources To pick the changes in: bf653b78f960 ("KVM: vmx: Introduce handle_unexpected_vmexit and handle WAITPKG vmexit") That trigger these changes in tooling: CC /tmp/build/perf/arch/x86/util/kvm-stat.o INSTALL GTK UI DESCEND plugins make[3]: Nothing to be done for '/tmp/build/perf/plugins/libtraceevent-dynamic-list'. INSTALL trace_plugins LD /tmp/build/perf/arch/x86/util/perf-in.o LD /tmp/build/perf/arch/x86/perf-in.o LD /tmp/build/perf/arch/perf-in.o LD /tmp/build/perf/perf-in.o LINK /tmp/build/perf/perf And this is not just because that header is included, kvm-stat.c uses the VMX_EXIT_REASONS define and it got changed by the above cset. And addresses this perf build warnings: Warning: Kernel ABI header at 'tools/arch/x86/include/uapi/asm/vmx.h' differs from latest version at 'arch/x86/include/uapi/asm/vmx.h' diff -u tools/arch/x86/include/uapi/asm/vmx.h arch/x86/include/uapi/asm/vmx.h Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paolo Bonzini Cc: Tao Xu Cc: Wang Nan Link: https://lkml.kernel.org/n/tip-gr1eel0hckmi5l3p2ewdpfxh@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/x86/include/uapi/asm/vmx.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/arch/x86/include/uapi/asm/vmx.h b/tools/arch/x86/include/uapi/asm/vmx.h index f01950aa7fae..3eb8411ab60e 100644 --- a/tools/arch/x86/include/uapi/asm/vmx.h +++ b/tools/arch/x86/include/uapi/asm/vmx.h @@ -86,6 +86,8 @@ #define EXIT_REASON_PML_FULL 62 #define EXIT_REASON_XSAVES 63 #define EXIT_REASON_XRSTORS 64 +#define EXIT_REASON_UMWAIT 67 +#define EXIT_REASON_TPAUSE 68 #define VMX_EXIT_REASONS \ { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \ @@ -144,7 +146,9 @@ { EXIT_REASON_RDSEED, "RDSEED" }, \ { EXIT_REASON_PML_FULL, "PML_FULL" }, \ { EXIT_REASON_XSAVES, "XSAVES" }, \ - { EXIT_REASON_XRSTORS, "XRSTORS" } + { EXIT_REASON_XRSTORS, "XRSTORS" }, \ + { EXIT_REASON_UMWAIT, "UMWAIT" }, \ + { EXIT_REASON_TPAUSE, "TPAUSE" } #define VMX_ABORT_SAVE_GUEST_MSR_FAIL 1 #define VMX_ABORT_LOAD_HOST_PDPTE_FAIL 2 -- GitLab From 7cb3a2445705e45af9b58dd241d26598a35b1fdd Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 15 Oct 2019 12:30:08 -0300 Subject: [PATCH 318/993] tools headers kvm: Sync kvm headers with the kernel sources To pick the changes in: 0cb8410b90e7 ("kvm: svm: Intercept RDPRU") That trigger a rebuild in too in tooling: CC /tmp/build/perf/arch/x86/util/kvm-stat.o But this time around no changes in tooling results, as SVM_EXIT_RDPRU wasn't added to SVM_EXIT_REASONS, that is used in kvm-stat.c. And addresses this perf build warnings: Warning: Kernel ABI header at 'tools/arch/x86/include/uapi/asm/svm.h' differs from latest version at 'arch/x86/include/uapi/asm/svm.h' diff -u tools/arch/x86/include/uapi/asm/svm.h arch/x86/include/uapi/asm/svm.h Cc: Adrian Hunter Cc: Jim Mattson Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paolo Bonzini Link: https://lkml.kernel.org/n/tip-pqzkt1hmfpqph3ts8i6zzmim@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/x86/include/uapi/asm/svm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/arch/x86/include/uapi/asm/svm.h b/tools/arch/x86/include/uapi/asm/svm.h index a9731f8a480f..2e8a30f06c74 100644 --- a/tools/arch/x86/include/uapi/asm/svm.h +++ b/tools/arch/x86/include/uapi/asm/svm.h @@ -75,6 +75,7 @@ #define SVM_EXIT_MWAIT 0x08b #define SVM_EXIT_MWAIT_COND 0x08c #define SVM_EXIT_XSETBV 0x08d +#define SVM_EXIT_RDPRU 0x08e #define SVM_EXIT_NPF 0x400 #define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401 #define SVM_EXIT_AVIC_UNACCELERATED_ACCESS 0x402 -- GitLab From 8daf1fb73295b43fb2f624f709449b484532ba64 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 15 Oct 2019 12:35:02 -0300 Subject: [PATCH 319/993] tools headers kvm: Sync kvm.h headers with the kernel sources To pick the changes in: 344c6c804703 ("KVM/Hyper-V: Add new KVM capability KVM_CAP_HYPERV_DIRECT_TLBFLUSH") dee04eee9182 ("KVM: RISC-V: Add KVM_REG_RISCV for ONE_REG interface") These trigger the rebuild of this object: CC /tmp/build/perf/trace/beauty/ioctl.o But do not result in any change in tooling, as the additions are not being used in any table generatator. This silences this perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/linux/kvm.h' differs from latest version at 'include/uapi/linux/kvm.h' diff -u tools/include/uapi/linux/kvm.h include/uapi/linux/kvm.h Cc: Adrian Hunter Cc: Anup Patel Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paolo Bonzini Cc: Paul Walmsley Cc: Tianyu Lan Link: https://lkml.kernel.org/n/tip-d1v48a0qfoe98u5v9tn3mu5u@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/kvm.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h index 233efbb1c81c..52641d8ca9e8 100644 --- a/tools/include/uapi/linux/kvm.h +++ b/tools/include/uapi/linux/kvm.h @@ -999,6 +999,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_ARM_PTRAUTH_GENERIC 172 #define KVM_CAP_PMU_EVENT_FILTER 173 #define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174 +#define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175 #ifdef KVM_CAP_IRQ_ROUTING @@ -1145,6 +1146,7 @@ struct kvm_dirty_tlb { #define KVM_REG_S390 0x5000000000000000ULL #define KVM_REG_ARM64 0x6000000000000000ULL #define KVM_REG_MIPS 0x7000000000000000ULL +#define KVM_REG_RISCV 0x8000000000000000ULL #define KVM_REG_SIZE_SHIFT 52 #define KVM_REG_SIZE_MASK 0x00f0000000000000ULL -- GitLab From 1d3f87233e26362fc3d4e59f0f31a71b570f90b9 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 26 Sep 2019 16:05:11 -0400 Subject: [PATCH 320/993] ceph: just skip unrecognized info in ceph_reply_info_extra In the future, we're going to want to extend the ceph_reply_info_extra for create replies. Currently though, the kernel code doesn't accept an extra blob that is larger than the expected data. Change the code to skip over any unrecognized fields at the end of the extra blob, rather than returning -EIO. Cc: stable@vger.kernel.org Signed-off-by: Jeff Layton Signed-off-by: Ilya Dryomov --- fs/ceph/mds_client.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index a8a8f84f3bbf..a5163296d9d9 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -384,8 +384,8 @@ static int parse_reply_info_readdir(void **p, void *end, } done: - if (*p != end) - goto bad; + /* Skip over any unrecognized fields */ + *p = end; return 0; bad: @@ -406,12 +406,10 @@ static int parse_reply_info_filelock(void **p, void *end, goto bad; info->filelock_reply = *p; - *p += sizeof(*info->filelock_reply); - if (unlikely(*p != end)) - goto bad; + /* Skip over any unrecognized fields */ + *p = end; return 0; - bad: return -EIO; } @@ -425,18 +423,21 @@ static int parse_reply_info_create(void **p, void *end, { if (features == (u64)-1 || (features & CEPH_FEATURE_REPLY_CREATE_INODE)) { + /* Malformed reply? */ if (*p == end) { info->has_create_ino = false; } else { info->has_create_ino = true; - info->ino = ceph_decode_64(p); + ceph_decode_64_safe(p, end, info->ino, bad); } + } else { + if (*p != end) + goto bad; } - if (unlikely(*p != end)) - goto bad; + /* Skip over any unrecognized fields */ + *p = end; return 0; - bad: return -EIO; } -- GitLab From 25e6be21230d3208d687dad90b6e43419013c351 Mon Sep 17 00:00:00 2001 From: Dongsheng Yang Date: Fri, 27 Sep 2019 15:33:22 +0000 Subject: [PATCH 321/993] rbd: cancel lock_dwork if the wait is interrupted There is a warning message in my test with below steps: # rbd bench --io-type write --io-size 4K --io-threads 1 --io-pattern rand test & # sleep 5 # pkill -9 rbd # rbd map test & # sleep 5 # pkill rbd The reason is that the rbd_add_acquire_lock() is interruptable, that means, when we kill the waiting on ->acquire_wait, the lock_dwork could be still running. 1. do_rbd_add() 2. lock_dwork rbd_add_acquire_lock() - queue_delayed_work() lock_dwork queued - wait_for_completion_killable_timeout() <-- kill happen rbd_dev_image_unlock() <-- UNLOCKED now, nothing to do. rbd_dev_device_release() rbd_dev_image_release() - ... lock successed here - cancel_delayed_work_sync(&rbd_dev->lock_dwork) Then when we reach the rbd_dev_free(), WARN_ON is triggered because lock_state is not RBD_LOCK_STATE_UNLOCKED. To fix it, this commit make sure the lock_dwork was finished before calling rbd_dev_image_unlock(). On the other hand, this would not happend in do_rbd_remove(), because after rbd mapped, lock_dwork will only be queued for IO request, and request will continue unless lock_dwork finished. when we call rbd_dev_image_unlock() in do_rbd_remove(), all requests are done. That means, lock_state should not be locked again after rbd_dev_image_unlock(). [ Cancel lock_dwork in rbd_add_acquire_lock(), only if the wait is interrupted. ] Fixes: 637cd060537d ("rbd: new exclusive lock wait/wake code") Signed-off-by: Dongsheng Yang Reviewed-by: Ilya Dryomov Signed-off-by: Ilya Dryomov --- drivers/block/rbd.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 7c4350c0fb77..39136675dae5 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -6639,10 +6639,13 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev) queue_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); ret = wait_for_completion_killable_timeout(&rbd_dev->acquire_wait, ceph_timeout_jiffies(rbd_dev->opts->lock_timeout)); - if (ret > 0) + if (ret > 0) { ret = rbd_dev->acquire_err; - else if (!ret) - ret = -ETIMEDOUT; + } else { + cancel_delayed_work_sync(&rbd_dev->lock_dwork); + if (!ret) + ret = -ETIMEDOUT; + } if (ret) { rbd_warn(rbd_dev, "failed to acquire exclusive lock: %ld", ret); -- GitLab From 5eca1379c0eb06e3908179665230a86d19bd2df7 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 15 Oct 2019 12:44:00 -0300 Subject: [PATCH 322/993] tools headers UAPI: Sync sched.h with the kernel To get the changes in: 78f6face5af3 ("sched: add kernel-doc for struct clone_args") f14c234b4bc5 ("clone3: switch to copy_struct_from_user()") This file gets rebuilt, but no changes ensues: CC /tmp/build/perf/trace/beauty/clone.o This addresses this perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/linux/sched.h' differs from latest version at 'include/uapi/linux/sched.h' diff -u tools/include/uapi/linux/sched.h include/uapi/linux/sched.h Cc: Adrian Hunter Cc: Aleksa Sarai Cc: Christian Brauner Cc: Jiri Olsa Cc: Namhyung Kim Link: https://lkml.kernel.org/n/tip-xqruu8wohwlbc57udg1g0xzx@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/sched.h | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/tools/include/uapi/linux/sched.h b/tools/include/uapi/linux/sched.h index b3105ac1381a..99335e1f4a27 100644 --- a/tools/include/uapi/linux/sched.h +++ b/tools/include/uapi/linux/sched.h @@ -33,8 +33,31 @@ #define CLONE_NEWNET 0x40000000 /* New network namespace */ #define CLONE_IO 0x80000000 /* Clone io context */ -/* - * Arguments for the clone3 syscall +#ifndef __ASSEMBLY__ +/** + * struct clone_args - arguments for the clone3 syscall + * @flags: Flags for the new process as listed above. + * All flags are valid except for CSIGNAL and + * CLONE_DETACHED. + * @pidfd: If CLONE_PIDFD is set, a pidfd will be + * returned in this argument. + * @child_tid: If CLONE_CHILD_SETTID is set, the TID of the + * child process will be returned in the child's + * memory. + * @parent_tid: If CLONE_PARENT_SETTID is set, the TID of + * the child process will be returned in the + * parent's memory. + * @exit_signal: The exit_signal the parent process will be + * sent when the child exits. + * @stack: Specify the location of the stack for the + * child process. + * @stack_size: The size of the stack for the child process. + * @tls: If CLONE_SETTLS is set, the tls descriptor + * is set to tls. + * + * The structure is versioned by size and thus extensible. + * New struct members must go at the end of the struct and + * must be properly 64bit aligned. */ struct clone_args { __aligned_u64 flags; @@ -46,6 +69,9 @@ struct clone_args { __aligned_u64 stack_size; __aligned_u64 tls; }; +#endif + +#define CLONE_ARGS_SIZE_VER0 64 /* sizeof first published struct */ /* * Scheduling policies -- GitLab From 5e0cd1ef64744e41e029dfca7d0ae285c486f386 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Tue, 15 Oct 2019 08:46:07 -0700 Subject: [PATCH 323/993] xfs: change the seconds fields in xfs_bulkstat to signed 64-bit time is a signed quantity in the kernel, so the bulkstat structure should reflect that. Note that the structure size stays the same and that we have not yet published userspace headers for this new ioctl so there are no users to break. Fixes: 7035f9724f84 ("xfs: introduce new v5 bulkstat structure") Signed-off-by: Darrick J. Wong Reviewed-by: Carlos Maiolino Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_fs.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index 39dd2b908106..e9371a8e0e26 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -366,11 +366,11 @@ struct xfs_bulkstat { uint64_t bs_blocks; /* number of blocks */ uint64_t bs_xflags; /* extended flags */ - uint64_t bs_atime; /* access time, seconds */ - uint64_t bs_mtime; /* modify time, seconds */ + int64_t bs_atime; /* access time, seconds */ + int64_t bs_mtime; /* modify time, seconds */ - uint64_t bs_ctime; /* inode change time, seconds */ - uint64_t bs_btime; /* creation time, seconds */ + int64_t bs_ctime; /* inode change time, seconds */ + int64_t bs_btime; /* creation time, seconds */ uint32_t bs_gen; /* generation count */ uint32_t bs_uid; /* user id */ -- GitLab From 9d179b865449b351ad5cb76dbea480c9170d4a27 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 15 Oct 2019 09:03:47 -0700 Subject: [PATCH 324/993] blkcg: Fix multiple bugs in blkcg_activate_policy() blkcg_activate_policy() has the following bugs. * cf09a8ee19ad ("blkcg: pass @q and @blkcg into blkcg_pol_alloc_pd_fn()") added @blkcg to ->pd_alloc_fn(); however, blkcg_activate_policy() ends up using pd's allocated for the root blkcg for all preallocations, so ->pd_init_fn() for non-root blkcgs can be passed in pd's which are allocated for the root blkcg. For blk-iocost, this means that ->pd_init_fn() can write beyond the end of the allocated object as it determines the length of the flex array at the end based on the blkcg's nesting level. * Each pd is initialized as they get allocated. If alloc fails, the policy will get freed with pd's initialized on it. * After the above partial failure, the partial pds are not freed. This patch fixes all the above issues by * Restructuring blkcg_activate_policy() so that alloc and init passes are separate. Init takes place only after all allocs succeeded and on failure all allocated pds are freed. * Unifying and fixing the cleanup of the remaining pd_prealloc. Signed-off-by: Tejun Heo Fixes: cf09a8ee19ad ("blkcg: pass @q and @blkcg into blkcg_pol_alloc_pd_fn()") Signed-off-by: Jens Axboe --- block/blk-cgroup.c | 69 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index b6f20be0fc78..5d21027b1faf 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -1362,7 +1362,7 @@ int blkcg_activate_policy(struct request_queue *q, const struct blkcg_policy *pol) { struct blkg_policy_data *pd_prealloc = NULL; - struct blkcg_gq *blkg; + struct blkcg_gq *blkg, *pinned_blkg = NULL; int ret; if (blkcg_policy_enabled(q, pol)) @@ -1370,49 +1370,82 @@ int blkcg_activate_policy(struct request_queue *q, if (queue_is_mq(q)) blk_mq_freeze_queue(q); -pd_prealloc: - if (!pd_prealloc) { - pd_prealloc = pol->pd_alloc_fn(GFP_KERNEL, q, &blkcg_root); - if (!pd_prealloc) { - ret = -ENOMEM; - goto out_bypass_end; - } - } - +retry: spin_lock_irq(&q->queue_lock); - /* blkg_list is pushed at the head, reverse walk to init parents first */ + /* blkg_list is pushed at the head, reverse walk to allocate parents first */ list_for_each_entry_reverse(blkg, &q->blkg_list, q_node) { struct blkg_policy_data *pd; if (blkg->pd[pol->plid]) continue; - pd = pol->pd_alloc_fn(GFP_NOWAIT | __GFP_NOWARN, q, &blkcg_root); - if (!pd) - swap(pd, pd_prealloc); + /* If prealloc matches, use it; otherwise try GFP_NOWAIT */ + if (blkg == pinned_blkg) { + pd = pd_prealloc; + pd_prealloc = NULL; + } else { + pd = pol->pd_alloc_fn(GFP_NOWAIT | __GFP_NOWARN, q, + blkg->blkcg); + } + if (!pd) { + /* + * GFP_NOWAIT failed. Free the existing one and + * prealloc for @blkg w/ GFP_KERNEL. + */ + if (pinned_blkg) + blkg_put(pinned_blkg); + blkg_get(blkg); + pinned_blkg = blkg; + spin_unlock_irq(&q->queue_lock); - goto pd_prealloc; + + if (pd_prealloc) + pol->pd_free_fn(pd_prealloc); + pd_prealloc = pol->pd_alloc_fn(GFP_KERNEL, q, + blkg->blkcg); + if (pd_prealloc) + goto retry; + else + goto enomem; } blkg->pd[pol->plid] = pd; pd->blkg = blkg; pd->plid = pol->plid; - if (pol->pd_init_fn) - pol->pd_init_fn(pd); } + /* all allocated, init in the same order */ + if (pol->pd_init_fn) + list_for_each_entry_reverse(blkg, &q->blkg_list, q_node) + pol->pd_init_fn(blkg->pd[pol->plid]); + __set_bit(pol->plid, q->blkcg_pols); ret = 0; spin_unlock_irq(&q->queue_lock); -out_bypass_end: +out: if (queue_is_mq(q)) blk_mq_unfreeze_queue(q); + if (pinned_blkg) + blkg_put(pinned_blkg); if (pd_prealloc) pol->pd_free_fn(pd_prealloc); return ret; + +enomem: + /* alloc failed, nothing's initialized yet, free everything */ + spin_lock_irq(&q->queue_lock); + list_for_each_entry(blkg, &q->blkg_list, q_node) { + if (blkg->pd[pol->plid]) { + pol->pd_free_fn(blkg->pd[pol->plid]); + blkg->pd[pol->plid] = NULL; + } + } + spin_unlock_irq(&q->queue_lock); + ret = -ENOMEM; + goto out; } EXPORT_SYMBOL_GPL(blkcg_activate_policy); -- GitLab From 307f4065b9d7c1e887e8bdfb2487e4638559fea1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 15 Oct 2019 08:49:27 -0700 Subject: [PATCH 325/993] blk-rq-qos: fix first node deletion of rq_qos_del() rq_qos_del() incorrectly assigns the node being deleted to the head if it was the first on the list in the !prev path. Fix it by iterating with ** instead. Signed-off-by: Tejun Heo Cc: Josef Bacik Fixes: a79050434b45 ("blk-rq-qos: refactor out common elements of blk-wbt") Cc: stable@vger.kernel.org # v4.19+ Signed-off-by: Jens Axboe --- block/blk-rq-qos.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h index e8cb68f6958a..2bc43e94f4c4 100644 --- a/block/blk-rq-qos.h +++ b/block/blk-rq-qos.h @@ -108,16 +108,13 @@ static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos) static inline void rq_qos_del(struct request_queue *q, struct rq_qos *rqos) { - struct rq_qos *cur, *prev = NULL; - for (cur = q->rq_qos; cur; cur = cur->next) { - if (cur == rqos) { - if (prev) - prev->next = rqos->next; - else - q->rq_qos = cur; + struct rq_qos **cur; + + for (cur = &q->rq_qos; *cur; cur = &(*cur)->next) { + if (*cur == rqos) { + *cur = rqos->next; break; } - prev = cur; } blk_mq_debugfs_unregister_rqos(rqos); -- GitLab From 5b3ec8134f5f9fa1ed0a538441a495521078bbee Mon Sep 17 00:00:00 2001 From: Steven Price Date: Wed, 9 Oct 2019 10:44:55 +0100 Subject: [PATCH 326/993] drm/panfrost: Handle resetting on timeout better Panfrost uses multiple schedulers (one for each slot, so 2 in reality), and on a timeout has to stop all the schedulers to safely perform a reset. However more than one scheduler can trigger a timeout at the same time. This race condition results in jobs being freed while they are still in use. When stopping other slots use cancel_delayed_work_sync() to ensure that any timeout started for that slot has completed. Also use mutex_trylock() to obtain reset_lock. This means that only one thread attempts the reset, the other threads will simply complete without doing anything (the first thread will wait for this in the call to cancel_delayed_work_sync()). While we're here and since the function is already dependent on sched_job not being NULL, let's remove the unnecessary checks. Fixes: aa20236784ab ("drm/panfrost: Prevent concurrent resets") Tested-by: Neil Armstrong Signed-off-by: Steven Price Cc: stable@vger.kernel.org Signed-off-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/20191009094456.9704-1-steven.price@arm.com --- drivers/gpu/drm/panfrost/panfrost_job.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c index a58551668d9a..21f34d44aac2 100644 --- a/drivers/gpu/drm/panfrost/panfrost_job.c +++ b/drivers/gpu/drm/panfrost/panfrost_job.c @@ -381,13 +381,19 @@ static void panfrost_job_timedout(struct drm_sched_job *sched_job) job_read(pfdev, JS_TAIL_LO(js)), sched_job); - mutex_lock(&pfdev->reset_lock); + if (!mutex_trylock(&pfdev->reset_lock)) + return; - for (i = 0; i < NUM_JOB_SLOTS; i++) - drm_sched_stop(&pfdev->js->queue[i].sched, sched_job); + for (i = 0; i < NUM_JOB_SLOTS; i++) { + struct drm_gpu_scheduler *sched = &pfdev->js->queue[i].sched; + + drm_sched_stop(sched, sched_job); + if (js != i) + /* Ensure any timeouts on other slots have finished */ + cancel_delayed_work_sync(&sched->work_tdr); + } - if (sched_job) - drm_sched_increase_karma(sched_job); + drm_sched_increase_karma(sched_job); spin_lock_irqsave(&pfdev->js->job_lock, flags); for (i = 0; i < NUM_JOB_SLOTS; i++) { -- GitLab From 8702ba9396bf7bbae2ab93c94acd4bd37cfa4f09 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Mon, 14 Oct 2019 14:34:51 +0800 Subject: [PATCH 327/993] btrfs: qgroup: Always free PREALLOC META reserve in btrfs_delalloc_release_extents() [Background] Btrfs qgroup uses two types of reserved space for METADATA space, PERTRANS and PREALLOC. PERTRANS is metadata space reserved for each transaction started by btrfs_start_transaction(). While PREALLOC is for delalloc, where we reserve space before joining a transaction, and finally it will be converted to PERTRANS after the writeback is done. [Inconsistency] However there is inconsistency in how we handle PREALLOC metadata space. The most obvious one is: In btrfs_buffered_write(): btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes, true); We always free qgroup PREALLOC meta space. While in btrfs_truncate_block(): btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize, (ret != 0)); We only free qgroup PREALLOC meta space when something went wrong. [The Correct Behavior] The correct behavior should be the one in btrfs_buffered_write(), we should always free PREALLOC metadata space. The reason is, the btrfs_delalloc_* mechanism works by: - Reserve metadata first, even it's not necessary In btrfs_delalloc_reserve_metadata() - Free the unused metadata space Normally in: btrfs_delalloc_release_extents() |- btrfs_inode_rsv_release() Here we do calculation on whether we should release or not. E.g. for 64K buffered write, the metadata rsv works like: /* The first page */ reserve_meta: num_bytes=calc_inode_reservations() free_meta: num_bytes=0 total: num_bytes=calc_inode_reservations() /* The first page caused one outstanding extent, thus needs metadata rsv */ /* The 2nd page */ reserve_meta: num_bytes=calc_inode_reservations() free_meta: num_bytes=calc_inode_reservations() total: not changed /* The 2nd page doesn't cause new outstanding extent, needs no new meta rsv, so we free what we have reserved */ /* The 3rd~16th pages */ reserve_meta: num_bytes=calc_inode_reservations() free_meta: num_bytes=calc_inode_reservations() total: not changed (still space for one outstanding extent) This means, if btrfs_delalloc_release_extents() determines to free some space, then those space should be freed NOW. So for qgroup, we should call btrfs_qgroup_free_meta_prealloc() other than btrfs_qgroup_convert_reserved_meta(). The good news is: - The callers are not that hot The hottest caller is in btrfs_buffered_write(), which is already fixed by commit 336a8bb8e36a ("btrfs: Fix wrong btrfs_delalloc_release_extents parameter"). Thus it's not that easy to cause false EDQUOT. - The trans commit in advance for qgroup would hide the bug Since commit f5fef4593653 ("btrfs: qgroup: Make qgroup async transaction commit more aggressive"), when btrfs qgroup metadata free space is slow, it will try to commit transaction and free the wrongly converted PERTRANS space, so it's not that easy to hit such bug. [FIX] So to fix the problem, remove the @qgroup_free parameter for btrfs_delalloc_release_extents(), and always pass true to btrfs_inode_rsv_release(). Reported-by: Filipe Manana Fixes: 43b18595d660 ("btrfs: qgroup: Use separate meta reservation type for delalloc") CC: stable@vger.kernel.org # 4.19+ Reviewed-by: Filipe Manana Signed-off-by: Qu Wenruo Signed-off-by: David Sterba --- fs/btrfs/ctree.h | 3 +-- fs/btrfs/delalloc-space.c | 6 ++---- fs/btrfs/file.c | 7 +++---- fs/btrfs/inode-map.c | 4 ++-- fs/btrfs/inode.c | 12 ++++++------ fs/btrfs/ioctl.c | 6 ++---- fs/btrfs/relocation.c | 9 ++++----- 7 files changed, 20 insertions(+), 27 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index c1489c229694..fe2b8765d9e6 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2487,8 +2487,7 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root, int nitems, bool use_global_rsv); void btrfs_subvolume_release_metadata(struct btrfs_fs_info *fs_info, struct btrfs_block_rsv *rsv); -void btrfs_delalloc_release_extents(struct btrfs_inode *inode, u64 num_bytes, - bool qgroup_free); +void btrfs_delalloc_release_extents(struct btrfs_inode *inode, u64 num_bytes); int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes); u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo); diff --git a/fs/btrfs/delalloc-space.c b/fs/btrfs/delalloc-space.c index d949d7d2abed..571e7b31ea2f 100644 --- a/fs/btrfs/delalloc-space.c +++ b/fs/btrfs/delalloc-space.c @@ -418,7 +418,6 @@ void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes, * btrfs_delalloc_release_extents - release our outstanding_extents * @inode: the inode to balance the reservation for. * @num_bytes: the number of bytes we originally reserved with - * @qgroup_free: do we need to free qgroup meta reservation or convert them. * * When we reserve space we increase outstanding_extents for the extents we may * add. Once we've set the range as delalloc or created our ordered extents we @@ -426,8 +425,7 @@ void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes, * temporarily tracked outstanding_extents. This _must_ be used in conjunction * with btrfs_delalloc_reserve_metadata. */ -void btrfs_delalloc_release_extents(struct btrfs_inode *inode, u64 num_bytes, - bool qgroup_free) +void btrfs_delalloc_release_extents(struct btrfs_inode *inode, u64 num_bytes) { struct btrfs_fs_info *fs_info = inode->root->fs_info; unsigned num_extents; @@ -441,7 +439,7 @@ void btrfs_delalloc_release_extents(struct btrfs_inode *inode, u64 num_bytes, if (btrfs_is_testing(fs_info)) return; - btrfs_inode_rsv_release(inode, qgroup_free); + btrfs_inode_rsv_release(inode, true); } /** diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 27e5b269e729..e955e7fa9201 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1692,7 +1692,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, force_page_uptodate); if (ret) { btrfs_delalloc_release_extents(BTRFS_I(inode), - reserve_bytes, true); + reserve_bytes); break; } @@ -1704,7 +1704,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, if (extents_locked == -EAGAIN) goto again; btrfs_delalloc_release_extents(BTRFS_I(inode), - reserve_bytes, true); + reserve_bytes); ret = extents_locked; break; } @@ -1772,8 +1772,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, else free_extent_state(cached_state); - btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes, - true); + btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes); if (ret) { btrfs_drop_pages(pages, num_pages); break; diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 63cad7865d75..37345fb6191d 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c @@ -501,13 +501,13 @@ int btrfs_save_ino_cache(struct btrfs_root *root, ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, prealloc, prealloc, prealloc, &alloc_hint); if (ret) { - btrfs_delalloc_release_extents(BTRFS_I(inode), prealloc, true); + btrfs_delalloc_release_extents(BTRFS_I(inode), prealloc); btrfs_delalloc_release_metadata(BTRFS_I(inode), prealloc, true); goto out_put; } ret = btrfs_write_out_ino_cache(root, trans, path, inode); - btrfs_delalloc_release_extents(BTRFS_I(inode), prealloc, false); + btrfs_delalloc_release_extents(BTRFS_I(inode), prealloc); out_put: iput(inode); out_release: diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 0f2754eaa05b..c3f386b7cc0b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2206,7 +2206,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) ClearPageChecked(page); set_page_dirty(page); - btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE, false); + btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE); out: unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end, &cached_state); @@ -4951,7 +4951,7 @@ int btrfs_truncate_block(struct inode *inode, loff_t from, loff_t len, if (!page) { btrfs_delalloc_release_space(inode, data_reserved, block_start, blocksize, true); - btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize, true); + btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize); ret = -ENOMEM; goto out; } @@ -5018,7 +5018,7 @@ int btrfs_truncate_block(struct inode *inode, loff_t from, loff_t len, if (ret) btrfs_delalloc_release_space(inode, data_reserved, block_start, blocksize, true); - btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize, (ret != 0)); + btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize); unlock_page(page); put_page(page); out: @@ -8709,7 +8709,7 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) } else if (ret >= 0 && (size_t)ret < count) btrfs_delalloc_release_space(inode, data_reserved, offset, count - (size_t)ret, true); - btrfs_delalloc_release_extents(BTRFS_I(inode), count, false); + btrfs_delalloc_release_extents(BTRFS_I(inode), count); } out: if (wakeup) @@ -9059,7 +9059,7 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf) unlock_extent_cached(io_tree, page_start, page_end, &cached_state); if (!ret2) { - btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE, true); + btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE); sb_end_pagefault(inode->i_sb); extent_changeset_free(data_reserved); return VM_FAULT_LOCKED; @@ -9068,7 +9068,7 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf) out_unlock: unlock_page(page); out: - btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE, (ret != 0)); + btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE); btrfs_delalloc_release_space(inode, data_reserved, page_start, reserved_space, (ret != 0)); out_noreserve: diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index de730e56d3f5..7c145a41decd 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1360,8 +1360,7 @@ static int cluster_pages_for_defrag(struct inode *inode, unlock_page(pages[i]); put_page(pages[i]); } - btrfs_delalloc_release_extents(BTRFS_I(inode), page_cnt << PAGE_SHIFT, - false); + btrfs_delalloc_release_extents(BTRFS_I(inode), page_cnt << PAGE_SHIFT); extent_changeset_free(data_reserved); return i_done; out: @@ -1372,8 +1371,7 @@ static int cluster_pages_for_defrag(struct inode *inode, btrfs_delalloc_release_space(inode, data_reserved, start_index << PAGE_SHIFT, page_cnt << PAGE_SHIFT, true); - btrfs_delalloc_release_extents(BTRFS_I(inode), page_cnt << PAGE_SHIFT, - true); + btrfs_delalloc_release_extents(BTRFS_I(inode), page_cnt << PAGE_SHIFT); extent_changeset_free(data_reserved); return ret; diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 7b883239fa7e..5cd42b66818c 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -3278,7 +3278,7 @@ static int relocate_file_extent_cluster(struct inode *inode, btrfs_delalloc_release_metadata(BTRFS_I(inode), PAGE_SIZE, true); btrfs_delalloc_release_extents(BTRFS_I(inode), - PAGE_SIZE, true); + PAGE_SIZE); ret = -ENOMEM; goto out; } @@ -3299,7 +3299,7 @@ static int relocate_file_extent_cluster(struct inode *inode, btrfs_delalloc_release_metadata(BTRFS_I(inode), PAGE_SIZE, true); btrfs_delalloc_release_extents(BTRFS_I(inode), - PAGE_SIZE, true); + PAGE_SIZE); ret = -EIO; goto out; } @@ -3328,7 +3328,7 @@ static int relocate_file_extent_cluster(struct inode *inode, btrfs_delalloc_release_metadata(BTRFS_I(inode), PAGE_SIZE, true); btrfs_delalloc_release_extents(BTRFS_I(inode), - PAGE_SIZE, true); + PAGE_SIZE); clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, @@ -3344,8 +3344,7 @@ static int relocate_file_extent_cluster(struct inode *inode, put_page(page); index++; - btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE, - false); + btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE); balance_dirty_pages_ratelimited(inode->i_mapping); btrfs_throttle(fs_info); } -- GitLab From 8e0d0ad206f08506c893326ca7c9c3d9cc042cef Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 15 Oct 2019 09:56:36 -0700 Subject: [PATCH 328/993] sparc64: disable fast-GUP due to unexplained oopses HAVE_FAST_GUP enables the lockless quick page table walker for simple cases, and is a nice optimization for some random loads that can then use get_user_pages_fast() rather than the more careful page walker. However, for some unexplained reason, it seems to be subtly broken on sparc64. The breakage is only with some compiler versions and some hardware, and nobody seems to have figured out what triggers it, although there's a simple reprodicer for the problem when it does trigger. The problem was introduced with the conversion to the generic GUP code in commit 7b9afb86b632 ("sparc64: use the generic get_user_pages_fast code"), but nothing looks obviously wrong in that conversion. It may be a compiler bug that just hits us with the code reorganization. Or it may be something very specific to sparc64. This disables HAVE_FAST_GUP entirely. That makes things like futexes a bit slower, but at least they work. If we can figure out the trigger, that would be lovely, but it's been three months already.. Link: https://lore.kernel.org/lkml/20190717215956.GA30369@altlinux.org/ Fixes: 7b9afb86b632 ("sparc64: use the generic get_user_pages_fast code") Reported-by: Dmitry V Levin Reported-by: Anatoly Pugachev Requested-by: Meelis Roos Suggested-by: Christoph Hellwig Cc: David Miller Signed-off-by: Linus Torvalds --- arch/sparc/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index fbc1aecf0f94..eb24cb1afc11 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -29,7 +29,6 @@ config SPARC select RTC_DRV_M48T59 select RTC_SYSTOHC select HAVE_ARCH_JUMP_LABEL if SPARC64 - select HAVE_FAST_GUP if SPARC64 select GENERIC_IRQ_SHOW select ARCH_WANT_IPC_PARSE_VERSION select GENERIC_PCI_IOMAP -- GitLab From 9786340acaa33b3722925125e2df358d14b8ee12 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Mon, 23 Sep 2019 20:21:22 +0200 Subject: [PATCH 329/993] ARM: dts: bcm2835-rpi-zero-w: Fix bus-width of sdhci The commit e7774049ff25 ("ARM: dts: bcm283x: Define MMC interfaces at board level") accidently dropped the bus width for the sdhci on the RPi Zero W, because the board file was relying on the defaults from bcm2835-rpi.dtsi. So fix this performance regression by adding the bus width to the board file. Fixes: e7774049ff25 ("ARM: dts: bcm283x: Define MMC interfaces at board level") Reported-by: Phil Elwell Signed-off-by: Stefan Wahren Signed-off-by: Florian Fainelli --- arch/arm/boot/dts/bcm2835-rpi-zero-w.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts index 09a088f98566..b75af21069f9 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts @@ -113,6 +113,7 @@ #address-cells = <1>; #size-cells = <0>; pinctrl-0 = <&emmc_gpio34 &gpclk2_gpio43>; + bus-width = <4>; mmc-pwrseq = <&wifi_pwrseq>; non-removable; status = "okay"; -- GitLab From b0818f80c8c1bc215bba276bd61c216014fab23b Mon Sep 17 00:00:00 2001 From: Mahesh Bandewar Date: Fri, 11 Oct 2019 18:14:55 -0700 Subject: [PATCH 330/993] blackhole_netdev: fix syzkaller reported issue While invalidating the dst, we assign backhole_netdev instead of loopback device. However, this device does not have idev pointer and hence no ip6_ptr even if IPv6 is enabled. Possibly this has triggered the syzbot reported crash. The syzbot report does not have reproducer, however, this is the only device that doesn't have matching idev created. Crash instruction is : static inline bool ip6_ignore_linkdown(const struct net_device *dev) { const struct inet6_dev *idev = __in6_dev_get(dev); return !!idev->cnf.ignore_routes_with_linkdown; <= crash } Also ipv6 always assumes presence of idev and never checks for it being NULL (as does the above referenced code). So adding a idev for the blackhole_netdev to avoid this class of crashes in the future. Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 7 ++++++- net/ipv6/route.c | 15 ++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 34ccef18b40e..4c87594d1389 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -6996,7 +6996,7 @@ static struct rtnl_af_ops inet6_ops __read_mostly = { int __init addrconf_init(void) { - struct inet6_dev *idev; + struct inet6_dev *idev, *bdev; int i, err; err = ipv6_addr_label_init(); @@ -7036,10 +7036,14 @@ int __init addrconf_init(void) */ rtnl_lock(); idev = ipv6_add_dev(init_net.loopback_dev); + bdev = ipv6_add_dev(blackhole_netdev); rtnl_unlock(); if (IS_ERR(idev)) { err = PTR_ERR(idev); goto errlo; + } else if (IS_ERR(bdev)) { + err = PTR_ERR(bdev); + goto errlo; } ip6_route_init_special_entries(); @@ -7124,6 +7128,7 @@ void addrconf_cleanup(void) addrconf_ifdown(dev, 1); } addrconf_ifdown(init_net.loopback_dev, 2); + addrconf_ifdown(blackhole_netdev, 2); /* * Check hash table. diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a63ff85fe141..742120728869 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -155,10 +155,9 @@ void rt6_uncached_list_del(struct rt6_info *rt) static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev) { - struct net_device *loopback_dev = net->loopback_dev; int cpu; - if (dev == loopback_dev) + if (dev == net->loopback_dev) return; for_each_possible_cpu(cpu) { @@ -171,7 +170,7 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev) struct net_device *rt_dev = rt->dst.dev; if (rt_idev->dev == dev) { - rt->rt6i_idev = in6_dev_get(loopback_dev); + rt->rt6i_idev = in6_dev_get(blackhole_netdev); in6_dev_put(rt_idev); } @@ -386,13 +385,11 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, { struct rt6_info *rt = (struct rt6_info *)dst; struct inet6_dev *idev = rt->rt6i_idev; - struct net_device *loopback_dev = - dev_net(dev)->loopback_dev; - if (idev && idev->dev != loopback_dev) { - struct inet6_dev *loopback_idev = in6_dev_get(loopback_dev); - if (loopback_idev) { - rt->rt6i_idev = loopback_idev; + if (idev && idev->dev != dev_net(dev)->loopback_dev) { + struct inet6_dev *ibdev = in6_dev_get(blackhole_netdev); + if (ibdev) { + rt->rt6i_idev = ibdev; in6_dev_put(idev); } } -- GitLab From 92696286f3bb37ba50e4bd8d1beb24afb759a799 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 11 Oct 2019 12:53:49 -0700 Subject: [PATCH 331/993] net: bcmgenet: Set phydev->dev_flags only for internal PHYs phydev->dev_flags is entirely dependent on the PHY device driver which is going to be used, setting the internal GENET PHY revision in those bits only makes sense when drivers/net/phy/bcm7xxx.c is the PHY driver being used. Fixes: 487320c54143 ("net: bcmgenet: communicate integrated PHY revision to PHY driver") Signed-off-by: Florian Fainelli Acked-by: Doug Berger Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmmii.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index 970e478a9017..94d1dd5d56bf 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -273,11 +273,12 @@ int bcmgenet_mii_probe(struct net_device *dev) struct bcmgenet_priv *priv = netdev_priv(dev); struct device_node *dn = priv->pdev->dev.of_node; struct phy_device *phydev; - u32 phy_flags; + u32 phy_flags = 0; int ret; /* Communicate the integrated PHY revision */ - phy_flags = priv->gphy_rev; + if (priv->internal_phy) + phy_flags = priv->gphy_rev; /* Initialize link state variables that bcmgenet_mii_setup() uses */ priv->old_link = -1; -- GitLab From f913eac8e555bc776565a21ce84bf2bcc3715cbb Mon Sep 17 00:00:00 2001 From: David Ahern Date: Fri, 11 Oct 2019 20:43:03 -0600 Subject: [PATCH 332/993] net: Update address for vrf and l3mdev in MAINTAINERS Use my kernel.org address for all entries in MAINTAINERS. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 55199ef7fa74..49e4b004917b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9126,7 +9126,7 @@ F: drivers/auxdisplay/ks0108.c F: include/linux/ks0108.h L3MDEV -M: David Ahern +M: David Ahern L: netdev@vger.kernel.org S: Maintained F: net/l3mdev @@ -17439,7 +17439,7 @@ F: include/linux/regulator/ K: regulator_get_optional VRF -M: David Ahern +M: David Ahern M: Shrijeet Mukherjee L: netdev@vger.kernel.org S: Maintained -- GitLab From ddc790e92b3afa4e366ffb41818cfcd19015031e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 11 Oct 2019 21:03:33 -0700 Subject: [PATCH 333/993] net: ethernet: broadcom: have drivers select DIMLIB as needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NET_VENDOR_BROADCOM is intended to control a kconfig menu only. It should not have anything to do with code generation. As such, it should not select DIMLIB for all drivers under NET_VENDOR_BROADCOM. Instead each driver that needs DIMLIB should select it (being the symbols SYSTEMPORT, BNXT, and BCMGENET). Link: https://lkml.kernel.org/r/alpine.DEB.2.21.1907021810220.13058@ramsan.of.borg/ Fixes: 4f75da3666c0 ("linux/dim: Move implementation to .c files") Reported-by: Geert Uytterhoeven Signed-off-by: Randy Dunlap Cc: Uwe Kleine-König Cc: Tal Gilboa Cc: Saeed Mahameed Cc: netdev@vger.kernel.org Cc: linux-rdma@vger.kernel.org Cc: "David S. Miller" Cc: Jakub Kicinski Cc: Doug Ledford Cc: Jason Gunthorpe Cc: Leon Romanovsky Cc: Or Gerlitz Cc: Sagi Grimberg Acked-by: Florian Fainelli Reviewed-by: Leon Romanovsky Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig index e24f5d2b6afe..53055ce5dfd6 100644 --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig @@ -8,7 +8,6 @@ config NET_VENDOR_BROADCOM default y depends on (SSB_POSSIBLE && HAS_DMA) || PCI || BCM63XX || \ SIBYTE_SB1xxx_SOC - select DIMLIB ---help--- If you have a network (Ethernet) chipset belonging to this class, say Y. @@ -69,6 +68,7 @@ config BCMGENET select FIXED_PHY select BCM7XXX_PHY select MDIO_BCM_UNIMAC + select DIMLIB help This driver supports the built-in Ethernet MACs found in the Broadcom BCM7xxx Set Top Box family chipset. @@ -188,6 +188,7 @@ config SYSTEMPORT select MII select PHYLIB select FIXED_PHY + select DIMLIB help This driver supports the built-in Ethernet MACs found in the Broadcom BCM7xxx Set Top Box family chipset using an internal @@ -200,6 +201,7 @@ config BNXT select LIBCRC32C select NET_DEVLINK select PAGE_POOL + select DIMLIB ---help--- This driver supports Broadcom NetXtreme-C/E 10/25/40/50 gigabit Ethernet cards. To compile this driver as a module, choose M here: -- GitLab From b14a39048c1156cfee76228bf449852da2f14df8 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 10 Oct 2019 14:58:34 +0200 Subject: [PATCH 334/993] USB: ldusb: fix memleak on disconnect If disconnect() races with release() after a process has been interrupted, release() could end up returning early and the driver would fail to free its driver data. Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") Cc: stable # 2.6.13 Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20191010125835.27031-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ldusb.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index f3108d85e768..147c90c2a4e5 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -380,10 +380,7 @@ static int ld_usb_release(struct inode *inode, struct file *file) goto exit; } - if (mutex_lock_interruptible(&dev->mutex)) { - retval = -ERESTARTSYS; - goto exit; - } + mutex_lock(&dev->mutex); if (dev->open_count != 1) { retval = -ENODEV; -- GitLab From b6c03e5f7b463efcafd1ce141bd5a8fc4e583ae2 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 10 Oct 2019 14:58:35 +0200 Subject: [PATCH 335/993] USB: legousbtower: fix memleak on disconnect If disconnect() races with release() after a process has been interrupted, release() could end up returning early and the driver would fail to free its driver data. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20191010125835.27031-3-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/legousbtower.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 9d4c52a7ebe0..62dab2441ec4 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -419,10 +419,7 @@ static int tower_release (struct inode *inode, struct file *file) goto exit; } - if (mutex_lock_interruptible(&dev->lock)) { - retval = -ERESTARTSYS; - goto exit; - } + mutex_lock(&dev->lock); if (dev->open_count != 1) { dev_dbg(&dev->udev->dev, "%s: device not opened exactly once\n", -- GitLab From fd47a417e75e2506eb3672ae569b1c87e3774155 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 11 Oct 2019 17:11:15 +0300 Subject: [PATCH 336/993] USB: legousbtower: fix a signedness bug in tower_probe() The problem is that sizeof() is unsigned long so negative error codes are type promoted to high positive values and the condition becomes false. Fixes: 1d427be4a39d ("USB: legousbtower: fix slab info leak at probe") Signed-off-by: Dan Carpenter Acked-by: Johan Hovold Link: https://lore.kernel.org/r/20191011141115.GA4521@mwanda Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/legousbtower.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 62dab2441ec4..23061f1526b4 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -878,7 +878,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device get_version_reply, sizeof(*get_version_reply), 1000); - if (result < sizeof(*get_version_reply)) { + if (result != sizeof(*get_version_reply)) { if (result >= 0) result = -EIO; dev_err(idev, "get version request failed: %d\n", result); -- GitLab From f616c3bda47e314ddb797e969f27081f3c33e3b3 Mon Sep 17 00:00:00 2001 From: Pawel Laszczak Date: Sun, 13 Oct 2019 10:20:20 +0100 Subject: [PATCH 337/993] usb: cdns3: Fix dequeue implementation. Dequeuing implementation in cdns3_gadget_ep_dequeue gets first request from deferred_req_list and changed TRB associated with it to LINK TRB. This approach is incorrect because deferred_req_list contains requests that have not been placed on hardware RING. In this case driver should just giveback this request to gadget driver. The patch implements new approach that first checks where dequeuing request is located and only when it's on Transfer Ring then changes TRB associated with it to LINK TRB. During processing completed transfers such LINK TRB will be ignored. Reported-by: Peter Chen Signed-off-by: Pawel Laszczak Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") Reviewed-by: Peter Chen Link: https://lore.kernel.org/r/1570958420-22196-1-git-send-email-pawell@cadence.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/gadget.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c index 2ca280f4c054..9050b380ab83 100644 --- a/drivers/usb/cdns3/gadget.c +++ b/drivers/usb/cdns3/gadget.c @@ -1145,6 +1145,14 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev, request = cdns3_next_request(&priv_ep->pending_req_list); priv_req = to_cdns3_request(request); + trb = priv_ep->trb_pool + priv_ep->dequeue; + + /* Request was dequeued and TRB was changed to TRB_LINK. */ + if (TRB_FIELD_TO_TYPE(trb->control) == TRB_LINK) { + trace_cdns3_complete_trb(priv_ep, trb); + cdns3_move_deq_to_next_trb(priv_req); + } + /* Re-select endpoint. It could be changed by other CPU during * handling usb_gadget_giveback_request. */ @@ -2067,6 +2075,7 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep, struct usb_request *req, *req_temp; struct cdns3_request *priv_req; struct cdns3_trb *link_trb; + u8 req_on_hw_ring = 0; unsigned long flags; int ret = 0; @@ -2083,8 +2092,10 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep, list_for_each_entry_safe(req, req_temp, &priv_ep->pending_req_list, list) { - if (request == req) + if (request == req) { + req_on_hw_ring = 1; goto found; + } } list_for_each_entry_safe(req, req_temp, &priv_ep->deferred_req_list, @@ -2096,27 +2107,21 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep, goto not_found; found: - - if (priv_ep->wa1_trb == priv_req->trb) - cdns3_wa1_restore_cycle_bit(priv_ep); - link_trb = priv_req->trb; - cdns3_move_deq_to_next_trb(priv_req); - cdns3_gadget_giveback(priv_ep, priv_req, -ECONNRESET); - - /* Update ring */ - request = cdns3_next_request(&priv_ep->deferred_req_list); - if (request) { - priv_req = to_cdns3_request(request); + /* Update ring only if removed request is on pending_req_list list */ + if (req_on_hw_ring) { link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma + (priv_req->start_trb * TRB_SIZE)); link_trb->control = (link_trb->control & TRB_CYCLE) | - TRB_TYPE(TRB_LINK) | TRB_CHAIN | TRB_TOGGLE; - } else { - priv_ep->flags |= EP_UPDATE_EP_TRBADDR; + TRB_TYPE(TRB_LINK) | TRB_CHAIN; + + if (priv_ep->wa1_trb == priv_req->trb) + cdns3_wa1_restore_cycle_bit(priv_ep); } + cdns3_gadget_giveback(priv_ep, priv_req, -ECONNRESET); + not_found: spin_unlock_irqrestore(&priv_dev->lock, flags); return ret; -- GitLab From b987b66ac3a2bc2f7b03a0ba48a07dc553100c07 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Mon, 14 Oct 2019 14:18:30 -0500 Subject: [PATCH 338/993] usb: udc: lpc32xx: fix bad bit shift operation It seems that the right variable to use in this case is *i*, instead of *n*, otherwise there is an undefined behavior when right shifiting by more than 31 bits when multiplying n by 8; notice that *n* can take values equal or greater than 4 (4, 8, 16, ...). Also, notice that under the current conditions (bl = 3), we are skiping the handling of bytes 3, 7, 31... So, fix this by updating this logic and limit *bl* up to 4 instead of up to 3. This fix is based on function udc_stuff_fifo(). Addresses-Coverity-ID: 1454834 ("Bad bit shift operation") Fixes: 24a28e428351 ("USB: gadget driver for LPC32xx") Cc: stable@vger.kernel.org Signed-off-by: Gustavo A. R. Silva Link: https://lore.kernel.org/r/20191014191830.GA10721@embeddedor Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/lpc32xx_udc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 2b1f3cc7819b..bf6c81e2f8cc 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -1177,11 +1177,11 @@ static void udc_pop_fifo(struct lpc32xx_udc *udc, u8 *data, u32 bytes) tmp = readl(USBD_RXDATA(udc->udp_baseaddr)); bl = bytes - n; - if (bl > 3) - bl = 3; + if (bl > 4) + bl = 4; for (i = 0; i < bl; i++) - data[n + i] = (u8) ((tmp >> (n * 8)) & 0xFF); + data[n + i] = (u8) ((tmp >> (i * 8)) & 0xFF); } break; -- GitLab From 7a759197974894213621aa65f0571b51904733d6 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 15 Oct 2019 19:55:22 +0200 Subject: [PATCH 339/993] USB: usblp: fix use-after-free on disconnect A recent commit addressing a runtime PM use-count regression, introduced a use-after-free by not making sure we held a reference to the struct usb_interface for the lifetime of the driver data. Fixes: 9a31535859bf ("USB: usblp: fix runtime PM after driver unbind") Cc: stable Reported-by: syzbot+cd24df4d075c319ebfc5@syzkaller.appspotmail.com Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20191015175522.18490-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usblp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index fb8bd60c83f4..0d8e3f3804a3 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -445,6 +445,7 @@ static void usblp_cleanup(struct usblp *usblp) kfree(usblp->readbuf); kfree(usblp->device_id_string); kfree(usblp->statusbuf); + usb_put_intf(usblp->intf); kfree(usblp); } @@ -1113,7 +1114,7 @@ static int usblp_probe(struct usb_interface *intf, init_waitqueue_head(&usblp->wwait); init_usb_anchor(&usblp->urbs); usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; - usblp->intf = intf; + usblp->intf = usb_get_intf(intf); /* Malloc device ID string buffer to the largest expected length, * since we can re-query it on an ioctl and a dynamic string @@ -1198,6 +1199,7 @@ static int usblp_probe(struct usb_interface *intf, kfree(usblp->readbuf); kfree(usblp->statusbuf); kfree(usblp->device_id_string); + usb_put_intf(usblp->intf); kfree(usblp); abort_ret: return retval; -- GitLab From f50b6805dbb993152025ec04dea094c40cc93a0c Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sun, 13 Oct 2019 23:00:16 +0100 Subject: [PATCH 340/993] 8250-men-mcb: fix error checking when get_num_ports returns -ENODEV The current checking for failure on the number of ports fails when -ENODEV is returned from the call to get_num_ports. Fix this by making num_ports and loop counter i signed rather than unsigned ints. Also add check for num_ports being less than zero to check for -ve error returns. Addresses-Coverity: ("Unsigned compared against 0") Fixes: e2fea54e4592 ("8250-men-mcb: add support for 16z025 and 16z057") Signed-off-by: Colin Ian King Reviewed-by: Michael Moese Link: https://lore.kernel.org/r/20191013220016.9369-1-colin.king@canonical.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_men_mcb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c index 02c5aff58a74..8df89e9cd254 100644 --- a/drivers/tty/serial/8250/8250_men_mcb.c +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -72,8 +72,8 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev, { struct serial_8250_men_mcb_data *data; struct resource *mem; - unsigned int num_ports; - unsigned int i; + int num_ports; + int i; void __iomem *membase; mem = mcb_get_resource(mdev, IORESOURCE_MEM); @@ -88,7 +88,7 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev, dev_dbg(&mdev->dev, "found a 16z%03u with %u ports\n", mdev->id, num_ports); - if (num_ports == 0 || num_ports > 4) { + if (num_ports <= 0 || num_ports > 4) { dev_err(&mdev->dev, "unexpected number of ports: %u\n", num_ports); return -ENODEV; @@ -133,7 +133,7 @@ static int serial_8250_men_mcb_probe(struct mcb_device *mdev, static void serial_8250_men_mcb_remove(struct mcb_device *mdev) { - unsigned int num_ports, i; + int num_ports, i; struct serial_8250_men_mcb_data *data = mcb_get_drvdata(mdev); if (!data) -- GitLab From 95f89e090618efca63918b658c2002e57d393036 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Tue, 15 Oct 2019 17:16:50 +0200 Subject: [PATCH 341/993] vfio/type1: Initialize resv_msi_base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After enabling CONFIG_IOMMU_DMA on X86 a new warning appears when compiling vfio: drivers/vfio/vfio_iommu_type1.c: In function ‘vfio_iommu_type1_attach_group’: drivers/vfio/vfio_iommu_type1.c:1827:7: warning: ‘resv_msi_base’ may be used uninitialized in this function [-Wmaybe-uninitialized] ret = iommu_get_msi_cookie(domain->domain, resv_msi_base); ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The warning is a false positive, because the call to iommu_get_msi_cookie() only happens when vfio_iommu_has_sw_msi() returned true. And that only happens when it also set resv_msi_base. But initialize the variable anyway to get rid of the warning. Signed-off-by: Joerg Roedel Reviewed-by: Cornelia Huck Reviewed-by: Eric Auger Signed-off-by: Alex Williamson --- drivers/vfio/vfio_iommu_type1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 96fddc1dafc3..d864277ea16f 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -1658,7 +1658,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, struct bus_type *bus = NULL; int ret; bool resv_msi, msi_remap; - phys_addr_t resv_msi_base; + phys_addr_t resv_msi_base = 0; struct iommu_domain_geometry geo; LIST_HEAD(iova_copy); LIST_HEAD(group_resv_regions); -- GitLab From 09d6ac8dc51a033ae0043c1fe40b4d02563c2496 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 15 Oct 2019 12:54:17 -0700 Subject: [PATCH 342/993] libata/ahci: Fix PCS quirk application Commit c312ef176399 "libata/ahci: Drop PCS quirk for Denverton and beyond" got the polarity wrong on the check for which board-ids should have the quirk applied. The board type board_ahci_pcs7 is defined at the end of the list such that "pcs7" boards can be special cased in the future if they need the quirk. All prior Intel board ids "< board_ahci_pcs7" should proceed with applying the quirk. Reported-by: Andreas Friedrich Reported-by: Stephen Douthit Fixes: c312ef176399 ("libata/ahci: Drop PCS quirk for Denverton and beyond") Cc: Signed-off-by: Dan Williams Signed-off-by: Jens Axboe --- drivers/ata/ahci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index dd92faf197d5..05c2b32dcc4d 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1600,7 +1600,9 @@ static void ahci_intel_pcs_quirk(struct pci_dev *pdev, struct ahci_host_priv *hp */ if (!id || id->vendor != PCI_VENDOR_ID_INTEL) return; - if (((enum board_ids) id->driver_data) < board_ahci_pcs7) + + /* Skip applying the quirk on Denverton and beyond */ + if (((enum board_ids) id->driver_data) >= board_ahci_pcs7) return; /* -- GitLab From 0c401fdf27ba52830c39670dc81cd8379756bd65 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 15 Oct 2019 13:52:03 -0700 Subject: [PATCH 343/993] xtensa: virt: fix PCI IO ports mapping virt device tree incorrectly uses 0xf0000000 on both sides of PCI IO ports address space mapping. This results in incorrect port address assignment in PCI IO BARs and subsequent crash on attempt to access them. Use 0 as base address in PCI IO ports address space. Signed-off-by: Max Filippov --- arch/xtensa/boot/dts/virt.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/xtensa/boot/dts/virt.dts b/arch/xtensa/boot/dts/virt.dts index a9dcd87b6eb1..611b98a02a65 100644 --- a/arch/xtensa/boot/dts/virt.dts +++ b/arch/xtensa/boot/dts/virt.dts @@ -56,7 +56,7 @@ reg = <0xf0100000 0x03f00000>; // BUS_ADDRESS(3) CPU_PHYSICAL(1) SIZE(2) - ranges = <0x01000000 0x0 0xf0000000 0xf0000000 0x0 0x00010000>, + ranges = <0x01000000 0x0 0x00000000 0xf0000000 0x0 0x00010000>, <0x02000000 0x0 0xf4000000 0xf4000000 0x0 0x08000000>; // PCI_DEVICE(3) INT#(1) CONTROLLER(PHANDLE) CONTROLLER_DATA(2) -- GitLab From 45144d42f299455911cc29366656c7324a3a7c97 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 14 Oct 2019 13:25:00 +0200 Subject: [PATCH 344/993] PCI: PM: Fix pci_power_up() There is an arbitrary difference between the system resume and runtime resume code paths for PCI devices regarding the delay to apply when switching the devices from D3cold to D0. Namely, pci_restore_standard_config() used in the runtime resume code path calls pci_set_power_state() which in turn invokes __pci_start_power_transition() to power up the device through the platform firmware and that function applies the transition delay (as per PCI Express Base Specification Revision 2.0, Section 6.6.1). However, pci_pm_default_resume_early() used in the system resume code path calls pci_power_up() which doesn't apply the delay at all and that causes issues to occur during resume from suspend-to-idle on some systems where the delay is required. Since there is no reason for that difference to exist, modify pci_power_up() to follow pci_set_power_state() more closely and invoke __pci_start_power_transition() from there to call the platform firmware to power up the device (in case that's necessary). Fixes: db288c9c5f9d ("PCI / PM: restore the original behavior of pci_set_power_state()") Reported-by: Daniel Drake Tested-by: Daniel Drake Link: https://lore.kernel.org/linux-pm/CAD8Lp44TYxrMgPLkHCqF9hv6smEurMXvmmvmtyFhZ6Q4SE+dig@mail.gmail.com/T/#m21be74af263c6a34f36e0fc5c77c5449d9406925 Signed-off-by: Rafael J. Wysocki Acked-by: Bjorn Helgaas Cc: 3.10+ # 3.10+ --- drivers/pci/pci.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e7982af9a5d8..a97e2571a527 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -958,19 +958,6 @@ void pci_refresh_power_state(struct pci_dev *dev) pci_update_current_state(dev, dev->current_state); } -/** - * pci_power_up - Put the given device into D0 forcibly - * @dev: PCI device to power up - */ -void pci_power_up(struct pci_dev *dev) -{ - if (platform_pci_power_manageable(dev)) - platform_pci_set_power_state(dev, PCI_D0); - - pci_raw_set_power_state(dev, PCI_D0); - pci_update_current_state(dev, PCI_D0); -} - /** * pci_platform_power_transition - Use platform to change device power state * @dev: PCI device to handle. @@ -1153,6 +1140,17 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) } EXPORT_SYMBOL(pci_set_power_state); +/** + * pci_power_up - Put the given device into D0 forcibly + * @dev: PCI device to power up + */ +void pci_power_up(struct pci_dev *dev) +{ + __pci_start_power_transition(dev, PCI_D0); + pci_raw_set_power_state(dev, PCI_D0); + pci_update_current_state(dev, PCI_D0); +} + /** * pci_choose_state - Choose the power state of a PCI device * @dev: PCI device to be suspended -- GitLab From b31141d390f1d47f1f3e1aef04909dc48e894611 Mon Sep 17 00:00:00 2001 From: Nishad Kamdar Date: Sat, 12 Oct 2019 17:48:56 +0530 Subject: [PATCH 345/993] net: dsa: microchip: Use the correct style for SPDX License Identifier This patch corrects the SPDX License Identifier style in header files related to Distributed Switch Architecture drivers for Microchip KSZ series switch support. For C header files Documentation/process/license-rules.rst mandates C-like comments (opposed to C source files where C++ style should be used) Changes made by using a script provided by Joe Perches here: https://lkml.org/lkml/2019/2/7/46. Suggested-by: Joe Perches Signed-off-by: Nishad Kamdar Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz9477_reg.h | 4 ++-- drivers/net/dsa/microchip/ksz_common.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz9477_reg.h b/drivers/net/dsa/microchip/ksz9477_reg.h index 2938e892b631..16939f29faa5 100644 --- a/drivers/net/dsa/microchip/ksz9477_reg.h +++ b/drivers/net/dsa/microchip/ksz9477_reg.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: GPL-2.0 - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* * Microchip KSZ9477 register definitions * * Copyright (C) 2017-2018 Microchip Technology Inc. diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index dd60d0837fc6..64c2677693d2 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: GPL-2.0 - * Microchip switch driver common header +/* SPDX-License-Identifier: GPL-2.0 */ +/* Microchip switch driver common header * * Copyright (C) 2017-2019 Microchip Technology Inc. */ -- GitLab From a03681dd5d1bf7b0ed3aad3162f7810af4c4e05b Mon Sep 17 00:00:00 2001 From: Nishad Kamdar Date: Sat, 12 Oct 2019 18:42:28 +0530 Subject: [PATCH 346/993] net: cavium: Use the correct style for SPDX License Identifier This patch corrects the SPDX License Identifier style in header files related to Cavium Ethernet drivers. For C header files Documentation/process/license-rules.rst mandates C-like comments (opposed to C source files where C++ style should be used) Changes made by using a script provided by Joe Perches here: https://lkml.org/lkml/2019/2/7/46. Suggested-by: Joe Perches Signed-off-by: Nishad Kamdar Signed-off-by: David S. Miller --- drivers/net/ethernet/cavium/common/cavium_ptp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cavium/common/cavium_ptp.h b/drivers/net/ethernet/cavium/common/cavium_ptp.h index be2bafc7beeb..a04eccbc78e8 100644 --- a/drivers/net/ethernet/cavium/common/cavium_ptp.h +++ b/drivers/net/ethernet/cavium/common/cavium_ptp.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* cavium_ptp.h - PTP 1588 clock on Cavium hardware * Copyright (c) 2003-2015, 2017 Cavium, Inc. */ -- GitLab From dedc5a08da07874c6e0d411e7f39c5c2cf137014 Mon Sep 17 00:00:00 2001 From: Davide Caratti Date: Sat, 12 Oct 2019 13:55:06 +0200 Subject: [PATCH 347/993] net: avoid errors when trying to pop MLPS header on non-MPLS packets the following script: # tc qdisc add dev eth0 clsact # tc filter add dev eth0 egress matchall action mpls pop implicitly makes the kernel drop all packets transmitted by eth0, if they don't have a MPLS header. This behavior is uncommon: other encapsulations (like VLAN) just let the packet pass unmodified. Since the result of MPLS 'pop' operation would be the same regardless of the presence / absence of MPLS header(s) in the original packet, we can let skb_mpls_pop() return 0 when dealing with non-MPLS packets. For the OVS use-case, this is acceptable because __ovs_nla_copy_actions() already ensures that MPLS 'pop' operation only occurs with packets having an MPLS Ethernet type (and there are no other callers in current code, so the semantic change should be ok). v2: better documentation of use-cases for skb_mpls_pop(), thanks to Simon Horman Fixes: 2a2ea50870ba ("net: sched: add mpls manipulation actions to TC") Reviewed-by: Simon Horman Acked-by: John Hurley Signed-off-by: Davide Caratti Signed-off-by: David S. Miller --- net/core/skbuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 8c178703467b..03b6809ebde4 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -5536,7 +5536,7 @@ int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto) int err; if (unlikely(!eth_p_mpls(skb->protocol))) - return -EINVAL; + return 0; err = skb_ensure_writable(skb, skb->mac_len + MPLS_HLEN); if (unlikely(err)) -- GitLab From fa4e0f8855fcba600e0be2575ee29c69166f74bd Mon Sep 17 00:00:00 2001 From: Davide Caratti Date: Sat, 12 Oct 2019 13:55:07 +0200 Subject: [PATCH 348/993] net/sched: fix corrupted L2 header with MPLS 'push' and 'pop' actions the following script: # tc qdisc add dev eth0 clsact # tc filter add dev eth0 egress protocol ip matchall \ > action mpls push protocol mpls_uc label 0x355aa bos 1 causes corruption of all IP packets transmitted by eth0. On TC egress, we can't rely on the value of skb->mac_len, because it's 0 and a MPLS 'push' operation will result in an overwrite of the first 4 octets in the packet L2 header (e.g. the Destination Address if eth0 is an Ethernet); the same error pattern is present also in the MPLS 'pop' operation. Fix this error in act_mpls data plane, computing 'mac_len' as the difference between the network header and the mac header (when not at TC ingress), and use it in MPLS 'push'/'pop' core functions. v2: unbreak 'make htmldocs' because of missing documentation of 'mac_len' in skb_mpls_pop(), reported by kbuild test robot CC: Lorenzo Bianconi Fixes: 2a2ea50870ba ("net: sched: add mpls manipulation actions to TC") Reviewed-by: Simon Horman Acked-by: John Hurley Signed-off-by: Davide Caratti Signed-off-by: David S. Miller --- include/linux/skbuff.h | 5 +++-- net/core/skbuff.c | 19 +++++++++++-------- net/openvswitch/actions.c | 5 +++-- net/sched/act_mpls.c | 12 ++++++++---- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 4351577b14d7..7914fdaf4226 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -3510,8 +3510,9 @@ int skb_ensure_writable(struct sk_buff *skb, int write_len); int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci); int skb_vlan_pop(struct sk_buff *skb); int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci); -int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto); -int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto); +int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto, + int mac_len); +int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len); int skb_mpls_update_lse(struct sk_buff *skb, __be32 mpls_lse); int skb_mpls_dec_ttl(struct sk_buff *skb); struct sk_buff *pskb_extract(struct sk_buff *skb, int off, int to_copy, diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 03b6809ebde4..867e61df00db 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -5477,12 +5477,14 @@ static void skb_mod_eth_type(struct sk_buff *skb, struct ethhdr *hdr, * @skb: buffer * @mpls_lse: MPLS label stack entry to push * @mpls_proto: ethertype of the new MPLS header (expects 0x8847 or 0x8848) + * @mac_len: length of the MAC header * * Expects skb->data at mac header. * * Returns 0 on success, -errno otherwise. */ -int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto) +int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto, + int mac_len) { struct mpls_shim_hdr *lse; int err; @@ -5499,15 +5501,15 @@ int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto) return err; if (!skb->inner_protocol) { - skb_set_inner_network_header(skb, skb->mac_len); + skb_set_inner_network_header(skb, mac_len); skb_set_inner_protocol(skb, skb->protocol); } skb_push(skb, MPLS_HLEN); memmove(skb_mac_header(skb) - MPLS_HLEN, skb_mac_header(skb), - skb->mac_len); + mac_len); skb_reset_mac_header(skb); - skb_set_network_header(skb, skb->mac_len); + skb_set_network_header(skb, mac_len); lse = mpls_hdr(skb); lse->label_stack_entry = mpls_lse; @@ -5526,29 +5528,30 @@ EXPORT_SYMBOL_GPL(skb_mpls_push); * * @skb: buffer * @next_proto: ethertype of header after popped MPLS header + * @mac_len: length of the MAC header * * Expects skb->data at mac header. * * Returns 0 on success, -errno otherwise. */ -int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto) +int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len) { int err; if (unlikely(!eth_p_mpls(skb->protocol))) return 0; - err = skb_ensure_writable(skb, skb->mac_len + MPLS_HLEN); + err = skb_ensure_writable(skb, mac_len + MPLS_HLEN); if (unlikely(err)) return err; skb_postpull_rcsum(skb, mpls_hdr(skb), MPLS_HLEN); memmove(skb_mac_header(skb) + MPLS_HLEN, skb_mac_header(skb), - skb->mac_len); + mac_len); __skb_pull(skb, MPLS_HLEN); skb_reset_mac_header(skb); - skb_set_network_header(skb, skb->mac_len); + skb_set_network_header(skb, mac_len); if (skb->dev && skb->dev->type == ARPHRD_ETHER) { struct ethhdr *hdr; diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 3572e11b6f21..1c77f520f474 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c @@ -165,7 +165,8 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key, { int err; - err = skb_mpls_push(skb, mpls->mpls_lse, mpls->mpls_ethertype); + err = skb_mpls_push(skb, mpls->mpls_lse, mpls->mpls_ethertype, + skb->mac_len); if (err) return err; @@ -178,7 +179,7 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key, { int err; - err = skb_mpls_pop(skb, ethertype); + err = skb_mpls_pop(skb, ethertype, skb->mac_len); if (err) return err; diff --git a/net/sched/act_mpls.c b/net/sched/act_mpls.c index e168df0e008a..4cf6c553bb0b 100644 --- a/net/sched/act_mpls.c +++ b/net/sched/act_mpls.c @@ -55,7 +55,7 @@ static int tcf_mpls_act(struct sk_buff *skb, const struct tc_action *a, struct tcf_mpls *m = to_mpls(a); struct tcf_mpls_params *p; __be32 new_lse; - int ret; + int ret, mac_len; tcf_lastuse_update(&m->tcf_tm); bstats_cpu_update(this_cpu_ptr(m->common.cpu_bstats), skb); @@ -63,8 +63,12 @@ static int tcf_mpls_act(struct sk_buff *skb, const struct tc_action *a, /* Ensure 'data' points at mac_header prior calling mpls manipulating * functions. */ - if (skb_at_tc_ingress(skb)) + if (skb_at_tc_ingress(skb)) { skb_push_rcsum(skb, skb->mac_len); + mac_len = skb->mac_len; + } else { + mac_len = skb_network_header(skb) - skb_mac_header(skb); + } ret = READ_ONCE(m->tcf_action); @@ -72,12 +76,12 @@ static int tcf_mpls_act(struct sk_buff *skb, const struct tc_action *a, switch (p->tcfm_action) { case TCA_MPLS_ACT_POP: - if (skb_mpls_pop(skb, p->tcfm_proto)) + if (skb_mpls_pop(skb, p->tcfm_proto, mac_len)) goto drop; break; case TCA_MPLS_ACT_PUSH: new_lse = tcf_mpls_get_lse(NULL, p, !eth_p_mpls(skb->protocol)); - if (skb_mpls_push(skb, new_lse, p->tcfm_proto)) + if (skb_mpls_push(skb, new_lse, p->tcfm_proto, mac_len)) goto drop; break; case TCA_MPLS_ACT_MODIFY: -- GitLab From c324345ce89c3cc50226372960619c7ee940f616 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Tue, 15 Oct 2019 17:37:37 -0700 Subject: [PATCH 349/993] Revert "Input: elantech - enable SMBus on new (2018+) systems" This reverts commit 883a2a80f79ca5c0c105605fafabd1f3df99b34c. Apparently use dmi_get_bios_year() as manufacturing date isn't accurate and this breaks older laptops with new BIOS update. So let's revert this patch. There are still new HP laptops still need to use SMBus to support all features, but it'll be enabled via a whitelist. Signed-off-by: Kai-Heng Feng Acked-by: Benjamin Tissoires Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191001070845.9720-1-kai.heng.feng@canonical.com Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/elantech.c | 55 ++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 04fe43440a3c..2d8434b7b623 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -1827,31 +1827,6 @@ static int elantech_create_smbus(struct psmouse *psmouse, leave_breadcrumbs); } -static bool elantech_use_host_notify(struct psmouse *psmouse, - struct elantech_device_info *info) -{ - if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version)) - return true; - - switch (info->bus) { - case ETP_BUS_PS2_ONLY: - /* expected case */ - break; - case ETP_BUS_SMB_HST_NTFY_ONLY: - case ETP_BUS_PS2_SMB_HST_NTFY: - /* SMbus implementation is stable since 2018 */ - if (dmi_get_bios_year() >= 2018) - return true; - /* fall through */ - default: - psmouse_dbg(psmouse, - "Ignoring SMBus bus provider %d\n", info->bus); - break; - } - - return false; -} - /** * elantech_setup_smbus - called once the PS/2 devices are enumerated * and decides to instantiate a SMBus InterTouch device. @@ -1871,7 +1846,7 @@ static int elantech_setup_smbus(struct psmouse *psmouse, * i2c_blacklist_pnp_ids. * Old ICs are up to the user to decide. */ - if (!elantech_use_host_notify(psmouse, info) || + if (!ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version) || psmouse_matches_pnp_id(psmouse, i2c_blacklist_pnp_ids)) return -ENXIO; } @@ -1891,6 +1866,34 @@ static int elantech_setup_smbus(struct psmouse *psmouse, return 0; } +static bool elantech_use_host_notify(struct psmouse *psmouse, + struct elantech_device_info *info) +{ + if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version)) + return true; + + switch (info->bus) { + case ETP_BUS_PS2_ONLY: + /* expected case */ + break; + case ETP_BUS_SMB_ALERT_ONLY: + /* fall-through */ + case ETP_BUS_PS2_SMB_ALERT: + psmouse_dbg(psmouse, "Ignoring SMBus provider through alert protocol.\n"); + break; + case ETP_BUS_SMB_HST_NTFY_ONLY: + /* fall-through */ + case ETP_BUS_PS2_SMB_HST_NTFY: + return true; + default: + psmouse_dbg(psmouse, + "Ignoring SMBus bus provider %d.\n", + info->bus); + } + + return false; +} + int elantech_init_smbus(struct psmouse *psmouse) { struct elantech_device_info info; -- GitLab From 4e3eff5beafa5c97cdf2af2181f46479941a7f45 Mon Sep 17 00:00:00 2001 From: MarkLee Date: Mon, 14 Oct 2019 15:15:17 +0800 Subject: [PATCH 350/993] net: ethernet: mediatek: Fix MT7629 missing GMII mode support In the original design, mtk_phy_connect function will set ge_mode=1 if phy-mode is GMII(PHY_INTERFACE_MODE_GMII) and then set the correct ge_mode to ETHSYS_SYSCFG0 register. This logic was broken after apply mediatek PHYLINK patch(Fixes tag), the new mtk_mac_config function will not set ge_mode=1 for GMII mode hence the final ETHSYS_SYSCFG0 setting will be incorrect for mt7629 GMII mode. This patch add the missing logic back to fix it. Fixes: b8fc9f30821e ("net: ethernet: mediatek: Add basic PHYLINK support") Signed-off-by: MarkLee Signed-off-by: David S. Miller --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index c61069340f4f..703adb96429e 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -261,6 +261,7 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode, ge_mode = 0; switch (state->interface) { case PHY_INTERFACE_MODE_MII: + case PHY_INTERFACE_MODE_GMII: ge_mode = 1; break; case PHY_INTERFACE_MODE_REVMII: -- GitLab From 2618500dd370da413cb1f616111e1bd8d9f5f94f Mon Sep 17 00:00:00 2001 From: MarkLee Date: Mon, 14 Oct 2019 15:15:18 +0800 Subject: [PATCH 351/993] arm: dts: mediatek: Update mt7629 dts to reflect the latest dt-binding * Removes mediatek,physpeed property from dtsi that is useless in PHYLINK * Use the fixed-link property speed = <2500> to set the phy in 2.5Gbit. * Set gmac1 to gmii mode that connect to a internal gphy Signed-off-by: MarkLee Signed-off-by: David S. Miller --- arch/arm/boot/dts/mt7629-rfb.dts | 13 ++++++++++++- arch/arm/boot/dts/mt7629.dtsi | 2 -- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/mt7629-rfb.dts b/arch/arm/boot/dts/mt7629-rfb.dts index 3621b7d2b22a..9980c10c6e29 100644 --- a/arch/arm/boot/dts/mt7629-rfb.dts +++ b/arch/arm/boot/dts/mt7629-rfb.dts @@ -66,9 +66,21 @@ pinctrl-1 = <&ephy_leds_pins>; status = "okay"; + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "2500base-x"; + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + gmac1: mac@1 { compatible = "mediatek,eth-mac"; reg = <1>; + phy-mode = "gmii"; phy-handle = <&phy0>; }; @@ -78,7 +90,6 @@ phy0: ethernet-phy@0 { reg = <0>; - phy-mode = "gmii"; }; }; }; diff --git a/arch/arm/boot/dts/mt7629.dtsi b/arch/arm/boot/dts/mt7629.dtsi index 9608bc2ccb3f..867b88103b9d 100644 --- a/arch/arm/boot/dts/mt7629.dtsi +++ b/arch/arm/boot/dts/mt7629.dtsi @@ -468,14 +468,12 @@ compatible = "mediatek,mt7629-sgmiisys", "syscon"; reg = <0x1b128000 0x3000>; #clock-cells = <1>; - mediatek,physpeed = "2500"; }; sgmiisys1: syscon@1b130000 { compatible = "mediatek,mt7629-sgmiisys", "syscon"; reg = <0x1b130000 0x3000>; #clock-cells = <1>; - mediatek,physpeed = "2500"; }; }; }; -- GitLab From cab209e571a9375f7dc6db69a6c40d2d98e57e3b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 14 Oct 2019 06:47:57 -0700 Subject: [PATCH 352/993] tcp: fix a possible lockdep splat in tcp_done() syzbot found that if __inet_inherit_port() returns an error, we call tcp_done() after inet_csk_prepare_forced_close(), meaning the socket lock is no longer held. We might fix this in a different way in net-next, but for 5.4 it seems safer to relax the lockdep check. Fixes: d983ea6f16b8 ("tcp: add rcu protection around tp->fastopen_rsk") Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index b2ac4f074e2d..42187a3b82f4 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3842,8 +3842,12 @@ void tcp_done(struct sock *sk) { struct request_sock *req; - req = rcu_dereference_protected(tcp_sk(sk)->fastopen_rsk, - lockdep_sock_is_held(sk)); + /* We might be called with a new socket, after + * inet_csk_prepare_forced_close() has been called + * so we can not use lockdep_sock_is_held(sk) + */ + req = rcu_dereference_protected(tcp_sk(sk)->fastopen_rsk, 1); + if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS); -- GitLab From b790b5549bdf498ab0ecc5632610a9149532fa38 Mon Sep 17 00:00:00 2001 From: Nishad Kamdar Date: Mon, 14 Oct 2019 21:51:20 +0530 Subject: [PATCH 353/993] net: dsa: sja1105: Use the correct style for SPDX License Identifier This patch corrects the SPDX License Identifier style in header files related to Distributed Switch Architecture drivers for NXP SJA1105 series Ethernet switch support. It uses an expilict block comment for the SPDX License Identifier. Changes made by using a script provided by Joe Perches here: https://lkml.org/lkml/2019/2/7/46. Suggested-by: Joe Perches Signed-off-by: Nishad Kamdar Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/sja1105/sja1105.h | 4 ++-- drivers/net/dsa/sja1105/sja1105_dynamic_config.h | 4 ++-- drivers/net/dsa/sja1105/sja1105_ptp.h | 4 ++-- drivers/net/dsa/sja1105/sja1105_static_config.h | 4 ++-- drivers/net/dsa/sja1105/sja1105_tas.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index e53e494c22e0..fbb564c3beb8 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: GPL-2.0 - * Copyright (c) 2018, Sensor-Technik Wiedemann GmbH +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2018, Sensor-Technik Wiedemann GmbH * Copyright (c) 2018-2019, Vladimir Oltean */ #ifndef _SJA1105_H diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.h b/drivers/net/dsa/sja1105/sja1105_dynamic_config.h index 740dadf43f01..1fc0d13dc623 100644 --- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.h +++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: GPL-2.0 - * Copyright (c) 2019, Vladimir Oltean +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2019, Vladimir Oltean */ #ifndef _SJA1105_DYNAMIC_CONFIG_H #define _SJA1105_DYNAMIC_CONFIG_H diff --git a/drivers/net/dsa/sja1105/sja1105_ptp.h b/drivers/net/dsa/sja1105/sja1105_ptp.h index af456b0a4d27..394e12a6ad59 100644 --- a/drivers/net/dsa/sja1105/sja1105_ptp.h +++ b/drivers/net/dsa/sja1105/sja1105_ptp.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: GPL-2.0 - * Copyright (c) 2019, Vladimir Oltean +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2019, Vladimir Oltean */ #ifndef _SJA1105_PTP_H #define _SJA1105_PTP_H diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.h b/drivers/net/dsa/sja1105/sja1105_static_config.h index 7f87022a2d61..f4a5c5c04311 100644 --- a/drivers/net/dsa/sja1105/sja1105_static_config.h +++ b/drivers/net/dsa/sja1105/sja1105_static_config.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright (c) 2016-2018, NXP Semiconductors +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2016-2018, NXP Semiconductors * Copyright (c) 2018-2019, Vladimir Oltean */ #ifndef _SJA1105_STATIC_CONFIG_H diff --git a/drivers/net/dsa/sja1105/sja1105_tas.h b/drivers/net/dsa/sja1105/sja1105_tas.h index 0b803c30e640..0aad212d88b2 100644 --- a/drivers/net/dsa/sja1105/sja1105_tas.h +++ b/drivers/net/dsa/sja1105/sja1105_tas.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: GPL-2.0 - * Copyright (c) 2019, Vladimir Oltean +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2019, Vladimir Oltean */ #ifndef _SJA1105_TAS_H #define _SJA1105_TAS_H -- GitLab From 39f13ea2f61b439ebe0060393e9c39925c9ee28c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 14 Oct 2019 11:22:30 -0700 Subject: [PATCH 354/993] net: avoid potential infinite loop in tc_ctl_action() tc_ctl_action() has the ability to loop forever if tcf_action_add() returns -EAGAIN. This special case has been done in case a module needed to be loaded, but it turns out that tcf_add_notify() could also return -EAGAIN if the socket sk_rcvbuf limit is hit. We need to separate the two cases, and only loop for the module loading case. While we are at it, add a limit of 10 attempts since unbounded loops are always scary. syzbot repro was something like : socket(PF_NETLINK, SOCK_RAW|SOCK_NONBLOCK, NETLINK_ROUTE) = 3 write(3, ..., 38) = 38 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [0], 4) = 0 sendmsg(3, {msg_name(0)=NULL, msg_iov(1)=[{..., 388}], msg_controllen=0, msg_flags=0x10}, ...) NMI backtrace for cpu 0 CPU: 0 PID: 1054 Comm: khungtaskd Not tainted 5.4.0-rc1+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x172/0x1f0 lib/dump_stack.c:113 nmi_cpu_backtrace.cold+0x70/0xb2 lib/nmi_backtrace.c:101 nmi_trigger_cpumask_backtrace+0x23b/0x28b lib/nmi_backtrace.c:62 arch_trigger_cpumask_backtrace+0x14/0x20 arch/x86/kernel/apic/hw_nmi.c:38 trigger_all_cpu_backtrace include/linux/nmi.h:146 [inline] check_hung_uninterruptible_tasks kernel/hung_task.c:205 [inline] watchdog+0x9d0/0xef0 kernel/hung_task.c:289 kthread+0x361/0x430 kernel/kthread.c:255 ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352 Sending NMI from CPU 0 to CPUs 1: NMI backtrace for cpu 1 CPU: 1 PID: 8859 Comm: syz-executor910 Not tainted 5.4.0-rc1+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:arch_local_save_flags arch/x86/include/asm/paravirt.h:751 [inline] RIP: 0010:lockdep_hardirqs_off+0x1df/0x2e0 kernel/locking/lockdep.c:3453 Code: 5c 08 00 00 5b 41 5c 41 5d 5d c3 48 c7 c0 58 1d f3 88 48 ba 00 00 00 00 00 fc ff df 48 c1 e8 03 80 3c 10 00 0f 85 d3 00 00 00 <48> 83 3d 21 9e 99 07 00 0f 84 b9 00 00 00 9c 58 0f 1f 44 00 00 f6 RSP: 0018:ffff8880a6f3f1b8 EFLAGS: 00000046 RAX: 1ffffffff11e63ab RBX: ffff88808c9c6080 RCX: 0000000000000000 RDX: dffffc0000000000 RSI: 0000000000000000 RDI: ffff88808c9c6914 RBP: ffff8880a6f3f1d0 R08: ffff88808c9c6080 R09: fffffbfff16be5d1 R10: fffffbfff16be5d0 R11: 0000000000000003 R12: ffffffff8746591f R13: ffff88808c9c6080 R14: ffffffff8746591f R15: 0000000000000003 FS: 00000000011e4880(0000) GS:ffff8880ae900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffff600400 CR3: 00000000a8920000 CR4: 00000000001406e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: trace_hardirqs_off+0x62/0x240 kernel/trace/trace_preemptirq.c:45 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:108 [inline] _raw_spin_lock_irqsave+0x6f/0xcd kernel/locking/spinlock.c:159 __wake_up_common_lock+0xc8/0x150 kernel/sched/wait.c:122 __wake_up+0xe/0x10 kernel/sched/wait.c:142 netlink_unlock_table net/netlink/af_netlink.c:466 [inline] netlink_unlock_table net/netlink/af_netlink.c:463 [inline] netlink_broadcast_filtered+0x705/0xb80 net/netlink/af_netlink.c:1514 netlink_broadcast+0x3a/0x50 net/netlink/af_netlink.c:1534 rtnetlink_send+0xdd/0x110 net/core/rtnetlink.c:714 tcf_add_notify net/sched/act_api.c:1343 [inline] tcf_action_add+0x243/0x370 net/sched/act_api.c:1362 tc_ctl_action+0x3b5/0x4bc net/sched/act_api.c:1410 rtnetlink_rcv_msg+0x463/0xb00 net/core/rtnetlink.c:5386 netlink_rcv_skb+0x177/0x450 net/netlink/af_netlink.c:2477 rtnetlink_rcv+0x1d/0x30 net/core/rtnetlink.c:5404 netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline] netlink_unicast+0x531/0x710 net/netlink/af_netlink.c:1328 netlink_sendmsg+0x8a5/0xd60 net/netlink/af_netlink.c:1917 sock_sendmsg_nosec net/socket.c:637 [inline] sock_sendmsg+0xd7/0x130 net/socket.c:657 ___sys_sendmsg+0x803/0x920 net/socket.c:2311 __sys_sendmsg+0x105/0x1d0 net/socket.c:2356 __do_sys_sendmsg net/socket.c:2365 [inline] __se_sys_sendmsg net/socket.c:2363 [inline] __x64_sys_sendmsg+0x78/0xb0 net/socket.c:2363 do_syscall_64+0xfa/0x760 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x440939 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet Reported-by: syzbot+cf0adbb9c28c8866c788@syzkaller.appspotmail.com Signed-off-by: David S. Miller --- net/sched/act_api.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 4e7429c6f864..69d4676a402f 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -1353,11 +1353,16 @@ static int tcf_action_add(struct net *net, struct nlattr *nla, struct netlink_ext_ack *extack) { size_t attr_size = 0; - int ret = 0; + int loop, ret; struct tc_action *actions[TCA_ACT_MAX_PRIO] = {}; - ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, actions, - &attr_size, true, extack); + for (loop = 0; loop < 10; loop++) { + ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, + actions, &attr_size, true, extack); + if (ret != -EAGAIN) + break; + } + if (ret < 0) return ret; ret = tcf_add_notify(net, n, actions, portid, attr_size, extack); @@ -1407,11 +1412,8 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, */ if (n->nlmsg_flags & NLM_F_REPLACE) ovr = 1; -replay: ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr, extack); - if (ret == -EAGAIN) - goto replay; break; case RTM_DELACTION: ret = tca_action_gd(net, tca[TCA_ACT_TAB], n, -- GitLab From 28aa7c86c2b49f659c8460a89e53b506c45979bb Mon Sep 17 00:00:00 2001 From: Vinicius Costa Gomes Date: Mon, 14 Oct 2019 13:38:22 -0700 Subject: [PATCH 355/993] sched: etf: Fix ordering of packets with same txtime When a application sends many packets with the same txtime, they may be transmitted out of order (different from the order in which they were enqueued). This happens because when inserting elements into the tree, when the txtime of two packets are the same, the new packet is inserted at the left side of the tree, causing the reordering. The only effect of this change should be that packets with the same txtime will be transmitted in the order they are enqueued. The application in question (the AVTP GStreamer plugin, still in development) is sending video traffic, in which each video frame have a single presentation time, the problem is that when packetizing, multiple packets end up with the same txtime. The receiving side was rejecting packets because they were being received out of order. Fixes: 25db26a91364 ("net/sched: Introduce the ETF Qdisc") Reported-by: Ederson de Souza Signed-off-by: Vinicius Costa Gomes Signed-off-by: David S. Miller --- net/sched/sch_etf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_etf.c b/net/sched/sch_etf.c index cebfb65d8556..b1da5589a0c6 100644 --- a/net/sched/sch_etf.c +++ b/net/sched/sch_etf.c @@ -177,7 +177,7 @@ static int etf_enqueue_timesortedlist(struct sk_buff *nskb, struct Qdisc *sch, parent = *p; skb = rb_to_skb(parent); - if (ktime_after(txtime, skb->tstamp)) { + if (ktime_compare(txtime, skb->tstamp) >= 0) { p = &parent->rb_right; leftmost = false; } else { -- GitLab From 63dfb7938b13fa2c2fbcb45f34d065769eb09414 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Tue, 15 Oct 2019 15:24:38 +0800 Subject: [PATCH 356/993] sctp: change sctp_prot .no_autobind with true syzbot reported a memory leak: BUG: memory leak, unreferenced object 0xffff888120b3d380 (size 64): backtrace: [...] slab_alloc mm/slab.c:3319 [inline] [...] kmem_cache_alloc+0x13f/0x2c0 mm/slab.c:3483 [...] sctp_bucket_create net/sctp/socket.c:8523 [inline] [...] sctp_get_port_local+0x189/0x5a0 net/sctp/socket.c:8270 [...] sctp_do_bind+0xcc/0x200 net/sctp/socket.c:402 [...] sctp_bindx_add+0x4b/0xd0 net/sctp/socket.c:497 [...] sctp_setsockopt_bindx+0x156/0x1b0 net/sctp/socket.c:1022 [...] sctp_setsockopt net/sctp/socket.c:4641 [inline] [...] sctp_setsockopt+0xaea/0x2dc0 net/sctp/socket.c:4611 [...] sock_common_setsockopt+0x38/0x50 net/core/sock.c:3147 [...] __sys_setsockopt+0x10f/0x220 net/socket.c:2084 [...] __do_sys_setsockopt net/socket.c:2100 [inline] It was caused by when sending msgs without binding a port, in the path: inet_sendmsg() -> inet_send_prepare() -> inet_autobind() -> .get_port/sctp_get_port(), sp->bind_hash will be set while bp->port is not. Later when binding another port by sctp_setsockopt_bindx(), a new bucket will be created as bp->port is not set. sctp's autobind is supposed to call sctp_autobind() where it does all things including setting bp->port. Since sctp_autobind() is called in sctp_sendmsg() if the sk is not yet bound, it should have skipped the auto bind. THis patch is to avoid calling inet_autobind() in inet_send_prepare() by changing sctp_prot .no_autobind with true, also remove the unused .get_port. Reported-by: syzbot+d44f7bbebdea49dbc84a@syzkaller.appspotmail.com Signed-off-by: Xin Long Acked-by: Marcelo Ricardo Leitner Signed-off-by: David S. Miller --- net/sctp/socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 939b8d2595bc..5ca0ec0e823c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -9500,7 +9500,7 @@ struct proto sctp_prot = { .backlog_rcv = sctp_backlog_rcv, .hash = sctp_hash, .unhash = sctp_unhash, - .get_port = sctp_get_port, + .no_autobind = true, .obj_size = sizeof(struct sctp_sock), .useroffset = offsetof(struct sctp_sock, subscribe), .usersize = offsetof(struct sctp_sock, initmsg) - @@ -9542,7 +9542,7 @@ struct proto sctpv6_prot = { .backlog_rcv = sctp_backlog_rcv, .hash = sctp_hash, .unhash = sctp_unhash, - .get_port = sctp_get_port, + .no_autobind = true, .obj_size = sizeof(struct sctp6_sock), .useroffset = offsetof(struct sctp6_sock, sctp.subscribe), .usersize = offsetof(struct sctp6_sock, sctp.initmsg) - -- GitLab From 61c1d33daf7b5146f44d4363b3322f8cda6a6c43 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Tue, 15 Oct 2019 16:42:45 +0200 Subject: [PATCH 357/993] net: i82596: fix dma_alloc_attr for sni_82596 Commit 7f683b920479 ("i825xx: switch to switch to dma_alloc_attrs") switched dma allocation over to dma_alloc_attr, but didn't convert the SNI part to request consistent DMA memory. This broke sni_82596 since driver doesn't do dma_cache_sync for performance reasons. Fix this by using different DMA_ATTRs for lasi_82596 and sni_82596. Fixes: 7f683b920479 ("i825xx: switch to switch to dma_alloc_attrs") Signed-off-by: Thomas Bogendoerfer Signed-off-by: David S. Miller --- drivers/net/ethernet/i825xx/lasi_82596.c | 4 +++- drivers/net/ethernet/i825xx/lib82596.c | 4 ++-- drivers/net/ethernet/i825xx/sni_82596.c | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/i825xx/lasi_82596.c b/drivers/net/ethernet/i825xx/lasi_82596.c index 211c5f74b4c8..aec7e98bcc85 100644 --- a/drivers/net/ethernet/i825xx/lasi_82596.c +++ b/drivers/net/ethernet/i825xx/lasi_82596.c @@ -96,6 +96,8 @@ #define OPT_SWAP_PORT 0x0001 /* Need to wordswp on the MPU port */ +#define LIB82596_DMA_ATTR DMA_ATTR_NON_CONSISTENT + #define DMA_WBACK(ndev, addr, len) \ do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_TO_DEVICE); } while (0) @@ -200,7 +202,7 @@ static int __exit lan_remove_chip(struct parisc_device *pdev) unregister_netdev (dev); dma_free_attrs(&pdev->dev, sizeof(struct i596_private), lp->dma, - lp->dma_addr, DMA_ATTR_NON_CONSISTENT); + lp->dma_addr, LIB82596_DMA_ATTR); free_netdev (dev); return 0; } diff --git a/drivers/net/ethernet/i825xx/lib82596.c b/drivers/net/ethernet/i825xx/lib82596.c index 1274ad24d6af..f9742af7f142 100644 --- a/drivers/net/ethernet/i825xx/lib82596.c +++ b/drivers/net/ethernet/i825xx/lib82596.c @@ -1065,7 +1065,7 @@ static int i82596_probe(struct net_device *dev) dma = dma_alloc_attrs(dev->dev.parent, sizeof(struct i596_dma), &lp->dma_addr, GFP_KERNEL, - DMA_ATTR_NON_CONSISTENT); + LIB82596_DMA_ATTR); if (!dma) { printk(KERN_ERR "%s: Couldn't get shared memory\n", __FILE__); return -ENOMEM; @@ -1087,7 +1087,7 @@ static int i82596_probe(struct net_device *dev) i = register_netdev(dev); if (i) { dma_free_attrs(dev->dev.parent, sizeof(struct i596_dma), - dma, lp->dma_addr, DMA_ATTR_NON_CONSISTENT); + dma, lp->dma_addr, LIB82596_DMA_ATTR); return i; } diff --git a/drivers/net/ethernet/i825xx/sni_82596.c b/drivers/net/ethernet/i825xx/sni_82596.c index 6eb6c2ff7f09..6436a98c5953 100644 --- a/drivers/net/ethernet/i825xx/sni_82596.c +++ b/drivers/net/ethernet/i825xx/sni_82596.c @@ -24,6 +24,8 @@ static const char sni_82596_string[] = "snirm_82596"; +#define LIB82596_DMA_ATTR 0 + #define DMA_WBACK(priv, addr, len) do { } while (0) #define DMA_INV(priv, addr, len) do { } while (0) #define DMA_WBACK_INV(priv, addr, len) do { } while (0) @@ -152,7 +154,7 @@ static int sni_82596_driver_remove(struct platform_device *pdev) unregister_netdev(dev); dma_free_attrs(dev->dev.parent, sizeof(struct i596_private), lp->dma, - lp->dma_addr, DMA_ATTR_NON_CONSISTENT); + lp->dma_addr, LIB82596_DMA_ATTR); iounmap(lp->ca); iounmap(lp->mpu_port); free_netdev (dev); -- GitLab From 539825a536040e09a2f26eb54bef206e8e8086b5 Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Tue, 15 Oct 2019 17:15:58 +0100 Subject: [PATCH 358/993] davinci_cpdma: make cpdma_chan_split_pool static The cpdma_chan_split_pool() function is not used outside of the driver, so make it static to avoid the following sparse warning: drivers/net/ethernet/ti/davinci_cpdma.c:725:5: warning: symbol 'cpdma_chan_split_pool' was not declared. Should it be static? Signed-off-by: Ben Dooks Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/davinci_cpdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c index a65edd2770e6..37ba708ac781 100644 --- a/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/drivers/net/ethernet/ti/davinci_cpdma.c @@ -722,7 +722,7 @@ static void cpdma_chan_set_descs(struct cpdma_ctlr *ctlr, * cpdma_chan_split_pool - Splits ctrl pool between all channels. * Has to be called under ctlr lock */ -int cpdma_chan_split_pool(struct cpdma_ctlr *ctlr) +static int cpdma_chan_split_pool(struct cpdma_ctlr *ctlr) { int tx_per_ch_desc = 0, rx_per_ch_desc = 0; int free_rx_num = 0, free_tx_num = 0; -- GitLab From bad28d889caea00bc9415c59fa6a433a72eeaf5e Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Tue, 15 Oct 2019 17:17:48 +0100 Subject: [PATCH 359/993] net: stmmac: make tc_flow_parsers static The tc_flow_parsers is not used outside of the driver, so make it static to avoid the following sparse warning: drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:516:3: warning: symbol 'tc_flow_parsers' was not declared. Should it be static? Signed-off-by: Ben Dooks Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c index e231098061b6..f9a9a9d82233 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c @@ -510,7 +510,7 @@ static struct stmmac_flow_entry *tc_find_flow(struct stmmac_priv *priv, return NULL; } -struct { +static struct { int (*fn)(struct stmmac_priv *priv, struct flow_cls_offload *cls, struct stmmac_flow_entry *entry); } tc_flow_parsers[] = { -- GitLab From efb86fede98cdc70b674692ff617b1162f642c49 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 15 Oct 2019 10:45:47 -0700 Subject: [PATCH 360/993] net: bcmgenet: Fix RGMII_MODE_EN value for GENET v1/2/3 The RGMII_MODE_EN bit value was 0 for GENET versions 1 through 3, and became 6 for GENET v4 and above, account for that difference. Fixes: aa09677cba42 ("net: bcmgenet: add MDIO routines") Signed-off-by: Florian Fainelli Acked-by: Doug Berger Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.h | 1 + drivers/net/ethernet/broadcom/genet/bcmmii.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 4a8fc03d82fd..dbc69d8fa05f 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -366,6 +366,7 @@ struct bcmgenet_mib_counters { #define EXT_PWR_DOWN_PHY_EN (1 << 20) #define EXT_RGMII_OOB_CTRL 0x0C +#define RGMII_MODE_EN_V123 (1 << 0) #define RGMII_LINK (1 << 4) #define OOB_DISABLE (1 << 5) #define RGMII_MODE_EN (1 << 6) diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index 94d1dd5d56bf..e7c291bf4ed1 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -258,7 +258,11 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) */ if (priv->ext_phy) { reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL); - reg |= RGMII_MODE_EN | id_mode_dis; + reg |= id_mode_dis; + if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv)) + reg |= RGMII_MODE_EN_V123; + else + reg |= RGMII_MODE_EN; bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); } -- GitLab From 77b6d09f4ae66d42cd63b121af67780ae3d1a5e9 Mon Sep 17 00:00:00 2001 From: Valentin Vidic Date: Tue, 15 Oct 2019 22:20:20 +0200 Subject: [PATCH 361/993] net: usb: sr9800: fix uninitialized local variable Make sure res does not contain random value if the call to sr_read_cmd fails for some reason. Reported-by: syzbot+f1842130bbcfb335bac1@syzkaller.appspotmail.com Signed-off-by: Valentin Vidic Signed-off-by: David S. Miller --- drivers/net/usb/sr9800.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/usb/sr9800.c b/drivers/net/usb/sr9800.c index c5d4a0060124..681e0def6356 100644 --- a/drivers/net/usb/sr9800.c +++ b/drivers/net/usb/sr9800.c @@ -335,7 +335,7 @@ static void sr_set_multicast(struct net_device *net) static int sr_mdio_read(struct net_device *net, int phy_id, int loc) { struct usbnet *dev = netdev_priv(net); - __le16 res; + __le16 res = 0; mutex_lock(&dev->phy_mutex); sr_set_sw_mii(dev); -- GitLab From 5bf4e52ff0317db083fafee010dc806f8d4cb0cb Mon Sep 17 00:00:00 2001 From: Greentime Hu Date: Tue, 8 Oct 2019 14:45:24 +0800 Subject: [PATCH 362/993] RISC-V: fix virtual address overlapped in FIXADDR_START and VMEMMAP_START This patch fixes the virtual address layout in pgtable.h. The virtual address of FIXADDR_START and VMEMMAP_START should not be overlapped. Fixes: d95f1a542c3d ("RISC-V: Implement sparsemem") Signed-off-by: Greentime Hu Reviewed-by: Anup Patel [paul.walmsley@sifive.com: fixed patch description] Signed-off-by: Paul Walmsley --- arch/riscv/include/asm/pgtable.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 7255f2d8395b..42292d99cc74 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -87,14 +87,6 @@ extern pgd_t swapper_pg_dir[]; #define VMALLOC_END (PAGE_OFFSET - 1) #define VMALLOC_START (PAGE_OFFSET - VMALLOC_SIZE) -#define FIXADDR_TOP VMALLOC_START -#ifdef CONFIG_64BIT -#define FIXADDR_SIZE PMD_SIZE -#else -#define FIXADDR_SIZE PGDIR_SIZE -#endif -#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) - /* * Roughly size the vmemmap space to be large enough to fit enough * struct pages to map half the virtual address space. Then @@ -108,6 +100,14 @@ extern pgd_t swapper_pg_dir[]; #define vmemmap ((struct page *)VMEMMAP_START) +#define FIXADDR_TOP (VMEMMAP_START) +#ifdef CONFIG_64BIT +#define FIXADDR_SIZE PMD_SIZE +#else +#define FIXADDR_SIZE PGDIR_SIZE +#endif +#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) + /* * ZERO_PAGE is a global shared page that is always zero, * used for zero-mapped memory areas, etc. -- GitLab From 16ff7bf6dbcc6f77d2eec1ac9120edf44213c2f1 Mon Sep 17 00:00:00 2001 From: Zhang Lixu Date: Wed, 16 Oct 2019 08:15:59 +0800 Subject: [PATCH 363/993] HID: intel-ish-hid: fix wrong error handling in ishtp_cl_alloc_tx_ring() When allocating tx ring buffers failed, should free tx buffers, not rx buffers. Signed-off-by: Zhang Lixu Acked-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ishtp/client-buffers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/intel-ish-hid/ishtp/client-buffers.c b/drivers/hid/intel-ish-hid/ishtp/client-buffers.c index 1b0a0cc605e7..513d7a4a1b8a 100644 --- a/drivers/hid/intel-ish-hid/ishtp/client-buffers.c +++ b/drivers/hid/intel-ish-hid/ishtp/client-buffers.c @@ -84,7 +84,7 @@ int ishtp_cl_alloc_tx_ring(struct ishtp_cl *cl) return 0; out: dev_err(&cl->device->dev, "error in allocating Tx pool\n"); - ishtp_cl_free_rx_ring(cl); + ishtp_cl_free_tx_ring(cl); return -ENOMEM; } -- GitLab From 775fd6bfefc66a8c33e91dd9687ed530643b954d Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 15 Oct 2019 21:51:43 -0700 Subject: [PATCH 364/993] xtensa: fix change_bit in exclusive access option change_bit implementation for XCHAL_HAVE_EXCLUSIVE case changes all bits except the one required due to copy-paste error from clear_bit. Cc: stable@vger.kernel.org # v5.2+ Fixes: f7c34874f04a ("xtensa: add exclusive atomics support") Signed-off-by: Max Filippov --- arch/xtensa/include/asm/bitops.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/xtensa/include/asm/bitops.h b/arch/xtensa/include/asm/bitops.h index aeb15f4c755b..be8b2be5a98b 100644 --- a/arch/xtensa/include/asm/bitops.h +++ b/arch/xtensa/include/asm/bitops.h @@ -148,7 +148,7 @@ static inline void change_bit(unsigned int bit, volatile unsigned long *p) " getex %0\n" " beqz %0, 1b\n" : "=&a" (tmp) - : "a" (~mask), "a" (p) + : "a" (mask), "a" (p) : "memory"); } -- GitLab From 6f1d1dc8d540a9aa6e39b9cb86d3a67bbc1c8d8d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 11 Oct 2019 11:57:35 +0200 Subject: [PATCH 365/993] USB: serial: ti_usb_3410_5052: fix port-close races Fix races between closing a port and opening or closing another port on the same device which could lead to a failure to start or stop the shared interrupt URB. The latter could potentially cause a use-after-free or worse in the completion handler on driver unbind. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable Signed-off-by: Johan Hovold --- drivers/usb/serial/ti_usb_3410_5052.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index dd0ad67aa71e..9174ba2e06da 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -776,7 +776,6 @@ static void ti_close(struct usb_serial_port *port) struct ti_port *tport; int port_number; int status; - int do_unlock; unsigned long flags; tdev = usb_get_serial_data(port->serial); @@ -800,16 +799,13 @@ static void ti_close(struct usb_serial_port *port) "%s - cannot send close port command, %d\n" , __func__, status); - /* if mutex_lock is interrupted, continue anyway */ - do_unlock = !mutex_lock_interruptible(&tdev->td_open_close_lock); + mutex_lock(&tdev->td_open_close_lock); --tport->tp_tdev->td_open_port_count; - if (tport->tp_tdev->td_open_port_count <= 0) { + if (tport->tp_tdev->td_open_port_count == 0) { /* last port is closed, shut down interrupt urb */ usb_kill_urb(port->serial->port[0]->interrupt_in_urb); - tport->tp_tdev->td_open_port_count = 0; } - if (do_unlock) - mutex_unlock(&tdev->td_open_close_lock); + mutex_unlock(&tdev->td_open_close_lock); } -- GitLab From bc25770f00d3f4e7482278f9823c2c2793605484 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 11 Oct 2019 11:57:36 +0200 Subject: [PATCH 366/993] USB: serial: ti_usb_3410_5052: clean up serial data access Use the tdev pointer directly instead of going through the port data when accessing the serial data in close(). Signed-off-by: Johan Hovold --- drivers/usb/serial/ti_usb_3410_5052.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 9174ba2e06da..ef23acc9b9ce 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -800,8 +800,8 @@ static void ti_close(struct usb_serial_port *port) , __func__, status); mutex_lock(&tdev->td_open_close_lock); - --tport->tp_tdev->td_open_port_count; - if (tport->tp_tdev->td_open_port_count == 0) { + --tdev->td_open_port_count; + if (tdev->td_open_port_count == 0) { /* last port is closed, shut down interrupt urb */ usb_kill_urb(port->serial->port[0]->interrupt_in_urb); } -- GitLab From 2d8b39a62a5d386a73f339e46fe05354a3a4895b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 15 Oct 2019 19:35:20 +0200 Subject: [PATCH 367/993] ACPI: processor: Avoid NULL pointer dereferences at init time If there are neither processor objects nor processor device objects in the ACPI tables, the per-CPU processors table will not be initialized and attempting to dereference pointers from there will cause the kernel to crash. This happens in acpi_processor_ppc_init() and acpi_thermal_cpufreq_init() after commit d15ce412737a ("ACPI: cpufreq: Switch to QoS requests instead of cpufreq notifier") which didn't add the requisite NULL pointer checks in there. Add the NULL pointer checks to acpi_processor_ppc_init() and acpi_thermal_cpufreq_init(), and to the corresponding "exit" routines. While at it, drop redundant return instructions from acpi_processor_ppc_init() and acpi_thermal_cpufreq_init(). Fixes: d15ce412737a ("ACPI: cpufreq: Switch to QoS requests instead of cpufreq notifier") Reported-by: Srinivas Pandruvada Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar --- drivers/acpi/processor_perflib.c | 10 ++++++---- drivers/acpi/processor_thermal.c | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 2261713d1aec..930a49fa4dfc 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -162,21 +162,23 @@ void acpi_processor_ppc_init(int cpu) struct acpi_processor *pr = per_cpu(processors, cpu); int ret; + if (!pr) + return; + ret = dev_pm_qos_add_request(get_cpu_device(cpu), &pr->perflib_req, DEV_PM_QOS_MAX_FREQUENCY, INT_MAX); - if (ret < 0) { + if (ret < 0) pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, ret); - return; - } } void acpi_processor_ppc_exit(int cpu) { struct acpi_processor *pr = per_cpu(processors, cpu); - dev_pm_qos_remove_request(&pr->perflib_req); + if (pr) + dev_pm_qos_remove_request(&pr->perflib_req); } static int acpi_processor_get_performance_control(struct acpi_processor *pr) diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index ec2638f1df4f..8227c7dd75b1 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -130,21 +130,23 @@ void acpi_thermal_cpufreq_init(int cpu) struct acpi_processor *pr = per_cpu(processors, cpu); int ret; + if (!pr) + return; + ret = dev_pm_qos_add_request(get_cpu_device(cpu), &pr->thermal_req, DEV_PM_QOS_MAX_FREQUENCY, INT_MAX); - if (ret < 0) { + if (ret < 0) pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, ret); - return; - } } void acpi_thermal_cpufreq_exit(int cpu) { struct acpi_processor *pr = per_cpu(processors, cpu); - dev_pm_qos_remove_request(&pr->thermal_req); + if (pr) + dev_pm_qos_remove_request(&pr->thermal_req); } #else /* ! CONFIG_CPU_FREQ */ static int cpufreq_get_max_state(unsigned int cpu) -- GitLab From 8f1c9dffe30b04219690f8e94a27b2ab977a66f2 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Fri, 11 Oct 2019 07:55:45 +0000 Subject: [PATCH 368/993] pinctrl: berlin: as370: fix a typo s/spififib/spdifib The function should be spdifib, fix this typo. Fixes: 423ddc580b13 ("pinctrl: berlin: add the as370 SoC pinctrl driver") Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20191011154321.44f08f9a@xhacker.debian Signed-off-by: Linus Walleij --- drivers/pinctrl/berlin/pinctrl-as370.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/berlin/pinctrl-as370.c b/drivers/pinctrl/berlin/pinctrl-as370.c index 44f8ccdbeeff..9dfdc275ee33 100644 --- a/drivers/pinctrl/berlin/pinctrl-as370.c +++ b/drivers/pinctrl/berlin/pinctrl-as370.c @@ -43,7 +43,7 @@ static const struct berlin_desc_group as370_soc_pinctrl_groups[] = { BERLIN_PINCTRL_FUNCTION(0x0, "gpio"), /* GPIO5 */ BERLIN_PINCTRL_FUNCTION(0x1, "i2s1"), /* DO3 */ BERLIN_PINCTRL_FUNCTION(0x2, "pwm"), /* PWM5 */ - BERLIN_PINCTRL_FUNCTION(0x3, "spififib"), /* SPDIFIB */ + BERLIN_PINCTRL_FUNCTION(0x3, "spdifib"), /* SPDIFIB */ BERLIN_PINCTRL_FUNCTION(0x4, "spdifo"), /* SPDIFO */ BERLIN_PINCTRL_FUNCTION(0x5, "phy")), /* DBG5 */ BERLIN_PINCTRL_GROUP("I2S1_MCLK", 0x0, 0x3, 0x12, -- GitLab From f418dddffc8007945fd5962380ebde770a240cf5 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 16 Oct 2019 23:27:32 +1100 Subject: [PATCH 369/993] usercopy: Avoid soft lockups in test_check_nonzero_user() On a machine with a 64K PAGE_SIZE, the nested for loops in test_check_nonzero_user() can lead to soft lockups, eg: watchdog: BUG: soft lockup - CPU#4 stuck for 22s! [modprobe:611] Modules linked in: test_user_copy(+) vmx_crypto gf128mul crc32c_vpmsum virtio_balloon ip_tables x_tables autofs4 CPU: 4 PID: 611 Comm: modprobe Tainted: G L 5.4.0-rc1-gcc-8.2.0-00001-gf5a1a536fa14-dirty #1151 ... NIP __might_sleep+0x20/0xc0 LR __might_fault+0x40/0x60 Call Trace: check_zeroed_user+0x12c/0x200 test_user_copy_init+0x67c/0x1210 [test_user_copy] do_one_initcall+0x60/0x340 do_init_module+0x7c/0x2f0 load_module+0x2d94/0x30e0 __do_sys_finit_module+0xc8/0x150 system_call+0x5c/0x68 Even with a 4K PAGE_SIZE the test takes multiple seconds. Instead tweak it to only scan a 1024 byte region, but make it cross the page boundary. Fixes: f5a1a536fa14 ("lib: introduce copy_struct_from_user() helper") Suggested-by: Aleksa Sarai Signed-off-by: Michael Ellerman Reviewed-by: Aleksa Sarai Acked-by: Christian Brauner Link: https://lore.kernel.org/r/20191016122732.13467-1-mpe@ellerman.id.au Signed-off-by: Christian Brauner --- lib/test_user_copy.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/test_user_copy.c b/lib/test_user_copy.c index ad2372727b1b..5ff04d8fe971 100644 --- a/lib/test_user_copy.c +++ b/lib/test_user_copy.c @@ -47,9 +47,25 @@ static bool is_zeroed(void *from, size_t size) static int test_check_nonzero_user(char *kmem, char __user *umem, size_t size) { int ret = 0; - size_t start, end, i; - size_t zero_start = size / 4; - size_t zero_end = size - zero_start; + size_t start, end, i, zero_start, zero_end; + + if (test(size < 2 * PAGE_SIZE, "buffer too small")) + return -EINVAL; + + /* + * We want to cross a page boundary to exercise the code more + * effectively. We also don't want to make the size we scan too large, + * otherwise the test can take a long time and cause soft lockups. So + * scan a 1024 byte region across the page boundary. + */ + size = 1024; + start = PAGE_SIZE - (size / 2); + + kmem += start; + umem += start; + + zero_start = size / 4; + zero_end = size - zero_start; /* * We conduct a series of check_nonzero_user() tests on a block of -- GitLab From 1abecfcaa7bba21c9985e0136fa49836164dd8fd Mon Sep 17 00:00:00 2001 From: Yunfeng Ye Date: Wed, 16 Oct 2019 16:38:45 +0800 Subject: [PATCH 370/993] perf kmem: Fix memory leak in compact_gfp_flags() The memory @orig_flags is allocated by strdup(), it is freed on the normal path, but leak to free on the error path. Fix this by adding free(orig_flags) on the error path. Fixes: 0e11115644b3 ("perf kmem: Print gfp flags in human readable string") Signed-off-by: Yunfeng Ye Cc: Alexander Shishkin Cc: Feilong Lin Cc: Hu Shiyuan Cc: Jiri Olsa Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/f9e9f458-96f3-4a97-a1d5-9feec2420e07@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kmem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 1e61e353f579..9661671cc26e 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -691,6 +691,7 @@ static char *compact_gfp_flags(char *gfp_flags) new = realloc(new_flags, len + strlen(cpt) + 2); if (new == NULL) { free(new_flags); + free(orig_flags); return NULL; } -- GitLab From 9091a0698be23561b2e1898139a62f8ba6d61d2d Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Tue, 8 Oct 2019 15:11:47 +1030 Subject: [PATCH 371/993] dt-bindings: pinctrl: aspeed-g6: Rework SD3 function and groups Rename SD3 functions and groups to EMMC to better reflect their intended use before the binding escapes too far into the wild. Also clean up the SD3 pin groups to eliminate some silliness that slipped through the cracks (SD3DAT[4-7]) by unifying them into three new groups: EMMCG1, EMMCG4 and EMMCG8 for 1, 4 and 8-bit data buses respectively. Signed-off-by: Andrew Jeffery Link: https://lore.kernel.org/r/20191008044153.12734-2-andrew@aj.id.au Reviewed-by: Rob Herring Reviewed-by: Joel Stanley Signed-off-by: Linus Walleij --- .../pinctrl/aspeed,ast2600-pinctrl.yaml | 86 +++++++++---------- 1 file changed, 42 insertions(+), 44 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml index f83d888176cc..064b7dfc4252 100644 --- a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml @@ -33,13 +33,13 @@ patternProperties: allOf: - $ref: "/schemas/types.yaml#/definitions/string" - enum: [ ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14, ADC15, - ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, ESPI, - ESPIALT, FSI1, FSI2, FWSPIABR, FWSPID, FWSPIWP, GPIT0, GPIT1, - GPIT2, GPIT3, GPIT4, GPIT5, GPIT6, GPIT7, GPIU0, GPIU1, GPIU2, - GPIU3, GPIU4, GPIU5, GPIU6, GPIU7, I2C1, I2C10, I2C11, I2C12, - I2C13, I2C14, I2C15, I2C16, I2C2, I2C3, I2C4, I2C5, I2C6, I2C7, - I2C8, I2C9, I3C3, I3C4, I3C5, I3C6, JTAGM, LHPD, LHSIRQ, LPC, - LPCHC, LPCPD, LPCPME, LPCSMI, LSIRQ, MACLINK1, MACLINK2, + ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, EMMC, + ESPI, ESPIALT, FSI1, FSI2, FWSPIABR, FWSPID, FWSPIWP, GPIT0, + GPIT1, GPIT2, GPIT3, GPIT4, GPIT5, GPIT6, GPIT7, GPIU0, GPIU1, + GPIU2, GPIU3, GPIU4, GPIU5, GPIU6, GPIU7, I2C1, I2C10, I2C11, + I2C12, I2C13, I2C14, I2C15, I2C16, I2C2, I2C3, I2C4, I2C5, I2C6, + I2C7, I2C8, I2C9, I3C3, I3C4, I3C5, I3C6, JTAGM, LHPD, LHSIRQ, + LPC, LPCHC, LPCPD, LPCPME, LPCSMI, LSIRQ, MACLINK1, MACLINK2, MACLINK3, MACLINK4, MDIO1, MDIO2, MDIO3, MDIO4, NCTS1, NCTS2, NCTS3, NCTS4, NDCD1, NDCD2, NDCD3, NDCD4, NDSR1, NDSR2, NDSR3, NDSR4, NDTR1, NDTR2, NDTR3, NDTR4, NRI1, NRI2, NRI3, NRI4, NRTS1, @@ -48,47 +48,45 @@ patternProperties: PWM8, PWM9, RGMII1, RGMII2, RGMII3, RGMII4, RMII1, RMII2, RMII3, RMII4, RXD1, RXD2, RXD3, RXD4, SALT1, SALT10, SALT11, SALT12, SALT13, SALT14, SALT15, SALT16, SALT2, SALT3, SALT4, SALT5, - SALT6, SALT7, SALT8, SALT9, SD1, SD2, SD3, SD3DAT4, SD3DAT5, - SD3DAT6, SD3DAT7, SGPM1, SGPS1, SIOONCTRL, SIOPBI, SIOPBO, - SIOPWREQ, SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, SPI1ABR, SPI1CS1, - SPI1WP, SPI2, SPI2CS1, SPI2CS2, TACH0, TACH1, TACH10, TACH11, - TACH12, TACH13, TACH14, TACH15, TACH2, TACH3, TACH4, TACH5, - TACH6, TACH7, TACH8, TACH9, THRU0, THRU1, THRU2, THRU3, TXD1, - TXD2, TXD3, TXD4, UART10, UART11, UART12, UART13, UART6, UART7, - UART8, UART9, VB, VGAHS, VGAVS, WDTRST1, WDTRST2, WDTRST3, - WDTRST4, ] + SALT6, SALT7, SALT8, SALT9, SD1, SD2, SGPM1, SGPS1, SIOONCTRL, + SIOPBI, SIOPBO, SIOPWREQ, SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, + SPI1ABR, SPI1CS1, SPI1WP, SPI2, SPI2CS1, SPI2CS2, TACH0, TACH1, + TACH10, TACH11, TACH12, TACH13, TACH14, TACH15, TACH2, TACH3, + TACH4, TACH5, TACH6, TACH7, TACH8, TACH9, THRU0, THRU1, THRU2, + THRU3, TXD1, TXD2, TXD3, TXD4, UART10, UART11, UART12, UART13, + UART6, UART7, UART8, UART9, VB, VGAHS, VGAVS, WDTRST1, WDTRST2, + WDTRST3, WDTRST4, ] groups: allOf: - $ref: "/schemas/types.yaml#/definitions/string" - enum: [ ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14, ADC15, - ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, ESPI, - ESPIALT, FSI1, FSI2, FWSPIABR, FWSPID, FWQSPID, FWSPIWP, GPIT0, - GPIT1, GPIT2, GPIT3, GPIT4, GPIT5, GPIT6, GPIT7, GPIU0, GPIU1, - GPIU2, GPIU3, GPIU4, GPIU5, GPIU6, GPIU7, HVI3C3, HVI3C4, I2C1, - I2C10, I2C11, I2C12, I2C13, I2C14, I2C15, I2C16, I2C2, I2C3, - I2C4, I2C5, I2C6, I2C7, I2C8, I2C9, I3C3, I3C4, I3C5, I3C6, - JTAGM, LHPD, LHSIRQ, LPC, LPCHC, LPCPD, LPCPME, LPCSMI, LSIRQ, - MACLINK1, MACLINK2, MACLINK3, MACLINK4, MDIO1, MDIO2, MDIO3, - MDIO4, NCTS1, NCTS2, NCTS3, NCTS4, NDCD1, NDCD2, NDCD3, NDCD4, - NDSR1, NDSR2, NDSR3, NDSR4, NDTR1, NDTR2, NDTR3, NDTR4, NRI1, - NRI2, NRI3, NRI4, NRTS1, NRTS2, NRTS3, NRTS4, OSCCLK, PEWAKE, - PWM0, PWM1, PWM10G0, PWM10G1, PWM11G0, PWM11G1, PWM12G0, PWM12G1, - PWM13G0, PWM13G1, PWM14G0, PWM14G1, PWM15G0, PWM15G1, PWM2, PWM3, - PWM4, PWM5, PWM6, PWM7, PWM8G0, PWM8G1, PWM9G0, PWM9G1, QSPI1, - QSPI2, RGMII1, RGMII2, RGMII3, RGMII4, RMII1, RMII2, RMII3, - RMII4, RXD1, RXD2, RXD3, RXD4, SALT1, SALT10G0, SALT10G1, - SALT11G0, SALT11G1, SALT12G0, SALT12G1, SALT13G0, SALT13G1, - SALT14G0, SALT14G1, SALT15G0, SALT15G1, SALT16G0, SALT16G1, - SALT2, SALT3, SALT4, SALT5, SALT6, SALT7, SALT8, SALT9G0, - SALT9G1, SD1, SD2, SD3, SD3DAT4, SD3DAT5, SD3DAT6, SD3DAT7, - SGPM1, SGPS1, SIOONCTRL, SIOPBI, SIOPBO, SIOPWREQ, SIOPWRGD, - SIOS3, SIOS5, SIOSCI, SPI1, SPI1ABR, SPI1CS1, SPI1WP, SPI2, - SPI2CS1, SPI2CS2, TACH0, TACH1, TACH10, TACH11, TACH12, TACH13, - TACH14, TACH15, TACH2, TACH3, TACH4, TACH5, TACH6, TACH7, TACH8, - TACH9, THRU0, THRU1, THRU2, THRU3, TXD1, TXD2, TXD3, TXD4, - UART10, UART11, UART12G0, UART12G1, UART13G0, UART13G1, UART6, - UART7, UART8, UART9, VB, VGAHS, VGAVS, WDTRST1, WDTRST2, WDTRST3, - WDTRST4, ] + ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, EMMCG1, + EMMCG4, EMMCG8, ESPI, ESPIALT, FSI1, FSI2, FWSPIABR, FWSPID, + FWQSPID, FWSPIWP, GPIT0, GPIT1, GPIT2, GPIT3, GPIT4, GPIT5, + GPIT6, GPIT7, GPIU0, GPIU1, GPIU2, GPIU3, GPIU4, GPIU5, GPIU6, + GPIU7, HVI3C3, HVI3C4, I2C1, I2C10, I2C11, I2C12, I2C13, I2C14, + I2C15, I2C16, I2C2, I2C3, I2C4, I2C5, I2C6, I2C7, I2C8, I2C9, + I3C3, I3C4, I3C5, I3C6, JTAGM, LHPD, LHSIRQ, LPC, LPCHC, LPCPD, + LPCPME, LPCSMI, LSIRQ, MACLINK1, MACLINK2, MACLINK3, MACLINK4, + MDIO1, MDIO2, MDIO3, MDIO4, NCTS1, NCTS2, NCTS3, NCTS4, NDCD1, + NDCD2, NDCD3, NDCD4, NDSR1, NDSR2, NDSR3, NDSR4, NDTR1, NDTR2, + NDTR3, NDTR4, NRI1, NRI2, NRI3, NRI4, NRTS1, NRTS2, NRTS3, NRTS4, + OSCCLK, PEWAKE, PWM0, PWM1, PWM10G0, PWM10G1, PWM11G0, PWM11G1, + PWM12G0, PWM12G1, PWM13G0, PWM13G1, PWM14G0, PWM14G1, PWM15G0, + PWM15G1, PWM2, PWM3, PWM4, PWM5, PWM6, PWM7, PWM8G0, PWM8G1, + PWM9G0, PWM9G1, QSPI1, QSPI2, RGMII1, RGMII2, RGMII3, RGMII4, + RMII1, RMII2, RMII3, RMII4, RXD1, RXD2, RXD3, RXD4, SALT1, + SALT10G0, SALT10G1, SALT11G0, SALT11G1, SALT12G0, SALT12G1, + SALT13G0, SALT13G1, SALT14G0, SALT14G1, SALT15G0, SALT15G1, + SALT16G0, SALT16G1, SALT2, SALT3, SALT4, SALT5, SALT6, SALT7, + SALT8, SALT9G0, SALT9G1, SD1, SD2, SD3, SGPM1, SGPS1, SIOONCTRL, + SIOPBI, SIOPBO, SIOPWREQ, SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, + SPI1ABR, SPI1CS1, SPI1WP, SPI2, SPI2CS1, SPI2CS2, TACH0, TACH1, + TACH10, TACH11, TACH12, TACH13, TACH14, TACH15, TACH2, TACH3, + TACH4, TACH5, TACH6, TACH7, TACH8, TACH9, THRU0, THRU1, THRU2, + THRU3, TXD1, TXD2, TXD3, TXD4, UART10, UART11, UART12G0, + UART12G1, UART13G0, UART13G1, UART6, UART7, UART8, UART9, VB, + VGAHS, VGAVS, WDTRST1, WDTRST2, WDTRST3, WDTRST4, ] required: - compatible -- GitLab From 377dfcdcc0469b6b38f7943de63a13132b066679 Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Tue, 8 Oct 2019 15:11:48 +1030 Subject: [PATCH 372/993] pinctrl: aspeed-g6: Sort pins for sanity Some pins crept in that weren't ordered in the list. Signed-off-by: Andrew Jeffery Link: https://lore.kernel.org/r/20191008044153.12734-3-andrew@aj.id.au Reviewed-by: Joel Stanley Signed-off-by: Linus Walleij --- drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c index 648ddb7f038a..ff208b7c75a8 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c @@ -1574,6 +1574,8 @@ static struct pinctrl_pin_desc aspeed_g6_pins[ASPEED_G6_NR_PINS] = { ASPEED_PINCTRL_PIN(A3), ASPEED_PINCTRL_PIN(AA11), ASPEED_PINCTRL_PIN(AA12), + ASPEED_PINCTRL_PIN(AA16), + ASPEED_PINCTRL_PIN(AA17), ASPEED_PINCTRL_PIN(AA23), ASPEED_PINCTRL_PIN(AA24), ASPEED_PINCTRL_PIN(AA25), @@ -1585,6 +1587,8 @@ static struct pinctrl_pin_desc aspeed_g6_pins[ASPEED_G6_NR_PINS] = { ASPEED_PINCTRL_PIN(AB11), ASPEED_PINCTRL_PIN(AB12), ASPEED_PINCTRL_PIN(AB15), + ASPEED_PINCTRL_PIN(AB16), + ASPEED_PINCTRL_PIN(AB17), ASPEED_PINCTRL_PIN(AB18), ASPEED_PINCTRL_PIN(AB19), ASPEED_PINCTRL_PIN(AB22), @@ -1602,6 +1606,7 @@ static struct pinctrl_pin_desc aspeed_g6_pins[ASPEED_G6_NR_PINS] = { ASPEED_PINCTRL_PIN(AC11), ASPEED_PINCTRL_PIN(AC12), ASPEED_PINCTRL_PIN(AC15), + ASPEED_PINCTRL_PIN(AC16), ASPEED_PINCTRL_PIN(AC17), ASPEED_PINCTRL_PIN(AC18), ASPEED_PINCTRL_PIN(AC19), @@ -1619,6 +1624,7 @@ static struct pinctrl_pin_desc aspeed_g6_pins[ASPEED_G6_NR_PINS] = { ASPEED_PINCTRL_PIN(AD12), ASPEED_PINCTRL_PIN(AD14), ASPEED_PINCTRL_PIN(AD15), + ASPEED_PINCTRL_PIN(AD16), ASPEED_PINCTRL_PIN(AD19), ASPEED_PINCTRL_PIN(AD20), ASPEED_PINCTRL_PIN(AD22), @@ -1634,8 +1640,11 @@ static struct pinctrl_pin_desc aspeed_g6_pins[ASPEED_G6_NR_PINS] = { ASPEED_PINCTRL_PIN(AE12), ASPEED_PINCTRL_PIN(AE14), ASPEED_PINCTRL_PIN(AE15), + ASPEED_PINCTRL_PIN(AE16), ASPEED_PINCTRL_PIN(AE18), ASPEED_PINCTRL_PIN(AE19), + ASPEED_PINCTRL_PIN(AE25), + ASPEED_PINCTRL_PIN(AE26), ASPEED_PINCTRL_PIN(AE7), ASPEED_PINCTRL_PIN(AE8), ASPEED_PINCTRL_PIN(AF10), @@ -1643,6 +1652,8 @@ static struct pinctrl_pin_desc aspeed_g6_pins[ASPEED_G6_NR_PINS] = { ASPEED_PINCTRL_PIN(AF12), ASPEED_PINCTRL_PIN(AF14), ASPEED_PINCTRL_PIN(AF15), + ASPEED_PINCTRL_PIN(AF24), + ASPEED_PINCTRL_PIN(AF25), ASPEED_PINCTRL_PIN(AF7), ASPEED_PINCTRL_PIN(AF8), ASPEED_PINCTRL_PIN(AF9), @@ -1792,17 +1803,6 @@ static struct pinctrl_pin_desc aspeed_g6_pins[ASPEED_G6_NR_PINS] = { ASPEED_PINCTRL_PIN(Y3), ASPEED_PINCTRL_PIN(Y4), ASPEED_PINCTRL_PIN(Y5), - ASPEED_PINCTRL_PIN(AB16), - ASPEED_PINCTRL_PIN(AA17), - ASPEED_PINCTRL_PIN(AB17), - ASPEED_PINCTRL_PIN(AE16), - ASPEED_PINCTRL_PIN(AC16), - ASPEED_PINCTRL_PIN(AA16), - ASPEED_PINCTRL_PIN(AD16), - ASPEED_PINCTRL_PIN(AF25), - ASPEED_PINCTRL_PIN(AE26), - ASPEED_PINCTRL_PIN(AE25), - ASPEED_PINCTRL_PIN(AF24), }; static const struct aspeed_pin_group aspeed_g6_groups[] = { -- GitLab From b178f91f449caec552e66d9842dcc2090a2e0987 Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Tue, 8 Oct 2019 15:11:49 +1030 Subject: [PATCH 373/993] pinctrl: aspeed-g6: Fix I2C14 SDA description The I2C function the pin participated in was incorrectly named SDA14 which lead to a failure to mux: [ 6.884344] No function I2C14 found on pin 7 (7). Found signal(s) MACLINK4, SDA14, GPIOA7 for function(s) MACLINK4, SDA14, GPIOA7 Fixes: 58dc52ad00a0 ("pinctrl: aspeed: Add AST2600 pinmux support") Signed-off-by: Andrew Jeffery Link: https://lore.kernel.org/r/20191008044153.12734-4-andrew@aj.id.au Reviewed-by: Joel Stanley Signed-off-by: Linus Walleij --- drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c index ff208b7c75a8..9079655cc818 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c @@ -87,7 +87,7 @@ FUNC_GROUP_DECL(MACLINK3, L23); #define K25 7 SIG_EXPR_LIST_DECL_SESG(K25, MACLINK4, MACLINK4, SIG_DESC_SET(SCU410, 7)); -SIG_EXPR_LIST_DECL_SESG(K25, SDA14, SDA14, SIG_DESC_SET(SCU4B0, 7)); +SIG_EXPR_LIST_DECL_SESG(K25, SDA14, I2C14, SIG_DESC_SET(SCU4B0, 7)); PIN_DECL_2(K25, GPIOA7, MACLINK4, SDA14); FUNC_GROUP_DECL(MACLINK4, K25); -- GitLab From 9979346f5560956daf2a73da854e88d60a5309cf Mon Sep 17 00:00:00 2001 From: Johnny Huang Date: Tue, 8 Oct 2019 15:11:50 +1030 Subject: [PATCH 374/993] pinctrl: aspeed-g6: Fix I3C3/I3C4 pinmux configuration The documentation to configure I3C3/FSI1 and I3C4/FSI2 was initially unclear. Fixes: 58dc52ad00a0 ("pinctrl: aspeed: Add AST2600 pinmux support") Signed-off-by: Johnny Huang [AJ: Tweak commit message, resolve rebase conflicts] Signed-off-by: Andrew Jeffery Link: https://lore.kernel.org/r/20191008044153.12734-5-andrew@aj.id.au Reviewed-by: Joel Stanley Signed-off-by: Linus Walleij --- drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c | 24 ++++++++-------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c index 9079655cc818..68b066594461 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c @@ -1513,18 +1513,14 @@ FUNC_GROUP_DECL(VB, Y1, Y2, Y3, Y4); * following 4 pins */ #define AF25 244 -SIG_EXPR_LIST_DECL_SEMG(AF25, I3C3SCL, I3C3, I3C3, SIG_DESC_SET(SCU438, 20), - SIG_DESC_SET(SCU4D8, 20)); -SIG_EXPR_LIST_DECL_SESG(AF25, FSI1CLK, FSI1, SIG_DESC_CLEAR(SCU438, 20), - SIG_DESC_SET(SCU4D8, 20)); +SIG_EXPR_LIST_DECL_SEMG(AF25, I3C3SCL, I3C3, I3C3, SIG_DESC_SET(SCU438, 20)); +SIG_EXPR_LIST_DECL_SESG(AF25, FSI1CLK, FSI1, SIG_DESC_SET(SCU4D8, 20)); PIN_DECL_(AF25, SIG_EXPR_LIST_PTR(AF25, I3C3SCL), SIG_EXPR_LIST_PTR(AF25, FSI1CLK)); #define AE26 245 -SIG_EXPR_LIST_DECL_SEMG(AE26, I3C3SDA, I3C3, I3C3, SIG_DESC_SET(SCU438, 21), - SIG_DESC_SET(SCU4D8, 21)); -SIG_EXPR_LIST_DECL_SESG(AE26, FSI1DATA, FSI1, SIG_DESC_CLEAR(SCU438, 21), - SIG_DESC_SET(SCU4D8, 21)); +SIG_EXPR_LIST_DECL_SEMG(AE26, I3C3SDA, I3C3, I3C3, SIG_DESC_SET(SCU438, 21)); +SIG_EXPR_LIST_DECL_SESG(AE26, FSI1DATA, FSI1, SIG_DESC_SET(SCU4D8, 21)); PIN_DECL_(AE26, SIG_EXPR_LIST_PTR(AE26, I3C3SDA), SIG_EXPR_LIST_PTR(AE26, FSI1DATA)); @@ -1533,18 +1529,14 @@ FUNC_DECL_2(I3C3, HVI3C3, I3C3); FUNC_GROUP_DECL(FSI1, AF25, AE26); #define AE25 246 -SIG_EXPR_LIST_DECL_SEMG(AE25, I3C4SCL, I3C4, I3C4, SIG_DESC_SET(SCU438, 22), - SIG_DESC_SET(SCU4D8, 22)); -SIG_EXPR_LIST_DECL_SESG(AE25, FSI2CLK, FSI2, SIG_DESC_CLEAR(SCU438, 22), - SIG_DESC_SET(SCU4D8, 22)); +SIG_EXPR_LIST_DECL_SEMG(AE25, I3C4SCL, I3C4, I3C4, SIG_DESC_SET(SCU438, 22)); +SIG_EXPR_LIST_DECL_SESG(AE25, FSI2CLK, FSI2, SIG_DESC_SET(SCU4D8, 22)); PIN_DECL_(AE25, SIG_EXPR_LIST_PTR(AE25, I3C4SCL), SIG_EXPR_LIST_PTR(AE25, FSI2CLK)); #define AF24 247 -SIG_EXPR_LIST_DECL_SEMG(AF24, I3C4SDA, I3C4, I3C4, SIG_DESC_SET(SCU438, 23), - SIG_DESC_SET(SCU4D8, 23)); -SIG_EXPR_LIST_DECL_SESG(AF24, FSI2DATA, FSI2, SIG_DESC_CLEAR(SCU438, 23), - SIG_DESC_SET(SCU4D8, 23)); +SIG_EXPR_LIST_DECL_SEMG(AF24, I3C4SDA, I3C4, I3C4, SIG_DESC_SET(SCU438, 23)); +SIG_EXPR_LIST_DECL_SESG(AF24, FSI2DATA, FSI2, SIG_DESC_SET(SCU4D8, 23)); PIN_DECL_(AF24, SIG_EXPR_LIST_PTR(AF24, I3C4SDA), SIG_EXPR_LIST_PTR(AF24, FSI2DATA)); -- GitLab From c136d4c71f755a189fe13a0cd4f3e8f538dda567 Mon Sep 17 00:00:00 2001 From: Andrew Jeffery Date: Tue, 8 Oct 2019 15:11:51 +1030 Subject: [PATCH 375/993] pinctrl: aspeed-g6: Make SIG_DESC_CLEAR() behave intuitively Signal descriptors can represent multi-bit bitfields and so have explicit "enable" and "disable" states. However many descriptor instances only describe a single bit, and so the SIG_DESC_SET() macro is provides an abstraction for the single-bit cases: Its expansion configures the "enable" state to set the bit and "disable" to clear. SIG_DESC_CLEAR() was introduced to provide a similar single-bit abstraction for for descriptors to clear the bit of interest. However its behaviour was defined as the literal inverse of SIG_DESC_SET() - the impact is the bit of interest is set in the disable path. This behaviour isn't intuitive and doesn't align with how we want to use the macro in practice, so make it clear the bit for both the enable and disable paths. Signed-off-by: Andrew Jeffery Link: https://lore.kernel.org/r/20191008044153.12734-6-andrew@aj.id.au Reviewed-by: Joel Stanley Signed-off-by: Linus Walleij --- drivers/pinctrl/aspeed/pinmux-aspeed.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/aspeed/pinmux-aspeed.h b/drivers/pinctrl/aspeed/pinmux-aspeed.h index a2c0d52e4f7b..d5202241f411 100644 --- a/drivers/pinctrl/aspeed/pinmux-aspeed.h +++ b/drivers/pinctrl/aspeed/pinmux-aspeed.h @@ -508,7 +508,7 @@ struct aspeed_pin_desc { * @idx: The bit index in the register */ #define SIG_DESC_SET(reg, idx) SIG_DESC_IP_BIT(ASPEED_IP_SCU, reg, idx, 1) -#define SIG_DESC_CLEAR(reg, idx) SIG_DESC_IP_BIT(ASPEED_IP_SCU, reg, idx, 0) +#define SIG_DESC_CLEAR(reg, idx) { ASPEED_IP_SCU, reg, BIT_MASK(idx), 0, 0 } #define SIG_DESC_LIST_SYM(sig, group) sig_descs_ ## sig ## _ ## group #define SIG_DESC_LIST_DECL(sig, group, ...) \ -- GitLab From 1550583432535dccaf1956c1d58e2866eacd173e Mon Sep 17 00:00:00 2001 From: Johnny Huang Date: Tue, 8 Oct 2019 15:11:52 +1030 Subject: [PATCH 376/993] pinctrl: aspeed-g6: Fix UART13 group pinmux When UART13G1 is set the pinmux configuration in SCU4B8 for UART13G0 should be cleared. Fixes: 58dc52ad00a0 ("pinctrl: aspeed: Add AST2600 pinmux support") Signed-off-by: Johnny Huang [AJ: Tweak commit message] Signed-off-by: Andrew Jeffery Link: https://lore.kernel.org/r/20191008044153.12734-7-andrew@aj.id.au Reviewed-by: Joel Stanley Signed-off-by: Linus Walleij --- drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c index 68b066594461..dc17cf3d3549 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c @@ -1262,13 +1262,13 @@ GROUP_DECL(SPI1, AB11, AC11, AA11); #define AD11 206 SIG_EXPR_LIST_DECL_SEMG(AD11, SPI1DQ2, QSPI1, SPI1, SIG_DESC_SET(SCU438, 14)); SIG_EXPR_LIST_DECL_SEMG(AD11, TXD13, UART13G1, UART13, - SIG_DESC_SET(SCU438, 14)); + SIG_DESC_CLEAR(SCU4B8, 2), SIG_DESC_SET(SCU4D8, 14)); PIN_DECL_2(AD11, GPIOZ6, SPI1DQ2, TXD13); #define AF10 207 SIG_EXPR_LIST_DECL_SEMG(AF10, SPI1DQ3, QSPI1, SPI1, SIG_DESC_SET(SCU438, 15)); SIG_EXPR_LIST_DECL_SEMG(AF10, RXD13, UART13G1, UART13, - SIG_DESC_SET(SCU438, 15)); + SIG_DESC_CLEAR(SCU4B8, 3), SIG_DESC_SET(SCU4D8, 15)); PIN_DECL_2(AF10, GPIOZ7, SPI1DQ3, RXD13); GROUP_DECL(QSPI1, AB11, AC11, AA11, AD11, AF10); -- GitLab From d6e7a1a5119c4e719b0d63651f09762d7384bfed Mon Sep 17 00:00:00 2001 From: Johnny Huang Date: Tue, 8 Oct 2019 15:11:53 +1030 Subject: [PATCH 377/993] pinctrl: aspeed-g6: Rename SD3 to EMMC and rework pin groups AST2600 EMMC support 3 types DAT bus sizes (1, 4 and 8-bit), corresponding to 3 groups: EMMCG1, EMMCG4 and EMMCG8 Fixes: 58dc52ad00a0 ("pinctrl: aspeed: Add AST2600 pinmux support") Signed-off-by: Johnny Huang Signed-off-by: Andrew Jeffery Link: https://lore.kernel.org/r/20191008044153.12734-8-andrew@aj.id.au Reviewed-by: Joel Stanley Signed-off-by: Linus Walleij --- drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c | 72 ++++++++++------------ drivers/pinctrl/aspeed/pinmux-aspeed.h | 1 + 2 files changed, 33 insertions(+), 40 deletions(-) diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c index dc17cf3d3549..c6800d220920 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c @@ -1440,74 +1440,72 @@ FUNC_GROUP_DECL(RGMII2, D4, C2, C1, D3, E4, F5, D2, E3, D1, F4, E2, E1); FUNC_GROUP_DECL(RMII2, D4, C2, C1, D3, D2, D1, F4, E2, E1); #define AB4 232 -SIG_EXPR_LIST_DECL_SESG(AB4, SD3CLK, SD3, SIG_DESC_SET(SCU400, 24)); -PIN_DECL_1(AB4, GPIO18D0, SD3CLK); +SIG_EXPR_LIST_DECL_SEMG(AB4, EMMCCLK, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 24)); +PIN_DECL_1(AB4, GPIO18D0, EMMCCLK); #define AA4 233 -SIG_EXPR_LIST_DECL_SESG(AA4, SD3CMD, SD3, SIG_DESC_SET(SCU400, 25)); -PIN_DECL_1(AA4, GPIO18D1, SD3CMD); +SIG_EXPR_LIST_DECL_SEMG(AA4, EMMCCMD, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 25)); +PIN_DECL_1(AA4, GPIO18D1, EMMCCMD); #define AC4 234 -SIG_EXPR_LIST_DECL_SESG(AC4, SD3DAT0, SD3, SIG_DESC_SET(SCU400, 26)); -PIN_DECL_1(AC4, GPIO18D2, SD3DAT0); +SIG_EXPR_LIST_DECL_SEMG(AC4, EMMCDAT0, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 26)); +PIN_DECL_1(AC4, GPIO18D2, EMMCDAT0); #define AA5 235 -SIG_EXPR_LIST_DECL_SESG(AA5, SD3DAT1, SD3, SIG_DESC_SET(SCU400, 27)); -PIN_DECL_1(AA5, GPIO18D3, SD3DAT1); +SIG_EXPR_LIST_DECL_SEMG(AA5, EMMCDAT1, EMMCG4, EMMC, SIG_DESC_SET(SCU400, 27)); +PIN_DECL_1(AA5, GPIO18D3, EMMCDAT1); #define Y5 236 -SIG_EXPR_LIST_DECL_SESG(Y5, SD3DAT2, SD3, SIG_DESC_SET(SCU400, 28)); -PIN_DECL_1(Y5, GPIO18D4, SD3DAT2); +SIG_EXPR_LIST_DECL_SEMG(Y5, EMMCDAT2, EMMCG4, EMMC, SIG_DESC_SET(SCU400, 28)); +PIN_DECL_1(Y5, GPIO18D4, EMMCDAT2); #define AB5 237 -SIG_EXPR_LIST_DECL_SESG(AB5, SD3DAT3, SD3, SIG_DESC_SET(SCU400, 29)); -PIN_DECL_1(AB5, GPIO18D5, SD3DAT3); +SIG_EXPR_LIST_DECL_SEMG(AB5, EMMCDAT3, EMMCG4, EMMC, SIG_DESC_SET(SCU400, 29)); +PIN_DECL_1(AB5, GPIO18D5, EMMCDAT3); #define AB6 238 -SIG_EXPR_LIST_DECL_SESG(AB6, SD3CD, SD3, SIG_DESC_SET(SCU400, 30)); -PIN_DECL_1(AB6, GPIO18D6, SD3CD); +SIG_EXPR_LIST_DECL_SEMG(AB6, EMMCCD, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 30)); +PIN_DECL_1(AB6, GPIO18D6, EMMCCD); #define AC5 239 -SIG_EXPR_LIST_DECL_SESG(AC5, SD3WP, SD3, SIG_DESC_SET(SCU400, 31)); -PIN_DECL_1(AC5, GPIO18D7, SD3WP); +SIG_EXPR_LIST_DECL_SEMG(AC5, EMMCWP, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 31)); +PIN_DECL_1(AC5, GPIO18D7, EMMCWP); -FUNC_GROUP_DECL(SD3, AB4, AA4, AC4, AA5, Y5, AB5, AB6, AC5); +GROUP_DECL(EMMCG1, AB4, AA4, AC4, AB6, AC5); +GROUP_DECL(EMMCG4, AB4, AA4, AC4, AA5, Y5, AB5, AB6, AC5); #define Y1 240 SIG_EXPR_LIST_DECL_SEMG(Y1, FWSPIDCS, FWSPID, FWSPID, SIG_DESC_SET(SCU500, 3)); SIG_EXPR_LIST_DECL_SESG(Y1, VBCS, VB, SIG_DESC_SET(SCU500, 5)); -SIG_EXPR_LIST_DECL_SESG(Y1, SD3DAT4, SD3DAT4, SIG_DESC_SET(SCU404, 0)); -PIN_DECL_3(Y1, GPIO18E0, FWSPIDCS, VBCS, SD3DAT4); -FUNC_GROUP_DECL(SD3DAT4, Y1); +SIG_EXPR_LIST_DECL_SEMG(Y1, EMMCDAT4, EMMCG8, EMMC, SIG_DESC_SET(SCU404, 0)); +PIN_DECL_3(Y1, GPIO18E0, FWSPIDCS, VBCS, EMMCDAT4); #define Y2 241 SIG_EXPR_LIST_DECL_SEMG(Y2, FWSPIDCK, FWSPID, FWSPID, SIG_DESC_SET(SCU500, 3)); SIG_EXPR_LIST_DECL_SESG(Y2, VBCK, VB, SIG_DESC_SET(SCU500, 5)); -SIG_EXPR_LIST_DECL_SESG(Y2, SD3DAT5, SD3DAT5, SIG_DESC_SET(SCU404, 1)); -PIN_DECL_3(Y2, GPIO18E1, FWSPIDCK, VBCK, SD3DAT5); -FUNC_GROUP_DECL(SD3DAT5, Y2); +SIG_EXPR_LIST_DECL_SEMG(Y2, EMMCDAT5, EMMCG8, EMMC, SIG_DESC_SET(SCU404, 1)); +PIN_DECL_3(Y2, GPIO18E1, FWSPIDCK, VBCK, EMMCDAT5); #define Y3 242 SIG_EXPR_LIST_DECL_SEMG(Y3, FWSPIDMOSI, FWSPID, FWSPID, SIG_DESC_SET(SCU500, 3)); SIG_EXPR_LIST_DECL_SESG(Y3, VBMOSI, VB, SIG_DESC_SET(SCU500, 5)); -SIG_EXPR_LIST_DECL_SESG(Y3, SD3DAT6, SD3DAT6, SIG_DESC_SET(SCU404, 2)); -PIN_DECL_3(Y3, GPIO18E2, FWSPIDMOSI, VBMOSI, SD3DAT6); -FUNC_GROUP_DECL(SD3DAT6, Y3); +SIG_EXPR_LIST_DECL_SEMG(Y3, EMMCDAT6, EMMCG8, EMMC, SIG_DESC_SET(SCU404, 2)); +PIN_DECL_3(Y3, GPIO18E2, FWSPIDMOSI, VBMOSI, EMMCDAT6); #define Y4 243 SIG_EXPR_LIST_DECL_SEMG(Y4, FWSPIDMISO, FWSPID, FWSPID, SIG_DESC_SET(SCU500, 3)); SIG_EXPR_LIST_DECL_SESG(Y4, VBMISO, VB, SIG_DESC_SET(SCU500, 5)); -SIG_EXPR_LIST_DECL_SESG(Y4, SD3DAT7, SD3DAT7, SIG_DESC_SET(SCU404, 3)); -PIN_DECL_3(Y4, GPIO18E3, FWSPIDMISO, VBMISO, SD3DAT7); -FUNC_GROUP_DECL(SD3DAT7, Y4); +SIG_EXPR_LIST_DECL_SEMG(Y4, EMMCDAT7, EMMCG8, EMMC, SIG_DESC_SET(SCU404, 3)); +PIN_DECL_3(Y4, GPIO18E3, FWSPIDMISO, VBMISO, EMMCDAT7); GROUP_DECL(FWSPID, Y1, Y2, Y3, Y4); GROUP_DECL(FWQSPID, Y1, Y2, Y3, Y4, AE12, AF12); +GROUP_DECL(EMMCG8, AB4, AA4, AC4, AA5, Y5, AB5, AB6, AC5, Y1, Y2, Y3, Y4); FUNC_DECL_2(FWSPID, FWSPID, FWQSPID); FUNC_GROUP_DECL(VB, Y1, Y2, Y3, Y4); - +FUNC_DECL_3(EMMC, EMMCG1, EMMCG4, EMMCG8); /* * FIXME: Confirm bits and priorities are the right way around for the * following 4 pins @@ -1968,11 +1966,9 @@ static const struct aspeed_pin_group aspeed_g6_groups[] = { ASPEED_PINCTRL_GROUP(SALT9G1), ASPEED_PINCTRL_GROUP(SD1), ASPEED_PINCTRL_GROUP(SD2), - ASPEED_PINCTRL_GROUP(SD3), - ASPEED_PINCTRL_GROUP(SD3DAT4), - ASPEED_PINCTRL_GROUP(SD3DAT5), - ASPEED_PINCTRL_GROUP(SD3DAT6), - ASPEED_PINCTRL_GROUP(SD3DAT7), + ASPEED_PINCTRL_GROUP(EMMCG1), + ASPEED_PINCTRL_GROUP(EMMCG4), + ASPEED_PINCTRL_GROUP(EMMCG8), ASPEED_PINCTRL_GROUP(SGPM1), ASPEED_PINCTRL_GROUP(SGPS1), ASPEED_PINCTRL_GROUP(SIOONCTRL), @@ -2051,6 +2047,7 @@ static const struct aspeed_pin_function aspeed_g6_functions[] = { ASPEED_PINCTRL_FUNC(ADC8), ASPEED_PINCTRL_FUNC(ADC9), ASPEED_PINCTRL_FUNC(BMCINT), + ASPEED_PINCTRL_FUNC(EMMC), ASPEED_PINCTRL_FUNC(ESPI), ASPEED_PINCTRL_FUNC(ESPIALT), ASPEED_PINCTRL_FUNC(FSI1), @@ -2183,11 +2180,6 @@ static const struct aspeed_pin_function aspeed_g6_functions[] = { ASPEED_PINCTRL_FUNC(SALT9), ASPEED_PINCTRL_FUNC(SD1), ASPEED_PINCTRL_FUNC(SD2), - ASPEED_PINCTRL_FUNC(SD3), - ASPEED_PINCTRL_FUNC(SD3DAT4), - ASPEED_PINCTRL_FUNC(SD3DAT5), - ASPEED_PINCTRL_FUNC(SD3DAT6), - ASPEED_PINCTRL_FUNC(SD3DAT7), ASPEED_PINCTRL_FUNC(SGPM1), ASPEED_PINCTRL_FUNC(SGPS1), ASPEED_PINCTRL_FUNC(SIOONCTRL), diff --git a/drivers/pinctrl/aspeed/pinmux-aspeed.h b/drivers/pinctrl/aspeed/pinmux-aspeed.h index d5202241f411..140c5ce9fbc1 100644 --- a/drivers/pinctrl/aspeed/pinmux-aspeed.h +++ b/drivers/pinctrl/aspeed/pinmux-aspeed.h @@ -738,6 +738,7 @@ struct aspeed_pin_desc { static const char *FUNC_SYM(func)[] = { __VA_ARGS__ } #define FUNC_DECL_2(func, one, two) FUNC_DECL_(func, #one, #two) +#define FUNC_DECL_3(func, one, two, three) FUNC_DECL_(func, #one, #two, #three) #define FUNC_GROUP_DECL(func, ...) \ GROUP_DECL(func, __VA_ARGS__); \ -- GitLab From bc88f85c6c09306bd21917e1ae28205e9cd775a7 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 16 Oct 2019 12:24:58 +0100 Subject: [PATCH 378/993] kthread: make __kthread_queue_delayed_work static The __kthread_queue_delayed_work is not exported so make it static, to avoid the following sparse warning: kernel/kthread.c:869:6: warning: symbol '__kthread_queue_delayed_work' was not declared. Should it be static? Signed-off-by: Ben Dooks Signed-off-by: Linus Torvalds --- kernel/kthread.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/kthread.c b/kernel/kthread.c index 621467c33fef..b262f47046ca 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -866,9 +866,9 @@ void kthread_delayed_work_timer_fn(struct timer_list *t) } EXPORT_SYMBOL(kthread_delayed_work_timer_fn); -void __kthread_queue_delayed_work(struct kthread_worker *worker, - struct kthread_delayed_work *dwork, - unsigned long delay) +static void __kthread_queue_delayed_work(struct kthread_worker *worker, + struct kthread_delayed_work *dwork, + unsigned long delay) { struct timer_list *timer = &dwork->timer; struct kthread_work *work = &dwork->work; -- GitLab From 3874d73e06c9b9dc15de0b7382fc223986d75571 Mon Sep 17 00:00:00 2001 From: Song Liu Date: Mon, 14 Oct 2019 16:58:35 -0700 Subject: [PATCH 379/993] md/raid0: fix warning message for parameter default_layout The message should match the parameter, i.e. raid0.default_layout. Fixes: c84a1372df92 ("md/raid0: avoid RAID0 data corruption due to layout confusion.") Cc: NeilBrown Reported-by: Ivan Topolsky Signed-off-by: Song Liu --- drivers/md/raid0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index f61693e59684..1e772287b1c8 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -154,7 +154,7 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) } else { pr_err("md/raid0:%s: cannot assemble multi-zone RAID0 with default_layout setting\n", mdname(mddev)); - pr_err("md/raid0: please set raid.default_layout to 1 or 2\n"); + pr_err("md/raid0: please set raid0.default_layout to 1 or 2\n"); err = -ENOTSUPP; goto abort; } -- GitLab From 19c95f261c6558d4c2cbbfacd2d8bb6501384601 Mon Sep 17 00:00:00 2001 From: Julien Thierry Date: Tue, 15 Oct 2019 18:25:44 +0100 Subject: [PATCH 380/993] arm64: entry.S: Do not preempt from IRQ before all cpufeatures are enabled Preempting from IRQ-return means that the task has its PSTATE saved on the stack, which will get restored when the task is resumed and does the actual IRQ return. However, enabling some CPU features requires modifying the PSTATE. This means that, if a task was scheduled out during an IRQ-return before all CPU features are enabled, the task might restore a PSTATE that does not include the feature enablement changes once scheduled back in. * Task 1: PAN == 0 ---| |--------------- | |<- return from IRQ, PSTATE.PAN = 0 | <- IRQ | +--------+ <- preempt() +-- ^ | reschedule Task 1, PSTATE.PAN == 1 * Init: --------------------+------------------------ ^ | enable_cpu_features set PSTATE.PAN on all CPUs Worse than this, since PSTATE is untouched when task switching is done, a task missing the new bits in PSTATE might affect another task, if both do direct calls to schedule() (outside of IRQ/exception contexts). Fix this by preventing preemption on IRQ-return until features are enabled on all CPUs. This way the only PSTATE values that are saved on the stack are from synchronous exceptions. These are expected to be fatal this early, the exception is BRK for WARN_ON(), but as this uses do_debug_exception() which keeps IRQs masked, it shouldn't call schedule(). Signed-off-by: Julien Thierry [james: Replaced a really cool hack, with an even simpler static key in C. expanded commit message with Julien's cover-letter ascii art] Signed-off-by: James Morse Signed-off-by: Will Deacon --- arch/arm64/kernel/entry.S | 2 +- arch/arm64/kernel/process.c | 18 ++++++++++++++++++ include/linux/sched.h | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index e304fe04b098..e1859e010c5f 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -680,7 +680,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING orr x24, x24, x0 alternative_else_nop_endif cbnz x24, 1f // preempt count != 0 || NMI return path - bl preempt_schedule_irq // irq en/disable is done inside + bl arm64_preempt_schedule_irq // irq en/disable is done inside 1: #endif diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 1fb2819fc048..71f788cd2b18 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -631,3 +633,19 @@ static int __init tagged_addr_init(void) core_initcall(tagged_addr_init); #endif /* CONFIG_ARM64_TAGGED_ADDR_ABI */ + +asmlinkage void __sched arm64_preempt_schedule_irq(void) +{ + lockdep_assert_irqs_disabled(); + + /* + * Preempting a task from an IRQ means we leave copies of PSTATE + * on the stack. cpufeature's enable calls may modify PSTATE, but + * resuming one of these preempted tasks would undo those changes. + * + * Only allow a task to be preempted once cpufeatures have been + * enabled. + */ + if (static_branch_likely(&arm64_const_caps_ready)) + preempt_schedule_irq(); +} diff --git a/include/linux/sched.h b/include/linux/sched.h index 2c2e56bd8913..67a1d86981a9 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -223,6 +223,7 @@ extern long schedule_timeout_uninterruptible(long timeout); extern long schedule_timeout_idle(long timeout); asmlinkage void schedule(void); extern void schedule_preempt_disabled(void); +asmlinkage void preempt_schedule_irq(void); extern int __must_check io_schedule_prepare(void); extern void io_schedule_finish(int token); -- GitLab From 29a0f5ad87e6f45c984ffffa57b7142d178ff422 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 16 Oct 2019 11:42:57 +0800 Subject: [PATCH 381/993] arm64: sysreg: fix incorrect definition of SYS_PAR_EL1_F The 'F' field of the PAR_EL1 register lives in bit 0, not bit 1. Fix the broken definition in 'sysreg.h'. Fixes: e8620cff9994 ("arm64: sysreg: Add some field definitions for PAR_EL1") Reviewed-by: Mark Rutland Signed-off-by: Yang Yingliang Signed-off-by: Will Deacon --- arch/arm64/include/asm/sysreg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 972d196c7714..6e919fafb43d 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -212,7 +212,7 @@ #define SYS_FAR_EL1 sys_reg(3, 0, 6, 0, 0) #define SYS_PAR_EL1 sys_reg(3, 0, 7, 4, 0) -#define SYS_PAR_EL1_F BIT(1) +#define SYS_PAR_EL1_F BIT(0) #define SYS_PAR_EL1_FST GENMASK(6, 1) /*** Statistical Profiling Extension ***/ -- GitLab From 3813733595c0c7c0674d106309b04e871d54dc1c Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Wed, 16 Oct 2019 12:03:04 +0100 Subject: [PATCH 382/993] arm64: mm: fix inverted PAR_EL1.F check When detecting a spurious EL1 translation fault, we have the CPU retry the translation using an AT S1E1R instruction, and inspect PAR_EL1 to determine if the fault was spurious. When PAR_EL1.F == 0, the AT instruction successfully translated the address without a fault, which implies the original fault was spurious. However, in this case we return false and treat the original fault as if it was not spurious. Invert the return value so that we treat such a case as spurious. Cc: Catalin Marinas Fixes: 42f91093b043 ("arm64: mm: Ignore spurious translation faults taken from the kernel") Tested-by: James Morse Signed-off-by: Mark Rutland Signed-off-by: Will Deacon --- arch/arm64/mm/fault.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 855f2a7954e6..9fc6db0bcbad 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -268,8 +268,12 @@ static bool __kprobes is_spurious_el1_translation_fault(unsigned long addr, par = read_sysreg(par_el1); local_irq_restore(flags); + /* + * If we now have a valid translation, treat the translation fault as + * spurious. + */ if (!(par & SYS_PAR_EL1_F)) - return false; + return true; /* * If we got a different type of fault from the AT instruction, -- GitLab From 597399d0cb91d049fcb78fb45c7694771b583bb7 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 15 Oct 2019 21:04:18 -0700 Subject: [PATCH 383/993] arm64: tags: Preserve tags for addresses translated via TTBR1 Sign-extending TTBR1 addresses when converting to an untagged address breaks the documented POSIX semantics for mlock() in some obscure error cases where we end up returning -EINVAL instead of -ENOMEM as a direct result of rewriting the upper address bits. Rework the untagged_addr() macro to preserve the upper address bits for TTBR1 addresses and only clear the tag bits for user addresses. This matches the behaviour of the 'clear_address_tag' assembly macro, so rename that and align the implementations at the same time so that they use the same instruction sequences for the tag manipulation. Link: https://lore.kernel.org/stable/20191014162651.GF19200@arrakis.emea.arm.com/ Reported-by: Jan Stancek Tested-by: Jan Stancek Reviewed-by: Catalin Marinas Tested-by: Catalin Marinas Reviewed-by: Vincenzo Frascino Tested-by: Vincenzo Frascino Reviewed-by: Andrey Konovalov Signed-off-by: Will Deacon --- arch/arm64/include/asm/asm-uaccess.h | 7 +++---- arch/arm64/include/asm/memory.h | 10 ++++++++-- arch/arm64/kernel/entry.S | 4 ++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/arch/arm64/include/asm/asm-uaccess.h b/arch/arm64/include/asm/asm-uaccess.h index f74909ba29bd..5bf963830b17 100644 --- a/arch/arm64/include/asm/asm-uaccess.h +++ b/arch/arm64/include/asm/asm-uaccess.h @@ -78,10 +78,9 @@ alternative_else_nop_endif /* * Remove the address tag from a virtual address, if present. */ - .macro clear_address_tag, dst, addr - tst \addr, #(1 << 55) - bic \dst, \addr, #(0xff << 56) - csel \dst, \dst, \addr, eq + .macro untagged_addr, dst, addr + sbfx \dst, \addr, #0, #56 + and \dst, \dst, \addr .endm #endif diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index b61b50bf68b1..c23c47360664 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -215,12 +215,18 @@ static inline unsigned long kaslr_offset(void) * up with a tagged userland pointer. Clear the tag to get a sane pointer to * pass on to access_ok(), for instance. */ -#define untagged_addr(addr) \ +#define __untagged_addr(addr) \ ((__force __typeof__(addr))sign_extend64((__force u64)(addr), 55)) +#define untagged_addr(addr) ({ \ + u64 __addr = (__force u64)addr; \ + __addr &= __untagged_addr(__addr); \ + (__force __typeof__(addr))__addr; \ +}) + #ifdef CONFIG_KASAN_SW_TAGS #define __tag_shifted(tag) ((u64)(tag) << 56) -#define __tag_reset(addr) untagged_addr(addr) +#define __tag_reset(addr) __untagged_addr(addr) #define __tag_get(addr) (__u8)((u64)(addr) >> 56) #else #define __tag_shifted(tag) 0UL diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index e1859e010c5f..a3a63092eba9 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -604,7 +604,7 @@ el1_da: */ mrs x3, far_el1 inherit_daif pstate=x23, tmp=x2 - clear_address_tag x0, x3 + untagged_addr x0, x3 mov x2, sp // struct pt_regs bl do_mem_abort @@ -808,7 +808,7 @@ el0_da: mrs x26, far_el1 ct_user_exit_irqoff enable_daif - clear_address_tag x0, x26 + untagged_addr x0, x26 mov x1, x25 mov x2, sp bl do_mem_abort -- GitLab From bd74708cd979f4934f0744055ce3b47da68733ce Mon Sep 17 00:00:00 2001 From: Mahesh Bandewar Date: Wed, 16 Oct 2019 00:04:38 -0700 Subject: [PATCH 384/993] Revert "blackhole_netdev: fix syzkaller reported issue" This reverts commit b0818f80c8c1bc215bba276bd61c216014fab23b. Started seeing weird behavior after this patch especially in the IPv6 code path. Haven't root caused it, but since this was applied to net branch, taking a precautionary measure to revert it and look / analyze those failures Revert this now and I'll send a better fix after analysing / fixing the weirdness observed. CC: Eric Dumazet CC: Wei Wang CC: David S. Miller Signed-off-by: Mahesh Bandewar Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 7 +------ net/ipv6/route.c | 15 +++++++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 4c87594d1389..34ccef18b40e 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -6996,7 +6996,7 @@ static struct rtnl_af_ops inet6_ops __read_mostly = { int __init addrconf_init(void) { - struct inet6_dev *idev, *bdev; + struct inet6_dev *idev; int i, err; err = ipv6_addr_label_init(); @@ -7036,14 +7036,10 @@ int __init addrconf_init(void) */ rtnl_lock(); idev = ipv6_add_dev(init_net.loopback_dev); - bdev = ipv6_add_dev(blackhole_netdev); rtnl_unlock(); if (IS_ERR(idev)) { err = PTR_ERR(idev); goto errlo; - } else if (IS_ERR(bdev)) { - err = PTR_ERR(bdev); - goto errlo; } ip6_route_init_special_entries(); @@ -7128,7 +7124,6 @@ void addrconf_cleanup(void) addrconf_ifdown(dev, 1); } addrconf_ifdown(init_net.loopback_dev, 2); - addrconf_ifdown(blackhole_netdev, 2); /* * Check hash table. diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 742120728869..a63ff85fe141 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -155,9 +155,10 @@ void rt6_uncached_list_del(struct rt6_info *rt) static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev) { + struct net_device *loopback_dev = net->loopback_dev; int cpu; - if (dev == net->loopback_dev) + if (dev == loopback_dev) return; for_each_possible_cpu(cpu) { @@ -170,7 +171,7 @@ static void rt6_uncached_list_flush_dev(struct net *net, struct net_device *dev) struct net_device *rt_dev = rt->dst.dev; if (rt_idev->dev == dev) { - rt->rt6i_idev = in6_dev_get(blackhole_netdev); + rt->rt6i_idev = in6_dev_get(loopback_dev); in6_dev_put(rt_idev); } @@ -385,11 +386,13 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, { struct rt6_info *rt = (struct rt6_info *)dst; struct inet6_dev *idev = rt->rt6i_idev; + struct net_device *loopback_dev = + dev_net(dev)->loopback_dev; - if (idev && idev->dev != dev_net(dev)->loopback_dev) { - struct inet6_dev *ibdev = in6_dev_get(blackhole_netdev); - if (ibdev) { - rt->rt6i_idev = ibdev; + if (idev && idev->dev != loopback_dev) { + struct inet6_dev *loopback_idev = in6_dev_get(loopback_dev); + if (loopback_idev) { + rt->rt6i_idev = loopback_idev; in6_dev_put(idev); } } -- GitLab From 128260a41eeba4dd8d4433eab96aeeb7192392a4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 23 Sep 2019 12:00:56 +0100 Subject: [PATCH 385/993] drm/i915/execlists: Refactor -EIO markup of hung requests Pull setting -EIO on the hung requests into its own utility function. Having allowed ourselves to short-circuit submission of completed requests, we can now do the mark_eio() prior to submission and avoid some redundant operations. Signed-off-by: Chris Wilson Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190923110056.15176-4-chris@chris-wilson.co.uk (cherry picked from commit 0d7cf7bc15e75bf79f2f65d61d19f896609f816a) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gt/intel_lrc.c | 31 ++++++++++++++++------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index bdfcc7bdadbf..46005986e95f 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -234,6 +234,13 @@ static void execlists_init_reg_state(u32 *reg_state, struct intel_engine_cs *engine, struct intel_ring *ring); +static void mark_eio(struct i915_request *rq) +{ + if (!i915_request_signaled(rq)) + dma_fence_set_error(&rq->fence, -EIO); + i915_request_mark_complete(rq); +} + static inline u32 intel_hws_preempt_address(struct intel_engine_cs *engine) { return (i915_ggtt_offset(engine->status_page.vma) + @@ -2574,12 +2581,8 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) __execlists_reset(engine, true); /* Mark all executing requests as skipped. */ - list_for_each_entry(rq, &engine->active.requests, sched.link) { - if (!i915_request_signaled(rq)) - dma_fence_set_error(&rq->fence, -EIO); - - i915_request_mark_complete(rq); - } + list_for_each_entry(rq, &engine->active.requests, sched.link) + mark_eio(rq); /* Flush the queued requests to the timeline list (for retiring). */ while ((rb = rb_first_cached(&execlists->queue))) { @@ -2587,9 +2590,8 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) int i; priolist_for_each_request_consume(rq, rn, p, i) { + mark_eio(rq); __i915_request_submit(rq); - dma_fence_set_error(&rq->fence, -EIO); - i915_request_mark_complete(rq); } rb_erase_cached(&p->node, &execlists->queue); @@ -2605,13 +2607,14 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) RB_CLEAR_NODE(rb); spin_lock(&ve->base.active.lock); - if (ve->request) { - ve->request->engine = engine; - __i915_request_submit(ve->request); - dma_fence_set_error(&ve->request->fence, -EIO); - i915_request_mark_complete(ve->request); + rq = fetch_and_zero(&ve->request); + if (rq) { + mark_eio(rq); + + rq->engine = engine; + __i915_request_submit(rq); + ve->base.execlists.queue_priority_hint = INT_MIN; - ve->request = NULL; } spin_unlock(&ve->base.active.lock); } -- GitLab From 0336ab580878f4c5663dfa2b66095821fdc3e588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 11 Oct 2019 23:20:30 +0300 Subject: [PATCH 386/993] drm/i915: Favor last VBT child device with conflicting AUX ch/DDC pin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first come first served apporoach to handling the VBT child device AUX ch conflicts has backfired. We have machines in the wild where the VBT specifies both port A eDP and port E DP (in that order) with port E being the real one. So let's try to flip the preference around and let the last child device win once again. Cc: stable@vger.kernel.org Cc: Jani Nikula Tested-by: Masami Ichikawa Tested-by: Torsten Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111966 Fixes: 36a0f92020dc ("drm/i915/bios: make child device order the priority order") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20191011202030.8829-1-ville.syrjala@linux.intel.com Acked-by: Jani Nikula (cherry picked from commit 41e35ffb380bde1379e4030bb5b2ac824d5139cf) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/intel_bios.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index efb39f350b19..3250c1b8dcca 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -1270,7 +1270,7 @@ static void sanitize_ddc_pin(struct drm_i915_private *dev_priv, DRM_DEBUG_KMS("port %c trying to use the same DDC pin (0x%x) as port %c, " "disabling port %c DVI/HDMI support\n", port_name(port), info->alternate_ddc_pin, - port_name(p), port_name(port)); + port_name(p), port_name(p)); /* * If we have multiple ports supposedly sharing the @@ -1278,9 +1278,14 @@ static void sanitize_ddc_pin(struct drm_i915_private *dev_priv, * port. Otherwise they share the same ddc bin and * system couldn't communicate with them separately. * - * Give child device order the priority, first come first - * served. + * Give inverse child device order the priority, + * last one wins. Yes, there are real machines + * (eg. Asrock B250M-HDV) where VBT has both + * port A and port E with the same AUX ch and + * we must pick port E :( */ + info = &dev_priv->vbt.ddi_port_info[p]; + info->supports_dvi = false; info->supports_hdmi = false; info->alternate_ddc_pin = 0; @@ -1316,7 +1321,7 @@ static void sanitize_aux_ch(struct drm_i915_private *dev_priv, DRM_DEBUG_KMS("port %c trying to use the same AUX CH (0x%x) as port %c, " "disabling port %c DP support\n", port_name(port), info->alternate_aux_channel, - port_name(p), port_name(port)); + port_name(p), port_name(p)); /* * If we have multiple ports supposedlt sharing the @@ -1324,9 +1329,14 @@ static void sanitize_aux_ch(struct drm_i915_private *dev_priv, * port. Otherwise they share the same aux channel * and system couldn't communicate with them separately. * - * Give child device order the priority, first come first - * served. + * Give inverse child device order the priority, + * last one wins. Yes, there are real machines + * (eg. Asrock B250M-HDV) where VBT has both + * port A and port E with the same AUX ch and + * we must pick port E :( */ + info = &dev_priv->vbt.ddi_port_info[p]; + info->supports_dp = false; info->alternate_aux_channel = 0; } -- GitLab From 4f2a572eda67aecb1e7e4fc26cc985fb8158f6e8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 28 Sep 2019 09:25:46 +0100 Subject: [PATCH 387/993] drm/i915/userptr: Never allow userptr into the mappable GGTT Daniel Vetter uncovered a nasty cycle in using the mmu-notifiers to invalidate userptr objects which also happen to be pulled into GGTT mmaps. That is when we unbind the userptr object (on mmu invalidation), we revoke all CPU mmaps, which may then recurse into mmu invalidation. We looked for ways of breaking the cycle, but the revocation on invalidation is required and cannot be avoided. The only solution we could see was to not allow such GGTT bindings of userptr objects in the first place. In practice, no one really wants to use a GGTT mmapping of a CPU pointer... Just before Daniel's explosive lockdep patches land in v5.4-rc1, we got a genuine blip from CI: <4>[ 246.793958] ====================================================== <4>[ 246.793972] WARNING: possible circular locking dependency detected <4>[ 246.793989] 5.3.0-gbd6c56f50d15-drmtip_372+ #1 Tainted: G U <4>[ 246.794003] ------------------------------------------------------ <4>[ 246.794017] kswapd0/145 is trying to acquire lock: <4>[ 246.794030] 000000003f565be6 (&dev->struct_mutex/1){+.+.}, at: userptr_mn_invalidate_range_start+0x18f/0x220 [i915] <4>[ 246.794250] but task is already holding lock: <4>[ 246.794263] 000000001799cef9 (&anon_vma->rwsem){++++}, at: page_lock_anon_vma_read+0xe6/0x2a0 <4>[ 246.794291] which lock already depends on the new lock. <4>[ 246.794307] the existing dependency chain (in reverse order) is: <4>[ 246.794322] -> #3 (&anon_vma->rwsem){++++}: <4>[ 246.794344] down_write+0x33/0x70 <4>[ 246.794357] __vma_adjust+0x3d9/0x7b0 <4>[ 246.794370] __split_vma+0x16a/0x180 <4>[ 246.794385] mprotect_fixup+0x2a5/0x320 <4>[ 246.794399] do_mprotect_pkey+0x208/0x2e0 <4>[ 246.794413] __x64_sys_mprotect+0x16/0x20 <4>[ 246.794429] do_syscall_64+0x55/0x1c0 <4>[ 246.794443] entry_SYSCALL_64_after_hwframe+0x49/0xbe <4>[ 246.794456] -> #2 (&mapping->i_mmap_rwsem){++++}: <4>[ 246.794478] down_write+0x33/0x70 <4>[ 246.794493] unmap_mapping_pages+0x48/0x130 <4>[ 246.794519] i915_vma_revoke_mmap+0x81/0x1b0 [i915] <4>[ 246.794519] i915_vma_unbind+0x11d/0x4a0 [i915] <4>[ 246.794519] i915_vma_destroy+0x31/0x300 [i915] <4>[ 246.794519] __i915_gem_free_objects+0xb8/0x4b0 [i915] <4>[ 246.794519] drm_file_free.part.0+0x1e6/0x290 <4>[ 246.794519] drm_release+0xa6/0xe0 <4>[ 246.794519] __fput+0xc2/0x250 <4>[ 246.794519] task_work_run+0x82/0xb0 <4>[ 246.794519] do_exit+0x35b/0xdb0 <4>[ 246.794519] do_group_exit+0x34/0xb0 <4>[ 246.794519] __x64_sys_exit_group+0xf/0x10 <4>[ 246.794519] do_syscall_64+0x55/0x1c0 <4>[ 246.794519] entry_SYSCALL_64_after_hwframe+0x49/0xbe <4>[ 246.794519] -> #1 (&vm->mutex){+.+.}: <4>[ 246.794519] i915_gem_shrinker_taints_mutex+0x6d/0xe0 [i915] <4>[ 246.794519] i915_address_space_init+0x9f/0x160 [i915] <4>[ 246.794519] i915_ggtt_init_hw+0x55/0x170 [i915] <4>[ 246.794519] i915_driver_probe+0xc9f/0x1620 [i915] <4>[ 246.794519] i915_pci_probe+0x43/0x1b0 [i915] <4>[ 246.794519] pci_device_probe+0x9e/0x120 <4>[ 246.794519] really_probe+0xea/0x3d0 <4>[ 246.794519] driver_probe_device+0x10b/0x120 <4>[ 246.794519] device_driver_attach+0x4a/0x50 <4>[ 246.794519] __driver_attach+0x97/0x130 <4>[ 246.794519] bus_for_each_dev+0x74/0xc0 <4>[ 246.794519] bus_add_driver+0x13f/0x210 <4>[ 246.794519] driver_register+0x56/0xe0 <4>[ 246.794519] do_one_initcall+0x58/0x300 <4>[ 246.794519] do_init_module+0x56/0x1f6 <4>[ 246.794519] load_module+0x25bd/0x2a40 <4>[ 246.794519] __se_sys_finit_module+0xd3/0xf0 <4>[ 246.794519] do_syscall_64+0x55/0x1c0 <4>[ 246.794519] entry_SYSCALL_64_after_hwframe+0x49/0xbe <4>[ 246.794519] -> #0 (&dev->struct_mutex/1){+.+.}: <4>[ 246.794519] __lock_acquire+0x15d8/0x1e90 <4>[ 246.794519] lock_acquire+0xa6/0x1c0 <4>[ 246.794519] __mutex_lock+0x9d/0x9b0 <4>[ 246.794519] userptr_mn_invalidate_range_start+0x18f/0x220 [i915] <4>[ 246.794519] __mmu_notifier_invalidate_range_start+0x85/0x110 <4>[ 246.794519] try_to_unmap_one+0x76b/0x860 <4>[ 246.794519] rmap_walk_anon+0x104/0x280 <4>[ 246.794519] try_to_unmap+0xc0/0xf0 <4>[ 246.794519] shrink_page_list+0x561/0xc10 <4>[ 246.794519] shrink_inactive_list+0x220/0x440 <4>[ 246.794519] shrink_node_memcg+0x36e/0x740 <4>[ 246.794519] shrink_node+0xcb/0x490 <4>[ 246.794519] balance_pgdat+0x241/0x580 <4>[ 246.794519] kswapd+0x16c/0x530 <4>[ 246.794519] kthread+0x119/0x130 <4>[ 246.794519] ret_from_fork+0x24/0x50 <4>[ 246.794519] other info that might help us debug this: <4>[ 246.794519] Chain exists of: &dev->struct_mutex/1 --> &mapping->i_mmap_rwsem --> &anon_vma->rwsem <4>[ 246.794519] Possible unsafe locking scenario: <4>[ 246.794519] CPU0 CPU1 <4>[ 246.794519] ---- ---- <4>[ 246.794519] lock(&anon_vma->rwsem); <4>[ 246.794519] lock(&mapping->i_mmap_rwsem); <4>[ 246.794519] lock(&anon_vma->rwsem); <4>[ 246.794519] lock(&dev->struct_mutex/1); <4>[ 246.794519] *** DEADLOCK *** v2: Say no to mmap_ioctl Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111744 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111870 Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Daniel Vetter Cc: stable@vger.kernel.org Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190928082546.3473-1-chris@chris-wilson.co.uk (cherry picked from commit a4311745bba9763e3c965643d4531bd5765b0513) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gem/i915_gem_mman.c | 7 +++++++ drivers/gpu/drm/i915/gem/i915_gem_object.h | 6 ++++++ drivers/gpu/drm/i915/gem/i915_gem_object_types.h | 3 ++- drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 1 + drivers/gpu/drm/i915/i915_gem.c | 3 +++ 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c index 91051e178021..05289edbafe3 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c @@ -364,6 +364,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf) return VM_FAULT_OOM; case -ENOSPC: case -EFAULT: + case -ENODEV: /* bad object, how did you get here! */ return VM_FAULT_SIGBUS; default: WARN_ONCE(ret, "unhandled error in %s: %i\n", __func__, ret); @@ -475,10 +476,16 @@ i915_gem_mmap_gtt(struct drm_file *file, if (!obj) return -ENOENT; + if (i915_gem_object_never_bind_ggtt(obj)) { + ret = -ENODEV; + goto out; + } + ret = create_mmap_offset(obj); if (ret == 0) *offset = drm_vma_node_offset_addr(&obj->base.vma_node); +out: i915_gem_object_put(obj); return ret; } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 5efb9936e05b..ddf3605bea8e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -152,6 +152,12 @@ i915_gem_object_is_proxy(const struct drm_i915_gem_object *obj) return obj->ops->flags & I915_GEM_OBJECT_IS_PROXY; } +static inline bool +i915_gem_object_never_bind_ggtt(const struct drm_i915_gem_object *obj) +{ + return obj->ops->flags & I915_GEM_OBJECT_NO_GGTT; +} + static inline bool i915_gem_object_needs_async_cancel(const struct drm_i915_gem_object *obj) { diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index ede0eb4218a8..646859fea224 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -32,7 +32,8 @@ struct drm_i915_gem_object_ops { #define I915_GEM_OBJECT_HAS_STRUCT_PAGE BIT(0) #define I915_GEM_OBJECT_IS_SHRINKABLE BIT(1) #define I915_GEM_OBJECT_IS_PROXY BIT(2) -#define I915_GEM_OBJECT_ASYNC_CANCEL BIT(3) +#define I915_GEM_OBJECT_NO_GGTT BIT(3) +#define I915_GEM_OBJECT_ASYNC_CANCEL BIT(4) /* Interface between the GEM object and its backing storage. * get_pages() is called once prior to the use of the associated set diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c index 11b231c187c5..6b3b50f0f6d9 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -702,6 +702,7 @@ i915_gem_userptr_dmabuf_export(struct drm_i915_gem_object *obj) static const struct drm_i915_gem_object_ops i915_gem_userptr_ops = { .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE | I915_GEM_OBJECT_IS_SHRINKABLE | + I915_GEM_OBJECT_NO_GGTT | I915_GEM_OBJECT_ASYNC_CANCEL, .get_pages = i915_gem_userptr_get_pages, .put_pages = i915_gem_userptr_put_pages, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 95e7c52cf8ed..d0f94f239919 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -969,6 +969,9 @@ i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj, lockdep_assert_held(&obj->base.dev->struct_mutex); + if (i915_gem_object_never_bind_ggtt(obj)) + return ERR_PTR(-ENODEV); + if (flags & PIN_MAPPABLE && (!view || view->type == I915_GGTT_VIEW_NORMAL)) { /* If the required space is larger than the available -- GitLab From 0a544a2a728e2e33bb7fc38dd542ecb90ee393eb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 23 Sep 2019 16:28:42 +0100 Subject: [PATCH 388/993] drm/i915: Fixup preempt-to-busy vs resubmission of a virtual request As preempt-to-busy leaves the request on the HW as the resubmission is processed, that request may complete in the background and even cause a second virtual request to enter queue. This second virtual request breaks our "single request in the virtual pipeline" assumptions. Furthermore, as the virtual request may be completed and retired, we lose the reference the virtual engine assumes is held. Normally, just removing the request from the scheduler queue removes it from the engine, but the virtual engine keeps track of its singleton request via its ve->request. This pointer needs protecting with a reference. v2: Drop unnecessary motion of rq->engine = owner Fixes: 22b7a426bbe1 ("drm/i915/execlists: Preempt-to-busy") Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Tvrtko Ursulin Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20190923152844.8914-1-chris@chris-wilson.co.uk (cherry picked from commit b647c7df01b75761b4c0b1cb6f4841088c0b1121) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gt/intel_lrc.c | 32 +++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 46005986e95f..06a506c29463 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -1243,6 +1243,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) submit = true; last = rq; } + i915_request_put(rq); /* * Hmm, we have a bunch of virtual engine requests, @@ -2613,6 +2614,7 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) rq->engine = engine; __i915_request_submit(rq); + i915_request_put(rq); ve->base.execlists.queue_priority_hint = INT_MIN; } @@ -3618,6 +3620,8 @@ static void virtual_submission_tasklet(unsigned long data) static void virtual_submit_request(struct i915_request *rq) { struct virtual_engine *ve = to_virtual_engine(rq->engine); + struct i915_request *old; + unsigned long flags; GEM_TRACE("%s: rq=%llx:%lld\n", ve->base.name, @@ -3626,15 +3630,31 @@ static void virtual_submit_request(struct i915_request *rq) GEM_BUG_ON(ve->base.submit_request != virtual_submit_request); - GEM_BUG_ON(ve->request); - GEM_BUG_ON(!list_empty(virtual_queue(ve))); + spin_lock_irqsave(&ve->base.active.lock, flags); + + old = ve->request; + if (old) { /* background completion event from preempt-to-busy */ + GEM_BUG_ON(!i915_request_completed(old)); + __i915_request_submit(old); + i915_request_put(old); + } - ve->base.execlists.queue_priority_hint = rq_prio(rq); - WRITE_ONCE(ve->request, rq); + if (i915_request_completed(rq)) { + __i915_request_submit(rq); - list_move_tail(&rq->sched.link, virtual_queue(ve)); + ve->base.execlists.queue_priority_hint = INT_MIN; + ve->request = NULL; + } else { + ve->base.execlists.queue_priority_hint = rq_prio(rq); + ve->request = i915_request_get(rq); + + GEM_BUG_ON(!list_empty(virtual_queue(ve))); + list_move_tail(&rq->sched.link, virtual_queue(ve)); + + tasklet_schedule(&ve->base.execlists.tasklet); + } - tasklet_schedule(&ve->base.execlists.tasklet); + spin_unlock_irqrestore(&ve->base.active.lock, flags); } static struct ve_bond * -- GitLab From 2ca4f6ca4562594ef161e4140c2a5e0e5282967b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 14 Oct 2019 06:04:38 -0700 Subject: [PATCH 389/993] rxrpc: use rcu protection while reading sk->sk_user_data We need to extend the rcu_read_lock() section in rxrpc_error_report() and use rcu_dereference_sk_user_data() instead of plain access to sk->sk_user_data to make sure all rules are respected. The compiler wont reload sk->sk_user_data at will, and RCU rules prevent memory beeing freed too soon. Fixes: f0308fb07080 ("rxrpc: Fix possible NULL pointer access in ICMP handling") Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both") Signed-off-by: Eric Dumazet Cc: David Howells Signed-off-by: David S. Miller --- net/rxrpc/peer_event.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/net/rxrpc/peer_event.c b/net/rxrpc/peer_event.c index 61451281d74a..48f67a9b1037 100644 --- a/net/rxrpc/peer_event.c +++ b/net/rxrpc/peer_event.c @@ -147,13 +147,16 @@ void rxrpc_error_report(struct sock *sk) { struct sock_exterr_skb *serr; struct sockaddr_rxrpc srx; - struct rxrpc_local *local = sk->sk_user_data; + struct rxrpc_local *local; struct rxrpc_peer *peer; struct sk_buff *skb; - if (unlikely(!local)) + rcu_read_lock(); + local = rcu_dereference_sk_user_data(sk); + if (unlikely(!local)) { + rcu_read_unlock(); return; - + } _enter("%p{%d}", sk, local->debug_id); /* Clear the outstanding error value on the socket so that it doesn't @@ -163,6 +166,7 @@ void rxrpc_error_report(struct sock *sk) skb = sock_dequeue_err_skb(sk); if (!skb) { + rcu_read_unlock(); _leave("UDP socket errqueue empty"); return; } @@ -170,11 +174,11 @@ void rxrpc_error_report(struct sock *sk) serr = SKB_EXT_ERR(skb); if (!skb->len && serr->ee.ee_origin == SO_EE_ORIGIN_TIMESTAMPING) { _leave("UDP empty message"); + rcu_read_unlock(); rxrpc_free_skb(skb, rxrpc_skb_freed); return; } - rcu_read_lock(); peer = rxrpc_lookup_peer_icmp_rcu(local, skb, &srx); if (peer && !rxrpc_get_peer_maybe(peer)) peer = NULL; -- GitLab From 3de5ae54712c75cf3c517a288e0a704784ec6cf5 Mon Sep 17 00:00:00 2001 From: Yonglong Liu Date: Wed, 16 Oct 2019 10:30:39 +0800 Subject: [PATCH 390/993] net: phy: Fix "link partner" information disappear issue Some drivers just call phy_ethtool_ksettings_set() to set the links, for those phy drivers that use genphy_read_status(), if autoneg is on, and the link is up, than execute "ethtool -s ethx autoneg on" will cause "link partner" information disappear. The call trace is phy_ethtool_ksettings_set()->phy_start_aneg() ->linkmode_zero(phydev->lp_advertising)->genphy_read_status(), the link didn't change, so genphy_read_status() just return, and phydev->lp_advertising is zero now. This patch moves the clear operation of lp_advertising from phy_start_aneg() to genphy_read_lpa()/genphy_c45_read_lpa(), and if autoneg on and autoneg not complete, just clear what the generic functions care about. Fixes: 88d6272acaaa ("net: phy: avoid unneeded MDIO reads in genphy_read_status") Signed-off-by: Yonglong Liu Reviewed-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/phy/phy-c45.c | 2 ++ drivers/net/phy/phy.c | 3 --- drivers/net/phy/phy_device.c | 11 ++++++++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c index 7935593debb1..a1caeee12236 100644 --- a/drivers/net/phy/phy-c45.c +++ b/drivers/net/phy/phy-c45.c @@ -323,6 +323,8 @@ int genphy_c45_read_pma(struct phy_device *phydev) { int val; + linkmode_zero(phydev->lp_advertising); + val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1); if (val < 0) return val; diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 119e6f466056..105d389b58e7 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -572,9 +572,6 @@ int phy_start_aneg(struct phy_device *phydev) if (AUTONEG_DISABLE == phydev->autoneg) phy_sanitize_settings(phydev); - /* Invalidate LP advertising flags */ - linkmode_zero(phydev->lp_advertising); - err = phy_config_aneg(phydev); if (err < 0) goto out_unlock; diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 9d2bbb13293e..adb66a2fae18 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1787,7 +1787,14 @@ int genphy_read_lpa(struct phy_device *phydev) { int lpa, lpagb; - if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) { + if (phydev->autoneg == AUTONEG_ENABLE) { + if (!phydev->autoneg_complete) { + mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, + 0); + mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, 0); + return 0; + } + if (phydev->is_gigabit_capable) { lpagb = phy_read(phydev, MII_STAT1000); if (lpagb < 0) @@ -1815,6 +1822,8 @@ int genphy_read_lpa(struct phy_device *phydev) return lpa; mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa); + } else { + linkmode_zero(phydev->lp_advertising); } return 0; -- GitLab From e497c20e203680aba9ccf7bb475959595908ca7e Mon Sep 17 00:00:00 2001 From: Biao Huang Date: Tue, 15 Oct 2019 11:24:44 +0800 Subject: [PATCH 391/993] net: stmmac: disable/enable ptp_ref_clk in suspend/resume flow disable ptp_ref_clk in suspend flow, and enable it in resume flow. Fixes: f573c0b9c4e0 ("stmmac: move stmmac_clk, pclk, clk_ptp_ref and stmmac_rst to platform structure") Signed-off-by: Biao Huang Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index c76a1336a451..8fa13d43b5bc 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -4742,8 +4742,10 @@ int stmmac_suspend(struct device *dev) stmmac_mac_set(priv, priv->ioaddr, false); pinctrl_pm_select_sleep_state(priv->device); /* Disable clock in case of PWM is off */ - clk_disable(priv->plat->pclk); - clk_disable(priv->plat->stmmac_clk); + if (priv->plat->clk_ptp_ref) + clk_disable_unprepare(priv->plat->clk_ptp_ref); + clk_disable_unprepare(priv->plat->pclk); + clk_disable_unprepare(priv->plat->stmmac_clk); } mutex_unlock(&priv->lock); @@ -4806,8 +4808,10 @@ int stmmac_resume(struct device *dev) } else { pinctrl_pm_select_default_state(priv->device); /* enable the clk previously disabled */ - clk_enable(priv->plat->stmmac_clk); - clk_enable(priv->plat->pclk); + clk_prepare_enable(priv->plat->stmmac_clk); + clk_prepare_enable(priv->plat->pclk); + if (priv->plat->clk_ptp_ref) + clk_prepare_enable(priv->plat->clk_ptp_ref); /* reset the phy so that it's ready */ if (priv->mii) stmmac_mdio_reset(priv->mii); -- GitLab From d10f60ae27d26d811e2a1bb39ded47df96d7499f Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 14 Oct 2019 16:51:28 +0000 Subject: [PATCH 392/993] powerpc/32s: fix allow/prevent_user_access() when crossing segment boundaries. Make sure starting addr is aligned to segment boundary so that when incrementing the segment, the starting address of the new segment is below the end address. Otherwise the last segment might get missed. Fixes: a68c31fc01ef ("powerpc/32s: Implement Kernel Userspace Access Protection") Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/067a1b09f15f421d40797c2d04c22d4049a1cee8.1571071875.git.christophe.leroy@c-s.fr --- arch/powerpc/include/asm/book3s/32/kup.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/include/asm/book3s/32/kup.h b/arch/powerpc/include/asm/book3s/32/kup.h index 677e9babef80..f9dc597b0b86 100644 --- a/arch/powerpc/include/asm/book3s/32/kup.h +++ b/arch/powerpc/include/asm/book3s/32/kup.h @@ -91,6 +91,7 @@ static inline void kuap_update_sr(u32 sr, u32 addr, u32 end) { + addr &= 0xf0000000; /* align addr to start of segment */ barrier(); /* make sure thread.kuap is updated before playing with SRs */ while (addr < end) { mtsrin(sr, addr); -- GitLab From 700dea5a0bea9f64eba89fae7cb2540326fdfdc1 Mon Sep 17 00:00:00 2001 From: Dmitry Goldin Date: Wed, 9 Oct 2019 13:42:14 +0000 Subject: [PATCH 393/993] kheaders: substituting --sort in archive creation The option --sort=ORDER was only introduced in tar 1.28 (2014), which is rather new and might not be available in some setups. This patch tries to replicate the previous behaviour as closely as possible to fix the kheaders build for older environments. It does not produce identical archives compared to the previous version due to minor sorting differences but produces reproducible results itself in my tests. Reported-by: Andreas Schwab Signed-off-by: Dmitry Goldin Tested-by: Andreas Schwab Tested-by: Quentin Perret Signed-off-by: Masahiro Yamada --- kernel/gen_kheaders.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh index aff79e461fc9..5a0fc0b0403a 100755 --- a/kernel/gen_kheaders.sh +++ b/kernel/gen_kheaders.sh @@ -71,10 +71,13 @@ done | cpio --quiet -pd $cpio_dir >/dev/null 2>&1 find $cpio_dir -type f -print0 | xargs -0 -P8 -n1 perl -pi -e 'BEGIN {undef $/;}; s/\/\*((?!SPDX).)*?\*\///smg;' -# Create archive and try to normalize metadata for reproducibility -tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ - --owner=0 --group=0 --sort=name --numeric-owner \ - -Jcf $tarfile -C $cpio_dir/ . > /dev/null +# Create archive and try to normalize metadata for reproducibility. +# For compatibility with older versions of tar, files are fed to tar +# pre-sorted, as --sort=name might not be available. +find $cpio_dir -printf "./%P\n" | LC_ALL=C sort | \ + tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ + --owner=0 --group=0 --numeric-owner --no-recursion \ + -Jcf $tarfile -C $cpio_dir/ -T - > /dev/null echo "$src_files_md5" > kernel/kheaders.md5 echo "$obj_files_md5" >> kernel/kheaders.md5 -- GitLab From 7571b6a17fcc5e4f6903f065a82d0e38011346ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szabolcs=20Sz=C5=91ke?= Date: Fri, 11 Oct 2019 19:19:36 +0200 Subject: [PATCH 394/993] ALSA: usb-audio: Disable quirks for BOSS Katana amplifiers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BOSS Katana amplifiers cannot be used for recording or playback if quirks are applied BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=195223 Signed-off-by: Szabolcs Szőke Cc: Link: https://lore.kernel.org/r/20191011171937.8013-1-szszoke.code@gmail.com Signed-off-by: Takashi Iwai --- sound/usb/pcm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 33cd26763c0e..ff5ab24f3bd1 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -348,6 +348,9 @@ static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs, ep = 0x84; ifnum = 0; goto add_sync_ep_from_ifnum; + case USB_ID(0x0582, 0x01d8): /* BOSS Katana */ + /* BOSS Katana amplifiers do not need quirks */ + return 0; } if (attr == USB_ENDPOINT_SYNC_ASYNC && -- GitLab From 8c8967a7dc01a25f57a0757fdca10987773cd1f2 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Thu, 17 Oct 2019 16:15:01 +0800 Subject: [PATCH 395/993] ALSA: hda/realtek - Enable headset mic on Asus MJ401TA On Asus MJ401TA (with Realtek ALC256), the headset mic is connected to pin 0x19, with default configuration value 0x411111f0 (indicating no physical connection). Enable this by quirking the pin. Mic jack detection was also tested and found to be working. This enables use of the headset mic on this product. Signed-off-by: Daniel Drake Cc: Link: https://lore.kernel.org/r/20191017081501.17135-1-drake@endlessm.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index b5c225a56b98..ce4f11659765 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5881,6 +5881,7 @@ enum { ALC225_FIXUP_WYSE_AUTO_MUTE, ALC225_FIXUP_WYSE_DISABLE_MIC_VREF, ALC286_FIXUP_ACER_AIO_HEADSET_MIC, + ALC256_FIXUP_ASUS_HEADSET_MIC, ALC256_FIXUP_ASUS_MIC_NO_PRESENCE, ALC299_FIXUP_PREDATOR_SPK, ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC, @@ -6930,6 +6931,15 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE }, + [ALC256_FIXUP_ASUS_HEADSET_MIC] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x19, 0x03a11020 }, /* headset mic with jack detect */ + { } + }, + .chained = true, + .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE + }, [ALC256_FIXUP_ASUS_MIC_NO_PRESENCE] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -7126,6 +7136,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC), + SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), -- GitLab From 1e72e673b9d102ff2e8333e74b3308d012ddf75b Mon Sep 17 00:00:00 2001 From: James Morse Date: Mon, 14 Oct 2019 18:19:18 +0100 Subject: [PATCH 396/993] EDAC/ghes: Fix Use after free in ghes_edac remove path ghes_edac models a single logical memory controller, and uses a global ghes_init variable to ensure only the first ghes_edac_register() will do anything. ghes_edac is registered the first time a GHES entry in the HEST is probed. There may be multiple entries, so subsequent attempts to register ghes_edac are silently ignored as the work has already been done. When a GHES entry is unregistered, it calls ghes_edac_unregister(), which free()s the memory behind the global variables in ghes_edac. But there may be multiple GHES entries, the next call to ghes_edac_unregister() will dereference the free()d memory, and attempt to free it a second time. This may also be triggered on a platform with one GHES entry, if the driver is unbound/re-bound and unbound. The re-bind step will do nothing because of ghes_init, the second unbind will then do the same work as the first. Doing the unregister work on the first call is unsafe, as another CPU may be processing a notification in ghes_edac_report_mem_error(), using the memory we are about to free. ghes_init is already half of the reference counting. We only need to do the register work for the first call, and the unregister work for the last. Add the unregister check. This means we no longer free ghes_edac's memory while there are GHES entries that may receive a notification. This was detected by KASAN and DEBUG_TEST_DRIVER_REMOVE. [ bp: merge into a single patch. ] Fixes: 0fe5f281f749 ("EDAC, ghes: Model a single, logical memory controller") Reported-by: John Garry Signed-off-by: James Morse Signed-off-by: Borislav Petkov Cc: linux-edac Cc: Mauro Carvalho Chehab Cc: Robert Richter Cc: Tony Luck Cc: Link: https://lkml.kernel.org/r/20191014171919.85044-2-james.morse@arm.com Link: https://lkml.kernel.org/r/304df85b-8b56-b77e-1a11-aa23769f2e7c@huawei.com --- drivers/edac/ghes_edac.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c index d413a0bdc9ad..0bb62857ffb2 100644 --- a/drivers/edac/ghes_edac.c +++ b/drivers/edac/ghes_edac.c @@ -553,7 +553,11 @@ void ghes_edac_unregister(struct ghes *ghes) if (!ghes_pvt) return; + if (atomic_dec_return(&ghes_init)) + return; + mci = ghes_pvt->mci; + ghes_pvt = NULL; edac_mc_del_mc(mci->pdev); edac_mc_free(mci); } -- GitLab From b1fc5833357524d5d342737913dbe32ff3557bc5 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Mon, 7 Oct 2019 11:45:36 +0100 Subject: [PATCH 397/993] stop_machine: Avoid potential race behaviour Both multi_cpu_stop() and set_state() access multi_stop_data::state racily using plain accesses. These are subject to compiler transformations which could break the intended behaviour of the code, and this situation is detected by KCSAN on both arm64 and x86 (splats below). Improve matters by using READ_ONCE() and WRITE_ONCE() to ensure that the compiler cannot elide, replay, or tear loads and stores. In multi_cpu_stop() the two loads of multi_stop_data::state are expected to be a consistent value, so snapshot the value into a temporary variable to ensure this. The state transitions are serialized by atomic manipulation of multi_stop_data::num_threads, and other fields in multi_stop_data are not modified while subject to concurrent reads. KCSAN splat on arm64: | BUG: KCSAN: data-race in multi_cpu_stop+0xa8/0x198 and set_state+0x80/0xb0 | | write to 0xffff00001003bd00 of 4 bytes by task 24 on cpu 3: | set_state+0x80/0xb0 | multi_cpu_stop+0x16c/0x198 | cpu_stopper_thread+0x170/0x298 | smpboot_thread_fn+0x40c/0x560 | kthread+0x1a8/0x1b0 | ret_from_fork+0x10/0x18 | | read to 0xffff00001003bd00 of 4 bytes by task 14 on cpu 1: | multi_cpu_stop+0xa8/0x198 | cpu_stopper_thread+0x170/0x298 | smpboot_thread_fn+0x40c/0x560 | kthread+0x1a8/0x1b0 | ret_from_fork+0x10/0x18 | | Reported by Kernel Concurrency Sanitizer on: | CPU: 1 PID: 14 Comm: migration/1 Not tainted 5.3.0-00007-g67ab35a199f4-dirty #3 | Hardware name: linux,dummy-virt (DT) KCSAN splat on x86: | write to 0xffffb0bac0013e18 of 4 bytes by task 19 on cpu 2: | set_state kernel/stop_machine.c:170 [inline] | ack_state kernel/stop_machine.c:177 [inline] | multi_cpu_stop+0x1a4/0x220 kernel/stop_machine.c:227 | cpu_stopper_thread+0x19e/0x280 kernel/stop_machine.c:516 | smpboot_thread_fn+0x1a8/0x300 kernel/smpboot.c:165 | kthread+0x1b5/0x200 kernel/kthread.c:255 | ret_from_fork+0x35/0x40 arch/x86/entry/entry_64.S:352 | | read to 0xffffb0bac0013e18 of 4 bytes by task 44 on cpu 7: | multi_cpu_stop+0xb4/0x220 kernel/stop_machine.c:213 | cpu_stopper_thread+0x19e/0x280 kernel/stop_machine.c:516 | smpboot_thread_fn+0x1a8/0x300 kernel/smpboot.c:165 | kthread+0x1b5/0x200 kernel/kthread.c:255 | ret_from_fork+0x35/0x40 arch/x86/entry/entry_64.S:352 | | Reported by Kernel Concurrency Sanitizer on: | CPU: 7 PID: 44 Comm: migration/7 Not tainted 5.3.0+ #1 | Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 Signed-off-by: Mark Rutland Signed-off-by: Thomas Gleixner Acked-by: Marco Elver Link: https://lkml.kernel.org/r/20191007104536.27276-1-mark.rutland@arm.com --- kernel/stop_machine.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index c7031a22aa7b..998d50ee2d9b 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c @@ -7,6 +7,7 @@ * Copyright (C) 2010 SUSE Linux Products GmbH * Copyright (C) 2010 Tejun Heo */ +#include #include #include #include @@ -167,7 +168,7 @@ static void set_state(struct multi_stop_data *msdata, /* Reset ack counter. */ atomic_set(&msdata->thread_ack, msdata->num_threads); smp_wmb(); - msdata->state = newstate; + WRITE_ONCE(msdata->state, newstate); } /* Last one to ack a state moves to the next state. */ @@ -186,7 +187,7 @@ void __weak stop_machine_yield(const struct cpumask *cpumask) static int multi_cpu_stop(void *data) { struct multi_stop_data *msdata = data; - enum multi_stop_state curstate = MULTI_STOP_NONE; + enum multi_stop_state newstate, curstate = MULTI_STOP_NONE; int cpu = smp_processor_id(), err = 0; const struct cpumask *cpumask; unsigned long flags; @@ -210,8 +211,9 @@ static int multi_cpu_stop(void *data) do { /* Chill out and ensure we re-read multi_stop_state. */ stop_machine_yield(cpumask); - if (msdata->state != curstate) { - curstate = msdata->state; + newstate = READ_ONCE(msdata->state); + if (newstate != curstate) { + curstate = newstate; switch (curstate) { case MULTI_STOP_DISABLE_IRQ: local_irq_disable(); -- GitLab From fd2b007eaec898564e269d1f478a2da0380ecf51 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Thu, 17 Oct 2019 10:38:36 +0800 Subject: [PATCH 398/993] btrfs: tracepoints: Fix wrong parameter order for qgroup events [BUG] For btrfs:qgroup_meta_reserve event, the trace event can output garbage: qgroup_meta_reserve: 9c7f6acc-b342-4037-bc47-7f6e4d2232d7: refroot=5(FS_TREE) type=DATA diff=2 The diff should always be alinged to sector size (4k), so there is definitely something wrong. [CAUSE] For the wrong @diff, it's caused by wrong parameter order. The correct parameters are: struct btrfs_root, s64 diff, int type. However the parameters used are: struct btrfs_root, int type, s64 diff. Fixes: 4ee0d8832c2e ("btrfs: qgroup: Update trace events for metadata reservation") CC: stable@vger.kernel.org # 4.19+ Reviewed-by: Nikolay Borisov Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/qgroup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index c4bb69941c77..3ad151655eb8 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -3629,7 +3629,7 @@ int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, return 0; BUG_ON(num_bytes != round_down(num_bytes, fs_info->nodesize)); - trace_qgroup_meta_reserve(root, type, (s64)num_bytes); + trace_qgroup_meta_reserve(root, (s64)num_bytes, type); ret = qgroup_reserve(root, num_bytes, enforce, type); if (ret < 0) return ret; @@ -3676,7 +3676,7 @@ void __btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes, */ num_bytes = sub_root_meta_rsv(root, num_bytes, type); BUG_ON(num_bytes != round_down(num_bytes, fs_info->nodesize)); - trace_qgroup_meta_reserve(root, type, -(s64)num_bytes); + trace_qgroup_meta_reserve(root, -(s64)num_bytes, type); btrfs_qgroup_free_refroot(fs_info, root->root_key.objectid, num_bytes, type); } -- GitLab From 1b2442b4ae0f234daeadd90e153b466332c466d8 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Thu, 17 Oct 2019 10:38:37 +0800 Subject: [PATCH 399/993] btrfs: tracepoints: Fix bad entry members of qgroup events [BUG] For btrfs:qgroup_meta_reserve event, the trace event can output garbage: qgroup_meta_reserve: 9c7f6acc-b342-4037-bc47-7f6e4d2232d7: refroot=5(FS_TREE) type=DATA diff=2 qgroup_meta_reserve: 9c7f6acc-b342-4037-bc47-7f6e4d2232d7: refroot=5(FS_TREE) type=0x258792 diff=2 The @type can be completely garbage, as DATA type is not possible for trace_qgroup_meta_reserve() trace event. [CAUSE] Ther are several problems related to qgroup trace events: - Unassigned entry member Member entry::type of trace_qgroup_update_reserve() and trace_qgourp_meta_reserve() is not assigned - Redundant entry member Member entry::type is completely useless in trace_qgroup_meta_convert() Fixes: 4ee0d8832c2e ("btrfs: qgroup: Update trace events for metadata reservation") CC: stable@vger.kernel.org # 4.10+ Reviewed-by: Nikolay Borisov Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba --- include/trace/events/btrfs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h index 5df604de4f11..75ae1899452b 100644 --- a/include/trace/events/btrfs.h +++ b/include/trace/events/btrfs.h @@ -1688,6 +1688,7 @@ TRACE_EVENT(qgroup_update_reserve, __entry->qgid = qgroup->qgroupid; __entry->cur_reserved = qgroup->rsv.values[type]; __entry->diff = diff; + __entry->type = type; ), TP_printk_btrfs("qgid=%llu type=%s cur_reserved=%llu diff=%lld", @@ -1710,6 +1711,7 @@ TRACE_EVENT(qgroup_meta_reserve, TP_fast_assign_btrfs(root->fs_info, __entry->refroot = root->root_key.objectid; __entry->diff = diff; + __entry->type = type; ), TP_printk_btrfs("refroot=%llu(%s) type=%s diff=%lld", @@ -1726,7 +1728,6 @@ TRACE_EVENT(qgroup_meta_convert, TP_STRUCT__entry_btrfs( __field( u64, refroot ) __field( s64, diff ) - __field( int, type ) ), TP_fast_assign_btrfs(root->fs_info, -- GitLab From 45d02f79b539073b76077836871de6b674e36eb4 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Wed, 16 Oct 2019 17:01:18 +0200 Subject: [PATCH 400/993] binder: Don't modify VMA bounds in ->mmap handler binder_mmap() tries to prevent the creation of overly big binder mappings by silently truncating the size of the VMA to 4MiB. However, this violates the API contract of mmap(). If userspace attempts to create a large binder VMA, and later attempts to unmap that VMA, it will call munmap() on a range beyond the end of the VMA, which may have been allocated to another VMA in the meantime. This can lead to userspace memory corruption. The following sequence of calls leads to a segfault without this commit: int main(void) { int binder_fd = open("/dev/binder", O_RDWR); if (binder_fd == -1) err(1, "open binder"); void *binder_mapping = mmap(NULL, 0x800000UL, PROT_READ, MAP_SHARED, binder_fd, 0); if (binder_mapping == MAP_FAILED) err(1, "mmap binder"); void *data_mapping = mmap(NULL, 0x400000UL, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (data_mapping == MAP_FAILED) err(1, "mmap data"); munmap(binder_mapping, 0x800000UL); *(char*)data_mapping = 1; return 0; } Cc: stable@vger.kernel.org Signed-off-by: Jann Horn Acked-by: Todd Kjos Acked-by: Christian Brauner Link: https://lore.kernel.org/r/20191016150119.154756-1-jannh@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder.c | 7 ------- drivers/android/binder_alloc.c | 6 ++++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 5b9ac2122e89..265d9dd46a5e 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -97,10 +97,6 @@ DEFINE_SHOW_ATTRIBUTE(proc); #define SZ_1K 0x400 #endif -#ifndef SZ_4M -#define SZ_4M 0x400000 -#endif - #define FORBIDDEN_MMAP_FLAGS (VM_WRITE) enum { @@ -5177,9 +5173,6 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) if (proc->tsk != current->group_leader) return -EINVAL; - if ((vma->vm_end - vma->vm_start) > SZ_4M) - vma->vm_end = vma->vm_start + SZ_4M; - binder_debug(BINDER_DEBUG_OPEN_CLOSE, "%s: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", __func__, proc->pid, vma->vm_start, vma->vm_end, diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index d42a8b2f636a..eb76a823fbb2 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "binder_alloc.h" #include "binder_trace.h" @@ -689,7 +690,9 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc, alloc->buffer = (void __user *)vma->vm_start; mutex_unlock(&binder_alloc_mmap_lock); - alloc->pages = kcalloc((vma->vm_end - vma->vm_start) / PAGE_SIZE, + alloc->buffer_size = min_t(unsigned long, vma->vm_end - vma->vm_start, + SZ_4M); + alloc->pages = kcalloc(alloc->buffer_size / PAGE_SIZE, sizeof(alloc->pages[0]), GFP_KERNEL); if (alloc->pages == NULL) { @@ -697,7 +700,6 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc, failure_string = "alloc page array"; goto err_alloc_pages_failed; } - alloc->buffer_size = vma->vm_end - vma->vm_start; buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); if (!buffer) { -- GitLab From 564b6bb9d42d31fc80c006658cf38940a9b99616 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 30 Aug 2019 13:22:02 +0300 Subject: [PATCH 401/993] ARM: davinci: dm365: Fix McBSP dma_slave_map entry dm365 have only single McBSP, so the device name is without .0 Fixes: 0c750e1fe481d ("ARM: davinci: dm365: Add dma_slave_map to edma") Signed-off-by: Peter Ujfalusi Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/dm365.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 8062412be70f..9fc5c73cc0be 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -462,8 +462,8 @@ static s8 dm365_queue_priority_mapping[][2] = { }; static const struct dma_slave_map dm365_edma_map[] = { - { "davinci-mcbsp.0", "tx", EDMA_FILTER_PARAM(0, 2) }, - { "davinci-mcbsp.0", "rx", EDMA_FILTER_PARAM(0, 3) }, + { "davinci-mcbsp", "tx", EDMA_FILTER_PARAM(0, 2) }, + { "davinci-mcbsp", "rx", EDMA_FILTER_PARAM(0, 3) }, { "davinci_voicecodec", "tx", EDMA_FILTER_PARAM(0, 2) }, { "davinci_voicecodec", "rx", EDMA_FILTER_PARAM(0, 3) }, { "spi_davinci.2", "tx", EDMA_FILTER_PARAM(0, 10) }, -- GitLab From 7b21483ccbef1b274a238c0653a03d778b21fbd7 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 22 Jul 2019 15:44:16 +0200 Subject: [PATCH 402/993] ARM: davinci_all_defconfig: enable GPIO backlight DA850 EVM has been converted to use GPIO backlight device for display backlight GPIO control. Enable the GPIO backlight module in davinci_all_defconfig to keep backlight support working. Signed-off-by: Bartosz Golaszewski [nsekhar@ti.com: edits to commit message for context] Signed-off-by: Sekhar Nori --- arch/arm/configs/davinci_all_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig index b34970ce6b31..2fbc11116d15 100644 --- a/arch/arm/configs/davinci_all_defconfig +++ b/arch/arm/configs/davinci_all_defconfig @@ -167,6 +167,7 @@ CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_DA8XX=y CONFIG_BACKLIGHT_PWM=m +CONFIG_BACKLIGHT_GPIO=m CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=m -- GitLab From 13bd677a472d534bf100bab2713efc3f9e3f5978 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 16 Oct 2019 09:21:50 -0400 Subject: [PATCH 403/993] dm cache: fix bugs when a GFP_NOWAIT allocation fails GFP_NOWAIT allocation can fail anytime - it doesn't wait for memory being available and it fails if the mempool is exhausted and there is not enough memory. If we go down this path: map_bio -> mg_start -> alloc_migration -> mempool_alloc(GFP_NOWAIT) we can see that map_bio() doesn't check the return value of mg_start(), and the bio is leaked. If we go down this path: map_bio -> mg_start -> mg_lock_writes -> alloc_prison_cell -> dm_bio_prison_alloc_cell_v2 -> mempool_alloc(GFP_NOWAIT) -> mg_lock_writes -> mg_complete the bio is ended with an error - it is unacceptable because it could cause filesystem corruption if the machine ran out of memory temporarily. Change GFP_NOWAIT to GFP_NOIO, so that the mempool code will properly wait until memory becomes available. mempool_alloc with GFP_NOIO can't fail, so remove the code paths that deal with allocation failure. Cc: stable@vger.kernel.org Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer --- drivers/md/dm-cache-target.c | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index d249cf8ac277..8346e6d1816c 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -542,7 +542,7 @@ static void wake_migration_worker(struct cache *cache) static struct dm_bio_prison_cell_v2 *alloc_prison_cell(struct cache *cache) { - return dm_bio_prison_alloc_cell_v2(cache->prison, GFP_NOWAIT); + return dm_bio_prison_alloc_cell_v2(cache->prison, GFP_NOIO); } static void free_prison_cell(struct cache *cache, struct dm_bio_prison_cell_v2 *cell) @@ -554,9 +554,7 @@ static struct dm_cache_migration *alloc_migration(struct cache *cache) { struct dm_cache_migration *mg; - mg = mempool_alloc(&cache->migration_pool, GFP_NOWAIT); - if (!mg) - return NULL; + mg = mempool_alloc(&cache->migration_pool, GFP_NOIO); memset(mg, 0, sizeof(*mg)); @@ -664,10 +662,6 @@ static bool bio_detain_shared(struct cache *cache, dm_oblock_t oblock, struct bi struct dm_bio_prison_cell_v2 *cell_prealloc, *cell; cell_prealloc = alloc_prison_cell(cache); /* FIXME: allow wait if calling from worker */ - if (!cell_prealloc) { - defer_bio(cache, bio); - return false; - } build_key(oblock, end, &key); r = dm_cell_get_v2(cache->prison, &key, lock_level(bio), bio, cell_prealloc, &cell); @@ -1493,11 +1487,6 @@ static int mg_lock_writes(struct dm_cache_migration *mg) struct dm_bio_prison_cell_v2 *prealloc; prealloc = alloc_prison_cell(cache); - if (!prealloc) { - DMERR_LIMIT("%s: alloc_prison_cell failed", cache_device_name(cache)); - mg_complete(mg, false); - return -ENOMEM; - } /* * Prevent writes to the block, but allow reads to continue. @@ -1535,11 +1524,6 @@ static int mg_start(struct cache *cache, struct policy_work *op, struct bio *bio } mg = alloc_migration(cache); - if (!mg) { - policy_complete_background_work(cache->policy, op, false); - background_work_end(cache); - return -ENOMEM; - } mg->op = op; mg->overwrite_bio = bio; @@ -1628,10 +1612,6 @@ static int invalidate_lock(struct dm_cache_migration *mg) struct dm_bio_prison_cell_v2 *prealloc; prealloc = alloc_prison_cell(cache); - if (!prealloc) { - invalidate_complete(mg, false); - return -ENOMEM; - } build_key(mg->invalidate_oblock, oblock_succ(mg->invalidate_oblock), &key); r = dm_cell_lock_v2(cache->prison, &key, @@ -1669,10 +1649,6 @@ static int invalidate_start(struct cache *cache, dm_cblock_t cblock, return -EPERM; mg = alloc_migration(cache); - if (!mg) { - background_work_end(cache); - return -ENOMEM; - } mg->overwrite_bio = bio; mg->invalidate_cblock = cblock; -- GitLab From 94989e318b2f11e217e86bee058088064fa9a2e9 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Thu, 17 Oct 2019 17:04:11 +0200 Subject: [PATCH 404/993] ALSA: hda - Force runtime PM on Nvidia HDMI codecs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Przemysław Kopa reports that since commit b516ea586d71 ("PCI: Enable NVIDIA HDA controllers"), the discrete GPU Nvidia GeForce GT 540M on his 2011 Samsung laptop refuses to runtime suspend, resulting in a power regression and excessive heat. Rivera Valdez witnesses the same issue with a GeForce GT 525M (GF108M) of the same era, as does another Arch Linux user named "R0AR" with a more recent GeForce GTX 1050 Ti (GP107M). The commit exposes the discrete GPU's HDA controller and all four codecs on the controller do not set the CLKSTOP and EPSS bits in the Supported Power States Response. They also do not set the PS-ClkStopOk bit in the Get Power State Response. hda_codec_runtime_suspend() therefore does not call snd_hdac_codec_link_down(), which prevents each codec and the PCI device from runtime suspending. The same issue is present on some AMD discrete GPUs and we addressed it by forcing runtime PM despite the bits not being set, see commit 57cb54e53bdd ("ALSA: hda - Force to link down at runtime suspend on ATI/AMD HDMI"). Do the same for Nvidia HDMI codecs. Fixes: b516ea586d71 ("PCI: Enable NVIDIA HDA controllers") Link: https://bbs.archlinux.org/viewtopic.php?pid=1865512 Link: https://bugs.freedesktop.org/show_bug.cgi?id=75985#c81 Reported-by: Przemysław Kopa Reported-by: Rivera Valdez Signed-off-by: Lukas Wunner Cc: Daniel Drake Cc: stable@vger.kernel.org # v5.3+ Link: https://lore.kernel.org/r/3086bc75135c1e3567c5bc4f3cc4ff5cbf7a56c2.1571324194.git.lukas@wunner.de Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index bca5de78e9ad..795cbda32cbb 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -3474,6 +3474,8 @@ static int patch_nvhdmi(struct hda_codec *codec) nvhdmi_chmap_cea_alloc_validate_get_type; spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate; + codec->link_down_at_suspend = 1; + generic_acomp_init(codec, &nvhdmi_audio_ops, nvhdmi_port2pin); return 0; -- GitLab From 283ea345934d277e30c841c577e0e2142b4bfcae Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 17 Oct 2019 16:22:37 +0200 Subject: [PATCH 405/993] coccinelle: api/devm_platform_ioremap_resource: remove useless script While it is useful for new drivers to use devm_platform_ioremap_resource, this script is currently used to spam maintainers, often updating very old drivers. The net benefit is the removal of 2 lines of code in the driver but the review load for the maintainers is huge. As of now, more that 560 patches have been sent, some of them obviously broken, as in: https://lore.kernel.org/lkml/9bbcce19c777583815c92ce3c2ff2586@www.loen.fr/ Remove the script to reduce the spam. Signed-off-by: Alexandre Belloni Acked-by: Julia Lawall Signed-off-by: Linus Torvalds --- .../api/devm_platform_ioremap_resource.cocci | 60 ------------------- 1 file changed, 60 deletions(-) delete mode 100644 scripts/coccinelle/api/devm_platform_ioremap_resource.cocci diff --git a/scripts/coccinelle/api/devm_platform_ioremap_resource.cocci b/scripts/coccinelle/api/devm_platform_ioremap_resource.cocci deleted file mode 100644 index 56a2e261d61d..000000000000 --- a/scripts/coccinelle/api/devm_platform_ioremap_resource.cocci +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/// Use devm_platform_ioremap_resource helper which wraps -/// platform_get_resource() and devm_ioremap_resource() together. -/// -// Confidence: High -// Copyright: (C) 2019 Himanshu Jha GPLv2. -// Copyright: (C) 2019 Julia Lawall, Inria/LIP6. GPLv2. -// Keywords: platform_get_resource, devm_ioremap_resource, -// Keywords: devm_platform_ioremap_resource - -virtual patch -virtual report - -@r depends on patch && !report@ -expression e1, e2, arg1, arg2, arg3; -identifier id; -@@ - -( -- id = platform_get_resource(arg1, IORESOURCE_MEM, arg2); -| -- struct resource *id = platform_get_resource(arg1, IORESOURCE_MEM, arg2); -) - ... when != id -- e1 = devm_ioremap_resource(arg3, id); -+ e1 = devm_platform_ioremap_resource(arg1, arg2); - ... when != id -? id = e2 - -@r1 depends on patch && !report@ -identifier r.id; -type T; -@@ - -- T *id; - ...when != id - -@r2 depends on report && !patch@ -identifier id; -expression e1, e2, arg1, arg2, arg3; -position j0; -@@ - -( - id = platform_get_resource(arg1, IORESOURCE_MEM, arg2); -| - struct resource *id = platform_get_resource(arg1, IORESOURCE_MEM, arg2); -) - ... when != id - e1@j0 = devm_ioremap_resource(arg3, id); - ... when != id -? id = e2 - -@script:python depends on report && !patch@ -e1 << r2.e1; -j0 << r2.j0; -@@ - -msg = "WARNING: Use devm_platform_ioremap_resource for %s" % (e1) -coccilib.report.print_report(j0[0], msg) -- GitLab From c7967fc1499beb9b70bb9d33525fb0b384af8883 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Tue, 15 Oct 2019 10:54:39 +0100 Subject: [PATCH 406/993] Btrfs: fix qgroup double free after failure to reserve metadata for delalloc If we fail to reserve metadata for delalloc operations we end up releasing the previously reserved qgroup amount twice, once explicitly under the 'out_qgroup' label by calling btrfs_qgroup_free_meta_prealloc() and once again, under label 'out_fail', by calling btrfs_inode_rsv_release() with a value of 'true' for its 'qgroup_free' argument, which results in btrfs_qgroup_free_meta_prealloc() being called again, so we end up having a double free. Also if we fail to reserve the necessary qgroup amount, we jump to the label 'out_fail', which calls btrfs_inode_rsv_release() and that in turns calls btrfs_qgroup_free_meta_prealloc(), even though we weren't able to reserve any qgroup amount. So we freed some amount we never reserved. So fix this by removing the call to btrfs_inode_rsv_release() in the failure path, since it's not necessary at all as we haven't changed the inode's block reserve in any way at this point. Fixes: c8eaeac7b73434 ("btrfs: reserve delalloc metadata differently") CC: stable@vger.kernel.org # 5.2+ Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/delalloc-space.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/btrfs/delalloc-space.c b/fs/btrfs/delalloc-space.c index 571e7b31ea2f..db9f2c58eb4a 100644 --- a/fs/btrfs/delalloc-space.c +++ b/fs/btrfs/delalloc-space.c @@ -381,7 +381,6 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes) out_qgroup: btrfs_qgroup_free_meta_prealloc(root, qgroup_reserve); out_fail: - btrfs_inode_rsv_release(inode, true); if (delalloc_lock) mutex_unlock(&inode->delalloc_mutex); return ret; -- GitLab From ba0b084ac309283db6e329785c1dc4f45fdbd379 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Wed, 16 Oct 2019 16:28:52 +0100 Subject: [PATCH 407/993] Btrfs: check for the full sync flag while holding the inode lock during fsync We were checking for the full fsync flag in the inode before locking the inode, which is racy, since at that that time it might not be set but after we acquire the inode lock some other task set it. One case where this can happen is on a system low on memory and some concurrent task failed to allocate an extent map and therefore set the full sync flag on the inode, to force the next fsync to work in full mode. A consequence of missing the full fsync flag set is hitting the problems fixed by commit 0c713cbab620 ("Btrfs: fix race between ranged fsync and writeback of adjacent ranges"), BUG_ON() when dropping extents from a log tree, hitting assertion failures at tree-log.c:copy_items() or all sorts of weird inconsistencies after replaying a log due to file extents items representing ranges that overlap. So just move the check such that it's done after locking the inode and before starting writeback again. Fixes: 0c713cbab620 ("Btrfs: fix race between ranged fsync and writeback of adjacent ranges") CC: stable@vger.kernel.org # 5.2+ Signed-off-by: Filipe Manana Signed-off-by: David Sterba --- fs/btrfs/file.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e955e7fa9201..435a502a3226 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2067,25 +2067,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) struct btrfs_trans_handle *trans; struct btrfs_log_ctx ctx; int ret = 0, err; - u64 len; - /* - * If the inode needs a full sync, make sure we use a full range to - * avoid log tree corruption, due to hole detection racing with ordered - * extent completion for adjacent ranges, and assertion failures during - * hole detection. - */ - if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, - &BTRFS_I(inode)->runtime_flags)) { - start = 0; - end = LLONG_MAX; - } - - /* - * The range length can be represented by u64, we have to do the typecasts - * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync() - */ - len = (u64)end - (u64)start + 1; trace_btrfs_sync_file(file, datasync); btrfs_init_log_ctx(&ctx, inode); @@ -2111,6 +2093,19 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) atomic_inc(&root->log_batch); + /* + * If the inode needs a full sync, make sure we use a full range to + * avoid log tree corruption, due to hole detection racing with ordered + * extent completion for adjacent ranges, and assertion failures during + * hole detection. Do this while holding the inode lock, to avoid races + * with other tasks. + */ + if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, + &BTRFS_I(inode)->runtime_flags)) { + start = 0; + end = LLONG_MAX; + } + /* * Before we acquired the inode's lock, someone may have dirtied more * pages in the target range. We need to make sure that writeback for @@ -2138,8 +2133,11 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) /* * We have to do this here to avoid the priority inversion of waiting on * IO of a lower priority task while holding a transaction open. + * + * Also, the range length can be represented by u64, we have to do the + * typecasts to avoid signed overflow if it's [0, LLONG_MAX]. */ - ret = btrfs_wait_ordered_range(inode, start, len); + ret = btrfs_wait_ordered_range(inode, start, (u64)end - (u64)start + 1); if (ret) { up_write(&BTRFS_I(inode)->dio_sem); inode_unlock(inode); -- GitLab From af0de1303c4e8f44fadd7b4c593f09f22324b04f Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 17 Oct 2019 15:25:47 +0200 Subject: [PATCH 408/993] usb: hso: obey DMA rules in tiocmget The serial state information must not be embedded into another data structure, as this interferes with cache handling for DMA on architectures without cache coherence.. That would result in data corruption on some architectures Allocating it separately. v2: fix syntax error Signed-off-by: Oliver Neukum Signed-off-by: David S. Miller --- drivers/net/usb/hso.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index a505b2ab88b8..74849da031fa 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -186,7 +186,7 @@ struct hso_tiocmget { int intr_completed; struct usb_endpoint_descriptor *endp; struct urb *urb; - struct hso_serial_state_notification serial_state_notification; + struct hso_serial_state_notification *serial_state_notification; u16 prev_UART_state_bitmap; struct uart_icount icount; }; @@ -1432,7 +1432,7 @@ static int tiocmget_submit_urb(struct hso_serial *serial, usb_rcvintpipe(usb, tiocmget->endp-> bEndpointAddress & 0x7F), - &tiocmget->serial_state_notification, + tiocmget->serial_state_notification, sizeof(struct hso_serial_state_notification), tiocmget_intr_callback, serial, tiocmget->endp->bInterval); @@ -1479,7 +1479,7 @@ static void tiocmget_intr_callback(struct urb *urb) /* wIndex should be the USB interface number of the port to which the * notification applies, which should always be the Modem port. */ - serial_state_notification = &tiocmget->serial_state_notification; + serial_state_notification = tiocmget->serial_state_notification; if (serial_state_notification->bmRequestType != BM_REQUEST_TYPE || serial_state_notification->bNotification != B_NOTIFICATION || le16_to_cpu(serial_state_notification->wValue) != W_VALUE || @@ -2565,6 +2565,8 @@ static void hso_free_tiomget(struct hso_serial *serial) usb_free_urb(tiocmget->urb); tiocmget->urb = NULL; serial->tiocmget = NULL; + kfree(tiocmget->serial_state_notification); + tiocmget->serial_state_notification = NULL; kfree(tiocmget); } } @@ -2615,10 +2617,13 @@ static struct hso_device *hso_create_bulk_serial_device( num_urbs = 2; serial->tiocmget = kzalloc(sizeof(struct hso_tiocmget), GFP_KERNEL); + serial->tiocmget->serial_state_notification + = kzalloc(sizeof(struct hso_serial_state_notification), + GFP_KERNEL); /* it isn't going to break our heart if serial->tiocmget * allocation fails don't bother checking this. */ - if (serial->tiocmget) { + if (serial->tiocmget && serial->tiocmget->serial_state_notification) { tiocmget = serial->tiocmget; tiocmget->endp = hso_get_ep(interface, USB_ENDPOINT_XFER_INT, -- GitLab From 8398b375a9e3f5e4bba9bcdfed152a8a247dee01 Mon Sep 17 00:00:00 2001 From: Florin Chiculita Date: Wed, 16 Oct 2019 10:36:22 +0300 Subject: [PATCH 409/993] dpaa2-eth: add irq for the dpmac connect/disconnect event Add IRQ for the DPNI endpoint change event, resolving the issue when a dynamically created DPNI gets a randomly generated hw address when the endpoint is a DPMAC object. Signed-off-by: Florin Chiculita Signed-off-by: Ioana Ciornei Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 6 +++++- drivers/net/ethernet/freescale/dpaa2/dpni.h | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index 162d7d8fb295..5acd734a216b 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -3306,6 +3306,9 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg) if (status & DPNI_IRQ_EVENT_LINK_CHANGED) link_state_update(netdev_priv(net_dev)); + if (status & DPNI_IRQ_EVENT_ENDPOINT_CHANGED) + set_mac_addr(netdev_priv(net_dev)); + return IRQ_HANDLED; } @@ -3331,7 +3334,8 @@ static int setup_irqs(struct fsl_mc_device *ls_dev) } err = dpni_set_irq_mask(ls_dev->mc_io, 0, ls_dev->mc_handle, - DPNI_IRQ_INDEX, DPNI_IRQ_EVENT_LINK_CHANGED); + DPNI_IRQ_INDEX, DPNI_IRQ_EVENT_LINK_CHANGED | + DPNI_IRQ_EVENT_ENDPOINT_CHANGED); if (err < 0) { dev_err(&ls_dev->dev, "dpni_set_irq_mask(): %d\n", err); goto free_irq; diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni.h b/drivers/net/ethernet/freescale/dpaa2/dpni.h index fd583911b6c0..ee0711d06b3a 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpni.h +++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h @@ -133,9 +133,12 @@ int dpni_reset(struct fsl_mc_io *mc_io, */ #define DPNI_IRQ_INDEX 0 /** - * IRQ event - indicates a change in link state + * IRQ events: + * indicates a change in link state + * indicates a change in endpoint */ #define DPNI_IRQ_EVENT_LINK_CHANGED 0x00000001 +#define DPNI_IRQ_EVENT_ENDPOINT_CHANGED 0x00000002 int dpni_set_irq_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, -- GitLab From a690af4f16f9bd1f976a4257e1529b6323a8d0e1 Mon Sep 17 00:00:00 2001 From: Ioana Radulescu Date: Wed, 16 Oct 2019 10:36:23 +0300 Subject: [PATCH 410/993] dpaa2-eth: Fix TX FQID values Depending on when MC connects the DPNI to a MAC, Tx FQIDs may not be available during probe time. Read the FQIDs each time the link goes up to avoid using invalid values. In case an error occurs or an invalid value is retrieved, fall back to QDID-based enqueueing. Fixes: 1fa0f68c9255 ("dpaa2-eth: Use FQ-based DPIO enqueue API") Signed-off-by: Ioana Radulescu Signed-off-by: Ioana Ciornei Signed-off-by: David S. Miller --- .../net/ethernet/freescale/dpaa2/dpaa2-eth.c | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index 5acd734a216b..19379bae0144 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -1235,6 +1235,8 @@ static void dpaa2_eth_set_rx_taildrop(struct dpaa2_eth_priv *priv, bool enable) priv->rx_td_enabled = enable; } +static void update_tx_fqids(struct dpaa2_eth_priv *priv); + static int link_state_update(struct dpaa2_eth_priv *priv) { struct dpni_link_state state = {0}; @@ -1261,6 +1263,7 @@ static int link_state_update(struct dpaa2_eth_priv *priv) goto out; if (state.up) { + update_tx_fqids(priv); netif_carrier_on(priv->net_dev); netif_tx_start_all_queues(priv->net_dev); } else { @@ -2533,6 +2536,47 @@ static int set_pause(struct dpaa2_eth_priv *priv) return 0; } +static void update_tx_fqids(struct dpaa2_eth_priv *priv) +{ + struct dpni_queue_id qid = {0}; + struct dpaa2_eth_fq *fq; + struct dpni_queue queue; + int i, j, err; + + /* We only use Tx FQIDs for FQID-based enqueue, so check + * if DPNI version supports it before updating FQIDs + */ + if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_ENQUEUE_FQID_VER_MAJOR, + DPNI_ENQUEUE_FQID_VER_MINOR) < 0) + return; + + for (i = 0; i < priv->num_fqs; i++) { + fq = &priv->fq[i]; + if (fq->type != DPAA2_TX_CONF_FQ) + continue; + for (j = 0; j < dpaa2_eth_tc_count(priv); j++) { + err = dpni_get_queue(priv->mc_io, 0, priv->mc_token, + DPNI_QUEUE_TX, j, fq->flowid, + &queue, &qid); + if (err) + goto out_err; + + fq->tx_fqid[j] = qid.fqid; + if (fq->tx_fqid[j] == 0) + goto out_err; + } + } + + priv->enqueue = dpaa2_eth_enqueue_fq; + + return; + +out_err: + netdev_info(priv->net_dev, + "Error reading Tx FQID, fallback to QDID-based enqueue\n"); + priv->enqueue = dpaa2_eth_enqueue_qd; +} + /* Configure the DPNI object this interface is associated with */ static int setup_dpni(struct fsl_mc_device *ls_dev) { -- GitLab From c9ad4c1049f7e0e8d59e975963dda002af47d93e Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Wed, 16 Oct 2019 09:22:05 +0100 Subject: [PATCH 411/993] net: stmmac: fix argument to stmmac_pcs_ctrl_ane() The stmmac_pcs_ctrl_ane() expects a register address as argument 1, but for some reason the mac_device_info is being passed. Fix the warning (and possible bug) from sparse: drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2613:17: warning: incorrect type in argument 1 (different address spaces) drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2613:17: expected void [noderef] *ioaddr drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:2613:17: got struct mac_device_info *hw Signed-off-by: Ben Dooks Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 8fa13d43b5bc..3dfd04e0506a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2610,7 +2610,7 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) } if (priv->hw->pcs) - stmmac_pcs_ctrl_ane(priv, priv->hw, 1, priv->hw->ps, 0); + stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, priv->hw->ps, 0); /* set TX and RX rings length */ stmmac_set_rings_length(priv); -- GitLab From 7f238ca984b9c6a89e2339c661440c775d617386 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 16 Oct 2019 15:33:23 +0200 Subject: [PATCH 412/993] net: dsa: microchip: Do not reinit mutexes on KSZ87xx The KSZ87xx driver calls mutex_init() on mutexes already inited in ksz_common.c ksz_switch_register(). Do not do it twice, drop the reinitialization. Signed-off-by: Marek Vasut Cc: Andrew Lunn Cc: David S. Miller Cc: Florian Fainelli Cc: George McCollister Cc: Tristram Ha Cc: Woojung Huh Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz8795.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index a23d3ffdf0c4..24a5e99f7fd5 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -1224,10 +1224,6 @@ static int ksz8795_switch_init(struct ksz_device *dev) { int i; - mutex_init(&dev->stats_mutex); - mutex_init(&dev->alu_mutex); - mutex_init(&dev->vlan_mutex); - dev->ds->ops = &ksz8795_switch_ops; for (i = 0; i < ARRAY_SIZE(ksz8795_switch_chips); i++) { -- GitLab From 013572a236ef53cbd1e315e0acf2ee632cc816d4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 16 Oct 2019 15:33:24 +0200 Subject: [PATCH 413/993] net: dsa: microchip: Add shared regmap mutex The KSZ driver uses one regmap per register width (8/16/32), each with it's own lock, but accessing the same set of registers. In theory, it is possible to create a race condition between these regmaps, although the underlying bus (SPI or I2C) locking should assure nothing bad will really happen and the accesses would be correct. To make the driver do the right thing, add one single shared mutex for all the regmaps used by the driver instead. This assures that even if some future hardware is on a bus which does not serialize the accesses the same way SPI or I2C does, nothing bad will happen. Note that the status_mutex was unused and only initied, hence it was renamed and repurposed as the regmap mutex. Signed-off-by: Marek Vasut Cc: Andrew Lunn Cc: David S. Miller Cc: Florian Fainelli Cc: George McCollister Cc: Tristram Ha Cc: Woojung Huh Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/dsa/microchip/ksz8795_spi.c | 7 ++++--- drivers/net/dsa/microchip/ksz9477_i2c.c | 6 ++++-- drivers/net/dsa/microchip/ksz9477_spi.c | 6 ++++-- drivers/net/dsa/microchip/ksz_common.c | 2 +- drivers/net/dsa/microchip/ksz_common.h | 16 +++++++++++++++- 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz8795_spi.c b/drivers/net/dsa/microchip/ksz8795_spi.c index d0f8153e86b7..8b00f8e6c02f 100644 --- a/drivers/net/dsa/microchip/ksz8795_spi.c +++ b/drivers/net/dsa/microchip/ksz8795_spi.c @@ -25,6 +25,7 @@ KSZ_REGMAP_TABLE(ksz8795, 16, SPI_ADDR_SHIFT, static int ksz8795_spi_probe(struct spi_device *spi) { + struct regmap_config rc; struct ksz_device *dev; int i, ret; @@ -33,9 +34,9 @@ static int ksz8795_spi_probe(struct spi_device *spi) return -ENOMEM; for (i = 0; i < ARRAY_SIZE(ksz8795_regmap_config); i++) { - dev->regmap[i] = devm_regmap_init_spi(spi, - &ksz8795_regmap_config - [i]); + rc = ksz8795_regmap_config[i]; + rc.lock_arg = &dev->regmap_mutex; + dev->regmap[i] = devm_regmap_init_spi(spi, &rc); if (IS_ERR(dev->regmap[i])) { ret = PTR_ERR(dev->regmap[i]); dev_err(&spi->dev, diff --git a/drivers/net/dsa/microchip/ksz9477_i2c.c b/drivers/net/dsa/microchip/ksz9477_i2c.c index 0b1e01f0873d..fdffd9e0c518 100644 --- a/drivers/net/dsa/microchip/ksz9477_i2c.c +++ b/drivers/net/dsa/microchip/ksz9477_i2c.c @@ -17,6 +17,7 @@ KSZ_REGMAP_TABLE(ksz9477, not_used, 16, 0, 0); static int ksz9477_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i2c_id) { + struct regmap_config rc; struct ksz_device *dev; int i, ret; @@ -25,8 +26,9 @@ static int ksz9477_i2c_probe(struct i2c_client *i2c, return -ENOMEM; for (i = 0; i < ARRAY_SIZE(ksz9477_regmap_config); i++) { - dev->regmap[i] = devm_regmap_init_i2c(i2c, - &ksz9477_regmap_config[i]); + rc = ksz9477_regmap_config[i]; + rc.lock_arg = &dev->regmap_mutex; + dev->regmap[i] = devm_regmap_init_i2c(i2c, &rc); if (IS_ERR(dev->regmap[i])) { ret = PTR_ERR(dev->regmap[i]); dev_err(&i2c->dev, diff --git a/drivers/net/dsa/microchip/ksz9477_spi.c b/drivers/net/dsa/microchip/ksz9477_spi.c index f4198d6f72be..c5f64959a184 100644 --- a/drivers/net/dsa/microchip/ksz9477_spi.c +++ b/drivers/net/dsa/microchip/ksz9477_spi.c @@ -24,6 +24,7 @@ KSZ_REGMAP_TABLE(ksz9477, 32, SPI_ADDR_SHIFT, static int ksz9477_spi_probe(struct spi_device *spi) { + struct regmap_config rc; struct ksz_device *dev; int i, ret; @@ -32,8 +33,9 @@ static int ksz9477_spi_probe(struct spi_device *spi) return -ENOMEM; for (i = 0; i < ARRAY_SIZE(ksz9477_regmap_config); i++) { - dev->regmap[i] = devm_regmap_init_spi(spi, - &ksz9477_regmap_config[i]); + rc = ksz9477_regmap_config[i]; + rc.lock_arg = &dev->regmap_mutex; + dev->regmap[i] = devm_regmap_init_spi(spi, &rc); if (IS_ERR(dev->regmap[i])) { ret = PTR_ERR(dev->regmap[i]); dev_err(&spi->dev, diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index b0b870f0c252..fe47180c908b 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -436,7 +436,7 @@ int ksz_switch_register(struct ksz_device *dev, } mutex_init(&dev->dev_mutex); - mutex_init(&dev->stats_mutex); + mutex_init(&dev->regmap_mutex); mutex_init(&dev->alu_mutex); mutex_init(&dev->vlan_mutex); diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 64c2677693d2..a20ebb749377 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -47,7 +47,7 @@ struct ksz_device { const char *name; struct mutex dev_mutex; /* device access */ - struct mutex stats_mutex; /* status access */ + struct mutex regmap_mutex; /* regmap access */ struct mutex alu_mutex; /* ALU access */ struct mutex vlan_mutex; /* vlan access */ const struct ksz_dev_ops *dev_ops; @@ -290,6 +290,18 @@ static inline void ksz_pwrite32(struct ksz_device *dev, int port, int offset, ksz_write32(dev, dev->dev_ops->get_port_addr(port, offset), data); } +static inline void ksz_regmap_lock(void *__mtx) +{ + struct mutex *mtx = __mtx; + mutex_lock(mtx); +} + +static inline void ksz_regmap_unlock(void *__mtx) +{ + struct mutex *mtx = __mtx; + mutex_unlock(mtx); +} + /* Regmap tables generation */ #define KSZ_SPI_OP_RD 3 #define KSZ_SPI_OP_WR 2 @@ -314,6 +326,8 @@ static inline void ksz_pwrite32(struct ksz_device *dev, int port, int offset, .write_flag_mask = \ KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_WR, swp, \ regbits, regpad), \ + .lock = ksz_regmap_lock, \ + .unlock = ksz_regmap_unlock, \ .reg_format_endian = REGMAP_ENDIAN_BIG, \ .val_format_endian = REGMAP_ENDIAN_BIG \ } -- GitLab From c8973df2da677f375f8b12b6eefca2f44c8884d5 Mon Sep 17 00:00:00 2001 From: Rafi Wiener Date: Wed, 2 Oct 2019 15:02:43 +0300 Subject: [PATCH 414/993] RDMA/mlx5: Clear old rate limit when closing QP Before QP is closed it changes to ERROR state, when this happens the QP was left with old rate limit that was already removed from the table. Fixes: 7d29f349a4b9 ("IB/mlx5: Properly adjust rate limit on QP state transitions") Signed-off-by: Rafi Wiener Signed-off-by: Oleg Kuporosov Signed-off-by: Leon Romanovsky Link: https://lore.kernel.org/r/20191002120243.16971-1-leon@kernel.org Signed-off-by: Doug Ledford --- drivers/infiniband/hw/mlx5/qp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 8937d72ddcf6..5fd071c05944 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -3249,10 +3249,12 @@ static int modify_raw_packet_qp_sq( } /* Only remove the old rate after new rate was set */ - if ((old_rl.rate && - !mlx5_rl_are_equal(&old_rl, &new_rl)) || - (new_state != MLX5_SQC_STATE_RDY)) + if ((old_rl.rate && !mlx5_rl_are_equal(&old_rl, &new_rl)) || + (new_state != MLX5_SQC_STATE_RDY)) { mlx5_rl_remove_rate(dev, &old_rl); + if (new_state != MLX5_SQC_STATE_RDY) + memset(&new_rl, 0, sizeof(new_rl)); + } ibqp->rl = new_rl; sq->state = new_state; -- GitLab From 9ed5bd7d22241ad232fd3a5be404e83eb6cadc04 Mon Sep 17 00:00:00 2001 From: Kaike Wan Date: Fri, 4 Oct 2019 16:40:35 -0400 Subject: [PATCH 415/993] IB/hfi1: Avoid excessive retry for TID RDMA READ request A TID RDMA READ request could be retried under one of the following conditions: - The RC retry timer expires; - A later TID RDMA READ RESP packet is received before the next expected one. For the latter, under normal conditions, the PSN in IB space is used for comparison. More specifically, the IB PSN in the incoming TID RDMA READ RESP packet is compared with the last IB PSN of a given TID RDMA READ request to determine if the request should be retried. This is similar to the retry logic for noraml RDMA READ request. However, if a TID RDMA READ RESP packet is lost due to congestion, header suppresion will be disabled and each incoming packet will raise an interrupt until the hardware flow is reloaded. Under this condition, each packet KDETH PSN will be checked by software against r_next_psn and a retry will be requested if the packet KDETH PSN is later than r_next_psn. Since each TID RDMA READ segment could have up to 64 packets and each TID RDMA READ request could have many segments, we could make far more retries under such conditions, and thus leading to RETRY_EXC_ERR status. This patch fixes the issue by removing the retry when the incoming packet KDETH PSN is later than r_next_psn. Instead, it resorts to RC timer and normal IB PSN comparison for any request retry. Fixes: 9905bf06e890 ("IB/hfi1: Add functions to receive TID RDMA READ response") Cc: Reviewed-by: Mike Marciniszyn Signed-off-by: Kaike Wan Signed-off-by: Dennis Dalessandro Link: https://lore.kernel.org/r/20191004204035.26542.41684.stgit@awfm-01.aw.intel.com Signed-off-by: Doug Ledford --- drivers/infiniband/hw/hfi1/tid_rdma.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/tid_rdma.c b/drivers/infiniband/hw/hfi1/tid_rdma.c index b4dcc4d29f84..f21fca3617d5 100644 --- a/drivers/infiniband/hw/hfi1/tid_rdma.c +++ b/drivers/infiniband/hw/hfi1/tid_rdma.c @@ -2736,11 +2736,6 @@ static bool handle_read_kdeth_eflags(struct hfi1_ctxtdata *rcd, diff = cmp_psn(psn, flow->flow_state.r_next_psn); if (diff > 0) { - if (!(qp->r_flags & RVT_R_RDMAR_SEQ)) - restart_tid_rdma_read_req(rcd, - qp, - wqe); - /* Drop the packet.*/ goto s_unlock; } else if (diff < 0) { -- GitLab From 22bb13653410424d9fce8d447506a41f8292f22f Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Fri, 4 Oct 2019 16:49:34 -0400 Subject: [PATCH 416/993] IB/hfi1: Use a common pad buffer for 9B and 16B packets There is no reason for a different pad buffer for the two packet types. Expand the current buffer allocation to allow for both packet types. Fixes: f8195f3b14a0 ("IB/hfi1: Eliminate allocation while atomic") Reported-by: Dan Carpenter Reviewed-by: Kaike Wan Reviewed-by: Dennis Dalessandro Signed-off-by: Mike Marciniszyn Signed-off-by: Dennis Dalessandro Link: https://lore.kernel.org/r/20191004204934.26838.13099.stgit@awfm-01.aw.intel.com Signed-off-by: Doug Ledford --- drivers/infiniband/hw/hfi1/sdma.c | 5 +++-- drivers/infiniband/hw/hfi1/verbs.c | 10 ++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c index 2ed7bfd5feea..c61b6022575e 100644 --- a/drivers/infiniband/hw/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c @@ -65,6 +65,7 @@ #define SDMA_DESCQ_CNT 2048 #define SDMA_DESC_INTR 64 #define INVALID_TAIL 0xffff +#define SDMA_PAD max_t(size_t, MAX_16B_PADDING, sizeof(u32)) static uint sdma_descq_cnt = SDMA_DESCQ_CNT; module_param(sdma_descq_cnt, uint, S_IRUGO); @@ -1296,7 +1297,7 @@ void sdma_clean(struct hfi1_devdata *dd, size_t num_engines) struct sdma_engine *sde; if (dd->sdma_pad_dma) { - dma_free_coherent(&dd->pcidev->dev, 4, + dma_free_coherent(&dd->pcidev->dev, SDMA_PAD, (void *)dd->sdma_pad_dma, dd->sdma_pad_phys); dd->sdma_pad_dma = NULL; @@ -1491,7 +1492,7 @@ int sdma_init(struct hfi1_devdata *dd, u8 port) } /* Allocate memory for pad */ - dd->sdma_pad_dma = dma_alloc_coherent(&dd->pcidev->dev, sizeof(u32), + dd->sdma_pad_dma = dma_alloc_coherent(&dd->pcidev->dev, SDMA_PAD, &dd->sdma_pad_phys, GFP_KERNEL); if (!dd->sdma_pad_dma) { dd_dev_err(dd, "failed to allocate SendDMA pad memory\n"); diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c index 7bff0a1e713d..089e201d7550 100644 --- a/drivers/infiniband/hw/hfi1/verbs.c +++ b/drivers/infiniband/hw/hfi1/verbs.c @@ -147,9 +147,6 @@ static int pio_wait(struct rvt_qp *qp, /* Length of buffer to create verbs txreq cache name */ #define TXREQ_NAME_LEN 24 -/* 16B trailing buffer */ -static const u8 trail_buf[MAX_16B_PADDING]; - static uint wss_threshold = 80; module_param(wss_threshold, uint, S_IRUGO); MODULE_PARM_DESC(wss_threshold, "Percentage (1-100) of LLC to use as a threshold for a cacheless copy"); @@ -820,8 +817,8 @@ static int build_verbs_tx_desc( /* add icrc, lt byte, and padding to flit */ if (extra_bytes) - ret = sdma_txadd_kvaddr(sde->dd, &tx->txreq, - (void *)trail_buf, extra_bytes); + ret = sdma_txadd_daddr(sde->dd, &tx->txreq, + sde->dd->sdma_pad_phys, extra_bytes); bail_txadd: return ret; @@ -1089,7 +1086,8 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps, } /* add icrc, lt byte, and padding to flit */ if (extra_bytes) - seg_pio_copy_mid(pbuf, trail_buf, extra_bytes); + seg_pio_copy_mid(pbuf, ppd->dd->sdma_pad_dma, + extra_bytes); seg_pio_copy_end(pbuf); } -- GitLab From ce584a8e2885c7b59dfacba42db39761243cacb2 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 15 Oct 2019 18:07:19 -0400 Subject: [PATCH 417/993] drm/amdgpu/uvd6: fix allocation size in enc ring test (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to allocate a large enough buffer for the session info, otherwise the IB test can overwrite other memory. v2: - session info is 128K according to mesa - use the same session info for create and destroy Bug: https://bugzilla.kernel.org/show_bug.cgi?id=204241 Acked-by: Christian König Reviewed-by: James Zhu Tested-by: James Zhu Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 31 ++++++++++++++++++--------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 670784a78512..217084d56ab8 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -206,13 +206,14 @@ static int uvd_v6_0_enc_ring_test_ring(struct amdgpu_ring *ring) * Open up a stream for HW test */ static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, + struct amdgpu_bo *bo, struct dma_fence **fence) { const unsigned ib_size_dw = 16; struct amdgpu_job *job; struct amdgpu_ib *ib; struct dma_fence *f = NULL; - uint64_t dummy; + uint64_t addr; int i, r; r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); @@ -220,15 +221,15 @@ static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle return r; ib = &job->ibs[0]; - dummy = ib->gpu_addr + 1024; + addr = amdgpu_bo_gpu_offset(bo); ib->length_dw = 0; ib->ptr[ib->length_dw++] = 0x00000018; ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ ib->ptr[ib->length_dw++] = handle; ib->ptr[ib->length_dw++] = 0x00010000; - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); - ib->ptr[ib->length_dw++] = dummy; + ib->ptr[ib->length_dw++] = upper_32_bits(addr); + ib->ptr[ib->length_dw++] = addr; ib->ptr[ib->length_dw++] = 0x00000014; ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ @@ -268,13 +269,14 @@ static int uvd_v6_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle */ static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, + struct amdgpu_bo *bo, struct dma_fence **fence) { const unsigned ib_size_dw = 16; struct amdgpu_job *job; struct amdgpu_ib *ib; struct dma_fence *f = NULL; - uint64_t dummy; + uint64_t addr; int i, r; r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); @@ -282,15 +284,15 @@ static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, return r; ib = &job->ibs[0]; - dummy = ib->gpu_addr + 1024; + addr = amdgpu_bo_gpu_offset(bo); ib->length_dw = 0; ib->ptr[ib->length_dw++] = 0x00000018; ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ ib->ptr[ib->length_dw++] = handle; ib->ptr[ib->length_dw++] = 0x00010000; - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); - ib->ptr[ib->length_dw++] = dummy; + ib->ptr[ib->length_dw++] = upper_32_bits(addr); + ib->ptr[ib->length_dw++] = addr; ib->ptr[ib->length_dw++] = 0x00000014; ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ @@ -327,13 +329,20 @@ static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) { struct dma_fence *fence = NULL; + struct amdgpu_bo *bo = NULL; long r; - r = uvd_v6_0_enc_get_create_msg(ring, 1, NULL); + r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + &bo, NULL, NULL); + if (r) + return r; + + r = uvd_v6_0_enc_get_create_msg(ring, 1, bo, NULL); if (r) goto error; - r = uvd_v6_0_enc_get_destroy_msg(ring, 1, &fence); + r = uvd_v6_0_enc_get_destroy_msg(ring, 1, bo, &fence); if (r) goto error; @@ -345,6 +354,8 @@ static int uvd_v6_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) error: dma_fence_put(fence); + amdgpu_bo_unreserve(bo); + amdgpu_bo_unref(&bo); return r; } -- GitLab From 5d230bc91f6c15e5d281f2851502918d98b9e770 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 15 Oct 2019 18:08:59 -0400 Subject: [PATCH 418/993] drm/amdgpu/uvd7: fix allocation size in enc ring test (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to allocate a large enough buffer for the session info, otherwise the IB test can overwrite other memory. v2: - session info is 128K according to mesa - use the same session info for create and destroy Bug: https://bugzilla.kernel.org/show_bug.cgi?id=204241 Acked-by: Christian König Reviewed-by: James Zhu Tested-by: James Zhu Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 33 ++++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index 01f658fa72c6..0995378d8263 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c @@ -214,13 +214,14 @@ static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring) * Open up a stream for HW test */ static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, + struct amdgpu_bo *bo, struct dma_fence **fence) { const unsigned ib_size_dw = 16; struct amdgpu_job *job; struct amdgpu_ib *ib; struct dma_fence *f = NULL; - uint64_t dummy; + uint64_t addr; int i, r; r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); @@ -228,15 +229,15 @@ static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle return r; ib = &job->ibs[0]; - dummy = ib->gpu_addr + 1024; + addr = amdgpu_bo_gpu_offset(bo); ib->length_dw = 0; ib->ptr[ib->length_dw++] = 0x00000018; ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ ib->ptr[ib->length_dw++] = handle; ib->ptr[ib->length_dw++] = 0x00000000; - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); - ib->ptr[ib->length_dw++] = dummy; + ib->ptr[ib->length_dw++] = upper_32_bits(addr); + ib->ptr[ib->length_dw++] = addr; ib->ptr[ib->length_dw++] = 0x00000014; ib->ptr[ib->length_dw++] = 0x00000002; /* task info */ @@ -275,13 +276,14 @@ static int uvd_v7_0_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle * Close up a stream for HW test or if userspace failed to do so */ static int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, - struct dma_fence **fence) + struct amdgpu_bo *bo, + struct dma_fence **fence) { const unsigned ib_size_dw = 16; struct amdgpu_job *job; struct amdgpu_ib *ib; struct dma_fence *f = NULL; - uint64_t dummy; + uint64_t addr; int i, r; r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); @@ -289,15 +291,15 @@ static int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handl return r; ib = &job->ibs[0]; - dummy = ib->gpu_addr + 1024; + addr = amdgpu_bo_gpu_offset(bo); ib->length_dw = 0; ib->ptr[ib->length_dw++] = 0x00000018; ib->ptr[ib->length_dw++] = 0x00000001; ib->ptr[ib->length_dw++] = handle; ib->ptr[ib->length_dw++] = 0x00000000; - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); - ib->ptr[ib->length_dw++] = dummy; + ib->ptr[ib->length_dw++] = upper_32_bits(addr); + ib->ptr[ib->length_dw++] = addr; ib->ptr[ib->length_dw++] = 0x00000014; ib->ptr[ib->length_dw++] = 0x00000002; @@ -334,13 +336,20 @@ static int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handl static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) { struct dma_fence *fence = NULL; + struct amdgpu_bo *bo = NULL; long r; - r = uvd_v7_0_enc_get_create_msg(ring, 1, NULL); + r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + &bo, NULL, NULL); + if (r) + return r; + + r = uvd_v7_0_enc_get_create_msg(ring, 1, bo, NULL); if (r) goto error; - r = uvd_v7_0_enc_get_destroy_msg(ring, 1, &fence); + r = uvd_v7_0_enc_get_destroy_msg(ring, 1, bo, &fence); if (r) goto error; @@ -352,6 +361,8 @@ static int uvd_v7_0_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) error: dma_fence_put(fence); + amdgpu_bo_unreserve(bo); + amdgpu_bo_unref(&bo); return r; } -- GitLab From c81fffc2c9450750dd7a54a36a788a860ab0425d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 15 Oct 2019 18:09:41 -0400 Subject: [PATCH 419/993] drm/amdgpu/vcn: fix allocation size in enc ring test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to allocate a large enough buffer for the session info, otherwise the IB test can overwrite other memory. - Session info is 128K according to mesa - Use the same session info for create and destroy Bug: https://bugzilla.kernel.org/show_bug.cgi?id=204241 Acked-by: Christian König Reviewed-by: James Zhu Tested-by: James Zhu Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 35 ++++++++++++++++--------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 7a6beb2e7c4e..3199e4a5ff12 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -569,13 +569,14 @@ int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring) } static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, - struct dma_fence **fence) + struct amdgpu_bo *bo, + struct dma_fence **fence) { const unsigned ib_size_dw = 16; struct amdgpu_job *job; struct amdgpu_ib *ib; struct dma_fence *f = NULL; - uint64_t dummy; + uint64_t addr; int i, r; r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); @@ -583,14 +584,14 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand return r; ib = &job->ibs[0]; - dummy = ib->gpu_addr + 1024; + addr = amdgpu_bo_gpu_offset(bo); ib->length_dw = 0; ib->ptr[ib->length_dw++] = 0x00000018; ib->ptr[ib->length_dw++] = 0x00000001; /* session info */ ib->ptr[ib->length_dw++] = handle; - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); - ib->ptr[ib->length_dw++] = dummy; + ib->ptr[ib->length_dw++] = upper_32_bits(addr); + ib->ptr[ib->length_dw++] = addr; ib->ptr[ib->length_dw++] = 0x0000000b; ib->ptr[ib->length_dw++] = 0x00000014; @@ -621,13 +622,14 @@ static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t hand } static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, - struct dma_fence **fence) + struct amdgpu_bo *bo, + struct dma_fence **fence) { const unsigned ib_size_dw = 16; struct amdgpu_job *job; struct amdgpu_ib *ib; struct dma_fence *f = NULL; - uint64_t dummy; + uint64_t addr; int i, r; r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); @@ -635,14 +637,14 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han return r; ib = &job->ibs[0]; - dummy = ib->gpu_addr + 1024; + addr = amdgpu_bo_gpu_offset(bo); ib->length_dw = 0; ib->ptr[ib->length_dw++] = 0x00000018; ib->ptr[ib->length_dw++] = 0x00000001; ib->ptr[ib->length_dw++] = handle; - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); - ib->ptr[ib->length_dw++] = dummy; + ib->ptr[ib->length_dw++] = upper_32_bits(addr); + ib->ptr[ib->length_dw++] = addr; ib->ptr[ib->length_dw++] = 0x0000000b; ib->ptr[ib->length_dw++] = 0x00000014; @@ -675,13 +677,20 @@ static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t han int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) { struct dma_fence *fence = NULL; + struct amdgpu_bo *bo = NULL; long r; - r = amdgpu_vcn_enc_get_create_msg(ring, 1, NULL); + r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + &bo, NULL, NULL); + if (r) + return r; + + r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL); if (r) goto error; - r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, &fence); + r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence); if (r) goto error; @@ -693,6 +702,8 @@ int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout) error: dma_fence_put(fence); + amdgpu_bo_unreserve(bo); + amdgpu_bo_unref(&bo); return r; } -- GitLab From 209620b422945ee03cebb03f726e706d537b692d Mon Sep 17 00:00:00 2001 From: Philip Yang Date: Thu, 3 Oct 2019 14:18:25 -0400 Subject: [PATCH 420/993] drm/amdgpu: user pages array memory leak fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit user_pages array should always be freed after validation regardless if user pages are changed after bo is created because with HMM change parse bo always allocate user pages array to get user pages for userptr bo. v2: remove unused local variable and amend commit v3: add back get user pages in gem_userptr_ioctl, to detect application bug where an userptr VMA is not ananymous memory and reject it. Bugzilla: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1844962 Signed-off-by: Philip Yang Tested-by: Joe Barnett Reviewed-by: Christian König Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 5.3 --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 2e53feed40e2..82823d9a8ba8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -536,7 +536,6 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, list_for_each_entry(lobj, validated, tv.head) { struct amdgpu_bo *bo = ttm_to_amdgpu_bo(lobj->tv.bo); - bool binding_userptr = false; struct mm_struct *usermm; usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm); @@ -553,7 +552,6 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, lobj->user_pages); - binding_userptr = true; } if (p->evictable == lobj) @@ -563,10 +561,8 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, if (r) return r; - if (binding_userptr) { - kvfree(lobj->user_pages); - lobj->user_pages = NULL; - } + kvfree(lobj->user_pages); + lobj->user_pages = NULL; } return 0; } -- GitLab From 3122051edc7c27cc08534be730f4c7c180919b8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 19 Sep 2019 10:38:57 +0200 Subject: [PATCH 421/993] drm/amdgpu: fix potential VM faults MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we allocate new page tables under memory pressure we should not evict old ones. Signed-off-by: Christian König Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 1fead0e8b890..7289e1b4fb60 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -453,7 +453,8 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, .interruptible = (bp->type != ttm_bo_type_kernel), .no_wait_gpu = false, .resv = bp->resv, - .flags = TTM_OPT_FLAG_ALLOW_RES_EVICT + .flags = bp->type != ttm_bo_type_kernel ? + TTM_OPT_FLAG_ALLOW_RES_EVICT : 0 }; struct amdgpu_bo *bo; unsigned long page_align, size = bp->size; -- GitLab From de51a5019ff32960218da8fd899fa3f361b031e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 18 Sep 2019 19:42:14 +0200 Subject: [PATCH 422/993] drm/amdgpu: fix error handling in amdgpu_bo_list_create MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to drop normal and userptr BOs separately. Signed-off-by: Christian König Acked-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 61e38e43ad1d..85b0515c0fdc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -140,7 +140,12 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp, return 0; error_free: - while (i--) { + for (i = 0; i < last_entry; ++i) { + struct amdgpu_bo *bo = ttm_to_amdgpu_bo(array[i].tv.bo); + + amdgpu_bo_unref(&bo); + } + for (i = first_userptr; i < num_entries; ++i) { struct amdgpu_bo *bo = ttm_to_amdgpu_bo(array[i].tv.bo); amdgpu_bo_unref(&bo); -- GitLab From ee027828c40faa92a7ef4c2b0641bbb3f4be95d3 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 17 Oct 2019 11:36:47 -0400 Subject: [PATCH 423/993] drm/amdgpu/vce: fix allocation size in enc ring test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to allocate a large enough buffer for the feedback buffer, otherwise the IB test can overwrite other memory. Reviewed-by: James Zhu Acked-by: Christian König Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 20 +++++++++++++++----- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h | 1 + 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index b70b3c45bb29..65044b1b3d4c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -429,13 +429,14 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp) * Open up a stream for HW test */ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, + struct amdgpu_bo *bo, struct dma_fence **fence) { const unsigned ib_size_dw = 1024; struct amdgpu_job *job; struct amdgpu_ib *ib; struct dma_fence *f = NULL; - uint64_t dummy; + uint64_t addr; int i, r; r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); @@ -444,7 +445,7 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, ib = &job->ibs[0]; - dummy = ib->gpu_addr + 1024; + addr = amdgpu_bo_gpu_offset(bo); /* stitch together an VCE create msg */ ib->length_dw = 0; @@ -476,8 +477,8 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, ib->ptr[ib->length_dw++] = 0x00000014; /* len */ ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */ - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); - ib->ptr[ib->length_dw++] = dummy; + ib->ptr[ib->length_dw++] = upper_32_bits(addr); + ib->ptr[ib->length_dw++] = addr; ib->ptr[ib->length_dw++] = 0x00000001; for (i = ib->length_dw; i < ib_size_dw; ++i) @@ -1110,13 +1111,20 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring) int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout) { struct dma_fence *fence = NULL; + struct amdgpu_bo *bo = NULL; long r; /* skip vce ring1/2 ib test for now, since it's not reliable */ if (ring != &ring->adev->vce.ring[0]) return 0; - r = amdgpu_vce_get_create_msg(ring, 1, NULL); + r = amdgpu_bo_create_reserved(ring->adev, 512, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + &bo, NULL, NULL); + if (r) + return r; + + r = amdgpu_vce_get_create_msg(ring, 1, bo, NULL); if (r) goto error; @@ -1132,5 +1140,7 @@ int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout) error: dma_fence_put(fence); + amdgpu_bo_unreserve(bo); + amdgpu_bo_unref(&bo); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h index 30ea54dd9117..e802f7d9db0a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h @@ -59,6 +59,7 @@ int amdgpu_vce_entity_init(struct amdgpu_device *adev); int amdgpu_vce_suspend(struct amdgpu_device *adev); int amdgpu_vce_resume(struct amdgpu_device *adev); int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, + struct amdgpu_bo *bo, struct dma_fence **fence); int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, bool direct, struct dma_fence **fence); -- GitLab From 491381ce07ca57f68c49c79a8a43da5b60749e32 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 17 Oct 2019 09:20:46 -0600 Subject: [PATCH 424/993] io_uring: fix up O_NONBLOCK handling for sockets We've got two issues with the non-regular file handling for non-blocking IO: 1) We don't want to re-do a short read in full for a non-regular file, as we can't just read the data again. 2) For non-regular files that don't support non-blocking IO attempts, we need to punt to async context even if the file is opened as non-blocking. Otherwise the caller always gets -EAGAIN. Add two new request flags to handle these cases. One is just a cache of the inode S_ISREG() status, the other tells io_uring that we always need to punt this request to async context, even if REQ_F_NOWAIT is set. Cc: stable@vger.kernel.org Reported-by: Hrvoje Zeba Tested-by: Hrvoje Zeba Signed-off-by: Jens Axboe --- fs/io_uring.c | 57 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index d2cb277da2f4..b7d4085d6ffd 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -322,6 +322,8 @@ struct io_kiocb { #define REQ_F_FAIL_LINK 256 /* fail rest of links */ #define REQ_F_SHADOW_DRAIN 512 /* link-drain shadow req */ #define REQ_F_TIMEOUT 1024 /* timeout request */ +#define REQ_F_ISREG 2048 /* regular file */ +#define REQ_F_MUST_PUNT 4096 /* must be punted even for NONBLOCK */ u64 user_data; u32 result; u32 sequence; @@ -914,26 +916,26 @@ static int io_iopoll_check(struct io_ring_ctx *ctx, unsigned *nr_events, return ret; } -static void kiocb_end_write(struct kiocb *kiocb) +static void kiocb_end_write(struct io_kiocb *req) { - if (kiocb->ki_flags & IOCB_WRITE) { - struct inode *inode = file_inode(kiocb->ki_filp); + /* + * Tell lockdep we inherited freeze protection from submission + * thread. + */ + if (req->flags & REQ_F_ISREG) { + struct inode *inode = file_inode(req->file); - /* - * Tell lockdep we inherited freeze protection from submission - * thread. - */ - if (S_ISREG(inode->i_mode)) - __sb_writers_acquired(inode->i_sb, SB_FREEZE_WRITE); - file_end_write(kiocb->ki_filp); + __sb_writers_acquired(inode->i_sb, SB_FREEZE_WRITE); } + file_end_write(req->file); } static void io_complete_rw(struct kiocb *kiocb, long res, long res2) { struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw); - kiocb_end_write(kiocb); + if (kiocb->ki_flags & IOCB_WRITE) + kiocb_end_write(req); if ((req->flags & REQ_F_LINK) && res != req->result) req->flags |= REQ_F_FAIL_LINK; @@ -945,7 +947,8 @@ static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2) { struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw); - kiocb_end_write(kiocb); + if (kiocb->ki_flags & IOCB_WRITE) + kiocb_end_write(req); if ((req->flags & REQ_F_LINK) && res != req->result) req->flags |= REQ_F_FAIL_LINK; @@ -1059,8 +1062,17 @@ static int io_prep_rw(struct io_kiocb *req, const struct sqe_submit *s, if (!req->file) return -EBADF; - if (force_nonblock && !io_file_supports_async(req->file)) - force_nonblock = false; + if (S_ISREG(file_inode(req->file)->i_mode)) + req->flags |= REQ_F_ISREG; + + /* + * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so + * we know to async punt it even if it was opened O_NONBLOCK + */ + if (force_nonblock && !io_file_supports_async(req->file)) { + req->flags |= REQ_F_MUST_PUNT; + return -EAGAIN; + } kiocb->ki_pos = READ_ONCE(sqe->off); kiocb->ki_flags = iocb_flags(kiocb->ki_filp); @@ -1081,7 +1093,8 @@ static int io_prep_rw(struct io_kiocb *req, const struct sqe_submit *s, return ret; /* don't allow async punt if RWF_NOWAIT was requested */ - if (kiocb->ki_flags & IOCB_NOWAIT) + if ((kiocb->ki_flags & IOCB_NOWAIT) || + (req->file->f_flags & O_NONBLOCK)) req->flags |= REQ_F_NOWAIT; if (force_nonblock) @@ -1382,7 +1395,9 @@ static int io_read(struct io_kiocb *req, const struct sqe_submit *s, * need async punt anyway, so it's more efficient to do it * here. */ - if (force_nonblock && ret2 > 0 && ret2 < read_size) + if (force_nonblock && !(req->flags & REQ_F_NOWAIT) && + (req->flags & REQ_F_ISREG) && + ret2 > 0 && ret2 < read_size) ret2 = -EAGAIN; /* Catch -EAGAIN return for forced non-blocking submission */ if (!force_nonblock || ret2 != -EAGAIN) { @@ -1447,7 +1462,7 @@ static int io_write(struct io_kiocb *req, const struct sqe_submit *s, * released so that it doesn't complain about the held lock when * we return to userspace. */ - if (S_ISREG(file_inode(file)->i_mode)) { + if (req->flags & REQ_F_ISREG) { __sb_start_write(file_inode(file)->i_sb, SB_FREEZE_WRITE, true); __sb_writers_release(file_inode(file)->i_sb, @@ -2282,7 +2297,13 @@ static int __io_queue_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, int ret; ret = __io_submit_sqe(ctx, req, s, force_nonblock); - if (ret == -EAGAIN && !(req->flags & REQ_F_NOWAIT)) { + + /* + * We async punt it if the file wasn't marked NOWAIT, or if the file + * doesn't support non-blocking read/write attempts + */ + if (ret == -EAGAIN && (!(req->flags & REQ_F_NOWAIT) || + (req->flags & REQ_F_MUST_PUNT))) { struct io_uring_sqe *sqe_copy; sqe_copy = kmemdup(s->sqe, sizeof(*sqe_copy), GFP_KERNEL); -- GitLab From 8b07a65ad30e5612d9590fb50468ff4fa314cfc7 Mon Sep 17 00:00:00 2001 From: yangerkun Date: Thu, 17 Oct 2019 12:12:35 +0800 Subject: [PATCH 425/993] io_uring: fix logic error in io_timeout If ctx->cached_sq_head < nxt_sq_head, we should add UINT_MAX to tmp, not tmp_nxt. Fixes: 5da0fb1ab34c ("io_uring: consider the overflow of sequence for timeout req") Signed-off-by: yangerkun Signed-off-by: Jens Axboe --- fs/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index b7d4085d6ffd..1d03afd74368 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1949,7 +1949,7 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe) * once there is some timeout req still be valid. */ if (ctx->cached_sq_head < nxt_sq_head) - tmp_nxt += UINT_MAX; + tmp += UINT_MAX; if (tmp >= tmp_nxt) break; -- GitLab From 8b95599c55ed24b36cf44a4720067cfe67edbcb4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 16 Oct 2019 15:35:06 +0200 Subject: [PATCH 426/993] net: phy: micrel: Discern KSZ8051 and KSZ8795 PHYs The KSZ8051 PHY and the KSZ8794/KSZ8795/KSZ8765 switch share exactly the same PHY ID. Since KSZ8051 is higher in the ksphy_driver[] list of PHYs in the micrel PHY driver, it is used even with the KSZ87xx switch. This is wrong, since the KSZ8051 configures registers of the PHY which are not present on the simplified KSZ87xx switch PHYs and misconfigures other registers of the KSZ87xx switch PHYs. Fortunatelly, it is possible to tell apart the KSZ8051 PHY from the KSZ87xx switch by checking the Basic Status register Bit 0, which is read-only and indicates presence of the Extended Capability Registers. The KSZ8051 PHY has those registers while the KSZ87xx switch does not. This patch implements simple check for the presence of this bit for both the KSZ8051 PHY and KSZ87xx switch, to let both use the correct PHY driver instance. Fixes: 9d162ed69f51 ("net: phy: micrel: add support for KSZ8795") Signed-off-by: Marek Vasut Cc: Andrew Lunn Cc: David S. Miller Cc: Florian Fainelli Cc: George McCollister Cc: Heiner Kallweit Cc: Sean Nyekjaer Cc: Tristram Ha Cc: Woojung Huh Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 2fea5541c35a..a0444e28c6e7 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -341,6 +341,35 @@ static int ksz8041_config_aneg(struct phy_device *phydev) return genphy_config_aneg(phydev); } +static int ksz8051_ksz8795_match_phy_device(struct phy_device *phydev, + const u32 ksz_phy_id) +{ + int ret; + + if ((phydev->phy_id & MICREL_PHY_ID_MASK) != ksz_phy_id) + return 0; + + ret = phy_read(phydev, MII_BMSR); + if (ret < 0) + return ret; + + /* KSZ8051 PHY and KSZ8794/KSZ8795/KSZ8765 switch share the same + * exact PHY ID. However, they can be told apart by the extended + * capability registers presence. The KSZ8051 PHY has them while + * the switch does not. + */ + ret &= BMSR_ERCAP; + if (ksz_phy_id == PHY_ID_KSZ8051) + return ret; + else + return !ret; +} + +static int ksz8051_match_phy_device(struct phy_device *phydev) +{ + return ksz8051_ksz8795_match_phy_device(phydev, PHY_ID_KSZ8051); +} + static int ksz8081_config_init(struct phy_device *phydev) { /* KSZPHY_OMSO_FACTORY_TEST is set at de-assertion of the reset line @@ -364,6 +393,11 @@ static int ksz8061_config_init(struct phy_device *phydev) return kszphy_config_init(phydev); } +static int ksz8795_match_phy_device(struct phy_device *phydev) +{ + return ksz8051_ksz8795_match_phy_device(phydev, PHY_ID_KSZ8795); +} + static int ksz9021_load_values_from_of(struct phy_device *phydev, const struct device_node *of_node, u16 reg, @@ -1017,8 +1051,6 @@ static struct phy_driver ksphy_driver[] = { .suspend = genphy_suspend, .resume = genphy_resume, }, { - .phy_id = PHY_ID_KSZ8051, - .phy_id_mask = MICREL_PHY_ID_MASK, .name = "Micrel KSZ8051", /* PHY_BASIC_FEATURES */ .driver_data = &ksz8051_type, @@ -1029,6 +1061,7 @@ static struct phy_driver ksphy_driver[] = { .get_sset_count = kszphy_get_sset_count, .get_strings = kszphy_get_strings, .get_stats = kszphy_get_stats, + .match_phy_device = ksz8051_match_phy_device, .suspend = genphy_suspend, .resume = genphy_resume, }, { @@ -1141,13 +1174,12 @@ static struct phy_driver ksphy_driver[] = { .suspend = genphy_suspend, .resume = genphy_resume, }, { - .phy_id = PHY_ID_KSZ8795, - .phy_id_mask = MICREL_PHY_ID_MASK, .name = "Micrel KSZ8795", /* PHY_BASIC_FEATURES */ .config_init = kszphy_config_init, .config_aneg = ksz8873mll_config_aneg, .read_status = ksz8873mll_read_status, + .match_phy_device = ksz8795_match_phy_device, .suspend = genphy_suspend, .resume = genphy_resume, }, { -- GitLab From 1d951ba3da67bbc7a9b0e05987e09552c2060e18 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 16 Oct 2019 15:35:07 +0200 Subject: [PATCH 427/993] net: phy: micrel: Update KSZ87xx PHY name The KSZ8795 PHY ID is in fact used by KSZ8794/KSZ8795/KSZ8765 switches. Update the PHY ID and name to reflect that, as this family of switches is commonly refered to as KSZ87xx Signed-off-by: Marek Vasut Cc: Andrew Lunn Cc: David S. Miller Cc: Florian Fainelli Cc: George McCollister Cc: Heiner Kallweit Cc: Sean Nyekjaer Cc: Tristram Ha Cc: Woojung Huh Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 4 ++-- include/linux/micrel_phy.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index a0444e28c6e7..63dedec0433d 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -395,7 +395,7 @@ static int ksz8061_config_init(struct phy_device *phydev) static int ksz8795_match_phy_device(struct phy_device *phydev) { - return ksz8051_ksz8795_match_phy_device(phydev, PHY_ID_KSZ8795); + return ksz8051_ksz8795_match_phy_device(phydev, PHY_ID_KSZ87XX); } static int ksz9021_load_values_from_of(struct phy_device *phydev, @@ -1174,7 +1174,7 @@ static struct phy_driver ksphy_driver[] = { .suspend = genphy_suspend, .resume = genphy_resume, }, { - .name = "Micrel KSZ8795", + .name = "Micrel KSZ87XX Switch", /* PHY_BASIC_FEATURES */ .config_init = kszphy_config_init, .config_aneg = ksz8873mll_config_aneg, diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h index ad24554f11f9..75f880c25bb8 100644 --- a/include/linux/micrel_phy.h +++ b/include/linux/micrel_phy.h @@ -31,7 +31,7 @@ #define PHY_ID_KSZ886X 0x00221430 #define PHY_ID_KSZ8863 0x00221435 -#define PHY_ID_KSZ8795 0x00221550 +#define PHY_ID_KSZ87XX 0x00221550 #define PHY_ID_KSZ9477 0x00221631 -- GitLab From 595e0651d0296bad2491a4a29a7a43eae6328b02 Mon Sep 17 00:00:00 2001 From: Stefano Brivio Date: Wed, 16 Oct 2019 20:52:09 +0200 Subject: [PATCH 428/993] ipv4: Return -ENETUNREACH if we can't create route but saddr is valid ...instead of -EINVAL. An issue was found with older kernel versions while unplugging a NFS client with pending RPCs, and the wrong error code here prevented it from recovering once link is back up with a configured address. Incidentally, this is not an issue anymore since commit 4f8943f80883 ("SUNRPC: Replace direct task wakeups from softirq context"), included in 5.2-rc7, had the effect of decoupling the forwarding of this error by using SO_ERROR in xs_wake_error(), as pointed out by Benjamin Coddington. To the best of my knowledge, this isn't currently causing any further issue, but the error code doesn't look appropriate anyway, and we might hit this in other paths as well. In detail, as analysed by Gonzalo Siero, once the route is deleted because the interface is down, and can't be resolved and we return -EINVAL here, this ends up, courtesy of inet_sk_rebuild_header(), as the socket error seen by tcp_write_err(), called by tcp_retransmit_timer(). In turn, tcp_write_err() indirectly calls xs_error_report(), which wakes up the RPC pending tasks with a status of -EINVAL. This is then seen by call_status() in the SUN RPC implementation, which aborts the RPC call calling rpc_exit(), instead of handling this as a potentially temporary condition, i.e. as a timeout. Return -EINVAL only if the input parameters passed to ip_route_output_key_hash_rcu() are actually invalid (this is the case if the specified source address is multicast, limited broadcast or all zeroes), but return -ENETUNREACH in all cases where, at the given moment, the given source address doesn't allow resolving the route. While at it, drop the initialisation of err to -ENETUNREACH, which was added to __ip_route_output_key() back then by commit 0315e3827048 ("net: Fix behaviour of unreachable, blackhole and prohibit routes"), but actually had no effect, as it was, and is, overwritten by the fib_lookup() return code assignment, and anyway ignored in all other branches, including the if (fl4->saddr) one: I find this rather confusing, as it would look like -ENETUNREACH is the "default" error, while that statement has no effect. Also note that after commit fc75fc8339e7 ("ipv4: dont create routes on down devices"), we would get -ENETUNREACH if the device is down, but -EINVAL if the source address is specified and we can't resolve the route, and this appears to be rather inconsistent. Reported-by: Stefan Walter Analysed-by: Benjamin Coddington Analysed-by: Gonzalo Siero Signed-off-by: Stefano Brivio Signed-off-by: David S. Miller --- net/ipv4/route.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 14654876127e..5bc172abd143 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2470,14 +2470,17 @@ struct rtable *ip_route_output_key_hash_rcu(struct net *net, struct flowi4 *fl4, int orig_oif = fl4->flowi4_oif; unsigned int flags = 0; struct rtable *rth; - int err = -ENETUNREACH; + int err; if (fl4->saddr) { - rth = ERR_PTR(-EINVAL); if (ipv4_is_multicast(fl4->saddr) || ipv4_is_lbcast(fl4->saddr) || - ipv4_is_zeronet(fl4->saddr)) + ipv4_is_zeronet(fl4->saddr)) { + rth = ERR_PTR(-EINVAL); goto out; + } + + rth = ERR_PTR(-ENETUNREACH); /* I removed check for oif == dev_out->oif here. It was wrong for two reasons: -- GitLab From 5018c59607a511cdee743b629c76206d9c9e6d7b Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Wed, 16 Oct 2019 12:03:15 -0700 Subject: [PATCH 429/993] ipv4: fix race condition between route lookup and invalidation Jesse and Ido reported the following race condition: - Received packet A is forwarded and cached dst entry is taken from the nexthop ('nhc->nhc_rth_input'). Calls skb_dst_set() - Given Jesse has busy routers ("ingesting full BGP routing tables from multiple ISPs"), route is added / deleted and rt_cache_flush() is called - Received packet B tries to use the same cached dst entry from t0, but rt_cache_valid() is no longer true and it is replaced in rt_cache_route() by the newer one. This calls dst_dev_put() on the original dst entry which assigns the blackhole netdev to 'dst->dev' - dst_input(skb) is called on packet A and it is dropped due to 'dst->dev' being the blackhole netdev There are 2 issues in the v4 routing code: 1. A per-netns counter is used to do the validation of the route. That means whenever a route is changed in the netns, users of all routes in the netns needs to redo lookup. v6 has an implementation of only updating fn_sernum for routes that are affected. 2. When rt_cache_valid() returns false, rt_cache_route() is called to throw away the current cache, and create a new one. This seems unnecessary because as long as this route does not change, the route cache does not need to be recreated. To fully solve the above 2 issues, it probably needs quite some code changes and requires careful testing, and does not suite for net branch. So this patch only tries to add the deleted cached rt into the uncached list, so user could still be able to use it to receive packets until it's done. Fixes: 95c47f9cf5e0 ("ipv4: call dst_dev_put() properly") Signed-off-by: Wei Wang Reported-by: Ido Schimmel Reported-by: Jesse Hathaway Tested-by: Jesse Hathaway Acked-by: Martin KaFai Lau Cc: David Ahern Reviewed-by: Ido Schimmel Signed-off-by: David S. Miller --- net/ipv4/route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 5bc172abd143..621f83434b24 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1482,7 +1482,7 @@ static bool rt_cache_route(struct fib_nh_common *nhc, struct rtable *rt) prev = cmpxchg(p, orig, rt); if (prev == orig) { if (orig) { - dst_dev_put(&orig->dst); + rt_add_uncached_list(orig); dst_release(&orig->dst); } } else { -- GitLab From 0cc76d2b14ffcd00a99d6ec3b9ebad39c659701a Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Thu, 17 Oct 2019 05:14:08 +0800 Subject: [PATCH 430/993] net: Update address for MediaTek ethernet driver in MAINTAINERS Update maintainers for MediaTek ethernet driver with Mark Lee. He is familiar with MediaTek mt762x series ethernet devices and will keep following maintenance from the vendor side. Signed-off-by: Sean Wang Signed-off-by: Mark Lee Signed-off-by: David S. Miller --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 49e4b004917b..60c8b337eb88 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10258,7 +10258,7 @@ MEDIATEK ETHERNET DRIVER M: Felix Fietkau M: John Crispin M: Sean Wang -M: Nelson Chang +M: Mark Lee L: netdev@vger.kernel.org S: Maintained F: drivers/net/ethernet/mediatek/ -- GitLab From 27e84243cb63601a10e366afe3e2d05bb03c1cb5 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Mon, 14 Oct 2019 20:29:04 +0200 Subject: [PATCH 431/993] scsi: target: core: Do not overwrite CDB byte 1 passthrough_parse_cdb() - used by TCMU and PSCSI - attepts to reset the LUN field of SCSI-2 CDBs (bits 5,6,7 of byte 1). The current code is wrong as for newer commands not having the LUN field it overwrites relevant command bits (e.g. for SECURITY PROTOCOL IN / OUT). We think this code was unnecessary from the beginning or at least it is no longer useful. So we remove it entirely. Link: https://lore.kernel.org/r/12498eab-76fd-eaad-1316-c2827badb76a@ts.fujitsu.com Signed-off-by: Bodo Stroesser Reviewed-by: Bart Van Assche Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/target/target_core_device.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 04bf2acd3800..2d19f0e332b0 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -1074,27 +1074,6 @@ passthrough_parse_cdb(struct se_cmd *cmd, struct se_device *dev = cmd->se_dev; unsigned int size; - /* - * Clear a lun set in the cdb if the initiator talking to use spoke - * and old standards version, as we can't assume the underlying device - * won't choke up on it. - */ - switch (cdb[0]) { - case READ_10: /* SBC - RDProtect */ - case READ_12: /* SBC - RDProtect */ - case READ_16: /* SBC - RDProtect */ - case SEND_DIAGNOSTIC: /* SPC - SELF-TEST Code */ - case VERIFY: /* SBC - VRProtect */ - case VERIFY_16: /* SBC - VRProtect */ - case WRITE_VERIFY: /* SBC - VRProtect */ - case WRITE_VERIFY_12: /* SBC - VRProtect */ - case MAINTENANCE_IN: /* SPC - Parameter Data Format for SA RTPG */ - break; - default: - cdb[1] &= 0x1f; /* clear logical unit number */ - break; - } - /* * For REPORT LUNS we always need to emulate the response, for everything * else, pass it up. -- GitLab From 134993456c28c2ae14bd953236eb0742fe23d577 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Mon, 14 Oct 2019 13:03:58 -0500 Subject: [PATCH 432/993] scsi: hpsa: add missing hunks in reset-patch Correct returning from reset before outstanding commands are completed for the device. Link: https://lore.kernel.org/r/157107623870.17997.11208813089704833029.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/hpsa.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 43a6b5350775..d93a5b20b9d1 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -5474,6 +5474,8 @@ static int hpsa_ciss_submit(struct ctlr_info *h, return SCSI_MLQUEUE_HOST_BUSY; } + c->device = dev; + enqueue_cmd_and_start_io(h, c); /* the cmd'll come back via intr handler in complete_scsi_command() */ return 0; @@ -5545,6 +5547,7 @@ static int hpsa_ioaccel_submit(struct ctlr_info *h, hpsa_cmd_init(h, c->cmdindex, c); c->cmd_type = CMD_SCSI; c->scsi_cmd = cmd; + c->device = dev; rc = hpsa_scsi_ioaccel_raid_map(h, c); if (rc < 0) /* scsi_dma_map failed. */ rc = SCSI_MLQUEUE_HOST_BUSY; @@ -5552,6 +5555,7 @@ static int hpsa_ioaccel_submit(struct ctlr_info *h, hpsa_cmd_init(h, c->cmdindex, c); c->cmd_type = CMD_SCSI; c->scsi_cmd = cmd; + c->device = dev; rc = hpsa_scsi_ioaccel_direct_map(h, c); if (rc < 0) /* scsi_dma_map failed. */ rc = SCSI_MLQUEUE_HOST_BUSY; -- GitLab From 77c301287ebae86cc71d03eb3806f271cb14da79 Mon Sep 17 00:00:00 2001 From: Yufen Yu Date: Tue, 15 Oct 2019 21:05:56 +0800 Subject: [PATCH 433/993] scsi: core: try to get module before removing device We have a test case like block/001 in blktests, which will create a scsi device by loading scsi_debug module and then try to delete the device by sysfs interface. At the same time, it may remove the scsi_debug module. And getting a invalid paging request BUG_ON as following: [ 34.625854] BUG: unable to handle page fault for address: ffffffffa0016bb8 [ 34.629189] Oops: 0000 [#1] SMP PTI [ 34.629618] CPU: 1 PID: 450 Comm: bash Tainted: G W 5.4.0-rc3+ #473 [ 34.632524] RIP: 0010:scsi_proc_hostdir_rm+0x5/0xa0 [ 34.643555] CR2: ffffffffa0016bb8 CR3: 000000012cd88000 CR4: 00000000000006e0 [ 34.644545] Call Trace: [ 34.644907] scsi_host_dev_release+0x6b/0x1f0 [ 34.645511] device_release+0x74/0x110 [ 34.646046] kobject_put+0x116/0x390 [ 34.646559] put_device+0x17/0x30 [ 34.647041] scsi_target_dev_release+0x2b/0x40 [ 34.647652] device_release+0x74/0x110 [ 34.648186] kobject_put+0x116/0x390 [ 34.648691] put_device+0x17/0x30 [ 34.649157] scsi_device_dev_release_usercontext+0x2e8/0x360 [ 34.649953] execute_in_process_context+0x29/0x80 [ 34.650603] scsi_device_dev_release+0x20/0x30 [ 34.651221] device_release+0x74/0x110 [ 34.651732] kobject_put+0x116/0x390 [ 34.652230] sysfs_unbreak_active_protection+0x3f/0x50 [ 34.652935] sdev_store_delete.cold.4+0x71/0x8f [ 34.653579] dev_attr_store+0x1b/0x40 [ 34.654103] sysfs_kf_write+0x3d/0x60 [ 34.654603] kernfs_fop_write+0x174/0x250 [ 34.655165] __vfs_write+0x1f/0x60 [ 34.655639] vfs_write+0xc7/0x280 [ 34.656117] ksys_write+0x6d/0x140 [ 34.656591] __x64_sys_write+0x1e/0x30 [ 34.657114] do_syscall_64+0xb1/0x400 [ 34.657627] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 34.658335] RIP: 0033:0x7f156f337130 During deleting scsi target, the scsi_debug module have been removed. Then, sdebug_driver_template belonged to the module cannot be accessd, resulting in scsi_proc_hostdir_rm() BUG_ON. To fix the bug, we add scsi_device_get() in sdev_store_delete() to try to increase refcount of module, avoiding the module been removed. Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191015130556.18061-1-yuyufen@huawei.com Signed-off-by: Yufen Yu Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_sysfs.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 64c96c7828ee..6d7362e7367e 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -730,6 +730,14 @@ sdev_store_delete(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct kernfs_node *kn; + struct scsi_device *sdev = to_scsi_device(dev); + + /* + * We need to try to get module, avoiding the module been removed + * during delete. + */ + if (scsi_device_get(sdev)) + return -ENODEV; kn = sysfs_break_active_protection(&dev->kobj, &attr->attr); WARN_ON_ONCE(!kn); @@ -744,9 +752,10 @@ sdev_store_delete(struct device *dev, struct device_attribute *attr, * state into SDEV_DEL. */ device_remove_file(dev, attr); - scsi_remove_device(to_scsi_device(dev)); + scsi_remove_device(sdev); if (kn) sysfs_unbreak_active_protection(kn); + scsi_device_put(sdev); return count; }; static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete); -- GitLab From 1052b41b25cbadcb85ff04c3b46663e21168dd3e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 17 Oct 2019 17:00:19 +0200 Subject: [PATCH 434/993] scsi: lpfc: remove left-over BUILD_NVME defines The BUILD_NVME define never got defined anywhere, causing NVMe commands to be treated as SCSI commands when freeing the buffers. This was causing a stuck discovery and a horrible crash in lpfc_set_rrq_active() later on. Link: https://lore.kernel.org/r/20191017150019.75769-1-hare@suse.de Fixes: c00f62e6c546 ("scsi: lpfc: Merge per-protocol WQ/CQ pairs into single per-cpu pair") Signed-off-by: Hannes Reinecke Reviewed-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_init.c | 2 -- drivers/scsi/lpfc/lpfc_scsi.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index de64880c6c60..2c1e085bd3ce 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -9053,7 +9053,6 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) } } -#if defined(BUILD_NVME) /* Clear NVME stats */ if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { @@ -9061,7 +9060,6 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) sizeof(phba->sli4_hba.hdwq[idx].nvme_cstat)); } } -#endif /* Clear SCSI stats */ if (phba->cfg_enable_fc4_type & LPFC_ENABLE_FCP) { diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index fe1097666de4..6822cd9ff8f1 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -528,7 +528,6 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, list_del_init(&psb->list); psb->exch_busy = 0; psb->status = IOSTAT_SUCCESS; -#ifdef BUILD_NVME if (psb->cur_iocbq.iocb_flag == LPFC_IO_NVME) { qp->abts_nvme_io_bufs--; spin_unlock(&qp->abts_io_buf_list_lock); @@ -536,7 +535,6 @@ lpfc_sli4_io_xri_aborted(struct lpfc_hba *phba, lpfc_sli4_nvme_xri_aborted(phba, axri, psb); return; } -#endif qp->abts_scsi_io_bufs--; spin_unlock(&qp->abts_io_buf_list_lock); -- GitLab From 7667819385457b4aeb5fac94f67f52ab52cc10d5 Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Thu, 17 Oct 2019 08:26:06 -0700 Subject: [PATCH 435/993] dmaengine: qcom: bam_dma: Fix resource leak bam_dma_terminate_all() will leak resources if any of the transactions are committed to the hardware (present in the desc fifo), and not complete. Since bam_dma_terminate_all() does not cause the hardware to be updated, the hardware will still operate on any previously committed transactions. This can cause memory corruption if the memory for the transaction has been reassigned, and will cause a sync issue between the BAM and its client(s). Fix this by properly updating the hardware in bam_dma_terminate_all(). Fixes: e7c0fe2a5c84 ("dmaengine: add Qualcomm BAM dma driver") Signed-off-by: Jeffrey Hugo Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191017152606.34120-1-jeffrey.l.hugo@gmail.com Signed-off-by: Vinod Koul --- drivers/dma/qcom/bam_dma.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c index 8e90a405939d..ef73f65224b1 100644 --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c @@ -694,6 +694,25 @@ static int bam_dma_terminate_all(struct dma_chan *chan) /* remove all transactions, including active transaction */ spin_lock_irqsave(&bchan->vc.lock, flag); + /* + * If we have transactions queued, then some might be committed to the + * hardware in the desc fifo. The only way to reset the desc fifo is + * to do a hardware reset (either by pipe or the entire block). + * bam_chan_init_hw() will trigger a pipe reset, and also reinit the + * pipe. If the pipe is left disabled (default state after pipe reset) + * and is accessed by a connected hardware engine, a fatal error in + * the BAM will occur. There is a small window where this could happen + * with bam_chan_init_hw(), but it is assumed that the caller has + * stopped activity on any attached hardware engine. Make sure to do + * this first so that the BAM hardware doesn't cause memory corruption + * by accessing freed resources. + */ + if (!list_empty(&bchan->desc_list)) { + async_desc = list_first_entry(&bchan->desc_list, + struct bam_async_desc, desc_node); + bam_chan_init_hw(bchan, async_desc->dir); + } + list_for_each_entry_safe(async_desc, tmp, &bchan->desc_list, desc_node) { list_add(&async_desc->vd.node, &bchan->vc.desc_issued); -- GitLab From 56a0b978d42f58c7e3ba715cf65af487d427524d Mon Sep 17 00:00:00 2001 From: John Garry Date: Tue, 15 Oct 2019 22:07:31 +0800 Subject: [PATCH 436/993] ACPI: CPPC: Set pcc_data[pcc_ss_id] to NULL in acpi_cppc_processor_exit() When enabling KASAN and DEBUG_TEST_DRIVER_REMOVE, I find this KASAN warning: [ 20.872057] BUG: KASAN: use-after-free in pcc_data_alloc+0x40/0xb8 [ 20.878226] Read of size 4 at addr ffff00236cdeb684 by task swapper/0/1 [ 20.884826] [ 20.886309] CPU: 19 PID: 1 Comm: swapper/0 Not tainted 5.4.0-rc1-00009-ge7f7df3db5bf-dirty #289 [ 20.894994] Hardware name: Huawei D06 /D06, BIOS Hisilicon D06 UEFI RC0 - V1.16.01 03/15/2019 [ 20.903505] Call trace: [ 20.905942] dump_backtrace+0x0/0x200 [ 20.909593] show_stack+0x14/0x20 [ 20.912899] dump_stack+0xd4/0x130 [ 20.916291] print_address_description.isra.9+0x6c/0x3b8 [ 20.921592] __kasan_report+0x12c/0x23c [ 20.925417] kasan_report+0xc/0x18 [ 20.928808] __asan_load4+0x94/0xb8 [ 20.932286] pcc_data_alloc+0x40/0xb8 [ 20.935938] acpi_cppc_processor_probe+0x4e8/0xb08 [ 20.940717] __acpi_processor_start+0x48/0xb0 [ 20.945062] acpi_processor_start+0x40/0x60 [ 20.949235] really_probe+0x118/0x548 [ 20.952887] driver_probe_device+0x7c/0x148 [ 20.957059] device_driver_attach+0x94/0xa0 [ 20.961231] __driver_attach+0xa4/0x110 [ 20.965055] bus_for_each_dev+0xe8/0x158 [ 20.968966] driver_attach+0x30/0x40 [ 20.972531] bus_add_driver+0x234/0x2f0 [ 20.976356] driver_register+0xbc/0x1d0 [ 20.980182] acpi_processor_driver_init+0x40/0xe4 [ 20.984875] do_one_initcall+0xb4/0x254 [ 20.988700] kernel_init_freeable+0x24c/0x2f8 [ 20.993047] kernel_init+0x10/0x118 [ 20.996524] ret_from_fork+0x10/0x18 [ 21.000087] [ 21.001567] Allocated by task 1: [ 21.004785] save_stack+0x28/0xc8 [ 21.008089] __kasan_kmalloc.isra.9+0xbc/0xd8 [ 21.012435] kasan_kmalloc+0xc/0x18 [ 21.015913] pcc_data_alloc+0x94/0xb8 [ 21.019564] acpi_cppc_processor_probe+0x4e8/0xb08 [ 21.024343] __acpi_processor_start+0x48/0xb0 [ 21.028689] acpi_processor_start+0x40/0x60 [ 21.032860] really_probe+0x118/0x548 [ 21.036512] driver_probe_device+0x7c/0x148 [ 21.040684] device_driver_attach+0x94/0xa0 [ 21.044855] __driver_attach+0xa4/0x110 [ 21.048680] bus_for_each_dev+0xe8/0x158 [ 21.052591] driver_attach+0x30/0x40 [ 21.056155] bus_add_driver+0x234/0x2f0 [ 21.059980] driver_register+0xbc/0x1d0 [ 21.063805] acpi_processor_driver_init+0x40/0xe4 [ 21.068497] do_one_initcall+0xb4/0x254 [ 21.072322] kernel_init_freeable+0x24c/0x2f8 [ 21.076667] kernel_init+0x10/0x118 [ 21.080144] ret_from_fork+0x10/0x18 [ 21.083707] [ 21.085186] Freed by task 1: [ 21.088056] save_stack+0x28/0xc8 [ 21.091360] __kasan_slab_free+0x118/0x180 [ 21.095445] kasan_slab_free+0x10/0x18 [ 21.099183] kfree+0x80/0x268 [ 21.102139] acpi_cppc_processor_exit+0x1a8/0x1b8 [ 21.106832] acpi_processor_stop+0x70/0x80 [ 21.110917] really_probe+0x174/0x548 [ 21.114568] driver_probe_device+0x7c/0x148 [ 21.118740] device_driver_attach+0x94/0xa0 [ 21.122912] __driver_attach+0xa4/0x110 [ 21.126736] bus_for_each_dev+0xe8/0x158 [ 21.130648] driver_attach+0x30/0x40 [ 21.134212] bus_add_driver+0x234/0x2f0 [ 21.0x10/0x18 [ 21.161764] [ 21.163244] The buggy address belongs to the object at ffff00236cdeb600 [ 21.163244] which belongs to the cache kmalloc-256 of size 256 [ 21.175750] The buggy address is located 132 bytes inside of [ 21.175750] 256-byte region [ffff00236cdeb600, ffff00236cdeb700) [ 21.187473] The buggy address belongs to the page: [ 21.192254] page:fffffe008d937a00 refcount:1 mapcount:0 mapping:ffff002370c0fa00 index:0x0 compound_mapcount: 0 [ 21.202331] flags: 0x1ffff00000010200(slab|head) [ 21.206940] raw: 1ffff00000010200 dead000000000100 dead000000000122 ffff002370c0fa00 [ 21.214671] raw: 0000000000000000 00000000802a002a 00000001ffffffff 0000000000000000 [ 21.222400] page dumped because: kasan: bad access detected [ 21.227959] [ 21.229438] Memory state around the buggy address: [ 21.234218] ffff00236cdeb580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 21.241427] ffff00236cdeb600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 21.248637] >ffff00236cdeb680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 21.255845] ^ [ 21.259062] ffff00236cdeb700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 21.266272] ffff00236cdeb780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 21.273480] ================================================================== It seems that global pcc_data[pcc_ss_id] can be freed in acpi_cppc_processor_exit(), but we may later reference this value, so NULLify it when freed. Also remove the useless setting of data "pcc_channel_acquired", which we're about to free. Fixes: 85b1407bf6d2 ("ACPI / CPPC: Make CPPC ACPI driver aware of PCC subspace IDs") Signed-off-by: John Garry Cc: 4.15+ # 4.15+ Signed-off-by: Rafael J. Wysocki --- drivers/acpi/cppc_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 3b2525908dd8..a1a858ad4d18 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -905,8 +905,8 @@ void acpi_cppc_processor_exit(struct acpi_processor *pr) pcc_data[pcc_ss_id]->refcount--; if (!pcc_data[pcc_ss_id]->refcount) { pcc_mbox_free_channel(pcc_data[pcc_ss_id]->pcc_channel); - pcc_data[pcc_ss_id]->pcc_channel_acquired = 0; kfree(pcc_data[pcc_ss_id]); + pcc_data[pcc_ss_id] = NULL; } } } -- GitLab From f7c0f50f1857c1cf013466fcea4dc98d116bf456 Mon Sep 17 00:00:00 2001 From: Andrea Parri Date: Tue, 15 Oct 2019 12:35:02 +0200 Subject: [PATCH 437/993] x86/hyperv: Set pv_info.name to "Hyper-V" Michael reported that the x86/hyperv initialization code prints the following dmesg when running in a VM on Hyper-V: [ 0.000738] Booting paravirtualized kernel on bare hardware Let the x86/hyperv initialization code set pv_info.name to "Hyper-V" so dmesg reports correctly: [ 0.000172] Booting paravirtualized kernel on Hyper-V [ tglx: Folded build fix provided by Yue ] Reported-by: Michael Kelley Signed-off-by: Andrea Parri Signed-off-by: Thomas Gleixner Reviewed-by: Wei Liu Reviewed-by: Michael Kelley Cc: YueHaibing Link: https://lkml.kernel.org/r/20191015103502.13156-1-parri.andrea@gmail.com --- arch/x86/kernel/cpu/mshyperv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 267daad8c036..c656d92cd708 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -216,6 +216,10 @@ static void __init ms_hyperv_init_platform(void) int hv_host_info_ecx; int hv_host_info_edx; +#ifdef CONFIG_PARAVIRT + pv_info.name = "Hyper-V"; +#endif + /* * Extract the features and hints */ -- GitLab From 228d120051a2234356690924c1f42e07e54e1eaf Mon Sep 17 00:00:00 2001 From: Zhenzhong Duan Date: Sun, 29 Sep 2019 09:13:52 +0800 Subject: [PATCH 438/993] x86/boot/acpi: Move get_cmdline_acpi_rsdp() under #ifdef guard When building with "EXTRA_CFLAGS=-Wall" gcc warns: arch/x86/boot/compressed/acpi.c:29:30: warning: get_cmdline_acpi_rsdp defined but not used [-Wunused-function] get_cmdline_acpi_rsdp() is only used when CONFIG_RANDOMIZE_BASE and CONFIG_MEMORY_HOTREMOVE are both enabled, so any build where one of these config options is disabled has this issue. Move the function under the same ifdef guard as the call site. [ tglx: Add context to the changelog so it becomes useful ] Fixes: 41fa1ee9c6d6 ("acpi: Ignore acpi_rsdp kernel param when the kernel has been locked down") Signed-off-by: Zhenzhong Duan Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/1569719633-32164-1-git-send-email-zhenzhong.duan@oracle.com --- arch/x86/boot/compressed/acpi.c | 48 ++++++++++++++++----------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c index 149795c369f2..25019d42ae93 100644 --- a/arch/x86/boot/compressed/acpi.c +++ b/arch/x86/boot/compressed/acpi.c @@ -20,30 +20,6 @@ */ struct mem_vector immovable_mem[MAX_NUMNODES*2]; -/* - * Max length of 64-bit hex address string is 19, prefix "0x" + 16 hex - * digits, and '\0' for termination. - */ -#define MAX_ADDR_LEN 19 - -static acpi_physical_address get_cmdline_acpi_rsdp(void) -{ - acpi_physical_address addr = 0; - -#ifdef CONFIG_KEXEC - char val[MAX_ADDR_LEN] = { }; - int ret; - - ret = cmdline_find_option("acpi_rsdp", val, MAX_ADDR_LEN); - if (ret < 0) - return 0; - - if (kstrtoull(val, 16, &addr)) - return 0; -#endif - return addr; -} - /* * Search EFI system tables for RSDP. If both ACPI_20_TABLE_GUID and * ACPI_TABLE_GUID are found, take the former, which has more features. @@ -298,6 +274,30 @@ acpi_physical_address get_rsdp_addr(void) } #if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_MEMORY_HOTREMOVE) +/* + * Max length of 64-bit hex address string is 19, prefix "0x" + 16 hex + * digits, and '\0' for termination. + */ +#define MAX_ADDR_LEN 19 + +static acpi_physical_address get_cmdline_acpi_rsdp(void) +{ + acpi_physical_address addr = 0; + +#ifdef CONFIG_KEXEC + char val[MAX_ADDR_LEN] = { }; + int ret; + + ret = cmdline_find_option("acpi_rsdp", val, MAX_ADDR_LEN); + if (ret < 0) + return 0; + + if (kstrtoull(val, 16, &addr)) + return 0; +#endif + return addr; +} + /* Compute SRAT address from RSDP. */ static unsigned long get_acpi_srat_table(void) { -- GitLab From 67b18dfb8cfc6d6c2f45ba8c546088f5c14f5bd5 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Wed, 16 Oct 2019 23:12:24 +0800 Subject: [PATCH 439/993] HID: i2c-hid: Remove runtime power management Runtime power management in i2c-hid brings lots of issues, such as: - When transitioning from display manager to desktop session, i2c-hid was closed and opened, so the device was set to SLEEP and ON in a short period. Vendors confirmed that their devices can't handle fast ON/SLEEP command because Windows doesn't have this behavior. - When rebooting, i2c-hid was closed, and the driver core put the device back to full power before shutdown. This behavior also triggers a quick SLEEP and ON commands that some devices can't handle, renders an unusable touchpad after reboot. - Most importantly, my power meter reports little to none energy saving when i2c-hid is runtime suspended. So let's remove runtime power management since there is no actual benefit. Signed-off-by: Kai-Heng Feng Acked-by: Hans de Goede Signed-off-by: Benjamin Tissoires --- drivers/hid/i2c-hid/i2c-hid-core.c | 118 ++--------------------------- 1 file changed, 7 insertions(+), 111 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 2a7c6e33bb1c..d9c55e30f986 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -48,8 +47,6 @@ /* quirks to control the device */ #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) -#define I2C_HID_QUIRK_NO_RUNTIME_PM BIT(2) -#define I2C_HID_QUIRK_DELAY_AFTER_SLEEP BIT(3) #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4) /* flags */ @@ -172,14 +169,7 @@ static const struct i2c_hid_quirks { { USB_VENDOR_ID_WEIDA, HID_ANY_ID, I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, - I2C_HID_QUIRK_NO_IRQ_AFTER_RESET | - I2C_HID_QUIRK_NO_RUNTIME_PM }, - { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_4B33, - I2C_HID_QUIRK_DELAY_AFTER_SLEEP }, - { USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_8001, - I2C_HID_QUIRK_NO_RUNTIME_PM }, - { I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_01F0, - I2C_HID_QUIRK_NO_RUNTIME_PM }, + I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, { USB_VENDOR_ID_ELAN, HID_ANY_ID, I2C_HID_QUIRK_BOGUS_IRQ }, { 0, 0 } @@ -397,7 +387,6 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) { struct i2c_hid *ihid = i2c_get_clientdata(client); int ret; - unsigned long now, delay; i2c_hid_dbg(ihid, "%s\n", __func__); @@ -415,22 +404,9 @@ static int i2c_hid_set_power(struct i2c_client *client, int power_state) goto set_pwr_exit; } - if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP && - power_state == I2C_HID_PWR_ON) { - now = jiffies; - if (time_after(ihid->sleep_delay, now)) { - delay = jiffies_to_usecs(ihid->sleep_delay - now); - usleep_range(delay, delay + 1); - } - } - ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state, 0, NULL, 0, NULL, 0); - if (ihid->quirks & I2C_HID_QUIRK_DELAY_AFTER_SLEEP && - power_state == I2C_HID_PWR_SLEEP) - ihid->sleep_delay = jiffies + msecs_to_jiffies(20); - if (ret) dev_err(&client->dev, "failed to change power setting.\n"); @@ -791,11 +767,6 @@ static int i2c_hid_open(struct hid_device *hid) { struct i2c_client *client = hid->driver_data; struct i2c_hid *ihid = i2c_get_clientdata(client); - int ret = 0; - - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) - return ret; set_bit(I2C_HID_STARTED, &ihid->flags); return 0; @@ -807,27 +778,6 @@ static void i2c_hid_close(struct hid_device *hid) struct i2c_hid *ihid = i2c_get_clientdata(client); clear_bit(I2C_HID_STARTED, &ihid->flags); - - /* Save some power */ - pm_runtime_put(&client->dev); -} - -static int i2c_hid_power(struct hid_device *hid, int lvl) -{ - struct i2c_client *client = hid->driver_data; - struct i2c_hid *ihid = i2c_get_clientdata(client); - - i2c_hid_dbg(ihid, "%s lvl:%d\n", __func__, lvl); - - switch (lvl) { - case PM_HINT_FULLON: - pm_runtime_get_sync(&client->dev); - break; - case PM_HINT_NORMAL: - pm_runtime_put(&client->dev); - break; - } - return 0; } struct hid_ll_driver i2c_hid_ll_driver = { @@ -836,7 +786,6 @@ struct hid_ll_driver i2c_hid_ll_driver = { .stop = i2c_hid_stop, .open = i2c_hid_open, .close = i2c_hid_close, - .power = i2c_hid_power, .output_report = i2c_hid_output_report, .raw_request = i2c_hid_raw_request, }; @@ -1104,9 +1053,6 @@ static int i2c_hid_probe(struct i2c_client *client, i2c_hid_acpi_fix_up_power(&client->dev); - pm_runtime_get_noresume(&client->dev); - pm_runtime_set_active(&client->dev); - pm_runtime_enable(&client->dev); device_enable_async_suspend(&client->dev); /* Make sure there is something at this address */ @@ -1114,16 +1060,16 @@ static int i2c_hid_probe(struct i2c_client *client, if (ret < 0) { dev_dbg(&client->dev, "nothing at this address: %d\n", ret); ret = -ENXIO; - goto err_pm; + goto err_regulator; } ret = i2c_hid_fetch_hid_descriptor(ihid); if (ret < 0) - goto err_pm; + goto err_regulator; ret = i2c_hid_init_irq(client); if (ret < 0) - goto err_pm; + goto err_regulator; hid = hid_allocate_device(); if (IS_ERR(hid)) { @@ -1154,9 +1100,6 @@ static int i2c_hid_probe(struct i2c_client *client, goto err_mem_free; } - if (!(ihid->quirks & I2C_HID_QUIRK_NO_RUNTIME_PM)) - pm_runtime_put(&client->dev); - return 0; err_mem_free: @@ -1165,10 +1108,6 @@ static int i2c_hid_probe(struct i2c_client *client, err_irq: free_irq(client->irq, ihid); -err_pm: - pm_runtime_put_noidle(&client->dev); - pm_runtime_disable(&client->dev); - err_regulator: regulator_bulk_disable(ARRAY_SIZE(ihid->pdata.supplies), ihid->pdata.supplies); @@ -1181,12 +1120,6 @@ static int i2c_hid_remove(struct i2c_client *client) struct i2c_hid *ihid = i2c_get_clientdata(client); struct hid_device *hid; - if (!(ihid->quirks & I2C_HID_QUIRK_NO_RUNTIME_PM)) - pm_runtime_get_sync(&client->dev); - pm_runtime_disable(&client->dev); - pm_runtime_set_suspended(&client->dev); - pm_runtime_put_noidle(&client->dev); - hid = ihid->hid; hid_destroy_device(hid); @@ -1219,25 +1152,15 @@ static int i2c_hid_suspend(struct device *dev) int wake_status; if (hid->driver && hid->driver->suspend) { - /* - * Wake up the device so that IO issues in - * HID driver's suspend code can succeed. - */ - ret = pm_runtime_resume(dev); - if (ret < 0) - return ret; - ret = hid->driver->suspend(hid, PMSG_SUSPEND); if (ret < 0) return ret; } - if (!pm_runtime_suspended(dev)) { - /* Save some power */ - i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); + /* Save some power */ + i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); - disable_irq(client->irq); - } + disable_irq(client->irq); if (device_may_wakeup(&client->dev)) { wake_status = enable_irq_wake(client->irq); @@ -1279,11 +1202,6 @@ static int i2c_hid_resume(struct device *dev) wake_status); } - /* We'll resume to full power */ - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - enable_irq(client->irq); /* Instead of resetting device, simply powers the device on. This @@ -1304,30 +1222,8 @@ static int i2c_hid_resume(struct device *dev) } #endif -#ifdef CONFIG_PM -static int i2c_hid_runtime_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - - i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); - disable_irq(client->irq); - return 0; -} - -static int i2c_hid_runtime_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - - enable_irq(client->irq); - i2c_hid_set_power(client, I2C_HID_PWR_ON); - return 0; -} -#endif - static const struct dev_pm_ops i2c_hid_pm = { SET_SYSTEM_SLEEP_PM_OPS(i2c_hid_suspend, i2c_hid_resume) - SET_RUNTIME_PM_OPS(i2c_hid_runtime_suspend, i2c_hid_runtime_resume, - NULL) }; static const struct i2c_device_id i2c_hid_id_table[] = { -- GitLab From abdd3d0b344fdf72a4904d09b97bc964d74c4419 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 17 Oct 2019 21:45:15 -0700 Subject: [PATCH 440/993] HID: logitech-hidpp: split g920_get_config() Original version of g920_get_config() contained two kind of actions: 1. Device specific communication to query/set some parameters which requires active communication channel with the device, or, put in other way, for the call to be sandwiched between hid_device_io_start() and hid_device_io_stop(). 2. Input subsystem specific FF controller initialization which, in order to access a valid 'struct hid_input' via 'hid->inputs.next', requires claimed hidinput which means be executed after the call to hid_hw_start() with connect_mask containing HID_CONNECT_HIDINPUT. Location of g920_get_config() can only fulfill requirements for #1 and not #2, which might result in following backtrace: [ 88.312258] logitech-hidpp-device 0003:046D:C262.0005: HID++ 4.2 device connected. [ 88.320298] BUG: kernel NULL pointer dereference, address: 0000000000000018 [ 88.320304] #PF: supervisor read access in kernel mode [ 88.320307] #PF: error_code(0x0000) - not-present page [ 88.320309] PGD 0 P4D 0 [ 88.320315] Oops: 0000 [#1] SMP PTI [ 88.320320] CPU: 1 PID: 3080 Comm: systemd-udevd Not tainted 5.4.0-rc1+ #31 [ 88.320322] Hardware name: Apple Inc. MacBookPro11,1/Mac-189A3D4F975D5FFC, BIOS 149.0.0.0.0 09/17/2018 [ 88.320334] RIP: 0010:hidpp_probe+0x61f/0x948 [hid_logitech_hidpp] [ 88.320338] Code: 81 00 00 48 89 ef e8 f0 d6 ff ff 41 89 c6 85 c0 75 b5 0f b6 44 24 28 48 8b 5d 00 88 44 24 1e 89 44 24 0c 48 8b 83 18 1c 00 00 <48> 8b 48 18 48 8b 83 10 19 00 00 48 8b 40 40 48 89 0c 24 0f b7 80 [ 88.320341] RSP: 0018:ffffb0a6824aba68 EFLAGS: 00010246 [ 88.320345] RAX: 0000000000000000 RBX: ffff93a50756e000 RCX: 0000000000010408 [ 88.320347] RDX: 0000000000000000 RSI: ffff93a51f0ad0a0 RDI: 000000000002d0a0 [ 88.320350] RBP: ffff93a50416da28 R08: ffff93a50416da70 R09: ffff93a50416da70 [ 88.320352] R10: 000000148ae9e60c R11: 00000000000f1525 R12: ffff93a50756e000 [ 88.320354] R13: ffff93a50756f8d0 R14: 0000000000000000 R15: ffff93a50756fc38 [ 88.320358] FS: 00007f8d8c1e0940(0000) GS:ffff93a51f080000(0000) knlGS:0000000000000000 [ 88.320361] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 88.320363] CR2: 0000000000000018 CR3: 00000003996d8003 CR4: 00000000001606e0 [ 88.320366] Call Trace: [ 88.320377] ? _cond_resched+0x15/0x30 [ 88.320387] ? create_pinctrl+0x2f/0x3c0 [ 88.320393] ? kernfs_link_sibling+0x94/0xe0 [ 88.320398] ? _cond_resched+0x15/0x30 [ 88.320402] ? kernfs_activate+0x5f/0x80 [ 88.320406] ? kernfs_add_one+0xe2/0x130 [ 88.320411] hid_device_probe+0x106/0x170 [ 88.320419] really_probe+0x147/0x3c0 [ 88.320424] driver_probe_device+0xb6/0x100 [ 88.320428] device_driver_attach+0x53/0x60 [ 88.320433] __driver_attach+0x8a/0x150 [ 88.320437] ? device_driver_attach+0x60/0x60 [ 88.320440] bus_for_each_dev+0x78/0xc0 [ 88.320445] bus_add_driver+0x14d/0x1f0 [ 88.320450] driver_register+0x6c/0xc0 [ 88.320453] ? 0xffffffffc0d67000 [ 88.320457] __hid_register_driver+0x4c/0x80 [ 88.320464] do_one_initcall+0x46/0x1f4 [ 88.320469] ? _cond_resched+0x15/0x30 [ 88.320474] ? kmem_cache_alloc_trace+0x162/0x220 [ 88.320481] ? do_init_module+0x23/0x230 [ 88.320486] do_init_module+0x5c/0x230 [ 88.320491] load_module+0x26e1/0x2990 [ 88.320502] ? ima_post_read_file+0xf0/0x100 [ 88.320508] ? __do_sys_finit_module+0xaa/0x110 [ 88.320512] __do_sys_finit_module+0xaa/0x110 [ 88.320520] do_syscall_64+0x5b/0x180 [ 88.320525] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 88.320528] RIP: 0033:0x7f8d8d1f01fd [ 88.320532] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 5b 8c 0c 00 f7 d8 64 89 01 48 [ 88.320535] RSP: 002b:00007ffefa3bb068 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 88.320539] RAX: ffffffffffffffda RBX: 000055922040cb40 RCX: 00007f8d8d1f01fd [ 88.320541] RDX: 0000000000000000 RSI: 00007f8d8ce4984d RDI: 0000000000000006 [ 88.320543] RBP: 0000000000020000 R08: 0000000000000000 R09: 0000000000000007 [ 88.320545] R10: 0000000000000006 R11: 0000000000000246 R12: 00007f8d8ce4984d [ 88.320547] R13: 0000000000000000 R14: 000055922040efc0 R15: 000055922040cb40 [ 88.320551] Modules linked in: hid_logitech_hidpp(+) fuse rfcomm ccm xt_CHECKSUM xt_MASQUERADE bridge stp llc nf_nat_tftp nf_conntrack_tftp nf_conntrack_netbios_ns nf_conntrack_broadcast xt_CT ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 xt_conntrack ebtable_nat ip6table_nat ip6table_mangle ip6table_raw ip6table_security iptable_nat nf_nat tun iptable_mangle iptable_raw iptable_security nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 libcrc32c ip_set nfnetlink ebtable_filter ebtables ip6table_filter ip6_tables cmac bnep sunrpc dm_crypt nls_utf8 hfsplus intel_rapl_msr intel_rapl_common ath9k_htc ath9k_common x86_pkg_temp_thermal intel_powerclamp b43 ath9k_hw coretemp snd_hda_codec_hdmi cordic kvm_intel snd_hda_codec_cirrus mac80211 snd_hda_codec_generic ledtrig_audio kvm snd_hda_intel snd_intel_nhlt irqbypass snd_hda_codec btusb btrtl snd_hda_core ath btbcm ssb snd_hwdep btintel snd_seq crct10dif_pclmul iTCO_wdt snd_seq_device crc32_pclmul bluetooth mmc_core iTCO_vendor_support joydev cfg80211 [ 88.320602] applesmc ghash_clmulni_intel ecdh_generic snd_pcm input_polldev intel_cstate ecc intel_uncore thunderbolt snd_timer i2c_i801 libarc4 rfkill intel_rapl_perf lpc_ich mei_me pcspkr bcm5974 snd bcma mei soundcore acpi_als sbs kfifo_buf sbshc industrialio apple_bl i915 i2c_algo_bit drm_kms_helper drm uas crc32c_intel usb_storage video hid_apple [ 88.320630] CR2: 0000000000000018 [ 88.320633] ---[ end trace 933491c8a4fadeb7 ]--- [ 88.320642] RIP: 0010:hidpp_probe+0x61f/0x948 [hid_logitech_hidpp] [ 88.320645] Code: 81 00 00 48 89 ef e8 f0 d6 ff ff 41 89 c6 85 c0 75 b5 0f b6 44 24 28 48 8b 5d 00 88 44 24 1e 89 44 24 0c 48 8b 83 18 1c 00 00 <48> 8b 48 18 48 8b 83 10 19 00 00 48 8b 40 40 48 89 0c 24 0f b7 80 [ 88.320647] RSP: 0018:ffffb0a6824aba68 EFLAGS: 00010246 [ 88.320650] RAX: 0000000000000000 RBX: ffff93a50756e000 RCX: 0000000000010408 [ 88.320652] RDX: 0000000000000000 RSI: ffff93a51f0ad0a0 RDI: 000000000002d0a0 [ 88.320655] RBP: ffff93a50416da28 R08: ffff93a50416da70 R09: ffff93a50416da70 [ 88.320657] R10: 000000148ae9e60c R11: 00000000000f1525 R12: ffff93a50756e000 [ 88.320659] R13: ffff93a50756f8d0 R14: 0000000000000000 R15: ffff93a50756fc38 [ 88.320662] FS: 00007f8d8c1e0940(0000) GS:ffff93a51f080000(0000) knlGS:0000000000000000 [ 88.320664] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 88.320667] CR2: 0000000000000018 CR3: 00000003996d8003 CR4: 00000000001606e0 To solve this issue: 1. Split g920_get_config() such that all of the device specific communication remains a part of the function and input subsystem initialization bits go to hidpp_ff_init() 2. Move call to hidpp_ff_init() from being a part of g920_get_config() to be the last step of .probe(), right after a call to hid_hw_start() with connect_mask containing HID_CONNECT_HIDINPUT. Fixes: 91cf9a98ae41 ("HID: logitech-hidpp: make .probe usbhid capable") Signed-off-by: Andrey Smirnov Tested-by: Sam Bazley Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: Henrik Rydberg Cc: Pierre-Loup A. Griffais Cc: Austin Palmer Cc: linux-input@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org # 5.2+ Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-logitech-hidpp.c | 150 ++++++++++++++++++++----------- 1 file changed, 96 insertions(+), 54 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 1ac1ecc1e67c..85911586b3b6 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -1669,6 +1669,7 @@ static void hidpp_touchpad_raw_xy_event(struct hidpp_device *hidpp_dev, #define HIDPP_FF_EFFECTID_NONE -1 #define HIDPP_FF_EFFECTID_AUTOCENTER -2 +#define HIDPP_AUTOCENTER_PARAMS_LENGTH 18 #define HIDPP_FF_MAX_PARAMS 20 #define HIDPP_FF_RESERVED_SLOTS 1 @@ -2009,7 +2010,7 @@ static int hidpp_ff_erase_effect(struct input_dev *dev, int effect_id) static void hidpp_ff_set_autocenter(struct input_dev *dev, u16 magnitude) { struct hidpp_ff_private_data *data = dev->ff->private; - u8 params[18]; + u8 params[HIDPP_AUTOCENTER_PARAMS_LENGTH]; dbg_hid("Setting autocenter to %d.\n", magnitude); @@ -2081,7 +2082,8 @@ static void hidpp_ff_destroy(struct ff_device *ff) kfree(data->effect_ids); } -static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) +static int hidpp_ff_init(struct hidpp_device *hidpp, + struct hidpp_ff_private_data *data) { struct hid_device *hid = hidpp->hid_dev; struct hid_input *hidinput; @@ -2089,9 +2091,7 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor); const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice); struct ff_device *ff; - struct hidpp_report response; - struct hidpp_ff_private_data *data; - int error, j, num_slots; + int error, j, num_slots = data->num_effects; u8 version; if (list_empty(&hid->inputs)) { @@ -2116,27 +2116,17 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) for (j = 0; hidpp_ff_effects_v2[j] >= 0; j++) set_bit(hidpp_ff_effects_v2[j], dev->ffbit); - /* Read number of slots available in device */ - error = hidpp_send_fap_command_sync(hidpp, feature_index, - HIDPP_FF_GET_INFO, NULL, 0, &response); - if (error) { - if (error < 0) - return error; - hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", - __func__, error); - return -EPROTO; - } - - num_slots = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS; - error = input_ff_create(dev, num_slots); if (error) { hid_err(dev, "Failed to create FF device!\n"); return error; } - - data = kzalloc(sizeof(*data), GFP_KERNEL); + /* + * Create a copy of passed data, so we can transfer memory + * ownership to FF core + */ + data = kmemdup(data, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; data->effect_ids = kcalloc(num_slots, sizeof(int), GFP_KERNEL); @@ -2152,10 +2142,7 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) } data->hidpp = hidpp; - data->feature_index = feature_index; data->version = version; - data->slot_autocenter = 0; - data->num_effects = num_slots; for (j = 0; j < num_slots; j++) data->effect_ids[j] = -1; @@ -2169,37 +2156,14 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) ff->set_autocenter = hidpp_ff_set_autocenter; ff->destroy = hidpp_ff_destroy; - - /* reset all forces */ - error = hidpp_send_fap_command_sync(hidpp, feature_index, - HIDPP_FF_RESET_ALL, NULL, 0, &response); - - /* Read current Range */ - error = hidpp_send_fap_command_sync(hidpp, feature_index, - HIDPP_FF_GET_APERTURE, NULL, 0, &response); - if (error) - hid_warn(hidpp->hid_dev, "Failed to read range from device!\n"); - data->range = error ? 900 : get_unaligned_be16(&response.fap.params[0]); - /* Create sysfs interface */ error = device_create_file(&(hidpp->hid_dev->dev), &dev_attr_range); if (error) hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d!\n", error); - /* Read the current gain values */ - error = hidpp_send_fap_command_sync(hidpp, feature_index, - HIDPP_FF_GET_GLOBAL_GAINS, NULL, 0, &response); - if (error) - hid_warn(hidpp->hid_dev, "Failed to read gain values from device!\n"); - data->gain = error ? 0xffff : get_unaligned_be16(&response.fap.params[0]); - /* ignore boost value at response.fap.params[2] */ - /* init the hardware command queue */ atomic_set(&data->workqueue_size, 0); - /* initialize with zero autocenter to get wheel in usable state */ - hidpp_ff_set_autocenter(dev, 0); - hid_info(hid, "Force feedback support loaded (firmware release %d).\n", version); @@ -2732,24 +2696,93 @@ static int k400_connect(struct hid_device *hdev, bool connected) #define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123 -static int g920_get_config(struct hidpp_device *hidpp) +static int g920_ff_set_autocenter(struct hidpp_device *hidpp, + struct hidpp_ff_private_data *data) { + struct hidpp_report response; + u8 params[HIDPP_AUTOCENTER_PARAMS_LENGTH] = { + [1] = HIDPP_FF_EFFECT_SPRING | HIDPP_FF_EFFECT_AUTOSTART, + }; + int ret; + + /* initialize with zero autocenter to get wheel in usable state */ + + dbg_hid("Setting autocenter to 0.\n"); + ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, + HIDPP_FF_DOWNLOAD_EFFECT, + params, ARRAY_SIZE(params), + &response); + if (ret) + hid_warn(hidpp->hid_dev, "Failed to autocenter device!\n"); + else + data->slot_autocenter = response.fap.params[0]; + + return ret; +} + +static int g920_get_config(struct hidpp_device *hidpp, + struct hidpp_ff_private_data *data) +{ + struct hidpp_report response; u8 feature_type; - u8 feature_index; int ret; + memset(data, 0, sizeof(*data)); + /* Find feature and store for later use */ ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK, - &feature_index, &feature_type); + &data->feature_index, &feature_type); if (ret) return ret; - ret = hidpp_ff_init(hidpp, feature_index); + /* Read number of slots available in device */ + ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, + HIDPP_FF_GET_INFO, + NULL, 0, + &response); + if (ret) { + if (ret < 0) + return ret; + hid_err(hidpp->hid_dev, + "%s: received protocol error 0x%02x\n", __func__, ret); + return -EPROTO; + } + + data->num_effects = response.fap.params[0] - HIDPP_FF_RESERVED_SLOTS; + + /* reset all forces */ + ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, + HIDPP_FF_RESET_ALL, + NULL, 0, + &response); if (ret) - hid_warn(hidpp->hid_dev, "Unable to initialize force feedback support, errno %d\n", - ret); + hid_warn(hidpp->hid_dev, "Failed to reset all forces!\n"); - return 0; + ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, + HIDPP_FF_GET_APERTURE, + NULL, 0, + &response); + if (ret) { + hid_warn(hidpp->hid_dev, + "Failed to read range from device!\n"); + } + data->range = ret ? + 900 : get_unaligned_be16(&response.fap.params[0]); + + /* Read the current gain values */ + ret = hidpp_send_fap_command_sync(hidpp, data->feature_index, + HIDPP_FF_GET_GLOBAL_GAINS, + NULL, 0, + &response); + if (ret) + hid_warn(hidpp->hid_dev, + "Failed to read gain values from device!\n"); + data->gain = ret ? + 0xffff : get_unaligned_be16(&response.fap.params[0]); + + /* ignore boost value at response.fap.params[2] */ + + return g920_ff_set_autocenter(hidpp, data); } /* -------------------------------------------------------------------------- */ @@ -3512,6 +3545,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) int ret; bool connected; unsigned int connect_mask = HID_CONNECT_DEFAULT; + struct hidpp_ff_private_data data; /* report_fixup needs drvdata to be set before we call hid_parse */ hidpp = devm_kzalloc(&hdev->dev, sizeof(*hidpp), GFP_KERNEL); @@ -3621,7 +3655,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) if (ret) goto hid_hw_init_fail; } else if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) { - ret = g920_get_config(hidpp); + ret = g920_get_config(hidpp, &data); if (ret) goto hid_hw_init_fail; } @@ -3643,6 +3677,14 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) goto hid_hw_start_fail; } + if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { + ret = hidpp_ff_init(hidpp, &data); + if (ret) + hid_warn(hidpp->hid_dev, + "Unable to initialize force feedback support, errno %d\n", + ret); + } + return ret; hid_hw_init_fail: -- GitLab From 905d754c53a522aacf806ea1d3e7c929148c1910 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 17 Oct 2019 21:45:16 -0700 Subject: [PATCH 441/993] HID: logitech-hidpp: rework device validation G920 device only advertises REPORT_ID_HIDPP_LONG and REPORT_ID_HIDPP_VERY_LONG in its HID report descriptor, so querying for REPORT_ID_HIDPP_SHORT with optional=false will always fail and prevent G920 to be recognized as a valid HID++ device. To fix this and improve some other aspects, modify hidpp_validate_device() as follows: - Inline the code of hidpp_validate_report() to simplify distingushing between non-present and invalid report descriptors - Drop the check for id >= HID_MAX_IDS || id < 0 since all of our IDs are static and known to satisfy that at compile time - Change the algorithms to check all possible report types (including very long report) and deem the device as a valid HID++ device if it supports at least one - Treat invalid report length as a hard stop for the validation algorithm, meaning that if any of the supported reports has invalid length we assume the worst and treat the device as a generic HID device. - Fold initialization of hidpp->very_long_report_length into hidpp_validate_device() since it already fetches very long report length and validates its value Fixes: fe3ee1ec007b ("HID: logitech-hidpp: allow non HID++ devices to be handled by this module") Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=204191 Reported-by: Sam Bazely Signed-off-by: Andrey Smirnov Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: Henrik Rydberg Cc: Pierre-Loup A. Griffais Cc: Austin Palmer Cc: linux-input@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org # 5.2+ Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-logitech-hidpp.c | 54 ++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 85911586b3b6..6e669eb7dc69 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -3498,34 +3498,45 @@ static int hidpp_get_report_length(struct hid_device *hdev, int id) return report->field[0]->report_count + 1; } -static bool hidpp_validate_report(struct hid_device *hdev, int id, - int expected_length, bool optional) +static bool hidpp_validate_device(struct hid_device *hdev) { - int report_length; + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + int id, report_length, supported_reports = 0; + + id = REPORT_ID_HIDPP_SHORT; + report_length = hidpp_get_report_length(hdev, id); + if (report_length) { + if (report_length < HIDPP_REPORT_SHORT_LENGTH) + goto bad_device; - if (id >= HID_MAX_IDS || id < 0) { - hid_err(hdev, "invalid HID report id %u\n", id); - return false; + supported_reports++; } + id = REPORT_ID_HIDPP_LONG; report_length = hidpp_get_report_length(hdev, id); - if (!report_length) - return optional; + if (report_length) { + if (report_length < HIDPP_REPORT_LONG_LENGTH) + goto bad_device; - if (report_length < expected_length) { - hid_warn(hdev, "not enough values in hidpp report %d\n", id); - return false; + supported_reports++; } - return true; -} + id = REPORT_ID_HIDPP_VERY_LONG; + report_length = hidpp_get_report_length(hdev, id); + if (report_length) { + if (report_length < HIDPP_REPORT_LONG_LENGTH || + report_length > HIDPP_REPORT_VERY_LONG_MAX_LENGTH) + goto bad_device; -static bool hidpp_validate_device(struct hid_device *hdev) -{ - return hidpp_validate_report(hdev, REPORT_ID_HIDPP_SHORT, - HIDPP_REPORT_SHORT_LENGTH, false) && - hidpp_validate_report(hdev, REPORT_ID_HIDPP_LONG, - HIDPP_REPORT_LONG_LENGTH, true); + supported_reports++; + hidpp->very_long_report_length = report_length; + } + + return supported_reports; + +bad_device: + hid_warn(hdev, "not enough values in hidpp report %d\n", id); + return false; } static bool hidpp_application_equals(struct hid_device *hdev, @@ -3572,11 +3583,6 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) return hid_hw_start(hdev, HID_CONNECT_DEFAULT); } - hidpp->very_long_report_length = - hidpp_get_report_length(hdev, REPORT_ID_HIDPP_VERY_LONG); - if (hidpp->very_long_report_length > HIDPP_REPORT_VERY_LONG_MAX_LENGTH) - hidpp->very_long_report_length = HIDPP_REPORT_VERY_LONG_MAX_LENGTH; - if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE) hidpp->quirks |= HIDPP_QUIRK_UNIFYING; -- GitLab From 08c453f6d073f069cf8e30e03cd3c16262c9b953 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 17 Oct 2019 21:45:17 -0700 Subject: [PATCH 442/993] HID: logitech-hidpp: do all FF cleanup in hidpp_ff_destroy() All of the FF-related resources belong to corresponding FF device, so they should be freed as a part of hidpp_ff_destroy() to avoid potential race condidions. Fixes: ff21a635dd1a ("HID: logitech-hidpp: Force feedback support for the Logitech G920") Suggested-by: Benjamin Tissoires Signed-off-by: Andrey Smirnov Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: Henrik Rydberg Cc: Pierre-Loup A. Griffais Cc: Austin Palmer Cc: linux-input@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org # 5.2+ Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-logitech-hidpp.c | 33 +++++--------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 6e669eb7dc69..8e91e2f06cb4 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -2078,7 +2078,12 @@ static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, hidpp static void hidpp_ff_destroy(struct ff_device *ff) { struct hidpp_ff_private_data *data = ff->private; + struct hid_device *hid = data->hidpp->hid_dev; + hid_info(hid, "Unloading HID++ force feedback.\n"); + + device_remove_file(&hid->dev, &dev_attr_range); + destroy_workqueue(data->wq); kfree(data->effect_ids); } @@ -2170,31 +2175,6 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, return 0; } -static int hidpp_ff_deinit(struct hid_device *hid) -{ - struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); - struct input_dev *dev = hidinput->input; - struct hidpp_ff_private_data *data; - - if (!dev) { - hid_err(hid, "Struct input_dev not found!\n"); - return -EINVAL; - } - - hid_info(hid, "Unloading HID++ force feedback.\n"); - data = dev->ff->private; - if (!data) { - hid_err(hid, "Private data not found!\n"); - return -EINVAL; - } - - destroy_workqueue(data->wq); - device_remove_file(&hid->dev, &dev_attr_range); - - return 0; -} - - /* ************************************************************************** */ /* */ /* Device Support */ @@ -3713,9 +3693,6 @@ static void hidpp_remove(struct hid_device *hdev) sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group); - if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) - hidpp_ff_deinit(hdev); - hid_hw_stop(hdev); cancel_work_sync(&hidpp->work); mutex_destroy(&hidpp->send_mutex); -- GitLab From a2b11184389489dcca4fa899b290fc2751ea55ac Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Fri, 18 Oct 2019 10:31:40 +0100 Subject: [PATCH 443/993] modpost: delegate updating namespaces to separate function Let the function 'sym_update_namespace' take care of updating the namespace for a symbol. While this currently only replaces one single location where namespaces are updated, in a following patch, this function will get more call sites. The function signature is intentionally close to sym_update_crc and taking the name by char* seems like unnecessary work as the symbol has to be looked up again. In a later patch of this series, this concern will be addressed. This function ensures that symbol::namespace is either NULL or has a valid non-empty value. Previously, the empty string was considered 'no namespace' as well and this lead to confusion. Acked-by: Will Deacon Reviewed-by: Greg Kroah-Hartman Reviewed-by: Masahiro Yamada Signed-off-by: Matthias Maennich Signed-off-by: Jessica Yu --- scripts/mod/modpost.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 936d3ad23c83..4041a265d2b6 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -362,6 +362,25 @@ static char *sym_extract_namespace(const char **symname) return namespace; } +static void sym_update_namespace(const char *symname, const char *namespace) +{ + struct symbol *s = find_symbol(symname); + + /* + * That symbol should have been created earlier and thus this is + * actually an assertion. + */ + if (!s) { + merror("Could not update namespace(%s) for symbol %s\n", + namespace, symname); + return; + } + + free(s->namespace); + s->namespace = + namespace && namespace[0] ? NOFAIL(strdup(namespace)) : NULL; +} + /** * Add an exported symbol - it may have already been added without a * CRC, in this case just update the CRC @@ -383,8 +402,7 @@ static struct symbol *sym_add_exported(const char *name, const char *namespace, s->module = mod; } } - free(s->namespace); - s->namespace = namespace ? strdup(namespace) : NULL; + sym_update_namespace(name, namespace); s->preloaded = 0; s->vmlinux = is_vmlinux(mod->name); s->kernel = 0; @@ -2196,7 +2214,7 @@ static int check_exports(struct module *mod) else basename = mod->name; - if (exp->namespace && exp->namespace[0]) { + if (exp->namespace) { add_namespace(&mod->required_namespaces, exp->namespace); -- GitLab From 9ae5bd1847566e079ffb7607394389ac54815f2b Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Fri, 18 Oct 2019 10:31:41 +0100 Subject: [PATCH 444/993] modpost: make updating the symbol namespace explicit Setting the symbol namespace of a symbol within sym_add_exported feels displaced and lead to issues in the current implementation of symbol namespaces. This patch makes updating the namespace an explicit call to decouple it from adding a symbol to the export list. Acked-by: Will Deacon Reviewed-by: Greg Kroah-Hartman Reviewed-by: Masahiro Yamada Signed-off-by: Matthias Maennich Signed-off-by: Jessica Yu --- scripts/mod/modpost.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 4041a265d2b6..c43f1b1532f7 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -385,8 +385,8 @@ static void sym_update_namespace(const char *symname, const char *namespace) * Add an exported symbol - it may have already been added without a * CRC, in this case just update the CRC **/ -static struct symbol *sym_add_exported(const char *name, const char *namespace, - struct module *mod, enum export export) +static struct symbol *sym_add_exported(const char *name, struct module *mod, + enum export export) { struct symbol *s = find_symbol(name); @@ -402,7 +402,6 @@ static struct symbol *sym_add_exported(const char *name, const char *namespace, s->module = mod; } } - sym_update_namespace(name, namespace); s->preloaded = 0; s->vmlinux = is_vmlinux(mod->name); s->kernel = 0; @@ -764,7 +763,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info, if (strstarts(symname, "__ksymtab_")) { name = symname + strlen("__ksymtab_"); namespace = sym_extract_namespace(&name); - sym_add_exported(name, namespace, mod, export); + sym_add_exported(name, mod, export); + sym_update_namespace(name, namespace); free(namespace); } if (strcmp(symname, "init_module") == 0) @@ -2472,12 +2472,12 @@ static void read_dump(const char *fname, unsigned int kernel) mod = new_module(modname); mod->skip = 1; } - s = sym_add_exported(symname, namespace, mod, - export_no(export)); + s = sym_add_exported(symname, mod, export_no(export)); s->kernel = kernel; s->preloaded = 1; s->is_static = 0; sym_update_crc(symname, mod, crc, export_no(export)); + sym_update_namespace(symname, namespace); } release_file(file, size); return; -- GitLab From 69923208431e097ce3830647aee98e5bd3e889c8 Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Fri, 18 Oct 2019 10:31:42 +0100 Subject: [PATCH 445/993] symbol namespaces: revert to previous __ksymtab name scheme The introduction of Symbol Namespaces changed the naming schema of the __ksymtab entries from __kysmtab__symbol to __ksymtab_NAMESPACE.symbol. That caused some breakages in tools that depend on the name layout in either the binaries(vmlinux,*.ko) or in System.map. E.g. kmod's depmod would not be able to read System.map without a patch to support symbol namespaces. A warning reported by depmod for namespaced symbols would look like depmod: WARNING: [...]/uas.ko needs unknown symbol usb_stor_adjust_quirks In order to address this issue, revert to the original naming scheme and rather read the __kstrtabns_ entries and their corresponding values from __ksymtab_strings to update the namespace values for symbols. After having read all symbols and handled them in handle_modversions(), the symbols are created. In a second pass, read the __kstrtabns_ entries and update the namespaces accordingly. Fixes: 8651ec01daed ("module: add support for symbol namespaces.") Reported-by: Stefan Wahren Suggested-by: Masahiro Yamada Acked-by: Will Deacon Reviewed-by: Greg Kroah-Hartman Reviewed-by: Masahiro Yamada Signed-off-by: Matthias Maennich Signed-off-by: Jessica Yu --- include/linux/export.h | 14 +++++--------- scripts/mod/modpost.c | 33 ++++++++++++++++++--------------- scripts/mod/modpost.h | 1 + 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/include/linux/export.h b/include/linux/export.h index 621158ecd2e2..941d075f03d6 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -18,8 +18,6 @@ extern struct module __this_module; #define THIS_MODULE ((struct module *)0) #endif -#define NS_SEPARATOR "." - #ifdef CONFIG_MODVERSIONS /* Mark the CRC weak since genksyms apparently decides not to * generate a checksums for some symbols */ @@ -48,11 +46,11 @@ extern struct module __this_module; * absolute relocations that require runtime processing on relocatable * kernels. */ -#define __KSYMTAB_ENTRY_NS(sym, sec, ns) \ +#define __KSYMTAB_ENTRY_NS(sym, sec) \ __ADDRESSABLE(sym) \ asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ " .balign 4 \n" \ - "__ksymtab_" #ns NS_SEPARATOR #sym ": \n" \ + "__ksymtab_" #sym ": \n" \ " .long " #sym "- . \n" \ " .long __kstrtab_" #sym "- . \n" \ " .long __kstrtabns_" #sym "- . \n" \ @@ -74,16 +72,14 @@ struct kernel_symbol { int namespace_offset; }; #else -#define __KSYMTAB_ENTRY_NS(sym, sec, ns) \ - static const struct kernel_symbol __ksymtab_##sym##__##ns \ - asm("__ksymtab_" #ns NS_SEPARATOR #sym) \ +#define __KSYMTAB_ENTRY_NS(sym, sec) \ + static const struct kernel_symbol __ksymtab_##sym \ __attribute__((section("___ksymtab" sec "+" #sym), used)) \ __aligned(sizeof(void *)) \ = { (unsigned long)&sym, __kstrtab_##sym, __kstrtabns_##sym } #define __KSYMTAB_ENTRY(sym, sec) \ static const struct kernel_symbol __ksymtab_##sym \ - asm("__ksymtab_" #sym) \ __attribute__((section("___ksymtab" sec "+" #sym), used)) \ __aligned(sizeof(void *)) \ = { (unsigned long)&sym, __kstrtab_##sym, NULL } @@ -115,7 +111,7 @@ struct kernel_symbol { static const char __kstrtabns_##sym[] \ __attribute__((section("__ksymtab_strings"), used, aligned(1))) \ = #ns; \ - __KSYMTAB_ENTRY_NS(sym, sec, ns) + __KSYMTAB_ENTRY_NS(sym, sec) #define ___EXPORT_SYMBOL(sym, sec) \ ___export_symbol_common(sym, sec); \ diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c43f1b1532f7..d2a30a7b3f07 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -348,18 +348,11 @@ static enum export export_from_sec(struct elf_info *elf, unsigned int sec) return export_unknown; } -static char *sym_extract_namespace(const char **symname) +static const char *namespace_from_kstrtabns(struct elf_info *info, + Elf_Sym *kstrtabns) { - char *namespace = NULL; - char *ns_separator; - - ns_separator = strchr(*symname, '.'); - if (ns_separator) { - namespace = NOFAIL(strndup(*symname, ns_separator - *symname)); - *symname = ns_separator + 1; - } - - return namespace; + char *value = info->ksymtab_strings + kstrtabns->st_value; + return value[0] ? value : NULL; } static void sym_update_namespace(const char *symname, const char *namespace) @@ -600,6 +593,10 @@ static int parse_elf(struct elf_info *info, const char *filename) info->export_unused_gpl_sec = i; else if (strcmp(secname, "__ksymtab_gpl_future") == 0) info->export_gpl_future_sec = i; + else if (strcmp(secname, "__ksymtab_strings") == 0) + info->ksymtab_strings = (void *)hdr + + sechdrs[i].sh_offset - + sechdrs[i].sh_addr; if (sechdrs[i].sh_type == SHT_SYMTAB) { unsigned int sh_link_idx; @@ -689,7 +686,6 @@ static void handle_modversions(struct module *mod, struct elf_info *info, enum export export; bool is_crc = false; const char *name; - char *namespace; if ((!is_vmlinux(mod->name) || mod->is_dot_o) && strstarts(symname, "__ksymtab")) @@ -762,10 +758,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, /* All exported symbols */ if (strstarts(symname, "__ksymtab_")) { name = symname + strlen("__ksymtab_"); - namespace = sym_extract_namespace(&name); sym_add_exported(name, mod, export); - sym_update_namespace(name, namespace); - free(namespace); } if (strcmp(symname, "init_module") == 0) mod->has_init = 1; @@ -2061,6 +2054,16 @@ static void read_symbols(const char *modname) handle_moddevtable(mod, &info, sym, symname); } + /* Apply symbol namespaces from __kstrtabns_ entries. */ + for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { + symname = remove_dot(info.strtab + sym->st_name); + + if (strstarts(symname, "__kstrtabns_")) + sym_update_namespace(symname + strlen("__kstrtabns_"), + namespace_from_kstrtabns(&info, + sym)); + } + // check for static EXPORT_SYMBOL_* functions && global vars for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { unsigned char bind = ELF_ST_BIND(sym->st_info); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 92a926d375d2..ad271bc6c313 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -143,6 +143,7 @@ struct elf_info { Elf_Section export_gpl_sec; Elf_Section export_unused_gpl_sec; Elf_Section export_gpl_future_sec; + char *ksymtab_strings; char *strtab; char *modinfo; unsigned int modinfo_len; -- GitLab From 09f3dbe474735df13dd8a66d3d1231048d9b373f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 7 Oct 2019 20:56:26 +0200 Subject: [PATCH 446/993] HID: i2c-hid: add Trekstor Primebook C11B to descriptor override The Primebook C11B uses the SIPODEV SP1064 touchpad. There are 2 versions of this 2-in-1 and the touchpad in the older version does not supply descriptors, so it has to be added to the override list. Cc: stable@vger.kernel.org Signed-off-by: Hans de Goede Signed-off-by: Benjamin Tissoires --- drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c index 75078c83be1a..d31ea82b84c1 100644 --- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c @@ -322,6 +322,25 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { }, .driver_data = (void *)&sipodev_desc }, + { + /* + * There are at least 2 Primebook C11B versions, the older + * version has a product-name of "Primebook C11B", and a + * bios version / release / firmware revision of: + * V2.1.2 / 05/03/2018 / 18.2 + * The new version has "PRIMEBOOK C11B" as product-name and a + * bios version / release / firmware revision of: + * CFALKSW05_BIOS_V1.1.2 / 11/19/2018 / 19.2 + * Only the older version needs this quirk, note the newer + * version will not match as it has a different product-name. + */ + .ident = "Trekstor Primebook C11B", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C11B"), + }, + .driver_data = (void *)&sipodev_desc + }, { .ident = "Direkt-Tek DTLAPY116-2", .matches = { -- GitLab From a4f40484e7f1dff56bb9f286cc59ffa36e0259eb Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Fri, 18 Oct 2019 10:53:14 +0800 Subject: [PATCH 447/993] nvme-pci: Set the prp2 correctly when using more than 4k page In the current code, the nvme is using a fixed 4k PRP entry size, but if the kernel use a page size which is more than 4k, we should consider the situation that the bv_offset may be larger than the dev->ctrl.page_size. Otherwise we may miss setting the prp2 and then cause the command can't be executed correctly. Fixes: dff824b2aadb ("nvme-pci: optimize mapping of small single segment requests") Cc: stable@vger.kernel.org Reviewed-by: Christoph Hellwig Signed-off-by: Kevin Hao Signed-off-by: Keith Busch --- drivers/nvme/host/pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 4b181969c432..869f462e6b6e 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -773,7 +773,8 @@ static blk_status_t nvme_setup_prp_simple(struct nvme_dev *dev, struct bio_vec *bv) { struct nvme_iod *iod = blk_mq_rq_to_pdu(req); - unsigned int first_prp_len = dev->ctrl.page_size - bv->bv_offset; + unsigned int offset = bv->bv_offset & (dev->ctrl.page_size - 1); + unsigned int first_prp_len = dev->ctrl.page_size - offset; iod->first_dma = dma_map_bvec(dev->dev, bv, rq_dma_dir(req), 0); if (dma_mapping_error(dev->dev, iod->first_dma)) -- GitLab From 46ac18c347b00be29b265c28209b0f3c38a1f142 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Fri, 18 Oct 2019 11:34:22 +0200 Subject: [PATCH 448/993] iommu/amd: Check PM_LEVEL_SIZE() condition in locked section The increase_address_space() function has to check the PM_LEVEL_SIZE() condition again under the domain->lock to avoid a false trigger of the WARN_ON_ONCE() and to avoid that the address space is increase more often than necessary. Reported-by: Qian Cai Fixes: 754265bcab78 ("iommu/amd: Fix race in increase_address_space()") Reviewed-by: Jerry Snitselaar Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index bcd89ea50a8b..dd555078258c 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -1464,6 +1464,7 @@ static void free_pagetable(struct protection_domain *domain) * to 64 bits. */ static bool increase_address_space(struct protection_domain *domain, + unsigned long address, gfp_t gfp) { unsigned long flags; @@ -1472,8 +1473,8 @@ static bool increase_address_space(struct protection_domain *domain, spin_lock_irqsave(&domain->lock, flags); - if (WARN_ON_ONCE(domain->mode == PAGE_MODE_6_LEVEL)) - /* address space already 64 bit large */ + if (address <= PM_LEVEL_SIZE(domain->mode) || + WARN_ON_ONCE(domain->mode == PAGE_MODE_6_LEVEL)) goto out; pte = (void *)get_zeroed_page(gfp); @@ -1506,7 +1507,7 @@ static u64 *alloc_pte(struct protection_domain *domain, BUG_ON(!is_power_of_2(page_size)); while (address > PM_LEVEL_SIZE(domain->mode)) - *updated = increase_address_space(domain, gfp) || *updated; + *updated = increase_address_space(domain, address, gfp) || *updated; level = domain->mode - 1; pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; -- GitLab From 9c24eaf81cc44d4bb38081c99eafd72ed85cf7f3 Mon Sep 17 00:00:00 2001 From: Arvind Sankar Date: Tue, 8 Oct 2019 10:33:57 -0400 Subject: [PATCH 449/993] iommu/vt-d: Return the correct dma mask when we are bypassing the IOMMU We must return a mask covering the full physical RAM when bypassing the IOMMU mapping. Also, in iommu_need_mapping, we need to check using dma_direct_get_required_mask to ensure that the device's dma_mask can cover physical RAM before deciding to bypass IOMMU mapping. Based on an earlier patch from Christoph Hellwig. Fixes: 249baa547901 ("dma-mapping: provide a better default ->get_required_mask") Signed-off-by: Arvind Sankar Reviewed-by: Lu Baolu Acked-by: Joerg Roedel Signed-off-by: Christoph Hellwig --- drivers/iommu/intel-iommu.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 3f974919d3bd..79e35b3180ac 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3471,7 +3471,7 @@ static bool iommu_need_mapping(struct device *dev) if (dev->coherent_dma_mask && dev->coherent_dma_mask < dma_mask) dma_mask = dev->coherent_dma_mask; - if (dma_mask >= dma_get_required_mask(dev)) + if (dma_mask >= dma_direct_get_required_mask(dev)) return false; /* @@ -3775,6 +3775,13 @@ static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nele return nelems; } +static u64 intel_get_required_mask(struct device *dev) +{ + if (!iommu_need_mapping(dev)) + return dma_direct_get_required_mask(dev); + return DMA_BIT_MASK(32); +} + static const struct dma_map_ops intel_dma_ops = { .alloc = intel_alloc_coherent, .free = intel_free_coherent, @@ -3787,6 +3794,7 @@ static const struct dma_map_ops intel_dma_ops = { .dma_supported = dma_direct_supported, .mmap = dma_common_mmap, .get_sgtable = dma_common_get_sgtable, + .get_required_mask = intel_get_required_mask, }; static void -- GitLab From 19feeee5c5af114f3cb8ad2772680b7a1d16f043 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Mon, 26 Aug 2019 19:14:51 -0500 Subject: [PATCH 450/993] ARM: OMAP2+: Plug in device_enable/idle ops for IOMMUs The OMAP IOMMU driver requires the device_enable/idle platform data ops on all the IOMMU devices to be able to enable and disable the clocks after commit db8918f61d51 ("iommu/omap: streamline enable/disable through runtime pm callbacks"). Plug in these pdata ops for all the existing IOMMUs through pdata quirks to maintain functionality. Signed-off-by: Suman Anna Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/pdata-quirks.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index d942a3357090..ac5da6ad2017 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -89,6 +89,8 @@ static struct iommu_platform_data omap3_iommu_pdata = { .reset_name = "mmu", .assert_reset = omap_device_assert_hardreset, .deassert_reset = omap_device_deassert_hardreset, + .device_enable = omap_device_enable, + .device_idle = omap_device_idle, }; static int omap3_sbc_t3730_twl_callback(struct device *dev, @@ -424,6 +426,8 @@ static struct iommu_platform_data omap4_iommu_pdata = { .reset_name = "mmu_cache", .assert_reset = omap_device_assert_hardreset, .deassert_reset = omap_device_deassert_hardreset, + .device_enable = omap_device_enable, + .device_idle = omap_device_idle, }; #endif -- GitLab From 0af3e1a491dde06dfcb0b063d5b543dfebded0f9 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Mon, 26 Aug 2019 19:14:52 -0500 Subject: [PATCH 451/993] ARM: OMAP2+: Add pdata for OMAP3 ISP IOMMU The OMAP3 ISP IOMMU does not have any reset lines, so it didn't need any pdata previously. The OMAP IOMMU driver now requires the platform data ops for device_enable/idle on all the IOMMU devices after commit db8918f61d51 ("iommu/omap: streamline enable/disable through runtime pm callbacks") to enable/disable the clocks properly and maintain the reference count and the omap_hwmod state machine. So, add these callbacks through iommu pdata quirks for the OMAP3 ISP IOMMU. Signed-off-by: Suman Anna Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/pdata-quirks.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index ac5da6ad2017..2efd18e8824c 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -93,6 +93,11 @@ static struct iommu_platform_data omap3_iommu_pdata = { .device_idle = omap_device_idle, }; +static struct iommu_platform_data omap3_iommu_isp_pdata = { + .device_enable = omap_device_enable, + .device_idle = omap_device_idle, +}; + static int omap3_sbc_t3730_twl_callback(struct device *dev, unsigned gpio, unsigned ngpio) @@ -621,6 +626,8 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = { #ifdef CONFIG_ARCH_OMAP3 OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu", &omap3_iommu_pdata), + OF_DEV_AUXDATA("ti,omap2-iommu", 0x480bd400, "480bd400.mmu", + &omap3_iommu_isp_pdata), OF_DEV_AUXDATA("ti,omap3-smartreflex-core", 0x480cb000, "480cb000.smartreflex", &omap_sr_pdata[OMAP_SR_CORE]), OF_DEV_AUXDATA("ti,omap3-smartreflex-mpu-iva", 0x480c9000, -- GitLab From c7d8669f46ba97f6a8e14d6e9b8d6c39e2c07727 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 17 Oct 2019 11:21:44 -0700 Subject: [PATCH 452/993] bus: ti-sysc: Fix watchdog quirk handling I noticed that when probed with ti-sysc, watchdog can trigger on am3, am4 and dra7 causing a device reset. Turns out I made several mistakes implementing the watchdog quirk handling: 1. We must do both writes to spr register 2. We must also call the reset quirk on disable 3. On am3 and am4 we need to also set swsup quirk flag I probably only tested this earlier with watchdog service running when the watchdog never gets disabled. Fixes: 4e23be473e30 ("bus: ti-sysc: Add support for module specific reset quirks") Signed-off-by: Tony Lindgren --- drivers/bus/ti-sysc.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index ad50efb470aa..2b6670daf7fc 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -74,6 +74,7 @@ static const char * const clock_names[SYSC_MAX_CLOCKS] = { * @clk_disable_quirk: module specific clock disable quirk * @reset_done_quirk: module specific reset done quirk * @module_enable_quirk: module specific enable quirk + * @module_disable_quirk: module specific disable quirk */ struct sysc { struct device *dev; @@ -100,6 +101,7 @@ struct sysc { void (*clk_disable_quirk)(struct sysc *sysc); void (*reset_done_quirk)(struct sysc *sysc); void (*module_enable_quirk)(struct sysc *sysc); + void (*module_disable_quirk)(struct sysc *sysc); }; static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np, @@ -959,6 +961,9 @@ static int sysc_disable_module(struct device *dev) if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV) return 0; + if (ddata->module_disable_quirk) + ddata->module_disable_quirk(ddata); + regbits = ddata->cap->regbits; reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); @@ -1248,6 +1253,9 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { SYSC_MODULE_QUIRK_SGX), SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, SYSC_MODULE_QUIRK_WDT), + /* Watchdog on am3 and am4 */ + SYSC_QUIRK("wdt", 0x44e35000, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, + SYSC_MODULE_QUIRK_WDT | SYSC_QUIRK_SWSUP_SIDLE), #ifdef DEBUG SYSC_QUIRK("adc", 0, 0, 0x10, -1, 0x47300001, 0xffffffff, 0), @@ -1440,14 +1448,14 @@ static void sysc_reset_done_quirk_wdt(struct sysc *ddata) !(val & 0x10), 100, MAX_MODULE_SOFTRESET_WAIT); if (error) - dev_warn(ddata->dev, "wdt disable spr failed\n"); + dev_warn(ddata->dev, "wdt disable step1 failed\n"); - sysc_write(ddata, wps, 0x5555); + sysc_write(ddata, spr, 0x5555); error = readl_poll_timeout(ddata->module_va + wps, val, !(val & 0x10), 100, MAX_MODULE_SOFTRESET_WAIT); if (error) - dev_warn(ddata->dev, "wdt disable wps failed\n"); + dev_warn(ddata->dev, "wdt disable step2 failed\n"); } static void sysc_init_module_quirks(struct sysc *ddata) @@ -1471,8 +1479,10 @@ static void sysc_init_module_quirks(struct sysc *ddata) if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_SGX) ddata->module_enable_quirk = sysc_module_enable_quirk_sgx; - if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_WDT) + if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_WDT) { ddata->reset_done_quirk = sysc_reset_done_quirk_wdt; + ddata->module_disable_quirk = sysc_reset_done_quirk_wdt; + } } static int sysc_clockdomain_init(struct sysc *ddata) -- GitLab From 7de48402faa32298c3551ea32c76ccb4f9d3025d Mon Sep 17 00:00:00 2001 From: Doug Berger Date: Wed, 16 Oct 2019 16:06:29 -0700 Subject: [PATCH 453/993] net: bcmgenet: don't set phydev->link from MAC When commit 28b2e0d2cd13 ("net: phy: remove parameter new_link from phy_mac_interrupt()") removed the new_link parameter it set the phydev->link state from the MAC before invoking phy_mac_interrupt(). However, once commit 88d6272acaaa ("net: phy: avoid unneeded MDIO reads in genphy_read_status") was added this initialization prevents the proper determination of the connection parameters by the function genphy_read_status(). This commit removes that initialization to restore the proper functionality. Fixes: 88d6272acaaa ("net: phy: avoid unneeded MDIO reads in genphy_read_status") Signed-off-by: Doug Berger Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 12cb77ef1081..10d68017ff6c 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2612,10 +2612,8 @@ static void bcmgenet_irq_task(struct work_struct *work) spin_unlock_irq(&priv->lock); /* Link UP/DOWN event */ - if (status & UMAC_IRQ_LINK_EVENT) { - priv->dev->phydev->link = !!(status & UMAC_IRQ_LINK_UP); + if (status & UMAC_IRQ_LINK_EVENT) phy_mac_interrupt(priv->dev->phydev); - } } /* bcmgenet_isr1: handle Rx and Tx priority queues */ -- GitLab From fe586b823372a9f43f90e2c6aa0573992ce7ccb7 Mon Sep 17 00:00:00 2001 From: Doug Berger Date: Wed, 16 Oct 2019 16:06:30 -0700 Subject: [PATCH 454/993] net: phy: bcm7xxx: define soft_reset for 40nm EPHY The internal 40nm EPHYs use a "Workaround for putting the PHY in IDDQ mode." These PHYs require a soft reset to restore functionality after they are powered back up. This commit defines the soft_reset function to use genphy_soft_reset during phy_init_hw to accommodate this. Fixes: 6e2d85ec0559 ("net: phy: Stop with excessive soft reset") Signed-off-by: Doug Berger Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/bcm7xxx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c index 8fc33867e524..af8eabe7a6d4 100644 --- a/drivers/net/phy/bcm7xxx.c +++ b/drivers/net/phy/bcm7xxx.c @@ -572,6 +572,7 @@ static int bcm7xxx_28nm_probe(struct phy_device *phydev) .name = _name, \ /* PHY_BASIC_FEATURES */ \ .flags = PHY_IS_INTERNAL, \ + .soft_reset = genphy_soft_reset, \ .config_init = bcm7xxx_config_init, \ .suspend = bcm7xxx_suspend, \ .resume = bcm7xxx_config_init, \ -- GitLab From 1f515486275a08a17a2c806b844cca18f7de5b34 Mon Sep 17 00:00:00 2001 From: Doug Berger Date: Wed, 16 Oct 2019 16:06:31 -0700 Subject: [PATCH 455/993] net: bcmgenet: soft reset 40nm EPHYs before MAC init It turns out that the "Workaround for putting the PHY in IDDQ mode" used by the internal EPHYs on 40nm Set-Top Box chips when powering down puts the interface to the GENET MAC in a state that can cause subsequent MAC resets to be incomplete. Rather than restore the forced soft reset when powering up internal PHYs, this commit moves the invocation of phy_init_hw earlier in the MAC initialization sequence to just before the MAC reset in the open and resume functions. This allows the interface to be stable and allows the MAC resets to be successful. The bcmgenet_mii_probe() function is split in two to accommodate this. The new function bcmgenet_mii_connect() handles the first half of the functionality before the MAC initialization, and the bcmgenet_mii_config() function is extended to provide the remaining PHY configuration following the MAC initialization. Fixes: 484bfa1507bf ("Revert "net: bcmgenet: Software reset EPHY after power on"") Signed-off-by: Doug Berger Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/genet/bcmgenet.c | 28 +++-- .../net/ethernet/broadcom/genet/bcmgenet.h | 2 +- drivers/net/ethernet/broadcom/genet/bcmmii.c | 112 ++++++++---------- 3 files changed, 69 insertions(+), 73 deletions(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 10d68017ff6c..f0937c650e3c 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2872,6 +2872,12 @@ static int bcmgenet_open(struct net_device *dev) if (priv->internal_phy) bcmgenet_power_up(priv, GENET_POWER_PASSIVE); + ret = bcmgenet_mii_connect(dev); + if (ret) { + netdev_err(dev, "failed to connect to PHY\n"); + goto err_clk_disable; + } + /* take MAC out of reset */ bcmgenet_umac_reset(priv); @@ -2881,6 +2887,12 @@ static int bcmgenet_open(struct net_device *dev) reg = bcmgenet_umac_readl(priv, UMAC_CMD); priv->crc_fwd_en = !!(reg & CMD_CRC_FWD); + ret = bcmgenet_mii_config(dev, true); + if (ret) { + netdev_err(dev, "unsupported PHY\n"); + goto err_disconnect_phy; + } + bcmgenet_set_hw_addr(priv, dev->dev_addr); if (priv->internal_phy) { @@ -2896,7 +2908,7 @@ static int bcmgenet_open(struct net_device *dev) ret = bcmgenet_init_dma(priv); if (ret) { netdev_err(dev, "failed to initialize DMA\n"); - goto err_clk_disable; + goto err_disconnect_phy; } /* Always enable ring 16 - descriptor ring */ @@ -2919,25 +2931,19 @@ static int bcmgenet_open(struct net_device *dev) goto err_irq0; } - ret = bcmgenet_mii_probe(dev); - if (ret) { - netdev_err(dev, "failed to connect to PHY\n"); - goto err_irq1; - } - bcmgenet_netif_start(dev); netif_tx_start_all_queues(dev); return 0; -err_irq1: - free_irq(priv->irq1, priv); err_irq0: free_irq(priv->irq0, priv); err_fini_dma: bcmgenet_dma_teardown(priv); bcmgenet_fini_dma(priv); +err_disconnect_phy: + phy_disconnect(dev->phydev); err_clk_disable: if (priv->internal_phy) bcmgenet_power_down(priv, GENET_POWER_PASSIVE); @@ -3618,6 +3624,8 @@ static int bcmgenet_resume(struct device *d) if (priv->internal_phy) bcmgenet_power_up(priv, GENET_POWER_PASSIVE); + phy_init_hw(dev->phydev); + bcmgenet_umac_reset(priv); init_umac(priv); @@ -3626,8 +3634,6 @@ static int bcmgenet_resume(struct device *d) if (priv->wolopts) clk_disable_unprepare(priv->clk_wol); - phy_init_hw(dev->phydev); - /* Speed settings must be restored */ bcmgenet_mii_config(priv->dev, false); diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index dbc69d8fa05f..7fbf573d8d52 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -720,8 +720,8 @@ GENET_IO_MACRO(rbuf, GENET_RBUF_OFF); /* MDIO routines */ int bcmgenet_mii_init(struct net_device *dev); +int bcmgenet_mii_connect(struct net_device *dev); int bcmgenet_mii_config(struct net_device *dev, bool init); -int bcmgenet_mii_probe(struct net_device *dev); void bcmgenet_mii_exit(struct net_device *dev); void bcmgenet_phy_power_set(struct net_device *dev, bool enable); void bcmgenet_mii_setup(struct net_device *dev); diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index e7c291bf4ed1..17bb8d60a157 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -173,6 +173,46 @@ static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv) bcmgenet_fixed_phy_link_update); } +int bcmgenet_mii_connect(struct net_device *dev) +{ + struct bcmgenet_priv *priv = netdev_priv(dev); + struct device_node *dn = priv->pdev->dev.of_node; + struct phy_device *phydev; + u32 phy_flags = 0; + int ret; + + /* Communicate the integrated PHY revision */ + if (priv->internal_phy) + phy_flags = priv->gphy_rev; + + /* Initialize link state variables that bcmgenet_mii_setup() uses */ + priv->old_link = -1; + priv->old_speed = -1; + priv->old_duplex = -1; + priv->old_pause = -1; + + if (dn) { + phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup, + phy_flags, priv->phy_interface); + if (!phydev) { + pr_err("could not attach to PHY\n"); + return -ENODEV; + } + } else { + phydev = dev->phydev; + phydev->dev_flags = phy_flags; + + ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup, + priv->phy_interface); + if (ret) { + pr_err("could not attach to PHY\n"); + return -ENODEV; + } + } + + return 0; +} + int bcmgenet_mii_config(struct net_device *dev, bool init) { struct bcmgenet_priv *priv = netdev_priv(dev); @@ -266,71 +306,21 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); } - if (init) - dev_info(kdev, "configuring instance for %s\n", phy_name); - - return 0; -} + if (init) { + linkmode_copy(phydev->advertising, phydev->supported); -int bcmgenet_mii_probe(struct net_device *dev) -{ - struct bcmgenet_priv *priv = netdev_priv(dev); - struct device_node *dn = priv->pdev->dev.of_node; - struct phy_device *phydev; - u32 phy_flags = 0; - int ret; - - /* Communicate the integrated PHY revision */ - if (priv->internal_phy) - phy_flags = priv->gphy_rev; - - /* Initialize link state variables that bcmgenet_mii_setup() uses */ - priv->old_link = -1; - priv->old_speed = -1; - priv->old_duplex = -1; - priv->old_pause = -1; - - if (dn) { - phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup, - phy_flags, priv->phy_interface); - if (!phydev) { - pr_err("could not attach to PHY\n"); - return -ENODEV; - } - } else { - phydev = dev->phydev; - phydev->dev_flags = phy_flags; - - ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup, - priv->phy_interface); - if (ret) { - pr_err("could not attach to PHY\n"); - return -ENODEV; - } - } + /* The internal PHY has its link interrupts routed to the + * Ethernet MAC ISRs. On GENETv5 there is a hardware issue + * that prevents the signaling of link UP interrupts when + * the link operates at 10Mbps, so fallback to polling for + * those versions of GENET. + */ + if (priv->internal_phy && !GENET_IS_V5(priv)) + phydev->irq = PHY_IGNORE_INTERRUPT; - /* Configure port multiplexer based on what the probed PHY device since - * reading the 'max-speed' property determines the maximum supported - * PHY speed which is needed for bcmgenet_mii_config() to configure - * things appropriately. - */ - ret = bcmgenet_mii_config(dev, true); - if (ret) { - phy_disconnect(dev->phydev); - return ret; + dev_info(kdev, "configuring instance for %s\n", phy_name); } - linkmode_copy(phydev->advertising, phydev->supported); - - /* The internal PHY has its link interrupts routed to the - * Ethernet MAC ISRs. On GENETv5 there is a hardware issue - * that prevents the signaling of link UP interrupts when - * the link operates at 10Mbps, so fallback to polling for - * those versions of GENET. - */ - if (priv->internal_phy && !GENET_IS_V5(priv)) - dev->phydev->irq = PHY_IGNORE_INTERRUPT; - return 0; } -- GitLab From 25382b991d252aed961cd434176240f9de6bb15f Mon Sep 17 00:00:00 2001 From: Doug Berger Date: Wed, 16 Oct 2019 16:06:32 -0700 Subject: [PATCH 456/993] net: bcmgenet: reset 40nm EPHY on energy detect The EPHY integrated into the 40nm Set-Top Box devices can falsely detect energy when connected to a disabled peer interface. When the peer interface is enabled the EPHY will detect and report the link as active, but on occasion may get into a state where it is not able to exchange data with the connected GENET MAC. This issue has not been observed when the link parameters are auto-negotiated; however, it has been observed with a manually configured link. It has been empirically determined that issuing a soft reset to the EPHY when energy is detected prevents it from getting into this bad state. Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file") Signed-off-by: Doug Berger Acked-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index f0937c650e3c..0f138280315a 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -2018,6 +2018,8 @@ static void bcmgenet_link_intr_enable(struct bcmgenet_priv *priv) */ if (priv->internal_phy) { int0_enable |= UMAC_IRQ_LINK_EVENT; + if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv)) + int0_enable |= UMAC_IRQ_PHY_DET_R; } else if (priv->ext_phy) { int0_enable |= UMAC_IRQ_LINK_EVENT; } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) { @@ -2611,9 +2613,14 @@ static void bcmgenet_irq_task(struct work_struct *work) priv->irq0_stat = 0; spin_unlock_irq(&priv->lock); + if (status & UMAC_IRQ_PHY_DET_R && + priv->dev->phydev->autoneg != AUTONEG_ENABLE) + phy_init_hw(priv->dev->phydev); + /* Link UP/DOWN event */ if (status & UMAC_IRQ_LINK_EVENT) phy_mac_interrupt(priv->dev->phydev); + } /* bcmgenet_isr1: handle Rx and Tx priority queues */ @@ -2708,7 +2715,7 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) } /* all other interested interrupts handled in bottom half */ - status &= UMAC_IRQ_LINK_EVENT; + status &= (UMAC_IRQ_LINK_EVENT | UMAC_IRQ_PHY_DET_R); if (status) { /* Save irq status for bottom-half processing. */ spin_lock_irqsave(&priv->lock, flags); -- GitLab From 9669fffc1415bb0c30e5d2ec98a8e1c3a418cb9c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 16 Oct 2019 18:00:56 -0700 Subject: [PATCH 457/993] net: ensure correct skb->tstamp in various fragmenters Thomas found that some forwarded packets would be stuck in FQ packet scheduler because their skb->tstamp contained timestamps far in the future. We thought we addressed this point in commit 8203e2d844d3 ("net: clear skb->tstamp in forwarding paths") but there is still an issue when/if a packet needs to be fragmented. In order to meet EDT requirements, we have to make sure all fragments get the original skb->tstamp. Note that this original skb->tstamp should be zero in forwarding path, but might have a non zero value in output path if user decided so. Fixes: fb420d5d91c1 ("tcp/fq: move back to CLOCK_MONOTONIC") Signed-off-by: Eric Dumazet Reported-by: Thomas Bartschies Signed-off-by: David S. Miller --- net/bridge/netfilter/nf_conntrack_bridge.c | 3 +++ net/ipv4/ip_output.c | 3 +++ net/ipv6/ip6_output.c | 3 +++ net/ipv6/netfilter.c | 3 +++ 4 files changed, 12 insertions(+) diff --git a/net/bridge/netfilter/nf_conntrack_bridge.c b/net/bridge/netfilter/nf_conntrack_bridge.c index 8842798c29e6..506d6141e44e 100644 --- a/net/bridge/netfilter/nf_conntrack_bridge.c +++ b/net/bridge/netfilter/nf_conntrack_bridge.c @@ -33,6 +33,7 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk, { int frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size; unsigned int hlen, ll_rs, mtu; + ktime_t tstamp = skb->tstamp; struct ip_frag_state state; struct iphdr *iph; int err; @@ -80,6 +81,7 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk, if (iter.frag) ip_fraglist_prepare(skb, &iter); + skb->tstamp = tstamp; err = output(net, sk, data, skb); if (err || !iter.frag) break; @@ -104,6 +106,7 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk, goto blackhole; } + skb2->tstamp = tstamp; err = output(net, sk, data, skb2); if (err) goto blackhole; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 28fca408812c..814b9b8882a0 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -771,6 +771,7 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, struct rtable *rt = skb_rtable(skb); unsigned int mtu, hlen, ll_rs; struct ip_fraglist_iter iter; + ktime_t tstamp = skb->tstamp; struct ip_frag_state state; int err = 0; @@ -846,6 +847,7 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, ip_fraglist_prepare(skb, &iter); } + skb->tstamp = tstamp; err = output(net, sk, skb); if (!err) @@ -900,6 +902,7 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, /* * Put this fragment into the sending queue. */ + skb2->tstamp = tstamp; err = output(net, sk, skb2); if (err) goto fail; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index edadee4a7e76..71827b56c006 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -768,6 +768,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, inet6_sk(skb->sk) : NULL; struct ip6_frag_state state; unsigned int mtu, hlen, nexthdr_offset; + ktime_t tstamp = skb->tstamp; int hroom, err = 0; __be32 frag_id; u8 *prevhdr, nexthdr = 0; @@ -855,6 +856,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, if (iter.frag) ip6_fraglist_prepare(skb, &iter); + skb->tstamp = tstamp; err = output(net, sk, skb); if (!err) IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), @@ -913,6 +915,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, /* * Put this fragment into the sending queue. */ + frag->tstamp = tstamp; err = output(net, sk, frag); if (err) goto fail; diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index a9bff556d3b2..409e79b84a83 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -119,6 +119,7 @@ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, struct sk_buff *)) { int frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size; + ktime_t tstamp = skb->tstamp; struct ip6_frag_state state; u8 *prevhdr, nexthdr = 0; unsigned int mtu, hlen; @@ -183,6 +184,7 @@ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, if (iter.frag) ip6_fraglist_prepare(skb, &iter); + skb->tstamp = tstamp; err = output(net, sk, data, skb); if (err || !iter.frag) break; @@ -215,6 +217,7 @@ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, goto blackhole; } + skb2->tstamp = tstamp; err = output(net, sk, data, skb2); if (err) goto blackhole; -- GitLab From 22e58665a01006d05f0239621f7d41cacca96cc4 Mon Sep 17 00:00:00 2001 From: Junya Monden Date: Wed, 16 Oct 2019 14:42:55 +0200 Subject: [PATCH 458/993] ASoC: rsnd: Reinitialize bit clock inversion flag for every format setting Unlike other format-related DAI parameters, rdai->bit_clk_inv flag is not properly re-initialized when setting format for new stream processing. The inversion, if requested, is then applied not to default, but to a previous value, which leads to SCKP bit in SSICR register being set incorrectly. Fix this by re-setting the flag to its initial value, determined by format. Fixes: 1a7889ca8aba3 ("ASoC: rsnd: fixup SND_SOC_DAIFMT_xB_xF behavior") Cc: Andrew Gabbasov Cc: Jiada Wang Cc: Timo Wischer Cc: stable@vger.kernel.org # v3.17+ Signed-off-by: Junya Monden Signed-off-by: Eugeniu Rosca Acked-by: Kuninori Morimoto Link: https://lore.kernel.org/r/20191016124255.7442-1-erosca@de.adit-jv.com Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index bda5b958d0dc..e9596c2096cd 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -761,6 +761,7 @@ static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) } /* set format */ + rdai->bit_clk_inv = 0; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: rdai->sys_delay = 0; -- GitLab From e5f0d490fb718254a884453e47fcd48493cd67ea Mon Sep 17 00:00:00 2001 From: Chuhong Yuan Date: Thu, 17 Oct 2019 10:50:44 +0800 Subject: [PATCH 459/993] ASoC: Intel: sof-rt5682: add a check for devm_clk_get sof_audio_probe misses a check for devm_clk_get and may cause problems. Add a check for it to fix the bug. Signed-off-by: Chuhong Yuan Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20191017025044.31474-1-hslester96@gmail.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_rt5682.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 5ce643d62faf..4f6e58c3954a 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -603,6 +603,15 @@ static int sof_audio_probe(struct platform_device *pdev) /* need to get main clock from pmc */ if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + if (IS_ERR(ctx->mclk)) { + ret = PTR_ERR(ctx->mclk); + + dev_err(&pdev->dev, + "Failed to get MCLK from pmc_plt_clk_3: %d\n", + ret); + return ret; + } + ret = clk_prepare_enable(ctx->mclk); if (ret < 0) { dev_err(&pdev->dev, -- GitLab From 9b7a7f921689d6c254e5acd670be631ebd82d54d Mon Sep 17 00:00:00 2001 From: Olivier Moysan Date: Fri, 18 Oct 2019 10:20:40 +0200 Subject: [PATCH 460/993] ASoC: stm32: sai: fix sysclk management on shutdown The commit below, adds a call to sysclk callback on shutdown. This introduces a regression in stm32 SAI driver, as some clock services are called twice, leading to unbalanced calls. Move processing related to mclk from shutdown to sysclk callback. When requested frequency is 0, assume shutdown and release mclk. Fixes: 2458adb8f92a ("SoC: simple-card-utils: set 0Hz to sysclk when shutdown") Signed-off-by: Olivier Moysan Link: https://lore.kernel.org/r/20191018082040.31022-1-olivier.moysan@st.com Signed-off-by: Mark Brown --- sound/soc/stm/stm32_sai_sub.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index d7501f88aaa6..a4060813bc74 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c @@ -505,10 +505,20 @@ static int stm32_sai_set_sysclk(struct snd_soc_dai *cpu_dai, if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) { ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, SAI_XCR1_NODIV, - (unsigned int)~SAI_XCR1_NODIV); + freq ? 0 : SAI_XCR1_NODIV); if (ret < 0) return ret; + /* Assume shutdown if requested frequency is 0Hz */ + if (!freq) { + /* Release mclk rate only if rate was actually set */ + if (sai->mclk_rate) { + clk_rate_exclusive_put(sai->sai_mclk); + sai->mclk_rate = 0; + } + return 0; + } + /* If master clock is used, set parent clock now */ ret = stm32_sai_set_parent_clock(sai, freq); if (ret) @@ -1093,15 +1103,6 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream, regmap_update_bits(sai->regmap, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0); - regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, SAI_XCR1_NODIV, - SAI_XCR1_NODIV); - - /* Release mclk rate only if rate was actually set */ - if (sai->mclk_rate) { - clk_rate_exclusive_put(sai->sai_mclk); - sai->mclk_rate = 0; - } - clk_disable_unprepare(sai->sai_ck); spin_lock_irqsave(&sai->irq_lock, flags); -- GitLab From 95a32c98055f664f9b3f34c41e153d4dcedd0eff Mon Sep 17 00:00:00 2001 From: Dragos Tarcatu Date: Fri, 18 Oct 2019 07:38:06 -0500 Subject: [PATCH 461/993] ASoC: SOF: control: return true when kcontrol values change All the kcontrol put() functions are currently returning 0 when successful. This does not go well with alsamixer as it does not seem to get notified on SND_CTL_EVENT_MASK_VALUE callbacks when values change for (some of) the sof kcontrols. This patch fixes that by returning true for volume, switch and enum type kcontrols when values do change in put(). Signed-off-by: Dragos Tarcatu Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20191018123806.18063-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/control.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/sound/soc/sof/control.c b/sound/soc/sof/control.c index a4983f90ff5b..2b8711eda362 100644 --- a/sound/soc/sof/control.c +++ b/sound/soc/sof/control.c @@ -60,13 +60,16 @@ int snd_sof_volume_put(struct snd_kcontrol *kcontrol, struct snd_sof_dev *sdev = scontrol->sdev; struct sof_ipc_ctrl_data *cdata = scontrol->control_data; unsigned int i, channels = scontrol->num_channels; + bool change = false; + u32 value; /* update each channel */ for (i = 0; i < channels; i++) { - cdata->chanv[i].value = - mixer_to_ipc(ucontrol->value.integer.value[i], + value = mixer_to_ipc(ucontrol->value.integer.value[i], scontrol->volume_table, sm->max + 1); + change = change || (value != cdata->chanv[i].value); cdata->chanv[i].channel = i; + cdata->chanv[i].value = value; } /* notify DSP of mixer updates */ @@ -76,8 +79,7 @@ int snd_sof_volume_put(struct snd_kcontrol *kcontrol, SOF_CTRL_TYPE_VALUE_CHAN_GET, SOF_CTRL_CMD_VOLUME, true); - - return 0; + return change; } int snd_sof_switch_get(struct snd_kcontrol *kcontrol, @@ -105,11 +107,15 @@ int snd_sof_switch_put(struct snd_kcontrol *kcontrol, struct snd_sof_dev *sdev = scontrol->sdev; struct sof_ipc_ctrl_data *cdata = scontrol->control_data; unsigned int i, channels = scontrol->num_channels; + bool change = false; + u32 value; /* update each channel */ for (i = 0; i < channels; i++) { - cdata->chanv[i].value = ucontrol->value.integer.value[i]; + value = ucontrol->value.integer.value[i]; + change = change || (value != cdata->chanv[i].value); cdata->chanv[i].channel = i; + cdata->chanv[i].value = value; } /* notify DSP of mixer updates */ @@ -120,7 +126,7 @@ int snd_sof_switch_put(struct snd_kcontrol *kcontrol, SOF_CTRL_CMD_SWITCH, true); - return 0; + return change; } int snd_sof_enum_get(struct snd_kcontrol *kcontrol, @@ -148,11 +154,15 @@ int snd_sof_enum_put(struct snd_kcontrol *kcontrol, struct snd_sof_dev *sdev = scontrol->sdev; struct sof_ipc_ctrl_data *cdata = scontrol->control_data; unsigned int i, channels = scontrol->num_channels; + bool change = false; + u32 value; /* update each channel */ for (i = 0; i < channels; i++) { - cdata->chanv[i].value = ucontrol->value.enumerated.item[i]; + value = ucontrol->value.enumerated.item[i]; + change = change || (value != cdata->chanv[i].value); cdata->chanv[i].channel = i; + cdata->chanv[i].value = value; } /* notify DSP of enum updates */ @@ -163,7 +173,7 @@ int snd_sof_enum_put(struct snd_kcontrol *kcontrol, SOF_CTRL_CMD_ENUM, true); - return 0; + return change; } int snd_sof_bytes_get(struct snd_kcontrol *kcontrol, -- GitLab From 2e978795bb4c14293bf6ecf32621d32529706aef Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Thu, 17 Oct 2019 10:11:03 +0300 Subject: [PATCH 462/993] mlxsw: spectrum_trap: Push Ethernet header before reporting trap devlink maintains packets and bytes statistics for each trap. Since eth_type_trans() was called to set the skb's protocol, the data pointer no longer points to the start of the packet and the bytes accounting is off by 14 bytes. Fix this by pushing the skb's data pointer to the start of the packet. Fixes: b5ce611fd96e ("mlxsw: spectrum: Add devlink-trap support") Reported-by: Alex Kushnarov Tested-by: Alex Kushnarov Acked-by: Jiri Pirko Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c index 899450b28621..7c03b661ae7e 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c @@ -99,6 +99,7 @@ static void mlxsw_sp_rx_drop_listener(struct sk_buff *skb, u8 local_port, devlink = priv_to_devlink(mlxsw_sp->core); in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core, local_port); + skb_push(skb, ETH_HLEN); devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port); consume_skb(skb); } -- GitLab From ec3359b685db834c249953db6ac5717bf5cde425 Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Thu, 17 Oct 2019 14:44:02 +0200 Subject: [PATCH 463/993] vsock/virtio: send a credit update when buffer size is changed When the user application set a new buffer size value, we should update the remote peer about this change, since it uses this information to calculate the credit available. Signed-off-by: Stefano Garzarella Signed-off-by: David S. Miller --- net/vmw_vsock/virtio_transport_common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index a666ef8fc54e..db127a69f5c3 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -458,6 +458,9 @@ void virtio_transport_set_buffer_size(struct vsock_sock *vsk, u64 val) vvs->buf_size_max = val; vvs->buf_size = val; vvs->buf_alloc = val; + + virtio_transport_send_credit_update(vsk, VIRTIO_VSOCK_TYPE_STREAM, + NULL); } EXPORT_SYMBOL_GPL(virtio_transport_set_buffer_size); -- GitLab From ae6fcfbf5f03de3407b809aaee319330d3dc7f8b Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Thu, 17 Oct 2019 14:44:03 +0200 Subject: [PATCH 464/993] vsock/virtio: discard packets if credit is not respected If the remote peer doesn't respect the credit information (buf_alloc, fwd_cnt), sending more data than it can send, we should drop the packets to prevent a malicious peer from using all of our memory. This is patch follows the VIRTIO spec: "VIRTIO_VSOCK_OP_RW data packets MUST only be transmitted when the peer has sufficient free buffer space for the payload" Signed-off-by: Stefano Garzarella Signed-off-by: David S. Miller --- net/vmw_vsock/virtio_transport_common.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index db127a69f5c3..481f7f8a1655 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -204,10 +204,14 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk, return virtio_transport_get_ops()->send_pkt(pkt); } -static void virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs, +static bool virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs, struct virtio_vsock_pkt *pkt) { + if (vvs->rx_bytes + pkt->len > vvs->buf_alloc) + return false; + vvs->rx_bytes += pkt->len; + return true; } static void virtio_transport_dec_rx_pkt(struct virtio_vsock_sock *vvs, @@ -879,14 +883,18 @@ virtio_transport_recv_enqueue(struct vsock_sock *vsk, struct virtio_vsock_pkt *pkt) { struct virtio_vsock_sock *vvs = vsk->trans; - bool free_pkt = false; + bool can_enqueue, free_pkt = false; pkt->len = le32_to_cpu(pkt->hdr.len); pkt->off = 0; spin_lock_bh(&vvs->rx_lock); - virtio_transport_inc_rx_pkt(vvs, pkt); + can_enqueue = virtio_transport_inc_rx_pkt(vvs, pkt); + if (!can_enqueue) { + free_pkt = true; + goto out; + } /* Try to copy small packets into the buffer of last packet queued, * to avoid wasting memory queueing the entire buffer with a small -- GitLab From 38b4fe320119859c11b1dc06f6b4987a16344fa1 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Thu, 17 Oct 2019 21:29:26 +0200 Subject: [PATCH 465/993] net: usb: lan78xx: Connect PHY before registering MAC As soon as the netdev is registers, the kernel can start using the interface. If the driver connects the MAC to the PHY after the netdev is registered, there is a race condition where the interface can be opened without having the PHY connected. Change the order to close this race condition. Fixes: 92571a1aae40 ("lan78xx: Connect phy early") Reported-by: Daniel Wagner Signed-off-by: Andrew Lunn Tested-by: Daniel Wagner Signed-off-by: David S. Miller --- drivers/net/usb/lan78xx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 58f5a219fb65..62948098191f 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -3782,10 +3782,14 @@ static int lan78xx_probe(struct usb_interface *intf, /* driver requires remote-wakeup capability during autosuspend. */ intf->needs_remote_wakeup = 1; + ret = lan78xx_phy_init(dev); + if (ret < 0) + goto out4; + ret = register_netdev(netdev); if (ret != 0) { netif_err(dev, probe, netdev, "couldn't register the device\n"); - goto out4; + goto out5; } usb_set_intfdata(intf, dev); @@ -3798,14 +3802,10 @@ static int lan78xx_probe(struct usb_interface *intf, pm_runtime_set_autosuspend_delay(&udev->dev, DEFAULT_AUTOSUSPEND_DELAY); - ret = lan78xx_phy_init(dev); - if (ret < 0) - goto out5; - return 0; out5: - unregister_netdev(netdev); + phy_disconnect(netdev->phydev); out4: usb_free_urb(dev->urb_intr); out3: -- GitLab From 612e0486ad0845c41ac10492e78144f99e326375 Mon Sep 17 00:00:00 2001 From: Potnuri Bharat Teja Date: Thu, 3 Oct 2019 16:13:53 +0530 Subject: [PATCH 466/993] iw_cxgb4: fix ECN check on the passive accept pass_accept_req() is using the same skb for handling accept request and sending accept reply to HW. Here req and rpl structures are pointing to same skb->data which is over written by INIT_TP_WR() and leads to accessing corrupt req fields in accept_cr() while checking for ECN flags. Reordered code in accept_cr() to fetch correct req fields. Fixes: 92e7ae7172 ("iw_cxgb4: Choose appropriate hw mtu index and ISS for iWARP connections") Signed-off-by: Potnuri Bharat Teja Link: https://lore.kernel.org/r/20191003104353.11590-1-bharat@chelsio.com Signed-off-by: Doug Ledford --- drivers/infiniband/hw/cxgb4/cm.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index e87fc0408470..9e8eca7b613c 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -2424,20 +2424,6 @@ static int accept_cr(struct c4iw_ep *ep, struct sk_buff *skb, enum chip_type adapter_type = ep->com.dev->rdev.lldi.adapter_type; pr_debug("ep %p tid %u\n", ep, ep->hwtid); - - skb_get(skb); - rpl = cplhdr(skb); - if (!is_t4(adapter_type)) { - skb_trim(skb, roundup(sizeof(*rpl5), 16)); - rpl5 = (void *)rpl; - INIT_TP_WR(rpl5, ep->hwtid); - } else { - skb_trim(skb, sizeof(*rpl)); - INIT_TP_WR(rpl, ep->hwtid); - } - OPCODE_TID(rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_PASS_ACCEPT_RPL, - ep->hwtid)); - cxgb_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx, enable_tcp_timestamps && req->tcpopt.tstamp, (ep->com.remote_addr.ss_family == AF_INET) ? 0 : 1); @@ -2483,6 +2469,20 @@ static int accept_cr(struct c4iw_ep *ep, struct sk_buff *skb, if (tcph->ece && tcph->cwr) opt2 |= CCTRL_ECN_V(1); } + + skb_get(skb); + rpl = cplhdr(skb); + if (!is_t4(adapter_type)) { + skb_trim(skb, roundup(sizeof(*rpl5), 16)); + rpl5 = (void *)rpl; + INIT_TP_WR(rpl5, ep->hwtid); + } else { + skb_trim(skb, sizeof(*rpl)); + INIT_TP_WR(rpl, ep->hwtid); + } + OPCODE_TID(rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_PASS_ACCEPT_RPL, + ep->hwtid)); + if (CHELSIO_CHIP_VERSION(adapter_type) > CHELSIO_T4) { u32 isn = (prandom_u32() & ~7UL) - 1; opt2 |= T5_OPT_2_VALID_F; -- GitLab From 54102dd410b037a4d7984e6a5826fb212c2f8aca Mon Sep 17 00:00:00 2001 From: Krishnamraju Eraparaju Date: Mon, 7 Oct 2019 15:56:27 +0530 Subject: [PATCH 467/993] RDMA/iwcm: move iw_rem_ref() calls out of spinlock kref release routines usually perform memory release operations, hence, they should not be called with spinlocks held. one such case is: SIW kref release routine siw_free_qp(), which can sleep via vfree() while freeing queue memory. Hence, all iw_rem_ref() calls in IWCM are moved out of spinlocks. Fixes: 922a8e9fb2e0 ("RDMA: iWARP Connection Manager.") Signed-off-by: Krishnamraju Eraparaju Reviewed-by: Bernard Metzler Link: https://lore.kernel.org/r/20191007102627.12568-1-krishna2@chelsio.com Signed-off-by: Doug Ledford --- drivers/infiniband/core/iwcm.c | 52 +++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index 72141c5b7c95..ade71823370f 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c @@ -372,6 +372,7 @@ EXPORT_SYMBOL(iw_cm_disconnect); static void destroy_cm_id(struct iw_cm_id *cm_id) { struct iwcm_id_private *cm_id_priv; + struct ib_qp *qp; unsigned long flags; cm_id_priv = container_of(cm_id, struct iwcm_id_private, id); @@ -389,6 +390,9 @@ static void destroy_cm_id(struct iw_cm_id *cm_id) set_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags); spin_lock_irqsave(&cm_id_priv->lock, flags); + qp = cm_id_priv->qp; + cm_id_priv->qp = NULL; + switch (cm_id_priv->state) { case IW_CM_STATE_LISTEN: cm_id_priv->state = IW_CM_STATE_DESTROYING; @@ -401,7 +405,7 @@ static void destroy_cm_id(struct iw_cm_id *cm_id) cm_id_priv->state = IW_CM_STATE_DESTROYING; spin_unlock_irqrestore(&cm_id_priv->lock, flags); /* Abrupt close of the connection */ - (void)iwcm_modify_qp_err(cm_id_priv->qp); + (void)iwcm_modify_qp_err(qp); spin_lock_irqsave(&cm_id_priv->lock, flags); break; case IW_CM_STATE_IDLE: @@ -426,11 +430,9 @@ static void destroy_cm_id(struct iw_cm_id *cm_id) BUG(); break; } - if (cm_id_priv->qp) { - cm_id_priv->id.device->ops.iw_rem_ref(cm_id_priv->qp); - cm_id_priv->qp = NULL; - } spin_unlock_irqrestore(&cm_id_priv->lock, flags); + if (qp) + cm_id_priv->id.device->ops.iw_rem_ref(qp); if (cm_id->mapped) { iwpm_remove_mapinfo(&cm_id->local_addr, &cm_id->m_local_addr); @@ -671,11 +673,11 @@ int iw_cm_accept(struct iw_cm_id *cm_id, BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_RECV); cm_id_priv->state = IW_CM_STATE_IDLE; spin_lock_irqsave(&cm_id_priv->lock, flags); - if (cm_id_priv->qp) { - cm_id->device->ops.iw_rem_ref(qp); - cm_id_priv->qp = NULL; - } + qp = cm_id_priv->qp; + cm_id_priv->qp = NULL; spin_unlock_irqrestore(&cm_id_priv->lock, flags); + if (qp) + cm_id->device->ops.iw_rem_ref(qp); clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); wake_up_all(&cm_id_priv->connect_wait); } @@ -696,7 +698,7 @@ int iw_cm_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param) struct iwcm_id_private *cm_id_priv; int ret; unsigned long flags; - struct ib_qp *qp; + struct ib_qp *qp = NULL; cm_id_priv = container_of(cm_id, struct iwcm_id_private, id); @@ -730,13 +732,13 @@ int iw_cm_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param) return 0; /* success */ spin_lock_irqsave(&cm_id_priv->lock, flags); - if (cm_id_priv->qp) { - cm_id->device->ops.iw_rem_ref(qp); - cm_id_priv->qp = NULL; - } + qp = cm_id_priv->qp; + cm_id_priv->qp = NULL; cm_id_priv->state = IW_CM_STATE_IDLE; err: spin_unlock_irqrestore(&cm_id_priv->lock, flags); + if (qp) + cm_id->device->ops.iw_rem_ref(qp); clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); wake_up_all(&cm_id_priv->connect_wait); return ret; @@ -878,6 +880,7 @@ static int cm_conn_est_handler(struct iwcm_id_private *cm_id_priv, static int cm_conn_rep_handler(struct iwcm_id_private *cm_id_priv, struct iw_cm_event *iw_event) { + struct ib_qp *qp = NULL; unsigned long flags; int ret; @@ -896,11 +899,13 @@ static int cm_conn_rep_handler(struct iwcm_id_private *cm_id_priv, cm_id_priv->state = IW_CM_STATE_ESTABLISHED; } else { /* REJECTED or RESET */ - cm_id_priv->id.device->ops.iw_rem_ref(cm_id_priv->qp); + qp = cm_id_priv->qp; cm_id_priv->qp = NULL; cm_id_priv->state = IW_CM_STATE_IDLE; } spin_unlock_irqrestore(&cm_id_priv->lock, flags); + if (qp) + cm_id_priv->id.device->ops.iw_rem_ref(qp); ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event); if (iw_event->private_data_len) @@ -942,21 +947,18 @@ static void cm_disconnect_handler(struct iwcm_id_private *cm_id_priv, static int cm_close_handler(struct iwcm_id_private *cm_id_priv, struct iw_cm_event *iw_event) { + struct ib_qp *qp; unsigned long flags; - int ret = 0; + int ret = 0, notify_event = 0; spin_lock_irqsave(&cm_id_priv->lock, flags); + qp = cm_id_priv->qp; + cm_id_priv->qp = NULL; - if (cm_id_priv->qp) { - cm_id_priv->id.device->ops.iw_rem_ref(cm_id_priv->qp); - cm_id_priv->qp = NULL; - } switch (cm_id_priv->state) { case IW_CM_STATE_ESTABLISHED: case IW_CM_STATE_CLOSING: cm_id_priv->state = IW_CM_STATE_IDLE; - spin_unlock_irqrestore(&cm_id_priv->lock, flags); - ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event); - spin_lock_irqsave(&cm_id_priv->lock, flags); + notify_event = 1; break; case IW_CM_STATE_DESTROYING: break; @@ -965,6 +967,10 @@ static int cm_close_handler(struct iwcm_id_private *cm_id_priv, } spin_unlock_irqrestore(&cm_id_priv->lock, flags); + if (qp) + cm_id_priv->id.device->ops.iw_rem_ref(qp); + if (notify_event) + ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event); return ret; } -- GitLab From 9fa8c9c647be624e91b09ecffa7cd97ee0600b40 Mon Sep 17 00:00:00 2001 From: Zhengjun Xing Date: Fri, 18 Oct 2019 09:20:34 +0800 Subject: [PATCH 468/993] tracing: Fix "gfp_t" format for synthetic events In the format of synthetic events, the "gfp_t" is shown as "signed:1", but in fact the "gfp_t" is "unsigned", should be shown as "signed:0". The issue can be reproduced by the following commands: echo 'memlatency u64 lat; unsigned int order; gfp_t gfp_flags; int migratetype' > /sys/kernel/debug/tracing/synthetic_events cat /sys/kernel/debug/tracing/events/synthetic/memlatency/format name: memlatency ID: 2233 format: field:unsigned short common_type; offset:0; size:2; signed:0; field:unsigned char common_flags; offset:2; size:1; signed:0; field:unsigned char common_preempt_count; offset:3; size:1; signed:0; field:int common_pid; offset:4; size:4; signed:1; field:u64 lat; offset:8; size:8; signed:0; field:unsigned int order; offset:16; size:4; signed:0; field:gfp_t gfp_flags; offset:24; size:4; signed:1; field:int migratetype; offset:32; size:4; signed:1; print fmt: "lat=%llu, order=%u, gfp_flags=%x, migratetype=%d", REC->lat, REC->order, REC->gfp_flags, REC->migratetype Link: http://lkml.kernel.org/r/20191018012034.6404-1-zhengjun.xing@linux.intel.com Reviewed-by: Tom Zanussi Signed-off-by: Zhengjun Xing Signed-off-by: Steven Rostedt (VMware) --- kernel/trace/trace_events_hist.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 57648c5aa679..7482a1466ebf 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -679,6 +679,8 @@ static bool synth_field_signed(char *type) { if (str_has_prefix(type, "u")) return false; + if (strcmp(type, "gfp_t") == 0) + return false; return true; } -- GitLab From e17fa5c95ef2434a08e0be217969d246d037f0c2 Mon Sep 17 00:00:00 2001 From: Krishnamraju Eraparaju Date: Mon, 7 Oct 2019 16:12:29 +0530 Subject: [PATCH 469/993] RDMA/siw: free siw_base_qp in kref release routine As siw_free_qp() is the last routine to access 'siw_base_qp' structure, freeing this structure early in siw_destroy_qp() could cause touch-after-free issue. Hence, moved kfree(siw_base_qp) from siw_destroy_qp() to siw_free_qp(). Fixes: 303ae1cdfdf7 ("rdma/siw: application interface") Signed-off-by: Krishnamraju Eraparaju Link: https://lore.kernel.org/r/20191007104229.29412-1-krishna2@chelsio.com Signed-off-by: Doug Ledford --- drivers/infiniband/sw/siw/siw_qp.c | 2 ++ drivers/infiniband/sw/siw/siw_verbs.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/sw/siw/siw_qp.c b/drivers/infiniband/sw/siw/siw_qp.c index 52d402f39df9..b4317480cee7 100644 --- a/drivers/infiniband/sw/siw/siw_qp.c +++ b/drivers/infiniband/sw/siw/siw_qp.c @@ -1312,6 +1312,7 @@ int siw_qp_add(struct siw_device *sdev, struct siw_qp *qp) void siw_free_qp(struct kref *ref) { struct siw_qp *found, *qp = container_of(ref, struct siw_qp, ref); + struct siw_base_qp *siw_base_qp = to_siw_base_qp(qp->ib_qp); struct siw_device *sdev = qp->sdev; unsigned long flags; @@ -1334,4 +1335,5 @@ void siw_free_qp(struct kref *ref) atomic_dec(&sdev->num_qp); siw_dbg_qp(qp, "free QP\n"); kfree_rcu(qp, rcu); + kfree(siw_base_qp); } diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c index 869e02b69a01..b18a677832e1 100644 --- a/drivers/infiniband/sw/siw/siw_verbs.c +++ b/drivers/infiniband/sw/siw/siw_verbs.c @@ -604,7 +604,6 @@ int siw_verbs_modify_qp(struct ib_qp *base_qp, struct ib_qp_attr *attr, int siw_destroy_qp(struct ib_qp *base_qp, struct ib_udata *udata) { struct siw_qp *qp = to_siw_qp(base_qp); - struct siw_base_qp *siw_base_qp = to_siw_base_qp(base_qp); struct siw_ucontext *uctx = rdma_udata_to_drv_context(udata, struct siw_ucontext, base_ucontext); @@ -641,7 +640,6 @@ int siw_destroy_qp(struct ib_qp *base_qp, struct ib_udata *udata) qp->scq = qp->rcq = NULL; siw_qp_put(qp); - kfree(siw_base_qp); return 0; } -- GitLab From b806c94ee44e53233b8ce6c92d9078d9781786a5 Mon Sep 17 00:00:00 2001 From: Kamal Heib Date: Tue, 8 Oct 2019 00:07:30 +0300 Subject: [PATCH 470/993] RDMA/qedr: Fix reported firmware version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove spaces from the reported firmware version string. Actual value: $ cat /sys/class/infiniband/qedr0/fw_ver 8. 37. 7. 0 Expected value: $ cat /sys/class/infiniband/qedr0/fw_ver 8.37.7.0 Fixes: ec72fce401c6 ("qedr: Add support for RoCE HW init") Signed-off-by: Kamal Heib Acked-by: Michal Kalderon  Link: https://lore.kernel.org/r/20191007210730.7173-1-kamalheib1@gmail.com Signed-off-by: Doug Ledford --- drivers/infiniband/hw/qedr/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c index 5136b835e1ba..dc71b6e16a07 100644 --- a/drivers/infiniband/hw/qedr/main.c +++ b/drivers/infiniband/hw/qedr/main.c @@ -76,7 +76,7 @@ static void qedr_get_dev_fw_str(struct ib_device *ibdev, char *str) struct qedr_dev *qedr = get_qedr_dev(ibdev); u32 fw_ver = (u32)qedr->attr.fw_ver; - snprintf(str, IB_FW_VERSION_NAME_MAX, "%d. %d. %d. %d", + snprintf(str, IB_FW_VERSION_NAME_MAX, "%d.%d.%d.%d", (fw_ver >> 24) & 0xFF, (fw_ver >> 16) & 0xFF, (fw_ver >> 8) & 0xFF, fw_ver & 0xFF); } -- GitLab From 777a8b32bc0f9bb25848a025f72a9febc30d9033 Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Wed, 2 Oct 2019 15:17:50 +0300 Subject: [PATCH 471/993] IB/core: Use rdma_read_gid_l2_fields to compare GID L2 fields Current code tries to derive VLAN ID and compares it with GID attribute for matching entry. This raw search fails on macvlan netdevice as its not a VLAN device, but its an upper device of a VLAN netdevice. Due to this limitation, incoming QP1 packets fail to match in the GID table. Such packets are dropped. Hence, to support it, use the existing rdma_read_gid_l2_fields() that takes care of diffferent device types. Fixes: dbf727de7440 ("IB/core: Use GID table in AH creation and dmac resolution") Signed-off-by: Parav Pandit Signed-off-by: Leon Romanovsky Link: https://lore.kernel.org/r/20191002121750.17313-1-leon@kernel.org Signed-off-by: Doug Ledford --- drivers/infiniband/core/verbs.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index f974b6854224..35c2841a569e 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -662,16 +662,17 @@ static bool find_gid_index(const union ib_gid *gid, void *context) { struct find_gid_index_context *ctx = context; + u16 vlan_id = 0xffff; + int ret; if (ctx->gid_type != gid_attr->gid_type) return false; - if ((!!(ctx->vlan_id != 0xffff) == !is_vlan_dev(gid_attr->ndev)) || - (is_vlan_dev(gid_attr->ndev) && - vlan_dev_vlan_id(gid_attr->ndev) != ctx->vlan_id)) + ret = rdma_read_gid_l2_fields(gid_attr, &vlan_id, NULL); + if (ret) return false; - return true; + return ctx->vlan_id == vlan_id; } static const struct ib_gid_attr * -- GitLab From 7a6f22d7479b7a0b68eadd308a997dd64dda7dae Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 18 Oct 2019 17:19:54 +0200 Subject: [PATCH 472/993] USB: ldusb: fix read info leaks Fix broken read implementation, which could be used to trigger slab info leaks. The driver failed to check if the custom ring buffer was still empty when waking up after having waited for more data. This would happen on every interrupt-in completion, even if no data had been added to the ring buffer (e.g. on disconnect events). Due to missing sanity checks and uninitialised (kmalloced) ring-buffer entries, this meant that huge slab info leaks could easily be triggered. Note that the empty-buffer check after wakeup is enough to fix the info leak on disconnect, but let's clear the buffer on allocation and add a sanity check to read() to prevent further leaks. Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") Cc: stable # 2.6.13 Reported-by: syzbot+6fe95b826644f7f12b0b@syzkaller.appspotmail.com Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20191018151955.25135-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ldusb.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 147c90c2a4e5..15b5f06fb0b3 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -464,7 +464,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, /* wait for data */ spin_lock_irq(&dev->rbsl); - if (dev->ring_head == dev->ring_tail) { + while (dev->ring_head == dev->ring_tail) { dev->interrupt_in_done = 0; spin_unlock_irq(&dev->rbsl); if (file->f_flags & O_NONBLOCK) { @@ -474,12 +474,17 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done); if (retval < 0) goto unlock_exit; - } else { - spin_unlock_irq(&dev->rbsl); + + spin_lock_irq(&dev->rbsl); } + spin_unlock_irq(&dev->rbsl); /* actual_buffer contains actual_length + interrupt_in_buffer */ actual_buffer = (size_t *)(dev->ring_buffer + dev->ring_tail * (sizeof(size_t)+dev->interrupt_in_endpoint_size)); + if (*actual_buffer > dev->interrupt_in_endpoint_size) { + retval = -EIO; + goto unlock_exit; + } bytes_to_read = min(count, *actual_buffer); if (bytes_to_read < *actual_buffer) dev_warn(&dev->intf->dev, "Read buffer overflow, %zd bytes dropped\n", @@ -690,10 +695,9 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n"); dev->interrupt_in_endpoint_size = usb_endpoint_maxp(dev->interrupt_in_endpoint); - dev->ring_buffer = - kmalloc_array(ring_buffer_size, - sizeof(size_t) + dev->interrupt_in_endpoint_size, - GFP_KERNEL); + dev->ring_buffer = kcalloc(ring_buffer_size, + sizeof(size_t) + dev->interrupt_in_endpoint_size, + GFP_KERNEL); if (!dev->ring_buffer) goto error; dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL); -- GitLab From 626c45d223e22090511acbfb481e0ece1de1356d Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Sun, 13 Oct 2019 12:53:23 +0200 Subject: [PATCH 473/993] ARM: dts: bcm2837-rpi-cm3: Avoid leds-gpio probing issue bcm2835-rpi.dtsi defines the behavior of the ACT LED, which is available on all Raspberry Pi boards. But there is no driver for this particual GPIO on CM3 in mainline yet, so this node was left incomplete without the actual GPIO definition. Since commit 025bf37725f1 ("gpio: Fix return value mismatch of function gpiod_get_from_of_node()") this causing probe issues of the leds-gpio driver for users of the CM3 dtsi file. leds-gpio: probe of leds failed with error -2 Until we have the necessary GPIO driver hide the ACT node for CM3 to avoid this. Reported-by: Fredrik Yhlen Signed-off-by: Stefan Wahren Fixes: a54fe8a6cf66 ("ARM: dts: add Raspberry Pi Compute Module 3 and IO board") Cc: Linus Walleij Cc: Krzysztof Kozlowski Signed-off-by: Florian Fainelli --- arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi index 7c3cb7ece6cb..925cb37c22f0 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi +++ b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi @@ -9,6 +9,14 @@ reg = <0 0x40000000>; }; + leds { + /* + * Since there is no upstream GPIO driver yet, + * remove the incomplete node. + */ + /delete-node/ act; + }; + reg_3v3: fixed-regulator { compatible = "regulator-fixed"; regulator-name = "3V3"; -- GitLab From 9794476942d8704cfbdef8d5f13427673ab70dcd Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Thu, 17 Oct 2019 10:58:01 +0300 Subject: [PATCH 474/993] usb: cdns3: Error out if USB_DR_MODE_UNKNOWN in cdns3_core_init_role() USB_DR_MODE_UNKNOWN should be treated as error as it is done in cdns3_drd_update_mode(). Fixes: 02ffc26df96b ("usb: cdns3: fix cdns3_core_init_role()") Signed-off-by: Roger Quadros Link: https://lore.kernel.org/r/20191017075801.8734-1-rogerq@ti.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index 1109dc5a4c39..c2123ef8d8a3 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -166,7 +166,6 @@ static int cdns3_core_init_role(struct cdns3 *cdns) goto err; switch (cdns->dr_mode) { - case USB_DR_MODE_UNKNOWN: case USB_DR_MODE_OTG: ret = cdns3_hw_role_switch(cdns); if (ret) @@ -182,6 +181,9 @@ static int cdns3_core_init_role(struct cdns3 *cdns) if (ret) goto err; break; + default: + ret = -EINVAL; + goto err; } return ret; -- GitLab From 0c258dec8d98af15b34dbffdb89c008b6da01ff8 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Mon, 16 Sep 2019 17:43:33 +0300 Subject: [PATCH 475/993] net/mlx5e: Tx, Fix assumption of single WQEBB of NOP in cleanup flow Cited patch removed the assumption only in datapath. Here we remove it also form control/cleanup flow. Fixes: 9ab0233728ca ("net/mlx5e: Tx, Don't implicitly assume SKB-less wqe has one WQEBB") Signed-off-by: Tariq Toukan Reviewed-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 6 +++++- drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 7569287f8f3c..b476b007f093 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -1349,9 +1349,13 @@ static void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq) /* last doorbell out, godspeed .. */ if (mlx5e_wqc_has_room_for(wq, sq->cc, sq->pc, 1)) { u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc); + struct mlx5e_tx_wqe_info *wi; struct mlx5e_tx_wqe *nop; - sq->db.wqe_info[pi].skb = NULL; + wi = &sq->db.wqe_info[pi]; + + memset(wi, 0, sizeof(*wi)); + wi->num_wqebbs = 1; nop = mlx5e_post_nop(wq, sq->sqn, &sq->pc); mlx5e_notify_hw(wq, sq->pc, sq->uar_map, &nop->ctrl); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c index d3a67a9b4eba..9094e9519db7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c @@ -550,8 +550,8 @@ void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq) wi = &sq->db.wqe_info[ci]; skb = wi->skb; - if (!skb) { /* nop */ - sq->cc++; + if (!skb) { + sq->cc += wi->num_wqebbs; continue; } -- GitLab From 500f36a485862cee15752b58a5a9a50c1f59ff58 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Mon, 16 Sep 2019 17:19:12 +0300 Subject: [PATCH 476/993] net/mlx5e: Tx, Zero-memset WQE info struct upon update Not all fields of WQE info are being written in the function, having some leftovers from previous rounds. Zero-memset it upon update. Particularly, not nullifying the wi->resync_dump_frag field will cause double free of the kTLS DUMPed frags. Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support") Signed-off-by: Tariq Toukan Reviewed-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h index 87be96747902..182d5c5664eb 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h @@ -92,7 +92,7 @@ mlx5e_fill_sq_frag_edge(struct mlx5e_txqsq *sq, struct mlx5_wq_cyc *wq, /* fill sq frag edge with nops to avoid wqe wrapping two pages */ for (; wi < edge_wi; wi++) { - wi->skb = NULL; + memset(wi, 0, sizeof(*wi)); wi->num_wqebbs = 1; mlx5e_post_nop(wq, sq->sqn, &sq->pc); } -- GitLab From 2c559361389b452ca23494080d0c65ab812706c1 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Wed, 18 Sep 2019 13:45:38 +0300 Subject: [PATCH 477/993] net/mlx5e: kTLS, Release reference on DUMPed fragments in shutdown flow A call to kTLS completion handler was missing in the TXQSQ release flow. Add it. Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support") Signed-off-by: Tariq Toukan Reviewed-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed --- .../mellanox/mlx5/core/en_accel/ktls.h | 7 ++++- .../mellanox/mlx5/core/en_accel/ktls_tx.c | 11 ++++++-- .../net/ethernet/mellanox/mlx5/core/en_tx.c | 28 ++++++++++--------- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h index b7298f9ee3d3..c4c128908b6e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h @@ -86,7 +86,7 @@ struct sk_buff *mlx5e_ktls_handle_tx_skb(struct net_device *netdev, struct mlx5e_tx_wqe **wqe, u16 *pi); void mlx5e_ktls_tx_handle_resync_dump_comp(struct mlx5e_txqsq *sq, struct mlx5e_tx_wqe_info *wi, - struct mlx5e_sq_dma *dma); + u32 *dma_fifo_cc); #else @@ -94,6 +94,11 @@ static inline void mlx5e_ktls_build_netdev(struct mlx5e_priv *priv) { } +static inline void +mlx5e_ktls_tx_handle_resync_dump_comp(struct mlx5e_txqsq *sq, + struct mlx5e_tx_wqe_info *wi, + u32 *dma_fifo_cc) {} + #endif #endif /* __MLX5E_TLS_H__ */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c index d195366461c9..90c6ce530a18 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c @@ -303,9 +303,16 @@ tx_post_resync_dump(struct mlx5e_txqsq *sq, skb_frag_t *frag, u32 tisn, bool fir void mlx5e_ktls_tx_handle_resync_dump_comp(struct mlx5e_txqsq *sq, struct mlx5e_tx_wqe_info *wi, - struct mlx5e_sq_dma *dma) + u32 *dma_fifo_cc) { - struct mlx5e_sq_stats *stats = sq->stats; + struct mlx5e_sq_stats *stats; + struct mlx5e_sq_dma *dma; + + if (!wi->resync_dump_frag) + return; + + dma = mlx5e_dma_get(sq, (*dma_fifo_cc)++); + stats = sq->stats; mlx5e_tx_dma_unmap(sq->pdev, dma); __skb_frag_unref(wi->resync_dump_frag); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c index 9094e9519db7..8dd8f0be101b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c @@ -479,14 +479,7 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget) skb = wi->skb; if (unlikely(!skb)) { -#ifdef CONFIG_MLX5_EN_TLS - if (wi->resync_dump_frag) { - struct mlx5e_sq_dma *dma = - mlx5e_dma_get(sq, dma_fifo_cc++); - - mlx5e_ktls_tx_handle_resync_dump_comp(sq, wi, dma); - } -#endif + mlx5e_ktls_tx_handle_resync_dump_comp(sq, wi, &dma_fifo_cc); sqcc += wi->num_wqebbs; continue; } @@ -542,29 +535,38 @@ void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq) { struct mlx5e_tx_wqe_info *wi; struct sk_buff *skb; + u32 dma_fifo_cc; + u16 sqcc; u16 ci; int i; - while (sq->cc != sq->pc) { - ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sq->cc); + sqcc = sq->cc; + dma_fifo_cc = sq->dma_fifo_cc; + + while (sqcc != sq->pc) { + ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sqcc); wi = &sq->db.wqe_info[ci]; skb = wi->skb; if (!skb) { - sq->cc += wi->num_wqebbs; + mlx5e_ktls_tx_handle_resync_dump_comp(sq, wi, &dma_fifo_cc); + sqcc += wi->num_wqebbs; continue; } for (i = 0; i < wi->num_dma; i++) { struct mlx5e_sq_dma *dma = - mlx5e_dma_get(sq, sq->dma_fifo_cc++); + mlx5e_dma_get(sq, dma_fifo_cc++); mlx5e_tx_dma_unmap(sq->pdev, dma); } dev_kfree_skb_any(skb); - sq->cc += wi->num_wqebbs; + sqcc += wi->num_wqebbs; } + + sq->dma_fifo_cc = dma_fifo_cc; + sq->cc = sqcc; } #ifdef CONFIG_MLX5_CORE_IPOIB -- GitLab From 9b1fef2f23c1141c9936debe633ff16e44c6137b Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Sun, 1 Sep 2019 13:53:26 +0300 Subject: [PATCH 478/993] net/mlx5e: kTLS, Size of a Dump WQE is fixed No Eth segment, so no dynamic inline headers. The size of a Dump WQE is fixed, use constants and remove unnecessary checks. Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support") Signed-off-by: Tariq Toukan Reviewed-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed --- .../net/ethernet/mellanox/mlx5/core/en/txrx.h | 2 +- .../ethernet/mellanox/mlx5/core/en_accel/ktls.h | 9 ++++++++- .../mellanox/mlx5/core/en_accel/ktls_tx.c | 17 +++-------------- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h index 182d5c5664eb..25f9dda578ac 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h @@ -23,7 +23,7 @@ #define MLX5E_SQ_TLS_ROOM \ (MLX5_SEND_WQE_MAX_WQEBBS + \ MLX5E_KTLS_STATIC_WQEBBS + MLX5E_KTLS_PROGRESS_WQEBBS + \ - MAX_SKB_FRAGS * MLX5E_KTLS_MAX_DUMP_WQEBBS) + MAX_SKB_FRAGS * MLX5E_KTLS_DUMP_WQEBBS) #endif #define INL_HDR_START_SZ (sizeof(((struct mlx5_wqe_eth_seg *)NULL)->inline_hdr.start)) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h index c4c128908b6e..eb692feba4a6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h @@ -21,7 +21,14 @@ MLX5_ST_SZ_BYTES(tls_progress_params)) #define MLX5E_KTLS_PROGRESS_WQEBBS \ (DIV_ROUND_UP(MLX5E_KTLS_PROGRESS_WQE_SZ, MLX5_SEND_WQE_BB)) -#define MLX5E_KTLS_MAX_DUMP_WQEBBS 2 + +struct mlx5e_dump_wqe { + struct mlx5_wqe_ctrl_seg ctrl; + struct mlx5_wqe_data_seg data; +}; + +#define MLX5E_KTLS_DUMP_WQEBBS \ + (DIV_ROUND_UP(sizeof(struct mlx5e_dump_wqe), MLX5_SEND_WQE_BB)) enum { MLX5E_TLS_PROGRESS_PARAMS_AUTH_STATE_NO_OFFLOAD = 0, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c index 90c6ce530a18..ac54767b7d86 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c @@ -250,11 +250,6 @@ tx_post_resync_params(struct mlx5e_txqsq *sq, mlx5e_ktls_tx_post_param_wqes(sq, priv_tx, skip_static_post, true); } -struct mlx5e_dump_wqe { - struct mlx5_wqe_ctrl_seg ctrl; - struct mlx5_wqe_data_seg data; -}; - static int tx_post_resync_dump(struct mlx5e_txqsq *sq, skb_frag_t *frag, u32 tisn, bool first) { @@ -262,7 +257,6 @@ tx_post_resync_dump(struct mlx5e_txqsq *sq, skb_frag_t *frag, u32 tisn, bool fir struct mlx5_wqe_data_seg *dseg; struct mlx5e_dump_wqe *wqe; dma_addr_t dma_addr = 0; - u8 num_wqebbs; u16 ds_cnt; int fsz; u16 pi; @@ -270,7 +264,6 @@ tx_post_resync_dump(struct mlx5e_txqsq *sq, skb_frag_t *frag, u32 tisn, bool fir wqe = mlx5e_sq_fetch_wqe(sq, sizeof(*wqe), &pi); ds_cnt = sizeof(*wqe) / MLX5_SEND_WQE_DS; - num_wqebbs = DIV_ROUND_UP(ds_cnt, MLX5_SEND_WQEBB_NUM_DS); cseg = &wqe->ctrl; dseg = &wqe->data; @@ -291,12 +284,8 @@ tx_post_resync_dump(struct mlx5e_txqsq *sq, skb_frag_t *frag, u32 tisn, bool fir dseg->byte_count = cpu_to_be32(fsz); mlx5e_dma_push(sq, dma_addr, fsz, MLX5E_DMA_MAP_PAGE); - tx_fill_wi(sq, pi, num_wqebbs, frag, fsz); - sq->pc += num_wqebbs; - - WARN(num_wqebbs > MLX5E_KTLS_MAX_DUMP_WQEBBS, - "unexpected DUMP num_wqebbs, %d > %d", - num_wqebbs, MLX5E_KTLS_MAX_DUMP_WQEBBS); + tx_fill_wi(sq, pi, MLX5E_KTLS_DUMP_WQEBBS, frag, fsz); + sq->pc += MLX5E_KTLS_DUMP_WQEBBS; return 0; } @@ -368,7 +357,7 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, stats->tls_ooo++; num_wqebbs = MLX5E_KTLS_STATIC_WQEBBS + MLX5E_KTLS_PROGRESS_WQEBBS + - (info.nr_frags ? info.nr_frags * MLX5E_KTLS_MAX_DUMP_WQEBBS : 1); + (info.nr_frags ? info.nr_frags * MLX5E_KTLS_DUMP_WQEBBS : 1); pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc); contig_wqebbs_room = mlx5_wq_cyc_get_contig_wqebbs(wq, pi); if (unlikely(contig_wqebbs_room < num_wqebbs)) -- GitLab From f45da3716fb2fb09e301a1b6edf200ff343dc06e Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Wed, 18 Sep 2019 13:50:32 +0300 Subject: [PATCH 479/993] net/mlx5e: kTLS, Save only the frag page to release at completion In TX resync flow where DUMP WQEs are posted, keep a pointer to the fragment page to unref it upon completion, instead of saving the whole fragment. In addition, move it the end of the arguments list in tx_fill_wi(). Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support") Signed-off-by: Tariq Toukan Reviewed-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en.h | 2 +- .../mellanox/mlx5/core/en_accel/ktls_tx.c | 27 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index 8d76452cacdc..cb6f7b87e38f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -345,7 +345,7 @@ struct mlx5e_tx_wqe_info { u8 num_wqebbs; u8 num_dma; #ifdef CONFIG_MLX5_EN_TLS - skb_frag_t *resync_dump_frag; + struct page *resync_dump_frag_page; #endif }; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c index ac54767b7d86..6dfb22d705b2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c @@ -108,16 +108,15 @@ build_progress_params(struct mlx5e_tx_wqe *wqe, u16 pc, u32 sqn, } static void tx_fill_wi(struct mlx5e_txqsq *sq, - u16 pi, u8 num_wqebbs, - skb_frag_t *resync_dump_frag, - u32 num_bytes) + u16 pi, u8 num_wqebbs, u32 num_bytes, + struct page *page) { struct mlx5e_tx_wqe_info *wi = &sq->db.wqe_info[pi]; - wi->skb = NULL; - wi->num_wqebbs = num_wqebbs; - wi->resync_dump_frag = resync_dump_frag; - wi->num_bytes = num_bytes; + memset(wi, 0, sizeof(*wi)); + wi->num_wqebbs = num_wqebbs; + wi->num_bytes = num_bytes; + wi->resync_dump_frag_page = page; } void mlx5e_ktls_tx_offload_set_pending(struct mlx5e_ktls_offload_context_tx *priv_tx) @@ -145,7 +144,7 @@ post_static_params(struct mlx5e_txqsq *sq, umr_wqe = mlx5e_sq_fetch_wqe(sq, MLX5E_KTLS_STATIC_UMR_WQE_SZ, &pi); build_static_params(umr_wqe, sq->pc, sq->sqn, priv_tx, fence); - tx_fill_wi(sq, pi, MLX5E_KTLS_STATIC_WQEBBS, NULL, 0); + tx_fill_wi(sq, pi, MLX5E_KTLS_STATIC_WQEBBS, 0, NULL); sq->pc += MLX5E_KTLS_STATIC_WQEBBS; } @@ -159,7 +158,7 @@ post_progress_params(struct mlx5e_txqsq *sq, wqe = mlx5e_sq_fetch_wqe(sq, MLX5E_KTLS_PROGRESS_WQE_SZ, &pi); build_progress_params(wqe, sq->pc, sq->sqn, priv_tx, fence); - tx_fill_wi(sq, pi, MLX5E_KTLS_PROGRESS_WQEBBS, NULL, 0); + tx_fill_wi(sq, pi, MLX5E_KTLS_PROGRESS_WQEBBS, 0, NULL); sq->pc += MLX5E_KTLS_PROGRESS_WQEBBS; } @@ -211,7 +210,7 @@ static bool tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx, while (remaining > 0) { skb_frag_t *frag = &record->frags[i]; - __skb_frag_ref(frag); + get_page(skb_frag_page(frag)); remaining -= skb_frag_size(frag); info->frags[i++] = frag; } @@ -284,7 +283,7 @@ tx_post_resync_dump(struct mlx5e_txqsq *sq, skb_frag_t *frag, u32 tisn, bool fir dseg->byte_count = cpu_to_be32(fsz); mlx5e_dma_push(sq, dma_addr, fsz, MLX5E_DMA_MAP_PAGE); - tx_fill_wi(sq, pi, MLX5E_KTLS_DUMP_WQEBBS, frag, fsz); + tx_fill_wi(sq, pi, MLX5E_KTLS_DUMP_WQEBBS, fsz, skb_frag_page(frag)); sq->pc += MLX5E_KTLS_DUMP_WQEBBS; return 0; @@ -297,14 +296,14 @@ void mlx5e_ktls_tx_handle_resync_dump_comp(struct mlx5e_txqsq *sq, struct mlx5e_sq_stats *stats; struct mlx5e_sq_dma *dma; - if (!wi->resync_dump_frag) + if (!wi->resync_dump_frag_page) return; dma = mlx5e_dma_get(sq, (*dma_fifo_cc)++); stats = sq->stats; mlx5e_tx_dma_unmap(sq->pdev, dma); - __skb_frag_unref(wi->resync_dump_frag); + put_page(wi->resync_dump_frag_page); stats->tls_dump_packets++; stats->tls_dump_bytes += wi->num_bytes; } @@ -314,7 +313,7 @@ static void tx_post_fence_nop(struct mlx5e_txqsq *sq) struct mlx5_wq_cyc *wq = &sq->wq; u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc); - tx_fill_wi(sq, pi, 1, NULL, 0); + tx_fill_wi(sq, pi, 1, 0, NULL); mlx5e_post_nop_fence(wq, sq->sqn, &sq->pc); } -- GitLab From 310d9b9d37220b590909e90e724fc5f346a98775 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Wed, 18 Sep 2019 13:57:40 +0300 Subject: [PATCH 480/993] net/mlx5e: kTLS, Save by-value copy of the record frags Access the record fragments only under the TLS ctx lock. In the resync flow, save a copy of them to be used when preparing and posting the required DUMP WQEs. Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support") Signed-off-by: Tariq Toukan Reviewed-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed --- .../net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c index 6dfb22d705b2..334808b1863b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c @@ -179,7 +179,7 @@ struct tx_sync_info { u64 rcd_sn; s32 sync_len; int nr_frags; - skb_frag_t *frags[MAX_SKB_FRAGS]; + skb_frag_t frags[MAX_SKB_FRAGS]; }; static bool tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx, @@ -212,11 +212,11 @@ static bool tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx, get_page(skb_frag_page(frag)); remaining -= skb_frag_size(frag); - info->frags[i++] = frag; + info->frags[i++] = *frag; } /* reduce the part which will be sent with the original SKB */ if (remaining < 0) - skb_frag_size_add(info->frags[i - 1], remaining); + skb_frag_size_add(&info->frags[i - 1], remaining); info->nr_frags = i; out: spin_unlock_irqrestore(&tx_ctx->lock, flags); @@ -365,7 +365,7 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, tx_post_resync_params(sq, priv_tx, info.rcd_sn); for (i = 0; i < info.nr_frags; i++) - if (tx_post_resync_dump(sq, info.frags[i], priv_tx->tisn, !i)) + if (tx_post_resync_dump(sq, &info.frags[i], priv_tx->tisn, !i)) goto err_out; /* If no dump WQE was sent, we need to have a fence NOP WQE before the -- GitLab From b61b24bd135a7775a2839863bd1d58a462a5f1e5 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Wed, 18 Sep 2019 13:57:40 +0300 Subject: [PATCH 481/993] net/mlx5e: kTLS, Fix page refcnt leak in TX resync error flow All references for frag pages that are obtained in tx_sync_info_get() should be released. Release usually occurs in the corresponding CQE of the WQE. In error flows, not all fragments have a WQE posted for them, hence no matching CQE will be generated. For these pages, release the reference in the error flow. Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support") Signed-off-by: Tariq Toukan Reviewed-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c index 334808b1863b..5f1d18fb644e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c @@ -329,7 +329,7 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, struct tx_sync_info info = {}; u16 contig_wqebbs_room, pi; u8 num_wqebbs; - int i; + int i = 0; if (!tx_sync_info_get(priv_tx, seq, &info)) { /* We might get here if a retransmission reaches the driver @@ -364,7 +364,7 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, tx_post_resync_params(sq, priv_tx, info.rcd_sn); - for (i = 0; i < info.nr_frags; i++) + for (; i < info.nr_frags; i++) if (tx_post_resync_dump(sq, &info.frags[i], priv_tx->tisn, !i)) goto err_out; @@ -377,6 +377,9 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, return skb; err_out: + for (; i < info.nr_frags; i++) + put_page(skb_frag_page(&info.frags[i])); + dev_kfree_skb_any(skb); return NULL; } -- GitLab From 700ec497424069fa4d8f3715759c4aaec016e840 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Mon, 7 Oct 2019 13:59:11 +0300 Subject: [PATCH 482/993] net/mlx5e: kTLS, Fix missing SQ edge fill Before posting the context params WQEs, make sure there is enough contiguous room for them, and fill frag edge if needed. When posting only a nop, no need for room check, as it needs a single WQEBB, meaning no contiguity issue. Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support") Signed-off-by: Tariq Toukan Reviewed-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed --- .../mellanox/mlx5/core/en_accel/ktls_tx.c | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c index 5f1d18fb644e..59e3f48470d9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c @@ -168,6 +168,14 @@ mlx5e_ktls_tx_post_param_wqes(struct mlx5e_txqsq *sq, bool skip_static_post, bool fence_first_post) { bool progress_fence = skip_static_post || !fence_first_post; + struct mlx5_wq_cyc *wq = &sq->wq; + u16 contig_wqebbs_room, pi; + + pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc); + contig_wqebbs_room = mlx5_wq_cyc_get_contig_wqebbs(wq, pi); + if (unlikely(contig_wqebbs_room < + MLX5E_KTLS_STATIC_WQEBBS + MLX5E_KTLS_PROGRESS_WQEBBS)) + mlx5e_fill_sq_frag_edge(sq, wq, pi, contig_wqebbs_room); if (!skip_static_post) post_static_params(sq, priv_tx, fence_first_post); @@ -355,10 +363,20 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, stats->tls_ooo++; - num_wqebbs = MLX5E_KTLS_STATIC_WQEBBS + MLX5E_KTLS_PROGRESS_WQEBBS + - (info.nr_frags ? info.nr_frags * MLX5E_KTLS_DUMP_WQEBBS : 1); + tx_post_resync_params(sq, priv_tx, info.rcd_sn); + + /* If no dump WQE was sent, we need to have a fence NOP WQE before the + * actual data xmit. + */ + if (!info.nr_frags) { + tx_post_fence_nop(sq); + return skb; + } + + num_wqebbs = info.nr_frags * MLX5E_KTLS_DUMP_WQEBBS; pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc); contig_wqebbs_room = mlx5_wq_cyc_get_contig_wqebbs(wq, pi); + if (unlikely(contig_wqebbs_room < num_wqebbs)) mlx5e_fill_sq_frag_edge(sq, wq, pi, contig_wqebbs_room); @@ -368,12 +386,6 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, if (tx_post_resync_dump(sq, &info.frags[i], priv_tx->tisn, !i)) goto err_out; - /* If no dump WQE was sent, we need to have a fence NOP WQE before the - * actual data xmit. - */ - if (!info.nr_frags) - tx_post_fence_nop(sq); - return skb; err_out: -- GitLab From 84d1bb2b139e0184b1754aa1b5776186b475fce8 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Mon, 7 Oct 2019 14:01:29 +0300 Subject: [PATCH 483/993] net/mlx5e: kTLS, Limit DUMP wqe size HW expects the data size in DUMP WQEs to be up to MTU. Make sure they are in range. We elevate the frag page refcount by 'n-1', in addition to the one obtained in tx_sync_info_get(), having an overall of 'n' references. We bulk increments by using a single page_ref_add() command, to optimize perfermance. The refcounts are released one by one, by the corresponding completions. Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support") Signed-off-by: Tariq Toukan Reviewed-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en.h | 1 + .../net/ethernet/mellanox/mlx5/core/en/txrx.h | 11 +++--- .../mellanox/mlx5/core/en_accel/ktls.h | 11 +++++- .../mellanox/mlx5/core/en_accel/ktls_tx.c | 34 ++++++++++++++++--- .../net/ethernet/mellanox/mlx5/core/en_main.c | 7 +++- 5 files changed, 52 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index cb6f7b87e38f..f1a7bc46f1c0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -410,6 +410,7 @@ struct mlx5e_txqsq { struct device *pdev; __be32 mkey_be; unsigned long state; + unsigned int hw_mtu; struct hwtstamp_config *tstamp; struct mlx5_clock *clock; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h index 25f9dda578ac..7c8796d9743f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h @@ -15,15 +15,14 @@ #else /* TLS offload requires additional stop_room for: * - a resync SKB. - * kTLS offload requires additional stop_room for: - * - static params WQE, - * - progress params WQE, and - * - resync DUMP per frag. + * kTLS offload requires fixed additional stop_room for: + * - a static params WQE, and a progress params WQE. + * The additional MTU-depending room for the resync DUMP WQEs + * will be calculated and added in runtime. */ #define MLX5E_SQ_TLS_ROOM \ (MLX5_SEND_WQE_MAX_WQEBBS + \ - MLX5E_KTLS_STATIC_WQEBBS + MLX5E_KTLS_PROGRESS_WQEBBS + \ - MAX_SKB_FRAGS * MLX5E_KTLS_DUMP_WQEBBS) + MLX5E_KTLS_STATIC_WQEBBS + MLX5E_KTLS_PROGRESS_WQEBBS) #endif #define INL_HDR_START_SZ (sizeof(((struct mlx5_wqe_eth_seg *)NULL)->inline_hdr.start)) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h index eb692feba4a6..929966e6fbc4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h @@ -94,7 +94,16 @@ struct sk_buff *mlx5e_ktls_handle_tx_skb(struct net_device *netdev, void mlx5e_ktls_tx_handle_resync_dump_comp(struct mlx5e_txqsq *sq, struct mlx5e_tx_wqe_info *wi, u32 *dma_fifo_cc); - +static inline u8 +mlx5e_ktls_dumps_num_wqebbs(struct mlx5e_txqsq *sq, unsigned int nfrags, + unsigned int sync_len) +{ + /* Given the MTU and sync_len, calculates an upper bound for the + * number of WQEBBs needed for the TX resync DUMP WQEs of a record. + */ + return MLX5E_KTLS_DUMP_WQEBBS * + (nfrags + DIV_ROUND_UP(sync_len, sq->hw_mtu)); +} #else static inline void mlx5e_ktls_build_netdev(struct mlx5e_priv *priv) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c index 59e3f48470d9..e10b0bb696da 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c @@ -373,7 +373,7 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, return skb; } - num_wqebbs = info.nr_frags * MLX5E_KTLS_DUMP_WQEBBS; + num_wqebbs = mlx5e_ktls_dumps_num_wqebbs(sq, info.nr_frags, info.sync_len); pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc); contig_wqebbs_room = mlx5_wq_cyc_get_contig_wqebbs(wq, pi); @@ -382,14 +382,40 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, tx_post_resync_params(sq, priv_tx, info.rcd_sn); - for (; i < info.nr_frags; i++) - if (tx_post_resync_dump(sq, &info.frags[i], priv_tx->tisn, !i)) - goto err_out; + for (; i < info.nr_frags; i++) { + unsigned int orig_fsz, frag_offset = 0, n = 0; + skb_frag_t *f = &info.frags[i]; + + orig_fsz = skb_frag_size(f); + + do { + bool fence = !(i || frag_offset); + unsigned int fsz; + + n++; + fsz = min_t(unsigned int, sq->hw_mtu, orig_fsz - frag_offset); + skb_frag_size_set(f, fsz); + if (tx_post_resync_dump(sq, f, priv_tx->tisn, fence)) { + page_ref_add(skb_frag_page(f), n - 1); + goto err_out; + } + + skb_frag_off_add(f, fsz); + frag_offset += fsz; + } while (frag_offset < orig_fsz); + + page_ref_add(skb_frag_page(f), n - 1); + } return skb; err_out: for (; i < info.nr_frags; i++) + /* The put_page() here undoes the page ref obtained in tx_sync_info_get(). + * Page refs obtained for the DUMP WQEs above (by page_ref_add) will be + * released only upon their completions (or in mlx5e_free_txqsq_descs, + * if channel closes). + */ put_page(skb_frag_page(&info.frags[i])); dev_kfree_skb_any(skb); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index b476b007f093..772bfdbdeb9c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -1128,6 +1128,7 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c, sq->txq_ix = txq_ix; sq->uar_map = mdev->mlx5e_res.bfreg.map; sq->min_inline_mode = params->tx_min_inline_mode; + sq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); sq->stats = &c->priv->channel_stats[c->ix].sq[tc]; sq->stop_room = MLX5E_SQ_STOP_ROOM; INIT_WORK(&sq->recover_work, mlx5e_tx_err_cqe_work); @@ -1135,10 +1136,14 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c, set_bit(MLX5E_SQ_STATE_VLAN_NEED_L2_INLINE, &sq->state); if (MLX5_IPSEC_DEV(c->priv->mdev)) set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state); +#ifdef CONFIG_MLX5_EN_TLS if (mlx5_accel_is_tls_device(c->priv->mdev)) { set_bit(MLX5E_SQ_STATE_TLS, &sq->state); - sq->stop_room += MLX5E_SQ_TLS_ROOM; + sq->stop_room += MLX5E_SQ_TLS_ROOM + + mlx5e_ktls_dumps_num_wqebbs(sq, MAX_SKB_FRAGS, + TLS_MAX_PAYLOAD_SIZE); } +#endif param->wq.db_numa_node = cpu_to_node(c->cpu); err = mlx5_wq_cyc_create(mdev, ¶m->wq, sqc_wq, wq, &sq->wq_ctrl); -- GitLab From ecdc65a3ec5d45725355479d63c23a20f4582104 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Sun, 6 Oct 2019 18:25:17 +0300 Subject: [PATCH 484/993] net/mlx5e: kTLS, Remove unneeded cipher type checks Cipher type is checked upon connection addition. No need to recheck it per every TX resync invocation. Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support") Signed-off-by: Tariq Toukan Reviewed-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c index e10b0bb696da..1bfeb558ff78 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c @@ -31,9 +31,6 @@ fill_static_params_ctx(void *ctx, struct mlx5e_ktls_offload_context_tx *priv_tx) char *salt, *rec_seq; u8 tls_version; - if (WARN_ON(crypto_info->cipher_type != TLS_CIPHER_AES_GCM_128)) - return; - info = (struct tls12_crypto_info_aes_gcm_128 *)crypto_info; EXTRACT_INFO_FIELDS; @@ -243,9 +240,6 @@ tx_post_resync_params(struct mlx5e_txqsq *sq, u16 rec_seq_sz; char *rec_seq; - if (WARN_ON(crypto_info->cipher_type != TLS_CIPHER_AES_GCM_128)) - return; - info = (struct tls12_crypto_info_aes_gcm_128 *)crypto_info; rec_seq = info->rec_seq; rec_seq_sz = sizeof(info->rec_seq); -- GitLab From af11a7a42454b17c77da5fa55b6b6325b11d60e5 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Sun, 22 Sep 2019 14:05:24 +0300 Subject: [PATCH 485/993] net/mlx5e: kTLS, Save a copy of the crypto info Do not assume the crypto info is accessible during the connection lifetime. Save a copy of it in the private TX context. Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support") Signed-off-by: Tariq Toukan Reviewed-by: Eran Ben Elisha Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h | 2 +- .../net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c | 8 ++------ 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c index d2ff74d52720..46725cd743a3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c @@ -38,7 +38,7 @@ static int mlx5e_ktls_add(struct net_device *netdev, struct sock *sk, return -ENOMEM; tx_priv->expected_seq = start_offload_tcp_sn; - tx_priv->crypto_info = crypto_info; + tx_priv->crypto_info = *(struct tls12_crypto_info_aes_gcm_128 *)crypto_info; mlx5e_set_ktls_tx_priv_ctx(tls_ctx, tx_priv); /* tc and underlay_qpn values are not in use for tls tis */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h index 929966e6fbc4..a3efa29a4629 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h @@ -44,7 +44,7 @@ enum { struct mlx5e_ktls_offload_context_tx { struct tls_offload_context_tx *tx_ctx; - struct tls_crypto_info *crypto_info; + struct tls12_crypto_info_aes_gcm_128 crypto_info; u32 expected_seq; u32 tisn; u32 key_id; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c index 1bfeb558ff78..badc6fd26a14 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c @@ -24,14 +24,12 @@ enum { static void fill_static_params_ctx(void *ctx, struct mlx5e_ktls_offload_context_tx *priv_tx) { - struct tls_crypto_info *crypto_info = priv_tx->crypto_info; - struct tls12_crypto_info_aes_gcm_128 *info; + struct tls12_crypto_info_aes_gcm_128 *info = &priv_tx->crypto_info; char *initial_rn, *gcm_iv; u16 salt_sz, rec_seq_sz; char *salt, *rec_seq; u8 tls_version; - info = (struct tls12_crypto_info_aes_gcm_128 *)crypto_info; EXTRACT_INFO_FIELDS; gcm_iv = MLX5_ADDR_OF(tls_static_params, ctx, gcm_iv); @@ -233,14 +231,12 @@ tx_post_resync_params(struct mlx5e_txqsq *sq, struct mlx5e_ktls_offload_context_tx *priv_tx, u64 rcd_sn) { - struct tls_crypto_info *crypto_info = priv_tx->crypto_info; - struct tls12_crypto_info_aes_gcm_128 *info; + struct tls12_crypto_info_aes_gcm_128 *info = &priv_tx->crypto_info; __be64 rn_be = cpu_to_be64(rcd_sn); bool skip_static_post; u16 rec_seq_sz; char *rec_seq; - info = (struct tls12_crypto_info_aes_gcm_128 *)crypto_info; rec_seq = info->rec_seq; rec_seq_sz = sizeof(info->rec_seq); -- GitLab From 46a3ea98074e2a7731ab9b84ec60fc18a2f909e5 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Thu, 3 Oct 2019 10:48:10 +0300 Subject: [PATCH 486/993] net/mlx5e: kTLS, Enhance TX resync flow Once the kTLS TX resync function is called, it used to return a binary value, for success or failure. However, in case the TLS SKB is a retransmission of the connection handshake, it initiates the resync flow (as the tcp seq check holds), while regular packet handle is expected. In this patch, we identify this case and skip the resync operation accordingly. Counters: - Add a counter (tls_skip_no_sync_data) to monitor this. - Bump the dump counters up as they are used more frequently. - Add a missing counter descriptor declaration for tls_resync_bytes in sq_stats_desc. Fixes: d2ead1f360e8 ("net/mlx5e: Add kTLS TX HW offload support") Signed-off-by: Tariq Toukan Signed-off-by: Saeed Mahameed --- .../mellanox/mlx5/core/en_accel/ktls_tx.c | 58 +++++++++++-------- .../ethernet/mellanox/mlx5/core/en_stats.c | 16 +++-- .../ethernet/mellanox/mlx5/core/en_stats.h | 10 ++-- 3 files changed, 51 insertions(+), 33 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c index badc6fd26a14..778dab1af8fc 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c @@ -185,26 +185,33 @@ struct tx_sync_info { skb_frag_t frags[MAX_SKB_FRAGS]; }; -static bool tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx, - u32 tcp_seq, struct tx_sync_info *info) +enum mlx5e_ktls_sync_retval { + MLX5E_KTLS_SYNC_DONE, + MLX5E_KTLS_SYNC_FAIL, + MLX5E_KTLS_SYNC_SKIP_NO_DATA, +}; + +static enum mlx5e_ktls_sync_retval +tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx, + u32 tcp_seq, struct tx_sync_info *info) { struct tls_offload_context_tx *tx_ctx = priv_tx->tx_ctx; + enum mlx5e_ktls_sync_retval ret = MLX5E_KTLS_SYNC_DONE; struct tls_record_info *record; int remaining, i = 0; unsigned long flags; - bool ret = true; spin_lock_irqsave(&tx_ctx->lock, flags); record = tls_get_record(tx_ctx, tcp_seq, &info->rcd_sn); if (unlikely(!record)) { - ret = false; + ret = MLX5E_KTLS_SYNC_FAIL; goto out; } if (unlikely(tcp_seq < tls_record_start_seq(record))) { - if (!tls_record_is_start_marker(record)) - ret = false; + ret = tls_record_is_start_marker(record) ? + MLX5E_KTLS_SYNC_SKIP_NO_DATA : MLX5E_KTLS_SYNC_FAIL; goto out; } @@ -316,20 +323,26 @@ static void tx_post_fence_nop(struct mlx5e_txqsq *sq) mlx5e_post_nop_fence(wq, sq->sqn, &sq->pc); } -static struct sk_buff * +static enum mlx5e_ktls_sync_retval mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, struct mlx5e_txqsq *sq, - struct sk_buff *skb, + int datalen, u32 seq) { struct mlx5e_sq_stats *stats = sq->stats; struct mlx5_wq_cyc *wq = &sq->wq; + enum mlx5e_ktls_sync_retval ret; struct tx_sync_info info = {}; u16 contig_wqebbs_room, pi; u8 num_wqebbs; int i = 0; - if (!tx_sync_info_get(priv_tx, seq, &info)) { + ret = tx_sync_info_get(priv_tx, seq, &info); + if (unlikely(ret != MLX5E_KTLS_SYNC_DONE)) { + if (ret == MLX5E_KTLS_SYNC_SKIP_NO_DATA) { + stats->tls_skip_no_sync_data++; + return MLX5E_KTLS_SYNC_SKIP_NO_DATA; + } /* We might get here if a retransmission reaches the driver * after the relevant record is acked. * It should be safe to drop the packet in this case @@ -339,13 +352,8 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, } if (unlikely(info.sync_len < 0)) { - u32 payload; - int headln; - - headln = skb_transport_offset(skb) + tcp_hdrlen(skb); - payload = skb->len - headln; - if (likely(payload <= -info.sync_len)) - return skb; + if (likely(datalen <= -info.sync_len)) + return MLX5E_KTLS_SYNC_DONE; stats->tls_drop_bypass_req++; goto err_out; @@ -360,7 +368,7 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, */ if (!info.nr_frags) { tx_post_fence_nop(sq); - return skb; + return MLX5E_KTLS_SYNC_DONE; } num_wqebbs = mlx5e_ktls_dumps_num_wqebbs(sq, info.nr_frags, info.sync_len); @@ -397,7 +405,7 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, page_ref_add(skb_frag_page(f), n - 1); } - return skb; + return MLX5E_KTLS_SYNC_DONE; err_out: for (; i < info.nr_frags; i++) @@ -408,8 +416,7 @@ mlx5e_ktls_tx_handle_ooo(struct mlx5e_ktls_offload_context_tx *priv_tx, */ put_page(skb_frag_page(&info.frags[i])); - dev_kfree_skb_any(skb); - return NULL; + return MLX5E_KTLS_SYNC_FAIL; } struct sk_buff *mlx5e_ktls_handle_tx_skb(struct net_device *netdev, @@ -445,10 +452,15 @@ struct sk_buff *mlx5e_ktls_handle_tx_skb(struct net_device *netdev, seq = ntohl(tcp_hdr(skb)->seq); if (unlikely(priv_tx->expected_seq != seq)) { - skb = mlx5e_ktls_tx_handle_ooo(priv_tx, sq, skb, seq); - if (unlikely(!skb)) + enum mlx5e_ktls_sync_retval ret = + mlx5e_ktls_tx_handle_ooo(priv_tx, sq, datalen, seq); + + if (likely(ret == MLX5E_KTLS_SYNC_DONE)) + *wqe = mlx5e_sq_fetch_wqe(sq, sizeof(**wqe), pi); + else if (ret == MLX5E_KTLS_SYNC_FAIL) + goto err_out; + else /* ret == MLX5E_KTLS_SYNC_SKIP_NO_DATA */ goto out; - *wqe = mlx5e_sq_fetch_wqe(sq, sizeof(**wqe), pi); } priv_tx->expected_seq = seq + datalen; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c index ac6fdcda7019..7e6ebd0505cc 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c @@ -52,11 +52,12 @@ static const struct counter_desc sw_stats_desc[] = { { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_encrypted_bytes) }, { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_ctx) }, { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_ooo) }, + { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_dump_packets) }, + { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_dump_bytes) }, { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_resync_bytes) }, + { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_skip_no_sync_data) }, { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_drop_no_sync_data) }, { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_drop_bypass_req) }, - { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_dump_packets) }, - { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_dump_bytes) }, #endif { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_lro_packets) }, @@ -288,11 +289,12 @@ static void mlx5e_grp_sw_update_stats(struct mlx5e_priv *priv) s->tx_tls_encrypted_bytes += sq_stats->tls_encrypted_bytes; s->tx_tls_ctx += sq_stats->tls_ctx; s->tx_tls_ooo += sq_stats->tls_ooo; + s->tx_tls_dump_bytes += sq_stats->tls_dump_bytes; + s->tx_tls_dump_packets += sq_stats->tls_dump_packets; s->tx_tls_resync_bytes += sq_stats->tls_resync_bytes; + s->tx_tls_skip_no_sync_data += sq_stats->tls_skip_no_sync_data; s->tx_tls_drop_no_sync_data += sq_stats->tls_drop_no_sync_data; s->tx_tls_drop_bypass_req += sq_stats->tls_drop_bypass_req; - s->tx_tls_dump_bytes += sq_stats->tls_dump_bytes; - s->tx_tls_dump_packets += sq_stats->tls_dump_packets; #endif s->tx_cqes += sq_stats->cqes; } @@ -1472,10 +1474,12 @@ static const struct counter_desc sq_stats_desc[] = { { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_encrypted_bytes) }, { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_ctx) }, { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_ooo) }, - { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_drop_no_sync_data) }, - { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_drop_bypass_req) }, { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_dump_packets) }, { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_dump_bytes) }, + { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_resync_bytes) }, + { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_skip_no_sync_data) }, + { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_drop_no_sync_data) }, + { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_drop_bypass_req) }, #endif { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_none) }, { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, stopped) }, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h index 79f261bf86ac..869f3502f631 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h @@ -129,11 +129,12 @@ struct mlx5e_sw_stats { u64 tx_tls_encrypted_bytes; u64 tx_tls_ctx; u64 tx_tls_ooo; + u64 tx_tls_dump_packets; + u64 tx_tls_dump_bytes; u64 tx_tls_resync_bytes; + u64 tx_tls_skip_no_sync_data; u64 tx_tls_drop_no_sync_data; u64 tx_tls_drop_bypass_req; - u64 tx_tls_dump_packets; - u64 tx_tls_dump_bytes; #endif u64 rx_xsk_packets; @@ -273,11 +274,12 @@ struct mlx5e_sq_stats { u64 tls_encrypted_bytes; u64 tls_ctx; u64 tls_ooo; + u64 tls_dump_packets; + u64 tls_dump_bytes; u64 tls_resync_bytes; + u64 tls_skip_no_sync_data; u64 tls_drop_no_sync_data; u64 tls_drop_bypass_req; - u64 tls_dump_packets; - u64 tls_dump_bytes; #endif /* less likely accessed in data path */ u64 csum_none; -- GitLab From 61ea02d2c13106116c6e4916ac5d9dd41151c959 Mon Sep 17 00:00:00 2001 From: Tariq Toukan Date: Tue, 24 Sep 2019 11:29:09 +0300 Subject: [PATCH 487/993] net/mlx5e: TX, Fix consumer index of error cqe dump The completion queue consumer index increments upon a call to mlx5_cqwq_pop(). When dumping an error CQE, the index is already incremented. Decrease one for the print command. Fixes: 16cc14d81733 ("net/mlx5e: Dump xmit error completions") Signed-off-by: Tariq Toukan Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c index 8dd8f0be101b..67dc4f0921b6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c @@ -403,7 +403,10 @@ netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev) static void mlx5e_dump_error_cqe(struct mlx5e_txqsq *sq, struct mlx5_err_cqe *err_cqe) { - u32 ci = mlx5_cqwq_get_ci(&sq->cq.wq); + struct mlx5_cqwq *wq = &sq->cq.wq; + u32 ci; + + ci = mlx5_cqwq_ctr2ix(wq, wq->cc - 1); netdev_err(sq->channel->netdev, "Error cqe on cqn 0x%x, ci 0x%x, sqn 0x%x, opcode 0x%x, syndrome 0x%x, vendor syndrome 0x%x\n", -- GitLab From c8c2a057fdc7de1cd16f4baa51425b932a42eb39 Mon Sep 17 00:00:00 2001 From: Navid Emamdoost Date: Tue, 24 Sep 2019 22:20:34 -0500 Subject: [PATCH 488/993] net/mlx5: prevent memory leak in mlx5_fpga_conn_create_cq In mlx5_fpga_conn_create_cq if mlx5_vector2eqn fails the allocated memory should be released. Fixes: 537a50574175 ("net/mlx5: FPGA, Add high-speed connection routines") Signed-off-by: Navid Emamdoost Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c index 4c50efe4e7f1..61021133029e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c @@ -464,8 +464,10 @@ static int mlx5_fpga_conn_create_cq(struct mlx5_fpga_conn *conn, int cq_size) } err = mlx5_vector2eqn(mdev, smp_processor_id(), &eqn, &irqn); - if (err) + if (err) { + kvfree(in); goto err_cqwq; + } cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context); MLX5_SET(cqc, cqc, log_cq_size, ilog2(cq_size)); -- GitLab From c7ed6d0183d5ea9bc31bcaeeba4070bd62546471 Mon Sep 17 00:00:00 2001 From: Navid Emamdoost Date: Fri, 27 Sep 2019 17:37:28 -0500 Subject: [PATCH 489/993] net/mlx5: fix memory leak in mlx5_fw_fatal_reporter_dump In mlx5_fw_fatal_reporter_dump if mlx5_crdump_collect fails the allocated memory for cr_data must be released otherwise there will be memory leak. To fix this, this commit changes the return instruction into goto error handling. Fixes: 9b1f29823605 ("net/mlx5: Add support for FW fatal reporter dump") Signed-off-by: Navid Emamdoost Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/health.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c index d685122d9ff7..c07f3154437c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/health.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c @@ -572,7 +572,7 @@ mlx5_fw_fatal_reporter_dump(struct devlink_health_reporter *reporter, return -ENOMEM; err = mlx5_crdump_collect(dev, cr_data); if (err) - return err; + goto free_data; if (priv_ctx) { struct mlx5_fw_reporter_ctx *fw_reporter_ctx = priv_ctx; -- GitLab From 11875ba7f251c52effb2b924e04c2ddefa9856ef Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Fri, 18 Oct 2019 14:00:42 +0200 Subject: [PATCH 490/993] selftests/bpf: More compatible nc options in test_tc_edt Out of the three nc implementations widely in use, at least two (BSD netcat and nmap-ncat) do not support -l combined with -s. Modify the nc invocation to be accepted by all of them. Fixes: 7df5e3db8f63 ("selftests: bpf: tc-bpf flow shaping with EDT") Signed-off-by: Jiri Benc Signed-off-by: Daniel Borkmann Acked-by: Peter Oskolkov Link: https://lore.kernel.org/bpf/f5bf07dccd8b552a76c84d49e80b86c5aa071122.1571400024.git.jbenc@redhat.com --- tools/testing/selftests/bpf/test_tc_edt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/test_tc_edt.sh b/tools/testing/selftests/bpf/test_tc_edt.sh index f38567ef694b..daa7d1b8d309 100755 --- a/tools/testing/selftests/bpf/test_tc_edt.sh +++ b/tools/testing/selftests/bpf/test_tc_edt.sh @@ -59,7 +59,7 @@ ip netns exec ${NS_SRC} tc filter add dev veth_src egress \ # start the listener ip netns exec ${NS_DST} bash -c \ - "nc -4 -l -s ${IP_DST} -p 9000 >/dev/null &" + "nc -4 -l -p 9000 >/dev/null &" declare -i NC_PID=$! sleep 1 -- GitLab From 66cf50e65b183c863825f5c28a818e3f47a72e40 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 18 Oct 2019 16:04:58 +0200 Subject: [PATCH 491/993] scsi: qla2xxx: fixup incorrect usage of host_byte DRIVER_ERROR is a a driver byte setting, not a host byte. The qla2xxx driver should rather return DID_ERROR here to be in line with the other drivers. Link: https://lore.kernel.org/r/20191018140458.108278-1-hare@suse.de Signed-off-by: Hannes Reinecke Acked-by: Himanshu Madhani Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_bsg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 28d587a89ba6..99f0a1a08143 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -253,7 +253,7 @@ qla2x00_process_els(struct bsg_job *bsg_job) srb_t *sp; const char *type; int req_sg_cnt, rsp_sg_cnt; - int rval = (DRIVER_ERROR << 16); + int rval = (DID_ERROR << 16); uint16_t nextlid = 0; if (bsg_request->msgcode == FC_BSG_RPT_ELS) { @@ -432,7 +432,7 @@ qla2x00_process_ct(struct bsg_job *bsg_job) struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; - int rval = (DRIVER_ERROR << 16); + int rval = (DID_ERROR << 16); int req_sg_cnt, rsp_sg_cnt; uint16_t loop_id; struct fc_port *fcport; @@ -1950,7 +1950,7 @@ qlafx00_mgmt_cmd(struct bsg_job *bsg_job) struct Scsi_Host *host = fc_bsg_to_shost(bsg_job); scsi_qla_host_t *vha = shost_priv(host); struct qla_hw_data *ha = vha->hw; - int rval = (DRIVER_ERROR << 16); + int rval = (DID_ERROR << 16); struct qla_mt_iocb_rqst_fx00 *piocb_rqst; srb_t *sp; int req_sg_cnt = 0, rsp_sg_cnt = 0; -- GitLab From 0ad8f7aa9f7ea839409f7f15f155a73f4f2d08b3 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Wed, 16 Oct 2019 11:23:16 -0700 Subject: [PATCH 492/993] MAINTAINERS: Use @kernel.org address for Paul Burton Switch to using my paulburton@kernel.org email address in order to avoid subject mangling that's being imposed on my previous address. Signed-off-by: Paul Burton Signed-off-by: Paul Burton Cc: linux-kernel@vger.kernel.org --- .mailmap | 3 ++- MAINTAINERS | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.mailmap b/.mailmap index edcac87e76c8..10b27ecb61c0 100644 --- a/.mailmap +++ b/.mailmap @@ -196,7 +196,8 @@ Oleksij Rempel Oleksij Rempel Paolo 'Blaisorblade' Giarrusso Patrick Mochel -Paul Burton +Paul Burton +Paul Burton Peter A Jonsson Peter Oruba Peter Oruba diff --git a/MAINTAINERS b/MAINTAINERS index a69e6db80c79..6c4dc607074a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3096,7 +3096,7 @@ S: Supported F: arch/arm64/net/ BPF JIT for MIPS (32-BIT AND 64-BIT) -M: Paul Burton +M: Paul Burton L: netdev@vger.kernel.org L: bpf@vger.kernel.org S: Maintained @@ -8001,7 +8001,7 @@ S: Maintained F: drivers/usb/atm/ueagle-atm.c IMGTEC ASCII LCD DRIVER -M: Paul Burton +M: Paul Burton S: Maintained F: Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt F: drivers/auxdisplay/img-ascii-lcd.c @@ -10828,7 +10828,7 @@ F: drivers/usb/image/microtek.* MIPS M: Ralf Baechle -M: Paul Burton +M: Paul Burton M: James Hogan L: linux-mips@vger.kernel.org W: http://www.linux-mips.org/ @@ -10842,7 +10842,7 @@ F: arch/mips/ F: drivers/platform/mips/ MIPS BOSTON DEVELOPMENT BOARD -M: Paul Burton +M: Paul Burton L: linux-mips@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/clock/img,boston-clock.txt @@ -10852,7 +10852,7 @@ F: drivers/clk/imgtec/clk-boston.c F: include/dt-bindings/clock/boston-clock.h MIPS GENERIC PLATFORM -M: Paul Burton +M: Paul Burton L: linux-mips@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/power/mti,mips-cpc.txt -- GitLab From 8a1bef4193e81c8afae4d2f107f1c09c8ce89470 Mon Sep 17 00:00:00 2001 From: Vincenzo Frascino Date: Wed, 16 Oct 2019 14:40:24 +0100 Subject: [PATCH 493/993] mips: vdso: Fix __arch_get_hw_counter() On some MIPS variants (e.g. MIPS r1), vDSO clock_mode is set to VDSO_CLOCK_NONE. When VDSO_CLOCK_NONE is set the expected kernel behavior is to fallback on syscalls. To do that the generic vDSO library expects UULONG_MAX as return value of __arch_get_hw_counter(). Fix __arch_get_hw_counter() on MIPS defining a __VDSO_USE_SYSCALL case that addressed the described scenario. Reported-by: Maxime Bizon Signed-off-by: Vincenzo Frascino Tested-by: Maxime Bizon Signed-off-by: Paul Burton Cc: linux-mips@vger.kernel.org --- arch/mips/include/asm/vdso/gettimeofday.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/mips/include/asm/vdso/gettimeofday.h b/arch/mips/include/asm/vdso/gettimeofday.h index e78462e8ca2e..b08825531e9f 100644 --- a/arch/mips/include/asm/vdso/gettimeofday.h +++ b/arch/mips/include/asm/vdso/gettimeofday.h @@ -24,6 +24,8 @@ #define VDSO_HAS_CLOCK_GETRES 1 +#define __VDSO_USE_SYSCALL ULLONG_MAX + #ifdef CONFIG_MIPS_CLOCK_VSYSCALL static __always_inline long gettimeofday_fallback( @@ -205,7 +207,7 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode) break; #endif default: - cycle_now = 0; + cycle_now = __VDSO_USE_SYSCALL; break; } -- GitLab From 535fb49e730a6fe1e9f11af4ae67ef4228ff4287 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 18 Oct 2019 18:21:11 +0200 Subject: [PATCH 494/993] scsi: lpfc: Check queue pointer before use The queue pointer might not be valid. The rest of the code checks the pointer before accessing it. lpfc_sli4_process_missed_mbox_completions is the only place where the check is missing. Fixes: 657add4e5e15 ("scsi: lpfc: Fix poor use of hardware queues if fewer irq vectors") Cc: James Smart Link: https://lore.kernel.org/r/20191018162111.8798-1-dwagner@suse.de Signed-off-by: Daniel Wagner Reviewed-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_sli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index a0c6945b8139..614f78dddafe 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -7866,7 +7866,7 @@ lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba) if (sli4_hba->hdwq) { for (eqidx = 0; eqidx < phba->cfg_irq_chann; eqidx++) { eq = phba->sli4_hba.hba_eq_hdl[eqidx].eq; - if (eq->queue_id == sli4_hba->mbx_cq->assoc_qid) { + if (eq && eq->queue_id == sli4_hba->mbx_cq->assoc_qid) { fpeq = eq; break; } -- GitLab From 74e5e468b664d3739b2872d54764af97ac38e795 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Thu, 10 Oct 2019 11:31:07 +0300 Subject: [PATCH 495/993] scsi: ufs-bsg: Wake the device before sending raw upiu commands The scsi async probe process is calling blk_pm_runtime_init for each lun, and then those request queues are monitored by the block layer pm engine (blk-pm.c). This is however, not the case for scsi-passthrough queues, created by bsg_setup_queue(). So the ufs-bsg driver might send various commands, disregarding the pm status of the device. This is wrong, regardless if its request queue is pm-aware or not. Fixes: df032bf27a41 (scsi: ufs: Add a bsg endpoint that supports UPIUs) Link: https://lore.kernel.org/r/1570696267-8487-1-git-send-email-avri.altman@wdc.com Reported-by: Yuliy Izrailov Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs_bsg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/scsi/ufs/ufs_bsg.c index a9344eb4e047..dc2f6d2b46ed 100644 --- a/drivers/scsi/ufs/ufs_bsg.c +++ b/drivers/scsi/ufs/ufs_bsg.c @@ -98,6 +98,8 @@ static int ufs_bsg_request(struct bsg_job *job) bsg_reply->reply_payload_rcv_len = 0; + pm_runtime_get_sync(hba->dev); + msgcode = bsg_request->msgcode; switch (msgcode) { case UPIU_TRANSACTION_QUERY_REQ: @@ -135,6 +137,8 @@ static int ufs_bsg_request(struct bsg_job *job) break; } + pm_runtime_put_sync(hba->dev); + if (!desc_buff) goto out; -- GitLab From b9959c7a347d6adbb558fba7e36e9fef3cba3b07 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 18 Oct 2019 18:41:16 -0400 Subject: [PATCH 496/993] filldir[64]: remove WARN_ON_ONCE() for bad directory entries This was always meant to be a temporary thing, just for testing and to see if it actually ever triggered. The only thing that reported it was syzbot doing disk image fuzzing, and then that warning is expected. So let's just remove it before -rc4, because the extra sanity testing should probably go to -stable, but we don't want the warning to do so. Reported-by: syzbot+3031f712c7ad5dd4d926@syzkaller.appspotmail.com Fixes: 8a23eb804ca4 ("Make filldir[64]() verify the directory entry filename is valid") Signed-off-by: Linus Torvalds --- fs/readdir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/readdir.c b/fs/readdir.c index 6e2623e57b2e..d26d5ea4de7b 100644 --- a/fs/readdir.c +++ b/fs/readdir.c @@ -105,9 +105,9 @@ EXPORT_SYMBOL(iterate_dir); */ static int verify_dirent_name(const char *name, int len) { - if (WARN_ON_ONCE(!len)) + if (!len) return -EIO; - if (WARN_ON_ONCE(memchr(name, '/', len))) + if (memchr(name, '/', len)) return -EIO; return 0; } -- GitLab From 05679ca6feebc1ef3bf743563315d9975adcf6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Thu, 17 Oct 2019 12:57:02 +0200 Subject: [PATCH 497/993] xdp: Prevent overflow in devmap_hash cost calculation for 32-bit builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tetsuo pointed out that without an explicit cast, the cost calculation for devmap_hash type maps could overflow on 32-bit builds. This adds the missing cast. Fixes: 6f9d451ab1a3 ("xdp: Add devmap_hash map type for looking up devices by hashed index") Reported-by: Tetsuo Handa Signed-off-by: Toke Høiland-Jørgensen Signed-off-by: Alexei Starovoitov Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20191017105702.2807093-1-toke@redhat.com --- kernel/bpf/devmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c index d27f3b60ff6d..c0a48f336997 100644 --- a/kernel/bpf/devmap.c +++ b/kernel/bpf/devmap.c @@ -128,7 +128,7 @@ static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr) if (!dtab->n_buckets) /* Overflow check */ return -EINVAL; - cost += sizeof(struct hlist_head) * dtab->n_buckets; + cost += (u64) sizeof(struct hlist_head) * dtab->n_buckets; } /* if map size is larger than memlock limit, reject it */ -- GitLab From 641fe2e9387a36f9ee01d7c69382d1fe147a5e98 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 18 Oct 2019 20:19:16 -0700 Subject: [PATCH 498/993] drivers/base/memory.c: don't access uninitialized memmaps in soft_offline_page_store() Uninitialized memmaps contain garbage and in the worst case trigger kernel BUGs, especially with CONFIG_PAGE_POISONING. They should not get touched. Right now, when trying to soft-offline a PFN that resides on a memory block that was never onlined, one gets a misleading error with CONFIG_PAGE_POISONING: :/# echo 5637144576 > /sys/devices/system/memory/soft_offline_page [ 23.097167] soft offline: 0x150000 page already poisoned But the actual result depends on the garbage in the memmap. soft_offline_page() can only work with online pages, it returns -EIO in case of ZONE_DEVICE. Make sure to only forward pages that are online (iow, managed by the buddy) and, therefore, have an initialized memmap. Add a check against pfn_to_online_page() and similarly return -EIO. Link: http://lkml.kernel.org/r/20191010141200.8985-1-david@redhat.com Fixes: f1dd2cd13c4b ("mm, memory_hotplug: do not associate hotadded memory to zones until online") [visible after d0dc12e86b319] Signed-off-by: David Hildenbrand Acked-by: Naoya Horiguchi Acked-by: Michal Hocko Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Cc: [4.13+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/memory.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 6bea4f3f8040..55907c27075b 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -540,6 +540,9 @@ static ssize_t soft_offline_page_store(struct device *dev, pfn >>= PAGE_SHIFT; if (!pfn_valid(pfn)) return -ENXIO; + /* Only online pages can be soft-offlined (esp., not ZONE_DEVICE). */ + if (!pfn_to_online_page(pfn)) + return -EIO; ret = soft_offline_page(pfn_to_page(pfn), 0); return ret == 0 ? count : ret; } -- GitLab From aad5f69bc161af489dbb5934868bd347282f0764 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 18 Oct 2019 20:19:20 -0700 Subject: [PATCH 499/993] fs/proc/page.c: don't access uninitialized memmaps in fs/proc/page.c There are three places where we access uninitialized memmaps, namely: - /proc/kpagecount - /proc/kpageflags - /proc/kpagecgroup We have initialized memmaps either when the section is online or when the page was initialized to the ZONE_DEVICE. Uninitialized memmaps contain garbage and in the worst case trigger kernel BUGs, especially with CONFIG_PAGE_POISONING. For example, not onlining a DIMM during boot and calling /proc/kpagecount with CONFIG_PAGE_POISONING: :/# cat /proc/kpagecount > tmp.test BUG: unable to handle page fault for address: fffffffffffffffe #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 114616067 P4D 114616067 PUD 114618067 PMD 0 Oops: 0000 [#1] SMP NOPTI CPU: 0 PID: 469 Comm: cat Not tainted 5.4.0-rc1-next-20191004+ #11 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.4 RIP: 0010:kpagecount_read+0xce/0x1e0 Code: e8 09 83 e0 3f 48 0f a3 02 73 2d 4c 89 e7 48 c1 e7 06 48 03 3d ab 51 01 01 74 1d 48 8b 57 08 480 RSP: 0018:ffffa14e409b7e78 EFLAGS: 00010202 RAX: fffffffffffffffe RBX: 0000000000020000 RCX: 0000000000000000 RDX: 0000000000000001 RSI: 00007f76b5595000 RDI: fffff35645000000 RBP: 00007f76b5595000 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000140000 R13: 0000000000020000 R14: 00007f76b5595000 R15: ffffa14e409b7f08 FS: 00007f76b577d580(0000) GS:ffff8f41bd400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: fffffffffffffffe CR3: 0000000078960000 CR4: 00000000000006f0 Call Trace: proc_reg_read+0x3c/0x60 vfs_read+0xc5/0x180 ksys_read+0x68/0xe0 do_syscall_64+0x5c/0xa0 entry_SYSCALL_64_after_hwframe+0x49/0xbe For now, let's drop support for ZONE_DEVICE from the three pseudo files in order to fix this. To distinguish offline memory (with garbage memmap) from ZONE_DEVICE memory with properly initialized memmaps, we would have to check get_dev_pagemap() and pfn_zone_device_reserved() right now. The usage of both (especially, special casing devmem) is frowned upon and needs to be reworked. The fundamental issue we have is: if (pfn_to_online_page(pfn)) { /* memmap initialized */ } else if (pfn_valid(pfn)) { /* * ??? * a) offline memory. memmap garbage. * b) devmem: memmap initialized to ZONE_DEVICE. * c) devmem: reserved for driver. memmap garbage. * (d) devmem: memmap currently initializing - garbage) */ } We'll leave the pfn_zone_device_reserved() check in stable_page_flags() in place as that function is also used from memory failure. We now no longer dump information about pages that are not in use anymore - offline. Link: http://lkml.kernel.org/r/20191009142435.3975-2-david@redhat.com Fixes: f1dd2cd13c4b ("mm, memory_hotplug: do not associate hotadded memory to zones until online") [visible after d0dc12e86b319] Signed-off-by: David Hildenbrand Reported-by: Qian Cai Acked-by: Michal Hocko Cc: Dan Williams Cc: Alexey Dobriyan Cc: Stephen Rothwell Cc: Toshiki Fukasawa Cc: Pankaj gupta Cc: Mike Rapoport Cc: Anthony Yznaga Cc: "Aneesh Kumar K.V" Cc: [4.13+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/page.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/fs/proc/page.c b/fs/proc/page.c index 544d1ee15aee..7c952ee732e6 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c @@ -42,10 +42,12 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf, return -EINVAL; while (count > 0) { - if (pfn_valid(pfn)) - ppage = pfn_to_page(pfn); - else - ppage = NULL; + /* + * TODO: ZONE_DEVICE support requires to identify + * memmaps that were actually initialized. + */ + ppage = pfn_to_online_page(pfn); + if (!ppage || PageSlab(ppage) || page_has_type(ppage)) pcount = 0; else @@ -216,10 +218,11 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf, return -EINVAL; while (count > 0) { - if (pfn_valid(pfn)) - ppage = pfn_to_page(pfn); - else - ppage = NULL; + /* + * TODO: ZONE_DEVICE support requires to identify + * memmaps that were actually initialized. + */ + ppage = pfn_to_online_page(pfn); if (put_user(stable_page_flags(ppage), out)) { ret = -EFAULT; @@ -261,10 +264,11 @@ static ssize_t kpagecgroup_read(struct file *file, char __user *buf, return -EINVAL; while (count > 0) { - if (pfn_valid(pfn)) - ppage = pfn_to_page(pfn); - else - ppage = NULL; + /* + * TODO: ZONE_DEVICE support requires to identify + * memmaps that were actually initialized. + */ + ppage = pfn_to_online_page(pfn); if (ppage) ino = page_cgroup_ino(ppage); -- GitLab From 96c804a6ae8c59a9092b3d5dd581198472063184 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 18 Oct 2019 20:19:23 -0700 Subject: [PATCH 500/993] mm/memory-failure.c: don't access uninitialized memmaps in memory_failure() We should check for pfn_to_online_page() to not access uninitialized memmaps. Reshuffle the code so we don't have to duplicate the error message. Link: http://lkml.kernel.org/r/20191009142435.3975-3-david@redhat.com Signed-off-by: David Hildenbrand Fixes: f1dd2cd13c4b ("mm, memory_hotplug: do not associate hotadded memory to zones until online") [visible after d0dc12e86b319] Acked-by: Naoya Horiguchi Cc: Michal Hocko Cc: [4.13+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory-failure.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 0ae72b6acee7..3151c87dff73 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1257,17 +1257,19 @@ int memory_failure(unsigned long pfn, int flags) if (!sysctl_memory_failure_recovery) panic("Memory failure on page %lx", pfn); - if (!pfn_valid(pfn)) { + p = pfn_to_online_page(pfn); + if (!p) { + if (pfn_valid(pfn)) { + pgmap = get_dev_pagemap(pfn, NULL); + if (pgmap) + return memory_failure_dev_pagemap(pfn, flags, + pgmap); + } pr_err("Memory failure: %#lx: memory outside kernel control\n", pfn); return -ENXIO; } - pgmap = get_dev_pagemap(pfn, NULL); - if (pgmap) - return memory_failure_dev_pagemap(pfn, flags, pgmap); - - p = pfn_to_page(pfn); if (PageHuge(p)) return memory_failure_hugetlb(pfn, flags); if (TestSetPageHWPoison(p)) { -- GitLab From ca210ba32ef7537b02731bfe255ed8eb1e4e2b59 Mon Sep 17 00:00:00 2001 From: Joel Colledge Date: Fri, 18 Oct 2019 20:19:26 -0700 Subject: [PATCH 501/993] scripts/gdb: fix lx-dmesg when CONFIG_PRINTK_CALLER is set When CONFIG_PRINTK_CALLER is set, struct printk_log contains an additional member caller_id. This affects the offset of the log text. Account for this by using the type information from gdb to determine all the offsets instead of using hardcoded values. This fixes following error: (gdb) lx-dmesg Python Exception embedded null character: Error occurred in Python command: embedded null character The read_u* utility functions now take an offset argument to make them easier to use. Link: http://lkml.kernel.org/r/20191011142500.2339-1-joel.colledge@linbit.com Signed-off-by: Joel Colledge Reviewed-by: Jan Kiszka Cc: Kieran Bingham Cc: Leonard Crestez Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gdb/linux/dmesg.py | 16 ++++++++++++---- scripts/gdb/linux/utils.py | 25 +++++++++++++------------ 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py index 6d2e09a2ad2f..2fa7bb83885f 100644 --- a/scripts/gdb/linux/dmesg.py +++ b/scripts/gdb/linux/dmesg.py @@ -16,6 +16,8 @@ import sys from linux import utils +printk_log_type = utils.CachedType("struct printk_log") + class LxDmesg(gdb.Command): """Print Linux kernel log buffer.""" @@ -42,9 +44,14 @@ class LxDmesg(gdb.Command): b = utils.read_memoryview(inf, log_buf_addr, log_next_idx) log_buf = a.tobytes() + b.tobytes() + length_offset = printk_log_type.get_type()['len'].bitpos // 8 + text_len_offset = printk_log_type.get_type()['text_len'].bitpos // 8 + time_stamp_offset = printk_log_type.get_type()['ts_nsec'].bitpos // 8 + text_offset = printk_log_type.get_type().sizeof + pos = 0 while pos < log_buf.__len__(): - length = utils.read_u16(log_buf[pos + 8:pos + 10]) + length = utils.read_u16(log_buf, pos + length_offset) if length == 0: if log_buf_2nd_half == -1: gdb.write("Corrupted log buffer!\n") @@ -52,10 +59,11 @@ class LxDmesg(gdb.Command): pos = log_buf_2nd_half continue - text_len = utils.read_u16(log_buf[pos + 10:pos + 12]) - text = log_buf[pos + 16:pos + 16 + text_len].decode( + text_len = utils.read_u16(log_buf, pos + text_len_offset) + text_start = pos + text_offset + text = log_buf[text_start:text_start + text_len].decode( encoding='utf8', errors='replace') - time_stamp = utils.read_u64(log_buf[pos:pos + 8]) + time_stamp = utils.read_u64(log_buf, pos + time_stamp_offset) for line in text.splitlines(): msg = u"[{time:12.6f}] {line}\n".format( diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py index bc67126118c4..ea94221dbd39 100644 --- a/scripts/gdb/linux/utils.py +++ b/scripts/gdb/linux/utils.py @@ -92,15 +92,16 @@ def read_memoryview(inf, start, length): return memoryview(inf.read_memory(start, length)) -def read_u16(buffer): +def read_u16(buffer, offset): + buffer_val = buffer[offset:offset + 2] value = [0, 0] - if type(buffer[0]) is str: - value[0] = ord(buffer[0]) - value[1] = ord(buffer[1]) + if type(buffer_val[0]) is str: + value[0] = ord(buffer_val[0]) + value[1] = ord(buffer_val[1]) else: - value[0] = buffer[0] - value[1] = buffer[1] + value[0] = buffer_val[0] + value[1] = buffer_val[1] if get_target_endianness() == LITTLE_ENDIAN: return value[0] + (value[1] << 8) @@ -108,18 +109,18 @@ def read_u16(buffer): return value[1] + (value[0] << 8) -def read_u32(buffer): +def read_u32(buffer, offset): if get_target_endianness() == LITTLE_ENDIAN: - return read_u16(buffer[0:2]) + (read_u16(buffer[2:4]) << 16) + return read_u16(buffer, offset) + (read_u16(buffer, offset + 2) << 16) else: - return read_u16(buffer[2:4]) + (read_u16(buffer[0:2]) << 16) + return read_u16(buffer, offset + 2) + (read_u16(buffer, offset) << 16) -def read_u64(buffer): +def read_u64(buffer, offset): if get_target_endianness() == LITTLE_ENDIAN: - return read_u32(buffer[0:4]) + (read_u32(buffer[4:8]) << 32) + return read_u32(buffer, offset) + (read_u32(buffer, offset + 4) << 32) else: - return read_u32(buffer[4:8]) + (read_u32(buffer[0:4]) << 32) + return read_u32(buffer, offset + 4) + (read_u32(buffer, offset) << 32) target_arch = None -- GitLab From a26ee565b6cd8dc2bf15ff6aa70bbb28f928b773 Mon Sep 17 00:00:00 2001 From: Qian Cai Date: Fri, 18 Oct 2019 20:19:29 -0700 Subject: [PATCH 502/993] mm/page_owner: don't access uninitialized memmaps when reading /proc/pagetypeinfo Uninitialized memmaps contain garbage and in the worst case trigger kernel BUGs, especially with CONFIG_PAGE_POISONING. They should not get touched. For example, when not onlining a memory block that is spanned by a zone and reading /proc/pagetypeinfo with CONFIG_DEBUG_VM_PGFLAGS and CONFIG_PAGE_POISONING, we can trigger a kernel BUG: :/# echo 1 > /sys/devices/system/memory/memory40/online :/# echo 1 > /sys/devices/system/memory/memory42/online :/# cat /proc/pagetypeinfo > test.file page:fffff2c585200000 is uninitialized and poisoned raw: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff raw: ffffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffff page dumped because: VM_BUG_ON_PAGE(PagePoisoned(p)) There is not page extension available. ------------[ cut here ]------------ kernel BUG at include/linux/mm.h:1107! invalid opcode: 0000 [#1] SMP NOPTI Please note that this change does not affect ZONE_DEVICE, because pagetypeinfo_showmixedcount_print() is called from mm/vmstat.c:pagetypeinfo_showmixedcount() only for populated zones, and ZONE_DEVICE is never populated (zone->present_pages always 0). [david@redhat.com: move check to outer loop, add comment, rephrase description] Link: http://lkml.kernel.org/r/20191011140638.8160-1-david@redhat.com Fixes: f1dd2cd13c4b ("mm, memory_hotplug: do not associate hotadded memory to zones until online") # visible after d0dc12e86b319 Signed-off-by: Qian Cai Signed-off-by: David Hildenbrand Acked-by: Michal Hocko Acked-by: Vlastimil Babka Cc: Thomas Gleixner Cc: "Peter Zijlstra (Intel)" Cc: Miles Chen Cc: Mike Rapoport Cc: Qian Cai Cc: Greg Kroah-Hartman Cc: [4.13+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/page_owner.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mm/page_owner.c b/mm/page_owner.c index e327bcd0380e..18ecde9f45b2 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -271,7 +271,8 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m, * not matter as the mixed block count will still be correct */ for (; pfn < end_pfn; ) { - if (!pfn_valid(pfn)) { + page = pfn_to_online_page(pfn); + if (!page) { pfn = ALIGN(pfn + 1, MAX_ORDER_NR_PAGES); continue; } @@ -279,13 +280,13 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m, block_end_pfn = ALIGN(pfn + 1, pageblock_nr_pages); block_end_pfn = min(block_end_pfn, end_pfn); - page = pfn_to_page(pfn); pageblock_mt = get_pageblock_migratetype(page); for (; pfn < block_end_pfn; pfn++) { if (!pfn_valid_within(pfn)) continue; + /* The pageblock is online, no need to recheck. */ page = pfn_to_page(pfn); if (page_zone(page) != zone) -- GitLab From 00d6c019b5bc175cee3770e0e659f2b5f4804ea5 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 18 Oct 2019 20:19:33 -0700 Subject: [PATCH 503/993] mm/memory_hotplug: don't access uninitialized memmaps in shrink_pgdat_span() We might use the nid of memmaps that were never initialized. For example, if the memmap was poisoned, we will crash the kernel in pfn_to_nid() right now. Let's use the calculated boundaries of the separate zones instead. This now also avoids having to iterate over a whole bunch of subsections again, after shrinking one zone. Before commit d0dc12e86b31 ("mm/memory_hotplug: optimize memory hotplug"), the memmap was initialized to 0 and the node was set to the right value. After that commit, the node might be garbage. We'll have to fix shrink_zone_span() next. Link: http://lkml.kernel.org/r/20191006085646.5768-4-david@redhat.com Fixes: f1dd2cd13c4b ("mm, memory_hotplug: do not associate hotadded memory to zones until online") [d0dc12e86b319] Signed-off-by: David Hildenbrand Reported-by: Aneesh Kumar K.V Cc: Oscar Salvador Cc: David Hildenbrand Cc: Michal Hocko Cc: Pavel Tatashin Cc: Dan Williams Cc: Wei Yang Cc: Alexander Duyck Cc: Alexander Potapenko Cc: Andy Lutomirski Cc: Anshuman Khandual Cc: Benjamin Herrenschmidt Cc: Borislav Petkov Cc: Catalin Marinas Cc: Christian Borntraeger Cc: Christophe Leroy Cc: Damian Tometzki Cc: Dave Hansen Cc: Fenghua Yu Cc: Gerald Schaefer Cc: Greg Kroah-Hartman Cc: Halil Pasic Cc: Heiko Carstens Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Ira Weiny Cc: Jason Gunthorpe Cc: Jun Yao Cc: Logan Gunthorpe Cc: Mark Rutland Cc: Masahiro Yamada Cc: "Matthew Wilcox (Oracle)" Cc: Mel Gorman Cc: Michael Ellerman Cc: Mike Rapoport Cc: Pankaj Gupta Cc: Paul Mackerras Cc: Pavel Tatashin Cc: Peter Zijlstra Cc: Qian Cai Cc: Rich Felker Cc: Robin Murphy Cc: Steve Capper Cc: Thomas Gleixner Cc: Tom Lendacky Cc: Tony Luck Cc: Vasily Gorbik Cc: Vlastimil Babka Cc: Wei Yang Cc: Will Deacon Cc: Yoshinori Sato Cc: Yu Zhao Cc: [4.13+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory_hotplug.c | 72 ++++++++++----------------------------------- 1 file changed, 15 insertions(+), 57 deletions(-) diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index b1be791f772d..df570e5c71cc 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -436,67 +436,25 @@ static void shrink_zone_span(struct zone *zone, unsigned long start_pfn, zone_span_writeunlock(zone); } -static void shrink_pgdat_span(struct pglist_data *pgdat, - unsigned long start_pfn, unsigned long end_pfn) +static void update_pgdat_span(struct pglist_data *pgdat) { - unsigned long pgdat_start_pfn = pgdat->node_start_pfn; - unsigned long p = pgdat_end_pfn(pgdat); /* pgdat_end_pfn namespace clash */ - unsigned long pgdat_end_pfn = p; - unsigned long pfn; - int nid = pgdat->node_id; - - if (pgdat_start_pfn == start_pfn) { - /* - * If the section is smallest section in the pgdat, it need - * shrink pgdat->node_start_pfn and pgdat->node_spanned_pages. - * In this case, we find second smallest valid mem_section - * for shrinking zone. - */ - pfn = find_smallest_section_pfn(nid, NULL, end_pfn, - pgdat_end_pfn); - if (pfn) { - pgdat->node_start_pfn = pfn; - pgdat->node_spanned_pages = pgdat_end_pfn - pfn; - } - } else if (pgdat_end_pfn == end_pfn) { - /* - * If the section is biggest section in the pgdat, it need - * shrink pgdat->node_spanned_pages. - * In this case, we find second biggest valid mem_section for - * shrinking zone. - */ - pfn = find_biggest_section_pfn(nid, NULL, pgdat_start_pfn, - start_pfn); - if (pfn) - pgdat->node_spanned_pages = pfn - pgdat_start_pfn + 1; - } - - /* - * If the section is not biggest or smallest mem_section in the pgdat, - * it only creates a hole in the pgdat. So in this case, we need not - * change the pgdat. - * But perhaps, the pgdat has only hole data. Thus it check the pgdat - * has only hole or not. - */ - pfn = pgdat_start_pfn; - for (; pfn < pgdat_end_pfn; pfn += PAGES_PER_SUBSECTION) { - if (unlikely(!pfn_valid(pfn))) - continue; - - if (pfn_to_nid(pfn) != nid) - continue; + unsigned long node_start_pfn = 0, node_end_pfn = 0; + struct zone *zone; - /* Skip range to be removed */ - if (pfn >= start_pfn && pfn < end_pfn) - continue; + for (zone = pgdat->node_zones; + zone < pgdat->node_zones + MAX_NR_ZONES; zone++) { + unsigned long zone_end_pfn = zone->zone_start_pfn + + zone->spanned_pages; - /* If we find valid section, we have nothing to do */ - return; + /* No need to lock the zones, they can't change. */ + if (zone_end_pfn > node_end_pfn) + node_end_pfn = zone_end_pfn; + if (zone->zone_start_pfn < node_start_pfn) + node_start_pfn = zone->zone_start_pfn; } - /* The pgdat has no valid section */ - pgdat->node_start_pfn = 0; - pgdat->node_spanned_pages = 0; + pgdat->node_start_pfn = node_start_pfn; + pgdat->node_spanned_pages = node_end_pfn - node_start_pfn; } static void __remove_zone(struct zone *zone, unsigned long start_pfn, @@ -507,7 +465,7 @@ static void __remove_zone(struct zone *zone, unsigned long start_pfn, pgdat_resize_lock(zone->zone_pgdat, &flags); shrink_zone_span(zone, start_pfn, start_pfn + nr_pages); - shrink_pgdat_span(pgdat, start_pfn, start_pfn + nr_pages); + update_pgdat_span(pgdat); pgdat_resize_unlock(zone->zone_pgdat, &flags); } -- GitLab From 77e080e7680e1e615587352f70c87b9e98126d03 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 18 Oct 2019 20:19:39 -0700 Subject: [PATCH 504/993] mm/memunmap: don't access uninitialized memmap in memunmap_pages() Patch series "mm/memory_hotplug: Shrink zones before removing memory", v6. This series fixes the access of uninitialized memmaps when shrinking zones/nodes and when removing memory. Also, it contains all fixes for crashes that can be triggered when removing certain namespace using memunmap_pages() - ZONE_DEVICE, reported by Aneesh. We stop trying to shrink ZONE_DEVICE, as it's buggy, fixing it would be more involved (we don't have SECTION_IS_ONLINE as an indicator), and shrinking is only of limited use (set_zone_contiguous() cannot detect the ZONE_DEVICE as contiguous). We continue shrinking !ZONE_DEVICE zones, however, I reduced the amount of code to a minimum. Shrinking is especially necessary to keep zone->contiguous set where possible, especially, on memory unplug of DIMMs at zone boundaries. -------------------------------------------------------------------------- Zones are now properly shrunk when offlining memory blocks or when onlining failed. This allows to properly shrink zones on memory unplug even if the separate memory blocks of a DIMM were onlined to different zones or re-onlined to a different zone after offlining. Example: :/# cat /proc/zoneinfo Node 1, zone Movable spanned 0 present 0 managed 0 :/# echo "online_movable" > /sys/devices/system/memory/memory41/state :/# echo "online_movable" > /sys/devices/system/memory/memory43/state :/# cat /proc/zoneinfo Node 1, zone Movable spanned 98304 present 65536 managed 65536 :/# echo 0 > /sys/devices/system/memory/memory43/online :/# cat /proc/zoneinfo Node 1, zone Movable spanned 32768 present 32768 managed 32768 :/# echo 0 > /sys/devices/system/memory/memory41/online :/# cat /proc/zoneinfo Node 1, zone Movable spanned 0 present 0 managed 0 This patch (of 10): With an altmap, the memmap falling into the reserved altmap space are not initialized and, therefore, contain a garbage NID and a garbage zone. Make sure to read the NID/zone from a memmap that was initialized. This fixes a kernel crash that is observed when destroying a namespace: kernel BUG at include/linux/mm.h:1107! cpu 0x1: Vector: 700 (Program Check) at [c000000274087890] pc: c0000000004b9728: memunmap_pages+0x238/0x340 lr: c0000000004b9724: memunmap_pages+0x234/0x340 ... pid = 3669, comm = ndctl kernel BUG at include/linux/mm.h:1107! devm_action_release+0x30/0x50 release_nodes+0x268/0x2d0 device_release_driver_internal+0x174/0x240 unbind_store+0x13c/0x190 drv_attr_store+0x44/0x60 sysfs_kf_write+0x70/0xa0 kernfs_fop_write+0x1ac/0x290 __vfs_write+0x3c/0x70 vfs_write+0xe4/0x200 ksys_write+0x7c/0x140 system_call+0x5c/0x68 The "page_zone(pfn_to_page(pfn)" was introduced by 69324b8f4833 ("mm, devm_memremap_pages: add MEMORY_DEVICE_PRIVATE support"), however, I think we will never have driver reserved memory with MEMORY_DEVICE_PRIVATE (no altmap AFAIKS). [david@redhat.com: minimze code changes, rephrase description] Link: http://lkml.kernel.org/r/20191006085646.5768-2-david@redhat.com Fixes: 2c2a5af6fed2 ("mm, memory_hotplug: add nid parameter to arch_remove_memory") Signed-off-by: Aneesh Kumar K.V Signed-off-by: David Hildenbrand Cc: Dan Williams Cc: Jason Gunthorpe Cc: Logan Gunthorpe Cc: Ira Weiny Cc: Damian Tometzki Cc: Alexander Duyck Cc: Alexander Potapenko Cc: Andy Lutomirski Cc: Anshuman Khandual Cc: Benjamin Herrenschmidt Cc: Borislav Petkov Cc: Catalin Marinas Cc: Christian Borntraeger Cc: Christophe Leroy Cc: Dave Hansen Cc: Fenghua Yu Cc: Gerald Schaefer Cc: Greg Kroah-Hartman Cc: Halil Pasic Cc: Heiko Carstens Cc: "H. Peter Anvin" Cc: Ingo Molnar Cc: Jun Yao Cc: Mark Rutland Cc: Masahiro Yamada Cc: "Matthew Wilcox (Oracle)" Cc: Mel Gorman Cc: Michael Ellerman Cc: Michal Hocko Cc: Mike Rapoport Cc: Oscar Salvador Cc: Pankaj Gupta Cc: Paul Mackerras Cc: Pavel Tatashin Cc: Pavel Tatashin Cc: Peter Zijlstra Cc: Qian Cai Cc: Rich Felker Cc: Robin Murphy Cc: Steve Capper Cc: Thomas Gleixner Cc: Tom Lendacky Cc: Tony Luck Cc: Vasily Gorbik Cc: Vlastimil Babka Cc: Wei Yang Cc: Wei Yang Cc: Will Deacon Cc: Yoshinori Sato Cc: Yu Zhao Cc: [5.0+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memremap.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mm/memremap.c b/mm/memremap.c index 68204912cc0a..03ccbdfeb697 100644 --- a/mm/memremap.c +++ b/mm/memremap.c @@ -103,6 +103,7 @@ static void dev_pagemap_cleanup(struct dev_pagemap *pgmap) void memunmap_pages(struct dev_pagemap *pgmap) { struct resource *res = &pgmap->res; + struct page *first_page; unsigned long pfn; int nid; @@ -111,14 +112,16 @@ void memunmap_pages(struct dev_pagemap *pgmap) put_page(pfn_to_page(pfn)); dev_pagemap_cleanup(pgmap); + /* make sure to access a memmap that was actually initialized */ + first_page = pfn_to_page(pfn_first(pgmap)); + /* pages are dead and unused, undo the arch mapping */ - nid = page_to_nid(pfn_to_page(PHYS_PFN(res->start))); + nid = page_to_nid(first_page); mem_hotplug_begin(); if (pgmap->type == MEMORY_DEVICE_PRIVATE) { - pfn = PHYS_PFN(res->start); - __remove_pages(page_zone(pfn_to_page(pfn)), pfn, - PHYS_PFN(resource_size(res)), NULL); + __remove_pages(page_zone(first_page), PHYS_PFN(res->start), + PHYS_PFN(resource_size(res)), NULL); } else { arch_remove_memory(nid, res->start, resource_size(res), pgmap_altmap(pgmap)); -- GitLab From b749ecfaf6c53ce79d6ab66afd2fc34189a073b1 Mon Sep 17 00:00:00 2001 From: Roman Gushchin Date: Fri, 18 Oct 2019 20:19:44 -0700 Subject: [PATCH 505/993] mm: memcg/slab: fix panic in __free_slab() caused by premature memcg pointer release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Karsten reported the following panic in __free_slab() happening on a s390x machine: Unable to handle kernel pointer dereference in virtual kernel address space Failing address: 0000000000000000 TEID: 0000000000000483 Fault in home space mode while using kernel ASCE. AS:00000000017d4007 R3:000000007fbd0007 S:000000007fbff000 P:000000000000003d Oops: 0004 ilc:3 Ý#1¨ PREEMPT SMP Modules linked in: tcp_diag inet_diag xt_tcpudp ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_conntrack ip6table_nat ip6table_mangle ip6table_raw ip6table_security iptable_at nf_nat CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.3.0-05872-g6133e3e4bada-dirty #14 Hardware name: IBM 2964 NC9 702 (z/VM 6.4.0) Krnl PSW : 0704d00180000000 00000000003cadb6 (__free_slab+0x686/0x6b0) R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:1 PM:0 RI:0 EA:3 Krnl GPRS: 00000000f3a32928 0000000000000000 000000007fbf5d00 000000000117c4b8 0000000000000000 000000009e3291c1 0000000000000000 0000000000000000 0000000000000003 0000000000000008 000000002b478b00 000003d080a97600 0000000000000003 0000000000000008 000000002b478b00 000003d080a97600 000000000117ba00 000003e000057db0 00000000003cabcc 000003e000057c78 Krnl Code: 00000000003cada6: e310a1400004 lg %r1,320(%r10) 00000000003cadac: c0e50046c286 brasl %r14,ca32b8 #00000000003cadb2: a7f4fe36 brc 15,3caa1e >00000000003cadb6: e32060800024 stg %r2,128(%r6) 00000000003cadbc: a7f4fd9e brc 15,3ca8f8 00000000003cadc0: c0e50046790c brasl %r14,c99fd8 00000000003cadc6: a7f4fe2c brc 15,3caa 00000000003cadc6: a7f4fe2c brc 15,3caa1e 00000000003cadca: ecb1ffff00d9 aghik %r11,%r1,-1 Call Trace: (<00000000003cabcc> __free_slab+0x49c/0x6b0) <00000000001f5886> rcu_core+0x5a6/0x7e0 <0000000000ca2dea> __do_softirq+0xf2/0x5c0 <0000000000152644> irq_exit+0x104/0x130 <000000000010d222> do_IRQ+0x9a/0xf0 <0000000000ca2344> ext_int_handler+0x130/0x134 <0000000000103648> enabled_wait+0x58/0x128 (<0000000000103634> enabled_wait+0x44/0x128) <0000000000103b00> arch_cpu_idle+0x40/0x58 <0000000000ca0544> default_idle_call+0x3c/0x68 <000000000018eaa4> do_idle+0xec/0x1c0 <000000000018ee0e> cpu_startup_entry+0x36/0x40 <000000000122df34> arch_call_rest_init+0x5c/0x88 <0000000000000000> 0x0 INFO: lockdep is turned off. Last Breaking-Event-Address: <00000000003ca8f4> __free_slab+0x1c4/0x6b0 Kernel panic - not syncing: Fatal exception in interrupt The kernel panics on an attempt to dereference the NULL memcg pointer. When shutdown_cache() is called from the kmem_cache_destroy() context, a memcg kmem_cache might have empty slab pages in a partial list, which are still charged to the memory cgroup. These pages are released by free_partial() at the beginning of shutdown_cache(): either directly or by scheduling a RCU-delayed work (if the kmem_cache has the SLAB_TYPESAFE_BY_RCU flag). The latter case is when the reported panic can happen: memcg_unlink_cache() is called immediately after shrinking partial lists, without waiting for scheduled RCU works. It sets the kmem_cache->memcg_params.memcg pointer to NULL, and the following attempt to dereference it by __free_slab() from the RCU work context causes the panic. To fix the issue, let's postpone the release of the memcg pointer to destroy_memcg_params(). It's called from a separate work context by slab_caches_to_rcu_destroy_workfn(), which contains a full RCU barrier. This guarantees that all scheduled page release RCU works will complete before the memcg pointer will be zeroed. Big thanks for Karsten for the perfect report containing all necessary information, his help with the analysis of the problem and testing of the fix. Link: http://lkml.kernel.org/r/20191010160549.1584316-1-guro@fb.com Fixes: fb2f2b0adb98 ("mm: memcg/slab: reparent memcg kmem_caches on cgroup removal") Signed-off-by: Roman Gushchin Reported-by: Karsten Graul Tested-by: Karsten Graul Acked-by: Vlastimil Babka Reviewed-by: Shakeel Butt Cc: Karsten Graul Cc: Vladimir Davydov Cc: David Rientjes Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab_common.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mm/slab_common.c b/mm/slab_common.c index c29f03adca91..f9fb27b4c843 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -178,10 +178,13 @@ static int init_memcg_params(struct kmem_cache *s, static void destroy_memcg_params(struct kmem_cache *s) { - if (is_root_cache(s)) + if (is_root_cache(s)) { kvfree(rcu_access_pointer(s->memcg_params.memcg_caches)); - else + } else { + mem_cgroup_put(s->memcg_params.memcg); + WRITE_ONCE(s->memcg_params.memcg, NULL); percpu_ref_exit(&s->memcg_params.refcnt); + } } static void free_memcg_params(struct rcu_head *rcu) @@ -253,8 +256,6 @@ static void memcg_unlink_cache(struct kmem_cache *s) } else { list_del(&s->memcg_params.children_node); list_del(&s->memcg_params.kmem_caches_node); - mem_cgroup_put(s->memcg_params.memcg); - WRITE_ONCE(s->memcg_params.memcg, NULL); } } #else -- GitLab From ce750f43f5790de74c1644c39d78f684071658d1 Mon Sep 17 00:00:00 2001 From: Chengguang Xu Date: Fri, 18 Oct 2019 20:19:47 -0700 Subject: [PATCH 506/993] ocfs2: fix error handling in ocfs2_setattr() Should set transfer_to[USRQUOTA/GRPQUOTA] to NULL on error case before jumping to do dqput(). Link: http://lkml.kernel.org/r/20191010082349.1134-1-cgxu519@mykernel.net Signed-off-by: Chengguang Xu Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Changwei Ge Cc: Gang He Cc: Jun Piao Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/file.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 2e982db3e1ae..53939bf9d7d2 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1230,6 +1230,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(attr->ia_uid)); if (IS_ERR(transfer_to[USRQUOTA])) { status = PTR_ERR(transfer_to[USRQUOTA]); + transfer_to[USRQUOTA] = NULL; goto bail_unlock; } } @@ -1239,6 +1240,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(attr->ia_gid)); if (IS_ERR(transfer_to[GRPQUOTA])) { status = PTR_ERR(transfer_to[GRPQUOTA]); + transfer_to[GRPQUOTA] = NULL; goto bail_unlock; } } -- GitLab From 6f24c8d30d08f270b54f4c2cb9b08dfccbe59c57 Mon Sep 17 00:00:00 2001 From: John Hubbard Date: Fri, 18 Oct 2019 20:19:50 -0700 Subject: [PATCH 507/993] mm/gup_benchmark: add a missing "w" to getopt string Even though gup_benchmark.c has code to handle the -w command-line option, the "w" is not part of the getopt string. It looks as if it has been missing the whole time. On my machine, this leads naturally to the following predictable result: $ sudo ./gup_benchmark -w ./gup_benchmark: invalid option -- 'w' ...which is fixed with this commit. Link: http://lkml.kernel.org/r/20191014184639.1512873-2-jhubbard@nvidia.com Signed-off-by: John Hubbard Acked-by: Kirill A. Shutemov Cc: Keith Busch Cc: Shuah Khan Cc: Christoph Hellwig Cc: "Aneesh Kumar K . V" Cc: Ira Weiny Cc: Christoph Hellwig Cc: kbuild test robot Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- tools/testing/selftests/vm/gup_benchmark.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/vm/gup_benchmark.c b/tools/testing/selftests/vm/gup_benchmark.c index c0534e298b51..cb3fc09645c4 100644 --- a/tools/testing/selftests/vm/gup_benchmark.c +++ b/tools/testing/selftests/vm/gup_benchmark.c @@ -37,7 +37,7 @@ int main(int argc, char **argv) char *file = "/dev/zero"; char *p; - while ((opt = getopt(argc, argv, "m:r:n:f:tTLUSH")) != -1) { + while ((opt = getopt(argc, argv, "m:r:n:f:tTLUwSH")) != -1) { switch (opt) { case 'm': size = atoi(optarg) * MB; -- GitLab From 0cd22afdcea21fa16bb5b0d3e0508ca42072d0bd Mon Sep 17 00:00:00 2001 From: John Hubbard Date: Fri, 18 Oct 2019 20:19:53 -0700 Subject: [PATCH 508/993] mm/gup: fix a misnamed "write" argument, and a related bug In several routines, the "flags" argument is incorrectly named "write". Change it to "flags". Also, in one place, the misnaming led to an actual bug: "flags & FOLL_WRITE" is required, rather than just "flags". (That problem was flagged by krobot, in v1 of this patch.) Also, change the flags argument from int, to unsigned int. You can see that this was a simple oversight, because the calling code passes "flags" to the fifth argument: gup_pgd_range(): ... if (!gup_huge_pd(__hugepd(pgd_val(pgd)), addr, PGDIR_SHIFT, next, flags, pages, nr)) ...which, until this patch, the callees referred to as "write". Also, change two lines to avoid checkpatch line length complaints, and another line to fix another oversight that checkpatch called out: missing "int" on pdshift. Link: http://lkml.kernel.org/r/20191014184639.1512873-3-jhubbard@nvidia.com Fixes: b798bec4741b ("mm/gup: change write parameter to flags in fast walk") Signed-off-by: John Hubbard Reported-by: kbuild test robot Suggested-by: Kirill A. Shutemov Suggested-by: Ira Weiny Acked-by: Kirill A. Shutemov Reviewed-by: Ira Weiny Cc: Christoph Hellwig Cc: Aneesh Kumar K.V Cc: Keith Busch Cc: Shuah Khan Cc: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/gup.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mm/gup.c b/mm/gup.c index 23a9f9c9d377..8f236a335ae9 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -1973,7 +1973,8 @@ static unsigned long hugepte_addr_end(unsigned long addr, unsigned long end, } static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, - unsigned long end, int write, struct page **pages, int *nr) + unsigned long end, unsigned int flags, + struct page **pages, int *nr) { unsigned long pte_end; struct page *head, *page; @@ -1986,7 +1987,7 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, pte = READ_ONCE(*ptep); - if (!pte_access_permitted(pte, write)) + if (!pte_access_permitted(pte, flags & FOLL_WRITE)) return 0; /* hugepages are never "special" */ @@ -2023,7 +2024,7 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, } static int gup_huge_pd(hugepd_t hugepd, unsigned long addr, - unsigned int pdshift, unsigned long end, int write, + unsigned int pdshift, unsigned long end, unsigned int flags, struct page **pages, int *nr) { pte_t *ptep; @@ -2033,7 +2034,7 @@ static int gup_huge_pd(hugepd_t hugepd, unsigned long addr, ptep = hugepte_offset(hugepd, addr, pdshift); do { next = hugepte_addr_end(addr, end, sz); - if (!gup_hugepte(ptep, sz, addr, end, write, pages, nr)) + if (!gup_hugepte(ptep, sz, addr, end, flags, pages, nr)) return 0; } while (ptep++, addr = next, addr != end); @@ -2041,7 +2042,7 @@ static int gup_huge_pd(hugepd_t hugepd, unsigned long addr, } #else static inline int gup_huge_pd(hugepd_t hugepd, unsigned long addr, - unsigned pdshift, unsigned long end, int write, + unsigned int pdshift, unsigned long end, unsigned int flags, struct page **pages, int *nr) { return 0; @@ -2049,7 +2050,8 @@ static inline int gup_huge_pd(hugepd_t hugepd, unsigned long addr, #endif /* CONFIG_ARCH_HAS_HUGEPD */ static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr, - unsigned long end, unsigned int flags, struct page **pages, int *nr) + unsigned long end, unsigned int flags, + struct page **pages, int *nr) { struct page *head, *page; int refs; -- GitLab From b11edebbc967ebf5c55b8f9e1d5bb6d68ec3a7fd Mon Sep 17 00:00:00 2001 From: Honglei Wang Date: Fri, 18 Oct 2019 20:19:58 -0700 Subject: [PATCH 509/993] mm: memcg: get number of pages on the LRU list in memcgroup base on lru_zone_size Commit 1a61ab8038e72 ("mm: memcontrol: replace zone summing with lruvec_page_state()") has made lruvec_page_state to use per-cpu counters instead of calculating it directly from lru_zone_size with an idea that this would be more effective. Tim has reported that this is not really the case for their database benchmark which is showing an opposite results where lruvec_page_state is taking up a huge chunk of CPU cycles (about 25% of the system time which is roughly 7% of total cpu cycles) on 5.3 kernels. The workload is running on a larger machine (96cpus), it has many cgroups (500) and it is heavily direct reclaim bound. Tim Chen said: : The problem can also be reproduced by running simple multi-threaded : pmbench benchmark with a fast Optane SSD swap (see profile below). : : : 6.15% 3.08% pmbench [kernel.vmlinux] [k] lruvec_lru_size : | : |--3.07%--lruvec_lru_size : | | : | |--2.11%--cpumask_next : | | | : | | --1.66%--find_next_bit : | | : | --0.57%--call_function_interrupt : | | : | --0.55%--smp_call_function_interrupt : | : |--1.59%--0x441f0fc3d009 : | _ops_rdtsc_init_base_freq : | access_histogram : | page_fault : | __do_page_fault : | handle_mm_fault : | __handle_mm_fault : | | : | --1.54%--do_swap_page : | swapin_readahead : | swap_cluster_readahead : | | : | --1.53%--read_swap_cache_async : | __read_swap_cache_async : | alloc_pages_vma : | __alloc_pages_nodemask : | __alloc_pages_slowpath : | try_to_free_pages : | do_try_to_free_pages : | shrink_node : | shrink_node_memcg : | | : | |--0.77%--lruvec_lru_size : | | : | --0.76%--inactive_list_is_low : | | : | --0.76%--lruvec_lru_size : | : --1.50%--measure_read : page_fault : __do_page_fault : handle_mm_fault : __handle_mm_fault : do_swap_page : swapin_readahead : swap_cluster_readahead : | : --1.48%--read_swap_cache_async : __read_swap_cache_async : alloc_pages_vma : __alloc_pages_nodemask : __alloc_pages_slowpath : try_to_free_pages : do_try_to_free_pages : shrink_node : shrink_node_memcg : | : |--0.75%--inactive_list_is_low : | | : | --0.75%--lruvec_lru_size : | : --0.73%--lruvec_lru_size The likely culprit is the cache traffic the lruvec_page_state_local generates. Dave Hansen says: : I was thinking purely of the cache footprint. If it's reading : pn->lruvec_stat_local->count[idx] is three separate cachelines, so 192 : bytes of cache *96 CPUs = 18k of data, mostly read-only. 1 cgroup would : be 18k of data for the whole system and the caching would be pretty : efficient and all 18k would probably survive a tight page fault loop in : the L1. 500 cgroups would be ~90k of data per CPU thread which doesn't : fit in the L1 and probably wouldn't survive a tight page fault loop if : both logical threads were banging on different cgroups. : : It's just a theory, but it's why I noted the number of cgroups when I : initially saw this show up in profiles Fix the regression by partially reverting the said commit and calculate the lru size explicitly. Link: http://lkml.kernel.org/r/20190905071034.16822-1-honglei.wang@oracle.com Fixes: 1a61ab8038e72 ("mm: memcontrol: replace zone summing with lruvec_page_state()") Signed-off-by: Honglei Wang Reported-by: Tim Chen Acked-by: Tim Chen Tested-by: Tim Chen Acked-by: Michal Hocko Cc: Vladimir Davydov Cc: Johannes Weiner Cc: Roman Gushchin Cc: Tejun Heo Cc: Dave Hansen Cc: [5.2+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index c6659bb758a4..024b7e929752 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -351,12 +351,13 @@ unsigned long zone_reclaimable_pages(struct zone *zone) */ unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru, int zone_idx) { - unsigned long lru_size; + unsigned long lru_size = 0; int zid; - if (!mem_cgroup_disabled()) - lru_size = lruvec_page_state_local(lruvec, NR_LRU_BASE + lru); - else + if (!mem_cgroup_disabled()) { + for (zid = 0; zid < MAX_NR_ZONES; zid++) + lru_size += mem_cgroup_get_zone_lru_size(lruvec, lru, zid); + } else lru_size = node_page_state(lruvec_pgdat(lruvec), NR_LRU_BASE + lru); for (zid = zone_idx + 1; zid < MAX_NR_ZONES; zid++) { -- GitLab From f3057ad767542be7bbac44e548cb44017178a163 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Fri, 18 Oct 2019 20:20:01 -0700 Subject: [PATCH 510/993] mm: memblock: do not enforce current limit for memblock_phys* family Until commit 92d12f9544b7 ("memblock: refactor internal allocation functions") the maximal address for memblock allocations was forced to memblock.current_limit only for the allocation functions returning virtual address. The changes introduced by that commit moved the limit enforcement into the allocation core and as a result the allocation functions returning physical address also started to limit allocations to memblock.current_limit. This caused breakage of etnaviv GPU driver: etnaviv etnaviv: bound 130000.gpu (ops gpu_ops) etnaviv etnaviv: bound 134000.gpu (ops gpu_ops) etnaviv etnaviv: bound 2204000.gpu (ops gpu_ops) etnaviv-gpu 130000.gpu: model: GC2000, revision: 5108 etnaviv-gpu 130000.gpu: command buffer outside valid memory window etnaviv-gpu 134000.gpu: model: GC320, revision: 5007 etnaviv-gpu 134000.gpu: command buffer outside valid memory window etnaviv-gpu 2204000.gpu: model: GC355, revision: 1215 etnaviv-gpu 2204000.gpu: Ignoring GPU with VG and FE2.0 Restore the behaviour of memblock_phys* family so that these functions will not enforce memblock.current_limit. Link: http://lkml.kernel.org/r/1570915861-17633-1-git-send-email-rppt@kernel.org Fixes: 92d12f9544b7 ("memblock: refactor internal allocation functions") Signed-off-by: Mike Rapoport Reported-by: Adam Ford Tested-by: Adam Ford [imx6q-logicpd] Cc: Catalin Marinas Cc: Christoph Hellwig Cc: Fabio Estevam Cc: Lucas Stach Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memblock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mm/memblock.c b/mm/memblock.c index 7d4f61ae666a..c4b16cae2bc9 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -1356,9 +1356,6 @@ static phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size, align = SMP_CACHE_BYTES; } - if (end > memblock.current_limit) - end = memblock.current_limit; - again: found = memblock_find_in_range_node(size, align, start, end, nid, flags); @@ -1469,6 +1466,9 @@ static void * __init memblock_alloc_internal( if (WARN_ON_ONCE(slab_is_available())) return kzalloc_node(size, GFP_NOWAIT, nid); + if (max_addr > memblock.current_limit) + max_addr = memblock.current_limit; + alloc = memblock_alloc_range_nid(size, align, min_addr, max_addr, nid); /* retry allocation without lower limit */ -- GitLab From f231fe4235e22e18d847e05cbe705deaca56580a Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 18 Oct 2019 20:20:05 -0700 Subject: [PATCH 511/993] hugetlbfs: don't access uninitialized memmaps in pfn_range_valid_gigantic() Uninitialized memmaps contain garbage and in the worst case trigger kernel BUGs, especially with CONFIG_PAGE_POISONING. They should not get touched. Let's make sure that we only consider online memory (managed by the buddy) that has initialized memmaps. ZONE_DEVICE is not applicable. page_zone() will call page_to_nid(), which will trigger VM_BUG_ON_PGFLAGS(PagePoisoned(page), page) with CONFIG_PAGE_POISONING and CONFIG_DEBUG_VM_PGFLAGS when called on uninitialized memmaps. This can be the case when an offline memory block (e.g., never onlined) is spanned by a zone. Note: As explained by Michal in [1], alloc_contig_range() will verify the range. So it boils down to the wrong access in this function. [1] http://lkml.kernel.org/r/20180423000943.GO17484@dhcp22.suse.cz Link: http://lkml.kernel.org/r/20191015120717.4858-1-david@redhat.com Fixes: f1dd2cd13c4b ("mm, memory_hotplug: do not associate hotadded memory to zones until online") [visible after d0dc12e86b319] Signed-off-by: David Hildenbrand Reported-by: Michal Hocko Acked-by: Michal Hocko Reviewed-by: Mike Kravetz Cc: Anshuman Khandual Cc: [4.13+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/hugetlb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index ef37c85423a5..b45a95363a84 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1084,11 +1084,10 @@ static bool pfn_range_valid_gigantic(struct zone *z, struct page *page; for (i = start_pfn; i < end_pfn; i++) { - if (!pfn_valid(i)) + page = pfn_to_online_page(i); + if (!page) return false; - page = pfn_to_page(i); - if (page_zone(page) != z) return false; -- GitLab From b918c43021baaa3648de09e19a4a3dd555a45f40 Mon Sep 17 00:00:00 2001 From: Yi Li Date: Fri, 18 Oct 2019 20:20:08 -0700 Subject: [PATCH 512/993] ocfs2: fix panic due to ocfs2_wq is null mount.ocfs2 failed when reading ocfs2 filesystem superblock encounters an error. ocfs2_initialize_super() returns before allocating ocfs2_wq. ocfs2_dismount_volume() triggers the following panic. Oct 15 16:09:27 cnwarekv-205120 kernel: On-disk corruption discovered.Please run fsck.ocfs2 once the filesystem is unmounted. Oct 15 16:09:27 cnwarekv-205120 kernel: (mount.ocfs2,22804,44): ocfs2_read_locked_inode:537 ERROR: status = -30 Oct 15 16:09:27 cnwarekv-205120 kernel: (mount.ocfs2,22804,44): ocfs2_init_global_system_inodes:458 ERROR: status = -30 Oct 15 16:09:27 cnwarekv-205120 kernel: (mount.ocfs2,22804,44): ocfs2_init_global_system_inodes:491 ERROR: status = -30 Oct 15 16:09:27 cnwarekv-205120 kernel: (mount.ocfs2,22804,44): ocfs2_initialize_super:2313 ERROR: status = -30 Oct 15 16:09:27 cnwarekv-205120 kernel: (mount.ocfs2,22804,44): ocfs2_fill_super:1033 ERROR: status = -30 ------------[ cut here ]------------ Oops: 0002 [#1] SMP NOPTI CPU: 1 PID: 11753 Comm: mount.ocfs2 Tainted: G E 4.14.148-200.ckv.x86_64 #1 Hardware name: Sugon H320-G30/35N16-US, BIOS 0SSDX017 12/21/2018 task: ffff967af0520000 task.stack: ffffa5f05484000 RIP: 0010:mutex_lock+0x19/0x20 Call Trace: flush_workqueue+0x81/0x460 ocfs2_shutdown_local_alloc+0x47/0x440 [ocfs2] ocfs2_dismount_volume+0x84/0x400 [ocfs2] ocfs2_fill_super+0xa4/0x1270 [ocfs2] ? ocfs2_initialize_super.isa.211+0xf20/0xf20 [ocfs2] mount_bdev+0x17f/0x1c0 mount_fs+0x3a/0x160 Link: http://lkml.kernel.org/r/1571139611-24107-1-git-send-email-yili@winhong.com Signed-off-by: Yi Li Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Junxiao Bi Cc: Changwei Ge Cc: Gang He Cc: Jun Piao Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/journal.c | 3 ++- fs/ocfs2/localalloc.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 930e3d388579..699a560efbb0 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -217,7 +217,8 @@ void ocfs2_recovery_exit(struct ocfs2_super *osb) /* At this point, we know that no more recovery threads can be * launched, so wait for any recovery completion work to * complete. */ - flush_workqueue(osb->ocfs2_wq); + if (osb->ocfs2_wq) + flush_workqueue(osb->ocfs2_wq); /* * Now that recovery is shut down, and the osb is about to be diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index 158e5af767fd..720e9f94957e 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c @@ -377,7 +377,8 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) struct ocfs2_dinode *alloc = NULL; cancel_delayed_work(&osb->la_enable_wq); - flush_workqueue(osb->ocfs2_wq); + if (osb->ocfs2_wq) + flush_workqueue(osb->ocfs2_wq); if (osb->local_alloc_state == OCFS2_LA_UNUSED) goto out; -- GitLab From ae8af4388db002bbd1df78ecee7ca31cee78e964 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Fri, 18 Oct 2019 20:20:11 -0700 Subject: [PATCH 513/993] mm/memcontrol: update lruvec counters in mem_cgroup_move_account Mapped, dirty and writeback pages are also counted in per-lruvec stats. These counters needs update when page is moved between cgroups. Currently is nobody *consuming* the lruvec versions of these counters and that there is no user-visible effect. Link: http://lkml.kernel.org/r/157112699975.7360.1062614888388489788.stgit@buzz Fixes: 00f3ca2c2d66 ("mm: memcontrol: per-lruvec stats infrastructure") Signed-off-by: Konstantin Khlebnikov Acked-by: Johannes Weiner Acked-by: Michal Hocko Cc: Vladimir Davydov Signed-off-by: Linus Torvalds --- mm/memcontrol.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index bdac56009a38..363106578876 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -5420,6 +5420,8 @@ static int mem_cgroup_move_account(struct page *page, struct mem_cgroup *from, struct mem_cgroup *to) { + struct lruvec *from_vec, *to_vec; + struct pglist_data *pgdat; unsigned long flags; unsigned int nr_pages = compound ? hpage_nr_pages(page) : 1; int ret; @@ -5443,11 +5445,15 @@ static int mem_cgroup_move_account(struct page *page, anon = PageAnon(page); + pgdat = page_pgdat(page); + from_vec = mem_cgroup_lruvec(pgdat, from); + to_vec = mem_cgroup_lruvec(pgdat, to); + spin_lock_irqsave(&from->move_lock, flags); if (!anon && page_mapped(page)) { - __mod_memcg_state(from, NR_FILE_MAPPED, -nr_pages); - __mod_memcg_state(to, NR_FILE_MAPPED, nr_pages); + __mod_lruvec_state(from_vec, NR_FILE_MAPPED, -nr_pages); + __mod_lruvec_state(to_vec, NR_FILE_MAPPED, nr_pages); } /* @@ -5459,14 +5465,14 @@ static int mem_cgroup_move_account(struct page *page, struct address_space *mapping = page_mapping(page); if (mapping_cap_account_dirty(mapping)) { - __mod_memcg_state(from, NR_FILE_DIRTY, -nr_pages); - __mod_memcg_state(to, NR_FILE_DIRTY, nr_pages); + __mod_lruvec_state(from_vec, NR_FILE_DIRTY, -nr_pages); + __mod_lruvec_state(to_vec, NR_FILE_DIRTY, nr_pages); } } if (PageWriteback(page)) { - __mod_memcg_state(from, NR_WRITEBACK, -nr_pages); - __mod_memcg_state(to, NR_WRITEBACK, nr_pages); + __mod_lruvec_state(from_vec, NR_WRITEBACK, -nr_pages); + __mod_lruvec_state(to_vec, NR_WRITEBACK, nr_pages); } #ifdef CONFIG_TRANSPARENT_HUGEPAGE -- GitLab From f7daefe4231e57381d92c2e2ad905a899c28e402 Mon Sep 17 00:00:00 2001 From: Chenwandun Date: Fri, 18 Oct 2019 20:20:14 -0700 Subject: [PATCH 514/993] zram: fix race between backing_dev_show and backing_dev_store CPU0: CPU1: backing_dev_show backing_dev_store ...... ...... file = zram->backing_dev; down_read(&zram->init_lock); down_read(&zram->init_init_lock) file_path(file, ...); zram->backing_dev = backing_dev; up_read(&zram->init_lock); up_read(&zram->init_lock); gets the value of zram->backing_dev too early in backing_dev_show, which resultin the value being NULL at the beginning, and not NULL later. backtrace: d_path+0xcc/0x174 file_path+0x10/0x18 backing_dev_show+0x40/0xb4 dev_attr_show+0x20/0x54 sysfs_kf_seq_show+0x9c/0x10c kernfs_seq_show+0x28/0x30 seq_read+0x184/0x488 kernfs_fop_read+0x5c/0x1a4 __vfs_read+0x44/0x128 vfs_read+0xa0/0x138 SyS_read+0x54/0xb4 Link: http://lkml.kernel.org/r/1571046839-16814-1-git-send-email-chenwandun@huawei.com Signed-off-by: Chenwandun Acked-by: Minchan Kim Cc: Sergey Senozhatsky Cc: Jens Axboe Cc: [4.14+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/zram/zram_drv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index d58a359a6622..4285e75e52c3 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -413,13 +413,14 @@ static void reset_bdev(struct zram *zram) static ssize_t backing_dev_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct file *file; struct zram *zram = dev_to_zram(dev); - struct file *file = zram->backing_dev; char *p; ssize_t ret; down_read(&zram->init_lock); - if (!zram->backing_dev) { + file = zram->backing_dev; + if (!file) { memcpy(buf, "none\n", 5); up_read(&zram->init_lock); return 5; -- GitLab From 444f84fd2ac7bae36f3dd3ce1d39d11211c2c72a Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 18 Oct 2019 20:20:17 -0700 Subject: [PATCH 515/993] mm: include for is_vma_temporary_stack Include for the definition of is_vma_temporary_stack to fix the following sparse warning: mm/rmap.c:1673:6: warning: symbol 'is_vma_temporary_stack' was not declared. Should it be static? Link: http://lkml.kernel.org/r/20191009151155.27763-1-ben.dooks@codethink.co.uk Signed-off-by: Ben Dooks Reviewed-by: Qian Cai Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/rmap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/rmap.c b/mm/rmap.c index d9a23bb773bf..0c7b2a9400d4 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include -- GitLab From d0e6a5821cdf08eea91d8597dce1ad695ebeb8bc Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 18 Oct 2019 20:20:20 -0700 Subject: [PATCH 516/993] mm/filemap.c: include for generic_file_vm_ops definition The generic_file_vm_ops is defined in so include it to fix the following warning: mm/filemap.c:2717:35: warning: symbol 'generic_file_vm_ops' was not declared. Should it be static? Link: http://lkml.kernel.org/r/20191008102311.25432-1-ben.dooks@codethink.co.uk Signed-off-by: Ben Dooks Reviewed-by: Andrew Morton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/filemap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/filemap.c b/mm/filemap.c index 1146fcfa3215..85b7d087eb45 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "internal.h" #define CREATE_TRACE_POINTS -- GitLab From a2ae8c0551050cbf3232fbb3d963a9bbe7b57268 Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Fri, 18 Oct 2019 20:20:24 -0700 Subject: [PATCH 517/993] mm/init-mm.c: include for vm_committed_as_batch mm_init.c needs to include for the definition of vm_committed_as_batch. Fixes the following sparse warning: mm/mm_init.c:141:5: warning: symbol 'vm_committed_as_batch' was not declared. Should it be static? Link: http://lkml.kernel.org/r/20191016091509.26708-1-ben.dooks@codethink.co.uk Signed-off-by: Ben Dooks Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/init-mm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/init-mm.c b/mm/init-mm.c index fb1e15028ef0..19603302a77f 100644 --- a/mm/init-mm.c +++ b/mm/init-mm.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include -- GitLab From 2be5fbf9a91c417cd178a481538baddda3e2f38c Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Fri, 18 Oct 2019 20:20:27 -0700 Subject: [PATCH 518/993] proc/meminfo: fix output alignment Patch series "Fixes for THP in page cache", v2. This patch (of 5): Add extra space for FileHugePages and FilePmdMapped, so the output is aligned with other rows. Link: http://lkml.kernel.org/r/20191017164223.2762148-2-songliubraving@fb.com Fixes: 60fbf0ab5da1 ("mm,thp: stats for file backed THP") Signed-off-by: Kirill A. Shutemov Signed-off-by: Song Liu Tested-by: Song Liu Acked-by: Yang Shi Cc: Matthew Wilcox Cc: Oleg Nesterov Cc: Srikar Dronamraju Cc: William Kucharski Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/meminfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index ac9247371871..8c1f1bb1a5ce 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c @@ -132,9 +132,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v) global_node_page_state(NR_SHMEM_THPS) * HPAGE_PMD_NR); show_val_kb(m, "ShmemPmdMapped: ", global_node_page_state(NR_SHMEM_PMDMAPPED) * HPAGE_PMD_NR); - show_val_kb(m, "FileHugePages: ", + show_val_kb(m, "FileHugePages: ", global_node_page_state(NR_FILE_THPS) * HPAGE_PMD_NR); - show_val_kb(m, "FilePmdMapped: ", + show_val_kb(m, "FilePmdMapped: ", global_node_page_state(NR_FILE_PMDMAPPED) * HPAGE_PMD_NR); #endif -- GitLab From 06d3eff62d9dc6f21e7ebeb14399f2542a36cdf5 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Fri, 18 Oct 2019 20:20:30 -0700 Subject: [PATCH 519/993] mm/thp: fix node page state in split_huge_page_to_list() Make sure split_huge_page_to_list() handles the state of shmem THP and file THP properly. Link: http://lkml.kernel.org/r/20191017164223.2762148-3-songliubraving@fb.com Fixes: 60fbf0ab5da1 ("mm,thp: stats for file backed THP") Signed-off-by: Kirill A. Shutemov Signed-off-by: Song Liu Tested-by: Song Liu Acked-by: Yang Shi Cc: Matthew Wilcox (Oracle) Cc: Oleg Nesterov Cc: Srikar Dronamraju Cc: William Kucharski Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/huge_memory.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index c5cb6dcd6c69..13cc93785006 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2789,8 +2789,13 @@ int split_huge_page_to_list(struct page *page, struct list_head *list) ds_queue->split_queue_len--; list_del(page_deferred_list(head)); } - if (mapping) - __dec_node_page_state(page, NR_SHMEM_THPS); + if (mapping) { + if (PageSwapBacked(page)) + __dec_node_page_state(page, NR_SHMEM_THPS); + else + __dec_node_page_state(page, NR_FILE_THPS); + } + spin_unlock(&ds_queue->split_queue_lock); __split_huge_page(page, list, end, flags); if (PageSwapCache(head)) { -- GitLab From 906d278d75e364f2bb85dc1e1ff6265ea46e7e43 Mon Sep 17 00:00:00 2001 From: William Kucharski Date: Fri, 18 Oct 2019 20:20:33 -0700 Subject: [PATCH 520/993] mm/vmscan.c: support removing arbitrary sized pages from mapping __remove_mapping() assumes that pages can only be either base pages or HPAGE_PMD_SIZE. Ask the page what size it is. Link: http://lkml.kernel.org/r/20191017164223.2762148-4-songliubraving@fb.com Fixes: 99cb0dbd47a1 ("mm,thp: add read-only THP support for (non-shmem) FS") Signed-off-by: William Kucharski Signed-off-by: Matthew Wilcox (Oracle) Signed-off-by: Song Liu Acked-by: Yang Shi Cc: "Kirill A. Shutemov" Cc: Oleg Nesterov Cc: Srikar Dronamraju Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 024b7e929752..ee4eecc7e1c2 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -933,10 +933,7 @@ static int __remove_mapping(struct address_space *mapping, struct page *page, * Note that if SetPageDirty is always performed via set_page_dirty, * and thus under the i_pages lock, then this ordering is not required. */ - if (unlikely(PageTransHuge(page)) && PageSwapCache(page)) - refcount = 1 + HPAGE_PMD_NR; - else - refcount = 2; + refcount = 1 + compound_nr(page); if (!page_ref_freeze(page, refcount)) goto cannot_free; /* note: atomic_cmpxchg in page_ref_freeze provides the smp_rmb */ -- GitLab From ef18a1ca847b01cb7296f11a728cb2f5ef671760 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Fri, 18 Oct 2019 20:20:36 -0700 Subject: [PATCH 521/993] mm/thp: allow dropping THP from page cache Once a THP is added to the page cache, it cannot be dropped via /proc/sys/vm/drop_caches. Fix this issue with proper handling in invalidate_mapping_pages(). Link: http://lkml.kernel.org/r/20191017164223.2762148-5-songliubraving@fb.com Fixes: 99cb0dbd47a1 ("mm,thp: add read-only THP support for (non-shmem) FS") Signed-off-by: Kirill A. Shutemov Signed-off-by: Song Liu Tested-by: Song Liu Acked-by: Yang Shi Cc: Matthew Wilcox (Oracle) Cc: Oleg Nesterov Cc: Srikar Dronamraju Cc: William Kucharski Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/truncate.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mm/truncate.c b/mm/truncate.c index 8563339041f6..dd9ebc1da356 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -592,6 +592,16 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping, unlock_page(page); continue; } + + /* Take a pin outside pagevec */ + get_page(page); + + /* + * Drop extra pins before trying to invalidate + * the huge page. + */ + pagevec_remove_exceptionals(&pvec); + pagevec_release(&pvec); } ret = invalidate_inode_page(page); @@ -602,6 +612,8 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping, */ if (!ret) deactivate_file_page(page); + if (PageTransHuge(page)) + put_page(page); count += ret; } pagevec_remove_exceptionals(&pvec); -- GitLab From aa5de305c90c995321df452f274fe75b52bd8fcc Mon Sep 17 00:00:00 2001 From: Song Liu Date: Fri, 18 Oct 2019 20:20:40 -0700 Subject: [PATCH 522/993] kernel/events/uprobes.c: only do FOLL_SPLIT_PMD for uprobe register Attaching uprobe to text section in THP splits the PMD mapped page table into PTE mapped entries. On uprobe detach, we would like to regroup PMD mapped page table entry to regain performance benefit of THP. However, the regroup is broken For perf_event based trace_uprobe. This is because perf_event based trace_uprobe calls uprobe_unregister twice on close: first in TRACE_REG_PERF_CLOSE, then in TRACE_REG_PERF_UNREGISTER. The second call will split the PMD mapped page table entry, which is not the desired behavior. Fix this by only use FOLL_SPLIT_PMD for uprobe register case. Add a WARN() to confirm uprobe unregister never work on huge pages, and abort the operation when this WARN() triggers. Link: http://lkml.kernel.org/r/20191017164223.2762148-6-songliubraving@fb.com Fixes: 5a52c9df62b4 ("uprobe: use FOLL_SPLIT_PMD instead of FOLL_SPLIT") Signed-off-by: Song Liu Reviewed-by: Srikar Dronamraju Cc: Kirill A. Shutemov Cc: Oleg Nesterov Cc: Matthew Wilcox (Oracle) Cc: William Kucharski Cc: Yang Shi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/events/uprobes.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 94d38a39d72e..c74761004ee5 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -474,14 +474,17 @@ int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, struct vm_area_struct *vma; int ret, is_register, ref_ctr_updated = 0; bool orig_page_huge = false; + unsigned int gup_flags = FOLL_FORCE; is_register = is_swbp_insn(&opcode); uprobe = container_of(auprobe, struct uprobe, arch); retry: + if (is_register) + gup_flags |= FOLL_SPLIT_PMD; /* Read the page with vaddr into memory */ - ret = get_user_pages_remote(NULL, mm, vaddr, 1, - FOLL_FORCE | FOLL_SPLIT_PMD, &old_page, &vma, NULL); + ret = get_user_pages_remote(NULL, mm, vaddr, 1, gup_flags, + &old_page, &vma, NULL); if (ret <= 0) return ret; @@ -489,6 +492,12 @@ int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, if (ret <= 0) goto put_old; + if (WARN(!is_register && PageCompound(old_page), + "uprobe unregister should never work on compound page\n")) { + ret = -EINVAL; + goto put_old; + } + /* We are going to replace instruction, update ref_ctr. */ if (!ref_ctr_updated && uprobe->ref_ctr_offset) { ret = update_ref_ctr(uprobe, mm, is_register ? 1 : -1); -- GitLab From 585d730d41120926e3f79a601edad3930fa28366 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Fri, 18 Oct 2019 20:20:43 -0700 Subject: [PATCH 523/993] scripts/gdb: fix debugging modules on s390 Currently lx-symbols assumes that module text is always located at module->core_layout->base, but s390 uses the following layout: +------+ <- module->core_layout->base | GOT | +------+ <- module->core_layout->base + module->arch->plt_offset | PLT | +------+ <- module->core_layout->base + module->arch->plt_offset + | TEXT | module->arch->plt_size +------+ Therefore, when trying to debug modules on s390, all the symbol addresses are skewed by plt_offset + plt_size. Fix by adding plt_offset + plt_size to module_addr in load_module_symbols(). Link: http://lkml.kernel.org/r/20191017085917.81791-1-iii@linux.ibm.com Signed-off-by: Ilya Leoshkevich Reviewed-by: Jan Kiszka Cc: Kieran Bingham Cc: Heiko Carstens Cc: Vasily Gorbik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/gdb/linux/symbols.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py index 34e40e96dee2..7b7c2fafbc68 100644 --- a/scripts/gdb/linux/symbols.py +++ b/scripts/gdb/linux/symbols.py @@ -15,7 +15,7 @@ import gdb import os import re -from linux import modules +from linux import modules, utils if hasattr(gdb, 'Breakpoint'): @@ -116,6 +116,12 @@ lx-symbols command.""" module_file = self._get_module_file(module_name) if module_file: + if utils.is_target_arch('s390'): + # Module text is preceded by PLT stubs on s390. + module_arch = module['arch'] + plt_offset = int(module_arch['plt_offset']) + plt_size = int(module_arch['plt_size']) + module_addr = hex(int(module_addr, 0) + plt_offset + plt_size) gdb.write("loading @{addr}: {filename}\n".format( addr=module_addr, filename=module_file)) cmdline = "add-symbol-file {filename} {addr}{sections}".format( -- GitLab From 580a05f9d4ada3bfb689140d0efec1efdb8a48da Mon Sep 17 00:00:00 2001 From: Yonglong Liu Date: Fri, 18 Oct 2019 11:42:59 +0800 Subject: [PATCH 524/993] net: hns3: fix mis-counting IRQ vector numbers issue Currently, the num_msi_left means the vector numbers of NIC, but if the PF supported RoCE, it contains the vector numbers of NIC and RoCE(Not expected). This may cause interrupts lost in some case, because of the NIC module used the vector resources which belongs to RoCE. This patch adds a new variable num_nic_msi to store the vector numbers of NIC, and adjust the default TQP numbers and rss_size according to the value of num_nic_msi. Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support") Signed-off-by: Yonglong Liu Signed-off-by: Huazhong Tan Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 2 ++ .../hisilicon/hns3/hns3pf/hclge_main.c | 21 +++++++++++++- .../hisilicon/hns3/hns3pf/hclge_main.h | 1 + .../ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 11 ++++++-- .../hisilicon/hns3/hns3vf/hclgevf_main.c | 28 +++++++++++++++++-- .../hisilicon/hns3/hns3vf/hclgevf_main.h | 1 + 6 files changed, 58 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index c4b7bf851a28..75ccc1e7076b 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -32,6 +32,8 @@ #define HNAE3_MOD_VERSION "1.0" +#define HNAE3_MIN_VECTOR_NUM 2 /* first one for misc, another for IO */ + /* Device IDs */ #define HNAE3_DEV_ID_GE 0xA220 #define HNAE3_DEV_ID_25GE 0xA221 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index fd7f94372ff0..e02e01bd9eff 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -906,6 +906,9 @@ static int hclge_query_pf_resource(struct hclge_dev *hdev) hnae3_get_field(__le16_to_cpu(req->pf_intr_vector_number), HCLGE_PF_VEC_NUM_M, HCLGE_PF_VEC_NUM_S); + /* nic's msix numbers is always equals to the roce's. */ + hdev->num_nic_msi = hdev->num_roce_msi; + /* PF should have NIC vectors and Roce vectors, * NIC vectors are queued before Roce vectors. */ @@ -915,6 +918,15 @@ static int hclge_query_pf_resource(struct hclge_dev *hdev) hdev->num_msi = hnae3_get_field(__le16_to_cpu(req->pf_intr_vector_number), HCLGE_PF_VEC_NUM_M, HCLGE_PF_VEC_NUM_S); + + hdev->num_nic_msi = hdev->num_msi; + } + + if (hdev->num_nic_msi < HNAE3_MIN_VECTOR_NUM) { + dev_err(&hdev->pdev->dev, + "Just %u msi resources, not enough for pf(min:2).\n", + hdev->num_nic_msi); + return -EINVAL; } return 0; @@ -1507,6 +1519,10 @@ static int hclge_assign_tqp(struct hclge_vport *vport, u16 num_tqps) kinfo->rss_size = min_t(u16, hdev->rss_size_max, vport->alloc_tqps / hdev->tm_info.num_tc); + /* ensure one to one mapping between irq and queue at default */ + kinfo->rss_size = min_t(u16, kinfo->rss_size, + (hdev->num_nic_msi - 1) / hdev->tm_info.num_tc); + return 0; } @@ -2285,7 +2301,8 @@ static int hclge_init_msi(struct hclge_dev *hdev) int vectors; int i; - vectors = pci_alloc_irq_vectors(pdev, 1, hdev->num_msi, + vectors = pci_alloc_irq_vectors(pdev, HNAE3_MIN_VECTOR_NUM, + hdev->num_msi, PCI_IRQ_MSI | PCI_IRQ_MSIX); if (vectors < 0) { dev_err(&pdev->dev, @@ -2300,6 +2317,7 @@ static int hclge_init_msi(struct hclge_dev *hdev) hdev->num_msi = vectors; hdev->num_msi_left = vectors; + hdev->base_msi_vector = pdev->irq; hdev->roce_base_vector = hdev->base_msi_vector + hdev->roce_base_msix_offset; @@ -3903,6 +3921,7 @@ static int hclge_get_vector(struct hnae3_handle *handle, u16 vector_num, int alloc = 0; int i, j; + vector_num = min_t(u16, hdev->num_nic_msi - 1, vector_num); vector_num = min(hdev->num_msi_left, vector_num); for (j = 0; j < vector_num; j++) { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 3e9574a9e22d..c3d56b872ed7 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -763,6 +763,7 @@ struct hclge_dev { u32 base_msi_vector; u16 *vector_status; int *vector_irq; + u16 num_nic_msi; /* Num of nic vectors for this PF */ u16 num_roce_msi; /* Num of roce vectors for this PF */ int roce_base_vector; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c index 9f0e35f27789..62399cc1c5a6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c @@ -537,9 +537,16 @@ static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport) kinfo->rss_size = kinfo->req_rss_size; } else if (kinfo->rss_size > max_rss_size || (!kinfo->req_rss_size && kinfo->rss_size < max_rss_size)) { + /* if user not set rss, the rss_size should compare with the + * valid msi numbers to ensure one to one map between tqp and + * irq as default. + */ + if (!kinfo->req_rss_size) + max_rss_size = min_t(u16, max_rss_size, + (hdev->num_nic_msi - 1) / + kinfo->num_tc); + /* Set to the maximum specification value (max_rss_size). */ - dev_info(&hdev->pdev->dev, "rss changes from %d to %d\n", - kinfo->rss_size, max_rss_size); kinfo->rss_size = max_rss_size; } diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index e3090b3dab1d..7d7e712691b9 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -411,6 +411,13 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev) kinfo->tqp[i] = &hdev->htqp[i].q; } + /* after init the max rss_size and tqps, adjust the default tqp numbers + * and rss size with the actual vector numbers + */ + kinfo->num_tqps = min_t(u16, hdev->num_nic_msix - 1, kinfo->num_tqps); + kinfo->rss_size = min_t(u16, kinfo->num_tqps / kinfo->num_tc, + kinfo->rss_size); + return 0; } @@ -502,6 +509,7 @@ static int hclgevf_get_vector(struct hnae3_handle *handle, u16 vector_num, int alloc = 0; int i, j; + vector_num = min_t(u16, hdev->num_nic_msix - 1, vector_num); vector_num = min(hdev->num_msi_left, vector_num); for (j = 0; j < vector_num; j++) { @@ -2246,13 +2254,14 @@ static int hclgevf_init_msi(struct hclgevf_dev *hdev) int vectors; int i; - if (hnae3_get_bit(hdev->ae_dev->flag, HNAE3_DEV_SUPPORT_ROCE_B)) + if (hnae3_dev_roce_supported(hdev)) vectors = pci_alloc_irq_vectors(pdev, hdev->roce_base_msix_offset + 1, hdev->num_msi, PCI_IRQ_MSIX); else - vectors = pci_alloc_irq_vectors(pdev, 1, hdev->num_msi, + vectors = pci_alloc_irq_vectors(pdev, HNAE3_MIN_VECTOR_NUM, + hdev->num_msi, PCI_IRQ_MSI | PCI_IRQ_MSIX); if (vectors < 0) { @@ -2268,6 +2277,7 @@ static int hclgevf_init_msi(struct hclgevf_dev *hdev) hdev->num_msi = vectors; hdev->num_msi_left = vectors; + hdev->base_msi_vector = pdev->irq; hdev->roce_base_vector = pdev->irq + hdev->roce_base_msix_offset; @@ -2533,7 +2543,7 @@ static int hclgevf_query_vf_resource(struct hclgevf_dev *hdev) req = (struct hclgevf_query_res_cmd *)desc.data; - if (hnae3_get_bit(hdev->ae_dev->flag, HNAE3_DEV_SUPPORT_ROCE_B)) { + if (hnae3_dev_roce_supported(hdev)) { hdev->roce_base_msix_offset = hnae3_get_field(__le16_to_cpu(req->msixcap_localid_ba_rocee), HCLGEVF_MSIX_OFT_ROCEE_M, @@ -2542,6 +2552,9 @@ static int hclgevf_query_vf_resource(struct hclgevf_dev *hdev) hnae3_get_field(__le16_to_cpu(req->vf_intr_vector_number), HCLGEVF_VEC_NUM_M, HCLGEVF_VEC_NUM_S); + /* nic's msix numbers is always equals to the roce's. */ + hdev->num_nic_msix = hdev->num_roce_msix; + /* VF should have NIC vectors and Roce vectors, NIC vectors * are queued before Roce vectors. The offset is fixed to 64. */ @@ -2551,6 +2564,15 @@ static int hclgevf_query_vf_resource(struct hclgevf_dev *hdev) hdev->num_msi = hnae3_get_field(__le16_to_cpu(req->vf_intr_vector_number), HCLGEVF_VEC_NUM_M, HCLGEVF_VEC_NUM_S); + + hdev->num_nic_msix = hdev->num_msi; + } + + if (hdev->num_nic_msix < HNAE3_MIN_VECTOR_NUM) { + dev_err(&hdev->pdev->dev, + "Just %u msi resources, not enough for vf(min:2).\n", + hdev->num_nic_msix); + return -EINVAL; } return 0; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h index bdde3afc286b..2b8d6bc6d224 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h @@ -270,6 +270,7 @@ struct hclgevf_dev { u16 num_msi; u16 num_msi_left; u16 num_msi_used; + u16 num_nic_msix; /* Num of nic vectors for this VF */ u16 num_roce_msix; /* Num of roce vectors for this VF */ u16 roce_base_msix_offset; int roce_base_vector; -- GitLab From 3d5c1a037d37392a6859afbde49be5ba6a70a6b3 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Fri, 18 Oct 2019 09:45:49 +0200 Subject: [PATCH 525/993] xen/netback: fix error path of xenvif_connect_data() xenvif_connect_data() calls module_put() in case of error. This is wrong as there is no related module_get(). Remove the superfluous module_put(). Fixes: 279f438e36c0a7 ("xen-netback: Don't destroy the netdev until the vif is shut down") Cc: # 3.12 Signed-off-by: Juergen Gross Reviewed-by: Paul Durrant Reviewed-by: Wei Liu Signed-off-by: David S. Miller --- drivers/net/xen-netback/interface.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 240f762b3749..103ed00775eb 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -719,7 +719,6 @@ int xenvif_connect_data(struct xenvif_queue *queue, xenvif_unmap_frontend_data_rings(queue); netif_napi_del(&queue->napi); err: - module_put(THIS_MODULE); return err; } -- GitLab From bd310aca442fcc72731b7acb65d32d05c956d56b Mon Sep 17 00:00:00 2001 From: Michael Tretter Date: Fri, 18 Oct 2019 16:11:43 +0200 Subject: [PATCH 526/993] macb: propagate errors when getting optional clocks The tx_clk, rx_clk, and tsu_clk are optional. Currently the macb driver marks clock as not available if it receives an error when trying to get a clock. This is wrong, because a clock controller might return -EPROBE_DEFER if a clock is not available, but will eventually become available. In these cases, the driver would probe successfully but will never be able to adjust the clocks, because the clocks were not available during probe, but became available later. For example, the clock controller for the ZynqMP is implemented in the PMU firmware and the clocks are only available after the firmware driver has been probed. Use devm_clk_get_optional() in instead of devm_clk_get() to get the optional clock and propagate all errors to the calling function. Signed-off-by: Michael Tretter Acked-by: Nicolas Ferre Tested-by: Nicolas Ferre Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb_main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 8e8d557901a9..1e1b774e1953 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -3405,17 +3405,17 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk, return err; } - *tx_clk = devm_clk_get(&pdev->dev, "tx_clk"); + *tx_clk = devm_clk_get_optional(&pdev->dev, "tx_clk"); if (IS_ERR(*tx_clk)) - *tx_clk = NULL; + return PTR_ERR(*tx_clk); - *rx_clk = devm_clk_get(&pdev->dev, "rx_clk"); + *rx_clk = devm_clk_get_optional(&pdev->dev, "rx_clk"); if (IS_ERR(*rx_clk)) - *rx_clk = NULL; + return PTR_ERR(*rx_clk); - *tsu_clk = devm_clk_get(&pdev->dev, "tsu_clk"); + *tsu_clk = devm_clk_get_optional(&pdev->dev, "tsu_clk"); if (IS_ERR(*tsu_clk)) - *tsu_clk = NULL; + return PTR_ERR(*tsu_clk); err = clk_prepare_enable(*pclk); if (err) { -- GitLab From a7fa12d15855904aff1716e1fc723c03ba38c5cc Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 18 Oct 2019 09:16:57 -0700 Subject: [PATCH 527/993] net: netem: fix error path for corrupted GSO frames To corrupt a GSO frame we first perform segmentation. We then proceed using the first segment instead of the full GSO skb and requeue the rest of the segments as separate packets. If there are any issues with processing the first segment we still want to process the rest, therefore we jump to the finish_segs label. Commit 177b8007463c ("net: netem: fix backlog accounting for corrupted GSO frames") started using the pointer to the first segment in the "rest of segments processing", but as mentioned above the first segment may had already been freed at this point. Backlog corrections for parent qdiscs have to be adjusted. Fixes: 177b8007463c ("net: netem: fix backlog accounting for corrupted GSO frames") Reported-by: kbuild test robot Reported-by: Dan Carpenter Reported-by: Ben Hutchings Signed-off-by: Jakub Kicinski Reviewed-by: Simon Horman Signed-off-by: David S. Miller --- net/sched/sch_netem.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 0e44039e729c..942eb17f413c 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -509,6 +509,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) { qdisc_drop(skb, sch, to_free); + skb = NULL; goto finish_segs; } @@ -593,9 +594,10 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, finish_segs: if (segs) { unsigned int len, last_len; - int nb = 0; + int nb; - len = skb->len; + len = skb ? skb->len : 0; + nb = skb ? 1 : 0; while (segs) { skb2 = segs->next; @@ -612,7 +614,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, } segs = skb2; } - qdisc_tree_reduce_backlog(sch, -nb, prev_len - len); + /* Parent qdiscs accounted for 1 skb of size @prev_len */ + qdisc_tree_reduce_backlog(sch, -(nb - 1), -(len - prev_len)); } return NET_XMIT_SUCCESS; } -- GitLab From e0ad032e144731a5928f2d75e91c2064ba1a764c Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 18 Oct 2019 09:16:58 -0700 Subject: [PATCH 528/993] net: netem: correct the parent's backlog when corrupted packet was dropped If packet corruption failed we jump to finish_segs and return NET_XMIT_SUCCESS. Seeing success will make the parent qdisc increment its backlog, that's incorrect - we need to return NET_XMIT_DROP. Fixes: 6071bd1aa13e ("netem: Segment GSO packets on enqueue") Signed-off-by: Jakub Kicinski Reviewed-by: Simon Horman Signed-off-by: David S. Miller --- net/sched/sch_netem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 942eb17f413c..42e557d48e4e 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -616,6 +616,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, } /* Parent qdiscs accounted for 1 skb of size @prev_len */ qdisc_tree_reduce_backlog(sch, -(nb - 1), -(len - prev_len)); + } else if (!skb) { + return NET_XMIT_DROP; } return NET_XMIT_SUCCESS; } -- GitLab From 3d00cf2fbb61212f47a3cf838be51c921366c937 Mon Sep 17 00:00:00 2001 From: Chenwandun Date: Fri, 18 Oct 2019 18:20:37 +0800 Subject: [PATCH 529/993] net: aquantia: add an error handling in aq_nic_set_multicast_list add an error handling in aq_nic_set_multicast_list, it may not work when hw_multicast_list_set error; and at the same time it will remove gcc Wunused-but-set-variable warning. Signed-off-by: Chenwandun Reviewed-by: Igor Russkikh Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index 2a18439b36fb..137c1de4c6ec 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -664,6 +664,8 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev) err = hw_ops->hw_multicast_list_set(self->aq_hw, self->mc_list.ar, self->mc_list.count); + if (err < 0) + return err; } return aq_nic_set_packet_filter(self, packet_filter); } -- GitLab From 05908d72cc8fa39058cd9535db2833089cc3df6f Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 18 Oct 2019 17:56:58 +0100 Subject: [PATCH 530/993] net: ethernet: dwmac-sun8i: show message only when switching to promisc Printing the info message every time more than the max number of mac addresses are requested generates unnecessary log spam. Showing it only when the hw is not already in promiscous mode is equally informative without being annoying. Signed-off-by: Mans Rullgard Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c index f97a4096f8fc..ddcc191febdb 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c @@ -651,7 +651,8 @@ static void sun8i_dwmac_set_filter(struct mac_device_info *hw, } } } else { - netdev_info(dev, "Too many address, switching to promiscuous\n"); + if (!(readl(ioaddr + EMAC_RX_FRM_FLT) & EMAC_FRM_FLT_RXALL)) + netdev_info(dev, "Too many address, switching to promiscuous\n"); v = EMAC_FRM_FLT_RXALL; } -- GitLab From 50c7d2ba9de20f60a2d527ad6928209ef67e4cdd Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 18 Oct 2019 17:02:46 -0400 Subject: [PATCH 531/993] net: dsa: fix switch tree list If there are multiple switch trees on the device, only the last one will be listed, because the arguments of list_add_tail are swapped. Fixes: 83c0afaec7b7 ("net: dsa: Add new binding implementation") Signed-off-by: Vivien Didelot Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/dsa2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 73002022c9d8..716d265ba8ca 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c @@ -46,7 +46,7 @@ static struct dsa_switch_tree *dsa_tree_alloc(int index) dst->index = index; INIT_LIST_HEAD(&dst->list); - list_add_tail(&dsa_tree_list, &dst->list); + list_add_tail(&dst->list, &dsa_tree_list); kref_init(&dst->refcount); -- GitLab From 2a06b8982f8f2f40d03a3daf634676386bd84dbc Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 18 Oct 2019 15:20:05 -0700 Subject: [PATCH 532/993] net: reorder 'struct net' fields to avoid false sharing Intel test robot reported a ~7% regression on TCP_CRR tests that they bisected to the cited commit. Indeed, every time a new TCP socket is created or deleted, the atomic counter net->count is touched (via get_net(net) and put_net(net) calls) So cpus might have to reload a contended cache line in net_hash_mix(net) calls. We need to reorder 'struct net' fields to move @hash_mix in a read mostly cache line. We move in the first cache line fields that can be dirtied often. We probably will have to address in a followup patch the __randomize_layout that was added in linux-4.13, since this might break our placement choices. Fixes: 355b98553789 ("netns: provide pure entropy for net_hash_mix()") Signed-off-by: Eric Dumazet Reported-by: kernel test robot Signed-off-by: David S. Miller --- include/net/net_namespace.h | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index f8712bbeb2e0..4c2cd9378699 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -52,6 +52,9 @@ struct bpf_prog; #define NETDEV_HASHENTRIES (1 << NETDEV_HASHBITS) struct net { + /* First cache line can be often dirtied. + * Do not place here read-mostly fields. + */ refcount_t passive; /* To decide when the network * namespace should be freed. */ @@ -60,7 +63,13 @@ struct net { */ spinlock_t rules_mod_lock; - u32 hash_mix; + unsigned int dev_unreg_count; + + unsigned int dev_base_seq; /* protected by rtnl_mutex */ + int ifindex; + + spinlock_t nsid_lock; + atomic_t fnhe_genid; struct list_head list; /* list of network namespaces */ struct list_head exit_list; /* To linked to call pernet exit @@ -76,11 +85,11 @@ struct net { #endif struct user_namespace *user_ns; /* Owning user namespace */ struct ucounts *ucounts; - spinlock_t nsid_lock; struct idr netns_ids; struct ns_common ns; + struct list_head dev_base_head; struct proc_dir_entry *proc_net; struct proc_dir_entry *proc_net_stat; @@ -93,17 +102,18 @@ struct net { struct uevent_sock *uevent_sock; /* uevent socket */ - struct list_head dev_base_head; struct hlist_head *dev_name_head; struct hlist_head *dev_index_head; - unsigned int dev_base_seq; /* protected by rtnl_mutex */ - int ifindex; - unsigned int dev_unreg_count; + /* Note that @hash_mix can be read millions times per second, + * it is critical that it is on a read_mostly cache line. + */ + u32 hash_mix; + + struct net_device *loopback_dev; /* The loopback */ /* core fib_rules */ struct list_head rules_ops; - struct net_device *loopback_dev; /* The loopback */ struct netns_core core; struct netns_mib mib; struct netns_packet packet; @@ -171,7 +181,6 @@ struct net { struct sock *crypto_nlsk; #endif struct sock *diag_nlsk; - atomic_t fnhe_genid; } __randomize_layout; #include -- GitLab From f4e23cf9477452640d2522f3286db5df6fcfe45a Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 3 Oct 2019 18:02:08 +0100 Subject: [PATCH 533/993] KVM: arm64: pmu: Fix cycle counter truncation When a counter is disabled, its value is sampled before the event is being disabled, and the value written back in the shadow register. In that process, the value gets truncated to 32bit, which is adequate for any counter but the cycle counter (defined as a 64bit counter). This obviously results in a corrupted counter, and things like "perf record -e cycles" not working at all when run in a guest... A similar, but less critical bug exists in kvm_pmu_get_counter_value. Make the truncation conditional on the counter not being the cycle counter, which results in a minor code reorganisation. Fixes: 80f393a23be6 ("KVM: arm/arm64: Support chained PMU counters") Reviewed-by: Andrew Murray Reported-by: Julien Thierry Signed-off-by: Marc Zyngier --- virt/kvm/arm/pmu.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c index 362a01886bab..c30c3a74fc7f 100644 --- a/virt/kvm/arm/pmu.c +++ b/virt/kvm/arm/pmu.c @@ -146,8 +146,7 @@ u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu, u64 select_idx) if (kvm_pmu_pmc_is_chained(pmc) && kvm_pmu_idx_is_high_counter(select_idx)) counter = upper_32_bits(counter); - - else if (!kvm_pmu_idx_is_64bit(vcpu, select_idx)) + else if (select_idx != ARMV8_PMU_CYCLE_IDX) counter = lower_32_bits(counter); return counter; @@ -193,7 +192,7 @@ static void kvm_pmu_release_perf_event(struct kvm_pmc *pmc) */ static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu, struct kvm_pmc *pmc) { - u64 counter, reg; + u64 counter, reg, val; pmc = kvm_pmu_get_canonical_pmc(pmc); if (!pmc->perf_event) @@ -201,16 +200,19 @@ static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu, struct kvm_pmc *pmc) counter = kvm_pmu_get_pair_counter_value(vcpu, pmc); - if (kvm_pmu_pmc_is_chained(pmc)) { - reg = PMEVCNTR0_EL0 + pmc->idx; - __vcpu_sys_reg(vcpu, reg) = lower_32_bits(counter); - __vcpu_sys_reg(vcpu, reg + 1) = upper_32_bits(counter); + if (pmc->idx == ARMV8_PMU_CYCLE_IDX) { + reg = PMCCNTR_EL0; + val = counter; } else { - reg = (pmc->idx == ARMV8_PMU_CYCLE_IDX) - ? PMCCNTR_EL0 : PMEVCNTR0_EL0 + pmc->idx; - __vcpu_sys_reg(vcpu, reg) = lower_32_bits(counter); + reg = PMEVCNTR0_EL0 + pmc->idx; + val = lower_32_bits(counter); } + __vcpu_sys_reg(vcpu, reg) = val; + + if (kvm_pmu_pmc_is_chained(pmc)) + __vcpu_sys_reg(vcpu, reg + 1) = upper_32_bits(counter); + kvm_pmu_release_perf_event(pmc); } -- GitLab From 6f16371453476fd094760ea3d6f00144e9ae3057 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 4 Oct 2019 11:03:09 +0100 Subject: [PATCH 534/993] arm64: KVM: Handle PMCR_EL0.LC as RES1 on pure AArch64 systems Of PMCR_EL0.LC, the ARMv8 ARM says: "In an AArch64 only implementation, this field is RES 1." So be it. Fixes: ab9468340d2bc ("arm64: KVM: Add access handler for PMCR register") Reviewed-by: Andrew Murray Signed-off-by: Marc Zyngier --- arch/arm64/kvm/sys_regs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 2071260a275b..46822afc57e0 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -632,6 +632,8 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) */ val = ((pmcr & ~ARMV8_PMU_PMCR_MASK) | (ARMV8_PMU_PMCR_MASK & 0xdecafbad)) & (~ARMV8_PMU_PMCR_E); + if (!system_supports_32bit_el0()) + val |= ARMV8_PMU_PMCR_LC; __vcpu_sys_reg(vcpu, r->reg) = val; } @@ -682,6 +684,8 @@ static bool access_pmcr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, val = __vcpu_sys_reg(vcpu, PMCR_EL0); val &= ~ARMV8_PMU_PMCR_MASK; val |= p->regval & ARMV8_PMU_PMCR_MASK; + if (!system_supports_32bit_el0()) + val |= ARMV8_PMU_PMCR_LC; __vcpu_sys_reg(vcpu, PMCR_EL0) = val; kvm_pmu_handle_pmcr(vcpu, val); kvm_vcpu_pmu_restore_guest(vcpu); -- GitLab From 725ce66979fb6da5c1aec5b064d0871bedc23bf7 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 8 Oct 2019 15:09:55 +0100 Subject: [PATCH 535/993] KVM: arm64: pmu: Set the CHAINED attribute before creating the in-kernel event The current convention for KVM to request a chained event from the host PMU is to set bit[0] in attr.config1 (PERF_ATTR_CFG1_KVM_PMU_CHAINED). But as it turns out, this bit gets set *after* we create the kernel event that backs our virtual counter, meaning that we never get a 64bit counter. Moving the setting to an earlier point solves the problem. Fixes: 80f393a23be6 ("KVM: arm/arm64: Support chained PMU counters") Reviewed-by: Andrew Murray Signed-off-by: Marc Zyngier --- virt/kvm/arm/pmu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c index c30c3a74fc7f..f291d4ac3519 100644 --- a/virt/kvm/arm/pmu.c +++ b/virt/kvm/arm/pmu.c @@ -569,12 +569,12 @@ static void kvm_pmu_create_perf_event(struct kvm_vcpu *vcpu, u64 select_idx) * high counter. */ attr.sample_period = (-counter) & GENMASK(63, 0); + if (kvm_pmu_counter_is_enabled(vcpu, pmc->idx + 1)) + attr.config1 |= PERF_ATTR_CFG1_KVM_PMU_CHAINED; + event = perf_event_create_kernel_counter(&attr, -1, current, kvm_pmu_perf_overflow, pmc + 1); - - if (kvm_pmu_counter_is_enabled(vcpu, pmc->idx + 1)) - attr.config1 |= PERF_ATTR_CFG1_KVM_PMU_CHAINED; } else { /* The initial sample period (overflow count) of an event. */ if (kvm_pmu_idx_is_64bit(vcpu, pmc->idx)) -- GitLab From 8c3252c06516eac22c4f8e2506122171abedcc09 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sun, 6 Oct 2019 10:28:50 +0100 Subject: [PATCH 536/993] KVM: arm64: pmu: Reset sample period on overflow handling The PMU emulation code uses the perf event sample period to trigger the overflow detection. This works fine for the *first* overflow handling, but results in a huge number of interrupts on the host, unrelated to the number of interrupts handled in the guest (a x20 factor is pretty common for the cycle counter). On a slow system (such as a SW model), this can result in the guest only making forward progress at a glacial pace. It turns out that the clue is in the name. The sample period is exactly that: a period. And once the an overflow has occured, the following period should be the full width of the associated counter, instead of whatever the guest had initially programed. Reset the sample period to the architected value in the overflow handler, which now results in a number of host interrupts that is much closer to the number of interrupts in the guest. Fixes: b02386eb7dac ("arm64: KVM: Add PMU overflow interrupt routing") Reviewed-by: Andrew Murray Signed-off-by: Marc Zyngier --- virt/kvm/arm/pmu.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c index f291d4ac3519..8731dfeced8b 100644 --- a/virt/kvm/arm/pmu.c +++ b/virt/kvm/arm/pmu.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -442,8 +443,25 @@ static void kvm_pmu_perf_overflow(struct perf_event *perf_event, struct pt_regs *regs) { struct kvm_pmc *pmc = perf_event->overflow_handler_context; + struct arm_pmu *cpu_pmu = to_arm_pmu(perf_event->pmu); struct kvm_vcpu *vcpu = kvm_pmc_to_vcpu(pmc); int idx = pmc->idx; + u64 period; + + cpu_pmu->pmu.stop(perf_event, PERF_EF_UPDATE); + + /* + * Reset the sample period to the architectural limit, + * i.e. the point where the counter overflows. + */ + period = -(local64_read(&perf_event->count)); + + if (!kvm_pmu_idx_is_64bit(vcpu, pmc->idx)) + period &= GENMASK(31, 0); + + local64_set(&perf_event->hw.period_left, 0); + perf_event->attr.sample_period = period; + perf_event->hw.sample_period = period; __vcpu_sys_reg(vcpu, PMOVSSET_EL0) |= BIT(idx); @@ -451,6 +469,8 @@ static void kvm_pmu_perf_overflow(struct perf_event *perf_event, kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu); kvm_vcpu_kick(vcpu); } + + cpu_pmu->pmu.start(perf_event, PERF_EF_RELOAD); } /** -- GitLab From 13301c6b16a6d809b331bb88e40ab9ce38238b8b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 20 Oct 2019 00:07:26 +0200 Subject: [PATCH 537/993] perf/x86/intel/pt: Fix base for single entry topa Jan reported failing ltp test for PT: https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/tracing/pt_test/pt_test.c It looks like the reason is this new commit added in this v5.4 merge window: 38bb8d77d0b9 ("perf/x86/intel/pt: Split ToPA metadata and page layout") which did not keep the TOPA_SHIFT for entry base. Add it back. Reported-by: Jan Stancek Signed-off-by: Jiri Olsa Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Linus Torvalds Cc: Mark Rutland Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Fixes: 38bb8d77d0b9 ("perf/x86/intel/pt: Split ToPA metadata and page layout") Link: https://lkml.kernel.org/r/20191019220726.12213-1-jolsa@kernel.org [ Minor changelog edits. ] Signed-off-by: Ingo Molnar --- arch/x86/events/intel/pt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 74e80ed9c6c4..05e43d0f430b 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -627,7 +627,7 @@ static struct topa *topa_alloc(int cpu, gfp_t gfp) * link as the 2nd entry in the table */ if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries)) { - TOPA_ENTRY(&tp->topa, 1)->base = page_to_phys(p); + TOPA_ENTRY(&tp->topa, 1)->base = page_to_phys(p) >> TOPA_SHIFT; TOPA_ENTRY(&tp->topa, 1)->end = 1; } -- GitLab From 6fc28b7e0aac8a72217b314dfb5208321d9448e2 Mon Sep 17 00:00:00 2001 From: "amy.shih" Date: Mon, 14 Oct 2019 16:24:51 +0800 Subject: [PATCH 538/993] hwmon: (nct7904) Fix the incorrect value of vsen_mask & tcpu_mask & temp_mode in nct7904_data struct. Voltage sensors overlap with external temperature sensors. Detect the multi-function of voltage, thermal diode, thermistor and reserved from register VT_ADC_MD_REG to set value of vsen_mask & tcpu_mask & temp_mode in nct7904_data struct. If the value is reserved, needs to disable the vsen_mask & tcpu_mask. Signed-off-by: amy.shih Link: https://lore.kernel.org/r/20191014082451.2895-1-Amy.Shih@advantech.com.tw Signed-off-by: Guenter Roeck --- drivers/hwmon/nct7904.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c index b26419dbe840..281c81edabc6 100644 --- a/drivers/hwmon/nct7904.c +++ b/drivers/hwmon/nct7904.c @@ -82,6 +82,10 @@ #define FANCTL1_FMR_REG 0x00 /* Bank 3; 1 reg per channel */ #define FANCTL1_OUT_REG 0x10 /* Bank 3; 1 reg per channel */ +#define VOLT_MONITOR_MODE 0x0 +#define THERMAL_DIODE_MODE 0x1 +#define THERMISTOR_MODE 0x3 + #define ENABLE_TSI BIT(1) static const unsigned short normal_i2c[] = { @@ -935,11 +939,16 @@ static int nct7904_probe(struct i2c_client *client, for (i = 0; i < 4; i++) { val = (ret >> (i * 2)) & 0x03; bit = (1 << i); - if (val == 0) { + if (val == VOLT_MONITOR_MODE) { data->tcpu_mask &= ~bit; + } else if (val == THERMAL_DIODE_MODE && i < 2) { + data->temp_mode |= bit; + data->vsen_mask &= ~(0x06 << (i * 2)); + } else if (val == THERMISTOR_MODE) { + data->vsen_mask &= ~(0x02 << (i * 2)); } else { - if (val == 0x1 || val == 0x2) - data->temp_mode |= bit; + /* Reserved */ + data->tcpu_mask &= ~bit; data->vsen_mask &= ~(0x06 << (i * 2)); } } -- GitLab From 7d194c2100ad2a6dded545887d02754948ca5241 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 20 Oct 2019 15:56:22 -0400 Subject: [PATCH 539/993] Linux 5.4-rc4 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 19efe04b398c..5475cdb6d57d 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc4 NAME = Nesting Opossum # *DOCUMENTATION* -- GitLab From 77751a466ebd1a785456556061a2db6d60ea3898 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 16 Oct 2019 12:41:24 +0200 Subject: [PATCH 540/993] PM: QoS: Introduce frequency QoS Introduce frequency QoS, based on the "raw" low-level PM QoS, to represent min and max frequency requests and aggregate constraints. The min and max frequency requests are to be represented by struct freq_qos_request objects and the aggregate constraints are to be represented by struct freq_constraints objects. The latter are expected to be initialized with the help of freq_constraints_init(). The freq_qos_read_value() helper is defined to retrieve the aggregate constraints values from a given struct freq_constraints object and there are the freq_qos_add_request(), freq_qos_update_request() and freq_qos_remove_request() helpers to manipulate the min and max frequency requests. It is assumed that the the helpers will not run concurrently with each other for the same struct freq_qos_request object, so if that may be the case, their uses must ensure proper synchronization between them (e.g. through locking). In addition, freq_qos_add_notifier() and freq_qos_remove_notifier() are provided to add and remove notifiers that will trigger on aggregate constraint changes to and from a given struct freq_constraints object, respectively. Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar --- include/linux/pm_qos.h | 44 ++++++++ kernel/power/qos.c | 240 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 284 insertions(+) diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 222c3e01397c..57b93e3d8f29 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -267,4 +267,48 @@ static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev) } #endif +#define FREQ_QOS_MIN_DEFAULT_VALUE 0 +#define FREQ_QOS_MAX_DEFAULT_VALUE (-1) + +enum freq_qos_req_type { + FREQ_QOS_MIN = 1, + FREQ_QOS_MAX, +}; + +struct freq_constraints { + struct pm_qos_constraints min_freq; + struct blocking_notifier_head min_freq_notifiers; + struct pm_qos_constraints max_freq; + struct blocking_notifier_head max_freq_notifiers; +}; + +struct freq_qos_request { + enum freq_qos_req_type type; + struct plist_node pnode; + struct freq_constraints *qos; +}; + +static inline int freq_qos_request_active(struct freq_qos_request *req) +{ + return !IS_ERR_OR_NULL(req->qos); +} + +void freq_constraints_init(struct freq_constraints *qos); + +s32 freq_qos_read_value(struct freq_constraints *qos, + enum freq_qos_req_type type); + +int freq_qos_add_request(struct freq_constraints *qos, + struct freq_qos_request *req, + enum freq_qos_req_type type, s32 value); +int freq_qos_update_request(struct freq_qos_request *req, s32 new_value); +int freq_qos_remove_request(struct freq_qos_request *req); + +int freq_qos_add_notifier(struct freq_constraints *qos, + enum freq_qos_req_type type, + struct notifier_block *notifier); +int freq_qos_remove_notifier(struct freq_constraints *qos, + enum freq_qos_req_type type, + struct notifier_block *notifier); + #endif diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 9568a2fe7c11..04e83fdfbe80 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -650,3 +650,243 @@ static int __init pm_qos_power_init(void) } late_initcall(pm_qos_power_init); + +/* Definitions related to the frequency QoS below. */ + +/** + * freq_constraints_init - Initialize frequency QoS constraints. + * @qos: Frequency QoS constraints to initialize. + */ +void freq_constraints_init(struct freq_constraints *qos) +{ + struct pm_qos_constraints *c; + + c = &qos->min_freq; + plist_head_init(&c->list); + c->target_value = FREQ_QOS_MIN_DEFAULT_VALUE; + c->default_value = FREQ_QOS_MIN_DEFAULT_VALUE; + c->no_constraint_value = FREQ_QOS_MIN_DEFAULT_VALUE; + c->type = PM_QOS_MAX; + c->notifiers = &qos->min_freq_notifiers; + BLOCKING_INIT_NOTIFIER_HEAD(c->notifiers); + + c = &qos->max_freq; + plist_head_init(&c->list); + c->target_value = FREQ_QOS_MAX_DEFAULT_VALUE; + c->default_value = FREQ_QOS_MAX_DEFAULT_VALUE; + c->no_constraint_value = FREQ_QOS_MAX_DEFAULT_VALUE; + c->type = PM_QOS_MIN; + c->notifiers = &qos->max_freq_notifiers; + BLOCKING_INIT_NOTIFIER_HEAD(c->notifiers); +} + +/** + * freq_qos_read_value - Get frequency QoS constraint for a given list. + * @qos: Constraints to evaluate. + * @type: QoS request type. + */ +s32 freq_qos_read_value(struct freq_constraints *qos, + enum freq_qos_req_type type) +{ + s32 ret; + + switch (type) { + case FREQ_QOS_MIN: + ret = IS_ERR_OR_NULL(qos) ? + FREQ_QOS_MIN_DEFAULT_VALUE : + pm_qos_read_value(&qos->min_freq); + break; + case FREQ_QOS_MAX: + ret = IS_ERR_OR_NULL(qos) ? + FREQ_QOS_MAX_DEFAULT_VALUE : + pm_qos_read_value(&qos->max_freq); + break; + default: + WARN_ON(1); + ret = 0; + } + + return ret; +} + +/** + * freq_qos_apply - Add/modify/remove frequency QoS request. + * @req: Constraint request to apply. + * @action: Action to perform (add/update/remove). + * @value: Value to assign to the QoS request. + */ +static int freq_qos_apply(struct freq_qos_request *req, + enum pm_qos_req_action action, s32 value) +{ + int ret; + + switch(req->type) { + case FREQ_QOS_MIN: + ret = pm_qos_update_target(&req->qos->min_freq, &req->pnode, + action, value); + break; + case FREQ_QOS_MAX: + ret = pm_qos_update_target(&req->qos->max_freq, &req->pnode, + action, value); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +/** + * freq_qos_add_request - Insert new frequency QoS request into a given list. + * @qos: Constraints to update. + * @req: Preallocated request object. + * @type: Request type. + * @value: Request value. + * + * Insert a new entry into the @qos list of requests, recompute the effective + * QoS constraint value for that list and initialize the @req object. The + * caller needs to save that object for later use in updates and removal. + * + * Return 1 if the effective constraint value has changed, 0 if the effective + * constraint value has not changed, or a negative error code on failures. + */ +int freq_qos_add_request(struct freq_constraints *qos, + struct freq_qos_request *req, + enum freq_qos_req_type type, s32 value) +{ + int ret; + + if (IS_ERR_OR_NULL(qos) || !req) + return -EINVAL; + + if (WARN(freq_qos_request_active(req), + "%s() called for active request\n", __func__)) + return -EINVAL; + + req->qos = qos; + req->type = type; + ret = freq_qos_apply(req, PM_QOS_ADD_REQ, value); + if (ret < 0) { + req->qos = NULL; + req->type = 0; + } + + return ret; +} +EXPORT_SYMBOL_GPL(freq_qos_add_request); + +/** + * freq_qos_update_request - Modify existing frequency QoS request. + * @req: Request to modify. + * @new_value: New request value. + * + * Update an existing frequency QoS request along with the effective constraint + * value for the list of requests it belongs to. + * + * Return 1 if the effective constraint value has changed, 0 if the effective + * constraint value has not changed, or a negative error code on failures. + */ +int freq_qos_update_request(struct freq_qos_request *req, s32 new_value) +{ + if (!req) + return -EINVAL; + + if (WARN(!freq_qos_request_active(req), + "%s() called for unknown object\n", __func__)) + return -EINVAL; + + if (req->pnode.prio == new_value) + return 0; + + return freq_qos_apply(req, PM_QOS_UPDATE_REQ, new_value); +} +EXPORT_SYMBOL_GPL(freq_qos_update_request); + +/** + * freq_qos_remove_request - Remove frequency QoS request from its list. + * @req: Request to remove. + * + * Remove the given frequency QoS request from the list of constraints it + * belongs to and recompute the effective constraint value for that list. + * + * Return 1 if the effective constraint value has changed, 0 if the effective + * constraint value has not changed, or a negative error code on failures. + */ +int freq_qos_remove_request(struct freq_qos_request *req) +{ + if (!req) + return -EINVAL; + + if (WARN(!freq_qos_request_active(req), + "%s() called for unknown object\n", __func__)) + return -EINVAL; + + return freq_qos_apply(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); +} +EXPORT_SYMBOL_GPL(freq_qos_remove_request); + +/** + * freq_qos_add_notifier - Add frequency QoS change notifier. + * @qos: List of requests to add the notifier to. + * @type: Request type. + * @notifier: Notifier block to add. + */ +int freq_qos_add_notifier(struct freq_constraints *qos, + enum freq_qos_req_type type, + struct notifier_block *notifier) +{ + int ret; + + if (IS_ERR_OR_NULL(qos) || !notifier) + return -EINVAL; + + switch (type) { + case FREQ_QOS_MIN: + ret = blocking_notifier_chain_register(qos->min_freq.notifiers, + notifier); + break; + case FREQ_QOS_MAX: + ret = blocking_notifier_chain_register(qos->max_freq.notifiers, + notifier); + break; + default: + WARN_ON(1); + ret = -EINVAL; + } + + return ret; +} +EXPORT_SYMBOL_GPL(freq_qos_add_notifier); + +/** + * freq_qos_remove_notifier - Remove frequency QoS change notifier. + * @qos: List of requests to remove the notifier from. + * @type: Request type. + * @notifier: Notifier block to remove. + */ +int freq_qos_remove_notifier(struct freq_constraints *qos, + enum freq_qos_req_type type, + struct notifier_block *notifier) +{ + int ret; + + if (IS_ERR_OR_NULL(qos) || !notifier) + return -EINVAL; + + switch (type) { + case FREQ_QOS_MIN: + ret = blocking_notifier_chain_unregister(qos->min_freq.notifiers, + notifier); + break; + case FREQ_QOS_MAX: + ret = blocking_notifier_chain_unregister(qos->max_freq.notifiers, + notifier); + break; + default: + WARN_ON(1); + ret = -EINVAL; + } + + return ret; +} +EXPORT_SYMBOL_GPL(freq_qos_remove_notifier); -- GitLab From 3000ce3c52f8b8db093e4dc649cd172390f71137 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 16 Oct 2019 12:47:06 +0200 Subject: [PATCH 541/993] cpufreq: Use per-policy frequency QoS Replace the CPU device PM QoS used for the management of min and max frequency constraints in cpufreq (and its users) with per-policy frequency QoS to avoid problems with cpufreq policies covering more then one CPU. Namely, a cpufreq driver is registered with the subsys interface which calls cpufreq_add_dev() for each CPU, starting from CPU0, so currently the PM QoS notifiers are added to the first CPU in the policy (i.e. CPU0 in the majority of cases). In turn, when the cpufreq driver is unregistered, the subsys interface doing that calls cpufreq_remove_dev() for each CPU, starting from CPU0, and the PM QoS notifiers are only removed when cpufreq_remove_dev() is called for the last CPU in the policy, say CPUx, which as a rule is not CPU0 if the policy covers more than one CPU. Then, the PM QoS notifiers cannot be removed, because CPUx does not have them, and they are still there in the device PM QoS notifiers list of CPU0, which prevents new PM QoS notifiers from being registered for CPU0 on the next attempt to register the cpufreq driver. The same issue occurs when the first CPU in the policy goes offline before unregistering the driver. After this change it does not matter which CPU is the policy CPU at the driver registration time and whether or not it is online all the time, because the frequency QoS is per policy and not per CPU. Fixes: 67d874c3b2c6 ("cpufreq: Register notifiers with the PM QoS framework") Reported-by: Dmitry Osipenko Tested-by: Dmitry Osipenko Reported-by: Sudeep Holla Tested-by: Sudeep Holla Diagnosed-by: Viresh Kumar Link: https://lore.kernel.org/linux-pm/5ad2624194baa2f53acc1f1e627eb7684c577a19.1562210705.git.viresh.kumar@linaro.org/T/#md2d89e95906b8c91c15f582146173dce2e86e99f Link: https://lore.kernel.org/linux-pm/20191017094612.6tbkwoq4harsjcqv@vireshk-i7/T/#m30d48cc23b9a80467fbaa16e30f90b3828a5a29b Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar --- drivers/acpi/processor_driver.c | 9 ++-- drivers/acpi/processor_perflib.c | 18 +++---- drivers/acpi/processor_thermal.c | 18 +++---- drivers/cpufreq/cpufreq.c | 59 ++++++++++------------ drivers/cpufreq/intel_pstate.c | 30 +++++------ drivers/cpufreq/ppc_cbe_cpufreq_pmi.c | 15 +++--- drivers/macintosh/windfarm_cpufreq_clamp.c | 38 ++++++++------ drivers/thermal/cpu_cooling.c | 14 ++--- include/acpi/processor.h | 20 ++++---- include/linux/cpufreq.h | 7 ++- 10 files changed, 114 insertions(+), 114 deletions(-) diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 08da9c29f1e9..62114a03a51a 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -290,14 +290,13 @@ static int acpi_processor_notifier(struct notifier_block *nb, unsigned long event, void *data) { struct cpufreq_policy *policy = data; - int cpu = policy->cpu; if (event == CPUFREQ_CREATE_POLICY) { - acpi_thermal_cpufreq_init(cpu); - acpi_processor_ppc_init(cpu); + acpi_thermal_cpufreq_init(policy); + acpi_processor_ppc_init(policy); } else if (event == CPUFREQ_REMOVE_POLICY) { - acpi_processor_ppc_exit(cpu); - acpi_thermal_cpufreq_exit(cpu); + acpi_processor_ppc_exit(policy); + acpi_thermal_cpufreq_exit(policy); } return 0; diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 930a49fa4dfc..753e171de006 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -81,10 +81,10 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) pr->performance_platform_limit = (int)ppc; if (ppc >= pr->performance->state_count || - unlikely(!dev_pm_qos_request_active(&pr->perflib_req))) + unlikely(!freq_qos_request_active(&pr->perflib_req))) return 0; - ret = dev_pm_qos_update_request(&pr->perflib_req, + ret = freq_qos_update_request(&pr->perflib_req, pr->performance->states[ppc].core_frequency * 1000); if (ret < 0) { pr_warn("Failed to update perflib freq constraint: CPU%d (%d)\n", @@ -157,28 +157,28 @@ void acpi_processor_ignore_ppc_init(void) ignore_ppc = 0; } -void acpi_processor_ppc_init(int cpu) +void acpi_processor_ppc_init(struct cpufreq_policy *policy) { + int cpu = policy->cpu; struct acpi_processor *pr = per_cpu(processors, cpu); int ret; if (!pr) return; - ret = dev_pm_qos_add_request(get_cpu_device(cpu), - &pr->perflib_req, DEV_PM_QOS_MAX_FREQUENCY, - INT_MAX); + ret = freq_qos_add_request(&policy->constraints, &pr->perflib_req, + FREQ_QOS_MAX, INT_MAX); if (ret < 0) pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, ret); } -void acpi_processor_ppc_exit(int cpu) +void acpi_processor_ppc_exit(struct cpufreq_policy *policy) { - struct acpi_processor *pr = per_cpu(processors, cpu); + struct acpi_processor *pr = per_cpu(processors, policy->cpu); if (pr) - dev_pm_qos_remove_request(&pr->perflib_req); + freq_qos_remove_request(&pr->perflib_req); } static int acpi_processor_get_performance_control(struct acpi_processor *pr) diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 8227c7dd75b1..c77a5b1fb107 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -105,7 +105,7 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) pr = per_cpu(processors, i); - if (unlikely(!dev_pm_qos_request_active(&pr->thermal_req))) + if (unlikely(!freq_qos_request_active(&pr->thermal_req))) continue; policy = cpufreq_cpu_get(i); @@ -116,7 +116,7 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) cpufreq_cpu_put(policy); - ret = dev_pm_qos_update_request(&pr->thermal_req, max_freq); + ret = freq_qos_update_request(&pr->thermal_req, max_freq); if (ret < 0) { pr_warn("Failed to update thermal freq constraint: CPU%d (%d)\n", pr->id, ret); @@ -125,28 +125,28 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) return 0; } -void acpi_thermal_cpufreq_init(int cpu) +void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy) { + int cpu = policy->cpu; struct acpi_processor *pr = per_cpu(processors, cpu); int ret; if (!pr) return; - ret = dev_pm_qos_add_request(get_cpu_device(cpu), - &pr->thermal_req, DEV_PM_QOS_MAX_FREQUENCY, - INT_MAX); + ret = freq_qos_add_request(&policy->constraints, &pr->thermal_req, + FREQ_QOS_MAX, INT_MAX); if (ret < 0) pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, ret); } -void acpi_thermal_cpufreq_exit(int cpu) +void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy) { - struct acpi_processor *pr = per_cpu(processors, cpu); + struct acpi_processor *pr = per_cpu(processors, policy->cpu); if (pr) - dev_pm_qos_remove_request(&pr->thermal_req); + freq_qos_remove_request(&pr->thermal_req); } #else /* ! CONFIG_CPU_FREQ */ static int cpufreq_get_max_state(unsigned int cpu) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index bffc11b87247..8478ff6f3045 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -720,7 +720,7 @@ static ssize_t store_##file_name \ if (ret != 1) \ return -EINVAL; \ \ - ret = dev_pm_qos_update_request(policy->object##_freq_req, val);\ + ret = freq_qos_update_request(policy->object##_freq_req, val);\ return ret >= 0 ? count : ret; \ } @@ -1202,19 +1202,21 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) goto err_free_real_cpus; } + freq_constraints_init(&policy->constraints); + policy->nb_min.notifier_call = cpufreq_notifier_min; policy->nb_max.notifier_call = cpufreq_notifier_max; - ret = dev_pm_qos_add_notifier(dev, &policy->nb_min, - DEV_PM_QOS_MIN_FREQUENCY); + ret = freq_qos_add_notifier(&policy->constraints, FREQ_QOS_MIN, + &policy->nb_min); if (ret) { dev_err(dev, "Failed to register MIN QoS notifier: %d (%*pbl)\n", ret, cpumask_pr_args(policy->cpus)); goto err_kobj_remove; } - ret = dev_pm_qos_add_notifier(dev, &policy->nb_max, - DEV_PM_QOS_MAX_FREQUENCY); + ret = freq_qos_add_notifier(&policy->constraints, FREQ_QOS_MAX, + &policy->nb_max); if (ret) { dev_err(dev, "Failed to register MAX QoS notifier: %d (%*pbl)\n", ret, cpumask_pr_args(policy->cpus)); @@ -1232,8 +1234,8 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) return policy; err_min_qos_notifier: - dev_pm_qos_remove_notifier(dev, &policy->nb_min, - DEV_PM_QOS_MIN_FREQUENCY); + freq_qos_remove_notifier(&policy->constraints, FREQ_QOS_MIN, + &policy->nb_min); err_kobj_remove: cpufreq_policy_put_kobj(policy); err_free_real_cpus: @@ -1250,7 +1252,6 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) static void cpufreq_policy_free(struct cpufreq_policy *policy) { - struct device *dev = get_cpu_device(policy->cpu); unsigned long flags; int cpu; @@ -1262,10 +1263,10 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy) per_cpu(cpufreq_cpu_data, cpu) = NULL; write_unlock_irqrestore(&cpufreq_driver_lock, flags); - dev_pm_qos_remove_notifier(dev, &policy->nb_max, - DEV_PM_QOS_MAX_FREQUENCY); - dev_pm_qos_remove_notifier(dev, &policy->nb_min, - DEV_PM_QOS_MIN_FREQUENCY); + freq_qos_remove_notifier(&policy->constraints, FREQ_QOS_MAX, + &policy->nb_max); + freq_qos_remove_notifier(&policy->constraints, FREQ_QOS_MIN, + &policy->nb_min); if (policy->max_freq_req) { /* @@ -1274,10 +1275,10 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy) */ blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_REMOVE_POLICY, policy); - dev_pm_qos_remove_request(policy->max_freq_req); + freq_qos_remove_request(policy->max_freq_req); } - dev_pm_qos_remove_request(policy->min_freq_req); + freq_qos_remove_request(policy->min_freq_req); kfree(policy->min_freq_req); cpufreq_policy_put_kobj(policy); @@ -1357,8 +1358,6 @@ static int cpufreq_online(unsigned int cpu) cpumask_and(policy->cpus, policy->cpus, cpu_online_mask); if (new_policy) { - struct device *dev = get_cpu_device(cpu); - for_each_cpu(j, policy->related_cpus) { per_cpu(cpufreq_cpu_data, j) = policy; add_cpu_dev_symlink(policy, j); @@ -1369,36 +1368,31 @@ static int cpufreq_online(unsigned int cpu) if (!policy->min_freq_req) goto out_destroy_policy; - ret = dev_pm_qos_add_request(dev, policy->min_freq_req, - DEV_PM_QOS_MIN_FREQUENCY, - policy->min); + ret = freq_qos_add_request(&policy->constraints, + policy->min_freq_req, FREQ_QOS_MIN, + policy->min); if (ret < 0) { /* - * So we don't call dev_pm_qos_remove_request() for an + * So we don't call freq_qos_remove_request() for an * uninitialized request. */ kfree(policy->min_freq_req); policy->min_freq_req = NULL; - - dev_err(dev, "Failed to add min-freq constraint (%d)\n", - ret); goto out_destroy_policy; } /* * This must be initialized right here to avoid calling - * dev_pm_qos_remove_request() on uninitialized request in case + * freq_qos_remove_request() on uninitialized request in case * of errors. */ policy->max_freq_req = policy->min_freq_req + 1; - ret = dev_pm_qos_add_request(dev, policy->max_freq_req, - DEV_PM_QOS_MAX_FREQUENCY, - policy->max); + ret = freq_qos_add_request(&policy->constraints, + policy->max_freq_req, FREQ_QOS_MAX, + policy->max); if (ret < 0) { policy->max_freq_req = NULL; - dev_err(dev, "Failed to add max-freq constraint (%d)\n", - ret); goto out_destroy_policy; } @@ -2374,7 +2368,6 @@ int cpufreq_set_policy(struct cpufreq_policy *policy, struct cpufreq_policy *new_policy) { struct cpufreq_governor *old_gov; - struct device *cpu_dev = get_cpu_device(policy->cpu); int ret; pr_debug("setting new policy for CPU %u: %u - %u kHz\n", @@ -2386,8 +2379,8 @@ int cpufreq_set_policy(struct cpufreq_policy *policy, * PM QoS framework collects all the requests from users and provide us * the final aggregated value here. */ - new_policy->min = dev_pm_qos_read_value(cpu_dev, DEV_PM_QOS_MIN_FREQUENCY); - new_policy->max = dev_pm_qos_read_value(cpu_dev, DEV_PM_QOS_MAX_FREQUENCY); + new_policy->min = freq_qos_read_value(&policy->constraints, FREQ_QOS_MIN); + new_policy->max = freq_qos_read_value(&policy->constraints, FREQ_QOS_MAX); /* verify the cpu speed can be set within this limit */ ret = cpufreq_driver->verify(new_policy); @@ -2518,7 +2511,7 @@ static int cpufreq_boost_set_sw(int state) break; } - ret = dev_pm_qos_update_request(policy->max_freq_req, policy->max); + ret = freq_qos_update_request(policy->max_freq_req, policy->max); if (ret < 0) break; } diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 9f02de9a1b47..53a51c169451 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1088,10 +1088,10 @@ static ssize_t store_no_turbo(struct kobject *a, struct kobj_attribute *b, static struct cpufreq_driver intel_pstate; -static void update_qos_request(enum dev_pm_qos_req_type type) +static void update_qos_request(enum freq_qos_req_type type) { int max_state, turbo_max, freq, i, perf_pct; - struct dev_pm_qos_request *req; + struct freq_qos_request *req; struct cpufreq_policy *policy; for_each_possible_cpu(i) { @@ -1112,7 +1112,7 @@ static void update_qos_request(enum dev_pm_qos_req_type type) else turbo_max = cpu->pstate.turbo_pstate; - if (type == DEV_PM_QOS_MIN_FREQUENCY) { + if (type == FREQ_QOS_MIN) { perf_pct = global.min_perf_pct; } else { req++; @@ -1122,7 +1122,7 @@ static void update_qos_request(enum dev_pm_qos_req_type type) freq = DIV_ROUND_UP(turbo_max * perf_pct, 100); freq *= cpu->pstate.scaling; - if (dev_pm_qos_update_request(req, freq) < 0) + if (freq_qos_update_request(req, freq) < 0) pr_warn("Failed to update freq constraint: CPU%d\n", i); } } @@ -1153,7 +1153,7 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct kobj_attribute *b, if (intel_pstate_driver == &intel_pstate) intel_pstate_update_policies(); else - update_qos_request(DEV_PM_QOS_MAX_FREQUENCY); + update_qos_request(FREQ_QOS_MAX); mutex_unlock(&intel_pstate_driver_lock); @@ -1187,7 +1187,7 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct kobj_attribute *b, if (intel_pstate_driver == &intel_pstate) intel_pstate_update_policies(); else - update_qos_request(DEV_PM_QOS_MIN_FREQUENCY); + update_qos_request(FREQ_QOS_MIN); mutex_unlock(&intel_pstate_driver_lock); @@ -2381,7 +2381,7 @@ static unsigned int intel_cpufreq_fast_switch(struct cpufreq_policy *policy, static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy) { int max_state, turbo_max, min_freq, max_freq, ret; - struct dev_pm_qos_request *req; + struct freq_qos_request *req; struct cpudata *cpu; struct device *dev; @@ -2416,15 +2416,15 @@ static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy) max_freq = DIV_ROUND_UP(turbo_max * global.max_perf_pct, 100); max_freq *= cpu->pstate.scaling; - ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_MIN_FREQUENCY, - min_freq); + ret = freq_qos_add_request(&policy->constraints, req, FREQ_QOS_MIN, + min_freq); if (ret < 0) { dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret); goto free_req; } - ret = dev_pm_qos_add_request(dev, req + 1, DEV_PM_QOS_MAX_FREQUENCY, - max_freq); + ret = freq_qos_add_request(&policy->constraints, req + 1, FREQ_QOS_MAX, + max_freq); if (ret < 0) { dev_err(dev, "Failed to add max-freq constraint (%d)\n", ret); goto remove_min_req; @@ -2435,7 +2435,7 @@ static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy) return 0; remove_min_req: - dev_pm_qos_remove_request(req); + freq_qos_remove_request(req); free_req: kfree(req); pstate_exit: @@ -2446,12 +2446,12 @@ static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy) static int intel_cpufreq_cpu_exit(struct cpufreq_policy *policy) { - struct dev_pm_qos_request *req; + struct freq_qos_request *req; req = policy->driver_data; - dev_pm_qos_remove_request(req + 1); - dev_pm_qos_remove_request(req); + freq_qos_remove_request(req + 1); + freq_qos_remove_request(req); kfree(req); return intel_pstate_cpu_exit(policy); diff --git a/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c b/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c index bc9dd30395c4..037fe23bc6ed 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq_pmi.c @@ -65,7 +65,7 @@ EXPORT_SYMBOL_GPL(cbe_cpufreq_set_pmode_pmi); static void cbe_cpufreq_handle_pmi(pmi_message_t pmi_msg) { struct cpufreq_policy *policy; - struct dev_pm_qos_request *req; + struct freq_qos_request *req; u8 node, slow_mode; int cpu, ret; @@ -86,7 +86,7 @@ static void cbe_cpufreq_handle_pmi(pmi_message_t pmi_msg) req = policy->driver_data; - ret = dev_pm_qos_update_request(req, + ret = freq_qos_update_request(req, policy->freq_table[slow_mode].frequency); if (ret < 0) pr_warn("Failed to update freq constraint: %d\n", ret); @@ -103,7 +103,7 @@ static struct pmi_handler cbe_pmi_handler = { void cbe_cpufreq_pmi_policy_init(struct cpufreq_policy *policy) { - struct dev_pm_qos_request *req; + struct freq_qos_request *req; int ret; if (!cbe_cpufreq_has_pmi) @@ -113,9 +113,8 @@ void cbe_cpufreq_pmi_policy_init(struct cpufreq_policy *policy) if (!req) return; - ret = dev_pm_qos_add_request(get_cpu_device(policy->cpu), req, - DEV_PM_QOS_MAX_FREQUENCY, - policy->freq_table[0].frequency); + ret = freq_qos_add_request(&policy->constraints, req, FREQ_QOS_MAX, + policy->freq_table[0].frequency); if (ret < 0) { pr_err("Failed to add freq constraint (%d)\n", ret); kfree(req); @@ -128,10 +127,10 @@ EXPORT_SYMBOL_GPL(cbe_cpufreq_pmi_policy_init); void cbe_cpufreq_pmi_policy_exit(struct cpufreq_policy *policy) { - struct dev_pm_qos_request *req = policy->driver_data; + struct freq_qos_request *req = policy->driver_data; if (cbe_cpufreq_has_pmi) { - dev_pm_qos_remove_request(req); + freq_qos_remove_request(req); kfree(req); } } diff --git a/drivers/macintosh/windfarm_cpufreq_clamp.c b/drivers/macintosh/windfarm_cpufreq_clamp.c index 705c6200814b..7b726f00f183 100644 --- a/drivers/macintosh/windfarm_cpufreq_clamp.c +++ b/drivers/macintosh/windfarm_cpufreq_clamp.c @@ -18,7 +18,7 @@ static int clamped; static struct wf_control *clamp_control; -static struct dev_pm_qos_request qos_req; +static struct freq_qos_request qos_req; static unsigned int min_freq, max_freq; static int clamp_set(struct wf_control *ct, s32 value) @@ -35,7 +35,7 @@ static int clamp_set(struct wf_control *ct, s32 value) } clamped = value; - return dev_pm_qos_update_request(&qos_req, freq); + return freq_qos_update_request(&qos_req, freq); } static int clamp_get(struct wf_control *ct, s32 *value) @@ -77,38 +77,44 @@ static int __init wf_cpufreq_clamp_init(void) min_freq = policy->cpuinfo.min_freq; max_freq = policy->cpuinfo.max_freq; + + ret = freq_qos_add_request(&policy->constraints, &qos_req, FREQ_QOS_MAX, + max_freq); + cpufreq_cpu_put(policy); + if (ret < 0) { + pr_err("%s: Failed to add freq constraint (%d)\n", __func__, + ret); + return ret; + } + dev = get_cpu_device(0); if (unlikely(!dev)) { pr_warn("%s: No cpu device for cpu0\n", __func__); - return -ENODEV; + ret = -ENODEV; + goto fail; } clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL); - if (clamp == NULL) - return -ENOMEM; - - ret = dev_pm_qos_add_request(dev, &qos_req, DEV_PM_QOS_MAX_FREQUENCY, - max_freq); - if (ret < 0) { - pr_err("%s: Failed to add freq constraint (%d)\n", __func__, - ret); - goto free; + if (clamp == NULL) { + ret = -ENOMEM; + goto fail; } clamp->ops = &clamp_ops; clamp->name = "cpufreq-clamp"; ret = wf_register_control(clamp); if (ret) - goto fail; + goto free; + clamp_control = clamp; return 0; - fail: - dev_pm_qos_remove_request(&qos_req); free: kfree(clamp); + fail: + freq_qos_remove_request(&qos_req); return ret; } @@ -116,7 +122,7 @@ static void __exit wf_cpufreq_clamp_exit(void) { if (clamp_control) { wf_unregister_control(clamp_control); - dev_pm_qos_remove_request(&qos_req); + freq_qos_remove_request(&qos_req); } } diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 391f39776c6a..6b9865c786ba 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -88,7 +88,7 @@ struct cpufreq_cooling_device { struct cpufreq_policy *policy; struct list_head node; struct time_in_idle *idle_time; - struct dev_pm_qos_request qos_req; + struct freq_qos_request qos_req; }; static DEFINE_IDA(cpufreq_ida); @@ -331,7 +331,7 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, cpufreq_cdev->cpufreq_state = state; - return dev_pm_qos_update_request(&cpufreq_cdev->qos_req, + return freq_qos_update_request(&cpufreq_cdev->qos_req, cpufreq_cdev->freq_table[state].frequency); } @@ -615,9 +615,9 @@ __cpufreq_cooling_register(struct device_node *np, cooling_ops = &cpufreq_cooling_ops; } - ret = dev_pm_qos_add_request(dev, &cpufreq_cdev->qos_req, - DEV_PM_QOS_MAX_FREQUENCY, - cpufreq_cdev->freq_table[0].frequency); + ret = freq_qos_add_request(&policy->constraints, + &cpufreq_cdev->qos_req, FREQ_QOS_MAX, + cpufreq_cdev->freq_table[0].frequency); if (ret < 0) { pr_err("%s: Failed to add freq constraint (%d)\n", __func__, ret); @@ -637,7 +637,7 @@ __cpufreq_cooling_register(struct device_node *np, return cdev; remove_qos_req: - dev_pm_qos_remove_request(&cpufreq_cdev->qos_req); + freq_qos_remove_request(&cpufreq_cdev->qos_req); remove_ida: ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id); free_table: @@ -736,7 +736,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) mutex_unlock(&cooling_list_lock); thermal_cooling_device_unregister(cdev); - dev_pm_qos_remove_request(&cpufreq_cdev->qos_req); + freq_qos_remove_request(&cpufreq_cdev->qos_req); ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id); kfree(cpufreq_cdev->idle_time); kfree(cpufreq_cdev->freq_table); diff --git a/include/acpi/processor.h b/include/acpi/processor.h index f936033cb9e6..47805172e73d 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -232,8 +232,8 @@ struct acpi_processor { struct acpi_processor_limit limit; struct thermal_cooling_device *cdev; struct device *dev; /* Processor device. */ - struct dev_pm_qos_request perflib_req; - struct dev_pm_qos_request thermal_req; + struct freq_qos_request perflib_req; + struct freq_qos_request thermal_req; }; struct acpi_processor_errata { @@ -302,8 +302,8 @@ static inline void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx #ifdef CONFIG_CPU_FREQ extern bool acpi_processor_cpufreq_init; void acpi_processor_ignore_ppc_init(void); -void acpi_processor_ppc_init(int cpu); -void acpi_processor_ppc_exit(int cpu); +void acpi_processor_ppc_init(struct cpufreq_policy *policy); +void acpi_processor_ppc_exit(struct cpufreq_policy *policy); void acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag); extern int acpi_processor_get_bios_limit(int cpu, unsigned int *limit); #else @@ -311,11 +311,11 @@ static inline void acpi_processor_ignore_ppc_init(void) { return; } -static inline void acpi_processor_ppc_init(int cpu) +static inline void acpi_processor_ppc_init(struct cpufreq_policy *policy) { return; } -static inline void acpi_processor_ppc_exit(int cpu) +static inline void acpi_processor_ppc_exit(struct cpufreq_policy *policy) { return; } @@ -431,14 +431,14 @@ static inline int acpi_processor_hotplug(struct acpi_processor *pr) int acpi_processor_get_limit_info(struct acpi_processor *pr); extern const struct thermal_cooling_device_ops processor_cooling_ops; #if defined(CONFIG_ACPI_CPU_FREQ_PSS) & defined(CONFIG_CPU_FREQ) -void acpi_thermal_cpufreq_init(int cpu); -void acpi_thermal_cpufreq_exit(int cpu); +void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy); +void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy); #else -static inline void acpi_thermal_cpufreq_init(int cpu) +static inline void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy) { return; } -static inline void acpi_thermal_cpufreq_exit(int cpu) +static inline void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy) { return; } diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index c57e88e85c41..92d5fdc8154e 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -76,8 +77,10 @@ struct cpufreq_policy { struct work_struct update; /* if update_policy() needs to be * called, but you're in IRQ context */ - struct dev_pm_qos_request *min_freq_req; - struct dev_pm_qos_request *max_freq_req; + struct freq_constraints constraints; + struct freq_qos_request *min_freq_req; + struct freq_qos_request *max_freq_req; + struct cpufreq_frequency_table *freq_table; enum cpufreq_table_sorting freq_table_sorted; -- GitLab From 2aac8bdf7a0fbd3e2a34141d28b57a7e21482cf7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 16 Oct 2019 12:47:53 +0200 Subject: [PATCH 542/993] PM: QoS: Drop frequency QoS types from device PM QoS There are no more active users of DEV_PM_QOS_MIN_FREQUENCY and DEV_PM_QOS_MAX_FREQUENCY device PM QoS request types, so drop them along with the code supporting them. Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar --- drivers/base/power/qos.c | 70 ++-------------------------------------- include/linux/pm_qos.h | 12 ------- 2 files changed, 2 insertions(+), 80 deletions(-) diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 6c90fd7e2ff8..350dcafd751f 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -115,20 +115,10 @@ s32 dev_pm_qos_read_value(struct device *dev, enum dev_pm_qos_req_type type) spin_lock_irqsave(&dev->power.lock, flags); - switch (type) { - case DEV_PM_QOS_RESUME_LATENCY: + if (type == DEV_PM_QOS_RESUME_LATENCY) { ret = IS_ERR_OR_NULL(qos) ? PM_QOS_RESUME_LATENCY_NO_CONSTRAINT : pm_qos_read_value(&qos->resume_latency); - break; - case DEV_PM_QOS_MIN_FREQUENCY: - ret = IS_ERR_OR_NULL(qos) ? PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE - : pm_qos_read_value(&qos->min_frequency); - break; - case DEV_PM_QOS_MAX_FREQUENCY: - ret = IS_ERR_OR_NULL(qos) ? PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE - : pm_qos_read_value(&qos->max_frequency); - break; - default: + } else { WARN_ON(1); ret = 0; } @@ -169,14 +159,6 @@ static int apply_constraint(struct dev_pm_qos_request *req, req->dev->power.set_latency_tolerance(req->dev, value); } break; - case DEV_PM_QOS_MIN_FREQUENCY: - ret = pm_qos_update_target(&qos->min_frequency, - &req->data.pnode, action, value); - break; - case DEV_PM_QOS_MAX_FREQUENCY: - ret = pm_qos_update_target(&qos->max_frequency, - &req->data.pnode, action, value); - break; case DEV_PM_QOS_FLAGS: ret = pm_qos_update_flags(&qos->flags, &req->data.flr, action, value); @@ -227,24 +209,6 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) c->no_constraint_value = PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT; c->type = PM_QOS_MIN; - c = &qos->min_frequency; - plist_head_init(&c->list); - c->target_value = PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE; - c->default_value = PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE; - c->no_constraint_value = PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE; - c->type = PM_QOS_MAX; - c->notifiers = ++n; - BLOCKING_INIT_NOTIFIER_HEAD(n); - - c = &qos->max_frequency; - plist_head_init(&c->list); - c->target_value = PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE; - c->default_value = PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE; - c->no_constraint_value = PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE; - c->type = PM_QOS_MIN; - c->notifiers = ++n; - BLOCKING_INIT_NOTIFIER_HEAD(n); - INIT_LIST_HEAD(&qos->flags.list); spin_lock_irq(&dev->power.lock); @@ -305,18 +269,6 @@ void dev_pm_qos_constraints_destroy(struct device *dev) memset(req, 0, sizeof(*req)); } - c = &qos->min_frequency; - plist_for_each_entry_safe(req, tmp, &c->list, data.pnode) { - apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE); - memset(req, 0, sizeof(*req)); - } - - c = &qos->max_frequency; - plist_for_each_entry_safe(req, tmp, &c->list, data.pnode) { - apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE); - memset(req, 0, sizeof(*req)); - } - f = &qos->flags; list_for_each_entry_safe(req, tmp, &f->list, data.flr.node) { apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); @@ -428,8 +380,6 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req, switch(req->type) { case DEV_PM_QOS_RESUME_LATENCY: case DEV_PM_QOS_LATENCY_TOLERANCE: - case DEV_PM_QOS_MIN_FREQUENCY: - case DEV_PM_QOS_MAX_FREQUENCY: curr_value = req->data.pnode.prio; break; case DEV_PM_QOS_FLAGS: @@ -557,14 +507,6 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier, ret = blocking_notifier_chain_register(dev->power.qos->resume_latency.notifiers, notifier); break; - case DEV_PM_QOS_MIN_FREQUENCY: - ret = blocking_notifier_chain_register(dev->power.qos->min_frequency.notifiers, - notifier); - break; - case DEV_PM_QOS_MAX_FREQUENCY: - ret = blocking_notifier_chain_register(dev->power.qos->max_frequency.notifiers, - notifier); - break; default: WARN_ON(1); ret = -EINVAL; @@ -604,14 +546,6 @@ int dev_pm_qos_remove_notifier(struct device *dev, ret = blocking_notifier_chain_unregister(dev->power.qos->resume_latency.notifiers, notifier); break; - case DEV_PM_QOS_MIN_FREQUENCY: - ret = blocking_notifier_chain_unregister(dev->power.qos->min_frequency.notifiers, - notifier); - break; - case DEV_PM_QOS_MAX_FREQUENCY: - ret = blocking_notifier_chain_unregister(dev->power.qos->max_frequency.notifiers, - notifier); - break; default: WARN_ON(1); ret = -EINVAL; diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 57b93e3d8f29..ebf5ef17cc2a 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -34,8 +34,6 @@ enum pm_qos_flags_status { #define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT PM_QOS_LATENCY_ANY #define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS PM_QOS_LATENCY_ANY_NS #define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0 -#define PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE 0 -#define PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE (-1) #define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1) #define PM_QOS_FLAG_NO_POWER_OFF (1 << 0) @@ -54,8 +52,6 @@ struct pm_qos_flags_request { enum dev_pm_qos_req_type { DEV_PM_QOS_RESUME_LATENCY = 1, DEV_PM_QOS_LATENCY_TOLERANCE, - DEV_PM_QOS_MIN_FREQUENCY, - DEV_PM_QOS_MAX_FREQUENCY, DEV_PM_QOS_FLAGS, }; @@ -97,14 +93,10 @@ struct pm_qos_flags { struct dev_pm_qos { struct pm_qos_constraints resume_latency; struct pm_qos_constraints latency_tolerance; - struct pm_qos_constraints min_frequency; - struct pm_qos_constraints max_frequency; struct pm_qos_flags flags; struct dev_pm_qos_request *resume_latency_req; struct dev_pm_qos_request *latency_tolerance_req; struct dev_pm_qos_request *flags_req; - struct dev_pm_qos_request *min_frequency_req; - struct dev_pm_qos_request *max_frequency_req; }; /* Action requested to pm_qos_update_target */ @@ -199,10 +191,6 @@ static inline s32 dev_pm_qos_read_value(struct device *dev, switch (type) { case DEV_PM_QOS_RESUME_LATENCY: return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; - case DEV_PM_QOS_MIN_FREQUENCY: - return PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE; - case DEV_PM_QOS_MAX_FREQUENCY: - return PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE; default: WARN_ON(1); return 0; -- GitLab From d532cc7efdfd7bf4b9e1c287d823e584843f1de1 Mon Sep 17 00:00:00 2001 From: "Paulo Alcantara (SUSE)" Date: Thu, 10 Oct 2019 12:31:58 -0300 Subject: [PATCH 543/993] cifs: Handle -EINPROGRESS only when noblockcnt is set We only want to avoid blocking in connect when mounting SMB root filesystems, otherwise bail out from generic_ip_connect() so cifs.ko can perform any reconnect failover appropriately. This fixes DFS failover/reconnection tests in upstream buildbot. Fixes: 8eecd1c2e5bc ("cifs: Add support for root file systems") Signed-off-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/connect.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index a64dfa95a925..bdea4b3e8005 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3882,8 +3882,12 @@ generic_ip_connect(struct TCP_Server_Info *server) rc = socket->ops->connect(socket, saddr, slen, server->noblockcnt ? O_NONBLOCK : 0); - - if (rc == -EINPROGRESS) + /* + * When mounting SMB root file systems, we do not want to block in + * connect. Otherwise bail out and then let cifs_reconnect() perform + * reconnect failover - if possible. + */ + if (server->noblockcnt && rc == -EINPROGRESS) rc = 0; if (rc < 0) { cifs_dbg(FYI, "Error %d connecting to server\n", rc); -- GitLab From 553292a6342bc9e5636953ac6e20bccedaacbd1c Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 11 Oct 2019 17:36:13 -0700 Subject: [PATCH 544/993] cifs: clarify comment about timestamp granularity for old servers It could be confusing why we set granularity to 1 seconds rather than 2 seconds (1 second is the max the VFS allows) for these mounts to very old servers ... Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index c049c7b3aa87..1a135d1b85bd 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -169,7 +169,13 @@ cifs_read_super(struct super_block *sb) else sb->s_maxbytes = MAX_NON_LFS; - /* Some very old servers like DOS and OS/2 used 2 second granularity */ + /* + * Some very old servers like DOS and OS/2 used 2 second granularity + * (while all current servers use 100ns granularity - see MS-DTYP) + * but 1 second is the maximum allowed granularity for the VFS + * so for old servers set time granularity to 1 second while for + * everything else (current servers) set it to 100ns. + */ if ((tcon->ses->server->vals->protocol_id == SMB10_PROT_ID) && ((tcon->ses->capabilities & tcon->ses->server->vals->cap_nt_find) == 0) && -- GitLab From 03d9a9fe3f3aec508e485dd3dcfa1e99933b4bdb Mon Sep 17 00:00:00 2001 From: Roberto Bergantinos Corpas Date: Mon, 14 Oct 2019 10:59:23 +0200 Subject: [PATCH 545/993] CIFS: avoid using MID 0xFFFF According to MS-CIFS specification MID 0xFFFF should not be used by the CIFS client, but we actually do. Besides, this has proven to cause races leading to oops between SendReceive2/cifs_demultiplex_thread. On SMB1, MID is a 2 byte value easy to reach in CurrentMid which may conflict with an oplock break notification request coming from server Signed-off-by: Roberto Bergantinos Corpas Reviewed-by: Ronnie Sahlberg Reviewed-by: Aurelien Aptel Signed-off-by: Steve French CC: Stable --- fs/cifs/smb1ops.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index b7421a096319..514810694c0f 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -171,6 +171,9 @@ cifs_get_next_mid(struct TCP_Server_Info *server) /* we do not want to loop forever */ last_mid = cur_mid; cur_mid++; + /* avoid 0xFFFF MID */ + if (cur_mid == 0xffff) + cur_mid++; /* * This nested loop looks more expensive than it is. -- GitLab From 783bf7b8b641167fb6f3f4f787f60ae62bad41b3 Mon Sep 17 00:00:00 2001 From: Chuhong Yuan Date: Mon, 14 Oct 2019 15:15:31 +0800 Subject: [PATCH 546/993] cifs: Fix missed free operations cifs_setattr_nounix has two paths which miss free operations for xid and fullpath. Use goto cifs_setattr_exit like other paths to fix them. CC: Stable Fixes: aa081859b10c ("cifs: flush before set-info if we have writeable handles") Signed-off-by: Chuhong Yuan Signed-off-by: Steve French Reviewed-by: Pavel Shilovsky --- fs/cifs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 5dcc95b38310..df9377828e2f 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -2475,9 +2475,9 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) rc = tcon->ses->server->ops->flush(xid, tcon, &wfile->fid); cifsFileInfo_put(wfile); if (rc) - return rc; + goto cifs_setattr_exit; } else if (rc != -EBADF) - return rc; + goto cifs_setattr_exit; else rc = 0; } -- GitLab From 24957db1004353346583c9cc6d783db8f213e3ad Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 17 Oct 2019 12:27:58 +0200 Subject: [PATCH 547/993] opp: core: Revert "add regulators enable and disable" All the drivers, which use the OPP framework control regulators, which are already enabled. Typically those regulators are also system critical, due to providing power to CPU core or system buses. It turned out that there are cases, where calling regulator_enable() on such boot-enabled regulator has side-effects and might change its initial voltage due to performing initial voltage balancing without all restrictions from the consumers. Until this issue becomes finally solved in regulator core, avoid calling regulator_enable()/disable() from the OPP framework. This reverts commit 7f93ff73f7c8c8bfa6be33bcc16470b0b44682aa. Signed-off-by: Marek Szyprowski Reviewed-by: Mark Brown Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 3b7ffd0234e9..9ff0538ee83a 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1626,12 +1626,6 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev, goto free_regulators; } - ret = regulator_enable(reg); - if (ret < 0) { - regulator_put(reg); - goto free_regulators; - } - opp_table->regulators[i] = reg; } @@ -1645,10 +1639,8 @@ struct opp_table *dev_pm_opp_set_regulators(struct device *dev, return opp_table; free_regulators: - while (i--) { - regulator_disable(opp_table->regulators[i]); - regulator_put(opp_table->regulators[i]); - } + while (i != 0) + regulator_put(opp_table->regulators[--i]); kfree(opp_table->regulators); opp_table->regulators = NULL; @@ -1674,10 +1666,8 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table) /* Make sure there are no concurrent readers while updating opp_table */ WARN_ON(!list_empty(&opp_table->opp_list)); - for (i = opp_table->regulator_count - 1; i >= 0; i--) { - regulator_disable(opp_table->regulators[i]); + for (i = opp_table->regulator_count - 1; i >= 0; i--) regulator_put(opp_table->regulators[i]); - } _free_set_opp_data(opp_table); -- GitLab From 2b319d1f6f92a4ced9897678113d176ee16ae85d Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 21 Oct 2019 09:11:40 +0200 Subject: [PATCH 548/993] fuse: don't dereference req->args on finished request Move the check for async request after check for the request being already finished and done with. Reported-by: syzbot+ae0bb7aae3de6b4594e2@syzkaller.appspotmail.com Fixes: d49937749fef ("fuse: stop copying args to fuse_req") Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index dadd617d826c..ed1abc9e33cf 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -276,10 +276,12 @@ static void flush_bg_queue(struct fuse_conn *fc) void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req) { struct fuse_iqueue *fiq = &fc->iq; - bool async = req->args->end; + bool async; if (test_and_set_bit(FR_FINISHED, &req->flags)) goto put_request; + + async = req->args->end; /* * test_and_set_bit() implies smp_mb() between bit * changing and below intr_entry check. Pairs with -- GitLab From 5e6c3c7b1ec217c1c4c95d9148182302b9969b97 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Mon, 21 Oct 2019 10:33:54 +0200 Subject: [PATCH 549/993] perf/aux: Fix tracking of auxiliary trace buffer allocation The following commit from the v5.4 merge window: d44248a41337 ("perf/core: Rework memory accounting in perf_mmap()") ... breaks auxiliary trace buffer tracking. If I run command 'perf record -e rbd000' to record samples and saving them in the **auxiliary** trace buffer then the value of 'locked_vm' becomes negative after all trace buffers have been allocated and released: During allocation the values increase: [52.250027] perf_mmap user->locked_vm:0x87 pinned_vm:0x0 ret:0 [52.250115] perf_mmap user->locked_vm:0x107 pinned_vm:0x0 ret:0 [52.250251] perf_mmap user->locked_vm:0x188 pinned_vm:0x0 ret:0 [52.250326] perf_mmap user->locked_vm:0x208 pinned_vm:0x0 ret:0 [52.250441] perf_mmap user->locked_vm:0x289 pinned_vm:0x0 ret:0 [52.250498] perf_mmap user->locked_vm:0x309 pinned_vm:0x0 ret:0 [52.250613] perf_mmap user->locked_vm:0x38a pinned_vm:0x0 ret:0 [52.250715] perf_mmap user->locked_vm:0x408 pinned_vm:0x2 ret:0 [52.250834] perf_mmap user->locked_vm:0x408 pinned_vm:0x83 ret:0 [52.250915] perf_mmap user->locked_vm:0x408 pinned_vm:0x103 ret:0 [52.251061] perf_mmap user->locked_vm:0x408 pinned_vm:0x184 ret:0 [52.251146] perf_mmap user->locked_vm:0x408 pinned_vm:0x204 ret:0 [52.251299] perf_mmap user->locked_vm:0x408 pinned_vm:0x285 ret:0 [52.251383] perf_mmap user->locked_vm:0x408 pinned_vm:0x305 ret:0 [52.251544] perf_mmap user->locked_vm:0x408 pinned_vm:0x386 ret:0 [52.251634] perf_mmap user->locked_vm:0x408 pinned_vm:0x406 ret:0 [52.253018] perf_mmap user->locked_vm:0x408 pinned_vm:0x487 ret:0 [52.253197] perf_mmap user->locked_vm:0x408 pinned_vm:0x508 ret:0 [52.253374] perf_mmap user->locked_vm:0x408 pinned_vm:0x589 ret:0 [52.253550] perf_mmap user->locked_vm:0x408 pinned_vm:0x60a ret:0 [52.253726] perf_mmap user->locked_vm:0x408 pinned_vm:0x68b ret:0 [52.253903] perf_mmap user->locked_vm:0x408 pinned_vm:0x70c ret:0 [52.254084] perf_mmap user->locked_vm:0x408 pinned_vm:0x78d ret:0 [52.254263] perf_mmap user->locked_vm:0x408 pinned_vm:0x80e ret:0 The value of user->locked_vm increases to a limit then the memory is tracked by pinned_vm. During deallocation the size is subtracted from pinned_vm until it hits a limit. Then a larger value is subtracted from locked_vm leading to a large number (because of type unsigned): [64.267797] perf_mmap_close mmap_user->locked_vm:0x408 pinned_vm:0x78d [64.267826] perf_mmap_close mmap_user->locked_vm:0x408 pinned_vm:0x70c [64.267848] perf_mmap_close mmap_user->locked_vm:0x408 pinned_vm:0x68b [64.267869] perf_mmap_close mmap_user->locked_vm:0x408 pinned_vm:0x60a [64.267891] perf_mmap_close mmap_user->locked_vm:0x408 pinned_vm:0x589 [64.267911] perf_mmap_close mmap_user->locked_vm:0x408 pinned_vm:0x508 [64.267933] perf_mmap_close mmap_user->locked_vm:0x408 pinned_vm:0x487 [64.267952] perf_mmap_close mmap_user->locked_vm:0x408 pinned_vm:0x406 [64.268883] perf_mmap_close mmap_user->locked_vm:0x307 pinned_vm:0x406 [64.269117] perf_mmap_close mmap_user->locked_vm:0x206 pinned_vm:0x406 [64.269433] perf_mmap_close mmap_user->locked_vm:0x105 pinned_vm:0x406 [64.269536] perf_mmap_close mmap_user->locked_vm:0x4 pinned_vm:0x404 [64.269797] perf_mmap_close mmap_user->locked_vm:0xffffffffffffff84 pinned_vm:0x303 [64.270105] perf_mmap_close mmap_user->locked_vm:0xffffffffffffff04 pinned_vm:0x202 [64.270374] perf_mmap_close mmap_user->locked_vm:0xfffffffffffffe84 pinned_vm:0x101 [64.270628] perf_mmap_close mmap_user->locked_vm:0xfffffffffffffe04 pinned_vm:0x0 This value sticks for the user until system is rebooted, causing follow-on system calls using locked_vm resource limit to fail. Note: There is no issue using the normal trace buffer. In fact the issue is in perf_mmap_close(). During allocation auxiliary trace buffer memory is either traced as 'extra' and added to 'pinned_vm' or trace as 'user_extra' and added to 'locked_vm'. This applies for normal trace buffers and auxiliary trace buffer. However in function perf_mmap_close() all auxiliary trace buffer is subtraced from 'locked_vm' and never from 'pinned_vm'. This breaks the ballance. Signed-off-by: Thomas Richter Acked-by: Peter Zijlstra Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: acme@kernel.org Cc: gor@linux.ibm.com Cc: hechaol@fb.com Cc: heiko.carstens@de.ibm.com Cc: linux-perf-users@vger.kernel.org Cc: songliubraving@fb.com Fixes: d44248a41337 ("perf/core: Rework memory accounting in perf_mmap()") Link: https://lkml.kernel.org/r/20191021083354.67868-1-tmricht@linux.ibm.com [ Minor readability edits. ] Signed-off-by: Ingo Molnar --- kernel/events/core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 9ec0b0bfddbd..f5d7950d1931 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -5607,8 +5607,10 @@ static void perf_mmap_close(struct vm_area_struct *vma) perf_pmu_output_stop(event); /* now it's safe to free the pages */ - atomic_long_sub(rb->aux_nr_pages, &mmap_user->locked_vm); - atomic64_sub(rb->aux_mmap_locked, &vma->vm_mm->pinned_vm); + if (!rb->aux_mmap_locked) + atomic_long_sub(rb->aux_nr_pages, &mmap_user->locked_vm); + else + atomic64_sub(rb->aux_mmap_locked, &vma->vm_mm->pinned_vm); /* this has to be the last one */ rb_free_aux(rb); -- GitLab From 83629532ce45ef9df1f297b419b9ea112045685d Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Thu, 2 May 2019 16:03:26 +0800 Subject: [PATCH 550/993] ALSA: hda/realtek - Add support for ALC711 Support new codec ALC711. Signed-off-by: Kailang Yang Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ce4f11659765..085a2f95e076 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -393,6 +393,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) case 0x10ec0700: case 0x10ec0701: case 0x10ec0703: + case 0x10ec0711: alc_update_coef_idx(codec, 0x10, 1<<15, 0); break; case 0x10ec0662: @@ -8019,6 +8020,7 @@ static int patch_alc269(struct hda_codec *codec) case 0x10ec0700: case 0x10ec0701: case 0x10ec0703: + case 0x10ec0711: spec->codec_variant = ALC269_TYPE_ALC700; spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */ alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */ @@ -9233,6 +9235,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = { HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269), HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269), HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0711, "ALC711", patch_alc269), HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662), HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880), HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882), -- GitLab From feb40824d78eac5e48f56498dca941754dff33d7 Mon Sep 17 00:00:00 2001 From: Faiz Abbas Date: Thu, 10 Oct 2019 16:22:30 +0530 Subject: [PATCH 551/993] mmc: sdhci-omap: Fix Tuning procedure for temperatures < -20C According to the App note[1] detailing the tuning algorithm, for temperatures < -20C, the initial tuning value should be min(largest value in LPW - 24, ceil(13/16 ratio of LPW)). The largest value in LPW is (max_window + 4 * (max_len - 1)) and not (max_window + 4 * max_len) itself. Fix this implementation. [1] http://www.ti.com/lit/an/spraca9b/spraca9b.pdf Fixes: 961de0a856e3 ("mmc: sdhci-omap: Workaround errata regarding SDR104/HS200 tuning failures (i929)") Cc: stable@vger.kernel.org Signed-off-by: Faiz Abbas Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c index 41c2677c587f..083e7e053c95 100644 --- a/drivers/mmc/host/sdhci-omap.c +++ b/drivers/mmc/host/sdhci-omap.c @@ -372,7 +372,7 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode) * on temperature */ if (temperature < -20000) - phase_delay = min(max_window + 4 * max_len - 24, + phase_delay = min(max_window + 4 * (max_len - 1) - 24, max_window + DIV_ROUND_UP(13 * max_len, 16) * 4); else if (temperature < 20000) -- GitLab From c07d0073b9ec80a139d07ebf78e9c30d2a28279e Mon Sep 17 00:00:00 2001 From: Faiz Abbas Date: Tue, 15 Oct 2019 00:08:49 +0530 Subject: [PATCH 552/993] mmc: cqhci: Commit descriptors before setting the doorbell Add a write memory barrier to make sure that descriptors are actually written to memory, before ringing the doorbell. Signed-off-by: Faiz Abbas Acked-by: Adrian Hunter Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson --- drivers/mmc/host/cqhci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/cqhci.c b/drivers/mmc/host/cqhci.c index f7bdae5354c3..5047f7343ffc 100644 --- a/drivers/mmc/host/cqhci.c +++ b/drivers/mmc/host/cqhci.c @@ -611,7 +611,8 @@ static int cqhci_request(struct mmc_host *mmc, struct mmc_request *mrq) cq_host->slot[tag].flags = 0; cq_host->qcnt += 1; - + /* Make sure descriptors are ready before ringing the doorbell */ + wmb(); cqhci_writel(cq_host, 1 << tag, CQHCI_TDBR); if (!(cqhci_readl(cq_host, CQHCI_TDBR) & (1 << tag))) pr_debug("%s: cqhci: doorbell not set for tag %d\n", -- GitLab From 1f0d9cbeec9bb0a1c2013342836f2c9754d6502b Mon Sep 17 00:00:00 2001 From: Jae Hyun Yoo Date: Wed, 9 Oct 2019 14:20:34 -0700 Subject: [PATCH 553/993] i2c: aspeed: fix master pending state handling In case of master pending state, it should not trigger a master command, otherwise data could be corrupted because this H/W shares the same data buffer for slave and master operations. It also means that H/W command queue handling is unreliable because of the buffer sharing issue. To fix this issue, it clears command queue if a master command is queued in pending state to use S/W solution instead of H/W command queue handling. Also, it refines restarting mechanism of the pending master command. Fixes: 2e57b7cebb98 ("i2c: aspeed: Add multi-master use case support") Signed-off-by: Jae Hyun Yoo Reviewed-by: Brendan Higgins Acked-by: Joel Stanley Tested-by: Tao Ren Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-aspeed.c | 54 +++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index fa66951b05d0..7b098ff5f5dd 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -108,6 +108,12 @@ #define ASPEED_I2CD_S_TX_CMD BIT(2) #define ASPEED_I2CD_M_TX_CMD BIT(1) #define ASPEED_I2CD_M_START_CMD BIT(0) +#define ASPEED_I2CD_MASTER_CMDS_MASK \ + (ASPEED_I2CD_M_STOP_CMD | \ + ASPEED_I2CD_M_S_RX_CMD_LAST | \ + ASPEED_I2CD_M_RX_CMD | \ + ASPEED_I2CD_M_TX_CMD | \ + ASPEED_I2CD_M_START_CMD) /* 0x18 : I2CD Slave Device Address Register */ #define ASPEED_I2CD_DEV_ADDR_MASK GENMASK(6, 0) @@ -336,18 +342,19 @@ static void aspeed_i2c_do_start(struct aspeed_i2c_bus *bus) struct i2c_msg *msg = &bus->msgs[bus->msgs_index]; u8 slave_addr = i2c_8bit_addr_from_msg(msg); - bus->master_state = ASPEED_I2C_MASTER_START; - #if IS_ENABLED(CONFIG_I2C_SLAVE) /* * If it's requested in the middle of a slave session, set the master * state to 'pending' then H/W will continue handling this master * command when the bus comes back to the idle state. */ - if (bus->slave_state != ASPEED_I2C_SLAVE_INACTIVE) + if (bus->slave_state != ASPEED_I2C_SLAVE_INACTIVE) { bus->master_state = ASPEED_I2C_MASTER_PENDING; + return; + } #endif /* CONFIG_I2C_SLAVE */ + bus->master_state = ASPEED_I2C_MASTER_START; bus->buf_index = 0; if (msg->flags & I2C_M_RD) { @@ -422,20 +429,6 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) } } -#if IS_ENABLED(CONFIG_I2C_SLAVE) - /* - * A pending master command will be started by H/W when the bus comes - * back to idle state after completing a slave operation so change the - * master state from 'pending' to 'start' at here if slave is inactive. - */ - if (bus->master_state == ASPEED_I2C_MASTER_PENDING) { - if (bus->slave_state != ASPEED_I2C_SLAVE_INACTIVE) - goto out_no_complete; - - bus->master_state = ASPEED_I2C_MASTER_START; - } -#endif /* CONFIG_I2C_SLAVE */ - /* Master is not currently active, irq was for someone else. */ if (bus->master_state == ASPEED_I2C_MASTER_INACTIVE || bus->master_state == ASPEED_I2C_MASTER_PENDING) @@ -462,11 +455,15 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) #if IS_ENABLED(CONFIG_I2C_SLAVE) /* * If a peer master starts a xfer immediately after it queues a - * master command, change its state to 'pending' then H/W will - * continue the queued master xfer just after completing the - * slave mode session. + * master command, clear the queued master command and change + * its state to 'pending'. To simplify handling of pending + * cases, it uses S/W solution instead of H/W command queue + * handling. */ if (unlikely(irq_status & ASPEED_I2CD_INTR_SLAVE_MATCH)) { + writel(readl(bus->base + ASPEED_I2C_CMD_REG) & + ~ASPEED_I2CD_MASTER_CMDS_MASK, + bus->base + ASPEED_I2C_CMD_REG); bus->master_state = ASPEED_I2C_MASTER_PENDING; dev_dbg(bus->dev, "master goes pending due to a slave start\n"); @@ -629,6 +626,14 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id) irq_handled |= aspeed_i2c_master_irq(bus, irq_remaining); } + + /* + * Start a pending master command at here if a slave operation is + * completed. + */ + if (bus->master_state == ASPEED_I2C_MASTER_PENDING && + bus->slave_state == ASPEED_I2C_SLAVE_INACTIVE) + aspeed_i2c_do_start(bus); #else irq_handled = aspeed_i2c_master_irq(bus, irq_remaining); #endif /* CONFIG_I2C_SLAVE */ @@ -691,6 +696,15 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap, ASPEED_I2CD_BUS_BUSY_STS)) aspeed_i2c_recover_bus(bus); + /* + * If timed out and the state is still pending, drop the pending + * master command. + */ + spin_lock_irqsave(&bus->lock, flags); + if (bus->master_state == ASPEED_I2C_MASTER_PENDING) + bus->master_state = ASPEED_I2C_MASTER_INACTIVE; + spin_unlock_irqrestore(&bus->lock, flags); + return -ETIMEDOUT; } -- GitLab From b88639b8e3808c948169af390bd7e84e909bde8d Mon Sep 17 00:00:00 2001 From: Mihail Atanassov Date: Thu, 10 Oct 2019 10:30:07 +0000 Subject: [PATCH 554/993] drm/komeda: Don't flush inactive pipes HW doesn't allow flushing inactive pipes and raises an MERR interrupt if you try to do so. Stop triggering the MERR interrupt in the middle of a commit by calling drm_atomic_helper_commit_planes with the ACTIVE_ONLY flag. Reviewed-by: James Qian Wang (Arm Technology China) Signed-off-by: Mihail Atanassov Link: https://patchwork.freedesktop.org/patch/msgid/20191010102950.56253-1-mihail.atanassov@arm.com --- drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index 8820ce15ce37..ae274902ff92 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -82,7 +82,8 @@ static void komeda_kms_commit_tail(struct drm_atomic_state *old_state) drm_atomic_helper_commit_modeset_disables(dev, old_state); - drm_atomic_helper_commit_planes(dev, old_state, 0); + drm_atomic_helper_commit_planes(dev, old_state, + DRM_PLANE_COMMIT_ACTIVE_ONLY); drm_atomic_helper_commit_modeset_enables(dev, old_state); -- GitLab From 8ae501e295cce9bc6e0dd82d5204a1d5faef44f8 Mon Sep 17 00:00:00 2001 From: Mihail Atanassov Date: Mon, 30 Sep 2019 12:23:07 +0000 Subject: [PATCH 555/993] drm/komeda: Fix typos in komeda_splitter_validate Fix both the string and the struct member being printed. Changes since v1: - Now with a bonus grammar fix, too. Fixes: 264b9436d23b ("drm/komeda: Enable writeback split support") Reviewed-by: James Qian Wang (Arm Technology China) Signed-off-by: Mihail Atanassov Link: https://patchwork.freedesktop.org/patch/msgid/20190930122231.33029-1-mihail.atanassov@arm.com --- drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c index ea26bc9c2d00..b848270e0a1f 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -564,8 +564,8 @@ komeda_splitter_validate(struct komeda_splitter *splitter, } if (!in_range(&splitter->vsize, dflow->in_h)) { - DRM_DEBUG_ATOMIC("split in_in: %d exceed the acceptable range.\n", - dflow->in_w); + DRM_DEBUG_ATOMIC("split in_h: %d exceeds the acceptable range.\n", + dflow->in_h); return -EINVAL; } -- GitLab From 6c26f71759a6efc04b888dd2c1cc4f1cac38cdf0 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 21 Oct 2019 15:57:07 +0200 Subject: [PATCH 556/993] fuse: don't advise readdirplus for negative lookup If the FUSE_READDIRPLUS_AUTO feature is enabled, then lookups on a directory before/during readdir are used as an indication that READDIRPLUS should be used instead of READDIR. However if the lookup turns out to be negative, then selecting READDIRPLUS makes no sense. Signed-off-by: Miklos Szeredi --- fs/fuse/dir.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index d572c900bb0f..b77954a27538 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -405,7 +405,8 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, else fuse_invalidate_entry_cache(entry); - fuse_advise_use_readdirplus(dir); + if (inode) + fuse_advise_use_readdirplus(dir); return newent; out_iput: -- GitLab From 51fecdd2555b3e0e05a78d30093c638d164a32f9 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Tue, 15 Oct 2019 13:46:22 -0400 Subject: [PATCH 557/993] virtiofs: Do not end request in submission context Submission context can hold some locks which end request code tries to hold again and deadlock can occur. For example, fc->bg_lock. If a background request is being submitted, it might hold fc->bg_lock and if we could not submit request (because device went away) and tried to end request, then deadlock happens. During testing, I also got a warning from deadlock detection code. So put requests on a list and end requests from a worker thread. I got following warning from deadlock detector. [ 603.137138] WARNING: possible recursive locking detected [ 603.137142] -------------------------------------------- [ 603.137144] blogbench/2036 is trying to acquire lock: [ 603.137149] 00000000f0f51107 (&(&fc->bg_lock)->rlock){+.+.}, at: fuse_request_end+0xdf/0x1c0 [fuse] [ 603.140701] [ 603.140701] but task is already holding lock: [ 603.140703] 00000000f0f51107 (&(&fc->bg_lock)->rlock){+.+.}, at: fuse_simple_background+0x92/0x1d0 [fuse] [ 603.140713] [ 603.140713] other info that might help us debug this: [ 603.140714] Possible unsafe locking scenario: [ 603.140714] [ 603.140715] CPU0 [ 603.140716] ---- [ 603.140716] lock(&(&fc->bg_lock)->rlock); [ 603.140718] lock(&(&fc->bg_lock)->rlock); [ 603.140719] [ 603.140719] *** DEADLOCK *** Signed-off-by: Vivek Goyal Signed-off-by: Miklos Szeredi --- fs/fuse/virtio_fs.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index e22a0c003c3d..7ea58606cc1d 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -30,6 +30,7 @@ struct virtio_fs_vq { struct virtqueue *vq; /* protected by ->lock */ struct work_struct done_work; struct list_head queued_reqs; + struct list_head end_reqs; /* End these requests */ struct delayed_work dispatch_work; struct fuse_dev *fud; bool connected; @@ -259,8 +260,27 @@ static void virtio_fs_hiprio_done_work(struct work_struct *work) spin_unlock(&fsvq->lock); } -static void virtio_fs_dummy_dispatch_work(struct work_struct *work) +static void virtio_fs_request_dispatch_work(struct work_struct *work) { + struct fuse_req *req; + struct virtio_fs_vq *fsvq = container_of(work, struct virtio_fs_vq, + dispatch_work.work); + struct fuse_conn *fc = fsvq->fud->fc; + + pr_debug("virtio-fs: worker %s called.\n", __func__); + while (1) { + spin_lock(&fsvq->lock); + req = list_first_entry_or_null(&fsvq->end_reqs, struct fuse_req, + list); + if (!req) { + spin_unlock(&fsvq->lock); + return; + } + + list_del_init(&req->list); + spin_unlock(&fsvq->lock); + fuse_request_end(fc, req); + } } static void virtio_fs_hiprio_dispatch_work(struct work_struct *work) @@ -502,6 +522,7 @@ static int virtio_fs_setup_vqs(struct virtio_device *vdev, names[VQ_HIPRIO] = fs->vqs[VQ_HIPRIO].name; INIT_WORK(&fs->vqs[VQ_HIPRIO].done_work, virtio_fs_hiprio_done_work); INIT_LIST_HEAD(&fs->vqs[VQ_HIPRIO].queued_reqs); + INIT_LIST_HEAD(&fs->vqs[VQ_HIPRIO].end_reqs); INIT_DELAYED_WORK(&fs->vqs[VQ_HIPRIO].dispatch_work, virtio_fs_hiprio_dispatch_work); spin_lock_init(&fs->vqs[VQ_HIPRIO].lock); @@ -511,8 +532,9 @@ static int virtio_fs_setup_vqs(struct virtio_device *vdev, spin_lock_init(&fs->vqs[i].lock); INIT_WORK(&fs->vqs[i].done_work, virtio_fs_requests_done_work); INIT_DELAYED_WORK(&fs->vqs[i].dispatch_work, - virtio_fs_dummy_dispatch_work); + virtio_fs_request_dispatch_work); INIT_LIST_HEAD(&fs->vqs[i].queued_reqs); + INIT_LIST_HEAD(&fs->vqs[i].end_reqs); snprintf(fs->vqs[i].name, sizeof(fs->vqs[i].name), "requests.%u", i - VQ_REQUEST); callbacks[i] = virtio_fs_vq_done; @@ -918,6 +940,7 @@ __releases(fiq->lock) struct fuse_conn *fc; struct fuse_req *req; struct fuse_pqueue *fpq; + struct virtio_fs_vq *fsvq; int ret; WARN_ON(list_empty(&fiq->pending)); @@ -951,7 +974,8 @@ __releases(fiq->lock) smp_mb__after_atomic(); retry: - ret = virtio_fs_enqueue_req(&fs->vqs[queue_id], req); + fsvq = &fs->vqs[queue_id]; + ret = virtio_fs_enqueue_req(fsvq, req); if (ret < 0) { if (ret == -ENOMEM || ret == -ENOSPC) { /* Virtqueue full. Retry submission */ @@ -965,7 +989,12 @@ __releases(fiq->lock) clear_bit(FR_SENT, &req->flags); list_del_init(&req->list); spin_unlock(&fpq->lock); - fuse_request_end(fc, req); + + /* Can't end request in submission context. Use a worker */ + spin_lock(&fsvq->lock); + list_add_tail(&req->list, &fsvq->end_reqs); + schedule_delayed_work(&fsvq->dispatch_work, 0); + spin_unlock(&fsvq->lock); return; } } -- GitLab From 7ee1e2e631dbf0ff0df2a67a1e01ba3c1dce7a46 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Tue, 15 Oct 2019 13:46:23 -0400 Subject: [PATCH 558/993] virtiofs: No need to check fpq->connected state In virtiofs we keep per queue connected state in virtio_fs_vq->connected and use that to end request if queue is not connected. And virtiofs does not even touch fpq->connected state. We probably need to merge these two at some point of time. For now, simplify the code a bit and do not worry about checking state of fpq->connected. Signed-off-by: Vivek Goyal Signed-off-by: Miklos Szeredi --- fs/fuse/virtio_fs.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index 7ea58606cc1d..a2724b77221d 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -960,13 +960,6 @@ __releases(fiq->lock) fpq = &fs->vqs[queue_id].fud->pq; spin_lock(&fpq->lock); - if (!fpq->connected) { - spin_unlock(&fpq->lock); - req->out.h.error = -ENODEV; - pr_err("virtio-fs: %s disconnected\n", __func__); - fuse_request_end(fc, req); - return; - } list_add_tail(&req->list, fpq->processing); spin_unlock(&fpq->lock); set_bit(FR_SENT, &req->flags); -- GitLab From 5dbe190f341206a7896f7e40c1e3a36933d812f3 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Tue, 15 Oct 2019 13:46:24 -0400 Subject: [PATCH 559/993] virtiofs: Set FR_SENT flag only after request has been sent FR_SENT flag should be set when request has been sent successfully sent over virtqueue. This is used by interrupt logic to figure out if interrupt request should be sent or not. Also add it to fqp->processing list after sending it successfully. Signed-off-by: Vivek Goyal Signed-off-by: Miklos Szeredi --- fs/fuse/virtio_fs.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index a2724b77221d..6d153e70c87b 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -857,6 +857,7 @@ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq, unsigned int i; int ret; bool notify; + struct fuse_pqueue *fpq; /* Does the sglist fit on the stack? */ total_sgs = sg_count_fuse_req(req); @@ -911,6 +912,15 @@ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq, goto out; } + /* Request successfully sent. */ + fpq = &fsvq->fud->pq; + spin_lock(&fpq->lock); + list_add_tail(&req->list, fpq->processing); + spin_unlock(&fpq->lock); + set_bit(FR_SENT, &req->flags); + /* matches barrier in request_wait_answer() */ + smp_mb__after_atomic(); + fsvq->in_flight++; notify = virtqueue_kick_prepare(vq); @@ -939,7 +949,6 @@ __releases(fiq->lock) struct virtio_fs *fs; struct fuse_conn *fc; struct fuse_req *req; - struct fuse_pqueue *fpq; struct virtio_fs_vq *fsvq; int ret; @@ -958,14 +967,6 @@ __releases(fiq->lock) req->in.h.nodeid, req->in.h.len, fuse_len_args(req->args->out_numargs, req->args->out_args)); - fpq = &fs->vqs[queue_id].fud->pq; - spin_lock(&fpq->lock); - list_add_tail(&req->list, fpq->processing); - spin_unlock(&fpq->lock); - set_bit(FR_SENT, &req->flags); - /* matches barrier in request_wait_answer() */ - smp_mb__after_atomic(); - retry: fsvq = &fs->vqs[queue_id]; ret = virtio_fs_enqueue_req(fsvq, req); @@ -978,10 +979,6 @@ __releases(fiq->lock) } req->out.h.error = ret; pr_err("virtio-fs: virtio_fs_enqueue_req() failed %d\n", ret); - spin_lock(&fpq->lock); - clear_bit(FR_SENT, &req->flags); - list_del_init(&req->list); - spin_unlock(&fpq->lock); /* Can't end request in submission context. Use a worker */ spin_lock(&fsvq->lock); -- GitLab From c17ea009610366146ec409fd6dc277e0f2510b10 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Tue, 15 Oct 2019 13:46:25 -0400 Subject: [PATCH 560/993] virtiofs: Count pending forgets as in_flight forgets If virtqueue is full, we put forget requests on a list and these forgets are dispatched later using a worker. As of now we don't count these forgets in fsvq->in_flight variable. This means when queue is being drained, we have to have special logic to first drain these pending requests and then wait for fsvq->in_flight to go to zero. By counting pending forgets in fsvq->in_flight, we can get rid of special logic and just wait for in_flight to go to zero. Worker thread will kick and drain all the forgets anyway, leading in_flight to zero. I also need similar logic for normal request queue in next patch where I am about to defer request submission in the worker context if queue is full. This simplifies the code a bit. Also add two helper functions to inc/dec in_flight. Decrement in_flight helper will later used to call completion when in_flight reaches zero. Signed-off-by: Vivek Goyal Signed-off-by: Miklos Szeredi --- fs/fuse/virtio_fs.c | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index 6d153e70c87b..3ea613d5e34f 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -67,6 +67,19 @@ static inline struct fuse_pqueue *vq_to_fpq(struct virtqueue *vq) return &vq_to_fsvq(vq)->fud->pq; } +/* Should be called with fsvq->lock held. */ +static inline void inc_in_flight_req(struct virtio_fs_vq *fsvq) +{ + fsvq->in_flight++; +} + +/* Should be called with fsvq->lock held. */ +static inline void dec_in_flight_req(struct virtio_fs_vq *fsvq) +{ + WARN_ON(fsvq->in_flight <= 0); + fsvq->in_flight--; +} + static void release_virtio_fs_obj(struct kref *ref) { struct virtio_fs *vfs = container_of(ref, struct virtio_fs, refcount); @@ -110,22 +123,6 @@ static void virtio_fs_drain_queue(struct virtio_fs_vq *fsvq) flush_delayed_work(&fsvq->dispatch_work); } -static inline void drain_hiprio_queued_reqs(struct virtio_fs_vq *fsvq) -{ - struct virtio_fs_forget *forget; - - spin_lock(&fsvq->lock); - while (1) { - forget = list_first_entry_or_null(&fsvq->queued_reqs, - struct virtio_fs_forget, list); - if (!forget) - break; - list_del(&forget->list); - kfree(forget); - } - spin_unlock(&fsvq->lock); -} - static void virtio_fs_drain_all_queues(struct virtio_fs *fs) { struct virtio_fs_vq *fsvq; @@ -133,9 +130,6 @@ static void virtio_fs_drain_all_queues(struct virtio_fs *fs) for (i = 0; i < fs->nvqs; i++) { fsvq = &fs->vqs[i]; - if (i == VQ_HIPRIO) - drain_hiprio_queued_reqs(fsvq); - virtio_fs_drain_queue(fsvq); } } @@ -254,7 +248,7 @@ static void virtio_fs_hiprio_done_work(struct work_struct *work) while ((req = virtqueue_get_buf(vq, &len)) != NULL) { kfree(req); - fsvq->in_flight--; + dec_in_flight_req(fsvq); } } while (!virtqueue_enable_cb(vq) && likely(!virtqueue_is_broken(vq))); spin_unlock(&fsvq->lock); @@ -306,6 +300,7 @@ static void virtio_fs_hiprio_dispatch_work(struct work_struct *work) list_del(&forget->list); if (!fsvq->connected) { + dec_in_flight_req(fsvq); spin_unlock(&fsvq->lock); kfree(forget); continue; @@ -327,13 +322,13 @@ static void virtio_fs_hiprio_dispatch_work(struct work_struct *work) } else { pr_debug("virtio-fs: Could not queue FORGET: err=%d. Dropping it.\n", ret); + dec_in_flight_req(fsvq); kfree(forget); } spin_unlock(&fsvq->lock); return; } - fsvq->in_flight++; notify = virtqueue_kick_prepare(vq); spin_unlock(&fsvq->lock); @@ -472,7 +467,7 @@ static void virtio_fs_requests_done_work(struct work_struct *work) fuse_request_end(fc, req); spin_lock(&fsvq->lock); - fsvq->in_flight--; + dec_in_flight_req(fsvq); spin_unlock(&fsvq->lock); } } @@ -730,6 +725,7 @@ __releases(fiq->lock) list_add_tail(&forget->list, &fsvq->queued_reqs); schedule_delayed_work(&fsvq->dispatch_work, msecs_to_jiffies(1)); + inc_in_flight_req(fsvq); } else { pr_debug("virtio-fs: Could not queue FORGET: err=%d. Dropping it.\n", ret); @@ -739,7 +735,7 @@ __releases(fiq->lock) goto out; } - fsvq->in_flight++; + inc_in_flight_req(fsvq); notify = virtqueue_kick_prepare(vq); spin_unlock(&fsvq->lock); @@ -921,7 +917,7 @@ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq, /* matches barrier in request_wait_answer() */ smp_mb__after_atomic(); - fsvq->in_flight++; + inc_in_flight_req(fsvq); notify = virtqueue_kick_prepare(vq); spin_unlock(&fsvq->lock); -- GitLab From a9bfd9dd3417561d06c81de04f6d6c1e0c9b3d44 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Tue, 15 Oct 2019 13:46:26 -0400 Subject: [PATCH 561/993] virtiofs: Retry request submission from worker context If regular request queue gets full, currently we sleep for a bit and retrying submission in submitter's context. This assumes submitter is not holding any spin lock. But this assumption is not true for background requests. For background requests, we are called with fc->bg_lock held. This can lead to deadlock where one thread is trying submission with fc->bg_lock held while request completion thread has called fuse_request_end() which tries to acquire fc->bg_lock and gets blocked. As request completion thread gets blocked, it does not make further progress and that means queue does not get empty and submitter can't submit more requests. To solve this issue, retry submission with the help of a worker, instead of retrying in submitter's context. We already do this for hiprio/forget requests. Reported-by: Chirantan Ekbote Signed-off-by: Vivek Goyal Signed-off-by: Miklos Szeredi --- fs/fuse/virtio_fs.c | 61 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index 3ea613d5e34f..2de8fc0d6a24 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -55,6 +55,9 @@ struct virtio_fs_forget { struct list_head list; }; +static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq, + struct fuse_req *req, bool in_flight); + static inline struct virtio_fs_vq *vq_to_fsvq(struct virtqueue *vq) { struct virtio_fs *fs = vq->vdev->priv; @@ -260,6 +263,7 @@ static void virtio_fs_request_dispatch_work(struct work_struct *work) struct virtio_fs_vq *fsvq = container_of(work, struct virtio_fs_vq, dispatch_work.work); struct fuse_conn *fc = fsvq->fud->fc; + int ret; pr_debug("virtio-fs: worker %s called.\n", __func__); while (1) { @@ -268,13 +272,45 @@ static void virtio_fs_request_dispatch_work(struct work_struct *work) list); if (!req) { spin_unlock(&fsvq->lock); - return; + break; } list_del_init(&req->list); spin_unlock(&fsvq->lock); fuse_request_end(fc, req); } + + /* Dispatch pending requests */ + while (1) { + spin_lock(&fsvq->lock); + req = list_first_entry_or_null(&fsvq->queued_reqs, + struct fuse_req, list); + if (!req) { + spin_unlock(&fsvq->lock); + return; + } + list_del_init(&req->list); + spin_unlock(&fsvq->lock); + + ret = virtio_fs_enqueue_req(fsvq, req, true); + if (ret < 0) { + if (ret == -ENOMEM || ret == -ENOSPC) { + spin_lock(&fsvq->lock); + list_add_tail(&req->list, &fsvq->queued_reqs); + schedule_delayed_work(&fsvq->dispatch_work, + msecs_to_jiffies(1)); + spin_unlock(&fsvq->lock); + return; + } + req->out.h.error = ret; + spin_lock(&fsvq->lock); + dec_in_flight_req(fsvq); + spin_unlock(&fsvq->lock); + pr_err("virtio-fs: virtio_fs_enqueue_req() failed %d\n", + ret); + fuse_request_end(fc, req); + } + } } static void virtio_fs_hiprio_dispatch_work(struct work_struct *work) @@ -837,7 +873,7 @@ static unsigned int sg_init_fuse_args(struct scatterlist *sg, /* Add a request to a virtqueue and kick the device */ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq, - struct fuse_req *req) + struct fuse_req *req, bool in_flight) { /* requests need at least 4 elements */ struct scatterlist *stack_sgs[6]; @@ -917,7 +953,8 @@ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq, /* matches barrier in request_wait_answer() */ smp_mb__after_atomic(); - inc_in_flight_req(fsvq); + if (!in_flight) + inc_in_flight_req(fsvq); notify = virtqueue_kick_prepare(vq); spin_unlock(&fsvq->lock); @@ -963,15 +1000,21 @@ __releases(fiq->lock) req->in.h.nodeid, req->in.h.len, fuse_len_args(req->args->out_numargs, req->args->out_args)); -retry: fsvq = &fs->vqs[queue_id]; - ret = virtio_fs_enqueue_req(fsvq, req); + ret = virtio_fs_enqueue_req(fsvq, req, false); if (ret < 0) { if (ret == -ENOMEM || ret == -ENOSPC) { - /* Virtqueue full. Retry submission */ - /* TODO use completion instead of timeout */ - usleep_range(20, 30); - goto retry; + /* + * Virtqueue full. Retry submission from worker + * context as we might be holding fc->bg_lock. + */ + spin_lock(&fsvq->lock); + list_add_tail(&req->list, &fsvq->queued_reqs); + inc_in_flight_req(fsvq); + schedule_delayed_work(&fsvq->dispatch_work, + msecs_to_jiffies(1)); + spin_unlock(&fsvq->lock); + return; } req->out.h.error = ret; pr_err("virtio-fs: virtio_fs_enqueue_req() failed %d\n", ret); -- GitLab From 2bb9f7566ba7ab3c2154964461e37b52cdc6b91b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 18 Oct 2019 11:39:34 +0200 Subject: [PATCH 562/993] mmc: mxs: fix flags passed to dmaengine_prep_slave_sg Since ceeeb99cd821 we no longer abuse the DMA_CTRL_ACK flag for custom driver use and introduced the MXS_DMA_CTRL_WAIT4END instead. We have not changed all users to this flag though. This patch fixes it for the mxs-mmc driver. Fixes: ceeeb99cd821 ("dmaengine: mxs: rename custom flag") Signed-off-by: Sascha Hauer Tested-by: Fabio Estevam Reported-by: Bruno Thomsen Tested-by: Bruno Thomsen Cc: stable@vger.kernel.org Signed-off-by: Ulf Hansson --- drivers/mmc/host/mxs-mmc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 78e7e350655c..4031217d21c3 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -266,7 +267,7 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host) ssp->ssp_pio_words[2] = cmd1; ssp->dma_dir = DMA_NONE; ssp->slave_dirn = DMA_TRANS_NONE; - desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); + desc = mxs_mmc_prep_dma(host, MXS_DMA_CTRL_WAIT4END); if (!desc) goto out; @@ -311,7 +312,7 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host) ssp->ssp_pio_words[2] = cmd1; ssp->dma_dir = DMA_NONE; ssp->slave_dirn = DMA_TRANS_NONE; - desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); + desc = mxs_mmc_prep_dma(host, MXS_DMA_CTRL_WAIT4END); if (!desc) goto out; @@ -441,7 +442,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) host->data = data; ssp->dma_dir = dma_data_dir; ssp->slave_dirn = slave_dirn; - desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | MXS_DMA_CTRL_WAIT4END); if (!desc) goto out; -- GitLab From 40a6b9a00930fd6b59aa2eb6135abc2efe5440c3 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 21 Oct 2019 12:41:40 +0200 Subject: [PATCH 563/993] Revert "pwm: Let pwm_get_state() return the last implemented state" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turns out that commit 01ccf903edd6 ("pwm: Let pwm_get_state() return the last implemented state") causes backlight failures on a number of boards. The reason is that some of the drivers do not write the full state through to the hardware registers, which means that ->get_state() subsequently does not return the correct state. Consumers which rely on pwm_get_state() returning the current state will therefore get confused and subsequently try to program a bad state. Before this change can be made, existing drivers need to be more carefully audited and fixed to behave as the framework expects. Until then, keep the original behaviour of returning the software state that was applied rather than reading the state back from hardware. Reviewed-by: Uwe Kleine-König Tested-by: Enric Balletbo i Serra Tested-by: Michal Vokáč Signed-off-by: Thierry Reding --- drivers/pwm/core.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 6ad51aa60c03..f877e77d9184 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -472,14 +472,7 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state) if (err) return err; - /* - * .apply might have to round some values in *state, if possible - * read the actually implemented value back. - */ - if (chip->ops->get_state) - chip->ops->get_state(chip, pwm, &pwm->state); - else - pwm->state = *state; + pwm->state = *state; } else { /* * FIXME: restore the initial state in case of error. -- GitLab From b1a402e75a5f5127ff1ffff0615249f98df8b7b3 Mon Sep 17 00:00:00 2001 From: Dixit Parmar Date: Mon, 21 Oct 2019 09:32:47 -0700 Subject: [PATCH 564/993] Input: st1232 - fix reporting multitouch coordinates For Sitronix st1633 multi-touch controller driver the coordinates reported for multiple fingers were wrong, as it was always taking LSB of coordinates from the first contact data. Signed-off-by: Dixit Parmar Reviewed-by: Martin Kepplinger Cc: stable@vger.kernel.org Fixes: 351e0592bfea ("Input: st1232 - add support for st1633") Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=204561 Link: https://lore.kernel.org/r/1566209314-21767-1-git-send-email-dixitparmar19@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/st1232.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index 34923399ece4..1139714e72e2 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -81,8 +81,10 @@ static int st1232_ts_read_data(struct st1232_ts_data *ts) for (i = 0, y = 0; i < ts->chip_info->max_fingers; i++, y += 3) { finger[i].is_valid = buf[i + y] >> 7; if (finger[i].is_valid) { - finger[i].x = ((buf[i + y] & 0x0070) << 4) | buf[i + 1]; - finger[i].y = ((buf[i + y] & 0x0007) << 8) | buf[i + 2]; + finger[i].x = ((buf[i + y] & 0x0070) << 4) | + buf[i + y + 1]; + finger[i].y = ((buf[i + y] & 0x0007) << 8) | + buf[i + y + 2]; /* st1232 includes a z-axis / touch strength */ if (ts->chip_info->have_z) -- GitLab From 2ecb287998a47cc0a766f6071f63bc185f338540 Mon Sep 17 00:00:00 2001 From: afzal mohammed Date: Mon, 21 Oct 2019 06:06:14 +0100 Subject: [PATCH 565/993] ARM: 8926/1: v7m: remove register save to stack before svc r0-r3 & r12 registers are saved & restored, before & after svc respectively. Intention was to preserve those registers across thread to handler mode switch. On v7-M, hardware saves the register context upon exception in AAPCS complaint way. Restoring r0-r3 & r12 is done from stack location where hardware saves it, not from the location on stack where these registers were saved. To clarify, on stm32f429 discovery board: 1. before svc, sp - 0x90009ff8 2. r0-r3,r12 saved to 0x90009ff8 - 0x9000a00b 3. upon svc, h/w decrements sp by 32 & pushes registers onto stack 4. after svc, sp - 0x90009fd8 5. r0-r3,r12 restored from 0x90009fd8 - 0x90009feb Above means r0-r3,r12 is not restored from the location where they are saved, but since hardware pushes the registers onto stack, the registers are restored correctly. Note that during register saving to stack (step 2), it goes past 0x9000a000. And it seems, based on objdump, there are global symbols residing there, and it perhaps can cause issues on a non-XIP Kernel (on XIP, data section is setup later). Based on the analysis above, manually saving registers onto stack is at best no-op and at worst can cause data section corruption. Hence remove storing of registers onto stack before svc. Fixes: b70cd406d7fe ("ARM: 8671/1: V7M: Preserve registers across switch from Thread to Handler mode") Signed-off-by: afzal mohammed Acked-by: Vladimir Murzin Signed-off-by: Russell King --- arch/arm/mm/proc-v7m.S | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S index efebf4120a0c..1a49d503eafc 100644 --- a/arch/arm/mm/proc-v7m.S +++ b/arch/arm/mm/proc-v7m.S @@ -132,7 +132,6 @@ __v7m_setup_cont: dsb mov r6, lr @ save LR ldr sp, =init_thread_union + THREAD_START_SP - stmia sp, {r0-r3, r12} cpsie i svc #0 1: cpsid i -- GitLab From e7a409c3f46cb0dbc7bfd4f6f9421d53e92614a5 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 19 Oct 2019 09:26:37 -0700 Subject: [PATCH 566/993] ipv4: fix IPSKB_FRAG_PMTU handling with fragmentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch removes the iph field from the state structure, which is not properly initialized. Instead, add a new field to make the "do we want to set DF" be the state bit and move the code to set the DF flag from ip_frag_next(). Joint work with Pablo and Linus. Fixes: 19c3401a917b ("net: ipv4: place control buffer handling away from fragmentation iterators") Reported-by: Patrick Schönthaler Signed-off-by: Eric Dumazet Signed-off-by: Pablo Neira Ayuso Signed-off-by: Linus Torvalds Signed-off-by: David S. Miller --- include/net/ip.h | 4 ++-- net/bridge/netfilter/nf_conntrack_bridge.c | 2 +- net/ipv4/ip_output.c | 11 ++++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/net/ip.h b/include/net/ip.h index 95bb77f95bcc..a2c61c36dc4a 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -185,7 +185,7 @@ static inline struct sk_buff *ip_fraglist_next(struct ip_fraglist_iter *iter) } struct ip_frag_state { - struct iphdr *iph; + bool DF; unsigned int hlen; unsigned int ll_rs; unsigned int mtu; @@ -196,7 +196,7 @@ struct ip_frag_state { }; void ip_frag_init(struct sk_buff *skb, unsigned int hlen, unsigned int ll_rs, - unsigned int mtu, struct ip_frag_state *state); + unsigned int mtu, bool DF, struct ip_frag_state *state); struct sk_buff *ip_frag_next(struct sk_buff *skb, struct ip_frag_state *state); diff --git a/net/bridge/netfilter/nf_conntrack_bridge.c b/net/bridge/netfilter/nf_conntrack_bridge.c index 506d6141e44e..809673222382 100644 --- a/net/bridge/netfilter/nf_conntrack_bridge.c +++ b/net/bridge/netfilter/nf_conntrack_bridge.c @@ -95,7 +95,7 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk, * This may also be a clone skbuff, we could preserve the geometry for * the copies but probably not worth the effort. */ - ip_frag_init(skb, hlen, ll_rs, frag_max_size, &state); + ip_frag_init(skb, hlen, ll_rs, frag_max_size, false, &state); while (state.left > 0) { struct sk_buff *skb2; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 814b9b8882a0..3d8baaaf7086 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -645,11 +645,12 @@ void ip_fraglist_prepare(struct sk_buff *skb, struct ip_fraglist_iter *iter) EXPORT_SYMBOL(ip_fraglist_prepare); void ip_frag_init(struct sk_buff *skb, unsigned int hlen, - unsigned int ll_rs, unsigned int mtu, + unsigned int ll_rs, unsigned int mtu, bool DF, struct ip_frag_state *state) { struct iphdr *iph = ip_hdr(skb); + state->DF = DF; state->hlen = hlen; state->ll_rs = ll_rs; state->mtu = mtu; @@ -668,9 +669,6 @@ static void ip_frag_ipcb(struct sk_buff *from, struct sk_buff *to, /* Copy the flags to each fragment. */ IPCB(to)->flags = IPCB(from)->flags; - if (IPCB(from)->flags & IPSKB_FRAG_PMTU) - state->iph->frag_off |= htons(IP_DF); - /* ANK: dirty, but effective trick. Upgrade options only if * the segment to be fragmented was THE FIRST (otherwise, * options are already fixed) and make it ONCE @@ -738,6 +736,8 @@ struct sk_buff *ip_frag_next(struct sk_buff *skb, struct ip_frag_state *state) */ iph = ip_hdr(skb2); iph->frag_off = htons((state->offset >> 3)); + if (state->DF) + iph->frag_off |= htons(IP_DF); /* * Added AC : If we are fragmenting a fragment that's not the @@ -883,7 +883,8 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, * Fragment the datagram. */ - ip_frag_init(skb, hlen, ll_rs, mtu, &state); + ip_frag_init(skb, hlen, ll_rs, mtu, IPCB(skb)->flags & IPSKB_FRAG_PMTU, + &state); /* * Keep copying data until we run out. -- GitLab From b3060531979422d5bb18d80226f978910284dc70 Mon Sep 17 00:00:00 2001 From: Kazutoshi Noguchi Date: Mon, 21 Oct 2019 00:03:07 +0900 Subject: [PATCH 567/993] r8152: add device id for Lenovo ThinkPad USB-C Dock Gen 2 This device is sold as 'ThinkPad USB-C Dock Gen 2 (40AS)'. Chipset is RTL8153 and works with r8152. Without this, the generic cdc_ether grabs the device, and the device jam connected networks up when the machine suspends. Signed-off-by: Kazutoshi Noguchi Signed-off-by: David S. Miller --- drivers/net/usb/cdc_ether.c | 7 +++++++ drivers/net/usb/r8152.c | 1 + 2 files changed, 8 insertions(+) diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 32f53de5b1fe..fe630438f67b 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -787,6 +787,13 @@ static const struct usb_device_id products[] = { .driver_info = 0, }, +/* ThinkPad USB-C Dock Gen 2 (based on Realtek RTL8153) */ +{ + USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0xa387, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, + /* NVIDIA Tegra USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ { USB_DEVICE_AND_INTERFACE_INFO(NVIDIA_VENDOR_ID, 0x09ff, USB_CLASS_COMM, diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index cee9fef925cd..d4a95b50bda6 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -5755,6 +5755,7 @@ static const struct usb_device_id rtl8152_table[] = { {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0xa387)}, {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)}, {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)}, {REALTEK_USB_DEVICE(VENDOR_ID_TPLINK, 0x0601)}, -- GitLab From ce197d83a9fc42795c248c90983bf05faf0f013b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Sat, 19 Oct 2019 13:19:31 +0200 Subject: [PATCH 568/993] xdp: Handle device unregister for devmap_hash map type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems I forgot to add handling of devmap_hash type maps to the device unregister hook for devmaps. This omission causes devices to not be properly released, which causes hangs. Fix this by adding the missing handler. Fixes: 6f9d451ab1a3 ("xdp: Add devmap_hash map type for looking up devices by hashed index") Reported-by: Tetsuo Handa Signed-off-by: Toke Høiland-Jørgensen Signed-off-by: Alexei Starovoitov Acked-by: Martin KaFai Lau Link: https://lore.kernel.org/bpf/20191019111931.2981954-1-toke@redhat.com --- kernel/bpf/devmap.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c index c0a48f336997..3867864cdc2f 100644 --- a/kernel/bpf/devmap.c +++ b/kernel/bpf/devmap.c @@ -719,6 +719,32 @@ const struct bpf_map_ops dev_map_hash_ops = { .map_check_btf = map_check_no_btf, }; +static void dev_map_hash_remove_netdev(struct bpf_dtab *dtab, + struct net_device *netdev) +{ + unsigned long flags; + u32 i; + + spin_lock_irqsave(&dtab->index_lock, flags); + for (i = 0; i < dtab->n_buckets; i++) { + struct bpf_dtab_netdev *dev; + struct hlist_head *head; + struct hlist_node *next; + + head = dev_map_index_hash(dtab, i); + + hlist_for_each_entry_safe(dev, next, head, index_hlist) { + if (netdev != dev->dev) + continue; + + dtab->items--; + hlist_del_rcu(&dev->index_hlist); + call_rcu(&dev->rcu, __dev_map_entry_free); + } + } + spin_unlock_irqrestore(&dtab->index_lock, flags); +} + static int dev_map_notification(struct notifier_block *notifier, ulong event, void *ptr) { @@ -735,6 +761,11 @@ static int dev_map_notification(struct notifier_block *notifier, */ rcu_read_lock(); list_for_each_entry_rcu(dtab, &dev_map_list, list) { + if (dtab->map.map_type == BPF_MAP_TYPE_DEVMAP_HASH) { + dev_map_hash_remove_netdev(dtab, netdev); + continue; + } + for (i = 0; i < dtab->map.max_entries; i++) { struct bpf_dtab_netdev *dev, *odev; -- GitLab From db633a4e0e6eda69b6065e3e106f9ea13a0676c3 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 21 Oct 2019 19:24:02 +0200 Subject: [PATCH 569/993] x86/cpu/vmware: Use the full form of INL in VMWARE_HYPERCALL, for clang/llvm LLVM's assembler doesn't accept the short form INL instruction: inl (%%dx) but instead insists on the output register to be explicitly specified. This was previously fixed for the VMWARE_PORT macro. Fix it also for the VMWARE_HYPERCALL macro. Suggested-by: Sami Tolvanen Signed-off-by: Thomas Hellstrom Reviewed-by: Nick Desaulniers Cc: Borislav Petkov Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sean Christopherson Cc: Thomas Gleixner Cc: clang-built-linux@googlegroups.com Fixes: b4dd4f6e3648 ("Add a header file for hypercall definitions") Link: https://lkml.kernel.org/r/20191021172403.3085-2-thomas_os@shipmail.org Signed-off-by: Ingo Molnar --- arch/x86/include/asm/vmware.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h index e00c9e875933..3caac90f9761 100644 --- a/arch/x86/include/asm/vmware.h +++ b/arch/x86/include/asm/vmware.h @@ -29,7 +29,8 @@ /* The low bandwidth call. The low word of edx is presumed clear. */ #define VMWARE_HYPERCALL \ - ALTERNATIVE_2("movw $" VMWARE_HYPERVISOR_PORT ", %%dx; inl (%%dx)", \ + ALTERNATIVE_2("movw $" VMWARE_HYPERVISOR_PORT ", %%dx; " \ + "inl (%%dx), %%eax", \ "vmcall", X86_FEATURE_VMCALL, \ "vmmcall", X86_FEATURE_VMW_VMMCALL) -- GitLab From 6fee2a0be0ecae939d4b6cd8297d88b5cbb61654 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 21 Oct 2019 19:24:03 +0200 Subject: [PATCH 570/993] x86/cpu/vmware: Fix platform detection VMWARE_PORT macro The platform detection VMWARE_PORT macro uses the VMWARE_HYPERVISOR_PORT definition, but expects it to be an integer. However, when it was moved to the new vmware.h include file, it was changed to be a string to better fit into the VMWARE_HYPERCALL set of macros. This obviously breaks the platform detection VMWARE_PORT functionality. Change the VMWARE_HYPERVISOR_PORT and VMWARE_HYPERVISOR_PORT_HB definitions to be integers, and use __stringify() for their stringified form when needed. Signed-off-by: Thomas Hellstrom Cc: Borislav Petkov Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Sean Christopherson Cc: Thomas Gleixner Fixes: b4dd4f6e3648 ("Add a header file for hypercall definitions") Link: https://lkml.kernel.org/r/20191021172403.3085-3-thomas_os@shipmail.org Signed-off-by: Ingo Molnar --- arch/x86/include/asm/vmware.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h index 3caac90f9761..ac9fc51e2b18 100644 --- a/arch/x86/include/asm/vmware.h +++ b/arch/x86/include/asm/vmware.h @@ -4,6 +4,7 @@ #include #include +#include /* * The hypercall definitions differ in the low word of the %edx argument @@ -20,8 +21,8 @@ */ /* Old port-based version */ -#define VMWARE_HYPERVISOR_PORT "0x5658" -#define VMWARE_HYPERVISOR_PORT_HB "0x5659" +#define VMWARE_HYPERVISOR_PORT 0x5658 +#define VMWARE_HYPERVISOR_PORT_HB 0x5659 /* Current vmcall / vmmcall version */ #define VMWARE_HYPERVISOR_HB BIT(0) @@ -29,7 +30,7 @@ /* The low bandwidth call. The low word of edx is presumed clear. */ #define VMWARE_HYPERCALL \ - ALTERNATIVE_2("movw $" VMWARE_HYPERVISOR_PORT ", %%dx; " \ + ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT) ", %%dx; " \ "inl (%%dx), %%eax", \ "vmcall", X86_FEATURE_VMCALL, \ "vmmcall", X86_FEATURE_VMW_VMMCALL) @@ -39,7 +40,8 @@ * HB and OUT bits set. */ #define VMWARE_HYPERCALL_HB_OUT \ - ALTERNATIVE_2("movw $" VMWARE_HYPERVISOR_PORT_HB ", %%dx; rep outsb", \ + ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; " \ + "rep outsb", \ "vmcall", X86_FEATURE_VMCALL, \ "vmmcall", X86_FEATURE_VMW_VMMCALL) @@ -48,7 +50,8 @@ * HB bit set. */ #define VMWARE_HYPERCALL_HB_IN \ - ALTERNATIVE_2("movw $" VMWARE_HYPERVISOR_PORT_HB ", %%dx; rep insb", \ + ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; " \ + "rep insb", \ "vmcall", X86_FEATURE_VMCALL, \ "vmmcall", X86_FEATURE_VMW_VMMCALL) #endif -- GitLab From 6b1340cc00edeadd52ebd8a45171f38c8de2a387 Mon Sep 17 00:00:00 2001 From: Prateek Sood Date: Tue, 15 Oct 2019 11:47:25 +0530 Subject: [PATCH 571/993] tracing: Fix race in perf_trace_buf initialization A race condition exists while initialiazing perf_trace_buf from perf_trace_init() and perf_kprobe_init(). CPU0 CPU1 perf_trace_init() mutex_lock(&event_mutex) perf_trace_event_init() perf_trace_event_reg() total_ref_count == 0 buf = alloc_percpu() perf_trace_buf[i] = buf tp_event->class->reg() //fails perf_kprobe_init() goto fail perf_trace_event_init() perf_trace_event_reg() fail: total_ref_count == 0 total_ref_count == 0 buf = alloc_percpu() perf_trace_buf[i] = buf tp_event->class->reg() total_ref_count++ free_percpu(perf_trace_buf[i]) perf_trace_buf[i] = NULL Any subsequent call to perf_trace_event_reg() will observe total_ref_count > 0, causing the perf_trace_buf to be always NULL. This can result in perf_trace_buf getting accessed from perf_trace_buf_alloc() without being initialized. Acquiring event_mutex in perf_kprobe_init() before calling perf_trace_event_init() should fix this race. The race caused the following bug: Unable to handle kernel paging request at virtual address 0000003106f2003c Mem abort info: ESR = 0x96000045 Exception class = DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 Data abort info: ISV = 0, ISS = 0x00000045 CM = 0, WnR = 1 user pgtable: 4k pages, 39-bit VAs, pgdp = ffffffc034b9b000 [0000003106f2003c] pgd=0000000000000000, pud=0000000000000000 Internal error: Oops: 96000045 [#1] PREEMPT SMP Process syz-executor (pid: 18393, stack limit = 0xffffffc093190000) pstate: 80400005 (Nzcv daif +PAN -UAO) pc : __memset+0x20/0x1ac lr : memset+0x3c/0x50 sp : ffffffc09319fc50 __memset+0x20/0x1ac perf_trace_buf_alloc+0x140/0x1a0 perf_trace_sys_enter+0x158/0x310 syscall_trace_enter+0x348/0x7c0 el0_svc_common+0x11c/0x368 el0_svc_handler+0x12c/0x198 el0_svc+0x8/0xc Ramdumps showed the following: total_ref_count = 3 perf_trace_buf = ( 0x0 -> NULL, 0x0 -> NULL, 0x0 -> NULL, 0x0 -> NULL) Link: http://lkml.kernel.org/r/1571120245-4186-1-git-send-email-prsood@codeaurora.org Cc: stable@vger.kernel.org Fixes: e12f03d7031a9 ("perf/core: Implement the 'perf_kprobe' PMU") Acked-by: Song Liu Signed-off-by: Prateek Sood Signed-off-by: Steven Rostedt (VMware) --- kernel/trace/trace_event_perf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 0892e38ed6fb..a9dfa04ffa44 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -272,9 +272,11 @@ int perf_kprobe_init(struct perf_event *p_event, bool is_retprobe) goto out; } + mutex_lock(&event_mutex); ret = perf_trace_event_init(tp_event, p_event); if (ret) destroy_local_trace_kprobe(tp_event); + mutex_unlock(&event_mutex); out: kfree(func); return ret; @@ -282,8 +284,10 @@ int perf_kprobe_init(struct perf_event *p_event, bool is_retprobe) void perf_kprobe_destroy(struct perf_event *p_event) { + mutex_lock(&event_mutex); perf_trace_event_close(p_event); perf_trace_event_unreg(p_event); + mutex_unlock(&event_mutex); destroy_local_trace_kprobe(p_event->tp_event); } -- GitLab From edffc70f505abdab885f4b4212438b4298dec78f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 18 Oct 2019 15:35:34 +0300 Subject: [PATCH 572/993] ACPI: NFIT: Fix unlock on error in scrub_show() We change the locking in this function and forgot to update this error path so we are accidentally still holding the "dev->lockdep_mutex". Fixes: 87a30e1f05d7 ("driver-core, libnvdimm: Let device subsystems add local lockdep coverage") Signed-off-by: Dan Carpenter Reviewed-by: Ira Weiny Acked-by: Dan Williams Cc: 5.3+ # 5.3+ Signed-off-by: Rafael J. Wysocki --- drivers/acpi/nfit/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index 1413324982f0..14e68f202f81 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -1322,7 +1322,7 @@ static ssize_t scrub_show(struct device *dev, nfit_device_lock(dev); nd_desc = dev_get_drvdata(dev); if (!nd_desc) { - device_unlock(dev); + nfit_device_unlock(dev); return rc; } acpi_desc = to_acpi_desc(nd_desc); -- GitLab From 31d851407f90076c58291fb5eadc82c1dd613cee Mon Sep 17 00:00:00 2001 From: Zhenzhong Duan Date: Fri, 18 Oct 2019 08:49:29 +0800 Subject: [PATCH 573/993] cpuidle: haltpoll: Take 'idle=' override into account Currenly haltpoll isn't aware of the 'idle=' override, the priority is 'idle=poll' > haltpoll > 'idle=halt'. When 'idle=poll' is used, cpuidle driver is bypassed but current_driver in sys still shows 'haltpoll'. When 'idle=halt' is used, haltpoll takes precedence and makes 'idle=halt' have no effect. Add a check to prevent the haltpoll driver from loading if 'idle=' is present. Signed-off-by: Zhenzhong Duan Co-developed-by: Joao Martins [ rjw: Subject ] Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/cpuidle-haltpoll.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/cpuidle/cpuidle-haltpoll.c b/drivers/cpuidle/cpuidle-haltpoll.c index 932390b028f1..b0ce9bc78113 100644 --- a/drivers/cpuidle/cpuidle-haltpoll.c +++ b/drivers/cpuidle/cpuidle-haltpoll.c @@ -95,6 +95,10 @@ static int __init haltpoll_init(void) int ret; struct cpuidle_driver *drv = &haltpoll_driver; + /* Do not load haltpoll if idle= is passed */ + if (boot_option_idle_override != IDLE_NO_OVERRIDE) + return -ENODEV; + cpuidle_poll_state_init(drv); if (!kvm_para_available() || -- GitLab From 41cd02c6f7f6e66e7abf02a4379e355a7db89f78 Mon Sep 17 00:00:00 2001 From: Jim Mattson Date: Fri, 4 Oct 2019 13:22:47 -0700 Subject: [PATCH 574/993] kvm: x86: Expose RDPID in KVM_GET_SUPPORTED_CPUID When the RDPID instruction is supported on the host, enumerate it in KVM_GET_SUPPORTED_CPUID. Signed-off-by: Jim Mattson Signed-off-by: Paolo Bonzini --- arch/x86/kvm/cpuid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 9c5029cf6f3f..f68c0c753c38 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -363,7 +363,7 @@ static inline void do_cpuid_7_mask(struct kvm_cpuid_entry2 *entry, int index) /* cpuid 7.0.ecx*/ const u32 kvm_cpuid_7_0_ecx_x86_features = - F(AVX512VBMI) | F(LA57) | F(PKU) | 0 /*OSPKE*/ | + F(AVX512VBMI) | F(LA57) | F(PKU) | 0 /*OSPKE*/ | F(RDPID) | F(AVX512_VPOPCNTDQ) | F(UMIP) | F(AVX512_VBMI2) | F(GFNI) | F(VAES) | F(VPCLMULQDQ) | F(AVX512_VNNI) | F(AVX512_BITALG) | F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B) | 0 /*WAITPKG*/; -- GitLab From 9de25d182b806d63412f6827e3066c031d4be500 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 7 Oct 2019 15:26:56 +0200 Subject: [PATCH 575/993] selftests: kvm: synchronize .gitignore to Makefile Because "Untracked files:" are annoying. Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/.gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index b35da375530a..409c1fa75e03 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -1,4 +1,5 @@ /s390x/sync_regs_test +/s390x/memop /x86_64/cr4_cpuid_sync_test /x86_64/evmcs_test /x86_64/hyperv_cpuid @@ -9,6 +10,7 @@ /x86_64/state_test /x86_64/sync_regs_test /x86_64/vmx_close_while_nested_test +/x86_64/vmx_dirty_log_test /x86_64/vmx_set_nested_state_test /x86_64/vmx_tsc_adjust_test /clear_dirty_log_test -- GitLab From 44551b2f693d1ddcab4ca9895074f8f61c3a72af Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Sun, 29 Sep 2019 09:06:56 +0800 Subject: [PATCH 576/993] KVM: Don't shrink/grow vCPU halt_poll_ns if host side polling is disabled Don't waste cycles to shrink/grow vCPU halt_poll_ns if host side polling is disabled. Acked-by: Marcelo Tosatti Cc: Marcelo Tosatti Signed-off-by: Wanpeng Li Signed-off-by: Paolo Bonzini --- virt/kvm/kvm_main.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index fd68fbe0a75d..67ef3f2e19e8 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2360,20 +2360,23 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu) kvm_arch_vcpu_unblocking(vcpu); block_ns = ktime_to_ns(cur) - ktime_to_ns(start); - if (!vcpu_valid_wakeup(vcpu)) - shrink_halt_poll_ns(vcpu); - else if (halt_poll_ns) { - if (block_ns <= vcpu->halt_poll_ns) - ; - /* we had a long block, shrink polling */ - else if (vcpu->halt_poll_ns && block_ns > halt_poll_ns) + if (!kvm_arch_no_poll(vcpu)) { + if (!vcpu_valid_wakeup(vcpu)) { shrink_halt_poll_ns(vcpu); - /* we had a short halt and our poll time is too small */ - else if (vcpu->halt_poll_ns < halt_poll_ns && - block_ns < halt_poll_ns) - grow_halt_poll_ns(vcpu); - } else - vcpu->halt_poll_ns = 0; + } else if (halt_poll_ns) { + if (block_ns <= vcpu->halt_poll_ns) + ; + /* we had a long block, shrink polling */ + else if (vcpu->halt_poll_ns && block_ns > halt_poll_ns) + shrink_halt_poll_ns(vcpu); + /* we had a short halt and our poll time is too small */ + else if (vcpu->halt_poll_ns < halt_poll_ns && + block_ns < halt_poll_ns) + grow_halt_poll_ns(vcpu); + } else { + vcpu->halt_poll_ns = 0; + } + } trace_kvm_vcpu_wakeup(block_ns, waited, vcpu_valid_wakeup(vcpu)); kvm_arch_vcpu_block_finish(vcpu); -- GitLab From 700c17d9cec8712f4091692488fb63e2680f7a5d Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Tue, 8 Oct 2019 21:43:36 +0200 Subject: [PATCH 577/993] selftests: kvm: vmx_set_nested_state_test: don't check for VMX support twice vmx_set_nested_state_test() checks if VMX is supported twice: in the very beginning (and skips the whole test if it's not) and before doing test_vmx_nested_state(). One should be enough. Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- .../selftests/kvm/x86_64/vmx_set_nested_state_test.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c index 853e370e8a39..a6d85614ae4d 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c @@ -271,12 +271,7 @@ int main(int argc, char *argv[]) state.flags = KVM_STATE_NESTED_RUN_PENDING; test_nested_state_expect_einval(vm, &state); - /* - * TODO: When SVM support is added for KVM_SET_NESTED_STATE - * add tests here to support it like VMX. - */ - if (entry->ecx & CPUID_VMX) - test_vmx_nested_state(vm); + test_vmx_nested_state(vm); kvm_vm_free(vm); return 0; -- GitLab From 9143613ef0ba9f88d2fef9038930637a0909d35a Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Tue, 8 Oct 2019 21:43:37 +0200 Subject: [PATCH 578/993] selftests: kvm: consolidate VMX support checks vmx_* tests require VMX and three of them implement the same check. Move it to vmx library. Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/include/x86_64/vmx.h | 2 ++ tools/testing/selftests/kvm/lib/x86_64/vmx.c | 10 ++++++++++ .../selftests/kvm/x86_64/vmx_close_while_nested_test.c | 6 +----- .../selftests/kvm/x86_64/vmx_set_nested_state_test.c | 6 +----- .../testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c | 6 +----- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86_64/vmx.h b/tools/testing/selftests/kvm/include/x86_64/vmx.h index 6ae5a47fe067..f52e0ba84fed 100644 --- a/tools/testing/selftests/kvm/include/x86_64/vmx.h +++ b/tools/testing/selftests/kvm/include/x86_64/vmx.h @@ -580,6 +580,8 @@ bool prepare_for_vmx_operation(struct vmx_pages *vmx); void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip, void *guest_rsp); bool load_vmcs(struct vmx_pages *vmx); +void nested_vmx_check_supported(void); + void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm, uint64_t nested_paddr, uint64_t paddr, uint32_t eptp_memslot); void nested_map(struct vmx_pages *vmx, struct kvm_vm *vm, diff --git a/tools/testing/selftests/kvm/lib/x86_64/vmx.c b/tools/testing/selftests/kvm/lib/x86_64/vmx.c index fab8f6b0bf52..f6ec97b7eaef 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/vmx.c +++ b/tools/testing/selftests/kvm/lib/x86_64/vmx.c @@ -376,6 +376,16 @@ void prepare_vmcs(struct vmx_pages *vmx, void *guest_rip, void *guest_rsp) init_vmcs_guest_state(guest_rip, guest_rsp); } +void nested_vmx_check_supported(void) +{ + struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1); + + if (!(entry->ecx & CPUID_VMX)) { + fprintf(stderr, "nested VMX not enabled, skipping test\n"); + exit(KSFT_SKIP); + } +} + void nested_pg_map(struct vmx_pages *vmx, struct kvm_vm *vm, uint64_t nested_paddr, uint64_t paddr, uint32_t eptp_memslot) { diff --git a/tools/testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c b/tools/testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c index 3b0ffe01dacd..5dfb53546a26 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_close_while_nested_test.c @@ -53,12 +53,8 @@ static void l1_guest_code(struct vmx_pages *vmx_pages) int main(int argc, char *argv[]) { vm_vaddr_t vmx_pages_gva; - struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1); - if (!(entry->ecx & CPUID_VMX)) { - fprintf(stderr, "nested VMX not enabled, skipping test\n"); - exit(KSFT_SKIP); - } + nested_vmx_check_supported(); vm = vm_create_default(VCPU_ID, 0, (void *) l1_guest_code); vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); diff --git a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c index a6d85614ae4d..9ef7fab39d48 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_set_nested_state_test.c @@ -224,7 +224,6 @@ int main(int argc, char *argv[]) { struct kvm_vm *vm; struct kvm_nested_state state; - struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1); have_evmcs = kvm_check_cap(KVM_CAP_HYPERV_ENLIGHTENED_VMCS); @@ -237,10 +236,7 @@ int main(int argc, char *argv[]) * AMD currently does not implement set_nested_state, so for now we * just early out. */ - if (!(entry->ecx & CPUID_VMX)) { - fprintf(stderr, "nested VMX not enabled, skipping test\n"); - exit(KSFT_SKIP); - } + nested_vmx_check_supported(); vm = vm_create_default(VCPU_ID, 0, 0); diff --git a/tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c b/tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c index f36c10eba71e..5590fd2bcf87 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_tsc_adjust_test.c @@ -128,12 +128,8 @@ static void report(int64_t val) int main(int argc, char *argv[]) { vm_vaddr_t vmx_pages_gva; - struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1); - if (!(entry->ecx & CPUID_VMX)) { - fprintf(stderr, "nested VMX not enabled, skipping test\n"); - exit(KSFT_SKIP); - } + nested_vmx_check_supported(); vm = vm_create_default(VCPU_ID, 0, (void *) l1_guest_code); vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); -- GitLab From 11eada4718a352a6a588de9908200c1e348530f1 Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Tue, 8 Oct 2019 21:43:38 +0200 Subject: [PATCH 579/993] selftests: kvm: vmx_dirty_log_test: skip the test when VMX is not supported vmx_dirty_log_test fails on AMD and this is no surprise as it is VMX specific. Bail early when nested VMX is unsupported. Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c b/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c index 0bca1cfe2c1e..a223a6401258 100644 --- a/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c +++ b/tools/testing/selftests/kvm/x86_64/vmx_dirty_log_test.c @@ -78,6 +78,8 @@ int main(int argc, char *argv[]) struct ucall uc; bool done = false; + nested_vmx_check_supported(); + /* Create VM */ vm = vm_create_default(VCPU_ID, 0, l1_guest_code); vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); -- GitLab From ef4059809890f732c69cc1726d3a9a108a832a2f Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Tue, 8 Oct 2019 20:08:08 +0200 Subject: [PATCH 580/993] selftests: kvm: fix sync_regs_test with newer gccs Commit 204c91eff798a ("KVM: selftests: do not blindly clobber registers in guest asm") was intended to make test more gcc-proof, however, the result is exactly the opposite: on newer gccs (e.g. 8.2.1) the test breaks with ==== Test Assertion Failure ==== x86_64/sync_regs_test.c:168: run->s.regs.regs.rbx == 0xBAD1DEA + 1 pid=14170 tid=14170 - Invalid argument 1 0x00000000004015b3: main at sync_regs_test.c:166 (discriminator 6) 2 0x00007f413fb66412: ?? ??:0 3 0x000000000040191d: _start at ??:? rbx sync regs value incorrect 0x1. Apparently, compile is still free to play games with registers even when they have variables attached. Re-write guest code with 'asm volatile' by embedding ucall there and making sure rbx is preserved. Fixes: 204c91eff798a ("KVM: selftests: do not blindly clobber registers in guest asm") Signed-off-by: Vitaly Kuznetsov Signed-off-by: Paolo Bonzini --- .../selftests/kvm/x86_64/sync_regs_test.c | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tools/testing/selftests/kvm/x86_64/sync_regs_test.c b/tools/testing/selftests/kvm/x86_64/sync_regs_test.c index 11c2a70a7b87..5c8224256294 100644 --- a/tools/testing/selftests/kvm/x86_64/sync_regs_test.c +++ b/tools/testing/selftests/kvm/x86_64/sync_regs_test.c @@ -22,18 +22,19 @@ #define VCPU_ID 5 +#define UCALL_PIO_PORT ((uint16_t)0x1000) + +/* + * ucall is embedded here to protect against compiler reshuffling registers + * before calling a function. In this test we only need to get KVM_EXIT_IO + * vmexit and preserve RBX, no additional information is needed. + */ void guest_code(void) { - /* - * use a callee-save register, otherwise the compiler - * saves it around the call to GUEST_SYNC. - */ - register u32 stage asm("rbx"); - for (;;) { - GUEST_SYNC(0); - stage++; - asm volatile ("" : : "r" (stage)); - } + asm volatile("1: in %[port], %%al\n" + "add $0x1, %%rbx\n" + "jmp 1b" + : : [port] "d" (UCALL_PIO_PORT) : "rax", "rbx"); } static void compare_regs(struct kvm_regs *left, struct kvm_regs *right) -- GitLab From 1a8211c7d8717b19c1e9fa41d19fe6a55409765e Mon Sep 17 00:00:00 2001 From: Liran Alon Date: Sun, 29 Sep 2019 17:50:18 +0300 Subject: [PATCH 581/993] KVM: VMX: Remove specialized handling of unexpected exit-reasons Commit bf653b78f960 ("KVM: vmx: Introduce handle_unexpected_vmexit and handle WAITPKG vmexit") introduced specialized handling of specific exit-reasons that should not be raised by CPU because KVM configures VMCS such that they should never be raised. However, since commit 7396d337cfad ("KVM: x86: Return to userspace with internal error on unexpected exit reason"), VMX & SVM exit handlers were modified to generically handle all unexpected exit-reasons by returning to userspace with internal error. Therefore, there is no need for specialized handling of specific unexpected exit-reasons (This specialized handling also introduced inconsistency for these exit-reasons to silently skip guest instruction instead of return to userspace on internal-error). Fixes: bf653b78f960 ("KVM: vmx: Introduce handle_unexpected_vmexit and handle WAITPKG vmexit") Signed-off-by: Liran Alon Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx/vmx.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index e7970a2e8eae..8f01019295a1 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -5543,14 +5543,6 @@ static int handle_encls(struct kvm_vcpu *vcpu) return 1; } -static int handle_unexpected_vmexit(struct kvm_vcpu *vcpu) -{ - kvm_skip_emulated_instruction(vcpu); - WARN_ONCE(1, "Unexpected VM-Exit Reason = 0x%x", - vmcs_read32(VM_EXIT_REASON)); - return 1; -} - /* * The exit handlers return 1 if the exit was handled fully and guest execution * may resume. Otherwise they set the kvm_run parameter to indicate what needs @@ -5602,15 +5594,11 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { [EXIT_REASON_INVVPID] = handle_vmx_instruction, [EXIT_REASON_RDRAND] = handle_invalid_op, [EXIT_REASON_RDSEED] = handle_invalid_op, - [EXIT_REASON_XSAVES] = handle_unexpected_vmexit, - [EXIT_REASON_XRSTORS] = handle_unexpected_vmexit, [EXIT_REASON_PML_FULL] = handle_pml_full, [EXIT_REASON_INVPCID] = handle_invpcid, [EXIT_REASON_VMFUNC] = handle_vmx_instruction, [EXIT_REASON_PREEMPTION_TIMER] = handle_preemption_timer, [EXIT_REASON_ENCLS] = handle_encls, - [EXIT_REASON_UMWAIT] = handle_unexpected_vmexit, - [EXIT_REASON_TPAUSE] = handle_unexpected_vmexit, }; static const int kvm_vmx_max_exit_handlers = -- GitLab From b4fdcf6056d9057fe762bd6d8060e3ab9949efea Mon Sep 17 00:00:00 2001 From: kbuild test robot Date: Sun, 29 Sep 2019 18:43:28 +0200 Subject: [PATCH 582/993] KVM: x86: fix bugon.cocci warnings Use BUG_ON instead of a if condition followed by BUG. Generated by: scripts/coccinelle/misc/bugon.cocci Fixes: 4b526de50e39 ("KVM: x86: Check kvm_rebooting in kvm_spurious_fault()") CC: Sean Christopherson Signed-off-by: kbuild test robot Signed-off-by: Julia Lawall Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 661e2bf38526..41aecc4c52d9 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -360,8 +360,7 @@ EXPORT_SYMBOL_GPL(kvm_set_apic_base); asmlinkage __visible void kvm_spurious_fault(void) { /* Fault while not rebooting. We want the trace. */ - if (!kvm_rebooting) - BUG(); + BUG_ON(!kvm_rebooting); } EXPORT_SYMBOL_GPL(kvm_spurious_fault); -- GitLab From 49dedf0dd0da073b3a0146a62c768887aea13508 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 10 Oct 2019 12:49:22 +0200 Subject: [PATCH 583/993] kvm: clear kvmclock MSR on reset After resetting the vCPU, the kvmclock MSR keeps the previous value but it is not enabled. This can be confusing, so fix it. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 41aecc4c52d9..5863c38108d9 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2536,6 +2536,7 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) static void kvmclock_reset(struct kvm_vcpu *vcpu) { vcpu->arch.pv_time_enabled = false; + vcpu->arch.time = 0; } static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa) @@ -2701,8 +2702,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_KVM_SYSTEM_TIME: { struct kvm_arch *ka = &vcpu->kvm->arch; - kvmclock_reset(vcpu); - if (vcpu->vcpu_id == 0 && !msr_info->host_initiated) { bool tmp = (msr == MSR_KVM_SYSTEM_TIME); @@ -2716,14 +2715,13 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu); /* we verify if the enable bit is set... */ + vcpu->arch.pv_time_enabled = false; if (!(data & 1)) break; - if (kvm_gfn_to_hva_cache_init(vcpu->kvm, + if (!kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.pv_time, data & ~1ULL, sizeof(struct pvclock_vcpu_time_info))) - vcpu->arch.pv_time_enabled = false; - else vcpu->arch.pv_time_enabled = true; break; -- GitLab From f3a519e4add93b7b31a6616f0b09635ff2e6a159 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Tue, 22 Oct 2019 10:39:40 +0300 Subject: [PATCH 584/993] perf/aux: Fix AUX output stopping Commit: 8a58ddae2379 ("perf/core: Fix exclusive events' grouping") allows CAP_EXCLUSIVE events to be grouped with other events. Since all of those also happen to be AUX events (which is not the case the other way around, because arch/s390), this changes the rules for stopping the output: the AUX event may not be on its PMU's context any more, if it's grouped with a HW event, in which case it will be on that HW event's context instead. If that's the case, munmap() of the AUX buffer can't find and stop the AUX event, potentially leaving the last reference with the atomic context, which will then end up freeing the AUX buffer. This will then trip warnings: Fix this by using the context's PMU context when looking for events to stop, instead of the event's PMU context. Signed-off-by: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20191022073940.61814-1-alexander.shishkin@linux.intel.com Signed-off-by: Ingo Molnar --- kernel/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index f5d7950d1931..bb3748d29b04 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6949,7 +6949,7 @@ static void __perf_event_output_stop(struct perf_event *event, void *data) static int __perf_pmu_output_stop(void *info) { struct perf_event *event = info; - struct pmu *pmu = event->pmu; + struct pmu *pmu = event->ctx->pmu; struct perf_cpu_context *cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); struct remote_output ro = { .rb = event->rb, -- GitLab From ba8bf0967a154796be15c4983603aad0b05c3138 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 22 Oct 2019 17:45:14 +0200 Subject: [PATCH 585/993] ALSA: usb-audio: Fix copy&paste error in the validator The recently introduced USB-audio descriptor validator had a stupid copy&paste error that may lead to an unexpected overlook of too short descriptors for processing and extension units. It's likely the cause of the report triggered by syzkaller fuzzer. Let's fix it. Fixes: 57f8770620e9 ("ALSA: usb-audio: More validations of descriptor units") Reported-by: syzbot+0620f79a1978b1133fd7@syzkaller.appspotmail.com Link: https://lore.kernel.org/r/s5hsgnkdbsl.wl-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/usb/validate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/usb/validate.c b/sound/usb/validate.c index 3c8f73a0eb12..a5e584b60dcd 100644 --- a/sound/usb/validate.c +++ b/sound/usb/validate.c @@ -75,7 +75,7 @@ static bool validate_processing_unit(const void *p, if (d->bLength < sizeof(*d)) return false; - len = d->bLength < sizeof(*d) + d->bNrInPins; + len = sizeof(*d) + d->bNrInPins; if (d->bLength < len) return false; switch (v->protocol) { -- GitLab From 388bb19be8eab4674a660e0c97eaf60775362bc7 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 10 Oct 2019 15:13:33 +0200 Subject: [PATCH 586/993] s390/zcrypt: fix memleak at release If a process is interrupted while accessing the crypto device and the global ap_perms_mutex is contented, release() could return early and fail to free related resources. Fixes: 00fab2350e6b ("s390/zcrypt: multiple zcrypt device nodes support") Cc: # 4.19 Cc: Harald Freudenberger Signed-off-by: Johan Hovold Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- drivers/s390/crypto/zcrypt_api.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 45bdb47f84c1..9157e728a362 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -522,8 +522,7 @@ static int zcrypt_release(struct inode *inode, struct file *filp) if (filp->f_inode->i_cdev == &zcrypt_cdev) { struct zcdn_device *zcdndev; - if (mutex_lock_interruptible(&ap_perms_mutex)) - return -ERESTARTSYS; + mutex_lock(&ap_perms_mutex); zcdndev = find_zcdndev_by_devt(filp->f_inode->i_rdev); mutex_unlock(&ap_perms_mutex); if (zcdndev) { -- GitLab From ac49303d9ef0ad98b79867a380ef23480e48870b Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Mon, 21 Oct 2019 19:56:00 +0200 Subject: [PATCH 587/993] s390/kaslr: add support for R_390_GLOB_DAT relocation type Commit "bpf: Process in-kernel BTF" in linux-next introduced an undefined __weak symbol, which results in an R_390_GLOB_DAT relocation type. That is not yet handled by the KASLR relocation code, and the kernel stops with the message "Unknown relocation type". Add code to detect and handle R_390_GLOB_DAT relocation types and undefined symbols. Fixes: 805bc0bc238f ("s390/kernel: build a relocatable kernel") Cc: # v5.2+ Acked-by: Heiko Carstens Signed-off-by: Gerald Schaefer Signed-off-by: Vasily Gorbik --- arch/s390/boot/startup.c | 14 +++++++++++--- arch/s390/kernel/machine_kexec_reloc.c | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c index 596ca7cc4d7b..5367950510f6 100644 --- a/arch/s390/boot/startup.c +++ b/arch/s390/boot/startup.c @@ -101,10 +101,18 @@ static void handle_relocs(unsigned long offset) dynsym = (Elf64_Sym *) vmlinux.dynsym_start; for (rela = rela_start; rela < rela_end; rela++) { loc = rela->r_offset + offset; - val = rela->r_addend + offset; + val = rela->r_addend; r_sym = ELF64_R_SYM(rela->r_info); - if (r_sym) - val += dynsym[r_sym].st_value; + if (r_sym) { + if (dynsym[r_sym].st_shndx != SHN_UNDEF) + val += dynsym[r_sym].st_value + offset; + } else { + /* + * 0 == undefined symbol table index (STN_UNDEF), + * used for R_390_RELATIVE, only add KASLR offset + */ + val += offset; + } r_type = ELF64_R_TYPE(rela->r_info); rc = arch_kexec_do_relocs(r_type, (void *) loc, val, 0); if (rc) diff --git a/arch/s390/kernel/machine_kexec_reloc.c b/arch/s390/kernel/machine_kexec_reloc.c index 3b664cb3ec4d..d5035de9020e 100644 --- a/arch/s390/kernel/machine_kexec_reloc.c +++ b/arch/s390/kernel/machine_kexec_reloc.c @@ -27,6 +27,7 @@ int arch_kexec_do_relocs(int r_type, void *loc, unsigned long val, *(u32 *)loc = val; break; case R_390_64: /* Direct 64 bit. */ + case R_390_GLOB_DAT: *(u64 *)loc = val; break; case R_390_PC16: /* PC relative 16 bit. */ -- GitLab From 6941051d3028963c3b0b3fcdd0815f2b51b957bb Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 18 Oct 2019 11:58:15 +0100 Subject: [PATCH 588/993] cpufreq: Cancel policy update work scheduled before freeing Scheduled policy update work may end up racing with the freeing of the policy and unregistering the driver. One possible race is as below, where the cpufreq_driver is unregistered, but the scheduled work gets executed at later stage when, cpufreq_driver is NULL (i.e. after freeing the policy and driver). Unable to handle kernel NULL pointer dereference at virtual address 0000001c pgd = (ptrval) [0000001c] *pgd=80000080204003, *pmd=00000000 Internal error: Oops: 206 [#1] SMP THUMB2 Modules linked in: CPU: 0 PID: 34 Comm: kworker/0:1 Not tainted 5.4.0-rc3-00006-g67f5a8081a4b #86 Hardware name: ARM-Versatile Express Workqueue: events handle_update PC is at cpufreq_set_policy+0x58/0x228 LR is at dev_pm_qos_read_value+0x77/0xac Control: 70c5387d Table: 80203000 DAC: fffffffd Process kworker/0:1 (pid: 34, stack limit = 0x(ptrval)) (cpufreq_set_policy) from (refresh_frequency_limits.part.24+0x37/0x48) (refresh_frequency_limits.part.24) from (handle_update+0x2f/0x38) (handle_update) from (process_one_work+0x16d/0x3cc) (process_one_work) from (worker_thread+0xff/0x414) (worker_thread) from (kthread+0xff/0x100) (kthread) from (ret_from_fork+0x11/0x28) Fixes: 67d874c3b2c6 ("cpufreq: Register notifiers with the PM QoS framework") Signed-off-by: Sudeep Holla [ rjw: Cancel the work before dropping the QoS requests ] Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 8478ff6f3045..48a224a6b178 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1268,6 +1268,9 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy) freq_qos_remove_notifier(&policy->constraints, FREQ_QOS_MIN, &policy->nb_min); + /* Cancel any pending policy->update work before freeing the policy. */ + cancel_work_sync(&policy->update); + if (policy->max_freq_req) { /* * CPUFREQ_CREATE_POLICY notification is sent only after -- GitLab From 5c94ac5d0f9e3c8791d1686e0bf22a2a341d1597 Mon Sep 17 00:00:00 2001 From: Miaohe Lin Date: Fri, 18 Oct 2019 10:50:31 +0800 Subject: [PATCH 589/993] KVM: SVM: Fix potential wrong physical id in avic_handle_ldr_update Guest physical APIC ID may not equal to vcpu->vcpu_id in some case. We may set the wrong physical id in avic_handle_ldr_update as we always use vcpu->vcpu_id. Get physical APIC ID from vAPIC page instead. Export and use kvm_xapic_id here and in avic_handle_apic_id_update as suggested by Vitaly. Signed-off-by: Miaohe Lin Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 5 ----- arch/x86/kvm/lapic.h | 5 +++++ arch/x86/kvm/svm.c | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 87b0fcc23ef8..b29d00b661ff 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -111,11 +111,6 @@ static inline int apic_enabled(struct kvm_lapic *apic) (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \ APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER) -static inline u8 kvm_xapic_id(struct kvm_lapic *apic) -{ - return kvm_lapic_get_reg(apic, APIC_ID) >> 24; -} - static inline u32 kvm_x2apic_id(struct kvm_lapic *apic) { return apic->vcpu->vcpu_id; diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 2aad7e226fc0..1f5014852e20 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -242,4 +242,9 @@ static inline enum lapic_mode kvm_apic_mode(u64 apic_base) return apic_base & (MSR_IA32_APICBASE_ENABLE | X2APIC_ENABLE); } +static inline u8 kvm_xapic_id(struct kvm_lapic *apic) +{ + return kvm_lapic_get_reg(apic, APIC_ID) >> 24; +} + #endif diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index f8ecb6df5106..ca200b50cde4 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -4591,6 +4591,7 @@ static int avic_handle_ldr_update(struct kvm_vcpu *vcpu) int ret = 0; struct vcpu_svm *svm = to_svm(vcpu); u32 ldr = kvm_lapic_get_reg(vcpu->arch.apic, APIC_LDR); + u32 id = kvm_xapic_id(vcpu->arch.apic); if (ldr == svm->ldr_reg) return 0; @@ -4598,7 +4599,7 @@ static int avic_handle_ldr_update(struct kvm_vcpu *vcpu) avic_invalidate_logical_id_entry(vcpu); if (ldr) - ret = avic_ldr_write(vcpu, vcpu->vcpu_id, ldr); + ret = avic_ldr_write(vcpu, id, ldr); if (!ret) svm->ldr_reg = ldr; @@ -4610,8 +4611,7 @@ static int avic_handle_apic_id_update(struct kvm_vcpu *vcpu) { u64 *old, *new; struct vcpu_svm *svm = to_svm(vcpu); - u32 apic_id_reg = kvm_lapic_get_reg(vcpu->arch.apic, APIC_ID); - u32 id = (apic_id_reg >> 24) & 0xff; + u32 id = kvm_xapic_id(vcpu->arch.apic); if (vcpu->vcpu_id == id) return 0; -- GitLab From 8ca8fa7f22dcb0a3265490a690b0c3e27de681f9 Mon Sep 17 00:00:00 2001 From: Eugeniy Paltsev Date: Fri, 18 Oct 2019 14:11:25 +0300 Subject: [PATCH 590/993] ARC: [plat-hsdk]: Enable on-board SPI NOR flash IC HSDK board has sst26wf016b SPI NOR flash IC installed, enable it. Acked-by: Alexey Brodkin Signed-off-by: Eugeniy Paltsev Signed-off-by: Vineet Gupta --- arch/arc/boot/dts/hsdk.dts | 8 ++++++++ arch/arc/configs/hsdk_defconfig | 2 ++ 2 files changed, 10 insertions(+) diff --git a/arch/arc/boot/dts/hsdk.dts b/arch/arc/boot/dts/hsdk.dts index bfc7f5f5d6f2..9bea5daadd23 100644 --- a/arch/arc/boot/dts/hsdk.dts +++ b/arch/arc/boot/dts/hsdk.dts @@ -264,6 +264,14 @@ clocks = <&input_clk>; cs-gpios = <&creg_gpio 0 GPIO_ACTIVE_LOW>, <&creg_gpio 1 GPIO_ACTIVE_LOW>; + + spi-flash@0 { + compatible = "sst26wf016b", "jedec,spi-nor"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + spi-max-frequency = <4000000>; + }; }; creg_gpio: gpio@14b0 { diff --git a/arch/arc/configs/hsdk_defconfig b/arch/arc/configs/hsdk_defconfig index 9b9a74444ce2..22fc70396a3b 100644 --- a/arch/arc/configs/hsdk_defconfig +++ b/arch/arc/configs/hsdk_defconfig @@ -32,6 +32,8 @@ CONFIG_INET=y CONFIG_DEVTMPFS=y # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_MTD=y +CONFIG_MTD_SPI_NOR=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y -- GitLab From ab563bf54a4d08cb59e7d7bcd419f7e8558a4964 Mon Sep 17 00:00:00 2001 From: Eugeniy Paltsev Date: Fri, 18 Oct 2019 14:11:26 +0300 Subject: [PATCH 591/993] ARC: [plat-hsdk]: Enable on-boardi SPI ADC IC HSDK board has adc108s102 SPI ADC IC installed, enable it. Acked-by: Alexey Brodkin Signed-off-by: Eugeniy Paltsev Signed-off-by: Vineet Gupta --- arch/arc/boot/dts/hsdk.dts | 15 +++++++++++++++ arch/arc/configs/hsdk_defconfig | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/arch/arc/boot/dts/hsdk.dts b/arch/arc/boot/dts/hsdk.dts index 9bea5daadd23..9acbeba832c0 100644 --- a/arch/arc/boot/dts/hsdk.dts +++ b/arch/arc/boot/dts/hsdk.dts @@ -65,6 +65,14 @@ clock-frequency = <33333333>; }; + reg_5v0: regulator-5v0 { + compatible = "regulator-fixed"; + + regulator-name = "5v0-supply"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + cpu_intc: cpu-interrupt-controller { compatible = "snps,archs-intc"; interrupt-controller; @@ -272,6 +280,13 @@ #size-cells = <1>; spi-max-frequency = <4000000>; }; + + adc@1 { + compatible = "ti,adc108s102"; + reg = <1>; + vref-supply = <®_5v0>; + spi-max-frequency = <1000000>; + }; }; creg_gpio: gpio@14b0 { diff --git a/arch/arc/configs/hsdk_defconfig b/arch/arc/configs/hsdk_defconfig index 22fc70396a3b..0974226fab55 100644 --- a/arch/arc/configs/hsdk_defconfig +++ b/arch/arc/configs/hsdk_defconfig @@ -57,6 +57,8 @@ CONFIG_GPIO_SYSFS=y CONFIG_GPIO_DWAPB=y CONFIG_GPIO_SNPS_CREG=y # CONFIG_HWMON is not set +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_DRM=y # CONFIG_DRM_FBDEV_EMULATION is not set CONFIG_DRM_UDL=y @@ -74,6 +76,8 @@ CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_DW=y CONFIG_DMADEVICES=y CONFIG_DW_AXI_DMAC=y +CONFIG_IIO=y +CONFIG_TI_ADC108S102=y CONFIG_EXT3_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y -- GitLab From 5effc09c4907901f0e71e68e5f2e14211d9a203f Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Tue, 22 Oct 2019 17:04:11 +0300 Subject: [PATCH 592/993] ARC: perf: Accommodate big-endian CPU 8-letter strings representing ARC perf events are stores in two 32-bit registers as ASCII characters like that: "IJMP", "IALL", "IJMPTAK" etc. And the same order of bytes in the word is used regardless CPU endianness. Which means in case of big-endian CPU core we need to swap bytes to get the same order as if it was on little-endian CPU. Otherwise we're seeing the following error message on boot: ------------------------->8---------------------- ARC perf : 8 counters (32 bits), 40 conditions, [overflow IRQ support] sysfs: cannot create duplicate filename '/devices/arc_pct/events/pmji' CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.2.18 #3 Stack Trace: arc_unwind_core+0xd4/0xfc dump_stack+0x64/0x80 sysfs_warn_dup+0x46/0x58 sysfs_add_file_mode_ns+0xb2/0x168 create_files+0x70/0x2a0 ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1 at kernel/events/core.c:12144 perf_event_sysfs_init+0x70/0xa0 Failed to register pmu: arc_pct, reason -17 Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.2.18 #3 Stack Trace: arc_unwind_core+0xd4/0xfc dump_stack+0x64/0x80 __warn+0x9c/0xd4 warn_slowpath_fmt+0x22/0x2c perf_event_sysfs_init+0x70/0xa0 ---[ end trace a75fb9a9837bd1ec ]--- ------------------------->8---------------------- What happens here we're trying to register more than one raw perf event with the same name "PMJI". Why? Because ARC perf events are 4 to 8 letters and encoded into two 32-bit words. In this particular case we deal with 2 events: * "IJMP____" which counts all jump & branch instructions * "IJMPC___" which counts only conditional jumps & branches Those strings are split in two 32-bit words this way "IJMP" + "____" & "IJMP" + "C___" correspondingly. Now if we read them swapped due to CPU core being big-endian then we read "PMJI" + "____" & "PMJI" + "___C". And since we interpret read array of ASCII letters as a null-terminated string on big-endian CPU we end up with 2 events of the same name "PMJI". Signed-off-by: Alexey Brodkin Cc: stable@vger.kernel.org Signed-off-by: Vineet Gupta --- arch/arc/kernel/perf_event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arc/kernel/perf_event.c b/arch/arc/kernel/perf_event.c index 861a8aea51f9..661fd842ea97 100644 --- a/arch/arc/kernel/perf_event.c +++ b/arch/arc/kernel/perf_event.c @@ -614,8 +614,8 @@ static int arc_pmu_device_probe(struct platform_device *pdev) /* loop thru all available h/w condition indexes */ for (i = 0; i < cc_bcr.c; i++) { write_aux_reg(ARC_REG_CC_INDEX, i); - cc_name.indiv.word0 = read_aux_reg(ARC_REG_CC_NAME0); - cc_name.indiv.word1 = read_aux_reg(ARC_REG_CC_NAME1); + cc_name.indiv.word0 = le32_to_cpu(read_aux_reg(ARC_REG_CC_NAME0)); + cc_name.indiv.word1 = le32_to_cpu(read_aux_reg(ARC_REG_CC_NAME1)); arc_pmu_map_hw_event(i, cc_name.str); arc_pmu_add_raw_event_attr(i, cc_name.str); -- GitLab From 671ddc700fd08b94967b1e2a937020e30c838609 Mon Sep 17 00:00:00 2001 From: Jim Mattson Date: Tue, 15 Oct 2019 10:44:05 -0700 Subject: [PATCH 593/993] KVM: nVMX: Don't leak L1 MMIO regions to L2 If the "virtualize APIC accesses" VM-execution control is set in the VMCS, the APIC virtualization hardware is triggered when a page walk in VMX non-root mode terminates at a PTE wherein the address of the 4k page frame matches the APIC-access address specified in the VMCS. On hardware, the APIC-access address may be any valid 4k-aligned physical address. KVM's nVMX implementation enforces the additional constraint that the APIC-access address specified in the vmcs12 must be backed by a "struct page" in L1. If not, L0 will simply clear the "virtualize APIC accesses" VM-execution control in the vmcs02. The problem with this approach is that the L1 guest has arranged the vmcs12 EPT tables--or shadow page tables, if the "enable EPT" VM-execution control is clear in the vmcs12--so that the L2 guest physical address(es)--or L2 guest linear address(es)--that reference the L2 APIC map to the APIC-access address specified in the vmcs12. Without the "virtualize APIC accesses" VM-execution control in the vmcs02, the APIC accesses in the L2 guest will directly access the APIC-access page in L1. When there is no mapping whatsoever for the APIC-access address in L1, the L2 VM just loses the intended APIC virtualization. However, when the APIC-access address is mapped to an MMIO region in L1, the L2 guest gets direct access to the L1 MMIO device. For example, if the APIC-access address specified in the vmcs12 is 0xfee00000, then L2 gets direct access to L1's APIC. Since this vmcs12 configuration is something that KVM cannot faithfully emulate, the appropriate response is to exit to userspace with KVM_INTERNAL_ERROR_EMULATION. Fixes: fe3ef05c7572 ("KVM: nVMX: Prepare vmcs02 from vmcs01 and vmcs12") Reported-by: Dan Cross Signed-off-by: Jim Mattson Reviewed-by: Peter Shier Reviewed-by: Sean Christopherson Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/vmx/nested.c | 64 ++++++++++++++++++--------------- arch/x86/kvm/vmx/nested.h | 13 ++++++- arch/x86/kvm/x86.c | 8 +++-- 4 files changed, 55 insertions(+), 32 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 50eb430b0ad8..24d6598dea29 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1189,7 +1189,7 @@ struct kvm_x86_ops { int (*set_nested_state)(struct kvm_vcpu *vcpu, struct kvm_nested_state __user *user_kvm_nested_state, struct kvm_nested_state *kvm_state); - void (*get_vmcs12_pages)(struct kvm_vcpu *vcpu); + bool (*get_vmcs12_pages)(struct kvm_vcpu *vcpu); int (*smi_allowed)(struct kvm_vcpu *vcpu); int (*pre_enter_smm)(struct kvm_vcpu *vcpu, char *smstate); diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index e76eb4f07f6c..0e7c9301fe86 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2917,7 +2917,7 @@ static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu) static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12); -static void nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) +static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) { struct vmcs12 *vmcs12 = get_vmcs12(vcpu); struct vcpu_vmx *vmx = to_vmx(vcpu); @@ -2937,19 +2937,18 @@ static void nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) vmx->nested.apic_access_page = NULL; } page = kvm_vcpu_gpa_to_page(vcpu, vmcs12->apic_access_addr); - /* - * If translation failed, no matter: This feature asks - * to exit when accessing the given address, and if it - * can never be accessed, this feature won't do - * anything anyway. - */ if (!is_error_page(page)) { vmx->nested.apic_access_page = page; hpa = page_to_phys(vmx->nested.apic_access_page); vmcs_write64(APIC_ACCESS_ADDR, hpa); } else { - secondary_exec_controls_clearbit(vmx, - SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES); + pr_debug_ratelimited("%s: no backing 'struct page' for APIC-access address in vmcs12\n", + __func__); + vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; + vcpu->run->internal.suberror = + KVM_INTERNAL_ERROR_EMULATION; + vcpu->run->internal.ndata = 0; + return false; } } @@ -2994,6 +2993,7 @@ static void nested_get_vmcs12_pages(struct kvm_vcpu *vcpu) exec_controls_setbit(vmx, CPU_BASED_USE_MSR_BITMAPS); else exec_controls_clearbit(vmx, CPU_BASED_USE_MSR_BITMAPS); + return true; } /* @@ -3032,13 +3032,15 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, /* * If from_vmentry is false, this is being called from state restore (either RSM * or KVM_SET_NESTED_STATE). Otherwise it's called from vmlaunch/vmresume. -+ * -+ * Returns: -+ * 0 - success, i.e. proceed with actual VMEnter -+ * 1 - consistency check VMExit -+ * -1 - consistency check VMFail + * + * Returns: + * NVMX_ENTRY_SUCCESS: Entered VMX non-root mode + * NVMX_ENTRY_VMFAIL: Consistency check VMFail + * NVMX_ENTRY_VMEXIT: Consistency check VMExit + * NVMX_ENTRY_KVM_INTERNAL_ERROR: KVM internal error */ -int nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry) +enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, + bool from_vmentry) { struct vcpu_vmx *vmx = to_vmx(vcpu); struct vmcs12 *vmcs12 = get_vmcs12(vcpu); @@ -3081,11 +3083,12 @@ int nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry) prepare_vmcs02_early(vmx, vmcs12); if (from_vmentry) { - nested_get_vmcs12_pages(vcpu); + if (unlikely(!nested_get_vmcs12_pages(vcpu))) + return NVMX_VMENTRY_KVM_INTERNAL_ERROR; if (nested_vmx_check_vmentry_hw(vcpu)) { vmx_switch_vmcs(vcpu, &vmx->vmcs01); - return -1; + return NVMX_VMENTRY_VMFAIL; } if (nested_vmx_check_guest_state(vcpu, vmcs12, &exit_qual)) @@ -3149,7 +3152,7 @@ int nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry) * returned as far as L1 is concerned. It will only return (and set * the success flag) when L2 exits (see nested_vmx_vmexit()). */ - return 0; + return NVMX_VMENTRY_SUCCESS; /* * A failed consistency check that leads to a VMExit during L1's @@ -3165,14 +3168,14 @@ int nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry) vmx_switch_vmcs(vcpu, &vmx->vmcs01); if (!from_vmentry) - return 1; + return NVMX_VMENTRY_VMEXIT; load_vmcs12_host_state(vcpu, vmcs12); vmcs12->vm_exit_reason = exit_reason | VMX_EXIT_REASONS_FAILED_VMENTRY; vmcs12->exit_qualification = exit_qual; if (enable_shadow_vmcs || vmx->nested.hv_evmcs) vmx->nested.need_vmcs12_to_shadow_sync = true; - return 1; + return NVMX_VMENTRY_VMEXIT; } /* @@ -3182,9 +3185,9 @@ int nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry) static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) { struct vmcs12 *vmcs12; + enum nvmx_vmentry_status status; struct vcpu_vmx *vmx = to_vmx(vcpu); u32 interrupt_shadow = vmx_get_interrupt_shadow(vcpu); - int ret; if (!nested_vmx_check_permission(vcpu)) return 1; @@ -3244,13 +3247,9 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) * the nested entry. */ vmx->nested.nested_run_pending = 1; - ret = nested_vmx_enter_non_root_mode(vcpu, true); - vmx->nested.nested_run_pending = !ret; - if (ret > 0) - return 1; - else if (ret) - return nested_vmx_failValid(vcpu, - VMXERR_ENTRY_INVALID_CONTROL_FIELD); + status = nested_vmx_enter_non_root_mode(vcpu, true); + if (unlikely(status != NVMX_VMENTRY_SUCCESS)) + goto vmentry_failed; /* Hide L1D cache contents from the nested guest. */ vmx->vcpu.arch.l1tf_flush_l1d = true; @@ -3281,6 +3280,15 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) return kvm_vcpu_halt(vcpu); } return 1; + +vmentry_failed: + vmx->nested.nested_run_pending = 0; + if (status == NVMX_VMENTRY_KVM_INTERNAL_ERROR) + return 0; + if (status == NVMX_VMENTRY_VMEXIT) + return 1; + WARN_ON_ONCE(status != NVMX_VMENTRY_VMFAIL); + return nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD); } /* diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h index 187d39bf0bf1..6280f33e5fa6 100644 --- a/arch/x86/kvm/vmx/nested.h +++ b/arch/x86/kvm/vmx/nested.h @@ -6,6 +6,16 @@ #include "vmcs12.h" #include "vmx.h" +/* + * Status returned by nested_vmx_enter_non_root_mode(): + */ +enum nvmx_vmentry_status { + NVMX_VMENTRY_SUCCESS, /* Entered VMX non-root mode */ + NVMX_VMENTRY_VMFAIL, /* Consistency check VMFail */ + NVMX_VMENTRY_VMEXIT, /* Consistency check VMExit */ + NVMX_VMENTRY_KVM_INTERNAL_ERROR,/* KVM internal error */ +}; + void vmx_leave_nested(struct kvm_vcpu *vcpu); void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps, bool apicv); @@ -13,7 +23,8 @@ void nested_vmx_hardware_unsetup(void); __init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *)); void nested_vmx_vcpu_setup(void); void nested_vmx_free_vcpu(struct kvm_vcpu *vcpu); -int nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry); +enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, + bool from_vmentry); bool nested_vmx_exit_reflected(struct kvm_vcpu *vcpu, u32 exit_reason); void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, u32 exit_intr_info, unsigned long exit_qualification); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 5863c38108d9..ff395f812719 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7938,8 +7938,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) bool req_immediate_exit = false; if (kvm_request_pending(vcpu)) { - if (kvm_check_request(KVM_REQ_GET_VMCS12_PAGES, vcpu)) - kvm_x86_ops->get_vmcs12_pages(vcpu); + if (kvm_check_request(KVM_REQ_GET_VMCS12_PAGES, vcpu)) { + if (unlikely(!kvm_x86_ops->get_vmcs12_pages(vcpu))) { + r = 0; + goto out; + } + } if (kvm_check_request(KVM_REQ_MMU_RELOAD, vcpu)) kvm_mmu_unload(vcpu); if (kvm_check_request(KVM_REQ_MIGRATE_TIMER, vcpu)) -- GitLab From a9018adfde809d44e71189b984fa61cc89682b5e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 11 Oct 2019 16:34:19 +0300 Subject: [PATCH 594/993] RDMA/uverbs: Prevent potential underflow The issue is in drivers/infiniband/core/uverbs_std_types_cq.c in the UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE) function. We check that: if (attr.comp_vector >= attrs->ufile->device->num_comp_vectors) { But we don't check if "attr.comp_vector" is negative. It could potentially lead to an array underflow. My concern would be where cq->vector is used in the create_cq() function from the cxgb4 driver. And really "attr.comp_vector" is appears as a u32 to user space so that's the right type to use. Fixes: 9ee79fce3642 ("IB/core: Add completion queue (cq) object actions") Link: https://lore.kernel.org/r/20191011133419.GA22905@mwanda Signed-off-by: Dan Carpenter Reviewed-by: Jason Gunthorpe Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/uverbs.h | 2 +- include/rdma/ib_verbs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 1e5aeb39f774..63f7f7db5902 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h @@ -98,7 +98,7 @@ ib_uverbs_init_udata_buf_or_null(struct ib_udata *udata, struct ib_uverbs_device { atomic_t refcount; - int num_comp_vectors; + u32 num_comp_vectors; struct completion comp; struct device dev; /* First group for device attributes, NULL terminated array */ diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 6a47ba85c54c..e7e733add99f 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -366,7 +366,7 @@ struct ib_tm_caps { struct ib_cq_init_attr { unsigned int cqe; - int comp_vector; + u32 comp_vector; u32 flags; }; -- GitLab From cd7455f1013ef96d5cbf5c05d2b7c06f273810a6 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Tue, 22 Oct 2019 15:57:23 +0200 Subject: [PATCH 595/993] bpf: Fix use after free in subprog's jited symbol removal syzkaller managed to trigger the following crash: [...] BUG: unable to handle page fault for address: ffffc90001923030 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD aa551067 P4D aa551067 PUD aa552067 PMD a572b067 PTE 80000000a1173163 Oops: 0000 [#1] PREEMPT SMP KASAN CPU: 0 PID: 7982 Comm: syz-executor912 Not tainted 5.4.0-rc3+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:bpf_jit_binary_hdr include/linux/filter.h:787 [inline] RIP: 0010:bpf_get_prog_addr_region kernel/bpf/core.c:531 [inline] RIP: 0010:bpf_tree_comp kernel/bpf/core.c:600 [inline] RIP: 0010:__lt_find include/linux/rbtree_latch.h:115 [inline] RIP: 0010:latch_tree_find include/linux/rbtree_latch.h:208 [inline] RIP: 0010:bpf_prog_kallsyms_find kernel/bpf/core.c:674 [inline] RIP: 0010:is_bpf_text_address+0x184/0x3b0 kernel/bpf/core.c:709 [...] Call Trace: kernel_text_address kernel/extable.c:147 [inline] __kernel_text_address+0x9a/0x110 kernel/extable.c:102 unwind_get_return_address+0x4c/0x90 arch/x86/kernel/unwind_frame.c:19 arch_stack_walk+0x98/0xe0 arch/x86/kernel/stacktrace.c:26 stack_trace_save+0xb6/0x150 kernel/stacktrace.c:123 save_stack mm/kasan/common.c:69 [inline] set_track mm/kasan/common.c:77 [inline] __kasan_kmalloc+0x11c/0x1b0 mm/kasan/common.c:510 kasan_slab_alloc+0xf/0x20 mm/kasan/common.c:518 slab_post_alloc_hook mm/slab.h:584 [inline] slab_alloc mm/slab.c:3319 [inline] kmem_cache_alloc+0x1f5/0x2e0 mm/slab.c:3483 getname_flags+0xba/0x640 fs/namei.c:138 getname+0x19/0x20 fs/namei.c:209 do_sys_open+0x261/0x560 fs/open.c:1091 __do_sys_open fs/open.c:1115 [inline] __se_sys_open fs/open.c:1110 [inline] __x64_sys_open+0x87/0x90 fs/open.c:1110 do_syscall_64+0xf7/0x1c0 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe [...] After further debugging it turns out that we walk kallsyms while in parallel we tear down a BPF program which contains subprograms that have been JITed though the program itself has not been fully exposed and is eventually bailing out with error. The bpf_prog_kallsyms_del_subprogs() in bpf_prog_load()'s error path removes the symbols, however, bpf_prog_free() tears down the JIT memory too early via scheduled work. Instead, it needs to properly respect RCU grace period as the kallsyms walk for BPF is under RCU. Fix it by refactoring __bpf_prog_put()'s tear down and reuse it in our error path where we defer final destruction when we have subprogs in the program. Fixes: 7d1982b4e335 ("bpf: fix panic in prog load calls cleanup") Fixes: 1c2a088a6626 ("bpf: x64: add JIT support for multi-function programs") Reported-by: syzbot+710043c5d1d5b5013bc7@syzkaller.appspotmail.com Signed-off-by: Daniel Borkmann Signed-off-by: Alexei Starovoitov Tested-by: syzbot+710043c5d1d5b5013bc7@syzkaller.appspotmail.com Link: https://lore.kernel.org/bpf/55f6367324c2d7e9583fa9ccf5385dcbba0d7a6e.1571752452.git.daniel@iogearbox.net --- include/linux/filter.h | 1 - kernel/bpf/core.c | 2 +- kernel/bpf/syscall.c | 31 ++++++++++++++++++++----------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index 2ce57645f3cd..0367a75f873b 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -1099,7 +1099,6 @@ static inline void bpf_get_prog_name(const struct bpf_prog *prog, char *sym) #endif /* CONFIG_BPF_JIT */ -void bpf_prog_kallsyms_del_subprogs(struct bpf_prog *fp); void bpf_prog_kallsyms_del_all(struct bpf_prog *fp); #define BPF_ANC BIT(15) diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 66088a9e9b9e..ef0e1e3e66f4 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -502,7 +502,7 @@ int bpf_remove_insns(struct bpf_prog *prog, u32 off, u32 cnt) return WARN_ON_ONCE(bpf_adj_branches(prog, off, off + cnt, off, false)); } -void bpf_prog_kallsyms_del_subprogs(struct bpf_prog *fp) +static void bpf_prog_kallsyms_del_subprogs(struct bpf_prog *fp) { int i; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 82eabd4e38ad..bcfc362de4f2 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1332,18 +1332,26 @@ static void __bpf_prog_put_rcu(struct rcu_head *rcu) bpf_prog_free(aux->prog); } +static void __bpf_prog_put_noref(struct bpf_prog *prog, bool deferred) +{ + bpf_prog_kallsyms_del_all(prog); + btf_put(prog->aux->btf); + kvfree(prog->aux->func_info); + bpf_prog_free_linfo(prog); + + if (deferred) + call_rcu(&prog->aux->rcu, __bpf_prog_put_rcu); + else + __bpf_prog_put_rcu(&prog->aux->rcu); +} + static void __bpf_prog_put(struct bpf_prog *prog, bool do_idr_lock) { if (atomic_dec_and_test(&prog->aux->refcnt)) { perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_UNLOAD, 0); /* bpf_prog_free_id() must be called first */ bpf_prog_free_id(prog, do_idr_lock); - bpf_prog_kallsyms_del_all(prog); - btf_put(prog->aux->btf); - kvfree(prog->aux->func_info); - bpf_prog_free_linfo(prog); - - call_rcu(&prog->aux->rcu, __bpf_prog_put_rcu); + __bpf_prog_put_noref(prog, true); } } @@ -1741,11 +1749,12 @@ static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr) return err; free_used_maps: - bpf_prog_free_linfo(prog); - kvfree(prog->aux->func_info); - btf_put(prog->aux->btf); - bpf_prog_kallsyms_del_subprogs(prog); - free_used_maps(prog->aux); + /* In case we have subprogs, we need to wait for a grace + * period before we can tear down JIT memory since symbols + * are already exposed under kallsyms. + */ + __bpf_prog_put_noref(prog, prog->aux->func_cnt); + return err; free_prog: bpf_prog_uncharge_memlock(prog); free_prog_sec: -- GitLab From 011c7289de619d76f82b0d9e9fec3f59d2fe57f7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 18 Sep 2019 21:55:11 +0200 Subject: [PATCH 596/993] dynamic_debug: provide dynamic_hex_dump stub The ionic driver started using dymamic_hex_dump(), but that is not always defined: drivers/net/ethernet/pensando/ionic/ionic_main.c:229:2: error: implicit declaration of function 'dynamic_hex_dump' [-Werror,-Wimplicit-function-declaration] Add a dummy implementation to use when CONFIG_DYNAMIC_DEBUG is disabled, printing nothing. Fixes: 938962d55229 ("ionic: Add adminq action") Signed-off-by: Arnd Bergmann Acked-by: Shannon Nelson Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 2 ++ drivers/net/ethernet/pensando/ionic/ionic_main.c | 2 ++ include/linux/dynamic_debug.h | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index 72107a0627a9..20faa8d24c9f 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright(c) 2017 - 2019 Pensando Systems, Inc */ +#include +#include #include #include #include diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c index 15e432386b35..aab311413412 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_main.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright(c) 2017 - 2019 Pensando Systems, Inc */ +#include +#include #include #include #include diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index 6c809440f319..4cf02ecd67de 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -204,6 +204,12 @@ static inline int ddebug_dyndbg_module_param_cb(char *param, char *val, do { if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0) #define dynamic_dev_dbg(dev, fmt, ...) \ do { if (0) dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); } while (0) +#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \ + groupsize, buf, len, ascii) \ + do { if (0) \ + print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, \ + rowsize, groupsize, buf, len, ascii); \ + } while (0) #endif #endif -- GitLab From 34c15202896d11e3974788daf9005a84ec45f7a2 Mon Sep 17 00:00:00 2001 From: yuqi jin Date: Mon, 21 Oct 2019 11:27:34 +0800 Subject: [PATCH 597/993] net: stmmac: Fix the problem of tso_xmit When the address width of DMA is greater than 32, the packet header occupies a BD descriptor. The starting address of the data should be added to the header length. Fixes: a993db88d17d ("net: stmmac: Enable support for > 32 Bits addressing in XGMAC") Cc: Eric Dumazet Cc: Giuseppe Cavallaro Cc: Alexandre Torgue Cc: Jose Abreu Cc: "David S. Miller" Cc: Maxime Coquelin Signed-off-by: yuqi jin Signed-off-by: Shaokun Zhang Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 3dfd04e0506a..4e9c848c67cc 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2995,6 +2995,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) } else { stmmac_set_desc_addr(priv, first, des); tmp_pay_len = pay_len; + des += proto_hdr_len; } stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue); -- GitLab From c329230ce886f449a6e559b636096b75ab00d18a Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Mon, 21 Oct 2019 01:34:25 -0400 Subject: [PATCH 598/993] bnxt_en: Fix the size of devlink MSIX parameters. The current code that rounds up the NVRAM parameter bit size to the next byte size for the devlink parameter is not always correct. The MSIX devlink parameters are 4 bytes and we don't get the correct size using this method. Fix it by adding a new dl_num_bytes member to the bnxt_dl_nvm_param structure which statically provides bytesize information according to the devlink parameter type definition. Fixes: 782a624d00fa ("bnxt_en: Add bnxt_en initial port params table and register it") Cc: Jiri Pirko Signed-off-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: Jakub Kicinski --- .../net/ethernet/broadcom/bnxt/bnxt_devlink.c | 28 +++++++++---------- .../net/ethernet/broadcom/bnxt/bnxt_devlink.h | 3 +- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c index e664392dccc0..68f74f52fe88 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c @@ -215,15 +215,15 @@ enum bnxt_dl_param_id { static const struct bnxt_dl_nvm_param nvm_params[] = { {DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV, NVM_OFF_ENABLE_SRIOV, - BNXT_NVM_SHARED_CFG, 1}, + BNXT_NVM_SHARED_CFG, 1, 1}, {DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI, NVM_OFF_IGNORE_ARI, - BNXT_NVM_SHARED_CFG, 1}, + BNXT_NVM_SHARED_CFG, 1, 1}, {DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX, - NVM_OFF_MSIX_VEC_PER_PF_MAX, BNXT_NVM_SHARED_CFG, 10}, + NVM_OFF_MSIX_VEC_PER_PF_MAX, BNXT_NVM_SHARED_CFG, 10, 4}, {DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN, - NVM_OFF_MSIX_VEC_PER_PF_MIN, BNXT_NVM_SHARED_CFG, 7}, + NVM_OFF_MSIX_VEC_PER_PF_MIN, BNXT_NVM_SHARED_CFG, 7, 4}, {BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK, NVM_OFF_DIS_GRE_VER_CHECK, - BNXT_NVM_SHARED_CFG, 1}, + BNXT_NVM_SHARED_CFG, 1, 1}, }; static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg, @@ -232,8 +232,8 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg, struct hwrm_nvm_get_variable_input *req = msg; void *data_addr = NULL, *buf = NULL; struct bnxt_dl_nvm_param nvm_param; - int bytesize, idx = 0, rc, i; dma_addr_t data_dma_addr; + int idx = 0, rc, i; /* Get/Set NVM CFG parameter is supported only on PFs */ if (BNXT_VF(bp)) @@ -254,10 +254,9 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg, else if (nvm_param.dir_type == BNXT_NVM_FUNC_CFG) idx = bp->pf.fw_fid - BNXT_FIRST_PF_FID; - bytesize = roundup(nvm_param.num_bits, BITS_PER_BYTE) / BITS_PER_BYTE; - switch (bytesize) { + switch (nvm_param.dl_num_bytes) { case 1: - if (nvm_param.num_bits == 1) + if (nvm_param.nvm_num_bits == 1) buf = &val->vbool; else buf = &val->vu8; @@ -272,29 +271,30 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg, return -EFAULT; } - data_addr = dma_alloc_coherent(&bp->pdev->dev, bytesize, + data_addr = dma_alloc_coherent(&bp->pdev->dev, nvm_param.dl_num_bytes, &data_dma_addr, GFP_KERNEL); if (!data_addr) return -ENOMEM; req->dest_data_addr = cpu_to_le64(data_dma_addr); - req->data_len = cpu_to_le16(nvm_param.num_bits); + req->data_len = cpu_to_le16(nvm_param.nvm_num_bits); req->option_num = cpu_to_le16(nvm_param.offset); req->index_0 = cpu_to_le16(idx); if (idx) req->dimensions = cpu_to_le16(1); if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE)) { - memcpy(data_addr, buf, bytesize); + memcpy(data_addr, buf, nvm_param.dl_num_bytes); rc = hwrm_send_message(bp, msg, msg_len, HWRM_CMD_TIMEOUT); } else { rc = hwrm_send_message_silent(bp, msg, msg_len, HWRM_CMD_TIMEOUT); } if (!rc && req->req_type == cpu_to_le16(HWRM_NVM_GET_VARIABLE)) - memcpy(buf, data_addr, bytesize); + memcpy(buf, data_addr, nvm_param.dl_num_bytes); - dma_free_coherent(&bp->pdev->dev, bytesize, data_addr, data_dma_addr); + dma_free_coherent(&bp->pdev->dev, nvm_param.dl_num_bytes, data_addr, + data_dma_addr); if (rc == -EACCES) netdev_err(bp->dev, "PF does not have admin privileges to modify NVM config\n"); return rc; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h index b97e0baeb42d..2f4fd0a7d04b 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h @@ -52,7 +52,8 @@ struct bnxt_dl_nvm_param { u16 id; u16 offset; u16 dir_type; - u16 num_bits; + u16 nvm_num_bits; + u8 dl_num_bytes; }; void bnxt_devlink_health_report(struct bnxt *bp, unsigned long event); -- GitLab From 83a46a82b96c1928ad82958752523fb0c7d9fcce Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Mon, 21 Oct 2019 01:34:26 -0400 Subject: [PATCH 599/993] bnxt_en: Fix devlink NVRAM related byte order related issues. The current code does not do endian swapping between the devlink parameter and the internal NVRAM representation. Define a union to represent the little endian NVRAM data and add 2 helper functions to copy to and from the NVRAM data with the proper byte swapping. Fixes: 782a624d00fa ("bnxt_en: Add bnxt_en initial port params table and register it") Cc: Jiri Pirko Reviewed-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: Jakub Kicinski --- .../net/ethernet/broadcom/bnxt/bnxt_devlink.c | 81 ++++++++++++------- 1 file changed, 54 insertions(+), 27 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c index 68f74f52fe88..bd4b9f31614e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c @@ -226,12 +226,55 @@ static const struct bnxt_dl_nvm_param nvm_params[] = { BNXT_NVM_SHARED_CFG, 1, 1}, }; +union bnxt_nvm_data { + u8 val8; + __le32 val32; +}; + +static void bnxt_copy_to_nvm_data(union bnxt_nvm_data *dst, + union devlink_param_value *src, + int nvm_num_bits, int dl_num_bytes) +{ + u32 val32 = 0; + + if (nvm_num_bits == 1) { + dst->val8 = src->vbool; + return; + } + if (dl_num_bytes == 4) + val32 = src->vu32; + else if (dl_num_bytes == 2) + val32 = (u32)src->vu16; + else if (dl_num_bytes == 1) + val32 = (u32)src->vu8; + dst->val32 = cpu_to_le32(val32); +} + +static void bnxt_copy_from_nvm_data(union devlink_param_value *dst, + union bnxt_nvm_data *src, + int nvm_num_bits, int dl_num_bytes) +{ + u32 val32; + + if (nvm_num_bits == 1) { + dst->vbool = src->val8; + return; + } + val32 = le32_to_cpu(src->val32); + if (dl_num_bytes == 4) + dst->vu32 = val32; + else if (dl_num_bytes == 2) + dst->vu16 = (u16)val32; + else if (dl_num_bytes == 1) + dst->vu8 = (u8)val32; +} + static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg, int msg_len, union devlink_param_value *val) { struct hwrm_nvm_get_variable_input *req = msg; - void *data_addr = NULL, *buf = NULL; struct bnxt_dl_nvm_param nvm_param; + union bnxt_nvm_data *data; dma_addr_t data_dma_addr; int idx = 0, rc, i; @@ -254,26 +297,9 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg, else if (nvm_param.dir_type == BNXT_NVM_FUNC_CFG) idx = bp->pf.fw_fid - BNXT_FIRST_PF_FID; - switch (nvm_param.dl_num_bytes) { - case 1: - if (nvm_param.nvm_num_bits == 1) - buf = &val->vbool; - else - buf = &val->vu8; - break; - case 2: - buf = &val->vu16; - break; - case 4: - buf = &val->vu32; - break; - default: - return -EFAULT; - } - - data_addr = dma_alloc_coherent(&bp->pdev->dev, nvm_param.dl_num_bytes, - &data_dma_addr, GFP_KERNEL); - if (!data_addr) + data = dma_alloc_coherent(&bp->pdev->dev, sizeof(*data), + &data_dma_addr, GFP_KERNEL); + if (!data) return -ENOMEM; req->dest_data_addr = cpu_to_le64(data_dma_addr); @@ -284,17 +310,18 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg, req->dimensions = cpu_to_le16(1); if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE)) { - memcpy(data_addr, buf, nvm_param.dl_num_bytes); + bnxt_copy_to_nvm_data(data, val, nvm_param.nvm_num_bits, + nvm_param.dl_num_bytes); rc = hwrm_send_message(bp, msg, msg_len, HWRM_CMD_TIMEOUT); } else { rc = hwrm_send_message_silent(bp, msg, msg_len, HWRM_CMD_TIMEOUT); + if (!rc) + bnxt_copy_from_nvm_data(val, data, + nvm_param.nvm_num_bits, + nvm_param.dl_num_bytes); } - if (!rc && req->req_type == cpu_to_le16(HWRM_NVM_GET_VARIABLE)) - memcpy(buf, data_addr, nvm_param.dl_num_bytes); - - dma_free_coherent(&bp->pdev->dev, nvm_param.dl_num_bytes, data_addr, - data_dma_addr); + dma_free_coherent(&bp->pdev->dev, sizeof(*data), data, data_dma_addr); if (rc == -EACCES) netdev_err(bp->dev, "PF does not have admin privileges to modify NVM config\n"); return rc; -- GitLab From c6a9e7aa2e8b15402022a15625284069d4fd6df0 Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Mon, 21 Oct 2019 01:34:27 -0400 Subject: [PATCH 600/993] bnxt_en: Adjust the time to wait before polling firmware readiness. When firmware indicates that driver needs to invoke firmware reset which is common for both error recovery and live firmware reset path, driver needs a different time to wait before polling for firmware readiness. Modify the wait time to fw_reset_min_dsecs, which is initialised to correct timeout for error recovery and firmware reset. Fixes: 4037eb715680 ("bnxt_en: Add a new BNXT_FW_RESET_STATE_POLL_FW_DOWN state.") Signed-off-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index b4a8cf620a0c..84926184bed2 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -10669,14 +10669,11 @@ static void bnxt_fw_reset_task(struct work_struct *work) bp->fw_reset_state = BNXT_FW_RESET_STATE_RESET_FW; } /* fall through */ - case BNXT_FW_RESET_STATE_RESET_FW: { - u32 wait_dsecs = bp->fw_health->post_reset_wait_dsecs; - + case BNXT_FW_RESET_STATE_RESET_FW: bnxt_reset_all(bp); bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV; - bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10); + bnxt_queue_fw_reset_work(bp, bp->fw_reset_min_dsecs * HZ / 10); return; - } case BNXT_FW_RESET_STATE_ENABLE_DEV: if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) && bp->fw_health) { -- GitLab From f255ed1c4e4c5ed8171b6e81dce1297df1f1b60c Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Mon, 21 Oct 2019 01:34:28 -0400 Subject: [PATCH 601/993] bnxt_en: Minor formatting changes in FW devlink_health_reporter Minor formatting changes to diagnose cb for FW devlink health reporter. Suggested-by: Jiri Pirko Cc: Jiri Pirko Signed-off-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: Jakub Kicinski --- .../net/ethernet/broadcom/bnxt/bnxt_devlink.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c index bd4b9f31614e..7151244f8c7d 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c @@ -29,25 +29,20 @@ static int bnxt_fw_reporter_diagnose(struct devlink_health_reporter *reporter, val = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG); health_status = val & 0xffff; - if (health_status == BNXT_FW_STATUS_HEALTHY) { - rc = devlink_fmsg_string_pair_put(fmsg, "FW status", - "Healthy;"); - if (rc) - return rc; - } else if (health_status < BNXT_FW_STATUS_HEALTHY) { - rc = devlink_fmsg_string_pair_put(fmsg, "FW status", - "Not yet completed initialization;"); + if (health_status < BNXT_FW_STATUS_HEALTHY) { + rc = devlink_fmsg_string_pair_put(fmsg, "Description", + "Not yet completed initialization"); if (rc) return rc; } else if (health_status > BNXT_FW_STATUS_HEALTHY) { - rc = devlink_fmsg_string_pair_put(fmsg, "FW status", - "Encountered fatal error and cannot recover;"); + rc = devlink_fmsg_string_pair_put(fmsg, "Description", + "Encountered fatal error and cannot recover"); if (rc) return rc; } if (val >> 16) { - rc = devlink_fmsg_u32_pair_put(fmsg, "Error", val >> 16); + rc = devlink_fmsg_u32_pair_put(fmsg, "Error code", val >> 16); if (rc) return rc; } -- GitLab From f6824308c4be25ba024ab942a6135aa0356acaea Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Mon, 21 Oct 2019 01:34:29 -0400 Subject: [PATCH 602/993] bnxt_en: Avoid disabling pci device in bnxt_remove_one() for already disabled device. With the recently added error recovery logic, the device may already be disabled if the firmware recovery is unsuccessful. In bnxt_remove_one(), check that the device is still enabled first before calling pci_disable_device(). Fixes: 3bc7d4a352ef ("bnxt_en: Add BNXT_STATE_IN_FW_RESET state.") Signed-off-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 84926184bed2..04ec909e06df 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -10382,7 +10382,8 @@ static void bnxt_cleanup_pci(struct bnxt *bp) { bnxt_unmap_bars(bp, bp->pdev); pci_release_regions(bp->pdev); - pci_disable_device(bp->pdev); + if (pci_is_enabled(bp->pdev)) + pci_disable_device(bp->pdev); } static void bnxt_init_dflt_coal(struct bnxt *bp) -- GitLab From d665c1281bc89ac85b8b0c058c22a3f94640a1d6 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Tue, 22 Oct 2019 07:57:42 +0800 Subject: [PATCH 603/993] net: sched: taprio: fix -Wmissing-prototypes warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We get one warnings when build kernel W=1: net/sched/sch_taprio.c:1155:6: warning: no previous prototype for ‘taprio_offload_config_changed’ [-Wmissing-prototypes] Make the function static to fix this. Fixes: 9c66d1564676 ("taprio: Add support for hardware offloading") Signed-off-by: Yi Wang Acked-by: Vinicius Costa Gomes Signed-off-by: Jakub Kicinski --- net/sched/sch_taprio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 6719a65169d4..2121187229cd 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -1152,7 +1152,7 @@ EXPORT_SYMBOL_GPL(taprio_offload_free); * offload state (PENDING, ACTIVE, INACTIVE) so it can be visible in dump(). * This is left as TODO. */ -void taprio_offload_config_changed(struct taprio_sched *q) +static void taprio_offload_config_changed(struct taprio_sched *q) { struct sched_gate_list *oper, *admin; -- GitLab From b5b9181c2403025b2c7ae7ea44333fd8fe6dbb54 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 21 Oct 2019 19:02:43 -0600 Subject: [PATCH 604/993] selftests: Make l2tp.sh executable Kernel test robot reported that the l2tp.sh test script failed: # selftests: net: l2tp.sh # Warning: file l2tp.sh is not executable, correct this. Set executable bits. Fixes: e858ef1cd4bc ("selftests: Add l2tp tests") Reported-by: kernel test robot Signed-off-by: David Ahern Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/l2tp.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tools/testing/selftests/net/l2tp.sh diff --git a/tools/testing/selftests/net/l2tp.sh b/tools/testing/selftests/net/l2tp.sh old mode 100644 new mode 100755 -- GitLab From 9464cc37f3671ee69cb1c00662b5e1f113a96b23 Mon Sep 17 00:00:00 2001 From: Hillf Danton Date: Mon, 21 Oct 2019 12:01:57 +0200 Subject: [PATCH 605/993] net: openvswitch: free vport unless register_netdevice() succeeds syzbot found the following crash on: HEAD commit: 1e78030e Merge tag 'mmc-v5.3-rc1' of git://git.kernel.org/.. git tree: upstream console output: https://syzkaller.appspot.com/x/log.txt?x=148d3d1a600000 kernel config: https://syzkaller.appspot.com/x/.config?x=30cef20daf3e9977 dashboard link: https://syzkaller.appspot.com/bug?extid=13210896153522fe1ee5 compiler: gcc (GCC) 9.0.0 20181231 (experimental) syz repro: https://syzkaller.appspot.com/x/repro.syz?x=136aa8c4600000 C reproducer: https://syzkaller.appspot.com/x/repro.c?x=109ba792600000 ===================================================================== BUG: memory leak unreferenced object 0xffff8881207e4100 (size 128): comm "syz-executor032", pid 7014, jiffies 4294944027 (age 13.830s) hex dump (first 32 bytes): 00 70 16 18 81 88 ff ff 80 af 8c 22 81 88 ff ff .p.........".... 00 b6 23 17 81 88 ff ff 00 00 00 00 00 00 00 00 ..#............. backtrace: [<000000000eb78212>] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline] [<000000000eb78212>] slab_post_alloc_hook mm/slab.h:522 [inline] [<000000000eb78212>] slab_alloc mm/slab.c:3319 [inline] [<000000000eb78212>] kmem_cache_alloc_trace+0x145/0x2c0 mm/slab.c:3548 [<00000000006ea6c6>] kmalloc include/linux/slab.h:552 [inline] [<00000000006ea6c6>] kzalloc include/linux/slab.h:748 [inline] [<00000000006ea6c6>] ovs_vport_alloc+0x37/0xf0 net/openvswitch/vport.c:130 [<00000000f9a04a7d>] internal_dev_create+0x24/0x1d0 net/openvswitch/vport-internal_dev.c:164 [<0000000056ee7c13>] ovs_vport_add+0x81/0x190 net/openvswitch/vport.c:199 [<000000005434efc7>] new_vport+0x19/0x80 net/openvswitch/datapath.c:194 [<00000000b7b253f1>] ovs_dp_cmd_new+0x22f/0x410 net/openvswitch/datapath.c:1614 [<00000000e0988518>] genl_family_rcv_msg+0x2ab/0x5b0 net/netlink/genetlink.c:629 [<00000000d0cc9347>] genl_rcv_msg+0x54/0x9c net/netlink/genetlink.c:654 [<000000006694b647>] netlink_rcv_skb+0x61/0x170 net/netlink/af_netlink.c:2477 [<0000000088381f37>] genl_rcv+0x29/0x40 net/netlink/genetlink.c:665 [<00000000dad42a47>] netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline] [<00000000dad42a47>] netlink_unicast+0x1ec/0x2d0 net/netlink/af_netlink.c:1328 [<0000000067e6b079>] netlink_sendmsg+0x270/0x480 net/netlink/af_netlink.c:1917 [<00000000aab08a47>] sock_sendmsg_nosec net/socket.c:637 [inline] [<00000000aab08a47>] sock_sendmsg+0x54/0x70 net/socket.c:657 [<000000004cb7c11d>] ___sys_sendmsg+0x393/0x3c0 net/socket.c:2311 [<00000000c4901c63>] __sys_sendmsg+0x80/0xf0 net/socket.c:2356 [<00000000c10abb2d>] __do_sys_sendmsg net/socket.c:2365 [inline] [<00000000c10abb2d>] __se_sys_sendmsg net/socket.c:2363 [inline] [<00000000c10abb2d>] __x64_sys_sendmsg+0x23/0x30 net/socket.c:2363 BUG: memory leak unreferenced object 0xffff88811723b600 (size 64): comm "syz-executor032", pid 7014, jiffies 4294944027 (age 13.830s) hex dump (first 32 bytes): 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 02 00 00 00 05 35 82 c1 .............5.. backtrace: [<00000000352f46d8>] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline] [<00000000352f46d8>] slab_post_alloc_hook mm/slab.h:522 [inline] [<00000000352f46d8>] slab_alloc mm/slab.c:3319 [inline] [<00000000352f46d8>] __do_kmalloc mm/slab.c:3653 [inline] [<00000000352f46d8>] __kmalloc+0x169/0x300 mm/slab.c:3664 [<000000008e48f3d1>] kmalloc include/linux/slab.h:557 [inline] [<000000008e48f3d1>] ovs_vport_set_upcall_portids+0x54/0xd0 net/openvswitch/vport.c:343 [<00000000541e4f4a>] ovs_vport_alloc+0x7f/0xf0 net/openvswitch/vport.c:139 [<00000000f9a04a7d>] internal_dev_create+0x24/0x1d0 net/openvswitch/vport-internal_dev.c:164 [<0000000056ee7c13>] ovs_vport_add+0x81/0x190 net/openvswitch/vport.c:199 [<000000005434efc7>] new_vport+0x19/0x80 net/openvswitch/datapath.c:194 [<00000000b7b253f1>] ovs_dp_cmd_new+0x22f/0x410 net/openvswitch/datapath.c:1614 [<00000000e0988518>] genl_family_rcv_msg+0x2ab/0x5b0 net/netlink/genetlink.c:629 [<00000000d0cc9347>] genl_rcv_msg+0x54/0x9c net/netlink/genetlink.c:654 [<000000006694b647>] netlink_rcv_skb+0x61/0x170 net/netlink/af_netlink.c:2477 [<0000000088381f37>] genl_rcv+0x29/0x40 net/netlink/genetlink.c:665 [<00000000dad42a47>] netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline] [<00000000dad42a47>] netlink_unicast+0x1ec/0x2d0 net/netlink/af_netlink.c:1328 [<0000000067e6b079>] netlink_sendmsg+0x270/0x480 net/netlink/af_netlink.c:1917 [<00000000aab08a47>] sock_sendmsg_nosec net/socket.c:637 [inline] [<00000000aab08a47>] sock_sendmsg+0x54/0x70 net/socket.c:657 [<000000004cb7c11d>] ___sys_sendmsg+0x393/0x3c0 net/socket.c:2311 [<00000000c4901c63>] __sys_sendmsg+0x80/0xf0 net/socket.c:2356 BUG: memory leak unreferenced object 0xffff8881228ca500 (size 128): comm "syz-executor032", pid 7015, jiffies 4294944622 (age 7.880s) hex dump (first 32 bytes): 00 f0 27 18 81 88 ff ff 80 ac 8c 22 81 88 ff ff ..'........".... 40 b7 23 17 81 88 ff ff 00 00 00 00 00 00 00 00 @.#............. backtrace: [<000000000eb78212>] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline] [<000000000eb78212>] slab_post_alloc_hook mm/slab.h:522 [inline] [<000000000eb78212>] slab_alloc mm/slab.c:3319 [inline] [<000000000eb78212>] kmem_cache_alloc_trace+0x145/0x2c0 mm/slab.c:3548 [<00000000006ea6c6>] kmalloc include/linux/slab.h:552 [inline] [<00000000006ea6c6>] kzalloc include/linux/slab.h:748 [inline] [<00000000006ea6c6>] ovs_vport_alloc+0x37/0xf0 net/openvswitch/vport.c:130 [<00000000f9a04a7d>] internal_dev_create+0x24/0x1d0 net/openvswitch/vport-internal_dev.c:164 [<0000000056ee7c13>] ovs_vport_add+0x81/0x190 net/openvswitch/vport.c:199 [<000000005434efc7>] new_vport+0x19/0x80 net/openvswitch/datapath.c:194 [<00000000b7b253f1>] ovs_dp_cmd_new+0x22f/0x410 net/openvswitch/datapath.c:1614 [<00000000e0988518>] genl_family_rcv_msg+0x2ab/0x5b0 net/netlink/genetlink.c:629 [<00000000d0cc9347>] genl_rcv_msg+0x54/0x9c net/netlink/genetlink.c:654 [<000000006694b647>] netlink_rcv_skb+0x61/0x170 net/netlink/af_netlink.c:2477 [<0000000088381f37>] genl_rcv+0x29/0x40 net/netlink/genetlink.c:665 [<00000000dad42a47>] netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline] [<00000000dad42a47>] netlink_unicast+0x1ec/0x2d0 net/netlink/af_netlink.c:1328 [<0000000067e6b079>] netlink_sendmsg+0x270/0x480 net/netlink/af_netlink.c:1917 [<00000000aab08a47>] sock_sendmsg_nosec net/socket.c:637 [inline] [<00000000aab08a47>] sock_sendmsg+0x54/0x70 net/socket.c:657 [<000000004cb7c11d>] ___sys_sendmsg+0x393/0x3c0 net/socket.c:2311 [<00000000c4901c63>] __sys_sendmsg+0x80/0xf0 net/socket.c:2356 [<00000000c10abb2d>] __do_sys_sendmsg net/socket.c:2365 [inline] [<00000000c10abb2d>] __se_sys_sendmsg net/socket.c:2363 [inline] [<00000000c10abb2d>] __x64_sys_sendmsg+0x23/0x30 net/socket.c:2363 ===================================================================== The function in net core, register_netdevice(), may fail with vport's destruction callback either invoked or not. After commit 309b66970ee2 ("net: openvswitch: do not free vport if register_netdevice() is failed."), the duty to destroy vport is offloaded from the driver OTOH, which ends up in the memory leak reported. It is fixed by releasing vport unless device is registered successfully. To do that, the callback assignment is defered until device is registered. Reported-by: syzbot+13210896153522fe1ee5@syzkaller.appspotmail.com Fixes: 309b66970ee2 ("net: openvswitch: do not free vport if register_netdevice() is failed.") Cc: Taehee Yoo Cc: Greg Rose Cc: Eric Dumazet Cc: Marcelo Ricardo Leitner Cc: Ying Xue Cc: Andrey Konovalov Signed-off-by: Hillf Danton Acked-by: Pravin B Shelar [sbrivio: this was sent to dev@openvswitch.org and never made its way to netdev -- resending original patch] Signed-off-by: Stefano Brivio Reviewed-by: Greg Rose Signed-off-by: Jakub Kicinski --- net/openvswitch/vport-internal_dev.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c index 21c90d3a7ebf..58a7b8312c28 100644 --- a/net/openvswitch/vport-internal_dev.c +++ b/net/openvswitch/vport-internal_dev.c @@ -137,7 +137,7 @@ static void do_setup(struct net_device *netdev) netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_OPENVSWITCH | IFF_NO_QUEUE; netdev->needs_free_netdev = true; - netdev->priv_destructor = internal_dev_destructor; + netdev->priv_destructor = NULL; netdev->ethtool_ops = &internal_dev_ethtool_ops; netdev->rtnl_link_ops = &internal_dev_link_ops; @@ -159,7 +159,6 @@ static struct vport *internal_dev_create(const struct vport_parms *parms) struct internal_dev *internal_dev; struct net_device *dev; int err; - bool free_vport = true; vport = ovs_vport_alloc(0, &ovs_internal_vport_ops, parms); if (IS_ERR(vport)) { @@ -190,10 +189,9 @@ static struct vport *internal_dev_create(const struct vport_parms *parms) rtnl_lock(); err = register_netdevice(vport->dev); - if (err) { - free_vport = false; + if (err) goto error_unlock; - } + vport->dev->priv_destructor = internal_dev_destructor; dev_set_promiscuity(vport->dev, 1); rtnl_unlock(); @@ -207,8 +205,7 @@ static struct vport *internal_dev_create(const struct vport_parms *parms) error_free_netdev: free_netdev(dev); error_free_vport: - if (free_vport) - ovs_vport_free(vport); + ovs_vport_free(vport); error: return ERR_PTR(err); } -- GitLab From 6c5d9c2a6bedbb3c3c14253776320c0ee564f064 Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Tue, 22 Oct 2019 15:44:40 +0100 Subject: [PATCH 606/993] ipv6: include for missing declarations Include for the missing declarations of various functions. Fixes the following sparse warnings: net/ipv6/addrconf_core.c:94:5: warning: symbol 'register_inet6addr_notifier' was not declared. Should it be static? net/ipv6/addrconf_core.c:100:5: warning: symbol 'unregister_inet6addr_notifier' was not declared. Should it be static? net/ipv6/addrconf_core.c:106:5: warning: symbol 'inet6addr_notifier_call_chain' was not declared. Should it be static? net/ipv6/addrconf_core.c:112:5: warning: symbol 'register_inet6addr_validator_notifier' was not declared. Should it be static? net/ipv6/addrconf_core.c:118:5: warning: symbol 'unregister_inet6addr_validator_notifier' was not declared. Should it be static? net/ipv6/addrconf_core.c:125:5: warning: symbol 'inet6addr_validator_notifier_call_chain' was not declared. Should it be static? net/ipv6/addrconf_core.c:237:6: warning: symbol 'in6_dev_finish_destroy' was not declared. Should it be static? Signed-off-by: Ben Dooks (Codethink) Signed-off-by: Jakub Kicinski --- net/ipv6/addrconf_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c index 783f3c1466da..2fc079284ca4 100644 --- a/net/ipv6/addrconf_core.c +++ b/net/ipv6/addrconf_core.c @@ -7,6 +7,7 @@ #include #include #include +#include #include /* if ipv6 module registers this function is used by xfrm to force all -- GitLab From 0fd103ccfe6a06e40e2d9d8c91d96332cc9e1239 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Tue, 22 Oct 2019 09:21:12 +0200 Subject: [PATCH 607/993] scsi: lpfc: Honor module parameter lpfc_use_adisc The initial lpfc_desc_set_adisc implementation in commit dea3101e0a5c ("lpfc: add Emulex FC driver version 8.0.28") enabled ADISC if cfg_use_adisc && RSCN_MODE && FCP_2_DEVICE In commit 92d7f7b0cde3 ("[SCSI] lpfc: NPIV: add NPIV support on top of SLI-3") this changed to (cfg_use_adisc && RSC_MODE) || FCP_2_DEVICE and later in commit ffc954936b13 ("[SCSI] lpfc 8.3.13: FC Discovery Fixes and enhancements.") to (cfg_use_adisc && RSC_MODE) || (FCP_2_DEVICE && FCP_TARGET) A customer reports that after a devloss, an ADISC failure is logged. It turns out the ADISC flag is set even the user explicitly set lpfc_use_adisc = 0. [Sat Dec 22 22:55:58 2018] lpfc 0000:82:00.0: 2:(0):0203 Devloss timeout on WWPN 50:01:43:80:12:8e:40:20 NPort x05df00 Data: x82000000 x8 xa [Sat Dec 22 23:08:20 2018] lpfc 0000:82:00.0: 2:(0):2755 ADISC failure DID:05DF00 Status:x9/x70000 [mkp: fixed Hannes' email] Fixes: 92d7f7b0cde3 ("[SCSI] lpfc: NPIV: add NPIV support on top of SLI-3") Cc: Dick Kennedy Cc: James Smart Link: https://lore.kernel.org/r/20191022072112.132268-1-dwagner@suse.de Reviewed-by: Hannes Reinecke Reviewed-by: James Smart Signed-off-by: Daniel Wagner Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nportdisc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index f4b879d25fe9..fc6e4546d738 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -851,9 +851,9 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) if (!(vport->fc_flag & FC_PT2PT)) { /* Check config parameter use-adisc or FCP-2 */ - if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) || + if (vport->cfg_use_adisc && ((vport->fc_flag & FC_RSCN_MODE) || ((ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) && - (ndlp->nlp_type & NLP_FCP_TARGET))) { + (ndlp->nlp_type & NLP_FCP_TARGET)))) { spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_NPR_ADISC; spin_unlock_irq(shost->host_lock); -- GitLab From c2ff2a36eff60efb5e123c940115216d6bf65684 Mon Sep 17 00:00:00 2001 From: Himanshu Madhani Date: Tue, 22 Oct 2019 12:36:42 -0700 Subject: [PATCH 608/993] scsi: qla2xxx: Initialized mailbox to prevent driver load failure This patch fixes issue with Gen7 adapter in a blade environment where one of the ports will not be detected by driver. Firmware expects mailbox 11 to be set or cleared by driver for newer ISP. Following message is seen in the log file: [ 18.810892] qla2xxx [0000:d8:00.0]-1820:1: **** Failed=102 mb[0]=4005 mb[1]=37 mb[2]=20 mb[3]=8 [ 18.819596] cmd=2 **** [mkp: typos] Link: https://lore.kernel.org/r/20191022193643.7076-2-hmadhani@marvell.com Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_mbx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 1cc6913f76c4..4a1f21c11758 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -702,6 +702,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) mcp->mb[2] = LSW(risc_addr); mcp->mb[3] = 0; mcp->mb[4] = 0; + mcp->mb[11] = 0; ha->flags.using_lr_setting = 0; if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { @@ -746,7 +747,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr) if (ha->flags.exchoffld_enabled) mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD; - mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1; + mcp->out_mb |= MBX_4 | MBX_3 | MBX_2 | MBX_1 | MBX_11; mcp->in_mb |= MBX_3 | MBX_2 | MBX_1; } else { mcp->mb[1] = LSW(risc_addr); -- GitLab From 8d8b83f5be2a3bdac3695a94e6cb5e50bd114869 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Tue, 22 Oct 2019 12:36:43 -0700 Subject: [PATCH 609/993] scsi: qla2xxx: Fix partial flash write of MBI For new adapters with multiple flash regions to write to, current code allows FW & Boot regions to be written, while other regions are blocked via sysfs. The fix is to block all flash read/write through sysfs interface. Fixes: e81d1bcbde06 ("scsi: qla2xxx: Further limit FLASH region write access from SysFS") Cc: stable@vger.kernel.org # 5.2 Link: https://lore.kernel.org/r/20191022193643.7076-3-hmadhani@marvell.com Signed-off-by: Quinn Tran Signed-off-by: Girish Basrur Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_attr.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 8b3015361428..8705ca6395e4 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -440,9 +440,6 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, valid = 0; if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0) valid = 1; - else if (start == (ha->flt_region_boot * 4) || - start == (ha->flt_region_fw * 4)) - valid = 1; else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) valid = 1; if (!valid) { @@ -489,8 +486,10 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, "Writing flash region -- 0x%x/0x%x.\n", ha->optrom_region_start, ha->optrom_region_size); - ha->isp_ops->write_optrom(vha, ha->optrom_buffer, + rval = ha->isp_ops->write_optrom(vha, ha->optrom_buffer, ha->optrom_region_start, ha->optrom_region_size); + if (rval) + rval = -EIO; break; default: rval = -EINVAL; -- GitLab From 4750c212174892d26645cdf5ad73fb0e9d594ed3 Mon Sep 17 00:00:00 2001 From: Pan Xiuli Date: Tue, 22 Oct 2019 14:44:02 -0500 Subject: [PATCH 610/993] ALSA: hda: Add Tigerlake/Jasperlake PCI ID Add HD Audio Device PCI ID for the Intel Tigerlake and Jasperlake platform. Signed-off-by: Pan Xiuli Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20191022194402.23178-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 240f4ca76391..a815bc811799 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2399,6 +2399,12 @@ static const struct pci_device_id azx_ids[] = { /* Icelake */ { PCI_DEVICE(0x8086, 0x34c8), .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, + /* Jasperlake */ + { PCI_DEVICE(0x8086, 0x38c8), + .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, + /* Tigerlake */ + { PCI_DEVICE(0x8086, 0xa0c8), + .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, /* Elkhart Lake */ { PCI_DEVICE(0x8086, 0x4b55), .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, -- GitLab From 3b4d9eb2ee74dd5ea7fa36cffb0ca7f5bc4924da Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Tue, 22 Oct 2019 23:30:38 +0200 Subject: [PATCH 611/993] bpf: Fix use after free in bpf_get_prog_name There is one more problematic case I noticed while recently fixing BPF kallsyms handling in cd7455f1013e ("bpf: Fix use after free in subprog's jited symbol removal") and that is bpf_get_prog_name(). If BTF has been attached to the prog, then we may be able to fetch the function signature type id in kallsyms through prog->aux->func_info[prog->aux->func_idx].type_id. However, while the BTF object itself is torn down via RCU callback, the prog's aux->func_info is immediately freed via kvfree(prog->aux->func_info) once the prog's refcount either hit zero or when subprograms were already exposed via kallsyms and we hit the error path added in 5482e9a93c83 ("bpf: Fix memleak in aux->func_info and aux->btf"). This violates RCU as well since kallsyms could be walked in parallel where we could access aux->func_info. Hence, defer kvfree() to after RCU grace period. Looking at ba64e7d85252 ("bpf: btf: support proper non-jit func info") there is no reason/dependency where we couldn't defer the kvfree(aux->func_info) into the RCU callback. Fixes: 5482e9a93c83 ("bpf: Fix memleak in aux->func_info and aux->btf") Fixes: ba64e7d85252 ("bpf: btf: support proper non-jit func info") Signed-off-by: Daniel Borkmann Signed-off-by: Alexei Starovoitov Acked-by: Yonghong Song Cc: Martin KaFai Lau Link: https://lore.kernel.org/bpf/875f2906a7c1a0691f2d567b4d8e4ea2739b1e88.1571779205.git.daniel@iogearbox.net --- kernel/bpf/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index bcfc362de4f2..0937719b87e2 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1326,6 +1326,7 @@ static void __bpf_prog_put_rcu(struct rcu_head *rcu) { struct bpf_prog_aux *aux = container_of(rcu, struct bpf_prog_aux, rcu); + kvfree(aux->func_info); free_used_maps(aux); bpf_prog_uncharge_memlock(aux->prog); security_bpf_prog_free(aux); @@ -1336,7 +1337,6 @@ static void __bpf_prog_put_noref(struct bpf_prog *prog, bool deferred) { bpf_prog_kallsyms_del_all(prog); btf_put(prog->aux->btf); - kvfree(prog->aux->func_info); bpf_prog_free_linfo(prog); if (deferred) -- GitLab From b19c23551be8de0d4e59fe6af70f10763e3cc595 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 18 Oct 2019 14:11:58 +0530 Subject: [PATCH 612/993] opp: Reinitialize the list_kref before adding the static OPPs again The list_kref reaches a count of 0 when all the static OPPs are removed, for example when dev_pm_opp_of_cpumask_remove_table() is called, though the actual OPP table may not get freed as it may still be referenced by other parts of the kernel, like from a call to dev_pm_opp_set_supported_hw(). And if we call dev_pm_opp_of_cpumask_add_table() again at this point, we must reinitialize the list_kref otherwise the kernel will hit a WARN() in kref infrastructure for incrementing a kref with value 0. Fixes: 11e1a1648298 ("opp: Don't decrement uninitialized list_kref") Reported-by: Dmitry Osipenko Tested-by: Dmitry Osipenko Signed-off-by: Viresh Kumar --- drivers/opp/of.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 6dc41faf74b5..1cbb58240b80 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -663,6 +663,13 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table) return 0; } + /* + * Re-initialize list_kref every time we add static OPPs to the OPP + * table as the reference count may be 0 after the last tie static OPPs + * were removed. + */ + kref_init(&opp_table->list_kref); + /* We have opp-table node now, iterate over it and add OPPs */ for_each_available_child_of_node(opp_table->np, np) { opp = _opp_add_static_v2(opp_table, dev, np); -- GitLab From 6370740e5f8ef12de7f9a9bf48a0393d202cd827 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 21 Oct 2019 09:29:20 -0700 Subject: [PATCH 613/993] fs/dax: Fix pmd vs pte conflict detection Users reported a v5.3 performance regression and inability to establish huge page mappings. A revised version of the ndctl "dax.sh" huge page unit test identifies commit 23c84eb78375 "dax: Fix missed wakeup with PMD faults" as the source. Update get_unlocked_entry() to check for NULL entries before checking the entry order, otherwise NULL is misinterpreted as a present pte conflict. The 'order' check needs to happen before the locked check as an unlocked entry at the wrong order must fallback to lookup the correct order. Reported-by: Jeff Smits Reported-by: Doug Nelson Cc: Fixes: 23c84eb78375 ("dax: Fix missed wakeup with PMD faults") Reviewed-by: Jan Kara Cc: Jeff Moyer Cc: Matthew Wilcox (Oracle) Reviewed-by: Johannes Thumshirn Link: https://lore.kernel.org/r/157167532455.3945484.11971474077040503994.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams --- fs/dax.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index 6bf81f931de3..2cc43cd914eb 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -220,10 +220,11 @@ static void *get_unlocked_entry(struct xa_state *xas, unsigned int order) for (;;) { entry = xas_find_conflict(xas); + if (!entry || WARN_ON_ONCE(!xa_is_value(entry))) + return entry; if (dax_entry_order(entry) < order) return XA_RETRY_ENTRY; - if (!entry || WARN_ON_ONCE(!xa_is_value(entry)) || - !dax_is_locked(entry)) + if (!dax_is_locked(entry)) return entry; wq = dax_entry_waitqueue(xas, entry, &ewait.key); -- GitLab From 80da5a809d193c60d090cbdf4fe316781bc07965 Mon Sep 17 00:00:00 2001 From: zhengbin Date: Wed, 23 Oct 2019 10:02:49 +0800 Subject: [PATCH 614/993] virtiofs: Remove set but not used variable 'fc' Fixes gcc '-Wunused-but-set-variable' warning: fs/fuse/virtio_fs.c: In function virtio_fs_wake_pending_and_unlock: fs/fuse/virtio_fs.c:983:20: warning: variable fc set but not used [-Wunused-but-set-variable] It is not used since commit 7ee1e2e631db ("virtiofs: No need to check fpq->connected state") Reported-by: Hulk Robot Signed-off-by: zhengbin Signed-off-by: Miklos Szeredi --- fs/fuse/virtio_fs.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index 2de8fc0d6a24..a5c86048b96e 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -980,7 +980,6 @@ __releases(fiq->lock) { unsigned int queue_id = VQ_REQUEST; /* TODO multiqueue */ struct virtio_fs *fs; - struct fuse_conn *fc; struct fuse_req *req; struct virtio_fs_vq *fsvq; int ret; @@ -993,7 +992,6 @@ __releases(fiq->lock) spin_unlock(&fiq->lock); fs = fiq->priv; - fc = fs->vqs[queue_id].fud->fc; pr_debug("%s: opcode %u unique %#llx nodeid %#llx in.len %u out.len %u\n", __func__, req->in.h.opcode, req->in.h.unique, -- GitLab From 09684950050be09ed6cd591e6fbf0c71d3473237 Mon Sep 17 00:00:00 2001 From: Jessica Yu Date: Mon, 21 Oct 2019 15:34:26 +0200 Subject: [PATCH 615/993] scripts/nsdeps: use alternative sed delimiter When doing an out of tree build with O=, the nsdeps script constructs the absolute pathname of the module source file so that it can insert MODULE_IMPORT_NS statements in the right place. However, ${srctree} contains an unescaped path to the source tree, which, when used in a sed substitution, makes sed complain: ++ sed 's/[^ ]* *//home/jeyu/jeyu-linux\/&/g' sed: -e expression #1, char 12: unknown option to `s' The sed substitution command 's' ends prematurely with the forward slashes in the pathname, and sed errors out when it encounters the 'h', which is an invalid sed substitution option. To avoid escaping forward slashes ${srctree}, we can use '|' as an alternative delimiter for sed instead to avoid this error. Reviewed-by: Masahiro Yamada Reviewed-by: Matthias Maennich Tested-by: Matthias Maennich Signed-off-by: Jessica Yu --- scripts/nsdeps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/nsdeps b/scripts/nsdeps index 3754dac13b31..dda6fbac016e 100644 --- a/scripts/nsdeps +++ b/scripts/nsdeps @@ -33,7 +33,7 @@ generate_deps() { if [ ! -f "$ns_deps_file" ]; then return; fi local mod_source_files=`cat $mod_file | sed -n 1p \ | sed -e 's/\.o/\.c/g' \ - | sed "s/[^ ]* */${srctree}\/&/g"` + | sed "s|[^ ]* *|${srctree}/&|g"` for ns in `cat $ns_deps_file`; do echo "Adding namespace $ns to module $mod_name (if needed)." generate_deps_for_ns $ns $mod_source_files -- GitLab From 7cded5658329dd26b9a80d4a6de2665bf93e9006 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 18 Oct 2019 10:49:01 +0300 Subject: [PATCH 616/993] iwlwifi: pcie: fix merge damage on making QnJ exclusive Two patches were sent out of order: one removed some conditions from an if and the other moved the code elsewhere. When sending the patch that moved the code, an older version of the original code was moved, causing the "make QnJ exclusive" code to be essentially undone. Fix that by removing the inclusive conditions from the check again. Fixes: 809805a820c6 ("iwlwifi: pcie: move some cfg mangling from trans_pcie_alloc to probe") Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 6f4bb7ce71a5..9d41d783e59f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -1067,11 +1067,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) && - ((cfg != &iwl_ax200_cfg_cc && - cfg != &killer1650x_2ax_cfg && - cfg != &killer1650w_2ax_cfg && - cfg != &iwl_ax201_cfg_quz_hr) || - iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) { + iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) { u32 hw_status; hw_status = iwl_read_prph(iwl_trans, UMAG_GEN_HW_STATUS); -- GitLab From 8c55dedb795be8ec0cf488f98c03a1c2176f7fb1 Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Fri, 18 Oct 2019 07:43:21 -0400 Subject: [PATCH 617/993] rtlwifi: Fix potential overflow on P2P code Nicolas Waisman noticed that even though noa_len is checked for a compatible length it's still possible to overrun the buffers of p2pinfo since there's no check on the upper bound of noa_num. Bound noa_num against P2P_MAX_NOA_NUM. Reported-by: Nicolas Waisman Signed-off-by: Laura Abbott Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo --- drivers/net/wireless/realtek/rtlwifi/ps.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c b/drivers/net/wireless/realtek/rtlwifi/ps.c index 70f04c2f5b17..fff8dda14023 100644 --- a/drivers/net/wireless/realtek/rtlwifi/ps.c +++ b/drivers/net/wireless/realtek/rtlwifi/ps.c @@ -754,6 +754,9 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, return; } else { noa_num = (noa_len - 2) / 13; + if (noa_num > P2P_MAX_NOA_NUM) + noa_num = P2P_MAX_NOA_NUM; + } noa_index = ie[3]; if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == @@ -848,6 +851,9 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data, return; } else { noa_num = (noa_len - 2) / 13; + if (noa_num > P2P_MAX_NOA_NUM) + noa_num = P2P_MAX_NOA_NUM; + } noa_index = ie[3]; if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == -- GitLab From 6dea7da7019aa04c02edf1878c9c2e59d6cb75a5 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sat, 19 Oct 2019 13:03:27 +0300 Subject: [PATCH 618/993] iwlwifi: pcie: fix PCI ID 0x2720 configs that should be soc Some entries for PCI ID 0x2720 were using iwl9260_2ac_cfg, but the correct is to use iwl9260_2ac_cfg_soc. Fix that. Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 9d41d783e59f..b7c3737c5c2f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -618,9 +618,9 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x271B, 0x0210, iwl9160_2ac_cfg)}, {IWL_PCI_DEVICE(0x271B, 0x0214, iwl9260_2ac_cfg)}, {IWL_PCI_DEVICE(0x271C, 0x0214, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2720, 0x003C, iwl9560_2ac_160_cfg)}, + {IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0x2720, 0x003C, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x0060, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x0064, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x00A0, iwl9462_2ac_cfg_soc)}, @@ -640,7 +640,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2720, 0x1552, iwl9560_killer_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x2030, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x2034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x4030, iwl9560_2ac_160_cfg)}, + {IWL_PCI_DEVICE(0x2720, 0x4030, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x4034, iwl9560_2ac_160_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x40A4, iwl9462_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2720, 0x4234, iwl9560_2ac_cfg_soc)}, -- GitLab From e55890150a961944e861a46efc8599f80f25de76 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sat, 19 Oct 2019 13:03:28 +0300 Subject: [PATCH 619/993] iwlwifi: pcie: fix all 9460 entries for qnj A bunch of the entries for qnj were wrong. The 9460 device doesn't exist, so update them to 9461 and 9462. There are still a bunch of other occurrences of 9460, but that will be fixed separately. Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index b7c3737c5c2f..03568f18a171 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -573,20 +573,20 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2526, 0x0034, iwl9560_2ac_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x0038, iwl9560_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x003C, iwl9560_2ac_160_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x0060, iwl9460_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x0064, iwl9460_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x00A0, iwl9460_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x00A4, iwl9460_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x0060, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x2526, 0x0064, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x2526, 0x00A0, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x2526, 0x00A4, iwl9462_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x0210, iwl9260_2ac_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x0214, iwl9260_2ac_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x0230, iwl9560_2ac_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x0234, iwl9560_2ac_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x0238, iwl9560_2ac_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x023C, iwl9560_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x0260, iwl9460_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x0260, iwl9461_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x0264, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2526, 0x02A0, iwl9460_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2526, 0x02A4, iwl9460_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x02A0, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x2526, 0x02A4, iwl9462_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x1010, iwl9260_2ac_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x1030, iwl9560_2ac_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x1210, iwl9260_2ac_cfg)}, @@ -603,7 +603,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x2526, 0x401C, iwl9260_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x4030, iwl9560_2ac_160_cfg)}, {IWL_PCI_DEVICE(0x2526, 0x4034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x2526, 0x40A4, iwl9460_2ac_cfg)}, + {IWL_PCI_DEVICE(0x2526, 0x40A4, iwl9462_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x4234, iwl9560_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x42A4, iwl9462_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x2526, 0x6010, iwl9260_2ac_160_cfg)}, -- GitLab From 91cf5dede57f9c4030c1378745d612eec2075652 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 19 Oct 2019 13:03:29 +0300 Subject: [PATCH 620/993] iwlwifi: mvm: handle iwl_mvm_tvqm_enable_txq() error return iwl_mvm_tvqm_enable_txq() can return an error, notably if unable to allocate memory for the queue. Handle this error throughout, avoiding storing the invalid value into a u16 which later leads to a disable of an invalid queue ("queue 65524 not used", where 65524 is just -ENOMEM in a u16). Signed-off-by: Johannes Berg Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo --- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 140 +++++++++++-------- 1 file changed, 83 insertions(+), 57 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 0bedba4c61f2..b3768d5d852a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1482,6 +1482,13 @@ static void iwl_mvm_realloc_queues_after_restart(struct iwl_mvm *mvm, mvm_sta->sta_id, i); txq_id = iwl_mvm_tvqm_enable_txq(mvm, mvm_sta->sta_id, i, wdg); + /* + * on failures, just set it to IWL_MVM_INVALID_QUEUE + * to try again later, we have no other good way of + * failing here + */ + if (txq_id < 0) + txq_id = IWL_MVM_INVALID_QUEUE; tid_data->txq_id = txq_id; /* @@ -1950,30 +1957,73 @@ void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta) sta->sta_id = IWL_MVM_INVALID_STA; } -static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 *queue, +static void iwl_mvm_enable_aux_snif_queue(struct iwl_mvm *mvm, u16 queue, u8 sta_id, u8 fifo) { unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ? mvm->trans->trans_cfg->base_params->wd_timeout : IWL_WATCHDOG_DISABLED; + struct iwl_trans_txq_scd_cfg cfg = { + .fifo = fifo, + .sta_id = sta_id, + .tid = IWL_MAX_TID_COUNT, + .aggregate = false, + .frame_limit = IWL_FRAME_LIMIT, + }; + + WARN_ON(iwl_mvm_has_new_tx_api(mvm)); + + iwl_mvm_enable_txq(mvm, NULL, queue, 0, &cfg, wdg_timeout); +} + +static int iwl_mvm_enable_aux_snif_queue_tvqm(struct iwl_mvm *mvm, u8 sta_id) +{ + unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ? + mvm->trans->trans_cfg->base_params->wd_timeout : + IWL_WATCHDOG_DISABLED; + + WARN_ON(!iwl_mvm_has_new_tx_api(mvm)); + + return iwl_mvm_tvqm_enable_txq(mvm, sta_id, IWL_MAX_TID_COUNT, + wdg_timeout); +} +static int iwl_mvm_add_int_sta_with_queue(struct iwl_mvm *mvm, int macidx, + int maccolor, + struct iwl_mvm_int_sta *sta, + u16 *queue, int fifo) +{ + int ret; + + /* Map queue to fifo - needs to happen before adding station */ + if (!iwl_mvm_has_new_tx_api(mvm)) + iwl_mvm_enable_aux_snif_queue(mvm, *queue, sta->sta_id, fifo); + + ret = iwl_mvm_add_int_sta_common(mvm, sta, NULL, macidx, maccolor); + if (ret) { + if (!iwl_mvm_has_new_tx_api(mvm)) + iwl_mvm_disable_txq(mvm, NULL, *queue, + IWL_MAX_TID_COUNT, 0); + return ret; + } + + /* + * For 22000 firmware and on we cannot add queue to a station unknown + * to firmware so enable queue here - after the station was added + */ if (iwl_mvm_has_new_tx_api(mvm)) { - int tvqm_queue = - iwl_mvm_tvqm_enable_txq(mvm, sta_id, - IWL_MAX_TID_COUNT, - wdg_timeout); - *queue = tvqm_queue; - } else { - struct iwl_trans_txq_scd_cfg cfg = { - .fifo = fifo, - .sta_id = sta_id, - .tid = IWL_MAX_TID_COUNT, - .aggregate = false, - .frame_limit = IWL_FRAME_LIMIT, - }; + int txq; - iwl_mvm_enable_txq(mvm, NULL, *queue, 0, &cfg, wdg_timeout); + txq = iwl_mvm_enable_aux_snif_queue_tvqm(mvm, sta->sta_id); + if (txq < 0) { + iwl_mvm_rm_sta_common(mvm, sta->sta_id); + return txq; + } + + *queue = txq; } + + return 0; } int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) @@ -1989,59 +2039,26 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) if (ret) return ret; - /* Map Aux queue to fifo - needs to happen before adding Aux station */ - if (!iwl_mvm_has_new_tx_api(mvm)) - iwl_mvm_enable_aux_snif_queue(mvm, &mvm->aux_queue, - mvm->aux_sta.sta_id, - IWL_MVM_TX_FIFO_MCAST); - - ret = iwl_mvm_add_int_sta_common(mvm, &mvm->aux_sta, NULL, - MAC_INDEX_AUX, 0); + ret = iwl_mvm_add_int_sta_with_queue(mvm, MAC_INDEX_AUX, 0, + &mvm->aux_sta, &mvm->aux_queue, + IWL_MVM_TX_FIFO_MCAST); if (ret) { iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta); return ret; } - /* - * For 22000 firmware and on we cannot add queue to a station unknown - * to firmware so enable queue here - after the station was added - */ - if (iwl_mvm_has_new_tx_api(mvm)) - iwl_mvm_enable_aux_snif_queue(mvm, &mvm->aux_queue, - mvm->aux_sta.sta_id, - IWL_MVM_TX_FIFO_MCAST); - return 0; } int iwl_mvm_add_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - int ret; lockdep_assert_held(&mvm->mutex); - /* Map snif queue to fifo - must happen before adding snif station */ - if (!iwl_mvm_has_new_tx_api(mvm)) - iwl_mvm_enable_aux_snif_queue(mvm, &mvm->snif_queue, - mvm->snif_sta.sta_id, + return iwl_mvm_add_int_sta_with_queue(mvm, mvmvif->id, mvmvif->color, + &mvm->snif_sta, &mvm->snif_queue, IWL_MVM_TX_FIFO_BE); - - ret = iwl_mvm_add_int_sta_common(mvm, &mvm->snif_sta, vif->addr, - mvmvif->id, 0); - if (ret) - return ret; - - /* - * For 22000 firmware and on we cannot add queue to a station unknown - * to firmware so enable queue here - after the station was added - */ - if (iwl_mvm_has_new_tx_api(mvm)) - iwl_mvm_enable_aux_snif_queue(mvm, &mvm->snif_queue, - mvm->snif_sta.sta_id, - IWL_MVM_TX_FIFO_BE); - - return 0; } int iwl_mvm_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) @@ -2133,6 +2150,10 @@ int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) queue = iwl_mvm_tvqm_enable_txq(mvm, bsta->sta_id, IWL_MAX_TID_COUNT, wdg_timeout); + if (queue < 0) { + iwl_mvm_rm_sta_common(mvm, bsta->sta_id); + return queue; + } if (vif->type == NL80211_IFTYPE_AP || vif->type == NL80211_IFTYPE_ADHOC) @@ -2307,10 +2328,8 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) } ret = iwl_mvm_add_int_sta_common(mvm, msta, maddr, mvmvif->id, mvmvif->color); - if (ret) { - iwl_mvm_dealloc_int_sta(mvm, msta); - return ret; - } + if (ret) + goto err; /* * Enable cab queue after the ADD_STA command is sent. @@ -2323,6 +2342,10 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) int queue = iwl_mvm_tvqm_enable_txq(mvm, msta->sta_id, 0, timeout); + if (queue < 0) { + ret = queue; + goto err; + } mvmvif->cab_queue = queue; } else if (!fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE)) @@ -2330,6 +2353,9 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) timeout); return 0; +err: + iwl_mvm_dealloc_int_sta(mvm, msta); + return ret; } static int __iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, u8 sta_id, -- GitLab From 9a47cb988338796b70c544919a8b6ba1f2245edb Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sat, 19 Oct 2019 13:03:30 +0300 Subject: [PATCH 621/993] iwlwifi: pcie: add workaround for power gating in integrated 22000 Add a workaround that forces power gating to be enabled on integrated 22000 devices. This improves power saving in certain situations. Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo --- drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 1 + drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 5 ++++ .../wireless/intel/iwlwifi/pcie/trans-gen2.c | 25 +++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h index cb4c5514a556..695bbaa86273 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h @@ -279,6 +279,7 @@ * Indicates MAC is entering a power-saving sleep power-down. * Not a good time to access device-internal resources. */ +#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004) #define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010) #define CSR_GP_CNTRL_REG_FLAG_XTAL_ON (0x00000400) diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h index f47e0f97acf8..23c25a7665f2 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h @@ -449,6 +449,11 @@ enum { #define PERSISTENCE_BIT BIT(12) #define PREG_WFPM_ACCESS BIT(12) +#define HPM_HIPM_GEN_CFG 0xA03458 +#define HPM_HIPM_GEN_CFG_CR_PG_EN BIT(0) +#define HPM_HIPM_GEN_CFG_CR_SLP_EN BIT(1) +#define HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE BIT(10) + #define UREG_DOORBELL_TO_ISR6 0xA05C04 #define UREG_DOORBELL_TO_ISR6_NMI_BIT BIT(0) #define UREG_DOORBELL_TO_ISR6_SUSPEND BIT(18) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index df8455f14e4d..ca3bb4d65b00 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -57,6 +57,24 @@ #include "internal.h" #include "fw/dbg.h" +static int iwl_pcie_gen2_force_power_gating(struct iwl_trans *trans) +{ + iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG, + HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE); + udelay(20); + iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG, + HPM_HIPM_GEN_CFG_CR_PG_EN | + HPM_HIPM_GEN_CFG_CR_SLP_EN); + udelay(20); + iwl_clear_bits_prph(trans, HPM_HIPM_GEN_CFG, + HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE); + + iwl_trans_sw_reset(trans); + iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + + return 0; +} + /* * Start up NIC's basic functionality after it has been reset * (e.g. after platform boot, or shutdown via iwl_pcie_apm_stop()) @@ -92,6 +110,13 @@ int iwl_pcie_gen2_apm_init(struct iwl_trans *trans) iwl_pcie_apm_config(trans); + if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 && + trans->cfg->integrated) { + ret = iwl_pcie_gen2_force_power_gating(trans); + if (ret) + return ret; + } + ret = iwl_finish_nic_init(trans, trans->trans_cfg); if (ret) return ret; -- GitLab From 17c216ed6b9eef34e647192063f6149d33eff579 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Sat, 19 Oct 2019 13:03:31 +0300 Subject: [PATCH 622/993] iwlwifi: pcie: 0x2720 is qu and 0x30DC is not When converting the wrong qu configurations in an earlier commit, I accidentally swapped 0x2720 and 0x30DC. Instead of converting 0x2720, I converted 0x30DC. Undo 0x30DC and convert 0x2720. Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 109 +++++++++--------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index 03568f18a171..040cec17d3ad 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -618,60 +618,61 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x271B, 0x0210, iwl9160_2ac_cfg)}, {IWL_PCI_DEVICE(0x271B, 0x0214, iwl9260_2ac_cfg)}, {IWL_PCI_DEVICE(0x271C, 0x0214, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x003C, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x0060, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x0064, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x00A0, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x00A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x0230, iwl9560_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2720, 0x0234, iwl9560_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2720, 0x0238, iwl9560_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2720, 0x023C, iwl9560_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2720, 0x0260, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x0264, iwl9461_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x02A0, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x02A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x1010, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2720, 0x1030, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x1210, iwl9260_2ac_cfg)}, - {IWL_PCI_DEVICE(0x2720, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x1552, iwl9560_killer_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x2030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x2034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x4030, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x4034, iwl9560_2ac_160_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x40A4, iwl9462_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x4234, iwl9560_2ac_cfg_soc)}, - {IWL_PCI_DEVICE(0x2720, 0x42A4, iwl9462_2ac_cfg_soc)}, - - {IWL_PCI_DEVICE(0x30DC, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, - {IWL_PCI_DEVICE(0x30DC, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + + {IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, + {IWL_PCI_DEVICE(0x2720, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, + + {IWL_PCI_DEVICE(0x30DC, 0x0030, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x0034, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x0038, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x003C, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x0060, iwl9460_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x0064, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x00A0, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x00A4, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x0230, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x0234, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x0238, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x023C, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x0260, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x0264, iwl9461_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x02A0, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x02A4, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x1010, iwl9260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x30DC, 0x1030, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x1210, iwl9260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x30DC, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x1552, iwl9560_killer_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x2030, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x2034, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x4030, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x4034, iwl9560_2ac_160_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x40A4, iwl9462_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x4234, iwl9560_2ac_cfg_soc)}, + {IWL_PCI_DEVICE(0x30DC, 0x42A4, iwl9462_2ac_cfg_soc)}, {IWL_PCI_DEVICE(0x31DC, 0x0030, iwl9560_2ac_160_cfg_shared_clk)}, {IWL_PCI_DEVICE(0x31DC, 0x0034, iwl9560_2ac_cfg_shared_clk)}, -- GitLab From b43f4a169f220e459edf3ea8f8cd3ec4ae7fa82d Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 20 Oct 2019 19:56:58 -0500 Subject: [PATCH 623/993] rtlwifi: rtl_pci: Fix problem of too small skb->len In commit 8020919a9b99 ("mac80211: Properly handle SKB with radiotap only"), buffers whose length is too short cause a WARN_ON(1) to be executed. This change exposed a fault in rtlwifi drivers, which is fixed by regarding packets with skb->len <= FCS_LEN as though they are in error and dropping them. The test is now annotated as likely. Cc: Stable # v5.0+ Signed-off-by: Larry Finger Signed-off-by: Kalle Valo --- drivers/net/wireless/realtek/rtlwifi/pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c index 6087ec7a90a6..f88d26535978 100644 --- a/drivers/net/wireless/realtek/rtlwifi/pci.c +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c @@ -822,7 +822,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) hdr = rtl_get_hdr(skb); fc = rtl_get_fc(skb); - if (!stats.crc && !stats.hwerror) { + if (!stats.crc && !stats.hwerror && (skb->len > FCS_LEN)) { memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); @@ -859,6 +859,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) _rtl_pci_rx_to_mac80211(hw, skb, rx_status); } } else { + /* drop packets with errors or those too short */ dev_kfree_skb_any(skb); } new_trx_end: -- GitLab From daf61b026f4686250e6afa619e6d7b49edc61df7 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 14 Oct 2019 11:03:15 +0200 Subject: [PATCH 624/993] netfilter: nf_flow_table: set timeout before insertion into hashes Other garbage collector might remove an entry not fully set up yet. [570953.958293] RIP: 0010:memcmp+0x9/0x50 [...] [570953.958567] flow_offload_hash_cmp+0x1e/0x30 [nf_flow_table] [570953.958585] flow_offload_lookup+0x8c/0x110 [nf_flow_table] [570953.958606] nf_flow_offload_ip_hook+0x135/0xb30 [nf_flow_table] [570953.958624] nf_flow_offload_inet_hook+0x35/0x37 [nf_flow_table_inet] [570953.958646] nf_hook_slow+0x3c/0xb0 [570953.958664] __netif_receive_skb_core+0x90f/0xb10 [570953.958678] ? ip_rcv_finish+0x82/0xa0 [570953.958692] __netif_receive_skb_one_core+0x3b/0x80 [570953.958711] __netif_receive_skb+0x18/0x60 [570953.958727] netif_receive_skb_internal+0x45/0xf0 [570953.958741] napi_gro_receive+0xcd/0xf0 [570953.958764] ixgbe_clean_rx_irq+0x432/0xe00 [ixgbe] [570953.958782] ixgbe_poll+0x27b/0x700 [ixgbe] [570953.958796] net_rx_action+0x284/0x3c0 [570953.958817] __do_softirq+0xcc/0x27c [570953.959464] irq_exit+0xe8/0x100 [570953.960097] do_IRQ+0x59/0xe0 [570953.960734] common_interrupt+0xf/0xf Fixes: 43c8f131184f ("netfilter: nf_flow_table: fix missing error check for rhashtable_insert_fast") Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_flow_table_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c index 132f5228b431..128245efe84a 100644 --- a/net/netfilter/nf_flow_table_core.c +++ b/net/netfilter/nf_flow_table_core.c @@ -202,6 +202,8 @@ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) { int err; + flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; + err = rhashtable_insert_fast(&flow_table->rhashtable, &flow->tuplehash[0].node, nf_flow_offload_rhash_params); @@ -218,7 +220,6 @@ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) return err; } - flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT; return 0; } EXPORT_SYMBOL_GPL(flow_offload_add); -- GitLab From 085461c8976e6cb4d5b608a7b7062f394c51a253 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 18 Oct 2019 14:10:31 +0200 Subject: [PATCH 625/993] netfilter: nf_tables_offload: restore basechain deletion Unbind callbacks on chain deletion. Fixes: 8fc618c52d16 ("netfilter: nf_tables_offload: refactor the nft_flow_offload_chain function") Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_tables_offload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c index e546f759b7a7..ad783f4840ef 100644 --- a/net/netfilter/nf_tables_offload.c +++ b/net/netfilter/nf_tables_offload.c @@ -347,7 +347,7 @@ int nft_flow_rule_offload_commit(struct net *net) policy = nft_trans_chain_policy(trans); err = nft_flow_offload_chain(trans->ctx.chain, &policy, - FLOW_BLOCK_BIND); + FLOW_BLOCK_UNBIND); break; case NFT_MSG_NEWRULE: if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)) -- GitLab From b24e7598db62386a95a3c8b9c75630c5d56fe077 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 23 Oct 2019 14:26:37 +0200 Subject: [PATCH 626/993] fuse: flush dirty data/metadata before non-truncate setattr If writeback cache is enabled, then writes might get reordered with chmod/chown/utimes. The problem with this is that performing the write in the fuse daemon might itself change some of these attributes. In such case the following sequence of operations will result in file ending up with the wrong mode, for example: int fd = open ("suid", O_WRONLY|O_CREAT|O_EXCL); write (fd, "1", 1); fchown (fd, 0, 0); fchmod (fd, 04755); close (fd); This patch fixes this by flushing pending writes before performing chown/chmod/utimes. Reported-by: Giuseppe Scrivano Tested-by: Giuseppe Scrivano Fixes: 4d99ff8f12eb ("fuse: Turn writeback cache on") Cc: # v3.15+ Signed-off-by: Miklos Szeredi --- fs/fuse/dir.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index b77954a27538..54d638f9ba1c 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1522,6 +1522,19 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr, is_truncate = true; } + /* Flush dirty data/metadata before non-truncate SETATTR */ + if (is_wb && S_ISREG(inode->i_mode) && + attr->ia_valid & + (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_MTIME_SET | + ATTR_TIMES_SET)) { + err = write_inode_now(inode, true); + if (err) + return err; + + fuse_set_nowrite(inode); + fuse_release_nowrite(inode); + } + if (is_truncate) { fuse_set_nowrite(inode); set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); -- GitLab From e4648309b85a78f8c787457832269a8712a8673e Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 23 Oct 2019 14:26:37 +0200 Subject: [PATCH 627/993] fuse: truncate pending writes on O_TRUNC Make sure cached writes are not reordered around open(..., O_TRUNC), with the obvious wrong results. Fixes: 4d99ff8f12eb ("fuse: Turn writeback cache on") Cc: # v3.15+ Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 0f0225686aee..6edf949b9139 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -217,7 +217,7 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir) { struct fuse_conn *fc = get_fuse_conn(inode); int err; - bool lock_inode = (file->f_flags & O_TRUNC) && + bool is_wb_truncate = (file->f_flags & O_TRUNC) && fc->atomic_o_trunc && fc->writeback_cache; @@ -225,16 +225,20 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir) if (err) return err; - if (lock_inode) + if (is_wb_truncate) { inode_lock(inode); + fuse_set_nowrite(inode); + } err = fuse_do_open(fc, get_node_id(inode), file, isdir); if (!err) fuse_finish_open(inode, file); - if (lock_inode) + if (is_wb_truncate) { + fuse_release_nowrite(inode); inode_unlock(inode); + } return err; } -- GitLab From 9de55a37fcc5f1550a743910f493197223f5e384 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Mon, 19 Aug 2019 11:10:30 -0600 Subject: [PATCH 628/993] fuse: Add changelog entries for protocols 7.1 - 7.8 Retroactively add changelog entry for FUSE protocols 7.1 through 7.8. Signed-off-by: Alan Somers Signed-off-by: Miklos Szeredi --- include/uapi/linux/fuse.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index 802b0377a49e..373cada89815 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -38,6 +38,43 @@ * * Protocol changelog: * + * 7.1: + * - add the following messages: + * FUSE_SETATTR, FUSE_SYMLINK, FUSE_MKNOD, FUSE_MKDIR, FUSE_UNLINK, + * FUSE_RMDIR, FUSE_RENAME, FUSE_LINK, FUSE_OPEN, FUSE_READ, FUSE_WRITE, + * FUSE_RELEASE, FUSE_FSYNC, FUSE_FLUSH, FUSE_SETXATTR, FUSE_GETXATTR, + * FUSE_LISTXATTR, FUSE_REMOVEXATTR, FUSE_OPENDIR, FUSE_READDIR, + * FUSE_RELEASEDIR + * - add padding to messages to accommodate 32-bit servers on 64-bit kernels + * + * 7.2: + * - add FOPEN_DIRECT_IO and FOPEN_KEEP_CACHE flags + * - add FUSE_FSYNCDIR message + * + * 7.3: + * - add FUSE_ACCESS message + * - add FUSE_CREATE message + * - add filehandle to fuse_setattr_in + * + * 7.4: + * - add frsize to fuse_kstatfs + * - clean up request size limit checking + * + * 7.5: + * - add flags and max_write to fuse_init_out + * + * 7.6: + * - add max_readahead to fuse_init_in and fuse_init_out + * + * 7.7: + * - add FUSE_INTERRUPT message + * - add POSIX file lock support + * + * 7.8: + * - add lock_owner and flags fields to fuse_release_in + * - add FUSE_BMAP message + * - add FUSE_DESTROY message + * * 7.9: * - new fuse_getattr_in input argument of GETATTR * - add lk_flags in fuse_lk_in -- GitLab From 091d1a7267726ba162b12ce9332d76cdae602789 Mon Sep 17 00:00:00 2001 From: Vasily Averin Date: Mon, 19 Aug 2019 08:48:26 +0300 Subject: [PATCH 629/993] fuse: redundant get_fuse_inode() calls in fuse_writepages_fill() Currently fuse_writepages_fill() calls get_fuse_inode() few times with the same argument. Signed-off-by: Vasily Averin Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 6edf949b9139..db48a5cf8620 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -2001,7 +2001,7 @@ static int fuse_writepages_fill(struct page *page, if (!data->ff) { err = -EIO; - data->ff = fuse_write_file_get(fc, get_fuse_inode(inode)); + data->ff = fuse_write_file_get(fc, fi); if (!data->ff) goto out_unlock; } @@ -2046,8 +2046,6 @@ static int fuse_writepages_fill(struct page *page, * under writeback, so we can release the page lock. */ if (data->wpa == NULL) { - struct fuse_inode *fi = get_fuse_inode(inode); - err = -ENOMEM; wpa = fuse_writepage_args_alloc(); if (!wpa) { -- GitLab From 1638b8f096ca165965189b9626564c933c79fe63 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 21 Oct 2019 12:07:15 +0200 Subject: [PATCH 630/993] lib/vdso: Make clock_getres() POSIX compliant again A recent commit removed the NULL pointer check from the clock_getres() implementation causing a test case to fault. POSIX requires an explicit NULL pointer check for clock_getres() aside of the validity check of the clock_id argument for obscure reasons. Add it back for both 32bit and 64bit. Note, this is only a partial revert of the offending commit which does not bring back the broken fallback invocation in the the 32bit compat implementations of clock_getres() and clock_gettime(). Fixes: a9446a906f52 ("lib/vdso/32: Remove inconsistent NULL pointer checks") Reported-by: Andreas Schwab Signed-off-by: Thomas Gleixner Tested-by: Christophe Leroy Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/alpine.DEB.2.21.1910211202260.1904@nanos.tec.linutronix.de --- lib/vdso/gettimeofday.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c index e630e7ff57f1..45f57fd2db64 100644 --- a/lib/vdso/gettimeofday.c +++ b/lib/vdso/gettimeofday.c @@ -214,9 +214,10 @@ int __cvdso_clock_getres_common(clockid_t clock, struct __kernel_timespec *res) return -1; } - res->tv_sec = 0; - res->tv_nsec = ns; - + if (likely(res)) { + res->tv_sec = 0; + res->tv_nsec = ns; + } return 0; } @@ -245,7 +246,7 @@ __cvdso_clock_getres_time32(clockid_t clock, struct old_timespec32 *res) ret = clock_getres_fallback(clock, &ts); #endif - if (likely(!ret)) { + if (likely(!ret && res)) { res->tv_sec = ts.tv_sec; res->tv_nsec = ts.tv_nsec; } -- GitLab From 086ee46b08634a999bcd1707eabe3b0dc1806674 Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Tue, 22 Oct 2019 14:12:26 +0100 Subject: [PATCH 631/993] timers/sched_clock: Include local timekeeping.h for missing declarations Include the timekeeping.h header to get the declaration of the sched_clock_{suspend,resume} functions. Fixes the following sparse warnings: kernel/time/sched_clock.c:275:5: warning: symbol 'sched_clock_suspend' was not declared. Should it be static? kernel/time/sched_clock.c:286:6: warning: symbol 'sched_clock_resume' was not declared. Should it be static? Signed-off-by: Ben Dooks (Codethink) Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/20191022131226.11465-1-ben.dooks@codethink.co.uk --- kernel/time/sched_clock.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c index 142b07619918..dbd69052eaa6 100644 --- a/kernel/time/sched_clock.c +++ b/kernel/time/sched_clock.c @@ -17,6 +17,8 @@ #include #include +#include "timekeeping.h" + /** * struct clock_read_data - data required to read from sched_clock() * -- GitLab From 7f2cbcbcafbca5360efbd175b3320852b8f7c637 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Mon, 21 Oct 2019 15:44:12 +0800 Subject: [PATCH 632/993] posix-cpu-timers: Fix two trivial comments Recent changes modified the function arguments of thread_group_sample_cputime() and task_cputimers_expired(), but forgot to update the comments. Fix it up. [ tglx: Changed the argument name of task_cputimers_expired() as the pointer points to an array of samples. ] Fixes: b7be4ef1365d ("posix-cpu-timers: Switch thread group sampling to array") Fixes: 001f7971433a ("posix-cpu-timers: Make expiry checks array based") Signed-off-by: Yi Wang Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/1571643852-21848-1-git-send-email-wang.yi59@zte.com.cn --- kernel/time/posix-cpu-timers.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index 92a431981b1c..42d512fcfda2 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -266,7 +266,7 @@ static void update_gt_cputime(struct task_cputime_atomic *cputime_atomic, /** * thread_group_sample_cputime - Sample cputime for a given task * @tsk: Task for which cputime needs to be started - * @iimes: Storage for time samples + * @samples: Storage for time samples * * Called from sys_getitimer() to calculate the expiry time of an active * timer. That means group cputime accounting is already active. Called @@ -1038,12 +1038,12 @@ static void posix_cpu_timer_rearm(struct k_itimer *timer) * member of @pct->bases[CLK].nextevt. False otherwise */ static inline bool -task_cputimers_expired(const u64 *sample, struct posix_cputimers *pct) +task_cputimers_expired(const u64 *samples, struct posix_cputimers *pct) { int i; for (i = 0; i < CPUCLOCK_MAX; i++) { - if (sample[i] >= pct->bases[i].nextevt) + if (samples[i] >= pct->bases[i].nextevt) return true; } return false; -- GitLab From bacdcb6675e170bb2e8d3824da220e10274f42a7 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 23 Oct 2019 08:31:38 -0700 Subject: [PATCH 633/993] dmaengine: cppi41: Fix cppi41_dma_prep_slave_sg() when idle Yegor Yefremov reported that musb and ftdi uart can fail for the first open of the uart unless connected using a hub. This is because the first dma call done by musb_ep_program() must wait if cppi41 is PM runtime suspended. Otherwise musb_ep_program() continues with other non-dma packets before the DMA transfer is started causing at least ftdi uarts to fail to receive data. Let's fix the issue by waking up cppi41 with PM runtime calls added to cppi41_dma_prep_slave_sg() and return NULL if still idled. This way we have musb_ep_program() continue with PIO until cppi41 is awake. Fixes: fdea2d09b997 ("dmaengine: cppi41: Add basic PM runtime support") Reported-by: Yegor Yefremov Signed-off-by: Tony Lindgren Cc: stable@vger.kernel.org # v4.9+ Link: https://lore.kernel.org/r/20191023153138.23442-1-tony@atomide.com Signed-off-by: Vinod Koul --- drivers/dma/ti/cppi41.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/dma/ti/cppi41.c b/drivers/dma/ti/cppi41.c index 2f946f55076c..8c2f7ebe998c 100644 --- a/drivers/dma/ti/cppi41.c +++ b/drivers/dma/ti/cppi41.c @@ -586,9 +586,22 @@ static struct dma_async_tx_descriptor *cppi41_dma_prep_slave_sg( enum dma_transfer_direction dir, unsigned long tx_flags, void *context) { struct cppi41_channel *c = to_cpp41_chan(chan); + struct dma_async_tx_descriptor *txd = NULL; + struct cppi41_dd *cdd = c->cdd; struct cppi41_desc *d; struct scatterlist *sg; unsigned int i; + int error; + + error = pm_runtime_get(cdd->ddev.dev); + if (error < 0) { + pm_runtime_put_noidle(cdd->ddev.dev); + + return NULL; + } + + if (cdd->is_suspended) + goto err_out_not_ready; d = c->desc; for_each_sg(sgl, sg, sg_len, i) { @@ -611,7 +624,13 @@ static struct dma_async_tx_descriptor *cppi41_dma_prep_slave_sg( d++; } - return &c->txd; + txd = &c->txd; + +err_out_not_ready: + pm_runtime_mark_last_busy(cdd->ddev.dev); + pm_runtime_put_autosuspend(cdd->ddev.dev); + + return txd; } static void cppi41_compute_td_desc(struct cppi41_desc *d) -- GitLab From 4cad2a574d342cd9b658db6e32e9024f559383ed Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Wed, 23 Oct 2019 14:21:57 +0200 Subject: [PATCH 634/993] panfrost: Properly undo pm_runtime_enable when deferring a probe When deferring the probe because of a missing regulator, we were calling pm_runtime_disable even if pm_runtime_enable wasn't called. Move the call to pm_runtime_disable to the right place. Fixes: 635430797d3f ("drm/panfrost: Rework runtime PM initialization") Reported-by: Chen-Yu Tsai Cc: Robin Murphy Signed-off-by: Tomeu Vizoso Reviewed-by: Robin Murphy Reviewed-by: Steven Price Signed-off-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/20191023122157.32067-1-tomeu.vizoso@collabora.com --- drivers/gpu/drm/panfrost/panfrost_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index bc2ddeb55f5d..f21bc8a7ee3a 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -556,11 +556,11 @@ static int panfrost_probe(struct platform_device *pdev) return 0; err_out2: + pm_runtime_disable(pfdev->dev); panfrost_devfreq_fini(pfdev); err_out1: panfrost_device_fini(pfdev); err_out0: - pm_runtime_disable(pfdev->dev); drm_dev_put(ddev); return err; } -- GitLab From 29cd13cfd7624726d9e6becbae9aa419ef35af7f Mon Sep 17 00:00:00 2001 From: Navid Emamdoost Date: Mon, 21 Oct 2019 13:52:49 -0500 Subject: [PATCH 635/993] drm/v3d: Fix memory leak in v3d_submit_cl_ioctl In the impelementation of v3d_submit_cl_ioctl() there are two memory leaks. One is when allocation for bin fails, and the other is when bin initialization fails. If kcalloc fails to allocate memory for bin then render->base should be put. Also, if v3d_job_init() fails to initialize bin->base then allocated memory for bin should be released. Fixes: a783a09ee76d ("drm/v3d: Refactor job management.") Signed-off-by: Navid Emamdoost Reviewed-by: Eric Anholt Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20191021185250.26130-1-navid.emamdoost@gmail.com --- drivers/gpu/drm/v3d/v3d_gem.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index 5d80507b539b..19c092d75266 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -557,13 +557,16 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, if (args->bcl_start != args->bcl_end) { bin = kcalloc(1, sizeof(*bin), GFP_KERNEL); - if (!bin) + if (!bin) { + v3d_job_put(&render->base); return -ENOMEM; + } ret = v3d_job_init(v3d, file_priv, &bin->base, v3d_job_free, args->in_sync_bcl); if (ret) { v3d_job_put(&render->base); + kfree(bin); return ret; } -- GitLab From 0d660ffbca1a5f16f6db8f6ccbea5c207ec7e361 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 18 Oct 2019 10:18:35 -0700 Subject: [PATCH 636/993] MAINTAINERS: Remove Gregory and Brian for ARCH_BRCMSTB The last time Gregory and Brian did a review was sometime around 2015, since then, they have not been active for ARCH_BRCMSTB changes. Following the position of other maintainers and Harald Welte's position here: [1] http://laforge.gnumonks.org/blog/20180307-mchardy-gpl/ remove both of them. Acked-by: Brian Norris Signed-off-by: Florian Fainelli --- MAINTAINERS | 2 -- 1 file changed, 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 14a939a9e1e7..e3f50d8ccac0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3242,8 +3242,6 @@ S: Maintained F: drivers/usb/gadget/udc/bcm63xx_udc.* BROADCOM BCM7XXX ARM ARCHITECTURE -M: Brian Norris -M: Gregory Fong M: Florian Fainelli M: bcm-kernel-feedback-list@broadcom.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -- GitLab From 9af865d95bd730c1d1035acd5dd6df105da98d0c Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 24 Sep 2019 14:37:56 -0500 Subject: [PATCH 637/993] dt-bindings: riscv: Fix CPU schema errors Fix the errors in the RiscV CPU DT schema: Documentation/devicetree/bindings/riscv/cpus.example.dt.yaml: cpu@0: 'timebase-frequency' is a required property Documentation/devicetree/bindings/riscv/cpus.example.dt.yaml: cpu@1: 'timebase-frequency' is a required property Documentation/devicetree/bindings/riscv/cpus.example.dt.yaml: cpu@0: compatible:0: 'riscv' is not one of ['sifive,rocket0', 'sifive,e5', 'sifive,e51', 'sifive,u54-mc', 'sifive,u54', 'sifive,u5'] Documentation/devicetree/bindings/riscv/cpus.example.dt.yaml: cpu@0: compatible: ['riscv'] is too short Documentation/devicetree/bindings/riscv/cpus.example.dt.yaml: cpu@0: 'timebase-frequency' is a required property The DT spec allows for 'timebase-frequency' to be in 'cpu' or 'cpus' node and RiscV requires it in /cpus node, so make it disallowed in cpu nodes. Fixes: 4fd669a8c487 ("dt-bindings: riscv: convert cpu binding to json-schema") Cc: Palmer Dabbelt Cc: Albert Ou Cc: linux-riscv@lists.infradead.org Acked-by: Paul Walmsley Signed-off-by: Rob Herring --- .../devicetree/bindings/riscv/cpus.yaml | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml index b261a3015f84..04819ad379c2 100644 --- a/Documentation/devicetree/bindings/riscv/cpus.yaml +++ b/Documentation/devicetree/bindings/riscv/cpus.yaml @@ -24,15 +24,17 @@ description: | properties: compatible: - items: - - enum: - - sifive,rocket0 - - sifive,e5 - - sifive,e51 - - sifive,u54-mc - - sifive,u54 - - sifive,u5 - - const: riscv + oneOf: + - items: + - enum: + - sifive,rocket0 + - sifive,e5 + - sifive,e51 + - sifive,u54-mc + - sifive,u54 + - sifive,u5 + - const: riscv + - const: riscv # Simulator only description: Identifies that the hart uses the RISC-V instruction set and identifies the type of the hart. @@ -66,12 +68,8 @@ properties: insensitive, letters in the riscv,isa string must be all lowercase to simplify parsing. - timebase-frequency: - type: integer - minimum: 1 - description: - Specifies the clock frequency of the system timer in Hz. - This value is common to all harts on a single system image. + # RISC-V requires 'timebase-frequency' in /cpus, so disallow it here + timebase-frequency: false interrupt-controller: type: object @@ -93,7 +91,6 @@ properties: required: - riscv,isa - - timebase-frequency - interrupt-controller examples: -- GitLab From e13de8fe0d6a51341671bbe384826d527afe8d44 Mon Sep 17 00:00:00 2001 From: Navid Emamdoost Date: Fri, 4 Oct 2019 13:58:43 -0500 Subject: [PATCH 638/993] of: unittest: fix memory leak in unittest_data_add In unittest_data_add, a copy buffer is created via kmemdup. This buffer is leaked if of_fdt_unflatten_tree fails. The release for the unittest_data buffer is added. Fixes: b951f9dc7f25 ("Enabling OF selftest to run without machine's devicetree") Signed-off-by: Navid Emamdoost Reviewed-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/unittest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 480a21e2ed39..92e895d86458 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -1207,6 +1207,7 @@ static int __init unittest_data_add(void) of_fdt_unflatten_tree(unittest_data, NULL, &unittest_data_node); if (!unittest_data_node) { pr_warn("%s: No tree to attach; not running tests\n", __func__); + kfree(unittest_data); return -ENODATA; } -- GitLab From 5dba51754b04a941a1064f584e7a7f607df3f9bc Mon Sep 17 00:00:00 2001 From: Chris Goldsworthy Date: Sat, 19 Oct 2019 18:57:24 -0700 Subject: [PATCH 639/993] of: reserved_mem: add missing of_node_put() for proper ref-counting Commit d698a388146c ("of: reserved-memory: ignore disabled memory-region nodes") added an early return in of_reserved_mem_device_init_by_idx(), but didn't call of_node_put() on a device_node whose ref-count was incremented in the call to of_parse_phandle() preceding the early exit. Fixes: d698a388146c ("of: reserved-memory: ignore disabled memory-region nodes") Signed-off-by: Chris Goldsworthy Cc: stable@vger.kernel.org Reviewed-by: Bjorn Andersson Signed-off-by: Rob Herring --- drivers/of/of_reserved_mem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 7989703b883c..6bd610ee2cd7 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -324,8 +324,10 @@ int of_reserved_mem_device_init_by_idx(struct device *dev, if (!target) return -ENODEV; - if (!of_device_is_available(target)) + if (!of_device_is_available(target)) { + of_node_put(target); return 0; + } rmem = __find_rmem(target); of_node_put(target); -- GitLab From ce42ef68b9d9c91f1de5891288bc38a21b346994 Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Wed, 23 Oct 2019 21:06:37 +0100 Subject: [PATCH 640/993] ANDROID: Move out patches/ and replace by link to kernel/common-patches project Change-Id: Ie9df0ea6933b34a1b97f5034bb8c6a913b079e08 Signed-off-by: Matthias Maennich --- patches | 1 + ...ndler-to-invalidate-vbmeta-partition.patch | 332 -- ...dd-an-IOCTL-to-check-ION-ABI-version.patch | 67 - ...NDROID-Add-initial-rockpi4_defconfig.patch | 561 -- ...OID-Add-initial-x86_64-gki_defconfig.patch | 382 -- ..._options2-to-view-private-mount-data.patch | 53 - ...OID-Adding-GKI-Ramdisk-to-gki-config.patch | 32 - ...ing-SERIAL_OF_PLATFORM-module-to-gki.patch | 46 - patches/ANDROID-CONFIG_MMC-m.patch | 48 - ...kpi4_defconfig-up-with-gki_defconfig.patch | 172 - ...Expose-gki_defconfig-to-build.config.patch | 39 - ...ANDROID-Fix-arm64-allmodconfig-build.patch | 34 - ...NDROID-Fix-x86_64-allmodconfig-build.patch | 41 - patches/ANDROID-Fixed-x86-regression.patch | 43 - ...ur-part-revert-of-asm-goto-usage-1-4.patch | 35 - ...ur-part-revert-of-asm-goto-usage-2-4.patch | 41 - ...ur-part-revert-of-asm-goto-usage-3-4.patch | 124 - ...ur-part-revert-of-asm-goto-usage-4-4.patch | 55 - ...NDROID-GKI-enable-CONFIG_SPI-for-x86.patch | 26 - ...DROID-GKI-enable-CONFIG_TIPC-for-x86.patch | 26 - ...cma-symbols-for-cma-heap-as-a-module.patch | 55 - ...D-Initial-abi_gki_aarch64-definition.patch | 58 - ...allow-overriding-clang-target-triple.patch | 61 - ...iled-to-suspend-in-dpm_suspend_start.patch | 69 - ...-Move-from-clang-r349610-to-r353983c.patch | 28 - ...ve-CONFIG_USELIB-from-x86-gki-config.patch | 22 - .../ANDROID-Removed-check-for-asm-goto.patch | 41 - ...-Removed-extraneous-configs-from-gki.patch | 55 - ...moved-extraneous-serial-8250-configs.patch | 44 - ...dcoded-kernel-command-line-arguments.patch | 25 - ...-unnecessary-modules-from-cuttlefish.patch | 33 - ...rs-make-headers-archive-reproducible.patch | 65 - ...-irq-don-t-set-the-chip-for-all-irqs.patch | 29 - ...emove-uses-of-variable-length-arrays.patch | 107 - ...nd-of-the-kernel-area-to-be-reserved.patch | 76 - ...NDROID-add-extra-free-kbytes-tunable.patch | 178 - ...-so-that-GKI-boots-on-x86-cuttlefish.patch | 49 - ...nfig-to-permit-usb-write-ops-on-init.patch | 37 - ...odconfig-Force-gki_defconfig-as-base.patch | 33 - ...OID-arm-enable-max-frequency-capping.patch | 30 - ...-copy-CONFIG_CMDLINE_EXTEND-from-ARM.patch | 52 - ...rm64-defconfig-Enable-EAS-by-default.patch | 44 - ...D-arm64-enable-max-frequency-capping.patch | 30 - ...-add-support-for-RT-prio-inheritance.patch | 570 -- ...onfigs-switch-prebuilt-path-location.patch | 41 - ...d-pre-and-post-change-rate-callbacks.patch | 87 - ...KOBJ_ONLINE-event-when-enabling-cpus.patch | 41 - ...ime_in_state-to-proc-uid-directories.patch | 139 - ...logy-implement-max-frequency-capping.patch | 135 - ...-uid_concurrent_-active-policy-_time.patch | 340 -- ...t-copy-invalid-freqs-from-freq-table.patch | 151 - ...ID-cpufreq-times-optimize-proc-files.patch | 72 - ...rd-fast-switch-frequency-transitions.patch | 111 - ...eq-times-track-per-uid-time-in-state.patch | 328 -- ...cpufreq-track-per-task-time-in-state.patch | 473 -- ...reate-build.configs-for-allmodconfig.patch | 54 - ...i-_defconfig-Enable-CONFIG_SDCARD_FS.patch | 37 - ...ROID-cuttlefish-overlayfs-regression.patch | 32 - .../ANDROID-dm-bow-Add-dm-bow-feature.patch | 1444 ----- ...OID-dm-bow-Fix-32-bit-compile-errors.patch | 76 - ...-mapping-buffers-with-DMA-attributes.patch | 42 - ...upport-for-partial-cache-maintenance.patch | 170 - ...o-get-flags-associated-with-a-buffer.patch | 76 - ...t-pass-cuttlefish-GKI-modularization.patch | 108 - .../ANDROID-fix-kernelci-build-break.patch | 39 - ...NDROID-fs-FS-tracepoints-to-track-IO.patch | 634 -- ...ID-fs-Restore-vfs_path_lookup-export.patch | 49 - ...fs-epoll-use-freezable-blocking-call.patch | 51 - ...-defconfigs-use-prebuilt-build-tools.patch | 41 - ...efconfig-Add-GKI_HACKS_to_FIX-config.patch | 41 - ...Enable-BPF_JIT-and-BPF_JIT_ALWAYS_ON.patch | 71 - ..._FREELIST-RANDOM-and-HARDENED-on-x86.patch | 37 - ..._defconfig-Enable-CONFIG_DM_SNAPSHOT.patch | 43 - ...-gki_defconfig-Enable-HiSilicon-SoCs.patch | 42 - ...-gki_defconfig-Enable-SERIAL_DEV_BUS.patch | 39 - ...D-gki_defconfig-Minimally-enable-EFI.patch | 65 - ...g-Remove-cuttlefish-specific-configs.patch | 93 - ...ommended-configs-not-present-on-b1c1.patch | 150 - ...nfig-common-configs-for-device-DLKMs.patch | 77 - ...i_defconfig-disable-BRIDGE_NETFILTER.patch | 25 - ...sable-CONFIG_LCD_CLASS_DEVICE-module.patch | 23 - ...i_defconfig-disable-IP_PNP-ECRYPT_FS.patch | 33 - ...ig-enable-CMA-and-increase-CMA_AREAS.patch | 25 - ...OID-gki_defconfig-enable-CONFIG_NLS_.patch | 139 - ...PARAVIRT-and-CONFIG_HYPERVISOR_GUEST.patch | 30 - ...ble-CONFIG_QCOM_-COMMAND_DB-RPMH-PDC.patch | 69 - ...nfig-enable-CONFIG_SPARSEMEM_VMEMMAP.patch | 50 - ...OID-gki_defconfig-enable-CONFIG_TIPC.patch | 24 - ...ROID-gki_defconfig-enable-CONFIG_UIO.patch | 37 - ...ANDROID-gki_defconfig-enable-DMA_CMA.patch | 27 - ...DROID-gki_defconfig-enable-REGULATOR.patch | 37 - ...EELIST_RANDOM-SLAB_FREELIST_HARDENED.patch | 28 - ...g-enable-accelerated-AES-and-SHA-256.patch | 47 - ...DROID-gki_defconfig-enable-fs-verity.patch | 41 - ...ID-gki_defconfig-enable-more-configs.patch | 85 - ...nfig-enabled-CONFIG_TMPFS-explicitly.patch | 46 - ...config-based-on-cuttlefish_defconfig.patch | 463 -- ..._defconfig-more-configs-for-partners.patch | 127 - ...onfig-more-generic-configs-for-DLKMs.patch | 65 - ...remove-PWRSEQ_EMMC-and-PWRSEQ_SIMPLE.patch | 27 - ...nfig-remove-more-recommended-configs.patch | 46 - ...-gki_defconfig-set-CONFIG_NR_CPUS-32.patch | 43 - ...ki_defconfig-sync-with-savedefconfig.patch | 24 - ...fconfig-workaround-to-enable-configs.patch | 54 - ...NDROID-init-GKI-add-GKI_HACKS_TO_FIX.patch | 53 - ...it-GKI-enable-hidden-configs-for-DRM.patch | 43 - ...t-GKI-enable-hidden-configs-for-GPIO.patch | 43 - ...KI-enable-hidden-configs-for-SND_SOC.patch | 42 - ...GKI-enable-hidden-configs-for-regmap.patch | 42 - ...OID-label-cuttlefish-modules-for-gki.patch | 50 - ...e-names-for-private-anonymous-memory.patch | 644 -- ...d-ignore-mmc-pm-notify-functionality.patch | 50 - ...esystem-private-data-to-mount-points.patch | 168 - ...OID-mnt-Fix-null-pointer-dereference.patch | 62 - ...tures-with-GKI_LEGACY_WEXT_ALLCONFIG.patch | 64 - ...toconf-routes-into-per-device-tables.patch | 266 - ...-SHA256-use-RFC-compliant-truncation.patch | 37 - ...t_IDLETIMER-Add-new-netlink-msg-type.patch | 450 -- ...-original-quota2-from-xtables-addons.patch | 515 -- ...-CONFIG_CMDLINE_EXTEND-config-option.patch | 179 - ...son-add-an-API-to-log-wakeup-reasons.patch | 584 -- .../ANDROID-proc-Add-proc-uid-directory.patch | 433 -- ...d.config-files-to-remove-duplication.patch | 111 - ...r-sync-flag-for-energy-aware-wakeups.patch | 51 - ...uce-uclamp-latency-and-boost-wrapper.patch | 67 - ...alance-of-single-task-in-sched-group.patch | 60 - ...r-sync-flag-for-energy-aware-wakeups.patch | 61 - ...in-case-of-max-frequency-constraints.patch | 219 - ...d-a-latency-sensitive-flag-to-uclamp.patch | 96 - ...-Also-do-misfit-in-overloaded-groups.patch | 33 - ...rove-throughput-for-asym-cap-systems.patch | 52 - ...-fair-Bias-EAS-placement-for-latency.patch | 126 - ...its-if-it-would-overload-local-group.patch | 57 - ...support-to-find_energy_efficient_cpu.patch | 63 - ...g-function-for-max-frequency-capping.patch | 80 - ...OID-sdcardfs-Add-sdcardfs-filesystem.patch | 5179 ----------------- .../ANDROID-sdcardfs-Define-magic-value.patch | 33 - ...OID-sdcardfs-Enable-modular-sdcardfs.patch | 99 - ...fs-fix-fall-through-in-param-parsing.patch | 24 - ...rther-restriction-of-perf_event_open.patch | 116 - ...ouple-ION-page-pooling-from-ION-core.patch | 181 - ...ion-Expose-ion_alloc-to-kernel-space.patch | 147 - ...upport-for-heap-specific-dma_buf_ops.patch | 331 -- ...DROID-staging-ion-Build-fix-for-mips.patch | 24 - ...n-Fix-uninitialized-variable-warning.patch | 47 - ...e-ion-heaps-into-their-own-directory.patch | 136 - ...-ion-Remove-unnecessary-ion-heap-ops.patch | 179 - ...-add-support-for-consistent-heap-ids.patch | 176 - ...ng-ion-export-ion_free-for-ion_heaps.patch | 60 - ...on-fix-off-by-1-error-in-heap-search.patch | 39 - ...ix-sparse-warning-in-ion-system-heap.patch | 31 - ...D-staging-ion-make-cma-heap-a-module.patch | 116 - ...make-system-and-contig-heaps-modular.patch | 512 -- ...-move-uapi-ion.h-to-uapi-linux-ion.h.patch | 33 - ...er-manipulators-into-a-separate-file.patch | 552 -- ...uf-manipulators-into-a-separate-file.patch | 677 --- ...ctor-ion-s-heap-API-into-linux-ion.h.patch | 871 --- ...ap-manipulators-into-a-separate-file.patch | 398 -- ...ecific-heap-ids-for-known-heap-types.patch | 129 - ...split-system-and-system-contig-heaps.patch | 297 - ...i-match-the-existing-heap-type-enums.patch | 46 - ...D-sync-defconfigs-with-savedefconfig.patch | 55 - ...DROID-taskstats-track-fsync-syscalls.patch | 135 - ...-accounting-for-the-cputimes-per-uid.patch | 314 - ...time-add-per-uid-IO-usage-accounting.patch | 647 -- ...ally-compile-sig_ok-in-struct-module.patch | 42 - .../ANDROID-update-arm64-gki_defconfig.patch | 26 - patches/ANDROID-update-gki_defconfig-2.patch | 39 - patches/ANDROID-update-gki_defconfig.patch | 39 - ...adget-Fix-dependency-for-f_accessory.patch | 48 - ...figfs-Add-Uevent-to-notify-userspace.patch | 275 - ...-attribute-to-determine-gadget-state.patch | 151 - ...s-Add-function-devices-to-the-parent.patch | 106 - ...dd-state-attribute-to-android_device.patch | 121 - ...fs-Add-usb_function-ptr-to-fi-struct.patch | 35 - ...ssory-Add-Android-Accessory-function.patch | 1625 ------ ...e-New-gadget-driver-for-audio-output.patch | 1150 ---- ...b-gadget-f_midi-create-F_midi-device.patch | 107 - ...-f-to-NULL-when-free-f_midi-function.patch | 53 - ...lesystems-with-per-mount-permissions.patch | 892 --- ...lesystems-with-per-mount-permissions.patch | 258 - ..._path-for-stacked-filesystem-support.patch | 109 - ...x86-Remove-a-useless-warning-message.patch | 36 - ...OID-x86-gki_defconfig-enable-DMA_CMA.patch | 24 - ...xfrm-remove-in_compat_syscall-checks.patch | 44 - ...to_dev-to-look-up-device-from-fwnode.patch | 68 - ...nking-devices-during-device-addition.patch | 240 - ...e-Add-sync_state-driver-bus-callback.patch | 252 - ...during-init-and-of_platform_populate.patch | 76 - ...nal-dependency-link-from-DT-bindings.patch | 362 -- ...-for-all-child-supplier-depencencies.patch | 90 - ...custom-soc-information-sysfs-entries.patch | 118 - patches/series | 197 - 193 files changed, 1 insertion(+), 33960 deletions(-) create mode 120000 patches delete mode 100644 patches/ANDROID-AVB-error-handler-to-invalidate-vbmeta-partition.patch delete mode 100644 patches/ANDROID-Add-an-IOCTL-to-check-ION-ABI-version.patch delete mode 100644 patches/ANDROID-Add-initial-rockpi4_defconfig.patch delete mode 100644 patches/ANDROID-Add-initial-x86_64-gki_defconfig.patch delete mode 100644 patches/ANDROID-Add-show_options2-to-view-private-mount-data.patch delete mode 100644 patches/ANDROID-Adding-GKI-Ramdisk-to-gki-config.patch delete mode 100644 patches/ANDROID-Adding-SERIAL_OF_PLATFORM-module-to-gki.patch delete mode 100644 patches/ANDROID-CONFIG_MMC-m.patch delete mode 100644 patches/ANDROID-Catch-rockpi4_defconfig-up-with-gki_defconfig.patch delete mode 100644 patches/ANDROID-Expose-gki_defconfig-to-build.config.patch delete mode 100644 patches/ANDROID-Fix-arm64-allmodconfig-build.patch delete mode 100644 patches/ANDROID-Fix-x86_64-allmodconfig-build.patch delete mode 100644 patches/ANDROID-Fixed-x86-regression.patch delete mode 100644 patches/ANDROID-Four-part-revert-of-asm-goto-usage-1-4.patch delete mode 100644 patches/ANDROID-Four-part-revert-of-asm-goto-usage-2-4.patch delete mode 100644 patches/ANDROID-Four-part-revert-of-asm-goto-usage-3-4.patch delete mode 100644 patches/ANDROID-Four-part-revert-of-asm-goto-usage-4-4.patch delete mode 100644 patches/ANDROID-GKI-enable-CONFIG_SPI-for-x86.patch delete mode 100644 patches/ANDROID-GKI-enable-CONFIG_TIPC-for-x86.patch delete mode 100644 patches/ANDROID-GKI-export-cma-symbols-for-cma-heap-as-a-module.patch delete mode 100644 patches/ANDROID-Initial-abi_gki_aarch64-definition.patch delete mode 100644 patches/ANDROID-Kbuild-LLVMLinux-allow-overriding-clang-target-triple.patch delete mode 100644 patches/ANDROID-Log-which-device-failed-to-suspend-in-dpm_suspend_start.patch delete mode 100644 patches/ANDROID-Move-from-clang-r349610-to-r353983c.patch delete mode 100644 patches/ANDROID-Remove-CONFIG_USELIB-from-x86-gki-config.patch delete mode 100644 patches/ANDROID-Removed-check-for-asm-goto.patch delete mode 100644 patches/ANDROID-Removed-extraneous-configs-from-gki.patch delete mode 100644 patches/ANDROID-Removed-extraneous-serial-8250-configs.patch delete mode 100644 patches/ANDROID-Removed-hardcoded-kernel-command-line-arguments.patch delete mode 100644 patches/ANDROID-Removed-unnecessary-modules-from-cuttlefish.patch delete mode 100644 patches/ANDROID-Revert-kheaders-make-headers-archive-reproducible.patch delete mode 100644 patches/ANDROID-Revert-um-irq-don-t-set-the-chip-for-all-irqs.patch delete mode 100644 patches/ANDROID-Revert-um-remove-uses-of-variable-length-arrays.patch delete mode 100644 patches/ANDROID-Revert-x86-mm-Identify-the-end-of-the-kernel-area-to-be-reserved.patch delete mode 100644 patches/ANDROID-add-extra-free-kbytes-tunable.patch delete mode 100644 patches/ANDROID-added-configs-so-that-GKI-boots-on-x86-cuttlefish.patch delete mode 100644 patches/ANDROID-adding-usb-HCD-dummy-config-to-permit-usb-write-ops-on-init.patch delete mode 100644 patches/ANDROID-allmodconfig-Force-gki_defconfig-as-base.patch delete mode 100644 patches/ANDROID-arm-enable-max-frequency-capping.patch delete mode 100644 patches/ANDROID-arm64-copy-CONFIG_CMDLINE_EXTEND-from-ARM.patch delete mode 100644 patches/ANDROID-arm64-defconfig-Enable-EAS-by-default.patch delete mode 100644 patches/ANDROID-arm64-enable-max-frequency-capping.patch delete mode 100644 patches/ANDROID-binder-add-support-for-RT-prio-inheritance.patch delete mode 100644 patches/ANDROID-build-configs-switch-prebuilt-path-location.patch delete mode 100644 patches/ANDROID-clk-add-pre-and-post-change-rate-callbacks.patch delete mode 100644 patches/ANDROID-cpu-send-KOBJ_ONLINE-event-when-enabling-cpus.patch delete mode 100644 patches/ANDROID-cpufreq-Add-time_in_state-to-proc-uid-directories.patch delete mode 100644 patches/ANDROID-cpufreq-arch_topology-implement-max-frequency-capping.patch delete mode 100644 patches/ANDROID-cpufreq-times-add-proc-uid_concurrent_-active-policy-_time.patch delete mode 100644 patches/ANDROID-cpufreq-times-don-t-copy-invalid-freqs-from-freq-table.patch delete mode 100644 patches/ANDROID-cpufreq-times-optimize-proc-files.patch delete mode 100644 patches/ANDROID-cpufreq-times-record-fast-switch-frequency-transitions.patch delete mode 100644 patches/ANDROID-cpufreq-times-track-per-uid-time-in-state.patch delete mode 100644 patches/ANDROID-cpufreq-track-per-task-time-in-state.patch delete mode 100644 patches/ANDROID-create-build.configs-for-allmodconfig.patch delete mode 100644 patches/ANDROID-cuttlefish-gki-_defconfig-Enable-CONFIG_SDCARD_FS.patch delete mode 100644 patches/ANDROID-cuttlefish-overlayfs-regression.patch delete mode 100644 patches/ANDROID-dm-bow-Add-dm-bow-feature.patch delete mode 100644 patches/ANDROID-dm-bow-Fix-32-bit-compile-errors.patch delete mode 100644 patches/ANDROID-dma-buf-Add-support-for-mapping-buffers-with-DMA-attributes.patch delete mode 100644 patches/ANDROID-dma-buf-Add-support-for-partial-cache-maintenance.patch delete mode 100644 patches/ANDROID-dma-buf-Add-support-to-get-flags-associated-with-a-buffer.patch delete mode 100644 patches/ANDROID-first-pass-cuttlefish-GKI-modularization.patch delete mode 100644 patches/ANDROID-fix-kernelci-build-break.patch delete mode 100644 patches/ANDROID-fs-FS-tracepoints-to-track-IO.patch delete mode 100644 patches/ANDROID-fs-Restore-vfs_path_lookup-export.patch delete mode 100644 patches/ANDROID-fs-epoll-use-freezable-blocking-call.patch delete mode 100644 patches/ANDROID-gki-cuttlefish-defconfigs-use-prebuilt-build-tools.patch delete mode 100644 patches/ANDROID-gki_defconfig-Add-GKI_HACKS_to_FIX-config.patch delete mode 100644 patches/ANDROID-gki_defconfig-Enable-BPF_JIT-and-BPF_JIT_ALWAYS_ON.patch delete mode 100644 patches/ANDROID-gki_defconfig-Enable-CMA-SLAB_FREELIST-RANDOM-and-HARDENED-on-x86.patch delete mode 100644 patches/ANDROID-gki_defconfig-Enable-CONFIG_DM_SNAPSHOT.patch delete mode 100644 patches/ANDROID-gki_defconfig-Enable-HiSilicon-SoCs.patch delete mode 100644 patches/ANDROID-gki_defconfig-Enable-SERIAL_DEV_BUS.patch delete mode 100644 patches/ANDROID-gki_defconfig-Minimally-enable-EFI.patch delete mode 100644 patches/ANDROID-gki_defconfig-Remove-cuttlefish-specific-configs.patch delete mode 100644 patches/ANDROID-gki_defconfig-Remove-recommended-configs-not-present-on-b1c1.patch delete mode 100644 patches/ANDROID-gki_defconfig-common-configs-for-device-DLKMs.patch delete mode 100644 patches/ANDROID-gki_defconfig-disable-BRIDGE_NETFILTER.patch delete mode 100644 patches/ANDROID-gki_defconfig-disable-CONFIG_LCD_CLASS_DEVICE-module.patch delete mode 100644 patches/ANDROID-gki_defconfig-disable-IP_PNP-ECRYPT_FS.patch delete mode 100644 patches/ANDROID-gki_defconfig-enable-CMA-and-increase-CMA_AREAS.patch delete mode 100644 patches/ANDROID-gki_defconfig-enable-CONFIG_NLS_.patch delete mode 100644 patches/ANDROID-gki_defconfig-enable-CONFIG_PARAVIRT-and-CONFIG_HYPERVISOR_GUEST.patch delete mode 100644 patches/ANDROID-gki_defconfig-enable-CONFIG_QCOM_-COMMAND_DB-RPMH-PDC.patch delete mode 100644 patches/ANDROID-gki_defconfig-enable-CONFIG_SPARSEMEM_VMEMMAP.patch delete mode 100644 patches/ANDROID-gki_defconfig-enable-CONFIG_TIPC.patch delete mode 100644 patches/ANDROID-gki_defconfig-enable-CONFIG_UIO.patch delete mode 100644 patches/ANDROID-gki_defconfig-enable-DMA_CMA.patch delete mode 100644 patches/ANDROID-gki_defconfig-enable-REGULATOR.patch delete mode 100644 patches/ANDROID-gki_defconfig-enable-SLAB_FREELIST_RANDOM-SLAB_FREELIST_HARDENED.patch delete mode 100644 patches/ANDROID-gki_defconfig-enable-accelerated-AES-and-SHA-256.patch delete mode 100644 patches/ANDROID-gki_defconfig-enable-fs-verity.patch delete mode 100644 patches/ANDROID-gki_defconfig-enable-more-configs.patch delete mode 100644 patches/ANDROID-gki_defconfig-enabled-CONFIG_TMPFS-explicitly.patch delete mode 100644 patches/ANDROID-gki_defconfig-initial-config-based-on-cuttlefish_defconfig.patch delete mode 100644 patches/ANDROID-gki_defconfig-more-configs-for-partners.patch delete mode 100644 patches/ANDROID-gki_defconfig-more-generic-configs-for-DLKMs.patch delete mode 100644 patches/ANDROID-gki_defconfig-remove-PWRSEQ_EMMC-and-PWRSEQ_SIMPLE.patch delete mode 100644 patches/ANDROID-gki_defconfig-remove-more-recommended-configs.patch delete mode 100644 patches/ANDROID-gki_defconfig-set-CONFIG_NR_CPUS-32.patch delete mode 100644 patches/ANDROID-gki_defconfig-sync-with-savedefconfig.patch delete mode 100644 patches/ANDROID-gki_defconfig-workaround-to-enable-configs.patch delete mode 100644 patches/ANDROID-init-GKI-add-GKI_HACKS_TO_FIX.patch delete mode 100644 patches/ANDROID-init-GKI-enable-hidden-configs-for-DRM.patch delete mode 100644 patches/ANDROID-init-GKI-enable-hidden-configs-for-GPIO.patch delete mode 100644 patches/ANDROID-init-GKI-enable-hidden-configs-for-SND_SOC.patch delete mode 100644 patches/ANDROID-init-GKI-enable-hidden-configs-for-regmap.patch delete mode 100644 patches/ANDROID-label-cuttlefish-modules-for-gki.patch delete mode 100644 patches/ANDROID-mm-add-a-field-to-store-names-for-private-anonymous-memory.patch delete mode 100644 patches/ANDROID-mmc-core-Add-ignore-mmc-pm-notify-functionality.patch delete mode 100644 patches/ANDROID-mnt-Add-filesystem-private-data-to-mount-points.patch delete mode 100644 patches/ANDROID-mnt-Fix-null-pointer-dereference.patch delete mode 100644 patches/ANDROID-net-enable-wireless-core-features-with-GKI_LEGACY_WEXT_ALLCONFIG.patch delete mode 100644 patches/ANDROID-net-ipv6-autoconf-routes-into-per-device-tables.patch delete mode 100644 patches/ANDROID-net-xfrm-make-PF_KEY-SHA256-use-RFC-compliant-truncation.patch delete mode 100644 patches/ANDROID-netfilter-xt_IDLETIMER-Add-new-netlink-msg-type.patch delete mode 100644 patches/ANDROID-netfilter-xt_quota2-adding-the-original-quota2-from-xtables-addons.patch delete mode 100644 patches/ANDROID-of-Support-CONFIG_CMDLINE_EXTEND-config-option.patch delete mode 100644 patches/ANDROID-power-wakeup_reason-add-an-API-to-log-wakeup-reasons.patch delete mode 100644 patches/ANDROID-proc-Add-proc-uid-directory.patch delete mode 100644 patches/ANDROID-refactor-build.config-files-to-remove-duplication.patch delete mode 100644 patches/ANDROID-sched-Honor-sync-flag-for-energy-aware-wakeups.patch delete mode 100644 patches/ANDROID-sched-Introduce-uclamp-latency-and-boost-wrapper.patch delete mode 100644 patches/ANDROID-sched-Prevent-unnecessary-active-balance-of-single-task-in-sched-group.patch delete mode 100644 patches/ANDROID-sched-Unconditionally-honor-sync-flag-for-energy-aware-wakeups.patch delete mode 100644 patches/ANDROID-sched-Update-max-cpu-capacity-in-case-of-max-frequency-constraints.patch delete mode 100644 patches/ANDROID-sched-core-Add-a-latency-sensitive-flag-to-uclamp.patch delete mode 100644 patches/ANDROID-sched-fair-Also-do-misfit-in-overloaded-groups.patch delete mode 100644 patches/ANDROID-sched-fair-Attempt-to-improve-throughput-for-asym-cap-systems.patch delete mode 100644 patches/ANDROID-sched-fair-Bias-EAS-placement-for-latency.patch delete mode 100644 patches/ANDROID-sched-fair-Don-t-balance-misfits-if-it-would-overload-local-group.patch delete mode 100644 patches/ANDROID-sched-fair-EAS-Add-uclamp-support-to-find_energy_efficient_cpu.patch delete mode 100644 patches/ANDROID-sched-fair-add-arch-scaling-function-for-max-frequency-capping.patch delete mode 100644 patches/ANDROID-sdcardfs-Add-sdcardfs-filesystem.patch delete mode 100644 patches/ANDROID-sdcardfs-Define-magic-value.patch delete mode 100644 patches/ANDROID-sdcardfs-Enable-modular-sdcardfs.patch delete mode 100644 patches/ANDROID-sdcardfs-fix-fall-through-in-param-parsing.patch delete mode 100644 patches/ANDROID-security-perf-Allow-further-restriction-of-perf_event_open.patch delete mode 100644 patches/ANDROID-staging-android-ion-Decouple-ION-page-pooling-from-ION-core.patch delete mode 100644 patches/ANDROID-staging-android-ion-Expose-ion_alloc-to-kernel-space.patch delete mode 100644 patches/ANDROID-staging-ion-Add-support-for-heap-specific-dma_buf_ops.patch delete mode 100644 patches/ANDROID-staging-ion-Build-fix-for-mips.patch delete mode 100644 patches/ANDROID-staging-ion-Fix-uninitialized-variable-warning.patch delete mode 100644 patches/ANDROID-staging-ion-Move-ion-heaps-into-their-own-directory.patch delete mode 100644 patches/ANDROID-staging-ion-Remove-unnecessary-ion-heap-ops.patch delete mode 100644 patches/ANDROID-staging-ion-add-support-for-consistent-heap-ids.patch delete mode 100644 patches/ANDROID-staging-ion-export-ion_free-for-ion_heaps.patch delete mode 100644 patches/ANDROID-staging-ion-fix-off-by-1-error-in-heap-search.patch delete mode 100644 patches/ANDROID-staging-ion-fix-sparse-warning-in-ion-system-heap.patch delete mode 100644 patches/ANDROID-staging-ion-make-cma-heap-a-module.patch delete mode 100644 patches/ANDROID-staging-ion-make-system-and-contig-heaps-modular.patch delete mode 100644 patches/ANDROID-staging-ion-move-uapi-ion.h-to-uapi-linux-ion.h.patch delete mode 100644 patches/ANDROID-staging-ion-refactor-ion-s-buffer-manipulators-into-a-separate-file.patch delete mode 100644 patches/ANDROID-staging-ion-refactor-ion-s-dmabuf-manipulators-into-a-separate-file.patch delete mode 100644 patches/ANDROID-staging-ion-refactor-ion-s-heap-API-into-linux-ion.h.patch delete mode 100644 patches/ANDROID-staging-ion-refactor-ion-s-heap-manipulators-into-a-separate-file.patch delete mode 100644 patches/ANDROID-staging-ion-reserve-specific-heap-ids-for-known-heap-types.patch delete mode 100644 patches/ANDROID-staging-ion-split-system-and-system-contig-heaps.patch delete mode 100644 patches/ANDROID-staging-ion-uapi-match-the-existing-heap-type-enums.patch delete mode 100644 patches/ANDROID-sync-defconfigs-with-savedefconfig.patch delete mode 100644 patches/ANDROID-taskstats-track-fsync-syscalls.patch delete mode 100644 patches/ANDROID-uid_cputime-Adds-accounting-for-the-cputimes-per-uid.patch delete mode 100644 patches/ANDROID-uid_cputime-add-per-uid-IO-usage-accounting.patch delete mode 100644 patches/ANDROID-unconditionally-compile-sig_ok-in-struct-module.patch delete mode 100644 patches/ANDROID-update-arm64-gki_defconfig.patch delete mode 100644 patches/ANDROID-update-gki_defconfig-2.patch delete mode 100644 patches/ANDROID-update-gki_defconfig.patch delete mode 100644 patches/ANDROID-usb-gadget-Fix-dependency-for-f_accessory.patch delete mode 100644 patches/ANDROID-usb-gadget-configfs-Add-Uevent-to-notify-userspace.patch delete mode 100644 patches/ANDROID-usb-gadget-configfs-Add-device-attribute-to-determine-gadget-state.patch delete mode 100644 patches/ANDROID-usb-gadget-configfs-Add-function-devices-to-the-parent.patch delete mode 100644 patches/ANDROID-usb-gadget-configfs-Add-state-attribute-to-android_device.patch delete mode 100644 patches/ANDROID-usb-gadget-configfs-Add-usb_function-ptr-to-fi-struct.patch delete mode 100644 patches/ANDROID-usb-gadget-f_accessory-Add-Android-Accessory-function.patch delete mode 100644 patches/ANDROID-usb-gadget-f_audio_source-New-gadget-driver-for-audio-output.patch delete mode 100644 patches/ANDROID-usb-gadget-f_midi-create-F_midi-device.patch delete mode 100644 patches/ANDROID-usb-gadget-f_midi-set-fi-f-to-NULL-when-free-f_midi-function.patch delete mode 100644 patches/ANDROID-vfs-Add-permission2-for-filesystems-with-per-mount-permissions.patch delete mode 100644 patches/ANDROID-vfs-Add-setattr2-for-filesystems-with-per-mount-permissions.patch delete mode 100644 patches/ANDROID-vfs-add-d_canonical_path-for-stacked-filesystem-support.patch delete mode 100644 patches/ANDROID-x86-Remove-a-useless-warning-message.patch delete mode 100644 patches/ANDROID-x86-gki_defconfig-enable-DMA_CMA.patch delete mode 100644 patches/ANDROID-xfrm-remove-in_compat_syscall-checks.patch delete mode 100644 patches/FROMGIT-driver-core-Add-fwnode_to_dev-to-look-up-device-from-fwnode.patch delete mode 100644 patches/FROMGIT-driver-core-Add-support-for-linking-devices-during-device-addition.patch delete mode 100644 patches/FROMGIT-driver-core-Add-sync_state-driver-bus-callback.patch delete mode 100644 patches/FROMGIT-of-platform-Pause-resume-sync-state-during-init-and-of_platform_populate.patch delete mode 100644 patches/FROMGIT-of-property-Add-functional-dependency-link-from-DT-bindings.patch delete mode 100644 patches/FROMGIT-of-property-Create-device-links-for-all-child-supplier-depencencies.patch delete mode 100644 patches/UPSTREAM-base-soc-Handle-custom-soc-information-sysfs-entries.patch delete mode 100644 patches/series diff --git a/patches b/patches new file mode 120000 index 000000000000..aa800371414b --- /dev/null +++ b/patches @@ -0,0 +1 @@ +../kernel/common-patches/android-mainline/ \ No newline at end of file diff --git a/patches/ANDROID-AVB-error-handler-to-invalidate-vbmeta-partition.patch b/patches/ANDROID-AVB-error-handler-to-invalidate-vbmeta-partition.patch deleted file mode 100644 index 70ae0a1c0d9b..000000000000 --- a/patches/ANDROID-AVB-error-handler-to-invalidate-vbmeta-partition.patch +++ /dev/null @@ -1,332 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: David Zeuthen -Date: Tue, 24 Jan 2017 13:17:01 -0500 -Subject: ANDROID: AVB error handler to invalidate vbmeta partition. - -If androidboot.vbmeta.invalidate_on_error is 'yes' and -androidboot.vbmeta.device is set and points to a device with vbmeta -magic, this header will be overwritten upon an irrecoverable dm-verity -error. The side-effect of this is that the slot will fail to verify on -next reboot, effectively triggering the boot loader to fallback to -another slot. This work both if the vbmeta struct is at the start of a -partition or if there's an AVB footer at the end. - -This code is based on drivers/md/dm-verity-chromeos.c from ChromiumOS. - -Bug: 31622239 -Bug: 120445368 -Test: Manually tested (other arch). -Signed-off-by: David Zeuthen -[astrachan: re-diffed against a kernel without dm-android-verity] -Change-Id: I571b5a75461da38ad832a9bea33c298bef859e26 -Signed-off-by: Alistair Strachan ---- - drivers/md/Kconfig | 11 ++ - drivers/md/Makefile | 4 + - drivers/md/dm-verity-avb.c | 229 ++++++++++++++++++++++++++++++++++ - drivers/md/dm-verity-target.c | 6 +- - drivers/md/dm-verity.h | 2 + - 5 files changed, 251 insertions(+), 1 deletion(-) - create mode 100644 drivers/md/dm-verity-avb.c - -diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig -index aa98953f4462..a744ba61ad21 100644 ---- a/drivers/md/Kconfig -+++ b/drivers/md/Kconfig -@@ -517,6 +517,17 @@ config DM_VERITY_VERIFY_ROOTHASH_SIG - - If unsure, say N. - -+config DM_VERITY_AVB -+ tristate "Support AVB specific verity error behavior" -+ depends on DM_VERITY -+ ---help--- -+ Enables Android Verified Boot platform-specific error -+ behavior. In particular, it will modify the vbmeta partition -+ specified on the kernel command-line when non-transient error -+ occurs (followed by a panic). -+ -+ If unsure, say N. -+ - config DM_VERITY_FEC - bool "Verity forward error correction support" - depends on DM_VERITY -diff --git a/drivers/md/Makefile b/drivers/md/Makefile -index d91a7edcd2ab..356b32d6b158 100644 ---- a/drivers/md/Makefile -+++ b/drivers/md/Makefile -@@ -80,6 +80,10 @@ ifeq ($(CONFIG_DM_UEVENT),y) - dm-mod-objs += dm-uevent.o - endif - -+ifeq ($(CONFIG_DM_VERITY_AVB),y) -+dm-verity-objs += dm-verity-avb.o -+endif -+ - ifeq ($(CONFIG_DM_VERITY_FEC),y) - dm-verity-objs += dm-verity-fec.o - endif -diff --git a/drivers/md/dm-verity-avb.c b/drivers/md/dm-verity-avb.c -new file mode 100644 -index 000000000000..a9f102aa379e ---- /dev/null -+++ b/drivers/md/dm-verity-avb.c -@@ -0,0 +1,229 @@ -+/* -+ * Copyright (C) 2017 Google. -+ * -+ * This file is released under the GPLv2. -+ * -+ * Based on drivers/md/dm-verity-chromeos.c -+ */ -+ -+#include -+#include -+#include -+ -+#define DM_MSG_PREFIX "verity-avb" -+ -+/* Set via module parameters. */ -+static char avb_vbmeta_device[64]; -+static char avb_invalidate_on_error[4]; -+ -+static void invalidate_vbmeta_endio(struct bio *bio) -+{ -+ if (bio->bi_status) -+ DMERR("invalidate_vbmeta_endio: error %d", bio->bi_status); -+ complete(bio->bi_private); -+} -+ -+static int invalidate_vbmeta_submit(struct bio *bio, -+ struct block_device *bdev, -+ int op, int access_last_sector, -+ struct page *page) -+{ -+ DECLARE_COMPLETION_ONSTACK(wait); -+ -+ bio->bi_private = &wait; -+ bio->bi_end_io = invalidate_vbmeta_endio; -+ bio_set_dev(bio, bdev); -+ bio_set_op_attrs(bio, op, REQ_SYNC); -+ -+ bio->bi_iter.bi_sector = 0; -+ if (access_last_sector) { -+ sector_t last_sector; -+ -+ last_sector = (i_size_read(bdev->bd_inode)>>SECTOR_SHIFT) - 1; -+ bio->bi_iter.bi_sector = last_sector; -+ } -+ if (!bio_add_page(bio, page, PAGE_SIZE, 0)) { -+ DMERR("invalidate_vbmeta_submit: bio_add_page error"); -+ return -EIO; -+ } -+ -+ submit_bio(bio); -+ /* Wait up to 2 seconds for completion or fail. */ -+ if (!wait_for_completion_timeout(&wait, msecs_to_jiffies(2000))) -+ return -EIO; -+ return 0; -+} -+ -+static int invalidate_vbmeta(dev_t vbmeta_devt) -+{ -+ int ret = 0; -+ struct block_device *bdev; -+ struct bio *bio; -+ struct page *page; -+ fmode_t dev_mode; -+ /* Ensure we do synchronous unblocked I/O. We may also need -+ * sync_bdev() on completion, but it really shouldn't. -+ */ -+ int access_last_sector = 0; -+ -+ DMINFO("invalidate_vbmeta: acting on device %d:%d", -+ MAJOR(vbmeta_devt), MINOR(vbmeta_devt)); -+ -+ /* First we open the device for reading. */ -+ dev_mode = FMODE_READ | FMODE_EXCL; -+ bdev = blkdev_get_by_dev(vbmeta_devt, dev_mode, -+ invalidate_vbmeta); -+ if (IS_ERR(bdev)) { -+ DMERR("invalidate_kernel: could not open device for reading"); -+ dev_mode = 0; -+ ret = -ENOENT; -+ goto failed_to_read; -+ } -+ -+ bio = bio_alloc(GFP_NOIO, 1); -+ if (!bio) { -+ ret = -ENOMEM; -+ goto failed_bio_alloc; -+ } -+ -+ page = alloc_page(GFP_NOIO); -+ if (!page) { -+ ret = -ENOMEM; -+ goto failed_to_alloc_page; -+ } -+ -+ access_last_sector = 0; -+ ret = invalidate_vbmeta_submit(bio, bdev, REQ_OP_READ, -+ access_last_sector, page); -+ if (ret) { -+ DMERR("invalidate_vbmeta: error reading"); -+ goto failed_to_submit_read; -+ } -+ -+ /* We have a page. Let's make sure it looks right. */ -+ if (memcmp("AVB0", page_address(page), 4) == 0) { -+ /* Stamp it. */ -+ memcpy(page_address(page), "AVE0", 4); -+ DMINFO("invalidate_vbmeta: found vbmeta partition"); -+ } else { -+ /* Could be this is on a AVB footer, check. Also, since the -+ * AVB footer is in the last 64 bytes, adjust for the fact that -+ * we're dealing with 512-byte sectors. -+ */ -+ size_t offset = (1<bi_remaining. -+ */ -+ bio_reset(bio); -+ -+ ret = invalidate_vbmeta_submit(bio, bdev, REQ_OP_WRITE, -+ access_last_sector, page); -+ if (ret) { -+ DMERR("invalidate_vbmeta: error writing"); -+ goto failed_to_submit_write; -+ } -+ -+ DMERR("invalidate_vbmeta: completed."); -+ ret = 0; -+failed_to_submit_write: -+failed_to_write: -+invalid_header: -+ __free_page(page); -+failed_to_submit_read: -+ /* Technically, we'll leak a page with the pending bio, but -+ * we're about to reboot anyway. -+ */ -+failed_to_alloc_page: -+ bio_put(bio); -+failed_bio_alloc: -+ if (dev_mode) -+ blkdev_put(bdev, dev_mode); -+failed_to_read: -+ return ret; -+} -+ -+void dm_verity_avb_error_handler(void) -+{ -+ dev_t dev; -+ -+ DMINFO("AVB error handler called for %s", avb_vbmeta_device); -+ -+ if (strcmp(avb_invalidate_on_error, "yes") != 0) { -+ DMINFO("Not configured to invalidate"); -+ return; -+ } -+ -+ if (avb_vbmeta_device[0] == '\0') { -+ DMERR("avb_vbmeta_device parameter not set"); -+ goto fail_no_dev; -+ } -+ -+ dev = name_to_dev_t(avb_vbmeta_device); -+ if (!dev) { -+ DMERR("No matching partition for device: %s", -+ avb_vbmeta_device); -+ goto fail_no_dev; -+ } -+ -+ invalidate_vbmeta(dev); -+ -+fail_no_dev: -+ ; -+} -+ -+static int __init dm_verity_avb_init(void) -+{ -+ DMINFO("AVB error handler initialized with vbmeta device: %s", -+ avb_vbmeta_device); -+ return 0; -+} -+ -+static void __exit dm_verity_avb_exit(void) -+{ -+} -+ -+module_init(dm_verity_avb_init); -+module_exit(dm_verity_avb_exit); -+ -+MODULE_AUTHOR("David Zeuthen "); -+MODULE_DESCRIPTION("AVB-specific error handler for dm-verity"); -+MODULE_LICENSE("GPL"); -+ -+/* Declare parameter with no module prefix */ -+#undef MODULE_PARAM_PREFIX -+#define MODULE_PARAM_PREFIX "androidboot.vbmeta." -+module_param_string(device, avb_vbmeta_device, sizeof(avb_vbmeta_device), 0); -+module_param_string(invalidate_on_error, avb_invalidate_on_error, -+ sizeof(avb_invalidate_on_error), 0); -diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c -index 4fb33e7562c5..99cee512273f 100644 ---- a/drivers/md/dm-verity-target.c -+++ b/drivers/md/dm-verity-target.c -@@ -251,8 +251,12 @@ static int verity_handle_err(struct dm_verity *v, enum verity_block_type type, - if (v->mode == DM_VERITY_MODE_LOGGING) - return 0; - -- if (v->mode == DM_VERITY_MODE_RESTART) -+ if (v->mode == DM_VERITY_MODE_RESTART) { -+#ifdef CONFIG_DM_VERITY_AVB -+ dm_verity_avb_error_handler(); -+#endif - kernel_restart("dm-verity device corrupted"); -+ } - - return 1; - } -diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h -index 641b9e3a399b..adbd64fde481 100644 ---- a/drivers/md/dm-verity.h -+++ b/drivers/md/dm-verity.h -@@ -128,4 +128,6 @@ extern int verity_hash(struct dm_verity *v, struct ahash_request *req, - extern int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io, - sector_t block, u8 *digest, bool *is_zero); - -+extern void dm_verity_avb_error_handler(void); -+ - #endif /* DM_VERITY_H */ diff --git a/patches/ANDROID-Add-an-IOCTL-to-check-ION-ABI-version.patch b/patches/ANDROID-Add-an-IOCTL-to-check-ION-ABI-version.patch deleted file mode 100644 index bbf4b8f97a65..000000000000 --- a/patches/ANDROID-Add-an-IOCTL-to-check-ION-ABI-version.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hridya Valsaraju -Date: Wed, 2 Oct 2019 14:32:19 -0700 -Subject: ANDROID: Add an IOCTL to check ION ABI version - -Userspace needs a way to detect ION ABI version at runtime to determine -heap IDs. CURRENT_ION_ABI_VERSION is set to 2 considering legacy and -upstream versions as 0 and 1. - -Bug: 140916230 -Test: make - -Signed-off-by: Hridya Valsaraju - -Change-Id: Ie9d9e23c2d8323620832906d33745d599cbce6be ---- - drivers/staging/android/ion/ion.c | 6 ++++++ - include/uapi/linux/ion.h | 7 +++++++ - 2 files changed, 13 insertions(+) - -diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c -index 2c915579f60b..a499a76453ee 100644 ---- a/drivers/staging/android/ion/ion.c -+++ b/drivers/staging/android/ion/ion.c -@@ -27,6 +27,8 @@ - - #include "ion_private.h" - -+#define ION_CURRENT_ABI_VERSION 2 -+ - static struct ion_device *internal_dev; - - /* Entry into ION allocator for rest of the kernel */ -@@ -108,6 +110,7 @@ static int ion_query_heaps(struct ion_heap_query *query) - union ion_ioctl_arg { - struct ion_allocation_data allocation; - struct ion_heap_query query; -+ u32 ion_abi_version; - }; - - static int validate_ioctl_arg(unsigned int cmd, union ion_ioctl_arg *arg) -@@ -169,6 +172,9 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) - case ION_IOC_HEAP_QUERY: - ret = ion_query_heaps(&data.query); - break; -+ case ION_IOC_ABI_VERSION: -+ data.ion_abi_version = ION_CURRENT_ABI_VERSION; -+ break; - default: - return -ENOTTY; - } -diff --git a/include/uapi/linux/ion.h b/include/uapi/linux/ion.h -index ad773e5fa4d2..fdb2eba7f500 100644 ---- a/include/uapi/linux/ion.h -+++ b/include/uapi/linux/ion.h -@@ -159,4 +159,11 @@ struct ion_heap_query { - #define ION_IOC_HEAP_QUERY _IOWR(ION_IOC_MAGIC, 8, \ - struct ion_heap_query) - -+/** -+ * DOC: ION_IOC_HEAP_ABI_VERSION - return ABI version -+ * -+ * Returns ABI version for this driver -+ */ -+#define ION_IOC_ABI_VERSION _IOR(ION_IOC_MAGIC, 9, \ -+ __u32) - #endif /* _UAPI_LINUX_ION_H */ diff --git a/patches/ANDROID-Add-initial-rockpi4_defconfig.patch b/patches/ANDROID-Add-initial-rockpi4_defconfig.patch deleted file mode 100644 index 9dd50e8ff11f..000000000000 --- a/patches/ANDROID-Add-initial-rockpi4_defconfig.patch +++ /dev/null @@ -1,561 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tristan Muntsinger -Date: Thu, 25 Jul 2019 13:48:04 -0700 -Subject: ANDROID: Add initial rockpi4_defconfig - -This is for the Rock Pi 4B board from Radxa with Rockchip's RK3399. - -Bug: 118442619 -Change-Id: If2ba4198ef268e5b249e909b1987d52f1c8d0def -Signed-off-by: Tristan Muntsinger ---- - arch/arm64/configs/rockpi4_defconfig | 540 +++++++++++++++++++++++++++ - 1 file changed, 540 insertions(+) - create mode 100644 arch/arm64/configs/rockpi4_defconfig - -diff --git a/arch/arm64/configs/rockpi4_defconfig b/arch/arm64/configs/rockpi4_defconfig -new file mode 100644 -index 000000000000..6d0cf70f3757 ---- /dev/null -+++ b/arch/arm64/configs/rockpi4_defconfig -@@ -0,0 +1,540 @@ -+CONFIG_AUDIT=y -+CONFIG_NO_HZ=y -+CONFIG_HIGH_RES_TIMERS=y -+CONFIG_PREEMPT=y -+CONFIG_TASKSTATS=y -+CONFIG_TASK_XACCT=y -+CONFIG_TASK_IO_ACCOUNTING=y -+CONFIG_PSI=y -+CONFIG_IKCONFIG=y -+CONFIG_IKCONFIG_PROC=y -+CONFIG_MEMCG=y -+CONFIG_MEMCG_SWAP=y -+CONFIG_BLK_CGROUP=y -+CONFIG_RT_GROUP_SCHED=y -+CONFIG_CGROUP_FREEZER=y -+CONFIG_CPUSETS=y -+CONFIG_CGROUP_CPUACCT=y -+CONFIG_CGROUP_BPF=y -+CONFIG_SCHED_AUTOGROUP=y -+CONFIG_BLK_DEV_INITRD=y -+# CONFIG_RD_BZIP2 is not set -+# CONFIG_RD_LZMA is not set -+# CONFIG_RD_XZ is not set -+# CONFIG_RD_LZO is not set -+# CONFIG_RD_LZ4 is not set -+# CONFIG_SYSFS_SYSCALL is not set -+CONFIG_FHANDLE=y -+CONFIG_KALLSYMS_ALL=y -+CONFIG_BPF_SYSCALL=y -+# CONFIG_RSEQ is not set -+CONFIG_EMBEDDED=y -+# CONFIG_VM_EVENT_COUNTERS is not set -+# CONFIG_COMPAT_BRK is not set -+# CONFIG_SLAB_MERGE_DEFAULT is not set -+CONFIG_SLAB_FREELIST_RANDOM=y -+CONFIG_SLAB_FREELIST_HARDENED=y -+CONFIG_PROFILING=y -+CONFIG_ARCH_ROCKCHIP=y -+CONFIG_SCHED_MC=y -+CONFIG_SECCOMP=y -+CONFIG_PARAVIRT=y -+CONFIG_COMPAT=y -+CONFIG_ARMV8_DEPRECATED=y -+CONFIG_SWP_EMULATION=y -+CONFIG_CP15_BARRIER_EMULATION=y -+CONFIG_SETEND_EMULATION=y -+CONFIG_RANDOMIZE_BASE=y -+CONFIG_CMDLINE="" -+# CONFIG_CMDLINE_FORCE is not set -+# CONFIG_EFI is not set -+CONFIG_PM_WAKELOCKS=y -+CONFIG_PM_WAKELOCKS_LIMIT=0 -+# CONFIG_PM_WAKELOCKS_GC is not set -+CONFIG_ENERGY_MODEL=y -+CONFIG_CPU_IDLE=y -+CONFIG_ARM_CPUIDLE=y -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_TIMES=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y -+CONFIG_CPU_FREQ_GOV_POWERSAVE=y -+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -+CONFIG_ARM_SCPI_CPUFREQ=y -+CONFIG_ARM_SCMI_CPUFREQ=y -+CONFIG_ARM_SCMI_PROTOCOL=y -+# CONFIG_ARM_SCMI_POWER_DOMAIN is not set -+CONFIG_ARM_SCPI_PROTOCOL=y -+# CONFIG_ARM_SCPI_POWER_DOMAIN is not set -+CONFIG_VIRTUALIZATION=y -+CONFIG_KVM=y -+CONFIG_VHOST_VSOCK=y -+CONFIG_ARM64_CRYPTO=y -+CONFIG_CRYPTO_AES_ARM64=y -+CONFIG_KPROBES=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+CONFIG_MODVERSIONS=y -+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -+CONFIG_BINFMT_MISC=y -+# CONFIG_SPARSEMEM_VMEMMAP is not set -+CONFIG_MEMORY_HOTPLUG=y -+CONFIG_TRANSPARENT_HUGEPAGE=y -+CONFIG_CMA=y -+CONFIG_CMA_AREAS=16 -+CONFIG_ZSMALLOC=y -+CONFIG_NET=y -+CONFIG_PACKET=y -+CONFIG_UNIX=y -+CONFIG_XFRM_USER=y -+CONFIG_XFRM_INTERFACE=y -+CONFIG_XFRM_STATISTICS=y -+CONFIG_NET_KEY=y -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_PNP=y -+CONFIG_NET_IPGRE_DEMUX=y -+CONFIG_NET_IPVTI=y -+CONFIG_INET_ESP=y -+CONFIG_INET_UDP_DIAG=y -+CONFIG_INET_DIAG_DESTROY=y -+CONFIG_IPV6_ROUTER_PREF=y -+CONFIG_IPV6_ROUTE_INFO=y -+CONFIG_IPV6_OPTIMISTIC_DAD=y -+CONFIG_INET6_ESP=y -+CONFIG_INET6_IPCOMP=y -+CONFIG_IPV6_MIP6=y -+CONFIG_IPV6_VTI=y -+CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_NETFILTER=y -+CONFIG_NF_CONNTRACK=y -+CONFIG_NF_CONNTRACK_SECMARK=y -+CONFIG_NF_CONNTRACK_EVENTS=y -+CONFIG_NF_CONNTRACK_AMANDA=y -+CONFIG_NF_CONNTRACK_FTP=y -+CONFIG_NF_CONNTRACK_H323=y -+CONFIG_NF_CONNTRACK_IRC=y -+CONFIG_NF_CONNTRACK_NETBIOS_NS=y -+CONFIG_NF_CONNTRACK_PPTP=y -+CONFIG_NF_CONNTRACK_SANE=y -+CONFIG_NF_CONNTRACK_TFTP=y -+CONFIG_NF_CT_NETLINK=y -+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y -+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y -+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y -+CONFIG_NETFILTER_XT_TARGET_CT=y -+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y -+CONFIG_NETFILTER_XT_TARGET_MARK=y -+CONFIG_NETFILTER_XT_TARGET_NFLOG=y -+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y -+CONFIG_NETFILTER_XT_TARGET_TPROXY=y -+CONFIG_NETFILTER_XT_TARGET_TRACE=y -+CONFIG_NETFILTER_XT_TARGET_SECMARK=y -+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y -+CONFIG_NETFILTER_XT_MATCH_BPF=y -+CONFIG_NETFILTER_XT_MATCH_COMMENT=y -+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y -+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y -+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y -+CONFIG_NETFILTER_XT_MATCH_HELPER=y -+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y -+CONFIG_NETFILTER_XT_MATCH_LENGTH=y -+CONFIG_NETFILTER_XT_MATCH_LIMIT=y -+CONFIG_NETFILTER_XT_MATCH_MAC=y -+CONFIG_NETFILTER_XT_MATCH_MARK=y -+CONFIG_NETFILTER_XT_MATCH_OWNER=y -+CONFIG_NETFILTER_XT_MATCH_POLICY=y -+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y -+CONFIG_NETFILTER_XT_MATCH_QUOTA=y -+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y -+CONFIG_NETFILTER_XT_MATCH_SOCKET=y -+CONFIG_NETFILTER_XT_MATCH_STATE=y -+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y -+CONFIG_NETFILTER_XT_MATCH_STRING=y -+CONFIG_NETFILTER_XT_MATCH_TIME=y -+CONFIG_NETFILTER_XT_MATCH_U32=y -+CONFIG_IP_NF_IPTABLES=y -+CONFIG_IP_NF_MATCH_ECN=y -+CONFIG_IP_NF_MATCH_TTL=y -+CONFIG_IP_NF_FILTER=y -+CONFIG_IP_NF_TARGET_REJECT=y -+CONFIG_IP_NF_NAT=y -+CONFIG_IP_NF_TARGET_MASQUERADE=y -+CONFIG_IP_NF_TARGET_NETMAP=y -+CONFIG_IP_NF_TARGET_REDIRECT=y -+CONFIG_IP_NF_MANGLE=y -+CONFIG_IP_NF_RAW=y -+CONFIG_IP_NF_SECURITY=y -+CONFIG_IP_NF_ARPTABLES=y -+CONFIG_IP_NF_ARPFILTER=y -+CONFIG_IP_NF_ARP_MANGLE=y -+CONFIG_IP6_NF_IPTABLES=y -+CONFIG_IP6_NF_MATCH_RPFILTER=y -+CONFIG_IP6_NF_FILTER=y -+CONFIG_IP6_NF_TARGET_REJECT=y -+CONFIG_IP6_NF_MANGLE=y -+CONFIG_IP6_NF_RAW=y -+CONFIG_L2TP=y -+CONFIG_BRIDGE=y -+CONFIG_NET_SCHED=y -+CONFIG_NET_SCH_HTB=y -+CONFIG_NET_SCH_INGRESS=y -+CONFIG_NET_CLS_U32=y -+CONFIG_NET_CLS_BPF=y -+CONFIG_NET_EMATCH=y -+CONFIG_NET_EMATCH_U32=y -+CONFIG_NET_CLS_ACT=y -+CONFIG_VSOCKETS=y -+CONFIG_VIRTIO_VSOCKETS=y -+CONFIG_BT=y -+CONFIG_CFG80211=y -+# CONFIG_CFG80211_DEFAULT_PS is not set -+# CONFIG_CFG80211_CRDA_SUPPORT is not set -+CONFIG_MAC80211=y -+# CONFIG_MAC80211_RC_MINSTREL is not set -+CONFIG_RFKILL=y -+CONFIG_PCI=y -+CONFIG_PCI_HOST_GENERIC=y -+CONFIG_DEVTMPFS=y -+# CONFIG_ALLOW_DEV_COREDUMP is not set -+CONFIG_DEBUG_DEVRES=y -+CONFIG_ZRAM=y -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_SIZE=8192 -+CONFIG_VIRTIO_BLK=y -+CONFIG_UID_SYS_STATS=y -+CONFIG_SCSI=y -+# CONFIG_SCSI_PROC_FS is not set -+CONFIG_BLK_DEV_SD=y -+CONFIG_SCSI_UFSHCD=y -+CONFIG_SCSI_UFSHCD_PLATFORM=y -+CONFIG_MD=y -+CONFIG_BLK_DEV_DM=y -+CONFIG_DM_CRYPT=y -+CONFIG_DM_UEVENT=y -+CONFIG_DM_VERITY=y -+CONFIG_DM_VERITY_AVB=y -+CONFIG_DM_VERITY_FEC=y -+CONFIG_DM_BOW=y -+CONFIG_NETDEVICES=y -+CONFIG_TUN=y -+CONFIG_VIRTIO_NET=y -+# CONFIG_NET_VENDOR_3COM is not set -+# CONFIG_NET_VENDOR_ADAPTEC is not set -+# CONFIG_NET_VENDOR_AGERE is not set -+# CONFIG_NET_VENDOR_ALACRITECH is not set -+# CONFIG_NET_VENDOR_ALTEON is not set -+# CONFIG_NET_VENDOR_AMAZON is not set -+# CONFIG_NET_VENDOR_AMD is not set -+# CONFIG_NET_VENDOR_AQUANTIA is not set -+# CONFIG_NET_VENDOR_ARC is not set -+# CONFIG_NET_VENDOR_ATHEROS is not set -+# CONFIG_NET_VENDOR_AURORA is not set -+# CONFIG_NET_VENDOR_BROADCOM is not set -+# CONFIG_NET_VENDOR_BROCADE is not set -+# CONFIG_NET_VENDOR_CADENCE is not set -+# CONFIG_NET_VENDOR_CAVIUM is not set -+# CONFIG_NET_VENDOR_CHELSIO is not set -+# CONFIG_NET_VENDOR_CISCO is not set -+# CONFIG_NET_VENDOR_CORTINA is not set -+# CONFIG_NET_VENDOR_DEC is not set -+# CONFIG_NET_VENDOR_DLINK is not set -+# CONFIG_NET_VENDOR_EMULEX is not set -+# CONFIG_NET_VENDOR_EZCHIP is not set -+# CONFIG_NET_VENDOR_HISILICON is not set -+# CONFIG_NET_VENDOR_HP is not set -+# CONFIG_NET_VENDOR_HUAWEI is not set -+# CONFIG_NET_VENDOR_INTEL is not set -+# CONFIG_NET_VENDOR_MARVELL is not set -+# CONFIG_NET_VENDOR_MELLANOX is not set -+# CONFIG_NET_VENDOR_MICREL is not set -+# CONFIG_NET_VENDOR_MICROCHIP is not set -+# CONFIG_NET_VENDOR_MICROSEMI is not set -+# CONFIG_NET_VENDOR_MYRI is not set -+# CONFIG_NET_VENDOR_NATSEMI is not set -+# CONFIG_NET_VENDOR_NETERION is not set -+# CONFIG_NET_VENDOR_NETRONOME is not set -+# CONFIG_NET_VENDOR_NI is not set -+# CONFIG_NET_VENDOR_NVIDIA is not set -+# CONFIG_NET_VENDOR_OKI is not set -+# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -+# CONFIG_NET_VENDOR_QLOGIC is not set -+# CONFIG_NET_VENDOR_QUALCOMM is not set -+# CONFIG_NET_VENDOR_RDC is not set -+# CONFIG_NET_VENDOR_REALTEK is not set -+# CONFIG_NET_VENDOR_RENESAS is not set -+# CONFIG_NET_VENDOR_ROCKER is not set -+# CONFIG_NET_VENDOR_SAMSUNG is not set -+# CONFIG_NET_VENDOR_SEEQ is not set -+# CONFIG_NET_VENDOR_SOLARFLARE is not set -+# CONFIG_NET_VENDOR_SILAN is not set -+# CONFIG_NET_VENDOR_SIS is not set -+# CONFIG_NET_VENDOR_SMSC is not set -+# CONFIG_NET_VENDOR_SOCIONEXT is not set -+CONFIG_STMMAC_ETH=y -+# CONFIG_DWMAC_GENERIC is not set -+# CONFIG_NET_VENDOR_SUN is not set -+# CONFIG_NET_VENDOR_SYNOPSYS is not set -+# CONFIG_NET_VENDOR_TEHUTI is not set -+# CONFIG_NET_VENDOR_TI is not set -+# CONFIG_NET_VENDOR_VIA is not set -+# CONFIG_NET_VENDOR_WIZNET is not set -+CONFIG_ROCKCHIP_PHY=y -+CONFIG_PPP=y -+CONFIG_PPP_BSDCOMP=y -+CONFIG_PPP_DEFLATE=y -+CONFIG_PPP_MPPE=y -+CONFIG_PPTP=y -+CONFIG_PPPOL2TP=y -+CONFIG_USB_RTL8152=y -+CONFIG_USB_USBNET=y -+# CONFIG_USB_NET_AX8817X is not set -+# CONFIG_USB_NET_AX88179_178A is not set -+# CONFIG_USB_NET_CDCETHER is not set -+# CONFIG_USB_NET_CDC_NCM is not set -+# CONFIG_USB_NET_NET1080 is not set -+# CONFIG_USB_NET_CDC_SUBSET is not set -+# CONFIG_USB_NET_ZAURUS is not set -+# CONFIG_WLAN_VENDOR_ADMTEK is not set -+# CONFIG_WLAN_VENDOR_ATH is not set -+# CONFIG_WLAN_VENDOR_ATMEL is not set -+# CONFIG_WLAN_VENDOR_BROADCOM is not set -+# CONFIG_WLAN_VENDOR_CISCO is not set -+# CONFIG_WLAN_VENDOR_INTEL is not set -+# CONFIG_WLAN_VENDOR_INTERSIL is not set -+# CONFIG_WLAN_VENDOR_MARVELL is not set -+# CONFIG_WLAN_VENDOR_MEDIATEK is not set -+# CONFIG_WLAN_VENDOR_RALINK is not set -+# CONFIG_WLAN_VENDOR_REALTEK is not set -+# CONFIG_WLAN_VENDOR_RSI is not set -+# CONFIG_WLAN_VENDOR_ST is not set -+# CONFIG_WLAN_VENDOR_TI is not set -+# CONFIG_WLAN_VENDOR_ZYDAS is not set -+# CONFIG_WLAN_VENDOR_QUANTENNA is not set -+CONFIG_VIRT_WIFI=y -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_JOYSTICK=y -+CONFIG_INPUT_MISC=y -+CONFIG_INPUT_UINPUT=y -+# CONFIG_VT is not set -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_DEVMEM is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_EXAR is not set -+CONFIG_SERIAL_8250_NR_UARTS=48 -+CONFIG_SERIAL_8250_EXTENDED=y -+CONFIG_SERIAL_8250_MANY_PORTS=y -+CONFIG_SERIAL_8250_SHARE_IRQ=y -+CONFIG_SERIAL_8250_DW=y -+CONFIG_SERIAL_OF_PLATFORM=y -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_VIRTIO_CONSOLE=y -+CONFIG_HW_RANDOM=y -+CONFIG_HW_RANDOM_VIRTIO=y -+# CONFIG_HW_RANDOM_CAVIUM is not set -+# CONFIG_DEVPORT is not set -+# CONFIG_I2C_COMPAT is not set -+CONFIG_I2C_MUX_PINCTRL=y -+CONFIG_I2C_DEMUX_PINCTRL=y -+# CONFIG_I2C_HELPER_AUTO is not set -+CONFIG_I2C_DESIGNWARE_PLATFORM=y -+CONFIG_I2C_DESIGNWARE_SLAVE=y -+CONFIG_I2C_RK3X=y -+CONFIG_SPI=y -+CONFIG_SPI_ROCKCHIP=y -+CONFIG_SPMI=y -+CONFIG_DEBUG_PINCTRL=y -+CONFIG_PINCTRL_AMD=y -+CONFIG_PINCTRL_SINGLE=y -+CONFIG_PINCTRL_RK805=y -+CONFIG_GPIO_SYSFS=y -+CONFIG_GPIO_GENERIC_PLATFORM=y -+CONFIG_POWER_AVS=y -+CONFIG_ROCKCHIP_IODOMAIN=y -+CONFIG_POWER_RESET_GPIO=y -+CONFIG_POWER_RESET_GPIO_RESTART=y -+CONFIG_POWER_RESET_RESTART=y -+CONFIG_POWER_RESET_SYSCON=y -+CONFIG_POWER_RESET_SYSCON_POWEROFF=y -+CONFIG_SYSCON_REBOOT_MODE=y -+# CONFIG_HWMON is not set -+CONFIG_THERMAL=y -+CONFIG_THERMAL_GOV_USER_SPACE=y -+CONFIG_CPU_THERMAL=y -+CONFIG_DEVFREQ_THERMAL=y -+CONFIG_ROCKCHIP_THERMAL=y -+CONFIG_WATCHDOG=y -+CONFIG_WATCHDOG_PRETIMEOUT_GOV=y -+# CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP is not set -+CONFIG_DW_WATCHDOG=y -+CONFIG_MFD_ACT8945A=y -+CONFIG_MFD_RK808=y -+CONFIG_REGULATOR=y -+CONFIG_REGULATOR_DEBUG=y -+CONFIG_REGULATOR_FIXED_VOLTAGE=y -+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y -+CONFIG_REGULATOR_USERSPACE_CONSUMER=y -+CONFIG_REGULATOR_GPIO=y -+CONFIG_REGULATOR_PWM=y -+CONFIG_REGULATOR_RK808=y -+CONFIG_REGULATOR_VCTRL=y -+CONFIG_MEDIA_SUPPORT=y -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+CONFIG_MEDIA_CONTROLLER=y -+CONFIG_VIDEO_V4L2_SUBDEV_API=y -+# CONFIG_VGA_ARB is not set -+CONFIG_DRM=y -+# CONFIG_DRM_FBDEV_EMULATION is not set -+CONFIG_DRM_ROCKCHIP=y -+CONFIG_ROCKCHIP_DW_HDMI=y -+CONFIG_DRM_VIRTIO_GPU=y -+# CONFIG_LCD_CLASS_DEVICE is not set -+CONFIG_BACKLIGHT_CLASS_DEVICE=y -+# CONFIG_BACKLIGHT_GENERIC is not set -+CONFIG_SOUND=y -+CONFIG_SND=y -+CONFIG_SND_HRTIMER=y -+CONFIG_SND_DYNAMIC_MINORS=y -+# CONFIG_SND_SUPPORT_OLD_API is not set -+# CONFIG_SND_VERBOSE_PROCFS is not set -+# CONFIG_SND_DRIVERS is not set -+CONFIG_SND_INTEL8X0=y -+CONFIG_SND_USB_AUDIO=y -+CONFIG_SND_SOC=y -+CONFIG_SND_SOC_TS3A227E=y -+CONFIG_HIDRAW=y -+CONFIG_UHID=y -+CONFIG_HID_APPLE=y -+CONFIG_HID_ELECOM=y -+CONFIG_HID_MAGICMOUSE=y -+CONFIG_HID_MICROSOFT=y -+CONFIG_HID_MULTITOUCH=y -+CONFIG_USB_HIDDEV=y -+CONFIG_USB=y -+CONFIG_USB_OTG=y -+CONFIG_USB_OTG_FSM=y -+CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_EHCI_ROOT_HUB_TT=y -+CONFIG_USB_EHCI_HCD_PLATFORM=y -+CONFIG_USB_OHCI_HCD=y -+# CONFIG_USB_OHCI_HCD_PCI is not set -+CONFIG_USB_OHCI_HCD_PLATFORM=y -+CONFIG_USB_GADGET=y -+CONFIG_USB_CONFIGFS=y -+CONFIG_USB_CONFIGFS_UEVENT=y -+CONFIG_USB_CONFIGFS_F_FS=y -+CONFIG_USB_CONFIGFS_F_ACC=y -+CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y -+CONFIG_USB_CONFIGFS_F_MIDI=y -+CONFIG_MMC=y -+# CONFIG_PWRSEQ_EMMC is not set -+# CONFIG_PWRSEQ_SIMPLE is not set -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y -+CONFIG_MMC_SDHCI_OF_ARASAN=y -+CONFIG_MMC_SDHCI_OF_DWCMSHC=y -+CONFIG_MMC_DW=y -+CONFIG_MMC_DW_ROCKCHIP=y -+CONFIG_MMC_CQHCI=y -+CONFIG_NEW_LEDS=y -+CONFIG_LEDS_CLASS=y -+CONFIG_LEDS_TRIGGERS=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_SYSTOHC is not set -+CONFIG_RTC_DRV_RK808=y -+CONFIG_RTC_DRV_PL030=y -+CONFIG_RTC_DRV_PL031=y -+CONFIG_DMADEVICES=y -+CONFIG_PL330_DMA=y -+CONFIG_VIRTIO_PCI=y -+# CONFIG_VIRTIO_PCI_LEGACY is not set -+CONFIG_VIRTIO_INPUT=y -+CONFIG_VIRTIO_MMIO=y -+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y -+CONFIG_STAGING=y -+CONFIG_ASHMEM=y -+CONFIG_ANDROID_VSOC=y -+CONFIG_ION=y -+CONFIG_COMMON_CLK_RK808=y -+CONFIG_COMMON_CLK_SCPI=y -+# CONFIG_COMMON_CLK_XGENE is not set -+CONFIG_HWSPINLOCK=y -+# CONFIG_FSL_ERRATUM_A008585 is not set -+# CONFIG_HISILICON_ERRATUM_161010101 is not set -+CONFIG_MAILBOX=y -+CONFIG_ROCKCHIP_MBOX=y -+CONFIG_ROCKCHIP_IOMMU=y -+CONFIG_ARM_SMMU=y -+CONFIG_ROCKCHIP_PM_DOMAINS=y -+CONFIG_DEVFREQ_GOV_PERFORMANCE=y -+CONFIG_DEVFREQ_GOV_POWERSAVE=y -+CONFIG_DEVFREQ_GOV_USERSPACE=y -+CONFIG_DEVFREQ_GOV_PASSIVE=y -+CONFIG_ARM_RK3399_DMC_DEVFREQ=y -+CONFIG_PWM=y -+CONFIG_PWM_ROCKCHIP=y -+CONFIG_PHY_ROCKCHIP_EMMC=y -+CONFIG_PHY_ROCKCHIP_INNO_HDMI=y -+CONFIG_PHY_ROCKCHIP_INNO_USB2=y -+CONFIG_PHY_ROCKCHIP_USB=y -+CONFIG_ANDROID=y -+CONFIG_ANDROID_BINDER_IPC=y -+CONFIG_ROCKCHIP_EFUSE=y -+CONFIG_INTERCONNECT=y -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_FS_SECURITY=y -+CONFIG_F2FS_FS=y -+CONFIG_F2FS_FS_SECURITY=y -+CONFIG_FS_ENCRYPTION=y -+# CONFIG_DNOTIFY is not set -+CONFIG_QUOTA=y -+CONFIG_QFMT_V2=y -+CONFIG_FUSE_FS=y -+CONFIG_OVERLAY_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_ECRYPT_FS=y -+CONFIG_PSTORE=y -+CONFIG_PSTORE_CONSOLE=y -+CONFIG_PSTORE_RAM=y -+CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y -+CONFIG_SECURITY=y -+CONFIG_SECURITY_NETWORK=y -+CONFIG_HARDENED_USERCOPY=y -+CONFIG_SECURITY_SELINUX=y -+CONFIG_CRYPTO_ADIANTUM=y -+CONFIG_CRYPTO_MD4=y -+CONFIG_CRYPTO_SHA512=y -+CONFIG_CRYPTO_LZ4=y -+CONFIG_CRYPTO_ZSTD=y -+CONFIG_CRYPTO_ANSI_CPRNG=y -+CONFIG_CRYPTO_DEV_ROCKCHIP=y -+CONFIG_CRYPTO_DEV_VIRTIO=y -+CONFIG_CRC_CCITT=y -+CONFIG_CRC8=y -+CONFIG_XZ_DEC=y -+CONFIG_DMA_CMA=y -+CONFIG_PRINTK_TIME=y -+CONFIG_DEBUG_INFO=y -+# CONFIG_ENABLE_MUST_CHECK is not set -+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set -+CONFIG_MAGIC_SYSRQ=y -+CONFIG_DEBUG_STACK_USAGE=y -+CONFIG_DEBUG_MEMORY_INIT=y -+CONFIG_SOFTLOCKUP_DETECTOR=y -+# CONFIG_DETECT_HUNG_TASK is not set -+CONFIG_PANIC_TIMEOUT=5 -+CONFIG_SCHEDSTATS=y -+CONFIG_FUNCTION_TRACER=y -+# CONFIG_RUNTIME_TESTING_MENU is not set -+CONFIG_CORESIGHT=y -+CONFIG_CORESIGHT_STM=y diff --git a/patches/ANDROID-Add-initial-x86_64-gki_defconfig.patch b/patches/ANDROID-Add-initial-x86_64-gki_defconfig.patch deleted file mode 100644 index 6e59028e8c33..000000000000 --- a/patches/ANDROID-Add-initial-x86_64-gki_defconfig.patch +++ /dev/null @@ -1,382 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Fri, 17 May 2019 16:52:29 -0700 -Subject: ANDROID: Add initial x86_64 gki_defconfig - -That is a copy from the aarch64 gki_defconfig. - -To be able to build in this configuration, - - + CONFIG_UNWINDER_FRAME_POINTER=y - -was necessary. - -Bug: 132113225 -Bug: 132629930 -Change-Id: I685ccea29efc7ba14f7b0a24f41983e37203f9a2 -Signed-off-by: Ram Muthiah -Signed-off-by: Matthias Maennich ---- - arch/x86/configs/gki_defconfig | 328 +++++++++++++++++++++++++++++++++ - build.config.gki.x86_64 | 17 ++ - 2 files changed, 345 insertions(+) - create mode 100644 arch/x86/configs/gki_defconfig - create mode 100644 build.config.gki.x86_64 - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -new file mode 100644 -index 000000000000..18ba312d0a60 ---- /dev/null -+++ b/arch/x86/configs/gki_defconfig -@@ -0,0 +1,328 @@ -+CONFIG_AUDIT=y -+CONFIG_NO_HZ=y -+CONFIG_HIGH_RES_TIMERS=y -+CONFIG_PREEMPT=y -+CONFIG_TASKSTATS=y -+CONFIG_TASK_XACCT=y -+CONFIG_TASK_IO_ACCOUNTING=y -+CONFIG_PSI=y -+CONFIG_IKCONFIG=y -+CONFIG_IKCONFIG_PROC=y -+CONFIG_MEMCG=y -+CONFIG_MEMCG_SWAP=y -+CONFIG_RT_GROUP_SCHED=y -+CONFIG_CGROUP_FREEZER=y -+CONFIG_CGROUP_CPUACCT=y -+CONFIG_CGROUP_BPF=y -+CONFIG_SCHED_AUTOGROUP=y -+CONFIG_BLK_DEV_INITRD=y -+# CONFIG_RD_BZIP2 is not set -+# CONFIG_RD_LZMA is not set -+# CONFIG_RD_XZ is not set -+# CONFIG_RD_LZO is not set -+# CONFIG_RD_LZ4 is not set -+# CONFIG_SYSFS_SYSCALL is not set -+# CONFIG_FHANDLE is not set -+CONFIG_KALLSYMS_ALL=y -+CONFIG_BPF_SYSCALL=y -+# CONFIG_RSEQ is not set -+CONFIG_EMBEDDED=y -+# CONFIG_VM_EVENT_COUNTERS is not set -+# CONFIG_COMPAT_BRK is not set -+# CONFIG_SLAB_MERGE_DEFAULT is not set -+CONFIG_PROFILING=y -+CONFIG_PM_WAKELOCKS=y -+CONFIG_PM_WAKELOCKS_LIMIT=0 -+# CONFIG_PM_WAKELOCKS_GC is not set -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_TIMES=y -+CONFIG_CPU_FREQ_GOV_POWERSAVE=y -+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -+CONFIG_KPROBES=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+CONFIG_MODVERSIONS=y -+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -+# CONFIG_SPARSEMEM_VMEMMAP is not set -+CONFIG_TRANSPARENT_HUGEPAGE=y -+CONFIG_ZSMALLOC=y -+CONFIG_NET=y -+CONFIG_PACKET=y -+CONFIG_UNIX=y -+CONFIG_XFRM_USER=y -+CONFIG_XFRM_INTERFACE=y -+CONFIG_XFRM_STATISTICS=y -+CONFIG_NET_KEY=y -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_NET_IPGRE_DEMUX=y -+CONFIG_NET_IPVTI=y -+CONFIG_INET_ESP=y -+CONFIG_INET_UDP_DIAG=y -+CONFIG_INET_DIAG_DESTROY=y -+CONFIG_IPV6_ROUTER_PREF=y -+CONFIG_IPV6_ROUTE_INFO=y -+CONFIG_IPV6_OPTIMISTIC_DAD=y -+CONFIG_INET6_ESP=y -+CONFIG_INET6_IPCOMP=y -+CONFIG_IPV6_MIP6=y -+CONFIG_IPV6_VTI=y -+CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_NETFILTER=y -+CONFIG_NF_CONNTRACK=y -+CONFIG_NF_CONNTRACK_SECMARK=y -+CONFIG_NF_CONNTRACK_EVENTS=y -+CONFIG_NF_CONNTRACK_AMANDA=y -+CONFIG_NF_CONNTRACK_FTP=y -+CONFIG_NF_CONNTRACK_H323=y -+CONFIG_NF_CONNTRACK_IRC=y -+CONFIG_NF_CONNTRACK_NETBIOS_NS=y -+CONFIG_NF_CONNTRACK_PPTP=y -+CONFIG_NF_CONNTRACK_SANE=y -+CONFIG_NF_CONNTRACK_TFTP=y -+CONFIG_NF_CT_NETLINK=y -+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y -+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y -+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y -+CONFIG_NETFILTER_XT_TARGET_CT=y -+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y -+CONFIG_NETFILTER_XT_TARGET_MARK=y -+CONFIG_NETFILTER_XT_TARGET_NFLOG=y -+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y -+CONFIG_NETFILTER_XT_TARGET_TPROXY=y -+CONFIG_NETFILTER_XT_TARGET_TRACE=y -+CONFIG_NETFILTER_XT_TARGET_SECMARK=y -+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y -+CONFIG_NETFILTER_XT_MATCH_BPF=y -+CONFIG_NETFILTER_XT_MATCH_COMMENT=y -+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y -+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y -+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y -+CONFIG_NETFILTER_XT_MATCH_HELPER=y -+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y -+CONFIG_NETFILTER_XT_MATCH_LENGTH=y -+CONFIG_NETFILTER_XT_MATCH_LIMIT=y -+CONFIG_NETFILTER_XT_MATCH_MAC=y -+CONFIG_NETFILTER_XT_MATCH_MARK=y -+CONFIG_NETFILTER_XT_MATCH_OWNER=y -+CONFIG_NETFILTER_XT_MATCH_POLICY=y -+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y -+CONFIG_NETFILTER_XT_MATCH_QUOTA=y -+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y -+CONFIG_NETFILTER_XT_MATCH_SOCKET=y -+CONFIG_NETFILTER_XT_MATCH_STATE=y -+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y -+CONFIG_NETFILTER_XT_MATCH_STRING=y -+CONFIG_NETFILTER_XT_MATCH_TIME=y -+CONFIG_NETFILTER_XT_MATCH_U32=y -+CONFIG_IP_NF_IPTABLES=y -+CONFIG_IP_NF_MATCH_ECN=y -+CONFIG_IP_NF_MATCH_TTL=y -+CONFIG_IP_NF_FILTER=y -+CONFIG_IP_NF_TARGET_REJECT=y -+CONFIG_IP_NF_NAT=y -+CONFIG_IP_NF_TARGET_MASQUERADE=y -+CONFIG_IP_NF_TARGET_NETMAP=y -+CONFIG_IP_NF_TARGET_REDIRECT=y -+CONFIG_IP_NF_MANGLE=y -+CONFIG_IP_NF_RAW=y -+CONFIG_IP_NF_SECURITY=y -+CONFIG_IP_NF_ARPTABLES=y -+CONFIG_IP_NF_ARPFILTER=y -+CONFIG_IP_NF_ARP_MANGLE=y -+CONFIG_IP6_NF_IPTABLES=y -+CONFIG_IP6_NF_MATCH_RPFILTER=y -+CONFIG_IP6_NF_FILTER=y -+CONFIG_IP6_NF_TARGET_REJECT=y -+CONFIG_IP6_NF_MANGLE=y -+CONFIG_IP6_NF_RAW=y -+CONFIG_L2TP=y -+CONFIG_NET_SCHED=y -+CONFIG_NET_SCH_HTB=y -+CONFIG_NET_SCH_INGRESS=y -+CONFIG_NET_CLS_U32=y -+CONFIG_NET_CLS_BPF=y -+CONFIG_NET_EMATCH=y -+CONFIG_NET_EMATCH_U32=y -+CONFIG_NET_CLS_ACT=y -+CONFIG_VSOCKETS=y -+CONFIG_VIRTIO_VSOCKETS=y -+CONFIG_CFG80211=y -+# CONFIG_CFG80211_DEFAULT_PS is not set -+# CONFIG_CFG80211_CRDA_SUPPORT is not set -+CONFIG_MAC80211=y -+# CONFIG_MAC80211_RC_MINSTREL is not set -+CONFIG_RFKILL=y -+# CONFIG_ALLOW_DEV_COREDUMP is not set -+CONFIG_DEBUG_DEVRES=y -+CONFIG_ZRAM=y -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_SIZE=8192 -+CONFIG_VIRTIO_BLK=y -+CONFIG_UID_SYS_STATS=y -+CONFIG_SCSI=y -+# CONFIG_SCSI_PROC_FS is not set -+CONFIG_BLK_DEV_SD=y -+CONFIG_SCSI_VIRTIO=y -+CONFIG_MD=y -+CONFIG_BLK_DEV_DM=y -+CONFIG_DM_CRYPT=y -+CONFIG_DM_UEVENT=y -+CONFIG_DM_VERITY=y -+CONFIG_DM_VERITY_AVB=y -+CONFIG_DM_VERITY_FEC=y -+CONFIG_DM_BOW=y -+CONFIG_NETDEVICES=y -+CONFIG_TUN=y -+CONFIG_VIRTIO_NET=y -+# CONFIG_ETHERNET is not set -+CONFIG_PHYLIB=y -+CONFIG_PPP=y -+CONFIG_PPP_BSDCOMP=y -+CONFIG_PPP_DEFLATE=y -+CONFIG_PPP_MPPE=y -+CONFIG_PPTP=y -+CONFIG_PPPOL2TP=y -+CONFIG_USB_RTL8152=y -+CONFIG_USB_USBNET=y -+# CONFIG_USB_NET_AX8817X is not set -+# CONFIG_USB_NET_AX88179_178A is not set -+# CONFIG_USB_NET_CDCETHER is not set -+# CONFIG_USB_NET_CDC_NCM is not set -+# CONFIG_USB_NET_NET1080 is not set -+# CONFIG_USB_NET_CDC_SUBSET is not set -+# CONFIG_USB_NET_ZAURUS is not set -+# CONFIG_WLAN_VENDOR_ADMTEK is not set -+# CONFIG_WLAN_VENDOR_ATH is not set -+# CONFIG_WLAN_VENDOR_ATMEL is not set -+# CONFIG_WLAN_VENDOR_BROADCOM is not set -+# CONFIG_WLAN_VENDOR_CISCO is not set -+# CONFIG_WLAN_VENDOR_INTEL is not set -+# CONFIG_WLAN_VENDOR_INTERSIL is not set -+# CONFIG_WLAN_VENDOR_MARVELL is not set -+# CONFIG_WLAN_VENDOR_MEDIATEK is not set -+# CONFIG_WLAN_VENDOR_RALINK is not set -+# CONFIG_WLAN_VENDOR_REALTEK is not set -+# CONFIG_WLAN_VENDOR_RSI is not set -+# CONFIG_WLAN_VENDOR_ST is not set -+# CONFIG_WLAN_VENDOR_TI is not set -+# CONFIG_WLAN_VENDOR_ZYDAS is not set -+# CONFIG_WLAN_VENDOR_QUANTENNA is not set -+CONFIG_VIRT_WIFI=y -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_JOYSTICK=y -+CONFIG_INPUT_MISC=y -+CONFIG_INPUT_UINPUT=y -+# CONFIG_VT is not set -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_DEVMEM is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+CONFIG_SERIAL_8250_NR_UARTS=48 -+CONFIG_SERIAL_8250_EXTENDED=y -+CONFIG_SERIAL_8250_MANY_PORTS=y -+CONFIG_SERIAL_8250_SHARE_IRQ=y -+CONFIG_VIRTIO_CONSOLE=y -+CONFIG_HW_RANDOM=y -+CONFIG_HW_RANDOM_VIRTIO=y -+# CONFIG_I2C_COMPAT is not set -+# CONFIG_I2C_HELPER_AUTO is not set -+CONFIG_GPIOLIB=y -+# CONFIG_HWMON is not set -+CONFIG_DEVFREQ_THERMAL=y -+CONFIG_MEDIA_SUPPORT=y -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+CONFIG_DRM=y -+# CONFIG_DRM_FBDEV_EMULATION is not set -+CONFIG_DRM_VIRTIO_GPU=y -+CONFIG_BACKLIGHT_CLASS_DEVICE=y -+CONFIG_SOUND=y -+CONFIG_SND=y -+CONFIG_SND_HRTIMER=y -+CONFIG_SND_DYNAMIC_MINORS=y -+# CONFIG_SND_SUPPORT_OLD_API is not set -+# CONFIG_SND_VERBOSE_PROCFS is not set -+# CONFIG_SND_DRIVERS is not set -+# CONFIG_SND_USB is not set -+CONFIG_HIDRAW=y -+CONFIG_UHID=y -+CONFIG_HID_APPLE=y -+CONFIG_HID_ELECOM=y -+CONFIG_HID_MAGICMOUSE=y -+CONFIG_HID_MICROSOFT=y -+CONFIG_HID_MULTITOUCH=y -+CONFIG_USB_HIDDEV=y -+CONFIG_USB=y -+CONFIG_USB_GADGET=y -+CONFIG_USB_CONFIGFS=y -+CONFIG_USB_CONFIGFS_UEVENT=y -+CONFIG_USB_CONFIGFS_F_FS=y -+CONFIG_USB_CONFIGFS_F_ACC=y -+CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y -+CONFIG_USB_CONFIGFS_F_MIDI=y -+CONFIG_MMC=y -+# CONFIG_MMC_BLOCK is not set -+CONFIG_NEW_LEDS=y -+CONFIG_LEDS_CLASS=y -+CONFIG_LEDS_TRIGGERS=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_SYSTOHC is not set -+CONFIG_VIRTIO_BALLOON=y -+CONFIG_VIRTIO_INPUT=y -+CONFIG_VIRTIO_MMIO=y -+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y -+CONFIG_STAGING=y -+CONFIG_ASHMEM=y -+CONFIG_ION=y -+CONFIG_MAILBOX=y -+CONFIG_PM_DEVFREQ=y -+CONFIG_ANDROID=y -+CONFIG_ANDROID_BINDER_IPC=y -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_FS_SECURITY=y -+CONFIG_F2FS_FS=y -+CONFIG_F2FS_FS_SECURITY=y -+# CONFIG_DNOTIFY is not set -+CONFIG_QUOTA=y -+CONFIG_QFMT_V2=y -+CONFIG_FUSE_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_PSTORE=y -+CONFIG_PSTORE_CONSOLE=y -+CONFIG_PSTORE_RAM=y -+CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y -+CONFIG_SECURITY=y -+CONFIG_SECURITY_NETWORK=y -+CONFIG_HARDENED_USERCOPY=y -+CONFIG_SECURITY_SELINUX=y -+CONFIG_CRYPTO_ADIANTUM=y -+CONFIG_CRYPTO_SHA512=y -+CONFIG_CRYPTO_LZ4=y -+CONFIG_CRYPTO_ZSTD=y -+CONFIG_CRYPTO_ANSI_CPRNG=y -+CONFIG_CRYPTO_DEV_VIRTIO=y -+CONFIG_CRC8=y -+CONFIG_XZ_DEC=y -+CONFIG_PRINTK_TIME=y -+CONFIG_DEBUG_INFO=y -+# CONFIG_ENABLE_MUST_CHECK is not set -+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set -+CONFIG_MAGIC_SYSRQ=y -+CONFIG_DEBUG_STACK_USAGE=y -+CONFIG_DEBUG_MEMORY_INIT=y -+CONFIG_SOFTLOCKUP_DETECTOR=y -+# CONFIG_DETECT_HUNG_TASK is not set -+CONFIG_PANIC_TIMEOUT=5 -+CONFIG_SCHEDSTATS=y -+# CONFIG_RUNTIME_TESTING_MENU is not set -+CONFIG_UNWINDER_FRAME_POINTER=y -diff --git a/build.config.gki.x86_64 b/build.config.gki.x86_64 -new file mode 100644 -index 000000000000..69d339dce4a0 ---- /dev/null -+++ b/build.config.gki.x86_64 -@@ -0,0 +1,17 @@ -+ARCH=x86_64 -+BRANCH=android-mainline -+CLANG_TRIPLE=x86_64-linux-gnu- -+CROSS_COMPILE=x86_64-linux-androidkernel- -+CC=clang -+DEFCONFIG=gki_defconfig -+EXTRA_CMDS='' -+KERNEL_DIR=common -+POST_DEFCONFIG_CMDS="check_defconfig" -+CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin -+LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin -+FILES=" -+arch/x86/boot/bzImage -+vmlinux -+System.map -+" -+STOP_SHIP_TRACEPRINTK=1 diff --git a/patches/ANDROID-Add-show_options2-to-view-private-mount-data.patch b/patches/ANDROID-Add-show_options2-to-view-private-mount-data.patch deleted file mode 100644 index 2ec7a16cbd86..000000000000 --- a/patches/ANDROID-Add-show_options2-to-view-private-mount-data.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Rosenberg -Date: Tue, 16 Jul 2019 18:09:39 -0700 -Subject: ANDROID: Add show_options2 to view private mount data - -Exposes private fs data via show_options2 - -Bug: 120446149 -Change-Id: I2d1c06fae274eeac03ac1924ef162f7bbb2f29d0 -Signed-off-by: Daniel Rosenberg ---- - fs/proc_namespace.c | 8 ++++++-- - include/linux/fs.h | 1 + - 2 files changed, 7 insertions(+), 2 deletions(-) - -diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c -index 273ee82d8aa9..5b8d065fa83c 100644 ---- a/fs/proc_namespace.c -+++ b/fs/proc_namespace.c -@@ -121,7 +121,9 @@ static int show_vfsmnt(struct seq_file *m, struct vfsmount *mnt) - if (err) - goto out; - show_mnt_opts(m, mnt); -- if (sb->s_op->show_options) -+ if (sb->s_op->show_options2) -+ err = sb->s_op->show_options2(mnt, m, mnt_path.dentry); -+ else if (sb->s_op->show_options) - err = sb->s_op->show_options(m, mnt_path.dentry); - seq_puts(m, " 0 0\n"); - out: -@@ -183,7 +185,9 @@ static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt) - err = show_sb_opts(m, sb); - if (err) - goto out; -- if (sb->s_op->show_options) -+ if (sb->s_op->show_options2) { -+ err = sb->s_op->show_options2(mnt, m, mnt->mnt_root); -+ } else if (sb->s_op->show_options) - err = sb->s_op->show_options(m, mnt->mnt_root); - seq_putc(m, '\n'); - out: -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 42c2cfc33ce7..eccf96ceef3b 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1965,6 +1965,7 @@ struct super_operations { - void (*umount_begin) (struct super_block *); - - int (*show_options)(struct seq_file *, struct dentry *); -+ int (*show_options2)(struct vfsmount *,struct seq_file *, struct dentry *); - int (*show_devname)(struct seq_file *, struct dentry *); - int (*show_path)(struct seq_file *, struct dentry *); - int (*show_stats)(struct seq_file *, struct dentry *); diff --git a/patches/ANDROID-Adding-GKI-Ramdisk-to-gki-config.patch b/patches/ANDROID-Adding-GKI-Ramdisk-to-gki-config.patch deleted file mode 100644 index 6b4cd338f73d..000000000000 --- a/patches/ANDROID-Adding-GKI-Ramdisk-to-gki-config.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Tue, 13 Aug 2019 10:11:28 -0700 -Subject: ANDROID: Adding GKI Ramdisk to gki config - -Test: Treehugger -Bug: 132629930 -Change-Id: I3773d828cea4ab0ea8cfaef8a533a5ae925f037c -Signed-of-by: Ram Muthiah ---- - build.config.gki.aarch64 | 1 + - build.config.gki.x86_64 | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 -index 79871cdc6d07..653e82bf1965 100644 ---- a/build.config.gki.aarch64 -+++ b/build.config.gki.aarch64 -@@ -16,3 +16,4 @@ vmlinux - System.map - " - STOP_SHIP_TRACEPRINTK=1 -+BUILD_INITRAMFS=1 -diff --git a/build.config.gki.x86_64 b/build.config.gki.x86_64 -index b5a7f4600101..5c2db37a2871 100644 ---- a/build.config.gki.x86_64 -+++ b/build.config.gki.x86_64 -@@ -16,3 +16,4 @@ vmlinux - System.map - " - STOP_SHIP_TRACEPRINTK=1 -+BUILD_INITRAMFS=1 diff --git a/patches/ANDROID-Adding-SERIAL_OF_PLATFORM-module-to-gki.patch b/patches/ANDROID-Adding-SERIAL_OF_PLATFORM-module-to-gki.patch deleted file mode 100644 index 7bc37b983f99..000000000000 --- a/patches/ANDROID-Adding-SERIAL_OF_PLATFORM-module-to-gki.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Wed, 4 Sep 2019 16:18:17 -0700 -Subject: ANDROID: Adding SERIAL_OF_PLATFORM module to gki - -Bug: 132629930 -Change-Id: I722540edb8b7a7289e45e63de2959399cb563e23 -Signed-off-by: Ram Muthiah ---- - arch/arm64/configs/gki_defconfig | 2 +- - arch/x86/configs/gki_defconfig | 2 ++ - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 6aae6d55e96c..d650f7d141e7 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -268,7 +268,7 @@ CONFIG_SERIAL_8250_NR_UARTS=48 - CONFIG_SERIAL_8250_EXTENDED=y - CONFIG_SERIAL_8250_MANY_PORTS=y - CONFIG_SERIAL_8250_SHARE_IRQ=y --CONFIG_SERIAL_OF_PLATFORM=y -+CONFIG_SERIAL_OF_PLATFORM=m - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_VIRTIO_CONSOLE=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index b3dad521ee8a..511a763add37 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -170,6 +170,7 @@ CONFIG_RFKILL=y - CONFIG_PCI=y - # CONFIG_ALLOW_DEV_COREDUMP is not set - CONFIG_DEBUG_DEVRES=y -+CONFIG_OF=y - CONFIG_ZRAM=y - CONFIG_BLK_DEV_LOOP=y - CONFIG_BLK_DEV_RAM=y -@@ -240,6 +241,7 @@ CONFIG_SERIAL_8250_NR_UARTS=48 - CONFIG_SERIAL_8250_EXTENDED=y - CONFIG_SERIAL_8250_MANY_PORTS=y - CONFIG_SERIAL_8250_SHARE_IRQ=y -+CONFIG_SERIAL_OF_PLATFORM=m - CONFIG_HW_RANDOM=y - CONFIG_HW_RANDOM_VIRTIO=m - # CONFIG_I2C_COMPAT is not set diff --git a/patches/ANDROID-CONFIG_MMC-m.patch b/patches/ANDROID-CONFIG_MMC-m.patch deleted file mode 100644 index 228f12394bbd..000000000000 --- a/patches/ANDROID-CONFIG_MMC-m.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mark Salyzyn -Date: Thu, 12 Sep 2019 14:06:44 -0700 -Subject: ANDROID: CONFIG_MMC=m - -Signed-off-by: Mark Salyzyn -Test: compile -Bug: 140652382 -Change-Id: Ie6002cde4d964920c71edd347851df9ceec4ee0f -(cherry picked from commit 30f8bea960e42921156a401e8e8ddb80fa3ee5c6) ---- - arch/arm64/configs/gki_defconfig | 6 +++--- - arch/x86/configs/gki_defconfig | 3 +-- - 2 files changed, 4 insertions(+), 5 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index ea9960028cfd..440173b3c301 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -323,11 +323,11 @@ CONFIG_USB_CONFIGFS_F_FS=y - CONFIG_USB_CONFIGFS_F_ACC=y - CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y - CONFIG_USB_CONFIGFS_F_MIDI=y --CONFIG_MMC=y -+CONFIG_MMC=m - # CONFIG_PWRSEQ_EMMC is not set - # CONFIG_PWRSEQ_SIMPLE is not set --CONFIG_MMC_SDHCI=y --CONFIG_MMC_SDHCI_PLTFM=y -+CONFIG_MMC_SDHCI=m -+CONFIG_MMC_SDHCI_PLTFM=m - CONFIG_NEW_LEDS=y - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_TRIGGERS=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index a5953d43d480..c206a2d0f9cf 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -280,8 +280,7 @@ CONFIG_USB_CONFIGFS_F_FS=y - CONFIG_USB_CONFIGFS_F_ACC=y - CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y - CONFIG_USB_CONFIGFS_F_MIDI=y --CONFIG_MMC=y --# CONFIG_MMC_BLOCK is not set -+CONFIG_MMC=m - CONFIG_NEW_LEDS=y - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_TRIGGERS=y diff --git a/patches/ANDROID-Catch-rockpi4_defconfig-up-with-gki_defconfig.patch b/patches/ANDROID-Catch-rockpi4_defconfig-up-with-gki_defconfig.patch deleted file mode 100644 index 008a680fe83b..000000000000 --- a/patches/ANDROID-Catch-rockpi4_defconfig-up-with-gki_defconfig.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alistair Delva -Date: Wed, 4 Sep 2019 12:25:57 -0700 -Subject: ANDROID: Catch rockpi4_defconfig up with gki_defconfig - -Change-Id: I640112a903d0b4944a087a4408241b901f37f6b8 -Signed-off-by: Alistair Delva ---- - arch/arm64/configs/rockpi4_defconfig | 31 +++++++++++++++------------- - 1 file changed, 17 insertions(+), 14 deletions(-) - -diff --git a/arch/arm64/configs/rockpi4_defconfig b/arch/arm64/configs/rockpi4_defconfig -index 6d0cf70f3757..2f97c1a8a60a 100644 ---- a/arch/arm64/configs/rockpi4_defconfig -+++ b/arch/arm64/configs/rockpi4_defconfig -@@ -1,3 +1,4 @@ -+CONFIG_LOCALVERSION="-mainline" - CONFIG_AUDIT=y - CONFIG_NO_HZ=y - CONFIG_HIGH_RES_TIMERS=y -@@ -24,7 +25,6 @@ CONFIG_BLK_DEV_INITRD=y - # CONFIG_RD_LZO is not set - # CONFIG_RD_LZ4 is not set - # CONFIG_SYSFS_SYSCALL is not set --CONFIG_FHANDLE=y - CONFIG_KALLSYMS_ALL=y - CONFIG_BPF_SYSCALL=y - # CONFIG_RSEQ is not set -@@ -35,8 +35,10 @@ CONFIG_EMBEDDED=y - CONFIG_SLAB_FREELIST_RANDOM=y - CONFIG_SLAB_FREELIST_HARDENED=y - CONFIG_PROFILING=y -+CONFIG_ARCH_QCOM=y - CONFIG_ARCH_ROCKCHIP=y - CONFIG_SCHED_MC=y -+CONFIG_NR_CPUS=32 - CONFIG_SECCOMP=y - CONFIG_PARAVIRT=y - CONFIG_COMPAT=y -@@ -45,9 +47,7 @@ CONFIG_SWP_EMULATION=y - CONFIG_CP15_BARRIER_EMULATION=y - CONFIG_SETEND_EMULATION=y - CONFIG_RANDOMIZE_BASE=y --CONFIG_CMDLINE="" --# CONFIG_CMDLINE_FORCE is not set --# CONFIG_EFI is not set -+# CONFIG_DMI is not set - CONFIG_PM_WAKELOCKS=y - CONFIG_PM_WAKELOCKS_LIMIT=0 - # CONFIG_PM_WAKELOCKS_GC is not set -@@ -65,6 +65,7 @@ CONFIG_ARM_SCMI_PROTOCOL=y - # CONFIG_ARM_SCMI_POWER_DOMAIN is not set - CONFIG_ARM_SCPI_PROTOCOL=y - # CONFIG_ARM_SCPI_POWER_DOMAIN is not set -+# CONFIG_EFI_ARMSTUB_DTB_LOADER is not set - CONFIG_VIRTUALIZATION=y - CONFIG_KVM=y - CONFIG_VHOST_VSOCK=y -@@ -93,7 +94,6 @@ CONFIG_INET=y - CONFIG_IP_MULTICAST=y - CONFIG_IP_ADVANCED_ROUTER=y - CONFIG_IP_MULTIPLE_TABLES=y --CONFIG_IP_PNP=y - CONFIG_NET_IPGRE_DEMUX=y - CONFIG_NET_IPVTI=y - CONFIG_INET_ESP=y -@@ -108,6 +108,7 @@ CONFIG_IPV6_MIP6=y - CONFIG_IPV6_VTI=y - CONFIG_IPV6_MULTIPLE_TABLES=y - CONFIG_NETFILTER=y -+# CONFIG_BRIDGE_NETFILTER is not set - CONFIG_NF_CONNTRACK=y - CONFIG_NF_CONNTRACK_SECMARK=y - CONFIG_NF_CONNTRACK_EVENTS=y -@@ -176,6 +177,7 @@ CONFIG_IP6_NF_FILTER=y - CONFIG_IP6_NF_TARGET_REJECT=y - CONFIG_IP6_NF_MANGLE=y - CONFIG_IP6_NF_RAW=y -+CONFIG_TIPC=y - CONFIG_L2TP=y - CONFIG_BRIDGE=y - CONFIG_NET_SCHED=y -@@ -376,7 +378,6 @@ CONFIG_WATCHDOG_PRETIMEOUT_GOV=y - CONFIG_DW_WATCHDOG=y - CONFIG_MFD_ACT8945A=y - CONFIG_MFD_RK808=y --CONFIG_REGULATOR=y - CONFIG_REGULATOR_DEBUG=y - CONFIG_REGULATOR_FIXED_VOLTAGE=y - CONFIG_REGULATOR_VIRTUAL_CONSUMER=y -@@ -388,7 +389,6 @@ CONFIG_REGULATOR_VCTRL=y - CONFIG_MEDIA_SUPPORT=y - CONFIG_MEDIA_CAMERA_SUPPORT=y - CONFIG_MEDIA_CONTROLLER=y --CONFIG_VIDEO_V4L2_SUBDEV_API=y - # CONFIG_VGA_ARB is not set - CONFIG_DRM=y - # CONFIG_DRM_FBDEV_EMULATION is not set -@@ -397,7 +397,6 @@ CONFIG_ROCKCHIP_DW_HDMI=y - CONFIG_DRM_VIRTIO_GPU=y - # CONFIG_LCD_CLASS_DEVICE is not set - CONFIG_BACKLIGHT_CLASS_DEVICE=y --# CONFIG_BACKLIGHT_GENERIC is not set - CONFIG_SOUND=y - CONFIG_SND=y - CONFIG_SND_HRTIMER=y -@@ -427,6 +426,7 @@ CONFIG_USB_OHCI_HCD=y - # CONFIG_USB_OHCI_HCD_PCI is not set - CONFIG_USB_OHCI_HCD_PLATFORM=y - CONFIG_USB_GADGET=y -+CONFIG_USB_DUMMY_HCD=m - CONFIG_USB_CONFIGFS=y - CONFIG_USB_CONFIGFS_UEVENT=y - CONFIG_USB_CONFIGFS_F_FS=y -@@ -442,10 +442,10 @@ CONFIG_MMC_SDHCI_OF_ARASAN=y - CONFIG_MMC_SDHCI_OF_DWCMSHC=y - CONFIG_MMC_DW=y - CONFIG_MMC_DW_ROCKCHIP=y --CONFIG_MMC_CQHCI=y - CONFIG_NEW_LEDS=y - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_TRIGGERS=y -+CONFIG_EDAC=y - CONFIG_RTC_CLASS=y - # CONFIG_RTC_SYSTOHC is not set - CONFIG_RTC_DRV_RK808=y -@@ -462,16 +462,17 @@ CONFIG_STAGING=y - CONFIG_ASHMEM=y - CONFIG_ANDROID_VSOC=y - CONFIG_ION=y -+CONFIG_ION_SYSTEM_HEAP=y -+CONFIG_ION_SYSTEM_CONTIG_HEAP=y - CONFIG_COMMON_CLK_RK808=y - CONFIG_COMMON_CLK_SCPI=y --# CONFIG_COMMON_CLK_XGENE is not set - CONFIG_HWSPINLOCK=y --# CONFIG_FSL_ERRATUM_A008585 is not set --# CONFIG_HISILICON_ERRATUM_161010101 is not set - CONFIG_MAILBOX=y - CONFIG_ROCKCHIP_MBOX=y - CONFIG_ROCKCHIP_IOMMU=y - CONFIG_ARM_SMMU=y -+CONFIG_QCOM_COMMAND_DB=y -+CONFIG_QCOM_RPMH=y - CONFIG_ROCKCHIP_PM_DOMAINS=y - CONFIG_DEVFREQ_GOV_PERFORMANCE=y - CONFIG_DEVFREQ_GOV_POWERSAVE=y -@@ -480,10 +481,12 @@ CONFIG_DEVFREQ_GOV_PASSIVE=y - CONFIG_ARM_RK3399_DMC_DEVFREQ=y - CONFIG_PWM=y - CONFIG_PWM_ROCKCHIP=y -+CONFIG_QCOM_PDC=y - CONFIG_PHY_ROCKCHIP_EMMC=y - CONFIG_PHY_ROCKCHIP_INNO_HDMI=y - CONFIG_PHY_ROCKCHIP_INNO_USB2=y - CONFIG_PHY_ROCKCHIP_USB=y -+CONFIG_RAS=y - CONFIG_ANDROID=y - CONFIG_ANDROID_BINDER_IPC=y - CONFIG_ROCKCHIP_EFUSE=y -@@ -500,9 +503,9 @@ CONFIG_FUSE_FS=y - CONFIG_OVERLAY_FS=y - CONFIG_MSDOS_FS=y - CONFIG_VFAT_FS=y --CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y --CONFIG_ECRYPT_FS=y -+# CONFIG_EFIVAR_FS is not set -+CONFIG_SDCARD_FS=y - CONFIG_PSTORE=y - CONFIG_PSTORE_CONSOLE=y - CONFIG_PSTORE_RAM=y diff --git a/patches/ANDROID-Expose-gki_defconfig-to-build.config.patch b/patches/ANDROID-Expose-gki_defconfig-to-build.config.patch deleted file mode 100644 index 29dc49ade845..000000000000 --- a/patches/ANDROID-Expose-gki_defconfig-to-build.config.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Matthias Maennich -Date: Wed, 8 May 2019 23:07:39 +0100 -Subject: ANDROID: Expose gki_defconfig to build.config - -With this in place, the gki_defconfig can be build with build.sh -machinery. - -Bug: 132113225 -Change-Id: I4c623a866cd41aa4587e4fab1c4e5254f6680542 -Signed-off-by: Matthias Maennich ---- - build.config.gki.aarch64 | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - create mode 100644 build.config.gki.aarch64 - -diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 -new file mode 100644 -index 000000000000..dec295284ffa ---- /dev/null -+++ b/build.config.gki.aarch64 -@@ -0,0 +1,17 @@ -+ARCH=arm64 -+BRANCH=android-mainline -+CLANG_TRIPLE=aarch64-linux-gnu- -+CROSS_COMPILE=aarch64-linux-androidkernel- -+CC=clang -+DEFCONFIG=gki_defconfig -+EXTRA_CMDS='' -+KERNEL_DIR=common -+POST_DEFCONFIG_CMDS="check_defconfig" -+CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r349610/bin -+LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin -+FILES=" -+arch/arm64/boot/Image.gz -+vmlinux -+System.map -+" -+STOP_SHIP_TRACEPRINTK=1 diff --git a/patches/ANDROID-Fix-arm64-allmodconfig-build.patch b/patches/ANDROID-Fix-arm64-allmodconfig-build.patch deleted file mode 100644 index 320c7a5b3efe..000000000000 --- a/patches/ANDROID-Fix-arm64-allmodconfig-build.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Quentin Perret -Date: Tue, 24 Sep 2019 17:28:02 +0100 -Subject: ANDROID: Fix arm64 allmodconfig build - -Allmodconfig on arm64 enables CPU_BIG_ENDIAN=y, which causes issues with -ld.lld which doesn't support linking aarch64be-linux-gnu targets (see -https://reviews.llvm.org/D58655#1410281). However, it is very unlikely -that real android devices run with arm64 BE hardware in practice. So, -until we can find a better fix, let's simply force CPU_BIG_ENDIAN=n for -allmodconfig builds. - -Bug: 141733632 -Bug: 140224784 -Signed-off-by: Quentin Perret -Change-Id: Ic4693ae1f462144c8219b397463ca341f6fe08a1 ---- - build.config.allmodconfig | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/build.config.allmodconfig b/build.config.allmodconfig -index 6e0404b8de47..deaa8f3d5a69 100644 ---- a/build.config.allmodconfig -+++ b/build.config.allmodconfig -@@ -6,7 +6,8 @@ POST_DEFCONFIG_CMDS="update_config" - function update_config() { - ${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \ - -d TEST_KMOD \ -- -d XFS_FS -+ -d XFS_FS \ -+ -d CPU_BIG_ENDIAN - (cd ${OUT_DIR} && \ - make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig) - } diff --git a/patches/ANDROID-Fix-x86_64-allmodconfig-build.patch b/patches/ANDROID-Fix-x86_64-allmodconfig-build.patch deleted file mode 100644 index fb81b8ce89a7..000000000000 --- a/patches/ANDROID-Fix-x86_64-allmodconfig-build.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alistair Delva -Date: Fri, 11 Oct 2019 10:24:23 -0400 -Subject: ANDROID: Fix x86_64 allmodconfig build - -CONFIG_KVM_INTEL depends on asm volatile goto which is about to be -supported in clang, but we haven't landed the upgraded compiler yet. -Suppress use of this kernel feature for now. - -In file included from arch/x86/kvm/vmx/vmx.h:11: -arch/x86/kvm/vmx/ops.h:157:2: error: 'asm goto' constructs are not -supported yet -vmx_asm2(vmwrite, "r"(field), "rm"(value), field, value); -^ - -Change-Id: If21ca65a7bd1e43c5f66a93a6108cf8aa49a9c64 -Signed-off-by: Alistair Delva ---- - build.config.allmodconfig | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/build.config.allmodconfig b/build.config.allmodconfig -index deaa8f3d5a69..854a8f8aa3f2 100644 ---- a/build.config.allmodconfig -+++ b/build.config.allmodconfig -@@ -2,12 +2,14 @@ DEFCONFIG=allmodconfig - KCONFIG_ALLCONFIG=${ROOT_DIR}/common/arch/${ARCH%_*}/configs/gki_defconfig - - # XFS_FS is currently broken on this branch with clang-9 -+# KVM_INTEL is broken on this branch due to lack of asm-goto support in clang - POST_DEFCONFIG_CMDS="update_config" - function update_config() { - ${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \ - -d TEST_KMOD \ - -d XFS_FS \ -- -d CPU_BIG_ENDIAN -+ -d CPU_BIG_ENDIAN \ -+ -d KVM_INTEL - (cd ${OUT_DIR} && \ - make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig) - } diff --git a/patches/ANDROID-Fixed-x86-regression.patch b/patches/ANDROID-Fixed-x86-regression.patch deleted file mode 100644 index 3cb293ca6a8e..000000000000 --- a/patches/ANDROID-Fixed-x86-regression.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Wed, 12 Jun 2019 14:25:25 -0700 -Subject: ANDROID: Fixed x86 regression - -Added SMP and CMDLINE to defconfig - -Test: Boot x86 gki -Change-Id: I6930d60dceb5b180825337d5371d375259984a33 -Signed-off-by: Ram Muthiah ---- - arch/x86/configs/gki_defconfig | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 864595c719e7..94690e9d016a 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -33,13 +33,14 @@ CONFIG_EMBEDDED=y - CONFIG_SLAB_FREELIST_RANDOM=y - CONFIG_SLAB_FREELIST_HARDENED=y - CONFIG_PROFILING=y -+CONFIG_SMP=y -+CONFIG_CMDLINE_BOOL=y -+CONFIG_CMDLINE="console=ttyS0 reboot=p" - CONFIG_PM_WAKELOCKS=y - CONFIG_PM_WAKELOCKS_LIMIT=0 - # CONFIG_PM_WAKELOCKS_GC is not set --CONFIG_CPU_FREQ=y - CONFIG_CPU_FREQ_TIMES=y - CONFIG_CPU_FREQ_GOV_POWERSAVE=y --CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y - CONFIG_IA32_EMULATION=y - CONFIG_KPROBES=y - CONFIG_MODULES=y -@@ -288,7 +289,6 @@ CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y - CONFIG_STAGING=y - CONFIG_ASHMEM=y - CONFIG_ION=y --CONFIG_MAILBOX=y - CONFIG_PM_DEVFREQ=y - CONFIG_ANDROID=y - CONFIG_ANDROID_BINDER_IPC=y diff --git a/patches/ANDROID-Four-part-revert-of-asm-goto-usage-1-4.patch b/patches/ANDROID-Four-part-revert-of-asm-goto-usage-1-4.patch deleted file mode 100644 index 9e032432c74d..000000000000 --- a/patches/ANDROID-Four-part-revert-of-asm-goto-usage-1-4.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Tue, 21 May 2019 18:15:10 -0700 -Subject: ANDROID-Four-part-revert-of-asm-goto-usage-1-4 - -Revert "x86/uaccess: Dont leak the AC flag into __put_user() argument evaluation" -This reverts commit 6ae865615fc43d014da2fd1f1bba7e81ee622d1b. - -Bug: 120440614 -Bug: 132629930 -Change-Id: I38f78e20d255ab4b33546d2e9d98f64d7e590e1d -Signed-off-by: Ram Muthiah ---- - arch/x86/include/asm/uaccess.h | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h -index 61d93f062a36..176c73385605 100644 ---- a/arch/x86/include/asm/uaccess.h -+++ b/arch/x86/include/asm/uaccess.h -@@ -429,11 +429,10 @@ do { \ - ({ \ - __label__ __pu_label; \ - int __pu_err = -EFAULT; \ -- __typeof__(*(ptr)) __pu_val = (x); \ -- __typeof__(ptr) __pu_ptr = (ptr); \ -- __typeof__(size) __pu_size = (size); \ -+ __typeof__(*(ptr)) __pu_val; \ -+ __pu_val = x; \ - __uaccess_begin(); \ -- __put_user_size(__pu_val, __pu_ptr, __pu_size, __pu_label); \ -+ __put_user_size(__pu_val, (ptr), (size), __pu_label); \ - __pu_err = 0; \ - __pu_label: \ - __uaccess_end(); \ diff --git a/patches/ANDROID-Four-part-revert-of-asm-goto-usage-2-4.patch b/patches/ANDROID-Four-part-revert-of-asm-goto-usage-2-4.patch deleted file mode 100644 index 0a0f4b131294..000000000000 --- a/patches/ANDROID-Four-part-revert-of-asm-goto-usage-2-4.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Tue, 21 May 2019 18:15:21 -0700 -Subject: ANDROID-Four-part-revert-of-asm-goto-usage-2-4 - -Revert "x86/uaccess: Don't leak the AC flag into __put_user() value evaluation" -This reverts commit 2a418cf3f5f1caf911af288e978d61c9844b0695. - -Bug: 120440614 -Bug: 132629930 -Change-Id: Ib177230b39d1247060f425205d63d65065ed936a -Signed-off-by: Ram Muthiah ---- - arch/x86/include/asm/uaccess.h | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - -diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h -index 176c73385605..8fc40674c174 100644 ---- a/arch/x86/include/asm/uaccess.h -+++ b/arch/x86/include/asm/uaccess.h -@@ -282,7 +282,7 @@ do { \ - __put_user_goto(x, ptr, "l", "k", "ir", label); \ - break; \ - case 8: \ -- __put_user_goto_u64(x, ptr, label); \ -+ __put_user_goto_u64((__typeof__(*ptr))(x), ptr, label); \ - break; \ - default: \ - __put_user_bad(); \ -@@ -429,10 +429,8 @@ do { \ - ({ \ - __label__ __pu_label; \ - int __pu_err = -EFAULT; \ -- __typeof__(*(ptr)) __pu_val; \ -- __pu_val = x; \ - __uaccess_begin(); \ -- __put_user_size(__pu_val, (ptr), (size), __pu_label); \ -+ __put_user_size((x), (ptr), (size), __pu_label); \ - __pu_err = 0; \ - __pu_label: \ - __uaccess_end(); \ diff --git a/patches/ANDROID-Four-part-revert-of-asm-goto-usage-3-4.patch b/patches/ANDROID-Four-part-revert-of-asm-goto-usage-3-4.patch deleted file mode 100644 index fca66a066ddb..000000000000 --- a/patches/ANDROID-Four-part-revert-of-asm-goto-usage-3-4.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Tue, 21 May 2019 18:20:17 -0700 -Subject: ANDROID-Four-part-revert-of-asm-goto-usage-3-4 - -Revert "Use __put_user_goto in __put_user_size() and unsafe_put_user()" -This reverts commit a959dc88f9c8900296ccf13e2f3e1cbc555a8917. - -Bug: 120440614 -Bug: 132629930 -Change-Id: I07410ed2bc7552f16ec119fbc2001bb43ffef6f4 -Signed-off-by: Ram Muthiah ---- - arch/x86/include/asm/uaccess.h | 57 ++++++++++++++++++++-------------- - 1 file changed, 33 insertions(+), 24 deletions(-) - -diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h -index 8fc40674c174..0b049e6baf31 100644 ---- a/arch/x86/include/asm/uaccess.h -+++ b/arch/x86/include/asm/uaccess.h -@@ -184,14 +184,19 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) - - - #ifdef CONFIG_X86_32 --#define __put_user_goto_u64(x, addr, label) \ -- asm_volatile_goto("\n" \ -- "1: movl %%eax,0(%1)\n" \ -- "2: movl %%edx,4(%1)\n" \ -- _ASM_EXTABLE_UA(1b, %l2) \ -- _ASM_EXTABLE_UA(2b, %l2) \ -- : : "A" (x), "r" (addr) \ -- : : label) -+#define __put_user_asm_u64(x, addr, err, errret) \ -+ asm volatile("\n" \ -+ "1: movl %%eax,0(%2)\n" \ -+ "2: movl %%edx,4(%2)\n" \ -+ "3:" \ -+ ".section .fixup,\"ax\"\n" \ -+ "4: movl %3,%0\n" \ -+ " jmp 3b\n" \ -+ ".previous\n" \ -+ _ASM_EXTABLE_UA(1b, 4b) \ -+ _ASM_EXTABLE_UA(2b, 4b) \ -+ : "=r" (err) \ -+ : "A" (x), "r" (addr), "i" (errret), "0" (err)) - - #define __put_user_asm_ex_u64(x, addr) \ - asm volatile("\n" \ -@@ -206,8 +211,8 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) - asm volatile("call __put_user_8" : "=a" (__ret_pu) \ - : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") - #else --#define __put_user_goto_u64(x, ptr, label) \ -- __put_user_goto(x, ptr, "q", "", "er", label) -+#define __put_user_asm_u64(x, ptr, retval, errret) \ -+ __put_user_asm(x, ptr, retval, "q", "", "er", errret) - #define __put_user_asm_ex_u64(x, addr) \ - __put_user_asm_ex(x, addr, "q", "", "er") - #define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu) -@@ -268,21 +273,23 @@ extern void __put_user_8(void); - __builtin_expect(__ret_pu, 0); \ - }) - --#define __put_user_size(x, ptr, size, label) \ -+#define __put_user_size(x, ptr, size, retval, errret) \ - do { \ -+ retval = 0; \ - __chk_user_ptr(ptr); \ - switch (size) { \ - case 1: \ -- __put_user_goto(x, ptr, "b", "b", "iq", label); \ -+ __put_user_asm(x, ptr, retval, "b", "b", "iq", errret); \ - break; \ - case 2: \ -- __put_user_goto(x, ptr, "w", "w", "ir", label); \ -+ __put_user_asm(x, ptr, retval, "w", "w", "ir", errret); \ - break; \ - case 4: \ -- __put_user_goto(x, ptr, "l", "k", "ir", label); \ -+ __put_user_asm(x, ptr, retval, "l", "k", "ir", errret); \ - break; \ - case 8: \ -- __put_user_goto_u64((__typeof__(*ptr))(x), ptr, label); \ -+ __put_user_asm_u64((__typeof__(*ptr))(x), ptr, retval, \ -+ errret); \ - break; \ - default: \ - __put_user_bad(); \ -@@ -427,12 +434,9 @@ do { \ - - #define __put_user_nocheck(x, ptr, size) \ - ({ \ -- __label__ __pu_label; \ -- int __pu_err = -EFAULT; \ -+ int __pu_err; \ - __uaccess_begin(); \ -- __put_user_size((x), (ptr), (size), __pu_label); \ -- __pu_err = 0; \ --__pu_label: \ -+ __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \ - __uaccess_end(); \ - __builtin_expect(__pu_err, 0); \ - }) -@@ -716,11 +720,16 @@ static __must_check __always_inline bool user_access_begin(const void __user *pt - #define user_access_begin(a,b) user_access_begin(a,b) - #define user_access_end() __uaccess_end() - --#define user_access_save() smap_save() --#define user_access_restore(x) smap_restore(x) -+#define user_access_save() smap_save() -+#define user_access_restore(x) smap_restore(x) - --#define unsafe_put_user(x, ptr, label) \ -- __put_user_size((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) -+#define unsafe_put_user(x, ptr, err_label) \ -+do { \ -+ int __pu_err; \ -+ __typeof__(*(ptr)) __pu_val = (x); \ -+ __put_user_size(__pu_val, (ptr), sizeof(*(ptr)), __pu_err, -EFAULT); \ -+ if (unlikely(__pu_err)) goto err_label; \ -+} while (0) - - #define unsafe_get_user(x, ptr, err_label) \ - do { \ diff --git a/patches/ANDROID-Four-part-revert-of-asm-goto-usage-4-4.patch b/patches/ANDROID-Four-part-revert-of-asm-goto-usage-4-4.patch deleted file mode 100644 index fba76ae57b9b..000000000000 --- a/patches/ANDROID-Four-part-revert-of-asm-goto-usage-4-4.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Tue, 21 May 2019 18:21:54 -0700 -Subject: ANDROID-Four-part-revert-of-asm-goto-usage-4-4 - -Revert "x86 uaccess: Introduce __put_user_goto" -This reverts commit 4a789213c9a54c8b618924d3421e56e98df8a447. - -Bug: 120440614 -Bug: 132629930 -Change-Id: If5e90d475d74d9aa3505972f43bc4ee48bed038f -Signed-off-by: Ram Muthiah ---- - arch/x86/include/asm/uaccess.h | 28 +++++++++++----------------- - 1 file changed, 11 insertions(+), 17 deletions(-) - -diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h -index 0b049e6baf31..d3b6c3ba61d1 100644 ---- a/arch/x86/include/asm/uaccess.h -+++ b/arch/x86/include/asm/uaccess.h -@@ -463,23 +463,17 @@ struct __large_struct { unsigned long buf[100]; }; - * we do not write to any memory gcc knows about, so there are no - * aliasing issues. - */ --#define __put_user_goto(x, addr, itype, rtype, ltype, label) \ -- asm_volatile_goto("\n" \ -- "1: mov"itype" %"rtype"0,%1\n" \ -- _ASM_EXTABLE_UA(1b, %l2) \ -- : : ltype(x), "m" (__m(addr)) \ -- : : label) -- --#define __put_user_failed(x, addr, itype, rtype, ltype, errret) \ -- ({ __label__ __puflab; \ -- int __pufret = errret; \ -- __put_user_goto(x,addr,itype,rtype,ltype,__puflab); \ -- __pufret = 0; \ -- __puflab: __pufret; }) -- --#define __put_user_asm(x, addr, retval, itype, rtype, ltype, errret) do { \ -- retval = __put_user_failed(x, addr, itype, rtype, ltype, errret); \ --} while (0) -+#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ -+ asm volatile("\n" \ -+ "1: mov"itype" %"rtype"1,%2\n" \ -+ "2:\n" \ -+ ".section .fixup,\"ax\"\n" \ -+ "3: mov %3,%0\n" \ -+ " jmp 2b\n" \ -+ ".previous\n" \ -+ _ASM_EXTABLE_UA(1b, 3b) \ -+ : "=r"(err) \ -+ : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err)) - - #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \ - asm volatile("1: mov"itype" %"rtype"0,%1\n" \ diff --git a/patches/ANDROID-GKI-enable-CONFIG_SPI-for-x86.patch b/patches/ANDROID-GKI-enable-CONFIG_SPI-for-x86.patch deleted file mode 100644 index ca971212a929..000000000000 --- a/patches/ANDROID-GKI-enable-CONFIG_SPI-for-x86.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mark Salyzyn -Date: Tue, 3 Sep 2019 09:42:35 -0700 -Subject: ANDROID: GKI: enable CONFIG_SPI for x86 - -Adds compile coverage for SPI in the TH builds, runtime no so much. - -Signed-off-by: Mark Salyzyn -Bug: 140290328 -Change-Id: I2d7777ab0e671248084880e5c1770b6ec6d7a650 ---- - arch/x86/configs/gki_defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index e86cd1009a67..9b76d55e8c41 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -240,6 +240,7 @@ CONFIG_HW_RANDOM=y - CONFIG_HW_RANDOM_VIRTIO=y - # CONFIG_I2C_COMPAT is not set - # CONFIG_I2C_HELPER_AUTO is not set -+CONFIG_SPI=y - CONFIG_GPIOLIB=y - # CONFIG_HWMON is not set - CONFIG_DEVFREQ_THERMAL=y diff --git a/patches/ANDROID-GKI-enable-CONFIG_TIPC-for-x86.patch b/patches/ANDROID-GKI-enable-CONFIG_TIPC-for-x86.patch deleted file mode 100644 index f478aa67e569..000000000000 --- a/patches/ANDROID-GKI-enable-CONFIG_TIPC-for-x86.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mark Salyzyn -Date: Tue, 3 Sep 2019 13:17:23 -0700 -Subject: ANDROID: GKI: enable CONFIG_TIPC for x86 - -Adds compile coverage for TIPC in the TH builds, runtime not so much. - -Signed-off-by: Mark Salyzyn -Bug: 140406060 -Change-Id: I7731157396372683c906f1f4eb2fdbdb7015f446 ---- - arch/x86/configs/gki_defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 9b76d55e8c41..6b0ff4ca236a 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -145,6 +145,7 @@ CONFIG_IP6_NF_FILTER=y - CONFIG_IP6_NF_TARGET_REJECT=y - CONFIG_IP6_NF_MANGLE=y - CONFIG_IP6_NF_RAW=y -+CONFIG_TIPC=y - CONFIG_L2TP=y - CONFIG_NET_SCHED=y - CONFIG_NET_SCH_HTB=y diff --git a/patches/ANDROID-GKI-export-cma-symbols-for-cma-heap-as-a-module.patch b/patches/ANDROID-GKI-export-cma-symbols-for-cma-heap-as-a-module.patch deleted file mode 100644 index 750af25c2d1e..000000000000 --- a/patches/ANDROID-GKI-export-cma-symbols-for-cma-heap-as-a-module.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Fri, 13 Sep 2019 14:50:38 -0700 -Subject: ANDROID: GKI: export cma symbols for cma heap as a module - -Bug: 140294230 -Test: builds - -Change-Id: I04c12174934c24a704d5c1e5be3e7e948c777a78 -Signed-off-by: Sandeep Patil ---- - mm/cma.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/mm/cma.c b/mm/cma.c -index 7fe0b8356775..db4642e58058 100644 ---- a/mm/cma.c -+++ b/mm/cma.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -54,6 +55,7 @@ const char *cma_get_name(const struct cma *cma) - { - return cma->name ? cma->name : "(undefined)"; - } -+EXPORT_SYMBOL_GPL(cma_get_name); - - static unsigned long cma_bitmap_aligned_mask(const struct cma *cma, - unsigned int align_order) -@@ -500,6 +502,7 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, - pr_debug("%s(): returned %p\n", __func__, page); - return page; - } -+EXPORT_SYMBOL_GPL(cma_alloc); - - /** - * cma_release() - release allocated pages -@@ -533,6 +536,7 @@ bool cma_release(struct cma *cma, const struct page *pages, unsigned int count) - - return true; - } -+EXPORT_SYMBOL_GPL(cma_release); - - int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data) - { -@@ -547,3 +551,4 @@ int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data) - - return 0; - } -+EXPORT_SYMBOL_GPL(cma_for_each_area); diff --git a/patches/ANDROID-Initial-abi_gki_aarch64-definition.patch b/patches/ANDROID-Initial-abi_gki_aarch64-definition.patch deleted file mode 100644 index ca1290799e7c..000000000000 --- a/patches/ANDROID-Initial-abi_gki_aarch64-definition.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Matthias Maennich -Date: Tue, 28 May 2019 12:38:16 +0100 -Subject: ANDROID: Initial abi_gki_aarch64 definition - -abi_gki_aarch64.out contains the ABI definition corresponding to the -current sources and the configuration referred to in -build.config.gki.aarch64. - -As part of the build.sh tooling it will be copied over into the -distribution for further inspection / analysis. See -https://android-review.googlesource.com/970737 for details on that -process. - -This is the initial version of this definition to allow implementation -of workflows around it. It is not considered stable at this point. It is -expected that it will break with significant changes from either -upstream or with changes implemented specific for this tree. Automated -validation is supposed to catch differences between this definition and -the actual binary before they are introduced into the tree. At a later -stage this validation should be part of build.sh itself. - -Bug: 133501930 -Change-Id: I815940ee13037ad450547e0ab0786e37f0b83d9b -Signed-off-by: Matthias Maennich ---- - build.config.gki.aarch64 | 24 +++++------------------- - 1 file changed, 5 insertions(+), 19 deletions(-) - -diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 -index 653e82bf1965..352a6382b06c 100644 ---- a/build.config.gki.aarch64 -+++ b/build.config.gki.aarch64 -@@ -1,19 +1,5 @@ --ARCH=arm64 --BRANCH=android-mainline --CLANG_TRIPLE=aarch64-linux-gnu- --CROSS_COMPILE=aarch64-linux-androidkernel- --CC=clang --DEFCONFIG=gki_defconfig --EXTRA_CMDS='' --KERNEL_DIR=common --POST_DEFCONFIG_CMDS="check_defconfig" --CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin --BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 --LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin --FILES=" --arch/arm64/boot/Image.gz --vmlinux --System.map --" --STOP_SHIP_TRACEPRINTK=1 --BUILD_INITRAMFS=1 -+. ${ROOT_DIR}/common/build.config.common -+. ${ROOT_DIR}/common/build.config.aarch64 -+. ${ROOT_DIR}/common/build.config.gki -+ -+ABI_DEFINITION=abi_gki_aarch64.xml diff --git a/patches/ANDROID-Kbuild-LLVMLinux-allow-overriding-clang-target-triple.patch b/patches/ANDROID-Kbuild-LLVMLinux-allow-overriding-clang-target-triple.patch deleted file mode 100644 index 07a260d4ab43..000000000000 --- a/patches/ANDROID-Kbuild-LLVMLinux-allow-overriding-clang-target-triple.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Greg Hackmann -Date: Tue, 25 Oct 2016 13:59:59 -0700 -Subject: ANDROID: Kbuild, LLVMLinux: allow overriding clang target triple - -Android has an unusual setup where the kernel needs to target -[arch]-linux-gnu to avoid Android userspace-specific flags and -optimizations, but AOSP doesn't ship a matching binutils. - -Add a new variable CLANG_TRIPLE which can override the "-target" triple -used to compile the kernel, while using a different CROSS_COMPILE to -pick the binutils/gcc installation. For Android you'd do something -like: - - export CLANG_TRIPLE=aarch64-linux-gnu- - export CROSS_COMPILE=aarch64-linux-android- - -If you don't need something like this, leave CLANG_TRIPLE unset and it -will default to CROSS_COMPILE. - -Change-Id: I85d63599c6ab8ed458071cdf9197d85b1f7f150b -Signed-off-by: Greg Hackmann -[astrachan: Added a script to check for incorrectly falling back to the - default when CLANG_TRIPLE is unset] -Bug: 118439987 -Bug: 120440614 -Test: make CLANG_TRIPLE=x86_64-linux-gnu CC=clang -Signed-off-by: Alistair Strachan ---- - Makefile | 6 +++++- - scripts/clang-android.sh | 4 ++++ - 2 files changed, 9 insertions(+), 1 deletion(-) - create mode 100644 scripts/clang-android.sh - -diff --git a/Makefile b/Makefile -index ffd7a912fc46..dd248a6159ee 100644 ---- a/Makefile -+++ b/Makefile -@@ -526,7 +526,11 @@ endif - - ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),) - ifneq ($(CROSS_COMPILE),) --CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%)) -+CLANG_TRIPLE ?= $(CROSS_COMPILE) -+CLANG_FLAGS += --target=$(notdir $(CLANG_TRIPLE:%-=%)) -+ifeq ($(shell $(srctree)/scripts/clang-android.sh $(CC) $(CLANG_FLAGS)), y) -+$(error "Clang with Android --target detected. Did you specify CLANG_TRIPLE?") -+endif - GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) - CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR) - GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..) -diff --git a/scripts/clang-android.sh b/scripts/clang-android.sh -new file mode 100644 -index 000000000000..9186c4f48576 ---- /dev/null -+++ b/scripts/clang-android.sh -@@ -0,0 +1,4 @@ -+#!/bin/sh -+# SPDX-License-Identifier: GPL-2.0 -+ -+$* -dM -E - &1 | grep -q __ANDROID__ && echo "y" diff --git a/patches/ANDROID-Log-which-device-failed-to-suspend-in-dpm_suspend_start.patch b/patches/ANDROID-Log-which-device-failed-to-suspend-in-dpm_suspend_start.patch deleted file mode 100644 index cf4824b4a27d..000000000000 --- a/patches/ANDROID-Log-which-device-failed-to-suspend-in-dpm_suspend_start.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: zhuguangqing -Date: Fri, 23 Aug 2019 09:04:06 +0800 -Subject: ANDROID: Log which device failed to suspend in dpm_suspend_start() - -Problem background: In the process of suspend, maybe some device suspend -callback failed in dpm_suspend_start()/dpm_prepare()/dpm_suspend(). -Because it's after suspend_console(), so printf() is disabled now. -Currently we can see "Some devices failed to suspend, or early wake -event detected" by log_suspend_abort_reason() in bugreport. There are -many devices but we don't know which exactly device failed. So we -want to do a little change to record which device failed. - -Note: I checked upstream LTS kernel, then I found the -patch can not be sent upstream, because it uses function -log_suspend_abort_reason() in wakeup_reason.c, the initial -patch(https://patchwork.kernel.org/patch/3827331/) for adding -/kernel/power/wakeup_reason.c is not accepted by upstream which -was merged in AOSP common kernels. So maybe the patch could -only be sent to AOSP common kernels. - -Test: manual - Use modified version for daily use two days, from -bugreport we can see which device failed. -Bug: 120445600 -Change-Id: I326c87ca1263496db79d08ec615f12fc22452d7a -Signed-off-by: zhuguangqing ---- - drivers/base/power/main.c | 1 + - kernel/power/suspend.c | 7 +++++-- - 2 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c -index f545b4526172..40657d602be6 100644 ---- a/drivers/base/power/main.c -+++ b/drivers/base/power/main.c -@@ -1996,6 +1996,7 @@ int dpm_prepare(pm_message_t state) - } - pr_info("Device %s not prepared for power transition: code %d\n", - dev_name(dev), error); -+ dpm_save_failed_dev(dev_name(dev)); - put_device(dev); - break; - } -diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c -index de6b24bc0619..0bb1c1d8c979 100644 ---- a/kernel/power/suspend.c -+++ b/kernel/power/suspend.c -@@ -489,7 +489,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) - */ - int suspend_devices_and_enter(suspend_state_t state) - { -- int error; -+ int error, last_dev; - bool wakeup = false; - - if (!sleep_state_supported(state)) -@@ -508,8 +508,11 @@ int suspend_devices_and_enter(suspend_state_t state) - suspend_test_start(); - error = dpm_suspend_start(PMSG_SUSPEND); - if (error) { -+ last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1; -+ last_dev %= REC_FAILED_NUM; - pr_err("Some devices failed to suspend, or early wake event detected\n"); -- log_suspend_abort_reason("Some devices failed to suspend, or early wake event detected"); -+ log_suspend_abort_reason("%s device failed to suspend, or early wake event detected", -+ suspend_stats.failed_devs[last_dev]); - goto Recover_platform; - } - suspend_test_finish("suspend devices"); diff --git a/patches/ANDROID-Move-from-clang-r349610-to-r353983c.patch b/patches/ANDROID-Move-from-clang-r349610-to-r353983c.patch deleted file mode 100644 index 33d80b0d4f8b..000000000000 --- a/patches/ANDROID-Move-from-clang-r349610-to-r353983c.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alistair Strachan -Date: Tue, 14 May 2019 16:07:58 -0700 -Subject: ANDROID: Move from clang r349610 to r353983c. - -Bug: 120439617 -Bug: 132097678 -Test: make ARCH=arm64 cuttlefish_defconfig && make ARCH=arm64 -Test: make ARCH=x86_64 x86_64_cuttlefish_defconfig && make ARCH=x86_64 -Change-Id: If5542a39e36fb4de6dd4b4135a22e188f752dd84 -Signed-off-by: Alistair Strachan ---- - build.config.gki.aarch64 | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 -index dec295284ffa..ecc2985e92cb 100644 ---- a/build.config.gki.aarch64 -+++ b/build.config.gki.aarch64 -@@ -7,7 +7,7 @@ DEFCONFIG=gki_defconfig - EXTRA_CMDS='' - KERNEL_DIR=common - POST_DEFCONFIG_CMDS="check_defconfig" --CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r349610/bin -+CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin - LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin - FILES=" - arch/arm64/boot/Image.gz diff --git a/patches/ANDROID-Remove-CONFIG_USELIB-from-x86-gki-config.patch b/patches/ANDROID-Remove-CONFIG_USELIB-from-x86-gki-config.patch deleted file mode 100644 index f5a6d06ae0ff..000000000000 --- a/patches/ANDROID-Remove-CONFIG_USELIB-from-x86-gki-config.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Fri, 20 Sep 2019 15:28:37 -0700 -Subject: ANDROID: Remove CONFIG_USELIB from x86 gki config - -Bug: 138199351 -Change-Id: Ib517ad710337a38602bf7f30ecf616d6d02ca8af -Signed-off-by: Ram Muthiah ---- - arch/x86/configs/gki_defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index bcd12981dff4..642729662b04 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -1,4 +1,5 @@ - CONFIG_LOCALVERSION="-mainline" -+# CONFIG_USELIB is not set - CONFIG_AUDIT=y - CONFIG_NO_HZ=y - CONFIG_HIGH_RES_TIMERS=y diff --git a/patches/ANDROID-Removed-check-for-asm-goto.patch b/patches/ANDROID-Removed-check-for-asm-goto.patch deleted file mode 100644 index 33f041226551..000000000000 --- a/patches/ANDROID-Removed-check-for-asm-goto.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alistair Strachan -Date: Wed, 24 Oct 2018 13:58:11 -0700 -Subject: ANDROID: Removed check for asm-goto - -Cherry pick was manually applied due to conflicts with -upstream commits: e9666d10a56 and 829fe4aa9ac --------- -Revert "x86: Force asm-goto" - -This reverts commit e501ce957a786ecd076ea0cfb10b114e6e4d0f40. - -This change broke building the x86_64 kernel with clang. The kernel -still builds and works fine without asm-goto support. Revert this -change to unblock testing clang kernels on cuttlefish. - -Bug: 118142806 -Bug: 120440614 -Bug: 132629930 -Change-Id: Ib32498acc0596264f8cd15de0b603579dd643dd7 -Signed-off-by: Alistair Strachan -Signed-off-by: Ram Muthiah ---- - arch/x86/Makefile | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/arch/x86/Makefile b/arch/x86/Makefile -index 94df0868804b..408bb5532d1b 100644 ---- a/arch/x86/Makefile -+++ b/arch/x86/Makefile -@@ -298,10 +298,6 @@ vdso_install: - - archprepare: checkbin - checkbin: --ifndef CONFIG_CC_HAS_ASM_GOTO -- @echo Compiler lacks asm-goto support. -- @exit 1 --endif - ifdef CONFIG_RETPOLINE - ifeq ($(RETPOLINE_CFLAGS),) - @echo "You are building kernel with non-retpoline compiler." >&2 diff --git a/patches/ANDROID-Removed-extraneous-configs-from-gki.patch b/patches/ANDROID-Removed-extraneous-configs-from-gki.patch deleted file mode 100644 index 2f8ab3df4b79..000000000000 --- a/patches/ANDROID-Removed-extraneous-configs-from-gki.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Wed, 12 Jun 2019 18:05:43 -0700 -Subject: ANDROID: Removed extraneous configs from gki - -Removed SCSI_VIRTIO and VIRTIO_BALLOON - -Test: Boot x86 cuttlefish and gki -Signed-off-by: Ram Muthiah -Change-Id: I342ee9a9a2c715565ce5304f37d40575c234efd6 ---- - arch/arm64/configs/gki_defconfig | 2 -- - arch/x86/configs/gki_defconfig | 2 -- - 2 files changed, 4 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 9bc2782661dc..7eeafbecf1b9 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -196,7 +196,6 @@ CONFIG_SCSI=y - CONFIG_BLK_DEV_SD=y - CONFIG_SCSI_UFSHCD=y - CONFIG_SCSI_UFSHCD_PLATFORM=y --CONFIG_SCSI_VIRTIO=y - CONFIG_MD=y - CONFIG_BLK_DEV_DM=y - CONFIG_DM_CRYPT=y -@@ -327,7 +326,6 @@ CONFIG_RTC_DRV_PL030=y - CONFIG_RTC_DRV_PL031=y - CONFIG_VIRTIO_PCI=y - # CONFIG_VIRTIO_PCI_LEGACY is not set --CONFIG_VIRTIO_BALLOON=y - CONFIG_VIRTIO_INPUT=y - CONFIG_VIRTIO_MMIO=y - CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 7f4edee2b52d..c0993920b94d 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -174,7 +174,6 @@ CONFIG_UID_SYS_STATS=y - CONFIG_SCSI=y - # CONFIG_SCSI_PROC_FS is not set - CONFIG_BLK_DEV_SD=y --CONFIG_SCSI_VIRTIO=y - CONFIG_MD=y - CONFIG_BLK_DEV_DM=y - CONFIG_DM_CRYPT=y -@@ -282,7 +281,6 @@ CONFIG_LEDS_TRIGGERS=y - CONFIG_RTC_CLASS=y - # CONFIG_RTC_SYSTOHC is not set - CONFIG_VIRTIO_PCI=y --CONFIG_VIRTIO_BALLOON=y - CONFIG_VIRTIO_INPUT=y - CONFIG_VIRTIO_MMIO=y - CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y diff --git a/patches/ANDROID-Removed-extraneous-serial-8250-configs.patch b/patches/ANDROID-Removed-extraneous-serial-8250-configs.patch deleted file mode 100644 index 86baa08485a1..000000000000 --- a/patches/ANDROID-Removed-extraneous-serial-8250-configs.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Sun, 15 Sep 2019 23:24:48 -0700 -Subject: ANDROID: Removed extraneous serial 8250 configs - -Signed-off-by: Ram Muthiah -Test: Local Boot of cuttlefish with this kernel -Bug: 132629930 -Change-Id: I12afb2b95105bfdbaa81cc51367664fa36a4f60c ---- - arch/arm64/configs/gki_defconfig | 4 ---- - arch/x86/configs/gki_defconfig | 4 ---- - 2 files changed, 8 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index d650f7d141e7..ea9960028cfd 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -264,10 +264,6 @@ CONFIG_SERIAL_8250=y - # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set - CONFIG_SERIAL_8250_CONSOLE=y - # CONFIG_SERIAL_8250_EXAR is not set --CONFIG_SERIAL_8250_NR_UARTS=48 --CONFIG_SERIAL_8250_EXTENDED=y --CONFIG_SERIAL_8250_MANY_PORTS=y --CONFIG_SERIAL_8250_SHARE_IRQ=y - CONFIG_SERIAL_OF_PLATFORM=m - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 511a763add37..a5953d43d480 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -237,10 +237,6 @@ CONFIG_INPUT_UINPUT=y - CONFIG_SERIAL_8250=y - # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set - CONFIG_SERIAL_8250_CONSOLE=y --CONFIG_SERIAL_8250_NR_UARTS=48 --CONFIG_SERIAL_8250_EXTENDED=y --CONFIG_SERIAL_8250_MANY_PORTS=y --CONFIG_SERIAL_8250_SHARE_IRQ=y - CONFIG_SERIAL_OF_PLATFORM=m - CONFIG_HW_RANDOM=y - CONFIG_HW_RANDOM_VIRTIO=m diff --git a/patches/ANDROID-Removed-hardcoded-kernel-command-line-arguments.patch b/patches/ANDROID-Removed-hardcoded-kernel-command-line-arguments.patch deleted file mode 100644 index 2af238eae67b..000000000000 --- a/patches/ANDROID-Removed-hardcoded-kernel-command-line-arguments.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Sun, 4 Aug 2019 13:37:09 -0700 -Subject: ANDROID: Removed hardcoded kernel command line arguments - -Test: Booted mainline on cuttlefish locally -Signed-off-by: Ram Muthiah -Change-Id: I5a32dcc1bc4faaff08b032f4ff8350adf2bbb5c1 ---- - arch/x86/configs/gki_defconfig | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 4016f8be75c5..731cec5e1bc3 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -35,8 +35,6 @@ CONFIG_SLAB_FREELIST_RANDOM=y - CONFIG_SLAB_FREELIST_HARDENED=y - CONFIG_PROFILING=y - CONFIG_SMP=y --CONFIG_CMDLINE_BOOL=y --CONFIG_CMDLINE="console=ttyS0 reboot=p" - CONFIG_PM_WAKELOCKS=y - CONFIG_PM_WAKELOCKS_LIMIT=0 - # CONFIG_PM_WAKELOCKS_GC is not set diff --git a/patches/ANDROID-Removed-unnecessary-modules-from-cuttlefish.patch b/patches/ANDROID-Removed-unnecessary-modules-from-cuttlefish.patch deleted file mode 100644 index e58596ec57e4..000000000000 --- a/patches/ANDROID-Removed-unnecessary-modules-from-cuttlefish.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Fri, 9 Aug 2019 12:48:12 -0700 -Subject: ANDROID: Removed unnecessary modules from cuttlefish. - -Modules do not succesfuly load on cuttlefish and are not needed for gki. - -Bug: 132629930 -Test: Treehugger + Launch local KO Ramdisk -Signed-of-by: Ram Muthiah -Change-Id: I07b6c140e4c474d66132a4fb5630d18933b69e81 ---- - arch/x86/configs/gki_defconfig | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 731cec5e1bc3..2d5f55d7b966 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -242,11 +242,13 @@ CONFIG_HW_RANDOM_VIRTIO=y - CONFIG_GPIOLIB=y - # CONFIG_HWMON is not set - CONFIG_DEVFREQ_THERMAL=y -+# CONFIG_X86_PKG_TEMP_THERMAL is not set - CONFIG_MEDIA_SUPPORT=y - CONFIG_MEDIA_CAMERA_SUPPORT=y - CONFIG_DRM=y - # CONFIG_DRM_FBDEV_EMULATION is not set - CONFIG_DRM_VIRTIO_GPU=y -+# CONFIG_LCD_CLASS_DEVICE is not set - CONFIG_BACKLIGHT_CLASS_DEVICE=y - CONFIG_SOUND=y - CONFIG_SND=y diff --git a/patches/ANDROID-Revert-kheaders-make-headers-archive-reproducible.patch b/patches/ANDROID-Revert-kheaders-make-headers-archive-reproducible.patch deleted file mode 100644 index 48f55767efb5..000000000000 --- a/patches/ANDROID-Revert-kheaders-make-headers-archive-reproducible.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alistair Delva -Date: Wed, 9 Oct 2019 15:25:35 -0400 -Subject: ANDROID: Revert "kheaders: make headers archive reproducible" - -This reverts commit 86cdd2fdc4e39c388d39c7ba2396d1a9dfd66226. - -Reason: Broke "make allmodconfig" on Android build machines - -$ tar: unrecognized option '--sort=name' -Try 'tar --help' or 'tar --usage' for more information. - -Signed-off-by: Alistair Delva -Change-Id: I3d406988f23201e5ab824ca7aed215ccc9d43279 ---- - Documentation/kbuild/reproducible-builds.rst | 13 ++++--------- - kernel/gen_kheaders.sh | 5 +---- - 2 files changed, 5 insertions(+), 13 deletions(-) - -diff --git a/Documentation/kbuild/reproducible-builds.rst b/Documentation/kbuild/reproducible-builds.rst -index 503393854e2e..ab92e98c89c8 100644 ---- a/Documentation/kbuild/reproducible-builds.rst -+++ b/Documentation/kbuild/reproducible-builds.rst -@@ -16,21 +16,16 @@ the kernel may be unreproducible, and how to avoid them. - Timestamps - ---------- - --The kernel embeds timestamps in three places: -+The kernel embeds a timestamp in two places: - - * The version string exposed by ``uname()`` and included in - ``/proc/version`` - - * File timestamps in the embedded initramfs - --* If enabled via ``CONFIG_IKHEADERS``, file timestamps of kernel -- headers embedded in the kernel or respective module, -- exposed via ``/sys/kernel/kheaders.tar.xz`` -- --By default the timestamp is the current time and in the case of --``kheaders`` the various files' modification times. This must --be overridden using the `KBUILD_BUILD_TIMESTAMP`_ variable. --If you are building from a git commit, you could use its commit date. -+By default the timestamp is the current time. This must be overridden -+using the `KBUILD_BUILD_TIMESTAMP`_ variable. If you are building -+from a git commit, you could use its commit date. - - The kernel does *not* use the ``__DATE__`` and ``__TIME__`` macros, - and enables warnings if they are used. If you incorporate external -diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh -index aff79e461fc9..9ff449888d9c 100755 ---- a/kernel/gen_kheaders.sh -+++ b/kernel/gen_kheaders.sh -@@ -71,10 +71,7 @@ done | cpio --quiet -pd $cpio_dir >/dev/null 2>&1 - find $cpio_dir -type f -print0 | - xargs -0 -P8 -n1 perl -pi -e 'BEGIN {undef $/;}; s/\/\*((?!SPDX).)*?\*\///smg;' - --# Create archive and try to normalize metadata for reproducibility --tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ -- --owner=0 --group=0 --sort=name --numeric-owner \ -- -Jcf $tarfile -C $cpio_dir/ . > /dev/null -+tar -Jcf $tarfile -C $cpio_dir/ . > /dev/null - - echo "$src_files_md5" > kernel/kheaders.md5 - echo "$obj_files_md5" >> kernel/kheaders.md5 diff --git a/patches/ANDROID-Revert-um-irq-don-t-set-the-chip-for-all-irqs.patch b/patches/ANDROID-Revert-um-irq-don-t-set-the-chip-for-all-irqs.patch deleted file mode 100644 index eba9c507a494..000000000000 --- a/patches/ANDROID-Revert-um-irq-don-t-set-the-chip-for-all-irqs.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alistair Delva -Date: Thu, 22 Aug 2019 16:53:19 -0700 -Subject: ANDROID: Revert "um: irq: don't set the chip for all irqs" - -This reverts commit 1987b1b8f9f17a06255877e7917d0bb5b5377774. - -Reason: Broke UML used by kernel_tests - -Bug: 139897923 -Change-Id: If3541721fdca7cf6d77410309ae5b503b5a848d0 -Signed-off-by: Alistair Delva ---- - arch/um/kernel/irq.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c -index 3577118bb4a5..9410424af710 100644 ---- a/arch/um/kernel/irq.c -+++ b/arch/um/kernel/irq.c -@@ -480,7 +480,7 @@ void __init init_IRQ(void) - irq_set_chip_and_handler(TIMER_IRQ, &SIGVTALRM_irq_type, handle_edge_irq); - - -- for (i = 1; i <= LAST_IRQ; i++) -+ for (i = 1; i < NR_IRQS; i++) - irq_set_chip_and_handler(i, &normal_irq_type, handle_edge_irq); - /* Initialize EPOLL Loop */ - os_setup_epoll(); diff --git a/patches/ANDROID-Revert-um-remove-uses-of-variable-length-arrays.patch b/patches/ANDROID-Revert-um-remove-uses-of-variable-length-arrays.patch deleted file mode 100644 index fa51a69e28fb..000000000000 --- a/patches/ANDROID-Revert-um-remove-uses-of-variable-length-arrays.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alistair Delva -Date: Thu, 22 Aug 2019 16:53:55 -0700 -Subject: ANDROID: Revert "um: remove uses of variable length arrays" - -This reverts commit 0d4e5ac7e78035950d564e65c38ce148cb9af681. - -Reason: Broke UML used by kernel_tests - -Bug: 139897923 -Change-Id: Ibf57c1f535e60caaef32dd14c4abbe253d8e185d -Signed-off-by: Alistair Delva ---- - arch/um/os-Linux/umid.c | 36 +++++++++--------------------------- - 1 file changed, 9 insertions(+), 27 deletions(-) - -diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c -index 44def53a11cd..4c19df8d2e80 100644 ---- a/arch/um/os-Linux/umid.c -+++ b/arch/um/os-Linux/umid.c -@@ -135,18 +135,12 @@ static int remove_files_and_dir(char *dir) - */ - static inline int is_umdir_used(char *dir) - { -- char pid[sizeof("nnnnn\0")], *end, *file; -+ char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; -+ char pid[sizeof("nnnnn\0")], *end; - int dead, fd, p, n, err; -- size_t filelen; - -- err = asprintf(&file, "%s/pid", dir); -- if (err < 0) -- return 0; -- -- filelen = strlen(file); -- -- n = snprintf(file, filelen, "%s/pid", dir); -- if (n >= filelen) { -+ n = snprintf(file, sizeof(file), "%s/pid", dir); -+ if (n >= sizeof(file)) { - printk(UM_KERN_ERR "is_umdir_used - pid filename too long\n"); - err = -E2BIG; - goto out; -@@ -191,7 +185,6 @@ static inline int is_umdir_used(char *dir) - out_close: - close(fd); - out: -- free(file); - return 0; - } - -@@ -217,21 +210,18 @@ static int umdir_take_if_dead(char *dir) - - static void __init create_pid_file(void) - { -- char pid[sizeof("nnnnn\0")], *file; -+ char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; -+ char pid[sizeof("nnnnn\0")]; - int fd, n; - -- file = malloc(strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")); -- if (!file) -- return; -- - if (umid_file_name("pid", file, sizeof(file))) -- goto out; -+ return; - - fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644); - if (fd < 0) { - printk(UM_KERN_ERR "Open of machine pid file \"%s\" failed: " - "%s\n", file, strerror(errno)); -- goto out; -+ return; - } - - snprintf(pid, sizeof(pid), "%d\n", getpid()); -@@ -241,8 +231,6 @@ static void __init create_pid_file(void) - errno); - - close(fd); --out: -- free(file); - } - - int __init set_umid(char *name) -@@ -397,19 +385,13 @@ __uml_setup("uml_dir=", set_uml_dir, - - static void remove_umid_dir(void) - { -- char *dir, err; -- -- dir = malloc(strlen(uml_dir) + UMID_LEN + 1); -- if (!dir) -- return; -+ char dir[strlen(uml_dir) + UMID_LEN + 1], err; - - sprintf(dir, "%s%s", uml_dir, umid); - err = remove_files_and_dir(dir); - if (err) - os_warn("%s - remove_files_and_dir failed with err = %d\n", - __func__, err); -- -- free(dir); - } - - __uml_exitcall(remove_umid_dir); diff --git a/patches/ANDROID-Revert-x86-mm-Identify-the-end-of-the-kernel-area-to-be-reserved.patch b/patches/ANDROID-Revert-x86-mm-Identify-the-end-of-the-kernel-area-to-be-reserved.patch deleted file mode 100644 index a544d46251d7..000000000000 --- a/patches/ANDROID-Revert-x86-mm-Identify-the-end-of-the-kernel-area-to-be-reserved.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Tue, 23 Jul 2019 14:52:18 +0200 -Subject: ANDROID: Revert "x86/mm: Identify the end of the kernel area to be - reserved" - -This reverts commit c603a309cc75f3dd018ddb20ee44c05047918cbf. - -It breaks the build with clang. - -Signed-off-by: Greg Kroah-Hartman -Change-Id: I2e50915dacfa823c80067f38dc43ef368c24bd2e ---- - arch/x86/include/asm/sections.h | 2 -- - arch/x86/kernel/setup.c | 8 +------- - arch/x86/kernel/vmlinux.lds.S | 9 +-------- - 3 files changed, 2 insertions(+), 17 deletions(-) - -diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h -index 71b32f2570ab..8ea1cfdbeabc 100644 ---- a/arch/x86/include/asm/sections.h -+++ b/arch/x86/include/asm/sections.h -@@ -13,6 +13,4 @@ extern char __end_rodata_aligned[]; - extern char __end_rodata_hpage_align[]; - #endif - --extern char __end_of_kernel_reserve[]; -- - #endif /* _ASM_X86_SECTIONS_H */ -diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index 77ea96b794bd..f007d910a6e6 100644 ---- a/arch/x86/kernel/setup.c -+++ b/arch/x86/kernel/setup.c -@@ -836,14 +836,8 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p) - - void __init setup_arch(char **cmdline_p) - { -- /* -- * Reserve the memory occupied by the kernel between _text and -- * __end_of_kernel_reserve symbols. Any kernel sections after the -- * __end_of_kernel_reserve symbol must be explicitly reserved with a -- * separate memblock_reserve() or they will be discarded. -- */ - memblock_reserve(__pa_symbol(_text), -- (unsigned long)__end_of_kernel_reserve - (unsigned long)_text); -+ (unsigned long)__bss_stop - (unsigned long)_text); - - /* - * Make sure page 0 is always reserved because on systems with -diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S -index e2feacf921a0..4f062d33ef73 100644 ---- a/arch/x86/kernel/vmlinux.lds.S -+++ b/arch/x86/kernel/vmlinux.lds.S -@@ -368,14 +368,6 @@ SECTIONS - __bss_stop = .; - } - -- /* -- * The memory occupied from _text to here, __end_of_kernel_reserve, is -- * automatically reserved in setup_arch(). Anything after here must be -- * explicitly reserved using memblock_reserve() or it will be discarded -- * and treated as available memory. -- */ -- __end_of_kernel_reserve = .; -- - . = ALIGN(PAGE_SIZE); - .brk : AT(ADDR(.brk) - LOAD_OFFSET) { - __brk_base = .; -@@ -415,6 +407,7 @@ SECTIONS - STABS_DEBUG - DWARF_DEBUG - -+ /* Sections to be discarded */ - DISCARDS - /DISCARD/ : { - *(.eh_frame) diff --git a/patches/ANDROID-add-extra-free-kbytes-tunable.patch b/patches/ANDROID-add-extra-free-kbytes-tunable.patch deleted file mode 100644 index f8a6e6a1b217..000000000000 --- a/patches/ANDROID-add-extra-free-kbytes-tunable.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Rik van Riel -Date: Thu, 1 Sep 2011 15:26:50 -0400 -Subject: ANDROID: add extra free kbytes tunable - -Add a userspace visible knob to tell the VM to keep an extra amount -of memory free, by increasing the gap between each zone's min and -low watermarks. - -This is useful for realtime applications that call system -calls and have a bound on the number of allocations that happen -in any short time period. In this application, extra_free_kbytes -would be left at an amount equal to or larger than than the -maximum number of allocations that happen in any burst. - -It may also be useful to reduce the memory use of virtual -machines (temporarily?), in a way that does not cause memory -fragmentation like ballooning does. - -[ccross] -Revived for use on old kernels where no other solution exists. -The tunable will be removed on kernels that do better at avoiding -direct reclaim. - -[surenb] -Will be reverted as soon as Android framework is reworked to -use upstream-supported watermark_scale_factor instead of -extra_free_kbytes. - -Bug: 86445363 -Bug: 109664768 -Bug: 120445732 -Change-Id: I765a42be8e964bfd3e2886d1ca85a29d60c3bb3e -Signed-off-by: Rik van Riel -Signed-off-by: Colin Cross -Signed-off-by: Suren Baghdasaryan ---- - Documentation/admin-guide/sysctl/vm.rst | 16 ++++++++++++++++ - kernel/sysctl.c | 9 +++++++++ - mm/page_alloc.c | 25 +++++++++++++++++++++---- - 3 files changed, 46 insertions(+), 4 deletions(-) - -diff --git a/Documentation/admin-guide/sysctl/vm.rst b/Documentation/admin-guide/sysctl/vm.rst -index 64aeee1009ca..9e8470008227 100644 ---- a/Documentation/admin-guide/sysctl/vm.rst -+++ b/Documentation/admin-guide/sysctl/vm.rst -@@ -37,6 +37,7 @@ Currently, these files are in /proc/sys/vm: - - dirty_writeback_centisecs - - drop_caches - - extfrag_threshold -+- extra_free_kbytes - - hugetlb_shm_group - - laptop_mode - - legacy_va_layout -@@ -287,6 +288,21 @@ only use the low memory and they can fill it up with dirty data without - any throttling. - - -+extra_free_kbytes -+ -+This parameter tells the VM to keep extra free memory between the threshold -+where background reclaim (kswapd) kicks in, and the threshold where direct -+reclaim (by allocating processes) kicks in. -+ -+This is useful for workloads that require low latency memory allocations -+and have a bounded burstiness in memory allocations, for example a -+realtime application that receives and transmits network traffic -+(causing in-kernel memory allocations) with a maximum total message burst -+size of 200MB may need 200MB of extra free memory to avoid direct reclaim -+related latencies. -+ -+============================================================== -+ - hugetlb_shm_group - ================= - -diff --git a/kernel/sysctl.c b/kernel/sysctl.c -index 00fcea236eba..570cf6083712 100644 ---- a/kernel/sysctl.c -+++ b/kernel/sysctl.c -@@ -111,6 +111,7 @@ extern char core_pattern[]; - extern unsigned int core_pipe_limit; - #endif - extern int pid_max; -+extern int extra_free_kbytes; - extern int pid_max_min, pid_max_max; - extern int percpu_pagelist_fraction; - extern int latencytop_enabled; -@@ -1524,6 +1525,14 @@ static struct ctl_table vm_table[] = { - .extra1 = SYSCTL_ONE, - .extra2 = &one_thousand, - }, -+ { -+ .procname = "extra_free_kbytes", -+ .data = &extra_free_kbytes, -+ .maxlen = sizeof(extra_free_kbytes), -+ .mode = 0644, -+ .proc_handler = min_free_kbytes_sysctl_handler, -+ .extra1 = SYSCTL_ZERO, -+ }, - { - .procname = "percpu_pagelist_fraction", - .data = &percpu_pagelist_fraction, -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index c0b2e0306720..ca7e48d00f3f 100644 ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -313,6 +313,11 @@ compound_page_dtor * const compound_page_dtors[] = { - #endif - }; - -+/* -+ * Try to keep at least this much lowmem free. Do not allow normal -+ * allocations below this point, only high priority ones. Automatically -+ * tuned according to the amount of memory in the system. -+ */ - int min_free_kbytes = 1024; - int user_min_free_kbytes = -1; - #ifdef CONFIG_DISCONTIGMEM -@@ -331,6 +336,13 @@ int watermark_boost_factor __read_mostly = 15000; - #endif - int watermark_scale_factor = 10; - -+/* -+ * Extra memory for the system to try freeing. Used to temporarily -+ * free memory, to make space for new workloads. Anyone can allocate -+ * down to the min watermarks controlled by min_free_kbytes above. -+ */ -+int extra_free_kbytes = 0; -+ - static unsigned long nr_kernel_pages __initdata; - static unsigned long nr_all_pages __initdata; - static unsigned long dma_reserve __initdata; -@@ -7731,6 +7743,7 @@ static void setup_per_zone_lowmem_reserve(void) - static void __setup_per_zone_wmarks(void) - { - unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10); -+ unsigned long pages_low = extra_free_kbytes >> (PAGE_SHIFT - 10); - unsigned long lowmem_pages = 0; - struct zone *zone; - unsigned long flags; -@@ -7742,11 +7755,13 @@ static void __setup_per_zone_wmarks(void) - } - - for_each_zone(zone) { -- u64 tmp; -+ u64 tmp, low; - - spin_lock_irqsave(&zone->lock, flags); - tmp = (u64)pages_min * zone_managed_pages(zone); - do_div(tmp, lowmem_pages); -+ low = (u64)pages_low * zone_managed_pages(zone); -+ do_div(low, vm_total_pages); - if (is_highmem(zone)) { - /* - * __GFP_HIGH and PF_MEMALLOC allocations usually don't -@@ -7779,8 +7794,10 @@ static void __setup_per_zone_wmarks(void) - mult_frac(zone_managed_pages(zone), - watermark_scale_factor, 10000)); - -- zone->_watermark[WMARK_LOW] = min_wmark_pages(zone) + tmp; -- zone->_watermark[WMARK_HIGH] = min_wmark_pages(zone) + tmp * 2; -+ zone->_watermark[WMARK_LOW] = min_wmark_pages(zone) + -+ low + tmp; -+ zone->_watermark[WMARK_HIGH] = min_wmark_pages(zone) + -+ low + tmp * 2; - zone->watermark_boost = 0; - - spin_unlock_irqrestore(&zone->lock, flags); -@@ -7864,7 +7881,7 @@ core_initcall(init_per_zone_wmark_min) - /* - * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so - * that we can call two helper functions whenever min_free_kbytes -- * changes. -+ * or extra_free_kbytes changes. - */ - int min_free_kbytes_sysctl_handler(struct ctl_table *table, int write, - void __user *buffer, size_t *length, loff_t *ppos) diff --git a/patches/ANDROID-added-configs-so-that-GKI-boots-on-x86-cuttlefish.patch b/patches/ANDROID-added-configs-so-that-GKI-boots-on-x86-cuttlefish.patch deleted file mode 100644 index 00cc791dffb3..000000000000 --- a/patches/ANDROID-added-configs-so-that-GKI-boots-on-x86-cuttlefish.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Wed, 22 May 2019 20:11:24 -0700 -Subject: ANDROID: added configs so that GKI boots on x86 cuttlefish - -Bug: 132629930 -Test: built and ran gki on cuttlefish locally -Change-Id: I2cbfef4fd97888edaa5b6413a2459160c7117bd5 -Signed-off-by: Ram Muthiah ---- - arch/x86/configs/gki_defconfig | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 18ba312d0a60..cdaba53b7bb0 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -38,6 +38,7 @@ CONFIG_CPU_FREQ=y - CONFIG_CPU_FREQ_TIMES=y - CONFIG_CPU_FREQ_GOV_POWERSAVE=y - CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -+CONFIG_IA32_EMULATION=y - CONFIG_KPROBES=y - CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y -@@ -156,6 +157,7 @@ CONFIG_CFG80211=y - CONFIG_MAC80211=y - # CONFIG_MAC80211_RC_MINSTREL is not set - CONFIG_RFKILL=y -+CONFIG_PCI=y - # CONFIG_ALLOW_DEV_COREDUMP is not set - CONFIG_DEBUG_DEVRES=y - CONFIG_ZRAM=y -@@ -274,6 +276,7 @@ CONFIG_LEDS_CLASS=y - CONFIG_LEDS_TRIGGERS=y - CONFIG_RTC_CLASS=y - # CONFIG_RTC_SYSTOHC is not set -+CONFIG_VIRTIO_PCI=y - CONFIG_VIRTIO_BALLOON=y - CONFIG_VIRTIO_INPUT=y - CONFIG_VIRTIO_MMIO=y -@@ -289,6 +292,7 @@ CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_SECURITY=y - CONFIG_F2FS_FS=y - CONFIG_F2FS_FS_SECURITY=y -+CONFIG_FS_ENCRYPTION=y - # CONFIG_DNOTIFY is not set - CONFIG_QUOTA=y - CONFIG_QFMT_V2=y diff --git a/patches/ANDROID-adding-usb-HCD-dummy-config-to-permit-usb-write-ops-on-init.patch b/patches/ANDROID-adding-usb-HCD-dummy-config-to-permit-usb-write-ops-on-init.patch deleted file mode 100644 index 624008ba1ffa..000000000000 --- a/patches/ANDROID-adding-usb-HCD-dummy-config-to-permit-usb-write-ops-on-init.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Wed, 3 Jul 2019 14:31:23 -0700 -Subject: ANDROID: adding usb HCD dummy config to permit usb write ops on init - -Bug: 136021903 -Change-Id: I45ae272fd7243e290f0701a7f29722788ce0cd5a -Signed-off-by: Ram Muthiah ---- - arch/arm64/configs/gki_defconfig | 1 + - arch/x86/configs/gki_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index ec0566116066..7c66f40c9739 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -314,6 +314,7 @@ CONFIG_HID_MULTITOUCH=y - CONFIG_USB_HIDDEV=y - CONFIG_USB=y - CONFIG_USB_GADGET=y -+CONFIG_USB_DUMMY_HCD=y - CONFIG_USB_CONFIGFS=y - CONFIG_USB_CONFIGFS_UEVENT=y - CONFIG_USB_CONFIGFS_F_FS=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index c0993920b94d..65c67797fb74 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -267,6 +267,7 @@ CONFIG_HID_MULTITOUCH=y - CONFIG_USB_HIDDEV=y - CONFIG_USB=y - CONFIG_USB_GADGET=y -+CONFIG_USB_DUMMY_HCD=y - CONFIG_USB_CONFIGFS=y - CONFIG_USB_CONFIGFS_UEVENT=y - CONFIG_USB_CONFIGFS_F_FS=y diff --git a/patches/ANDROID-allmodconfig-Force-gki_defconfig-as-base.patch b/patches/ANDROID-allmodconfig-Force-gki_defconfig-as-base.patch deleted file mode 100644 index 3fbe7bd0888a..000000000000 --- a/patches/ANDROID-allmodconfig-Force-gki_defconfig-as-base.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Quentin Perret -Date: Mon, 30 Sep 2019 16:23:52 +0100 -Subject: ANDROID: allmodconfig: Force gki_defconfig as base - -Allmodconfig enables as many options as it can to maximize the number of -modules it can build. While this is generally a good idea, this can also -lead to very convoluted configurations (such as CPU_BIG_ENDIAN=y on -arm64) which we don't necessarily want to support even if they break. On -the other hand, gki_defconfig already contains the set of core options -we definitely want to support, so it makes sense to use that as a base. - -Point KCONFIG_ALLMODCONFIG to the relevant gki_defconfig file in order -to ensure a minimally sensible config that allconfig is not allowed to -modify. - -Bug: 140224784 -Signed-off-by: Quentin Perret -Change-Id: Ib4cf3c9565f040a577ce3cec008293520be1af84 ---- - build.config.allmodconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/build.config.allmodconfig b/build.config.allmodconfig -index 43b1a70d5800..6e0404b8de47 100644 ---- a/build.config.allmodconfig -+++ b/build.config.allmodconfig -@@ -1,4 +1,5 @@ - DEFCONFIG=allmodconfig -+KCONFIG_ALLCONFIG=${ROOT_DIR}/common/arch/${ARCH%_*}/configs/gki_defconfig - - # XFS_FS is currently broken on this branch with clang-9 - POST_DEFCONFIG_CMDS="update_config" diff --git a/patches/ANDROID-arm-enable-max-frequency-capping.patch b/patches/ANDROID-arm-enable-max-frequency-capping.patch deleted file mode 100644 index 75c127f127c2..000000000000 --- a/patches/ANDROID-arm-enable-max-frequency-capping.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dietmar Eggemann -Date: Thu, 10 May 2018 16:58:04 +0100 -Subject: ANDROID: arm: enable max frequency capping - -Defines arch_scale_max_freq_capacity() to use the topology driver -scale function. - -Signed-off-by: Ionela Voinescu -Signed-off-by: Dietmar Eggemann -Signed-off-by: Quentin Perret -Change-Id: I79f444399ea3b2948364fde80ccee52a9ece5b9a ---- - arch/arm/include/asm/topology.h | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h -index 8a0fae94d45e..a2edacb56459 100644 ---- a/arch/arm/include/asm/topology.h -+++ b/arch/arm/include/asm/topology.h -@@ -10,6 +10,9 @@ - /* Replace task scheduler's default frequency-invariant accounting */ - #define arch_scale_freq_capacity topology_get_freq_scale - -+/* Replace task scheduler's default max-frequency-invariant accounting */ -+#define arch_scale_max_freq_capacity topology_get_max_freq_scale -+ - /* Replace task scheduler's default cpu-invariant accounting */ - #define arch_scale_cpu_capacity topology_get_cpu_scale - diff --git a/patches/ANDROID-arm64-copy-CONFIG_CMDLINE_EXTEND-from-ARM.patch b/patches/ANDROID-arm64-copy-CONFIG_CMDLINE_EXTEND-from-ARM.patch deleted file mode 100644 index bea175fb8503..000000000000 --- a/patches/ANDROID-arm64-copy-CONFIG_CMDLINE_EXTEND-from-ARM.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Colin Cross -Date: Wed, 2 Apr 2014 18:02:15 -0700 -Subject: ANDROID: arm64: copy CONFIG_CMDLINE_EXTEND from ARM - -Copy the config choice for CONFIG_CMDLINE_EXTEND from -arch/arm/Kconfig, including CONFIG_CMDLINE_FROM_BOOTLOADER -as the default. These will be used by drivers/of/fdt.c. - -Bug: 120440972 -Change-Id: I8416038498ddf8fc1e99ab06109825eb1492aa7f -Signed-off-by: Colin Cross ---- - arch/arm64/Kconfig | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index 950a56b71ff0..acf1c5999153 100644 ---- a/arch/arm64/Kconfig -+++ b/arch/arm64/Kconfig -@@ -1578,6 +1578,23 @@ config CMDLINE - entering them here. As a minimum, you should specify the the - root device (e.g. root=/dev/nfs). - -+choice -+ prompt "Kernel command line type" if CMDLINE != "" -+ default CMDLINE_FROM_BOOTLOADER -+ -+config CMDLINE_FROM_BOOTLOADER -+ bool "Use bootloader kernel arguments if available" -+ help -+ Uses the command-line options passed by the boot loader. If -+ the boot loader doesn't provide any, the default kernel command -+ string provided in CMDLINE will be used. -+ -+config CMDLINE_EXTEND -+ bool "Extend bootloader kernel arguments" -+ help -+ The command-line arguments provided by the boot loader will be -+ appended to the default kernel command string. -+ - config CMDLINE_FORCE - bool "Always use the default kernel command string" - help -@@ -1585,6 +1602,7 @@ config CMDLINE_FORCE - loader passes other arguments to the kernel. - This is useful if you cannot or don't want to change the - command-line options your boot loader passes to the kernel. -+endchoice - - config EFI_STUB - bool diff --git a/patches/ANDROID-arm64-defconfig-Enable-EAS-by-default.patch b/patches/ANDROID-arm64-defconfig-Enable-EAS-by-default.patch deleted file mode 100644 index e3beb974407b..000000000000 --- a/patches/ANDROID-arm64-defconfig-Enable-EAS-by-default.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Quentin Perret -Date: Wed, 3 Jul 2019 10:48:14 +0100 -Subject: ANDROID: arm64: defconfig: Enable EAS by default - -Use schedutil as default cpufreq governor so EAS can start. Also, enable -util-clamp to enable frequency selection biasing. - -Change-Id: Iec9098f27c0353dabc23bd98efbca6479de41796 -Signed-off-by: Quentin Perret ---- - arch/arm64/configs/defconfig | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig -index c9a867ac32d4..7456909a8a64 100644 ---- a/arch/arm64/configs/defconfig -+++ b/arch/arm64/configs/defconfig -@@ -13,10 +13,12 @@ CONFIG_TASK_XACCT=y - CONFIG_TASK_IO_ACCOUNTING=y - CONFIG_IKCONFIG=y - CONFIG_IKCONFIG_PROC=y -+CONFIG_UCLAMP_TASK=y - CONFIG_NUMA_BALANCING=y - CONFIG_MEMCG=y - CONFIG_MEMCG_SWAP=y - CONFIG_BLK_CGROUP=y -+CONFIG_UCLAMP_TASK_GROUP=y - CONFIG_CGROUP_PIDS=y - CONFIG_CGROUP_HUGETLB=y - CONFIG_CPUSETS=y -@@ -71,10 +73,12 @@ CONFIG_COMPAT=y - CONFIG_RANDOMIZE_BASE=y - CONFIG_HIBERNATION=y - CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y -+CONFIG_ENERGY_MODEL=y - CONFIG_ARM_CPUIDLE=y - CONFIG_ARM_PSCI_CPUIDLE=y - CONFIG_CPU_FREQ=y - CONFIG_CPU_FREQ_STAT=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y - CONFIG_CPU_FREQ_GOV_POWERSAVE=m - CONFIG_CPU_FREQ_GOV_USERSPACE=y - CONFIG_CPU_FREQ_GOV_ONDEMAND=y diff --git a/patches/ANDROID-arm64-enable-max-frequency-capping.patch b/patches/ANDROID-arm64-enable-max-frequency-capping.patch deleted file mode 100644 index a1f1d77484b5..000000000000 --- a/patches/ANDROID-arm64-enable-max-frequency-capping.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dietmar Eggemann -Date: Thu, 10 May 2018 16:54:16 +0100 -Subject: ANDROID: arm64: enable max frequency capping - -Defines arch_scale_max_freq_capacity() to use the topology driver -scale function. - -Change-Id: If7565747ec862e42ac55196240522ef8d22ca67d -Signed-off-by: Ionela Voinescu -Signed-off-by: Dietmar Eggemann -Signed-off-by: Quentin Perret ---- - arch/arm64/include/asm/topology.h | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h -index a4d945db95a2..70697177d6ec 100644 ---- a/arch/arm64/include/asm/topology.h -+++ b/arch/arm64/include/asm/topology.h -@@ -19,6 +19,9 @@ int pcibus_to_node(struct pci_bus *bus); - /* Replace task scheduler's default frequency-invariant accounting */ - #define arch_scale_freq_capacity topology_get_freq_scale - -+/* Replace task scheduler's default max-frequency-invariant accounting */ -+#define arch_scale_max_freq_capacity topology_get_max_freq_scale -+ - /* Replace task scheduler's default cpu-invariant accounting */ - #define arch_scale_cpu_capacity topology_get_cpu_scale - diff --git a/patches/ANDROID-binder-add-support-for-RT-prio-inheritance.patch b/patches/ANDROID-binder-add-support-for-RT-prio-inheritance.patch deleted file mode 100644 index 543ff8273675..000000000000 --- a/patches/ANDROID-binder-add-support-for-RT-prio-inheritance.patch +++ /dev/null @@ -1,570 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Martijn Coenen -Date: Tue, 6 Jun 2017 17:04:42 -0700 -Subject: ANDROID: binder: add support for RT prio inheritance. - -Adds support for SCHED_BATCH/SCHED_FIFO/SCHED_RR -priority inheritance. - -Bug: 34461621 -Bug: 37293077 -Bug: 120446518 -Change-Id: I71f356e476be2933713a0ecfa2cc31aa141e2dc6 -Signed-off-by: Martijn Coenen -[AmitP: Include for struct sched_param] -Signed-off-by: Amit Pundir -[astrachan: Folded the following changes into this patch: - 69308b3b07dd ("ANDROID: binder: add min sched_policy to node.") - 7a6edeb62d86 ("ANDROID: binder: improve priority inheritance.") - 22b061b17679 ("ANDROID: binder: don't check prio permissions on restore.") - 67cf97141d81 ("ANDROID: binder: Add tracing for binder priority inheritance.") - fb92c34f7ba3 ("ANDROID: binder: add RT inheritance flag to node.") - c847b48f8cda ("ANDROID: binder: init desired_prio.sched_policy before use it")] -Signed-off-by: Alistair Strachan ---- - drivers/android/binder.c | 243 ++++++++++++++++++++++++---- - drivers/android/binder_trace.h | 24 +++ - include/uapi/linux/android/binder.h | 50 +++++- - 3 files changed, 284 insertions(+), 33 deletions(-) - -diff --git a/drivers/android/binder.c b/drivers/android/binder.c -index 5b9ac2122e89..4cd82572785d 100644 ---- a/drivers/android/binder.c -+++ b/drivers/android/binder.c -@@ -66,6 +66,7 @@ - #include - #include - -+#include - #include - #include - -@@ -296,10 +297,13 @@ struct binder_error { - * and by @lock) - * @has_async_transaction: async transaction to node in progress - * (protected by @lock) -+ * @sched_policy: minimum scheduling policy for node -+ * (invariant after initialized) - * @accept_fds: file descriptor operations supported for node - * (invariant after initialized) - * @min_priority: minimum scheduling priority - * (invariant after initialized) -+ * @inherit_rt: inherit RT scheduling policy from caller - * @txn_security_ctx: require sender's security context - * (invariant after initialized) - * @async_todo: list of async work items -@@ -337,6 +341,8 @@ struct binder_node { - /* - * invariant after initialization - */ -+ u8 sched_policy:2; -+ u8 inherit_rt:1; - u8 accept_fds:1; - u8 txn_security_ctx:1; - u8 min_priority; -@@ -410,6 +416,22 @@ enum binder_deferred_state { - BINDER_DEFERRED_RELEASE = 0x02, - }; - -+/** -+ * struct binder_priority - scheduler policy and priority -+ * @sched_policy scheduler policy -+ * @prio [100..139] for SCHED_NORMAL, [0..99] for FIFO/RT -+ * -+ * The binder driver supports inheriting the following scheduler policies: -+ * SCHED_NORMAL -+ * SCHED_BATCH -+ * SCHED_FIFO -+ * SCHED_RR -+ */ -+struct binder_priority { -+ unsigned int sched_policy; -+ int prio; -+}; -+ - /** - * struct binder_proc - binder process bookkeeping - * @proc_node: element for binder_procs list -@@ -484,7 +506,7 @@ struct binder_proc { - int requested_threads; - int requested_threads_started; - int tmp_ref; -- long default_priority; -+ struct binder_priority default_priority; - struct dentry *debugfs_entry; - struct binder_alloc alloc; - struct binder_context *context; -@@ -535,6 +557,7 @@ enum { - * @is_dead: thread is dead and awaiting free - * when outstanding transactions are cleaned up - * (protected by @proc->inner_lock) -+ * @task: struct task_struct for this thread - * - * Bookkeeping structure for binder threads. - */ -@@ -554,6 +577,7 @@ struct binder_thread { - struct binder_stats stats; - atomic_t tmp_ref; - bool is_dead; -+ struct task_struct *task; - }; - - /** -@@ -587,8 +611,9 @@ struct binder_transaction { - struct binder_buffer *buffer; - unsigned int code; - unsigned int flags; -- long priority; -- long saved_priority; -+ struct binder_priority priority; -+ struct binder_priority saved_priority; -+ bool set_priority_called; - kuid_t sender_euid; - struct list_head fd_fixups; - binder_uintptr_t security_ctx; -@@ -1047,22 +1072,145 @@ static void binder_wakeup_proc_ilocked(struct binder_proc *proc) - binder_wakeup_thread_ilocked(proc, thread, /* sync = */false); - } - --static void binder_set_nice(long nice) -+static bool is_rt_policy(int policy) -+{ -+ return policy == SCHED_FIFO || policy == SCHED_RR; -+} -+ -+static bool is_fair_policy(int policy) -+{ -+ return policy == SCHED_NORMAL || policy == SCHED_BATCH; -+} -+ -+static bool binder_supported_policy(int policy) -+{ -+ return is_fair_policy(policy) || is_rt_policy(policy); -+} -+ -+static int to_userspace_prio(int policy, int kernel_priority) -+{ -+ if (is_fair_policy(policy)) -+ return PRIO_TO_NICE(kernel_priority); -+ else -+ return MAX_USER_RT_PRIO - 1 - kernel_priority; -+} -+ -+static int to_kernel_prio(int policy, int user_priority) - { -- long min_nice; -+ if (is_fair_policy(policy)) -+ return NICE_TO_PRIO(user_priority); -+ else -+ return MAX_USER_RT_PRIO - 1 - user_priority; -+} - -- if (can_nice(current, nice)) { -- set_user_nice(current, nice); -+static void binder_do_set_priority(struct task_struct *task, -+ struct binder_priority desired, -+ bool verify) -+{ -+ int priority; /* user-space prio value */ -+ bool has_cap_nice; -+ unsigned int policy = desired.sched_policy; -+ -+ if (task->policy == policy && task->normal_prio == desired.prio) - return; -+ -+ has_cap_nice = has_capability_noaudit(task, CAP_SYS_NICE); -+ -+ priority = to_userspace_prio(policy, desired.prio); -+ -+ if (verify && is_rt_policy(policy) && !has_cap_nice) { -+ long max_rtprio = task_rlimit(task, RLIMIT_RTPRIO); -+ -+ if (max_rtprio == 0) { -+ policy = SCHED_NORMAL; -+ priority = MIN_NICE; -+ } else if (priority > max_rtprio) { -+ priority = max_rtprio; -+ } -+ } -+ -+ if (verify && is_fair_policy(policy) && !has_cap_nice) { -+ long min_nice = rlimit_to_nice(task_rlimit(task, RLIMIT_NICE)); -+ -+ if (min_nice > MAX_NICE) { -+ binder_user_error("%d RLIMIT_NICE not set\n", -+ task->pid); -+ return; -+ } else if (priority < min_nice) { -+ priority = min_nice; -+ } -+ } -+ -+ if (policy != desired.sched_policy || -+ to_kernel_prio(policy, priority) != desired.prio) -+ binder_debug(BINDER_DEBUG_PRIORITY_CAP, -+ "%d: priority %d not allowed, using %d instead\n", -+ task->pid, desired.prio, -+ to_kernel_prio(policy, priority)); -+ -+ trace_binder_set_priority(task->tgid, task->pid, task->normal_prio, -+ to_kernel_prio(policy, priority), -+ desired.prio); -+ -+ /* Set the actual priority */ -+ if (task->policy != policy || is_rt_policy(policy)) { -+ struct sched_param params; -+ -+ params.sched_priority = is_rt_policy(policy) ? priority : 0; -+ -+ sched_setscheduler_nocheck(task, -+ policy | SCHED_RESET_ON_FORK, -+ ¶ms); - } -- min_nice = rlimit_to_nice(rlimit(RLIMIT_NICE)); -- binder_debug(BINDER_DEBUG_PRIORITY_CAP, -- "%d: nice value %ld not allowed use %ld instead\n", -- current->pid, nice, min_nice); -- set_user_nice(current, min_nice); -- if (min_nice <= MAX_NICE) -+ if (is_fair_policy(policy)) -+ set_user_nice(task, priority); -+} -+ -+static void binder_set_priority(struct task_struct *task, -+ struct binder_priority desired) -+{ -+ binder_do_set_priority(task, desired, /* verify = */ true); -+} -+ -+static void binder_restore_priority(struct task_struct *task, -+ struct binder_priority desired) -+{ -+ binder_do_set_priority(task, desired, /* verify = */ false); -+} -+ -+static void binder_transaction_priority(struct task_struct *task, -+ struct binder_transaction *t, -+ struct binder_priority node_prio, -+ bool inherit_rt) -+{ -+ struct binder_priority desired_prio = t->priority; -+ -+ if (t->set_priority_called) - return; -- binder_user_error("%d RLIMIT_NICE not set\n", current->pid); -+ -+ t->set_priority_called = true; -+ t->saved_priority.sched_policy = task->policy; -+ t->saved_priority.prio = task->normal_prio; -+ -+ if (!inherit_rt && is_rt_policy(desired_prio.sched_policy)) { -+ desired_prio.prio = NICE_TO_PRIO(0); -+ desired_prio.sched_policy = SCHED_NORMAL; -+ } -+ -+ if (node_prio.prio < t->priority.prio || -+ (node_prio.prio == t->priority.prio && -+ node_prio.sched_policy == SCHED_FIFO)) { -+ /* -+ * In case the minimum priority on the node is -+ * higher (lower value), use that priority. If -+ * the priority is the same, but the node uses -+ * SCHED_FIFO, prefer SCHED_FIFO, since it can -+ * run unbounded, unlike SCHED_RR. -+ */ -+ desired_prio = node_prio; -+ } -+ -+ binder_set_priority(task, desired_prio); - } - - static struct binder_node *binder_get_node_ilocked(struct binder_proc *proc, -@@ -1115,6 +1263,7 @@ static struct binder_node *binder_init_node_ilocked( - binder_uintptr_t ptr = fp ? fp->binder : 0; - binder_uintptr_t cookie = fp ? fp->cookie : 0; - __u32 flags = fp ? fp->flags : 0; -+ s8 priority; - - assert_spin_locked(&proc->inner_lock); - -@@ -1147,8 +1296,12 @@ static struct binder_node *binder_init_node_ilocked( - node->ptr = ptr; - node->cookie = cookie; - node->work.type = BINDER_WORK_NODE; -- node->min_priority = flags & FLAT_BINDER_FLAG_PRIORITY_MASK; -+ priority = flags & FLAT_BINDER_FLAG_PRIORITY_MASK; -+ node->sched_policy = (flags & FLAT_BINDER_FLAG_SCHED_POLICY_MASK) >> -+ FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT; -+ node->min_priority = to_kernel_prio(node->sched_policy, priority); - node->accept_fds = !!(flags & FLAT_BINDER_FLAG_ACCEPTS_FDS); -+ node->inherit_rt = !!(flags & FLAT_BINDER_FLAG_INHERIT_RT); - node->txn_security_ctx = !!(flags & FLAT_BINDER_FLAG_TXN_SECURITY_CTX); - spin_lock_init(&node->lock); - INIT_LIST_HEAD(&node->work.entry); -@@ -2759,11 +2912,15 @@ static bool binder_proc_transaction(struct binder_transaction *t, - struct binder_thread *thread) - { - struct binder_node *node = t->buffer->target_node; -+ struct binder_priority node_prio; - bool oneway = !!(t->flags & TF_ONE_WAY); - bool pending_async = false; - - BUG_ON(!node); - binder_node_lock(node); -+ node_prio.prio = node->min_priority; -+ node_prio.sched_policy = node->sched_policy; -+ - if (oneway) { - BUG_ON(thread); - if (node->has_async_transaction) { -@@ -2784,12 +2941,15 @@ static bool binder_proc_transaction(struct binder_transaction *t, - if (!thread && !pending_async) - thread = binder_select_thread_ilocked(proc); - -- if (thread) -+ if (thread) { -+ binder_transaction_priority(thread->task, t, node_prio, -+ node->inherit_rt); - binder_enqueue_thread_work_ilocked(thread, &t->work); -- else if (!pending_async) -+ } else if (!pending_async) { - binder_enqueue_work_ilocked(&t->work, &proc->todo); -- else -+ } else { - binder_enqueue_work_ilocked(&t->work, &node->async_todo); -+ } - - if (!pending_async) - binder_wakeup_thread_ilocked(proc, thread, !oneway /* sync */); -@@ -2910,7 +3070,6 @@ static void binder_transaction(struct binder_proc *proc, - } - thread->transaction_stack = in_reply_to->to_parent; - binder_inner_proc_unlock(proc); -- binder_set_nice(in_reply_to->saved_priority); - target_thread = binder_get_txn_from_and_acq_inner(in_reply_to); - if (target_thread == NULL) { - /* annotation for sparse */ -@@ -3109,7 +3268,15 @@ static void binder_transaction(struct binder_proc *proc, - t->to_thread = target_thread; - t->code = tr->code; - t->flags = tr->flags; -- t->priority = task_nice(current); -+ if (!(t->flags & TF_ONE_WAY) && -+ binder_supported_policy(current->policy)) { -+ /* Inherit supported policies for synchronous transactions */ -+ t->priority.sched_policy = current->policy; -+ t->priority.prio = current->normal_prio; -+ } else { -+ /* Otherwise, fall back to the default priority */ -+ t->priority = target_proc->default_priority; -+ } - - if (target_node && target_node->txn_security_ctx) { - u32 secid; -@@ -3436,6 +3603,7 @@ static void binder_transaction(struct binder_proc *proc, - binder_enqueue_thread_work_ilocked(target_thread, &t->work); - binder_inner_proc_unlock(target_proc); - wake_up_interruptible_sync(&target_thread->wait); -+ binder_restore_priority(current, in_reply_to->saved_priority); - binder_free_transaction(in_reply_to); - } else if (!(t->flags & TF_ONE_WAY)) { - BUG_ON(t->buffer->async_transaction != 0); -@@ -3546,6 +3714,7 @@ static void binder_transaction(struct binder_proc *proc, - - BUG_ON(thread->return_error.cmd != BR_OK); - if (in_reply_to) { -+ binder_restore_priority(current, in_reply_to->saved_priority); - thread->return_error.cmd = BR_TRANSACTION_COMPLETE; - binder_enqueue_thread_work(thread, &thread->return_error.work); - binder_send_failed_reply(in_reply_to, return_error); -@@ -4212,7 +4381,7 @@ static int binder_thread_read(struct binder_proc *proc, - wait_event_interruptible(binder_user_error_wait, - binder_stop_on_user_error < 2); - } -- binder_set_nice(proc->default_priority); -+ binder_restore_priority(current, proc->default_priority); - } - - if (non_block) { -@@ -4434,16 +4603,14 @@ static int binder_thread_read(struct binder_proc *proc, - BUG_ON(t->buffer == NULL); - if (t->buffer->target_node) { - struct binder_node *target_node = t->buffer->target_node; -+ struct binder_priority node_prio; - - trd->target.ptr = target_node->ptr; - trd->cookie = target_node->cookie; -- t->saved_priority = task_nice(current); -- if (t->priority < target_node->min_priority && -- !(t->flags & TF_ONE_WAY)) -- binder_set_nice(t->priority); -- else if (!(t->flags & TF_ONE_WAY) || -- t->saved_priority > target_node->min_priority) -- binder_set_nice(target_node->min_priority); -+ node_prio.sched_policy = target_node->sched_policy; -+ node_prio.prio = target_node->min_priority; -+ binder_transaction_priority(current, t, node_prio, -+ target_node->inherit_rt); - cmd = BR_TRANSACTION; - } else { - trd->target.ptr = 0; -@@ -4655,6 +4822,8 @@ static struct binder_thread *binder_get_thread_ilocked( - binder_stats_created(BINDER_STAT_THREAD); - thread->proc = proc; - thread->pid = current->pid; -+ get_task_struct(current); -+ thread->task = current; - atomic_set(&thread->tmp_ref, 0); - init_waitqueue_head(&thread->wait); - INIT_LIST_HEAD(&thread->todo); -@@ -4705,6 +4874,7 @@ static void binder_free_thread(struct binder_thread *thread) - BUG_ON(!list_empty(&thread->todo)); - binder_stats_deleted(BINDER_STAT_THREAD); - binder_proc_dec_tmpref(thread->proc); -+ put_task_struct(thread->task); - kfree(thread); - } - -@@ -5226,7 +5396,14 @@ static int binder_open(struct inode *nodp, struct file *filp) - get_task_struct(current->group_leader); - proc->tsk = current->group_leader; - INIT_LIST_HEAD(&proc->todo); -- proc->default_priority = task_nice(current); -+ if (binder_supported_policy(current->policy)) { -+ proc->default_priority.sched_policy = current->policy; -+ proc->default_priority.prio = current->normal_prio; -+ } else { -+ proc->default_priority.sched_policy = SCHED_NORMAL; -+ proc->default_priority.prio = NICE_TO_PRIO(0); -+ } -+ - /* binderfs stashes devices in i_private */ - if (is_binderfs_device(nodp)) { - binder_dev = nodp->i_private; -@@ -5547,13 +5724,14 @@ static void print_binder_transaction_ilocked(struct seq_file *m, - spin_lock(&t->lock); - to_proc = t->to_proc; - seq_printf(m, -- "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %ld r%d", -+ "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %d:%d r%d", - prefix, t->debug_id, t, - t->from ? t->from->proc->pid : 0, - t->from ? t->from->pid : 0, - to_proc ? to_proc->pid : 0, - t->to_thread ? t->to_thread->pid : 0, -- t->code, t->flags, t->priority, t->need_reply); -+ t->code, t->flags, t->priority.sched_policy, -+ t->priority.prio, t->need_reply); - spin_unlock(&t->lock); - - if (proc != to_proc) { -@@ -5671,8 +5849,9 @@ static void print_binder_node_nilocked(struct seq_file *m, - hlist_for_each_entry(ref, &node->refs, node_entry) - count++; - -- seq_printf(m, " node %d: u%016llx c%016llx hs %d hw %d ls %d lw %d is %d iw %d tr %d", -+ seq_printf(m, " node %d: u%016llx c%016llx pri %d:%d hs %d hw %d ls %d lw %d is %d iw %d tr %d", - node->debug_id, (u64)node->ptr, (u64)node->cookie, -+ node->sched_policy, node->min_priority, - node->has_strong_ref, node->has_weak_ref, - node->local_strong_refs, node->local_weak_refs, - node->internal_strong_refs, count, node->tmp_refs); -diff --git a/drivers/android/binder_trace.h b/drivers/android/binder_trace.h -index 6731c3cd8145..a70e23716ad0 100644 ---- a/drivers/android/binder_trace.h -+++ b/drivers/android/binder_trace.h -@@ -76,6 +76,30 @@ DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_ioctl_done); - DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_write_done); - DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_read_done); - -+TRACE_EVENT(binder_set_priority, -+ TP_PROTO(int proc, int thread, unsigned int old_prio, -+ unsigned int desired_prio, unsigned int new_prio), -+ TP_ARGS(proc, thread, old_prio, new_prio, desired_prio), -+ -+ TP_STRUCT__entry( -+ __field(int, proc) -+ __field(int, thread) -+ __field(unsigned int, old_prio) -+ __field(unsigned int, new_prio) -+ __field(unsigned int, desired_prio) -+ ), -+ TP_fast_assign( -+ __entry->proc = proc; -+ __entry->thread = thread; -+ __entry->old_prio = old_prio; -+ __entry->new_prio = new_prio; -+ __entry->desired_prio = desired_prio; -+ ), -+ TP_printk("proc=%d thread=%d old=%d => new=%d desired=%d", -+ __entry->proc, __entry->thread, __entry->old_prio, -+ __entry->new_prio, __entry->desired_prio) -+); -+ - TRACE_EVENT(binder_wait_for_work, - TP_PROTO(bool proc_work, bool transaction_stack, bool thread_todo), - TP_ARGS(proc_work, transaction_stack, thread_todo), -diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h -index 2832134e5397..11babae0339f 100644 ---- a/include/uapi/linux/android/binder.h -+++ b/include/uapi/linux/android/binder.h -@@ -38,10 +38,58 @@ enum { - BINDER_TYPE_PTR = B_PACK_CHARS('p', 't', '*', B_TYPE_LARGE), - }; - --enum { -+/** -+ * enum flat_binder_object_shifts: shift values for flat_binder_object_flags -+ * @FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT: shift for getting scheduler policy. -+ * -+ */ -+enum flat_binder_object_shifts { -+ FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT = 9, -+}; -+ -+/** -+ * enum flat_binder_object_flags - flags for use in flat_binder_object.flags -+ */ -+enum flat_binder_object_flags { -+ /** -+ * @FLAT_BINDER_FLAG_PRIORITY_MASK: bit-mask for min scheduler priority -+ * -+ * These bits can be used to set the minimum scheduler priority -+ * at which transactions into this node should run. Valid values -+ * in these bits depend on the scheduler policy encoded in -+ * @FLAT_BINDER_FLAG_SCHED_POLICY_MASK. -+ * -+ * For SCHED_NORMAL/SCHED_BATCH, the valid range is between [-20..19] -+ * For SCHED_FIFO/SCHED_RR, the value can run between [1..99] -+ */ - FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff, -+ /** -+ * @FLAT_BINDER_FLAG_ACCEPTS_FDS: whether the node accepts fds. -+ */ - FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100, - -+ /** -+ * @FLAT_BINDER_FLAG_SCHED_POLICY_MASK: bit-mask for scheduling policy -+ * -+ * These two bits can be used to set the min scheduling policy at which -+ * transactions on this node should run. These match the UAPI -+ * scheduler policy values, eg: -+ * 00b: SCHED_NORMAL -+ * 01b: SCHED_FIFO -+ * 10b: SCHED_RR -+ * 11b: SCHED_BATCH -+ */ -+ FLAT_BINDER_FLAG_SCHED_POLICY_MASK = -+ 3U << FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT, -+ -+ /** -+ * @FLAT_BINDER_FLAG_INHERIT_RT: whether the node inherits RT policy -+ * -+ * Only when set, calls into this node will inherit a real-time -+ * scheduling policy from the caller (for synchronous transactions). -+ */ -+ FLAT_BINDER_FLAG_INHERIT_RT = 0x800, -+ - /** - * @FLAT_BINDER_FLAG_TXN_SECURITY_CTX: request security contexts - * diff --git a/patches/ANDROID-build-configs-switch-prebuilt-path-location.patch b/patches/ANDROID-build-configs-switch-prebuilt-path-location.patch deleted file mode 100644 index 9eed0e98f5b4..000000000000 --- a/patches/ANDROID-build-configs-switch-prebuilt-path-location.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Matthias Maennich -Date: Mon, 8 Jul 2019 22:21:06 +0100 -Subject: ANDROID: build configs: switch prebuilt path location - -Move to a kernel specific prebuilt path. - -Bug: 135922132 -Change-Id: I8755f8f0154eecc86ad598be7a7811e9d8f068ed -Signed-off-by: Matthias Maennich ---- - build.config.gki.aarch64 | 2 +- - build.config.gki.x86_64 | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 -index 24dade721f96..79871cdc6d07 100644 ---- a/build.config.gki.aarch64 -+++ b/build.config.gki.aarch64 -@@ -8,7 +8,7 @@ EXTRA_CMDS='' - KERNEL_DIR=common - POST_DEFCONFIG_CMDS="check_defconfig" - CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin --BUILDTOOLS_PREBUILT_BIN=prebuilts/build-tools/path/linux-x86 -+BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 - LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin - FILES=" - arch/arm64/boot/Image.gz -diff --git a/build.config.gki.x86_64 b/build.config.gki.x86_64 -index 3ce45e962732..b5a7f4600101 100644 ---- a/build.config.gki.x86_64 -+++ b/build.config.gki.x86_64 -@@ -8,7 +8,7 @@ EXTRA_CMDS='' - KERNEL_DIR=common - POST_DEFCONFIG_CMDS="check_defconfig" - CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin --BUILDTOOLS_PREBUILT_BIN=prebuilts/build-tools/path/linux-x86 -+BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 - LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin - FILES=" - arch/x86/boot/bzImage diff --git a/patches/ANDROID-clk-add-pre-and-post-change-rate-callbacks.patch b/patches/ANDROID-clk-add-pre-and-post-change-rate-callbacks.patch deleted file mode 100644 index 9227eae53b85..000000000000 --- a/patches/ANDROID-clk-add-pre-and-post-change-rate-callbacks.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: David Dai -Date: Mon, 19 Aug 2019 16:35:44 -0700 -Subject: ANDROID: clk: add pre and post change rate callbacks - -There are scenarios where a rate change could result in a configuration -change for both the targeted clock and its parent. - -For example, setting the rate for a clock could require both slewing its parent -PLL as well as adjusting the clock's divider values. Due to the fact that -rate change propagation always occurs from parent to child, we could exceed -the allowed operating frequencies for the clock as the parent slews to a higher -frequency before increasing the downstream divider. - -Add a pre change call back which allows the clock to adjust its divider -appropriately before any rate change has occurred from its parents to ensure -that the clock's requirements are always within safe frequencies during parent -rate changes. The symmetrical post change call back handles the scenario where -the divider adjusts to a lower value and can only be safely adjusted after the -parent rate changes. - -Change-Id: I4f8cf9df6fc256d065599de86a34cf99eae4d853 -Signed-off-by: David Dai ---- - drivers/clk/clk.c | 10 ++++++++++ - include/linux/clk-provider.h | 13 +++++++++++++ - 2 files changed, 23 insertions(+) - -diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c -index 1c677d7f7f53..020fdb8105cc 100644 ---- a/drivers/clk/clk.c -+++ b/drivers/clk/clk.c -@@ -1980,6 +1980,13 @@ static struct clk_core *clk_propagate_rate_change(struct clk_core *core, - fail_clk = core; - } - -+ if (core->ops->pre_rate_change) { -+ ret = core->ops->pre_rate_change(core->hw, core->rate, -+ core->new_rate); -+ if (ret) -+ fail_clk = core; -+ } -+ - hlist_for_each_entry(child, &core->children, child_node) { - /* Skip children who will be reparented to another clock */ - if (child->new_parent && child->new_parent != core) -@@ -2082,6 +2089,9 @@ static void clk_change_rate(struct clk_core *core) - if (core->flags & CLK_RECALC_NEW_RATES) - (void)clk_calc_new_rates(core, core->new_rate); - -+ if (core->ops->post_rate_change) -+ core->ops->post_rate_change(core->hw, old_rate, core->rate); -+ - /* - * Use safe iteration, as change_rate can actually swap parents - * for certain clock types. -diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h -index 2fdfe8061363..73e4369e8408 100644 ---- a/include/linux/clk-provider.h -+++ b/include/linux/clk-provider.h -@@ -199,6 +199,13 @@ struct clk_duty { - * directory is provided as an argument. Called with - * prepare_lock held. Returns 0 on success, -EERROR otherwise. - * -+ * @pre_rate_change: Optional callback for a clock to fulfill its rate -+ * change requirements before any rate change has occurred in -+ * its clock tree. Returns 0 on success, -EERROR otherwise. -+ * -+ * @post_rate_change: Optional callback for a clock to clean up any -+ * requirements that were needed while the clock and its tree -+ * was changing states. Returns 0 on success, -EERROR otherwise. - * - * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow - * implementations to split any work between atomic (enable) and sleepable -@@ -245,6 +252,12 @@ struct clk_ops { - struct clk_duty *duty); - void (*init)(struct clk_hw *hw); - void (*debug_init)(struct clk_hw *hw, struct dentry *dentry); -+ int (*pre_rate_change)(struct clk_hw *hw, -+ unsigned long rate, -+ unsigned long new_rate); -+ int (*post_rate_change)(struct clk_hw *hw, -+ unsigned long old_rate, -+ unsigned long rate); - }; - - /** diff --git a/patches/ANDROID-cpu-send-KOBJ_ONLINE-event-when-enabling-cpus.patch b/patches/ANDROID-cpu-send-KOBJ_ONLINE-event-when-enabling-cpus.patch deleted file mode 100644 index 4e2100e62017..000000000000 --- a/patches/ANDROID-cpu-send-KOBJ_ONLINE-event-when-enabling-cpus.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Thierry Strudel -Date: Tue, 14 Jun 2016 17:46:44 -0700 -Subject: ANDROID: cpu: send KOBJ_ONLINE event when enabling cpus - -In case some sysfs nodes needs to be labeled with a different label than -sysfs then user needs to be notified when a core is brought back online. - -Bug: 29359497 -Bug: 120444461 -Change-Id: I0395c86e01cd49c348fda8f93087d26f88557c91 -Signed-off-by: Thierry Strudel ---- - kernel/cpu.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/kernel/cpu.c b/kernel/cpu.c -index fc28e17940e0..4bc4f6cd5634 100644 ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -1276,6 +1276,7 @@ void __weak arch_enable_nonboot_cpus_end(void) - void enable_nonboot_cpus(void) - { - int cpu, error; -+ struct device *cpu_device; - - /* Allow everyone to use the CPU hotplug again */ - cpu_maps_update_begin(); -@@ -1293,6 +1294,12 @@ void enable_nonboot_cpus(void) - trace_suspend_resume(TPS("CPU_ON"), cpu, false); - if (!error) { - pr_info("CPU%d is up\n", cpu); -+ cpu_device = get_cpu_device(cpu); -+ if (!cpu_device) -+ pr_err("%s: failed to get cpu%d device\n", -+ __func__, cpu); -+ else -+ kobject_uevent(&cpu_device->kobj, KOBJ_ONLINE); - continue; - } - pr_warn("Error taking CPU%d up: %d\n", cpu, error); diff --git a/patches/ANDROID-cpufreq-Add-time_in_state-to-proc-uid-directories.patch b/patches/ANDROID-cpufreq-Add-time_in_state-to-proc-uid-directories.patch deleted file mode 100644 index 9ed234f1a48c..000000000000 --- a/patches/ANDROID-cpufreq-Add-time_in_state-to-proc-uid-directories.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Connor O'Brien -Date: Mon, 22 Jan 2018 18:28:08 -0800 -Subject: ANDROID: cpufreq: Add time_in_state to /proc/uid directories - -Add per-uid files that report the data in binary format rather than -text, to allow faster reading & parsing by userspace. - -Signed-off-by: Connor O'Brien -Bug: 72339335 -Bug: 127641090 -Test: compare values to those reported in /proc/uid_time_in_state -Change-Id: I463039ea7f17b842be4c70024fe772539fe2ce02 ---- - drivers/cpufreq/cpufreq_times.c | 49 +++++++++++++++++++++++++++++++++ - fs/proc/uid.c | 16 ++++++++++- - include/linux/cpufreq_times.h | 1 + - 3 files changed, 65 insertions(+), 1 deletion(-) - -diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c -index 15b52e1f82fc..a43eeee30e8e 100644 ---- a/drivers/cpufreq/cpufreq_times.c -+++ b/drivers/cpufreq/cpufreq_times.c -@@ -58,6 +58,19 @@ static struct cpu_freqs *all_freqs[NR_CPUS]; - - static unsigned int next_offset; - -+ -+/* Caller must hold rcu_read_lock() */ -+static struct uid_entry *find_uid_entry_rcu(uid_t uid) -+{ -+ struct uid_entry *uid_entry; -+ -+ hash_for_each_possible_rcu(uid_hash_table, uid_entry, hash, uid) { -+ if (uid_entry->uid == uid) -+ return uid_entry; -+ } -+ return NULL; -+} -+ - /* Caller must hold uid lock */ - static struct uid_entry *find_uid_entry_locked(uid_t uid) - { -@@ -127,6 +140,36 @@ static bool freq_index_invalid(unsigned int index) - return true; - } - -+static int single_uid_time_in_state_show(struct seq_file *m, void *ptr) -+{ -+ struct uid_entry *uid_entry; -+ unsigned int i; -+ u64 time; -+ uid_t uid = from_kuid_munged(current_user_ns(), *(kuid_t *)m->private); -+ -+ if (uid == overflowuid) -+ return -EINVAL; -+ -+ rcu_read_lock(); -+ -+ uid_entry = find_uid_entry_rcu(uid); -+ if (!uid_entry) { -+ rcu_read_unlock(); -+ return 0; -+ } -+ -+ for (i = 0; i < uid_entry->max_state; ++i) { -+ if (freq_index_invalid(i)) -+ continue; -+ time = nsec_to_clock_t(uid_entry->time_in_state[i]); -+ seq_write(m, &time, sizeof(time)); -+ } -+ -+ rcu_read_unlock(); -+ -+ return 0; -+} -+ - static void *uid_seq_start(struct seq_file *seq, loff_t *pos) - { - if (*pos >= HASH_SIZE(uid_hash_table)) -@@ -397,6 +440,12 @@ static int uid_time_in_state_open(struct inode *inode, struct file *file) - return seq_open(file, &uid_time_in_state_seq_ops); - } - -+int single_uid_time_in_state_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, single_uid_time_in_state_show, -+ &(inode->i_uid)); -+} -+ - static const struct file_operations uid_time_in_state_fops = { - .open = uid_time_in_state_open, - .read = seq_read, -diff --git a/fs/proc/uid.c b/fs/proc/uid.c -index ae720b93a0ed..311717ea199a 100644 ---- a/fs/proc/uid.c -+++ b/fs/proc/uid.c -@@ -2,6 +2,7 @@ - * /proc/uid support - */ - -+#include - #include - #include - #include -@@ -82,7 +83,20 @@ struct uid_entry { - .fop = FOP, \ - } - --static const struct uid_entry uid_base_stuff[] = {}; -+#ifdef CONFIG_CPU_FREQ_TIMES -+static const struct file_operations proc_uid_time_in_state_operations = { -+ .open = single_uid_time_in_state_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+#endif -+ -+static const struct uid_entry uid_base_stuff[] = { -+#ifdef CONFIG_CPU_FREQ_TIMES -+ NOD("time_in_state", 0444, NULL, &proc_uid_time_in_state_operations), -+#endif -+}; - - static const struct inode_operations proc_uid_def_inode_operations = { - .setattr = proc_setattr, -diff --git a/include/linux/cpufreq_times.h b/include/linux/cpufreq_times.h -index a03157f649a4..757bf0cb6070 100644 ---- a/include/linux/cpufreq_times.h -+++ b/include/linux/cpufreq_times.h -@@ -29,6 +29,7 @@ void cpufreq_acct_update_power(struct task_struct *p, u64 cputime); - void cpufreq_times_create_policy(struct cpufreq_policy *policy); - void cpufreq_times_record_transition(struct cpufreq_freqs *freq); - void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end); -+int single_uid_time_in_state_open(struct inode *inode, struct file *file); - #else - static inline void cpufreq_task_times_init(struct task_struct *p) {} - static inline void cpufreq_task_times_alloc(struct task_struct *p) {} diff --git a/patches/ANDROID-cpufreq-arch_topology-implement-max-frequency-capping.patch b/patches/ANDROID-cpufreq-arch_topology-implement-max-frequency-capping.patch deleted file mode 100644 index 0a60fd0beb4e..000000000000 --- a/patches/ANDROID-cpufreq-arch_topology-implement-max-frequency-capping.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dietmar Eggemann -Date: Thu, 10 May 2018 16:52:33 +0100 -Subject: ANDROID: cpufreq: arch_topology: implement max frequency capping - -Implements the Max Frequency Capping Engine (MFCE) getter function -topology_get_max_freq_scale() to provide the scheduler with a -maximum frequency scaling correction factor for more accurate cpu -capacity handling by being able to deal with max frequency capping. - -This scaling factor describes the influence of running a cpu with a -current maximum frequency (policy) lower than the maximum possible -frequency (cpuinfo). - -The factor is: - - policy_max_freq(cpu) << SCHED_CAPACITY_SHIFT / cpuinfo_max_freq(cpu) - -It also implements the MFCE setter function arch_set_max_freq_scale() -which is called from cpufreq_set_policy(). - -Change-Id: I59e52861ee260755ab0518fe1f7183a2e4e3d0fc -Signed-off-by: Ionela Voinescu -Signed-off-by: Dietmar Eggemann -[Trivial cherry-pick issue in cpufreq.c] -Signed-off-by: Quentin Perret ---- - drivers/base/arch_topology.c | 25 ++++++++++++++++++++++++- - drivers/cpufreq/cpufreq.c | 8 ++++++++ - include/linux/arch_topology.h | 8 ++++++++ - include/linux/cpufreq.h | 2 ++ - 4 files changed, 42 insertions(+), 1 deletion(-) - -diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c -index 1eb81f113786..c0cf9ef5c2f5 100644 ---- a/drivers/base/arch_topology.c -+++ b/drivers/base/arch_topology.c -@@ -22,6 +22,8 @@ - #include - - DEFINE_PER_CPU(unsigned long, freq_scale) = SCHED_CAPACITY_SCALE; -+DEFINE_PER_CPU(unsigned long, max_cpu_freq); -+DEFINE_PER_CPU(unsigned long, max_freq_scale) = SCHED_CAPACITY_SCALE; - - void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq, - unsigned long max_freq) -@@ -31,8 +33,29 @@ void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq, - - scale = (cur_freq << SCHED_CAPACITY_SHIFT) / max_freq; - -- for_each_cpu(i, cpus) -+ for_each_cpu(i, cpus) { - per_cpu(freq_scale, i) = scale; -+ per_cpu(max_cpu_freq, i) = max_freq; -+ } -+} -+ -+void arch_set_max_freq_scale(struct cpumask *cpus, -+ unsigned long policy_max_freq) -+{ -+ unsigned long scale, max_freq; -+ int cpu = cpumask_first(cpus); -+ -+ if (cpu > nr_cpu_ids) -+ return; -+ -+ max_freq = per_cpu(max_cpu_freq, cpu); -+ if (!max_freq) -+ return; -+ -+ scale = (policy_max_freq << SCHED_CAPACITY_SHIFT) / max_freq; -+ -+ for_each_cpu(cpu, cpus) -+ per_cpu(max_freq_scale, cpu) = scale; - } - - DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE; -diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c -index f9de9dece70f..9c15d7f52e1c 100644 ---- a/drivers/cpufreq/cpufreq.c -+++ b/drivers/cpufreq/cpufreq.c -@@ -153,6 +153,12 @@ __weak void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq, - } - EXPORT_SYMBOL_GPL(arch_set_freq_scale); - -+__weak void arch_set_max_freq_scale(struct cpumask *cpus, -+ unsigned long policy_max_freq) -+{ -+} -+EXPORT_SYMBOL_GPL(arch_set_max_freq_scale); -+ - /* - * This is a generic cpufreq init() routine which can be used by cpufreq - * drivers of SMP systems. It will do following: -@@ -2407,6 +2413,8 @@ int cpufreq_set_policy(struct cpufreq_policy *policy, - policy->max = new_policy->max; - trace_cpu_frequency_limits(policy); - -+ arch_set_max_freq_scale(policy->cpus, policy->max); -+ - policy->cached_target_freq = UINT_MAX; - - pr_debug("new min and max freqs are %u - %u kHz\n", -diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h -index 42f2b5126094..5402bc0e2b1e 100644 ---- a/include/linux/arch_topology.h -+++ b/include/linux/arch_topology.h -@@ -33,6 +33,14 @@ unsigned long topology_get_freq_scale(int cpu) - return per_cpu(freq_scale, cpu); - } - -+DECLARE_PER_CPU(unsigned long, max_freq_scale); -+ -+static inline -+unsigned long topology_get_max_freq_scale(struct sched_domain *sd, int cpu) -+{ -+ return per_cpu(max_freq_scale, cpu); -+} -+ - struct cpu_topology { - int thread_id; - int core_id; -diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h -index c57e88e85c41..fca45a2749d4 100644 ---- a/include/linux/cpufreq.h -+++ b/include/linux/cpufreq.h -@@ -984,6 +984,8 @@ extern unsigned int arch_freq_get_on_cpu(int cpu); - - extern void arch_set_freq_scale(struct cpumask *cpus, unsigned long cur_freq, - unsigned long max_freq); -+extern void arch_set_max_freq_scale(struct cpumask *cpus, -+ unsigned long policy_max_freq); - - /* the following are really really optional */ - extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs; diff --git a/patches/ANDROID-cpufreq-times-add-proc-uid_concurrent_-active-policy-_time.patch b/patches/ANDROID-cpufreq-times-add-proc-uid_concurrent_-active-policy-_time.patch deleted file mode 100644 index c6b01f153e62..000000000000 --- a/patches/ANDROID-cpufreq-times-add-proc-uid_concurrent_-active-policy-_time.patch +++ /dev/null @@ -1,340 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Connor O'Brien -Date: Fri, 5 Oct 2018 19:20:54 -0700 -Subject: ANDROID: cpufreq: times: add - /proc/uid_concurrent_{active,policy}_time - -In order to model the energy used by the cpu, we need to expose cpu -time information to userspace. We can use this information to blame -uids for the energy they are using. - -This patch adds 2 files: - -/proc/uid_concurrent_active_time outputs the time each uid spent -running with 1 to num_possible_cpus online and not idle. - -For instance, if 4 cores are online and active for 50ms and the uid is -running on one of the cores, the uid should be blamed for 1/4 of the -base energy used by the cpu when 1 or more cores is active. - -/proc/uid_concurrent_policy_time outputs the time each uid spent -running on group of cpu's with the same policy with 1 to -num_related_cpus online and not idle. - -For instance, if 2 cores that are a part of the same policy are online -and active for 50ms and the uid is running on one of the cores, the -uid should be blamed for 1/2 of the energy that is used everytime one -or more cpus in the same policy is active. - -This patch is based on commit c89e69136fec ("ANDROID: cpufreq: -uid_concurrent_active_time") and commit 989212536842 ("ANDROID: -cpufreq: uid_concurrent_policy_time") in the android-msm-wahoo-4.4 -kernel by Marissa Wall. - -Bug: 111216804 -Bug: 127641090 -Test: cat files on hikey960 and confirm output is reasonable -Change-Id: I1a342361af5c04ecee58d1ab667c91c1bce42445 -Signed-off-by: Connor O'Brien ---- - .../ABI/testing/procfs-concurrent_time | 16 ++ - drivers/cpufreq/cpufreq_times.c | 190 +++++++++++++++++- - 2 files changed, 204 insertions(+), 2 deletions(-) - create mode 100644 Documentation/ABI/testing/procfs-concurrent_time - -diff --git a/Documentation/ABI/testing/procfs-concurrent_time b/Documentation/ABI/testing/procfs-concurrent_time -new file mode 100644 -index 000000000000..55b414289b40 ---- /dev/null -+++ b/Documentation/ABI/testing/procfs-concurrent_time -@@ -0,0 +1,16 @@ -+What: /proc/uid_concurrent_active_time -+Date: December 2018 -+Contact: Connor O'Brien -+Description: -+ The /proc/uid_concurrent_active_time file displays aggregated cputime -+ numbers for each uid, broken down by the total number of cores that were -+ active while the uid's task was running. -+ -+What: /proc/uid_concurrent_policy_time -+Date: December 2018 -+Contact: Connor O'Brien -+Description: -+ The /proc/uid_concurrent_policy_time file displays aggregated cputime -+ numbers for each uid, broken down based on the cpufreq policy -+ of the core used by the uid's task and the number of cores associated -+ with that policy that were active while the uid's task was running. -diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c -index a43eeee30e8e..aaded60c9a21 100644 ---- a/drivers/cpufreq/cpufreq_times.c -+++ b/drivers/cpufreq/cpufreq_times.c -@@ -32,11 +32,17 @@ static DECLARE_HASHTABLE(uid_hash_table, UID_HASH_BITS); - static DEFINE_SPINLOCK(task_time_in_state_lock); /* task->time_in_state */ - static DEFINE_SPINLOCK(uid_lock); /* uid_hash_table */ - -+struct concurrent_times { -+ atomic64_t active[NR_CPUS]; -+ atomic64_t policy[NR_CPUS]; -+}; -+ - struct uid_entry { - uid_t uid; - unsigned int max_state; - struct hlist_node hash; - struct rcu_head rcu; -+ struct concurrent_times *concurrent_times; - u64 time_in_state[0]; - }; - -@@ -87,6 +93,7 @@ static struct uid_entry *find_uid_entry_locked(uid_t uid) - static struct uid_entry *find_or_register_uid_locked(uid_t uid) - { - struct uid_entry *uid_entry, *temp; -+ struct concurrent_times *times; - unsigned int max_state = READ_ONCE(next_offset); - size_t alloc_size = sizeof(*uid_entry) + max_state * - sizeof(uid_entry->time_in_state[0]); -@@ -115,9 +122,15 @@ static struct uid_entry *find_or_register_uid_locked(uid_t uid) - uid_entry = kzalloc(alloc_size, GFP_ATOMIC); - if (!uid_entry) - return NULL; -+ times = kzalloc(sizeof(*times), GFP_ATOMIC); -+ if (!times) { -+ kfree(uid_entry); -+ return NULL; -+ } - - uid_entry->uid = uid; - uid_entry->max_state = max_state; -+ uid_entry->concurrent_times = times; - - hash_add_rcu(uid_hash_table, &uid_entry->hash, uid); - -@@ -232,6 +245,86 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v) - return 0; - } - -+static int concurrent_time_seq_show(struct seq_file *m, void *v, -+ atomic64_t *(*get_times)(struct concurrent_times *)) -+{ -+ struct uid_entry *uid_entry; -+ int i, num_possible_cpus = num_possible_cpus(); -+ -+ rcu_read_lock(); -+ -+ hlist_for_each_entry_rcu(uid_entry, (struct hlist_head *)v, hash) { -+ atomic64_t *times = get_times(uid_entry->concurrent_times); -+ -+ seq_put_decimal_ull(m, "", (u64)uid_entry->uid); -+ seq_putc(m, ':'); -+ -+ for (i = 0; i < num_possible_cpus; ++i) { -+ u64 time = nsec_to_clock_t(atomic64_read(×[i])); -+ -+ seq_put_decimal_ull(m, " ", time); -+ } -+ seq_putc(m, '\n'); -+ } -+ -+ rcu_read_unlock(); -+ -+ return 0; -+} -+ -+static inline atomic64_t *get_active_times(struct concurrent_times *times) -+{ -+ return times->active; -+} -+ -+static int concurrent_active_time_seq_show(struct seq_file *m, void *v) -+{ -+ if (v == uid_hash_table) { -+ seq_put_decimal_ull(m, "cpus: ", num_possible_cpus()); -+ seq_putc(m, '\n'); -+ } -+ -+ return concurrent_time_seq_show(m, v, get_active_times); -+} -+ -+static inline atomic64_t *get_policy_times(struct concurrent_times *times) -+{ -+ return times->policy; -+} -+ -+static int concurrent_policy_time_seq_show(struct seq_file *m, void *v) -+{ -+ int i; -+ struct cpu_freqs *freqs, *last_freqs = NULL; -+ -+ if (v == uid_hash_table) { -+ int cnt = 0; -+ -+ for_each_possible_cpu(i) { -+ freqs = all_freqs[i]; -+ if (!freqs) -+ continue; -+ if (freqs != last_freqs) { -+ if (last_freqs) { -+ seq_put_decimal_ull(m, ": ", cnt); -+ seq_putc(m, ' '); -+ cnt = 0; -+ } -+ seq_put_decimal_ull(m, "policy", i); -+ -+ last_freqs = freqs; -+ } -+ cnt++; -+ } -+ if (last_freqs) { -+ seq_put_decimal_ull(m, ": ", cnt); -+ seq_putc(m, '\n'); -+ } -+ } -+ -+ return concurrent_time_seq_show(m, v, get_policy_times); -+} -+ - void cpufreq_task_times_init(struct task_struct *p) - { - unsigned long flags; -@@ -326,11 +419,16 @@ void cpufreq_acct_update_power(struct task_struct *p, u64 cputime) - { - unsigned long flags; - unsigned int state; -+ unsigned int active_cpu_cnt = 0; -+ unsigned int policy_cpu_cnt = 0; -+ unsigned int policy_first_cpu; - struct uid_entry *uid_entry; - struct cpu_freqs *freqs = all_freqs[task_cpu(p)]; -+ struct cpufreq_policy *policy; - uid_t uid = from_kuid_munged(current_user_ns(), task_uid(p)); -+ int cpu = 0; - -- if (!freqs || p->flags & PF_EXITING) -+ if (!freqs || is_idle_task(p) || p->flags & PF_EXITING) - return; - - state = freqs->offset + READ_ONCE(freqs->last_index); -@@ -346,6 +444,42 @@ void cpufreq_acct_update_power(struct task_struct *p, u64 cputime) - if (uid_entry && state < uid_entry->max_state) - uid_entry->time_in_state[state] += cputime; - spin_unlock_irqrestore(&uid_lock, flags); -+ -+ rcu_read_lock(); -+ uid_entry = find_uid_entry_rcu(uid); -+ if (!uid_entry) { -+ rcu_read_unlock(); -+ return; -+ } -+ -+ for_each_possible_cpu(cpu) -+ if (!idle_cpu(cpu)) -+ ++active_cpu_cnt; -+ -+ atomic64_add(cputime, -+ &uid_entry->concurrent_times->active[active_cpu_cnt - 1]); -+ -+ policy = cpufreq_cpu_get(task_cpu(p)); -+ if (!policy) { -+ /* -+ * This CPU may have just come up and not have a cpufreq policy -+ * yet. -+ */ -+ rcu_read_unlock(); -+ return; -+ } -+ -+ for_each_cpu(cpu, policy->related_cpus) -+ if (!idle_cpu(cpu)) -+ ++policy_cpu_cnt; -+ -+ policy_first_cpu = cpumask_first(policy->related_cpus); -+ cpufreq_cpu_put(policy); -+ -+ atomic64_add(cputime, -+ &uid_entry->concurrent_times->policy[policy_first_cpu + -+ policy_cpu_cnt - 1]); -+ rcu_read_unlock(); - } - - void cpufreq_times_create_policy(struct cpufreq_policy *policy) -@@ -387,6 +521,14 @@ void cpufreq_times_create_policy(struct cpufreq_policy *policy) - all_freqs[cpu] = freqs; - } - -+static void uid_entry_reclaim(struct rcu_head *rcu) -+{ -+ struct uid_entry *uid_entry = container_of(rcu, struct uid_entry, rcu); -+ -+ kfree(uid_entry->concurrent_times); -+ kfree(uid_entry); -+} -+ - void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end) - { - struct uid_entry *uid_entry; -@@ -400,7 +542,7 @@ void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end) - hash, uid_start) { - if (uid_start == uid_entry->uid) { - hash_del_rcu(&uid_entry->hash); -- kfree_rcu(uid_entry, rcu); -+ call_rcu(&uid_entry->rcu, uid_entry_reclaim); - } - } - } -@@ -453,11 +595,55 @@ static const struct file_operations uid_time_in_state_fops = { - .release = seq_release, - }; - -+static const struct seq_operations concurrent_active_time_seq_ops = { -+ .start = uid_seq_start, -+ .next = uid_seq_next, -+ .stop = uid_seq_stop, -+ .show = concurrent_active_time_seq_show, -+}; -+ -+static int concurrent_active_time_open(struct inode *inode, struct file *file) -+{ -+ return seq_open(file, &concurrent_active_time_seq_ops); -+} -+ -+static const struct file_operations concurrent_active_time_fops = { -+ .open = concurrent_active_time_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = seq_release, -+}; -+ -+static const struct seq_operations concurrent_policy_time_seq_ops = { -+ .start = uid_seq_start, -+ .next = uid_seq_next, -+ .stop = uid_seq_stop, -+ .show = concurrent_policy_time_seq_show, -+}; -+ -+static int concurrent_policy_time_open(struct inode *inode, struct file *file) -+{ -+ return seq_open(file, &concurrent_policy_time_seq_ops); -+} -+ -+static const struct file_operations concurrent_policy_time_fops = { -+ .open = concurrent_policy_time_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = seq_release, -+}; -+ - static int __init cpufreq_times_init(void) - { - proc_create_data("uid_time_in_state", 0444, NULL, - &uid_time_in_state_fops, NULL); - -+ proc_create_data("uid_concurrent_active_time", 0444, NULL, -+ &concurrent_active_time_fops, NULL); -+ -+ proc_create_data("uid_concurrent_policy_time", 0444, NULL, -+ &concurrent_policy_time_fops, NULL); -+ - return 0; - } - diff --git a/patches/ANDROID-cpufreq-times-don-t-copy-invalid-freqs-from-freq-table.patch b/patches/ANDROID-cpufreq-times-don-t-copy-invalid-freqs-from-freq-table.patch deleted file mode 100644 index 8ce77cf8ca2d..000000000000 --- a/patches/ANDROID-cpufreq-times-don-t-copy-invalid-freqs-from-freq-table.patch +++ /dev/null @@ -1,151 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Connor O'Brien -Date: Fri, 1 Mar 2019 15:40:30 -0800 -Subject: ANDROID: cpufreq: times: don't copy invalid freqs from freq table - -Invalid frequency checks are a bottleneck in reading -/proc/uid_time_in_state, but there's no reason to include invalid -frequencies in our local copies of frequency tables. Revise -cpufreq_times_create_policy() to only copy valid frequencies, and -eliminate all the checks this change makes unnecessary. - -Bug: 111216804 -Test: cat /proc/uid_time_in_state & confirm values & format are sane -Test: /proc/uid_time_in_state read times reduced by ~40% -Change-Id: I506420a6ac5fe8a6c87d01b16ad267b192d43f1d -Signed-off-by: Connor O'Brien ---- - drivers/cpufreq/cpufreq_times.c | 55 ++++++++++++--------------------- - 1 file changed, 19 insertions(+), 36 deletions(-) - -diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c -index 2883d675b1eb..5b5248a7c87c 100644 ---- a/drivers/cpufreq/cpufreq_times.c -+++ b/drivers/cpufreq/cpufreq_times.c -@@ -137,27 +137,10 @@ static struct uid_entry *find_or_register_uid_locked(uid_t uid) - return uid_entry; - } - --static bool freq_index_invalid(unsigned int index) --{ -- unsigned int cpu; -- struct cpu_freqs *freqs; -- -- for_each_possible_cpu(cpu) { -- freqs = all_freqs[cpu]; -- if (!freqs || index < freqs->offset || -- freqs->offset + freqs->max_state <= index) -- continue; -- return freqs->freq_table[index - freqs->offset] == -- CPUFREQ_ENTRY_INVALID; -- } -- return true; --} -- - static int single_uid_time_in_state_show(struct seq_file *m, void *ptr) - { - struct uid_entry *uid_entry; - unsigned int i; -- u64 time; - uid_t uid = from_kuid_munged(current_user_ns(), *(kuid_t *)m->private); - - if (uid == overflowuid) -@@ -172,9 +155,7 @@ static int single_uid_time_in_state_show(struct seq_file *m, void *ptr) - } - - for (i = 0; i < uid_entry->max_state; ++i) { -- if (freq_index_invalid(i)) -- continue; -- time = nsec_to_clock_t(uid_entry->time_in_state[i]); -+ u64 time = nsec_to_clock_t(uid_entry->time_in_state[i]); - seq_write(m, &time, sizeof(time)); - } - -@@ -219,9 +200,6 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v) - continue; - last_freqs = freqs; - for (i = 0; i < freqs->max_state; i++) { -- if (freqs->freq_table[i] == -- CPUFREQ_ENTRY_INVALID) -- continue; - seq_put_decimal_ull(m, " ", - freqs->freq_table[i]); - } -@@ -237,10 +215,7 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v) - seq_putc(m, ':'); - } - for (i = 0; i < uid_entry->max_state; ++i) { -- u64 time; -- if (freq_index_invalid(i)) -- continue; -- time = nsec_to_clock_t(uid_entry->time_in_state[i]); -+ u64 time = nsec_to_clock_t(uid_entry->time_in_state[i]); - seq_put_decimal_ull(m, " ", time); - } - if (uid_entry->max_state) -@@ -407,8 +382,6 @@ int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns, - - seq_printf(m, "cpu%u\n", cpu); - for (i = 0; i < freqs->max_state; i++) { -- if (freqs->freq_table[i] == CPUFREQ_ENTRY_INVALID) -- continue; - cputime = 0; - if (freqs->offset + i < p->max_state && - p->time_in_state) -@@ -488,9 +461,19 @@ void cpufreq_acct_update_power(struct task_struct *p, u64 cputime) - rcu_read_unlock(); - } - -+static int cpufreq_times_get_index(struct cpu_freqs *freqs, unsigned int freq) -+{ -+ int index; -+ for (index = 0; index < freqs->max_state; ++index) { -+ if (freqs->freq_table[index] == freq) -+ return index; -+ } -+ return -1; -+} -+ - void cpufreq_times_create_policy(struct cpufreq_policy *policy) - { -- int cpu, index; -+ int cpu, index = 0; - unsigned int count = 0; - struct cpufreq_frequency_table *pos, *table; - struct cpu_freqs *freqs; -@@ -503,7 +486,7 @@ void cpufreq_times_create_policy(struct cpufreq_policy *policy) - if (!table) - return; - -- cpufreq_for_each_entry(pos, table) -+ cpufreq_for_each_valid_entry(pos, table) - count++; - - tmp = kzalloc(sizeof(*freqs) + sizeof(freqs->freq_table[0]) * count, -@@ -514,13 +497,13 @@ void cpufreq_times_create_policy(struct cpufreq_policy *policy) - freqs = tmp; - freqs->max_state = count; - -- index = cpufreq_frequency_table_get_index(policy, policy->cur); -+ cpufreq_for_each_valid_entry(pos, table) -+ freqs->freq_table[index++] = pos->frequency; -+ -+ index = cpufreq_times_get_index(freqs, policy->cur); - if (index >= 0) - WRITE_ONCE(freqs->last_index, index); - -- cpufreq_for_each_entry(pos, table) -- freqs->freq_table[pos - table] = pos->frequency; -- - freqs->offset = next_offset; - WRITE_ONCE(next_offset, freqs->offset + count); - for_each_cpu(cpu, policy->related_cpus) -@@ -564,7 +547,7 @@ void cpufreq_times_record_transition(struct cpufreq_policy *policy, - if (!freqs) - return; - -- index = cpufreq_frequency_table_get_index(policy, new_freq); -+ index = cpufreq_times_get_index(freqs, new_freq); - if (index >= 0) - WRITE_ONCE(freqs->last_index, index); - } diff --git a/patches/ANDROID-cpufreq-times-optimize-proc-files.patch b/patches/ANDROID-cpufreq-times-optimize-proc-files.patch deleted file mode 100644 index 68b9b4058102..000000000000 --- a/patches/ANDROID-cpufreq-times-optimize-proc-files.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Connor O'Brien -Date: Wed, 20 Feb 2019 12:17:48 -0800 -Subject: ANDROID: cpufreq: times: optimize proc files - -The majority of the time spent reading /proc/uid_time_in_state is due -to seq_printf calls. Use the faster seq_put_* variations instead. - -Also skip empty hash buckets in uid_seq_next for a further performance -improvement. - -Bug: 111216804 -Bug: 127641090 -Test: Read /proc/uid_time_in_state and confirm output is sane -Test: Compare read times to confirm performance improvement -Change-Id: If8783b498ed73d2ddb186a49438af41ac5ab9957 -Signed-off-by: Connor O'Brien ---- - drivers/cpufreq/cpufreq_times.c | 22 ++++++++++++++-------- - 1 file changed, 14 insertions(+), 8 deletions(-) - -diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c -index 42420c5e1e6f..2883d675b1eb 100644 ---- a/drivers/cpufreq/cpufreq_times.c -+++ b/drivers/cpufreq/cpufreq_times.c -@@ -193,10 +193,12 @@ static void *uid_seq_start(struct seq_file *seq, loff_t *pos) - - static void *uid_seq_next(struct seq_file *seq, void *v, loff_t *pos) - { -- (*pos)++; -+ do { -+ (*pos)++; - -- if (*pos >= HASH_SIZE(uid_hash_table)) -- return NULL; -+ if (*pos >= HASH_SIZE(uid_hash_table)) -+ return NULL; -+ } while (hlist_empty(&uid_hash_table[*pos])); - - return &uid_hash_table[*pos]; - } -@@ -220,7 +222,8 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v) - if (freqs->freq_table[i] == - CPUFREQ_ENTRY_INVALID) - continue; -- seq_printf(m, " %d", freqs->freq_table[i]); -+ seq_put_decimal_ull(m, " ", -+ freqs->freq_table[i]); - } - } - seq_putc(m, '\n'); -@@ -229,13 +232,16 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v) - rcu_read_lock(); - - hlist_for_each_entry_rcu(uid_entry, (struct hlist_head *)v, hash) { -- if (uid_entry->max_state) -- seq_printf(m, "%d:", uid_entry->uid); -+ if (uid_entry->max_state) { -+ seq_put_decimal_ull(m, "", uid_entry->uid); -+ seq_putc(m, ':'); -+ } - for (i = 0; i < uid_entry->max_state; ++i) { -+ u64 time; - if (freq_index_invalid(i)) - continue; -- seq_printf(m, " %lu", (unsigned long)nsec_to_clock_t( -- uid_entry->time_in_state[i])); -+ time = nsec_to_clock_t(uid_entry->time_in_state[i]); -+ seq_put_decimal_ull(m, " ", time); - } - if (uid_entry->max_state) - seq_putc(m, '\n'); diff --git a/patches/ANDROID-cpufreq-times-record-fast-switch-frequency-transitions.patch b/patches/ANDROID-cpufreq-times-record-fast-switch-frequency-transitions.patch deleted file mode 100644 index 2e652eb7566b..000000000000 --- a/patches/ANDROID-cpufreq-times-record-fast-switch-frequency-transitions.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Connor O'Brien -Date: Fri, 8 Feb 2019 12:30:41 -0800 -Subject: ANDROID: cpufreq: times: record fast switch frequency transitions - -cpufreq_times_record_transition() is not called when fast switch is -enabled, leading /proc/uid_time_in_state to attribute all time on a -cluster to a single frequency. To fix this, add a call to -cpufreq_times_record_transition() in the fast switch path. - -Also revise cpufreq_times_record_transition() to simplify the new call -and more closely align with cpufreq_stats_record_transition(). - -Bug: 121287027 -Bug: 127641090 -Test: /proc/uid_time_in_state shows times for more than one freq per -cluster -Change-Id: Ib63d19006878fafb88475e401ef243bdd8b11979 -Signed-off-by: Connor O'Brien ---- - drivers/cpufreq/cpufreq.c | 10 ++++++++-- - drivers/cpufreq/cpufreq_times.c | 15 ++++----------- - include/linux/cpufreq_times.h | 5 +++-- - 3 files changed, 15 insertions(+), 15 deletions(-) - -diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c -index a6512ee4b8cc..f9de9dece70f 100644 ---- a/drivers/cpufreq/cpufreq.c -+++ b/drivers/cpufreq/cpufreq.c -@@ -380,7 +380,7 @@ static void cpufreq_notify_transition(struct cpufreq_policy *policy, - CPUFREQ_POSTCHANGE, freqs); - - cpufreq_stats_record_transition(policy, freqs->new); -- cpufreq_times_record_transition(freqs); -+ cpufreq_times_record_transition(policy, freqs->new); - policy->cur = freqs->new; - } - } -@@ -2023,9 +2023,15 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier); - unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy, - unsigned int target_freq) - { -+ int ret; -+ - target_freq = clamp_val(target_freq, policy->min, policy->max); - -- return cpufreq_driver->fast_switch(policy, target_freq); -+ ret = cpufreq_driver->fast_switch(policy, target_freq); -+ if (ret) -+ cpufreq_times_record_transition(policy, ret); -+ -+ return ret; - } - EXPORT_SYMBOL_GPL(cpufreq_driver_fast_switch); - -diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c -index aaded60c9a21..42420c5e1e6f 100644 ---- a/drivers/cpufreq/cpufreq_times.c -+++ b/drivers/cpufreq/cpufreq_times.c -@@ -550,24 +550,17 @@ void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end) - spin_unlock_irqrestore(&uid_lock, flags); - } - --void cpufreq_times_record_transition(struct cpufreq_freqs *freq) -+void cpufreq_times_record_transition(struct cpufreq_policy *policy, -+ unsigned int new_freq) - { - int index; -- struct cpu_freqs *freqs = all_freqs[freq->cpu]; -- struct cpufreq_policy *policy; -- -+ struct cpu_freqs *freqs = all_freqs[policy->cpu]; - if (!freqs) - return; - -- policy = cpufreq_cpu_get(freq->cpu); -- if (!policy) -- return; -- -- index = cpufreq_frequency_table_get_index(policy, freq->new); -+ index = cpufreq_frequency_table_get_index(policy, new_freq); - if (index >= 0) - WRITE_ONCE(freqs->last_index, index); -- -- cpufreq_cpu_put(policy); - } - - static const struct seq_operations uid_time_in_state_seq_ops = { -diff --git a/include/linux/cpufreq_times.h b/include/linux/cpufreq_times.h -index 757bf0cb6070..0eb6dc9d0fe2 100644 ---- a/include/linux/cpufreq_times.h -+++ b/include/linux/cpufreq_times.h -@@ -27,7 +27,8 @@ int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns, - struct pid *pid, struct task_struct *p); - void cpufreq_acct_update_power(struct task_struct *p, u64 cputime); - void cpufreq_times_create_policy(struct cpufreq_policy *policy); --void cpufreq_times_record_transition(struct cpufreq_freqs *freq); -+void cpufreq_times_record_transition(struct cpufreq_policy *policy, -+ unsigned int new_freq); - void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end); - int single_uid_time_in_state_open(struct inode *inode, struct file *file); - #else -@@ -38,7 +39,7 @@ static inline void cpufreq_acct_update_power(struct task_struct *p, - u64 cputime) {} - static inline void cpufreq_times_create_policy(struct cpufreq_policy *policy) {} - static inline void cpufreq_times_record_transition( -- struct cpufreq_freqs *freq) {} -+ struct cpufreq_policy *policy, unsigned int new_freq) {} - static inline void cpufreq_task_times_remove_uids(uid_t uid_start, - uid_t uid_end) {} - #endif /* CONFIG_CPU_FREQ_TIMES */ diff --git a/patches/ANDROID-cpufreq-times-track-per-uid-time-in-state.patch b/patches/ANDROID-cpufreq-times-track-per-uid-time-in-state.patch deleted file mode 100644 index a378a5dd64d9..000000000000 --- a/patches/ANDROID-cpufreq-times-track-per-uid-time-in-state.patch +++ /dev/null @@ -1,328 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Connor O'Brien -Date: Tue, 6 Feb 2018 13:30:27 -0800 -Subject: ANDROID: cpufreq: times: track per-uid time in state - -Add /proc/uid_time_in_state showing per uid/frequency/cluster -times. Allow uid removal through /proc/uid_cputime/remove_uid_range. - -Signed-off-by: Connor O'Brien -Bug: 72339335 -Bug: 127641090 -Test: Read /proc/uid_time_in_state -Change-Id: I20ba3546a27c25b7e7991e2a86986e158aafa58c ---- - drivers/cpufreq/cpufreq_times.c | 208 ++++++++++++++++++++++++++++++++ - drivers/misc/uid_sys_stats.c | 4 + - include/linux/cpufreq_times.h | 3 + - 3 files changed, 215 insertions(+) - -diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c -index 339a3e9cf082..15b52e1f82fc 100644 ---- a/drivers/cpufreq/cpufreq_times.c -+++ b/drivers/cpufreq/cpufreq_times.c -@@ -15,14 +15,30 @@ - - #include - #include -+#include -+#include - #include -+#include - #include - #include - #include - #include - #include - -+#define UID_HASH_BITS 10 -+ -+static DECLARE_HASHTABLE(uid_hash_table, UID_HASH_BITS); -+ - static DEFINE_SPINLOCK(task_time_in_state_lock); /* task->time_in_state */ -+static DEFINE_SPINLOCK(uid_lock); /* uid_hash_table */ -+ -+struct uid_entry { -+ uid_t uid; -+ unsigned int max_state; -+ struct hlist_node hash; -+ struct rcu_head rcu; -+ u64 time_in_state[0]; -+}; - - /** - * struct cpu_freqs - per-cpu frequency information -@@ -42,6 +58,137 @@ static struct cpu_freqs *all_freqs[NR_CPUS]; - - static unsigned int next_offset; - -+/* Caller must hold uid lock */ -+static struct uid_entry *find_uid_entry_locked(uid_t uid) -+{ -+ struct uid_entry *uid_entry; -+ -+ hash_for_each_possible(uid_hash_table, uid_entry, hash, uid) { -+ if (uid_entry->uid == uid) -+ return uid_entry; -+ } -+ return NULL; -+} -+ -+/* Caller must hold uid lock */ -+static struct uid_entry *find_or_register_uid_locked(uid_t uid) -+{ -+ struct uid_entry *uid_entry, *temp; -+ unsigned int max_state = READ_ONCE(next_offset); -+ size_t alloc_size = sizeof(*uid_entry) + max_state * -+ sizeof(uid_entry->time_in_state[0]); -+ -+ uid_entry = find_uid_entry_locked(uid); -+ if (uid_entry) { -+ if (uid_entry->max_state == max_state) -+ return uid_entry; -+ /* uid_entry->time_in_state is too small to track all freqs, so -+ * expand it. -+ */ -+ temp = __krealloc(uid_entry, alloc_size, GFP_ATOMIC); -+ if (!temp) -+ return uid_entry; -+ temp->max_state = max_state; -+ memset(temp->time_in_state + uid_entry->max_state, 0, -+ (max_state - uid_entry->max_state) * -+ sizeof(uid_entry->time_in_state[0])); -+ if (temp != uid_entry) { -+ hlist_replace_rcu(&uid_entry->hash, &temp->hash); -+ kfree_rcu(uid_entry, rcu); -+ } -+ return temp; -+ } -+ -+ uid_entry = kzalloc(alloc_size, GFP_ATOMIC); -+ if (!uid_entry) -+ return NULL; -+ -+ uid_entry->uid = uid; -+ uid_entry->max_state = max_state; -+ -+ hash_add_rcu(uid_hash_table, &uid_entry->hash, uid); -+ -+ return uid_entry; -+} -+ -+static bool freq_index_invalid(unsigned int index) -+{ -+ unsigned int cpu; -+ struct cpu_freqs *freqs; -+ -+ for_each_possible_cpu(cpu) { -+ freqs = all_freqs[cpu]; -+ if (!freqs || index < freqs->offset || -+ freqs->offset + freqs->max_state <= index) -+ continue; -+ return freqs->freq_table[index - freqs->offset] == -+ CPUFREQ_ENTRY_INVALID; -+ } -+ return true; -+} -+ -+static void *uid_seq_start(struct seq_file *seq, loff_t *pos) -+{ -+ if (*pos >= HASH_SIZE(uid_hash_table)) -+ return NULL; -+ -+ return &uid_hash_table[*pos]; -+} -+ -+static void *uid_seq_next(struct seq_file *seq, void *v, loff_t *pos) -+{ -+ (*pos)++; -+ -+ if (*pos >= HASH_SIZE(uid_hash_table)) -+ return NULL; -+ -+ return &uid_hash_table[*pos]; -+} -+ -+static void uid_seq_stop(struct seq_file *seq, void *v) { } -+ -+static int uid_time_in_state_seq_show(struct seq_file *m, void *v) -+{ -+ struct uid_entry *uid_entry; -+ struct cpu_freqs *freqs, *last_freqs = NULL; -+ int i, cpu; -+ -+ if (v == uid_hash_table) { -+ seq_puts(m, "uid:"); -+ for_each_possible_cpu(cpu) { -+ freqs = all_freqs[cpu]; -+ if (!freqs || freqs == last_freqs) -+ continue; -+ last_freqs = freqs; -+ for (i = 0; i < freqs->max_state; i++) { -+ if (freqs->freq_table[i] == -+ CPUFREQ_ENTRY_INVALID) -+ continue; -+ seq_printf(m, " %d", freqs->freq_table[i]); -+ } -+ } -+ seq_putc(m, '\n'); -+ } -+ -+ rcu_read_lock(); -+ -+ hlist_for_each_entry_rcu(uid_entry, (struct hlist_head *)v, hash) { -+ if (uid_entry->max_state) -+ seq_printf(m, "%d:", uid_entry->uid); -+ for (i = 0; i < uid_entry->max_state; ++i) { -+ if (freq_index_invalid(i)) -+ continue; -+ seq_printf(m, " %lu", (unsigned long)nsec_to_clock_t( -+ uid_entry->time_in_state[i])); -+ } -+ if (uid_entry->max_state) -+ seq_putc(m, '\n'); -+ } -+ -+ rcu_read_unlock(); -+ return 0; -+} -+ - void cpufreq_task_times_init(struct task_struct *p) - { - unsigned long flags; -@@ -90,6 +237,9 @@ void cpufreq_task_times_exit(struct task_struct *p) - unsigned long flags; - void *temp; - -+ if (!p->time_in_state) -+ return; -+ - spin_lock_irqsave(&task_time_in_state_lock, flags); - temp = p->time_in_state; - p->time_in_state = NULL; -@@ -133,7 +283,9 @@ void cpufreq_acct_update_power(struct task_struct *p, u64 cputime) - { - unsigned long flags; - unsigned int state; -+ struct uid_entry *uid_entry; - struct cpu_freqs *freqs = all_freqs[task_cpu(p)]; -+ uid_t uid = from_kuid_munged(current_user_ns(), task_uid(p)); - - if (!freqs || p->flags & PF_EXITING) - return; -@@ -145,6 +297,12 @@ void cpufreq_acct_update_power(struct task_struct *p, u64 cputime) - p->time_in_state) - p->time_in_state[state] += cputime; - spin_unlock_irqrestore(&task_time_in_state_lock, flags); -+ -+ spin_lock_irqsave(&uid_lock, flags); -+ uid_entry = find_or_register_uid_locked(uid); -+ if (uid_entry && state < uid_entry->max_state) -+ uid_entry->time_in_state[state] += cputime; -+ spin_unlock_irqrestore(&uid_lock, flags); - } - - void cpufreq_times_create_policy(struct cpufreq_policy *policy) -@@ -186,6 +344,27 @@ void cpufreq_times_create_policy(struct cpufreq_policy *policy) - all_freqs[cpu] = freqs; - } - -+void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end) -+{ -+ struct uid_entry *uid_entry; -+ struct hlist_node *tmp; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&uid_lock, flags); -+ -+ for (; uid_start <= uid_end; uid_start++) { -+ hash_for_each_possible_safe(uid_hash_table, uid_entry, tmp, -+ hash, uid_start) { -+ if (uid_start == uid_entry->uid) { -+ hash_del_rcu(&uid_entry->hash); -+ kfree_rcu(uid_entry, rcu); -+ } -+ } -+ } -+ -+ spin_unlock_irqrestore(&uid_lock, flags); -+} -+ - void cpufreq_times_record_transition(struct cpufreq_freqs *freq) - { - int index; -@@ -205,3 +384,32 @@ void cpufreq_times_record_transition(struct cpufreq_freqs *freq) - - cpufreq_cpu_put(policy); - } -+ -+static const struct seq_operations uid_time_in_state_seq_ops = { -+ .start = uid_seq_start, -+ .next = uid_seq_next, -+ .stop = uid_seq_stop, -+ .show = uid_time_in_state_seq_show, -+}; -+ -+static int uid_time_in_state_open(struct inode *inode, struct file *file) -+{ -+ return seq_open(file, &uid_time_in_state_seq_ops); -+} -+ -+static const struct file_operations uid_time_in_state_fops = { -+ .open = uid_time_in_state_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = seq_release, -+}; -+ -+static int __init cpufreq_times_init(void) -+{ -+ proc_create_data("uid_time_in_state", 0444, NULL, -+ &uid_time_in_state_fops, NULL); -+ -+ return 0; -+} -+ -+early_initcall(cpufreq_times_init); -diff --git a/drivers/misc/uid_sys_stats.c b/drivers/misc/uid_sys_stats.c -index 36b5f37fca2f..88dc1cd3a204 100644 ---- a/drivers/misc/uid_sys_stats.c -+++ b/drivers/misc/uid_sys_stats.c -@@ -14,6 +14,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -420,6 +421,9 @@ static ssize_t uid_remove_write(struct file *file, - return -EINVAL; - } - -+ /* Also remove uids from /proc/uid_time_in_state */ -+ cpufreq_task_times_remove_uids(uid_start, uid_end); -+ - rt_mutex_lock(&uid_lock); - - for (; uid_start <= uid_end; uid_start++) { -diff --git a/include/linux/cpufreq_times.h b/include/linux/cpufreq_times.h -index bfef6e62c68a..a03157f649a4 100644 ---- a/include/linux/cpufreq_times.h -+++ b/include/linux/cpufreq_times.h -@@ -28,6 +28,7 @@ int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns, - void cpufreq_acct_update_power(struct task_struct *p, u64 cputime); - void cpufreq_times_create_policy(struct cpufreq_policy *policy); - void cpufreq_times_record_transition(struct cpufreq_freqs *freq); -+void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end); - #else - static inline void cpufreq_task_times_init(struct task_struct *p) {} - static inline void cpufreq_task_times_alloc(struct task_struct *p) {} -@@ -37,5 +38,7 @@ static inline void cpufreq_acct_update_power(struct task_struct *p, - static inline void cpufreq_times_create_policy(struct cpufreq_policy *policy) {} - static inline void cpufreq_times_record_transition( - struct cpufreq_freqs *freq) {} -+static inline void cpufreq_task_times_remove_uids(uid_t uid_start, -+ uid_t uid_end) {} - #endif /* CONFIG_CPU_FREQ_TIMES */ - #endif /* _LINUX_CPUFREQ_TIMES_H */ diff --git a/patches/ANDROID-cpufreq-track-per-task-time-in-state.patch b/patches/ANDROID-cpufreq-track-per-task-time-in-state.patch deleted file mode 100644 index 0caca72adcd4..000000000000 --- a/patches/ANDROID-cpufreq-track-per-task-time-in-state.patch +++ /dev/null @@ -1,473 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Connor O'Brien -Date: Wed, 31 Jan 2018 18:11:57 -0800 -Subject: ANDROID: cpufreq: track per-task time in state - -Add time in state data to task structs, and create -/proc//time_in_state files to show how long each individual task -has run at each frequency. -Create a CONFIG_CPU_FREQ_TIMES option to enable/disable this tracking. - -Bug: 72339335 -Bug: 127641090 -Test: Read /proc//time_in_state -Change-Id: Ia6456754f4cb1e83b2bc35efa8fbe9f8696febc8 -Signed-off-by: Connor O'Brien -[astrachan: Folded the following changes into this patch: - a6d3de6a7fba ("ANDROID: Reduce use of #ifdef CONFIG_CPU_FREQ_TIMES") - b89ada5d9c09 ("ANDROID: Fix massive cpufreq_times memory leaks")] -Signed-off-by: Alistair Strachan ---- - drivers/cpufreq/Kconfig | 7 ++ - drivers/cpufreq/Makefile | 5 +- - drivers/cpufreq/cpufreq.c | 3 + - drivers/cpufreq/cpufreq_times.c | 207 ++++++++++++++++++++++++++++++++ - fs/proc/base.c | 7 ++ - include/linux/cpufreq_times.h | 41 +++++++ - include/linux/sched.h | 4 + - kernel/fork.c | 7 ++ - kernel/sched/cputime.c | 7 ++ - 9 files changed, 287 insertions(+), 1 deletion(-) - create mode 100644 drivers/cpufreq/cpufreq_times.c - create mode 100644 include/linux/cpufreq_times.h - -diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig -index bff5295016ae..f711715aa579 100644 ---- a/drivers/cpufreq/Kconfig -+++ b/drivers/cpufreq/Kconfig -@@ -34,6 +34,13 @@ config CPU_FREQ_STAT - - If in doubt, say N. - -+config CPU_FREQ_TIMES -+ bool "CPU frequency time-in-state statistics" -+ help -+ Export CPU time-in-state information through procfs. -+ -+ If in doubt, say N. -+ - choice - prompt "Default CPUFreq governor" - default CPU_FREQ_DEFAULT_GOV_USERSPACE if ARM_SA1100_CPUFREQ || ARM_SA1110_CPUFREQ -diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile -index 9a9f5ccd13d9..93d52a112cab 100644 ---- a/drivers/cpufreq/Makefile -+++ b/drivers/cpufreq/Makefile -@@ -5,7 +5,10 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq.o freq_table.o - # CPUfreq stats - obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o - --# CPUfreq governors -+# CPUfreq times -+obj-$(CONFIG_CPU_FREQ_TIMES) += cpufreq_times.o -+ -+# CPUfreq governors - obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o - obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o - obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o -diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c -index c52d6fa32aac..a6512ee4b8cc 100644 ---- a/drivers/cpufreq/cpufreq.c -+++ b/drivers/cpufreq/cpufreq.c -@@ -16,6 +16,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -379,6 +380,7 @@ static void cpufreq_notify_transition(struct cpufreq_policy *policy, - CPUFREQ_POSTCHANGE, freqs); - - cpufreq_stats_record_transition(policy, freqs->new); -+ cpufreq_times_record_transition(freqs); - policy->cur = freqs->new; - } - } -@@ -1460,6 +1462,7 @@ static int cpufreq_online(unsigned int cpu) - goto out_destroy_policy; - - cpufreq_stats_create_table(policy); -+ cpufreq_times_create_policy(policy); - - write_lock_irqsave(&cpufreq_driver_lock, flags); - list_add(&policy->policy_list, &cpufreq_policy_list); -diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c -new file mode 100644 -index 000000000000..339a3e9cf082 ---- /dev/null -+++ b/drivers/cpufreq/cpufreq_times.c -@@ -0,0 +1,207 @@ -+/* drivers/cpufreq/cpufreq_times.c -+ * -+ * Copyright (C) 2018 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static DEFINE_SPINLOCK(task_time_in_state_lock); /* task->time_in_state */ -+ -+/** -+ * struct cpu_freqs - per-cpu frequency information -+ * @offset: start of these freqs' stats in task time_in_state array -+ * @max_state: number of entries in freq_table -+ * @last_index: index in freq_table of last frequency switched to -+ * @freq_table: list of available frequencies -+ */ -+struct cpu_freqs { -+ unsigned int offset; -+ unsigned int max_state; -+ unsigned int last_index; -+ unsigned int freq_table[0]; -+}; -+ -+static struct cpu_freqs *all_freqs[NR_CPUS]; -+ -+static unsigned int next_offset; -+ -+void cpufreq_task_times_init(struct task_struct *p) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&task_time_in_state_lock, flags); -+ p->time_in_state = NULL; -+ spin_unlock_irqrestore(&task_time_in_state_lock, flags); -+ p->max_state = 0; -+} -+ -+void cpufreq_task_times_alloc(struct task_struct *p) -+{ -+ void *temp; -+ unsigned long flags; -+ unsigned int max_state = READ_ONCE(next_offset); -+ -+ /* We use one array to avoid multiple allocs per task */ -+ temp = kcalloc(max_state, sizeof(p->time_in_state[0]), GFP_ATOMIC); -+ if (!temp) -+ return; -+ -+ spin_lock_irqsave(&task_time_in_state_lock, flags); -+ p->time_in_state = temp; -+ spin_unlock_irqrestore(&task_time_in_state_lock, flags); -+ p->max_state = max_state; -+} -+ -+/* Caller must hold task_time_in_state_lock */ -+static int cpufreq_task_times_realloc_locked(struct task_struct *p) -+{ -+ void *temp; -+ unsigned int max_state = READ_ONCE(next_offset); -+ -+ temp = krealloc(p->time_in_state, max_state * sizeof(u64), GFP_ATOMIC); -+ if (!temp) -+ return -ENOMEM; -+ p->time_in_state = temp; -+ memset(p->time_in_state + p->max_state, 0, -+ (max_state - p->max_state) * sizeof(u64)); -+ p->max_state = max_state; -+ return 0; -+} -+ -+void cpufreq_task_times_exit(struct task_struct *p) -+{ -+ unsigned long flags; -+ void *temp; -+ -+ spin_lock_irqsave(&task_time_in_state_lock, flags); -+ temp = p->time_in_state; -+ p->time_in_state = NULL; -+ spin_unlock_irqrestore(&task_time_in_state_lock, flags); -+ kfree(temp); -+} -+ -+int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns, -+ struct pid *pid, struct task_struct *p) -+{ -+ unsigned int cpu, i; -+ u64 cputime; -+ unsigned long flags; -+ struct cpu_freqs *freqs; -+ struct cpu_freqs *last_freqs = NULL; -+ -+ spin_lock_irqsave(&task_time_in_state_lock, flags); -+ for_each_possible_cpu(cpu) { -+ freqs = all_freqs[cpu]; -+ if (!freqs || freqs == last_freqs) -+ continue; -+ last_freqs = freqs; -+ -+ seq_printf(m, "cpu%u\n", cpu); -+ for (i = 0; i < freqs->max_state; i++) { -+ if (freqs->freq_table[i] == CPUFREQ_ENTRY_INVALID) -+ continue; -+ cputime = 0; -+ if (freqs->offset + i < p->max_state && -+ p->time_in_state) -+ cputime = p->time_in_state[freqs->offset + i]; -+ seq_printf(m, "%u %lu\n", freqs->freq_table[i], -+ (unsigned long)nsec_to_clock_t(cputime)); -+ } -+ } -+ spin_unlock_irqrestore(&task_time_in_state_lock, flags); -+ return 0; -+} -+ -+void cpufreq_acct_update_power(struct task_struct *p, u64 cputime) -+{ -+ unsigned long flags; -+ unsigned int state; -+ struct cpu_freqs *freqs = all_freqs[task_cpu(p)]; -+ -+ if (!freqs || p->flags & PF_EXITING) -+ return; -+ -+ state = freqs->offset + READ_ONCE(freqs->last_index); -+ -+ spin_lock_irqsave(&task_time_in_state_lock, flags); -+ if ((state < p->max_state || !cpufreq_task_times_realloc_locked(p)) && -+ p->time_in_state) -+ p->time_in_state[state] += cputime; -+ spin_unlock_irqrestore(&task_time_in_state_lock, flags); -+} -+ -+void cpufreq_times_create_policy(struct cpufreq_policy *policy) -+{ -+ int cpu, index; -+ unsigned int count = 0; -+ struct cpufreq_frequency_table *pos, *table; -+ struct cpu_freqs *freqs; -+ void *tmp; -+ -+ if (all_freqs[policy->cpu]) -+ return; -+ -+ table = policy->freq_table; -+ if (!table) -+ return; -+ -+ cpufreq_for_each_entry(pos, table) -+ count++; -+ -+ tmp = kzalloc(sizeof(*freqs) + sizeof(freqs->freq_table[0]) * count, -+ GFP_KERNEL); -+ if (!tmp) -+ return; -+ -+ freqs = tmp; -+ freqs->max_state = count; -+ -+ index = cpufreq_frequency_table_get_index(policy, policy->cur); -+ if (index >= 0) -+ WRITE_ONCE(freqs->last_index, index); -+ -+ cpufreq_for_each_entry(pos, table) -+ freqs->freq_table[pos - table] = pos->frequency; -+ -+ freqs->offset = next_offset; -+ WRITE_ONCE(next_offset, freqs->offset + count); -+ for_each_cpu(cpu, policy->related_cpus) -+ all_freqs[cpu] = freqs; -+} -+ -+void cpufreq_times_record_transition(struct cpufreq_freqs *freq) -+{ -+ int index; -+ struct cpu_freqs *freqs = all_freqs[freq->cpu]; -+ struct cpufreq_policy *policy; -+ -+ if (!freqs) -+ return; -+ -+ policy = cpufreq_cpu_get(freq->cpu); -+ if (!policy) -+ return; -+ -+ index = cpufreq_frequency_table_get_index(policy, freq->new); -+ if (index >= 0) -+ WRITE_ONCE(freqs->last_index, index); -+ -+ cpufreq_cpu_put(policy); -+} -diff --git a/fs/proc/base.c b/fs/proc/base.c -index ebea9501afb8..7d13501910ee 100644 ---- a/fs/proc/base.c -+++ b/fs/proc/base.c -@@ -94,6 +94,7 @@ - #include - #include - #include -+#include - #include - #include "internal.h" - #include "fd.h" -@@ -3091,6 +3092,9 @@ static const struct pid_entry tgid_base_stuff[] = { - #ifdef CONFIG_LIVEPATCH - ONE("patch_state", S_IRUSR, proc_pid_patch_state), - #endif -+#ifdef CONFIG_CPU_FREQ_TIMES -+ ONE("time_in_state", 0444, proc_time_in_state_show), -+#endif - #ifdef CONFIG_STACKLEAK_METRICS - ONE("stack_depth", S_IRUGO, proc_stack_depth), - #endif -@@ -3487,6 +3491,9 @@ static const struct pid_entry tid_base_stuff[] = { - #ifdef CONFIG_PROC_PID_ARCH_STATUS - ONE("arch_status", S_IRUGO, proc_pid_arch_status), - #endif -+#ifdef CONFIG_CPU_FREQ_TIMES -+ ONE("time_in_state", 0444, proc_time_in_state_show), -+#endif - }; - - static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx) -diff --git a/include/linux/cpufreq_times.h b/include/linux/cpufreq_times.h -new file mode 100644 -index 000000000000..bfef6e62c68a ---- /dev/null -+++ b/include/linux/cpufreq_times.h -@@ -0,0 +1,41 @@ -+/* drivers/cpufreq/cpufreq_times.c -+ * -+ * Copyright (C) 2018 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef _LINUX_CPUFREQ_TIMES_H -+#define _LINUX_CPUFREQ_TIMES_H -+ -+#include -+#include -+ -+#ifdef CONFIG_CPU_FREQ_TIMES -+void cpufreq_task_times_init(struct task_struct *p); -+void cpufreq_task_times_alloc(struct task_struct *p); -+void cpufreq_task_times_exit(struct task_struct *p); -+int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns, -+ struct pid *pid, struct task_struct *p); -+void cpufreq_acct_update_power(struct task_struct *p, u64 cputime); -+void cpufreq_times_create_policy(struct cpufreq_policy *policy); -+void cpufreq_times_record_transition(struct cpufreq_freqs *freq); -+#else -+static inline void cpufreq_task_times_init(struct task_struct *p) {} -+static inline void cpufreq_task_times_alloc(struct task_struct *p) {} -+static inline void cpufreq_task_times_exit(struct task_struct *p) {} -+static inline void cpufreq_acct_update_power(struct task_struct *p, -+ u64 cputime) {} -+static inline void cpufreq_times_create_policy(struct cpufreq_policy *policy) {} -+static inline void cpufreq_times_record_transition( -+ struct cpufreq_freqs *freq) {} -+#endif /* CONFIG_CPU_FREQ_TIMES */ -+#endif /* _LINUX_CPUFREQ_TIMES_H */ -diff --git a/include/linux/sched.h b/include/linux/sched.h -index 2c2e56bd8913..16c499ca096b 100644 ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -840,6 +840,10 @@ struct task_struct { - u64 stimescaled; - #endif - u64 gtime; -+#ifdef CONFIG_CPU_FREQ_TIMES -+ u64 *time_in_state; -+ unsigned int max_state; -+#endif - struct prev_cputime prev_cputime; - #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN - struct vtime vtime; -diff --git a/kernel/fork.c b/kernel/fork.c -index bcdf53125210..d8cba7583875 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -93,6 +93,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -451,6 +452,8 @@ void put_task_stack(struct task_struct *tsk) - - void free_task(struct task_struct *tsk) - { -+ cpufreq_task_times_exit(tsk); -+ - #ifndef CONFIG_THREAD_INFO_IN_TASK - /* - * The task is finally done with both the stack and thread_info, -@@ -1852,6 +1855,8 @@ static __latent_entropy struct task_struct *copy_process( - if (!p) - goto fork_out; - -+ cpufreq_task_times_init(p); -+ - /* - * This _must_ happen before we call free_task(), i.e. before we jump - * to any of the bad_fork_* labels. This is to avoid freeing -@@ -2369,6 +2374,8 @@ long _do_fork(struct kernel_clone_args *args) - if (IS_ERR(p)) - return PTR_ERR(p); - -+ cpufreq_task_times_alloc(p); -+ - /* - * Do this prior waking up the new thread - the thread pointer - * might get invalid after that point, if the thread exits quickly. -diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c -index 46ed4e1383e2..fc49c1e169d9 100644 ---- a/kernel/sched/cputime.c -+++ b/kernel/sched/cputime.c -@@ -2,6 +2,7 @@ - /* - * Simple CPU accounting cgroup controller - */ -+#include - #include "sched.h" - - #ifdef CONFIG_IRQ_TIME_ACCOUNTING -@@ -129,6 +130,9 @@ void account_user_time(struct task_struct *p, u64 cputime) - - /* Account for user time used */ - acct_account_cputime(p); -+ -+ /* Account power usage for user time */ -+ cpufreq_acct_update_power(p, cputime); - } - - /* -@@ -173,6 +177,9 @@ void account_system_index_time(struct task_struct *p, - - /* Account for system time used */ - acct_account_cputime(p); -+ -+ /* Account power usage for system time */ -+ cpufreq_acct_update_power(p, cputime); - } - - /* diff --git a/patches/ANDROID-create-build.configs-for-allmodconfig.patch b/patches/ANDROID-create-build.configs-for-allmodconfig.patch deleted file mode 100644 index 53cf4b565012..000000000000 --- a/patches/ANDROID-create-build.configs-for-allmodconfig.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Matthias Maennich -Date: Thu, 29 Aug 2019 12:41:43 +0100 -Subject: ANDROID: create build.configs for allmodconfig - -Bug: 140224784 -Change-Id: I920e8737ee596e1b80428ff9831981c775570070 -Signed-off-by: Matthias Maennich ---- - build.config.allmodconfig | 11 +++++++++++ - build.config.allmodconfig.aarch64 | 4 ++++ - build.config.allmodconfig.x86_64 | 4 ++++ - 3 files changed, 19 insertions(+) - create mode 100644 build.config.allmodconfig - create mode 100644 build.config.allmodconfig.aarch64 - create mode 100644 build.config.allmodconfig.x86_64 - -diff --git a/build.config.allmodconfig b/build.config.allmodconfig -new file mode 100644 -index 000000000000..43b1a70d5800 ---- /dev/null -+++ b/build.config.allmodconfig -@@ -0,0 +1,11 @@ -+DEFCONFIG=allmodconfig -+ -+# XFS_FS is currently broken on this branch with clang-9 -+POST_DEFCONFIG_CMDS="update_config" -+function update_config() { -+ ${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \ -+ -d TEST_KMOD \ -+ -d XFS_FS -+ (cd ${OUT_DIR} && \ -+ make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig) -+} -diff --git a/build.config.allmodconfig.aarch64 b/build.config.allmodconfig.aarch64 -new file mode 100644 -index 000000000000..863ab1caddab ---- /dev/null -+++ b/build.config.allmodconfig.aarch64 -@@ -0,0 +1,4 @@ -+. ${ROOT_DIR}/common/build.config.common -+. ${ROOT_DIR}/common/build.config.aarch64 -+. ${ROOT_DIR}/common/build.config.allmodconfig -+ -diff --git a/build.config.allmodconfig.x86_64 b/build.config.allmodconfig.x86_64 -new file mode 100644 -index 000000000000..bedb3869d99b ---- /dev/null -+++ b/build.config.allmodconfig.x86_64 -@@ -0,0 +1,4 @@ -+. ${ROOT_DIR}/common/build.config.common -+. ${ROOT_DIR}/common/build.config.x86_64 -+. ${ROOT_DIR}/common/build.config.allmodconfig -+ diff --git a/patches/ANDROID-cuttlefish-gki-_defconfig-Enable-CONFIG_SDCARD_FS.patch b/patches/ANDROID-cuttlefish-gki-_defconfig-Enable-CONFIG_SDCARD_FS.patch deleted file mode 100644 index f281b1ec1b14..000000000000 --- a/patches/ANDROID-cuttlefish-gki-_defconfig-Enable-CONFIG_SDCARD_FS.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alistair Strachan -Date: Fri, 26 Oct 2018 10:02:08 -0700 -Subject: ANDROID: {cuttlefish,gki}_defconfig: Enable CONFIG_SDCARD_FS - -Bug: 118439987 -Change-Id: I020ec721d98c5612bfe76dcfc05caabb1f3588c1 -Signed-off-by: Alistair Strachan ---- - arch/arm64/configs/gki_defconfig | 1 + - arch/x86/configs/gki_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 140804afdd32..18e8f81cc0fb 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -379,6 +379,7 @@ CONFIG_VFAT_FS=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y - CONFIG_ECRYPT_FS=y -+CONFIG_SDCARD_FS=y - CONFIG_PSTORE=y - CONFIG_PSTORE_CONSOLE=y - CONFIG_PSTORE_RAM=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 65c67797fb74..eacebe96e422 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -304,6 +304,7 @@ CONFIG_MSDOS_FS=y - CONFIG_VFAT_FS=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_SDCARD_FS=y - CONFIG_PSTORE=y - CONFIG_PSTORE_CONSOLE=y - CONFIG_PSTORE_RAM=y diff --git a/patches/ANDROID-cuttlefish-overlayfs-regression.patch b/patches/ANDROID-cuttlefish-overlayfs-regression.patch deleted file mode 100644 index a3b79ff9cdf3..000000000000 --- a/patches/ANDROID-cuttlefish-overlayfs-regression.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mark Salyzyn -Date: Wed, 28 Aug 2019 09:38:07 -0700 -Subject: ANDROID: cuttlefish: overlayfs: regression - -commit a77712c342a56420013625c93d8aa1501455a984 -("ANDROID: Remove unused cuttlefish build infra") caused a -regression in availability of CONFIG_OVERLAY_FS configuration. - -NB: The upstream work to add override_creds to overlayfs is - required in order to pass adb-remount-test.sh. - -Signed-off-by: Mark Salyzyn -Test: confirm overlay filesystem available in the build -Bug: 138649540 -Change-Id: I9e51475f1025f726e69c6f513099248bf452cc2d ---- - arch/x86/configs/gki_defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index a37fa09bd107..b3dad521ee8a 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -311,6 +311,7 @@ CONFIG_FS_ENCRYPTION=y - CONFIG_QUOTA=y - CONFIG_QFMT_V2=y - CONFIG_FUSE_FS=y -+CONFIG_OVERLAY_FS=y - CONFIG_MSDOS_FS=y - CONFIG_VFAT_FS=y - CONFIG_TMPFS=y diff --git a/patches/ANDROID-dm-bow-Add-dm-bow-feature.patch b/patches/ANDROID-dm-bow-Add-dm-bow-feature.patch deleted file mode 100644 index b56f8da9a8bf..000000000000 --- a/patches/ANDROID-dm-bow-Add-dm-bow-feature.patch +++ /dev/null @@ -1,1444 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Lawrence -Date: Tue, 23 Oct 2018 08:56:04 -0700 -Subject: ANDROID: dm-bow: Add dm-bow feature - -Based on https://www.redhat.com/archives/dm-devel/2019-March/msg00025.html - -Third version of dm-bow. Key changes: - -Free list added -Support for block sizes other than 4k -Handles writes during trim phase, and overlapping trims -Integer overflow error -Support trims even if underlying device doesn't -Numerous small bug fixes - -bow == backup on write - -USE CASE: - -dm-bow takes a snapshot of an existing file system before mounting. -The user may, before removing the device, commit the snapshot. -Alternatively the user may remove the device and then run a command -line utility to restore the device to its original state. - -dm-bow does not require an external device - -dm-bow efficiently uses all the available free space on the file system. - -IMPLEMENTATION: - -dm-bow can be in one of three states. - -In state one, the free blocks on the device are identified by issuing -an FSTRIM to the filesystem. - -In state two, any writes cause the overwritten data to be backup up -to the available free space. While in this state, the device can be -restored by unmounting the filesystem, removing the dm-bow device -and running a usermode tool over the underlying device. - -In state three, the changes are committed, dm-bow is in pass-through -mode and the drive can no longer be restored. - -It is planned to use this driver to enable restoration of a failed -update attempt on Android devices using ext4. - -Test: Can boot Android with userdata mounted on this device. Can commit -userdata after SUW has run. Can then reboot, make changes and roll back. - -Known issues: - -Mutex is held around entire flush operation, including lengthy I/O. Plan -is to convert to state machine with pending queues. - -Interaction with block encryption is unknown, especially with respect -to sector 0. - -Bug: 119769411 -Bug: 129280212 -Test: Dogfooded on Wahoo. - Ran under Cuttlefish, running VtsKernelBowTest & - VtsKernelCheckpointTest tests against 4.19, 4.14 & 4.9 kernels -Change-Id: Id70988bbd797ebe3e76fc175094388b423c8da8c -Signed-off-by: Paul Lawrence ---- - Documentation/device-mapper/dm-bow.txt | 99 ++ - drivers/md/Kconfig | 12 + - drivers/md/Makefile | 1 + - drivers/md/dm-bow.c | 1226 ++++++++++++++++++++++++ - 4 files changed, 1338 insertions(+) - create mode 100644 Documentation/device-mapper/dm-bow.txt - create mode 100644 drivers/md/dm-bow.c - -diff --git a/Documentation/device-mapper/dm-bow.txt b/Documentation/device-mapper/dm-bow.txt -new file mode 100644 -index 000000000000..e3fc4d22e0f4 ---- /dev/null -+++ b/Documentation/device-mapper/dm-bow.txt -@@ -0,0 +1,99 @@ -+dm_bow (backup on write) -+======================== -+ -+dm_bow is a device mapper driver that uses the free space on a device to back up -+data that is overwritten. The changes can then be committed by a simple state -+change, or rolled back by removing the dm_bow device and running a command line -+utility over the underlying device. -+ -+dm_bow has three states, set by writing ‘1’ or ‘2’ to /sys/block/dm-?/bow/state. -+It is only possible to go from state 0 (initial state) to state 1, and then from -+state 1 to state 2. -+ -+State 0: dm_bow collects all trims to the device and assumes that these mark -+free space on the overlying file system that can be safely used. Typically the -+mount code would create the dm_bow device, mount the file system, call the -+FITRIM ioctl on the file system then switch to state 1. These trims are not -+propagated to the underlying device. -+ -+State 1: All writes to the device cause the underlying data to be backed up to -+the free (trimmed) area as needed in such a way as they can be restored. -+However, the writes, with one exception, then happen exactly as they would -+without dm_bow, so the device is always in a good final state. The exception is -+that sector 0 is used to keep a log of the latest changes, both to indicate that -+we are in this state and to allow rollback. See below for all details. If there -+isn't enough free space, writes are failed with -ENOSPC. -+ -+State 2: The transition to state 2 triggers replacing the special sector 0 with -+the normal sector 0, and the freeing of all state information. dm_bow then -+becomes a pass-through driver, allowing the device to continue to be used with -+minimal performance impact. -+ -+Usage -+===== -+dm-bow takes one command line parameter, the name of the underlying device. -+ -+dm-bow will typically be used in the following way. dm-bow will be loaded with a -+suitable underlying device and the resultant device will be mounted. A file -+system trim will be issued via the FITRIM ioctl, then the device will be -+switched to state 1. The file system will now be used as normal. At some point, -+the changes can either be committed by switching to state 2, or rolled back by -+unmounting the file system, removing the dm-bow device and running the command -+line utility. Note that rebooting the device will be equivalent to unmounting -+and removing, but the command line utility must still be run -+ -+Details of operation in state 1 -+=============================== -+ -+dm_bow maintains a type for all sectors. A sector can be any of: -+ -+SECTOR0 -+SECTOR0_CURRENT -+UNCHANGED -+FREE -+CHANGED -+BACKUP -+ -+SECTOR0 is the first sector on the device, and is used to hold the log of -+changes. This is the one exception. -+ -+SECTOR0_CURRENT is a sector picked from the FREE sectors, and is where reads and -+writes from the true sector zero are redirected to. Note that like any backup -+sector, if the sector is written to directly, it must be moved again. -+ -+UNCHANGED means that the sector has not been changed since we entered state 1. -+Thus if it is written to or trimmed, the contents must first be backed up. -+ -+FREE means that the sector was trimmed in state 0 and has not yet been written -+to or used for backup. On being written to, a FREE sector is changed to CHANGED. -+ -+CHANGED means that the sector has been modified, and can be further modified -+without further backup. -+ -+BACKUP means that this is a free sector being used as a backup. On being written -+to, the contents must first be backed up again. -+ -+All backup operations are logged to the first sector. The log sector has the -+format: -+-------------------------------------------------------- -+| Magic | Count | Sequence | Log entry | Log entry | … -+-------------------------------------------------------- -+ -+Magic is a magic number. Count is the number of log entries. Sequence is 0 -+initially. A log entry is -+ -+----------------------------------- -+| Source | Dest | Size | Checksum | -+----------------------------------- -+ -+When SECTOR0 is full, the log sector is backed up and another empty log sector -+created with sequence number one higher. The first entry in any log entry with -+sequence > 0 therefore must be the log of the backing up of the previous log -+sector. Note that sequence is not strictly needed, but is a useful sanity check -+and potentially limits the time spent trying to restore a corrupted snapshot. -+ -+On entering state 1, dm_bow has a list of free sectors. All other sectors are -+unchanged. Sector0_current is selected from the free sectors and the contents of -+sector 0 are copied there. The sector 0 is backed up, which triggers the first -+log entry to be written. -+ -diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig -index a744ba61ad21..2bce42552769 100644 ---- a/drivers/md/Kconfig -+++ b/drivers/md/Kconfig -@@ -608,4 +608,16 @@ config DM_ZONED - - If unsure, say N. - -+config DM_BOW -+ tristate "Backup block device" -+ depends on BLK_DEV_DM -+ select DM_BUFIO -+ ---help--- -+ This device-mapper target takes a device and keeps a log of all -+ changes using free blocks identified by issuing a trim command. -+ This can then be restored by running a command line utility, -+ or committed by simply replacing the target. -+ -+ If unsure, say N. -+ - endif # MD -diff --git a/drivers/md/Makefile b/drivers/md/Makefile -index 356b32d6b158..a9a602dfc4a3 100644 ---- a/drivers/md/Makefile -+++ b/drivers/md/Makefile -@@ -71,6 +71,7 @@ obj-$(CONFIG_DM_LOG_WRITES) += dm-log-writes.o - obj-$(CONFIG_DM_INTEGRITY) += dm-integrity.o - obj-$(CONFIG_DM_ZONED) += dm-zoned.o - obj-$(CONFIG_DM_WRITECACHE) += dm-writecache.o -+obj-$(CONFIG_DM_BOW) += dm-bow.o - - ifeq ($(CONFIG_DM_INIT),y) - dm-mod-objs += dm-init.o -diff --git a/drivers/md/dm-bow.c b/drivers/md/dm-bow.c -new file mode 100644 -index 000000000000..0d176aa140df ---- /dev/null -+++ b/drivers/md/dm-bow.c -@@ -0,0 +1,1226 @@ -+/* -+ * Copyright (C) 2018 Google Limited. -+ * -+ * This file is released under the GPL. -+ */ -+ -+#include "dm.h" -+#include "dm-core.h" -+ -+#include -+#include -+#include -+ -+#define DM_MSG_PREFIX "bow" -+ -+struct log_entry { -+ u64 source; -+ u64 dest; -+ u32 size; -+ u32 checksum; -+} __packed; -+ -+struct log_sector { -+ u32 magic; -+ u16 header_version; -+ u16 header_size; -+ u32 block_size; -+ u32 count; -+ u32 sequence; -+ sector_t sector0; -+ struct log_entry entries[]; -+} __packed; -+ -+/* -+ * MAGIC is BOW in ascii -+ */ -+#define MAGIC 0x00574f42 -+#define HEADER_VERSION 0x0100 -+ -+/* -+ * A sorted set of ranges representing the state of the data on the device. -+ * Use an rb_tree for fast lookup of a given sector -+ * Consecutive ranges are always of different type - operations on this -+ * set must merge matching consecutive ranges. -+ * -+ * Top range is always of type TOP -+ */ -+struct bow_range { -+ struct rb_node node; -+ sector_t sector; -+ enum { -+ INVALID, /* Type not set */ -+ SECTOR0, /* First sector - holds log record */ -+ SECTOR0_CURRENT,/* Live contents of sector0 */ -+ UNCHANGED, /* Original contents */ -+ TRIMMED, /* Range has been trimmed */ -+ CHANGED, /* Range has been changed */ -+ BACKUP, /* Range is being used as a backup */ -+ TOP, /* Final range - sector is size of device */ -+ } type; -+ struct list_head trimmed_list; /* list of TRIMMED ranges */ -+}; -+ -+static const char * const readable_type[] = { -+ "Invalid", -+ "Sector0", -+ "Sector0_current", -+ "Unchanged", -+ "Free", -+ "Changed", -+ "Backup", -+ "Top", -+}; -+ -+enum state { -+ TRIM, -+ CHECKPOINT, -+ COMMITTED, -+}; -+ -+struct bow_context { -+ struct dm_dev *dev; -+ u32 block_size; -+ u32 block_shift; -+ struct workqueue_struct *workqueue; -+ struct dm_bufio_client *bufio; -+ struct mutex ranges_lock; /* Hold to access this struct and/or ranges */ -+ struct rb_root ranges; -+ struct dm_kobject_holder kobj_holder; /* for sysfs attributes */ -+ atomic_t state; /* One of the enum state values above */ -+ u64 trims_total; -+ struct log_sector *log_sector; -+ struct list_head trimmed_list; -+ bool forward_trims; -+}; -+ -+sector_t range_top(struct bow_range *br) -+{ -+ return container_of(rb_next(&br->node), struct bow_range, node) -+ ->sector; -+} -+ -+u64 range_size(struct bow_range *br) -+{ -+ return (range_top(br) - br->sector) * SECTOR_SIZE; -+} -+ -+static sector_t bvec_top(struct bvec_iter *bi_iter) -+{ -+ return bi_iter->bi_sector + bi_iter->bi_size / SECTOR_SIZE; -+} -+ -+/* -+ * Find the first range that overlaps with bi_iter -+ * bi_iter is set to the size of the overlapping sub-range -+ */ -+static struct bow_range *find_first_overlapping_range(struct rb_root *ranges, -+ struct bvec_iter *bi_iter) -+{ -+ struct rb_node *node = ranges->rb_node; -+ struct bow_range *br; -+ -+ while (node) { -+ br = container_of(node, struct bow_range, node); -+ -+ if (br->sector <= bi_iter->bi_sector -+ && bi_iter->bi_sector < range_top(br)) -+ break; -+ -+ if (bi_iter->bi_sector < br->sector) -+ node = node->rb_left; -+ else -+ node = node->rb_right; -+ } -+ -+ WARN_ON(!node); -+ if (!node) -+ return NULL; -+ -+ if (range_top(br) - bi_iter->bi_sector -+ < bi_iter->bi_size >> SECTOR_SHIFT) -+ bi_iter->bi_size = (range_top(br) - bi_iter->bi_sector) -+ << SECTOR_SHIFT; -+ -+ return br; -+} -+ -+void add_before(struct rb_root *ranges, struct bow_range *new_br, -+ struct bow_range *existing) -+{ -+ struct rb_node *parent = &(existing->node); -+ struct rb_node **link = &(parent->rb_left); -+ -+ while (*link) { -+ parent = *link; -+ link = &((*link)->rb_right); -+ } -+ -+ rb_link_node(&new_br->node, parent, link); -+ rb_insert_color(&new_br->node, ranges); -+} -+ -+/* -+ * Given a range br returned by find_first_overlapping_range, split br into a -+ * leading range, a range matching the bi_iter and a trailing range. -+ * Leading and trailing may end up size 0 and will then be deleted. The -+ * new range matching the bi_iter is then returned and should have its type -+ * and type specific fields populated. -+ * If bi_iter runs off the end of the range, bi_iter is truncated accordingly -+ */ -+static int split_range(struct bow_context *bc, struct bow_range **br, -+ struct bvec_iter *bi_iter) -+{ -+ struct bow_range *new_br; -+ -+ if (bi_iter->bi_sector < (*br)->sector) { -+ WARN_ON(true); -+ return BLK_STS_IOERR; -+ } -+ -+ if (bi_iter->bi_sector > (*br)->sector) { -+ struct bow_range *leading_br = -+ kzalloc(sizeof(*leading_br), GFP_KERNEL); -+ -+ if (!leading_br) -+ return BLK_STS_RESOURCE; -+ -+ *leading_br = **br; -+ if (leading_br->type == TRIMMED) -+ list_add(&leading_br->trimmed_list, &bc->trimmed_list); -+ -+ add_before(&bc->ranges, leading_br, *br); -+ (*br)->sector = bi_iter->bi_sector; -+ } -+ -+ if (bvec_top(bi_iter) >= range_top(*br)) { -+ bi_iter->bi_size = (range_top(*br) - (*br)->sector) -+ * SECTOR_SIZE; -+ return BLK_STS_OK; -+ } -+ -+ /* new_br will be the beginning, existing br will be the tail */ -+ new_br = kzalloc(sizeof(*new_br), GFP_KERNEL); -+ if (!new_br) -+ return BLK_STS_RESOURCE; -+ -+ new_br->sector = (*br)->sector; -+ (*br)->sector = bvec_top(bi_iter); -+ add_before(&bc->ranges, new_br, *br); -+ *br = new_br; -+ -+ return BLK_STS_OK; -+} -+ -+/* -+ * Sets type of a range. May merge range into surrounding ranges -+ * Since br may be invalidated, always sets br to NULL to prevent -+ * usage after this is called -+ */ -+static void set_type(struct bow_context *bc, struct bow_range **br, int type) -+{ -+ struct bow_range *prev = container_of(rb_prev(&(*br)->node), -+ struct bow_range, node); -+ struct bow_range *next = container_of(rb_next(&(*br)->node), -+ struct bow_range, node); -+ -+ if ((*br)->type == TRIMMED) { -+ bc->trims_total -= range_size(*br); -+ list_del(&(*br)->trimmed_list); -+ } -+ -+ if (type == TRIMMED) { -+ bc->trims_total += range_size(*br); -+ list_add(&(*br)->trimmed_list, &bc->trimmed_list); -+ } -+ -+ (*br)->type = type; -+ -+ if (next->type == type) { -+ if (type == TRIMMED) -+ list_del(&next->trimmed_list); -+ rb_erase(&next->node, &bc->ranges); -+ kfree(next); -+ } -+ -+ if (prev->type == type) { -+ if (type == TRIMMED) -+ list_del(&(*br)->trimmed_list); -+ rb_erase(&(*br)->node, &bc->ranges); -+ kfree(*br); -+ } -+ -+ *br = NULL; -+} -+ -+static struct bow_range *find_free_range(struct bow_context *bc) -+{ -+ if (list_empty(&bc->trimmed_list)) { -+ DMERR("Unable to find free space to back up to"); -+ return NULL; -+ } -+ -+ return list_first_entry(&bc->trimmed_list, struct bow_range, -+ trimmed_list); -+} -+ -+static sector_t sector_to_page(struct bow_context const *bc, sector_t sector) -+{ -+ WARN_ON(sector % (bc->block_size / SECTOR_SIZE) != 0); -+ return sector >> (bc->block_shift - SECTOR_SHIFT); -+} -+ -+static int copy_data(struct bow_context const *bc, -+ struct bow_range *source, struct bow_range *dest, -+ u32 *checksum) -+{ -+ int i; -+ -+ if (range_size(source) != range_size(dest)) { -+ WARN_ON(1); -+ return BLK_STS_IOERR; -+ } -+ -+ if (checksum) -+ *checksum = sector_to_page(bc, source->sector); -+ -+ for (i = 0; i < range_size(source) >> bc->block_shift; ++i) { -+ struct dm_buffer *read_buffer, *write_buffer; -+ u8 *read, *write; -+ sector_t page = sector_to_page(bc, source->sector) + i; -+ -+ read = dm_bufio_read(bc->bufio, page, &read_buffer); -+ if (IS_ERR(read)) { -+ DMERR("Cannot read page %lu", page); -+ return PTR_ERR(read); -+ } -+ -+ if (checksum) -+ *checksum = crc32(*checksum, read, bc->block_size); -+ -+ write = dm_bufio_new(bc->bufio, -+ sector_to_page(bc, dest->sector) + i, -+ &write_buffer); -+ if (IS_ERR(write)) { -+ DMERR("Cannot write sector"); -+ dm_bufio_release(read_buffer); -+ return PTR_ERR(write); -+ } -+ -+ memcpy(write, read, bc->block_size); -+ -+ dm_bufio_mark_buffer_dirty(write_buffer); -+ dm_bufio_release(write_buffer); -+ dm_bufio_release(read_buffer); -+ } -+ -+ dm_bufio_write_dirty_buffers(bc->bufio); -+ return BLK_STS_OK; -+} -+ -+/****** logging functions ******/ -+ -+static int add_log_entry(struct bow_context *bc, sector_t source, sector_t dest, -+ unsigned int size, u32 checksum); -+ -+static int backup_log_sector(struct bow_context *bc) -+{ -+ struct bow_range *first_br, *free_br; -+ struct bvec_iter bi_iter; -+ u32 checksum = 0; -+ int ret; -+ -+ first_br = container_of(rb_first(&bc->ranges), struct bow_range, node); -+ -+ if (first_br->type != SECTOR0) { -+ WARN_ON(1); -+ return BLK_STS_IOERR; -+ } -+ -+ if (range_size(first_br) != bc->block_size) { -+ WARN_ON(1); -+ return BLK_STS_IOERR; -+ } -+ -+ free_br = find_free_range(bc); -+ /* No space left - return this error to userspace */ -+ if (!free_br) -+ return BLK_STS_NOSPC; -+ bi_iter.bi_sector = free_br->sector; -+ bi_iter.bi_size = bc->block_size; -+ ret = split_range(bc, &free_br, &bi_iter); -+ if (ret) -+ return ret; -+ if (bi_iter.bi_size != bc->block_size) { -+ WARN_ON(1); -+ return BLK_STS_IOERR; -+ } -+ -+ ret = copy_data(bc, first_br, free_br, &checksum); -+ if (ret) -+ return ret; -+ -+ bc->log_sector->count = 0; -+ bc->log_sector->sequence++; -+ ret = add_log_entry(bc, first_br->sector, free_br->sector, -+ range_size(first_br), checksum); -+ if (ret) -+ return ret; -+ -+ set_type(bc, &free_br, BACKUP); -+ return BLK_STS_OK; -+} -+ -+static int add_log_entry(struct bow_context *bc, sector_t source, sector_t dest, -+ unsigned int size, u32 checksum) -+{ -+ struct dm_buffer *sector_buffer; -+ u8 *sector; -+ -+ if (sizeof(struct log_sector) -+ + sizeof(struct log_entry) * (bc->log_sector->count + 1) -+ > bc->block_size) { -+ int ret = backup_log_sector(bc); -+ -+ if (ret) -+ return ret; -+ } -+ -+ sector = dm_bufio_new(bc->bufio, 0, §or_buffer); -+ if (IS_ERR(sector)) { -+ DMERR("Cannot write boot sector"); -+ dm_bufio_release(sector_buffer); -+ return BLK_STS_NOSPC; -+ } -+ -+ bc->log_sector->entries[bc->log_sector->count].source = source; -+ bc->log_sector->entries[bc->log_sector->count].dest = dest; -+ bc->log_sector->entries[bc->log_sector->count].size = size; -+ bc->log_sector->entries[bc->log_sector->count].checksum = checksum; -+ bc->log_sector->count++; -+ -+ memcpy(sector, bc->log_sector, bc->block_size); -+ dm_bufio_mark_buffer_dirty(sector_buffer); -+ dm_bufio_release(sector_buffer); -+ dm_bufio_write_dirty_buffers(bc->bufio); -+ return BLK_STS_OK; -+} -+ -+static int prepare_log(struct bow_context *bc) -+{ -+ struct bow_range *free_br, *first_br; -+ struct bvec_iter bi_iter; -+ u32 checksum = 0; -+ int ret; -+ -+ /* Carve out first sector as log sector */ -+ first_br = container_of(rb_first(&bc->ranges), struct bow_range, node); -+ if (first_br->type != UNCHANGED) { -+ WARN_ON(1); -+ return BLK_STS_IOERR; -+ } -+ -+ if (range_size(first_br) < bc->block_size) { -+ WARN_ON(1); -+ return BLK_STS_IOERR; -+ } -+ bi_iter.bi_sector = 0; -+ bi_iter.bi_size = bc->block_size; -+ ret = split_range(bc, &first_br, &bi_iter); -+ if (ret) -+ return ret; -+ first_br->type = SECTOR0; -+ if (range_size(first_br) != bc->block_size) { -+ WARN_ON(1); -+ return BLK_STS_IOERR; -+ } -+ -+ /* Find free sector for active sector0 reads/writes */ -+ free_br = find_free_range(bc); -+ if (!free_br) -+ return BLK_STS_NOSPC; -+ bi_iter.bi_sector = free_br->sector; -+ bi_iter.bi_size = bc->block_size; -+ ret = split_range(bc, &free_br, &bi_iter); -+ if (ret) -+ return ret; -+ free_br->type = SECTOR0_CURRENT; -+ -+ /* Copy data */ -+ ret = copy_data(bc, first_br, free_br, NULL); -+ if (ret) -+ return ret; -+ -+ bc->log_sector->sector0 = free_br->sector; -+ -+ /* Find free sector to back up original sector zero */ -+ free_br = find_free_range(bc); -+ if (!free_br) -+ return BLK_STS_NOSPC; -+ bi_iter.bi_sector = free_br->sector; -+ bi_iter.bi_size = bc->block_size; -+ ret = split_range(bc, &free_br, &bi_iter); -+ if (ret) -+ return ret; -+ -+ /* Back up */ -+ ret = copy_data(bc, first_br, free_br, &checksum); -+ if (ret) -+ return ret; -+ -+ /* -+ * Set up our replacement boot sector - it will get written when we -+ * add the first log entry, which we do immediately -+ */ -+ bc->log_sector->magic = MAGIC; -+ bc->log_sector->header_version = HEADER_VERSION; -+ bc->log_sector->header_size = sizeof(*bc->log_sector); -+ bc->log_sector->block_size = bc->block_size; -+ bc->log_sector->count = 0; -+ bc->log_sector->sequence = 0; -+ -+ /* Add log entry */ -+ ret = add_log_entry(bc, first_br->sector, free_br->sector, -+ range_size(first_br), checksum); -+ if (ret) -+ return ret; -+ -+ set_type(bc, &free_br, BACKUP); -+ return BLK_STS_OK; -+} -+ -+static struct bow_range *find_sector0_current(struct bow_context *bc) -+{ -+ struct bvec_iter bi_iter; -+ -+ bi_iter.bi_sector = bc->log_sector->sector0; -+ bi_iter.bi_size = bc->block_size; -+ return find_first_overlapping_range(&bc->ranges, &bi_iter); -+} -+ -+/****** sysfs interface functions ******/ -+ -+static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, -+ char *buf) -+{ -+ struct bow_context *bc = container_of(kobj, struct bow_context, -+ kobj_holder.kobj); -+ -+ return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&bc->state)); -+} -+ -+static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct bow_context *bc = container_of(kobj, struct bow_context, -+ kobj_holder.kobj); -+ enum state state, original_state; -+ int ret; -+ -+ state = buf[0] - '0'; -+ if (state < TRIM || state > COMMITTED) { -+ DMERR("State value %d out of range", state); -+ return -EINVAL; -+ } -+ -+ mutex_lock(&bc->ranges_lock); -+ original_state = atomic_read(&bc->state); -+ if (state != original_state + 1) { -+ DMERR("Invalid state change from %d to %d", -+ original_state, state); -+ ret = -EINVAL; -+ goto bad; -+ } -+ -+ DMINFO("Switching to state %s", state == CHECKPOINT ? "Checkpoint" -+ : state == COMMITTED ? "Committed" : "Unknown"); -+ -+ if (state == CHECKPOINT) { -+ ret = prepare_log(bc); -+ if (ret) { -+ DMERR("Failed to switch to checkpoint state"); -+ goto bad; -+ } -+ } else if (state == COMMITTED) { -+ struct bow_range *br = find_sector0_current(bc); -+ struct bow_range *sector0_br = -+ container_of(rb_first(&bc->ranges), struct bow_range, -+ node); -+ -+ ret = copy_data(bc, br, sector0_br, 0); -+ if (ret) { -+ DMERR("Failed to switch to committed state"); -+ goto bad; -+ } -+ } -+ atomic_inc(&bc->state); -+ ret = count; -+ -+bad: -+ mutex_unlock(&bc->ranges_lock); -+ return ret; -+} -+ -+static ssize_t free_show(struct kobject *kobj, struct kobj_attribute *attr, -+ char *buf) -+{ -+ struct bow_context *bc = container_of(kobj, struct bow_context, -+ kobj_holder.kobj); -+ u64 trims_total; -+ -+ mutex_lock(&bc->ranges_lock); -+ trims_total = bc->trims_total; -+ mutex_unlock(&bc->ranges_lock); -+ -+ return scnprintf(buf, PAGE_SIZE, "%llu\n", trims_total); -+} -+ -+static struct kobj_attribute attr_state = __ATTR_RW(state); -+static struct kobj_attribute attr_free = __ATTR_RO(free); -+ -+static struct attribute *bow_attrs[] = { -+ &attr_state.attr, -+ &attr_free.attr, -+ NULL -+}; -+ -+static struct kobj_type bow_ktype = { -+ .sysfs_ops = &kobj_sysfs_ops, -+ .default_attrs = bow_attrs, -+ .release = dm_kobject_release -+}; -+ -+/****** constructor/destructor ******/ -+ -+static void dm_bow_dtr(struct dm_target *ti) -+{ -+ struct bow_context *bc = (struct bow_context *) ti->private; -+ struct kobject *kobj; -+ -+ while (rb_first(&bc->ranges)) { -+ struct bow_range *br = container_of(rb_first(&bc->ranges), -+ struct bow_range, node); -+ -+ rb_erase(&br->node, &bc->ranges); -+ kfree(br); -+ } -+ if (bc->workqueue) -+ destroy_workqueue(bc->workqueue); -+ if (bc->bufio) -+ dm_bufio_client_destroy(bc->bufio); -+ -+ kobj = &bc->kobj_holder.kobj; -+ if (kobj->state_initialized) { -+ kobject_put(kobj); -+ wait_for_completion(dm_get_completion_from_kobject(kobj)); -+ } -+ -+ kfree(bc->log_sector); -+ kfree(bc); -+} -+ -+static int dm_bow_ctr(struct dm_target *ti, unsigned int argc, char **argv) -+{ -+ struct bow_context *bc; -+ struct bow_range *br; -+ int ret; -+ struct mapped_device *md = dm_table_get_md(ti->table); -+ -+ if (argc != 1) { -+ ti->error = "Invalid argument count"; -+ return -EINVAL; -+ } -+ -+ bc = kzalloc(sizeof(*bc), GFP_KERNEL); -+ if (!bc) { -+ ti->error = "Cannot allocate bow context"; -+ return -ENOMEM; -+ } -+ -+ ti->num_flush_bios = 1; -+ ti->num_discard_bios = 1; -+ ti->num_write_same_bios = 1; -+ ti->private = bc; -+ -+ ret = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), -+ &bc->dev); -+ if (ret) { -+ ti->error = "Device lookup failed"; -+ goto bad; -+ } -+ -+ if (bc->dev->bdev->bd_queue->limits.max_discard_sectors == 0) { -+ bc->dev->bdev->bd_queue->limits.discard_granularity = 1 << 12; -+ bc->dev->bdev->bd_queue->limits.max_hw_discard_sectors = 1 << 15; -+ bc->dev->bdev->bd_queue->limits.max_discard_sectors = 1 << 15; -+ bc->forward_trims = false; -+ } else { -+ bc->forward_trims = true; -+ } -+ -+ bc->block_size = bc->dev->bdev->bd_queue->limits.logical_block_size; -+ bc->block_shift = ilog2(bc->block_size); -+ bc->log_sector = kzalloc(bc->block_size, GFP_KERNEL); -+ if (!bc->log_sector) { -+ ti->error = "Cannot allocate log sector"; -+ goto bad; -+ } -+ -+ init_completion(&bc->kobj_holder.completion); -+ ret = kobject_init_and_add(&bc->kobj_holder.kobj, &bow_ktype, -+ &disk_to_dev(dm_disk(md))->kobj, "%s", -+ "bow"); -+ if (ret) { -+ ti->error = "Cannot create sysfs node"; -+ goto bad; -+ } -+ -+ mutex_init(&bc->ranges_lock); -+ bc->ranges = RB_ROOT; -+ bc->bufio = dm_bufio_client_create(bc->dev->bdev, bc->block_size, 1, 0, -+ NULL, NULL); -+ if (IS_ERR(bc->bufio)) { -+ ti->error = "Cannot initialize dm-bufio"; -+ ret = PTR_ERR(bc->bufio); -+ bc->bufio = NULL; -+ goto bad; -+ } -+ -+ bc->workqueue = alloc_workqueue("dm-bow", -+ WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM -+ | WQ_UNBOUND, num_online_cpus()); -+ if (!bc->workqueue) { -+ ti->error = "Cannot allocate workqueue"; -+ ret = -ENOMEM; -+ goto bad; -+ } -+ -+ INIT_LIST_HEAD(&bc->trimmed_list); -+ -+ br = kzalloc(sizeof(*br), GFP_KERNEL); -+ if (!br) { -+ ti->error = "Cannot allocate ranges"; -+ ret = -ENOMEM; -+ goto bad; -+ } -+ -+ br->sector = ti->len; -+ br->type = TOP; -+ rb_link_node(&br->node, NULL, &bc->ranges.rb_node); -+ rb_insert_color(&br->node, &bc->ranges); -+ -+ br = kzalloc(sizeof(*br), GFP_KERNEL); -+ if (!br) { -+ ti->error = "Cannot allocate ranges"; -+ ret = -ENOMEM; -+ goto bad; -+ } -+ -+ br->sector = 0; -+ br->type = UNCHANGED; -+ rb_link_node(&br->node, bc->ranges.rb_node, -+ &bc->ranges.rb_node->rb_left); -+ rb_insert_color(&br->node, &bc->ranges); -+ -+ ti->discards_supported = true; -+ -+ return 0; -+ -+bad: -+ dm_bow_dtr(ti); -+ return ret; -+} -+ -+/****** Handle writes ******/ -+ -+static int prepare_unchanged_range(struct bow_context *bc, struct bow_range *br, -+ struct bvec_iter *bi_iter, -+ bool record_checksum) -+{ -+ struct bow_range *backup_br; -+ struct bvec_iter backup_bi; -+ sector_t log_source, log_dest; -+ unsigned int log_size; -+ u32 checksum = 0; -+ int ret; -+ int original_type; -+ sector_t sector0; -+ -+ /* Find a free range */ -+ backup_br = find_free_range(bc); -+ if (!backup_br) -+ return BLK_STS_NOSPC; -+ -+ /* Carve out a backup range. This may be smaller than the br given */ -+ backup_bi.bi_sector = backup_br->sector; -+ backup_bi.bi_size = min(range_size(backup_br), (u64) bi_iter->bi_size); -+ ret = split_range(bc, &backup_br, &backup_bi); -+ if (ret) -+ return ret; -+ -+ /* -+ * Carve out a changed range. This will not be smaller than the backup -+ * br since the backup br is smaller than the source range and iterator -+ */ -+ bi_iter->bi_size = backup_bi.bi_size; -+ ret = split_range(bc, &br, bi_iter); -+ if (ret) -+ return ret; -+ if (range_size(br) != range_size(backup_br)) { -+ WARN_ON(1); -+ return BLK_STS_IOERR; -+ } -+ -+ -+ /* Copy data over */ -+ ret = copy_data(bc, br, backup_br, record_checksum ? &checksum : NULL); -+ if (ret) -+ return ret; -+ -+ /* Add an entry to the log */ -+ log_source = br->sector; -+ log_dest = backup_br->sector; -+ log_size = range_size(br); -+ -+ /* -+ * Set the types. Note that since set_type also amalgamates ranges -+ * we have to set both sectors to their final type before calling -+ * set_type on either -+ */ -+ original_type = br->type; -+ sector0 = backup_br->sector; -+ if (backup_br->type == TRIMMED) -+ list_del(&backup_br->trimmed_list); -+ backup_br->type = br->type == SECTOR0_CURRENT ? SECTOR0_CURRENT -+ : BACKUP; -+ br->type = CHANGED; -+ set_type(bc, &backup_br, backup_br->type); -+ -+ /* -+ * Add the log entry after marking the backup sector, since adding a log -+ * can cause another backup -+ */ -+ ret = add_log_entry(bc, log_source, log_dest, log_size, checksum); -+ if (ret) { -+ br->type = original_type; -+ return ret; -+ } -+ -+ /* Now it is safe to mark this backup successful */ -+ if (original_type == SECTOR0_CURRENT) -+ bc->log_sector->sector0 = sector0; -+ -+ set_type(bc, &br, br->type); -+ return ret; -+} -+ -+static int prepare_free_range(struct bow_context *bc, struct bow_range *br, -+ struct bvec_iter *bi_iter) -+{ -+ int ret; -+ -+ ret = split_range(bc, &br, bi_iter); -+ if (ret) -+ return ret; -+ set_type(bc, &br, CHANGED); -+ return BLK_STS_OK; -+} -+ -+static int prepare_changed_range(struct bow_context *bc, struct bow_range *br, -+ struct bvec_iter *bi_iter) -+{ -+ /* Nothing to do ... */ -+ return BLK_STS_OK; -+} -+ -+static int prepare_one_range(struct bow_context *bc, -+ struct bvec_iter *bi_iter) -+{ -+ struct bow_range *br = find_first_overlapping_range(&bc->ranges, -+ bi_iter); -+ switch (br->type) { -+ case CHANGED: -+ return prepare_changed_range(bc, br, bi_iter); -+ -+ case TRIMMED: -+ return prepare_free_range(bc, br, bi_iter); -+ -+ case UNCHANGED: -+ case BACKUP: -+ return prepare_unchanged_range(bc, br, bi_iter, true); -+ -+ /* -+ * We cannot track the checksum for the active sector0, since it -+ * may change at any point. -+ */ -+ case SECTOR0_CURRENT: -+ return prepare_unchanged_range(bc, br, bi_iter, false); -+ -+ case SECTOR0: /* Handled in the dm_bow_map */ -+ case TOP: /* Illegal - top is off the end of the device */ -+ default: -+ WARN_ON(1); -+ return BLK_STS_IOERR; -+ } -+} -+ -+struct write_work { -+ struct work_struct work; -+ struct bow_context *bc; -+ struct bio *bio; -+}; -+ -+static void bow_write(struct work_struct *work) -+{ -+ struct write_work *ww = container_of(work, struct write_work, work); -+ struct bow_context *bc = ww->bc; -+ struct bio *bio = ww->bio; -+ struct bvec_iter bi_iter = bio->bi_iter; -+ int ret = BLK_STS_OK; -+ -+ kfree(ww); -+ -+ mutex_lock(&bc->ranges_lock); -+ do { -+ ret = prepare_one_range(bc, &bi_iter); -+ bi_iter.bi_sector += bi_iter.bi_size / SECTOR_SIZE; -+ bi_iter.bi_size = bio->bi_iter.bi_size -+ - (bi_iter.bi_sector - bio->bi_iter.bi_sector) -+ * SECTOR_SIZE; -+ } while (!ret && bi_iter.bi_size); -+ -+ mutex_unlock(&bc->ranges_lock); -+ -+ if (!ret) { -+ bio_set_dev(bio, bc->dev->bdev); -+ submit_bio(bio); -+ } else { -+ DMERR("Write failure with error %d", -ret); -+ bio->bi_status = ret; -+ bio_endio(bio); -+ } -+} -+ -+static int queue_write(struct bow_context *bc, struct bio *bio) -+{ -+ struct write_work *ww = kmalloc(sizeof(*ww), GFP_NOIO | __GFP_NORETRY -+ | __GFP_NOMEMALLOC | __GFP_NOWARN); -+ if (!ww) { -+ DMERR("Failed to allocate write_work"); -+ return -ENOMEM; -+ } -+ -+ INIT_WORK(&ww->work, bow_write); -+ ww->bc = bc; -+ ww->bio = bio; -+ queue_work(bc->workqueue, &ww->work); -+ return DM_MAPIO_SUBMITTED; -+} -+ -+static int handle_sector0(struct bow_context *bc, struct bio *bio) -+{ -+ int ret = DM_MAPIO_REMAPPED; -+ -+ if (bio->bi_iter.bi_size > bc->block_size) { -+ struct bio * split = bio_split(bio, -+ bc->block_size >> SECTOR_SHIFT, -+ GFP_NOIO, -+ &fs_bio_set); -+ if (!split) { -+ DMERR("Failed to split bio"); -+ bio->bi_status = BLK_STS_RESOURCE; -+ bio_endio(bio); -+ return DM_MAPIO_SUBMITTED; -+ } -+ -+ bio_chain(split, bio); -+ split->bi_iter.bi_sector = bc->log_sector->sector0; -+ bio_set_dev(split, bc->dev->bdev); -+ submit_bio(split); -+ -+ if (bio_data_dir(bio) == WRITE) -+ ret = queue_write(bc, bio); -+ } else { -+ bio->bi_iter.bi_sector = bc->log_sector->sector0; -+ } -+ -+ return ret; -+} -+ -+static int add_trim(struct bow_context *bc, struct bio *bio) -+{ -+ struct bow_range *br; -+ struct bvec_iter bi_iter = bio->bi_iter; -+ -+ DMDEBUG("add_trim: %lu, %u", -+ bio->bi_iter.bi_sector, bio->bi_iter.bi_size); -+ -+ do { -+ br = find_first_overlapping_range(&bc->ranges, &bi_iter); -+ -+ switch (br->type) { -+ case UNCHANGED: -+ if (!split_range(bc, &br, &bi_iter)) -+ set_type(bc, &br, TRIMMED); -+ break; -+ -+ case TRIMMED: -+ /* Nothing to do */ -+ break; -+ -+ default: -+ /* No other case is legal in TRIM state */ -+ WARN_ON(true); -+ break; -+ } -+ -+ bi_iter.bi_sector += bi_iter.bi_size / SECTOR_SIZE; -+ bi_iter.bi_size = bio->bi_iter.bi_size -+ - (bi_iter.bi_sector - bio->bi_iter.bi_sector) -+ * SECTOR_SIZE; -+ -+ } while (bi_iter.bi_size); -+ -+ bio_endio(bio); -+ return DM_MAPIO_SUBMITTED; -+} -+ -+static int remove_trim(struct bow_context *bc, struct bio *bio) -+{ -+ struct bow_range *br; -+ struct bvec_iter bi_iter = bio->bi_iter; -+ -+ DMDEBUG("remove_trim: %lu, %u", -+ bio->bi_iter.bi_sector, bio->bi_iter.bi_size); -+ -+ do { -+ br = find_first_overlapping_range(&bc->ranges, &bi_iter); -+ -+ switch (br->type) { -+ case UNCHANGED: -+ /* Nothing to do */ -+ break; -+ -+ case TRIMMED: -+ if (!split_range(bc, &br, &bi_iter)) -+ set_type(bc, &br, UNCHANGED); -+ break; -+ -+ default: -+ /* No other case is legal in TRIM state */ -+ WARN_ON(true); -+ break; -+ } -+ -+ bi_iter.bi_sector += bi_iter.bi_size / SECTOR_SIZE; -+ bi_iter.bi_size = bio->bi_iter.bi_size -+ - (bi_iter.bi_sector - bio->bi_iter.bi_sector) -+ * SECTOR_SIZE; -+ -+ } while (bi_iter.bi_size); -+ -+ return DM_MAPIO_REMAPPED; -+} -+ -+int remap_unless_illegal_trim(struct bow_context *bc, struct bio *bio) -+{ -+ if (!bc->forward_trims && bio_op(bio) == REQ_OP_DISCARD) { -+ bio->bi_status = BLK_STS_NOTSUPP; -+ bio_endio(bio); -+ return DM_MAPIO_SUBMITTED; -+ } else { -+ bio_set_dev(bio, bc->dev->bdev); -+ return DM_MAPIO_REMAPPED; -+ } -+} -+ -+/****** dm interface ******/ -+ -+static int dm_bow_map(struct dm_target *ti, struct bio *bio) -+{ -+ int ret = DM_MAPIO_REMAPPED; -+ struct bow_context *bc = ti->private; -+ -+ if (likely(bc->state.counter == COMMITTED)) -+ return remap_unless_illegal_trim(bc, bio); -+ -+ if (bio_data_dir(bio) == READ && bio->bi_iter.bi_sector != 0) -+ return remap_unless_illegal_trim(bc, bio); -+ -+ if (atomic_read(&bc->state) != COMMITTED) { -+ enum state state; -+ -+ mutex_lock(&bc->ranges_lock); -+ state = atomic_read(&bc->state); -+ if (state == TRIM) { -+ if (bio_op(bio) == REQ_OP_DISCARD) -+ ret = add_trim(bc, bio); -+ else if (bio_data_dir(bio) == WRITE) -+ ret = remove_trim(bc, bio); -+ else -+ /* pass-through */; -+ } else if (state == CHECKPOINT) { -+ if (bio->bi_iter.bi_sector == 0) -+ ret = handle_sector0(bc, bio); -+ else if (bio_data_dir(bio) == WRITE) -+ ret = queue_write(bc, bio); -+ else -+ /* pass-through */; -+ } else { -+ /* pass-through */ -+ } -+ mutex_unlock(&bc->ranges_lock); -+ } -+ -+ if (ret == DM_MAPIO_REMAPPED) -+ return remap_unless_illegal_trim(bc, bio); -+ -+ return ret; -+} -+ -+static void dm_bow_tablestatus(struct dm_target *ti, char *result, -+ unsigned int maxlen) -+{ -+ char *end = result + maxlen; -+ struct bow_context *bc = ti->private; -+ struct rb_node *i; -+ int trimmed_list_length = 0; -+ int trimmed_range_count = 0; -+ struct bow_range *br; -+ -+ if (maxlen == 0) -+ return; -+ result[0] = 0; -+ -+ list_for_each_entry(br, &bc->trimmed_list, trimmed_list) -+ if (br->type == TRIMMED) { -+ ++trimmed_list_length; -+ } else { -+ scnprintf(result, end - result, -+ "ERROR: non-trimmed entry in trimmed_list"); -+ return; -+ } -+ -+ if (!rb_first(&bc->ranges)) { -+ scnprintf(result, end - result, "ERROR: Empty ranges"); -+ return; -+ } -+ -+ if (container_of(rb_first(&bc->ranges), struct bow_range, node) -+ ->sector) { -+ scnprintf(result, end - result, -+ "ERROR: First range does not start at sector 0"); -+ return; -+ } -+ -+ for (i = rb_first(&bc->ranges); i; i = rb_next(i)) { -+ struct bow_range *br = container_of(i, struct bow_range, node); -+ -+ result += scnprintf(result, end - result, "%s: %lu", -+ readable_type[br->type], br->sector); -+ if (result >= end) -+ return; -+ -+ result += scnprintf(result, end - result, "\n"); -+ if (result >= end) -+ return; -+ -+ if (br->type == TRIMMED) -+ ++trimmed_range_count; -+ -+ if (br->type == TOP) { -+ if (br->sector != ti->len) { -+ scnprintf(result, end - result, -+ "\nERROR: Top sector is incorrect"); -+ } -+ -+ if (&br->node != rb_last(&bc->ranges)) { -+ scnprintf(result, end - result, -+ "\nERROR: Top sector is not last"); -+ } -+ -+ break; -+ } -+ -+ if (!rb_next(i)) { -+ scnprintf(result, end - result, -+ "\nERROR: Last range not of type TOP"); -+ return; -+ } -+ -+ if (br->sector > range_top(br)) { -+ scnprintf(result, end - result, -+ "\nERROR: sectors out of order"); -+ return; -+ } -+ } -+ -+ if (trimmed_range_count != trimmed_list_length) -+ scnprintf(result, end - result, -+ "\nERROR: not all trimmed ranges in trimmed list"); -+} -+ -+static void dm_bow_status(struct dm_target *ti, status_type_t type, -+ unsigned int status_flags, char *result, -+ unsigned int maxlen) -+{ -+ switch (type) { -+ case STATUSTYPE_INFO: -+ if (maxlen) -+ result[0] = 0; -+ break; -+ -+ case STATUSTYPE_TABLE: -+ dm_bow_tablestatus(ti, result, maxlen); -+ break; -+ } -+} -+ -+int dm_bow_prepare_ioctl(struct dm_target *ti, struct block_device **bdev) -+{ -+ struct bow_context *bc = ti->private; -+ struct dm_dev *dev = bc->dev; -+ -+ *bdev = dev->bdev; -+ /* Only pass ioctls through if the device sizes match exactly. */ -+ return ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT; -+} -+ -+static int dm_bow_iterate_devices(struct dm_target *ti, -+ iterate_devices_callout_fn fn, void *data) -+{ -+ struct bow_context *bc = ti->private; -+ -+ return fn(ti, bc->dev, 0, ti->len, data); -+} -+ -+static struct target_type bow_target = { -+ .name = "bow", -+ .version = {1, 1, 1}, -+ .module = THIS_MODULE, -+ .ctr = dm_bow_ctr, -+ .dtr = dm_bow_dtr, -+ .map = dm_bow_map, -+ .status = dm_bow_status, -+ .prepare_ioctl = dm_bow_prepare_ioctl, -+ .iterate_devices = dm_bow_iterate_devices, -+}; -+ -+int __init dm_bow_init(void) -+{ -+ int r = dm_register_target(&bow_target); -+ -+ if (r < 0) -+ DMERR("registering bow failed %d", r); -+ return r; -+} -+ -+void dm_bow_exit(void) -+{ -+ dm_unregister_target(&bow_target); -+} -+ -+MODULE_LICENSE("GPL"); -+ -+module_init(dm_bow_init); -+module_exit(dm_bow_exit); diff --git a/patches/ANDROID-dm-bow-Fix-32-bit-compile-errors.patch b/patches/ANDROID-dm-bow-Fix-32-bit-compile-errors.patch deleted file mode 100644 index 9f38d14bf59e..000000000000 --- a/patches/ANDROID-dm-bow-Fix-32-bit-compile-errors.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paul Lawrence -Date: Tue, 26 Mar 2019 09:05:55 -0700 -Subject: ANDROID: dm-bow: Fix 32 bit compile errors - -See https://www.kernel.org/doc/html/v4.17/core-api/printk-formats.html - -Also 64-bit modulus not defined on 32-bit architectures - -Test: i386_defconfig and x86_64_cuttlefish_defconfig compile -Change-Id: I57b9372e12e97b9a18232191b525e7601bc57a24 -Signed-off-by: Paul Lawrence ---- - drivers/md/dm-bow.c | 21 +++++++++++++-------- - 1 file changed, 13 insertions(+), 8 deletions(-) - -diff --git a/drivers/md/dm-bow.c b/drivers/md/dm-bow.c -index 0d176aa140df..9323c7c8580d 100644 ---- a/drivers/md/dm-bow.c -+++ b/drivers/md/dm-bow.c -@@ -266,7 +266,8 @@ static struct bow_range *find_free_range(struct bow_context *bc) - - static sector_t sector_to_page(struct bow_context const *bc, sector_t sector) - { -- WARN_ON(sector % (bc->block_size / SECTOR_SIZE) != 0); -+ WARN_ON((sector & (((sector_t)1 << (bc->block_shift - SECTOR_SHIFT)) - 1)) -+ != 0); - return sector >> (bc->block_shift - SECTOR_SHIFT); - } - -@@ -291,7 +292,8 @@ static int copy_data(struct bow_context const *bc, - - read = dm_bufio_read(bc->bufio, page, &read_buffer); - if (IS_ERR(read)) { -- DMERR("Cannot read page %lu", page); -+ DMERR("Cannot read page %llu", -+ (unsigned long long)page); - return PTR_ERR(read); - } - -@@ -952,8 +954,9 @@ static int add_trim(struct bow_context *bc, struct bio *bio) - struct bow_range *br; - struct bvec_iter bi_iter = bio->bi_iter; - -- DMDEBUG("add_trim: %lu, %u", -- bio->bi_iter.bi_sector, bio->bi_iter.bi_size); -+ DMDEBUG("add_trim: %llu, %u", -+ (unsigned long long)bio->bi_iter.bi_sector, -+ bio->bi_iter.bi_size); - - do { - br = find_first_overlapping_range(&bc->ranges, &bi_iter); -@@ -990,8 +993,9 @@ static int remove_trim(struct bow_context *bc, struct bio *bio) - struct bow_range *br; - struct bvec_iter bi_iter = bio->bi_iter; - -- DMDEBUG("remove_trim: %lu, %u", -- bio->bi_iter.bi_sector, bio->bi_iter.bi_size); -+ DMDEBUG("remove_trim: %llu, %u", -+ (unsigned long long)bio->bi_iter.bi_sector, -+ bio->bi_iter.bi_size); - - do { - br = find_first_overlapping_range(&bc->ranges, &bi_iter); -@@ -1116,8 +1120,9 @@ static void dm_bow_tablestatus(struct dm_target *ti, char *result, - for (i = rb_first(&bc->ranges); i; i = rb_next(i)) { - struct bow_range *br = container_of(i, struct bow_range, node); - -- result += scnprintf(result, end - result, "%s: %lu", -- readable_type[br->type], br->sector); -+ result += scnprintf(result, end - result, "%s: %llu", -+ readable_type[br->type], -+ (unsigned long long)br->sector); - if (result >= end) - return; - diff --git a/patches/ANDROID-dma-buf-Add-support-for-mapping-buffers-with-DMA-attributes.patch b/patches/ANDROID-dma-buf-Add-support-for-mapping-buffers-with-DMA-attributes.patch deleted file mode 100644 index e6a9bcfbd24e..000000000000 --- a/patches/ANDROID-dma-buf-Add-support-for-mapping-buffers-with-DMA-attributes.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "Isaac J. Manjarres" -Date: Wed, 19 Jun 2019 15:37:13 -0700 -Subject: ANDROID: dma-buf: Add support for mapping buffers with DMA attributes - -When mapping the memory represented by a dma-buf into a device's -address space, it might be desireable to map the memory with -certain DMA attributes. Thus, introduce the dma_mapping_attrs -field in the dma_buf_attachment structure so that when -the memory is mapped with dma_buf_map_attachment, it is mapped -with the desired DMA attributes. - -Bug: 133508579 -Test: ion-unit-tests -Change-Id: Ib2e5bafdc02ae31a58ce96a82d77cc508dd71bd4 -Signed-off-by: Isaac J. Manjarres -Signed-off-by: Sandeep Patil ---- - include/linux/dma-buf.h | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h -index b1457e6b76d8..0458da673ec5 100644 ---- a/include/linux/dma-buf.h -+++ b/include/linux/dma-buf.h -@@ -384,6 +384,8 @@ struct dma_buf { - * @sgt: cached mapping. - * @dir: direction of cached mapping. - * @priv: exporter specific attachment data. -+ * @dma_map_attrs: DMA attributes to be used when the exporter maps the buffer -+ * through dma_buf_map_attachment. - * - * This structure holds the attachment information between the dma_buf buffer - * and its user device(s). The list contains one attachment struct per device -@@ -401,6 +403,7 @@ struct dma_buf_attachment { - struct sg_table *sgt; - enum dma_data_direction dir; - void *priv; -+ unsigned long dma_map_attrs; - }; - - /** diff --git a/patches/ANDROID-dma-buf-Add-support-for-partial-cache-maintenance.patch b/patches/ANDROID-dma-buf-Add-support-for-partial-cache-maintenance.patch deleted file mode 100644 index fa949dfd435e..000000000000 --- a/patches/ANDROID-dma-buf-Add-support-for-partial-cache-maintenance.patch +++ /dev/null @@ -1,170 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "Isaac J. Manjarres" -Date: Wed, 19 Jun 2019 15:37:11 -0700 -Subject: ANDROID: dma-buf: Add support for partial cache maintenance - -In order to improve performance, allow dma-buf clients to -apply cache maintenance to only a subset of a dma-buf. - -Kernel clients will be able to use the dma_buf_begin_cpu_access_partial -and dma_buf_end_cpu_access_partial functions to only apply cache -maintenance to a range within the dma-buf. - -Bug: 133508579 -Test: ion-unit-tests -Change-Id: Icce61fc21b1542f5248daea34f713184449a62c3 -Signed-off-by: Isaac J. Manjarres -Signed-off-by: Sandeep Patil ---- - drivers/dma-buf/dma-buf.c | 40 +++++++++++++++++++++++++ - include/linux/dma-buf.h | 63 +++++++++++++++++++++++++++++++++++++++ - 2 files changed, 103 insertions(+) - -diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c -index 433d91d710e4..532a854be1b3 100644 ---- a/drivers/dma-buf/dma-buf.c -+++ b/drivers/dma-buf/dma-buf.c -@@ -957,6 +957,30 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, - } - EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access); - -+int dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf, -+ enum dma_data_direction direction, -+ unsigned int offset, unsigned int len) -+{ -+ int ret = 0; -+ -+ if (WARN_ON(!dmabuf)) -+ return -EINVAL; -+ -+ if (dmabuf->ops->begin_cpu_access_partial) -+ ret = dmabuf->ops->begin_cpu_access_partial(dmabuf, direction, -+ offset, len); -+ -+ /* Ensure that all fences are waited upon - but we first allow -+ * the native handler the chance to do so more efficiently if it -+ * chooses. A double invocation here will be reasonably cheap no-op. -+ */ -+ if (ret == 0) -+ ret = __dma_buf_begin_cpu_access(dmabuf, direction); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access_partial); -+ - /** - * dma_buf_end_cpu_access - Must be called after accessing a dma_buf from the - * cpu in the kernel context. Calls end_cpu_access to allow exporter-specific -@@ -983,6 +1007,22 @@ int dma_buf_end_cpu_access(struct dma_buf *dmabuf, - } - EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access); - -+int dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf, -+ enum dma_data_direction direction, -+ unsigned int offset, unsigned int len) -+{ -+ int ret = 0; -+ -+ WARN_ON(!dmabuf); -+ -+ if (dmabuf->ops->end_cpu_access_partial) -+ ret = dmabuf->ops->end_cpu_access_partial(dmabuf, direction, -+ offset, len); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access_partial); -+ - /** - * dma_buf_kmap - Map a page of the buffer object into kernel address space. The - * same restrictions as for kmap and friends apply. -diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h -index ec212cb27fdc..b1457e6b76d8 100644 ---- a/include/linux/dma-buf.h -+++ b/include/linux/dma-buf.h -@@ -178,6 +178,41 @@ struct dma_buf_ops { - */ - int (*begin_cpu_access)(struct dma_buf *, enum dma_data_direction); - -+ /** -+ * @begin_cpu_access_partial: -+ * -+ * This is called from dma_buf_begin_cpu_access_partial() and allows the -+ * exporter to ensure that the memory specified in the range is -+ * available for cpu access - the exporter might need to allocate or -+ * swap-in and pin the backing storage. -+ * The exporter also needs to ensure that cpu access is -+ * coherent for the access direction. The direction can be used by the -+ * exporter to optimize the cache flushing, i.e. access with a different -+ * direction (read instead of write) might return stale or even bogus -+ * data (e.g. when the exporter needs to copy the data to temporary -+ * storage). -+ * -+ * This callback is optional. -+ * -+ * FIXME: This is both called through the DMA_BUF_IOCTL_SYNC command -+ * from userspace (where storage shouldn't be pinned to avoid handing -+ * de-factor mlock rights to userspace) and for the kernel-internal -+ * users of the various kmap interfaces, where the backing storage must -+ * be pinned to guarantee that the atomic kmap calls can succeed. Since -+ * there's no in-kernel users of the kmap interfaces yet this isn't a -+ * real problem. -+ * -+ * Returns: -+ * -+ * 0 on success or a negative error code on failure. This can for -+ * example fail when the backing storage can't be allocated. Can also -+ * return -ERESTARTSYS or -EINTR when the call has been interrupted and -+ * needs to be restarted. -+ */ -+ int (*begin_cpu_access_partial)(struct dma_buf *dmabuf, -+ enum dma_data_direction, -+ unsigned int offset, unsigned int len); -+ - /** - * @end_cpu_access: - * -@@ -197,6 +232,28 @@ struct dma_buf_ops { - */ - int (*end_cpu_access)(struct dma_buf *, enum dma_data_direction); - -+ /** -+ * @end_cpu_access_partial: -+ * -+ * This is called from dma_buf_end_cpu_access_partial() when the -+ * importer is done accessing the CPU. The exporter can use to limit -+ * cache flushing to only the range specefied and to unpin any -+ * resources pinned in @begin_cpu_access_umapped. -+ * The result of any dma_buf kmap calls after end_cpu_access_partial is -+ * undefined. -+ * -+ * This callback is optional. -+ * -+ * Returns: -+ * -+ * 0 on success or a negative error code on failure. Can return -+ * -ERESTARTSYS or -EINTR when the call has been interrupted and needs -+ * to be restarted. -+ */ -+ int (*end_cpu_access_partial)(struct dma_buf *dmabuf, -+ enum dma_data_direction, -+ unsigned int offset, unsigned int len); -+ - /** - * @mmap: - * -@@ -411,8 +468,14 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *, - enum dma_data_direction); - int dma_buf_begin_cpu_access(struct dma_buf *dma_buf, - enum dma_data_direction dir); -+int dma_buf_begin_cpu_access_partial(struct dma_buf *dma_buf, -+ enum dma_data_direction dir, -+ unsigned int offset, unsigned int len); - int dma_buf_end_cpu_access(struct dma_buf *dma_buf, - enum dma_data_direction dir); -+int dma_buf_end_cpu_access_partial(struct dma_buf *dma_buf, -+ enum dma_data_direction dir, -+ unsigned int offset, unsigned int len); - void *dma_buf_kmap(struct dma_buf *, unsigned long); - void dma_buf_kunmap(struct dma_buf *, unsigned long, void *); - diff --git a/patches/ANDROID-dma-buf-Add-support-to-get-flags-associated-with-a-buffer.patch b/patches/ANDROID-dma-buf-Add-support-to-get-flags-associated-with-a-buffer.patch deleted file mode 100644 index 5f2b3d17985c..000000000000 --- a/patches/ANDROID-dma-buf-Add-support-to-get-flags-associated-with-a-buffer.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "Isaac J. Manjarres" -Date: Wed, 19 Jun 2019 15:37:12 -0700 -Subject: ANDROID: dma-buf: Add support to get flags associated with a buffer - -Allow kernel clients to get the flags associated with a buffer -that is wrapped by a dma-buf. This information can be used to -communicate the type of memory associated with the -buffer(e.g. uncached vs cached memory). - -Bug: 133508579 -Test: ion-unit-tests -Change-Id: I82eab8beb738b258616c22a01080615d7ffb6ad5 -Signed-off-by: Isaac J. Manjarres -Signed-off-by: Sandeep Patil ---- - drivers/dma-buf/dma-buf.c | 14 ++++++++++++++ - include/linux/dma-buf.h | 15 +++++++++++++++ - 2 files changed, 29 insertions(+) - -diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c -index 532a854be1b3..59f6a39120fd 100644 ---- a/drivers/dma-buf/dma-buf.c -+++ b/drivers/dma-buf/dma-buf.c -@@ -1188,6 +1188,20 @@ void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) - } - EXPORT_SYMBOL_GPL(dma_buf_vunmap); - -+int dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags) -+{ -+ int ret = 0; -+ -+ if (WARN_ON(!dmabuf) || !flags) -+ return -EINVAL; -+ -+ if (dmabuf->ops->get_flags) -+ ret = dmabuf->ops->get_flags(dmabuf, flags); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(dma_buf_get_flags); -+ - #ifdef CONFIG_DEBUG_FS - static int dma_buf_debug_show(struct seq_file *s, void *unused) - { -diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h -index 0458da673ec5..f26b4a8212d0 100644 ---- a/include/linux/dma-buf.h -+++ b/include/linux/dma-buf.h -@@ -318,6 +318,20 @@ struct dma_buf_ops { - - void *(*vmap)(struct dma_buf *); - void (*vunmap)(struct dma_buf *, void *vaddr); -+ -+ /** -+ * @get_flags: -+ * -+ * This is called by dma_buf_get_flags and is used to get the buffer's -+ * flags. -+ * This callback is optional. -+ * -+ * Returns: -+ * -+ * 0 on success or a negative error code on failure. On success flags -+ * will be populated with the buffer's flags. -+ */ -+ int (*get_flags)(struct dma_buf *dmabuf, unsigned long *flags); - }; - - /** -@@ -486,4 +500,5 @@ int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *, - unsigned long); - void *dma_buf_vmap(struct dma_buf *); - void dma_buf_vunmap(struct dma_buf *, void *vaddr); -+int dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags); - #endif /* __DMA_BUF_H__ */ diff --git a/patches/ANDROID-first-pass-cuttlefish-GKI-modularization.patch b/patches/ANDROID-first-pass-cuttlefish-GKI-modularization.patch deleted file mode 100644 index 813e51f1a383..000000000000 --- a/patches/ANDROID-first-pass-cuttlefish-GKI-modularization.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Thu, 29 Aug 2019 19:15:01 -0700 -Subject: ANDROID: first pass cuttlefish GKI modularization - -Bug: 132629930 -Signed-off-by: Ram Muthiah -Change-Id: Ie2a4d08596b0e2af7c868224bc18dcd6adae7ee0 ---- - arch/x86/configs/gki_defconfig | 28 ++++++++++++++++------------ - 1 file changed, 16 insertions(+), 12 deletions(-) - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 6b0ff4ca236a..a37fa09bd107 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -155,8 +155,12 @@ CONFIG_NET_CLS_BPF=y - CONFIG_NET_EMATCH=y - CONFIG_NET_EMATCH_U32=y - CONFIG_NET_CLS_ACT=y --CONFIG_VSOCKETS=y --CONFIG_VIRTIO_VSOCKETS=y -+CONFIG_VSOCKETS=m -+CONFIG_VIRTIO_VSOCKETS=m -+CONFIG_CAN=m -+# CONFIG_CAN_BCM is not set -+# CONFIG_CAN_GW is not set -+CONFIG_CAN_VCAN=m - CONFIG_CFG80211=y - # CONFIG_CFG80211_DEFAULT_PS is not set - # CONFIG_CFG80211_CRDA_SUPPORT is not set -@@ -170,7 +174,7 @@ CONFIG_ZRAM=y - CONFIG_BLK_DEV_LOOP=y - CONFIG_BLK_DEV_RAM=y - CONFIG_BLK_DEV_RAM_SIZE=8192 --CONFIG_VIRTIO_BLK=y -+CONFIG_VIRTIO_BLK=m - CONFIG_UID_SYS_STATS=y - CONFIG_SCSI=y - # CONFIG_SCSI_PROC_FS is not set -@@ -185,7 +189,7 @@ CONFIG_DM_VERITY_FEC=y - CONFIG_DM_BOW=y - CONFIG_NETDEVICES=y - CONFIG_TUN=y --CONFIG_VIRTIO_NET=y -+CONFIG_VIRTIO_NET=m - # CONFIG_ETHERNET is not set - CONFIG_PHYLIB=y - CONFIG_PPP=y -@@ -219,7 +223,7 @@ CONFIG_USB_USBNET=y - # CONFIG_WLAN_VENDOR_TI is not set - # CONFIG_WLAN_VENDOR_ZYDAS is not set - # CONFIG_WLAN_VENDOR_QUANTENNA is not set --CONFIG_VIRT_WIFI=y -+CONFIG_VIRT_WIFI=m - CONFIG_INPUT_EVDEV=y - # CONFIG_INPUT_KEYBOARD is not set - # CONFIG_INPUT_MOUSE is not set -@@ -236,9 +240,8 @@ CONFIG_SERIAL_8250_NR_UARTS=48 - CONFIG_SERIAL_8250_EXTENDED=y - CONFIG_SERIAL_8250_MANY_PORTS=y - CONFIG_SERIAL_8250_SHARE_IRQ=y --CONFIG_VIRTIO_CONSOLE=y - CONFIG_HW_RANDOM=y --CONFIG_HW_RANDOM_VIRTIO=y -+CONFIG_HW_RANDOM_VIRTIO=m - # CONFIG_I2C_COMPAT is not set - # CONFIG_I2C_HELPER_AUTO is not set - CONFIG_SPI=y -@@ -250,7 +253,7 @@ CONFIG_MEDIA_SUPPORT=y - CONFIG_MEDIA_CAMERA_SUPPORT=y - CONFIG_DRM=y - # CONFIG_DRM_FBDEV_EMULATION is not set --CONFIG_DRM_VIRTIO_GPU=y -+CONFIG_DRM_VIRTIO_GPU=m - # CONFIG_LCD_CLASS_DEVICE is not set - CONFIG_BACKLIGHT_CLASS_DEVICE=y - CONFIG_SOUND=y -@@ -260,6 +263,7 @@ CONFIG_SND_DYNAMIC_MINORS=y - # CONFIG_SND_SUPPORT_OLD_API is not set - # CONFIG_SND_VERBOSE_PROCFS is not set - # CONFIG_SND_DRIVERS is not set -+CONFIG_SND_INTEL8X0=m - # CONFIG_SND_USB is not set - CONFIG_HIDRAW=y - CONFIG_UHID=y -@@ -285,9 +289,10 @@ CONFIG_LEDS_CLASS=y - CONFIG_LEDS_TRIGGERS=y - CONFIG_RTC_CLASS=y - # CONFIG_RTC_SYSTOHC is not set --CONFIG_VIRTIO_PCI=y --CONFIG_VIRTIO_INPUT=y --CONFIG_VIRTIO_MMIO=y -+CONFIG_RTC_DRV_TEST=m -+CONFIG_VIRTIO_PCI=m -+CONFIG_VIRTIO_INPUT=m -+CONFIG_VIRTIO_MMIO=m - CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y - CONFIG_STAGING=y - CONFIG_ASHMEM=y -@@ -325,7 +330,6 @@ CONFIG_CRYPTO_SHA512=y - CONFIG_CRYPTO_LZ4=y - CONFIG_CRYPTO_ZSTD=y - CONFIG_CRYPTO_ANSI_CPRNG=y --CONFIG_CRYPTO_DEV_VIRTIO=y - CONFIG_CRC8=y - CONFIG_XZ_DEC=y - CONFIG_DMA_CMA=y diff --git a/patches/ANDROID-fix-kernelci-build-break.patch b/patches/ANDROID-fix-kernelci-build-break.patch deleted file mode 100644 index fa850a2aabbf..000000000000 --- a/patches/ANDROID-fix-kernelci-build-break.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Todd Kjos -Date: Tue, 20 Aug 2019 09:41:56 -0700 -Subject: ANDROID: fix kernelci build-break - -Added missing #includes to fix 'allmodconfig' builds - -Bug: 120445624 -Bug: 120445421 -Change-Id: Ia8823adf2b33aa31c6d3f9d50ca7679ef4a64eaa -Signed-off-by: Todd Kjos ---- - include/linux/netfilter/xt_quota2.h | 1 + - include/trace/events/android_fs.h | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/include/linux/netfilter/xt_quota2.h b/include/linux/netfilter/xt_quota2.h -index eadc6903314e..a3918718cbf8 100644 ---- a/include/linux/netfilter/xt_quota2.h -+++ b/include/linux/netfilter/xt_quota2.h -@@ -1,5 +1,6 @@ - #ifndef _XT_QUOTA_H - #define _XT_QUOTA_H -+#include - - enum xt_quota_flags { - XT_QUOTA_INVERT = 1 << 0, -diff --git a/include/trace/events/android_fs.h b/include/trace/events/android_fs.h -index 49509533d3fa..7edb6bcfe482 100644 ---- a/include/trace/events/android_fs.h -+++ b/include/trace/events/android_fs.h -@@ -4,6 +4,7 @@ - #if !defined(_TRACE_ANDROID_FS_H) || defined(TRACE_HEADER_MULTI_READ) - #define _TRACE_ANDROID_FS_H - -+#include - #include - #include - diff --git a/patches/ANDROID-fs-FS-tracepoints-to-track-IO.patch b/patches/ANDROID-fs-FS-tracepoints-to-track-IO.patch deleted file mode 100644 index f8f5918a298b..000000000000 --- a/patches/ANDROID-fs-FS-tracepoints-to-track-IO.patch +++ /dev/null @@ -1,634 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mohan Srinivasan -Date: Wed, 14 Dec 2016 16:39:51 -0800 -Subject: ANDROID: fs: FS tracepoints to track IO. - -Adds tracepoints in ext4/f2fs/mpage to track readpages/buffered -write()s. This allows us to track files that are being read/written -to PIDs. - -Bug: 120445624 -Change-Id: I44476230324e9397e292328463f846af4befbd6d -[joelaf: Needed for storaged fsync accounting ("storaged --uid" and - "storaged --task".)] -Signed-off-by: Mohan Srinivasan -[AmitP: Folded following android-4.9 commit changes into this patch - a5c4dbb05ab7 ("ANDROID: Replace spaces by '_' for some - android filesystem tracepoints.")] -Signed-off-by: Amit Pundir -[astrachan: Folded 63066f4acf92 ("ANDROID: fs: Refactor FS - readpage/write tracepoints.") into this patch -Signed-off-by: Alistair Strachan ---- - fs/ext4/inline.c | 14 +++++ - fs/ext4/inode.c | 55 ++++++++++++++++++ - fs/ext4/readpage.c | 47 ++++++++++++++-- - fs/f2fs/data.c | 42 ++++++++++++++ - fs/f2fs/inline.c | 18 ++++++ - fs/mpage.c | 36 ++++++++++++ - include/trace/events/android_fs.h | 65 ++++++++++++++++++++++ - include/trace/events/android_fs_template.h | 64 +++++++++++++++++++++ - 8 files changed, 337 insertions(+), 4 deletions(-) - create mode 100644 include/trace/events/android_fs.h - create mode 100644 include/trace/events/android_fs_template.h - -diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c -index 2fec62d764fa..2f187da48c83 100644 ---- a/fs/ext4/inline.c -+++ b/fs/ext4/inline.c -@@ -12,6 +12,7 @@ - #include "ext4.h" - #include "xattr.h" - #include "truncate.h" -+#include - - #define EXT4_XATTR_SYSTEM_DATA "data" - #define EXT4_MIN_INLINE_DATA_SIZE ((sizeof(__le32) * EXT4_N_BLOCKS)) -@@ -505,6 +506,17 @@ int ext4_readpage_inline(struct inode *inode, struct page *page) - return -EAGAIN; - } - -+ if (trace_android_fs_dataread_start_enabled()) { -+ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; -+ -+ path = android_fstrace_get_pathname(pathbuf, -+ MAX_TRACE_PATHBUF_LEN, -+ inode); -+ trace_android_fs_dataread_start(inode, page_offset(page), -+ PAGE_SIZE, current->pid, -+ path, current->comm); -+ } -+ - /* - * Current inline data can only exist in the 1st page, - * So for all the other pages, just set them uptodate. -@@ -516,6 +528,8 @@ int ext4_readpage_inline(struct inode *inode, struct page *page) - SetPageUptodate(page); - } - -+ trace_android_fs_dataread_end(inode, page_offset(page), PAGE_SIZE); -+ - up_read(&EXT4_I(inode)->xattr_sem); - - unlock_page(page); -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index 516faa280ced..ac409eb63100 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -47,6 +47,7 @@ - #include "truncate.h" - - #include -+#include - - #define MPAGE_DA_EXTENT_TAIL 0x01 - -@@ -1269,6 +1270,16 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, - if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) - return -EIO; - -+ if (trace_android_fs_datawrite_start_enabled()) { -+ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; -+ -+ path = android_fstrace_get_pathname(pathbuf, -+ MAX_TRACE_PATHBUF_LEN, -+ inode); -+ trace_android_fs_datawrite_start(inode, pos, len, -+ current->pid, path, -+ current->comm); -+ } - trace_ext4_write_begin(inode, pos, len, flags); - /* - * Reserve one block more for addition to orphan list in case -@@ -1411,6 +1422,7 @@ static int ext4_write_end(struct file *file, - int inline_data = ext4_has_inline_data(inode); - bool verity = ext4_verity_in_progress(inode); - -+ trace_android_fs_datawrite_end(inode, pos, len); - trace_ext4_write_end(inode, pos, len, copied); - if (inline_data) { - ret = ext4_write_inline_data_end(inode, pos, len, -@@ -1521,6 +1533,7 @@ static int ext4_journalled_write_end(struct file *file, - int inline_data = ext4_has_inline_data(inode); - bool verity = ext4_verity_in_progress(inode); - -+ trace_android_fs_datawrite_end(inode, pos, len); - trace_ext4_journalled_write_end(inode, pos, len, copied); - from = pos & (PAGE_SIZE - 1); - to = from + len; -@@ -3040,6 +3053,16 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, - len, flags, pagep, fsdata); - } - *fsdata = (void *)0; -+ if (trace_android_fs_datawrite_start_enabled()) { -+ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; -+ -+ path = android_fstrace_get_pathname(pathbuf, -+ MAX_TRACE_PATHBUF_LEN, -+ inode); -+ trace_android_fs_datawrite_start(inode, pos, len, -+ current->pid, -+ path, current->comm); -+ } - trace_ext4_da_write_begin(inode, pos, len, flags); - - if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) { -@@ -3158,6 +3181,7 @@ static int ext4_da_write_end(struct file *file, - return ext4_write_end(file, mapping, pos, - len, copied, page, fsdata); - -+ trace_android_fs_datawrite_end(inode, pos, len); - trace_ext4_da_write_end(inode, pos, len, copied); - start = pos & (PAGE_SIZE - 1); - end = start + copied - 1; -@@ -3846,6 +3870,7 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter) - size_t count = iov_iter_count(iter); - loff_t offset = iocb->ki_pos; - ssize_t ret; -+ int rw = iov_iter_rw(iter); - - #ifdef CONFIG_FS_ENCRYPTION - if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode)) -@@ -3864,12 +3889,42 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter) - if (ext4_has_inline_data(inode)) - return 0; - -+ if (trace_android_fs_dataread_start_enabled() && -+ (rw == READ)) { -+ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; -+ -+ path = android_fstrace_get_pathname(pathbuf, -+ MAX_TRACE_PATHBUF_LEN, -+ inode); -+ trace_android_fs_dataread_start(inode, offset, count, -+ current->pid, path, -+ current->comm); -+ } -+ if (trace_android_fs_datawrite_start_enabled() && -+ (rw == WRITE)) { -+ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; -+ -+ path = android_fstrace_get_pathname(pathbuf, -+ MAX_TRACE_PATHBUF_LEN, -+ inode); -+ trace_android_fs_datawrite_start(inode, offset, count, -+ current->pid, path, -+ current->comm); -+ } - trace_ext4_direct_IO_enter(inode, offset, count, iov_iter_rw(iter)); - if (iov_iter_rw(iter) == READ) - ret = ext4_direct_IO_read(iocb, iter); - else - ret = ext4_direct_IO_write(iocb, iter); - trace_ext4_direct_IO_exit(inode, offset, count, iov_iter_rw(iter), ret); -+ -+ if (trace_android_fs_dataread_start_enabled() && -+ (rw == READ)) -+ trace_android_fs_dataread_end(inode, offset, count); -+ if (trace_android_fs_datawrite_start_enabled() && -+ (rw == WRITE)) -+ trace_android_fs_datawrite_end(inode, offset, count); -+ - return ret; - } - -diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c -index a30b203fa461..0d88b82a5929 100644 ---- a/fs/ext4/readpage.c -+++ b/fs/ext4/readpage.c -@@ -46,6 +46,7 @@ - #include - - #include "ext4.h" -+#include - - #define NUM_PREALLOC_POST_READ_CTXS 128 - -@@ -146,6 +147,17 @@ static bool bio_post_read_required(struct bio *bio) - return bio->bi_private && !bio->bi_status; - } - -+static void -+ext4_trace_read_completion(struct bio *bio) -+{ -+ struct page *first_page = bio->bi_io_vec[0].bv_page; -+ -+ if (first_page != NULL) -+ trace_android_fs_dataread_end(first_page->mapping->host, -+ page_offset(first_page), -+ bio->bi_iter.bi_size); -+} -+ - /* - * I/O completion handler for multipage BIOs. - * -@@ -160,6 +172,9 @@ static bool bio_post_read_required(struct bio *bio) - */ - static void mpage_end_io(struct bio *bio) - { -+ if (trace_android_fs_dataread_start_enabled()) -+ ext4_trace_read_completion(bio); -+ - if (bio_post_read_required(bio)) { - struct bio_post_read_ctx *ctx = bio->bi_private; - -@@ -209,6 +224,30 @@ static inline loff_t ext4_readpage_limit(struct inode *inode) - return i_size_read(inode); - } - -+static void -+ext4_submit_bio_read(struct bio *bio) -+{ -+ if (trace_android_fs_dataread_start_enabled()) { -+ struct page *first_page = bio->bi_io_vec[0].bv_page; -+ -+ if (first_page != NULL) { -+ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; -+ -+ path = android_fstrace_get_pathname(pathbuf, -+ MAX_TRACE_PATHBUF_LEN, -+ first_page->mapping->host); -+ trace_android_fs_dataread_start( -+ first_page->mapping->host, -+ page_offset(first_page), -+ bio->bi_iter.bi_size, -+ current->pid, -+ path, -+ current->comm); -+ } -+ } -+ submit_bio(bio); -+} -+ - int ext4_mpage_readpages(struct address_space *mapping, - struct list_head *pages, struct page *page, - unsigned nr_pages, bool is_readahead) -@@ -354,7 +393,7 @@ int ext4_mpage_readpages(struct address_space *mapping, - */ - if (bio && (last_block_in_bio != blocks[0] - 1)) { - submit_and_realloc: -- submit_bio(bio); -+ ext4_submit_bio_read(bio); - bio = NULL; - } - if (bio == NULL) { -@@ -385,14 +424,14 @@ int ext4_mpage_readpages(struct address_space *mapping, - if (((map.m_flags & EXT4_MAP_BOUNDARY) && - (relative_block == map.m_len)) || - (first_hole != blocks_per_page)) { -- submit_bio(bio); -+ ext4_submit_bio_read(bio); - bio = NULL; - } else - last_block_in_bio = blocks[blocks_per_page - 1]; - goto next_page; - confused: - if (bio) { -- submit_bio(bio); -+ ext4_submit_bio_read(bio); - bio = NULL; - } - if (!PageUptodate(page)) -@@ -405,7 +444,7 @@ int ext4_mpage_readpages(struct address_space *mapping, - } - BUG_ON(pages && !list_empty(pages)); - if (bio) -- submit_bio(bio); -+ ext4_submit_bio_read(bio); - return 0; - } - -diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c -index 5755e897a5f0..9155256779bf 100644 ---- a/fs/f2fs/data.c -+++ b/fs/f2fs/data.c -@@ -25,6 +25,7 @@ - #include "segment.h" - #include "trace.h" - #include -+#include - - #define NUM_PREALLOC_POST_READ_CTXS 128 - -@@ -2623,6 +2624,16 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping, - block_t blkaddr = NULL_ADDR; - int err = 0; - -+ if (trace_android_fs_datawrite_start_enabled()) { -+ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; -+ -+ path = android_fstrace_get_pathname(pathbuf, -+ MAX_TRACE_PATHBUF_LEN, -+ inode); -+ trace_android_fs_datawrite_start(inode, pos, len, -+ current->pid, path, -+ current->comm); -+ } - trace_f2fs_write_begin(inode, pos, len, flags); - - if (!f2fs_is_checkpoint_ready(sbi)) { -@@ -2730,6 +2741,7 @@ static int f2fs_write_end(struct file *file, - { - struct inode *inode = page->mapping->host; - -+ trace_android_fs_datawrite_end(inode, pos, len); - trace_f2fs_write_end(inode, pos, len, copied); - - /* -@@ -2846,6 +2858,29 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) - - trace_f2fs_direct_IO_enter(inode, offset, count, rw); - -+ if (trace_android_fs_dataread_start_enabled() && -+ (rw == READ)) { -+ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; -+ -+ path = android_fstrace_get_pathname(pathbuf, -+ MAX_TRACE_PATHBUF_LEN, -+ inode); -+ trace_android_fs_dataread_start(inode, offset, -+ count, current->pid, path, -+ current->comm); -+ } -+ if (trace_android_fs_datawrite_start_enabled() && -+ (rw == WRITE)) { -+ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; -+ -+ path = android_fstrace_get_pathname(pathbuf, -+ MAX_TRACE_PATHBUF_LEN, -+ inode); -+ trace_android_fs_datawrite_start(inode, offset, count, -+ current->pid, path, -+ current->comm); -+ } -+ - if (rw == WRITE && whint_mode == WHINT_MODE_OFF) - iocb->ki_hint = WRITE_LIFE_NOT_SET; - -@@ -2891,6 +2926,13 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) - } - - out: -+ if (trace_android_fs_dataread_start_enabled() && -+ (rw == READ)) -+ trace_android_fs_dataread_end(inode, offset, count); -+ if (trace_android_fs_datawrite_start_enabled() && -+ (rw == WRITE)) -+ trace_android_fs_datawrite_end(inode, offset, count); -+ - trace_f2fs_direct_IO_exit(inode, offset, count, rw, err); - - return err; -diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c -index 896db0416f0e..59adbfa25bac 100644 ---- a/fs/f2fs/inline.c -+++ b/fs/f2fs/inline.c -@@ -11,6 +11,7 @@ - - #include "f2fs.h" - #include "node.h" -+#include - - bool f2fs_may_inline_data(struct inode *inode) - { -@@ -84,14 +85,29 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page) - { - struct page *ipage; - -+ if (trace_android_fs_dataread_start_enabled()) { -+ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; -+ -+ path = android_fstrace_get_pathname(pathbuf, -+ MAX_TRACE_PATHBUF_LEN, -+ inode); -+ trace_android_fs_dataread_start(inode, page_offset(page), -+ PAGE_SIZE, current->pid, -+ path, current->comm); -+ } -+ - ipage = f2fs_get_node_page(F2FS_I_SB(inode), inode->i_ino); - if (IS_ERR(ipage)) { -+ trace_android_fs_dataread_end(inode, page_offset(page), -+ PAGE_SIZE); - unlock_page(page); - return PTR_ERR(ipage); - } - - if (!f2fs_has_inline_data(inode)) { - f2fs_put_page(ipage, 1); -+ trace_android_fs_dataread_end(inode, page_offset(page), -+ PAGE_SIZE); - return -EAGAIN; - } - -@@ -103,6 +119,8 @@ int f2fs_read_inline_data(struct inode *inode, struct page *page) - if (!PageUptodate(page)) - SetPageUptodate(page); - f2fs_put_page(ipage, 1); -+ trace_android_fs_dataread_end(inode, page_offset(page), -+ PAGE_SIZE); - unlock_page(page); - return 0; - } -diff --git a/fs/mpage.c b/fs/mpage.c -index a63620cdb73a..e8281998e690 100644 ---- a/fs/mpage.c -+++ b/fs/mpage.c -@@ -32,6 +32,14 @@ - #include - #include "internal.h" - -+#define CREATE_TRACE_POINTS -+#include -+ -+EXPORT_TRACEPOINT_SYMBOL(android_fs_datawrite_start); -+EXPORT_TRACEPOINT_SYMBOL(android_fs_datawrite_end); -+EXPORT_TRACEPOINT_SYMBOL(android_fs_dataread_start); -+EXPORT_TRACEPOINT_SYMBOL(android_fs_dataread_end); -+ - /* - * I/O completion handler for multipage BIOs. - * -@@ -49,6 +57,16 @@ static void mpage_end_io(struct bio *bio) - struct bio_vec *bv; - struct bvec_iter_all iter_all; - -+ if (trace_android_fs_dataread_end_enabled() && -+ (bio_data_dir(bio) == READ)) { -+ struct page *first_page = bio->bi_io_vec[0].bv_page; -+ -+ if (first_page != NULL) -+ trace_android_fs_dataread_end(first_page->mapping->host, -+ page_offset(first_page), -+ bio->bi_iter.bi_size); -+ } -+ - bio_for_each_segment_all(bv, bio, iter_all) { - struct page *page = bv->bv_page; - page_endio(page, bio_op(bio), -@@ -60,6 +78,24 @@ static void mpage_end_io(struct bio *bio) - - static struct bio *mpage_bio_submit(int op, int op_flags, struct bio *bio) - { -+ if (trace_android_fs_dataread_start_enabled() && (op == REQ_OP_READ)) { -+ struct page *first_page = bio->bi_io_vec[0].bv_page; -+ -+ if (first_page != NULL) { -+ char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; -+ -+ path = android_fstrace_get_pathname(pathbuf, -+ MAX_TRACE_PATHBUF_LEN, -+ first_page->mapping->host); -+ trace_android_fs_dataread_start( -+ first_page->mapping->host, -+ page_offset(first_page), -+ bio->bi_iter.bi_size, -+ current->pid, -+ path, -+ current->comm); -+ } -+ } - bio->bi_end_io = mpage_end_io; - bio_set_op_attrs(bio, op, op_flags); - guard_bio_eod(op, bio); -diff --git a/include/trace/events/android_fs.h b/include/trace/events/android_fs.h -new file mode 100644 -index 000000000000..49509533d3fa ---- /dev/null -+++ b/include/trace/events/android_fs.h -@@ -0,0 +1,65 @@ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM android_fs -+ -+#if !defined(_TRACE_ANDROID_FS_H) || defined(TRACE_HEADER_MULTI_READ) -+#define _TRACE_ANDROID_FS_H -+ -+#include -+#include -+ -+DEFINE_EVENT(android_fs_data_start_template, android_fs_dataread_start, -+ TP_PROTO(struct inode *inode, loff_t offset, int bytes, -+ pid_t pid, char *pathname, char *command), -+ TP_ARGS(inode, offset, bytes, pid, pathname, command)); -+ -+DEFINE_EVENT(android_fs_data_end_template, android_fs_dataread_end, -+ TP_PROTO(struct inode *inode, loff_t offset, int bytes), -+ TP_ARGS(inode, offset, bytes)); -+ -+DEFINE_EVENT(android_fs_data_start_template, android_fs_datawrite_start, -+ TP_PROTO(struct inode *inode, loff_t offset, int bytes, -+ pid_t pid, char *pathname, char *command), -+ TP_ARGS(inode, offset, bytes, pid, pathname, command)); -+ -+DEFINE_EVENT(android_fs_data_end_template, android_fs_datawrite_end, -+ TP_PROTO(struct inode *inode, loff_t offset, int bytes), -+ TP_ARGS(inode, offset, bytes)); -+ -+#endif /* _TRACE_ANDROID_FS_H */ -+ -+/* This part must be outside protection */ -+#include -+ -+#ifndef ANDROID_FSTRACE_GET_PATHNAME -+#define ANDROID_FSTRACE_GET_PATHNAME -+ -+/* Sizes an on-stack array, so careful if sizing this up ! */ -+#define MAX_TRACE_PATHBUF_LEN 256 -+ -+static inline char * -+android_fstrace_get_pathname(char *buf, int buflen, struct inode *inode) -+{ -+ char *path; -+ struct dentry *d; -+ -+ /* -+ * d_obtain_alias() will either iput() if it locates an existing -+ * dentry or transfer the reference to the new dentry created. -+ * So get an extra reference here. -+ */ -+ ihold(inode); -+ d = d_obtain_alias(inode); -+ if (likely(!IS_ERR(d))) { -+ path = dentry_path_raw(d, buf, buflen); -+ if (unlikely(IS_ERR(path))) { -+ strcpy(buf, "ERROR"); -+ path = buf; -+ } -+ dput(d); -+ } else { -+ strcpy(buf, "ERROR"); -+ path = buf; -+ } -+ return path; -+} -+#endif -diff --git a/include/trace/events/android_fs_template.h b/include/trace/events/android_fs_template.h -new file mode 100644 -index 000000000000..b23d17b56c63 ---- /dev/null -+++ b/include/trace/events/android_fs_template.h -@@ -0,0 +1,64 @@ -+#if !defined(_TRACE_ANDROID_FS_TEMPLATE_H) || defined(TRACE_HEADER_MULTI_READ) -+#define _TRACE_ANDROID_FS_TEMPLATE_H -+ -+#include -+ -+DECLARE_EVENT_CLASS(android_fs_data_start_template, -+ TP_PROTO(struct inode *inode, loff_t offset, int bytes, -+ pid_t pid, char *pathname, char *command), -+ TP_ARGS(inode, offset, bytes, pid, pathname, command), -+ TP_STRUCT__entry( -+ __string(pathbuf, pathname); -+ __field(loff_t, offset); -+ __field(int, bytes); -+ __field(loff_t, i_size); -+ __string(cmdline, command); -+ __field(pid_t, pid); -+ __field(ino_t, ino); -+ ), -+ TP_fast_assign( -+ { -+ /* -+ * Replace the spaces in filenames and cmdlines -+ * because this screws up the tooling that parses -+ * the traces. -+ */ -+ __assign_str(pathbuf, pathname); -+ (void)strreplace(__get_str(pathbuf), ' ', '_'); -+ __entry->offset = offset; -+ __entry->bytes = bytes; -+ __entry->i_size = i_size_read(inode); -+ __assign_str(cmdline, command); -+ (void)strreplace(__get_str(cmdline), ' ', '_'); -+ __entry->pid = pid; -+ __entry->ino = inode->i_ino; -+ } -+ ), -+ TP_printk("entry_name %s, offset %llu, bytes %d, cmdline %s," -+ " pid %d, i_size %llu, ino %lu", -+ __get_str(pathbuf), __entry->offset, __entry->bytes, -+ __get_str(cmdline), __entry->pid, __entry->i_size, -+ (unsigned long) __entry->ino) -+); -+ -+DECLARE_EVENT_CLASS(android_fs_data_end_template, -+ TP_PROTO(struct inode *inode, loff_t offset, int bytes), -+ TP_ARGS(inode, offset, bytes), -+ TP_STRUCT__entry( -+ __field(ino_t, ino); -+ __field(loff_t, offset); -+ __field(int, bytes); -+ ), -+ TP_fast_assign( -+ { -+ __entry->ino = inode->i_ino; -+ __entry->offset = offset; -+ __entry->bytes = bytes; -+ } -+ ), -+ TP_printk("ino %lu, offset %llu, bytes %d", -+ (unsigned long) __entry->ino, -+ __entry->offset, __entry->bytes) -+); -+ -+#endif /* _TRACE_ANDROID_FS_TEMPLATE_H */ diff --git a/patches/ANDROID-fs-Restore-vfs_path_lookup-export.patch b/patches/ANDROID-fs-Restore-vfs_path_lookup-export.patch deleted file mode 100644 index 2cd56a0634b3..000000000000 --- a/patches/ANDROID-fs-Restore-vfs_path_lookup-export.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alistair Strachan -Date: Mon, 19 Nov 2018 22:38:23 -0800 -Subject: ANDROID: fs: Restore vfs_path_lookup() export - -Partial revert of 197df04c749a ("rename user_path_umountat() to -user_path_mountpoint_at()"), to restore access to vfs_path_lookup() -without including fs/internal.h, as needed by sdcardfs. - -Test: HiKey/X15 + Pie + android-mainline, - and HiKey + AOSP Maser + android-mainline, - directories under /sdcard created, - output of mount is right, - CTS test collecting device infor works - -Change-Id: I757f2df9f4dcc66f633939e7833e6fa2ac0ff4f8 -Signed-off-by: Alistair Strachan -Signed-off-by: Yongqin Liu ---- - fs/internal.h | 2 -- - include/linux/namei.h | 2 ++ - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/fs/internal.h b/fs/internal.h -index 315fcd8d237c..df6e4c4584f3 100644 ---- a/fs/internal.h -+++ b/fs/internal.h -@@ -62,8 +62,6 @@ extern int finish_clean_context(struct fs_context *fc); - extern int filename_lookup(int dfd, struct filename *name, unsigned flags, - struct path *path, struct path *root); - extern int user_path_mountpoint_at(int, const char __user *, unsigned int, struct path *); --extern int vfs_path_lookup(struct dentry *, struct vfsmount *, -- const char *, unsigned int, struct path *); - long do_mknodat(int dfd, const char __user *filename, umode_t mode, - unsigned int dev); - long do_mkdirat(int dfd, const char __user *pathname, umode_t mode); -diff --git a/include/linux/namei.h b/include/linux/namei.h -index cb288d62f1d6..5f04b40747b2 100644 ---- a/include/linux/namei.h -+++ b/include/linux/namei.h -@@ -55,6 +55,8 @@ extern struct dentry *kern_path_create(int, const char *, struct path *, unsigne - extern struct dentry *user_path_create(int, const char __user *, struct path *, unsigned int); - extern void done_path_create(struct path *, struct dentry *); - extern struct dentry *kern_path_locked(const char *, struct path *); -+extern int vfs_path_lookup(struct dentry *, struct vfsmount *, -+ const char *, unsigned int, struct path *); - extern int kern_path_mountpoint(int, const char *, struct path *, unsigned int); - - extern struct dentry *try_lookup_one_len(const char *, struct dentry *, int); diff --git a/patches/ANDROID-fs-epoll-use-freezable-blocking-call.patch b/patches/ANDROID-fs-epoll-use-freezable-blocking-call.patch deleted file mode 100644 index 3fe2cf9bc7e7..000000000000 --- a/patches/ANDROID-fs-epoll-use-freezable-blocking-call.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Colin Cross -Date: Mon, 6 May 2013 23:50:16 +0000 -Subject: ANDROID: fs: epoll: use freezable blocking call - -Avoid waking up every thread sleeping in an epoll_wait call during -suspend and resume by calling a freezable blocking call. Previous -patches modified the freezer to avoid sending wakeups to threads -that are blocked in freezable blocking calls. - -This call was selected to be converted to a freezable call because -it doesn't hold any locks or release any resources when interrupted -that might be needed by another freezing task or a kernel driver -during suspend, and is a common site where idle userspace tasks are -blocked. - -Bug: 77139736 -Bug: 120440023 -Change-Id: I848d08d28c89302fd42bbbdfa76489a474ab27bf -[ccross: This was upstream (https://lkml.org/lkml/2013/5/6/823), but - reverted because it reportedly caused memory corruption on - 32-bit x86 (https://patchwork.kernel.org/patch/3162301/).] -Acked-by: Tejun Heo -Signed-off-by: Colin Cross -Signed-off-by: Rafael J. Wysocki ---- - fs/eventpoll.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/fs/eventpoll.c b/fs/eventpoll.c -index c4159bcc05d9..6730d92e225a 100644 ---- a/fs/eventpoll.c -+++ b/fs/eventpoll.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1912,7 +1913,8 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, - break; - } - -- if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS)) { -+ if (!freezable_schedule_hrtimeout_range(to, slack, -+ HRTIMER_MODE_ABS)) { - timed_out = 1; - break; - } diff --git a/patches/ANDROID-gki-cuttlefish-defconfigs-use-prebuilt-build-tools.patch b/patches/ANDROID-gki-cuttlefish-defconfigs-use-prebuilt-build-tools.patch deleted file mode 100644 index 8e210a466e7b..000000000000 --- a/patches/ANDROID-gki-cuttlefish-defconfigs-use-prebuilt-build-tools.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Matthias Maennich -Date: Mon, 24 Jun 2019 18:10:19 +0100 -Subject: ANDROID: gki/cuttlefish defconfigs: use prebuilt build-tools - -Rather than relying on the hosts build tools, use a set of prebuilt -build-tools. These are tools like awk, cat, cp, hostname, python, rm, -sed, etc. - -Bug: 135922132 -Change-Id: Ie6b0bd208c684c9f153eb2f0bfac4712e02e8e05 -Signed-off-by: Matthias Maennich ---- - build.config.gki.aarch64 | 1 + - build.config.gki.x86_64 | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 -index ecc2985e92cb..24dade721f96 100644 ---- a/build.config.gki.aarch64 -+++ b/build.config.gki.aarch64 -@@ -8,6 +8,7 @@ EXTRA_CMDS='' - KERNEL_DIR=common - POST_DEFCONFIG_CMDS="check_defconfig" - CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin -+BUILDTOOLS_PREBUILT_BIN=prebuilts/build-tools/path/linux-x86 - LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin - FILES=" - arch/arm64/boot/Image.gz -diff --git a/build.config.gki.x86_64 b/build.config.gki.x86_64 -index 69d339dce4a0..3ce45e962732 100644 ---- a/build.config.gki.x86_64 -+++ b/build.config.gki.x86_64 -@@ -8,6 +8,7 @@ EXTRA_CMDS='' - KERNEL_DIR=common - POST_DEFCONFIG_CMDS="check_defconfig" - CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin -+BUILDTOOLS_PREBUILT_BIN=prebuilts/build-tools/path/linux-x86 - LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin - FILES=" - arch/x86/boot/bzImage diff --git a/patches/ANDROID-gki_defconfig-Add-GKI_HACKS_to_FIX-config.patch b/patches/ANDROID-gki_defconfig-Add-GKI_HACKS_to_FIX-config.patch deleted file mode 100644 index c852c93fbf3f..000000000000 --- a/patches/ANDROID-gki_defconfig-Add-GKI_HACKS_to_FIX-config.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Todd Kjos -Date: Tue, 17 Sep 2019 16:22:18 -0700 -Subject: ANDROID: gki_defconfig: Add GKI_HACKS_to_FIX config - -Enable config which selects a number of non-module -options which are usually selected by drivers built -as modules - -Bug: 141266428 -Change-Id: I8d95c96b74b2cfd861d68573135455a3392ff522 -Signed-off-by: Todd Kjos ---- - arch/arm64/configs/gki_defconfig | 1 + - arch/x86/configs/gki_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index f65b544d17a4..8edcded9ab1f 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -72,6 +72,7 @@ CONFIG_KPROBES=y - CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y -+CONFIG_GKI_HACKS_TO_FIX=y - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set - CONFIG_MEMORY_HOTPLUG=y - CONFIG_TRANSPARENT_HUGEPAGE=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 3e8f580e0bde..bf0ab5abf5e7 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -47,6 +47,7 @@ CONFIG_KPROBES=y - CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y -+CONFIG_GKI_HACKS_TO_FIX=y - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set - CONFIG_TRANSPARENT_HUGEPAGE=y - CONFIG_CMA=y diff --git a/patches/ANDROID-gki_defconfig-Enable-BPF_JIT-and-BPF_JIT_ALWAYS_ON.patch b/patches/ANDROID-gki_defconfig-Enable-BPF_JIT-and-BPF_JIT_ALWAYS_ON.patch deleted file mode 100644 index 6cf2a2f474cf..000000000000 --- a/patches/ANDROID-gki_defconfig-Enable-BPF_JIT-and-BPF_JIT_ALWAYS_ON.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= -Date: Tue, 8 Oct 2019 08:51:00 -0700 -Subject: ANDROID: gki_defconfig: Enable BPF_JIT and BPF_JIT_ALWAYS_ON -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Generated via: - echo 'CONFIG_BPF_JIT=y' >> arch/x86/configs/gki_defconfig - echo 'CONFIG_BPF_JIT_ALWAYS_ON=y' >> arch/x86/configs/gki_defconfig - - make ARCH=x86_64 gki_defconfig - make ARCH=x86_64 savedefconfig - mv defconfig arch/x86/configs/gki_defconfig - - echo 'CONFIG_BPF_JIT=y' >> arch/arm64/configs/gki_defconfig - echo 'CONFIG_BPF_JIT_ALWAYS_ON=y' >> arch/arm64/configs/gki_defconfig - - make ARCH=arm64 gki_defconfig - make ARCH=arm64 savedefconfig - mv defconfig arch/arm64/configs/gki_defconfig - -Bug: 140377409 -Signed-off-by: Maciej Żenczykowski -Change-Id: I84e917b75ca2cbe4d4b61c0d042f9fbcf5bdf519 ---- - arch/arm64/configs/gki_defconfig | 2 ++ - arch/x86/configs/gki_defconfig | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 97e0e47767e2..9e3b34fa8b64 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -28,6 +28,7 @@ CONFIG_BLK_DEV_INITRD=y - # CONFIG_FHANDLE is not set - CONFIG_KALLSYMS_ALL=y - CONFIG_BPF_SYSCALL=y -+CONFIG_BPF_JIT_ALWAYS_ON=y - # CONFIG_RSEQ is not set - CONFIG_EMBEDDED=y - # CONFIG_VM_EVENT_COUNTERS is not set -@@ -187,6 +188,7 @@ CONFIG_NET_EMATCH_U32=y - CONFIG_NET_CLS_ACT=y - CONFIG_VSOCKETS=y - CONFIG_VIRTIO_VSOCKETS=y -+CONFIG_BPF_JIT=y - CONFIG_BT=y - CONFIG_CFG80211=y - # CONFIG_CFG80211_DEFAULT_PS is not set -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 7890c249bca9..f539970bf631 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -27,6 +27,7 @@ CONFIG_BLK_DEV_INITRD=y - # CONFIG_FHANDLE is not set - CONFIG_KALLSYMS_ALL=y - CONFIG_BPF_SYSCALL=y -+CONFIG_BPF_JIT_ALWAYS_ON=y - # CONFIG_RSEQ is not set - CONFIG_EMBEDDED=y - # CONFIG_VM_EVENT_COUNTERS is not set -@@ -159,6 +160,7 @@ CONFIG_NET_EMATCH_U32=y - CONFIG_NET_CLS_ACT=y - CONFIG_VSOCKETS=m - CONFIG_VIRTIO_VSOCKETS=m -+CONFIG_BPF_JIT=y - CONFIG_CAN=m - # CONFIG_CAN_BCM is not set - # CONFIG_CAN_GW is not set diff --git a/patches/ANDROID-gki_defconfig-Enable-CMA-SLAB_FREELIST-RANDOM-and-HARDENED-on-x86.patch b/patches/ANDROID-gki_defconfig-Enable-CMA-SLAB_FREELIST-RANDOM-and-HARDENED-on-x86.patch deleted file mode 100644 index 143a83783cde..000000000000 --- a/patches/ANDROID-gki_defconfig-Enable-CMA-SLAB_FREELIST-RANDOM-and-HARDENED-on-x86.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Mon, 3 Jun 2019 13:53:01 -0700 -Subject: ANDROID: gki_defconfig: Enable CMA, SLAB_FREELIST (RANDOM and - HARDENED) on x86 - -Fixes: 134087016 -Fixes: 134378085 -Test: Boot x86 cuttlefish -Change-Id: I64f9714bbda558056c47f09a5e768d7eb83e2640 -Signed-off-by: Ram Muthiah ---- - arch/x86/configs/gki_defconfig | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index cdaba53b7bb0..864595c719e7 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -30,6 +30,8 @@ CONFIG_EMBEDDED=y - # CONFIG_VM_EVENT_COUNTERS is not set - # CONFIG_COMPAT_BRK is not set - # CONFIG_SLAB_MERGE_DEFAULT is not set -+CONFIG_SLAB_FREELIST_RANDOM=y -+CONFIG_SLAB_FREELIST_HARDENED=y - CONFIG_PROFILING=y - CONFIG_PM_WAKELOCKS=y - CONFIG_PM_WAKELOCKS_LIMIT=0 -@@ -46,6 +48,8 @@ CONFIG_MODVERSIONS=y - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set - # CONFIG_SPARSEMEM_VMEMMAP is not set - CONFIG_TRANSPARENT_HUGEPAGE=y -+CONFIG_CMA=y -+CONFIG_CMA_AREAS=16 - CONFIG_ZSMALLOC=y - CONFIG_NET=y - CONFIG_PACKET=y diff --git a/patches/ANDROID-gki_defconfig-Enable-CONFIG_DM_SNAPSHOT.patch b/patches/ANDROID-gki_defconfig-Enable-CONFIG_DM_SNAPSHOT.patch deleted file mode 100644 index b16aacf1a6a9..000000000000 --- a/patches/ANDROID-gki_defconfig-Enable-CONFIG_DM_SNAPSHOT.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alessio Balsini -Date: Fri, 11 Oct 2019 13:50:20 +0100 -Subject: ANDROID: gki_defconfig: Enable CONFIG_DM_SNAPSHOT - -The snapshot dm target is required to implement the Virtual-AB -mechanism. -Introduce CONFIG_DM_SNAPSHOT in arm64 and x86 gki defconfigs to -enable this feature. - -Bug: 142527064 -Test: kernel build -Signed-off-by: Alessio Balsini -Change-Id: I69bc614509eaff259a2aa9195e7e1d406b36bbb2 ---- - arch/arm64/configs/gki_defconfig | 1 + - arch/x86/configs/gki_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 6ccf6c7ef9ec..ed21a0d79f4c 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -216,6 +216,7 @@ CONFIG_SCSI_UFSHCD_PLATFORM=y - CONFIG_MD=y - CONFIG_BLK_DEV_DM=y - CONFIG_DM_CRYPT=y -+CONFIG_DM_SNAPSHOT=y - CONFIG_DM_UEVENT=y - CONFIG_DM_VERITY=y - CONFIG_DM_VERITY_AVB=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 931fcbdced69..fbcf73e4f66f 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -189,6 +189,7 @@ CONFIG_BLK_DEV_SD=y - CONFIG_MD=y - CONFIG_BLK_DEV_DM=y - CONFIG_DM_CRYPT=y -+CONFIG_DM_SNAPSHOT=y - CONFIG_DM_UEVENT=y - CONFIG_DM_VERITY=y - CONFIG_DM_VERITY_AVB=y diff --git a/patches/ANDROID-gki_defconfig-Enable-HiSilicon-SoCs.patch b/patches/ANDROID-gki_defconfig-Enable-HiSilicon-SoCs.patch deleted file mode 100644 index c8b5484b9252..000000000000 --- a/patches/ANDROID-gki_defconfig-Enable-HiSilicon-SoCs.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Todd Kjos -Date: Wed, 18 Sep 2019 10:49:45 -0700 -Subject: ANDROID: gki_defconfig: Enable HiSilicon SoCs - -Enable configs required for HiSilicon SoCs. - -Bug: 141265942 -Change-Id: Iedb2b795bda690bdec4db3265dc391f7837208e0 -Signed-off-by: Todd Kjos ---- - arch/arm64/configs/gki_defconfig | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 1263dc50f970..f964b81a1e4b 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -36,6 +36,7 @@ CONFIG_EMBEDDED=y - CONFIG_SLAB_FREELIST_RANDOM=y - CONFIG_SLAB_FREELIST_HARDENED=y - CONFIG_PROFILING=y -+CONFIG_ARCH_HISI=y - CONFIG_ARCH_QCOM=y - CONFIG_SCHED_MC=y - CONFIG_NR_CPUS=32 -@@ -195,6 +196,7 @@ CONFIG_MAC80211=y - CONFIG_RFKILL=y - CONFIG_PCI=y - CONFIG_PCI_HOST_GENERIC=y -+CONFIG_PCIE_KIRIN=y - # CONFIG_ALLOW_DEV_COREDUMP is not set - CONFIG_DEBUG_DEVRES=y - CONFIG_ZRAM=y -@@ -280,6 +282,7 @@ CONFIG_SPI=y - CONFIG_SPMI=y - CONFIG_PINCTRL_AMD=y - CONFIG_POWER_AVS=y -+CONFIG_POWER_RESET_HISI=y - # CONFIG_HWMON is not set - CONFIG_THERMAL=y - CONFIG_THERMAL_GOV_USER_SPACE=y diff --git a/patches/ANDROID-gki_defconfig-Enable-SERIAL_DEV_BUS.patch b/patches/ANDROID-gki_defconfig-Enable-SERIAL_DEV_BUS.patch deleted file mode 100644 index e152de9afbc7..000000000000 --- a/patches/ANDROID-gki_defconfig-Enable-SERIAL_DEV_BUS.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Todd Kjos -Date: Tue, 17 Sep 2019 16:25:46 -0700 -Subject: ANDROID: gki_defconfig: Enable SERIAL_DEV_BUS - -Enable CONFIG_SERIAL_DEV_BUS for hikey/db845c - -Bug: 141265942 -Change-Id: Iedc0d96ed10011ca0b5bedd7384f5158f32c6c76 -Signed-off-by: Todd Kjos ---- - arch/arm64/configs/gki_defconfig | 1 + - arch/x86/configs/gki_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 8edcded9ab1f..1263dc50f970 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -268,6 +268,7 @@ CONFIG_SERIAL_8250_CONSOLE=y - CONFIG_SERIAL_OF_PLATFORM=m - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_SERIAL_DEV_BUS=y - CONFIG_VIRTIO_CONSOLE=y - CONFIG_HW_RANDOM=y - CONFIG_HW_RANDOM_VIRTIO=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index bf0ab5abf5e7..bcd12981dff4 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -239,6 +239,7 @@ CONFIG_SERIAL_8250=y - # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set - CONFIG_SERIAL_8250_CONSOLE=y - CONFIG_SERIAL_OF_PLATFORM=m -+CONFIG_SERIAL_DEV_BUS=y - CONFIG_HW_RANDOM=y - CONFIG_HW_RANDOM_VIRTIO=m - # CONFIG_I2C_COMPAT is not set diff --git a/patches/ANDROID-gki_defconfig-Minimally-enable-EFI.patch b/patches/ANDROID-gki_defconfig-Minimally-enable-EFI.patch deleted file mode 100644 index 44c5ec720496..000000000000 --- a/patches/ANDROID-gki_defconfig-Minimally-enable-EFI.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: John Stultz -Date: Fri, 16 Aug 2019 22:33:20 +0000 -Subject: ANDROID: gki_defconfig: Minimally enable EFI - -HiKey/HiKey960 need UEFI support to boot but don't need much of -the other options that default on when enabling EFI. - -Bug: 140204135 -Signed-off-by: John Stultz -Change-Id: I5c2e63701ae93277fcc3ddb36a39637237c65194 ---- - arch/arm64/configs/gki_defconfig | 4 +++- - arch/x86/configs/gki_defconfig | 2 ++ - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 2773a84fd939..006692f065d4 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -46,7 +46,7 @@ CONFIG_SWP_EMULATION=y - CONFIG_CP15_BARRIER_EMULATION=y - CONFIG_SETEND_EMULATION=y - CONFIG_RANDOMIZE_BASE=y --# CONFIG_EFI is not set -+# CONFIG_DMI is not set - CONFIG_PM_WAKELOCKS=y - CONFIG_PM_WAKELOCKS_LIMIT=0 - # CONFIG_PM_WAKELOCKS_GC is not set -@@ -64,6 +64,7 @@ CONFIG_ARM_SCMI_PROTOCOL=y - # CONFIG_ARM_SCMI_POWER_DOMAIN is not set - CONFIG_ARM_SCPI_PROTOCOL=y - # CONFIG_ARM_SCPI_POWER_DOMAIN is not set -+# CONFIG_EFI_ARMSTUB_DTB_LOADER is not set - CONFIG_ARM64_CRYPTO=y - CONFIG_CRYPTO_AES_ARM64=y - CONFIG_KPROBES=y -@@ -382,6 +383,7 @@ CONFIG_MSDOS_FS=y - CONFIG_VFAT_FS=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y -+# CONFIG_EFIVAR_FS is not set - CONFIG_SDCARD_FS=y - CONFIG_PSTORE=y - CONFIG_PSTORE_CONSOLE=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index a1b2121bde8b..ed8296e953ed 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -36,6 +36,7 @@ CONFIG_SLAB_FREELIST_HARDENED=y - CONFIG_PROFILING=y - CONFIG_SMP=y - CONFIG_NR_CPUS=32 -+CONFIG_EFI=y - CONFIG_PM_WAKELOCKS=y - CONFIG_PM_WAKELOCKS_LIMIT=0 - # CONFIG_PM_WAKELOCKS_GC is not set -@@ -308,6 +309,7 @@ CONFIG_MSDOS_FS=y - CONFIG_VFAT_FS=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y -+# CONFIG_EFIVAR_FS is not set - CONFIG_SDCARD_FS=y - CONFIG_PSTORE=y - CONFIG_PSTORE_CONSOLE=y diff --git a/patches/ANDROID-gki_defconfig-Remove-cuttlefish-specific-configs.patch b/patches/ANDROID-gki_defconfig-Remove-cuttlefish-specific-configs.patch deleted file mode 100644 index d518202e98dc..000000000000 --- a/patches/ANDROID-gki_defconfig-Remove-cuttlefish-specific-configs.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Fri, 10 May 2019 14:33:29 -0700 -Subject: ANDROID: gki_defconfig: Remove cuttlefish-specific configs - -Left enabled: -- configs for virtualization CONFIG_PARAVIRT, CONFIG_VIRTIO_*, etc. -- cuttlefish doesn't boot without CONFIG_KSM, CONFIG_SGETMASK_SYSCALL, - CONFIG_SCHED_AUTOGROUP - -A number of config should be modules, but due to lack of module support -in userspace are left built in: -- CONFIG_PCI_HOST_GENERIC -- CONFIG_SERIAL_* -- CONFIG_MAC80211 -- CONFIG_SND_INTEL8X0 -- CONFIG_RTC_DRV_PL030 -- CONFIG_RTC_DRV_PL031 -- CONFIG_CRYPTO_ADIANTUM -- CONFIG_CRYPTO_ZSTD - -Test: boot cuttlefish on arm64 -Signed-off-by: Tri Vo -(partially cherry picked from commit a651d6eccc912ea60d8b79ddeec23ffb1f85b65f) ---- - arch/arm64/configs/gki_defconfig | 12 ------------ - 1 file changed, 12 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index a747e222db8e..41a892ca324d 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -34,7 +34,6 @@ CONFIG_EMBEDDED=y - # CONFIG_SLAB_MERGE_DEFAULT is not set - CONFIG_PROFILING=y - CONFIG_SCHED_MC=y --CONFIG_HZ_100=y - CONFIG_SECCOMP=y - CONFIG_PARAVIRT=y - CONFIG_ARMV8_DEPRECATED=y -@@ -56,7 +55,6 @@ CONFIG_CPU_FREQ_TIMES=y - CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y - CONFIG_CPU_FREQ_GOV_POWERSAVE=y - CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y --CONFIG_CPUFREQ_DT=y - CONFIG_ARM_SCPI_CPUFREQ=y - CONFIG_ARM_SCMI_CPUFREQ=y - CONFIG_ARM_SCMI_PROTOCOL=y -@@ -90,10 +88,6 @@ CONFIG_INET_ESP=y - # CONFIG_INET_XFRM_MODE_BEET is not set - CONFIG_INET_UDP_DIAG=y - CONFIG_INET_DIAG_DESTROY=y --CONFIG_TCP_CONG_ADVANCED=y --# CONFIG_TCP_CONG_BIC is not set --# CONFIG_TCP_CONG_WESTWOOD is not set --# CONFIG_TCP_CONG_HTCP is not set - CONFIG_IPV6_ROUTER_PREF=y - CONFIG_IPV6_ROUTE_INFO=y - CONFIG_IPV6_OPTIMISTIC_DAD=y -@@ -191,10 +185,8 @@ CONFIG_RFKILL=y - CONFIG_PCI=y - CONFIG_PCI_HOST_GENERIC=y - # CONFIG_UEVENT_HELPER is not set --CONFIG_DEVTMPFS=y - # CONFIG_ALLOW_DEV_COREDUMP is not set - CONFIG_DEBUG_DEVRES=y --CONFIG_OF_UNITTEST=y - CONFIG_ZRAM=y - CONFIG_BLK_DEV_LOOP=y - CONFIG_BLK_DEV_RAM=y -@@ -214,8 +206,6 @@ CONFIG_DM_VERITY_AVB=y - CONFIG_DM_VERITY_FEC=y - CONFIG_DM_BOW=y - CONFIG_NETDEVICES=y --CONFIG_NETCONSOLE=y --CONFIG_NETCONSOLE_DYNAMIC=y - CONFIG_TUN=y - CONFIG_VIRTIO_NET=y - # CONFIG_ETHERNET is not set -@@ -366,7 +356,6 @@ CONFIG_XZ_DEC=y - CONFIG_PRINTK_TIME=y - CONFIG_DEBUG_INFO=y - # CONFIG_ENABLE_MUST_CHECK is not set --CONFIG_FRAME_WARN=1024 - # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set - CONFIG_MAGIC_SYSRQ=y - CONFIG_DEBUG_STACK_USAGE=y -@@ -375,5 +364,4 @@ CONFIG_SOFTLOCKUP_DETECTOR=y - # CONFIG_DETECT_HUNG_TASK is not set - CONFIG_PANIC_TIMEOUT=5 - CONFIG_SCHEDSTATS=y --CONFIG_RCU_CPU_STALL_TIMEOUT=60 - # CONFIG_RUNTIME_TESTING_MENU is not set diff --git a/patches/ANDROID-gki_defconfig-Remove-recommended-configs-not-present-on-b1c1.patch b/patches/ANDROID-gki_defconfig-Remove-recommended-configs-not-present-on-b1c1.patch deleted file mode 100644 index 26b735eedcaa..000000000000 --- a/patches/ANDROID-gki_defconfig-Remove-recommended-configs-not-present-on-b1c1.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Sat, 4 May 2019 17:45:04 -0700 -Subject: ANDROID: gki_defconfig: Remove recommended configs not present on - b1c1 - -Enable: -CONFIG_USB because it's required. -CONFIG_OVERLAY_FS, CONFIG_ARM64_SW_TTBR0_PAN because cuttlefish doesn't -boot without these. - -CONFIG_PSI, CONFIG_DM_BOW, CONFIG_HIDRAW, CONFIG_USB_HIDDEV, -CONFIG_MSDOS_FS, CONFIG_PANIC_TIMEOUT=5 are not strictly required, but -seem appropriate for a "generic" kernel. - -Note that cuttlefish-specific modules, that are neither required nor -recommended, are still enabled. - -Test: boot cuttlefish on a arm64 machine -Signed-off-by: Tri Vo -(partially cherry picked from commit 37381a5b77c8496a5bc5827ddbaf106e51d2c0c0) ---- - arch/arm64/configs/gki_defconfig | 68 +------------------------------- - 1 file changed, 1 insertion(+), 67 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index a87cf1871f12..a747e222db8e 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -3,7 +3,6 @@ CONFIG_NO_HZ=y - CONFIG_HIGH_RES_TIMERS=y - CONFIG_PREEMPT=y - CONFIG_TASKSTATS=y --CONFIG_TASK_DELAY_ACCT=y - CONFIG_TASK_XACCT=y - CONFIG_TASK_IO_ACCOUNTING=y - CONFIG_PSI=y -@@ -49,7 +48,6 @@ CONFIG_COMPAT=y - CONFIG_PM_WAKELOCKS=y - CONFIG_PM_WAKELOCKS_LIMIT=0 - # CONFIG_PM_WAKELOCKS_GC is not set --CONFIG_PM_DEBUG=y - CONFIG_ENERGY_MODEL=y - CONFIG_CPU_IDLE=y - CONFIG_ARM_CPUIDLE=y -@@ -176,7 +174,6 @@ CONFIG_IP6_NF_RAW=y - CONFIG_L2TP=y - CONFIG_NET_SCHED=y - CONFIG_NET_SCH_HTB=y --CONFIG_NET_SCH_NETEM=y - CONFIG_NET_SCH_INGRESS=y - CONFIG_NET_CLS_U32=y - CONFIG_NET_CLS_BPF=y -@@ -259,15 +256,6 @@ CONFIG_INPUT_EVDEV=y - # CONFIG_INPUT_KEYBOARD is not set - # CONFIG_INPUT_MOUSE is not set - CONFIG_INPUT_JOYSTICK=y --CONFIG_JOYSTICK_XPAD=y --CONFIG_JOYSTICK_XPAD_FF=y --CONFIG_JOYSTICK_XPAD_LEDS=y --CONFIG_INPUT_TABLET=y --CONFIG_TABLET_USB_ACECAD=y --CONFIG_TABLET_USB_AIPTEK=y --CONFIG_TABLET_USB_GTCO=y --CONFIG_TABLET_USB_HANWANG=y --CONFIG_TABLET_USB_KBTAB=y - CONFIG_INPUT_MISC=y - CONFIG_INPUT_UINPUT=y - # CONFIG_VT is not set -@@ -309,65 +297,13 @@ CONFIG_SND_INTEL8X0=y - # CONFIG_SND_USB is not set - CONFIG_HIDRAW=y - CONFIG_UHID=y --CONFIG_HID_A4TECH=y --CONFIG_HID_ACRUX=y --CONFIG_HID_ACRUX_FF=y - CONFIG_HID_APPLE=y --CONFIG_HID_BELKIN=y --CONFIG_HID_CHERRY=y --CONFIG_HID_CHICONY=y --CONFIG_HID_PRODIKEYS=y --CONFIG_HID_CYPRESS=y --CONFIG_HID_DRAGONRISE=y --CONFIG_DRAGONRISE_FF=y --CONFIG_HID_EMS_FF=y - CONFIG_HID_ELECOM=y --CONFIG_HID_EZKEY=y --CONFIG_HID_HOLTEK=y --CONFIG_HID_KEYTOUCH=y --CONFIG_HID_KYE=y --CONFIG_HID_UCLOGIC=y --CONFIG_HID_WALTOP=y --CONFIG_HID_GYRATION=y --CONFIG_HID_TWINHAN=y --CONFIG_HID_KENSINGTON=y --CONFIG_HID_LCPOWER=y --CONFIG_HID_LOGITECH=y --CONFIG_HID_LOGITECH_DJ=y --CONFIG_LOGITECH_FF=y --CONFIG_LOGIRUMBLEPAD2_FF=y --CONFIG_LOGIG940_FF=y - CONFIG_HID_MAGICMOUSE=y - CONFIG_HID_MICROSOFT=y --CONFIG_HID_MONTEREY=y - CONFIG_HID_MULTITOUCH=y --CONFIG_HID_NTRIG=y --CONFIG_HID_ORTEK=y --CONFIG_HID_PANTHERLORD=y --CONFIG_PANTHERLORD_FF=y --CONFIG_HID_PETALYNX=y --CONFIG_HID_PICOLCD=y --CONFIG_HID_PRIMAX=y --CONFIG_HID_ROCCAT=y --CONFIG_HID_SAITEK=y --CONFIG_HID_SAMSUNG=y --CONFIG_HID_SONY=y --CONFIG_HID_SPEEDLINK=y --CONFIG_HID_SUNPLUS=y --CONFIG_HID_GREENASIA=y --CONFIG_GREENASIA_FF=y --CONFIG_HID_SMARTJOYPLUS=y --CONFIG_SMARTJOYPLUS_FF=y --CONFIG_HID_TIVO=y --CONFIG_HID_TOPSEED=y --CONFIG_HID_THRUSTMASTER=y --CONFIG_HID_WACOM=y --CONFIG_HID_WIIMOTE=y --CONFIG_HID_ZEROPLUS=y --CONFIG_HID_ZYDACRON=y - CONFIG_USB_HIDDEV=y --CONFIG_USB_ANNOUNCE_NEW_DEVICES=y --CONFIG_USB_EHCI_HCD=y -+CONFIG_USB=y - CONFIG_USB_GADGET=y - CONFIG_USB_CONFIGFS=y - CONFIG_USB_CONFIGFS_UEVENT=y -@@ -418,7 +354,6 @@ CONFIG_PSTORE_RAM=y - CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y - CONFIG_SECURITY=y - CONFIG_SECURITY_NETWORK=y --CONFIG_LSM_MMAP_MIN_ADDR=65536 - CONFIG_HARDENED_USERCOPY=y - CONFIG_SECURITY_SELINUX=y - CONFIG_CRYPTO_ADIANTUM=y -@@ -441,5 +376,4 @@ CONFIG_SOFTLOCKUP_DETECTOR=y - CONFIG_PANIC_TIMEOUT=5 - CONFIG_SCHEDSTATS=y - CONFIG_RCU_CPU_STALL_TIMEOUT=60 --CONFIG_ENABLE_DEFAULT_TRACERS=y - # CONFIG_RUNTIME_TESTING_MENU is not set diff --git a/patches/ANDROID-gki_defconfig-common-configs-for-device-DLKMs.patch b/patches/ANDROID-gki_defconfig-common-configs-for-device-DLKMs.patch deleted file mode 100644 index 4453ed6a43cd..000000000000 --- a/patches/ANDROID-gki_defconfig-common-configs-for-device-DLKMs.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Sat, 11 May 2019 16:48:08 -0700 -Subject: ANDROID: gki_defconfig: common configs for device DLKMs - -Test: boot arm64 cuttlefish -Signed-off-by: Tri Vo -(partially cherry picked from commit 6742f3f75046867373ac782e709681c98f72a744) ---- - arch/arm64/configs/gki_defconfig | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 41a892ca324d..cc9ecd83a69c 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -269,22 +269,30 @@ CONFIG_HW_RANDOM_VIRTIO=y - # CONFIG_DEVPORT is not set - # CONFIG_I2C_COMPAT is not set - # CONFIG_I2C_HELPER_AUTO is not set -+CONFIG_SPMI=y -+CONFIG_GPIOLIB=y - # CONFIG_HWMON is not set - CONFIG_THERMAL=y -+CONFIG_THERMAL_GOV_USER_SPACE=y - CONFIG_CPU_THERMAL=y -+CONFIG_DEVFREQ_THERMAL=y -+CONFIG_REGULATOR=y - CONFIG_MEDIA_SUPPORT=y -+CONFIG_MEDIA_CAMERA_SUPPORT=y - # CONFIG_VGA_ARB is not set - CONFIG_DRM=y - # CONFIG_DRM_FBDEV_EMULATION is not set - CONFIG_DRM_VIRTIO_GPU=y -+CONFIG_BACKLIGHT_LCD_SUPPORT=y -+CONFIG_BACKLIGHT_CLASS_DEVICE=y - CONFIG_SOUND=y - CONFIG_SND=y - CONFIG_SND_HRTIMER=y -+CONFIG_SND_DYNAMIC_MINORS=y - # CONFIG_SND_SUPPORT_OLD_API is not set - # CONFIG_SND_VERBOSE_PROCFS is not set - # CONFIG_SND_DRIVERS is not set - CONFIG_SND_INTEL8X0=y --# CONFIG_SND_USB is not set - CONFIG_HIDRAW=y - CONFIG_UHID=y - CONFIG_HID_APPLE=y -@@ -305,6 +313,9 @@ CONFIG_MMC=y - # CONFIG_PWRSEQ_EMMC is not set - # CONFIG_PWRSEQ_SIMPLE is not set - # CONFIG_MMC_BLOCK is not set -+CONFIG_NEW_LEDS=y -+CONFIG_LEDS_CLASS=y -+CONFIG_LEDS_TRIGGERS=y - CONFIG_RTC_CLASS=y - # CONFIG_RTC_SYSTOHC is not set - CONFIG_RTC_DRV_PL030=y -@@ -321,7 +332,9 @@ CONFIG_ANDROID_VSOC=y - CONFIG_ION=y - CONFIG_COMMON_CLK_SCPI=y - CONFIG_MAILBOX=y --# CONFIG_IOMMU_SUPPORT is not set -+CONFIG_PM_DEVFREQ=y -+CONFIG_PWM=y -+CONFIG_GENERIC_PHY=y - CONFIG_ANDROID=y - CONFIG_ANDROID_BINDER_IPC=y - CONFIG_EXT4_FS=y -@@ -352,6 +365,7 @@ CONFIG_CRYPTO_LZ4=y - CONFIG_CRYPTO_ZSTD=y - CONFIG_CRYPTO_ANSI_CPRNG=y - CONFIG_CRYPTO_DEV_VIRTIO=y -+CONFIG_CRC8=y - CONFIG_XZ_DEC=y - CONFIG_PRINTK_TIME=y - CONFIG_DEBUG_INFO=y diff --git a/patches/ANDROID-gki_defconfig-disable-BRIDGE_NETFILTER.patch b/patches/ANDROID-gki_defconfig-disable-BRIDGE_NETFILTER.patch deleted file mode 100644 index 9c8776f20068..000000000000 --- a/patches/ANDROID-gki_defconfig-disable-BRIDGE_NETFILTER.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Wed, 17 Jul 2019 15:25:54 -0700 -Subject: ANDROID: gki_defconfig: disable BRIDGE_NETFILTER - -This config is explicitly disabled on Pixel 3. - -Change-Id: I126e5222180e3880a71c0f78b99276b0157ef4c8 -Signed-off-by: Tri Vo ---- - arch/arm64/configs/gki_defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 45644397a2d7..140804afdd32 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -101,6 +101,7 @@ CONFIG_IPV6_MIP6=y - CONFIG_IPV6_VTI=y - CONFIG_IPV6_MULTIPLE_TABLES=y - CONFIG_NETFILTER=y -+# CONFIG_BRIDGE_NETFILTER is not set - CONFIG_NF_CONNTRACK=y - CONFIG_NF_CONNTRACK_SECMARK=y - CONFIG_NF_CONNTRACK_EVENTS=y diff --git a/patches/ANDROID-gki_defconfig-disable-CONFIG_LCD_CLASS_DEVICE-module.patch b/patches/ANDROID-gki_defconfig-disable-CONFIG_LCD_CLASS_DEVICE-module.patch deleted file mode 100644 index 029c7e8a77f7..000000000000 --- a/patches/ANDROID-gki_defconfig-disable-CONFIG_LCD_CLASS_DEVICE-module.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Tue, 14 May 2019 17:32:43 -0700 -Subject: ANDROID: gki_defconfig: disable CONFIG_LCD_CLASS_DEVICE module - -CONFIG_LCD_CLASS_DEVICE is set to "m" by default when -CONFIG_BACKLIGHT_LCD_SUPPORT is set. We don't need lcd.ko though. ---- - arch/arm64/configs/gki_defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index cc9ecd83a69c..4b17f0f9d0ae 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -284,6 +284,7 @@ CONFIG_DRM=y - # CONFIG_DRM_FBDEV_EMULATION is not set - CONFIG_DRM_VIRTIO_GPU=y - CONFIG_BACKLIGHT_LCD_SUPPORT=y -+# CONFIG_LCD_CLASS_DEVICE is not set - CONFIG_BACKLIGHT_CLASS_DEVICE=y - CONFIG_SOUND=y - CONFIG_SND=y diff --git a/patches/ANDROID-gki_defconfig-disable-IP_PNP-ECRYPT_FS.patch b/patches/ANDROID-gki_defconfig-disable-IP_PNP-ECRYPT_FS.patch deleted file mode 100644 index ba50ac2937b6..000000000000 --- a/patches/ANDROID-gki_defconfig-disable-IP_PNP-ECRYPT_FS.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Thu, 8 Aug 2019 17:06:26 -0700 -Subject: ANDROID: gki_defconfig: disable IP_PNP, ECRYPT_FS - -Neither are necessary on android devices. - -Change-Id: I61008f47c53fb88fcdbdcd889346a214b23246ad -Signed-off-by: Tri Vo ---- - arch/arm64/configs/gki_defconfig | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 43a1fea94c6a..539f42574383 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -87,7 +87,6 @@ CONFIG_INET=y - CONFIG_IP_MULTICAST=y - CONFIG_IP_ADVANCED_ROUTER=y - CONFIG_IP_MULTIPLE_TABLES=y --CONFIG_IP_PNP=y - CONFIG_NET_IPGRE_DEMUX=y - CONFIG_NET_IPVTI=y - CONFIG_INET_ESP=y -@@ -379,7 +378,6 @@ CONFIG_MSDOS_FS=y - CONFIG_VFAT_FS=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y --CONFIG_ECRYPT_FS=y - CONFIG_SDCARD_FS=y - CONFIG_PSTORE=y - CONFIG_PSTORE_CONSOLE=y diff --git a/patches/ANDROID-gki_defconfig-enable-CMA-and-increase-CMA_AREAS.patch b/patches/ANDROID-gki_defconfig-enable-CMA-and-increase-CMA_AREAS.patch deleted file mode 100644 index 1132f5b9cece..000000000000 --- a/patches/ANDROID-gki_defconfig-enable-CMA-and-increase-CMA_AREAS.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Mon, 3 Jun 2019 11:50:28 -0700 -Subject: ANDROID: gki_defconfig: enable CMA and increase CMA_AREAS - -Fixes: 134378085 -Test: boot arm64 cuttlefish -Signed-off-by: Tri Vo ---- - arch/arm64/configs/gki_defconfig | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index c9720858fd9a..bf15919ba7e7 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -66,6 +66,8 @@ CONFIG_MODVERSIONS=y - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set - # CONFIG_SPARSEMEM_VMEMMAP is not set - CONFIG_TRANSPARENT_HUGEPAGE=y -+CONFIG_CMA=y -+CONFIG_CMA_AREAS=16 - CONFIG_ZSMALLOC=y - CONFIG_NET=y - CONFIG_PACKET=y diff --git a/patches/ANDROID-gki_defconfig-enable-CONFIG_NLS_.patch b/patches/ANDROID-gki_defconfig-enable-CONFIG_NLS_.patch deleted file mode 100644 index 9f5b623ef1bd..000000000000 --- a/patches/ANDROID-gki_defconfig-enable-CONFIG_NLS_.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Tue, 8 Oct 2019 15:12:37 -0700 -Subject: ANDROID: gki_defconfig: enable CONFIG_NLS_* - -CONFIG_NLS_CODEPAGE_437 and CONFIG_NLS_ISO8859_1 are needed by cuttlefish -to pass the CTS test - StorageManagerTest#testMountAndUnmountObbNormal - -Adding the remaining 47 NLS Configs to account for possible i18n -requirements not caught by CTS/VTS - -Bug: 138199351 -Change-Id: I897873c8454f8329f4dc53d9af71907ba71790b7 -Signed-off-by: Ram Muthiah ---- - arch/arm64/configs/gki_defconfig | 49 ++++++++++++++++++++++++++++++++ - arch/x86/configs/gki_defconfig | 49 ++++++++++++++++++++++++++++++++ - 2 files changed, 98 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 0b7669f8fedd..29cc5898a871 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -391,6 +391,55 @@ CONFIG_SDCARD_FS=y - CONFIG_PSTORE=y - CONFIG_PSTORE_CONSOLE=y - CONFIG_PSTORE_RAM=y -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=y -+CONFIG_NLS_CODEPAGE_775=y -+CONFIG_NLS_CODEPAGE_850=y -+CONFIG_NLS_CODEPAGE_852=y -+CONFIG_NLS_CODEPAGE_855=y -+CONFIG_NLS_CODEPAGE_857=y -+CONFIG_NLS_CODEPAGE_860=y -+CONFIG_NLS_CODEPAGE_861=y -+CONFIG_NLS_CODEPAGE_862=y -+CONFIG_NLS_CODEPAGE_863=y -+CONFIG_NLS_CODEPAGE_864=y -+CONFIG_NLS_CODEPAGE_865=y -+CONFIG_NLS_CODEPAGE_866=y -+CONFIG_NLS_CODEPAGE_869=y -+CONFIG_NLS_CODEPAGE_936=y -+CONFIG_NLS_CODEPAGE_950=y -+CONFIG_NLS_CODEPAGE_932=y -+CONFIG_NLS_CODEPAGE_949=y -+CONFIG_NLS_CODEPAGE_874=y -+CONFIG_NLS_ISO8859_8=y -+CONFIG_NLS_CODEPAGE_1250=y -+CONFIG_NLS_CODEPAGE_1251=y -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_NLS_ISO8859_2=y -+CONFIG_NLS_ISO8859_3=y -+CONFIG_NLS_ISO8859_4=y -+CONFIG_NLS_ISO8859_5=y -+CONFIG_NLS_ISO8859_6=y -+CONFIG_NLS_ISO8859_7=y -+CONFIG_NLS_ISO8859_9=y -+CONFIG_NLS_ISO8859_13=y -+CONFIG_NLS_ISO8859_14=y -+CONFIG_NLS_ISO8859_15=y -+CONFIG_NLS_KOI8_R=y -+CONFIG_NLS_KOI8_U=y -+CONFIG_NLS_MAC_ROMAN=y -+CONFIG_NLS_MAC_CELTIC=y -+CONFIG_NLS_MAC_CENTEURO=y -+CONFIG_NLS_MAC_CROATIAN=y -+CONFIG_NLS_MAC_CYRILLIC=y -+CONFIG_NLS_MAC_GAELIC=y -+CONFIG_NLS_MAC_GREEK=y -+CONFIG_NLS_MAC_ICELAND=y -+CONFIG_NLS_MAC_INUIT=y -+CONFIG_NLS_MAC_ROMANIAN=y -+CONFIG_NLS_MAC_TURKISH=y -+CONFIG_NLS_UTF8=y - CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y - CONFIG_SECURITY=y - CONFIG_SECURITY_NETWORK=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 78283ea8c1c8..5059dcaf01bb 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -324,6 +324,55 @@ CONFIG_SDCARD_FS=y - CONFIG_PSTORE=y - CONFIG_PSTORE_CONSOLE=y - CONFIG_PSTORE_RAM=y -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_CODEPAGE_737=y -+CONFIG_NLS_CODEPAGE_775=y -+CONFIG_NLS_CODEPAGE_850=y -+CONFIG_NLS_CODEPAGE_852=y -+CONFIG_NLS_CODEPAGE_855=y -+CONFIG_NLS_CODEPAGE_857=y -+CONFIG_NLS_CODEPAGE_860=y -+CONFIG_NLS_CODEPAGE_861=y -+CONFIG_NLS_CODEPAGE_862=y -+CONFIG_NLS_CODEPAGE_863=y -+CONFIG_NLS_CODEPAGE_864=y -+CONFIG_NLS_CODEPAGE_865=y -+CONFIG_NLS_CODEPAGE_866=y -+CONFIG_NLS_CODEPAGE_869=y -+CONFIG_NLS_CODEPAGE_936=y -+CONFIG_NLS_CODEPAGE_950=y -+CONFIG_NLS_CODEPAGE_932=y -+CONFIG_NLS_CODEPAGE_949=y -+CONFIG_NLS_CODEPAGE_874=y -+CONFIG_NLS_ISO8859_8=y -+CONFIG_NLS_CODEPAGE_1250=y -+CONFIG_NLS_CODEPAGE_1251=y -+CONFIG_NLS_ASCII=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_NLS_ISO8859_2=y -+CONFIG_NLS_ISO8859_3=y -+CONFIG_NLS_ISO8859_4=y -+CONFIG_NLS_ISO8859_5=y -+CONFIG_NLS_ISO8859_6=y -+CONFIG_NLS_ISO8859_7=y -+CONFIG_NLS_ISO8859_9=y -+CONFIG_NLS_ISO8859_13=y -+CONFIG_NLS_ISO8859_14=y -+CONFIG_NLS_ISO8859_15=y -+CONFIG_NLS_KOI8_R=y -+CONFIG_NLS_KOI8_U=y -+CONFIG_NLS_MAC_ROMAN=y -+CONFIG_NLS_MAC_CELTIC=y -+CONFIG_NLS_MAC_CENTEURO=y -+CONFIG_NLS_MAC_CROATIAN=y -+CONFIG_NLS_MAC_CYRILLIC=y -+CONFIG_NLS_MAC_GAELIC=y -+CONFIG_NLS_MAC_GREEK=y -+CONFIG_NLS_MAC_ICELAND=y -+CONFIG_NLS_MAC_INUIT=y -+CONFIG_NLS_MAC_ROMANIAN=y -+CONFIG_NLS_MAC_TURKISH=y -+CONFIG_NLS_UTF8=y - CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y - CONFIG_SECURITY=y - CONFIG_SECURITY_NETWORK=y diff --git a/patches/ANDROID-gki_defconfig-enable-CONFIG_PARAVIRT-and-CONFIG_HYPERVISOR_GUEST.patch b/patches/ANDROID-gki_defconfig-enable-CONFIG_PARAVIRT-and-CONFIG_HYPERVISOR_GUEST.patch deleted file mode 100644 index 7c8f54ea5c5c..000000000000 --- a/patches/ANDROID-gki_defconfig-enable-CONFIG_PARAVIRT-and-CONFIG_HYPERVISOR_GUEST.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Thu, 10 Oct 2019 08:45:15 -0700 -Subject: ANDROID: gki_defconfig: enable CONFIG_PARAVIRT and - CONFIG_HYPERVISOR_GUEST - -CONFIG_HYPERVISOR_GUEST is needed by cuttlefish to pass the CTS Bionic tests: -clock_getres_CLOCK_MONOTONIC, clock_getres_CLOCK_REALTIME, and -clock_getres_CLOCK_BOOTTIME - -Bug: 138199351 -Change-Id: I3e209035cdd7a29e020078f8aba567d9c8446347 -Signed-off-by: Ram Muthiah ---- - arch/x86/configs/gki_defconfig | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 5059dcaf01bb..0e23b0cc3a8c 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -37,6 +37,8 @@ CONFIG_SLAB_FREELIST_RANDOM=y - CONFIG_SLAB_FREELIST_HARDENED=y - CONFIG_PROFILING=y - CONFIG_SMP=y -+CONFIG_HYPERVISOR_GUEST=y -+CONFIG_PARAVIRT=y - CONFIG_NR_CPUS=32 - CONFIG_EFI=y - CONFIG_PM_WAKELOCKS=y diff --git a/patches/ANDROID-gki_defconfig-enable-CONFIG_QCOM_-COMMAND_DB-RPMH-PDC.patch b/patches/ANDROID-gki_defconfig-enable-CONFIG_QCOM_-COMMAND_DB-RPMH-PDC.patch deleted file mode 100644 index 0f91c2fb992b..000000000000 --- a/patches/ANDROID-gki_defconfig-enable-CONFIG_QCOM_-COMMAND_DB-RPMH-PDC.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Thu, 29 Aug 2019 14:04:15 -0700 -Subject: ANDROID: gki_defconfig: enable CONFIG_QCOM_{COMMAND_DB,RPMH,PDC} - -CONFIG_ARCH_QCOM is a dependency of the above and selects -CONFIG_{PINCTRL, REGULATOR, TMPFS}. - -Bug: 133441279 -Bug: 133441092 -Bug: 133440650 -Change-Id: I22c37946ec3a62ccbd3fa65bbc09076964d86475 -Signed-off-by: Tri Vo ---- - arch/arm64/configs/gki_defconfig | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 604b97841737..6aae6d55e96c 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -36,6 +36,7 @@ CONFIG_EMBEDDED=y - CONFIG_SLAB_FREELIST_RANDOM=y - CONFIG_SLAB_FREELIST_HARDENED=y - CONFIG_PROFILING=y -+CONFIG_ARCH_QCOM=y - CONFIG_SCHED_MC=y - CONFIG_NR_CPUS=32 - CONFIG_SECCOMP=y -@@ -279,7 +280,6 @@ CONFIG_HW_RANDOM_VIRTIO=y - # CONFIG_I2C_HELPER_AUTO is not set - CONFIG_SPI=y - CONFIG_SPMI=y --CONFIG_PINCTRL=y - CONFIG_PINCTRL_AMD=y - CONFIG_POWER_AVS=y - # CONFIG_HWMON is not set -@@ -290,7 +290,6 @@ CONFIG_DEVFREQ_THERMAL=y - CONFIG_WATCHDOG=y - CONFIG_MFD_ACT8945A=y - CONFIG_MFD_SYSCON=y --CONFIG_REGULATOR=y - CONFIG_MEDIA_SUPPORT=y - CONFIG_MEDIA_CAMERA_SUPPORT=y - CONFIG_MEDIA_CONTROLLER=y -@@ -357,12 +356,15 @@ CONFIG_COMMON_CLK_SCPI=y - CONFIG_HWSPINLOCK=y - CONFIG_MAILBOX=y - CONFIG_ARM_SMMU=y -+CONFIG_QCOM_COMMAND_DB=y -+CONFIG_QCOM_RPMH=y - CONFIG_DEVFREQ_GOV_PERFORMANCE=y - CONFIG_DEVFREQ_GOV_POWERSAVE=y - CONFIG_DEVFREQ_GOV_USERSPACE=y - CONFIG_DEVFREQ_GOV_PASSIVE=y - CONFIG_EXTCON=y - CONFIG_PWM=y -+CONFIG_QCOM_PDC=y - CONFIG_GENERIC_PHY=y - CONFIG_RAS=y - CONFIG_ANDROID=y -@@ -380,7 +382,6 @@ CONFIG_FUSE_FS=y - CONFIG_OVERLAY_FS=y - CONFIG_MSDOS_FS=y - CONFIG_VFAT_FS=y --CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y - # CONFIG_EFIVAR_FS is not set - CONFIG_SDCARD_FS=y diff --git a/patches/ANDROID-gki_defconfig-enable-CONFIG_SPARSEMEM_VMEMMAP.patch b/patches/ANDROID-gki_defconfig-enable-CONFIG_SPARSEMEM_VMEMMAP.patch deleted file mode 100644 index 899cf5416558..000000000000 --- a/patches/ANDROID-gki_defconfig-enable-CONFIG_SPARSEMEM_VMEMMAP.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mark Salyzyn -Date: Thu, 29 Aug 2019 08:00:26 -0700 -Subject: ANDROID: gki_defconfig enable CONFIG_SPARSEMEM_VMEMMAP - -Legacy Ion driver and SPARSEMEM for carveout regions results -in invalid page structures breaking page_to_pfn(). This can -be temporarily resolved with SPARSEMEM_VMEMMAP until the Ion -driver is refactored and can be reinvestigated. - -At that time if it can be solved, or maybe correct this issue -utilizing less resources than SPARSEMEM_VMEMMAP requires. The -ABI does not change so we have the flexibility to adjust this -configuration. - -Signed-off-by: Mark Salyzyn -Bug: 138851285 -Bug: 138149732 -Test: ABI_DEFINITION=common/abi_gki_aarch64.xml \ - BUILD_CONFIG=common/build.config.gki.aarch64 ./build/build_abi.sh -Change-Id: I25cc8ebe9e25260b9869c5e8d8667b280f83ca51 ---- - arch/arm64/configs/gki_defconfig | 1 - - arch/x86/configs/gki_defconfig | 1 - - 2 files changed, 2 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 006692f065d4..604b97841737 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -72,7 +72,6 @@ CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set --# CONFIG_SPARSEMEM_VMEMMAP is not set - CONFIG_MEMORY_HOTPLUG=y - CONFIG_TRANSPARENT_HUGEPAGE=y - CONFIG_CMA=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index ed8296e953ed..e86cd1009a67 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -48,7 +48,6 @@ CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set --# CONFIG_SPARSEMEM_VMEMMAP is not set - CONFIG_TRANSPARENT_HUGEPAGE=y - CONFIG_CMA=y - CONFIG_CMA_AREAS=16 diff --git a/patches/ANDROID-gki_defconfig-enable-CONFIG_TIPC.patch b/patches/ANDROID-gki_defconfig-enable-CONFIG_TIPC.patch deleted file mode 100644 index 82ab1f640a76..000000000000 --- a/patches/ANDROID-gki_defconfig-enable-CONFIG_TIPC.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Fri, 23 Aug 2019 10:57:25 -0700 -Subject: ANDROID: gki_defconfig: enable CONFIG_TIPC - -Test: n/a -Change-Id: If068edf432bd2574a9ca8257e5a4f43731328317 -Signed-off-by: Tri Vo ---- - arch/arm64/configs/gki_defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 73acbe383203..b70d608b1ee6 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -170,6 +170,7 @@ CONFIG_IP6_NF_FILTER=y - CONFIG_IP6_NF_TARGET_REJECT=y - CONFIG_IP6_NF_MANGLE=y - CONFIG_IP6_NF_RAW=y -+CONFIG_TIPC=y - CONFIG_L2TP=y - CONFIG_BRIDGE=y - CONFIG_NET_SCHED=y diff --git a/patches/ANDROID-gki_defconfig-enable-CONFIG_UIO.patch b/patches/ANDROID-gki_defconfig-enable-CONFIG_UIO.patch deleted file mode 100644 index 27f513271d2c..000000000000 --- a/patches/ANDROID-gki_defconfig-enable-CONFIG_UIO.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Wed, 18 Sep 2019 14:07:28 -0700 -Subject: ANDROID: gki_defconfig: enable CONFIG_UIO - -Bug: 135666008 -Change-Id: I1fac71548c2f442d3622ff068928662d1ba6e3dd -Signed-off-by: Tri Vo ---- - arch/arm64/configs/gki_defconfig | 1 + - arch/x86/configs/gki_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 440173b3c301..f65b544d17a4 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -337,6 +337,7 @@ CONFIG_RTC_CLASS=y - CONFIG_RTC_DRV_PL030=y - CONFIG_RTC_DRV_PL031=y - CONFIG_DMADEVICES=y -+CONFIG_UIO=y - CONFIG_VIRTIO_PCI=y - # CONFIG_VIRTIO_PCI_LEGACY is not set - CONFIG_VIRTIO_INPUT=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index c206a2d0f9cf..3e8f580e0bde 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -287,6 +287,7 @@ CONFIG_LEDS_TRIGGERS=y - CONFIG_RTC_CLASS=y - # CONFIG_RTC_SYSTOHC is not set - CONFIG_RTC_DRV_TEST=m -+CONFIG_UIO=y - CONFIG_VIRTIO_PCI=m - CONFIG_VIRTIO_INPUT=m - CONFIG_VIRTIO_MMIO=m diff --git a/patches/ANDROID-gki_defconfig-enable-DMA_CMA.patch b/patches/ANDROID-gki_defconfig-enable-DMA_CMA.patch deleted file mode 100644 index 0fae24345dfd..000000000000 --- a/patches/ANDROID-gki_defconfig-enable-DMA_CMA.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Wed, 12 Jun 2019 15:26:49 -0700 -Subject: ANDROID: gki_defconfig: enable DMA_CMA - -And update ABI representation. - -Fixes: 134916881 -Test: boot arm64 cuttlefish -Signed-off-by: Tri Vo -Change-Id: Id0d270f510aa0a06dc5a082ef35c3d969b72cc35 ---- - arch/arm64/configs/gki_defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index ef79e45cae16..9bc2782661dc 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -373,6 +373,7 @@ CONFIG_CRYPTO_ANSI_CPRNG=y - CONFIG_CRYPTO_DEV_VIRTIO=y - CONFIG_CRC8=y - CONFIG_XZ_DEC=y -+CONFIG_DMA_CMA=y - CONFIG_PRINTK_TIME=y - CONFIG_DEBUG_INFO=y - # CONFIG_ENABLE_MUST_CHECK is not set diff --git a/patches/ANDROID-gki_defconfig-enable-REGULATOR.patch b/patches/ANDROID-gki_defconfig-enable-REGULATOR.patch deleted file mode 100644 index 6d9f0f2670a9..000000000000 --- a/patches/ANDROID-gki_defconfig-enable-REGULATOR.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Tue, 8 Oct 2019 12:38:34 -0700 -Subject: ANDROID: gki_defconfig: enable REGULATOR - -Fixes: 142334529 -Change-Id: If2e17aec00c2f2202f6f9203192afcd8e12228a6 -Signed-off-by: Tri Vo ---- - arch/arm64/configs/gki_defconfig | 1 + - arch/x86/configs/gki_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 9e3b34fa8b64..0b7669f8fedd 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -293,6 +293,7 @@ CONFIG_DEVFREQ_THERMAL=y - CONFIG_WATCHDOG=y - CONFIG_MFD_ACT8945A=y - CONFIG_MFD_SYSCON=y -+CONFIG_REGULATOR=y - CONFIG_MEDIA_SUPPORT=y - CONFIG_MEDIA_CAMERA_SUPPORT=y - CONFIG_MEDIA_CONTROLLER=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index f539970bf631..78283ea8c1c8 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -252,6 +252,7 @@ CONFIG_GPIOLIB=y - # CONFIG_HWMON is not set - CONFIG_DEVFREQ_THERMAL=y - # CONFIG_X86_PKG_TEMP_THERMAL is not set -+CONFIG_REGULATOR=y - CONFIG_MEDIA_SUPPORT=y - CONFIG_MEDIA_CAMERA_SUPPORT=y - CONFIG_DRM=y diff --git a/patches/ANDROID-gki_defconfig-enable-SLAB_FREELIST_RANDOM-SLAB_FREELIST_HARDENED.patch b/patches/ANDROID-gki_defconfig-enable-SLAB_FREELIST_RANDOM-SLAB_FREELIST_HARDENED.patch deleted file mode 100644 index 925a152e28d1..000000000000 --- a/patches/ANDROID-gki_defconfig-enable-SLAB_FREELIST_RANDOM-SLAB_FREELIST_HARDENED.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Mon, 3 Jun 2019 12:54:46 -0700 -Subject: ANDROID: gki_defconfig: enable SLAB_FREELIST_RANDOM, - SLAB_FREELIST_HARDENED - -Security hardening - -Fixes: 134087016 -Test: boot arm64 cuttlefish -Signed-off-by: Tri Vo ---- - arch/arm64/configs/gki_defconfig | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index bf15919ba7e7..ef79e45cae16 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -31,6 +31,8 @@ CONFIG_EMBEDDED=y - # CONFIG_VM_EVENT_COUNTERS is not set - # CONFIG_COMPAT_BRK is not set - # CONFIG_SLAB_MERGE_DEFAULT is not set -+CONFIG_SLAB_FREELIST_RANDOM=y -+CONFIG_SLAB_FREELIST_HARDENED=y - CONFIG_PROFILING=y - CONFIG_SCHED_MC=y - CONFIG_SECCOMP=y diff --git a/patches/ANDROID-gki_defconfig-enable-accelerated-AES-and-SHA-256.patch b/patches/ANDROID-gki_defconfig-enable-accelerated-AES-and-SHA-256.patch deleted file mode 100644 index b628bb68957f..000000000000 --- a/patches/ANDROID-gki_defconfig-enable-accelerated-AES-and-SHA-256.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Eric Biggers -Date: Wed, 9 Oct 2019 13:00:58 -0700 -Subject: ANDROID: gki_defconfig: enable accelerated AES and SHA-256 - -Enable AES and SHA-256 accelerated with the ARM Cryptography Extensions -or with AES-NI, as recommended by -kernel-configs/android-4.19/android-recommended-{arm64,x86}.config. -These are ~10x faster than the other software implementations of AES and -SHA-256 on most devices, and often are required to get acceptable -fscrypt and dm-verity performance. - -Bug: 142410832 -Change-Id: Ia2794f47711132d5caa9021e6e81fb625e02be8d -Signed-off-by: Eric Biggers ---- - arch/arm64/configs/gki_defconfig | 3 ++- - arch/x86/configs/gki_defconfig | 2 ++ - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 29cc5898a871..98520ebdd4d6 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -69,7 +69,8 @@ CONFIG_ARM_SCPI_PROTOCOL=y - # CONFIG_ARM_SCPI_POWER_DOMAIN is not set - # CONFIG_EFI_ARMSTUB_DTB_LOADER is not set - CONFIG_ARM64_CRYPTO=y --CONFIG_CRYPTO_AES_ARM64=y -+CONFIG_CRYPTO_SHA2_ARM64_CE=y -+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y - CONFIG_KPROBES=y - CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 0e23b0cc3a8c..931fcbdced69 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -381,6 +381,8 @@ CONFIG_SECURITY_NETWORK=y - CONFIG_HARDENED_USERCOPY=y - CONFIG_SECURITY_SELINUX=y - CONFIG_CRYPTO_ADIANTUM=y -+CONFIG_CRYPTO_SHA256_SSSE3=y -+CONFIG_CRYPTO_AES_NI_INTEL=y - CONFIG_CRYPTO_LZ4=y - CONFIG_CRYPTO_ZSTD=y - CONFIG_CRYPTO_ANSI_CPRNG=y diff --git a/patches/ANDROID-gki_defconfig-enable-fs-verity.patch b/patches/ANDROID-gki_defconfig-enable-fs-verity.patch deleted file mode 100644 index d0eba23c8a79..000000000000 --- a/patches/ANDROID-gki_defconfig-enable-fs-verity.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Eric Biggers -Date: Thu, 10 Oct 2019 15:45:41 -0700 -Subject: ANDROID: gki_defconfig: enable fs-verity - -fs-verity will be used for APK verification in R. - -Bug: 142494008 -Change-Id: Ia18eb35fcdbccabab47de5fb26daba455fc1eb77 -Signed-off-by: Eric Biggers ---- - arch/arm64/configs/gki_defconfig | 2 ++ - arch/x86/configs/gki_defconfig | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index ed21a0d79f4c..80ebf75319a1 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -381,6 +381,8 @@ CONFIG_EXT4_FS_SECURITY=y - CONFIG_F2FS_FS=y - CONFIG_F2FS_FS_SECURITY=y - CONFIG_FS_ENCRYPTION=y -+CONFIG_FS_VERITY=y -+CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y - # CONFIG_DNOTIFY is not set - CONFIG_QUOTA=y - CONFIG_QFMT_V2=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index fbcf73e4f66f..18c3429c7ede 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -313,6 +313,8 @@ CONFIG_EXT4_FS_SECURITY=y - CONFIG_F2FS_FS=y - CONFIG_F2FS_FS_SECURITY=y - CONFIG_FS_ENCRYPTION=y -+CONFIG_FS_VERITY=y -+CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y - # CONFIG_DNOTIFY is not set - CONFIG_QUOTA=y - CONFIG_QFMT_V2=y diff --git a/patches/ANDROID-gki_defconfig-enable-more-configs.patch b/patches/ANDROID-gki_defconfig-enable-more-configs.patch deleted file mode 100644 index 5a144c2468b7..000000000000 --- a/patches/ANDROID-gki_defconfig-enable-more-configs.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Tue, 16 Jul 2019 16:27:17 -0700 -Subject: ANDROID: gki_defconfig: enable more configs - -Enable following configs: -CONFIG_RAS -CONFIG_EDAC -CONFIG_SPI -CONFIG_DMADEVICES -CONFIG_POWER_AVS -CONFIG_WATCHDOG -CONFIG_USB_OTG -CONFIG_MMC_BLOCK - -Fixes: 137124260 -Fixes: 136278478 -Fixes: 136279343 -Fixes: 136279418 -Fixes: 136279652 -Fixes: 136279658 -Fixes: 136281307 -Change-Id: I630dd2ffd4f6694b497cbb273830d643878694f6 -Signed-off-by: Tri Vo ---- - arch/arm64/configs/gki_defconfig | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 7c66f40c9739..45644397a2d7 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -274,14 +274,17 @@ CONFIG_HW_RANDOM_VIRTIO=y - # CONFIG_DEVPORT is not set - # CONFIG_I2C_COMPAT is not set - # CONFIG_I2C_HELPER_AUTO is not set -+CONFIG_SPI=y - CONFIG_SPMI=y - CONFIG_PINCTRL=y - CONFIG_PINCTRL_AMD=y -+CONFIG_POWER_AVS=y - # CONFIG_HWMON is not set - CONFIG_THERMAL=y - CONFIG_THERMAL_GOV_USER_SPACE=y - CONFIG_CPU_THERMAL=y - CONFIG_DEVFREQ_THERMAL=y -+CONFIG_WATCHDOG=y - CONFIG_MFD_ACT8945A=y - CONFIG_MFD_SYSCON=y - CONFIG_REGULATOR=y -@@ -313,6 +316,7 @@ CONFIG_HID_MICROSOFT=y - CONFIG_HID_MULTITOUCH=y - CONFIG_USB_HIDDEV=y - CONFIG_USB=y -+CONFIG_USB_OTG=y - CONFIG_USB_GADGET=y - CONFIG_USB_DUMMY_HCD=y - CONFIG_USB_CONFIGFS=y -@@ -324,16 +328,17 @@ CONFIG_USB_CONFIGFS_F_MIDI=y - CONFIG_MMC=y - # CONFIG_PWRSEQ_EMMC is not set - # CONFIG_PWRSEQ_SIMPLE is not set --# CONFIG_MMC_BLOCK is not set - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_NEW_LEDS=y - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_TRIGGERS=y -+CONFIG_EDAC=y - CONFIG_RTC_CLASS=y - # CONFIG_RTC_SYSTOHC is not set - CONFIG_RTC_DRV_PL030=y - CONFIG_RTC_DRV_PL031=y -+CONFIG_DMADEVICES=y - CONFIG_VIRTIO_PCI=y - # CONFIG_VIRTIO_PCI_LEGACY is not set - CONFIG_VIRTIO_INPUT=y -@@ -354,6 +359,7 @@ CONFIG_DEVFREQ_GOV_PASSIVE=y - CONFIG_EXTCON=y - CONFIG_PWM=y - CONFIG_GENERIC_PHY=y -+CONFIG_RAS=y - CONFIG_ANDROID=y - CONFIG_ANDROID_BINDER_IPC=y - CONFIG_INTERCONNECT=y diff --git a/patches/ANDROID-gki_defconfig-enabled-CONFIG_TMPFS-explicitly.patch b/patches/ANDROID-gki_defconfig-enabled-CONFIG_TMPFS-explicitly.patch deleted file mode 100644 index 950b0bb248b6..000000000000 --- a/patches/ANDROID-gki_defconfig-enabled-CONFIG_TMPFS-explicitly.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Yongqin Liu -Date: Thu, 10 Oct 2019 11:35:16 +0800 -Subject: ANDROID: gki_defconfig: enabled CONFIG_TMPFS explicitly - -otherwise will cause init boot failure reported like this: - -[ 1.959344] Run /init as init process -[ 1.966119] tmpfs: Unknown parameter 'mode' -[ 1.971092] tmpfs: Unknown parameter 'mode' -[ 1.975426] tmpfs: Unknown parameter 'mode' -[ 1.979709] tmpfs: Unknown parameter 'mode' -[ 1.984298] init: mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755") failed Invalid argument -[ 1.993214] init: mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV, "mode=0755,uid=0,gid=1000") failed Invalid argument -[ 2.005417] init: mount("tmpfs", "/apex", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV, "mode=0755,uid=0,gid=0") failed Invalid argument -[ 2.017435] init: mount("tmpfs", "/debug_ramdisk", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV, "mode=0755,uid=0,gid=0") failed Invalid argument -[ 2.030276] init: Init encountered errors starting first stage, aborting -[ 2.057074] init: #00 pc 00000000002eeac8 /init (UnwindStackCurrent::UnwindFromContext(unsigned long, void*)+96) -[ 2.067403] init: #01 pc 00000000002730c4 /init (android::init::InitFatalReboot()+92) -[ 2.075341] init: #02 pc 00000000002754f4 /init (android::init::InitAborter(char const*)+44) -[ 2.083887] init: #03 pc 00000000002ae4f8 /init (android::base::LogMessage::~LogMessage()+608) -[ 2.092605] init: #04 pc 000000000026aba8 /init (android::init::FirstStageMain(int, char**)+4400) -[ 2.101588] init: #05 pc 00000000003599e4 /init (__real_libc_init(void*, void (*)(), int (*)(int, char**, char**), structors_array_t const*, bionic_tcb*)+572) -[ 2.115863] init: Reboot ending, jumping to kernel -[ 2.121709] reboot: Restarting system with command 'bootloader' - -Tested: with hikey - -Change-Id: I607856cbcc5bfdaf304b13089c07ca0cf10c2f76 -Signed-off-by: Yongqin Liu ---- - arch/arm64/configs/gki_defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 98520ebdd4d6..6ccf6c7ef9ec 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -387,6 +387,7 @@ CONFIG_FUSE_FS=y - CONFIG_OVERLAY_FS=y - CONFIG_MSDOS_FS=y - CONFIG_VFAT_FS=y -+CONFIG_TMPFS=y - # CONFIG_EFIVAR_FS is not set - CONFIG_SDCARD_FS=y - CONFIG_PSTORE=y diff --git a/patches/ANDROID-gki_defconfig-initial-config-based-on-cuttlefish_defconfig.patch b/patches/ANDROID-gki_defconfig-initial-config-based-on-cuttlefish_defconfig.patch deleted file mode 100644 index 3ad69bcba47d..000000000000 --- a/patches/ANDROID-gki_defconfig-initial-config-based-on-cuttlefish_defconfig.patch +++ /dev/null @@ -1,463 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Mon, 13 May 2019 16:00:04 -0700 -Subject: ANDROID: gki_defconfig: initial config based on cuttlefish_defconfig - -Test: boot arm64 cuttlefish -Signed-off-by: Tri Vo ---- - arch/arm64/configs/gki_defconfig | 445 +++++++++++++++++++++++++++++++ - 1 file changed, 445 insertions(+) - create mode 100644 arch/arm64/configs/gki_defconfig - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -new file mode 100644 -index 000000000000..a87cf1871f12 ---- /dev/null -+++ b/arch/arm64/configs/gki_defconfig -@@ -0,0 +1,445 @@ -+CONFIG_AUDIT=y -+CONFIG_NO_HZ=y -+CONFIG_HIGH_RES_TIMERS=y -+CONFIG_PREEMPT=y -+CONFIG_TASKSTATS=y -+CONFIG_TASK_DELAY_ACCT=y -+CONFIG_TASK_XACCT=y -+CONFIG_TASK_IO_ACCOUNTING=y -+CONFIG_PSI=y -+CONFIG_IKCONFIG=y -+CONFIG_IKCONFIG_PROC=y -+CONFIG_MEMCG=y -+CONFIG_MEMCG_SWAP=y -+CONFIG_RT_GROUP_SCHED=y -+CONFIG_CGROUP_FREEZER=y -+CONFIG_CPUSETS=y -+CONFIG_CGROUP_CPUACCT=y -+CONFIG_CGROUP_BPF=y -+CONFIG_SCHED_AUTOGROUP=y -+CONFIG_BLK_DEV_INITRD=y -+# CONFIG_RD_BZIP2 is not set -+# CONFIG_RD_LZMA is not set -+# CONFIG_RD_XZ is not set -+# CONFIG_RD_LZO is not set -+# CONFIG_RD_LZ4 is not set -+CONFIG_SGETMASK_SYSCALL=y -+# CONFIG_SYSFS_SYSCALL is not set -+# CONFIG_FHANDLE is not set -+CONFIG_KALLSYMS_ALL=y -+CONFIG_BPF_SYSCALL=y -+# CONFIG_RSEQ is not set -+CONFIG_EMBEDDED=y -+# CONFIG_VM_EVENT_COUNTERS is not set -+# CONFIG_COMPAT_BRK is not set -+# CONFIG_SLAB_MERGE_DEFAULT is not set -+CONFIG_PROFILING=y -+CONFIG_SCHED_MC=y -+CONFIG_HZ_100=y -+CONFIG_SECCOMP=y -+CONFIG_PARAVIRT=y -+CONFIG_ARMV8_DEPRECATED=y -+CONFIG_SWP_EMULATION=y -+CONFIG_CP15_BARRIER_EMULATION=y -+CONFIG_SETEND_EMULATION=y -+CONFIG_ARM64_SW_TTBR0_PAN=y -+CONFIG_RANDOMIZE_BASE=y -+# CONFIG_EFI is not set -+CONFIG_COMPAT=y -+CONFIG_PM_WAKELOCKS=y -+CONFIG_PM_WAKELOCKS_LIMIT=0 -+# CONFIG_PM_WAKELOCKS_GC is not set -+CONFIG_PM_DEBUG=y -+CONFIG_ENERGY_MODEL=y -+CONFIG_CPU_IDLE=y -+CONFIG_ARM_CPUIDLE=y -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_TIMES=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y -+CONFIG_CPU_FREQ_GOV_POWERSAVE=y -+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -+CONFIG_CPUFREQ_DT=y -+CONFIG_ARM_SCPI_CPUFREQ=y -+CONFIG_ARM_SCMI_CPUFREQ=y -+CONFIG_ARM_SCMI_PROTOCOL=y -+# CONFIG_ARM_SCMI_POWER_DOMAIN is not set -+CONFIG_ARM_SCPI_PROTOCOL=y -+# CONFIG_ARM_SCPI_POWER_DOMAIN is not set -+CONFIG_KPROBES=y -+CONFIG_JUMP_LABEL=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+CONFIG_MODVERSIONS=y -+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -+# CONFIG_SPARSEMEM_VMEMMAP is not set -+CONFIG_KSM=y -+CONFIG_TRANSPARENT_HUGEPAGE=y -+CONFIG_ZSMALLOC=y -+CONFIG_NET=y -+CONFIG_PACKET=y -+CONFIG_UNIX=y -+CONFIG_XFRM_USER=y -+CONFIG_XFRM_INTERFACE=y -+CONFIG_XFRM_STATISTICS=y -+CONFIG_NET_KEY=y -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+CONFIG_IP_ADVANCED_ROUTER=y -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_NET_IPGRE_DEMUX=y -+CONFIG_NET_IPVTI=y -+CONFIG_INET_ESP=y -+# CONFIG_INET_XFRM_MODE_BEET is not set -+CONFIG_INET_UDP_DIAG=y -+CONFIG_INET_DIAG_DESTROY=y -+CONFIG_TCP_CONG_ADVANCED=y -+# CONFIG_TCP_CONG_BIC is not set -+# CONFIG_TCP_CONG_WESTWOOD is not set -+# CONFIG_TCP_CONG_HTCP is not set -+CONFIG_IPV6_ROUTER_PREF=y -+CONFIG_IPV6_ROUTE_INFO=y -+CONFIG_IPV6_OPTIMISTIC_DAD=y -+CONFIG_INET6_ESP=y -+CONFIG_INET6_IPCOMP=y -+CONFIG_IPV6_MIP6=y -+CONFIG_IPV6_VTI=y -+CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_NETFILTER=y -+CONFIG_NF_CONNTRACK=y -+CONFIG_NF_CONNTRACK_SECMARK=y -+CONFIG_NF_CONNTRACK_EVENTS=y -+CONFIG_NF_CONNTRACK_AMANDA=y -+CONFIG_NF_CONNTRACK_FTP=y -+CONFIG_NF_CONNTRACK_H323=y -+CONFIG_NF_CONNTRACK_IRC=y -+CONFIG_NF_CONNTRACK_NETBIOS_NS=y -+CONFIG_NF_CONNTRACK_PPTP=y -+CONFIG_NF_CONNTRACK_SANE=y -+CONFIG_NF_CONNTRACK_TFTP=y -+CONFIG_NF_CT_NETLINK=y -+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y -+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y -+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y -+CONFIG_NETFILTER_XT_TARGET_CT=y -+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y -+CONFIG_NETFILTER_XT_TARGET_MARK=y -+CONFIG_NETFILTER_XT_TARGET_NFLOG=y -+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y -+CONFIG_NETFILTER_XT_TARGET_TPROXY=y -+CONFIG_NETFILTER_XT_TARGET_TRACE=y -+CONFIG_NETFILTER_XT_TARGET_SECMARK=y -+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y -+CONFIG_NETFILTER_XT_MATCH_BPF=y -+CONFIG_NETFILTER_XT_MATCH_COMMENT=y -+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y -+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y -+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y -+CONFIG_NETFILTER_XT_MATCH_HELPER=y -+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y -+CONFIG_NETFILTER_XT_MATCH_LENGTH=y -+CONFIG_NETFILTER_XT_MATCH_LIMIT=y -+CONFIG_NETFILTER_XT_MATCH_MAC=y -+CONFIG_NETFILTER_XT_MATCH_MARK=y -+CONFIG_NETFILTER_XT_MATCH_OWNER=y -+CONFIG_NETFILTER_XT_MATCH_POLICY=y -+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y -+CONFIG_NETFILTER_XT_MATCH_QUOTA=y -+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y -+CONFIG_NETFILTER_XT_MATCH_SOCKET=y -+CONFIG_NETFILTER_XT_MATCH_STATE=y -+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y -+CONFIG_NETFILTER_XT_MATCH_STRING=y -+CONFIG_NETFILTER_XT_MATCH_TIME=y -+CONFIG_NETFILTER_XT_MATCH_U32=y -+CONFIG_IP_NF_IPTABLES=y -+CONFIG_IP_NF_MATCH_ECN=y -+CONFIG_IP_NF_MATCH_TTL=y -+CONFIG_IP_NF_FILTER=y -+CONFIG_IP_NF_TARGET_REJECT=y -+CONFIG_IP_NF_NAT=y -+CONFIG_IP_NF_TARGET_MASQUERADE=y -+CONFIG_IP_NF_TARGET_NETMAP=y -+CONFIG_IP_NF_TARGET_REDIRECT=y -+CONFIG_IP_NF_MANGLE=y -+CONFIG_IP_NF_RAW=y -+CONFIG_IP_NF_SECURITY=y -+CONFIG_IP_NF_ARPTABLES=y -+CONFIG_IP_NF_ARPFILTER=y -+CONFIG_IP_NF_ARP_MANGLE=y -+CONFIG_IP6_NF_IPTABLES=y -+CONFIG_IP6_NF_MATCH_RPFILTER=y -+CONFIG_IP6_NF_FILTER=y -+CONFIG_IP6_NF_TARGET_REJECT=y -+CONFIG_IP6_NF_MANGLE=y -+CONFIG_IP6_NF_RAW=y -+CONFIG_L2TP=y -+CONFIG_NET_SCHED=y -+CONFIG_NET_SCH_HTB=y -+CONFIG_NET_SCH_NETEM=y -+CONFIG_NET_SCH_INGRESS=y -+CONFIG_NET_CLS_U32=y -+CONFIG_NET_CLS_BPF=y -+CONFIG_NET_EMATCH=y -+CONFIG_NET_EMATCH_U32=y -+CONFIG_NET_CLS_ACT=y -+CONFIG_VSOCKETS=y -+CONFIG_VIRTIO_VSOCKETS=y -+CONFIG_CFG80211=y -+# CONFIG_CFG80211_DEFAULT_PS is not set -+# CONFIG_CFG80211_CRDA_SUPPORT is not set -+CONFIG_MAC80211=y -+# CONFIG_MAC80211_RC_MINSTREL is not set -+CONFIG_RFKILL=y -+CONFIG_PCI=y -+CONFIG_PCI_HOST_GENERIC=y -+# CONFIG_UEVENT_HELPER is not set -+CONFIG_DEVTMPFS=y -+# CONFIG_ALLOW_DEV_COREDUMP is not set -+CONFIG_DEBUG_DEVRES=y -+CONFIG_OF_UNITTEST=y -+CONFIG_ZRAM=y -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_SIZE=8192 -+CONFIG_VIRTIO_BLK=y -+CONFIG_UID_SYS_STATS=y -+CONFIG_SCSI=y -+# CONFIG_SCSI_PROC_FS is not set -+CONFIG_BLK_DEV_SD=y -+CONFIG_SCSI_VIRTIO=y -+CONFIG_MD=y -+CONFIG_BLK_DEV_DM=y -+CONFIG_DM_CRYPT=y -+CONFIG_DM_UEVENT=y -+CONFIG_DM_VERITY=y -+CONFIG_DM_VERITY_AVB=y -+CONFIG_DM_VERITY_FEC=y -+CONFIG_DM_BOW=y -+CONFIG_NETDEVICES=y -+CONFIG_NETCONSOLE=y -+CONFIG_NETCONSOLE_DYNAMIC=y -+CONFIG_TUN=y -+CONFIG_VIRTIO_NET=y -+# CONFIG_ETHERNET is not set -+CONFIG_PHYLIB=y -+CONFIG_PPP=y -+CONFIG_PPP_BSDCOMP=y -+CONFIG_PPP_DEFLATE=y -+CONFIG_PPP_MPPE=y -+CONFIG_PPTP=y -+CONFIG_PPPOL2TP=y -+CONFIG_USB_RTL8152=y -+CONFIG_USB_USBNET=y -+# CONFIG_USB_NET_AX8817X is not set -+# CONFIG_USB_NET_AX88179_178A is not set -+# CONFIG_USB_NET_CDCETHER is not set -+# CONFIG_USB_NET_CDC_NCM is not set -+# CONFIG_USB_NET_NET1080 is not set -+# CONFIG_USB_NET_CDC_SUBSET is not set -+# CONFIG_USB_NET_ZAURUS is not set -+# CONFIG_WLAN_VENDOR_ADMTEK is not set -+# CONFIG_WLAN_VENDOR_ATH is not set -+# CONFIG_WLAN_VENDOR_ATMEL is not set -+# CONFIG_WLAN_VENDOR_BROADCOM is not set -+# CONFIG_WLAN_VENDOR_CISCO is not set -+# CONFIG_WLAN_VENDOR_INTEL is not set -+# CONFIG_WLAN_VENDOR_INTERSIL is not set -+# CONFIG_WLAN_VENDOR_MARVELL is not set -+# CONFIG_WLAN_VENDOR_MEDIATEK is not set -+# CONFIG_WLAN_VENDOR_RALINK is not set -+# CONFIG_WLAN_VENDOR_REALTEK is not set -+# CONFIG_WLAN_VENDOR_RSI is not set -+# CONFIG_WLAN_VENDOR_ST is not set -+# CONFIG_WLAN_VENDOR_TI is not set -+# CONFIG_WLAN_VENDOR_ZYDAS is not set -+# CONFIG_WLAN_VENDOR_QUANTENNA is not set -+CONFIG_VIRT_WIFI=y -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_JOYSTICK=y -+CONFIG_JOYSTICK_XPAD=y -+CONFIG_JOYSTICK_XPAD_FF=y -+CONFIG_JOYSTICK_XPAD_LEDS=y -+CONFIG_INPUT_TABLET=y -+CONFIG_TABLET_USB_ACECAD=y -+CONFIG_TABLET_USB_AIPTEK=y -+CONFIG_TABLET_USB_GTCO=y -+CONFIG_TABLET_USB_HANWANG=y -+CONFIG_TABLET_USB_KBTAB=y -+CONFIG_INPUT_MISC=y -+CONFIG_INPUT_UINPUT=y -+# CONFIG_VT is not set -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_DEVMEM is not set -+CONFIG_SERIAL_8250=y -+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_EXAR is not set -+CONFIG_SERIAL_8250_NR_UARTS=48 -+CONFIG_SERIAL_8250_EXTENDED=y -+CONFIG_SERIAL_8250_MANY_PORTS=y -+CONFIG_SERIAL_8250_SHARE_IRQ=y -+CONFIG_SERIAL_OF_PLATFORM=y -+CONFIG_SERIAL_AMBA_PL011=y -+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -+CONFIG_VIRTIO_CONSOLE=y -+CONFIG_HW_RANDOM=y -+CONFIG_HW_RANDOM_VIRTIO=y -+# CONFIG_HW_RANDOM_CAVIUM is not set -+# CONFIG_DEVPORT is not set -+# CONFIG_I2C_COMPAT is not set -+# CONFIG_I2C_HELPER_AUTO is not set -+# CONFIG_HWMON is not set -+CONFIG_THERMAL=y -+CONFIG_CPU_THERMAL=y -+CONFIG_MEDIA_SUPPORT=y -+# CONFIG_VGA_ARB is not set -+CONFIG_DRM=y -+# CONFIG_DRM_FBDEV_EMULATION is not set -+CONFIG_DRM_VIRTIO_GPU=y -+CONFIG_SOUND=y -+CONFIG_SND=y -+CONFIG_SND_HRTIMER=y -+# CONFIG_SND_SUPPORT_OLD_API is not set -+# CONFIG_SND_VERBOSE_PROCFS is not set -+# CONFIG_SND_DRIVERS is not set -+CONFIG_SND_INTEL8X0=y -+# CONFIG_SND_USB is not set -+CONFIG_HIDRAW=y -+CONFIG_UHID=y -+CONFIG_HID_A4TECH=y -+CONFIG_HID_ACRUX=y -+CONFIG_HID_ACRUX_FF=y -+CONFIG_HID_APPLE=y -+CONFIG_HID_BELKIN=y -+CONFIG_HID_CHERRY=y -+CONFIG_HID_CHICONY=y -+CONFIG_HID_PRODIKEYS=y -+CONFIG_HID_CYPRESS=y -+CONFIG_HID_DRAGONRISE=y -+CONFIG_DRAGONRISE_FF=y -+CONFIG_HID_EMS_FF=y -+CONFIG_HID_ELECOM=y -+CONFIG_HID_EZKEY=y -+CONFIG_HID_HOLTEK=y -+CONFIG_HID_KEYTOUCH=y -+CONFIG_HID_KYE=y -+CONFIG_HID_UCLOGIC=y -+CONFIG_HID_WALTOP=y -+CONFIG_HID_GYRATION=y -+CONFIG_HID_TWINHAN=y -+CONFIG_HID_KENSINGTON=y -+CONFIG_HID_LCPOWER=y -+CONFIG_HID_LOGITECH=y -+CONFIG_HID_LOGITECH_DJ=y -+CONFIG_LOGITECH_FF=y -+CONFIG_LOGIRUMBLEPAD2_FF=y -+CONFIG_LOGIG940_FF=y -+CONFIG_HID_MAGICMOUSE=y -+CONFIG_HID_MICROSOFT=y -+CONFIG_HID_MONTEREY=y -+CONFIG_HID_MULTITOUCH=y -+CONFIG_HID_NTRIG=y -+CONFIG_HID_ORTEK=y -+CONFIG_HID_PANTHERLORD=y -+CONFIG_PANTHERLORD_FF=y -+CONFIG_HID_PETALYNX=y -+CONFIG_HID_PICOLCD=y -+CONFIG_HID_PRIMAX=y -+CONFIG_HID_ROCCAT=y -+CONFIG_HID_SAITEK=y -+CONFIG_HID_SAMSUNG=y -+CONFIG_HID_SONY=y -+CONFIG_HID_SPEEDLINK=y -+CONFIG_HID_SUNPLUS=y -+CONFIG_HID_GREENASIA=y -+CONFIG_GREENASIA_FF=y -+CONFIG_HID_SMARTJOYPLUS=y -+CONFIG_SMARTJOYPLUS_FF=y -+CONFIG_HID_TIVO=y -+CONFIG_HID_TOPSEED=y -+CONFIG_HID_THRUSTMASTER=y -+CONFIG_HID_WACOM=y -+CONFIG_HID_WIIMOTE=y -+CONFIG_HID_ZEROPLUS=y -+CONFIG_HID_ZYDACRON=y -+CONFIG_USB_HIDDEV=y -+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -+CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_GADGET=y -+CONFIG_USB_CONFIGFS=y -+CONFIG_USB_CONFIGFS_UEVENT=y -+CONFIG_USB_CONFIGFS_F_FS=y -+CONFIG_USB_CONFIGFS_F_ACC=y -+CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y -+CONFIG_USB_CONFIGFS_F_MIDI=y -+CONFIG_MMC=y -+# CONFIG_PWRSEQ_EMMC is not set -+# CONFIG_PWRSEQ_SIMPLE is not set -+# CONFIG_MMC_BLOCK is not set -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_SYSTOHC is not set -+CONFIG_RTC_DRV_PL030=y -+CONFIG_RTC_DRV_PL031=y -+CONFIG_VIRTIO_PCI=y -+# CONFIG_VIRTIO_PCI_LEGACY is not set -+CONFIG_VIRTIO_BALLOON=y -+CONFIG_VIRTIO_INPUT=y -+CONFIG_VIRTIO_MMIO=y -+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y -+CONFIG_STAGING=y -+CONFIG_ASHMEM=y -+CONFIG_ANDROID_VSOC=y -+CONFIG_ION=y -+CONFIG_COMMON_CLK_SCPI=y -+CONFIG_MAILBOX=y -+# CONFIG_IOMMU_SUPPORT is not set -+CONFIG_ANDROID=y -+CONFIG_ANDROID_BINDER_IPC=y -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_FS_SECURITY=y -+CONFIG_F2FS_FS=y -+CONFIG_F2FS_FS_SECURITY=y -+CONFIG_FS_ENCRYPTION=y -+# CONFIG_DNOTIFY is not set -+CONFIG_QUOTA=y -+CONFIG_QFMT_V2=y -+CONFIG_FUSE_FS=y -+CONFIG_OVERLAY_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_PSTORE=y -+CONFIG_PSTORE_CONSOLE=y -+CONFIG_PSTORE_RAM=y -+CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y -+CONFIG_SECURITY=y -+CONFIG_SECURITY_NETWORK=y -+CONFIG_LSM_MMAP_MIN_ADDR=65536 -+CONFIG_HARDENED_USERCOPY=y -+CONFIG_SECURITY_SELINUX=y -+CONFIG_CRYPTO_ADIANTUM=y -+CONFIG_CRYPTO_SHA512=y -+CONFIG_CRYPTO_LZ4=y -+CONFIG_CRYPTO_ZSTD=y -+CONFIG_CRYPTO_ANSI_CPRNG=y -+CONFIG_CRYPTO_DEV_VIRTIO=y -+CONFIG_XZ_DEC=y -+CONFIG_PRINTK_TIME=y -+CONFIG_DEBUG_INFO=y -+# CONFIG_ENABLE_MUST_CHECK is not set -+CONFIG_FRAME_WARN=1024 -+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set -+CONFIG_MAGIC_SYSRQ=y -+CONFIG_DEBUG_STACK_USAGE=y -+CONFIG_DEBUG_MEMORY_INIT=y -+CONFIG_SOFTLOCKUP_DETECTOR=y -+# CONFIG_DETECT_HUNG_TASK is not set -+CONFIG_PANIC_TIMEOUT=5 -+CONFIG_SCHEDSTATS=y -+CONFIG_RCU_CPU_STALL_TIMEOUT=60 -+CONFIG_ENABLE_DEFAULT_TRACERS=y -+# CONFIG_RUNTIME_TESTING_MENU is not set diff --git a/patches/ANDROID-gki_defconfig-more-configs-for-partners.patch b/patches/ANDROID-gki_defconfig-more-configs-for-partners.patch deleted file mode 100644 index 108b3bcadb2b..000000000000 --- a/patches/ANDROID-gki_defconfig-more-configs-for-partners.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Thu, 20 Jun 2019 14:30:05 -0700 -Subject: ANDROID: gki_defconfig: more configs for partners - -Bug: 135666008 -Signed-off-by: Tri Vo -Change-Id: I5e13f602bcacb416cace48f92f40689ebd3bb12e ---- - arch/arm64/configs/gki_defconfig | 21 ++++++++++++++++++++- - 1 file changed, 20 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 7eeafbecf1b9..3afe7f8d8310 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -10,6 +10,7 @@ CONFIG_IKCONFIG=y - CONFIG_IKCONFIG_PROC=y - CONFIG_MEMCG=y - CONFIG_MEMCG_SWAP=y -+CONFIG_BLK_CGROUP=y - CONFIG_RT_GROUP_SCHED=y - CONFIG_CGROUP_FREEZER=y - CONFIG_CPUSETS=y -@@ -61,12 +62,15 @@ CONFIG_ARM_SCMI_PROTOCOL=y - # CONFIG_ARM_SCMI_POWER_DOMAIN is not set - CONFIG_ARM_SCPI_PROTOCOL=y - # CONFIG_ARM_SCPI_POWER_DOMAIN is not set -+CONFIG_ARM64_CRYPTO=y -+CONFIG_CRYPTO_AES_ARM64=y - CONFIG_KPROBES=y - CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set - # CONFIG_SPARSEMEM_VMEMMAP is not set -+CONFIG_MEMORY_HOTPLUG=y - CONFIG_TRANSPARENT_HUGEPAGE=y - CONFIG_CMA=y - CONFIG_CMA_AREAS=16 -@@ -82,6 +86,7 @@ CONFIG_INET=y - CONFIG_IP_MULTICAST=y - CONFIG_IP_ADVANCED_ROUTER=y - CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_PNP=y - CONFIG_NET_IPGRE_DEMUX=y - CONFIG_NET_IPVTI=y - CONFIG_INET_ESP=y -@@ -165,6 +170,7 @@ CONFIG_IP6_NF_TARGET_REJECT=y - CONFIG_IP6_NF_MANGLE=y - CONFIG_IP6_NF_RAW=y - CONFIG_L2TP=y -+CONFIG_BRIDGE=y - CONFIG_NET_SCHED=y - CONFIG_NET_SCH_HTB=y - CONFIG_NET_SCH_INGRESS=y -@@ -175,6 +181,7 @@ CONFIG_NET_EMATCH_U32=y - CONFIG_NET_CLS_ACT=y - CONFIG_VSOCKETS=y - CONFIG_VIRTIO_VSOCKETS=y -+CONFIG_BT=y - CONFIG_CFG80211=y - # CONFIG_CFG80211_DEFAULT_PS is not set - # CONFIG_CFG80211_CRDA_SUPPORT is not set -@@ -242,7 +249,6 @@ CONFIG_USB_USBNET=y - # CONFIG_WLAN_VENDOR_QUANTENNA is not set - CONFIG_VIRT_WIFI=y - CONFIG_INPUT_EVDEV=y --# CONFIG_INPUT_KEYBOARD is not set - # CONFIG_INPUT_MOUSE is not set - CONFIG_INPUT_JOYSTICK=y - CONFIG_INPUT_MISC=y -@@ -276,9 +282,11 @@ CONFIG_THERMAL=y - CONFIG_THERMAL_GOV_USER_SPACE=y - CONFIG_CPU_THERMAL=y - CONFIG_DEVFREQ_THERMAL=y -+CONFIG_MFD_SYSCON=y - CONFIG_REGULATOR=y - CONFIG_MEDIA_SUPPORT=y - CONFIG_MEDIA_CAMERA_SUPPORT=y -+CONFIG_MEDIA_CONTROLLER=y - # CONFIG_VGA_ARB is not set - CONFIG_DRM=y - # CONFIG_DRM_FBDEV_EMULATION is not set -@@ -334,8 +342,14 @@ CONFIG_ASHMEM=y - CONFIG_ANDROID_VSOC=y - CONFIG_ION=y - CONFIG_COMMON_CLK_SCPI=y -+CONFIG_HWSPINLOCK=y - CONFIG_MAILBOX=y - CONFIG_ARM_SMMU=y -+CONFIG_DEVFREQ_GOV_PERFORMANCE=y -+CONFIG_DEVFREQ_GOV_POWERSAVE=y -+CONFIG_DEVFREQ_GOV_USERSPACE=y -+CONFIG_DEVFREQ_GOV_PASSIVE=y -+CONFIG_EXTCON=y - CONFIG_PWM=y - CONFIG_GENERIC_PHY=y - CONFIG_ANDROID=y -@@ -355,6 +369,7 @@ CONFIG_MSDOS_FS=y - CONFIG_VFAT_FS=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_ECRYPT_FS=y - CONFIG_PSTORE=y - CONFIG_PSTORE_CONSOLE=y - CONFIG_PSTORE_RAM=y -@@ -364,11 +379,13 @@ CONFIG_SECURITY_NETWORK=y - CONFIG_HARDENED_USERCOPY=y - CONFIG_SECURITY_SELINUX=y - CONFIG_CRYPTO_ADIANTUM=y -+CONFIG_CRYPTO_MD4=y - CONFIG_CRYPTO_SHA512=y - CONFIG_CRYPTO_LZ4=y - CONFIG_CRYPTO_ZSTD=y - CONFIG_CRYPTO_ANSI_CPRNG=y - CONFIG_CRYPTO_DEV_VIRTIO=y -+CONFIG_CRC_CCITT=y - CONFIG_CRC8=y - CONFIG_XZ_DEC=y - CONFIG_DMA_CMA=y -@@ -384,3 +401,5 @@ CONFIG_SOFTLOCKUP_DETECTOR=y - CONFIG_PANIC_TIMEOUT=5 - CONFIG_SCHEDSTATS=y - # CONFIG_RUNTIME_TESTING_MENU is not set -+CONFIG_CORESIGHT=y -+CONFIG_CORESIGHT_STM=y diff --git a/patches/ANDROID-gki_defconfig-more-generic-configs-for-DLKMs.patch b/patches/ANDROID-gki_defconfig-more-generic-configs-for-DLKMs.patch deleted file mode 100644 index 5eccb244a503..000000000000 --- a/patches/ANDROID-gki_defconfig-more-generic-configs-for-DLKMs.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Sun, 19 May 2019 14:37:03 -0700 -Subject: ANDROID: gki_defconfig: more generic configs for DLKMs - -Test: boot arm64 cuttlefish -Signed-off-by: Tri Vo -Change-Id: I9f6380927f348d0a5e20d1acff2bef4331c3f591 ---- - arch/arm64/configs/gki_defconfig | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index b7ae05eb896e..04f531ef2511 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -192,6 +192,8 @@ CONFIG_UID_SYS_STATS=y - CONFIG_SCSI=y - # CONFIG_SCSI_PROC_FS is not set - CONFIG_BLK_DEV_SD=y -+CONFIG_SCSI_UFSHCD=y -+CONFIG_SCSI_UFSHCD_PLATFORM=y - CONFIG_SCSI_VIRTIO=y - CONFIG_MD=y - CONFIG_BLK_DEV_DM=y -@@ -266,6 +268,7 @@ CONFIG_HW_RANDOM_VIRTIO=y - # CONFIG_I2C_COMPAT is not set - # CONFIG_I2C_HELPER_AUTO is not set - CONFIG_SPMI=y -+CONFIG_PINCTRL=y - CONFIG_GPIOLIB=y - # CONFIG_HWMON is not set - CONFIG_THERMAL=y -@@ -290,6 +293,8 @@ CONFIG_SND_DYNAMIC_MINORS=y - # CONFIG_SND_VERBOSE_PROCFS is not set - # CONFIG_SND_DRIVERS is not set - CONFIG_SND_INTEL8X0=y -+CONFIG_SND_USB_AUDIO=y -+CONFIG_SND_SOC=y - CONFIG_HIDRAW=y - CONFIG_UHID=y - CONFIG_HID_APPLE=y -@@ -310,6 +315,8 @@ CONFIG_MMC=y - # CONFIG_PWRSEQ_EMMC is not set - # CONFIG_PWRSEQ_SIMPLE is not set - # CONFIG_MMC_BLOCK is not set -+CONFIG_MMC_SDHCI=y -+CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_NEW_LEDS=y - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_TRIGGERS=y -@@ -329,11 +336,12 @@ CONFIG_ANDROID_VSOC=y - CONFIG_ION=y - CONFIG_COMMON_CLK_SCPI=y - CONFIG_MAILBOX=y --CONFIG_PM_DEVFREQ=y -+CONFIG_ARM_SMMU=y - CONFIG_PWM=y - CONFIG_GENERIC_PHY=y - CONFIG_ANDROID=y - CONFIG_ANDROID_BINDER_IPC=y -+CONFIG_INTERCONNECT=y - CONFIG_EXT4_FS=y - CONFIG_EXT4_FS_SECURITY=y - CONFIG_F2FS_FS=y diff --git a/patches/ANDROID-gki_defconfig-remove-PWRSEQ_EMMC-and-PWRSEQ_SIMPLE.patch b/patches/ANDROID-gki_defconfig-remove-PWRSEQ_EMMC-and-PWRSEQ_SIMPLE.patch deleted file mode 100644 index e0854d154867..000000000000 --- a/patches/ANDROID-gki_defconfig-remove-PWRSEQ_EMMC-and-PWRSEQ_SIMPLE.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Thu, 17 Oct 2019 18:28:10 -0700 -Subject: ANDROID: gki_defconfig: remove PWRSEQ_EMMC and PWRSEQ_SIMPLE - -These modules are not required for GKI. - -Bug: 139431025 -Signed-off-by: Ram Muthiah -Change-Id: I9a82010eb326b0a336725037e0356a63a0c9f053 ---- - arch/x86/configs/gki_defconfig | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 18c3429c7ede..949c449b9d1f 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -289,6 +289,8 @@ CONFIG_USB_CONFIGFS_F_ACC=y - CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y - CONFIG_USB_CONFIGFS_F_MIDI=y - CONFIG_MMC=m -+# CONFIG_PWRSEQ_EMMC is not set -+# CONFIG_PWRSEQ_SIMPLE is not set - CONFIG_NEW_LEDS=y - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_TRIGGERS=y diff --git a/patches/ANDROID-gki_defconfig-remove-more-recommended-configs.patch b/patches/ANDROID-gki_defconfig-remove-more-recommended-configs.patch deleted file mode 100644 index 64dba450ab4e..000000000000 --- a/patches/ANDROID-gki_defconfig-remove-more-recommended-configs.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Thu, 16 May 2019 09:57:57 -0700 -Subject: ANDROID: gki_defconfig: remove more recommended configs - -Disable following configs: -CONFIG_KSM -CONFIG_SGETMASK_SYSCALL -CONFIG_ARM64_SW_TTBR0_PAN - -Bug: 132717553 -Test: boot arm64 cuttlefish -Signed-off-by: Tri Vo -Change-Id: I2689515f3ddff10d6ad09c41ac5f4a0415922357 ---- - arch/arm64/configs/gki_defconfig | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 9c1086a740cf..b7ae05eb896e 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -22,7 +22,6 @@ CONFIG_BLK_DEV_INITRD=y - # CONFIG_RD_XZ is not set - # CONFIG_RD_LZO is not set - # CONFIG_RD_LZ4 is not set --CONFIG_SGETMASK_SYSCALL=y - # CONFIG_SYSFS_SYSCALL is not set - # CONFIG_FHANDLE is not set - CONFIG_KALLSYMS_ALL=y -@@ -40,7 +39,6 @@ CONFIG_ARMV8_DEPRECATED=y - CONFIG_SWP_EMULATION=y - CONFIG_CP15_BARRIER_EMULATION=y - CONFIG_SETEND_EMULATION=y --CONFIG_ARM64_SW_TTBR0_PAN=y - CONFIG_RANDOMIZE_BASE=y - # CONFIG_EFI is not set - CONFIG_COMPAT=y -@@ -67,7 +65,6 @@ CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set - # CONFIG_SPARSEMEM_VMEMMAP is not set --CONFIG_KSM=y - CONFIG_TRANSPARENT_HUGEPAGE=y - CONFIG_ZSMALLOC=y - CONFIG_NET=y diff --git a/patches/ANDROID-gki_defconfig-set-CONFIG_NR_CPUS-32.patch b/patches/ANDROID-gki_defconfig-set-CONFIG_NR_CPUS-32.patch deleted file mode 100644 index 0e8f93a6efe6..000000000000 --- a/patches/ANDROID-gki_defconfig-set-CONFIG_NR_CPUS-32.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mark Salyzyn -Date: Mon, 26 Aug 2019 07:56:13 -0700 -Subject: ANDROID: gki_defconfig: set CONFIG_NR_CPUS=32 - -Consensus is that CONFIG_NR_CPUS of 32 will deal with the future -products with a moderate engineering margin. - -Signed-off-by: Mark Salyzyn -Test: confirm value propagates to .config -Bug: 139693734 -Bug: 139406736 -Bug: 139692860 -Change-Id: I9687d37da254a612947398a45ae56ab01e676562 ---- - arch/arm64/configs/gki_defconfig | 1 + - arch/x86/configs/gki_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index b70d608b1ee6..2773a84fd939 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -37,6 +37,7 @@ CONFIG_SLAB_FREELIST_RANDOM=y - CONFIG_SLAB_FREELIST_HARDENED=y - CONFIG_PROFILING=y - CONFIG_SCHED_MC=y -+CONFIG_NR_CPUS=32 - CONFIG_SECCOMP=y - CONFIG_PARAVIRT=y - CONFIG_COMPAT=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index ae3d165a79c3..a1b2121bde8b 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -35,6 +35,7 @@ CONFIG_SLAB_FREELIST_RANDOM=y - CONFIG_SLAB_FREELIST_HARDENED=y - CONFIG_PROFILING=y - CONFIG_SMP=y -+CONFIG_NR_CPUS=32 - CONFIG_PM_WAKELOCKS=y - CONFIG_PM_WAKELOCKS_LIMIT=0 - # CONFIG_PM_WAKELOCKS_GC is not set diff --git a/patches/ANDROID-gki_defconfig-sync-with-savedefconfig.patch b/patches/ANDROID-gki_defconfig-sync-with-savedefconfig.patch deleted file mode 100644 index 915681f42836..000000000000 --- a/patches/ANDROID-gki_defconfig-sync-with-savedefconfig.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Wed, 15 May 2019 15:47:18 -0700 -Subject: ANDROID: gki_defconfig: sync with savedefconfig - -Otherwise, build/build.sh will complain. - -Signed-off-by: Tri Vo ---- - arch/arm64/configs/gki_defconfig | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 4b17f0f9d0ae..9c1086a740cf 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -62,7 +62,6 @@ CONFIG_ARM_SCMI_PROTOCOL=y - CONFIG_ARM_SCPI_PROTOCOL=y - # CONFIG_ARM_SCPI_POWER_DOMAIN is not set - CONFIG_KPROBES=y --CONFIG_JUMP_LABEL=y - CONFIG_MODULES=y - CONFIG_MODULE_UNLOAD=y - CONFIG_MODVERSIONS=y diff --git a/patches/ANDROID-gki_defconfig-workaround-to-enable-configs.patch b/patches/ANDROID-gki_defconfig-workaround-to-enable-configs.patch deleted file mode 100644 index 41435210f23a..000000000000 --- a/patches/ANDROID-gki_defconfig-workaround-to-enable-configs.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Thu, 20 Jun 2019 18:04:53 -0700 -Subject: ANDROID: gki_defconfig: workaround to enable configs - -We're interested in following configs, which can't be selected by -themselves: -CONFIG_GPIOLIB_IRQCHIP -CONFIG_GENERIC_PINCONF -CONFIG_PINCONF -CONFIG_PINMUX -CONFIG_GENERIC_TRACER -CONFIG_MFD_CORE - -As a workaround, enable configs that select the above: -CONFIG_PINCTRL_AMD -CONFIG_MFD_ACT8945A -CONFIG_FUNCTION_TRACER - -Bug: 135666008 -Bug: 135247530 -Change-Id: If348f54fc11ab2c35ed2241d50327d8ce3b0b72e -Signed-off-by: Tri Vo ---- - arch/arm64/configs/gki_defconfig | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 3afe7f8d8310..ec0566116066 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -276,12 +276,13 @@ CONFIG_HW_RANDOM_VIRTIO=y - # CONFIG_I2C_HELPER_AUTO is not set - CONFIG_SPMI=y - CONFIG_PINCTRL=y --CONFIG_GPIOLIB=y -+CONFIG_PINCTRL_AMD=y - # CONFIG_HWMON is not set - CONFIG_THERMAL=y - CONFIG_THERMAL_GOV_USER_SPACE=y - CONFIG_CPU_THERMAL=y - CONFIG_DEVFREQ_THERMAL=y -+CONFIG_MFD_ACT8945A=y - CONFIG_MFD_SYSCON=y - CONFIG_REGULATOR=y - CONFIG_MEDIA_SUPPORT=y -@@ -400,6 +401,7 @@ CONFIG_SOFTLOCKUP_DETECTOR=y - # CONFIG_DETECT_HUNG_TASK is not set - CONFIG_PANIC_TIMEOUT=5 - CONFIG_SCHEDSTATS=y -+CONFIG_FUNCTION_TRACER=y - # CONFIG_RUNTIME_TESTING_MENU is not set - CONFIG_CORESIGHT=y - CONFIG_CORESIGHT_STM=y diff --git a/patches/ANDROID-init-GKI-add-GKI_HACKS_TO_FIX.patch b/patches/ANDROID-init-GKI-add-GKI_HACKS_TO_FIX.patch deleted file mode 100644 index 2b4985a50f7c..000000000000 --- a/patches/ANDROID-init-GKI-add-GKI_HACKS_TO_FIX.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Todd Kjos -Date: Wed, 28 Aug 2019 15:52:02 -0700 -Subject: ANDROID: init: GKI: add GKI_HACKS_TO_FIX - -Add CONFIG_GKI_HACKS_TO_FIX as a mechanism to force -hidden configs to be selected for modules that will be built -separately. Also used to select drivers that need to be -modularized. - -As these issues are resolved upstream, the configs should -be removed from GKI_HACKS_TO_FIX - -Bug: 141266428 -Change-Id: Ic8b2a17cd3a389ac5ef999c8c79b5b5dfee73c8a -Signed-off-by: Todd Kjos ---- - init/Kconfig | 2 ++ - init/Kconfig.gki | 15 +++++++++++++++ - 2 files changed, 17 insertions(+) - create mode 100644 init/Kconfig.gki - -diff --git a/init/Kconfig b/init/Kconfig -index b4daad2bac23..e3f4463ac31c 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -2258,3 +2258,5 @@ config ARCH_HAS_SYNC_CORE_BEFORE_USERMODE - # . - config ARCH_HAS_SYSCALL_WRAPPER - def_bool n -+ -+source "init/Kconfig.gki" -diff --git a/init/Kconfig.gki b/init/Kconfig.gki -new file mode 100644 -index 000000000000..fafcd618037d ---- /dev/null -+++ b/init/Kconfig.gki -@@ -0,0 +1,15 @@ -+# Atrocities needed for -+# a) building GKI modules in separate tree, or -+# b) building drivers that are not modularizable -+# -+# All of these should be reworked into an upstream solution -+# if possible. -+# -+config GKI_HACKS_TO_FIX -+ bool "GKI Dummy config options" -+ help -+ Dummy config option used to enable core functionality used by -+ modules that may not be selectable in this config. -+ -+ Unless you are building a GKI kernel to be used with modules -+ built from a different config, say N here. diff --git a/patches/ANDROID-init-GKI-enable-hidden-configs-for-DRM.patch b/patches/ANDROID-init-GKI-enable-hidden-configs-for-DRM.patch deleted file mode 100644 index 7ba6ac3ed05d..000000000000 --- a/patches/ANDROID-init-GKI-enable-hidden-configs-for-DRM.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Todd Kjos -Date: Tue, 17 Sep 2019 14:36:04 -0700 -Subject: ANDROID: init: GKI: enable hidden configs for DRM - -Add hidden configs to GKI_HACKS_TO_FIX so they -are enabled for loadable DRM modules built -out-of-tree. - -Bug: 141266428 -Change-Id: Ibeda203afa54edc4f9a1daec9b4e8a928eb934fb -Signed-off-by: Todd Kjos ---- - init/Kconfig.gki | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/init/Kconfig.gki b/init/Kconfig.gki -index fafcd618037d..6c3f89bd8e25 100644 ---- a/init/Kconfig.gki -+++ b/init/Kconfig.gki -@@ -1,3 +1,14 @@ -+config GKI_HIDDEN_DRM_CONFIGS -+ bool "Hidden DRM configs needed for GKI" -+ select DRM_KMS_HELPER if (HAS_IOMEM && DRM) -+ select DRM_GEM_CMA_HELPER -+ select DRM_KMS_CMA_HELPER -+ select DRM_MIPI_DSI -+ help -+ Dummy config option used to enable hidden DRM configs. -+ These are normally selected implicitely when including a -+ DRM module, but for GKI, the modules are built out-of-tree. -+ - # Atrocities needed for - # a) building GKI modules in separate tree, or - # b) building drivers that are not modularizable -@@ -7,6 +18,7 @@ - # - config GKI_HACKS_TO_FIX - bool "GKI Dummy config options" -+ select GKI_HIDDEN_DRM_CONFIGS - help - Dummy config option used to enable core functionality used by - modules that may not be selectable in this config. diff --git a/patches/ANDROID-init-GKI-enable-hidden-configs-for-GPIO.patch b/patches/ANDROID-init-GKI-enable-hidden-configs-for-GPIO.patch deleted file mode 100644 index a5fa929f8c76..000000000000 --- a/patches/ANDROID-init-GKI-enable-hidden-configs-for-GPIO.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Todd Kjos -Date: Tue, 17 Sep 2019 16:19:15 -0700 -Subject: ANDROID: init: GKI: enable hidden configs for GPIO - -Add hidden configs to GKI_HACKS_TO_FIX so they are -enabled for loadable GPIO modules built out-of-tree - -Bug: 141266428 -Change-Id: Ie6e79921df67e86783f04cb869604c988656a034 -Signed-off-by: Todd Kjos ---- - init/Kconfig.gki | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/init/Kconfig.gki b/init/Kconfig.gki -index bbd5fac69355..5df8c67123ef 100644 ---- a/init/Kconfig.gki -+++ b/init/Kconfig.gki -@@ -25,6 +25,15 @@ config GKI_HIDDEN_SND_SOC_CONFIGS - These are normally selected implicitely when a module - that relies on it is configured. - -+config GKI_HIDDEN_GPIO_CONFIGS -+ bool "Hidden GPIO configs needed for GKI" -+ select PINCTRL_SINGLE if (PINCTRL && OF && HAS_IOMEM) -+ select GPIO_PL061 if (HAS_IOMEM && ARM_AMBA && GPIOLIB) -+ help -+ Dummy config option used to enable hidden GPIO configs. -+ These are normally selected implicitely when a module -+ that relies on it is configured. -+ - # Atrocities needed for - # a) building GKI modules in separate tree, or - # b) building drivers that are not modularizable -@@ -37,6 +46,7 @@ config GKI_HACKS_TO_FIX - select GKI_HIDDEN_DRM_CONFIGS - select GKI_HIDDEN_REGMAP_CONFIGS - select GKI_HIDDEN_SND_SOC_CONFIGS -+ select GKI_HIDDEN_GPIO_CONFIGS - help - Dummy config option used to enable core functionality used by - modules that may not be selectable in this config. diff --git a/patches/ANDROID-init-GKI-enable-hidden-configs-for-SND_SOC.patch b/patches/ANDROID-init-GKI-enable-hidden-configs-for-SND_SOC.patch deleted file mode 100644 index 1a3cf524a7ec..000000000000 --- a/patches/ANDROID-init-GKI-enable-hidden-configs-for-SND_SOC.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Todd Kjos -Date: Tue, 17 Sep 2019 15:57:02 -0700 -Subject: ANDROID: init: GKI: enable hidden configs for SND_SOC - -Add hidden configs to GKI_HACKS_TO_FIX so they are -enabled for loadable SND_SOC modules built out-of-tree - -Bug: 141266428 -Change-Id: I4782b5bb401a76c647bac41258c1371762dace1c -Signed-off-by: Todd Kjos ---- - init/Kconfig.gki | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/init/Kconfig.gki b/init/Kconfig.gki -index 45966f3325b9..bbd5fac69355 100644 ---- a/init/Kconfig.gki -+++ b/init/Kconfig.gki -@@ -17,6 +17,14 @@ config GKI_HIDDEN_REGMAP_CONFIGS - These are normally selected implicitely when a module - that relies on it is configured. - -+config GKI_HIDDEN_SND_SOC_CONFIGS -+ bool "Hidden SND_SOC configs needed for GKI" -+ select SND_SOC_GENERIC_DMAENGINE_PCM if (SND_SOC && SND) -+ help -+ Dummy config option used to enable hidden SND_SOC configs. -+ These are normally selected implicitely when a module -+ that relies on it is configured. -+ - # Atrocities needed for - # a) building GKI modules in separate tree, or - # b) building drivers that are not modularizable -@@ -28,6 +36,7 @@ config GKI_HACKS_TO_FIX - bool "GKI Dummy config options" - select GKI_HIDDEN_DRM_CONFIGS - select GKI_HIDDEN_REGMAP_CONFIGS -+ select GKI_HIDDEN_SND_SOC_CONFIGS - help - Dummy config option used to enable core functionality used by - modules that may not be selectable in this config. diff --git a/patches/ANDROID-init-GKI-enable-hidden-configs-for-regmap.patch b/patches/ANDROID-init-GKI-enable-hidden-configs-for-regmap.patch deleted file mode 100644 index 51938cdb18dc..000000000000 --- a/patches/ANDROID-init-GKI-enable-hidden-configs-for-regmap.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Todd Kjos -Date: Tue, 17 Sep 2019 15:38:05 -0700 -Subject: ANDROID: init: GKI: enable hidden configs for regmap - -Add hidden configs to GKI_HACKS_TO_FIX so they are -enabled for loadable regmap modules built out-of-tree. - -Bug: 141266428 -Change-Id: I1dedb1fd6e26e36c12b28fcbbf0302f074547101 -Signed-off-by: Todd Kjos ---- - init/Kconfig.gki | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/init/Kconfig.gki b/init/Kconfig.gki -index 6c3f89bd8e25..45966f3325b9 100644 ---- a/init/Kconfig.gki -+++ b/init/Kconfig.gki -@@ -9,6 +9,14 @@ config GKI_HIDDEN_DRM_CONFIGS - These are normally selected implicitely when including a - DRM module, but for GKI, the modules are built out-of-tree. - -+config GKI_HIDDEN_REGMAP_CONFIGS -+ bool "Hidden Regmap configs needed for GKI" -+ select REGMAP_IRQ -+ help -+ Dummy config option used to enable hidden regmap configs. -+ These are normally selected implicitely when a module -+ that relies on it is configured. -+ - # Atrocities needed for - # a) building GKI modules in separate tree, or - # b) building drivers that are not modularizable -@@ -19,6 +27,7 @@ config GKI_HIDDEN_DRM_CONFIGS - config GKI_HACKS_TO_FIX - bool "GKI Dummy config options" - select GKI_HIDDEN_DRM_CONFIGS -+ select GKI_HIDDEN_REGMAP_CONFIGS - help - Dummy config option used to enable core functionality used by - modules that may not be selectable in this config. diff --git a/patches/ANDROID-label-cuttlefish-modules-for-gki.patch b/patches/ANDROID-label-cuttlefish-modules-for-gki.patch deleted file mode 100644 index f781df6df191..000000000000 --- a/patches/ANDROID-label-cuttlefish-modules-for-gki.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Tue, 23 Jul 2019 15:19:58 -0700 -Subject: ANDROID: label cuttlefish modules for gki - -Bug: 138227143 -Test: Boot x86 cuttlefish and gki locally and via forrest -Change-Id: Iff0ea7f31f53897e16d753491e41c5f087abf77c -Signed-off-by: Ram Muthiah ---- - arch/arm64/configs/gki_defconfig | 3 ++- - arch/x86/configs/gki_defconfig | 3 ++- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 18e8f81cc0fb..43a1fea94c6a 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -1,3 +1,4 @@ -+CONFIG_LOCALVERSION="-mainline" - CONFIG_AUDIT=y - CONFIG_NO_HZ=y - CONFIG_HIGH_RES_TIMERS=y -@@ -319,7 +320,7 @@ CONFIG_USB_HIDDEV=y - CONFIG_USB=y - CONFIG_USB_OTG=y - CONFIG_USB_GADGET=y --CONFIG_USB_DUMMY_HCD=y -+CONFIG_USB_DUMMY_HCD=m - CONFIG_USB_CONFIGFS=y - CONFIG_USB_CONFIGFS_UEVENT=y - CONFIG_USB_CONFIGFS_F_FS=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index eacebe96e422..4016f8be75c5 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -1,3 +1,4 @@ -+CONFIG_LOCALVERSION="-mainline" - CONFIG_AUDIT=y - CONFIG_NO_HZ=y - CONFIG_HIGH_RES_TIMERS=y -@@ -267,7 +268,7 @@ CONFIG_HID_MULTITOUCH=y - CONFIG_USB_HIDDEV=y - CONFIG_USB=y - CONFIG_USB_GADGET=y --CONFIG_USB_DUMMY_HCD=y -+CONFIG_USB_DUMMY_HCD=m - CONFIG_USB_CONFIGFS=y - CONFIG_USB_CONFIGFS_UEVENT=y - CONFIG_USB_CONFIGFS_F_FS=y diff --git a/patches/ANDROID-mm-add-a-field-to-store-names-for-private-anonymous-memory.patch b/patches/ANDROID-mm-add-a-field-to-store-names-for-private-anonymous-memory.patch deleted file mode 100644 index 0e465172ef06..000000000000 --- a/patches/ANDROID-mm-add-a-field-to-store-names-for-private-anonymous-memory.patch +++ /dev/null @@ -1,644 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Colin Cross -Date: Tue, 27 Oct 2015 16:42:08 -0700 -Subject: ANDROID: mm: add a field to store names for private anonymous memory - -Userspace processes often have multiple allocators that each do -anonymous mmaps to get memory. When examining memory usage of -individual processes or systems as a whole, it is useful to be -able to break down the various heaps that were allocated by -each layer and examine their size, RSS, and physical memory -usage. - -This patch adds a user pointer to the shared union in -vm_area_struct that points to a null terminated string inside -the user process containing a name for the vma. vmas that -point to the same address will be merged, but vmas that -point to equivalent strings at different addresses will -not be merged. - -Userspace can set the name for a region of memory by calling -prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, start, len, (unsigned long)name); -Setting the name to NULL clears it. - -The names of named anonymous vmas are shown in /proc/pid/maps -as [anon:] and in /proc/pid/smaps in a new "Name" field -that is only present for named vmas. If the userspace pointer -is no longer valid all or part of the name will be replaced -with "". - -The idea to store a userspace pointer to reduce the complexity -within mm (at the expense of the complexity of reading -/proc/pid/mem) came from Dave Hansen. This results in no -runtime overhead in the mm subsystem other than comparing -the anon_name pointers when considering vma merging. The pointer -is stored in a union with fieds that are only used on file-backed -mappings, so it does not increase memory usage. - -Includes fix from Jed Davis for typo in -prctl_set_vma_anon_name, which could attempt to set the name -across two vmas at the same time due to a typo, which might -corrupt the vma list. Fix it to use tmp instead of end to limit -the name setting to a single vma at a time. - -Bug: 120441514 -Change-Id: I9aa7b6b5ef536cd780599ba4e2fba8ceebe8b59f -Signed-off-by: Dmitry Shmidt -[AmitP: Fix get_user_pages_remote() call to align with upstream commit - 5b56d49fc31d ("mm: add locked parameter to get_user_pages_remote()")] -Signed-off-by: Amit Pundir ---- - Documentation/filesystems/proc.txt | 6 ++ - fs/proc/task_mmu.c | 64 +++++++++++- - fs/userfaultfd.c | 9 +- - include/linux/mm.h | 2 +- - include/linux/mm_types.h | 24 ++++- - include/uapi/linux/prctl.h | 3 + - kernel/sys.c | 152 +++++++++++++++++++++++++++++ - mm/madvise.c | 2 +- - mm/mempolicy.c | 3 +- - mm/mlock.c | 2 +- - mm/mmap.c | 39 +++++--- - mm/mprotect.c | 2 +- - 12 files changed, 280 insertions(+), 28 deletions(-) - -diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt -index 99ca040e3f90..4579d1452f89 100644 ---- a/Documentation/filesystems/proc.txt -+++ b/Documentation/filesystems/proc.txt -@@ -415,6 +415,8 @@ is not associated with a file: - [stack] = the stack of the main process - [vdso] = the "virtual dynamic shared object", - the kernel system call handler -+ [anon:] = an anonymous mapping that has been -+ named by userspace - - or if empty, the mapping is anonymous. - -@@ -447,6 +449,7 @@ MMUPageSize: 4 kB - Locked: 0 kB - THPeligible: 0 - VmFlags: rd ex mr mw me dw -+Name: name from userspace - - The first of these lines shows the same information as is displayed for the - mapping in /proc/PID/maps. Following lines show the size of the mapping -@@ -526,6 +529,9 @@ be vanished or the reverse -- new added. Interpretation of their meaning - might change in future as well. So each consumer of these flags has to - follow each specific kernel version for the exact semantic. - -+The "Name" field will only be present on a mapping that has been named by -+userspace, and will show the name passed in by userspace. -+ - This file is only present if the CONFIG_MMU kernel configuration option is - enabled. - -diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index 9442631fd4af..1ce1cb08a5d3 100644 ---- a/fs/proc/task_mmu.c -+++ b/fs/proc/task_mmu.c -@@ -123,6 +123,56 @@ static void release_task_mempolicy(struct proc_maps_private *priv) - } - #endif - -+static void seq_print_vma_name(struct seq_file *m, struct vm_area_struct *vma) -+{ -+ const char __user *name = vma_get_anon_name(vma); -+ struct mm_struct *mm = vma->vm_mm; -+ -+ unsigned long page_start_vaddr; -+ unsigned long page_offset; -+ unsigned long num_pages; -+ unsigned long max_len = NAME_MAX; -+ int i; -+ -+ page_start_vaddr = (unsigned long)name & PAGE_MASK; -+ page_offset = (unsigned long)name - page_start_vaddr; -+ num_pages = DIV_ROUND_UP(page_offset + max_len, PAGE_SIZE); -+ -+ seq_puts(m, "[anon:"); -+ -+ for (i = 0; i < num_pages; i++) { -+ int len; -+ int write_len; -+ const char *kaddr; -+ long pages_pinned; -+ struct page *page; -+ -+ pages_pinned = get_user_pages_remote(current, mm, -+ page_start_vaddr, 1, 0, &page, NULL, NULL); -+ if (pages_pinned < 1) { -+ seq_puts(m, "]"); -+ return; -+ } -+ -+ kaddr = (const char *)kmap(page); -+ len = min(max_len, PAGE_SIZE - page_offset); -+ write_len = strnlen(kaddr + page_offset, len); -+ seq_write(m, kaddr + page_offset, write_len); -+ kunmap(page); -+ put_page(page); -+ -+ /* if strnlen hit a null terminator then we're done */ -+ if (write_len != len) -+ break; -+ -+ max_len -= len; -+ page_offset = 0; -+ page_start_vaddr += PAGE_SIZE; -+ } -+ -+ seq_putc(m, ']'); -+} -+ - static void vma_stop(struct proc_maps_private *priv) - { - struct mm_struct *mm = priv->mm; -@@ -348,8 +398,15 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) - goto done; - } - -- if (is_stack(vma)) -+ if (is_stack(vma)) { - name = "[stack]"; -+ goto done; -+ } -+ -+ if (vma_get_anon_name(vma)) { -+ seq_pad(m, ' '); -+ seq_print_vma_name(m, vma); -+ } - } - - done: -@@ -832,6 +889,11 @@ static int show_smap(struct seq_file *m, void *v) - smap_gather_stats(vma, &mss); - - show_map_vma(m, vma); -+ if (vma_get_anon_name(vma)) { -+ seq_puts(m, "Name: "); -+ seq_print_vma_name(m, vma); -+ seq_putc(m, '\n'); -+ } - - SEQ_PUT_DEC("Size: ", vma->vm_end - vma->vm_start); - SEQ_PUT_DEC(" kB\nKernelPageSize: ", vma_kernel_pagesize(vma)); -diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c -index f9fd18670e22..fc08951daa62 100644 ---- a/fs/userfaultfd.c -+++ b/fs/userfaultfd.c -@@ -912,7 +912,8 @@ static int userfaultfd_release(struct inode *inode, struct file *file) - new_flags, vma->anon_vma, - vma->vm_file, vma->vm_pgoff, - vma_policy(vma), -- NULL_VM_UFFD_CTX); -+ NULL_VM_UFFD_CTX, -+ vma_get_anon_name(vma)); - if (prev) - vma = prev; - else -@@ -1464,7 +1465,8 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, - prev = vma_merge(mm, prev, start, vma_end, new_flags, - vma->anon_vma, vma->vm_file, vma->vm_pgoff, - vma_policy(vma), -- ((struct vm_userfaultfd_ctx){ ctx })); -+ ((struct vm_userfaultfd_ctx){ ctx }), -+ vma_get_anon_name(vma)); - if (prev) { - vma = prev; - goto next; -@@ -1626,7 +1628,8 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, - prev = vma_merge(mm, prev, start, vma_end, new_flags, - vma->anon_vma, vma->vm_file, vma->vm_pgoff, - vma_policy(vma), -- NULL_VM_UFFD_CTX); -+ NULL_VM_UFFD_CTX, -+ vma_get_anon_name(vma)); - if (prev) { - vma = prev; - goto next; -diff --git a/include/linux/mm.h b/include/linux/mm.h -index cc292273e6ba..3d0c800fe574 100644 ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -2278,7 +2278,7 @@ static inline int vma_adjust(struct vm_area_struct *vma, unsigned long start, - extern struct vm_area_struct *vma_merge(struct mm_struct *, - struct vm_area_struct *prev, unsigned long addr, unsigned long end, - unsigned long vm_flags, struct anon_vma *, struct file *, pgoff_t, -- struct mempolicy *, struct vm_userfaultfd_ctx); -+ struct mempolicy *, struct vm_userfaultfd_ctx, const char __user *); - extern struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *); - extern int __split_vma(struct mm_struct *, struct vm_area_struct *, - unsigned long addr, int new_below); -diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index 2222fa795284..7812502ce65a 100644 ---- a/include/linux/mm_types.h -+++ b/include/linux/mm_types.h -@@ -313,11 +313,18 @@ struct vm_area_struct { - /* - * For areas with an address space and backing store, - * linkage into the address_space->i_mmap interval tree. -+ * -+ * For private anonymous mappings, a pointer to a null terminated string -+ * in the user process containing the name given to the vma, or NULL -+ * if unnamed. - */ -- struct { -- struct rb_node rb; -- unsigned long rb_subtree_last; -- } shared; -+ union { -+ struct { -+ struct rb_node rb; -+ unsigned long rb_subtree_last; -+ } shared; -+ const char __user *anon_name; -+ }; - - /* - * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma -@@ -749,4 +756,13 @@ typedef struct { - unsigned long val; - } swp_entry_t; - -+/* Return the name for an anonymous mapping or NULL for a file-backed mapping */ -+static inline const char __user *vma_get_anon_name(struct vm_area_struct *vma) -+{ -+ if (vma->vm_file) -+ return NULL; -+ -+ return vma->anon_name; -+} -+ - #endif /* _LINUX_MM_TYPES_H */ -diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h -index 7da1b37b27aa..bc4a5d963ac8 100644 ---- a/include/uapi/linux/prctl.h -+++ b/include/uapi/linux/prctl.h -@@ -234,4 +234,7 @@ struct prctl_mm_map { - #define PR_GET_TAGGED_ADDR_CTRL 56 - # define PR_TAGGED_ADDR_ENABLE (1UL << 0) - -+#define PR_SET_VMA 0x53564d41 -+# define PR_SET_VMA_ANON_NAME 0 -+ - #endif /* _LINUX_PRCTL_H */ -diff --git a/kernel/sys.c b/kernel/sys.c -index a611d1d58c7d..70660867f50e 100644 ---- a/kernel/sys.c -+++ b/kernel/sys.c -@@ -42,6 +42,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -2259,6 +2261,153 @@ int __weak arch_prctl_spec_ctrl_set(struct task_struct *t, unsigned long which, - return -EINVAL; - } - -+#ifdef CONFIG_MMU -+static int prctl_update_vma_anon_name(struct vm_area_struct *vma, -+ struct vm_area_struct **prev, -+ unsigned long start, unsigned long end, -+ const char __user *name_addr) -+{ -+ struct mm_struct *mm = vma->vm_mm; -+ int error = 0; -+ pgoff_t pgoff; -+ -+ if (name_addr == vma_get_anon_name(vma)) { -+ *prev = vma; -+ goto out; -+ } -+ -+ pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT); -+ *prev = vma_merge(mm, *prev, start, end, vma->vm_flags, vma->anon_vma, -+ vma->vm_file, pgoff, vma_policy(vma), -+ vma->vm_userfaultfd_ctx, name_addr); -+ if (*prev) { -+ vma = *prev; -+ goto success; -+ } -+ -+ *prev = vma; -+ -+ if (start != vma->vm_start) { -+ error = split_vma(mm, vma, start, 1); -+ if (error) -+ goto out; -+ } -+ -+ if (end != vma->vm_end) { -+ error = split_vma(mm, vma, end, 0); -+ if (error) -+ goto out; -+ } -+ -+success: -+ if (!vma->vm_file) -+ vma->anon_name = name_addr; -+ -+out: -+ if (error == -ENOMEM) -+ error = -EAGAIN; -+ return error; -+} -+ -+static int prctl_set_vma_anon_name(unsigned long start, unsigned long end, -+ unsigned long arg) -+{ -+ unsigned long tmp; -+ struct vm_area_struct *vma, *prev; -+ int unmapped_error = 0; -+ int error = -EINVAL; -+ -+ /* -+ * If the interval [start,end) covers some unmapped address -+ * ranges, just ignore them, but return -ENOMEM at the end. -+ * - this matches the handling in madvise. -+ */ -+ vma = find_vma_prev(current->mm, start, &prev); -+ if (vma && start > vma->vm_start) -+ prev = vma; -+ -+ for (;;) { -+ /* Still start < end. */ -+ error = -ENOMEM; -+ if (!vma) -+ return error; -+ -+ /* Here start < (end|vma->vm_end). */ -+ if (start < vma->vm_start) { -+ unmapped_error = -ENOMEM; -+ start = vma->vm_start; -+ if (start >= end) -+ return error; -+ } -+ -+ /* Here vma->vm_start <= start < (end|vma->vm_end) */ -+ tmp = vma->vm_end; -+ if (end < tmp) -+ tmp = end; -+ -+ /* Here vma->vm_start <= start < tmp <= (end|vma->vm_end). */ -+ error = prctl_update_vma_anon_name(vma, &prev, start, tmp, -+ (const char __user *)arg); -+ if (error) -+ return error; -+ start = tmp; -+ if (prev && start < prev->vm_end) -+ start = prev->vm_end; -+ error = unmapped_error; -+ if (start >= end) -+ return error; -+ if (prev) -+ vma = prev->vm_next; -+ else /* madvise_remove dropped mmap_sem */ -+ vma = find_vma(current->mm, start); -+ } -+} -+ -+static int prctl_set_vma(unsigned long opt, unsigned long start, -+ unsigned long len_in, unsigned long arg) -+{ -+ struct mm_struct *mm = current->mm; -+ int error; -+ unsigned long len; -+ unsigned long end; -+ -+ if (start & ~PAGE_MASK) -+ return -EINVAL; -+ len = (len_in + ~PAGE_MASK) & PAGE_MASK; -+ -+ /* Check to see whether len was rounded up from small -ve to zero */ -+ if (len_in && !len) -+ return -EINVAL; -+ -+ end = start + len; -+ if (end < start) -+ return -EINVAL; -+ -+ if (end == start) -+ return 0; -+ -+ down_write(&mm->mmap_sem); -+ -+ switch (opt) { -+ case PR_SET_VMA_ANON_NAME: -+ error = prctl_set_vma_anon_name(start, end, arg); -+ break; -+ default: -+ error = -EINVAL; -+ } -+ -+ up_write(&mm->mmap_sem); -+ -+ return error; -+} -+#else /* CONFIG_MMU */ -+static int prctl_set_vma(unsigned long opt, unsigned long start, -+ unsigned long len_in, unsigned long arg) -+{ -+ return -EINVAL; -+} -+#endif -+ - SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, - unsigned long, arg4, unsigned long, arg5) - { -@@ -2471,6 +2620,9 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, - return -EINVAL; - error = arch_prctl_spec_ctrl_set(me, arg2, arg3); - break; -+ case PR_SET_VMA: -+ error = prctl_set_vma(arg2, arg3, arg4, arg5); -+ break; - case PR_PAC_RESET_KEYS: - if (arg3 || arg4 || arg5) - return -EINVAL; -diff --git a/mm/madvise.c b/mm/madvise.c -index 2be9f3fdb05e..1cfc273b7e25 100644 ---- a/mm/madvise.c -+++ b/mm/madvise.c -@@ -134,7 +134,7 @@ static long madvise_behavior(struct vm_area_struct *vma, - pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT); - *prev = vma_merge(mm, *prev, start, end, new_flags, vma->anon_vma, - vma->vm_file, pgoff, vma_policy(vma), -- vma->vm_userfaultfd_ctx); -+ vma->vm_userfaultfd_ctx, vma_get_anon_name(vma)); - if (*prev) { - vma = *prev; - goto success; -diff --git a/mm/mempolicy.c b/mm/mempolicy.c -index 4ae967bcf954..9271109b7d3a 100644 ---- a/mm/mempolicy.c -+++ b/mm/mempolicy.c -@@ -757,7 +757,8 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, - ((vmstart - vma->vm_start) >> PAGE_SHIFT); - prev = vma_merge(mm, prev, vmstart, vmend, vma->vm_flags, - vma->anon_vma, vma->vm_file, pgoff, -- new_pol, vma->vm_userfaultfd_ctx); -+ new_pol, vma->vm_userfaultfd_ctx, -+ vma_get_anon_name(vma)); - if (prev) { - vma = prev; - next = vma->vm_next; -diff --git a/mm/mlock.c b/mm/mlock.c -index a72c1eeded77..646acba3045b 100644 ---- a/mm/mlock.c -+++ b/mm/mlock.c -@@ -535,7 +535,7 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev, - pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT); - *prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma, - vma->vm_file, pgoff, vma_policy(vma), -- vma->vm_userfaultfd_ctx); -+ vma->vm_userfaultfd_ctx, vma_get_anon_name(vma)); - if (*prev) { - vma = *prev; - goto success; -diff --git a/mm/mmap.c b/mm/mmap.c -index a7d8c84d19b7..fa75b568d481 100644 ---- a/mm/mmap.c -+++ b/mm/mmap.c -@@ -1017,7 +1017,8 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, - */ - static inline int is_mergeable_vma(struct vm_area_struct *vma, - struct file *file, unsigned long vm_flags, -- struct vm_userfaultfd_ctx vm_userfaultfd_ctx) -+ struct vm_userfaultfd_ctx vm_userfaultfd_ctx, -+ const char __user *anon_name) - { - /* - * VM_SOFTDIRTY should not prevent from VMA merging, if we -@@ -1035,6 +1036,8 @@ static inline int is_mergeable_vma(struct vm_area_struct *vma, - return 0; - if (!is_mergeable_vm_userfaultfd_ctx(vma, vm_userfaultfd_ctx)) - return 0; -+ if (vma_get_anon_name(vma) != anon_name) -+ return 0; - return 1; - } - -@@ -1067,9 +1070,10 @@ static int - can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags, - struct anon_vma *anon_vma, struct file *file, - pgoff_t vm_pgoff, -- struct vm_userfaultfd_ctx vm_userfaultfd_ctx) -+ struct vm_userfaultfd_ctx vm_userfaultfd_ctx, -+ const char __user *anon_name) - { -- if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx) && -+ if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx, anon_name) && - is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) { - if (vma->vm_pgoff == vm_pgoff) - return 1; -@@ -1088,9 +1092,10 @@ static int - can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, - struct anon_vma *anon_vma, struct file *file, - pgoff_t vm_pgoff, -- struct vm_userfaultfd_ctx vm_userfaultfd_ctx) -+ struct vm_userfaultfd_ctx vm_userfaultfd_ctx, -+ const char __user *anon_name) - { -- if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx) && -+ if (is_mergeable_vma(vma, file, vm_flags, vm_userfaultfd_ctx, anon_name) && - is_mergeable_anon_vma(anon_vma, vma->anon_vma, vma)) { - pgoff_t vm_pglen; - vm_pglen = vma_pages(vma); -@@ -1101,9 +1106,9 @@ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, - } - - /* -- * Given a mapping request (addr,end,vm_flags,file,pgoff), figure out -- * whether that can be merged with its predecessor or its successor. -- * Or both (it neatly fills a hole). -+ * Given a mapping request (addr,end,vm_flags,file,pgoff,anon_name), -+ * figure out whether that can be merged with its predecessor or its -+ * successor. Or both (it neatly fills a hole). - * - * In most cases - when called for mmap, brk or mremap - [addr,end) is - * certain not to be mapped by the time vma_merge is called; but when -@@ -1145,7 +1150,8 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, - unsigned long end, unsigned long vm_flags, - struct anon_vma *anon_vma, struct file *file, - pgoff_t pgoff, struct mempolicy *policy, -- struct vm_userfaultfd_ctx vm_userfaultfd_ctx) -+ struct vm_userfaultfd_ctx vm_userfaultfd_ctx, -+ const char __user *anon_name) - { - pgoff_t pglen = (end - addr) >> PAGE_SHIFT; - struct vm_area_struct *area, *next; -@@ -1178,7 +1184,8 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, - mpol_equal(vma_policy(prev), policy) && - can_vma_merge_after(prev, vm_flags, - anon_vma, file, pgoff, -- vm_userfaultfd_ctx)) { -+ vm_userfaultfd_ctx, -+ anon_name)) { - /* - * OK, it can. Can we now merge in the successor as well? - */ -@@ -1187,7 +1194,8 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, - can_vma_merge_before(next, vm_flags, - anon_vma, file, - pgoff+pglen, -- vm_userfaultfd_ctx) && -+ vm_userfaultfd_ctx, -+ anon_name) && - is_mergeable_anon_vma(prev->anon_vma, - next->anon_vma, NULL)) { - /* cases 1, 6 */ -@@ -1210,7 +1218,8 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm, - mpol_equal(policy, vma_policy(next)) && - can_vma_merge_before(next, vm_flags, - anon_vma, file, pgoff+pglen, -- vm_userfaultfd_ctx)) { -+ vm_userfaultfd_ctx, -+ anon_name)) { - if (prev && addr < prev->vm_end) /* case 4 */ - err = __vma_adjust(prev, prev->vm_start, - addr, prev->vm_pgoff, NULL, next); -@@ -1764,7 +1773,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, - * Can we just expand an old mapping? - */ - vma = vma_merge(mm, prev, addr, addr + len, vm_flags, -- NULL, file, pgoff, NULL, NULL_VM_UFFD_CTX); -+ NULL, file, pgoff, NULL, NULL_VM_UFFD_CTX, NULL); - if (vma) - goto out; - -@@ -3041,7 +3050,7 @@ static int do_brk_flags(unsigned long addr, unsigned long len, unsigned long fla - - /* Can we just expand an old private anonymous mapping? */ - vma = vma_merge(mm, prev, addr, addr + len, flags, -- NULL, NULL, pgoff, NULL, NULL_VM_UFFD_CTX); -+ NULL, NULL, pgoff, NULL, NULL_VM_UFFD_CTX, NULL); - if (vma) - goto out; - -@@ -3239,7 +3248,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, - return NULL; /* should never get here */ - new_vma = vma_merge(mm, prev, addr, addr + len, vma->vm_flags, - vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma), -- vma->vm_userfaultfd_ctx); -+ vma->vm_userfaultfd_ctx, vma_get_anon_name(vma)); - if (new_vma) { - /* - * Source vma may have been merged into new_vma -diff --git a/mm/mprotect.c b/mm/mprotect.c -index 7967825f6d33..3cad0a44df91 100644 ---- a/mm/mprotect.c -+++ b/mm/mprotect.c -@@ -394,7 +394,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, - pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT); - *pprev = vma_merge(mm, *pprev, start, end, newflags, - vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma), -- vma->vm_userfaultfd_ctx); -+ vma->vm_userfaultfd_ctx, vma_get_anon_name(vma)); - if (*pprev) { - vma = *pprev; - VM_WARN_ON((vma->vm_flags ^ newflags) & ~VM_SOFTDIRTY); diff --git a/patches/ANDROID-mmc-core-Add-ignore-mmc-pm-notify-functionality.patch b/patches/ANDROID-mmc-core-Add-ignore-mmc-pm-notify-functionality.patch deleted file mode 100644 index 20e2983675e3..000000000000 --- a/patches/ANDROID-mmc-core-Add-ignore-mmc-pm-notify-functionality.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dmitry Shmidt -Date: Thu, 7 Oct 2010 14:39:16 -0700 -Subject: ANDROID: mmc: core: Add "ignore mmc pm notify" functionality - -Used to prevent remounting MMC on suspend/resume. - -Bug: 120441127 -Change-Id: I20821a82831b07ca037973d5d92e832372c6b583 -Signed-off-by: Dmitry Shmidt ---- - drivers/mmc/core/host.c | 6 ++++-- - include/linux/mmc/pm.h | 1 + - 2 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c -index 105b7a7c0251..faa6975d436c 100644 ---- a/drivers/mmc/core/host.c -+++ b/drivers/mmc/core/host.c -@@ -480,7 +480,8 @@ int mmc_add_host(struct mmc_host *host) - #endif - - mmc_start_host(host); -- mmc_register_pm_notifier(host); -+ if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) -+ mmc_register_pm_notifier(host); - - return 0; - } -@@ -497,7 +498,8 @@ EXPORT_SYMBOL(mmc_add_host); - */ - void mmc_remove_host(struct mmc_host *host) - { -- mmc_unregister_pm_notifier(host); -+ if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) -+ mmc_unregister_pm_notifier(host); - mmc_stop_host(host); - - #ifdef CONFIG_DEBUG_FS -diff --git a/include/linux/mmc/pm.h b/include/linux/mmc/pm.h -index 3549f8045784..1d554b858086 100644 ---- a/include/linux/mmc/pm.h -+++ b/include/linux/mmc/pm.h -@@ -23,5 +23,6 @@ typedef unsigned int mmc_pm_flag_t; - - #define MMC_PM_KEEP_POWER (1 << 0) /* preserve card power during suspend */ - #define MMC_PM_WAKE_SDIO_IRQ (1 << 1) /* wake up host system on SDIO IRQ assertion */ -+#define MMC_PM_IGNORE_PM_NOTIFY (1 << 2) /* ignore mmc pm notify */ - - #endif /* LINUX_MMC_PM_H */ diff --git a/patches/ANDROID-mnt-Add-filesystem-private-data-to-mount-points.patch b/patches/ANDROID-mnt-Add-filesystem-private-data-to-mount-points.patch deleted file mode 100644 index 2a45e89f56a6..000000000000 --- a/patches/ANDROID-mnt-Add-filesystem-private-data-to-mount-points.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Rosenberg -Date: Wed, 26 Oct 2016 15:29:51 -0700 -Subject: ANDROID: mnt: Add filesystem private data to mount points - -This starts to add private data associated directly -to mount points. The intent is to give filesystems -a sense of where they have come from, as a means of -letting a filesystem take different actions based on -this information. - -Bug: 62094374 -Bug: 120446149 -Bug: 122428178 -Change-Id: Ie769d7b3bb2f5972afe05c1bf16cf88c91647ab2 -Signed-off-by: Daniel Rosenberg -[astrachan: Folded 89a54ed3bf68 ("ANDROID: mnt: Fix next_descendent") - into this patch] -[drosen: Folded 138993ea820 ("Android: mnt: Propagate remount - correctly") into this patch, integrated fs_context things - Now has update_mnt_data instead of needing remount2 -Signed-off-by: Alistair Strachan ---- - fs/namespace.c | 28 +++++++++++++++++++++++++++- - fs/pnode.c | 16 ++++++++++++++++ - fs/pnode.h | 1 + - include/linux/fs.h | 4 ++++ - include/linux/mount.h | 1 + - 5 files changed, 49 insertions(+), 1 deletion(-) - -diff --git a/fs/namespace.c b/fs/namespace.c -index fe0e9e1410fe..4ec782ed6069 100644 ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -198,6 +198,7 @@ static struct mount *alloc_vfsmnt(const char *name) - mnt->mnt_count = 1; - mnt->mnt_writers = 0; - #endif -+ mnt->mnt.data = NULL; - - INIT_HLIST_NODE(&mnt->mnt_hash); - INIT_LIST_HEAD(&mnt->mnt_child); -@@ -547,6 +548,7 @@ int sb_prepare_remount_readonly(struct super_block *sb) - - static void free_vfsmnt(struct mount *mnt) - { -+ kfree(mnt->mnt.data); - kfree_const(mnt->mnt_devname); - #ifdef CONFIG_SMP - free_percpu(mnt->mnt_pcp); -@@ -941,6 +943,15 @@ struct vfsmount *vfs_create_mount(struct fs_context *fc) - if (!mnt) - return ERR_PTR(-ENOMEM); - -+ if (fc->fs_type->alloc_mnt_data) { -+ mnt->mnt.data = fc->fs_type->alloc_mnt_data(); -+ if (!mnt->mnt.data) { -+ mnt_free_id(mnt); -+ free_vfsmnt(mnt); -+ return ERR_PTR(-ENOMEM); -+ } -+ fc->root->d_sb->s_op->update_mnt_data(mnt->mnt.data, fc); -+ } - if (fc->sb_flags & SB_KERNMOUNT) - mnt->mnt.mnt_flags = MNT_INTERNAL; - -@@ -1024,6 +1035,14 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, - if (!mnt) - return ERR_PTR(-ENOMEM); - -+ if (sb->s_op->clone_mnt_data) { -+ mnt->mnt.data = sb->s_op->clone_mnt_data(old->mnt.data); -+ if (!mnt->mnt.data) { -+ err = -ENOMEM; -+ goto out_free; -+ } -+ } -+ - if (flag & (CL_SLAVE | CL_PRIVATE | CL_SHARED_TO_SLAVE)) - mnt->mnt_group_id = 0; /* not a peer of original */ - else -@@ -2549,8 +2568,15 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags, - err = -EPERM; - if (ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) { - err = reconfigure_super(fc); -- if (!err) -+ if (!err) { -+ sb->s_op->update_mnt_data(mnt->mnt.data, fc); - set_mount_attributes(mnt, mnt_flags); -+ namespace_lock(); -+ lock_mount_hash(); -+ propagate_remount(mnt); -+ unlock_mount_hash(); -+ namespace_unlock(); -+ } - } - up_write(&sb->s_umount); - } -diff --git a/fs/pnode.c b/fs/pnode.c -index 49f6d7ff2139..16b2d165b5e9 100644 ---- a/fs/pnode.c -+++ b/fs/pnode.c -@@ -601,3 +601,19 @@ int propagate_umount(struct list_head *list) - - return 0; - } -+ -+void propagate_remount(struct mount *mnt) -+{ -+ struct mount *parent = mnt->mnt_parent; -+ struct mount *p = mnt, *m; -+ struct super_block *sb = mnt->mnt.mnt_sb; -+ -+ if (!sb->s_op->copy_mnt_data) -+ return; -+ for (p = propagation_next(parent, parent); p; -+ p = propagation_next(p, parent)) { -+ m = __lookup_mnt(&p->mnt, mnt->mnt_mountpoint); -+ if (m) -+ sb->s_op->copy_mnt_data(m->mnt.data, mnt->mnt.data); -+ } -+} -diff --git a/fs/pnode.h b/fs/pnode.h -index 49a058c73e4c..a95e519b77bf 100644 ---- a/fs/pnode.h -+++ b/fs/pnode.h -@@ -42,6 +42,7 @@ int propagate_mnt(struct mount *, struct mountpoint *, struct mount *, - int propagate_umount(struct list_head *); - int propagate_mount_busy(struct mount *, int); - void propagate_mount_unlock(struct mount *); -+void propagate_remount(struct mount *); - void mnt_release_group_id(struct mount *); - int get_dominating_id(struct mount *mnt, const struct path *root); - unsigned int mnt_get_count(struct mount *mnt); -diff --git a/include/linux/fs.h b/include/linux/fs.h -index eccf96ceef3b..f3fa2a711152 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1962,6 +1962,9 @@ struct super_operations { - int (*unfreeze_fs) (struct super_block *); - int (*statfs) (struct dentry *, struct kstatfs *); - int (*remount_fs) (struct super_block *, int *, char *); -+ void *(*clone_mnt_data) (void *); -+ void (*copy_mnt_data) (void *, void *); -+ void (*update_mnt_data) (void *, struct fs_context *); - void (*umount_begin) (struct super_block *); - - int (*show_options)(struct seq_file *, struct dentry *); -@@ -2234,6 +2237,7 @@ struct file_system_type { - const struct fs_parameter_description *parameters; - struct dentry *(*mount) (struct file_system_type *, int, - const char *, void *); -+ void *(*alloc_mnt_data) (void); - void (*kill_sb) (struct super_block *); - struct module *owner; - struct file_system_type * next; -diff --git a/include/linux/mount.h b/include/linux/mount.h -index bf8cc4108b8f..20541916e360 100644 ---- a/include/linux/mount.h -+++ b/include/linux/mount.h -@@ -69,6 +69,7 @@ struct vfsmount { - struct dentry *mnt_root; /* root of the mounted tree */ - struct super_block *mnt_sb; /* pointer to superblock */ - int mnt_flags; -+ void *data; - } __randomize_layout; - - struct file; /* forward dec */ diff --git a/patches/ANDROID-mnt-Fix-null-pointer-dereference.patch b/patches/ANDROID-mnt-Fix-null-pointer-dereference.patch deleted file mode 100644 index 8b1747ecfd1b..000000000000 --- a/patches/ANDROID-mnt-Fix-null-pointer-dereference.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alistair Delva -Date: Mon, 22 Jul 2019 14:29:35 -0700 -Subject: ANDROID: mnt: Fix null pointer dereference - -Fix "ANDROID: mnt: Add filesystem private data to mount points" to only -call update_mnt_data() if the filesystem provides the function. This -avoids a null pointer dereference in do_mount(). - -Reported-by: youling 257 -Signed-off-by: Alistair Delva -Signed-off-by: Daniel Rosenberg -Change-Id: I6aedaa89536ae85e6bc29093f38934c672c8fe42 ---- - fs/namespace.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/fs/namespace.c b/fs/namespace.c -index 4ec782ed6069..b7eb5f242b86 100644 ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -935,9 +935,11 @@ static struct mount *skip_mnt_tree(struct mount *p) - struct vfsmount *vfs_create_mount(struct fs_context *fc) - { - struct mount *mnt; -+ struct super_block *sb; - - if (!fc->root) - return ERR_PTR(-EINVAL); -+ sb = fc->root->d_sb; - - mnt = alloc_vfsmnt(fc->source ?: "none"); - if (!mnt) -@@ -950,7 +952,8 @@ struct vfsmount *vfs_create_mount(struct fs_context *fc) - free_vfsmnt(mnt); - return ERR_PTR(-ENOMEM); - } -- fc->root->d_sb->s_op->update_mnt_data(mnt->mnt.data, fc); -+ if (sb->s_op->update_mnt_data) -+ sb->s_op->update_mnt_data(mnt->mnt.data, fc); - } - if (fc->sb_flags & SB_KERNMOUNT) - mnt->mnt.mnt_flags = MNT_INTERNAL; -@@ -2568,7 +2571,7 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags, - err = -EPERM; - if (ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) { - err = reconfigure_super(fc); -- if (!err) { -+ if (!err && sb->s_op->update_mnt_data) { - sb->s_op->update_mnt_data(mnt->mnt.data, fc); - set_mount_attributes(mnt, mnt_flags); - namespace_lock(); -@@ -2576,7 +2579,8 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags, - propagate_remount(mnt); - unlock_mount_hash(); - namespace_unlock(); -- } -+ } else if (!err) -+ set_mount_attributes(mnt, mnt_flags); - } - up_write(&sb->s_umount); - } diff --git a/patches/ANDROID-net-enable-wireless-core-features-with-GKI_LEGACY_WEXT_ALLCONFIG.patch b/patches/ANDROID-net-enable-wireless-core-features-with-GKI_LEGACY_WEXT_ALLCONFIG.patch deleted file mode 100644 index 50e80fbb0099..000000000000 --- a/patches/ANDROID-net-enable-wireless-core-features-with-GKI_LEGACY_WEXT_ALLCONFIG.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mark Salyzyn -Date: Fri, 30 Aug 2019 08:23:25 -0700 -Subject: ANDROID: net: enable wireless core features with - GKI_LEGACY_WEXT_ALLCONFIG - -In embedded environments the requirements are to be able to pick and -chose which features one requires built into the kernel. If an -embedded environment wants to supports loading modules that have been -kbuilt out of tree, there is a need to enable hidden configurations -for legacy wireless core features to provide the API surface for -them to load. - -Introduce CONFIG_GKI_LEGACY_WEXT_ALLCONFIG to select all legacy wireless -extension core features by activating in turn all the associated -hidden configuration options, without having to specifically select -any wireless module(s). - -(rejected upstream commit url https://lkml.org/lkml/2019/9/6/878) -Signed-off-by: Mark Salyzyn -Bug: 140250271 -Change-Id: Ie40e656d87ce21ae82f04ffe8dae2f0efab88a2e ---- - init/Kconfig.gki | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/init/Kconfig.gki b/init/Kconfig.gki -index 5df8c67123ef..b2f3ecefd782 100644 ---- a/init/Kconfig.gki -+++ b/init/Kconfig.gki -@@ -34,6 +34,25 @@ config GKI_HIDDEN_GPIO_CONFIGS - These are normally selected implicitely when a module - that relies on it is configured. - -+# LEGACY_WEXT_ALLCONFIG Discussed upstream, soundly rejected as a unique -+# problem for GKI to solve. It should be noted that these extensions are -+# in-effect deprecated and generally unsupported and we should pressure -+# the SOC vendors to drop any modules that require these extensions. -+config GKI_LEGACY_WEXT_ALLCONFIG -+ bool "Hidden wireless extension configs needed for GKI" -+ select WIRELESS_EXT -+ select WEXT_CORE -+ select WEXT_PROC -+ select WEXT_SPY -+ select WEXT_PRIV -+ help -+ Dummy config option used to enable all the hidden legacy wireless -+ extensions to the core wireless network functionality used by -+ add-in modules. -+ -+ If you are not building a kernel to be used for a variety of -+ out-of-kernel built wireless modules, say N here. -+ - # Atrocities needed for - # a) building GKI modules in separate tree, or - # b) building drivers that are not modularizable -@@ -47,6 +66,7 @@ config GKI_HACKS_TO_FIX - select GKI_HIDDEN_REGMAP_CONFIGS - select GKI_HIDDEN_SND_SOC_CONFIGS - select GKI_HIDDEN_GPIO_CONFIGS -+ select GKI_LEGACY_WEXT_ALLCONFIG - help - Dummy config option used to enable core functionality used by - modules that may not be selectable in this config. diff --git a/patches/ANDROID-net-ipv6-autoconf-routes-into-per-device-tables.patch b/patches/ANDROID-net-ipv6-autoconf-routes-into-per-device-tables.patch deleted file mode 100644 index c488a4ccd341..000000000000 --- a/patches/ANDROID-net-ipv6-autoconf-routes-into-per-device-tables.patch +++ /dev/null @@ -1,266 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Lorenzo Colitti -Date: Wed, 26 Mar 2014 19:35:41 +0900 -Subject: ANDROID: net: ipv6: autoconf routes into per-device tables - -Currently, IPv6 router discovery always puts routes into -RT6_TABLE_MAIN. This causes problems for connection managers -that want to support multiple simultaneous network connections -and want control over which one is used by default (e.g., wifi -and wired). - -To work around this connection managers typically take the routes -they prefer and copy them to static routes with low metrics in -the main table. This puts the burden on the connection manager -to watch netlink to see if the routes have changed, delete the -routes when their lifetime expires, etc. - -Instead, this patch adds a per-interface sysctl to have the -kernel put autoconf routes into different tables. This allows -each interface to have its own autoconf table, and choosing the -default interface (or using different interfaces at the same -time for different types of traffic) can be done using -appropriate ip rules. - -The sysctl behaves as follows: - -- = 0: default. Put routes into RT6_TABLE_MAIN as before. -- > 0: manual. Put routes into the specified table. -- < 0: automatic. Add the absolute value of the sysctl to the - device's ifindex, and use that table. - -The automatic mode is most useful in conjunction with -net.ipv6.conf.default.accept_ra_rt_table. A connection manager -or distribution could set it to, say, -100 on boot, and -thereafter just use IP rules. - -Signed-off-by: Lorenzo Colitti -[AmitP: Refactored original changes to align with - the changes introduced by upstream commits - 830218c1add1 ("net: ipv6: Fix processing of RAs in presence of VRF"), - 8d1c802b2815 ("net/ipv6: Flip FIB entries to fib6_info"). - - Also folded following android-4.9 commit changes into this patch - be65fb01da4d ("ANDROID: net: ipv6: remove unused variable ifindex in")] -Bug: 120445791 -Change-Id: I82d16e3737d9cdfa6489e649e247894d0d60cbb1 -Signed-off-by: Amit Pundir ---- - include/linux/ipv6.h | 1 + - include/net/addrconf.h | 12 ++++++++++ - net/ipv6/addrconf.c | 33 +++++++++++++++++++++++++-- - net/ipv6/route.c | 51 ++++++++++++------------------------------ - 4 files changed, 58 insertions(+), 39 deletions(-) - -diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h -index ea7c7906591e..76cfef3d43f3 100644 ---- a/include/linux/ipv6.h -+++ b/include/linux/ipv6.h -@@ -42,6 +42,7 @@ struct ipv6_devconf { - __s32 accept_ra_rt_info_max_plen; - #endif - #endif -+ __s32 accept_ra_rt_table; - __s32 proxy_ndp; - __s32 accept_source_route; - __s32 accept_ra_from_local; -diff --git a/include/net/addrconf.h b/include/net/addrconf.h -index 3f62b347b04a..2306098a7f2d 100644 ---- a/include/net/addrconf.h -+++ b/include/net/addrconf.h -@@ -266,6 +266,18 @@ static inline bool ipv6_is_mld(struct sk_buff *skb, int nexthdr, int offset) - void addrconf_prefix_rcv(struct net_device *dev, - u8 *opt, int len, bool sllao); - -+/* Determines into what table to put autoconf PIO/RIO/default routes -+ * learned on this device. -+ * -+ * - If 0, use the same table for every device. This puts routes into -+ * one of RT_TABLE_{PREFIX,INFO,DFLT} depending on the type of route -+ * (but note that these three are currently all equal to -+ * RT6_TABLE_MAIN). -+ * - If > 0, use the specified table. -+ * - If < 0, put routes into table dev->ifindex + (-rt_table). -+ */ -+u32 addrconf_rt_table(const struct net_device *dev, u32 default_table); -+ - /* - * anycast prototypes (anycast.c) - */ -diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index 34ccef18b40e..b2f002624391 100644 ---- a/net/ipv6/addrconf.c -+++ b/net/ipv6/addrconf.c -@@ -217,6 +217,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { - .accept_ra_rt_info_max_plen = 0, - #endif - #endif -+ .accept_ra_rt_table = 0, - .proxy_ndp = 0, - .accept_source_route = 0, /* we do not accept RH0 by default. */ - .disable_ipv6 = 0, -@@ -271,6 +272,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { - .accept_ra_rt_info_max_plen = 0, - #endif - #endif -+ .accept_ra_rt_table = 0, - .proxy_ndp = 0, - .accept_source_route = 0, /* we do not accept RH0 by default. */ - .disable_ipv6 = 0, -@@ -2361,6 +2363,26 @@ static void ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpad - ipv6_regen_rndid(idev); - } - -+u32 addrconf_rt_table(const struct net_device *dev, u32 default_table) -+{ -+ struct inet6_dev *idev = in6_dev_get(dev); -+ int sysctl; -+ u32 table; -+ -+ if (!idev) -+ return default_table; -+ sysctl = idev->cnf.accept_ra_rt_table; -+ if (sysctl == 0) { -+ table = default_table; -+ } else if (sysctl > 0) { -+ table = (u32) sysctl; -+ } else { -+ table = (unsigned) dev->ifindex + (-sysctl); -+ } -+ in6_dev_put(idev); -+ return table; -+} -+ - /* - * Add prefix route. - */ -@@ -2371,7 +2393,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, u32 metric, - u32 flags, gfp_t gfp_flags) - { - struct fib6_config cfg = { -- .fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_PREFIX, -+ .fc_table = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_PREFIX), - .fc_metric = metric ? : IP6_RT_PRIO_ADDRCONF, - .fc_ifindex = dev->ifindex, - .fc_expires = expires, -@@ -2406,7 +2428,7 @@ static struct fib6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, - struct fib6_node *fn; - struct fib6_info *rt = NULL; - struct fib6_table *table; -- u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_PREFIX; -+ u32 tb_id = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_PREFIX); - - table = fib6_get_table(dev_net(dev), tb_id); - if (!table) -@@ -6641,6 +6663,13 @@ static const struct ctl_table addrconf_sysctl[] = { - }, - #endif - #endif -+ { -+ .procname = "accept_ra_rt_table", -+ .data = &ipv6_devconf.accept_ra_rt_table, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = proc_dointvec, -+ }, - { - .procname = "proxy_ndp", - .data = &ipv6_devconf.proxy_ndp, -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index a63ff85fe141..a9fd86522e17 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -4079,7 +4079,7 @@ static struct fib6_info *rt6_get_route_info(struct net *net, - const struct in6_addr *gwaddr, - struct net_device *dev) - { -- u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO; -+ u32 tb_id = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_INFO); - int ifindex = dev->ifindex; - struct fib6_node *fn; - struct fib6_info *rt = NULL; -@@ -4133,7 +4133,7 @@ static struct fib6_info *rt6_add_route_info(struct net *net, - .fc_nlinfo.nl_net = net, - }; - -- cfg.fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_INFO, -+ cfg.fc_table = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_INFO), - cfg.fc_dst = *prefix; - cfg.fc_gateway = *gwaddr; - -@@ -4151,7 +4151,7 @@ struct fib6_info *rt6_get_dflt_router(struct net *net, - const struct in6_addr *addr, - struct net_device *dev) - { -- u32 tb_id = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT; -+ u32 tb_id = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_DFLT); - struct fib6_info *rt; - struct fib6_table *table; - -@@ -4185,7 +4185,7 @@ struct fib6_info *rt6_add_dflt_router(struct net *net, - unsigned int pref) - { - struct fib6_config cfg = { -- .fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT, -+ .fc_table = l3mdev_fib_table(dev) ? : addrconf_rt_table(dev, RT6_TABLE_DFLT), - .fc_metric = IP6_RT_PRIO_USER, - .fc_ifindex = dev->ifindex, - .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | -@@ -4210,47 +4210,24 @@ struct fib6_info *rt6_add_dflt_router(struct net *net, - return rt6_get_dflt_router(net, gwaddr, dev); - } - --static void __rt6_purge_dflt_routers(struct net *net, -- struct fib6_table *table) -+static int rt6_addrconf_purge(struct fib6_info *rt, void *arg) - { -- struct fib6_info *rt; -- --restart: -- rcu_read_lock(); -- for_each_fib6_node_rt_rcu(&table->tb6_root) { -- struct net_device *dev = fib6_info_nh_dev(rt); -- struct inet6_dev *idev = dev ? __in6_dev_get(dev) : NULL; -+ struct net_device *dev = fib6_info_nh_dev(rt); -+ struct inet6_dev *idev = dev ? __in6_dev_get(dev) : NULL; - -- if (rt->fib6_flags & (RTF_DEFAULT | RTF_ADDRCONF) && -- (!idev || idev->cnf.accept_ra != 2) && -- fib6_info_hold_safe(rt)) { -- rcu_read_unlock(); -- ip6_del_rt(net, rt); -- goto restart; -- } -+ if (rt->fib6_flags & (RTF_DEFAULT | RTF_ADDRCONF) && -+ (!idev || idev->cnf.accept_ra != 2)) { -+ /* Delete this route. See fib6_clean_tree() */ -+ return -1; - } -- rcu_read_unlock(); - -- table->flags &= ~RT6_TABLE_HAS_DFLT_ROUTER; -+ /* Continue walking */ -+ return 0; - } - - void rt6_purge_dflt_routers(struct net *net) - { -- struct fib6_table *table; -- struct hlist_head *head; -- unsigned int h; -- -- rcu_read_lock(); -- -- for (h = 0; h < FIB6_TABLE_HASHSZ; h++) { -- head = &net->ipv6.fib_table_hash[h]; -- hlist_for_each_entry_rcu(table, head, tb6_hlist) { -- if (table->flags & RT6_TABLE_HAS_DFLT_ROUTER) -- __rt6_purge_dflt_routers(net, table); -- } -- } -- -- rcu_read_unlock(); -+ fib6_clean_all(net, rt6_addrconf_purge, NULL); - } - - static void rtmsg_to_fib6_config(struct net *net, diff --git a/patches/ANDROID-net-xfrm-make-PF_KEY-SHA256-use-RFC-compliant-truncation.patch b/patches/ANDROID-net-xfrm-make-PF_KEY-SHA256-use-RFC-compliant-truncation.patch deleted file mode 100644 index 774d1fcc6ef5..000000000000 --- a/patches/ANDROID-net-xfrm-make-PF_KEY-SHA256-use-RFC-compliant-truncation.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Lorenzo Colitti -Date: Wed, 10 May 2017 23:54:04 +0900 -Subject: ANDROID: net: xfrm: make PF_KEY SHA256 use RFC-compliant truncation. - -When using the PF_KEY interface, SHA-256 hashes are hardcoded to -use 96-bit truncation. This is a violation of RFC4868, which -specifies 128-bit truncation, but will not be fixed upstream due -to backwards compatibility concerns and because the PF_KEY -interface is deprecated in favour of netlink XFRM (which allows -the app to specify an arbitrary truncation length). - -Change the hardcoded truncation length from 96 to 128 so that -PF_KEY apps such as racoon will work with standards-compliant VPN -servers. - -Bug: 34114242 -Bug: 120440497 -Change-Id: Ie46bff4b6358f18117d0be241171d677d31d33f7 -Signed-off-by: Lorenzo Colitti ---- - net/xfrm/xfrm_algo.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c -index 32a378e7011f..8b06ef53d7fc 100644 ---- a/net/xfrm/xfrm_algo.c -+++ b/net/xfrm/xfrm_algo.c -@@ -237,7 +237,7 @@ static struct xfrm_algo_desc aalg_list[] = { - - .uinfo = { - .auth = { -- .icv_truncbits = 96, -+ .icv_truncbits = 128, - .icv_fullbits = 256, - } - }, diff --git a/patches/ANDROID-netfilter-xt_IDLETIMER-Add-new-netlink-msg-type.patch b/patches/ANDROID-netfilter-xt_IDLETIMER-Add-new-netlink-msg-type.patch deleted file mode 100644 index 7068cc911dd7..000000000000 --- a/patches/ANDROID-netfilter-xt_IDLETIMER-Add-new-netlink-msg-type.patch +++ /dev/null @@ -1,450 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: JP Abgrall -Date: Thu, 26 Apr 2012 23:28:35 -0700 -Subject: ANDROID: netfilter: xt_IDLETIMER: Add new netlink msg type - -Send notifications when the label becomes active after an idle period. -Send netlink message notifications in addition to sysfs notifications. -Using a uevent with - subsystem=xt_idletimer - INTERFACE=... - STATE={active,inactive} - -This is backport from common android-3.0 -commit: beb914e987cbbd368988d2b94a6661cb907c4d5a -with uevent support instead of a new netlink message type. - -Bug: 120445672 -Change-Id: I31677ef00c94b5f82c8457e5bf9e5e584c23c523 -Signed-off-by: Ashish Sharma -Signed-off-by: JP Abgrall -[astrachan: Folded the following changes into this patch: - ee0b238fada5 ("netfilter: xt_IDLETIMER: time-stamp and suspend/resume handling.") - 728c058a495e ("netfilter: xt_IDLETIMER: Adds the uid field in the msg") - 5ebea489d44c ("netfilter: xt_IDLETIMER: Fix use after free condition during work") - 5ab69d7ba2c5 ("netfilter: xt_IDLETIMER: Use fullsock when querying uid")] -Signed-off-by: Alistair Strachan ---- - include/uapi/linux/netfilter/xt_IDLETIMER.h | 8 + - net/netfilter/xt_IDLETIMER.c | 251 +++++++++++++++++++- - 2 files changed, 247 insertions(+), 12 deletions(-) - -diff --git a/include/uapi/linux/netfilter/xt_IDLETIMER.h b/include/uapi/linux/netfilter/xt_IDLETIMER.h -index 3c586a19baea..c82a1c1d53ec 100644 ---- a/include/uapi/linux/netfilter/xt_IDLETIMER.h -+++ b/include/uapi/linux/netfilter/xt_IDLETIMER.h -@@ -5,6 +5,7 @@ - * Header file for Xtables timer target module. - * - * Copyright (C) 2004, 2010 Nokia Corporation -+ * - * Written by Timo Teras - * - * Converted to x_tables and forward-ported to 2.6.34 -@@ -33,12 +34,19 @@ - #include - - #define MAX_IDLETIMER_LABEL_SIZE 28 -+#define NLMSG_MAX_SIZE 64 -+ -+#define NL_EVENT_TYPE_INACTIVE 0 -+#define NL_EVENT_TYPE_ACTIVE 1 - - struct idletimer_tg_info { - __u32 timeout; - - char label[MAX_IDLETIMER_LABEL_SIZE]; - -+ /* Use netlink messages for notification in addition to sysfs */ -+ __u8 send_nl_msg; -+ - /* for kernel module internal use only */ - struct idletimer_tg *timer __attribute__((aligned(8))); - }; -diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c -index f56d3ed93e56..5f4a3229ed92 100644 ---- a/net/netfilter/xt_IDLETIMER.c -+++ b/net/netfilter/xt_IDLETIMER.c -@@ -6,6 +6,7 @@ - * After timer expires a kevent will be sent. - * - * Copyright (C) 2004, 2010 Nokia Corporation -+ * - * Written by Timo Teras - * - * Converted to x_tables and reworked for upstream inclusion -@@ -25,8 +26,17 @@ - #include - #include - #include -+#include - #include - #include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include - - struct idletimer_tg { - struct list_head entry; -@@ -36,14 +46,111 @@ struct idletimer_tg { - struct kobject *kobj; - struct device_attribute attr; - -+ struct timespec64 delayed_timer_trigger; -+ struct timespec64 last_modified_timer; -+ struct timespec64 last_suspend_time; -+ struct notifier_block pm_nb; -+ -+ int timeout; - unsigned int refcnt; -+ bool work_pending; -+ bool send_nl_msg; -+ bool active; -+ uid_t uid; - }; - - static LIST_HEAD(idletimer_tg_list); - static DEFINE_MUTEX(list_mutex); -+static DEFINE_SPINLOCK(timestamp_lock); - - static struct kobject *idletimer_tg_kobj; - -+static bool check_for_delayed_trigger(struct idletimer_tg *timer, -+ struct timespec64 *ts) -+{ -+ bool state; -+ struct timespec64 temp; -+ spin_lock_bh(×tamp_lock); -+ timer->work_pending = false; -+ if ((ts->tv_sec - timer->last_modified_timer.tv_sec) > timer->timeout || -+ timer->delayed_timer_trigger.tv_sec != 0) { -+ state = false; -+ temp.tv_sec = timer->timeout; -+ temp.tv_nsec = 0; -+ if (timer->delayed_timer_trigger.tv_sec != 0) { -+ temp = timespec64_add(timer->delayed_timer_trigger, -+ temp); -+ ts->tv_sec = temp.tv_sec; -+ ts->tv_nsec = temp.tv_nsec; -+ timer->delayed_timer_trigger.tv_sec = 0; -+ timer->work_pending = true; -+ schedule_work(&timer->work); -+ } else { -+ temp = timespec64_add(timer->last_modified_timer, temp); -+ ts->tv_sec = temp.tv_sec; -+ ts->tv_nsec = temp.tv_nsec; -+ } -+ } else { -+ state = timer->active; -+ } -+ spin_unlock_bh(×tamp_lock); -+ return state; -+} -+ -+static void notify_netlink_uevent(const char *iface, struct idletimer_tg *timer) -+{ -+ char iface_msg[NLMSG_MAX_SIZE]; -+ char state_msg[NLMSG_MAX_SIZE]; -+ char timestamp_msg[NLMSG_MAX_SIZE]; -+ char uid_msg[NLMSG_MAX_SIZE]; -+ char *envp[] = { iface_msg, state_msg, timestamp_msg, uid_msg, NULL }; -+ int res; -+ struct timespec64 ts; -+ uint64_t time_ns; -+ bool state; -+ -+ res = snprintf(iface_msg, NLMSG_MAX_SIZE, "INTERFACE=%s", -+ iface); -+ if (NLMSG_MAX_SIZE <= res) { -+ pr_err("message too long (%d)", res); -+ return; -+ } -+ -+ ts = ktime_to_timespec64(ktime_get_boottime()); -+ state = check_for_delayed_trigger(timer, &ts); -+ res = snprintf(state_msg, NLMSG_MAX_SIZE, "STATE=%s", -+ state ? "active" : "inactive"); -+ -+ if (NLMSG_MAX_SIZE <= res) { -+ pr_err("message too long (%d)", res); -+ return; -+ } -+ -+ if (state) { -+ res = snprintf(uid_msg, NLMSG_MAX_SIZE, "UID=%u", timer->uid); -+ if (NLMSG_MAX_SIZE <= res) -+ pr_err("message too long (%d)", res); -+ } else { -+ res = snprintf(uid_msg, NLMSG_MAX_SIZE, "UID="); -+ if (NLMSG_MAX_SIZE <= res) -+ pr_err("message too long (%d)", res); -+ } -+ -+ time_ns = timespec64_to_ns(&ts); -+ res = snprintf(timestamp_msg, NLMSG_MAX_SIZE, "TIME_NS=%llu", time_ns); -+ if (NLMSG_MAX_SIZE <= res) { -+ timestamp_msg[0] = '\0'; -+ pr_err("message too long (%d)", res); -+ } -+ -+ pr_debug("putting nlmsg: <%s> <%s> <%s> <%s>\n", iface_msg, state_msg, -+ timestamp_msg, uid_msg); -+ kobject_uevent_env(idletimer_tg_kobj, KOBJ_CHANGE, envp); -+ return; -+ -+ -+} -+ - static - struct idletimer_tg *__idletimer_tg_find_by_label(const char *label) - { -@@ -62,6 +169,7 @@ static ssize_t idletimer_tg_show(struct device *dev, - { - struct idletimer_tg *timer; - unsigned long expires = 0; -+ unsigned long now = jiffies; - - mutex_lock(&list_mutex); - -@@ -71,11 +179,15 @@ static ssize_t idletimer_tg_show(struct device *dev, - - mutex_unlock(&list_mutex); - -- if (time_after(expires, jiffies)) -+ if (time_after(expires, now)) - return sprintf(buf, "%u\n", -- jiffies_to_msecs(expires - jiffies) / 1000); -+ jiffies_to_msecs(expires - now) / 1000); - -- return sprintf(buf, "0\n"); -+ if (timer->send_nl_msg) -+ return sprintf(buf, "0 %d\n", -+ jiffies_to_msecs(now - expires) / 1000); -+ else -+ return sprintf(buf, "0\n"); - } - - static void idletimer_tg_work(struct work_struct *work) -@@ -84,6 +196,9 @@ static void idletimer_tg_work(struct work_struct *work) - work); - - sysfs_notify(idletimer_tg_kobj, NULL, timer->attr.attr.name); -+ -+ if (timer->send_nl_msg) -+ notify_netlink_uevent(timer->attr.attr.name, timer); - } - - static void idletimer_tg_expired(struct timer_list *t) -@@ -91,8 +206,56 @@ static void idletimer_tg_expired(struct timer_list *t) - struct idletimer_tg *timer = from_timer(timer, t, timer); - - pr_debug("timer %s expired\n", timer->attr.attr.name); -- -+ spin_lock_bh(×tamp_lock); -+ timer->active = false; -+ timer->work_pending = true; - schedule_work(&timer->work); -+ spin_unlock_bh(×tamp_lock); -+} -+ -+static int idletimer_resume(struct notifier_block *notifier, -+ unsigned long pm_event, void *unused) -+{ -+ struct timespec64 ts; -+ unsigned long time_diff, now = jiffies; -+ struct idletimer_tg *timer = container_of(notifier, -+ struct idletimer_tg, pm_nb); -+ if (!timer) -+ return NOTIFY_DONE; -+ switch (pm_event) { -+ case PM_SUSPEND_PREPARE: -+ timer->last_suspend_time = -+ ktime_to_timespec64(ktime_get_boottime()); -+ break; -+ case PM_POST_SUSPEND: -+ spin_lock_bh(×tamp_lock); -+ if (!timer->active) { -+ spin_unlock_bh(×tamp_lock); -+ break; -+ } -+ /* since jiffies are not updated when suspended now represents -+ * the time it would have suspended */ -+ if (time_after(timer->timer.expires, now)) { -+ ts = ktime_to_timespec64(ktime_get_boottime()); -+ ts = timespec64_sub(ts, timer->last_suspend_time); -+ time_diff = timespec64_to_jiffies(&ts); -+ if (timer->timer.expires > (time_diff + now)) { -+ mod_timer_pending(&timer->timer, -+ (timer->timer.expires - time_diff)); -+ } else { -+ del_timer(&timer->timer); -+ timer->timer.expires = 0; -+ timer->active = false; -+ timer->work_pending = true; -+ schedule_work(&timer->work); -+ } -+ } -+ spin_unlock_bh(×tamp_lock); -+ break; -+ default: -+ break; -+ } -+ return NOTIFY_DONE; - } - - static int idletimer_check_sysfs_name(const char *name, unsigned int size) -@@ -144,6 +307,22 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) - - timer_setup(&info->timer->timer, idletimer_tg_expired, 0); - info->timer->refcnt = 1; -+ info->timer->send_nl_msg = (info->send_nl_msg == 0) ? false : true; -+ info->timer->active = true; -+ info->timer->timeout = info->timeout; -+ -+ info->timer->delayed_timer_trigger.tv_sec = 0; -+ info->timer->delayed_timer_trigger.tv_nsec = 0; -+ info->timer->work_pending = false; -+ info->timer->uid = 0; -+ info->timer->last_modified_timer = -+ ktime_to_timespec64(ktime_get_boottime()); -+ -+ info->timer->pm_nb.notifier_call = idletimer_resume; -+ ret = register_pm_notifier(&info->timer->pm_nb); -+ if (ret) -+ printk(KERN_WARNING "[%s] Failed to register pm notifier %d\n", -+ __func__, ret); - - INIT_WORK(&info->timer->work, idletimer_tg_work); - -@@ -160,6 +339,42 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) - return ret; - } - -+static void reset_timer(const struct idletimer_tg_info *info, -+ struct sk_buff *skb) -+{ -+ unsigned long now = jiffies; -+ struct idletimer_tg *timer = info->timer; -+ bool timer_prev; -+ -+ spin_lock_bh(×tamp_lock); -+ timer_prev = timer->active; -+ timer->active = true; -+ /* timer_prev is used to guard overflow problem in time_before*/ -+ if (!timer_prev || time_before(timer->timer.expires, now)) { -+ pr_debug("Starting Checkentry timer (Expired, Jiffies): %lu, %lu\n", -+ timer->timer.expires, now); -+ -+ /* Stores the uid resposible for waking up the radio */ -+ if (skb && (skb->sk)) { -+ timer->uid = from_kuid_munged(current_user_ns(), -+ sock_i_uid(skb_to_full_sk(skb))); -+ } -+ -+ /* checks if there is a pending inactive notification*/ -+ if (timer->work_pending) -+ timer->delayed_timer_trigger = timer->last_modified_timer; -+ else { -+ timer->work_pending = true; -+ schedule_work(&timer->work); -+ } -+ } -+ -+ timer->last_modified_timer = ktime_to_timespec64(ktime_get_boottime()); -+ mod_timer(&timer->timer, -+ msecs_to_jiffies(info->timeout * 1000) + now); -+ spin_unlock_bh(×tamp_lock); -+} -+ - /* - * The actual xt_tables plugin. - */ -@@ -167,13 +382,23 @@ static unsigned int idletimer_tg_target(struct sk_buff *skb, - const struct xt_action_param *par) - { - const struct idletimer_tg_info *info = par->targinfo; -+ unsigned long now = jiffies; - - pr_debug("resetting timer %s, timeout period %u\n", - info->label, info->timeout); - -- mod_timer(&info->timer->timer, -- msecs_to_jiffies(info->timeout * 1000) + jiffies); -+ BUG_ON(!info->timer); -+ -+ info->timer->active = true; -+ -+ if (time_before(info->timer->timer.expires, now)) { -+ schedule_work(&info->timer->work); -+ pr_debug("Starting timer %s (Expired, Jiffies): %lu, %lu\n", -+ info->label, info->timer->timer.expires, now); -+ } - -+ /* TODO: Avoid modifying timers on each packet */ -+ reset_timer(info, skb); - return XT_CONTINUE; - } - -@@ -182,7 +407,7 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par) - struct idletimer_tg_info *info = par->targinfo; - int ret; - -- pr_debug("checkentry targinfo%s\n", info->label); -+ pr_debug("checkentry targinfo %s\n", info->label); - - if (info->timeout == 0) { - pr_debug("timeout value is zero\n"); -@@ -204,9 +429,7 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par) - info->timer = __idletimer_tg_find_by_label(info->label); - if (info->timer) { - info->timer->refcnt++; -- mod_timer(&info->timer->timer, -- msecs_to_jiffies(info->timeout * 1000) + jiffies); -- -+ reset_timer(info, NULL); - pr_debug("increased refcnt of timer %s to %u\n", - info->label, info->timer->refcnt); - } else { -@@ -219,6 +442,7 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par) - } - - mutex_unlock(&list_mutex); -+ - return 0; - } - -@@ -235,13 +459,14 @@ static void idletimer_tg_destroy(const struct xt_tgdtor_param *par) - - list_del(&info->timer->entry); - del_timer_sync(&info->timer->timer); -- cancel_work_sync(&info->timer->work); - sysfs_remove_file(idletimer_tg_kobj, &info->timer->attr.attr); -+ unregister_pm_notifier(&info->timer->pm_nb); -+ cancel_work_sync(&info->timer->work); - kfree(info->timer->attr.attr.name); - kfree(info->timer); - } else { - pr_debug("decreased refcnt of timer %s to %u\n", -- info->label, info->timer->refcnt); -+ info->label, info->timer->refcnt); - } - - mutex_unlock(&list_mutex); -@@ -249,6 +474,7 @@ static void idletimer_tg_destroy(const struct xt_tgdtor_param *par) - - static struct xt_target idletimer_tg __read_mostly = { - .name = "IDLETIMER", -+ .revision = 1, - .family = NFPROTO_UNSPEC, - .target = idletimer_tg_target, - .targetsize = sizeof(struct idletimer_tg_info), -@@ -315,3 +541,4 @@ MODULE_DESCRIPTION("Xtables: idle time monitor"); - MODULE_LICENSE("GPL v2"); - MODULE_ALIAS("ipt_IDLETIMER"); - MODULE_ALIAS("ip6t_IDLETIMER"); -+MODULE_ALIAS("arpt_IDLETIMER"); diff --git a/patches/ANDROID-netfilter-xt_quota2-adding-the-original-quota2-from-xtables-addons.patch b/patches/ANDROID-netfilter-xt_quota2-adding-the-original-quota2-from-xtables-addons.patch deleted file mode 100644 index 18ec993a490e..000000000000 --- a/patches/ANDROID-netfilter-xt_quota2-adding-the-original-quota2-from-xtables-addons.patch +++ /dev/null @@ -1,515 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: JP Abgrall -Date: Tue, 21 Jun 2011 11:14:49 -0700 -Subject: ANDROID: netfilter: xt_quota2: adding the original quota2 from - xtables-addons - -The original xt_quota in the kernel is plain broken: - - counts quota at a per CPU level - (was written back when ubiquitous SMP was just a dream) - - provides no way to count across IPV4/IPV6. - -This patch is the original unaltered code from: - http://sourceforge.net/projects/xtables-addons - - at commit e84391ce665cef046967f796dd91026851d6bbf3 - -Bug: 120445421 -Change-Id: I19d49858840effee9ecf6cff03c23b45a97efdeb -Signed-off-by: JP Abgrall -[astrachan: Folded 4d33aa305871 ("netfilter: xt_quota2: fixup the quota2, - and enable.") into this patch] -Signed-off-by: Alistair Strachan ---- - include/linux/netfilter/xt_quota2.h | 25 ++ - net/netfilter/Kconfig | 23 ++ - net/netfilter/Makefile | 1 + - net/netfilter/xt_quota2.c | 401 ++++++++++++++++++++++++++++ - 4 files changed, 450 insertions(+) - create mode 100644 include/linux/netfilter/xt_quota2.h - create mode 100644 net/netfilter/xt_quota2.c - -diff --git a/include/linux/netfilter/xt_quota2.h b/include/linux/netfilter/xt_quota2.h -new file mode 100644 -index 000000000000..eadc6903314e ---- /dev/null -+++ b/include/linux/netfilter/xt_quota2.h -@@ -0,0 +1,25 @@ -+#ifndef _XT_QUOTA_H -+#define _XT_QUOTA_H -+ -+enum xt_quota_flags { -+ XT_QUOTA_INVERT = 1 << 0, -+ XT_QUOTA_GROW = 1 << 1, -+ XT_QUOTA_PACKET = 1 << 2, -+ XT_QUOTA_NO_CHANGE = 1 << 3, -+ XT_QUOTA_MASK = 0x0F, -+}; -+ -+struct xt_quota_counter; -+ -+struct xt_quota_mtinfo2 { -+ char name[15]; -+ u_int8_t flags; -+ -+ /* Comparison-invariant */ -+ aligned_u64 quota; -+ -+ /* Used internally by the kernel */ -+ struct xt_quota_counter *master __attribute__((aligned(8))); -+}; -+ -+#endif /* _XT_QUOTA_H */ -diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig -index 91efae88e8c2..ea957f78a5a9 100644 ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -1484,6 +1484,29 @@ config NETFILTER_XT_MATCH_QUOTA - If you want to compile it as a module, say M here and read - . If unsure, say `N'. - -+config NETFILTER_XT_MATCH_QUOTA2 -+ tristate '"quota2" match support' -+ depends on NETFILTER_ADVANCED -+ help -+ This option adds a `quota2' match, which allows to match on a -+ byte counter correctly and not per CPU. -+ It allows naming the quotas. -+ This is based on http://xtables-addons.git.sourceforge.net -+ -+ If you want to compile it as a module, say M here and read -+ . If unsure, say `N'. -+ -+config NETFILTER_XT_MATCH_QUOTA2_LOG -+ bool '"quota2" Netfilter LOG support' -+ depends on NETFILTER_XT_MATCH_QUOTA2 -+ default n -+ help -+ This option allows `quota2' to log ONCE when a quota limit -+ is passed. It logs via NETLINK using the NETLINK_NFLOG family. -+ It logs similarly to how ipt_ULOG would without data. -+ -+ If unsure, say `N'. -+ - config NETFILTER_XT_MATCH_RATEEST - tristate '"rateest" match support' - depends on NETFILTER_ADVANCED -diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile -index 4fc075b612fe..f3e1af382948 100644 ---- a/net/netfilter/Makefile -+++ b/net/netfilter/Makefile -@@ -192,6 +192,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o - obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o - obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o - obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o -+obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA2) += xt_quota2.o - obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o - obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o - obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) += xt_recent.o -diff --git a/net/netfilter/xt_quota2.c b/net/netfilter/xt_quota2.c -new file mode 100644 -index 000000000000..24b774263aa6 ---- /dev/null -+++ b/net/netfilter/xt_quota2.c -@@ -0,0 +1,401 @@ -+/* -+ * xt_quota2 - enhanced xt_quota that can count upwards and in packets -+ * as a minimal accounting match. -+ * by Jan Engelhardt , 2008 -+ * -+ * Originally based on xt_quota.c: -+ * netfilter module to enforce network quotas -+ * Sam Johnston -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License; either -+ * version 2 of the License, as published by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG -+/* For compatibility, these definitions are copied from the -+ * deprecated header file */ -+#define ULOG_MAC_LEN 80 -+#define ULOG_PREFIX_LEN 32 -+ -+/* Format of the ULOG packets passed through netlink */ -+typedef struct ulog_packet_msg { -+ unsigned long mark; -+ long timestamp_sec; -+ long timestamp_usec; -+ unsigned int hook; -+ char indev_name[IFNAMSIZ]; -+ char outdev_name[IFNAMSIZ]; -+ size_t data_len; -+ char prefix[ULOG_PREFIX_LEN]; -+ unsigned char mac_len; -+ unsigned char mac[ULOG_MAC_LEN]; -+ unsigned char payload[0]; -+} ulog_packet_msg_t; -+#endif -+ -+/** -+ * @lock: lock to protect quota writers from each other -+ */ -+struct xt_quota_counter { -+ u_int64_t quota; -+ spinlock_t lock; -+ struct list_head list; -+ atomic_t ref; -+ char name[sizeof(((struct xt_quota_mtinfo2 *)NULL)->name)]; -+ struct proc_dir_entry *procfs_entry; -+}; -+ -+#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG -+/* Harald's favorite number +1 :D From ipt_ULOG.C */ -+static int qlog_nl_event = 112; -+module_param_named(event_num, qlog_nl_event, uint, S_IRUGO | S_IWUSR); -+MODULE_PARM_DESC(event_num, -+ "Event number for NETLINK_NFLOG message. 0 disables log." -+ "111 is what ipt_ULOG uses."); -+static struct sock *nflognl; -+#endif -+ -+static LIST_HEAD(counter_list); -+static DEFINE_SPINLOCK(counter_list_lock); -+ -+static struct proc_dir_entry *proc_xt_quota; -+static unsigned int quota_list_perms = S_IRUGO | S_IWUSR; -+static kuid_t quota_list_uid = KUIDT_INIT(0); -+static kgid_t quota_list_gid = KGIDT_INIT(0); -+module_param_named(perms, quota_list_perms, uint, S_IRUGO | S_IWUSR); -+ -+#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG -+static void quota2_log(unsigned int hooknum, -+ const struct sk_buff *skb, -+ const struct net_device *in, -+ const struct net_device *out, -+ const char *prefix) -+{ -+ ulog_packet_msg_t *pm; -+ struct sk_buff *log_skb; -+ size_t size; -+ struct nlmsghdr *nlh; -+ -+ if (!qlog_nl_event) -+ return; -+ -+ size = NLMSG_SPACE(sizeof(*pm)); -+ size = max(size, (size_t)NLMSG_GOODSIZE); -+ log_skb = alloc_skb(size, GFP_ATOMIC); -+ if (!log_skb) { -+ pr_err("xt_quota2: cannot alloc skb for logging\n"); -+ return; -+ } -+ -+ nlh = nlmsg_put(log_skb, /*pid*/0, /*seq*/0, qlog_nl_event, -+ sizeof(*pm), 0); -+ if (!nlh) { -+ pr_err("xt_quota2: nlmsg_put failed\n"); -+ kfree_skb(log_skb); -+ return; -+ } -+ pm = nlmsg_data(nlh); -+ if (skb->tstamp == 0) -+ __net_timestamp((struct sk_buff *)skb); -+ pm->data_len = 0; -+ pm->hook = hooknum; -+ if (prefix != NULL) -+ strlcpy(pm->prefix, prefix, sizeof(pm->prefix)); -+ else -+ *(pm->prefix) = '\0'; -+ if (in) -+ strlcpy(pm->indev_name, in->name, sizeof(pm->indev_name)); -+ else -+ pm->indev_name[0] = '\0'; -+ -+ if (out) -+ strlcpy(pm->outdev_name, out->name, sizeof(pm->outdev_name)); -+ else -+ pm->outdev_name[0] = '\0'; -+ -+ NETLINK_CB(log_skb).dst_group = 1; -+ pr_debug("throwing 1 packets to netlink group 1\n"); -+ netlink_broadcast(nflognl, log_skb, 0, 1, GFP_ATOMIC); -+} -+#else -+static void quota2_log(unsigned int hooknum, -+ const struct sk_buff *skb, -+ const struct net_device *in, -+ const struct net_device *out, -+ const char *prefix) -+{ -+} -+#endif /* if+else CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG */ -+ -+static ssize_t quota_proc_read(struct file *file, char __user *buf, -+ size_t size, loff_t *ppos) -+{ -+ struct xt_quota_counter *e = PDE_DATA(file_inode(file)); -+ char tmp[24]; -+ size_t tmp_size; -+ -+ spin_lock_bh(&e->lock); -+ tmp_size = scnprintf(tmp, sizeof(tmp), "%llu\n", e->quota); -+ spin_unlock_bh(&e->lock); -+ return simple_read_from_buffer(buf, size, ppos, tmp, tmp_size); -+} -+ -+static ssize_t quota_proc_write(struct file *file, const char __user *input, -+ size_t size, loff_t *ppos) -+{ -+ struct xt_quota_counter *e = PDE_DATA(file_inode(file)); -+ char buf[sizeof("18446744073709551616")]; -+ -+ if (size > sizeof(buf)) -+ size = sizeof(buf); -+ if (copy_from_user(buf, input, size) != 0) -+ return -EFAULT; -+ buf[sizeof(buf)-1] = '\0'; -+ -+ spin_lock_bh(&e->lock); -+ e->quota = simple_strtoull(buf, NULL, 0); -+ spin_unlock_bh(&e->lock); -+ return size; -+} -+ -+static const struct file_operations q2_counter_fops = { -+ .read = quota_proc_read, -+ .write = quota_proc_write, -+ .llseek = default_llseek, -+}; -+ -+static struct xt_quota_counter * -+q2_new_counter(const struct xt_quota_mtinfo2 *q, bool anon) -+{ -+ struct xt_quota_counter *e; -+ unsigned int size; -+ -+ /* Do not need all the procfs things for anonymous counters. */ -+ size = anon ? offsetof(typeof(*e), list) : sizeof(*e); -+ e = kmalloc(size, GFP_KERNEL); -+ if (e == NULL) -+ return NULL; -+ -+ e->quota = q->quota; -+ spin_lock_init(&e->lock); -+ if (!anon) { -+ INIT_LIST_HEAD(&e->list); -+ atomic_set(&e->ref, 1); -+ strlcpy(e->name, q->name, sizeof(e->name)); -+ } -+ return e; -+} -+ -+/** -+ * q2_get_counter - get ref to counter or create new -+ * @name: name of counter -+ */ -+static struct xt_quota_counter * -+q2_get_counter(const struct xt_quota_mtinfo2 *q) -+{ -+ struct proc_dir_entry *p; -+ struct xt_quota_counter *e = NULL; -+ struct xt_quota_counter *new_e; -+ -+ if (*q->name == '\0') -+ return q2_new_counter(q, true); -+ -+ /* No need to hold a lock while getting a new counter */ -+ new_e = q2_new_counter(q, false); -+ if (new_e == NULL) -+ goto out; -+ -+ spin_lock_bh(&counter_list_lock); -+ list_for_each_entry(e, &counter_list, list) -+ if (strcmp(e->name, q->name) == 0) { -+ atomic_inc(&e->ref); -+ spin_unlock_bh(&counter_list_lock); -+ kfree(new_e); -+ pr_debug("xt_quota2: old counter name=%s", e->name); -+ return e; -+ } -+ e = new_e; -+ pr_debug("xt_quota2: new_counter name=%s", e->name); -+ list_add_tail(&e->list, &counter_list); -+ /* The entry having a refcount of 1 is not directly destructible. -+ * This func has not yet returned the new entry, thus iptables -+ * has not references for destroying this entry. -+ * For another rule to try to destroy it, it would 1st need for this -+ * func* to be re-invoked, acquire a new ref for the same named quota. -+ * Nobody will access the e->procfs_entry either. -+ * So release the lock. */ -+ spin_unlock_bh(&counter_list_lock); -+ -+ /* create_proc_entry() is not spin_lock happy */ -+ p = e->procfs_entry = proc_create_data(e->name, quota_list_perms, -+ proc_xt_quota, &q2_counter_fops, e); -+ -+ if (IS_ERR_OR_NULL(p)) { -+ spin_lock_bh(&counter_list_lock); -+ list_del(&e->list); -+ spin_unlock_bh(&counter_list_lock); -+ goto out; -+ } -+ proc_set_user(p, quota_list_uid, quota_list_gid); -+ return e; -+ -+ out: -+ kfree(e); -+ return NULL; -+} -+ -+static int quota_mt2_check(const struct xt_mtchk_param *par) -+{ -+ struct xt_quota_mtinfo2 *q = par->matchinfo; -+ -+ pr_debug("xt_quota2: check() flags=0x%04x", q->flags); -+ -+ if (q->flags & ~XT_QUOTA_MASK) -+ return -EINVAL; -+ -+ q->name[sizeof(q->name)-1] = '\0'; -+ if (*q->name == '.' || strchr(q->name, '/') != NULL) { -+ printk(KERN_ERR "xt_quota.3: illegal name\n"); -+ return -EINVAL; -+ } -+ -+ q->master = q2_get_counter(q); -+ if (q->master == NULL) { -+ printk(KERN_ERR "xt_quota.3: memory alloc failure\n"); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static void quota_mt2_destroy(const struct xt_mtdtor_param *par) -+{ -+ struct xt_quota_mtinfo2 *q = par->matchinfo; -+ struct xt_quota_counter *e = q->master; -+ -+ if (*q->name == '\0') { -+ kfree(e); -+ return; -+ } -+ -+ spin_lock_bh(&counter_list_lock); -+ if (!atomic_dec_and_test(&e->ref)) { -+ spin_unlock_bh(&counter_list_lock); -+ return; -+ } -+ -+ list_del(&e->list); -+ remove_proc_entry(e->name, proc_xt_quota); -+ spin_unlock_bh(&counter_list_lock); -+ kfree(e); -+} -+ -+static bool -+quota_mt2(const struct sk_buff *skb, struct xt_action_param *par) -+{ -+ struct xt_quota_mtinfo2 *q = (void *)par->matchinfo; -+ struct xt_quota_counter *e = q->master; -+ bool ret = q->flags & XT_QUOTA_INVERT; -+ -+ spin_lock_bh(&e->lock); -+ if (q->flags & XT_QUOTA_GROW) { -+ /* -+ * While no_change is pointless in "grow" mode, we will -+ * implement it here simply to have a consistent behavior. -+ */ -+ if (!(q->flags & XT_QUOTA_NO_CHANGE)) { -+ e->quota += (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len; -+ } -+ ret = true; -+ } else { -+ if (e->quota >= skb->len) { -+ if (!(q->flags & XT_QUOTA_NO_CHANGE)) -+ e->quota -= (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len; -+ ret = !ret; -+ } else { -+ /* We are transitioning, log that fact. */ -+ if (e->quota) { -+ quota2_log(xt_hooknum(par), -+ skb, -+ xt_in(par), -+ xt_out(par), -+ q->name); -+ } -+ /* we do not allow even small packets from now on */ -+ e->quota = 0; -+ } -+ } -+ spin_unlock_bh(&e->lock); -+ return ret; -+} -+ -+static struct xt_match quota_mt2_reg[] __read_mostly = { -+ { -+ .name = "quota2", -+ .revision = 3, -+ .family = NFPROTO_IPV4, -+ .checkentry = quota_mt2_check, -+ .match = quota_mt2, -+ .destroy = quota_mt2_destroy, -+ .matchsize = sizeof(struct xt_quota_mtinfo2), -+ .me = THIS_MODULE, -+ }, -+ { -+ .name = "quota2", -+ .revision = 3, -+ .family = NFPROTO_IPV6, -+ .checkentry = quota_mt2_check, -+ .match = quota_mt2, -+ .destroy = quota_mt2_destroy, -+ .matchsize = sizeof(struct xt_quota_mtinfo2), -+ .me = THIS_MODULE, -+ }, -+}; -+ -+static int __init quota_mt2_init(void) -+{ -+ int ret; -+ pr_debug("xt_quota2: init()"); -+ -+#ifdef CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG -+ nflognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, NULL); -+ if (!nflognl) -+ return -ENOMEM; -+#endif -+ -+ proc_xt_quota = proc_mkdir("xt_quota", init_net.proc_net); -+ if (proc_xt_quota == NULL) -+ return -EACCES; -+ -+ ret = xt_register_matches(quota_mt2_reg, ARRAY_SIZE(quota_mt2_reg)); -+ if (ret < 0) -+ remove_proc_entry("xt_quota", init_net.proc_net); -+ pr_debug("xt_quota2: init() %d", ret); -+ return ret; -+} -+ -+static void __exit quota_mt2_exit(void) -+{ -+ xt_unregister_matches(quota_mt2_reg, ARRAY_SIZE(quota_mt2_reg)); -+ remove_proc_entry("xt_quota", init_net.proc_net); -+} -+ -+module_init(quota_mt2_init); -+module_exit(quota_mt2_exit); -+MODULE_DESCRIPTION("Xtables: countdown quota match; up counter"); -+MODULE_AUTHOR("Sam Johnston "); -+MODULE_AUTHOR("Jan Engelhardt "); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("ipt_quota2"); -+MODULE_ALIAS("ip6t_quota2"); diff --git a/patches/ANDROID-of-Support-CONFIG_CMDLINE_EXTEND-config-option.patch b/patches/ANDROID-of-Support-CONFIG_CMDLINE_EXTEND-config-option.patch deleted file mode 100644 index 4973521f7168..000000000000 --- a/patches/ANDROID-of-Support-CONFIG_CMDLINE_EXTEND-config-option.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Doug Anderson -Date: Thu, 2 Feb 2012 22:58:28 -0800 -Subject: ANDROID: of: Support CONFIG_CMDLINE_EXTEND config option - -The old logic assumes CMDLINE_FROM_BOOTLOADER vs. CMDLINE_FORCE and -ignores CMDLINE_EXTEND. Here's the old logic: - -- CONFIG_CMDLINE_FORCE=true - CONFIG_CMDLINE -- dt bootargs=non-empty: - dt bootargs -- dt bootargs=empty, @data is non-empty string - @data is left unchanged -- dt bootargs=empty, @data is empty string - CONFIG_CMDLINE (or "" if that's not defined) - -The new logic is now documented in of_fdt.h and is copied here for -reference: - -- CONFIG_CMDLINE_FORCE=true - CONFIG_CMDLINE -- CONFIG_CMDLINE_EXTEND=true, @data is non-empty string - @data + dt bootargs (even if dt bootargs are empty) -- CONFIG_CMDLINE_EXTEND=true, @data is empty string - CONFIG_CMDLINE + dt bootargs (even if dt bootargs are empty) -- CMDLINE_FROM_BOOTLOADER=true, dt bootargs=non-empty: - dt bootargs -- CMDLINE_FROM_BOOTLOADER=true, dt bootargs=empty, @data is non-empty string - @data is left unchanged -- CMDLINE_FROM_BOOTLOADER=true, dt bootargs=empty, @data is empty string - CONFIG_CMDLINE (or "" if that's not defined) - -Signed-off-by: Doug Anderson -CC: devicetree-discuss@lists.ozlabs.org -CC: Grant Likely -CC: Benjamin Herrenschmidt -CC: Rob Herring -Bug: 120440972 -Change-Id: I40ace250847f813358125dfcaa8998fd32cf7ea3 -Signed-off-by: Colin Cross -[AmitP: Folded following android-4.9 commit changes into this patch - e820270abb5d ("ANDROID: of: fix CONFIG_CMDLINE_EXTEND") - 9a4a74055444 ("ANDROID: of: Fix build warnings")] -Signed-off-by: Amit Pundir ---- - drivers/of/fdt.c | 74 ++++++++++++++++++++++++++++-------------- - include/linux/of_fdt.h | 21 ++++++++++++ - 2 files changed, 70 insertions(+), 25 deletions(-) - -diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c -index 223d617ecfe1..650c028de779 100644 ---- a/drivers/of/fdt.c -+++ b/drivers/of/fdt.c -@@ -1040,43 +1040,67 @@ int __init early_init_dt_scan_memory(unsigned long node, const char *uname, - return 0; - } - -+/* -+ * Convert configs to something easy to use in C code -+ */ -+#if defined(CONFIG_CMDLINE_FORCE) -+static const int overwrite_incoming_cmdline = 1; -+static const int read_dt_cmdline; -+static const int concat_cmdline; -+#elif defined(CONFIG_CMDLINE_EXTEND) -+static const int overwrite_incoming_cmdline; -+static const int read_dt_cmdline = 1; -+static const int concat_cmdline = 1; -+#else /* CMDLINE_FROM_BOOTLOADER */ -+static const int overwrite_incoming_cmdline; -+static const int read_dt_cmdline = 1; -+static const int concat_cmdline; -+#endif -+ -+#ifdef CONFIG_CMDLINE -+static const char *config_cmdline = CONFIG_CMDLINE; -+#else -+static const char *config_cmdline = ""; -+#endif -+ - int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, - int depth, void *data) - { -- int l; -- const char *p; -+ int l = 0; -+ const char *p = NULL; - const void *rng_seed; -+ char *cmdline = data; - - pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); - -- if (depth != 1 || !data || -+ if (depth != 1 || !cmdline || - (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) - return 0; - - early_init_dt_check_for_initrd(node); - -- /* Retrieve command line */ -- p = of_get_flat_dt_prop(node, "bootargs", &l); -- if (p != NULL && l > 0) -- strlcpy(data, p, min(l, COMMAND_LINE_SIZE)); -- -- /* -- * CONFIG_CMDLINE is meant to be a default in case nothing else -- * managed to set the command line, unless CONFIG_CMDLINE_FORCE -- * is set in which case we override whatever was found earlier. -- */ --#ifdef CONFIG_CMDLINE --#if defined(CONFIG_CMDLINE_EXTEND) -- strlcat(data, " ", COMMAND_LINE_SIZE); -- strlcat(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); --#elif defined(CONFIG_CMDLINE_FORCE) -- strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); --#else -- /* No arguments from boot loader, use kernel's cmdl*/ -- if (!((char *)data)[0]) -- strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); --#endif --#endif /* CONFIG_CMDLINE */ -+ /* Put CONFIG_CMDLINE in if forced or if data had nothing in it to start */ -+ if (overwrite_incoming_cmdline || !cmdline[0]) -+ strlcpy(cmdline, config_cmdline, COMMAND_LINE_SIZE); -+ -+ /* Retrieve command line unless forcing */ -+ if (read_dt_cmdline) -+ p = of_get_flat_dt_prop(node, "bootargs", &l); -+ -+ if (p != NULL && l > 0) { -+ if (concat_cmdline) { -+ int cmdline_len; -+ int copy_len; -+ strlcat(cmdline, " ", COMMAND_LINE_SIZE); -+ cmdline_len = strlen(cmdline); -+ copy_len = COMMAND_LINE_SIZE - cmdline_len - 1; -+ copy_len = min((int)l, copy_len); -+ strncpy(cmdline + cmdline_len, p, copy_len); -+ cmdline[cmdline_len + copy_len] = '\0'; -+ } else { -+ strlcpy(cmdline, p, min(l, COMMAND_LINE_SIZE)); -+ } -+ } - - pr_debug("Command line is: %s\n", (char*)data); - -diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h -index acf820e88952..9bbd5c06cb39 100644 ---- a/include/linux/of_fdt.h -+++ b/include/linux/of_fdt.h -@@ -58,6 +58,27 @@ extern int of_flat_dt_is_compatible(unsigned long node, const char *name); - extern unsigned long of_get_flat_dt_root(void); - extern uint32_t of_get_flat_dt_phandle(unsigned long node); - -+/* -+ * early_init_dt_scan_chosen - scan the device tree for ramdisk and bootargs -+ * -+ * The boot arguments will be placed into the memory pointed to by @data. -+ * That memory should be COMMAND_LINE_SIZE big and initialized to be a valid -+ * (possibly empty) string. Logic for what will be in @data after this -+ * function finishes: -+ * -+ * - CONFIG_CMDLINE_FORCE=true -+ * CONFIG_CMDLINE -+ * - CONFIG_CMDLINE_EXTEND=true, @data is non-empty string -+ * @data + dt bootargs (even if dt bootargs are empty) -+ * - CONFIG_CMDLINE_EXTEND=true, @data is empty string -+ * CONFIG_CMDLINE + dt bootargs (even if dt bootargs are empty) -+ * - CMDLINE_FROM_BOOTLOADER=true, dt bootargs=non-empty: -+ * dt bootargs -+ * - CMDLINE_FROM_BOOTLOADER=true, dt bootargs=empty, @data is non-empty string -+ * @data is left unchanged -+ * - CMDLINE_FROM_BOOTLOADER=true, dt bootargs=empty, @data is empty string -+ * CONFIG_CMDLINE (or "" if that's not defined) -+ */ - extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, - int depth, void *data); - extern int early_init_dt_scan_memory(unsigned long node, const char *uname, diff --git a/patches/ANDROID-power-wakeup_reason-add-an-API-to-log-wakeup-reasons.patch b/patches/ANDROID-power-wakeup_reason-add-an-API-to-log-wakeup-reasons.patch deleted file mode 100644 index acfe8cb9fe50..000000000000 --- a/patches/ANDROID-power-wakeup_reason-add-an-API-to-log-wakeup-reasons.patch +++ /dev/null @@ -1,584 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ruchi Kandoi -Date: Wed, 19 Feb 2014 15:30:47 -0800 -Subject: ANDROID: power: wakeup_reason: add an API to log wakeup reasons - -Add API log_wakeup_reason() and expose it to userspace via sysfs path -/sys/kernel/wakeup_reasons/last_resume_reason - -Bug: 120445600 -Signed-off-by: Ruchi Kandoi -[AmitP: Folded following android-4.9 commit changes into this patch - 1135122a192a ("ANDROID: POWER: fix compile warnings in log_wakeup_reason") - b4e6247778b0 ("ANDROID: Power: Changes the permission to read only for sysfs file /sys/kernel/wakeup_reasons/last_resume_reason") - e13dbc7c69cd ("ANDROID: power: wakeup_reason: rename irq_count to irqcount")] -Signed-off-by: Amit Pundir -[astrachan: Folded the following changes into this patch: - 39d7c7fe91c0 ("ANDROID: power: wakeup_reason: Add guard condition for maximum wakeup reasons") - 0730434bdf49 ("ANDROID: power: wakeup_reason: Avoids bogus error messages for the suspend aborts.") - 4e42dceae54e ("ANDROID: power: wakeup_reason: Adds functionality to log the last suspend abort reason.") - f21313b70ac7 ("ANDROID: power: wakeup_reason: Report suspend times from last_suspend_time") - f97ec34442ac ("ANDROID: power: wakeup_reason: fix suspend time reporting") - cd92df73e504 ("ANDROID: power: wakeup: Add last wake up source logging for suspend abort reason.") - 546b6ae3c087 ("ANDROID: power: wakeup: Add the guard condition for len in pm_get_active_wakeup_sources") - 1453d9ffcdbe ("ANDROID: power: wakeup_reason: make logging work in an interrupt context.")] -Change-Id: I81addaf420f1338255c5d0638b0d244a99d777d1 -Signed-off-by: Alistair Strachan ---- - .../ABI/testing/sysfs-kernel-wakeup_reasons | 16 ++ - drivers/base/power/main.c | 5 + - drivers/base/power/wakeup.c | 32 +++ - drivers/base/syscore.c | 5 +- - include/linux/suspend.h | 1 + - include/linux/wakeup_reason.h | 30 +++ - kernel/power/Makefile | 1 + - kernel/power/process.c | 22 +- - kernel/power/suspend.c | 20 +- - kernel/power/wakeup_reason.c | 215 ++++++++++++++++++ - 10 files changed, 339 insertions(+), 8 deletions(-) - create mode 100644 Documentation/ABI/testing/sysfs-kernel-wakeup_reasons - create mode 100644 include/linux/wakeup_reason.h - create mode 100644 kernel/power/wakeup_reason.c - -diff --git a/Documentation/ABI/testing/sysfs-kernel-wakeup_reasons b/Documentation/ABI/testing/sysfs-kernel-wakeup_reasons -new file mode 100644 -index 000000000000..acb19b91c192 ---- /dev/null -+++ b/Documentation/ABI/testing/sysfs-kernel-wakeup_reasons -@@ -0,0 +1,16 @@ -+What: /sys/kernel/wakeup_reasons/last_resume_reason -+Date: February 2014 -+Contact: Ruchi Kandoi -+Description: -+ The /sys/kernel/wakeup_reasons/last_resume_reason is -+ used to report wakeup reasons after system exited suspend. -+ -+What: /sys/kernel/wakeup_reasons/last_suspend_time -+Date: March 2015 -+Contact: jinqian -+Description: -+ The /sys/kernel/wakeup_reasons/last_suspend_time is -+ used to report time spent in last suspend cycle. It contains -+ two numbers (in seconds) separated by space. First number is -+ the time spent in suspend and resume processes. Second number -+ is the time spent in sleep state. -\ No newline at end of file -diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c -index 134a8af51511..f545b4526172 100644 ---- a/drivers/base/power/main.c -+++ b/drivers/base/power/main.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - - #include "../base.h" - #include "power.h" -@@ -1683,6 +1684,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) - pm_callback_t callback = NULL; - const char *info = NULL; - int error = 0; -+ char suspend_abort[MAX_SUSPEND_ABORT_LEN]; - DECLARE_DPM_WATCHDOG_ON_STACK(wd); - - TRACE_DEVICE(dev); -@@ -1706,6 +1708,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) - - if (pm_wakeup_pending()) { - dev->power.direct_complete = false; -+ pm_get_active_wakeup_sources(suspend_abort, -+ MAX_SUSPEND_ABORT_LEN); -+ log_suspend_abort_reason(suspend_abort); - async_error = -EBUSY; - goto Complete; - } -diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c -index 5817b51d2b15..06b3ce836a24 100644 ---- a/drivers/base/power/wakeup.c -+++ b/drivers/base/power/wakeup.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - - #include "power.h" -@@ -813,6 +814,37 @@ void pm_wakeup_dev_event(struct device *dev, unsigned int msec, bool hard) - } - EXPORT_SYMBOL_GPL(pm_wakeup_dev_event); - -+void pm_get_active_wakeup_sources(char *pending_wakeup_source, size_t max) -+{ -+ struct wakeup_source *ws, *last_active_ws = NULL; -+ int len = 0; -+ bool active = false; -+ -+ rcu_read_lock(); -+ list_for_each_entry_rcu(ws, &wakeup_sources, entry) { -+ if (ws->active && len < max) { -+ if (!active) -+ len += scnprintf(pending_wakeup_source, max, -+ "Pending Wakeup Sources: "); -+ len += scnprintf(pending_wakeup_source + len, max - len, -+ "%s ", ws->name); -+ active = true; -+ } else if (!active && -+ (!last_active_ws || -+ ktime_to_ns(ws->last_time) > -+ ktime_to_ns(last_active_ws->last_time))) { -+ last_active_ws = ws; -+ } -+ } -+ if (!active && last_active_ws) { -+ scnprintf(pending_wakeup_source, max, -+ "Last active Wakeup Source: %s", -+ last_active_ws->name); -+ } -+ rcu_read_unlock(); -+} -+EXPORT_SYMBOL_GPL(pm_get_active_wakeup_sources); -+ - void pm_print_active_wakeup_sources(void) - { - struct wakeup_source *ws; -diff --git a/drivers/base/syscore.c b/drivers/base/syscore.c -index 0d346a307140..f3ca20cc817b 100644 ---- a/drivers/base/syscore.c -+++ b/drivers/base/syscore.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - static LIST_HEAD(syscore_ops_list); - static DEFINE_MUTEX(syscore_ops_lock); -@@ -74,7 +75,9 @@ int syscore_suspend(void) - return 0; - - err_out: -- pr_err("PM: System core suspend callback %pS failed.\n", ops->suspend); -+ log_suspend_abort_reason("System core suspend callback %pS failed", -+ ops->suspend); -+ pr_err("PM: System core suspend callback %pF failed.\n", ops->suspend); - - list_for_each_entry_continue(ops, &syscore_ops_list, node) - if (ops->resume) -diff --git a/include/linux/suspend.h b/include/linux/suspend.h -index 6fc8843f1c9e..60113c8a796f 100644 ---- a/include/linux/suspend.h -+++ b/include/linux/suspend.h -@@ -503,6 +503,7 @@ extern bool pm_get_wakeup_count(unsigned int *count, bool block); - extern bool pm_save_wakeup_count(unsigned int count); - extern void pm_wakep_autosleep_enabled(bool set); - extern void pm_print_active_wakeup_sources(void); -+extern void pm_get_active_wakeup_sources(char *pending_sources, size_t max); - - extern void lock_system_sleep(void); - extern void unlock_system_sleep(void); -diff --git a/include/linux/wakeup_reason.h b/include/linux/wakeup_reason.h -new file mode 100644 -index 000000000000..9fbe209c7177 ---- /dev/null -+++ b/include/linux/wakeup_reason.h -@@ -0,0 +1,30 @@ -+/* -+ * include/linux/wakeup_reason.h -+ * -+ * Logs the reason which caused the kernel to resume -+ * from the suspend mode. -+ * -+ * Copyright (C) 2014 Google, Inc. -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ */ -+ -+#ifndef _LINUX_WAKEUP_REASON_H -+#define _LINUX_WAKEUP_REASON_H -+ -+#define MAX_SUSPEND_ABORT_LEN 256 -+ -+void log_wakeup_reason(int irq); -+#ifdef CONFIG_SUSPEND -+void log_suspend_abort_reason(const char *fmt, ...); -+#else -+static inline void log_suspend_abort_reason(const char *fmt, ...) { } -+#endif -+ -+#endif /* _LINUX_WAKEUP_REASON_H */ -diff --git a/kernel/power/Makefile b/kernel/power/Makefile -index e7e47d9be1e5..c673a1b73973 100644 ---- a/kernel/power/Makefile -+++ b/kernel/power/Makefile -@@ -16,4 +16,5 @@ obj-$(CONFIG_PM_WAKELOCKS) += wakelock.o - - obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o - -+obj-$(CONFIG_SUSPEND) += wakeup_reason.o - obj-$(CONFIG_ENERGY_MODEL) += energy_model.o -diff --git a/kernel/power/process.c b/kernel/power/process.c -index 4b6a54da7e65..dfd2494543c1 100644 ---- a/kernel/power/process.c -+++ b/kernel/power/process.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - /* - * Timeout for stopping processes -@@ -38,6 +39,9 @@ static int try_to_freeze_tasks(bool user_only) - unsigned int elapsed_msecs; - bool wakeup = false; - int sleep_usecs = USEC_PER_MSEC; -+#ifdef CONFIG_PM_SLEEP -+ char suspend_abort[MAX_SUSPEND_ABORT_LEN]; -+#endif - - start = ktime_get_boottime(); - -@@ -67,6 +71,11 @@ static int try_to_freeze_tasks(bool user_only) - break; - - if (pm_wakeup_pending()) { -+#ifdef CONFIG_PM_SLEEP -+ pm_get_active_wakeup_sources(suspend_abort, -+ MAX_SUSPEND_ABORT_LEN); -+ log_suspend_abort_reason(suspend_abort); -+#endif - wakeup = true; - break; - } -@@ -85,18 +94,21 @@ static int try_to_freeze_tasks(bool user_only) - elapsed = ktime_sub(end, start); - elapsed_msecs = ktime_to_ms(elapsed); - -- if (todo) { -+ if (wakeup) { - pr_cont("\n"); -- pr_err("Freezing of tasks %s after %d.%03d seconds " -- "(%d tasks refusing to freeze, wq_busy=%d):\n", -- wakeup ? "aborted" : "failed", -+ pr_err("Freezing of tasks aborted after %d.%03d seconds", -+ elapsed_msecs / 1000, elapsed_msecs % 1000); -+ } else if (todo) { -+ pr_cont("\n"); -+ pr_err("Freezing of tasks failed after %d.%03d seconds" -+ " (%d tasks refusing to freeze, wq_busy=%d):\n", - elapsed_msecs / 1000, elapsed_msecs % 1000, - todo - wq_busy, wq_busy); - - if (wq_busy) - show_workqueue_state(); - -- if (!wakeup || pm_debug_messages_on) { -+ if (pm_debug_messages_on) { - read_lock(&tasklist_lock); - for_each_process_thread(g, p) { - if (p != current && !freezer_should_skip(p) -diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c -index f3b7239f1892..de6b24bc0619 100644 ---- a/kernel/power/suspend.c -+++ b/kernel/power/suspend.c -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include - - #include "power.h" - -@@ -389,7 +390,8 @@ void __weak arch_suspend_enable_irqs(void) - */ - static int suspend_enter(suspend_state_t state, bool *wakeup) - { -- int error; -+ char suspend_abort[MAX_SUSPEND_ABORT_LEN]; -+ int error, last_dev; - - error = platform_suspend_prepare(state); - if (error) -@@ -397,7 +399,11 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) - - error = dpm_suspend_late(PMSG_SUSPEND); - if (error) { -+ last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1; -+ last_dev %= REC_FAILED_NUM; - pr_err("late suspend of devices failed\n"); -+ log_suspend_abort_reason("%s device failed to power down", -+ suspend_stats.failed_devs[last_dev]); - goto Platform_finish; - } - error = platform_suspend_prepare_late(state); -@@ -406,7 +412,11 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) - - error = dpm_suspend_noirq(PMSG_SUSPEND); - if (error) { -+ last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1; -+ last_dev %= REC_FAILED_NUM; - pr_err("noirq suspend of devices failed\n"); -+ log_suspend_abort_reason("noirq suspend of %s device failed", -+ suspend_stats.failed_devs[last_dev]); - goto Platform_early_resume; - } - error = platform_suspend_prepare_noirq(state); -@@ -422,8 +432,10 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) - } - - error = suspend_disable_secondary_cpus(); -- if (error || suspend_test(TEST_CPUS)) -+ if (error || suspend_test(TEST_CPUS)) { -+ log_suspend_abort_reason("Disabling non-boot cpus failed"); - goto Enable_cpus; -+ } - - arch_suspend_disable_irqs(); - BUG_ON(!irqs_disabled()); -@@ -440,6 +452,9 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) - trace_suspend_resume(TPS("machine_suspend"), - state, false); - } else if (*wakeup) { -+ pm_get_active_wakeup_sources(suspend_abort, -+ MAX_SUSPEND_ABORT_LEN); -+ log_suspend_abort_reason(suspend_abort); - error = -EBUSY; - } - syscore_resume(); -@@ -494,6 +509,7 @@ int suspend_devices_and_enter(suspend_state_t state) - error = dpm_suspend_start(PMSG_SUSPEND); - if (error) { - pr_err("Some devices failed to suspend, or early wake event detected\n"); -+ log_suspend_abort_reason("Some devices failed to suspend, or early wake event detected"); - goto Recover_platform; - } - suspend_test_finish("suspend devices"); -diff --git a/kernel/power/wakeup_reason.c b/kernel/power/wakeup_reason.c -new file mode 100644 -index 000000000000..3ce5c902e3d3 ---- /dev/null -+++ b/kernel/power/wakeup_reason.c -@@ -0,0 +1,215 @@ -+/* -+ * kernel/power/wakeup_reason.c -+ * -+ * Logs the reasons which caused the kernel to resume from -+ * the suspend mode. -+ * -+ * Copyright (C) 2014 Google, Inc. -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#define MAX_WAKEUP_REASON_IRQS 32 -+static int irq_list[MAX_WAKEUP_REASON_IRQS]; -+static int irqcount; -+static bool suspend_abort; -+static char abort_reason[MAX_SUSPEND_ABORT_LEN]; -+static struct kobject *wakeup_reason; -+static spinlock_t resume_reason_lock; -+ -+static ktime_t last_monotime; /* monotonic time before last suspend */ -+static ktime_t curr_monotime; /* monotonic time after last suspend */ -+static ktime_t last_stime; /* monotonic boottime offset before last suspend */ -+static ktime_t curr_stime; /* monotonic boottime offset after last suspend */ -+ -+static ssize_t last_resume_reason_show(struct kobject *kobj, struct kobj_attribute *attr, -+ char *buf) -+{ -+ int irq_no, buf_offset = 0; -+ struct irq_desc *desc; -+ unsigned long flags; -+ spin_lock_irqsave(&resume_reason_lock, flags); -+ if (suspend_abort) { -+ buf_offset = sprintf(buf, "Abort: %s", abort_reason); -+ } else { -+ for (irq_no = 0; irq_no < irqcount; irq_no++) { -+ desc = irq_to_desc(irq_list[irq_no]); -+ if (desc && desc->action && desc->action->name) -+ buf_offset += sprintf(buf + buf_offset, "%d %s\n", -+ irq_list[irq_no], desc->action->name); -+ else -+ buf_offset += sprintf(buf + buf_offset, "%d\n", -+ irq_list[irq_no]); -+ } -+ } -+ spin_unlock_irqrestore(&resume_reason_lock, flags); -+ return buf_offset; -+} -+ -+static ssize_t last_suspend_time_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ struct timespec64 sleep_time; -+ struct timespec64 total_time; -+ struct timespec64 suspend_resume_time; -+ -+ /* -+ * total_time is calculated from monotonic bootoffsets because -+ * unlike CLOCK_MONOTONIC it include the time spent in suspend state. -+ */ -+ total_time = ktime_to_timespec64(ktime_sub(curr_stime, last_stime)); -+ -+ /* -+ * suspend_resume_time is calculated as monotonic (CLOCK_MONOTONIC) -+ * time interval before entering suspend and post suspend. -+ */ -+ suspend_resume_time = -+ ktime_to_timespec64(ktime_sub(curr_monotime, last_monotime)); -+ -+ /* sleep_time = total_time - suspend_resume_time */ -+ sleep_time = timespec64_sub(total_time, suspend_resume_time); -+ -+ /* Export suspend_resume_time and sleep_time in pair here. */ -+ return sprintf(buf, "%llu.%09lu %llu.%09lu\n", -+ suspend_resume_time.tv_sec, suspend_resume_time.tv_nsec, -+ sleep_time.tv_sec, sleep_time.tv_nsec); -+} -+ -+static struct kobj_attribute resume_reason = __ATTR_RO(last_resume_reason); -+static struct kobj_attribute suspend_time = __ATTR_RO(last_suspend_time); -+ -+static struct attribute *attrs[] = { -+ &resume_reason.attr, -+ &suspend_time.attr, -+ NULL, -+}; -+static struct attribute_group attr_group = { -+ .attrs = attrs, -+}; -+ -+/* -+ * logs all the wake up reasons to the kernel -+ * stores the irqs to expose them to the userspace via sysfs -+ */ -+void log_wakeup_reason(int irq) -+{ -+ struct irq_desc *desc; -+ unsigned long flags; -+ desc = irq_to_desc(irq); -+ if (desc && desc->action && desc->action->name) -+ printk(KERN_INFO "Resume caused by IRQ %d, %s\n", irq, -+ desc->action->name); -+ else -+ printk(KERN_INFO "Resume caused by IRQ %d\n", irq); -+ -+ spin_lock_irqsave(&resume_reason_lock, flags); -+ if (irqcount == MAX_WAKEUP_REASON_IRQS) { -+ spin_unlock_irqrestore(&resume_reason_lock, flags); -+ printk(KERN_WARNING "Resume caused by more than %d IRQs\n", -+ MAX_WAKEUP_REASON_IRQS); -+ return; -+ } -+ -+ irq_list[irqcount++] = irq; -+ spin_unlock_irqrestore(&resume_reason_lock, flags); -+} -+ -+void log_suspend_abort_reason(const char *fmt, ...) -+{ -+ unsigned long flags; -+ va_list args; -+ -+ spin_lock_irqsave(&resume_reason_lock, flags); -+ -+ //Suspend abort reason has already been logged. -+ if (suspend_abort) { -+ spin_unlock_irqrestore(&resume_reason_lock, flags); -+ return; -+ } -+ -+ suspend_abort = true; -+ va_start(args, fmt); -+ vsnprintf(abort_reason, MAX_SUSPEND_ABORT_LEN, fmt, args); -+ va_end(args); -+ spin_unlock_irqrestore(&resume_reason_lock, flags); -+} -+ -+/* Detects a suspend and clears all the previous wake up reasons*/ -+static int wakeup_reason_pm_event(struct notifier_block *notifier, -+ unsigned long pm_event, void *unused) -+{ -+ unsigned long flags; -+ switch (pm_event) { -+ case PM_SUSPEND_PREPARE: -+ spin_lock_irqsave(&resume_reason_lock, flags); -+ irqcount = 0; -+ suspend_abort = false; -+ spin_unlock_irqrestore(&resume_reason_lock, flags); -+ /* monotonic time since boot */ -+ last_monotime = ktime_get(); -+ /* monotonic time since boot including the time spent in suspend */ -+ last_stime = ktime_get_boottime(); -+ break; -+ case PM_POST_SUSPEND: -+ /* monotonic time since boot */ -+ curr_monotime = ktime_get(); -+ /* monotonic time since boot including the time spent in suspend */ -+ curr_stime = ktime_get_boottime(); -+ break; -+ default: -+ break; -+ } -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block wakeup_reason_pm_notifier_block = { -+ .notifier_call = wakeup_reason_pm_event, -+}; -+ -+/* Initializes the sysfs parameter -+ * registers the pm_event notifier -+ */ -+int __init wakeup_reason_init(void) -+{ -+ int retval; -+ spin_lock_init(&resume_reason_lock); -+ retval = register_pm_notifier(&wakeup_reason_pm_notifier_block); -+ if (retval) -+ printk(KERN_WARNING "[%s] failed to register PM notifier %d\n", -+ __func__, retval); -+ -+ wakeup_reason = kobject_create_and_add("wakeup_reasons", kernel_kobj); -+ if (!wakeup_reason) { -+ printk(KERN_WARNING "[%s] failed to create a sysfs kobject\n", -+ __func__); -+ return 1; -+ } -+ retval = sysfs_create_group(wakeup_reason, &attr_group); -+ if (retval) { -+ kobject_put(wakeup_reason); -+ printk(KERN_WARNING "[%s] failed to create a sysfs group %d\n", -+ __func__, retval); -+ } -+ return 0; -+} -+ -+late_initcall(wakeup_reason_init); diff --git a/patches/ANDROID-proc-Add-proc-uid-directory.patch b/patches/ANDROID-proc-Add-proc-uid-directory.patch deleted file mode 100644 index c6a41602d3ec..000000000000 --- a/patches/ANDROID-proc-Add-proc-uid-directory.patch +++ /dev/null @@ -1,433 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Connor O'Brien -Date: Mon, 16 Oct 2017 10:30:24 -0700 -Subject: ANDROID: proc: Add /proc/uid directory - -Add support for reporting per-uid information through procfs, roughly -following the approach used for per-tid and per-tgid directories in -fs/proc/base.c. -This also entails some new tracking of which uids have been used, to -avoid losing information when the last task with a given uid exits. - -Bug: 72339335 -Bug: 127641090 -Test: ls /proc/uid/; compare with UIDs in /proc/uid_time_in_state -Change-Id: I0908f0c04438b11ceb673d860e58441bf503d478 -Signed-off-by: Connor O'Brien -[AmitP: Fix proc_fill_cache() now that upstream commit - 0168b9e38c42 ("procfs: switch instantiate_t to d_splice_alias()"), - switched instantiate() callback to d_splice_alias()] -Signed-off-by: Amit Pundir -[astrachan: Folded 97b7790f505e ("ANDROID: proc: fix undefined behavior - in proc_uid_base_readdir") into this change] -Signed-off-by: Alistair Strachan ---- - fs/proc/Kconfig | 6 + - fs/proc/Makefile | 1 + - fs/proc/internal.h | 9 ++ - fs/proc/root.c | 1 + - fs/proc/uid.c | 290 ++++++++++++++++++++++++++++++++++++++++ - include/linux/proc_fs.h | 6 + - kernel/user.c | 3 + - 7 files changed, 316 insertions(+) - create mode 100644 fs/proc/uid.c - -diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig -index cb5629bd5fff..313ae27bb674 100644 ---- a/fs/proc/Kconfig -+++ b/fs/proc/Kconfig -@@ -103,3 +103,9 @@ config PROC_CHILDREN - config PROC_PID_ARCH_STATUS - def_bool n - depends on PROC_FS -+ -+config PROC_UID -+ bool "Include /proc/uid/ files" -+ depends on PROC_FS && RT_MUTEXES -+ help -+ Provides aggregated per-uid information under /proc/uid. -diff --git a/fs/proc/Makefile b/fs/proc/Makefile -index ead487e80510..3f849ca0edce 100644 ---- a/fs/proc/Makefile -+++ b/fs/proc/Makefile -@@ -27,6 +27,7 @@ proc-y += softirqs.o - proc-y += namespaces.o - proc-y += self.o - proc-y += thread_self.o -+proc-$(CONFIG_PROC_UID) += uid.o - proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o - proc-$(CONFIG_NET) += proc_net.o - proc-$(CONFIG_PROC_KCORE) += kcore.o -diff --git a/fs/proc/internal.h b/fs/proc/internal.h -index cd0c8d5ce9a1..95846552ef24 100644 ---- a/fs/proc/internal.h -+++ b/fs/proc/internal.h -@@ -253,6 +253,15 @@ static inline void proc_sys_evict_inode(struct inode *inode, - struct ctl_table_header *head) { } - #endif - -+/* -+ * uid.c -+ */ -+#ifdef CONFIG_PROC_UID -+extern int proc_uid_init(void); -+#else -+static inline void proc_uid_init(void) { } -+#endif -+ - /* - * proc_tty.c - */ -diff --git a/fs/proc/root.c b/fs/proc/root.c -index 0b7c8dffc9ae..485237e7cce1 100644 ---- a/fs/proc/root.c -+++ b/fs/proc/root.c -@@ -221,6 +221,7 @@ void __init proc_root_init(void) - proc_symlink("mounts", NULL, "self/mounts"); - - proc_net_init(); -+ proc_uid_init(); - proc_mkdir("fs", NULL); - proc_mkdir("driver", NULL); - proc_create_mount_point("fs/nfsd"); /* somewhere for the nfsd filesystem to be mounted */ -diff --git a/fs/proc/uid.c b/fs/proc/uid.c -new file mode 100644 -index 000000000000..ae720b93a0ed ---- /dev/null -+++ b/fs/proc/uid.c -@@ -0,0 +1,290 @@ -+/* -+ * /proc/uid support -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "internal.h" -+ -+static struct proc_dir_entry *proc_uid; -+ -+#define UID_HASH_BITS 10 -+ -+static DECLARE_HASHTABLE(proc_uid_hash_table, UID_HASH_BITS); -+ -+/* -+ * use rt_mutex here to avoid priority inversion between high-priority readers -+ * of these files and tasks calling proc_register_uid(). -+ */ -+static DEFINE_RT_MUTEX(proc_uid_lock); /* proc_uid_hash_table */ -+ -+struct uid_hash_entry { -+ uid_t uid; -+ struct hlist_node hash; -+}; -+ -+/* Caller must hold proc_uid_lock */ -+static bool uid_hash_entry_exists_locked(uid_t uid) -+{ -+ struct uid_hash_entry *entry; -+ -+ hash_for_each_possible(proc_uid_hash_table, entry, hash, uid) { -+ if (entry->uid == uid) -+ return true; -+ } -+ return false; -+} -+ -+void proc_register_uid(kuid_t kuid) -+{ -+ struct uid_hash_entry *entry; -+ bool exists; -+ uid_t uid = from_kuid_munged(current_user_ns(), kuid); -+ -+ rt_mutex_lock(&proc_uid_lock); -+ exists = uid_hash_entry_exists_locked(uid); -+ rt_mutex_unlock(&proc_uid_lock); -+ if (exists) -+ return; -+ -+ entry = kzalloc(sizeof(struct uid_hash_entry), GFP_KERNEL); -+ if (!entry) -+ return; -+ entry->uid = uid; -+ -+ rt_mutex_lock(&proc_uid_lock); -+ if (uid_hash_entry_exists_locked(uid)) -+ kfree(entry); -+ else -+ hash_add(proc_uid_hash_table, &entry->hash, uid); -+ rt_mutex_unlock(&proc_uid_lock); -+} -+ -+struct uid_entry { -+ const char *name; -+ int len; -+ umode_t mode; -+ const struct inode_operations *iop; -+ const struct file_operations *fop; -+}; -+ -+#define NOD(NAME, MODE, IOP, FOP) { \ -+ .name = (NAME), \ -+ .len = sizeof(NAME) - 1, \ -+ .mode = MODE, \ -+ .iop = IOP, \ -+ .fop = FOP, \ -+} -+ -+static const struct uid_entry uid_base_stuff[] = {}; -+ -+static const struct inode_operations proc_uid_def_inode_operations = { -+ .setattr = proc_setattr, -+}; -+ -+static struct inode *proc_uid_make_inode(struct super_block *sb, kuid_t kuid) -+{ -+ struct inode *inode; -+ -+ inode = new_inode(sb); -+ if (!inode) -+ return NULL; -+ -+ inode->i_ino = get_next_ino(); -+ inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); -+ inode->i_op = &proc_uid_def_inode_operations; -+ inode->i_uid = kuid; -+ -+ return inode; -+} -+ -+static struct dentry *proc_uident_instantiate(struct dentry *dentry, -+ struct task_struct *unused, const void *ptr) -+{ -+ const struct uid_entry *u = ptr; -+ struct inode *inode; -+ -+ uid_t uid = name_to_int(&dentry->d_name); -+ kuid_t kuid; -+ bool uid_exists; -+ rt_mutex_lock(&proc_uid_lock); -+ uid_exists = uid_hash_entry_exists_locked(uid); -+ rt_mutex_unlock(&proc_uid_lock); -+ if (uid_exists) { -+ kuid = make_kuid(current_user_ns(), uid); -+ inode = proc_uid_make_inode(dentry->d_sb, kuid); -+ if (!inode) -+ return ERR_PTR(-ENOENT); -+ } else { -+ return ERR_PTR(-ENOENT); -+ } -+ -+ inode->i_mode = u->mode; -+ if (S_ISDIR(inode->i_mode)) -+ set_nlink(inode, 2); -+ if (u->iop) -+ inode->i_op = u->iop; -+ if (u->fop) -+ inode->i_fop = u->fop; -+ -+ return d_splice_alias(inode, dentry); -+} -+ -+static struct dentry *proc_uid_base_lookup(struct inode *dir, -+ struct dentry *dentry, -+ unsigned int flags) -+{ -+ const struct uid_entry *u, *last; -+ unsigned int nents = ARRAY_SIZE(uid_base_stuff); -+ -+ if (nents == 0) -+ return ERR_PTR(-ENOENT); -+ -+ last = &uid_base_stuff[nents - 1]; -+ for (u = uid_base_stuff; u <= last; u++) { -+ if (u->len != dentry->d_name.len) -+ continue; -+ if (!memcmp(dentry->d_name.name, u->name, u->len)) -+ break; -+ } -+ if (u > last) -+ return ERR_PTR(-ENOENT); -+ -+ return proc_uident_instantiate(dentry, NULL, u); -+} -+ -+static int proc_uid_base_readdir(struct file *file, struct dir_context *ctx) -+{ -+ unsigned int nents = ARRAY_SIZE(uid_base_stuff); -+ const struct uid_entry *u; -+ -+ if (!dir_emit_dots(file, ctx)) -+ return 0; -+ -+ if (ctx->pos >= nents + 2) -+ return 0; -+ -+ for (u = uid_base_stuff + (ctx->pos - 2); -+ u < uid_base_stuff + nents; u++) { -+ if (!proc_fill_cache(file, ctx, u->name, u->len, -+ proc_uident_instantiate, NULL, u)) -+ break; -+ ctx->pos++; -+ } -+ -+ return 0; -+} -+ -+static const struct inode_operations proc_uid_base_inode_operations = { -+ .lookup = proc_uid_base_lookup, -+ .setattr = proc_setattr, -+}; -+ -+static const struct file_operations proc_uid_base_operations = { -+ .read = generic_read_dir, -+ .iterate = proc_uid_base_readdir, -+ .llseek = default_llseek, -+}; -+ -+static struct dentry *proc_uid_instantiate(struct dentry *dentry, -+ struct task_struct *unused, const void *ptr) -+{ -+ unsigned int i, len; -+ nlink_t nlinks; -+ kuid_t *kuid = (kuid_t *)ptr; -+ struct inode *inode = proc_uid_make_inode(dentry->d_sb, *kuid); -+ -+ if (!inode) -+ return ERR_PTR(-ENOENT); -+ -+ inode->i_mode = S_IFDIR | 0555; -+ inode->i_op = &proc_uid_base_inode_operations; -+ inode->i_fop = &proc_uid_base_operations; -+ inode->i_flags |= S_IMMUTABLE; -+ -+ nlinks = 2; -+ len = ARRAY_SIZE(uid_base_stuff); -+ for (i = 0; i < len; ++i) { -+ if (S_ISDIR(uid_base_stuff[i].mode)) -+ ++nlinks; -+ } -+ set_nlink(inode, nlinks); -+ -+ return d_splice_alias(inode, dentry); -+} -+ -+static int proc_uid_readdir(struct file *file, struct dir_context *ctx) -+{ -+ int last_shown, i; -+ unsigned long bkt; -+ struct uid_hash_entry *entry; -+ -+ if (!dir_emit_dots(file, ctx)) -+ return 0; -+ -+ i = 0; -+ last_shown = ctx->pos - 2; -+ rt_mutex_lock(&proc_uid_lock); -+ hash_for_each(proc_uid_hash_table, bkt, entry, hash) { -+ int len; -+ char buf[PROC_NUMBUF]; -+ -+ if (i < last_shown) -+ continue; -+ len = snprintf(buf, sizeof(buf), "%u", entry->uid); -+ if (!proc_fill_cache(file, ctx, buf, len, -+ proc_uid_instantiate, NULL, &entry->uid)) -+ break; -+ i++; -+ ctx->pos++; -+ } -+ rt_mutex_unlock(&proc_uid_lock); -+ return 0; -+} -+ -+static struct dentry *proc_uid_lookup(struct inode *dir, struct dentry *dentry, -+ unsigned int flags) -+{ -+ int result = -ENOENT; -+ -+ uid_t uid = name_to_int(&dentry->d_name); -+ bool uid_exists; -+ -+ rt_mutex_lock(&proc_uid_lock); -+ uid_exists = uid_hash_entry_exists_locked(uid); -+ rt_mutex_unlock(&proc_uid_lock); -+ if (uid_exists) { -+ kuid_t kuid = make_kuid(current_user_ns(), uid); -+ -+ return proc_uid_instantiate(dentry, NULL, &kuid); -+ } -+ return ERR_PTR(result); -+} -+ -+static const struct file_operations proc_uid_operations = { -+ .read = generic_read_dir, -+ .iterate = proc_uid_readdir, -+ .llseek = default_llseek, -+}; -+ -+static const struct inode_operations proc_uid_inode_operations = { -+ .lookup = proc_uid_lookup, -+ .setattr = proc_setattr, -+}; -+ -+int __init proc_uid_init(void) -+{ -+ proc_uid = proc_mkdir("uid", NULL); -+ if (!proc_uid) -+ return -ENOMEM; -+ proc_uid->proc_iops = &proc_uid_inode_operations; -+ proc_uid->proc_fops = &proc_uid_operations; -+ -+ return 0; -+} -diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h -index a705aa2d03f9..35e83f86e51a 100644 ---- a/include/linux/proc_fs.h -+++ b/include/linux/proc_fs.h -@@ -131,6 +131,12 @@ static inline struct pid *tgid_pidfd_to_pid(const struct file *file) - - #endif /* CONFIG_PROC_FS */ - -+#ifdef CONFIG_PROC_UID -+extern void proc_register_uid(kuid_t uid); -+#else -+static inline void proc_register_uid(kuid_t uid) {} -+#endif -+ - struct net; - - static inline struct proc_dir_entry *proc_net_mkdir( -diff --git a/kernel/user.c b/kernel/user.c -index 5235d7f49982..a32a8a59a13c 100644 ---- a/kernel/user.c -+++ b/kernel/user.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - - /* -@@ -205,6 +206,7 @@ struct user_struct *alloc_uid(kuid_t uid) - } - spin_unlock_irq(&uidhash_lock); - } -+ proc_register_uid(uid); - - return up; - } -@@ -223,6 +225,7 @@ static int __init uid_cache_init(void) - spin_lock_irq(&uidhash_lock); - uid_hash_insert(&root_user, uidhashentry(GLOBAL_ROOT_UID)); - spin_unlock_irq(&uidhash_lock); -+ proc_register_uid(GLOBAL_ROOT_UID); - - return 0; - } diff --git a/patches/ANDROID-refactor-build.config-files-to-remove-duplication.patch b/patches/ANDROID-refactor-build.config-files-to-remove-duplication.patch deleted file mode 100644 index 81b688b3a936..000000000000 --- a/patches/ANDROID-refactor-build.config-files-to-remove-duplication.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Matthias Maennich -Date: Thu, 29 Aug 2019 12:34:52 +0100 -Subject: ANDROID: refactor build.config files to remove duplication - -The build.config.* files largely contain duplicate information by their -nature. Reorganize them reduce duplication and to allow adding new -configurations without copying the definitions again. - -Bug: 140224784 -Change-Id: I6a3810a125b0ed48591690ca33bb5c02be58218a -Signed-off-by: Matthias Maennich ---- - build.config.aarch64 | 11 +++++++++++ - build.config.common | 9 +++++++++ - build.config.gki | 4 ++++ - build.config.gki.x86_64 | 23 ++++------------------- - build.config.x86_64 | 11 +++++++++++ - 5 files changed, 39 insertions(+), 19 deletions(-) - create mode 100644 build.config.aarch64 - create mode 100644 build.config.common - create mode 100644 build.config.gki - create mode 100644 build.config.x86_64 - -diff --git a/build.config.aarch64 b/build.config.aarch64 -new file mode 100644 -index 000000000000..523bbc0449f7 ---- /dev/null -+++ b/build.config.aarch64 -@@ -0,0 +1,11 @@ -+ARCH=arm64 -+ -+CLANG_TRIPLE=aarch64-linux-gnu- -+CROSS_COMPILE=aarch64-linux-androidkernel- -+LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin -+ -+FILES=" -+arch/arm64/boot/Image.gz -+vmlinux -+System.map -+" -diff --git a/build.config.common b/build.config.common -new file mode 100644 -index 000000000000..3f1fac231a82 ---- /dev/null -+++ b/build.config.common -@@ -0,0 +1,9 @@ -+BRANCH=android-mainline -+KERNEL_DIR=common -+ -+CC=clang -+CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin -+BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 -+ -+EXTRA_CMDS='' -+STOP_SHIP_TRACEPRINTK=1 -diff --git a/build.config.gki b/build.config.gki -new file mode 100644 -index 000000000000..66f6eb8baadb ---- /dev/null -+++ b/build.config.gki -@@ -0,0 +1,4 @@ -+DEFCONFIG=gki_defconfig -+POST_DEFCONFIG_CMDS="check_defconfig" -+BUILD_INITRAMFS=1 -+ -diff --git a/build.config.gki.x86_64 b/build.config.gki.x86_64 -index 5c2db37a2871..627d1e1c27ab 100644 ---- a/build.config.gki.x86_64 -+++ b/build.config.gki.x86_64 -@@ -1,19 +1,4 @@ --ARCH=x86_64 --BRANCH=android-mainline --CLANG_TRIPLE=x86_64-linux-gnu- --CROSS_COMPILE=x86_64-linux-androidkernel- --CC=clang --DEFCONFIG=gki_defconfig --EXTRA_CMDS='' --KERNEL_DIR=common --POST_DEFCONFIG_CMDS="check_defconfig" --CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r353983c/bin --BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 --LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin --FILES=" --arch/x86/boot/bzImage --vmlinux --System.map --" --STOP_SHIP_TRACEPRINTK=1 --BUILD_INITRAMFS=1 -+. ${ROOT_DIR}/common/build.config.common -+. ${ROOT_DIR}/common/build.config.x86_64 -+. ${ROOT_DIR}/common/build.config.gki -+ -diff --git a/build.config.x86_64 b/build.config.x86_64 -new file mode 100644 -index 000000000000..df73a47e7220 ---- /dev/null -+++ b/build.config.x86_64 -@@ -0,0 +1,11 @@ -+ARCH=x86_64 -+ -+CLANG_TRIPLE=x86_64-linux-gnu- -+CROSS_COMPILE=x86_64-linux-androidkernel- -+LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin -+ -+FILES=" -+arch/x86/boot/bzImage -+vmlinux -+System.map -+" diff --git a/patches/ANDROID-sched-Honor-sync-flag-for-energy-aware-wakeups.patch b/patches/ANDROID-sched-Honor-sync-flag-for-energy-aware-wakeups.patch deleted file mode 100644 index 0e51f4e02b75..000000000000 --- a/patches/ANDROID-sched-Honor-sync-flag-for-energy-aware-wakeups.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Redpath -Date: Thu, 17 Oct 2019 11:18:08 +0100 -Subject: ANDROID: sched: Honor sync flag for energy-aware wakeups - -Since we don't do energy-aware wakeups when we are overutilized, always -honoring sync wakeups in this state does not prevent wake-wide mechanics -overruling the flag as normal. - -Having the check for (cpu_rq(cpu)->nr_running == 1) in the test condition -means that we only bypass the energy model for sync wakeups where the -cpu is about to become idle. This matches the use of this flag in Binder -which is the main place where sync wakeups come from in Android. - -This patch is based upon previous work to build EAS for android products. -It replaces -commit 79e3a4a27ee5 ("ANDROID: sched: Unconditionally honor sync flag - for energy-aware wakeups") -in what's considered to be 'EAS'. - -sync-hint code taken from wahoo -https://android.googlesource.com/kernel/msm/+/4a5e890ec60d -written by Juri Lelli - -Change-Id: I4b3d79141fc8e53dc51cd63ac11096c2e3cb10f5 -Signed-off-by: Chris Redpath -(cherry-picked from commit f1ec666a62de) -[ Moved the feature to find_energy_efficient_cpu() and removed the - sysctl knob ] -Signed-off-by: Quentin Perret -[ Add 'cpu_rq(cpu)->nr_running == 1' to the condition and remove the - word 'Unconditionally' from the patch name ] -Signed-off-by: Dietmar Eggemann ---- - kernel/sched/fair.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index ba1eaa599dbc..8f8692baa679 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -6364,7 +6364,8 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy - goto fail; - - cpu = smp_processor_id(); -- if (sync && cpumask_test_cpu(cpu, p->cpus_ptr)) { -+ if (sync && cpu_rq(cpu)->nr_running == 1 && -+ cpumask_test_cpu(cpu, p->cpus_ptr)) { - rcu_read_unlock(); - return cpu; - } diff --git a/patches/ANDROID-sched-Introduce-uclamp-latency-and-boost-wrapper.patch b/patches/ANDROID-sched-Introduce-uclamp-latency-and-boost-wrapper.patch deleted file mode 100644 index 552fbd9a44fa..000000000000 --- a/patches/ANDROID-sched-Introduce-uclamp-latency-and-boost-wrapper.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Quentin Perret -Date: Tue, 30 Jul 2019 13:58:29 +0100 -Subject: ANDROID: sched: Introduce uclamp latency and boost wrapper - -Introduce a simple helper to read the latency_sensitive flag from a -task. It is called uclamp_latency_sensitive() to match the API -proposed by Patrick. - -While at it, introduce uclamp_boosted() which returns true only when a -task has a non-null min-clamp. - -Change-Id: I5fc747da8b58625257a6604a3c88487b657fbe7a -Suggested-by: Patrick Bellasi -Signed-off-by: Quentin Perret ---- - kernel/sched/sched.h | 28 ++++++++++++++++++++++++++++ - 1 file changed, 28 insertions(+) - -diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h -index 7de9f16cb838..4f0d1668c283 100644 ---- a/kernel/sched/sched.h -+++ b/kernel/sched/sched.h -@@ -2333,6 +2333,11 @@ static inline unsigned int uclamp_util(struct rq *rq, unsigned int util) - { - return uclamp_util_with(rq, util, NULL); - } -+ -+static inline bool uclamp_boosted(struct task_struct *p) -+{ -+ return uclamp_eff_value(p, UCLAMP_MIN) > 0; -+} - #else /* CONFIG_UCLAMP_TASK */ - static inline unsigned int uclamp_util_with(struct rq *rq, unsigned int util, - struct task_struct *p) -@@ -2343,8 +2348,31 @@ static inline unsigned int uclamp_util(struct rq *rq, unsigned int util) - { - return util; - } -+static inline bool uclamp_boosted(struct task_struct *p) -+{ -+ return false; -+} - #endif /* CONFIG_UCLAMP_TASK */ - -+#ifdef CONFIG_UCLAMP_TASK_GROUP -+static inline bool uclamp_latency_sensitive(struct task_struct *p) -+{ -+ struct cgroup_subsys_state *css = task_css(p, cpu_cgrp_id); -+ struct task_group *tg; -+ -+ if (!css) -+ return false; -+ tg = container_of(css, struct task_group, css); -+ -+ return tg->latency_sensitive; -+} -+#else -+static inline bool uclamp_latency_sensitive(struct task_struct *p) -+{ -+ return false; -+} -+#endif /* CONFIG_UCLAMP_TASK_GROUP */ -+ - #ifdef arch_scale_freq_capacity - # ifndef arch_scale_freq_invariant - # define arch_scale_freq_invariant() true diff --git a/patches/ANDROID-sched-Prevent-unnecessary-active-balance-of-single-task-in-sched-group.patch b/patches/ANDROID-sched-Prevent-unnecessary-active-balance-of-single-task-in-sched-group.patch deleted file mode 100644 index 19d240f9ef0f..000000000000 --- a/patches/ANDROID-sched-Prevent-unnecessary-active-balance-of-single-task-in-sched-group.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Morten Rasmussen -Date: Thu, 2 Jul 2015 17:16:34 +0100 -Subject: ANDROID: sched: Prevent unnecessary active balance of single task in - sched group - -Scenarios with the busiest group having just one task and the local -being idle on topologies with sched groups with different numbers of -cpus manage to dodge all load-balance bailout conditions resulting the -nr_balance_failed counter to be incremented. This eventually causes a -pointless active migration of the task. This patch prevents this by not -incrementing the counter when the busiest group only has one task. -ASYM_PACKING migrations and migrations due to reduced capacity should -still take place as these are explicitly captured by -need_active_balance(). - -A better solution would be to not attempt the load-balance in the first -place, but that requires significant changes to the order of bailout -conditions and statistics gathering. - -Change-Id: I28f69c72febe0211decbe77b7bc3e48839d3d7b3 -cc: Ingo Molnar -cc: Peter Zijlstra -Signed-off-by: Morten Rasmussen -Signed-off-by: Quentin Perret ---- - kernel/sched/fair.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index f0631d17c0bf..b62581b58f13 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -7120,6 +7120,7 @@ struct lb_env { - int new_dst_cpu; - enum cpu_idle_type idle; - long imbalance; -+ unsigned int src_grp_nr_running; - /* The set of CPUs under consideration for load-balancing */ - struct cpumask *cpus; - -@@ -8302,6 +8303,8 @@ static inline void update_sd_lb_stats(struct lb_env *env, struct sd_lb_stats *sd - if (env->sd->flags & SD_NUMA) - env->fbq_type = fbq_classify_group(&sds->busiest_stat); - -+ env->src_grp_nr_running = sds->busiest_stat.sum_nr_running; -+ - if (!env->sd->parent) { - struct root_domain *rd = env->dst_rq->rd; - -@@ -8996,7 +8999,8 @@ static int load_balance(int this_cpu, struct rq *this_rq, - * excessive cache_hot migrations and active balances. - */ - if (idle != CPU_NEWLY_IDLE) -- sd->nr_balance_failed++; -+ if (env.src_grp_nr_running > 1) -+ sd->nr_balance_failed++; - - if (need_active_balance(&env)) { - unsigned long flags; diff --git a/patches/ANDROID-sched-Unconditionally-honor-sync-flag-for-energy-aware-wakeups.patch b/patches/ANDROID-sched-Unconditionally-honor-sync-flag-for-energy-aware-wakeups.patch deleted file mode 100644 index 24d18deb0a67..000000000000 --- a/patches/ANDROID-sched-Unconditionally-honor-sync-flag-for-energy-aware-wakeups.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Redpath -Date: Wed, 27 Mar 2019 17:15:17 +0000 -Subject: ANDROID: sched: Unconditionally honor sync flag for energy-aware - wakeups - -Since we don't do energy-aware wakeups when we are overutilized, always -honoring sync wakeups in this state does not prevent wake-wide mechanics -overruling the flag as normal. - -This patch is based upon previous work to build EAS for android products. - -sync-hint code taken from commit 4a5e890ec60d -"sched/fair: add tunable to force selection at cpu granularity" written -by Juri Lelli - -Change-Id: I4b3d79141fc8e53dc51cd63ac11096c2e3cb10f5 -Signed-off-by: Chris Redpath -(cherry-picked from commit f1ec666a62dec1083ed52fe1ddef093b84373aaf) -[ Moved the feature to find_energy_efficient_cpu() and removed the - sysctl knob ] -Signed-off-by: Quentin Perret ---- - kernel/sched/fair.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index 49137eff0c8e..43d3321ce61e 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -6344,7 +6344,7 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd) - * other use-cases too. So, until someone finds a better way to solve this, - * let's keep things simple by re-using the existing slow path. - */ --static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) -+static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sync) - { - unsigned long prev_delta = ULONG_MAX, best_delta = ULONG_MAX; - struct root_domain *rd = cpu_rq(smp_processor_id())->rd; -@@ -6358,6 +6358,12 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) - if (!pd || READ_ONCE(rd->overutilized)) - goto fail; - -+ cpu = smp_processor_id(); -+ if (sync && cpumask_test_cpu(cpu, p->cpus_ptr)) { -+ rcu_read_unlock(); -+ return cpu; -+ } -+ - /* - * Energy-aware wake-up happens on the lowest sched_domain starting - * from sd_asym_cpucapacity spanning over this_cpu and prev_cpu. -@@ -6469,7 +6475,7 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f - record_wakee(p); - - if (sched_energy_enabled()) { -- new_cpu = find_energy_efficient_cpu(p, prev_cpu); -+ new_cpu = find_energy_efficient_cpu(p, prev_cpu, sync); - if (new_cpu >= 0) - return new_cpu; - new_cpu = prev_cpu; diff --git a/patches/ANDROID-sched-Update-max-cpu-capacity-in-case-of-max-frequency-constraints.patch b/patches/ANDROID-sched-Update-max-cpu-capacity-in-case-of-max-frequency-constraints.patch deleted file mode 100644 index 31edbbd46338..000000000000 --- a/patches/ANDROID-sched-Update-max-cpu-capacity-in-case-of-max-frequency-constraints.patch +++ /dev/null @@ -1,219 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dietmar Eggemann -Date: Sat, 26 Sep 2015 18:19:54 +0100 -Subject: ANDROID: sched: Update max cpu capacity in case of max frequency - constraints - -Wakeup balancing uses cpu capacity awareness and needs to know the -system-wide maximum cpu capacity. - -Patch "sched: Store system-wide maximum cpu capacity in root domain" -finds the system-wide maximum cpu capacity during scheduler domain -hierarchy setup. This is sufficient as long as maximum frequency -invariance is not enabled. - -If it is enabled, the system-wide maximum cpu capacity can change -between scheduler domain hierarchy setups due to frequency capping. - -The cpu capacity is changed in update_cpu_capacity() which is called in -load balance on the lowest scheduler domain hierarchy level. To be able -to know if a change in cpu capacity for a certain cpu also has an effect -on the system-wide maximum cpu capacity it is normally necessary to -iterate over all cpus. This would be way too costly. That's why this -patch follows a different approach. - -The unsigned long max_cpu_capacity value in struct root_domain is -replaced with a struct max_cpu_capacity, containing value (the -max_cpu_capacity) and cpu (the cpu index of the cpu providing the -maximum cpu_capacity). - -Changes to the system-wide maximum cpu capacity and the cpu index are -made if: - - 1 System-wide maximum cpu capacity < cpu capacity - 2 System-wide maximum cpu capacity > cpu capacity and cpu index == cpu - -There are no changes to the system-wide maximum cpu capacity in all -other cases. - -Atomic read and write access to the pair (max_cpu_capacity.val, -max_cpu_capacity.cpu) is enforced by max_cpu_capacity.lock. - -The access to max_cpu_capacity.val in task_fits_max() is still performed -without taking the max_cpu_capacity.lock. - -The code to set max cpu capacity in build_sched_domains() has been -removed because the whole functionality is now provided by -update_cpu_capacity() instead. - -This approach can introduce errors temporarily, e.g. in case the cpu -currently providing the max cpu capacity has its cpu capacity lowered -due to frequency capping and calls update_cpu_capacity() before any cpu -which might provide the max cpu now. - -Change-Id: I5063befab088fbf49e5d5e484ce0c6ee6165283a -Signed-off-by: Ionela Voinescu * -Signed-off-by: Dietmar Eggemann -(- Fixed cherry-pick issues, and conflict with a0fe2cf086ae "sched/fair: - Tune down misfit NOHZ kicks" which makes use of max_cpu_capacity - - Squashed "sched/fair: remove printk while schedule is in progress" - fix from Caesar Wang ) -Signed-off-by: Quentin Perret ---- - kernel/sched/fair.c | 34 ++++++++++++++++++++++++++++++++-- - kernel/sched/sched.h | 10 +++++++++- - kernel/sched/topology.c | 15 +++------------ - 3 files changed, 44 insertions(+), 15 deletions(-) - -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index c0b1c1233727..f0631d17c0bf 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -6203,7 +6203,7 @@ static int wake_cap(struct task_struct *p, int cpu, int prev_cpu) - return 0; - - min_cap = min(capacity_orig_of(prev_cpu), capacity_orig_of(cpu)); -- max_cap = cpu_rq(cpu)->rd->max_cpu_capacity; -+ max_cap = cpu_rq(cpu)->rd->max_cpu_capacity.val; - - /* Minimum capacity is close to max, no need to abort wake_affine */ - if (max_cap - min_cap < max_cap >> 3) -@@ -7755,16 +7755,46 @@ static unsigned long scale_rt_capacity(int cpu, unsigned long max) - return scale_irq_capacity(free, irq, max); - } - -+void init_max_cpu_capacity(struct max_cpu_capacity *mcc) { -+ raw_spin_lock_init(&mcc->lock); -+ mcc->val = 0; -+ mcc->cpu = -1; -+} -+ - static void update_cpu_capacity(struct sched_domain *sd, int cpu) - { - unsigned long capacity = arch_scale_cpu_capacity(cpu); - struct sched_group *sdg = sd->groups; -+ struct max_cpu_capacity *mcc; -+ unsigned long max_capacity; -+ int max_cap_cpu; -+ unsigned long flags; - - cpu_rq(cpu)->cpu_capacity_orig = capacity; - - capacity *= arch_scale_max_freq_capacity(sd, cpu); - capacity >>= SCHED_CAPACITY_SHIFT; - -+ mcc = &cpu_rq(cpu)->rd->max_cpu_capacity; -+ -+ raw_spin_lock_irqsave(&mcc->lock, flags); -+ max_capacity = mcc->val; -+ max_cap_cpu = mcc->cpu; -+ -+ if ((max_capacity > capacity && max_cap_cpu == cpu) || -+ (max_capacity < capacity)) { -+ mcc->val = capacity; -+ mcc->cpu = cpu; -+#ifdef CONFIG_SCHED_DEBUG -+ raw_spin_unlock_irqrestore(&mcc->lock, flags); -+ printk_deferred(KERN_INFO "CPU%d: update max cpu_capacity %lu\n", -+ cpu, capacity); -+ goto skip_unlock; -+#endif -+ } -+ raw_spin_unlock_irqrestore(&mcc->lock, flags); -+ -+skip_unlock: __attribute__ ((unused)); - capacity = scale_rt_capacity(cpu, capacity); - - if (!capacity) -@@ -7869,7 +7899,7 @@ check_cpu_capacity(struct rq *rq, struct sched_domain *sd) - static inline int check_misfit_status(struct rq *rq, struct sched_domain *sd) - { - return rq->misfit_task_load && -- (rq->cpu_capacity_orig < rq->rd->max_cpu_capacity || -+ (rq->cpu_capacity_orig < rq->rd->max_cpu_capacity.val || - check_cpu_capacity(rq, sd)); - } - -diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h -index f0b6e3ab2c96..9015c687de19 100644 ---- a/kernel/sched/sched.h -+++ b/kernel/sched/sched.h -@@ -717,6 +717,12 @@ struct perf_domain { - struct rcu_head rcu; - }; - -+struct max_cpu_capacity { -+ raw_spinlock_t lock; -+ unsigned long val; -+ int cpu; -+}; -+ - /* Scheduling group status flags */ - #define SG_OVERLOAD 0x1 /* More than one runnable task on a CPU. */ - #define SG_OVERUTILIZED 0x2 /* One or more CPUs are over-utilized. */ -@@ -775,7 +781,8 @@ struct root_domain { - cpumask_var_t rto_mask; - struct cpupri cpupri; - -- unsigned long max_cpu_capacity; -+ /* Maximum cpu capacity in the system. */ -+ struct max_cpu_capacity max_cpu_capacity; - - /* - * NULL-terminated list of performance domains intersecting with the -@@ -785,6 +792,7 @@ struct root_domain { - }; - - extern void init_defrootdomain(void); -+extern void init_max_cpu_capacity(struct max_cpu_capacity *mcc); - extern int sched_init_domains(const struct cpumask *cpu_map); - extern void rq_attach_root(struct rq *rq, struct root_domain *rd); - extern void sched_get_rd(struct root_domain *rd); -diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c -index b5667a273bf6..4ad1e5194555 100644 ---- a/kernel/sched/topology.c -+++ b/kernel/sched/topology.c -@@ -510,6 +510,9 @@ static int init_rootdomain(struct root_domain *rd) - - if (cpupri_init(&rd->cpupri) != 0) - goto free_cpudl; -+ -+ init_max_cpu_capacity(&rd->max_cpu_capacity); -+ - return 0; - - free_cpudl: -@@ -1951,7 +1954,6 @@ build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *att - enum s_alloc alloc_state; - struct sched_domain *sd; - struct s_data d; -- struct rq *rq = NULL; - int i, ret = -ENOMEM; - struct sched_domain_topology_level *tl_asym; - bool has_asym = false; -@@ -2014,13 +2016,7 @@ build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *att - /* Attach the domains */ - rcu_read_lock(); - for_each_cpu(i, cpu_map) { -- rq = cpu_rq(i); - sd = *per_cpu_ptr(d.sd, i); -- -- /* Use READ_ONCE()/WRITE_ONCE() to avoid load/store tearing: */ -- if (rq->cpu_capacity_orig > READ_ONCE(d.rd->max_cpu_capacity)) -- WRITE_ONCE(d.rd->max_cpu_capacity, rq->cpu_capacity_orig); -- - cpu_attach_domain(sd, d.rd, i); - } - rcu_read_unlock(); -@@ -2028,11 +2024,6 @@ build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *att - if (has_asym) - static_branch_enable_cpuslocked(&sched_asym_cpucapacity); - -- if (rq && sched_debug_enabled) { -- pr_info("root domain span: %*pbl (max cpu_capacity = %lu)\n", -- cpumask_pr_args(cpu_map), rq->rd->max_cpu_capacity); -- } -- - ret = 0; - error: - __free_domain_allocs(&d, alloc_state, cpu_map); diff --git a/patches/ANDROID-sched-core-Add-a-latency-sensitive-flag-to-uclamp.patch b/patches/ANDROID-sched-core-Add-a-latency-sensitive-flag-to-uclamp.patch deleted file mode 100644 index 4be1a7f12441..000000000000 --- a/patches/ANDROID-sched-core-Add-a-latency-sensitive-flag-to-uclamp.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Quentin Perret -Date: Tue, 30 Jul 2019 13:54:00 +0100 -Subject: ANDROID: sched/core: Add a latency-sensitive flag to uclamp - -Add a 'latency_sensitive' flag to uclamp in order to express the need -for some tasks to find a CPU where they can wake-up quickly. This is not -expected to be used without cgroup support, so add solely a cgroup -interface for it. - -As this flag represents a boolean attribute and not an amount of -resources to be shared, it is not clear what the delegation logic should -be. As such, it is kept simple: every new cgroup starts with -latency_sensitive set to false, regardless of the parent. - -In essence, this is similar to SchedTune's prefer-idle flag which was -used in android-4.19 and prior. - -Change-Id: I722d8ecabb428bb7b95a5b54bc70a87f182dde2a -Signed-off-by: Quentin Perret ---- - kernel/sched/core.c | 33 +++++++++++++++++++++++++++++++++ - kernel/sched/sched.h | 2 ++ - 2 files changed, 35 insertions(+) - -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index dd05a378631a..c05d05094e70 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -7327,6 +7327,27 @@ static int cpu_uclamp_max_show(struct seq_file *sf, void *v) - cpu_uclamp_print(sf, UCLAMP_MAX); - return 0; - } -+ -+static int cpu_uclamp_ls_write_u64(struct cgroup_subsys_state *css, -+ struct cftype *cftype, u64 ls) -+{ -+ struct task_group *tg; -+ -+ if (ls > 1) -+ return -EINVAL; -+ tg = css_tg(css); -+ tg->latency_sensitive = (unsigned int) ls; -+ -+ return 0; -+} -+ -+static u64 cpu_uclamp_ls_read_u64(struct cgroup_subsys_state *css, -+ struct cftype *cft) -+{ -+ struct task_group *tg = css_tg(css); -+ -+ return (u64) tg->latency_sensitive; -+} - #endif /* CONFIG_UCLAMP_TASK_GROUP */ - - #ifdef CONFIG_FAIR_GROUP_SCHED -@@ -7687,6 +7708,12 @@ static struct cftype cpu_legacy_files[] = { - .seq_show = cpu_uclamp_max_show, - .write = cpu_uclamp_max_write, - }, -+ { -+ .name = "uclamp.latency_sensitive", -+ .flags = CFTYPE_NOT_ON_ROOT, -+ .read_u64 = cpu_uclamp_ls_read_u64, -+ .write_u64 = cpu_uclamp_ls_write_u64, -+ }, - #endif - { } /* Terminate */ - }; -@@ -7868,6 +7895,12 @@ static struct cftype cpu_files[] = { - .seq_show = cpu_uclamp_max_show, - .write = cpu_uclamp_max_write, - }, -+ { -+ .name = "uclamp.latency_sensitive", -+ .flags = CFTYPE_NOT_ON_ROOT, -+ .read_u64 = cpu_uclamp_ls_read_u64, -+ .write_u64 = cpu_uclamp_ls_write_u64, -+ }, - #endif - { } /* terminate */ - }; -diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h -index 9015c687de19..7de9f16cb838 100644 ---- a/kernel/sched/sched.h -+++ b/kernel/sched/sched.h -@@ -399,6 +399,8 @@ struct task_group { - struct uclamp_se uclamp_req[UCLAMP_CNT]; - /* Effective clamp values used for a task group */ - struct uclamp_se uclamp[UCLAMP_CNT]; -+ /* Latency-sensitive flag used for a task group */ -+ unsigned int latency_sensitive; - #endif - - }; diff --git a/patches/ANDROID-sched-fair-Also-do-misfit-in-overloaded-groups.patch b/patches/ANDROID-sched-fair-Also-do-misfit-in-overloaded-groups.patch deleted file mode 100644 index c987b468edb5..000000000000 --- a/patches/ANDROID-sched-fair-Also-do-misfit-in-overloaded-groups.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Redpath -Date: Tue, 5 Jun 2018 12:21:33 +0100 -Subject: ANDROID: sched/fair: Also do misfit in overloaded groups - -If we can classify the group as overloaded, that overrides -any classification as misfit but we may still have misfit -tasks present. Check the rq we're looking at to see if -this is the case. - -Change-Id: Ida8eb66aa625e34de3fe2ee1b0dd8a78926273d8 -Signed-off-by: Chris Redpath -[Removed stray reference to rq_has_misfit] -Signed-off-by: Valentin Schneider -Signed-off-by: Quentin Perret ---- - kernel/sched/fair.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index 7faaf156b66c..699f8256dc94 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -8806,6 +8806,9 @@ static int need_active_balance(struct lb_env *env) - if (voluntary_active_balance(env)) - return 1; - -+ if (env->src_grp_type == group_overloaded && env->src_rq->misfit_task_load) -+ return 1; -+ - return unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2); - } - diff --git a/patches/ANDROID-sched-fair-Attempt-to-improve-throughput-for-asym-cap-systems.patch b/patches/ANDROID-sched-fair-Attempt-to-improve-throughput-for-asym-cap-systems.patch deleted file mode 100644 index 9a40b3a94498..000000000000 --- a/patches/ANDROID-sched-fair-Attempt-to-improve-throughput-for-asym-cap-systems.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Redpath -Date: Fri, 1 Jun 2018 20:34:10 +0100 -Subject: ANDROID: sched/fair: Attempt to improve throughput for asym cap - systems - -In some systems the capacity and group weights line up to defeat all the -small imbalance correction conditions in fix_small_imbalance, which can -cause bad task placement. Add a new condition if the existing code can't -see anything to fix: - -If we have asymmetric capacity, and there are more tasks than CPUs in -the busiest group *and* there are less tasks than CPUs in the local group -then we try to pull something. There could be transient small tasks which -prevent this from working, but on the whole it is beneficial for those -systems with inconvenient capacity/cluster size relationships. - -Change-Id: Icf81cde215c082a61f816534b7990ccb70aee409 -Signed-off-by: Chris Redpath -Signed-off-by: Quentin Perret ---- - kernel/sched/fair.c | 17 ++++++++++++++++- - 1 file changed, 16 insertions(+), 1 deletion(-) - -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index b62581b58f13..f9902c86c5b9 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -8433,7 +8433,22 @@ void fix_small_imbalance(struct lb_env *env, struct sd_lb_stats *sds) - capa_move /= SCHED_CAPACITY_SCALE; - - /* Move if we gain throughput */ -- if (capa_move > capa_now) -+ if (capa_move > capa_now) { -+ env->imbalance = busiest->load_per_task; -+ return; -+ } -+ -+ /* We can't see throughput improvement with the load-based -+ * method, but it is possible depending upon group size and -+ * capacity range that there might still be an underutilized -+ * cpu available in an asymmetric capacity system. Do one last -+ * check just in case. -+ */ -+ if (env->sd->flags & SD_ASYM_CPUCAPACITY && -+ busiest->group_type == group_overloaded && -+ busiest->sum_nr_running > busiest->group_weight && -+ local->sum_nr_running < local->group_weight && -+ local->group_capacity < busiest->group_capacity) - env->imbalance = busiest->load_per_task; - } - diff --git a/patches/ANDROID-sched-fair-Bias-EAS-placement-for-latency.patch b/patches/ANDROID-sched-fair-Bias-EAS-placement-for-latency.patch deleted file mode 100644 index f0898a7c70dd..000000000000 --- a/patches/ANDROID-sched-fair-Bias-EAS-placement-for-latency.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Quentin Perret -Date: Wed, 27 Feb 2019 11:21:24 +0000 -Subject: ANDROID: sched/fair: Bias EAS placement for latency - -Add to find_energy_efficient_cpu() a latency sensitive case which mimics -what was done for prefer-idle in android-4.19 and before (see [1] for -reference). - -This isn't strictly equivalent to the legacy algorithm but comes real -close, and isn't very invasive. Overall, the idea is to select the -biggest idle CPU we can find for latency-sensitive boosted tasks, and -the smallest CPU where the can fit for latency-sensitive non-boosted -tasks. - -The main differences with the legacy behaviour are the following: - - 1. the policy for 'prefer idle' when there isn't a single idle CPU in - the system is simpler now. We just pick the CPU with the highest - spare capacity; - - 2. the cstate awareness is implemented by minimizing the exit latency - rather than the idle state index. This is how it is done in the slow - path (find_idlest_group_cpu()), it doesn't require us to keep hooks - into CPUIdle, and should actually be better because what we want is - a CPU that can wake up quickly; - - 3. non-latency-sensitive tasks just use the standard mainline - energy-aware wake-up path, which decides the placement using the - Energy Model; - - 4. the 'boosted' and 'latency_sensitive' attributes of a task come from - util_clamp (which now replaces schedtune). - -[1] https://android.googlesource.com/kernel/common.git/+/c27c56105dcaaae54ecc39ef33fbfac87a1486fc - -Change-Id: Ia58516906e9cb5abe08385a8cd088097043d8703 -Signed-off-by: Quentin Perret ---- - kernel/sched/fair.c | 40 ++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 38 insertions(+), 2 deletions(-) - -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index 699f8256dc94..ba1eaa599dbc 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -6348,8 +6348,13 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy - { - unsigned long prev_delta = ULONG_MAX, best_delta = ULONG_MAX; - struct root_domain *rd = cpu_rq(smp_processor_id())->rd; -+ int max_spare_cap_cpu_ls = prev_cpu, best_idle_cpu = -1; -+ unsigned long max_spare_cap_ls = 0, target_cap; - unsigned long cpu_cap, util, base_energy = 0; -+ bool boosted, latency_sensitive = false; -+ unsigned int min_exit_lat = UINT_MAX; - int cpu, best_energy_cpu = prev_cpu; -+ struct cpuidle_state *idle; - struct sched_domain *sd; - struct perf_domain *pd; - -@@ -6378,6 +6383,10 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy - if (!task_util_est(p)) - goto unlock; - -+ latency_sensitive = uclamp_latency_sensitive(p); -+ boosted = uclamp_boosted(p); -+ target_cap = boosted ? 0 : ULONG_MAX; -+ - for (; pd; pd = pd->next) { - unsigned long cur_delta, spare_cap, max_spare_cap = 0; - unsigned long base_energy_pd; -@@ -6402,7 +6411,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy - continue; - - /* Always use prev_cpu as a candidate. */ -- if (cpu == prev_cpu) { -+ if (!latency_sensitive && cpu == prev_cpu) { - prev_delta = compute_energy(p, prev_cpu, pd); - prev_delta -= base_energy_pd; - best_delta = min(best_delta, prev_delta); -@@ -6417,10 +6426,34 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy - max_spare_cap = spare_cap; - max_spare_cap_cpu = cpu; - } -+ -+ if (!latency_sensitive) -+ continue; -+ -+ if (idle_cpu(cpu)) { -+ cpu_cap = capacity_orig_of(cpu); -+ if (boosted && cpu_cap < target_cap) -+ continue; -+ if (!boosted && cpu_cap > target_cap) -+ continue; -+ idle = idle_get_state(cpu_rq(cpu)); -+ if (idle && idle->exit_latency > min_exit_lat && -+ cpu_cap == target_cap) -+ continue; -+ -+ if (idle) -+ min_exit_lat = idle->exit_latency; -+ target_cap = cpu_cap; -+ best_idle_cpu = cpu; -+ } else if (spare_cap > max_spare_cap_ls) { -+ max_spare_cap_ls = spare_cap; -+ max_spare_cap_cpu_ls = cpu; -+ } - } - - /* Evaluate the energy impact of using this CPU. */ -- if (max_spare_cap_cpu >= 0 && max_spare_cap_cpu != prev_cpu) { -+ if (!latency_sensitive && max_spare_cap_cpu >= 0 && -+ max_spare_cap_cpu != prev_cpu) { - cur_delta = compute_energy(p, max_spare_cap_cpu, pd); - cur_delta -= base_energy_pd; - if (cur_delta < best_delta) { -@@ -6432,6 +6465,9 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu, int sy - unlock: - rcu_read_unlock(); - -+ if (latency_sensitive) -+ return best_idle_cpu >= 0 ? best_idle_cpu : max_spare_cap_cpu_ls; -+ - /* - * Pick the best CPU if prev_cpu cannot be used, or if it saves at - * least 6% of the energy used by prev_cpu. diff --git a/patches/ANDROID-sched-fair-Don-t-balance-misfits-if-it-would-overload-local-group.patch b/patches/ANDROID-sched-fair-Don-t-balance-misfits-if-it-would-overload-local-group.patch deleted file mode 100644 index 9dda1e6414ab..000000000000 --- a/patches/ANDROID-sched-fair-Don-t-balance-misfits-if-it-would-overload-local-group.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Redpath -Date: Tue, 5 Jun 2018 11:47:57 +0100 -Subject: ANDROID: sched/fair: Don't balance misfits if it would overload local - group - -When load balancing in a system with misfit tasks present, if we always -pull a misfit task to the local group this can lead to pulling a running -task from a smaller capacity CPUs to a bigger CPU which is busy. In this -situation, the pulled task is likely not to get a chance to run before -an idle balance on another small CPU pulls it back. This penalises the -pulled task as it is stopped for a short amount of time and then likely -relocated to a different CPU (since the original CPU just did a NEWLY_IDLE -balance and reset the periodic interval). - -If we only do this unconditionally for NEWLY_IDLE balance, we can be -sure that any tasks and load which are present on the local group are -related to short-running tasks which we are happy to displace for a -longer running task in a system with misfit tasks present. - -However, other balance types should only pull a task if we think -that the local group is underutilized - checking the number of tasks -gives us a conservative estimate here since if they were short tasks -we would have been doing NEWLY_IDLE balances instead. - -Change-Id: I710add1ab1139482620b6addc8370ad194791beb -Signed-off-by: Chris Redpath -Signed-off-by: Quentin Perret ---- - kernel/sched/fair.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index f9902c86c5b9..7faaf156b66c 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -8517,8 +8517,18 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s - (sds->avg_load - local->avg_load) * local->group_capacity - ) / SCHED_CAPACITY_SCALE; - -- /* Boost imbalance to allow misfit task to be balanced. */ -- if (busiest->group_type == group_misfit_task) { -+ /* Boost imbalance to allow misfit task to be balanced. -+ * Always do this if we are doing a NEWLY_IDLE balance -+ * on the assumption that any tasks we have must not be -+ * long-running (and hence we cannot rely upon load). -+ * However if we are not idle, we should assume the tasks -+ * we have are longer running and not override load-based -+ * calculations above unless we are sure that the local -+ * group is underutilized. -+ */ -+ if (busiest->group_type == group_misfit_task && -+ (env->idle == CPU_NEWLY_IDLE || -+ local->sum_nr_running < local->group_weight)) { - env->imbalance = max_t(long, env->imbalance, - busiest->group_misfit_task_load); - } diff --git a/patches/ANDROID-sched-fair-EAS-Add-uclamp-support-to-find_energy_efficient_cpu.patch b/patches/ANDROID-sched-fair-EAS-Add-uclamp-support-to-find_energy_efficient_cpu.patch deleted file mode 100644 index d8f74c8d9e4c..000000000000 --- a/patches/ANDROID-sched-fair-EAS-Add-uclamp-support-to-find_energy_efficient_cpu.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Patrick Bellasi -Date: Tue, 18 Dec 2018 10:31:30 +0000 -Subject: ANDROID: sched/fair: EAS: Add uclamp support to - find_energy_efficient_cpu() - -Utilization clamping can be used to boost the utilization of small tasks -or cap that of big tasks. Thus, one of its possible usages is to bias -tasks placement to "promote" small tasks on higher capacity (less energy -efficient) CPUs or "constraint" big tasks on small capacity (more energy -efficient) CPUs. - -When the Energy Aware Scheduler (EAS) looks for the most energy -efficient CPU to run a task on, it currently considers only the -effective utiliation estimated for a task. - -Fix this by adding an additional check to skip CPUs which capacity is -smaller then the task clamped utilization. - -Change-Id: I43fa6fa27e27c1eb5272c6a45d1a6a5b0faae1aa -Signed-off-by: Patrick Bellasi -Cc: Ingo Molnar -Cc: Peter Zijlstra -Signed-off-by: Quentin Perret ---- - kernel/sched/fair.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index 682a754ea3e1..49137eff0c8e 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -6034,6 +6034,19 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target) - return target; - } - -+static unsigned int uclamp_task_util(struct task_struct *p) -+{ -+#ifdef CONFIG_UCLAMP_TASK -+ unsigned int min_util = uclamp_eff_value(p, UCLAMP_MIN); -+ unsigned int max_util = uclamp_eff_value(p, UCLAMP_MAX); -+ unsigned int est_util = task_util_est(p); -+ -+ return clamp(est_util, min_util, max_util); -+#else -+ return task_util_est(p); -+#endif -+} -+ - /** - * Amount of capacity of a CPU that is (estimated to be) used by CFS tasks - * @cpu: the CPU to get the utilization of -@@ -6378,6 +6391,10 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu) - if (!fits_capacity(util, cpu_cap)) - continue; - -+ /* Skip CPUs which do not fit task requirements */ -+ if (cpu_cap < uclamp_task_util(p)) -+ continue; -+ - /* Always use prev_cpu as a candidate. */ - if (cpu == prev_cpu) { - prev_delta = compute_energy(p, prev_cpu, pd); diff --git a/patches/ANDROID-sched-fair-add-arch-scaling-function-for-max-frequency-capping.patch b/patches/ANDROID-sched-fair-add-arch-scaling-function-for-max-frequency-capping.patch deleted file mode 100644 index 79a4b3ac8995..000000000000 --- a/patches/ANDROID-sched-fair-add-arch-scaling-function-for-max-frequency-capping.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dietmar Eggemann -Date: Thu, 10 May 2018 15:48:06 +0100 -Subject: ANDROID: sched/fair: add arch scaling function for max frequency - capping - -To be able to scale the cpu capacity by this factor introduce a call to -the new arch scaling function arch_scale_max_freq_capacity() in -update_cpu_capacity() and provide a default implementation which returns -SCHED_CAPACITY_SCALE. - -Another subsystem (e.g. cpufreq) or architectural or platform specific -code can overwrite this default implementation, exactly as for frequency -and cpu invariance. It has to be enabled by the arch by defining -arch_scale_max_freq_capacity to the actual implementation. - -Change-Id: I770a8b1f4f7340e9e314f71c64a765bf880f4b4d -Signed-off-by: Ionela Voinescu -Signed-off-by: Dietmar Eggemann -( Fixed conflict with scaling against the PELT-based scale_rt_capacity ) -Signed-off-by: Quentin Perret ---- - kernel/sched/fair.c | 12 ++++++++---- - kernel/sched/sched.h | 9 +++++++++ - 2 files changed, 17 insertions(+), 4 deletions(-) - -diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c -index 43d3321ce61e..c0b1c1233727 100644 ---- a/kernel/sched/fair.c -+++ b/kernel/sched/fair.c -@@ -7733,10 +7733,9 @@ static inline void init_sd_lb_stats(struct sd_lb_stats *sds) - }; - } - --static unsigned long scale_rt_capacity(struct sched_domain *sd, int cpu) -+static unsigned long scale_rt_capacity(int cpu, unsigned long max) - { - struct rq *rq = cpu_rq(cpu); -- unsigned long max = arch_scale_cpu_capacity(cpu); - unsigned long used, free; - unsigned long irq; - -@@ -7758,10 +7757,15 @@ static unsigned long scale_rt_capacity(struct sched_domain *sd, int cpu) - - static void update_cpu_capacity(struct sched_domain *sd, int cpu) - { -- unsigned long capacity = scale_rt_capacity(sd, cpu); -+ unsigned long capacity = arch_scale_cpu_capacity(cpu); - struct sched_group *sdg = sd->groups; - -- cpu_rq(cpu)->cpu_capacity_orig = arch_scale_cpu_capacity(cpu); -+ cpu_rq(cpu)->cpu_capacity_orig = capacity; -+ -+ capacity *= arch_scale_max_freq_capacity(sd, cpu); -+ capacity >>= SCHED_CAPACITY_SHIFT; -+ -+ capacity = scale_rt_capacity(cpu, capacity); - - if (!capacity) - capacity = 1; -diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h -index 0db2c1b3361e..f0b6e3ab2c96 100644 ---- a/kernel/sched/sched.h -+++ b/kernel/sched/sched.h -@@ -1961,6 +1961,15 @@ unsigned long arch_scale_freq_capacity(int cpu) - } - #endif - -+#ifndef arch_scale_max_freq_capacity -+struct sched_domain; -+static __always_inline -+unsigned long arch_scale_max_freq_capacity(struct sched_domain *sd, int cpu) -+{ -+ return SCHED_CAPACITY_SCALE; -+} -+#endif -+ - #ifdef CONFIG_SMP - #ifdef CONFIG_PREEMPTION - diff --git a/patches/ANDROID-sdcardfs-Add-sdcardfs-filesystem.patch b/patches/ANDROID-sdcardfs-Add-sdcardfs-filesystem.patch deleted file mode 100644 index 81ae7b528ca2..000000000000 --- a/patches/ANDROID-sdcardfs-Add-sdcardfs-filesystem.patch +++ /dev/null @@ -1,5179 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Campello -Date: Mon, 20 Jul 2015 16:23:50 -0700 -Subject: ANDROID: sdcardfs: Add sdcardfs filesystem - -Bug: 11118565 -Bug: 27915347 -Bug: 27992761 -Bug: 28024488 -Bug: 30013843 -Bug: 30954918 -Bug: 34133558 -Bug: 34262585 -Bug: 34542611 -Bug: 34691169 -Bug: 34723223 -Bug: 35307857 -Bug: 35331000 -Bug: 35633782 -Bug: 35643557 -Bug: 35666680 -bug: 35766959 -Bug: 35766959 -Bug: 35848445 -Bug: 36004503 -Bug: 36007653 -Bug: 36138424 -Bug: 36160015 -Bug: 37193650 -Bug: 37231161 -Bug: 37488099 -Bug: 37516160 -Bug: 38045152 -Bug: 38117720 -Bug: 38502532 -Bug: 62390017 -Bug: 63245673 -Bug: 63260873 -Bug: 63785372 -Bug: 64672411 -Bug: 70278506 -Bug: 72007585 -Bug: 73055997 -Bug: 73287721 -Bug: 75987238 -Bug: 77923821 -Bug: 78262592 -Bug: 111641492 -Bug: 111642636 -Bug: 111860541 -Change-Id: Ic1e01e602ce335d97342be54f3da0c5c65c087cc -Signed-off-by: Daniel Rosenberg -[astrachan: Folded the following changes into this patch: - 903cea7ab0b2 ("ANDROID: Included sdcardfs source code for kernel 3.0") - 612a725e3d97 ("ANDROID: Port of sdcardfs to 4.4") - e4187c55208b ("ANDROID: Changed type-casting in packagelist management") - cf76072a5cd8 ("ANDROID: sdcardfs: Bring up to date with Android M permissions:") - a43aa502c608 ("ANDROID: sdcardfs: Add support for d_canonical_path") - d8fefbf85af2 ("ANDROID: sdcardfs: remove effectless config option") - 416677409336 ("ANDROID: sdcardfs: Remove unused code") - 8e49a570d351 ("ANDROID: sdcardfs: remove unneeded __init and __exit") - 40ee0e93f1d7 ("ANDROID: sdcardfs: Truncate packages_gid.list on overflow") - b1d9602aa3fe ("ANDROID: sdcardfs: fix itnull.cocci warnings") - 60a177f5a167 ("ANDROID: sdcardfs: override umask on mkdir and create") - efb3d2695203 ("ANDROID: sdcardfs: Check for other cases on path lookup") - 0da87f63666f ("ANDROID: sdcardfs: Fix locking for permission fix up") - 75b93060655e ("ANDROID: sdcardfs: Switch package list to RCU") - 657b0a00f497 ("ANDROID: sdcardfs: Added top to sdcardfs_inode_info") - 5008d91cba25 ("ANDROID: sdcardfs: fix external storage exporting incorrect uid") - e06c452d0d07 ("ANDROID: sdcardfs: Move directory unlock before touch") - 72e5443a2816 ("ANDROID: sdcardfs: User new permission2 functions") - ae8be7da556d ("ANDROID: sdcardfs: Add gid and mask to private mount data") - 151a3efe57a6 ("ANDROID: sdcardfs: Use per mount permissions") - cff865a370f3 ("ANDROID: sdcardfs: Switch ->d_inode to d_inode()") - 065ac66804bf ("ANDROID: sdcardfs: Fix locking issue with permision fix up") - 31ea603eb3c4 ("ANDROID: sdcardfs: use wrappers to access i_mutex") - c25c2f5018a2 ("ANDROID: sdcardfs: add parent pointer into dentry name hash") - 58616bb4ec68 ("ANDROID: sdcardfs: get rid of 'parent' argument of ->d_compare()") - 1654d7ffdd20 ("ANDROID: sdcardfs: Propagate dentry down to inode_change_ok()") - 39335cac1d2f ("ANDROID: sdcardfs: make it use new .rename i_op") - 7622bb3fcc79 ("ANDROID: sdcardfs: eliminate the offset argument to ->direct_IO") - 843bd7295ee0 ("ANDROID: sdcardfs: Allow non-owners to touch") - e3d74804d174 ("ANDROID: sdcardfs: Refactor configfs interface") - 5833eda87a72 ("ANDROID: sdcardfs: add support for user permission isolation") - d83fb1f41dd4 ("ANDROID: sdcardfs: Remove redundant operation") - 8767af17c0e5 ("ANDROID: sdcardfs: Add GID Derivation to sdcardfs") - 7119d96ad3ee ("ANDROID: sdcardfs: switch to full_name_hash and qstr") - 778e02a54859 ("ANDROID: sdcardfs: Switch strcasecmp for internal call") - cd4965d04404 ("ANDROID: sdcardfs: Fix incorrect hash") - 40a2ee053505 ("ANDROID: sdcardfs: Add missing path_put") - da5342bac57a ("ANDROID: sdcardfs: Don't bother deleting freelist") - c91857b01e05 ("ANDROID: sdcardfs: implement vm_ops->page_mkwrite") - f62b3906044b ("ANDROID: sdcardfs: support direct-IO (DIO) operations") - c2e216d36d63 ("ANDROID: sdcardfs: Fix case insensitive lookup") - 57b92ab6f774 ("ANDROID: sdcardfs: rate limit warning print") - 8534cee39a81 ("ANDROID: sdcardfs: Replace get/put with d_lock") - 156085b2fccf ("ANDROID: sdcardfs: Use spin_lock_nested") - 8a260cabac4e ("ANDROID: sdcardfs: Switch to internal case insensitive compare") - a8d51569573c ("ANDROID: sdcardfs: Use d_invalidate instead of drop_recurisve") - 932a6071de63 ("ANDROID: sdcardfs: Get the blocksize from the lower fs") - 0ad4c0f87527 ("ANDROID: sdcardfs: declare MODULE_ALIAS_FS") - b97c83b5b683 ("ANDROID: sdcardfs: Use case insensitive hash function") - 9920dfb08265 ("ANDROID: sdcardfs: move path_put outside of spinlock") - f9a25348b233 ("ANDROID: sdcardfs: Remove uninformative prints") - 720d9030bea1 ("ANDROID: sdcardfs: Fix gid issue") - 4cbb7fa6e66c ("ANDROID: sdcardfs: correct order of descriptors") - 6cff6cc301ed ("ANDROID: sdcardfs: Fix formatting") - ac2a40412e26 ("ANDROID: sdcardfs: Fix style issues with comments") - 2212bb8ec064 ("ANDROID: sdcardfs: remove unneeded null check") - 4c1a0add8d21 ("ANDROID: sdcardfs: Use pr_[...] instead of printk") - 74535fe211ac ("ANDROID: sdcardfs: Use to kstrout") - e6cf8dffd014 ("ANDROID: sdcardfs: Use seq_puts over seq_printf") - 2b1ac93a90b6 ("ANDROID: sdcardfs: Fix style issues in macros") - bab6d117426f ("ANDROID: sdcardfs: remove unnecessary call to do_munmap") - 1c0bf09f19b6 ("ANDROID: sdcardfs: copy lower inode attributes in ->ioctl") - 42f3db55942b ("ANDROID: sdcardfs: fix ->llseek to update upper and lower offset") - 97ad6205055e ("ANDROID: sdcardfs: add read_iter/write_iter opeations") - be9abc81332b ("ANDROID: sdcardfs: use d_splice_alias") - 4e90114cb1b4 ("ANDROID: sdcardfs: update module info") - 0e1f7ab14924 ("ANDROID: sdcardfs: Directly pass lower file for mmap") - 28be4beb43f9 ("ANDROID: sdcardfs: Change cache GID value") - 9fc2c452aefe ("ANDROID: sdcardfs: ->iget fixes") - 9bb72cf15cbc ("ANDROID: sdcardfs: Don't do d_add for lower fs") - 1bc21a04c11b ("ANDROID: sdcardfs: Don't complain in fixup_lower_ownership") - 0fb5b10b28a9 ("ANDROID: sdcardfs: Use filesystem specific hash") - 30e2f0aadce2 ("ANDROID: sdcardfs: Copy meta-data from lower inode") - f748c7053194 ("ANDROID: sdcardfs: Avoid setting GIDs outside of valid ranges") - 3d38f08bacdb ("ANDROID: sdcardfs: Call lower fs's revalidate") - 2d1f1c203978 ("ANDROID: sdcardfs: Don't iput if we didn't igrab") - 857fc5e717fc ("ANDROID: sdcardfs: fix sdcardfs_destroy_inode for the inode RCU approach") - 4fceeccf1d23 ("ANDROID: sdcardfs: Move top to its own struct") - f51470044a15 ("ANDROID: sdcardfs: Check for NULL in revalidate") - 8c7f6c97ac81 ("ANDROID: sdcardfs: d_splice_alias can return error values") - 17da01b37d61 ("ANDROID: sdcardfs: remove dead function open_flags_to_access_mode()") - 16662dd604be ("ANDROID: sdcardfs: use mount_nodev and fix a issue in sdcardfs_kill_sb") - 43c0dca6039a ("ANDROID: sdcardfs: Remove unnecessary lock") - 48960c25cdc1 ("ANDROID: sdcardfs: override credential for ioctl to lower fs") - 5d6410b9a88d ("ANDROID: Sdcardfs: Move gid derivation under flag") - c7dd98431f83 ("ANDROID: sdcardfs: Add default_normal option") - db9bf31a5d86 ("ANDROID: sdcardfs: port to 4.14") - c70c9d1e82d2 ("ANDROID: sdcardfs: Use lower getattr times/size") - 04e961477d62 ("ANDROID: sdcardfs: Protect set_top") - 1ed04b79d281 ("ANDROID: sdcardfs: Hold i_mutex for i_size_write") - 77f52fc10982 ("ANDROID: sdcardfs: Set num in extension_details during make_item") - d71596efa247 ("ANDROID: sdcardfs: fix lock issue on 32 bit/SMP architectures") - ee6b07fced4a ("ANDROID: sdcardfs: Fix sdcardfs to stop creating cases-sensitive duplicate entries.") - ce12807d5b75 ("ANDROID: sdcardfs: Check for private data earlier") - c080450304cd ("ANDROID: sdcardfs: d_make_root calls iput") - 900e77796781 ("ANDROID: sdcardfs: Set s_root to NULL after putting") - 49092e89ffa4 ("ANDROID: sdcardfs: Don't d_drop in d_revalidate") - e1f978bc9b9c ("ANDROID: sdcardfs: fix potential crash when reserved_mb is not zero") - faa148eaf8ed ("ANDROID: sdcardfs: Check stacked filesystem depth") - 6edd721e972c ("ANDROID: sdcardfs: Don't use OVERRIDE_CRED macro") - 11ca578b4336 ("ANDROID: sdcardfs: Change current->fs under lock") - 83dea6ba6ea7 ("ANDROID: sdcardfs: Use inode iversion helpers") - 12064f3a794e ("ANDROID: sdcardfs: Add option to drop unused dentries") - d9fe221bbf84 ("ANDROID: sdcardfs: Add sandbox") - f544ad0b1547 ("ANDROID: sdcardfs: Add option to not link obb")] -Signed-off-by: Alistair Strachan -[drosen: folded in e6e368c99975 ("fs: sdcardfs: Add missing option to show_options")] ---- - fs/Kconfig | 1 + - fs/Makefile | 1 + - fs/sdcardfs/Kconfig | 13 + - fs/sdcardfs/Makefile | 7 + - fs/sdcardfs/dentry.c | 196 +++++++++ - fs/sdcardfs/derived_perm.c | 477 ++++++++++++++++++++ - fs/sdcardfs/file.c | 467 ++++++++++++++++++++ - fs/sdcardfs/inode.c | 821 ++++++++++++++++++++++++++++++++++ - fs/sdcardfs/lookup.c | 470 ++++++++++++++++++++ - fs/sdcardfs/main.c | 454 +++++++++++++++++++ - fs/sdcardfs/mmap.c | 87 ++++ - fs/sdcardfs/multiuser.h | 53 +++ - fs/sdcardfs/packagelist.c | 882 +++++++++++++++++++++++++++++++++++++ - fs/sdcardfs/sdcardfs.h | 662 ++++++++++++++++++++++++++++ - fs/sdcardfs/super.c | 297 +++++++++++++ - 15 files changed, 4888 insertions(+) - create mode 100644 fs/sdcardfs/Kconfig - create mode 100644 fs/sdcardfs/Makefile - create mode 100644 fs/sdcardfs/dentry.c - create mode 100644 fs/sdcardfs/derived_perm.c - create mode 100644 fs/sdcardfs/file.c - create mode 100644 fs/sdcardfs/inode.c - create mode 100644 fs/sdcardfs/lookup.c - create mode 100644 fs/sdcardfs/main.c - create mode 100644 fs/sdcardfs/mmap.c - create mode 100644 fs/sdcardfs/multiuser.h - create mode 100644 fs/sdcardfs/packagelist.c - create mode 100644 fs/sdcardfs/sdcardfs.h - create mode 100644 fs/sdcardfs/super.c - -diff --git a/fs/Kconfig b/fs/Kconfig -index 2501e6f1f965..42fe99e24071 100644 ---- a/fs/Kconfig -+++ b/fs/Kconfig -@@ -243,6 +243,7 @@ source "fs/orangefs/Kconfig" - source "fs/adfs/Kconfig" - source "fs/affs/Kconfig" - source "fs/ecryptfs/Kconfig" -+source "fs/sdcardfs/Kconfig" - source "fs/hfs/Kconfig" - source "fs/hfsplus/Kconfig" - source "fs/befs/Kconfig" -diff --git a/fs/Makefile b/fs/Makefile -index 14231b4cf383..cc5524e8acda 100644 ---- a/fs/Makefile -+++ b/fs/Makefile -@@ -87,6 +87,7 @@ obj-$(CONFIG_ISO9660_FS) += isofs/ - obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+ - obj-$(CONFIG_HFS_FS) += hfs/ - obj-$(CONFIG_ECRYPT_FS) += ecryptfs/ -+obj-$(CONFIG_SDCARD_FS) += sdcardfs/ - obj-$(CONFIG_VXFS_FS) += freevxfs/ - obj-$(CONFIG_NFS_FS) += nfs/ - obj-$(CONFIG_EXPORTFS) += exportfs/ -diff --git a/fs/sdcardfs/Kconfig b/fs/sdcardfs/Kconfig -new file mode 100644 -index 000000000000..a1c103316ac7 ---- /dev/null -+++ b/fs/sdcardfs/Kconfig -@@ -0,0 +1,13 @@ -+config SDCARD_FS -+ tristate "sdcard file system" -+ depends on CONFIGFS_FS -+ default n -+ help -+ Sdcardfs is based on Wrapfs file system. -+ -+config SDCARD_FS_FADV_NOACTIVE -+ bool "sdcardfs fadvise noactive support" -+ depends on FADV_NOACTIVE -+ default y -+ help -+ Sdcardfs supports fadvise noactive mode. -diff --git a/fs/sdcardfs/Makefile b/fs/sdcardfs/Makefile -new file mode 100644 -index 000000000000..b84fbb2b45a4 ---- /dev/null -+++ b/fs/sdcardfs/Makefile -@@ -0,0 +1,7 @@ -+SDCARDFS_VERSION="0.1" -+ -+EXTRA_CFLAGS += -DSDCARDFS_VERSION=\"$(SDCARDFS_VERSION)\" -+ -+obj-$(CONFIG_SDCARD_FS) += sdcardfs.o -+ -+sdcardfs-y := dentry.o file.o inode.o main.o super.o lookup.o mmap.o packagelist.o derived_perm.o -diff --git a/fs/sdcardfs/dentry.c b/fs/sdcardfs/dentry.c -new file mode 100644 -index 000000000000..cb573f1efbfc ---- /dev/null -+++ b/fs/sdcardfs/dentry.c -@@ -0,0 +1,196 @@ -+/* -+ * fs/sdcardfs/dentry.c -+ * -+ * Copyright (c) 2013 Samsung Electronics Co. Ltd -+ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, -+ * Sunghwan Yun, Sungjong Seo -+ * -+ * This program has been developed as a stackable file system based on -+ * the WrapFS which written by -+ * -+ * Copyright (c) 1998-2011 Erez Zadok -+ * Copyright (c) 2009 Shrikar Archak -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * This file is dual licensed. It may be redistributed and/or modified -+ * under the terms of the Apache 2.0 License OR version 2 of the GNU -+ * General Public License. -+ */ -+ -+#include "sdcardfs.h" -+#include "linux/ctype.h" -+ -+/* -+ * returns: -ERRNO if error (returned to user) -+ * 0: tell VFS to invalidate dentry -+ * 1: dentry is valid -+ */ -+static int sdcardfs_d_revalidate(struct dentry *dentry, unsigned int flags) -+{ -+ int err = 1; -+ struct path parent_lower_path, lower_path; -+ struct dentry *parent_dentry = NULL; -+ struct dentry *parent_lower_dentry = NULL; -+ struct dentry *lower_cur_parent_dentry = NULL; -+ struct dentry *lower_dentry = NULL; -+ struct inode *inode; -+ struct sdcardfs_inode_data *data; -+ -+ if (flags & LOOKUP_RCU) -+ return -ECHILD; -+ -+ spin_lock(&dentry->d_lock); -+ if (IS_ROOT(dentry)) { -+ spin_unlock(&dentry->d_lock); -+ return 1; -+ } -+ spin_unlock(&dentry->d_lock); -+ -+ /* check uninitialized obb_dentry and -+ * whether the base obbpath has been changed or not -+ */ -+ if (is_obbpath_invalid(dentry)) { -+ return 0; -+ } -+ -+ parent_dentry = dget_parent(dentry); -+ sdcardfs_get_lower_path(parent_dentry, &parent_lower_path); -+ sdcardfs_get_real_lower(dentry, &lower_path); -+ parent_lower_dentry = parent_lower_path.dentry; -+ lower_dentry = lower_path.dentry; -+ lower_cur_parent_dentry = dget_parent(lower_dentry); -+ -+ if ((lower_dentry->d_flags & DCACHE_OP_REVALIDATE)) { -+ err = lower_dentry->d_op->d_revalidate(lower_dentry, flags); -+ if (err == 0) { -+ goto out; -+ } -+ } -+ -+ spin_lock(&lower_dentry->d_lock); -+ if (d_unhashed(lower_dentry)) { -+ spin_unlock(&lower_dentry->d_lock); -+ err = 0; -+ goto out; -+ } -+ spin_unlock(&lower_dentry->d_lock); -+ -+ if (parent_lower_dentry != lower_cur_parent_dentry) { -+ err = 0; -+ goto out; -+ } -+ -+ if (dentry < lower_dentry) { -+ spin_lock(&dentry->d_lock); -+ spin_lock_nested(&lower_dentry->d_lock, DENTRY_D_LOCK_NESTED); -+ } else { -+ spin_lock(&lower_dentry->d_lock); -+ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); -+ } -+ -+ if (!qstr_case_eq(&dentry->d_name, &lower_dentry->d_name)) { -+ err = 0; -+ } -+ -+ if (dentry < lower_dentry) { -+ spin_unlock(&lower_dentry->d_lock); -+ spin_unlock(&dentry->d_lock); -+ } else { -+ spin_unlock(&dentry->d_lock); -+ spin_unlock(&lower_dentry->d_lock); -+ } -+ if (!err) -+ goto out; -+ -+ /* If our top's inode is gone, we may be out of date */ -+ inode = igrab(d_inode(dentry)); -+ if (inode) { -+ data = top_data_get(SDCARDFS_I(inode)); -+ if (!data || data->abandoned) { -+ err = 0; -+ } -+ if (data) -+ data_put(data); -+ iput(inode); -+ } -+ -+out: -+ dput(parent_dentry); -+ dput(lower_cur_parent_dentry); -+ sdcardfs_put_lower_path(parent_dentry, &parent_lower_path); -+ sdcardfs_put_real_lower(dentry, &lower_path); -+ return err; -+} -+ -+/* 1 = delete, 0 = cache */ -+static int sdcardfs_d_delete(const struct dentry *d) -+{ -+ return SDCARDFS_SB(d->d_sb)->options.nocache ? 1 : 0; -+} -+ -+static void sdcardfs_d_release(struct dentry *dentry) -+{ -+ if (!dentry || !dentry->d_fsdata) -+ return; -+ /* release and reset the lower paths */ -+ if (has_graft_path(dentry)) -+ sdcardfs_put_reset_orig_path(dentry); -+ sdcardfs_put_reset_lower_path(dentry); -+ free_dentry_private_data(dentry); -+} -+ -+static int sdcardfs_hash_ci(const struct dentry *dentry, -+ struct qstr *qstr) -+{ -+ /* -+ * This function is copy of vfat_hashi. -+ * FIXME Should we support national language? -+ * Refer to vfat_hashi() -+ * struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io; -+ */ -+ const unsigned char *name; -+ unsigned int len; -+ unsigned long hash; -+ -+ name = qstr->name; -+ len = qstr->len; -+ -+ hash = init_name_hash(dentry); -+ while (len--) -+ hash = partial_name_hash(tolower(*name++), hash); -+ qstr->hash = end_name_hash(hash); -+ -+ return 0; -+} -+ -+/* -+ * Case insensitive compare of two vfat names. -+ */ -+static int sdcardfs_cmp_ci(const struct dentry *dentry, -+ unsigned int len, const char *str, const struct qstr *name) -+{ -+ /* FIXME Should we support national language? */ -+ -+ if (name->len == len) { -+ if (str_n_case_eq(name->name, str, len)) -+ return 0; -+ } -+ return 1; -+} -+ -+static void sdcardfs_canonical_path(const struct path *path, -+ struct path *actual_path) -+{ -+ sdcardfs_get_real_lower(path->dentry, actual_path); -+} -+ -+const struct dentry_operations sdcardfs_ci_dops = { -+ .d_revalidate = sdcardfs_d_revalidate, -+ .d_delete = sdcardfs_d_delete, -+ .d_release = sdcardfs_d_release, -+ .d_hash = sdcardfs_hash_ci, -+ .d_compare = sdcardfs_cmp_ci, -+ .d_canonical_path = sdcardfs_canonical_path, -+}; -+ -diff --git a/fs/sdcardfs/derived_perm.c b/fs/sdcardfs/derived_perm.c -new file mode 100644 -index 000000000000..78a669c8a4d6 ---- /dev/null -+++ b/fs/sdcardfs/derived_perm.c -@@ -0,0 +1,477 @@ -+/* -+ * fs/sdcardfs/derived_perm.c -+ * -+ * Copyright (c) 2013 Samsung Electronics Co. Ltd -+ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, -+ * Sunghwan Yun, Sungjong Seo -+ * -+ * This program has been developed as a stackable file system based on -+ * the WrapFS which written by -+ * -+ * Copyright (c) 1998-2011 Erez Zadok -+ * Copyright (c) 2009 Shrikar Archak -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * This file is dual licensed. It may be redistributed and/or modified -+ * under the terms of the Apache 2.0 License OR version 2 of the GNU -+ * General Public License. -+ */ -+ -+#include "sdcardfs.h" -+ -+/* copy derived state from parent inode */ -+static void inherit_derived_state(struct inode *parent, struct inode *child) -+{ -+ struct sdcardfs_inode_info *pi = SDCARDFS_I(parent); -+ struct sdcardfs_inode_info *ci = SDCARDFS_I(child); -+ -+ ci->data->perm = PERM_INHERIT; -+ ci->data->userid = pi->data->userid; -+ ci->data->d_uid = pi->data->d_uid; -+ ci->data->under_android = pi->data->under_android; -+ ci->data->under_cache = pi->data->under_cache; -+ ci->data->under_obb = pi->data->under_obb; -+} -+ -+/* helper function for derived state */ -+void setup_derived_state(struct inode *inode, perm_t perm, userid_t userid, -+ uid_t uid) -+{ -+ struct sdcardfs_inode_info *info = SDCARDFS_I(inode); -+ -+ info->data->perm = perm; -+ info->data->userid = userid; -+ info->data->d_uid = uid; -+ info->data->under_android = false; -+ info->data->under_cache = false; -+ info->data->under_obb = false; -+} -+ -+/* While renaming, there is a point where we want the path from dentry, -+ * but the name from newdentry -+ */ -+void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, -+ const struct qstr *name) -+{ -+ struct sdcardfs_inode_info *info = SDCARDFS_I(d_inode(dentry)); -+ struct sdcardfs_inode_info *parent_info = SDCARDFS_I(d_inode(parent)); -+ struct sdcardfs_inode_data *parent_data = parent_info->data; -+ appid_t appid; -+ unsigned long user_num; -+ int err; -+ struct qstr q_Android = QSTR_LITERAL("Android"); -+ struct qstr q_data = QSTR_LITERAL("data"); -+ struct qstr q_sandbox = QSTR_LITERAL("sandbox"); -+ struct qstr q_obb = QSTR_LITERAL("obb"); -+ struct qstr q_media = QSTR_LITERAL("media"); -+ struct qstr q_cache = QSTR_LITERAL("cache"); -+ -+ /* By default, each inode inherits from its parent. -+ * the properties are maintained on its private fields -+ * because the inode attributes will be modified with that of -+ * its lower inode. -+ * These values are used by our custom permission call instead -+ * of using the inode permissions. -+ */ -+ -+ inherit_derived_state(d_inode(parent), d_inode(dentry)); -+ -+ /* Files don't get special labels */ -+ if (!S_ISDIR(d_inode(dentry)->i_mode)) { -+ set_top(info, parent_info); -+ return; -+ } -+ /* Derive custom permissions based on parent and current node */ -+ switch (parent_data->perm) { -+ case PERM_INHERIT: -+ case PERM_ANDROID_PACKAGE_CACHE: -+ set_top(info, parent_info); -+ break; -+ case PERM_PRE_ROOT: -+ /* Legacy internal layout places users at top level */ -+ info->data->perm = PERM_ROOT; -+ err = kstrtoul(name->name, 10, &user_num); -+ if (err) -+ info->data->userid = 0; -+ else -+ info->data->userid = user_num; -+ break; -+ case PERM_ROOT: -+ /* Assume masked off by default. */ -+ if (qstr_case_eq(name, &q_Android)) { -+ /* App-specific directories inside; let anyone traverse */ -+ info->data->perm = PERM_ANDROID; -+ info->data->under_android = true; -+ } else { -+ set_top(info, parent_info); -+ } -+ break; -+ case PERM_ANDROID: -+ if (qstr_case_eq(name, &q_data)) { -+ /* App-specific directories inside; let anyone traverse */ -+ info->data->perm = PERM_ANDROID_DATA; -+ } else if (qstr_case_eq(name, &q_sandbox)) { -+ /* App-specific directories inside; let anyone traverse */ -+ info->data->perm = PERM_ANDROID_DATA; -+ } else if (qstr_case_eq(name, &q_obb)) { -+ /* App-specific directories inside; let anyone traverse */ -+ info->data->perm = PERM_ANDROID_OBB; -+ info->data->under_obb = true; -+ /* Single OBB directory is always shared */ -+ } else if (qstr_case_eq(name, &q_media)) { -+ /* App-specific directories inside; let anyone traverse */ -+ info->data->perm = PERM_ANDROID_MEDIA; -+ } else { -+ set_top(info, parent_info); -+ } -+ break; -+ case PERM_ANDROID_OBB: -+ case PERM_ANDROID_DATA: -+ case PERM_ANDROID_MEDIA: -+ info->data->perm = PERM_ANDROID_PACKAGE; -+ appid = get_appid(name->name); -+ if (appid != 0 && !is_excluded(name->name, parent_data->userid)) -+ info->data->d_uid = -+ multiuser_get_uid(parent_data->userid, appid); -+ break; -+ case PERM_ANDROID_PACKAGE: -+ if (qstr_case_eq(name, &q_cache)) { -+ info->data->perm = PERM_ANDROID_PACKAGE_CACHE; -+ info->data->under_cache = true; -+ } -+ set_top(info, parent_info); -+ break; -+ } -+} -+ -+void get_derived_permission(struct dentry *parent, struct dentry *dentry) -+{ -+ get_derived_permission_new(parent, dentry, &dentry->d_name); -+} -+ -+static appid_t get_type(const char *name) -+{ -+ const char *ext = strrchr(name, '.'); -+ appid_t id; -+ -+ if (ext && ext[0]) { -+ ext = &ext[1]; -+ id = get_ext_gid(ext); -+ return id?:AID_MEDIA_RW; -+ } -+ return AID_MEDIA_RW; -+} -+ -+void fixup_lower_ownership(struct dentry *dentry, const char *name) -+{ -+ struct path path; -+ struct inode *inode; -+ struct inode *delegated_inode = NULL; -+ int error; -+ struct sdcardfs_inode_info *info; -+ struct sdcardfs_inode_data *info_d; -+ struct sdcardfs_inode_data *info_top; -+ perm_t perm; -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); -+ uid_t uid = sbi->options.fs_low_uid; -+ gid_t gid = sbi->options.fs_low_gid; -+ struct iattr newattrs; -+ -+ if (!sbi->options.gid_derivation) -+ return; -+ -+ info = SDCARDFS_I(d_inode(dentry)); -+ info_d = info->data; -+ perm = info_d->perm; -+ if (info_d->under_obb) { -+ perm = PERM_ANDROID_OBB; -+ } else if (info_d->under_cache) { -+ perm = PERM_ANDROID_PACKAGE_CACHE; -+ } else if (perm == PERM_INHERIT) { -+ info_top = top_data_get(info); -+ perm = info_top->perm; -+ data_put(info_top); -+ } -+ -+ switch (perm) { -+ case PERM_ROOT: -+ case PERM_ANDROID: -+ case PERM_ANDROID_DATA: -+ case PERM_ANDROID_MEDIA: -+ case PERM_ANDROID_PACKAGE: -+ case PERM_ANDROID_PACKAGE_CACHE: -+ uid = multiuser_get_uid(info_d->userid, uid); -+ break; -+ case PERM_ANDROID_OBB: -+ uid = AID_MEDIA_OBB; -+ break; -+ case PERM_PRE_ROOT: -+ default: -+ break; -+ } -+ switch (perm) { -+ case PERM_ROOT: -+ case PERM_ANDROID: -+ case PERM_ANDROID_DATA: -+ case PERM_ANDROID_MEDIA: -+ if (S_ISDIR(d_inode(dentry)->i_mode)) -+ gid = multiuser_get_uid(info_d->userid, AID_MEDIA_RW); -+ else -+ gid = multiuser_get_uid(info_d->userid, get_type(name)); -+ break; -+ case PERM_ANDROID_OBB: -+ gid = AID_MEDIA_OBB; -+ break; -+ case PERM_ANDROID_PACKAGE: -+ if (uid_is_app(info_d->d_uid)) -+ gid = multiuser_get_ext_gid(info_d->d_uid); -+ else -+ gid = multiuser_get_uid(info_d->userid, AID_MEDIA_RW); -+ break; -+ case PERM_ANDROID_PACKAGE_CACHE: -+ if (uid_is_app(info_d->d_uid)) -+ gid = multiuser_get_ext_cache_gid(info_d->d_uid); -+ else -+ gid = multiuser_get_uid(info_d->userid, AID_MEDIA_RW); -+ break; -+ case PERM_PRE_ROOT: -+ default: -+ break; -+ } -+ -+ sdcardfs_get_lower_path(dentry, &path); -+ inode = d_inode(path.dentry); -+ if (d_inode(path.dentry)->i_gid.val != gid || d_inode(path.dentry)->i_uid.val != uid) { -+retry_deleg: -+ newattrs.ia_valid = ATTR_GID | ATTR_UID | ATTR_FORCE; -+ newattrs.ia_uid = make_kuid(current_user_ns(), uid); -+ newattrs.ia_gid = make_kgid(current_user_ns(), gid); -+ if (!S_ISDIR(inode->i_mode)) -+ newattrs.ia_valid |= -+ ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; -+ inode_lock(inode); -+ error = security_path_chown(&path, newattrs.ia_uid, newattrs.ia_gid); -+ if (!error) -+ error = notify_change2(path.mnt, path.dentry, &newattrs, &delegated_inode); -+ inode_unlock(inode); -+ if (delegated_inode) { -+ error = break_deleg_wait(&delegated_inode); -+ if (!error) -+ goto retry_deleg; -+ } -+ if (error) -+ pr_debug("sdcardfs: Failed to touch up lower fs gid/uid for %s\n", name); -+ } -+ sdcardfs_put_lower_path(dentry, &path); -+} -+ -+static int descendant_may_need_fixup(struct sdcardfs_inode_data *data, -+ struct limit_search *limit) -+{ -+ if (data->perm == PERM_ROOT) -+ return (limit->flags & BY_USERID) ? -+ data->userid == limit->userid : 1; -+ if (data->perm == PERM_PRE_ROOT || data->perm == PERM_ANDROID) -+ return 1; -+ return 0; -+} -+ -+static int needs_fixup(perm_t perm) -+{ -+ if (perm == PERM_ANDROID_DATA || perm == PERM_ANDROID_OBB -+ || perm == PERM_ANDROID_MEDIA) -+ return 1; -+ return 0; -+} -+ -+static void __fixup_perms_recursive(struct dentry *dentry, struct limit_search *limit, int depth) -+{ -+ struct dentry *child; -+ struct sdcardfs_inode_info *info; -+ -+ /* -+ * All paths will terminate their recursion on hitting PERM_ANDROID_OBB, -+ * PERM_ANDROID_MEDIA, or PERM_ANDROID_DATA. This happens at a depth of -+ * at most 3. -+ */ -+ WARN(depth > 3, "%s: Max expected depth exceeded!\n", __func__); -+ spin_lock_nested(&dentry->d_lock, depth); -+ if (!d_inode(dentry)) { -+ spin_unlock(&dentry->d_lock); -+ return; -+ } -+ info = SDCARDFS_I(d_inode(dentry)); -+ -+ if (needs_fixup(info->data->perm)) { -+ list_for_each_entry(child, &dentry->d_subdirs, d_child) { -+ spin_lock_nested(&child->d_lock, depth + 1); -+ if (!(limit->flags & BY_NAME) || qstr_case_eq(&child->d_name, &limit->name)) { -+ if (d_inode(child)) { -+ get_derived_permission(dentry, child); -+ fixup_tmp_permissions(d_inode(child)); -+ spin_unlock(&child->d_lock); -+ break; -+ } -+ } -+ spin_unlock(&child->d_lock); -+ } -+ } else if (descendant_may_need_fixup(info->data, limit)) { -+ list_for_each_entry(child, &dentry->d_subdirs, d_child) { -+ __fixup_perms_recursive(child, limit, depth + 1); -+ } -+ } -+ spin_unlock(&dentry->d_lock); -+} -+ -+void fixup_perms_recursive(struct dentry *dentry, struct limit_search *limit) -+{ -+ __fixup_perms_recursive(dentry, limit, 0); -+} -+ -+/* main function for updating derived permission */ -+inline void update_derived_permission_lock(struct dentry *dentry) -+{ -+ struct dentry *parent; -+ -+ if (!dentry || !d_inode(dentry)) { -+ pr_err("sdcardfs: %s: invalid dentry\n", __func__); -+ return; -+ } -+ /* FIXME: -+ * 1. need to check whether the dentry is updated or not -+ * 2. remove the root dentry update -+ */ -+ if (!IS_ROOT(dentry)) { -+ parent = dget_parent(dentry); -+ if (parent) { -+ get_derived_permission(parent, dentry); -+ dput(parent); -+ } -+ } -+ fixup_tmp_permissions(d_inode(dentry)); -+} -+ -+int need_graft_path(struct dentry *dentry) -+{ -+ int ret = 0; -+ struct dentry *parent = dget_parent(dentry); -+ struct sdcardfs_inode_info *parent_info = SDCARDFS_I(d_inode(parent)); -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); -+ struct qstr obb = QSTR_LITERAL("obb"); -+ -+ if (!sbi->options.unshared_obb && -+ parent_info->data->perm == PERM_ANDROID && -+ qstr_case_eq(&dentry->d_name, &obb)) { -+ -+ /* /Android/obb is the base obbpath of DERIVED_UNIFIED */ -+ if (!(sbi->options.multiuser == false -+ && parent_info->data->userid == 0)) { -+ ret = 1; -+ } -+ } -+ dput(parent); -+ return ret; -+} -+ -+int is_obbpath_invalid(struct dentry *dent) -+{ -+ int ret = 0; -+ struct sdcardfs_dentry_info *di = SDCARDFS_D(dent); -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dent->d_sb); -+ char *path_buf, *obbpath_s; -+ int need_put = 0; -+ struct path lower_path; -+ -+ /* check the base obbpath has been changed. -+ * this routine can check an uninitialized obb dentry as well. -+ * regarding the uninitialized obb, refer to the sdcardfs_mkdir() -+ */ -+ spin_lock(&di->lock); -+ if (di->orig_path.dentry) { -+ if (!di->lower_path.dentry) { -+ ret = 1; -+ } else { -+ path_get(&di->lower_path); -+ -+ path_buf = kmalloc(PATH_MAX, GFP_ATOMIC); -+ if (!path_buf) { -+ ret = 1; -+ pr_err("sdcardfs: fail to allocate path_buf in %s.\n", __func__); -+ } else { -+ obbpath_s = d_path(&di->lower_path, path_buf, PATH_MAX); -+ if (d_unhashed(di->lower_path.dentry) || -+ !str_case_eq(sbi->obbpath_s, obbpath_s)) { -+ ret = 1; -+ } -+ kfree(path_buf); -+ } -+ -+ pathcpy(&lower_path, &di->lower_path); -+ need_put = 1; -+ } -+ } -+ spin_unlock(&di->lock); -+ if (need_put) -+ path_put(&lower_path); -+ return ret; -+} -+ -+int is_base_obbpath(struct dentry *dentry) -+{ -+ int ret = 0; -+ struct dentry *parent = dget_parent(dentry); -+ struct sdcardfs_inode_info *parent_info = SDCARDFS_I(d_inode(parent)); -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); -+ struct qstr q_obb = QSTR_LITERAL("obb"); -+ -+ spin_lock(&SDCARDFS_D(dentry)->lock); -+ if (sbi->options.multiuser) { -+ if (parent_info->data->perm == PERM_PRE_ROOT && -+ qstr_case_eq(&dentry->d_name, &q_obb)) { -+ ret = 1; -+ } -+ } else if (parent_info->data->perm == PERM_ANDROID && -+ qstr_case_eq(&dentry->d_name, &q_obb)) { -+ ret = 1; -+ } -+ spin_unlock(&SDCARDFS_D(dentry)->lock); -+ return ret; -+} -+ -+/* The lower_path will be stored to the dentry's orig_path -+ * and the base obbpath will be copyed to the lower_path variable. -+ * if an error returned, there's no change in the lower_path -+ * returns: -ERRNO if error (0: no error) -+ */ -+int setup_obb_dentry(struct dentry *dentry, struct path *lower_path) -+{ -+ int err = 0; -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); -+ struct path obbpath; -+ -+ /* A local obb dentry must have its own orig_path to support rmdir -+ * and mkdir of itself. Usually, we expect that the sbi->obbpath -+ * is avaiable on this stage. -+ */ -+ sdcardfs_set_orig_path(dentry, lower_path); -+ -+ err = kern_path(sbi->obbpath_s, -+ LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &obbpath); -+ -+ if (!err) { -+ /* the obbpath base has been found */ -+ pathcpy(lower_path, &obbpath); -+ } else { -+ /* if the sbi->obbpath is not available, we can optionally -+ * setup the lower_path with its orig_path. -+ * but, the current implementation just returns an error -+ * because the sdcard daemon also regards this case as -+ * a lookup fail. -+ */ -+ pr_info("sdcardfs: the sbi->obbpath is not available\n"); -+ } -+ return err; -+} -+ -+ -diff --git a/fs/sdcardfs/file.c b/fs/sdcardfs/file.c -new file mode 100644 -index 000000000000..271c4c4cb760 ---- /dev/null -+++ b/fs/sdcardfs/file.c -@@ -0,0 +1,467 @@ -+/* -+ * fs/sdcardfs/file.c -+ * -+ * Copyright (c) 2013 Samsung Electronics Co. Ltd -+ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, -+ * Sunghwan Yun, Sungjong Seo -+ * -+ * This program has been developed as a stackable file system based on -+ * the WrapFS which written by -+ * -+ * Copyright (c) 1998-2011 Erez Zadok -+ * Copyright (c) 2009 Shrikar Archak -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * This file is dual licensed. It may be redistributed and/or modified -+ * under the terms of the Apache 2.0 License OR version 2 of the GNU -+ * General Public License. -+ */ -+ -+#include "sdcardfs.h" -+#ifdef CONFIG_SDCARD_FS_FADV_NOACTIVE -+#include -+#endif -+ -+static ssize_t sdcardfs_read(struct file *file, char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ int err; -+ struct file *lower_file; -+ struct dentry *dentry = file->f_path.dentry; -+#ifdef CONFIG_SDCARD_FS_FADV_NOACTIVE -+ struct backing_dev_info *bdi; -+#endif -+ -+ lower_file = sdcardfs_lower_file(file); -+ -+#ifdef CONFIG_SDCARD_FS_FADV_NOACTIVE -+ if (file->f_mode & FMODE_NOACTIVE) { -+ if (!(lower_file->f_mode & FMODE_NOACTIVE)) { -+ bdi = lower_file->f_mapping->backing_dev_info; -+ lower_file->f_ra.ra_pages = bdi->ra_pages * 2; -+ spin_lock(&lower_file->f_lock); -+ lower_file->f_mode |= FMODE_NOACTIVE; -+ spin_unlock(&lower_file->f_lock); -+ } -+ } -+#endif -+ -+ err = vfs_read(lower_file, buf, count, ppos); -+ /* update our inode atime upon a successful lower read */ -+ if (err >= 0) -+ fsstack_copy_attr_atime(d_inode(dentry), -+ file_inode(lower_file)); -+ -+ return err; -+} -+ -+static ssize_t sdcardfs_write(struct file *file, const char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ int err; -+ struct file *lower_file; -+ struct dentry *dentry = file->f_path.dentry; -+ struct inode *inode = d_inode(dentry); -+ -+ /* check disk space */ -+ if (!check_min_free_space(dentry, count, 0)) { -+ pr_err("No minimum free space.\n"); -+ return -ENOSPC; -+ } -+ -+ lower_file = sdcardfs_lower_file(file); -+ err = vfs_write(lower_file, buf, count, ppos); -+ /* update our inode times+sizes upon a successful lower write */ -+ if (err >= 0) { -+ if (sizeof(loff_t) > sizeof(long)) -+ inode_lock(inode); -+ fsstack_copy_inode_size(inode, file_inode(lower_file)); -+ fsstack_copy_attr_times(inode, file_inode(lower_file)); -+ if (sizeof(loff_t) > sizeof(long)) -+ inode_unlock(inode); -+ } -+ -+ return err; -+} -+ -+static int sdcardfs_readdir(struct file *file, struct dir_context *ctx) -+{ -+ int err; -+ struct file *lower_file = NULL; -+ struct dentry *dentry = file->f_path.dentry; -+ -+ lower_file = sdcardfs_lower_file(file); -+ -+ lower_file->f_pos = file->f_pos; -+ err = iterate_dir(lower_file, ctx); -+ file->f_pos = lower_file->f_pos; -+ if (err >= 0) /* copy the atime */ -+ fsstack_copy_attr_atime(d_inode(dentry), -+ file_inode(lower_file)); -+ return err; -+} -+ -+static long sdcardfs_unlocked_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ long err = -ENOTTY; -+ struct file *lower_file; -+ const struct cred *saved_cred = NULL; -+ struct dentry *dentry = file->f_path.dentry; -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); -+ -+ lower_file = sdcardfs_lower_file(file); -+ -+ /* XXX: use vfs_ioctl if/when VFS exports it */ -+ if (!lower_file || !lower_file->f_op) -+ goto out; -+ -+ /* save current_cred and override it */ -+ saved_cred = override_fsids(sbi, SDCARDFS_I(file_inode(file))->data); -+ if (!saved_cred) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ if (lower_file->f_op->unlocked_ioctl) -+ err = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg); -+ -+ /* some ioctls can change inode attributes (EXT2_IOC_SETFLAGS) */ -+ if (!err) -+ sdcardfs_copy_and_fix_attrs(file_inode(file), -+ file_inode(lower_file)); -+ revert_fsids(saved_cred); -+out: -+ return err; -+} -+ -+#ifdef CONFIG_COMPAT -+static long sdcardfs_compat_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ long err = -ENOTTY; -+ struct file *lower_file; -+ const struct cred *saved_cred = NULL; -+ struct dentry *dentry = file->f_path.dentry; -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); -+ -+ lower_file = sdcardfs_lower_file(file); -+ -+ /* XXX: use vfs_ioctl if/when VFS exports it */ -+ if (!lower_file || !lower_file->f_op) -+ goto out; -+ -+ /* save current_cred and override it */ -+ saved_cred = override_fsids(sbi, SDCARDFS_I(file_inode(file))->data); -+ if (!saved_cred) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ if (lower_file->f_op->compat_ioctl) -+ err = lower_file->f_op->compat_ioctl(lower_file, cmd, arg); -+ -+ revert_fsids(saved_cred); -+out: -+ return err; -+} -+#endif -+ -+static int sdcardfs_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ int err = 0; -+ bool willwrite; -+ struct file *lower_file; -+ const struct vm_operations_struct *saved_vm_ops = NULL; -+ -+ /* this might be deferred to mmap's writepage */ -+ willwrite = ((vma->vm_flags | VM_SHARED | VM_WRITE) == vma->vm_flags); -+ -+ /* -+ * File systems which do not implement ->writepage may use -+ * generic_file_readonly_mmap as their ->mmap op. If you call -+ * generic_file_readonly_mmap with VM_WRITE, you'd get an -EINVAL. -+ * But we cannot call the lower ->mmap op, so we can't tell that -+ * writeable mappings won't work. Therefore, our only choice is to -+ * check if the lower file system supports the ->writepage, and if -+ * not, return EINVAL (the same error that -+ * generic_file_readonly_mmap returns in that case). -+ */ -+ lower_file = sdcardfs_lower_file(file); -+ if (willwrite && !lower_file->f_mapping->a_ops->writepage) { -+ err = -EINVAL; -+ pr_err("sdcardfs: lower file system does not support writeable mmap\n"); -+ goto out; -+ } -+ -+ /* -+ * find and save lower vm_ops. -+ * -+ * XXX: the VFS should have a cleaner way of finding the lower vm_ops -+ */ -+ if (!SDCARDFS_F(file)->lower_vm_ops) { -+ err = lower_file->f_op->mmap(lower_file, vma); -+ if (err) { -+ pr_err("sdcardfs: lower mmap failed %d\n", err); -+ goto out; -+ } -+ saved_vm_ops = vma->vm_ops; /* save: came from lower ->mmap */ -+ } -+ -+ /* -+ * Next 3 lines are all I need from generic_file_mmap. I definitely -+ * don't want its test for ->readpage which returns -ENOEXEC. -+ */ -+ file_accessed(file); -+ vma->vm_ops = &sdcardfs_vm_ops; -+ -+ file->f_mapping->a_ops = &sdcardfs_aops; /* set our aops */ -+ if (!SDCARDFS_F(file)->lower_vm_ops) /* save for our ->fault */ -+ SDCARDFS_F(file)->lower_vm_ops = saved_vm_ops; -+ vma->vm_private_data = file; -+ get_file(lower_file); -+ vma->vm_file = lower_file; -+ -+out: -+ return err; -+} -+ -+static int sdcardfs_open(struct inode *inode, struct file *file) -+{ -+ int err = 0; -+ struct file *lower_file = NULL; -+ struct path lower_path; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent = dget_parent(dentry); -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); -+ const struct cred *saved_cred = NULL; -+ -+ /* don't open unhashed/deleted files */ -+ if (d_unhashed(dentry)) { -+ err = -ENOENT; -+ goto out_err; -+ } -+ -+ if (!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) { -+ err = -EACCES; -+ goto out_err; -+ } -+ -+ /* save current_cred and override it */ -+ saved_cred = override_fsids(sbi, SDCARDFS_I(inode)->data); -+ if (!saved_cred) { -+ err = -ENOMEM; -+ goto out_err; -+ } -+ -+ file->private_data = -+ kzalloc(sizeof(struct sdcardfs_file_info), GFP_KERNEL); -+ if (!SDCARDFS_F(file)) { -+ err = -ENOMEM; -+ goto out_revert_cred; -+ } -+ -+ /* open lower object and link sdcardfs's file struct to lower's */ -+ sdcardfs_get_lower_path(file->f_path.dentry, &lower_path); -+ lower_file = dentry_open(&lower_path, file->f_flags, current_cred()); -+ path_put(&lower_path); -+ if (IS_ERR(lower_file)) { -+ err = PTR_ERR(lower_file); -+ lower_file = sdcardfs_lower_file(file); -+ if (lower_file) { -+ sdcardfs_set_lower_file(file, NULL); -+ fput(lower_file); /* fput calls dput for lower_dentry */ -+ } -+ } else { -+ sdcardfs_set_lower_file(file, lower_file); -+ } -+ -+ if (err) -+ kfree(SDCARDFS_F(file)); -+ else -+ sdcardfs_copy_and_fix_attrs(inode, sdcardfs_lower_inode(inode)); -+ -+out_revert_cred: -+ revert_fsids(saved_cred); -+out_err: -+ dput(parent); -+ return err; -+} -+ -+static int sdcardfs_flush(struct file *file, fl_owner_t id) -+{ -+ int err = 0; -+ struct file *lower_file = NULL; -+ -+ lower_file = sdcardfs_lower_file(file); -+ if (lower_file && lower_file->f_op && lower_file->f_op->flush) { -+ filemap_write_and_wait(file->f_mapping); -+ err = lower_file->f_op->flush(lower_file, id); -+ } -+ -+ return err; -+} -+ -+/* release all lower object references & free the file info structure */ -+static int sdcardfs_file_release(struct inode *inode, struct file *file) -+{ -+ struct file *lower_file; -+ -+ lower_file = sdcardfs_lower_file(file); -+ if (lower_file) { -+ sdcardfs_set_lower_file(file, NULL); -+ fput(lower_file); -+ } -+ -+ kfree(SDCARDFS_F(file)); -+ return 0; -+} -+ -+static int sdcardfs_fsync(struct file *file, loff_t start, loff_t end, -+ int datasync) -+{ -+ int err; -+ struct file *lower_file; -+ struct path lower_path; -+ struct dentry *dentry = file->f_path.dentry; -+ -+ err = __generic_file_fsync(file, start, end, datasync); -+ if (err) -+ goto out; -+ -+ lower_file = sdcardfs_lower_file(file); -+ sdcardfs_get_lower_path(dentry, &lower_path); -+ err = vfs_fsync_range(lower_file, start, end, datasync); -+ sdcardfs_put_lower_path(dentry, &lower_path); -+out: -+ return err; -+} -+ -+static int sdcardfs_fasync(int fd, struct file *file, int flag) -+{ -+ int err = 0; -+ struct file *lower_file = NULL; -+ -+ lower_file = sdcardfs_lower_file(file); -+ if (lower_file->f_op && lower_file->f_op->fasync) -+ err = lower_file->f_op->fasync(fd, lower_file, flag); -+ -+ return err; -+} -+ -+/* -+ * Sdcardfs cannot use generic_file_llseek as ->llseek, because it would -+ * only set the offset of the upper file. So we have to implement our -+ * own method to set both the upper and lower file offsets -+ * consistently. -+ */ -+static loff_t sdcardfs_file_llseek(struct file *file, loff_t offset, int whence) -+{ -+ int err; -+ struct file *lower_file; -+ -+ err = generic_file_llseek(file, offset, whence); -+ if (err < 0) -+ goto out; -+ -+ lower_file = sdcardfs_lower_file(file); -+ err = generic_file_llseek(lower_file, offset, whence); -+ -+out: -+ return err; -+} -+ -+/* -+ * Sdcardfs read_iter, redirect modified iocb to lower read_iter -+ */ -+ssize_t sdcardfs_read_iter(struct kiocb *iocb, struct iov_iter *iter) -+{ -+ int err; -+ struct file *file = iocb->ki_filp, *lower_file; -+ -+ lower_file = sdcardfs_lower_file(file); -+ if (!lower_file->f_op->read_iter) { -+ err = -EINVAL; -+ goto out; -+ } -+ -+ get_file(lower_file); /* prevent lower_file from being released */ -+ iocb->ki_filp = lower_file; -+ err = lower_file->f_op->read_iter(iocb, iter); -+ iocb->ki_filp = file; -+ fput(lower_file); -+ /* update upper inode atime as needed */ -+ if (err >= 0 || err == -EIOCBQUEUED) -+ fsstack_copy_attr_atime(file->f_path.dentry->d_inode, -+ file_inode(lower_file)); -+out: -+ return err; -+} -+ -+/* -+ * Sdcardfs write_iter, redirect modified iocb to lower write_iter -+ */ -+ssize_t sdcardfs_write_iter(struct kiocb *iocb, struct iov_iter *iter) -+{ -+ int err; -+ struct file *file = iocb->ki_filp, *lower_file; -+ struct inode *inode = file->f_path.dentry->d_inode; -+ -+ lower_file = sdcardfs_lower_file(file); -+ if (!lower_file->f_op->write_iter) { -+ err = -EINVAL; -+ goto out; -+ } -+ -+ get_file(lower_file); /* prevent lower_file from being released */ -+ iocb->ki_filp = lower_file; -+ err = lower_file->f_op->write_iter(iocb, iter); -+ iocb->ki_filp = file; -+ fput(lower_file); -+ /* update upper inode times/sizes as needed */ -+ if (err >= 0 || err == -EIOCBQUEUED) { -+ if (sizeof(loff_t) > sizeof(long)) -+ inode_lock(inode); -+ fsstack_copy_inode_size(inode, file_inode(lower_file)); -+ fsstack_copy_attr_times(inode, file_inode(lower_file)); -+ if (sizeof(loff_t) > sizeof(long)) -+ inode_unlock(inode); -+ } -+out: -+ return err; -+} -+ -+const struct file_operations sdcardfs_main_fops = { -+ .llseek = generic_file_llseek, -+ .read = sdcardfs_read, -+ .write = sdcardfs_write, -+ .unlocked_ioctl = sdcardfs_unlocked_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = sdcardfs_compat_ioctl, -+#endif -+ .mmap = sdcardfs_mmap, -+ .open = sdcardfs_open, -+ .flush = sdcardfs_flush, -+ .release = sdcardfs_file_release, -+ .fsync = sdcardfs_fsync, -+ .fasync = sdcardfs_fasync, -+ .read_iter = sdcardfs_read_iter, -+ .write_iter = sdcardfs_write_iter, -+}; -+ -+/* trimmed directory options */ -+const struct file_operations sdcardfs_dir_fops = { -+ .llseek = sdcardfs_file_llseek, -+ .read = generic_read_dir, -+ .iterate = sdcardfs_readdir, -+ .unlocked_ioctl = sdcardfs_unlocked_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = sdcardfs_compat_ioctl, -+#endif -+ .open = sdcardfs_open, -+ .release = sdcardfs_file_release, -+ .flush = sdcardfs_flush, -+ .fsync = sdcardfs_fsync, -+ .fasync = sdcardfs_fasync, -+}; -diff --git a/fs/sdcardfs/inode.c b/fs/sdcardfs/inode.c -new file mode 100644 -index 000000000000..4dd681e0d59d ---- /dev/null -+++ b/fs/sdcardfs/inode.c -@@ -0,0 +1,821 @@ -+/* -+ * fs/sdcardfs/inode.c -+ * -+ * Copyright (c) 2013 Samsung Electronics Co. Ltd -+ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, -+ * Sunghwan Yun, Sungjong Seo -+ * -+ * This program has been developed as a stackable file system based on -+ * the WrapFS which written by -+ * -+ * Copyright (c) 1998-2011 Erez Zadok -+ * Copyright (c) 2009 Shrikar Archak -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * This file is dual licensed. It may be redistributed and/or modified -+ * under the terms of the Apache 2.0 License OR version 2 of the GNU -+ * General Public License. -+ */ -+ -+#include "sdcardfs.h" -+#include -+#include -+#include -+ -+const struct cred *override_fsids(struct sdcardfs_sb_info *sbi, -+ struct sdcardfs_inode_data *data) -+{ -+ struct cred *cred; -+ const struct cred *old_cred; -+ uid_t uid; -+ -+ cred = prepare_creds(); -+ if (!cred) -+ return NULL; -+ -+ if (sbi->options.gid_derivation) { -+ if (data->under_obb) -+ uid = AID_MEDIA_OBB; -+ else -+ uid = multiuser_get_uid(data->userid, sbi->options.fs_low_uid); -+ } else { -+ uid = sbi->options.fs_low_uid; -+ } -+ cred->fsuid = make_kuid(&init_user_ns, uid); -+ cred->fsgid = make_kgid(&init_user_ns, sbi->options.fs_low_gid); -+ -+ old_cred = override_creds(cred); -+ -+ return old_cred; -+} -+ -+void revert_fsids(const struct cred *old_cred) -+{ -+ const struct cred *cur_cred; -+ -+ cur_cred = current->cred; -+ revert_creds(old_cred); -+ put_cred(cur_cred); -+} -+ -+static int sdcardfs_create(struct inode *dir, struct dentry *dentry, -+ umode_t mode, bool want_excl) -+{ -+ int err; -+ struct dentry *lower_dentry; -+ struct vfsmount *lower_dentry_mnt; -+ struct dentry *lower_parent_dentry = NULL; -+ struct path lower_path; -+ const struct cred *saved_cred = NULL; -+ struct fs_struct *saved_fs; -+ struct fs_struct *copied_fs; -+ -+ if (!check_caller_access_to_name(dir, &dentry->d_name)) { -+ err = -EACCES; -+ goto out_eacces; -+ } -+ -+ /* save current_cred and override it */ -+ saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb), -+ SDCARDFS_I(dir)->data); -+ if (!saved_cred) -+ return -ENOMEM; -+ -+ sdcardfs_get_lower_path(dentry, &lower_path); -+ lower_dentry = lower_path.dentry; -+ lower_dentry_mnt = lower_path.mnt; -+ lower_parent_dentry = lock_parent(lower_dentry); -+ -+ /* set last 16bytes of mode field to 0664 */ -+ mode = (mode & S_IFMT) | 00664; -+ -+ /* temporarily change umask for lower fs write */ -+ saved_fs = current->fs; -+ copied_fs = copy_fs_struct(current->fs); -+ if (!copied_fs) { -+ err = -ENOMEM; -+ goto out_unlock; -+ } -+ copied_fs->umask = 0; -+ task_lock(current); -+ current->fs = copied_fs; -+ task_unlock(current); -+ -+ err = vfs_create2(lower_dentry_mnt, d_inode(lower_parent_dentry), lower_dentry, mode, want_excl); -+ if (err) -+ goto out; -+ -+ err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path, -+ SDCARDFS_I(dir)->data->userid); -+ if (err) -+ goto out; -+ fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir)); -+ fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry)); -+ fixup_lower_ownership(dentry, dentry->d_name.name); -+ -+out: -+ task_lock(current); -+ current->fs = saved_fs; -+ task_unlock(current); -+ free_fs_struct(copied_fs); -+out_unlock: -+ unlock_dir(lower_parent_dentry); -+ sdcardfs_put_lower_path(dentry, &lower_path); -+ revert_fsids(saved_cred); -+out_eacces: -+ return err; -+} -+ -+static int sdcardfs_unlink(struct inode *dir, struct dentry *dentry) -+{ -+ int err; -+ struct dentry *lower_dentry; -+ struct vfsmount *lower_mnt; -+ struct inode *lower_dir_inode = sdcardfs_lower_inode(dir); -+ struct dentry *lower_dir_dentry; -+ struct path lower_path; -+ const struct cred *saved_cred = NULL; -+ -+ if (!check_caller_access_to_name(dir, &dentry->d_name)) { -+ err = -EACCES; -+ goto out_eacces; -+ } -+ -+ /* save current_cred and override it */ -+ saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb), -+ SDCARDFS_I(dir)->data); -+ if (!saved_cred) -+ return -ENOMEM; -+ -+ sdcardfs_get_lower_path(dentry, &lower_path); -+ lower_dentry = lower_path.dentry; -+ lower_mnt = lower_path.mnt; -+ dget(lower_dentry); -+ lower_dir_dentry = lock_parent(lower_dentry); -+ -+ err = vfs_unlink2(lower_mnt, lower_dir_inode, lower_dentry, NULL); -+ -+ /* -+ * Note: unlinking on top of NFS can cause silly-renamed files. -+ * Trying to delete such files results in EBUSY from NFS -+ * below. Silly-renamed files will get deleted by NFS later on, so -+ * we just need to detect them here and treat such EBUSY errors as -+ * if the upper file was successfully deleted. -+ */ -+ if (err == -EBUSY && lower_dentry->d_flags & DCACHE_NFSFS_RENAMED) -+ err = 0; -+ if (err) -+ goto out; -+ fsstack_copy_attr_times(dir, lower_dir_inode); -+ fsstack_copy_inode_size(dir, lower_dir_inode); -+ set_nlink(d_inode(dentry), -+ sdcardfs_lower_inode(d_inode(dentry))->i_nlink); -+ d_inode(dentry)->i_ctime = dir->i_ctime; -+ d_drop(dentry); /* this is needed, else LTP fails (VFS won't do it) */ -+out: -+ unlock_dir(lower_dir_dentry); -+ dput(lower_dentry); -+ sdcardfs_put_lower_path(dentry, &lower_path); -+ revert_fsids(saved_cred); -+out_eacces: -+ return err; -+} -+ -+static int touch(char *abs_path, mode_t mode) -+{ -+ struct file *filp = filp_open(abs_path, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, mode); -+ -+ if (IS_ERR(filp)) { -+ if (PTR_ERR(filp) == -EEXIST) { -+ return 0; -+ } else { -+ pr_err("sdcardfs: failed to open(%s): %ld\n", -+ abs_path, PTR_ERR(filp)); -+ return PTR_ERR(filp); -+ } -+ } -+ filp_close(filp, current->files); -+ return 0; -+} -+ -+static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) -+{ -+ int err; -+ int make_nomedia_in_obb = 0; -+ struct dentry *lower_dentry; -+ struct vfsmount *lower_mnt; -+ struct dentry *lower_parent_dentry = NULL; -+ struct dentry *parent_dentry = NULL; -+ struct path lower_path; -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); -+ const struct cred *saved_cred = NULL; -+ struct sdcardfs_inode_data *pd = SDCARDFS_I(dir)->data; -+ int touch_err = 0; -+ struct fs_struct *saved_fs; -+ struct fs_struct *copied_fs; -+ struct qstr q_obb = QSTR_LITERAL("obb"); -+ struct qstr q_data = QSTR_LITERAL("data"); -+ -+ if (!check_caller_access_to_name(dir, &dentry->d_name)) { -+ err = -EACCES; -+ goto out_eacces; -+ } -+ -+ /* save current_cred and override it */ -+ saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb), -+ SDCARDFS_I(dir)->data); -+ if (!saved_cred) -+ return -ENOMEM; -+ -+ /* check disk space */ -+ parent_dentry = dget_parent(dentry); -+ if (!check_min_free_space(parent_dentry, 0, 1)) { -+ pr_err("sdcardfs: No minimum free space.\n"); -+ err = -ENOSPC; -+ dput(parent_dentry); -+ goto out_revert; -+ } -+ dput(parent_dentry); -+ -+ /* the lower_dentry is negative here */ -+ sdcardfs_get_lower_path(dentry, &lower_path); -+ lower_dentry = lower_path.dentry; -+ lower_mnt = lower_path.mnt; -+ lower_parent_dentry = lock_parent(lower_dentry); -+ -+ /* set last 16bytes of mode field to 0775 */ -+ mode = (mode & S_IFMT) | 00775; -+ -+ /* temporarily change umask for lower fs write */ -+ saved_fs = current->fs; -+ copied_fs = copy_fs_struct(current->fs); -+ if (!copied_fs) { -+ err = -ENOMEM; -+ unlock_dir(lower_parent_dentry); -+ goto out_unlock; -+ } -+ copied_fs->umask = 0; -+ task_lock(current); -+ current->fs = copied_fs; -+ task_unlock(current); -+ -+ err = vfs_mkdir2(lower_mnt, d_inode(lower_parent_dentry), lower_dentry, mode); -+ -+ if (err) { -+ unlock_dir(lower_parent_dentry); -+ goto out; -+ } -+ -+ /* if it is a local obb dentry, setup it with the base obbpath */ -+ if (need_graft_path(dentry)) { -+ -+ err = setup_obb_dentry(dentry, &lower_path); -+ if (err) { -+ /* if the sbi->obbpath is not available, the lower_path won't be -+ * changed by setup_obb_dentry() but the lower path is saved to -+ * its orig_path. this dentry will be revalidated later. -+ * but now, the lower_path should be NULL -+ */ -+ sdcardfs_put_reset_lower_path(dentry); -+ -+ /* the newly created lower path which saved to its orig_path or -+ * the lower_path is the base obbpath. -+ * therefore, an additional path_get is required -+ */ -+ path_get(&lower_path); -+ } else -+ make_nomedia_in_obb = 1; -+ } -+ -+ err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path, pd->userid); -+ if (err) { -+ unlock_dir(lower_parent_dentry); -+ goto out; -+ } -+ -+ fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir)); -+ fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry)); -+ /* update number of links on parent directory */ -+ set_nlink(dir, sdcardfs_lower_inode(dir)->i_nlink); -+ fixup_lower_ownership(dentry, dentry->d_name.name); -+ unlock_dir(lower_parent_dentry); -+ if ((!sbi->options.multiuser) && (qstr_case_eq(&dentry->d_name, &q_obb)) -+ && (pd->perm == PERM_ANDROID) && (pd->userid == 0)) -+ make_nomedia_in_obb = 1; -+ -+ /* When creating /Android/data and /Android/obb, mark them as .nomedia */ -+ if (make_nomedia_in_obb || -+ ((pd->perm == PERM_ANDROID) -+ && (qstr_case_eq(&dentry->d_name, &q_data)))) { -+ revert_fsids(saved_cred); -+ saved_cred = override_fsids(sbi, -+ SDCARDFS_I(d_inode(dentry))->data); -+ if (!saved_cred) { -+ pr_err("sdcardfs: failed to set up .nomedia in %s: %d\n", -+ lower_path.dentry->d_name.name, -+ -ENOMEM); -+ goto out; -+ } -+ set_fs_pwd(current->fs, &lower_path); -+ touch_err = touch(".nomedia", 0664); -+ if (touch_err) { -+ pr_err("sdcardfs: failed to create .nomedia in %s: %d\n", -+ lower_path.dentry->d_name.name, -+ touch_err); -+ goto out; -+ } -+ } -+out: -+ task_lock(current); -+ current->fs = saved_fs; -+ task_unlock(current); -+ -+ free_fs_struct(copied_fs); -+out_unlock: -+ sdcardfs_put_lower_path(dentry, &lower_path); -+out_revert: -+ revert_fsids(saved_cred); -+out_eacces: -+ return err; -+} -+ -+static int sdcardfs_rmdir(struct inode *dir, struct dentry *dentry) -+{ -+ struct dentry *lower_dentry; -+ struct dentry *lower_dir_dentry; -+ struct vfsmount *lower_mnt; -+ int err; -+ struct path lower_path; -+ const struct cred *saved_cred = NULL; -+ -+ if (!check_caller_access_to_name(dir, &dentry->d_name)) { -+ err = -EACCES; -+ goto out_eacces; -+ } -+ -+ /* save current_cred and override it */ -+ saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb), -+ SDCARDFS_I(dir)->data); -+ if (!saved_cred) -+ return -ENOMEM; -+ -+ /* sdcardfs_get_real_lower(): in case of remove an user's obb dentry -+ * the dentry on the original path should be deleted. -+ */ -+ sdcardfs_get_real_lower(dentry, &lower_path); -+ -+ lower_dentry = lower_path.dentry; -+ lower_mnt = lower_path.mnt; -+ lower_dir_dentry = lock_parent(lower_dentry); -+ -+ err = vfs_rmdir2(lower_mnt, d_inode(lower_dir_dentry), lower_dentry); -+ if (err) -+ goto out; -+ -+ d_drop(dentry); /* drop our dentry on success (why not VFS's job?) */ -+ if (d_inode(dentry)) -+ clear_nlink(d_inode(dentry)); -+ fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); -+ fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry)); -+ set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink); -+ -+out: -+ unlock_dir(lower_dir_dentry); -+ sdcardfs_put_real_lower(dentry, &lower_path); -+ revert_fsids(saved_cred); -+out_eacces: -+ return err; -+} -+ -+/* -+ * The locking rules in sdcardfs_rename are complex. We could use a simpler -+ * superblock-level name-space lock for renames and copy-ups. -+ */ -+static int sdcardfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry, -+ unsigned int flags) -+{ -+ int err = 0; -+ struct dentry *lower_old_dentry = NULL; -+ struct dentry *lower_new_dentry = NULL; -+ struct dentry *lower_old_dir_dentry = NULL; -+ struct dentry *lower_new_dir_dentry = NULL; -+ struct vfsmount *lower_mnt = NULL; -+ struct dentry *trap = NULL; -+ struct path lower_old_path, lower_new_path; -+ const struct cred *saved_cred = NULL; -+ -+ if (flags) -+ return -EINVAL; -+ -+ if (!check_caller_access_to_name(old_dir, &old_dentry->d_name) || -+ !check_caller_access_to_name(new_dir, &new_dentry->d_name)) { -+ err = -EACCES; -+ goto out_eacces; -+ } -+ -+ /* save current_cred and override it */ -+ saved_cred = override_fsids(SDCARDFS_SB(old_dir->i_sb), -+ SDCARDFS_I(new_dir)->data); -+ if (!saved_cred) -+ return -ENOMEM; -+ -+ sdcardfs_get_real_lower(old_dentry, &lower_old_path); -+ sdcardfs_get_lower_path(new_dentry, &lower_new_path); -+ lower_old_dentry = lower_old_path.dentry; -+ lower_new_dentry = lower_new_path.dentry; -+ lower_mnt = lower_old_path.mnt; -+ lower_old_dir_dentry = dget_parent(lower_old_dentry); -+ lower_new_dir_dentry = dget_parent(lower_new_dentry); -+ -+ trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); -+ /* source should not be ancestor of target */ -+ if (trap == lower_old_dentry) { -+ err = -EINVAL; -+ goto out; -+ } -+ /* target should not be ancestor of source */ -+ if (trap == lower_new_dentry) { -+ err = -ENOTEMPTY; -+ goto out; -+ } -+ -+ err = vfs_rename2(lower_mnt, -+ d_inode(lower_old_dir_dentry), lower_old_dentry, -+ d_inode(lower_new_dir_dentry), lower_new_dentry, -+ NULL, 0); -+ if (err) -+ goto out; -+ -+ /* Copy attrs from lower dir, but i_uid/i_gid */ -+ sdcardfs_copy_and_fix_attrs(new_dir, d_inode(lower_new_dir_dentry)); -+ fsstack_copy_inode_size(new_dir, d_inode(lower_new_dir_dentry)); -+ -+ if (new_dir != old_dir) { -+ sdcardfs_copy_and_fix_attrs(old_dir, d_inode(lower_old_dir_dentry)); -+ fsstack_copy_inode_size(old_dir, d_inode(lower_old_dir_dentry)); -+ } -+ get_derived_permission_new(new_dentry->d_parent, old_dentry, &new_dentry->d_name); -+ fixup_tmp_permissions(d_inode(old_dentry)); -+ fixup_lower_ownership(old_dentry, new_dentry->d_name.name); -+ d_invalidate(old_dentry); /* Can't fixup ownership recursively :( */ -+out: -+ unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); -+ dput(lower_old_dir_dentry); -+ dput(lower_new_dir_dentry); -+ sdcardfs_put_real_lower(old_dentry, &lower_old_path); -+ sdcardfs_put_lower_path(new_dentry, &lower_new_path); -+ revert_fsids(saved_cred); -+out_eacces: -+ return err; -+} -+ -+#if 0 -+static int sdcardfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) -+{ -+ int err; -+ struct dentry *lower_dentry; -+ struct path lower_path; -+ /* XXX readlink does not requires overriding credential */ -+ -+ sdcardfs_get_lower_path(dentry, &lower_path); -+ lower_dentry = lower_path.dentry; -+ if (!d_inode(lower_dentry)->i_op || -+ !d_inode(lower_dentry)->i_op->readlink) { -+ err = -EINVAL; -+ goto out; -+ } -+ -+ err = d_inode(lower_dentry)->i_op->readlink(lower_dentry, -+ buf, bufsiz); -+ if (err < 0) -+ goto out; -+ fsstack_copy_attr_atime(d_inode(dentry), d_inode(lower_dentry)); -+ -+out: -+ sdcardfs_put_lower_path(dentry, &lower_path); -+ return err; -+} -+#endif -+ -+#if 0 -+static const char *sdcardfs_follow_link(struct dentry *dentry, void **cookie) -+{ -+ char *buf; -+ int len = PAGE_SIZE, err; -+ mm_segment_t old_fs; -+ -+ /* This is freed by the put_link method assuming a successful call. */ -+ buf = kmalloc(len, GFP_KERNEL); -+ if (!buf) { -+ buf = ERR_PTR(-ENOMEM); -+ return buf; -+ } -+ -+ /* read the symlink, and then we will follow it */ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = sdcardfs_readlink(dentry, buf, len); -+ set_fs(old_fs); -+ if (err < 0) { -+ kfree(buf); -+ buf = ERR_PTR(err); -+ } else { -+ buf[err] = '\0'; -+ } -+ return *cookie = buf; -+} -+#endif -+ -+static int sdcardfs_permission_wrn(struct inode *inode, int mask) -+{ -+ WARN_RATELIMIT(1, "sdcardfs does not support permission. Use permission2.\n"); -+ return -EINVAL; -+} -+ -+void copy_attrs(struct inode *dest, const struct inode *src) -+{ -+ dest->i_mode = src->i_mode; -+ dest->i_uid = src->i_uid; -+ dest->i_gid = src->i_gid; -+ dest->i_rdev = src->i_rdev; -+ dest->i_atime = src->i_atime; -+ dest->i_mtime = src->i_mtime; -+ dest->i_ctime = src->i_ctime; -+ dest->i_blkbits = src->i_blkbits; -+ dest->i_flags = src->i_flags; -+#ifdef CONFIG_FS_POSIX_ACL -+ dest->i_acl = src->i_acl; -+#endif -+#ifdef CONFIG_SECURITY -+ dest->i_security = src->i_security; -+#endif -+} -+ -+static int sdcardfs_permission(struct vfsmount *mnt, struct inode *inode, int mask) -+{ -+ int err; -+ struct inode tmp; -+ struct sdcardfs_inode_data *top = top_data_get(SDCARDFS_I(inode)); -+ -+ if (IS_ERR(mnt)) -+ return PTR_ERR(mnt); -+ -+ if (!top) -+ return -EINVAL; -+ -+ /* -+ * Permission check on sdcardfs inode. -+ * Calling process should have AID_SDCARD_RW permission -+ * Since generic_permission only needs i_mode, i_uid, -+ * i_gid, and i_sb, we can create a fake inode to pass -+ * this information down in. -+ * -+ * The underlying code may attempt to take locks in some -+ * cases for features we're not using, but if that changes, -+ * locks must be dealt with to avoid undefined behavior. -+ */ -+ copy_attrs(&tmp, inode); -+ tmp.i_uid = make_kuid(&init_user_ns, top->d_uid); -+ tmp.i_gid = make_kgid(&init_user_ns, get_gid(mnt, inode->i_sb, top)); -+ tmp.i_mode = (inode->i_mode & S_IFMT) -+ | get_mode(mnt, SDCARDFS_I(inode), top); -+ data_put(top); -+ tmp.i_sb = inode->i_sb; -+ if (IS_POSIXACL(inode)) -+ pr_warn("%s: This may be undefined behavior...\n", __func__); -+ err = generic_permission(&tmp, mask); -+ return err; -+} -+ -+static int sdcardfs_setattr_wrn(struct dentry *dentry, struct iattr *ia) -+{ -+ WARN_RATELIMIT(1, "sdcardfs does not support setattr. User setattr2.\n"); -+ return -EINVAL; -+} -+ -+static int sdcardfs_setattr(struct vfsmount *mnt, struct dentry *dentry, struct iattr *ia) -+{ -+ int err; -+ struct dentry *lower_dentry; -+ struct vfsmount *lower_mnt; -+ struct inode *inode; -+ struct inode *lower_inode; -+ struct path lower_path; -+ struct iattr lower_ia; -+ struct dentry *parent; -+ struct inode tmp; -+ struct dentry tmp_d; -+ struct sdcardfs_inode_data *top; -+ -+ const struct cred *saved_cred = NULL; -+ -+ inode = d_inode(dentry); -+ top = top_data_get(SDCARDFS_I(inode)); -+ -+ if (!top) -+ return -EINVAL; -+ -+ /* -+ * Permission check on sdcardfs inode. -+ * Calling process should have AID_SDCARD_RW permission -+ * Since generic_permission only needs i_mode, i_uid, -+ * i_gid, and i_sb, we can create a fake inode to pass -+ * this information down in. -+ * -+ * The underlying code may attempt to take locks in some -+ * cases for features we're not using, but if that changes, -+ * locks must be dealt with to avoid undefined behavior. -+ * -+ */ -+ copy_attrs(&tmp, inode); -+ tmp.i_uid = make_kuid(&init_user_ns, top->d_uid); -+ tmp.i_gid = make_kgid(&init_user_ns, get_gid(mnt, dentry->d_sb, top)); -+ tmp.i_mode = (inode->i_mode & S_IFMT) -+ | get_mode(mnt, SDCARDFS_I(inode), top); -+ tmp.i_size = i_size_read(inode); -+ data_put(top); -+ tmp.i_sb = inode->i_sb; -+ tmp_d.d_inode = &tmp; -+ -+ /* -+ * Check if user has permission to change dentry. We don't check if -+ * this user can change the lower inode: that should happen when -+ * calling notify_change on the lower inode. -+ */ -+ /* prepare our own lower struct iattr (with the lower file) */ -+ memcpy(&lower_ia, ia, sizeof(lower_ia)); -+ /* Allow touch updating timestamps. A previous permission check ensures -+ * we have write access. Changes to mode, owner, and group are ignored -+ */ -+ ia->ia_valid |= ATTR_FORCE; -+ err = setattr_prepare(&tmp_d, ia); -+ -+ if (!err) { -+ /* check the Android group ID */ -+ parent = dget_parent(dentry); -+ if (!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) -+ err = -EACCES; -+ dput(parent); -+ } -+ -+ if (err) -+ goto out_err; -+ -+ /* save current_cred and override it */ -+ saved_cred = override_fsids(SDCARDFS_SB(dentry->d_sb), -+ SDCARDFS_I(inode)->data); -+ if (!saved_cred) -+ return -ENOMEM; -+ -+ sdcardfs_get_lower_path(dentry, &lower_path); -+ lower_dentry = lower_path.dentry; -+ lower_mnt = lower_path.mnt; -+ lower_inode = sdcardfs_lower_inode(inode); -+ -+ if (ia->ia_valid & ATTR_FILE) -+ lower_ia.ia_file = sdcardfs_lower_file(ia->ia_file); -+ -+ lower_ia.ia_valid &= ~(ATTR_UID | ATTR_GID | ATTR_MODE); -+ -+ /* -+ * If shrinking, first truncate upper level to cancel writing dirty -+ * pages beyond the new eof; and also if its' maxbytes is more -+ * limiting (fail with -EFBIG before making any change to the lower -+ * level). There is no need to vmtruncate the upper level -+ * afterwards in the other cases: we fsstack_copy_inode_size from -+ * the lower level. -+ */ -+ if (ia->ia_valid & ATTR_SIZE) { -+ err = inode_newsize_ok(&tmp, ia->ia_size); -+ if (err) { -+ goto out; -+ } -+ truncate_setsize(inode, ia->ia_size); -+ } -+ -+ /* -+ * mode change is for clearing setuid/setgid bits. Allow lower fs -+ * to interpret this in its own way. -+ */ -+ if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) -+ lower_ia.ia_valid &= ~ATTR_MODE; -+ -+ /* notify the (possibly copied-up) lower inode */ -+ /* -+ * Note: we use d_inode(lower_dentry), because lower_inode may be -+ * unlinked (no inode->i_sb and i_ino==0. This happens if someone -+ * tries to open(), unlink(), then ftruncate() a file. -+ */ -+ inode_lock(d_inode(lower_dentry)); -+ err = notify_change2(lower_mnt, lower_dentry, &lower_ia, /* note: lower_ia */ -+ NULL); -+ inode_unlock(d_inode(lower_dentry)); -+ if (err) -+ goto out; -+ -+ /* get attributes from the lower inode and update derived permissions */ -+ sdcardfs_copy_and_fix_attrs(inode, lower_inode); -+ -+ /* -+ * Not running fsstack_copy_inode_size(inode, lower_inode), because -+ * VFS should update our inode size, and notify_change on -+ * lower_inode should update its size. -+ */ -+ -+out: -+ sdcardfs_put_lower_path(dentry, &lower_path); -+ revert_fsids(saved_cred); -+out_err: -+ return err; -+} -+ -+static int sdcardfs_fillattr(struct vfsmount *mnt, struct inode *inode, -+ struct kstat *lower_stat, struct kstat *stat) -+{ -+ struct sdcardfs_inode_info *info = SDCARDFS_I(inode); -+ struct sdcardfs_inode_data *top = top_data_get(info); -+ struct super_block *sb = inode->i_sb; -+ -+ if (!top) -+ return -EINVAL; -+ -+ stat->dev = inode->i_sb->s_dev; -+ stat->ino = inode->i_ino; -+ stat->mode = (inode->i_mode & S_IFMT) | get_mode(mnt, info, top); -+ stat->nlink = inode->i_nlink; -+ stat->uid = make_kuid(&init_user_ns, top->d_uid); -+ stat->gid = make_kgid(&init_user_ns, get_gid(mnt, sb, top)); -+ stat->rdev = inode->i_rdev; -+ stat->size = lower_stat->size; -+ stat->atime = lower_stat->atime; -+ stat->mtime = lower_stat->mtime; -+ stat->ctime = lower_stat->ctime; -+ stat->blksize = lower_stat->blksize; -+ stat->blocks = lower_stat->blocks; -+ data_put(top); -+ return 0; -+} -+static int sdcardfs_getattr(const struct path *path, struct kstat *stat, -+ u32 request_mask, unsigned int flags) -+{ -+ struct vfsmount *mnt = path->mnt; -+ struct dentry *dentry = path->dentry; -+ struct kstat lower_stat; -+ struct path lower_path; -+ struct dentry *parent; -+ int err; -+ -+ parent = dget_parent(dentry); -+ if (!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) { -+ dput(parent); -+ return -EACCES; -+ } -+ dput(parent); -+ -+ sdcardfs_get_lower_path(dentry, &lower_path); -+ err = vfs_getattr(&lower_path, &lower_stat, request_mask, flags); -+ if (err) -+ goto out; -+ sdcardfs_copy_and_fix_attrs(d_inode(dentry), -+ d_inode(lower_path.dentry)); -+ err = sdcardfs_fillattr(mnt, d_inode(dentry), &lower_stat, stat); -+out: -+ sdcardfs_put_lower_path(dentry, &lower_path); -+ return err; -+} -+ -+const struct inode_operations sdcardfs_symlink_iops = { -+ .permission2 = sdcardfs_permission, -+ .setattr2 = sdcardfs_setattr, -+ /* XXX Following operations are implemented, -+ * but FUSE(sdcard) or FAT does not support them -+ * These methods are *NOT* perfectly tested. -+ .readlink = sdcardfs_readlink, -+ .follow_link = sdcardfs_follow_link, -+ .put_link = kfree_put_link, -+ */ -+}; -+ -+const struct inode_operations sdcardfs_dir_iops = { -+ .create = sdcardfs_create, -+ .lookup = sdcardfs_lookup, -+ .permission = sdcardfs_permission_wrn, -+ .permission2 = sdcardfs_permission, -+ .unlink = sdcardfs_unlink, -+ .mkdir = sdcardfs_mkdir, -+ .rmdir = sdcardfs_rmdir, -+ .rename = sdcardfs_rename, -+ .setattr = sdcardfs_setattr_wrn, -+ .setattr2 = sdcardfs_setattr, -+ .getattr = sdcardfs_getattr, -+}; -+ -+const struct inode_operations sdcardfs_main_iops = { -+ .permission = sdcardfs_permission_wrn, -+ .permission2 = sdcardfs_permission, -+ .setattr = sdcardfs_setattr_wrn, -+ .setattr2 = sdcardfs_setattr, -+ .getattr = sdcardfs_getattr, -+}; -diff --git a/fs/sdcardfs/lookup.c b/fs/sdcardfs/lookup.c -new file mode 100644 -index 000000000000..a5c9686090e0 ---- /dev/null -+++ b/fs/sdcardfs/lookup.c -@@ -0,0 +1,470 @@ -+/* -+ * fs/sdcardfs/lookup.c -+ * -+ * Copyright (c) 2013 Samsung Electronics Co. Ltd -+ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, -+ * Sunghwan Yun, Sungjong Seo -+ * -+ * This program has been developed as a stackable file system based on -+ * the WrapFS which written by -+ * -+ * Copyright (c) 1998-2011 Erez Zadok -+ * Copyright (c) 2009 Shrikar Archak -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * This file is dual licensed. It may be redistributed and/or modified -+ * under the terms of the Apache 2.0 License OR version 2 of the GNU -+ * General Public License. -+ */ -+ -+#include "sdcardfs.h" -+#include "linux/delay.h" -+ -+/* The dentry cache is just so we have properly sized dentries */ -+static struct kmem_cache *sdcardfs_dentry_cachep; -+ -+int sdcardfs_init_dentry_cache(void) -+{ -+ sdcardfs_dentry_cachep = -+ kmem_cache_create("sdcardfs_dentry", -+ sizeof(struct sdcardfs_dentry_info), -+ 0, SLAB_RECLAIM_ACCOUNT, NULL); -+ -+ return sdcardfs_dentry_cachep ? 0 : -ENOMEM; -+} -+ -+void sdcardfs_destroy_dentry_cache(void) -+{ -+ kmem_cache_destroy(sdcardfs_dentry_cachep); -+} -+ -+void free_dentry_private_data(struct dentry *dentry) -+{ -+ kmem_cache_free(sdcardfs_dentry_cachep, dentry->d_fsdata); -+ dentry->d_fsdata = NULL; -+} -+ -+/* allocate new dentry private data */ -+int new_dentry_private_data(struct dentry *dentry) -+{ -+ struct sdcardfs_dentry_info *info = SDCARDFS_D(dentry); -+ -+ /* use zalloc to init dentry_info.lower_path */ -+ info = kmem_cache_zalloc(sdcardfs_dentry_cachep, GFP_ATOMIC); -+ if (!info) -+ return -ENOMEM; -+ -+ spin_lock_init(&info->lock); -+ dentry->d_fsdata = info; -+ -+ return 0; -+} -+ -+struct inode_data { -+ struct inode *lower_inode; -+ userid_t id; -+}; -+ -+static int sdcardfs_inode_test(struct inode *inode, void *candidate_data/*void *candidate_lower_inode*/) -+{ -+ struct inode *current_lower_inode = sdcardfs_lower_inode(inode); -+ userid_t current_userid = SDCARDFS_I(inode)->data->userid; -+ -+ if (current_lower_inode == ((struct inode_data *)candidate_data)->lower_inode && -+ current_userid == ((struct inode_data *)candidate_data)->id) -+ return 1; /* found a match */ -+ else -+ return 0; /* no match */ -+} -+ -+static int sdcardfs_inode_set(struct inode *inode, void *lower_inode) -+{ -+ /* we do actual inode initialization in sdcardfs_iget */ -+ return 0; -+} -+ -+struct inode *sdcardfs_iget(struct super_block *sb, struct inode *lower_inode, userid_t id) -+{ -+ struct sdcardfs_inode_info *info; -+ struct inode_data data; -+ struct inode *inode; /* the new inode to return */ -+ -+ if (!igrab(lower_inode)) -+ return ERR_PTR(-ESTALE); -+ -+ data.id = id; -+ data.lower_inode = lower_inode; -+ inode = iget5_locked(sb, /* our superblock */ -+ /* -+ * hashval: we use inode number, but we can -+ * also use "(unsigned long)lower_inode" -+ * instead. -+ */ -+ lower_inode->i_ino, /* hashval */ -+ sdcardfs_inode_test, /* inode comparison function */ -+ sdcardfs_inode_set, /* inode init function */ -+ &data); /* data passed to test+set fxns */ -+ if (!inode) { -+ iput(lower_inode); -+ return ERR_PTR(-ENOMEM); -+ } -+ /* if found a cached inode, then just return it (after iput) */ -+ if (!(inode->i_state & I_NEW)) { -+ iput(lower_inode); -+ return inode; -+ } -+ -+ /* initialize new inode */ -+ info = SDCARDFS_I(inode); -+ -+ inode->i_ino = lower_inode->i_ino; -+ sdcardfs_set_lower_inode(inode, lower_inode); -+ -+ inode_inc_iversion_raw(inode); -+ -+ /* use different set of inode ops for symlinks & directories */ -+ if (S_ISDIR(lower_inode->i_mode)) -+ inode->i_op = &sdcardfs_dir_iops; -+ else if (S_ISLNK(lower_inode->i_mode)) -+ inode->i_op = &sdcardfs_symlink_iops; -+ else -+ inode->i_op = &sdcardfs_main_iops; -+ -+ /* use different set of file ops for directories */ -+ if (S_ISDIR(lower_inode->i_mode)) -+ inode->i_fop = &sdcardfs_dir_fops; -+ else -+ inode->i_fop = &sdcardfs_main_fops; -+ -+ inode->i_mapping->a_ops = &sdcardfs_aops; -+ -+ inode->i_atime.tv_sec = 0; -+ inode->i_atime.tv_nsec = 0; -+ inode->i_mtime.tv_sec = 0; -+ inode->i_mtime.tv_nsec = 0; -+ inode->i_ctime.tv_sec = 0; -+ inode->i_ctime.tv_nsec = 0; -+ -+ /* properly initialize special inodes */ -+ if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) || -+ S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode)) -+ init_special_inode(inode, lower_inode->i_mode, -+ lower_inode->i_rdev); -+ -+ /* all well, copy inode attributes */ -+ sdcardfs_copy_and_fix_attrs(inode, lower_inode); -+ fsstack_copy_inode_size(inode, lower_inode); -+ -+ unlock_new_inode(inode); -+ return inode; -+} -+ -+/* -+ * Helper interpose routine, called directly by ->lookup to handle -+ * spliced dentries. -+ */ -+static struct dentry *__sdcardfs_interpose(struct dentry *dentry, -+ struct super_block *sb, -+ struct path *lower_path, -+ userid_t id) -+{ -+ struct inode *inode; -+ struct inode *lower_inode; -+ struct super_block *lower_sb; -+ struct dentry *ret_dentry; -+ -+ lower_inode = d_inode(lower_path->dentry); -+ lower_sb = sdcardfs_lower_super(sb); -+ -+ /* check that the lower file system didn't cross a mount point */ -+ if (lower_inode->i_sb != lower_sb) { -+ ret_dentry = ERR_PTR(-EXDEV); -+ goto out; -+ } -+ -+ /* -+ * We allocate our new inode below by calling sdcardfs_iget, -+ * which will initialize some of the new inode's fields -+ */ -+ -+ /* inherit lower inode number for sdcardfs's inode */ -+ inode = sdcardfs_iget(sb, lower_inode, id); -+ if (IS_ERR(inode)) { -+ ret_dentry = ERR_CAST(inode); -+ goto out; -+ } -+ -+ ret_dentry = d_splice_alias(inode, dentry); -+ dentry = ret_dentry ?: dentry; -+ if (!IS_ERR(dentry)) -+ update_derived_permission_lock(dentry); -+out: -+ return ret_dentry; -+} -+ -+/* -+ * Connect an sdcardfs inode dentry/inode with several lower ones. This is -+ * the classic stackable file system "vnode interposition" action. -+ * -+ * @dentry: sdcardfs's dentry which interposes on lower one -+ * @sb: sdcardfs's super_block -+ * @lower_path: the lower path (caller does path_get/put) -+ */ -+int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb, -+ struct path *lower_path, userid_t id) -+{ -+ struct dentry *ret_dentry; -+ -+ ret_dentry = __sdcardfs_interpose(dentry, sb, lower_path, id); -+ return PTR_ERR(ret_dentry); -+} -+ -+struct sdcardfs_name_data { -+ struct dir_context ctx; -+ const struct qstr *to_find; -+ char *name; -+ bool found; -+}; -+ -+static int sdcardfs_name_match(struct dir_context *ctx, const char *name, -+ int namelen, loff_t offset, u64 ino, unsigned int d_type) -+{ -+ struct sdcardfs_name_data *buf = container_of(ctx, struct sdcardfs_name_data, ctx); -+ struct qstr candidate = QSTR_INIT(name, namelen); -+ -+ if (qstr_case_eq(buf->to_find, &candidate)) { -+ memcpy(buf->name, name, namelen); -+ buf->name[namelen] = 0; -+ buf->found = true; -+ return 1; -+ } -+ return 0; -+} -+ -+/* -+ * Main driver function for sdcardfs's lookup. -+ * -+ * Returns: NULL (ok), ERR_PTR if an error occurred. -+ * Fills in lower_parent_path with on success. -+ */ -+static struct dentry *__sdcardfs_lookup(struct dentry *dentry, -+ unsigned int flags, struct path *lower_parent_path, userid_t id) -+{ -+ int err = 0; -+ struct vfsmount *lower_dir_mnt; -+ struct dentry *lower_dir_dentry = NULL; -+ struct dentry *lower_dentry; -+ const struct qstr *name; -+ struct path lower_path; -+ struct qstr dname; -+ struct dentry *ret_dentry = NULL; -+ struct sdcardfs_sb_info *sbi; -+ -+ sbi = SDCARDFS_SB(dentry->d_sb); -+ /* must initialize dentry operations */ -+ d_set_d_op(dentry, &sdcardfs_ci_dops); -+ -+ if (IS_ROOT(dentry)) -+ goto out; -+ -+ name = &dentry->d_name; -+ -+ /* now start the actual lookup procedure */ -+ lower_dir_dentry = lower_parent_path->dentry; -+ lower_dir_mnt = lower_parent_path->mnt; -+ -+ /* Use vfs_path_lookup to check if the dentry exists or not */ -+ err = vfs_path_lookup(lower_dir_dentry, lower_dir_mnt, name->name, 0, -+ &lower_path); -+ /* check for other cases */ -+ if (err == -ENOENT) { -+ struct file *file; -+ const struct cred *cred = current_cred(); -+ -+ struct sdcardfs_name_data buffer = { -+ .ctx.actor = sdcardfs_name_match, -+ .to_find = name, -+ .name = __getname(), -+ .found = false, -+ }; -+ -+ if (!buffer.name) { -+ err = -ENOMEM; -+ goto out; -+ } -+ file = dentry_open(lower_parent_path, O_RDONLY, cred); -+ if (IS_ERR(file)) { -+ err = PTR_ERR(file); -+ goto put_name; -+ } -+ err = iterate_dir(file, &buffer.ctx); -+ fput(file); -+ if (err) -+ goto put_name; -+ -+ if (buffer.found) -+ err = vfs_path_lookup(lower_dir_dentry, -+ lower_dir_mnt, -+ buffer.name, 0, -+ &lower_path); -+ else -+ err = -ENOENT; -+put_name: -+ __putname(buffer.name); -+ } -+ -+ /* no error: handle positive dentries */ -+ if (!err) { -+ /* check if the dentry is an obb dentry -+ * if true, the lower_inode must be replaced with -+ * the inode of the graft path -+ */ -+ -+ if (need_graft_path(dentry)) { -+ -+ /* setup_obb_dentry() -+ * The lower_path will be stored to the dentry's orig_path -+ * and the base obbpath will be copyed to the lower_path variable. -+ * if an error returned, there's no change in the lower_path -+ * returns: -ERRNO if error (0: no error) -+ */ -+ err = setup_obb_dentry(dentry, &lower_path); -+ -+ if (err) { -+ /* if the sbi->obbpath is not available, we can optionally -+ * setup the lower_path with its orig_path. -+ * but, the current implementation just returns an error -+ * because the sdcard daemon also regards this case as -+ * a lookup fail. -+ */ -+ pr_info("sdcardfs: base obbpath is not available\n"); -+ sdcardfs_put_reset_orig_path(dentry); -+ goto out; -+ } -+ } -+ -+ sdcardfs_set_lower_path(dentry, &lower_path); -+ ret_dentry = -+ __sdcardfs_interpose(dentry, dentry->d_sb, &lower_path, id); -+ if (IS_ERR(ret_dentry)) { -+ err = PTR_ERR(ret_dentry); -+ /* path_put underlying path on error */ -+ sdcardfs_put_reset_lower_path(dentry); -+ } -+ goto out; -+ } -+ -+ /* -+ * We don't consider ENOENT an error, and we want to return a -+ * negative dentry. -+ */ -+ if (err && err != -ENOENT) -+ goto out; -+ -+ /* instatiate a new negative dentry */ -+ dname.name = name->name; -+ dname.len = name->len; -+ -+ /* See if the low-level filesystem might want -+ * to use its own hash -+ */ -+ lower_dentry = d_hash_and_lookup(lower_dir_dentry, &dname); -+ if (IS_ERR(lower_dentry)) -+ return lower_dentry; -+ -+ if (!lower_dentry) { -+ /* We called vfs_path_lookup earlier, and did not get a negative -+ * dentry then. Don't confuse the lower filesystem by forcing -+ * one on it now... -+ */ -+ err = -ENOENT; -+ goto out; -+ } -+ -+ lower_path.dentry = lower_dentry; -+ lower_path.mnt = mntget(lower_dir_mnt); -+ sdcardfs_set_lower_path(dentry, &lower_path); -+ -+ /* -+ * If the intent is to create a file, then don't return an error, so -+ * the VFS will continue the process of making this negative dentry -+ * into a positive one. -+ */ -+ if (flags & (LOOKUP_CREATE|LOOKUP_RENAME_TARGET)) -+ err = 0; -+ -+out: -+ if (err) -+ return ERR_PTR(err); -+ return ret_dentry; -+} -+ -+/* -+ * On success: -+ * fills dentry object appropriate values and returns NULL. -+ * On fail (== error) -+ * returns error ptr -+ * -+ * @dir : Parent inode. -+ * @dentry : Target dentry to lookup. we should set each of fields. -+ * (dentry->d_name is initialized already) -+ * @nd : nameidata of parent inode -+ */ -+struct dentry *sdcardfs_lookup(struct inode *dir, struct dentry *dentry, -+ unsigned int flags) -+{ -+ struct dentry *ret = NULL, *parent; -+ struct path lower_parent_path; -+ int err = 0; -+ const struct cred *saved_cred = NULL; -+ -+ parent = dget_parent(dentry); -+ -+ if (!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) { -+ ret = ERR_PTR(-EACCES); -+ goto out_err; -+ } -+ -+ /* save current_cred and override it */ -+ saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb), -+ SDCARDFS_I(dir)->data); -+ if (!saved_cred) { -+ ret = ERR_PTR(-ENOMEM); -+ goto out_err; -+ } -+ -+ sdcardfs_get_lower_path(parent, &lower_parent_path); -+ -+ /* allocate dentry private data. We free it in ->d_release */ -+ err = new_dentry_private_data(dentry); -+ if (err) { -+ ret = ERR_PTR(err); -+ goto out; -+ } -+ -+ ret = __sdcardfs_lookup(dentry, flags, &lower_parent_path, -+ SDCARDFS_I(dir)->data->userid); -+ if (IS_ERR(ret)) -+ goto out; -+ if (ret) -+ dentry = ret; -+ if (d_inode(dentry)) { -+ fsstack_copy_attr_times(d_inode(dentry), -+ sdcardfs_lower_inode(d_inode(dentry))); -+ /* get derived permission */ -+ get_derived_permission(parent, dentry); -+ fixup_tmp_permissions(d_inode(dentry)); -+ fixup_lower_ownership(dentry, dentry->d_name.name); -+ } -+ /* update parent directory's atime */ -+ fsstack_copy_attr_atime(d_inode(parent), -+ sdcardfs_lower_inode(d_inode(parent))); -+ -+out: -+ sdcardfs_put_lower_path(parent, &lower_parent_path); -+ revert_fsids(saved_cred); -+out_err: -+ dput(parent); -+ return ret; -+} -diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c -new file mode 100644 -index 000000000000..b8e5cf2b9ae5 ---- /dev/null -+++ b/fs/sdcardfs/main.c -@@ -0,0 +1,454 @@ -+/* -+ * fs/sdcardfs/main.c -+ * -+ * Copyright (c) 2013 Samsung Electronics Co. Ltd -+ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, -+ * Sunghwan Yun, Sungjong Seo -+ * -+ * This program has been developed as a stackable file system based on -+ * the WrapFS which written by -+ * -+ * Copyright (c) 1998-2011 Erez Zadok -+ * Copyright (c) 2009 Shrikar Archak -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * This file is dual licensed. It may be redistributed and/or modified -+ * under the terms of the Apache 2.0 License OR version 2 of the GNU -+ * General Public License. -+ */ -+ -+#include "sdcardfs.h" -+#include -+#include -+#include -+#include -+#include -+ -+enum sdcardfs_param { -+ Opt_fsuid, -+ Opt_fsgid, -+ Opt_gid, -+ Opt_debug, -+ Opt_mask, -+ Opt_multiuser, -+ Opt_userid, -+ Opt_reserved_mb, -+ Opt_gid_derivation, -+ Opt_default_normal, -+ Opt_nocache, -+ Opt_unshared_obb, -+ Opt_err, -+}; -+ -+static const struct fs_parameter_spec sdcardfs_param_specs[] = { -+ fsparam_u32("fsuid", Opt_fsuid), -+ fsparam_u32("fsgid", Opt_fsgid), -+ fsparam_u32("gid", Opt_gid), -+ fsparam_bool("debug", Opt_debug), -+ fsparam_u32("mask", Opt_mask), -+ fsparam_u32("userid", Opt_userid), -+ fsparam_bool("multiuser", Opt_multiuser), -+ fsparam_bool("derive_gid", Opt_gid_derivation), -+ fsparam_bool("default_normal", Opt_default_normal), -+ fsparam_bool("unshared_obb", Opt_unshared_obb), -+ fsparam_u32("reserved_mb", Opt_reserved_mb), -+ fsparam_bool("nocache", Opt_nocache), -+ {} -+}; -+ -+static const struct fs_parameter_description sdcardfs_parameters = { -+ .name = "sdcardfs", -+ .specs = sdcardfs_param_specs, -+}; -+ -+static int sdcardfs_parse_param(struct fs_context *fc, struct fs_parameter *param) -+{ -+ struct sdcardfs_context_options *fc_opts = fc->fs_private; -+ struct sdcardfs_mount_options *opts = &fc_opts->opts; -+ struct sdcardfs_vfsmount_options *vfsopts = &fc_opts->vfsopts; -+ struct fs_parse_result result; -+ int opt; -+ -+ opt = fs_parse(fc, &sdcardfs_parameters, param, &result); -+ if (opt < 0) -+ return opt; -+ -+ switch (opt) { -+ case Opt_debug: -+ opts->debug = true; -+ case Opt_fsuid: -+ opts->fs_low_uid = result.uint_32; -+ break; -+ case Opt_fsgid: -+ opts->fs_low_gid = result.uint_32; -+ break; -+ case Opt_gid: -+ vfsopts->gid = result.uint_32; -+ break; -+ case Opt_userid: -+ opts->fs_user_id = result.uint_32; -+ break; -+ case Opt_mask: -+ vfsopts->mask = result.uint_32; -+ break; -+ case Opt_multiuser: -+ opts->multiuser = true; -+ break; -+ case Opt_reserved_mb: -+ opts->reserved_mb = result.uint_32; -+ break; -+ case Opt_gid_derivation: -+ opts->gid_derivation = true; -+ break; -+ case Opt_default_normal: -+ opts->default_normal = true; -+ break; -+ case Opt_nocache: -+ opts->nocache = true; -+ break; -+ case Opt_unshared_obb: -+ opts->unshared_obb = true; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static void copy_sb_opts(struct sdcardfs_mount_options *opts, -+ struct fs_context *fc) -+{ -+ struct sdcardfs_context_options *fcopts = fc->fs_private; -+ -+ opts->debug = fcopts->opts.debug; -+ opts->default_normal = fcopts->opts.default_normal; -+ opts->fs_low_gid = fcopts->opts.fs_low_gid; -+ opts->fs_low_uid = fcopts->opts.fs_low_uid; -+ opts->fs_user_id = fcopts->opts.fs_user_id; -+ opts->gid_derivation = fcopts->opts.gid_derivation; -+ opts->multiuser = fcopts->opts.multiuser; -+ opts->nocache = fcopts->opts.nocache; -+ opts->reserved_mb = fcopts->opts.reserved_mb; -+ opts->unshared_obb = fcopts->opts.unshared_obb; -+} -+ -+#if 0 -+/* -+ * our custom d_alloc_root work-alike -+ * -+ * we can't use d_alloc_root if we want to use our own interpose function -+ * unchanged, so we simply call our own "fake" d_alloc_root -+ */ -+static struct dentry *sdcardfs_d_alloc_root(struct super_block *sb) -+{ -+ struct dentry *ret = NULL; -+ -+ if (sb) { -+ static const struct qstr name = { -+ .name = "/", -+ .len = 1 -+ }; -+ -+ ret = d_alloc(NULL, &name); -+ if (ret) { -+ d_set_d_op(ret, &sdcardfs_ci_dops); -+ ret->d_sb = sb; -+ ret->d_parent = ret; -+ } -+ } -+ return ret; -+} -+#endif -+ -+DEFINE_MUTEX(sdcardfs_super_list_lock); -+EXPORT_SYMBOL_GPL(sdcardfs_super_list_lock); -+LIST_HEAD(sdcardfs_super_list); -+EXPORT_SYMBOL_GPL(sdcardfs_super_list); -+ -+struct sdcardfs_mount_private { -+ struct vfsmount *mnt; -+ const char *dev_name; -+ void *raw_data; -+}; -+ -+static int __sdcardfs_fill_super( -+ struct super_block *sb, -+ struct fs_context *fc) -+{ -+ int err = 0; -+ struct super_block *lower_sb; -+ struct path lower_path; -+ struct sdcardfs_sb_info *sb_info; -+ struct inode *inode; -+ const char *dev_name = fc->source; -+ struct sdcardfs_context_options *fcopts = fc->fs_private; -+ struct sdcardfs_mount_options *opts = &fcopts->opts; -+ struct sdcardfs_vfsmount_options *mntopts = &fcopts->vfsopts; -+ -+ pr_info("sdcardfs version 2.0\n"); -+ -+ if (!dev_name) { -+ pr_err("sdcardfs: read_super: missing dev_name argument\n"); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ pr_info("sdcardfs: dev_name -> %s\n", dev_name); -+ pr_info("sdcardfs: gid=%d,mask=%x\n", mntopts->gid, mntopts->mask); -+ -+ /* parse lower path */ -+ err = kern_path(dev_name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, -+ &lower_path); -+ if (err) { -+ pr_err("sdcardfs: error accessing lower directory '%s'\n", dev_name); -+ goto out; -+ } -+ -+ /* allocate superblock private data */ -+ sb->s_fs_info = kzalloc(sizeof(struct sdcardfs_sb_info), GFP_KERNEL); -+ if (!SDCARDFS_SB(sb)) { -+ pr_crit("sdcardfs: read_super: out of memory\n"); -+ err = -ENOMEM; -+ goto out_free; -+ } -+ -+ sb_info = sb->s_fs_info; -+ copy_sb_opts(&sb_info->options, fc); -+ if (opts->debug) { -+ pr_info("sdcardfs : options - debug:%d\n", opts->debug); -+ pr_info("sdcardfs : options - gid:%d\n", mntopts->gid); -+ pr_info("sdcardfs : options - mask:%d\n", mntopts->mask); -+ } -+ -+ /* set the lower superblock field of upper superblock */ -+ lower_sb = lower_path.dentry->d_sb; -+ atomic_inc(&lower_sb->s_active); -+ sdcardfs_set_lower_super(sb, lower_sb); -+ -+ sb->s_stack_depth = lower_sb->s_stack_depth + 1; -+ if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { -+ pr_err("sdcardfs: maximum fs stacking depth exceeded\n"); -+ err = -EINVAL; -+ goto out_sput; -+ } -+ -+ /* inherit maxbytes from lower file system */ -+ sb->s_maxbytes = lower_sb->s_maxbytes; -+ -+ /* -+ * Our c/m/atime granularity is 1 ns because we may stack on file -+ * systems whose granularity is as good. -+ */ -+ sb->s_time_gran = 1; -+ -+ sb->s_magic = SDCARDFS_SUPER_MAGIC; -+ sb->s_op = &sdcardfs_sops; -+ -+ /* get a new inode and allocate our root dentry */ -+ inode = sdcardfs_iget(sb, d_inode(lower_path.dentry), 0); -+ if (IS_ERR(inode)) { -+ err = PTR_ERR(inode); -+ goto out_sput; -+ } -+ sb->s_root = d_make_root(inode); -+ if (!sb->s_root) { -+ err = -ENOMEM; -+ goto out_sput; -+ } -+ d_set_d_op(sb->s_root, &sdcardfs_ci_dops); -+ -+ /* link the upper and lower dentries */ -+ sb->s_root->d_fsdata = NULL; -+ err = new_dentry_private_data(sb->s_root); -+ if (err) -+ goto out_freeroot; -+ -+ /* set the lower dentries for s_root */ -+ sdcardfs_set_lower_path(sb->s_root, &lower_path); -+ -+ /* -+ * No need to call interpose because we already have a positive -+ * dentry, which was instantiated by d_make_root. Just need to -+ * d_rehash it. -+ */ -+ d_rehash(sb->s_root); -+ -+ /* setup permission policy */ -+ sb_info->obbpath_s = kzalloc(PATH_MAX, GFP_KERNEL); -+ mutex_lock(&sdcardfs_super_list_lock); -+ if (sb_info->options.multiuser) { -+ setup_derived_state(d_inode(sb->s_root), PERM_PRE_ROOT, -+ sb_info->options.fs_user_id, AID_ROOT); -+ snprintf(sb_info->obbpath_s, PATH_MAX, "%s/obb", dev_name); -+ } else { -+ setup_derived_state(d_inode(sb->s_root), PERM_ROOT, -+ sb_info->options.fs_user_id, AID_ROOT); -+ snprintf(sb_info->obbpath_s, PATH_MAX, "%s/Android/obb", dev_name); -+ } -+ fixup_tmp_permissions(d_inode(sb->s_root)); -+ sb_info->sb = sb; -+ list_add(&sb_info->list, &sdcardfs_super_list); -+ mutex_unlock(&sdcardfs_super_list_lock); -+ -+ if (!(fc->sb_flags & SB_SILENT)) -+ pr_info("sdcardfs: mounted on top of %s type %s\n", -+ dev_name, lower_sb->s_type->name); -+ goto out; /* all is well */ -+ -+ /* no longer needed: free_dentry_private_data(sb->s_root); */ -+out_freeroot: -+ dput(sb->s_root); -+ sb->s_root = NULL; -+out_sput: -+ /* drop refs we took earlier */ -+ atomic_dec(&lower_sb->s_active); -+ kfree(SDCARDFS_SB(sb)); -+ sb->s_fs_info = NULL; -+out_free: -+ path_put(&lower_path); -+ -+out: -+ return err; -+} -+ -+static int sdcardfs_get_tree(struct fs_context *fc) -+{ -+ return vfs_get_super(fc, vfs_get_independent_super, -+ __sdcardfs_fill_super); -+} -+ -+void *sdcardfs_alloc_mnt_data(void) -+{ -+ return kmalloc(sizeof(struct sdcardfs_vfsmount_options), GFP_KERNEL); -+} -+ -+void sdcardfs_kill_sb(struct super_block *sb) -+{ -+ struct sdcardfs_sb_info *sbi; -+ -+ if (sb->s_magic == SDCARDFS_SUPER_MAGIC && sb->s_fs_info) { -+ sbi = SDCARDFS_SB(sb); -+ mutex_lock(&sdcardfs_super_list_lock); -+ list_del(&sbi->list); -+ mutex_unlock(&sdcardfs_super_list_lock); -+ } -+ kill_anon_super(sb); -+} -+ -+static void sdcardfs_free_fs_context(struct fs_context *fc) -+{ -+ struct sdcardfs_context_options *fc_opts = fc->fs_private; -+ -+ kfree(fc_opts); -+} -+ -+/* Most of the remount happens in sdcardfs_update_mnt_data */ -+static int sdcardfs_reconfigure_context(struct fs_context *fc) -+{ -+ struct sdcardfs_context_options *fc_opts = fc->fs_private; -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(fc->root->d_sb); -+ -+ sbi->options.debug = fc_opts->opts.debug; -+ if (sbi->options.debug) { -+ pr_info("sdcardfs : options - debug:%d\n", sbi->options.debug); -+ pr_info("sdcardfs : options - gid:%d\n", fc_opts->vfsopts.gid); -+ pr_info("sdcardfs : options - mask:%d\n", -+ fc_opts->vfsopts.mask); -+ } -+ return 0; -+} -+ -+/* reconfigure is handled by sdcardfs_update_mnt_data */ -+static const struct fs_context_operations sdcardfs_context_options_ops = { -+ -+ .parse_param = sdcardfs_parse_param, -+ .get_tree = sdcardfs_get_tree, -+ .free = sdcardfs_free_fs_context, -+ .reconfigure = sdcardfs_reconfigure_context, -+}; -+ -+static int sdcardfs_init_fs_context(struct fs_context *fc) -+{ -+ struct sdcardfs_context_options *fc_opts = -+ kmalloc(sizeof(struct sdcardfs_context_options), GFP_KERNEL); -+ -+ /* by default, we use AID_MEDIA_RW as uid, gid */ -+ fc_opts->opts.fs_low_uid = AID_MEDIA_RW; -+ fc_opts->opts.fs_low_gid = AID_MEDIA_RW; -+ fc_opts->opts.fs_user_id = 0; -+ fc_opts->vfsopts.gid = 0; -+ fc_opts->vfsopts.mask = 0; -+ -+ /* by default, 0MB is reserved */ -+ fc_opts->opts.reserved_mb = 0; -+ /* by default, gid derivation is off */ -+ fc_opts->opts.gid_derivation = false; -+ fc_opts->opts.default_normal = false; -+ fc_opts->opts.nocache = false; -+ fc_opts->opts.multiuser = false; -+ fc_opts->opts.debug = false; -+ -+ fc->fs_private = fc_opts; -+ fc->ops = &sdcardfs_context_options_ops; -+ return 0; -+} -+ -+static struct file_system_type sdcardfs_fs_type = { -+ .owner = THIS_MODULE, -+ .name = SDCARDFS_NAME, -+ .alloc_mnt_data = sdcardfs_alloc_mnt_data, -+ .kill_sb = sdcardfs_kill_sb, -+ .init_fs_context = sdcardfs_init_fs_context, -+ .fs_flags = 0, -+}; -+MODULE_ALIAS_FS(SDCARDFS_NAME); -+ -+static int __init init_sdcardfs_fs(void) -+{ -+ int err; -+ -+ pr_info("Registering sdcardfs " SDCARDFS_VERSION "\n"); -+ -+ err = sdcardfs_init_inode_cache(); -+ if (err) -+ goto out; -+ err = sdcardfs_init_dentry_cache(); -+ if (err) -+ goto out; -+ err = packagelist_init(); -+ if (err) -+ goto out; -+ err = register_filesystem(&sdcardfs_fs_type); -+out: -+ if (err) { -+ sdcardfs_destroy_inode_cache(); -+ sdcardfs_destroy_dentry_cache(); -+ packagelist_exit(); -+ } -+ return err; -+} -+ -+static void __exit exit_sdcardfs_fs(void) -+{ -+ sdcardfs_destroy_inode_cache(); -+ sdcardfs_destroy_dentry_cache(); -+ packagelist_exit(); -+ unregister_filesystem(&sdcardfs_fs_type); -+ pr_info("Completed sdcardfs module unload\n"); -+} -+ -+/* Original wrapfs authors */ -+MODULE_AUTHOR("Erez Zadok, Filesystems and Storage Lab, Stony Brook University (http://www.fsl.cs.sunysb.edu/)"); -+ -+/* Original sdcardfs authors */ -+MODULE_AUTHOR("Woojoong Lee, Daeho Jeong, Kitae Lee, Yeongjin Gil System Memory Lab., Samsung Electronics"); -+ -+/* Current maintainer */ -+MODULE_AUTHOR("Daniel Rosenberg, Google"); -+MODULE_DESCRIPTION("Sdcardfs " SDCARDFS_VERSION); -+MODULE_LICENSE("GPL"); -+ -+module_init(init_sdcardfs_fs); -+module_exit(exit_sdcardfs_fs); -diff --git a/fs/sdcardfs/mmap.c b/fs/sdcardfs/mmap.c -new file mode 100644 -index 000000000000..0ec0950c2447 ---- /dev/null -+++ b/fs/sdcardfs/mmap.c -@@ -0,0 +1,87 @@ -+/* -+ * fs/sdcardfs/mmap.c -+ * -+ * Copyright (c) 2013 Samsung Electronics Co. Ltd -+ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, -+ * Sunghwan Yun, Sungjong Seo -+ * -+ * This program has been developed as a stackable file system based on -+ * the WrapFS which written by -+ * -+ * Copyright (c) 1998-2011 Erez Zadok -+ * Copyright (c) 2009 Shrikar Archak -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * This file is dual licensed. It may be redistributed and/or modified -+ * under the terms of the Apache 2.0 License OR version 2 of the GNU -+ * General Public License. -+ */ -+ -+#include "sdcardfs.h" -+ -+static vm_fault_t sdcardfs_fault(struct vm_fault *vmf) -+{ -+ vm_fault_t err; -+ struct file *file; -+ const struct vm_operations_struct *lower_vm_ops; -+ -+ file = (struct file *)vmf->vma->vm_private_data; -+ lower_vm_ops = SDCARDFS_F(file)->lower_vm_ops; -+ BUG_ON(!lower_vm_ops); -+ -+ err = lower_vm_ops->fault(vmf); -+ return err; -+} -+ -+static void sdcardfs_vm_open(struct vm_area_struct *vma) -+{ -+ struct file *file = (struct file *)vma->vm_private_data; -+ -+ get_file(file); -+} -+ -+static void sdcardfs_vm_close(struct vm_area_struct *vma) -+{ -+ struct file *file = (struct file *)vma->vm_private_data; -+ -+ fput(file); -+} -+ -+static vm_fault_t sdcardfs_page_mkwrite(struct vm_fault *vmf) -+{ -+ vm_fault_t err = 0; -+ struct file *file; -+ const struct vm_operations_struct *lower_vm_ops; -+ -+ file = (struct file *)vmf->vma->vm_private_data; -+ lower_vm_ops = SDCARDFS_F(file)->lower_vm_ops; -+ BUG_ON(!lower_vm_ops); -+ if (!lower_vm_ops->page_mkwrite) -+ goto out; -+ -+ err = lower_vm_ops->page_mkwrite(vmf); -+out: -+ return err; -+} -+ -+static ssize_t sdcardfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) -+{ -+ /* -+ * This function should never be called directly. We need it -+ * to exist, to get past a check in open_check_o_direct(), -+ * which is called from do_last(). -+ */ -+ return -EINVAL; -+} -+ -+const struct address_space_operations sdcardfs_aops = { -+ .direct_IO = sdcardfs_direct_IO, -+}; -+ -+const struct vm_operations_struct sdcardfs_vm_ops = { -+ .fault = sdcardfs_fault, -+ .page_mkwrite = sdcardfs_page_mkwrite, -+ .open = sdcardfs_vm_open, -+ .close = sdcardfs_vm_close, -+}; -diff --git a/fs/sdcardfs/multiuser.h b/fs/sdcardfs/multiuser.h -new file mode 100644 -index 000000000000..85341e753f8c ---- /dev/null -+++ b/fs/sdcardfs/multiuser.h -@@ -0,0 +1,53 @@ -+/* -+ * fs/sdcardfs/multiuser.h -+ * -+ * Copyright (c) 2013 Samsung Electronics Co. Ltd -+ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, -+ * Sunghwan Yun, Sungjong Seo -+ * -+ * This program has been developed as a stackable file system based on -+ * the WrapFS which written by -+ * -+ * Copyright (c) 1998-2011 Erez Zadok -+ * Copyright (c) 2009 Shrikar Archak -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * This file is dual licensed. It may be redistributed and/or modified -+ * under the terms of the Apache 2.0 License OR version 2 of the GNU -+ * General Public License. -+ */ -+ -+#define AID_USER_OFFSET 100000 /* offset for uid ranges for each user */ -+#define AID_APP_START 10000 /* first app user */ -+#define AID_APP_END 19999 /* last app user */ -+#define AID_CACHE_GID_START 20000 /* start of gids for apps to mark cached data */ -+#define AID_EXT_GID_START 30000 /* start of gids for apps to mark external data */ -+#define AID_EXT_CACHE_GID_START 40000 /* start of gids for apps to mark external cached data */ -+#define AID_EXT_CACHE_GID_END 49999 /* end of gids for apps to mark external cached data */ -+#define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */ -+ -+typedef uid_t userid_t; -+typedef uid_t appid_t; -+ -+static inline uid_t multiuser_get_uid(userid_t user_id, appid_t app_id) -+{ -+ return (user_id * AID_USER_OFFSET) + (app_id % AID_USER_OFFSET); -+} -+ -+static inline bool uid_is_app(uid_t uid) -+{ -+ appid_t appid = uid % AID_USER_OFFSET; -+ -+ return appid >= AID_APP_START && appid <= AID_APP_END; -+} -+ -+static inline gid_t multiuser_get_ext_cache_gid(uid_t uid) -+{ -+ return uid - AID_APP_START + AID_EXT_CACHE_GID_START; -+} -+ -+static inline gid_t multiuser_get_ext_gid(uid_t uid) -+{ -+ return uid - AID_APP_START + AID_EXT_GID_START; -+} -diff --git a/fs/sdcardfs/packagelist.c b/fs/sdcardfs/packagelist.c -new file mode 100644 -index 000000000000..4b9a5635f1e0 ---- /dev/null -+++ b/fs/sdcardfs/packagelist.c -@@ -0,0 +1,882 @@ -+/* -+ * fs/sdcardfs/packagelist.c -+ * -+ * Copyright (c) 2013 Samsung Electronics Co. Ltd -+ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, -+ * Sunghwan Yun, Sungjong Seo -+ * -+ * This program has been developed as a stackable file system based on -+ * the WrapFS which written by -+ * -+ * Copyright (c) 1998-2011 Erez Zadok -+ * Copyright (c) 2009 Shrikar Archak -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * This file is dual licensed. It may be redistributed and/or modified -+ * under the terms of the Apache 2.0 License OR version 2 of the GNU -+ * General Public License. -+ */ -+ -+#include "sdcardfs.h" -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+struct hashtable_entry { -+ struct hlist_node hlist; -+ struct hlist_node dlist; /* for deletion cleanup */ -+ struct qstr key; -+ atomic_t value; -+}; -+ -+static DEFINE_HASHTABLE(package_to_appid, 8); -+static DEFINE_HASHTABLE(package_to_userid, 8); -+static DEFINE_HASHTABLE(ext_to_groupid, 8); -+ -+ -+static struct kmem_cache *hashtable_entry_cachep; -+ -+static unsigned int full_name_case_hash(const void *salt, const unsigned char *name, unsigned int len) -+{ -+ unsigned long hash = init_name_hash(salt); -+ -+ while (len--) -+ hash = partial_name_hash(tolower(*name++), hash); -+ return end_name_hash(hash); -+} -+ -+static inline void qstr_init(struct qstr *q, const char *name) -+{ -+ q->name = name; -+ q->len = strlen(q->name); -+ q->hash = full_name_case_hash(0, q->name, q->len); -+} -+ -+static inline int qstr_copy(const struct qstr *src, struct qstr *dest) -+{ -+ dest->name = kstrdup(src->name, GFP_KERNEL); -+ dest->hash_len = src->hash_len; -+ return !!dest->name; -+} -+ -+ -+static appid_t __get_appid(const struct qstr *key) -+{ -+ struct hashtable_entry *hash_cur; -+ unsigned int hash = key->hash; -+ appid_t ret_id; -+ -+ rcu_read_lock(); -+ hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) { -+ if (qstr_case_eq(key, &hash_cur->key)) { -+ ret_id = atomic_read(&hash_cur->value); -+ rcu_read_unlock(); -+ return ret_id; -+ } -+ } -+ rcu_read_unlock(); -+ return 0; -+} -+ -+appid_t get_appid(const char *key) -+{ -+ struct qstr q; -+ -+ qstr_init(&q, key); -+ return __get_appid(&q); -+} -+ -+static appid_t __get_ext_gid(const struct qstr *key) -+{ -+ struct hashtable_entry *hash_cur; -+ unsigned int hash = key->hash; -+ appid_t ret_id; -+ -+ rcu_read_lock(); -+ hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) { -+ if (qstr_case_eq(key, &hash_cur->key)) { -+ ret_id = atomic_read(&hash_cur->value); -+ rcu_read_unlock(); -+ return ret_id; -+ } -+ } -+ rcu_read_unlock(); -+ return 0; -+} -+ -+appid_t get_ext_gid(const char *key) -+{ -+ struct qstr q; -+ -+ qstr_init(&q, key); -+ return __get_ext_gid(&q); -+} -+ -+static appid_t __is_excluded(const struct qstr *app_name, userid_t user) -+{ -+ struct hashtable_entry *hash_cur; -+ unsigned int hash = app_name->hash; -+ -+ rcu_read_lock(); -+ hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) { -+ if (atomic_read(&hash_cur->value) == user && -+ qstr_case_eq(app_name, &hash_cur->key)) { -+ rcu_read_unlock(); -+ return 1; -+ } -+ } -+ rcu_read_unlock(); -+ return 0; -+} -+ -+appid_t is_excluded(const char *key, userid_t user) -+{ -+ struct qstr q; -+ qstr_init(&q, key); -+ return __is_excluded(&q, user); -+} -+ -+/* Kernel has already enforced everything we returned through -+ * derive_permissions_locked(), so this is used to lock down access -+ * even further, such as enforcing that apps hold sdcard_rw. -+ */ -+int check_caller_access_to_name(struct inode *parent_node, const struct qstr *name) -+{ -+ struct qstr q_autorun = QSTR_LITERAL("autorun.inf"); -+ struct qstr q__android_secure = QSTR_LITERAL(".android_secure"); -+ struct qstr q_android_secure = QSTR_LITERAL("android_secure"); -+ -+ /* Always block security-sensitive files at root */ -+ if (parent_node && SDCARDFS_I(parent_node)->data->perm == PERM_ROOT) { -+ if (qstr_case_eq(name, &q_autorun) -+ || qstr_case_eq(name, &q__android_secure) -+ || qstr_case_eq(name, &q_android_secure)) { -+ return 0; -+ } -+ } -+ -+ /* Root always has access; access for any other UIDs should always -+ * be controlled through packages.list. -+ */ -+ if (from_kuid(&init_user_ns, current_fsuid()) == 0) -+ return 1; -+ -+ /* No extra permissions to enforce */ -+ return 1; -+} -+ -+static struct hashtable_entry *alloc_hashtable_entry(const struct qstr *key, -+ appid_t value) -+{ -+ struct hashtable_entry *ret = kmem_cache_alloc(hashtable_entry_cachep, -+ GFP_KERNEL); -+ if (!ret) -+ return NULL; -+ INIT_HLIST_NODE(&ret->dlist); -+ INIT_HLIST_NODE(&ret->hlist); -+ -+ if (!qstr_copy(key, &ret->key)) { -+ kmem_cache_free(hashtable_entry_cachep, ret); -+ return NULL; -+ } -+ -+ atomic_set(&ret->value, value); -+ return ret; -+} -+ -+static int insert_packagelist_appid_entry_locked(const struct qstr *key, appid_t value) -+{ -+ struct hashtable_entry *hash_cur; -+ struct hashtable_entry *new_entry; -+ unsigned int hash = key->hash; -+ -+ hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) { -+ if (qstr_case_eq(key, &hash_cur->key)) { -+ atomic_set(&hash_cur->value, value); -+ return 0; -+ } -+ } -+ new_entry = alloc_hashtable_entry(key, value); -+ if (!new_entry) -+ return -ENOMEM; -+ hash_add_rcu(package_to_appid, &new_entry->hlist, hash); -+ return 0; -+} -+ -+static int insert_ext_gid_entry_locked(const struct qstr *key, appid_t value) -+{ -+ struct hashtable_entry *hash_cur; -+ struct hashtable_entry *new_entry; -+ unsigned int hash = key->hash; -+ -+ /* An extension can only belong to one gid */ -+ hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) { -+ if (qstr_case_eq(key, &hash_cur->key)) -+ return -EINVAL; -+ } -+ new_entry = alloc_hashtable_entry(key, value); -+ if (!new_entry) -+ return -ENOMEM; -+ hash_add_rcu(ext_to_groupid, &new_entry->hlist, hash); -+ return 0; -+} -+ -+static int insert_userid_exclude_entry_locked(const struct qstr *key, userid_t value) -+{ -+ struct hashtable_entry *hash_cur; -+ struct hashtable_entry *new_entry; -+ unsigned int hash = key->hash; -+ -+ /* Only insert if not already present */ -+ hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) { -+ if (atomic_read(&hash_cur->value) == value && -+ qstr_case_eq(key, &hash_cur->key)) -+ return 0; -+ } -+ new_entry = alloc_hashtable_entry(key, value); -+ if (!new_entry) -+ return -ENOMEM; -+ hash_add_rcu(package_to_userid, &new_entry->hlist, hash); -+ return 0; -+} -+ -+static void fixup_all_perms_name(const struct qstr *key) -+{ -+ struct sdcardfs_sb_info *sbinfo; -+ struct limit_search limit = { -+ .flags = BY_NAME, -+ .name = QSTR_INIT(key->name, key->len), -+ }; -+ list_for_each_entry(sbinfo, &sdcardfs_super_list, list) { -+ if (sbinfo_has_sdcard_magic(sbinfo)) -+ fixup_perms_recursive(sbinfo->sb->s_root, &limit); -+ } -+} -+ -+static void fixup_all_perms_name_userid(const struct qstr *key, userid_t userid) -+{ -+ struct sdcardfs_sb_info *sbinfo; -+ struct limit_search limit = { -+ .flags = BY_NAME | BY_USERID, -+ .name = QSTR_INIT(key->name, key->len), -+ .userid = userid, -+ }; -+ list_for_each_entry(sbinfo, &sdcardfs_super_list, list) { -+ if (sbinfo_has_sdcard_magic(sbinfo)) -+ fixup_perms_recursive(sbinfo->sb->s_root, &limit); -+ } -+} -+ -+static void fixup_all_perms_userid(userid_t userid) -+{ -+ struct sdcardfs_sb_info *sbinfo; -+ struct limit_search limit = { -+ .flags = BY_USERID, -+ .userid = userid, -+ }; -+ list_for_each_entry(sbinfo, &sdcardfs_super_list, list) { -+ if (sbinfo_has_sdcard_magic(sbinfo)) -+ fixup_perms_recursive(sbinfo->sb->s_root, &limit); -+ } -+} -+ -+static int insert_packagelist_entry(const struct qstr *key, appid_t value) -+{ -+ int err; -+ -+ mutex_lock(&sdcardfs_super_list_lock); -+ err = insert_packagelist_appid_entry_locked(key, value); -+ if (!err) -+ fixup_all_perms_name(key); -+ mutex_unlock(&sdcardfs_super_list_lock); -+ -+ return err; -+} -+ -+static int insert_ext_gid_entry(const struct qstr *key, appid_t value) -+{ -+ int err; -+ -+ mutex_lock(&sdcardfs_super_list_lock); -+ err = insert_ext_gid_entry_locked(key, value); -+ mutex_unlock(&sdcardfs_super_list_lock); -+ -+ return err; -+} -+ -+static int insert_userid_exclude_entry(const struct qstr *key, userid_t value) -+{ -+ int err; -+ -+ mutex_lock(&sdcardfs_super_list_lock); -+ err = insert_userid_exclude_entry_locked(key, value); -+ if (!err) -+ fixup_all_perms_name_userid(key, value); -+ mutex_unlock(&sdcardfs_super_list_lock); -+ -+ return err; -+} -+ -+static void free_hashtable_entry(struct hashtable_entry *entry) -+{ -+ kfree(entry->key.name); -+ kmem_cache_free(hashtable_entry_cachep, entry); -+} -+ -+static void remove_packagelist_entry_locked(const struct qstr *key) -+{ -+ struct hashtable_entry *hash_cur; -+ unsigned int hash = key->hash; -+ struct hlist_node *h_t; -+ HLIST_HEAD(free_list); -+ -+ hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) { -+ if (qstr_case_eq(key, &hash_cur->key)) { -+ hash_del_rcu(&hash_cur->hlist); -+ hlist_add_head(&hash_cur->dlist, &free_list); -+ } -+ } -+ hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) { -+ if (qstr_case_eq(key, &hash_cur->key)) { -+ hash_del_rcu(&hash_cur->hlist); -+ hlist_add_head(&hash_cur->dlist, &free_list); -+ break; -+ } -+ } -+ synchronize_rcu(); -+ hlist_for_each_entry_safe(hash_cur, h_t, &free_list, dlist) -+ free_hashtable_entry(hash_cur); -+} -+ -+static void remove_packagelist_entry(const struct qstr *key) -+{ -+ mutex_lock(&sdcardfs_super_list_lock); -+ remove_packagelist_entry_locked(key); -+ fixup_all_perms_name(key); -+ mutex_unlock(&sdcardfs_super_list_lock); -+} -+ -+static void remove_ext_gid_entry_locked(const struct qstr *key, gid_t group) -+{ -+ struct hashtable_entry *hash_cur; -+ unsigned int hash = key->hash; -+ -+ hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) { -+ if (qstr_case_eq(key, &hash_cur->key) && atomic_read(&hash_cur->value) == group) { -+ hash_del_rcu(&hash_cur->hlist); -+ synchronize_rcu(); -+ free_hashtable_entry(hash_cur); -+ break; -+ } -+ } -+} -+ -+static void remove_ext_gid_entry(const struct qstr *key, gid_t group) -+{ -+ mutex_lock(&sdcardfs_super_list_lock); -+ remove_ext_gid_entry_locked(key, group); -+ mutex_unlock(&sdcardfs_super_list_lock); -+} -+ -+static void remove_userid_all_entry_locked(userid_t userid) -+{ -+ struct hashtable_entry *hash_cur; -+ struct hlist_node *h_t; -+ HLIST_HEAD(free_list); -+ int i; -+ -+ hash_for_each_rcu(package_to_userid, i, hash_cur, hlist) { -+ if (atomic_read(&hash_cur->value) == userid) { -+ hash_del_rcu(&hash_cur->hlist); -+ hlist_add_head(&hash_cur->dlist, &free_list); -+ } -+ } -+ synchronize_rcu(); -+ hlist_for_each_entry_safe(hash_cur, h_t, &free_list, dlist) { -+ free_hashtable_entry(hash_cur); -+ } -+} -+ -+static void remove_userid_all_entry(userid_t userid) -+{ -+ mutex_lock(&sdcardfs_super_list_lock); -+ remove_userid_all_entry_locked(userid); -+ fixup_all_perms_userid(userid); -+ mutex_unlock(&sdcardfs_super_list_lock); -+} -+ -+static void remove_userid_exclude_entry_locked(const struct qstr *key, userid_t userid) -+{ -+ struct hashtable_entry *hash_cur; -+ unsigned int hash = key->hash; -+ -+ hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) { -+ if (qstr_case_eq(key, &hash_cur->key) && -+ atomic_read(&hash_cur->value) == userid) { -+ hash_del_rcu(&hash_cur->hlist); -+ synchronize_rcu(); -+ free_hashtable_entry(hash_cur); -+ break; -+ } -+ } -+} -+ -+static void remove_userid_exclude_entry(const struct qstr *key, userid_t userid) -+{ -+ mutex_lock(&sdcardfs_super_list_lock); -+ remove_userid_exclude_entry_locked(key, userid); -+ fixup_all_perms_name_userid(key, userid); -+ mutex_unlock(&sdcardfs_super_list_lock); -+} -+ -+static void packagelist_destroy(void) -+{ -+ struct hashtable_entry *hash_cur; -+ struct hlist_node *h_t; -+ HLIST_HEAD(free_list); -+ int i; -+ -+ mutex_lock(&sdcardfs_super_list_lock); -+ hash_for_each_rcu(package_to_appid, i, hash_cur, hlist) { -+ hash_del_rcu(&hash_cur->hlist); -+ hlist_add_head(&hash_cur->dlist, &free_list); -+ } -+ hash_for_each_rcu(package_to_userid, i, hash_cur, hlist) { -+ hash_del_rcu(&hash_cur->hlist); -+ hlist_add_head(&hash_cur->dlist, &free_list); -+ } -+ synchronize_rcu(); -+ hlist_for_each_entry_safe(hash_cur, h_t, &free_list, dlist) -+ free_hashtable_entry(hash_cur); -+ mutex_unlock(&sdcardfs_super_list_lock); -+ pr_info("sdcardfs: destroyed packagelist pkgld\n"); -+} -+ -+#define SDCARDFS_CONFIGFS_ATTR(_pfx, _name) \ -+static struct configfs_attribute _pfx##attr_##_name = { \ -+ .ca_name = __stringify(_name), \ -+ .ca_mode = S_IRUGO | S_IWUGO, \ -+ .ca_owner = THIS_MODULE, \ -+ .show = _pfx##_name##_show, \ -+ .store = _pfx##_name##_store, \ -+} -+ -+#define SDCARDFS_CONFIGFS_ATTR_RO(_pfx, _name) \ -+static struct configfs_attribute _pfx##attr_##_name = { \ -+ .ca_name = __stringify(_name), \ -+ .ca_mode = S_IRUGO, \ -+ .ca_owner = THIS_MODULE, \ -+ .show = _pfx##_name##_show, \ -+} -+ -+#define SDCARDFS_CONFIGFS_ATTR_WO(_pfx, _name) \ -+static struct configfs_attribute _pfx##attr_##_name = { \ -+ .ca_name = __stringify(_name), \ -+ .ca_mode = S_IWUGO, \ -+ .ca_owner = THIS_MODULE, \ -+ .store = _pfx##_name##_store, \ -+} -+ -+struct package_details { -+ struct config_item item; -+ struct qstr name; -+}; -+ -+static inline struct package_details *to_package_details(struct config_item *item) -+{ -+ return item ? container_of(item, struct package_details, item) : NULL; -+} -+ -+static ssize_t package_details_appid_show(struct config_item *item, char *page) -+{ -+ return scnprintf(page, PAGE_SIZE, "%u\n", __get_appid(&to_package_details(item)->name)); -+} -+ -+static ssize_t package_details_appid_store(struct config_item *item, -+ const char *page, size_t count) -+{ -+ unsigned int tmp; -+ int ret; -+ -+ ret = kstrtouint(page, 10, &tmp); -+ if (ret) -+ return ret; -+ -+ ret = insert_packagelist_entry(&to_package_details(item)->name, tmp); -+ -+ if (ret) -+ return ret; -+ -+ return count; -+} -+ -+static ssize_t package_details_excluded_userids_show(struct config_item *item, -+ char *page) -+{ -+ struct package_details *package_details = to_package_details(item); -+ struct hashtable_entry *hash_cur; -+ unsigned int hash = package_details->name.hash; -+ int count = 0; -+ -+ rcu_read_lock(); -+ hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) { -+ if (qstr_case_eq(&package_details->name, &hash_cur->key)) -+ count += scnprintf(page + count, PAGE_SIZE - count, -+ "%d ", atomic_read(&hash_cur->value)); -+ } -+ rcu_read_unlock(); -+ if (count) -+ count--; -+ count += scnprintf(page + count, PAGE_SIZE - count, "\n"); -+ return count; -+} -+ -+static ssize_t package_details_excluded_userids_store(struct config_item *item, -+ const char *page, size_t count) -+{ -+ unsigned int tmp; -+ int ret; -+ -+ ret = kstrtouint(page, 10, &tmp); -+ if (ret) -+ return ret; -+ -+ ret = insert_userid_exclude_entry(&to_package_details(item)->name, tmp); -+ -+ if (ret) -+ return ret; -+ -+ return count; -+} -+ -+static ssize_t package_details_clear_userid_store(struct config_item *item, -+ const char *page, size_t count) -+{ -+ unsigned int tmp; -+ int ret; -+ -+ ret = kstrtouint(page, 10, &tmp); -+ if (ret) -+ return ret; -+ remove_userid_exclude_entry(&to_package_details(item)->name, tmp); -+ return count; -+} -+ -+static void package_details_release(struct config_item *item) -+{ -+ struct package_details *package_details = to_package_details(item); -+ -+ pr_info("sdcardfs: removing %s\n", package_details->name.name); -+ remove_packagelist_entry(&package_details->name); -+ kfree(package_details->name.name); -+ kfree(package_details); -+} -+ -+SDCARDFS_CONFIGFS_ATTR(package_details_, appid); -+SDCARDFS_CONFIGFS_ATTR(package_details_, excluded_userids); -+SDCARDFS_CONFIGFS_ATTR_WO(package_details_, clear_userid); -+ -+static struct configfs_attribute *package_details_attrs[] = { -+ &package_details_attr_appid, -+ &package_details_attr_excluded_userids, -+ &package_details_attr_clear_userid, -+ NULL, -+}; -+ -+static struct configfs_item_operations package_details_item_ops = { -+ .release = package_details_release, -+}; -+ -+static struct config_item_type package_appid_type = { -+ .ct_item_ops = &package_details_item_ops, -+ .ct_attrs = package_details_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+struct extensions_value { -+ struct config_group group; -+ unsigned int num; -+}; -+ -+struct extension_details { -+ struct config_item item; -+ struct qstr name; -+ unsigned int num; -+}; -+ -+static inline struct extensions_value *to_extensions_value(struct config_item *item) -+{ -+ return item ? container_of(to_config_group(item), struct extensions_value, group) : NULL; -+} -+ -+static inline struct extension_details *to_extension_details(struct config_item *item) -+{ -+ return item ? container_of(item, struct extension_details, item) : NULL; -+} -+ -+static void extension_details_release(struct config_item *item) -+{ -+ struct extension_details *extension_details = to_extension_details(item); -+ -+ pr_info("sdcardfs: No longer mapping %s files to gid %d\n", -+ extension_details->name.name, extension_details->num); -+ remove_ext_gid_entry(&extension_details->name, extension_details->num); -+ kfree(extension_details->name.name); -+ kfree(extension_details); -+} -+ -+static struct configfs_item_operations extension_details_item_ops = { -+ .release = extension_details_release, -+}; -+ -+static struct config_item_type extension_details_type = { -+ .ct_item_ops = &extension_details_item_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct config_item *extension_details_make_item(struct config_group *group, const char *name) -+{ -+ struct extensions_value *extensions_value = to_extensions_value(&group->cg_item); -+ struct extension_details *extension_details = kzalloc(sizeof(struct extension_details), GFP_KERNEL); -+ const char *tmp; -+ int ret; -+ -+ if (!extension_details) -+ return ERR_PTR(-ENOMEM); -+ -+ tmp = kstrdup(name, GFP_KERNEL); -+ if (!tmp) { -+ kfree(extension_details); -+ return ERR_PTR(-ENOMEM); -+ } -+ qstr_init(&extension_details->name, tmp); -+ extension_details->num = extensions_value->num; -+ ret = insert_ext_gid_entry(&extension_details->name, extensions_value->num); -+ -+ if (ret) { -+ kfree(extension_details->name.name); -+ kfree(extension_details); -+ return ERR_PTR(ret); -+ } -+ config_item_init_type_name(&extension_details->item, name, &extension_details_type); -+ -+ return &extension_details->item; -+} -+ -+static struct configfs_group_operations extensions_value_group_ops = { -+ .make_item = extension_details_make_item, -+}; -+ -+static struct config_item_type extensions_name_type = { -+ .ct_group_ops = &extensions_value_group_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct config_group *extensions_make_group(struct config_group *group, const char *name) -+{ -+ struct extensions_value *extensions_value; -+ unsigned int tmp; -+ int ret; -+ -+ extensions_value = kzalloc(sizeof(struct extensions_value), GFP_KERNEL); -+ if (!extensions_value) -+ return ERR_PTR(-ENOMEM); -+ ret = kstrtouint(name, 10, &tmp); -+ if (ret) { -+ kfree(extensions_value); -+ return ERR_PTR(ret); -+ } -+ -+ extensions_value->num = tmp; -+ config_group_init_type_name(&extensions_value->group, name, -+ &extensions_name_type); -+ return &extensions_value->group; -+} -+ -+static void extensions_drop_group(struct config_group *group, struct config_item *item) -+{ -+ struct extensions_value *value = to_extensions_value(item); -+ -+ pr_info("sdcardfs: No longer mapping any files to gid %d\n", value->num); -+ kfree(value); -+} -+ -+static struct configfs_group_operations extensions_group_ops = { -+ .make_group = extensions_make_group, -+ .drop_item = extensions_drop_group, -+}; -+ -+static struct config_item_type extensions_type = { -+ .ct_group_ops = &extensions_group_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+struct config_group extension_group = { -+ .cg_item = { -+ .ci_namebuf = "extensions", -+ .ci_type = &extensions_type, -+ }, -+}; -+ -+static struct config_item *packages_make_item(struct config_group *group, const char *name) -+{ -+ struct package_details *package_details; -+ const char *tmp; -+ -+ package_details = kzalloc(sizeof(struct package_details), GFP_KERNEL); -+ if (!package_details) -+ return ERR_PTR(-ENOMEM); -+ tmp = kstrdup(name, GFP_KERNEL); -+ if (!tmp) { -+ kfree(package_details); -+ return ERR_PTR(-ENOMEM); -+ } -+ qstr_init(&package_details->name, tmp); -+ config_item_init_type_name(&package_details->item, name, -+ &package_appid_type); -+ -+ return &package_details->item; -+} -+ -+static ssize_t packages_list_show(struct config_item *item, char *page) -+{ -+ struct hashtable_entry *hash_cur_app; -+ struct hashtable_entry *hash_cur_user; -+ int i; -+ int count = 0, written = 0; -+ const char errormsg[] = "\n"; -+ unsigned int hash; -+ -+ rcu_read_lock(); -+ hash_for_each_rcu(package_to_appid, i, hash_cur_app, hlist) { -+ written = scnprintf(page + count, PAGE_SIZE - sizeof(errormsg) - count, "%s %d\n", -+ hash_cur_app->key.name, atomic_read(&hash_cur_app->value)); -+ hash = hash_cur_app->key.hash; -+ hash_for_each_possible_rcu(package_to_userid, hash_cur_user, hlist, hash) { -+ if (qstr_case_eq(&hash_cur_app->key, &hash_cur_user->key)) { -+ written += scnprintf(page + count + written - 1, -+ PAGE_SIZE - sizeof(errormsg) - count - written + 1, -+ " %d\n", atomic_read(&hash_cur_user->value)) - 1; -+ } -+ } -+ if (count + written == PAGE_SIZE - sizeof(errormsg) - 1) { -+ count += scnprintf(page + count, PAGE_SIZE - count, errormsg); -+ break; -+ } -+ count += written; -+ } -+ rcu_read_unlock(); -+ -+ return count; -+} -+ -+static ssize_t packages_remove_userid_store(struct config_item *item, -+ const char *page, size_t count) -+{ -+ unsigned int tmp; -+ int ret; -+ -+ ret = kstrtouint(page, 10, &tmp); -+ if (ret) -+ return ret; -+ remove_userid_all_entry(tmp); -+ return count; -+} -+ -+static struct configfs_attribute packages_attr_packages_gid_list = { -+ .ca_name = "packages_gid.list", -+ .ca_mode = S_IRUGO, -+ .ca_owner = THIS_MODULE, -+ .show = packages_list_show, -+}; -+ -+SDCARDFS_CONFIGFS_ATTR_WO(packages_, remove_userid); -+ -+static struct configfs_attribute *packages_attrs[] = { -+ &packages_attr_packages_gid_list, -+ &packages_attr_remove_userid, -+ NULL, -+}; -+ -+/* -+ * Note that, since no extra work is required on ->drop_item(), -+ * no ->drop_item() is provided. -+ */ -+static struct configfs_group_operations packages_group_ops = { -+ .make_item = packages_make_item, -+}; -+ -+static struct config_item_type packages_type = { -+ .ct_group_ops = &packages_group_ops, -+ .ct_attrs = packages_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+struct config_group *sd_default_groups[] = { -+ &extension_group, -+ NULL, -+}; -+ -+static struct configfs_subsystem sdcardfs_packages = { -+ .su_group = { -+ .cg_item = { -+ .ci_namebuf = "sdcardfs", -+ .ci_type = &packages_type, -+ }, -+ }, -+}; -+ -+static int configfs_sdcardfs_init(void) -+{ -+ int ret, i; -+ struct configfs_subsystem *subsys = &sdcardfs_packages; -+ -+ config_group_init(&subsys->su_group); -+ for (i = 0; sd_default_groups[i]; i++) { -+ config_group_init(sd_default_groups[i]); -+ configfs_add_default_group(sd_default_groups[i], &subsys->su_group); -+ } -+ mutex_init(&subsys->su_mutex); -+ ret = configfs_register_subsystem(subsys); -+ if (ret) { -+ pr_err("Error %d while registering subsystem %s\n", -+ ret, -+ subsys->su_group.cg_item.ci_namebuf); -+ } -+ return ret; -+} -+ -+static void configfs_sdcardfs_exit(void) -+{ -+ configfs_unregister_subsystem(&sdcardfs_packages); -+} -+ -+int packagelist_init(void) -+{ -+ hashtable_entry_cachep = -+ kmem_cache_create("packagelist_hashtable_entry", -+ sizeof(struct hashtable_entry), 0, 0, NULL); -+ if (!hashtable_entry_cachep) { -+ pr_err("sdcardfs: failed creating pkgl_hashtable entry slab cache\n"); -+ return -ENOMEM; -+ } -+ -+ configfs_sdcardfs_init(); -+ return 0; -+} -+ -+void packagelist_exit(void) -+{ -+ configfs_sdcardfs_exit(); -+ packagelist_destroy(); -+ kmem_cache_destroy(hashtable_entry_cachep); -+} -diff --git a/fs/sdcardfs/sdcardfs.h b/fs/sdcardfs/sdcardfs.h -new file mode 100644 -index 000000000000..f813d23cddcd ---- /dev/null -+++ b/fs/sdcardfs/sdcardfs.h -@@ -0,0 +1,662 @@ -+/* -+ * fs/sdcardfs/sdcardfs.h -+ * -+ * The sdcardfs v2.0 -+ * This file system replaces the sdcard daemon on Android -+ * On version 2.0, some of the daemon functions have been ported -+ * to support the multi-user concepts of Android 4.4 -+ * -+ * Copyright (c) 2013 Samsung Electronics Co. Ltd -+ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, -+ * Sunghwan Yun, Sungjong Seo -+ * -+ * This program has been developed as a stackable file system based on -+ * the WrapFS which written by -+ * -+ * Copyright (c) 1998-2011 Erez Zadok -+ * Copyright (c) 2009 Shrikar Archak -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * This file is dual licensed. It may be redistributed and/or modified -+ * under the terms of the Apache 2.0 License OR version 2 of the GNU -+ * General Public License. -+ */ -+ -+#ifndef _SDCARDFS_H_ -+#define _SDCARDFS_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "multiuser.h" -+ -+/* the file system name */ -+#define SDCARDFS_NAME "sdcardfs" -+ -+/* sdcardfs root inode number */ -+#define SDCARDFS_ROOT_INO 1 -+ -+/* useful for tracking code reachability */ -+#define UDBG pr_default("DBG:%s:%s:%d\n", __FILE__, __func__, __LINE__) -+ -+#define SDCARDFS_DIRENT_SIZE 256 -+ -+/* temporary static uid settings for development */ -+#define AID_ROOT 0 /* uid for accessing /mnt/sdcard & extSdcard */ -+#define AID_MEDIA_RW 1023 /* internal media storage write access */ -+ -+#define AID_SDCARD_RW 1015 /* external storage write access */ -+#define AID_SDCARD_R 1028 /* external storage read access */ -+#define AID_SDCARD_PICS 1033 /* external storage photos access */ -+#define AID_SDCARD_AV 1034 /* external storage audio/video access */ -+#define AID_SDCARD_ALL 1035 /* access all users external storage */ -+#define AID_MEDIA_OBB 1059 /* obb files */ -+ -+#define AID_SDCARD_IMAGE 1057 -+ -+#define AID_PACKAGE_INFO 1027 -+ -+ -+/* -+ * Permissions are handled by our permission function. -+ * We don't want anyone who happens to look at our inode value to prematurely -+ * block access, so store more permissive values. These are probably never -+ * used. -+ */ -+#define fixup_tmp_permissions(x) \ -+ do { \ -+ (x)->i_uid = make_kuid(&init_user_ns, \ -+ SDCARDFS_I(x)->data->d_uid); \ -+ (x)->i_gid = make_kgid(&init_user_ns, AID_SDCARD_RW); \ -+ (x)->i_mode = ((x)->i_mode & S_IFMT) | 0775;\ -+ } while (0) -+ -+/* Android 5.0 support */ -+ -+/* Permission mode for a specific node. Controls how file permissions -+ * are derived for children nodes. -+ */ -+typedef enum { -+ /* Nothing special; this node should just inherit from its parent. */ -+ PERM_INHERIT, -+ /* This node is one level above a normal root; used for legacy layouts -+ * which use the first level to represent user_id. -+ */ -+ PERM_PRE_ROOT, -+ /* This node is "/" */ -+ PERM_ROOT, -+ /* This node is "/Android" */ -+ PERM_ANDROID, -+ /* This node is "/Android/data" */ -+ PERM_ANDROID_DATA, -+ /* This node is "/Android/obb" */ -+ PERM_ANDROID_OBB, -+ /* This node is "/Android/media" */ -+ PERM_ANDROID_MEDIA, -+ /* This node is "/Android/[data|media|obb]/[package]" */ -+ PERM_ANDROID_PACKAGE, -+ /* This node is "/Android/[data|media|obb]/[package]/cache" */ -+ PERM_ANDROID_PACKAGE_CACHE, -+} perm_t; -+ -+struct sdcardfs_sb_info; -+struct sdcardfs_mount_options; -+struct sdcardfs_inode_info; -+struct sdcardfs_inode_data; -+ -+/* Do not directly use this function. Use OVERRIDE_CRED() instead. */ -+const struct cred *override_fsids(struct sdcardfs_sb_info *sbi, -+ struct sdcardfs_inode_data *data); -+/* Do not directly use this function, use REVERT_CRED() instead. */ -+void revert_fsids(const struct cred *old_cred); -+ -+/* operations vectors defined in specific files */ -+extern const struct file_operations sdcardfs_main_fops; -+extern const struct file_operations sdcardfs_dir_fops; -+extern const struct inode_operations sdcardfs_main_iops; -+extern const struct inode_operations sdcardfs_dir_iops; -+extern const struct inode_operations sdcardfs_symlink_iops; -+extern const struct super_operations sdcardfs_sops; -+extern const struct dentry_operations sdcardfs_ci_dops; -+extern const struct address_space_operations sdcardfs_aops, sdcardfs_dummy_aops; -+extern const struct vm_operations_struct sdcardfs_vm_ops; -+ -+extern int sdcardfs_init_inode_cache(void); -+extern void sdcardfs_destroy_inode_cache(void); -+extern int sdcardfs_init_dentry_cache(void); -+extern void sdcardfs_destroy_dentry_cache(void); -+extern int new_dentry_private_data(struct dentry *dentry); -+extern void free_dentry_private_data(struct dentry *dentry); -+extern struct dentry *sdcardfs_lookup(struct inode *dir, struct dentry *dentry, -+ unsigned int flags); -+extern struct inode *sdcardfs_iget(struct super_block *sb, -+ struct inode *lower_inode, userid_t id); -+extern int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb, -+ struct path *lower_path, userid_t id); -+ -+/* file private data */ -+struct sdcardfs_file_info { -+ struct file *lower_file; -+ const struct vm_operations_struct *lower_vm_ops; -+}; -+ -+struct sdcardfs_inode_data { -+ struct kref refcount; -+ bool abandoned; -+ -+ perm_t perm; -+ userid_t userid; -+ uid_t d_uid; -+ bool under_android; -+ bool under_cache; -+ bool under_obb; -+}; -+ -+/* sdcardfs inode data in memory */ -+struct sdcardfs_inode_info { -+ struct inode *lower_inode; -+ /* state derived based on current position in hierarchy */ -+ struct sdcardfs_inode_data *data; -+ -+ /* top folder for ownership */ -+ spinlock_t top_lock; -+ struct sdcardfs_inode_data *top_data; -+ -+ struct inode vfs_inode; -+}; -+ -+ -+/* sdcardfs dentry data in memory */ -+struct sdcardfs_dentry_info { -+ spinlock_t lock; /* protects lower_path */ -+ struct path lower_path; -+ struct path orig_path; -+}; -+ -+struct sdcardfs_mount_options { -+ uid_t fs_low_uid; -+ gid_t fs_low_gid; -+ userid_t fs_user_id; -+ bool multiuser; -+ bool gid_derivation; -+ bool default_normal; -+ bool unshared_obb; -+ unsigned int reserved_mb; -+ bool nocache; -+ bool debug; -+}; -+ -+struct sdcardfs_vfsmount_options { -+ gid_t gid; -+ mode_t mask; -+}; -+ -+struct sdcardfs_context_options { -+ struct sdcardfs_mount_options opts; -+ struct sdcardfs_vfsmount_options vfsopts; -+}; -+ -+extern int parse_options_remount(struct super_block *sb, char *options, int silent, -+ struct sdcardfs_vfsmount_options *vfsopts); -+ -+/* sdcardfs super-block data in memory */ -+struct sdcardfs_sb_info { -+ struct super_block *sb; -+ struct super_block *lower_sb; -+ /* derived perm policy : some of options have been added -+ * to sdcardfs_mount_options (Android 4.4 support) -+ */ -+ struct sdcardfs_mount_options options; -+ spinlock_t lock; /* protects obbpath */ -+ char *obbpath_s; -+ struct path obbpath; -+ void *pkgl_id; -+ struct list_head list; -+}; -+ -+/* -+ * inode to private data -+ * -+ * Since we use containers and the struct inode is _inside_ the -+ * sdcardfs_inode_info structure, SDCARDFS_I will always (given a non-NULL -+ * inode pointer), return a valid non-NULL pointer. -+ */ -+static inline struct sdcardfs_inode_info *SDCARDFS_I(const struct inode *inode) -+{ -+ return container_of(inode, struct sdcardfs_inode_info, vfs_inode); -+} -+ -+/* dentry to private data */ -+#define SDCARDFS_D(dent) ((struct sdcardfs_dentry_info *)(dent)->d_fsdata) -+ -+/* superblock to private data */ -+#define SDCARDFS_SB(super) ((struct sdcardfs_sb_info *)(super)->s_fs_info) -+ -+/* file to private Data */ -+#define SDCARDFS_F(file) ((struct sdcardfs_file_info *)((file)->private_data)) -+ -+/* file to lower file */ -+static inline struct file *sdcardfs_lower_file(const struct file *f) -+{ -+ return SDCARDFS_F(f)->lower_file; -+} -+ -+static inline void sdcardfs_set_lower_file(struct file *f, struct file *val) -+{ -+ SDCARDFS_F(f)->lower_file = val; -+} -+ -+/* inode to lower inode. */ -+static inline struct inode *sdcardfs_lower_inode(const struct inode *i) -+{ -+ return SDCARDFS_I(i)->lower_inode; -+} -+ -+static inline void sdcardfs_set_lower_inode(struct inode *i, struct inode *val) -+{ -+ SDCARDFS_I(i)->lower_inode = val; -+} -+ -+/* superblock to lower superblock */ -+static inline struct super_block *sdcardfs_lower_super( -+ const struct super_block *sb) -+{ -+ return SDCARDFS_SB(sb)->lower_sb; -+} -+ -+static inline void sdcardfs_set_lower_super(struct super_block *sb, -+ struct super_block *val) -+{ -+ SDCARDFS_SB(sb)->lower_sb = val; -+} -+ -+/* path based (dentry/mnt) macros */ -+static inline void pathcpy(struct path *dst, const struct path *src) -+{ -+ dst->dentry = src->dentry; -+ dst->mnt = src->mnt; -+} -+ -+/* sdcardfs_get_pname functions calls path_get() -+ * therefore, the caller must call "proper" path_put functions -+ */ -+#define SDCARDFS_DENT_FUNC(pname) \ -+static inline void sdcardfs_get_##pname(const struct dentry *dent, \ -+ struct path *pname) \ -+{ \ -+ spin_lock(&SDCARDFS_D(dent)->lock); \ -+ pathcpy(pname, &SDCARDFS_D(dent)->pname); \ -+ path_get(pname); \ -+ spin_unlock(&SDCARDFS_D(dent)->lock); \ -+ return; \ -+} \ -+static inline void sdcardfs_put_##pname(const struct dentry *dent, \ -+ struct path *pname) \ -+{ \ -+ path_put(pname); \ -+ return; \ -+} \ -+static inline void sdcardfs_set_##pname(const struct dentry *dent, \ -+ struct path *pname) \ -+{ \ -+ spin_lock(&SDCARDFS_D(dent)->lock); \ -+ pathcpy(&SDCARDFS_D(dent)->pname, pname); \ -+ spin_unlock(&SDCARDFS_D(dent)->lock); \ -+ return; \ -+} \ -+static inline void sdcardfs_reset_##pname(const struct dentry *dent) \ -+{ \ -+ spin_lock(&SDCARDFS_D(dent)->lock); \ -+ SDCARDFS_D(dent)->pname.dentry = NULL; \ -+ SDCARDFS_D(dent)->pname.mnt = NULL; \ -+ spin_unlock(&SDCARDFS_D(dent)->lock); \ -+ return; \ -+} \ -+static inline void sdcardfs_put_reset_##pname(const struct dentry *dent) \ -+{ \ -+ struct path pname; \ -+ spin_lock(&SDCARDFS_D(dent)->lock); \ -+ if (SDCARDFS_D(dent)->pname.dentry) { \ -+ pathcpy(&pname, &SDCARDFS_D(dent)->pname); \ -+ SDCARDFS_D(dent)->pname.dentry = NULL; \ -+ SDCARDFS_D(dent)->pname.mnt = NULL; \ -+ spin_unlock(&SDCARDFS_D(dent)->lock); \ -+ path_put(&pname); \ -+ } else \ -+ spin_unlock(&SDCARDFS_D(dent)->lock); \ -+ return; \ -+} -+ -+SDCARDFS_DENT_FUNC(lower_path) -+SDCARDFS_DENT_FUNC(orig_path) -+ -+static inline bool sbinfo_has_sdcard_magic(struct sdcardfs_sb_info *sbinfo) -+{ -+ return sbinfo && sbinfo->sb -+ && sbinfo->sb->s_magic == SDCARDFS_SUPER_MAGIC; -+} -+ -+static inline struct sdcardfs_inode_data *data_get( -+ struct sdcardfs_inode_data *data) -+{ -+ if (data) -+ kref_get(&data->refcount); -+ return data; -+} -+ -+static inline struct sdcardfs_inode_data *top_data_get( -+ struct sdcardfs_inode_info *info) -+{ -+ struct sdcardfs_inode_data *top_data; -+ -+ spin_lock(&info->top_lock); -+ top_data = data_get(info->top_data); -+ spin_unlock(&info->top_lock); -+ return top_data; -+} -+ -+extern void data_release(struct kref *ref); -+ -+static inline void data_put(struct sdcardfs_inode_data *data) -+{ -+ kref_put(&data->refcount, data_release); -+} -+ -+static inline void release_own_data(struct sdcardfs_inode_info *info) -+{ -+ /* -+ * This happens exactly once per inode. At this point, the inode that -+ * originally held this data is about to be freed, and all references -+ * to it are held as a top value, and will likely be released soon. -+ */ -+ info->data->abandoned = true; -+ data_put(info->data); -+} -+ -+static inline void set_top(struct sdcardfs_inode_info *info, -+ struct sdcardfs_inode_info *top_owner) -+{ -+ struct sdcardfs_inode_data *old_top; -+ struct sdcardfs_inode_data *new_top = NULL; -+ -+ if (top_owner) -+ new_top = top_data_get(top_owner); -+ -+ spin_lock(&info->top_lock); -+ old_top = info->top_data; -+ info->top_data = new_top; -+ if (old_top) -+ data_put(old_top); -+ spin_unlock(&info->top_lock); -+} -+ -+static inline int get_gid(struct vfsmount *mnt, -+ struct super_block *sb, -+ struct sdcardfs_inode_data *data) -+{ -+ struct sdcardfs_vfsmount_options *vfsopts = mnt->data; -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(sb); -+ -+ if (vfsopts->gid == AID_SDCARD_RW && !sbi->options.default_normal) -+ /* As an optimization, certain trusted system components only run -+ * as owner but operate across all users. Since we're now handing -+ * out the sdcard_rw GID only to trusted apps, we're okay relaxing -+ * the user boundary enforcement for the default view. The UIDs -+ * assigned to app directories are still multiuser aware. -+ */ -+ return AID_SDCARD_RW; -+ else -+ return multiuser_get_uid(data->userid, vfsopts->gid); -+} -+ -+static inline int get_mode(struct vfsmount *mnt, -+ struct sdcardfs_inode_info *info, -+ struct sdcardfs_inode_data *data) -+{ -+ int owner_mode; -+ int filtered_mode; -+ struct sdcardfs_vfsmount_options *opts = mnt->data; -+ int visible_mode = 0775 & ~opts->mask; -+ -+ -+ if (data->perm == PERM_PRE_ROOT) { -+ /* Top of multi-user view should always be visible to ensure -+ * secondary users can traverse inside. -+ */ -+ visible_mode = 0711; -+ } else if (data->under_android) { -+ /* Block "other" access to Android directories, since only apps -+ * belonging to a specific user should be in there; we still -+ * leave +x open for the default view. -+ */ -+ if (opts->gid == AID_SDCARD_RW) -+ visible_mode = visible_mode & ~0006; -+ else -+ visible_mode = visible_mode & ~0007; -+ } -+ owner_mode = info->lower_inode->i_mode & 0700; -+ filtered_mode = visible_mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6)); -+ return filtered_mode; -+} -+ -+static inline int has_graft_path(const struct dentry *dent) -+{ -+ int ret = 0; -+ -+ spin_lock(&SDCARDFS_D(dent)->lock); -+ if (SDCARDFS_D(dent)->orig_path.dentry != NULL) -+ ret = 1; -+ spin_unlock(&SDCARDFS_D(dent)->lock); -+ -+ return ret; -+} -+ -+static inline void sdcardfs_get_real_lower(const struct dentry *dent, -+ struct path *real_lower) -+{ -+ /* in case of a local obb dentry -+ * the orig_path should be returned -+ */ -+ if (has_graft_path(dent)) -+ sdcardfs_get_orig_path(dent, real_lower); -+ else -+ sdcardfs_get_lower_path(dent, real_lower); -+} -+ -+static inline void sdcardfs_put_real_lower(const struct dentry *dent, -+ struct path *real_lower) -+{ -+ if (has_graft_path(dent)) -+ sdcardfs_put_orig_path(dent, real_lower); -+ else -+ sdcardfs_put_lower_path(dent, real_lower); -+} -+ -+extern struct mutex sdcardfs_super_list_lock; -+extern struct list_head sdcardfs_super_list; -+ -+/* for packagelist.c */ -+extern appid_t get_appid(const char *app_name); -+extern appid_t get_ext_gid(const char *app_name); -+extern appid_t is_excluded(const char *app_name, userid_t userid); -+extern int check_caller_access_to_name(struct inode *parent_node, const struct qstr *name); -+extern int packagelist_init(void); -+extern void packagelist_exit(void); -+ -+/* for derived_perm.c */ -+#define BY_NAME (1 << 0) -+#define BY_USERID (1 << 1) -+struct limit_search { -+ unsigned int flags; -+ struct qstr name; -+ userid_t userid; -+}; -+ -+extern void setup_derived_state(struct inode *inode, perm_t perm, -+ userid_t userid, uid_t uid); -+extern void get_derived_permission(struct dentry *parent, struct dentry *dentry); -+extern void get_derived_permission_new(struct dentry *parent, struct dentry *dentry, const struct qstr *name); -+extern void fixup_perms_recursive(struct dentry *dentry, struct limit_search *limit); -+ -+extern void update_derived_permission_lock(struct dentry *dentry); -+void fixup_lower_ownership(struct dentry *dentry, const char *name); -+extern int need_graft_path(struct dentry *dentry); -+extern int is_base_obbpath(struct dentry *dentry); -+extern int is_obbpath_invalid(struct dentry *dentry); -+extern int setup_obb_dentry(struct dentry *dentry, struct path *lower_path); -+ -+/* locking helpers */ -+static inline struct dentry *lock_parent(struct dentry *dentry) -+{ -+ struct dentry *dir = dget_parent(dentry); -+ -+ inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); -+ return dir; -+} -+ -+static inline void unlock_dir(struct dentry *dir) -+{ -+ inode_unlock(d_inode(dir)); -+ dput(dir); -+} -+ -+static inline int prepare_dir(const char *path_s, uid_t uid, gid_t gid, mode_t mode) -+{ -+ int err; -+ struct dentry *dent; -+ struct iattr attrs; -+ struct path parent; -+ -+ dent = kern_path_locked(path_s, &parent); -+ if (IS_ERR(dent)) { -+ err = PTR_ERR(dent); -+ if (err == -EEXIST) -+ err = 0; -+ goto out_unlock; -+ } -+ -+ err = vfs_mkdir2(parent.mnt, d_inode(parent.dentry), dent, mode); -+ if (err) { -+ if (err == -EEXIST) -+ err = 0; -+ goto out_dput; -+ } -+ -+ attrs.ia_uid = make_kuid(&init_user_ns, uid); -+ attrs.ia_gid = make_kgid(&init_user_ns, gid); -+ attrs.ia_valid = ATTR_UID | ATTR_GID; -+ inode_lock(d_inode(dent)); -+ notify_change2(parent.mnt, dent, &attrs, NULL); -+ inode_unlock(d_inode(dent)); -+ -+out_dput: -+ dput(dent); -+ -+out_unlock: -+ /* parent dentry locked by lookup_create */ -+ inode_unlock(d_inode(parent.dentry)); -+ path_put(&parent); -+ return err; -+} -+ -+/* -+ * Return 1, if a disk has enough free space, otherwise 0. -+ * We assume that any files can not be overwritten. -+ */ -+static inline int check_min_free_space(struct dentry *dentry, size_t size, int dir) -+{ -+ int err; -+ struct path lower_path; -+ struct kstatfs statfs; -+ u64 avail; -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); -+ -+ if (sbi->options.reserved_mb) { -+ /* Get fs stat of lower filesystem. */ -+ sdcardfs_get_lower_path(dentry, &lower_path); -+ err = vfs_statfs(&lower_path, &statfs); -+ sdcardfs_put_lower_path(dentry, &lower_path); -+ -+ if (unlikely(err)) -+ return 0; -+ -+ /* Invalid statfs informations. */ -+ if (unlikely(statfs.f_bsize == 0)) -+ return 0; -+ -+ /* if you are checking directory, set size to f_bsize. */ -+ if (unlikely(dir)) -+ size = statfs.f_bsize; -+ -+ /* available size */ -+ avail = statfs.f_bavail * statfs.f_bsize; -+ -+ /* not enough space */ -+ if ((u64)size > avail) -+ return 0; -+ -+ /* enough space */ -+ if ((avail - size) > (sbi->options.reserved_mb * 1024 * 1024)) -+ return 1; -+ -+ return 0; -+ } else -+ return 1; -+} -+ -+/* -+ * Copies attrs and maintains sdcardfs managed attrs -+ * Since our permission check handles all special permissions, set those to be open -+ */ -+static inline void sdcardfs_copy_and_fix_attrs(struct inode *dest, const struct inode *src) -+{ -+ dest->i_mode = (src->i_mode & S_IFMT) | S_IRWXU | S_IRWXG | -+ S_IROTH | S_IXOTH; /* 0775 */ -+ dest->i_uid = make_kuid(&init_user_ns, SDCARDFS_I(dest)->data->d_uid); -+ dest->i_gid = make_kgid(&init_user_ns, AID_SDCARD_RW); -+ dest->i_rdev = src->i_rdev; -+ dest->i_atime = src->i_atime; -+ dest->i_mtime = src->i_mtime; -+ dest->i_ctime = src->i_ctime; -+ dest->i_blkbits = src->i_blkbits; -+ dest->i_flags = src->i_flags; -+ set_nlink(dest, src->i_nlink); -+} -+ -+static inline bool str_case_eq(const char *s1, const char *s2) -+{ -+ return !strcasecmp(s1, s2); -+} -+ -+static inline bool str_n_case_eq(const char *s1, const char *s2, size_t len) -+{ -+ return !strncasecmp(s1, s2, len); -+} -+ -+static inline bool qstr_case_eq(const struct qstr *q1, const struct qstr *q2) -+{ -+ return q1->len == q2->len && str_n_case_eq(q1->name, q2->name, q2->len); -+} -+ -+#define QSTR_LITERAL(string) QSTR_INIT(string, sizeof(string)-1) -+ -+#endif /* not _SDCARDFS_H_ */ -diff --git a/fs/sdcardfs/super.c b/fs/sdcardfs/super.c -new file mode 100644 -index 000000000000..6b1d27e5067b ---- /dev/null -+++ b/fs/sdcardfs/super.c -@@ -0,0 +1,297 @@ -+/* -+ * fs/sdcardfs/super.c -+ * -+ * Copyright (c) 2013 Samsung Electronics Co. Ltd -+ * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun, -+ * Sunghwan Yun, Sungjong Seo -+ * -+ * This program has been developed as a stackable file system based on -+ * the WrapFS which written by -+ * -+ * Copyright (c) 1998-2011 Erez Zadok -+ * Copyright (c) 2009 Shrikar Archak -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * This file is dual licensed. It may be redistributed and/or modified -+ * under the terms of the Apache 2.0 License OR version 2 of the GNU -+ * General Public License. -+ */ -+ -+#include -+ -+#include "sdcardfs.h" -+ -+/* -+ * The inode cache is used with alloc_inode for both our inode info and the -+ * vfs inode. -+ */ -+static struct kmem_cache *sdcardfs_inode_cachep; -+ -+/* -+ * To support the top references, we must track some data separately. -+ * An sdcardfs_inode_info always has a reference to its data, and once set up, -+ * also has a reference to its top. The top may be itself, in which case it -+ * holds two references to its data. When top is changed, it takes a ref to the -+ * new data and then drops the ref to the old data. -+ */ -+static struct kmem_cache *sdcardfs_inode_data_cachep; -+ -+void data_release(struct kref *ref) -+{ -+ struct sdcardfs_inode_data *data = -+ container_of(ref, struct sdcardfs_inode_data, refcount); -+ -+ kmem_cache_free(sdcardfs_inode_data_cachep, data); -+} -+ -+/* final actions when unmounting a file system */ -+static void sdcardfs_put_super(struct super_block *sb) -+{ -+ struct sdcardfs_sb_info *spd; -+ struct super_block *s; -+ -+ spd = SDCARDFS_SB(sb); -+ if (!spd) -+ return; -+ -+ if (spd->obbpath_s) { -+ kfree(spd->obbpath_s); -+ path_put(&spd->obbpath); -+ } -+ -+ /* decrement lower super references */ -+ s = sdcardfs_lower_super(sb); -+ sdcardfs_set_lower_super(sb, NULL); -+ atomic_dec(&s->s_active); -+ -+ kfree(spd); -+ sb->s_fs_info = NULL; -+} -+ -+static int sdcardfs_statfs(struct dentry *dentry, struct kstatfs *buf) -+{ -+ int err; -+ struct path lower_path; -+ u32 min_blocks; -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); -+ -+ sdcardfs_get_lower_path(dentry, &lower_path); -+ err = vfs_statfs(&lower_path, buf); -+ sdcardfs_put_lower_path(dentry, &lower_path); -+ -+ if (sbi->options.reserved_mb) { -+ /* Invalid statfs informations. */ -+ if (buf->f_bsize == 0) { -+ pr_err("Returned block size is zero.\n"); -+ return -EINVAL; -+ } -+ -+ min_blocks = ((sbi->options.reserved_mb * 1024 * 1024)/buf->f_bsize); -+ buf->f_blocks -= min_blocks; -+ -+ if (buf->f_bavail > min_blocks) -+ buf->f_bavail -= min_blocks; -+ else -+ buf->f_bavail = 0; -+ -+ /* Make reserved blocks invisiable to media storage */ -+ buf->f_bfree = buf->f_bavail; -+ } -+ -+ /* set return buf to our f/s to avoid confusing user-level utils */ -+ buf->f_type = SDCARDFS_SUPER_MAGIC; -+ -+ return err; -+} -+ -+static void *sdcardfs_clone_mnt_data(void *data) -+{ -+ struct sdcardfs_vfsmount_options *opt = kmalloc(sizeof(struct sdcardfs_vfsmount_options), GFP_KERNEL); -+ struct sdcardfs_vfsmount_options *old = data; -+ -+ if (!opt) -+ return NULL; -+ opt->gid = old->gid; -+ opt->mask = old->mask; -+ return opt; -+} -+ -+static void sdcardfs_copy_mnt_data(void *data, void *newdata) -+{ -+ struct sdcardfs_vfsmount_options *old = data; -+ struct sdcardfs_vfsmount_options *new = newdata; -+ -+ old->gid = new->gid; -+ old->mask = new->mask; -+} -+ -+static void sdcardfs_update_mnt_data(void *data, struct fs_context *fc) -+{ -+ struct sdcardfs_vfsmount_options *opts = data; -+ struct sdcardfs_context_options *fcopts = fc->fs_private; -+ -+ opts->gid = fcopts->vfsopts.gid; -+ opts->mask = fcopts->vfsopts.mask; -+} -+ -+/* -+ * Called by iput() when the inode reference count reached zero -+ * and the inode is not hashed anywhere. Used to clear anything -+ * that needs to be, before the inode is completely destroyed and put -+ * on the inode free list. -+ */ -+static void sdcardfs_evict_inode(struct inode *inode) -+{ -+ struct inode *lower_inode; -+ -+ truncate_inode_pages(&inode->i_data, 0); -+ set_top(SDCARDFS_I(inode), NULL); -+ clear_inode(inode); -+ /* -+ * Decrement a reference to a lower_inode, which was incremented -+ * by our read_inode when it was created initially. -+ */ -+ lower_inode = sdcardfs_lower_inode(inode); -+ sdcardfs_set_lower_inode(inode, NULL); -+ iput(lower_inode); -+} -+ -+static struct inode *sdcardfs_alloc_inode(struct super_block *sb) -+{ -+ struct sdcardfs_inode_info *i; -+ struct sdcardfs_inode_data *d; -+ -+ i = kmem_cache_alloc(sdcardfs_inode_cachep, GFP_KERNEL); -+ if (!i) -+ return NULL; -+ -+ /* memset everything up to the inode to 0 */ -+ memset(i, 0, offsetof(struct sdcardfs_inode_info, vfs_inode)); -+ -+ d = kmem_cache_alloc(sdcardfs_inode_data_cachep, -+ GFP_KERNEL | __GFP_ZERO); -+ if (!d) { -+ kmem_cache_free(sdcardfs_inode_cachep, i); -+ return NULL; -+ } -+ -+ i->data = d; -+ kref_init(&d->refcount); -+ i->top_data = d; -+ spin_lock_init(&i->top_lock); -+ kref_get(&d->refcount); -+ -+ inode_set_iversion(&i->vfs_inode, 1); -+ return &i->vfs_inode; -+} -+ -+static void i_callback(struct rcu_head *head) -+{ -+ struct inode *inode = container_of(head, struct inode, i_rcu); -+ -+ release_own_data(SDCARDFS_I(inode)); -+ kmem_cache_free(sdcardfs_inode_cachep, SDCARDFS_I(inode)); -+} -+ -+static void sdcardfs_destroy_inode(struct inode *inode) -+{ -+ call_rcu(&inode->i_rcu, i_callback); -+} -+ -+/* sdcardfs inode cache constructor */ -+static void init_once(void *obj) -+{ -+ struct sdcardfs_inode_info *i = obj; -+ -+ inode_init_once(&i->vfs_inode); -+} -+ -+int sdcardfs_init_inode_cache(void) -+{ -+ sdcardfs_inode_cachep = -+ kmem_cache_create("sdcardfs_inode_cache", -+ sizeof(struct sdcardfs_inode_info), 0, -+ SLAB_RECLAIM_ACCOUNT, init_once); -+ -+ if (!sdcardfs_inode_cachep) -+ return -ENOMEM; -+ -+ sdcardfs_inode_data_cachep = -+ kmem_cache_create("sdcardfs_inode_data_cache", -+ sizeof(struct sdcardfs_inode_data), 0, -+ SLAB_RECLAIM_ACCOUNT, NULL); -+ if (!sdcardfs_inode_data_cachep) { -+ kmem_cache_destroy(sdcardfs_inode_cachep); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+/* sdcardfs inode cache destructor */ -+void sdcardfs_destroy_inode_cache(void) -+{ -+ kmem_cache_destroy(sdcardfs_inode_data_cachep); -+ kmem_cache_destroy(sdcardfs_inode_cachep); -+} -+ -+/* -+ * Used only in nfs, to kill any pending RPC tasks, so that subsequent -+ * code can actually succeed and won't leave tasks that need handling. -+ */ -+static void sdcardfs_umount_begin(struct super_block *sb) -+{ -+ struct super_block *lower_sb; -+ -+ lower_sb = sdcardfs_lower_super(sb); -+ if (lower_sb && lower_sb->s_op && lower_sb->s_op->umount_begin) -+ lower_sb->s_op->umount_begin(lower_sb); -+} -+ -+static int sdcardfs_show_options(struct vfsmount *mnt, struct seq_file *m, -+ struct dentry *root) -+{ -+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(root->d_sb); -+ struct sdcardfs_mount_options *opts = &sbi->options; -+ struct sdcardfs_vfsmount_options *vfsopts = mnt->data; -+ -+ if (opts->fs_low_uid != 0) -+ seq_printf(m, ",fsuid=%u", opts->fs_low_uid); -+ if (opts->fs_low_gid != 0) -+ seq_printf(m, ",fsgid=%u", opts->fs_low_gid); -+ if (vfsopts->gid != 0) -+ seq_printf(m, ",gid=%u", vfsopts->gid); -+ if (opts->multiuser) -+ seq_puts(m, ",multiuser"); -+ if (vfsopts->mask) -+ seq_printf(m, ",mask=%u", vfsopts->mask); -+ if (opts->fs_user_id) -+ seq_printf(m, ",userid=%u", opts->fs_user_id); -+ if (opts->gid_derivation) -+ seq_puts(m, ",derive_gid"); -+ if (opts->default_normal) -+ seq_puts(m, ",default_normal"); -+ if (opts->reserved_mb != 0) -+ seq_printf(m, ",reserved=%uMB", opts->reserved_mb); -+ if (opts->nocache) -+ seq_printf(m, ",nocache"); -+ if (opts->unshared_obb) -+ seq_printf(m, ",unshared_obb"); -+ -+ return 0; -+}; -+ -+const struct super_operations sdcardfs_sops = { -+ .put_super = sdcardfs_put_super, -+ .statfs = sdcardfs_statfs, -+ .clone_mnt_data = sdcardfs_clone_mnt_data, -+ .copy_mnt_data = sdcardfs_copy_mnt_data, -+ .update_mnt_data = sdcardfs_update_mnt_data, -+ .evict_inode = sdcardfs_evict_inode, -+ .umount_begin = sdcardfs_umount_begin, -+ .show_options2 = sdcardfs_show_options, -+ .alloc_inode = sdcardfs_alloc_inode, -+ .destroy_inode = sdcardfs_destroy_inode, -+ .drop_inode = generic_delete_inode, -+}; diff --git a/patches/ANDROID-sdcardfs-Define-magic-value.patch b/patches/ANDROID-sdcardfs-Define-magic-value.patch deleted file mode 100644 index c1120820ccaa..000000000000 --- a/patches/ANDROID-sdcardfs-Define-magic-value.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Rosenberg -Date: Tue, 15 Nov 2016 13:35:18 -0800 -Subject: ANDROID: sdcardfs: Define magic value - -Define a filesystem magic value to be used for sdcardfs. - -Test: HiKey/X15 + Pie + android-mainline, - and HiKey + AOSP Maser + android-mainline, - directories under /sdcard created, - output of mount is right, - CTS test collecting device infor works - -Change-Id: I54daa1452aa6a3ce0401d7d923e0a897f0c26d96 -Signed-off-by: Daniel Rosenberg -Signed-off-by: Yongqin Liu ---- - include/uapi/linux/magic.h | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h -index 903cc2d2750b..5c4bf0ad580c 100644 ---- a/include/uapi/linux/magic.h -+++ b/include/uapi/linux/magic.h -@@ -58,6 +58,8 @@ - #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs" - #define REISER2FS_JR_SUPER_MAGIC_STRING "ReIsEr3Fs" - -+#define SDCARDFS_SUPER_MAGIC 0x5dca2df5 -+ - #define SMB_SUPER_MAGIC 0x517B - #define CGROUP_SUPER_MAGIC 0x27e0eb - #define CGROUP2_SUPER_MAGIC 0x63677270 diff --git a/patches/ANDROID-sdcardfs-Enable-modular-sdcardfs.patch b/patches/ANDROID-sdcardfs-Enable-modular-sdcardfs.patch deleted file mode 100644 index 1c55ba222875..000000000000 --- a/patches/ANDROID-sdcardfs-Enable-modular-sdcardfs.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Rosenberg -Date: Tue, 30 Jan 2018 14:24:02 -0800 -Subject: ANDROID: sdcardfs: Enable modular sdcardfs - -Export the following symbols: - -- copy_fs_struct -- free_fs_struct -- security_path_chown -- set_fs_pwd -- vfs_read -- vfs_write - -These are needed to build sdcardfs as a module. - -Test: HiKey/X15 + Pie + android-mainline, - and HiKey + AOSP Maser + android-mainline, - directories under /sdcard created, - output of mount is right, - CTS test collecting device infor works - -Bug: 35142419 -Change-Id: If6e14f0b3bdc858a9f684e6c209927a9232091f0 -Signed-off-by: Daniel Rosenberg -Signed-off-by: Guenter Roeck -[astrachan: Folded the following changes into this patch: - e19f69662df5 ("ANDROID: Revert "fs: unexport vfs_read and vfs_write"") - 17071a8e1e7d ("ANDROID: fs: Export free_fs_struct and set_fs_pwd") - 2e9a639597cd ("ANDROID: export security_path_chown")] -Signed-off-by: Alistair Strachan -Signed-off-by: Yongqin Liu ---- - fs/fs_struct.c | 3 +++ - fs/read_write.c | 3 +++ - security/security.c | 1 + - 3 files changed, 7 insertions(+) - -diff --git a/fs/fs_struct.c b/fs/fs_struct.c -index ca639ed967b7..57f9817a9808 100644 ---- a/fs/fs_struct.c -+++ b/fs/fs_struct.c -@@ -46,6 +46,7 @@ void set_fs_pwd(struct fs_struct *fs, const struct path *path) - if (old_pwd.dentry) - path_put(&old_pwd); - } -+EXPORT_SYMBOL(set_fs_pwd); - - static inline int replace_path(struct path *p, const struct path *old, const struct path *new) - { -@@ -91,6 +92,7 @@ void free_fs_struct(struct fs_struct *fs) - path_put(&fs->pwd); - kmem_cache_free(fs_cachep, fs); - } -+EXPORT_SYMBOL(free_fs_struct); - - void exit_fs(struct task_struct *tsk) - { -@@ -129,6 +131,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old) - } - return fs; - } -+EXPORT_SYMBOL_GPL(copy_fs_struct); - - int unshare_fs_struct(void) - { -diff --git a/fs/read_write.c b/fs/read_write.c -index 5bbf587f5bc1..45929fe56cfa 100644 ---- a/fs/read_write.c -+++ b/fs/read_write.c -@@ -469,6 +469,8 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) - return ret; - } - -+EXPORT_SYMBOL(vfs_read); -+ - static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) - { - struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; -@@ -566,6 +568,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ - - return ret; - } -+EXPORT_SYMBOL(vfs_write); - - /* file_ppos returns &file->f_pos or NULL if file is stream */ - static inline loff_t *file_ppos(struct file *file) -diff --git a/security/security.c b/security/security.c -index 1bc000f834e2..ab1a1a10c671 100644 ---- a/security/security.c -+++ b/security/security.c -@@ -1101,6 +1101,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) - return 0; - return call_int_hook(path_chown, 0, path, uid, gid); - } -+EXPORT_SYMBOL(security_path_chown); - - int security_path_chroot(const struct path *path) - { diff --git a/patches/ANDROID-sdcardfs-fix-fall-through-in-param-parsing.patch b/patches/ANDROID-sdcardfs-fix-fall-through-in-param-parsing.patch deleted file mode 100644 index 97551d203dd3..000000000000 --- a/patches/ANDROID-sdcardfs-fix-fall-through-in-param-parsing.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Rosenberg -Date: Tue, 27 Aug 2019 16:20:38 -0700 -Subject: ANDROID: sdcardfs: fix fall through in param parsing - -Fixes: commit bafafd3663c2e ("ANDROID: sdcardfs: Add sdcardfs filesystem") -Change-Id: I936ac03b999095d46810c0ca55a7a29cab52d82a -Signed-off-by: Daniel Rosenberg ---- - fs/sdcardfs/main.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c -index b8e5cf2b9ae5..818122410bfe 100644 ---- a/fs/sdcardfs/main.c -+++ b/fs/sdcardfs/main.c -@@ -77,6 +77,7 @@ static int sdcardfs_parse_param(struct fs_context *fc, struct fs_parameter *para - switch (opt) { - case Opt_debug: - opts->debug = true; -+ break; - case Opt_fsuid: - opts->fs_low_uid = result.uint_32; - break; diff --git a/patches/ANDROID-security-perf-Allow-further-restriction-of-perf_event_open.patch b/patches/ANDROID-security-perf-Allow-further-restriction-of-perf_event_open.patch deleted file mode 100644 index e26f35e7f9af..000000000000 --- a/patches/ANDROID-security-perf-Allow-further-restriction-of-perf_event_open.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jeff Vander Stoep -Date: Sun, 29 May 2016 14:22:32 -0700 -Subject: ANDROID: security,perf: Allow further restriction of perf_event_open - -When kernel.perf_event_open is set to 3 (or greater), disallow all -access to performance events by users without CAP_SYS_ADMIN. -Add a Kconfig symbol CONFIG_SECURITY_PERF_EVENTS_RESTRICT that -makes this value the default. - -This is based on a similar feature in grsecurity -(CONFIG_GRKERNSEC_PERF_HARDEN). This version doesn't include making -the variable read-only. It also allows enabling further restriction -at run-time regardless of whether the default is changed. - -https://lkml.org/lkml/2016/1/11/587 - -Bug: 29054680 -Bug: 120445712 -Change-Id: Iff5bff4fc1042e85866df9faa01bce8d04335ab8 -[jeffv: Upstream doesn't want it https://lkml.org/lkml/2016/6/17/101] -Signed-off-by: Ben Hutchings ---- - Documentation/admin-guide/sysctl/kernel.rst | 5 ++++- - include/linux/perf_event.h | 5 +++++ - kernel/events/core.c | 8 ++++++++ - security/Kconfig | 9 +++++++++ - 4 files changed, 26 insertions(+), 1 deletion(-) - -diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst -index 032c7cd3cede..172fac5c58b1 100644 ---- a/Documentation/admin-guide/sysctl/kernel.rst -+++ b/Documentation/admin-guide/sysctl/kernel.rst -@@ -720,7 +720,8 @@ perf_event_paranoid: - ==================== - - Controls use of the performance events system by unprivileged --users (without CAP_SYS_ADMIN). The default value is 2. -+users (without CAP_SYS_ADMIN). The default value is 3 if -+CONFIG_SECURITY_PERF_EVENTS_RESTRICT is set, or 2 otherwise. - - === ================================================================== - -1 Allow use of (almost) all events by all users -@@ -734,6 +735,8 @@ users (without CAP_SYS_ADMIN). The default value is 2. - >=1 Disallow CPU event access by users without CAP_SYS_ADMIN - - >=2 Disallow kernel profiling by users without CAP_SYS_ADMIN -+ -+>=3: Disallow all event access by users without CAP_SYS_ADMIN - === ================================================================== - - -diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h -index 61448c19a132..a24e32410915 100644 ---- a/include/linux/perf_event.h -+++ b/include/linux/perf_event.h -@@ -1241,6 +1241,11 @@ extern int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, - int perf_event_max_stack_handler(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos); - -+static inline bool perf_paranoid_any(void) -+{ -+ return sysctl_perf_event_paranoid > 2; -+} -+ - static inline bool perf_paranoid_tracepoint_raw(void) - { - return sysctl_perf_event_paranoid > -1; -diff --git a/kernel/events/core.c b/kernel/events/core.c -index 9ec0b0bfddbd..db1cbe0b652d 100644 ---- a/kernel/events/core.c -+++ b/kernel/events/core.c -@@ -398,8 +398,13 @@ static cpumask_var_t perf_online_mask; - * 0 - disallow raw tracepoint access for unpriv - * 1 - disallow cpu events for unpriv - * 2 - disallow kernel profiling for unpriv -+ * 3 - disallow all unpriv perf event use - */ -+#ifdef CONFIG_SECURITY_PERF_EVENTS_RESTRICT -+int sysctl_perf_event_paranoid __read_mostly = 3; -+#else - int sysctl_perf_event_paranoid __read_mostly = 2; -+#endif - - /* Minimum for 512 kiB + 1 user control page */ - int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */ -@@ -10886,6 +10891,9 @@ SYSCALL_DEFINE5(perf_event_open, - if (flags & ~PERF_FLAG_ALL) - return -EINVAL; - -+ if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ - err = perf_copy_attr(attr_uptr, &attr); - if (err) - return err; -diff --git a/security/Kconfig b/security/Kconfig -index 2a1a2d396228..c66f43a36dbe 100644 ---- a/security/Kconfig -+++ b/security/Kconfig -@@ -19,6 +19,15 @@ config SECURITY_DMESG_RESTRICT - - If you are unsure how to answer this question, answer N. - -+config SECURITY_PERF_EVENTS_RESTRICT -+ bool "Restrict unprivileged use of performance events" -+ depends on PERF_EVENTS -+ help -+ If you say Y here, the kernel.perf_event_paranoid sysctl -+ will be set to 3 by default, and no unprivileged use of the -+ perf_event_open syscall will be permitted unless it is -+ changed. -+ - config SECURITY - bool "Enable different security models" - depends on SYSFS diff --git a/patches/ANDROID-staging-android-ion-Decouple-ION-page-pooling-from-ION-core.patch b/patches/ANDROID-staging-android-ion-Decouple-ION-page-pooling-from-ION-core.patch deleted file mode 100644 index 6359a88e6278..000000000000 --- a/patches/ANDROID-staging-android-ion-Decouple-ION-page-pooling-from-ION-core.patch +++ /dev/null @@ -1,181 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "Isaac J. Manjarres" -Date: Wed, 19 Jun 2019 15:37:15 -0700 -Subject: ANDROID: staging: android: ion: Decouple ION page pooling from ION - core - -Since page pooling is compiled together with the system heap, -and it is the only user, page pooling should not be a part -of the ION core. Thus, separate it out as a library, and -give it its own interface. - -Bug: 133508579 -Test: ion-unit-tests -Change-Id: I95909d250fc37a401d9e23264cd27c78a2a74637 -Signed-off-by: Isaac J. Manjarres -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/ion.h | 51 -------------- - drivers/staging/android/ion/ion_page_pool.c | 2 +- - drivers/staging/android/ion/ion_page_pool.h | 66 +++++++++++++++++++ - drivers/staging/android/ion/ion_system_heap.c | 1 + - 4 files changed, 68 insertions(+), 52 deletions(-) - create mode 100644 drivers/staging/android/ion/ion_page_pool.h - -diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h -index 74914a266e25..6f9f7c365f38 100644 ---- a/drivers/staging/android/ion/ion.h -+++ b/drivers/staging/android/ion/ion.h -@@ -249,55 +249,4 @@ size_t ion_heap_freelist_shrink(struct ion_heap *heap, - */ - size_t ion_heap_freelist_size(struct ion_heap *heap); - --/** -- * functions for creating and destroying a heap pool -- allows you -- * to keep a pool of pre allocated memory to use from your heap. Keeping -- * a pool of memory that is ready for dma, ie any cached mapping have been -- * invalidated from the cache, provides a significant performance benefit on -- * many systems -- */ -- --/** -- * struct ion_page_pool - pagepool struct -- * @high_count: number of highmem items in the pool -- * @low_count: number of lowmem items in the pool -- * @high_items: list of highmem items -- * @low_items: list of lowmem items -- * @mutex: lock protecting this struct and especially the count -- * item list -- * @gfp_mask: gfp_mask to use from alloc -- * @order: order of pages in the pool -- * @list: plist node for list of pools -- * -- * Allows you to keep a pool of pre allocated pages to use from your heap. -- * Keeping a pool of pages that is ready for dma, ie any cached mapping have -- * been invalidated from the cache, provides a significant performance benefit -- * on many systems -- */ --struct ion_page_pool { -- int high_count; -- int low_count; -- struct list_head high_items; -- struct list_head low_items; -- struct mutex mutex; -- gfp_t gfp_mask; -- unsigned int order; -- struct plist_node list; --}; -- --struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order); --void ion_page_pool_destroy(struct ion_page_pool *pool); --struct page *ion_page_pool_alloc(struct ion_page_pool *pool); --void ion_page_pool_free(struct ion_page_pool *pool, struct page *page); -- --/** ion_page_pool_shrink - shrinks the size of the memory cached in the pool -- * @pool: the pool -- * @gfp_mask: the memory type to reclaim -- * @nr_to_scan: number of items to shrink in pages -- * -- * returns the number of items freed in pages -- */ --int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, -- int nr_to_scan); -- - #endif /* _ION_H */ -diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c -index f85ec5b16b65..f1bc165e644e 100644 ---- a/drivers/staging/android/ion/ion_page_pool.c -+++ b/drivers/staging/android/ion/ion_page_pool.c -@@ -10,7 +10,7 @@ - #include - #include - --#include "ion.h" -+#include "ion_page_pool.h" - - static inline struct page *ion_page_pool_alloc_pages(struct ion_page_pool *pool) - { -diff --git a/drivers/staging/android/ion/ion_page_pool.h b/drivers/staging/android/ion/ion_page_pool.h -new file mode 100644 -index 000000000000..e205d0086833 ---- /dev/null -+++ b/drivers/staging/android/ion/ion_page_pool.h -@@ -0,0 +1,66 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * ION Page Pool kernel interface header -+ * -+ * Copyright (C) 2011 Google, Inc. -+ */ -+ -+#ifndef _ION_PAGE_POOL_H -+#define _ION_PAGE_POOL_H -+ -+#include -+#include -+#include -+#include -+ -+/** -+ * functions for creating and destroying a heap pool -- allows you -+ * to keep a pool of pre allocated memory to use from your heap. Keeping -+ * a pool of memory that is ready for dma, ie any cached mapping have been -+ * invalidated from the cache, provides a significant performance benefit on -+ * many systems -+ */ -+ -+/** -+ * struct ion_page_pool - pagepool struct -+ * @high_count: number of highmem items in the pool -+ * @low_count: number of lowmem items in the pool -+ * @high_items: list of highmem items -+ * @low_items: list of lowmem items -+ * @mutex: lock protecting this struct and especially the count -+ * item list -+ * @gfp_mask: gfp_mask to use from alloc -+ * @order: order of pages in the pool -+ * @list: plist node for list of pools -+ * -+ * Allows you to keep a pool of pre allocated pages to use from your heap. -+ * Keeping a pool of pages that is ready for dma, ie any cached mapping have -+ * been invalidated from the cache, provides a significant performance benefit -+ * on many systems -+ */ -+struct ion_page_pool { -+ int high_count; -+ int low_count; -+ struct list_head high_items; -+ struct list_head low_items; -+ struct mutex mutex; -+ gfp_t gfp_mask; -+ unsigned int order; -+ struct plist_node list; -+}; -+ -+struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order); -+void ion_page_pool_destroy(struct ion_page_pool *pool); -+struct page *ion_page_pool_alloc(struct ion_page_pool *pool); -+void ion_page_pool_free(struct ion_page_pool *pool, struct page *page); -+ -+/** ion_page_pool_shrink - shrinks the size of the memory cached in the pool -+ * @pool: the pool -+ * @gfp_mask: the memory type to reclaim -+ * @nr_to_scan: number of items to shrink in pages -+ * -+ * returns the number of items freed in pages -+ */ -+int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, -+ int nr_to_scan); -+#endif /* _ION_PAGE_POOL_H */ -diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c -index b83a1d16bd89..ee301df7b7b7 100644 ---- a/drivers/staging/android/ion/ion_system_heap.c -+++ b/drivers/staging/android/ion/ion_system_heap.c -@@ -15,6 +15,7 @@ - #include - - #include "ion.h" -+#include "ion_page_pool.h" - - #define NUM_ORDERS ARRAY_SIZE(orders) - diff --git a/patches/ANDROID-staging-android-ion-Expose-ion_alloc-to-kernel-space.patch b/patches/ANDROID-staging-android-ion-Expose-ion_alloc-to-kernel-space.patch deleted file mode 100644 index 6d922c9f0f20..000000000000 --- a/patches/ANDROID-staging-android-ion-Expose-ion_alloc-to-kernel-space.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: "Isaac J. Manjarres" -Date: Wed, 19 Jun 2019 15:37:14 -0700 -Subject: ANDROID: staging: android: ion: Expose ion_alloc() to kernel space - -Expose ion_alloc() to kernel space clients. Users of this -function will receive a dma-buf structure for sharing -the ION buffer that was allocated. - -Bug: 133508579 -Test: ion-unit-tests -Change-Id: I410044127ba92a759a79c65e422b0b75b74e2159 -Signed-off-by: Isaac J. Manjarres -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/ion.c | 40 +++++++++++++++++++++++-------- - include/linux/ion.h | 26 ++++++++++++++++++++ - 2 files changed, 56 insertions(+), 10 deletions(-) - create mode 100644 include/linux/ion.h - -diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c -index e6b1ca141b93..2e5c6ae2f3fc 100644 ---- a/drivers/staging/android/ion/ion.c -+++ b/drivers/staging/android/ion/ion.c -@@ -3,6 +3,8 @@ - * ION Memory Allocator - * - * Copyright (C) 2011 Google, Inc. -+ * Copyright (c) 2019, The Linux Foundation. All rights reserved. -+ * - */ - - #include -@@ -353,13 +355,13 @@ static const struct dma_buf_ops dma_buf_ops = { - .unmap = ion_dma_buf_kunmap, - }; - --static int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) -+static struct dma_buf *ion_alloc_dmabuf(size_t len, unsigned int heap_id_mask, -+ unsigned int flags) - { - struct ion_device *dev = internal_dev; - struct ion_buffer *buffer = NULL; - struct ion_heap *heap; - DEFINE_DMA_BUF_EXPORT_INFO(exp_info); -- int fd; - struct dma_buf *dmabuf; - - pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__, -@@ -373,7 +375,7 @@ static int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) - len = PAGE_ALIGN(len); - - if (!len) -- return -EINVAL; -+ return ERR_PTR(-EINVAL); - - down_read(&dev->lock); - plist_for_each_entry(heap, &dev->heaps, node) { -@@ -387,10 +389,10 @@ static int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) - up_read(&dev->lock); - - if (!buffer) -- return -ENODEV; -+ return ERR_PTR(-ENODEV); - - if (IS_ERR(buffer)) -- return PTR_ERR(buffer); -+ return ERR_CAST(buffer); - - exp_info.ops = &dma_buf_ops; - exp_info.size = buffer->size; -@@ -398,10 +400,28 @@ static int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) - exp_info.priv = buffer; - - dmabuf = dma_buf_export(&exp_info); -- if (IS_ERR(dmabuf)) { -+ if (IS_ERR(dmabuf)) - _ion_buffer_destroy(buffer); -+ -+ return dmabuf; -+} -+ -+struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, -+ unsigned int flags) -+{ -+ return ion_alloc_dmabuf(len, heap_id_mask, flags); -+} -+EXPORT_SYMBOL_GPL(ion_alloc); -+ -+static int ion_alloc_fd(size_t len, unsigned int heap_id_mask, -+ unsigned int flags) -+{ -+ int fd; -+ struct dma_buf *dmabuf; -+ -+ dmabuf = ion_alloc_dmabuf(len, heap_id_mask, flags); -+ if (IS_ERR(dmabuf)) - return PTR_ERR(dmabuf); -- } - - fd = dma_buf_fd(dmabuf, O_CLOEXEC); - if (fd < 0) -@@ -506,9 +526,9 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) - { - int fd; - -- fd = ion_alloc(data.allocation.len, -- data.allocation.heap_id_mask, -- data.allocation.flags); -+ fd = ion_alloc_fd(data.allocation.len, -+ data.allocation.heap_id_mask, -+ data.allocation.flags); - if (fd < 0) - return fd; - -diff --git a/include/linux/ion.h b/include/linux/ion.h -new file mode 100644 -index 000000000000..7bec77d98224 ---- /dev/null -+++ b/include/linux/ion.h -@@ -0,0 +1,26 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+/* -+ * Copyright (c) 2019, The Linux Foundation. All rights reserved. -+ */ -+ -+#ifndef _ION_KERNEL_H -+#define _ION_KERNEL_H -+ -+#include -+#include -+ -+#ifdef CONFIG_ION -+/* -+ * Allocates an ION buffer. -+ */ -+struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, -+ unsigned int flags); -+ -+#else -+static inline struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, -+ unsigned int flags) -+{ -+ return ERR_PTR(-ENOMEM); -+} -+#endif /* CONFIG_ION */ -+#endif /* _ION_KERNEL_H */ diff --git a/patches/ANDROID-staging-ion-Add-support-for-heap-specific-dma_buf_ops.patch b/patches/ANDROID-staging-ion-Add-support-for-heap-specific-dma_buf_ops.patch deleted file mode 100644 index 776750716d20..000000000000 --- a/patches/ANDROID-staging-ion-Add-support-for-heap-specific-dma_buf_ops.patch +++ /dev/null @@ -1,331 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Sun, 1 Sep 2019 22:38:52 -0700 -Subject: ANDROID: staging: ion: Add support for heap-specific dma_buf_ops - -All dma_buf ops are registered by ion core. However, if a given heap -provides a specific dmabuf operation, that will be preferred over the -default ion core implementation - -Some dma_buf_ops like get_flags, begin_cpu_access_partial etc are -entirely not supported by ion core and will return -EOPNOTSUPP if the -heap implementation doesn't provided the necessary overrides. - -Tested with ion unit test with default system heap. - -Bug: 133508579 -Bug: 140290587 -Test: ion-unit-test - -Change-Id: Id13c5c280064b6f47de327223733c2c393f1a41a -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/ion_dma_buf.c | 207 +++++++++++++++++----- - include/linux/ion.h | 2 + - 2 files changed, 163 insertions(+), 46 deletions(-) - -diff --git a/drivers/staging/android/ion/ion_dma_buf.c b/drivers/staging/android/ion/ion_dma_buf.c -index 0de08e6f1af5..e52db6a182ae 100644 ---- a/drivers/staging/android/ion/ion_dma_buf.c -+++ b/drivers/staging/android/ion/ion_dma_buf.c -@@ -6,7 +6,6 @@ - */ - - #include --#include - #include - #include - #include -@@ -96,80 +95,68 @@ static void ion_dma_buf_detatch(struct dma_buf *dmabuf, - kfree(a); - } - --static struct sg_table *ion_dma_buf_map(struct dma_buf_attachment *attachment, -+static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment, - enum dma_data_direction direction) - { -- struct ion_dma_buf_attachment *a = attachment->priv; -+ struct ion_buffer *buffer = attachment->dmabuf->priv; -+ struct ion_heap *heap = buffer->heap; -+ struct ion_dma_buf_attachment *a; - struct sg_table *table; - -+ if (heap->buf_ops.map_dma_buf) -+ return heap->buf_ops.map_dma_buf(attachment, direction); -+ -+ a = attachment->priv; - table = a->table; - -- if (!dma_map_sg(attachment->dev, table->sgl, table->nents, -- direction)) -+ if (!dma_map_sg(attachment->dev, table->sgl, table->nents, direction)) - return ERR_PTR(-ENOMEM); - - return table; - } - --static void ion_dma_buf_unmap(struct dma_buf_attachment *attachment, -+static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment, - struct sg_table *table, - enum dma_data_direction direction) - { -- dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); --} -- --static int ion_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) --{ -- struct ion_buffer *buffer = dmabuf->priv; -- int ret = 0; -+ struct ion_buffer *buffer = attachment->dmabuf->priv; -+ struct ion_heap *heap = buffer->heap; - -- if (!buffer->heap->ops->map_user) { -- pr_err("%s: this heap does not define a method for mapping to userspace\n", -- __func__); -- return -EINVAL; -- } -- -- if (!(buffer->flags & ION_FLAG_CACHED)) -- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); -+ if (heap->buf_ops.unmap_dma_buf) -+ return heap->buf_ops.unmap_dma_buf(attachment, table, -+ direction); - -- mutex_lock(&buffer->lock); -- /* now map it to userspace */ -- ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma); -- mutex_unlock(&buffer->lock); -- -- if (ret) -- pr_err("%s: failure mapping buffer to userspace\n", -- __func__); -- -- return ret; -+ dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); - } - - static void ion_dma_buf_release(struct dma_buf *dmabuf) - { - struct ion_buffer *buffer = dmabuf->priv; -+ struct ion_heap *heap = buffer->heap; - -- ion_free(buffer); --} -- --static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) --{ -- struct ion_buffer *buffer = dmabuf->priv; -+ if (heap->buf_ops.release) -+ return heap->buf_ops.release(dmabuf); - -- return buffer->vaddr + offset * PAGE_SIZE; -+ ion_free(buffer); - } - - static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, - enum dma_data_direction direction) - { - struct ion_buffer *buffer = dmabuf->priv; -+ struct ion_heap *heap = buffer->heap; - void *vaddr; - struct ion_dma_buf_attachment *a; -- int ret = 0; -+ int ret; -+ -+ if (heap->buf_ops.begin_cpu_access) -+ return heap->buf_ops.begin_cpu_access(dmabuf, direction); - - /* - * TODO: Move this elsewhere because we don't always need a vaddr - */ -- if (buffer->heap->ops->map_kernel) { -+ ret = 0; -+ if (heap->ops->map_kernel) { - mutex_lock(&buffer->lock); - vaddr = ion_buffer_kmap_get(buffer); - if (IS_ERR(vaddr)) { -@@ -190,13 +177,36 @@ static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, - return ret; - } - -+static int -+ion_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf, -+ enum dma_data_direction direction, -+ unsigned int offset, unsigned int len) -+{ -+ struct ion_buffer *buffer = dmabuf->priv; -+ struct ion_heap *heap = buffer->heap; -+ -+ /* This is done to make sure partial buffer cache flush / invalidate is -+ * allowed. The implementation may be vendor specific in this case, so -+ * ion core does not provide a default implementation -+ */ -+ if (!heap->buf_ops.begin_cpu_access_partial) -+ return -EOPNOTSUPP; -+ -+ return heap->buf_ops.begin_cpu_access_partial(dmabuf, direction, offset, -+ len); -+} -+ - static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, - enum dma_data_direction direction) - { - struct ion_buffer *buffer = dmabuf->priv; -+ struct ion_heap *heap = buffer->heap; - struct ion_dma_buf_attachment *a; - -- if (buffer->heap->ops->map_kernel) { -+ if (heap->buf_ops.end_cpu_access) -+ return heap->buf_ops.end_cpu_access(dmabuf, direction); -+ -+ if (heap->ops->map_kernel) { - mutex_lock(&buffer->lock); - ion_buffer_kmap_put(buffer); - mutex_unlock(&buffer->lock); -@@ -212,16 +222,121 @@ static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, - return 0; - } - -+static int ion_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf, -+ enum dma_data_direction direction, -+ unsigned int offset, -+ unsigned int len) -+{ -+ struct ion_buffer *buffer = dmabuf->priv; -+ struct ion_heap *heap = buffer->heap; -+ -+ /* This is done to make sure partial buffer cache flush / invalidate is -+ * allowed. The implementation may be vendor specific in this case, so -+ * ion core does not provide a default implementation -+ */ -+ if (!heap->buf_ops.end_cpu_access_partial) -+ return -EOPNOTSUPP; -+ -+ return heap->buf_ops.end_cpu_access_partial(dmabuf, direction, offset, -+ len); -+} -+ -+static void *ion_dma_buf_map(struct dma_buf *dmabuf, unsigned long offset) -+{ -+ struct ion_buffer *buffer = dmabuf->priv; -+ struct ion_heap *heap = buffer->heap; -+ -+ if (heap->buf_ops.map) -+ return heap->buf_ops.map(dmabuf, offset); -+ -+ return buffer->vaddr + offset * PAGE_SIZE; -+} -+ -+static int ion_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) -+{ -+ struct ion_buffer *buffer = dmabuf->priv; -+ struct ion_heap *heap = buffer->heap; -+ int ret; -+ -+ /* now map it to userspace */ -+ if (heap->buf_ops.mmap) { -+ ret = heap->buf_ops.mmap(dmabuf, vma); -+ } else { -+ mutex_lock(&buffer->lock); -+ if (!(buffer->flags & ION_FLAG_CACHED)) -+ vma->vm_page_prot = -+ pgprot_writecombine(vma->vm_page_prot); -+ -+ ret = ion_heap_map_user(heap, buffer, vma); -+ mutex_unlock(&buffer->lock); -+ } -+ -+ if (ret) -+ pr_err("%s: failure mapping buffer to userspace\n", __func__); -+ -+ return ret; -+} -+ -+static void ion_dma_buf_unmap(struct dma_buf *dmabuf, unsigned long offset, -+ void *addr) -+{ -+ struct ion_buffer *buffer = dmabuf->priv; -+ struct ion_heap *heap = buffer->heap; -+ -+ if (!heap->buf_ops.unmap) -+ return; -+ heap->buf_ops.unmap(dmabuf, offset, addr); -+} -+ -+static void *ion_dma_buf_vmap(struct dma_buf *dmabuf) -+{ -+ struct ion_buffer *buffer = dmabuf->priv; -+ struct ion_heap *heap = buffer->heap; -+ -+ if (!heap->buf_ops.vmap) -+ return ERR_PTR(-EOPNOTSUPP); -+ -+ return heap->buf_ops.vmap(dmabuf); -+} -+ -+static void ion_dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr) -+{ -+ struct ion_buffer *buffer = dmabuf->priv; -+ struct ion_heap *heap = buffer->heap; -+ -+ if (!heap->buf_ops.vunmap) -+ return; -+ -+ return heap->buf_ops.vunmap(dmabuf, vaddr); -+} -+ -+static int ion_dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags) -+{ -+ struct ion_buffer *buffer = dmabuf->priv; -+ struct ion_heap *heap = buffer->heap; -+ -+ if (!heap->buf_ops.get_flags) -+ return -EOPNOTSUPP; -+ -+ return heap->buf_ops.get_flags(dmabuf, flags); -+} -+ - static const struct dma_buf_ops dma_buf_ops = { -- .map_dma_buf = ion_dma_buf_map, -- .unmap_dma_buf = ion_dma_buf_unmap, -- .mmap = ion_dma_buf_mmap, -- .release = ion_dma_buf_release, - .attach = ion_dma_buf_attach, - .detach = ion_dma_buf_detatch, -+ .map_dma_buf = ion_map_dma_buf, -+ .unmap_dma_buf = ion_unmap_dma_buf, -+ .release = ion_dma_buf_release, - .begin_cpu_access = ion_dma_buf_begin_cpu_access, -+ .begin_cpu_access_partial = ion_dma_buf_begin_cpu_access_partial, - .end_cpu_access = ion_dma_buf_end_cpu_access, -- .map = ion_dma_buf_kmap, -+ .end_cpu_access_partial = ion_dma_buf_end_cpu_access_partial, -+ .mmap = ion_dma_buf_mmap, -+ .map = ion_dma_buf_map, -+ .unmap = ion_dma_buf_unmap, -+ .vmap = ion_dma_buf_vmap, -+ .vunmap = ion_dma_buf_vunmap, -+ .get_flags = ion_dma_buf_get_flags, - }; - - struct dma_buf *ion_dmabuf_alloc(struct ion_device *dev, size_t len, -diff --git a/include/linux/ion.h b/include/linux/ion.h -index 5d68674b015a..1e4846db0c6d 100644 ---- a/include/linux/ion.h -+++ b/include/linux/ion.h -@@ -101,6 +101,7 @@ struct ion_heap_ops { - * @node: rb node to put the heap on the device's tree of heaps - * @type: type of heap - * @ops: ops struct as above -+ * @buf_ops: dma_buf ops specific to the heap implementation. - * @flags: flags - * @id: id of heap, also indicates priority of this heap when - * allocating. These are specified by platform data and -@@ -126,6 +127,7 @@ struct ion_heap { - struct plist_node node; - enum ion_heap_type type; - struct ion_heap_ops *ops; -+ struct dma_buf_ops buf_ops; - unsigned long flags; - unsigned int id; - const char *name; diff --git a/patches/ANDROID-staging-ion-Build-fix-for-mips.patch b/patches/ANDROID-staging-ion-Build-fix-for-mips.patch deleted file mode 100644 index 3f51840c86ed..000000000000 --- a/patches/ANDROID-staging-ion-Build-fix-for-mips.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alistair Delva -Date: Mon, 19 Aug 2019 18:27:29 -0700 -Subject: ANDROID: staging: ion: Build fix for mips - -Bug: 133508579 -Change-Id: Ie795483ace50537029921d86347f38bd1e5ee58a -Signed-off-by: Alistair Delva ---- - drivers/staging/android/ion/ion_buffer.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/staging/android/ion/ion_buffer.c b/drivers/staging/android/ion/ion_buffer.c -index 879b3ddb08c0..961605a35c59 100644 ---- a/drivers/staging/android/ion/ion_buffer.c -+++ b/drivers/staging/android/ion/ion_buffer.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - - #include "ion_private.h" - diff --git a/patches/ANDROID-staging-ion-Fix-uninitialized-variable-warning.patch b/patches/ANDROID-staging-ion-Fix-uninitialized-variable-warning.patch deleted file mode 100644 index c6e15e5dfcaa..000000000000 --- a/patches/ANDROID-staging-ion-Fix-uninitialized-variable-warning.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Fri, 30 Aug 2019 14:46:57 -0700 -Subject: ANDROID: staging: ion: Fix uninitialized variable warning - -Warning: - In file included from include/linux/bitops.h:19:0, - from include/linux/bitmap.h:8, - from drivers/staging/android/ion/ion.c:10: - drivers/staging/android/ion/ion.c: In function '__ion_device_add_heap': ->> arch/m68k/include/asm/bitops.h:371:28: warning: 'end_bit' may be used uninitialized in this function [-Wmaybe-uninitialized] - #define find_next_zero_bit find_next_zero_bit - ^~~~~~~~~~~~~~~~~~ - drivers/staging/android/ion/ion.c:228:17: note: 'end_bit' was declared here - int start_bit, end_bit; - ^~~~~~~ - In file included from include/linux/bitops.h:19:0, - from include/linux/bitmap.h:8, - from drivers/staging/android/ion/ion.c:10: ->> arch/m68k/include/asm/bitops.h:354:10: warning: 'start_bit' may be used uninitialized in this function [-Wmaybe-uninitialized] - offset -= bit; - ~~~~~~~^~~~~~ - drivers/staging/android/ion/ion.c:228:6: note: 'start_bit' was declared here - int start_bit, end_bit; - ^~~~~~~~~ - -Change-Id: I2df4a5b36f457aca5f19c03976ae7229c35ecdb3 -Reported-by: kbuild test robot -Fixes: acbfdf321afb ("ANDROID: staging: ion: add support for consistent heap ids") -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/ion.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c -index c7be7457a709..c8ed051715bc 100644 ---- a/drivers/staging/android/ion/ion.c -+++ b/drivers/staging/android/ion/ion.c -@@ -225,7 +225,7 @@ DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, - static int ion_assign_heap_id(struct ion_heap *heap, struct ion_device *dev) - { - int id_bit; -- int start_bit, end_bit; -+ int start_bit, end_bit = -1; - - switch (heap->type) { - case ION_HEAP_TYPE_SYSTEM: diff --git a/patches/ANDROID-staging-ion-Move-ion-heaps-into-their-own-directory.patch b/patches/ANDROID-staging-ion-Move-ion-heaps-into-their-own-directory.patch deleted file mode 100644 index a4f3e0d0556b..000000000000 --- a/patches/ANDROID-staging-ion-Move-ion-heaps-into-their-own-directory.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Thu, 8 Aug 2019 08:00:53 -0700 -Subject: ANDROID: staging: ion: Move ion heaps into their own directory - -This is preparatory work for ION heaps to be kernel modules, so -they stay in their own directory inside ION. The heap modules are -planned to be *overridable*, so it makes sense to isolate them -in source to explicitly draw the line between what is a kernel API. - -Bug: 133508579 -Test: ion-unit-tests - -Change-Id: Iefc4e22d186139832f54b9cfc629383fb6698fc6 -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/Kconfig | 15 +-------------- - drivers/staging/android/ion/Makefile | 5 ++--- - drivers/staging/android/ion/heaps/Kconfig | 15 +++++++++++++++ - drivers/staging/android/ion/heaps/Makefile | 3 +++ - .../android/ion/{ => heaps}/ion_cma_heap.c | 2 +- - .../android/ion/{ => heaps}/ion_page_pool.c | 0 - .../android/ion/{ => heaps}/ion_page_pool.h | 0 - .../android/ion/{ => heaps}/ion_system_heap.c | 2 +- - 8 files changed, 23 insertions(+), 19 deletions(-) - create mode 100644 drivers/staging/android/ion/heaps/Kconfig - create mode 100644 drivers/staging/android/ion/heaps/Makefile - rename drivers/staging/android/ion/{ => heaps}/ion_cma_heap.c (99%) - rename drivers/staging/android/ion/{ => heaps}/ion_page_pool.c (100%) - rename drivers/staging/android/ion/{ => heaps}/ion_page_pool.h (100%) - rename drivers/staging/android/ion/{ => heaps}/ion_system_heap.c (99%) - -diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig -index 989fe84a9f9d..7b7da979991e 100644 ---- a/drivers/staging/android/ion/Kconfig -+++ b/drivers/staging/android/ion/Kconfig -@@ -11,17 +11,4 @@ menuconfig ION - If you're not using Android its probably safe to - say N here. - --config ION_SYSTEM_HEAP -- bool "Ion system heap" -- depends on ION -- help -- Choose this option to enable the Ion system heap. The system heap -- is backed by pages from the buddy allocator. If in doubt, say Y. -- --config ION_CMA_HEAP -- bool "Ion CMA heap support" -- depends on ION && DMA_CMA -- help -- Choose this option to enable CMA heaps with Ion. This heap is backed -- by the Contiguous Memory Allocator (CMA). If your system has these -- regions, you should say Y here. -+source "drivers/staging/android/ion/heaps/Kconfig" -diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile -index b6fab2816781..1f7704e02fb0 100644 ---- a/drivers/staging/android/ion/Makefile -+++ b/drivers/staging/android/ion/Makefile -@@ -1,4 +1,3 @@ - # SPDX-License-Identifier: GPL-2.0 --obj-$(CONFIG_ION) += ion.o ion_buffer.o ion_dma_buf.o ion_heap.o --obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o --obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o -+obj-$(CONFIG_ION) += ion.o ion_buffer.o ion_dma_buf.o ion_heap.o -+obj-y += heaps/ -diff --git a/drivers/staging/android/ion/heaps/Kconfig b/drivers/staging/android/ion/heaps/Kconfig -new file mode 100644 -index 000000000000..7affa91ecabb ---- /dev/null -+++ b/drivers/staging/android/ion/heaps/Kconfig -@@ -0,0 +1,15 @@ -+# SPDX-License-Identifier: GPL-2.0 -+config ION_SYSTEM_HEAP -+ bool "Ion system heap" -+ depends on ION -+ help -+ Choose this option to enable the Ion system heap. The system heap -+ is backed by pages from the buddy allocator. If in doubt, say Y. -+ -+config ION_CMA_HEAP -+ bool "Ion CMA heap support" -+ depends on ION && DMA_CMA -+ help -+ Choose this option to enable CMA heaps with Ion. This heap is backed -+ by the Contiguous Memory Allocator (CMA). If your system has these -+ regions, you should say Y here. -diff --git a/drivers/staging/android/ion/heaps/Makefile b/drivers/staging/android/ion/heaps/Makefile -new file mode 100644 -index 000000000000..127912629f0b ---- /dev/null -+++ b/drivers/staging/android/ion/heaps/Makefile -@@ -0,0 +1,3 @@ -+# SPDX-License-Identifier: GPL-2.0 -+obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o -+obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o -diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/heaps/ion_cma_heap.c -similarity index 99% -rename from drivers/staging/android/ion/ion_cma_heap.c -rename to drivers/staging/android/ion/heaps/ion_cma_heap.c -index bf65e67ef9d8..0872e5d630f8 100644 ---- a/drivers/staging/android/ion/ion_cma_heap.c -+++ b/drivers/staging/android/ion/heaps/ion_cma_heap.c -@@ -14,7 +14,7 @@ - #include - #include - --#include "ion.h" -+#include "../ion.h" - - struct ion_cma_heap { - struct ion_heap heap; -diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/heaps/ion_page_pool.c -similarity index 100% -rename from drivers/staging/android/ion/ion_page_pool.c -rename to drivers/staging/android/ion/heaps/ion_page_pool.c -diff --git a/drivers/staging/android/ion/ion_page_pool.h b/drivers/staging/android/ion/heaps/ion_page_pool.h -similarity index 100% -rename from drivers/staging/android/ion/ion_page_pool.h -rename to drivers/staging/android/ion/heaps/ion_page_pool.h -diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/heaps/ion_system_heap.c -similarity index 99% -rename from drivers/staging/android/ion/ion_system_heap.c -rename to drivers/staging/android/ion/heaps/ion_system_heap.c -index d1cb9e69399e..8e26016082d4 100644 ---- a/drivers/staging/android/ion/ion_system_heap.c -+++ b/drivers/staging/android/ion/heaps/ion_system_heap.c -@@ -14,7 +14,7 @@ - #include - #include - --#include "ion.h" -+#include "../ion.h" - #include "ion_page_pool.h" - - #define NUM_ORDERS ARRAY_SIZE(orders) diff --git a/patches/ANDROID-staging-ion-Remove-unnecessary-ion-heap-ops.patch b/patches/ANDROID-staging-ion-Remove-unnecessary-ion-heap-ops.patch deleted file mode 100644 index 96c805e0a3b7..000000000000 --- a/patches/ANDROID-staging-ion-Remove-unnecessary-ion-heap-ops.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Sun, 1 Sep 2019 23:02:37 -0700 -Subject: ANDROID: staging: ion: Remove unnecessary ion heap ops - -The heap operations are redundant now that we have default -dma_buf operations. So, remove them. - -Bug: 133508579 -Bug: 140290587 -Test: ion-unit-tests - -Change-Id: I8f87c22896e128f48ed222421cabc23ab238ff69 -Signed-off-by: Sandeep Patil ---- - .../staging/android/ion/heaps/ion_cma_heap.c | 3 --- - .../ion/heaps/ion_system_contig_heap.c | 3 --- - .../android/ion/heaps/ion_system_heap.c | 3 --- - drivers/staging/android/ion/ion_buffer.c | 6 ++--- - drivers/staging/android/ion/ion_dma_buf.c | 25 +++++++------------ - include/linux/ion.h | 9 +------ - 6 files changed, 13 insertions(+), 36 deletions(-) - -diff --git a/drivers/staging/android/ion/heaps/ion_cma_heap.c b/drivers/staging/android/ion/heaps/ion_cma_heap.c -index 83f7dce74f18..236b6c576cdb 100644 ---- a/drivers/staging/android/ion/heaps/ion_cma_heap.c -+++ b/drivers/staging/android/ion/heaps/ion_cma_heap.c -@@ -95,9 +95,6 @@ static void ion_cma_free(struct ion_buffer *buffer) - static struct ion_heap_ops ion_cma_ops = { - .allocate = ion_cma_allocate, - .free = ion_cma_free, -- .map_user = ion_heap_map_user, -- .map_kernel = ion_heap_map_kernel, -- .unmap_kernel = ion_heap_unmap_kernel, - }; - - static struct ion_heap *__ion_cma_heap_create(struct cma *cma) -diff --git a/drivers/staging/android/ion/heaps/ion_system_contig_heap.c b/drivers/staging/android/ion/heaps/ion_system_contig_heap.c -index 9cb18e38dc96..36e8769f3ef7 100644 ---- a/drivers/staging/android/ion/heaps/ion_system_contig_heap.c -+++ b/drivers/staging/android/ion/heaps/ion_system_contig_heap.c -@@ -77,9 +77,6 @@ static void ion_system_contig_heap_free(struct ion_buffer *buffer) - static struct ion_heap_ops kmalloc_ops = { - .allocate = ion_system_contig_heap_allocate, - .free = ion_system_contig_heap_free, -- .map_kernel = ion_heap_map_kernel, -- .unmap_kernel = ion_heap_unmap_kernel, -- .map_user = ion_heap_map_user, - }; - - static struct ion_heap contig_heap = { -diff --git a/drivers/staging/android/ion/heaps/ion_system_heap.c b/drivers/staging/android/ion/heaps/ion_system_heap.c -index 3aed952c219d..792cd130e493 100644 ---- a/drivers/staging/android/ion/heaps/ion_system_heap.c -+++ b/drivers/staging/android/ion/heaps/ion_system_heap.c -@@ -241,9 +241,6 @@ static int ion_system_heap_create_pools(struct ion_page_pool **pools) - static struct ion_heap_ops system_heap_ops = { - .allocate = ion_system_heap_allocate, - .free = ion_system_heap_free, -- .map_kernel = ion_heap_map_kernel, -- .unmap_kernel = ion_heap_unmap_kernel, -- .map_user = ion_heap_map_user, - .shrink = ion_system_heap_shrink, - }; - -diff --git a/drivers/staging/android/ion/ion_buffer.c b/drivers/staging/android/ion/ion_buffer.c -index 961605a35c59..4157f5d040f2 100644 ---- a/drivers/staging/android/ion/ion_buffer.c -+++ b/drivers/staging/android/ion/ion_buffer.c -@@ -201,7 +201,7 @@ void ion_buffer_release(struct ion_buffer *buffer) - if (buffer->kmap_cnt > 0) { - pr_warn_once("%s: buffer still mapped in the kernel\n", - __func__); -- buffer->heap->ops->unmap_kernel(buffer->heap, buffer); -+ ion_heap_unmap_kernel(buffer->heap, buffer); - } - buffer->heap->ops->free(buffer); - spin_lock(&buffer->heap->stat_lock); -@@ -245,7 +245,7 @@ void *ion_buffer_kmap_get(struct ion_buffer *buffer) - buffer->kmap_cnt++; - return buffer->vaddr; - } -- vaddr = buffer->heap->ops->map_kernel(buffer->heap, buffer); -+ vaddr = ion_heap_map_kernel(buffer->heap, buffer); - if (WARN_ONCE(!vaddr, - "heap->ops->map_kernel should return ERR_PTR on error")) - return ERR_PTR(-EINVAL); -@@ -260,7 +260,7 @@ void ion_buffer_kmap_put(struct ion_buffer *buffer) - { - buffer->kmap_cnt--; - if (!buffer->kmap_cnt) { -- buffer->heap->ops->unmap_kernel(buffer->heap, buffer); -+ ion_heap_unmap_kernel(buffer->heap, buffer); - buffer->vaddr = NULL; - } - } -diff --git a/drivers/staging/android/ion/ion_dma_buf.c b/drivers/staging/android/ion/ion_dma_buf.c -index e52db6a182ae..7ded926f52d4 100644 ---- a/drivers/staging/android/ion/ion_dma_buf.c -+++ b/drivers/staging/android/ion/ion_dma_buf.c -@@ -154,19 +154,16 @@ static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, - - /* - * TODO: Move this elsewhere because we don't always need a vaddr -+ * FIXME: Why do we need a vaddr here? - */ - ret = 0; -- if (heap->ops->map_kernel) { -- mutex_lock(&buffer->lock); -- vaddr = ion_buffer_kmap_get(buffer); -- if (IS_ERR(vaddr)) { -- ret = PTR_ERR(vaddr); -- goto unlock; -- } -- mutex_unlock(&buffer->lock); -+ mutex_lock(&buffer->lock); -+ vaddr = ion_buffer_kmap_get(buffer); -+ if (IS_ERR(vaddr)) { -+ ret = PTR_ERR(vaddr); -+ goto unlock; - } - -- mutex_lock(&buffer->lock); - list_for_each_entry(a, &buffer->attachments, list) { - dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, - direction); -@@ -206,13 +203,9 @@ static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, - if (heap->buf_ops.end_cpu_access) - return heap->buf_ops.end_cpu_access(dmabuf, direction); - -- if (heap->ops->map_kernel) { -- mutex_lock(&buffer->lock); -- ion_buffer_kmap_put(buffer); -- mutex_unlock(&buffer->lock); -- } -- - mutex_lock(&buffer->lock); -+ -+ ion_buffer_kmap_put(buffer); - list_for_each_entry(a, &buffer->attachments, list) { - dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, - direction); -@@ -249,7 +242,7 @@ static void *ion_dma_buf_map(struct dma_buf *dmabuf, unsigned long offset) - if (heap->buf_ops.map) - return heap->buf_ops.map(dmabuf, offset); - -- return buffer->vaddr + offset * PAGE_SIZE; -+ return ion_buffer_kmap_get(buffer) + offset * PAGE_SIZE; - } - - static int ion_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) -diff --git a/include/linux/ion.h b/include/linux/ion.h -index 1e4846db0c6d..87aa2bcec7d3 100644 ---- a/include/linux/ion.h -+++ b/include/linux/ion.h -@@ -57,11 +57,8 @@ struct ion_buffer { - * struct ion_heap_ops - ops to operate on a given heap - * @allocate: allocate memory - * @free: free memory -- * @map_kernel map memory to the kernel -- * @unmap_kernel unmap memory to the kernel -- * @map_user map memory to userspace - * -- * allocate, phys, and map_user return 0 on success, -errno on error. -+ * allocate returns 0 on success, -errno on error. - * map_dma and map_kernel return pointer on success, ERR_PTR on - * error. @free will be called with ION_PRIV_FLAG_SHRINKER_FREE set in - * the buffer's private_flags when called from a shrinker. In that -@@ -73,10 +70,6 @@ struct ion_heap_ops { - struct ion_buffer *buffer, unsigned long len, - unsigned long flags); - void (*free)(struct ion_buffer *buffer); -- void * (*map_kernel)(struct ion_heap *heap, struct ion_buffer *buffer); -- void (*unmap_kernel)(struct ion_heap *heap, struct ion_buffer *buffer); -- int (*map_user)(struct ion_heap *mapper, struct ion_buffer *buffer, -- struct vm_area_struct *vma); - int (*shrink)(struct ion_heap *heap, gfp_t gfp_mask, int nr_to_scan); - }; - diff --git a/patches/ANDROID-staging-ion-add-support-for-consistent-heap-ids.patch b/patches/ANDROID-staging-ion-add-support-for-consistent-heap-ids.patch deleted file mode 100644 index 795e97974767..000000000000 --- a/patches/ANDROID-staging-ion-add-support-for-consistent-heap-ids.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Mon, 26 Aug 2019 22:46:07 -0700 -Subject: ANDROID: staging: ion: add support for consistent heap ids - -heap id is part of ION's UAPI. Since the heaps are now kernel modules, -the current scheme of incrementing the heap id for the next heap doesn't -work. For example, if one insert->remove->insert the system heap module, -the heap id associated with the system heap changes. This immediately -breaks all of userspace. - -So, in order to fix this, we reserve first 16 heap ids for GKI heaps -and leave 16 more heap ids for any custom heap type that may exist. - -Bug: 133508579 -Test: ion-unit-test -Test: ion-unit-test (after removal and insertion of system heap module) - -Change-Id: I8412e590263869e029151a017b072399f54206f0 -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/ion.c | 79 ++++++++++++++++++++++- - drivers/staging/android/ion/ion_private.h | 5 +- - 2 files changed, 80 insertions(+), 4 deletions(-) - -diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c -index 548d65dbd3ac..c7be7457a709 100644 ---- a/drivers/staging/android/ion/ion.c -+++ b/drivers/staging/android/ion/ion.c -@@ -7,6 +7,7 @@ - * - */ - -+#include - #include - #include - #include -@@ -27,7 +28,6 @@ - #include "ion_private.h" - - static struct ion_device *internal_dev; --static int heap_id; - - /* Entry into ION allocator for rest of the kernel */ - struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, -@@ -222,6 +222,69 @@ static int debug_shrink_get(void *data, u64 *val) - DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, - debug_shrink_set, "%llu\n"); - -+static int ion_assign_heap_id(struct ion_heap *heap, struct ion_device *dev) -+{ -+ int id_bit; -+ int start_bit, end_bit; -+ -+ switch (heap->type) { -+ case ION_HEAP_TYPE_SYSTEM: -+ id_bit = ffs(ION_HEAP_SYSTEM); -+ break; -+ case ION_HEAP_TYPE_SYSTEM_CONTIG: -+ id_bit = ffs(ION_HEAP_SYSTEM_CONTIG); -+ break; -+ case ION_HEAP_TYPE_CHUNK: -+ id_bit = ffs(ION_HEAP_CHUNK); -+ break; -+ case ION_HEAP_TYPE_CARVEOUT: -+ id_bit = 0; -+ start_bit = ffs(ION_HEAP_CARVEOUT_START); -+ end_bit = ffs(ION_HEAP_CARVEOUT_END); -+ break; -+ case ION_HEAP_TYPE_DMA: -+ id_bit = 0; -+ start_bit = ffs(ION_HEAP_DMA_START); -+ end_bit = ffs(ION_HEAP_DMA_END); -+ break; -+ case ION_HEAP_TYPE_CUSTOM ... ION_HEAP_TYPE_MAX: -+ id_bit = 0; -+ start_bit = ffs(ION_HEAP_CUSTOM_START); -+ end_bit = ffs(ION_HEAP_CUSTOM_END); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* For carveout, dma & custom heaps, we first let the heaps choose their -+ * own IDs. This allows the old behaviour of knowing the heap ids -+ * of these type of heaps in advance in user space. If a heap with -+ * that ID already exists, it is an error. -+ * -+ * If the heap hasn't picked an id by itself, then we assign it -+ * one. -+ */ -+ if (!id_bit) { -+ if (heap->id) { -+ id_bit = ffs(heap->id); -+ if (id_bit < start_bit || id_bit > end_bit) -+ return -EINVAL; -+ } else { -+ id_bit = find_next_zero_bit(dev->heap_ids, end_bit + 1, -+ start_bit); -+ if (id_bit > end_bit) -+ return -ENOSPC; -+ } -+ } -+ -+ if (test_and_set_bit(id_bit - 1, dev->heap_ids)) -+ return -EEXIST; -+ heap->id = id_bit; -+ dev->heap_cnt++; -+ -+ return 0; -+} -+ - int __ion_device_add_heap(struct ion_heap *heap, struct module *owner) - { - struct ion_device *dev = internal_dev; -@@ -283,7 +346,14 @@ int __ion_device_add_heap(struct ion_heap *heap, struct module *owner) - - heap->debugfs_dir = heap_root; - down_write(&dev->lock); -- heap->id = heap_id++; -+ ret = ion_assign_heap_id(heap, dev); -+ if (ret) { -+ pr_err("%s: Failed to assign heap id for heap type %x\n", -+ __func__, heap->type); -+ up_write(&dev->lock); -+ goto out_debugfs_cleanup; -+ } -+ - /* - * use negative heap->id to reverse the priority -- when traversing - * the list later attempt higher id numbers first -@@ -291,11 +361,12 @@ int __ion_device_add_heap(struct ion_heap *heap, struct module *owner) - plist_node_init(&heap->node, -heap->id); - plist_add(&heap->node, &dev->heaps); - -- dev->heap_cnt++; - up_write(&dev->lock); - - return 0; - -+out_debugfs_cleanup: -+ debugfs_remove_recursive(heap->debugfs_dir); - out_heap_cleanup: - ion_heap_cleanup(heap); - out: -@@ -321,6 +392,8 @@ void ion_device_remove_heap(struct ion_heap *heap) - __func__, heap->name); - } - debugfs_remove_recursive(heap->debugfs_dir); -+ clear_bit(heap->id - 1, dev->heap_ids); -+ dev->heap_cnt--; - up_write(&dev->lock); - } - EXPORT_SYMBOL(ion_device_remove_heap); -diff --git a/drivers/staging/android/ion/ion_private.h b/drivers/staging/android/ion/ion_private.h -index 5cc09fbfbefe..2f5376e131c3 100644 ---- a/drivers/staging/android/ion/ion_private.h -+++ b/drivers/staging/android/ion/ion_private.h -@@ -23,13 +23,16 @@ - * @dev: the actual misc device - * @buffers: an rb tree of all the existing buffers - * @buffer_lock: lock protecting the tree of buffers -- * @lock: rwsem protecting the tree of heaps and clients -+ * @lock: rwsem protecting the tree of heaps, heap_bitmap and -+ * clients -+ * @heap_ids: bitmap of register heap ids - */ - struct ion_device { - struct miscdevice dev; - struct rb_root buffers; - struct mutex buffer_lock; - struct rw_semaphore lock; -+ DECLARE_BITMAP(heap_ids, ION_NUM_MAX_HEAPS); - struct plist_head heaps; - struct dentry *debug_root; - int heap_cnt; diff --git a/patches/ANDROID-staging-ion-export-ion_free-for-ion_heaps.patch b/patches/ANDROID-staging-ion-export-ion_free-for-ion_heaps.patch deleted file mode 100644 index 4ede4c8a29d1..000000000000 --- a/patches/ANDROID-staging-ion-export-ion_free-for-ion_heaps.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Tue, 10 Sep 2019 05:13:51 -0700 -Subject: ANDROID: staging: ion: export ion_free() for ion_heaps. - -ion_free() is a generic function needed to release -an ion buffer back to the heap. So, export it for the -heap module. - -Bug: 140294230 -Test: ion-unit-tests - -Change-Id: Iaa467ab3df18fa219412dd9f5913cd022a93455d -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/ion.c | 1 + - include/linux/ion.h | 12 ++++++++++++ - 2 files changed, 13 insertions(+) - -diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c -index aaa02c671a91..2c915579f60b 100644 ---- a/drivers/staging/android/ion/ion.c -+++ b/drivers/staging/android/ion/ion.c -@@ -41,6 +41,7 @@ int ion_free(struct ion_buffer *buffer) - { - return ion_buffer_destroy(internal_dev, buffer); - } -+EXPORT_SYMBOL_GPL(ion_free); - - static int ion_alloc_fd(size_t len, unsigned int heap_id_mask, - unsigned int flags) -diff --git a/include/linux/ion.h b/include/linux/ion.h -index 87aa2bcec7d3..88622fb8f9ea 100644 ---- a/include/linux/ion.h -+++ b/include/linux/ion.h -@@ -293,6 +293,13 @@ int ion_buffer_zero(struct ion_buffer *buffer); - struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, - unsigned int flags); - -+/** -+ * ion_free - Releases the ion buffer. -+ * -+ * @buffer: ion buffer to be released -+ */ -+int ion_free(struct ion_buffer *buffer); -+ - #else - - static inline int __ion_device_add_heap(struct ion_heap *heap, -@@ -357,5 +364,10 @@ static inline struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, - return ERR_PTR(-ENOMEM); - } - -+static inline int ion_free(struct ion_buffer *buffer) -+{ -+ return 0; -+} -+ - #endif /* CONFIG_ION */ - #endif /* _ION_KERNEL_H */ diff --git a/patches/ANDROID-staging-ion-fix-off-by-1-error-in-heap-search.patch b/patches/ANDROID-staging-ion-fix-off-by-1-error-in-heap-search.patch deleted file mode 100644 index cb66ae6b3168..000000000000 --- a/patches/ANDROID-staging-ion-fix-off-by-1-error-in-heap-search.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Mon, 9 Sep 2019 08:21:20 -0700 -Subject: ANDROID: staging: ion: fix off-by-1 error in heap search - -ion allocation was wrong because of an off-by-1 error -in heap search for buffer allocation. Fix it. - -Bug: 140507100 -Test: ion-unit-tests - -Change-Id: I6ac5b0ddc6b31b5409645f62a96781d464b7bdf3 -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/ion.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c -index c8ed051715bc..aaa02c671a91 100644 ---- a/drivers/staging/android/ion/ion.c -+++ b/drivers/staging/android/ion/ion.c -@@ -279,7 +279,7 @@ static int ion_assign_heap_id(struct ion_heap *heap, struct ion_device *dev) - - if (test_and_set_bit(id_bit - 1, dev->heap_ids)) - return -EEXIST; -- heap->id = id_bit; -+ heap->id = id_bit - 1; - dev->heap_cnt++; - - return 0; -@@ -392,7 +392,7 @@ void ion_device_remove_heap(struct ion_heap *heap) - __func__, heap->name); - } - debugfs_remove_recursive(heap->debugfs_dir); -- clear_bit(heap->id - 1, dev->heap_ids); -+ clear_bit(heap->id, dev->heap_ids); - dev->heap_cnt--; - up_write(&dev->lock); - } diff --git a/patches/ANDROID-staging-ion-fix-sparse-warning-in-ion-system-heap.patch b/patches/ANDROID-staging-ion-fix-sparse-warning-in-ion-system-heap.patch deleted file mode 100644 index 6cfa27b7a926..000000000000 --- a/patches/ANDROID-staging-ion-fix-sparse-warning-in-ion-system-heap.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Wed, 9 Oct 2019 21:38:04 -0700 -Subject: ANDROID: staging: ion: fix sparse warning in ion system heap - -drivers/staging/android/ion/heaps/ion_system_heap.c:250:24: sparse: sparse: -symbol 'system_heap' was not declared. Should it be static? - -Fixes: 142434553 -Test: Build and boot cuttlefish - -Change-Id: I6e1eb9365ca12c2d081533ed2db9881086531ec7 -Reported-by: kbuild test robot -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/heaps/ion_system_heap.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/staging/android/ion/heaps/ion_system_heap.c b/drivers/staging/android/ion/heaps/ion_system_heap.c -index 792cd130e493..054324784ab9 100644 ---- a/drivers/staging/android/ion/heaps/ion_system_heap.c -+++ b/drivers/staging/android/ion/heaps/ion_system_heap.c -@@ -244,7 +244,7 @@ static struct ion_heap_ops system_heap_ops = { - .shrink = ion_system_heap_shrink, - }; - --struct ion_system_heap system_heap = { -+static struct ion_system_heap system_heap = { - .heap = { - .ops = &system_heap_ops, - .type = ION_HEAP_TYPE_SYSTEM, diff --git a/patches/ANDROID-staging-ion-make-cma-heap-a-module.patch b/patches/ANDROID-staging-ion-make-cma-heap-a-module.patch deleted file mode 100644 index 0ad88c8f4eeb..000000000000 --- a/patches/ANDROID-staging-ion-make-cma-heap-a-module.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Fri, 13 Sep 2019 14:52:14 -0700 -Subject: ANDROID: staging: ion: make cma heap a module - -Add all cma areas that we can find as cma heaps. - -Bug: 133508579 -Test: build and insmod ion_cma_heap - -Change-Id: I3cf1884c8d8914ae31d55e2f2770104347844036 -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/heaps/Kconfig | 2 +- - .../staging/android/ion/heaps/ion_cma_heap.c | 56 ++++++++++++------- - 2 files changed, 36 insertions(+), 22 deletions(-) - -diff --git a/drivers/staging/android/ion/heaps/Kconfig b/drivers/staging/android/ion/heaps/Kconfig -index af6fce69e61a..617d6e7ea583 100644 ---- a/drivers/staging/android/ion/heaps/Kconfig -+++ b/drivers/staging/android/ion/heaps/Kconfig -@@ -15,7 +15,7 @@ config ION_SYSTEM_CONTIG_HEAP - contiguous. If in doubt, say Y. - - config ION_CMA_HEAP -- bool "Ion CMA heap support" -+ tristate "Ion CMA heap support" - depends on ION && DMA_CMA - help - Choose this option to enable CMA heaps with Ion. This heap is backed -diff --git a/drivers/staging/android/ion/heaps/ion_cma_heap.c b/drivers/staging/android/ion/heaps/ion_cma_heap.c -index 236b6c576cdb..9584972b5005 100644 ---- a/drivers/staging/android/ion/heaps/ion_cma_heap.c -+++ b/drivers/staging/android/ion/heaps/ion_cma_heap.c -@@ -18,7 +18,7 @@ - struct ion_cma_heap { - struct ion_heap heap; - struct cma *cma; --}; -+} cma_heaps[MAX_CMA_AREAS]; - - #define to_cma_heap(x) container_of(x, struct ion_cma_heap, heap) - -@@ -97,38 +97,52 @@ static struct ion_heap_ops ion_cma_ops = { - .free = ion_cma_free, - }; - --static struct ion_heap *__ion_cma_heap_create(struct cma *cma) -+static int __ion_add_cma_heap(struct cma *cma, void *data) - { -+ int *cma_nr = data; - struct ion_cma_heap *cma_heap; -+ int ret; - -- cma_heap = kzalloc(sizeof(*cma_heap), GFP_KERNEL); -- -- if (!cma_heap) -- return ERR_PTR(-ENOMEM); -+ if (*cma_nr >= MAX_CMA_AREAS) -+ return -EINVAL; - -+ cma_heap = &cma_heaps[*cma_nr]; - cma_heap->heap.ops = &ion_cma_ops; -- cma_heap->cma = cma; - cma_heap->heap.type = ION_HEAP_TYPE_DMA; -- return &cma_heap->heap; -+ cma_heap->heap.name = cma_get_name(cma); -+ -+ ret = ion_device_add_heap(&cma_heap->heap); -+ if (ret) -+ goto out; -+ -+ cma_heap->cma = cma; -+ *cma_nr += 1; -+out: -+ return 0; - } - --static int __ion_add_cma_heaps(struct cma *cma, void *data) -+static int __init ion_cma_heap_init(void) - { -- struct ion_heap *heap; -- -- heap = __ion_cma_heap_create(cma); -- if (IS_ERR(heap)) -- return PTR_ERR(heap); -+ int ret; -+ int nr = 0; - -- heap->name = cma_get_name(cma); -+ ret = cma_for_each_area(__ion_add_cma_heap, &nr); -+ if (ret) { -+ for (nr = 0; nr < MAX_CMA_AREAS && cma_heaps[nr].cma; nr++) -+ ion_device_remove_heap(&cma_heaps[nr].heap); -+ } - -- ion_device_add_heap(heap); -- return 0; -+ return ret; - } - --static int ion_add_cma_heaps(void) -+static void __exit ion_cma_heap_exit(void) - { -- cma_for_each_area(__ion_add_cma_heaps, NULL); -- return 0; -+ int nr; -+ -+ for (nr = 0; nr < MAX_CMA_AREAS && cma_heaps[nr].cma; nr++) -+ ion_device_remove_heap(&cma_heaps[nr].heap); - } --device_initcall(ion_add_cma_heaps); -+ -+module_init(ion_cma_heap_init); -+module_exit(ion_cma_heap_exit); -+MODULE_LICENSE("GPL v2"); diff --git a/patches/ANDROID-staging-ion-make-system-and-contig-heaps-modular.patch b/patches/ANDROID-staging-ion-make-system-and-contig-heaps-modular.patch deleted file mode 100644 index 833b0c6ea2c1..000000000000 --- a/patches/ANDROID-staging-ion-make-system-and-contig-heaps-modular.patch +++ /dev/null @@ -1,512 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Mon, 12 Aug 2019 17:23:25 -0700 -Subject: ANDROID: staging: ion: make system and contig heaps modular - -Add symmetric heap add/remove APIs and export symbols from -ion core that are needed to make both heaps modular. - -Bug: 133508579 -Test: ion-unit-test, rmmod, modprobe - -Change-Id: Ic5f40936531936c9bfab48ea147108c019d28e2c -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/heaps/Kconfig | 4 +- - drivers/staging/android/ion/heaps/Makefile | 4 +- - .../ion/heaps/ion_system_contig_heap.c | 36 ++++------ - .../android/ion/heaps/ion_system_heap.c | 67 +++++++++---------- - drivers/staging/android/ion/ion.c | 54 ++++++++++++--- - drivers/staging/android/ion/ion_buffer.c | 13 ++++ - drivers/staging/android/ion/ion_heap.c | 39 ++++++++++- - drivers/staging/android/ion/ion_private.h | 3 + - include/linux/ion.h | 24 ++++++- - 9 files changed, 169 insertions(+), 75 deletions(-) - -diff --git a/drivers/staging/android/ion/heaps/Kconfig b/drivers/staging/android/ion/heaps/Kconfig -index f1c7a6b79c01..af6fce69e61a 100644 ---- a/drivers/staging/android/ion/heaps/Kconfig -+++ b/drivers/staging/android/ion/heaps/Kconfig -@@ -1,13 +1,13 @@ - # SPDX-License-Identifier: GPL-2.0 - config ION_SYSTEM_HEAP -- bool "Ion system heap" -+ tristate "Ion system heap" - depends on ION - help - Choose this option to enable the Ion system heap. The system heap - is backed by pages from the buddy allocator. If in doubt, say Y. - - config ION_SYSTEM_CONTIG_HEAP -- bool "Ion system contig heap" -+ tristate "Ion system contig heap" - depends on ION - help - Choose this option to enable Ion system contig heap. The system contig heap -diff --git a/drivers/staging/android/ion/heaps/Makefile b/drivers/staging/android/ion/heaps/Makefile -index e2ee931100d0..449879035877 100644 ---- a/drivers/staging/android/ion/heaps/Makefile -+++ b/drivers/staging/android/ion/heaps/Makefile -@@ -1,4 +1,6 @@ - # SPDX-License-Identifier: GPL-2.0 --obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o -+obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_sys_heap.o -+ion_sys_heap-y := ion_system_heap.o ion_page_pool.o -+ - obj-$(CONFIG_ION_SYSTEM_CONTIG_HEAP) += ion_system_contig_heap.o - obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o -diff --git a/drivers/staging/android/ion/heaps/ion_system_contig_heap.c b/drivers/staging/android/ion/heaps/ion_system_contig_heap.c -index 3a07ef931c2e..9cb18e38dc96 100644 ---- a/drivers/staging/android/ion/heaps/ion_system_contig_heap.c -+++ b/drivers/staging/android/ion/heaps/ion_system_contig_heap.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -81,31 +82,22 @@ static struct ion_heap_ops kmalloc_ops = { - .map_user = ion_heap_map_user, - }; - --static struct ion_heap *__ion_system_contig_heap_create(void) --{ -- struct ion_heap *heap; -- -- heap = kzalloc(sizeof(*heap), GFP_KERNEL); -- if (!heap) -- return ERR_PTR(-ENOMEM); -- heap->ops = &kmalloc_ops; -- heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; -- heap->name = "ion_system_contig_heap"; -+static struct ion_heap contig_heap = { -+ .ops = &kmalloc_ops, -+ .type = ION_HEAP_TYPE_SYSTEM_CONTIG, -+ .name = "ion_system_contig_heap", -+}; - -- return heap; -+static int __init ion_system_contig_heap_init(void) -+{ -+ return ion_device_add_heap(&contig_heap); - } - --static int ion_system_contig_heap_create(void) -+static void __exit ion_system_contig_heap_exit(void) - { -- struct ion_heap *heap; -- -- heap = __ion_system_contig_heap_create(); -- if (IS_ERR(heap)) -- return PTR_ERR(heap); -- -- ion_device_add_heap(heap); -- -- return 0; -+ ion_device_remove_heap(&contig_heap); - } --device_initcall(ion_system_contig_heap_create); - -+module_init(ion_system_contig_heap_init); -+module_exit(ion_system_contig_heap_exit); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/staging/android/ion/heaps/ion_system_heap.c b/drivers/staging/android/ion/heaps/ion_system_heap.c -index 25ea31757578..3aed952c219d 100644 ---- a/drivers/staging/android/ion/heaps/ion_system_heap.c -+++ b/drivers/staging/android/ion/heaps/ion_system_heap.c -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -204,15 +205,6 @@ static int ion_system_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask, - return nr_total; - } - --static struct ion_heap_ops system_heap_ops = { -- .allocate = ion_system_heap_allocate, -- .free = ion_system_heap_free, -- .map_kernel = ion_heap_map_kernel, -- .unmap_kernel = ion_heap_unmap_kernel, -- .map_user = ion_heap_map_user, -- .shrink = ion_system_heap_shrink, --}; -- - static void ion_system_heap_destroy_pools(struct ion_page_pool **pools) - { - int i; -@@ -246,38 +238,39 @@ static int ion_system_heap_create_pools(struct ion_page_pool **pools) - return -ENOMEM; - } - --static struct ion_heap *__ion_system_heap_create(void) --{ -- struct ion_system_heap *heap; -- -- heap = kzalloc(sizeof(*heap), GFP_KERNEL); -- if (!heap) -- return ERR_PTR(-ENOMEM); -- heap->heap.ops = &system_heap_ops; -- heap->heap.type = ION_HEAP_TYPE_SYSTEM; -- heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; -+static struct ion_heap_ops system_heap_ops = { -+ .allocate = ion_system_heap_allocate, -+ .free = ion_system_heap_free, -+ .map_kernel = ion_heap_map_kernel, -+ .unmap_kernel = ion_heap_unmap_kernel, -+ .map_user = ion_heap_map_user, -+ .shrink = ion_system_heap_shrink, -+}; - -- if (ion_system_heap_create_pools(heap->pools)) -- goto free_heap; -+struct ion_system_heap system_heap = { -+ .heap = { -+ .ops = &system_heap_ops, -+ .type = ION_HEAP_TYPE_SYSTEM, -+ .flags = ION_HEAP_FLAG_DEFER_FREE, -+ .name = "ion_system_heap", -+ } -+}; - -- return &heap->heap; -+static int __init ion_system_heap_init(void) -+{ -+ int ret = ion_system_heap_create_pools(system_heap.pools); -+ if (ret) -+ return ret; - --free_heap: -- kfree(heap); -- return ERR_PTR(-ENOMEM); -+ return ion_device_add_heap(&system_heap.heap); - } - --static int ion_system_heap_create(void) -+static void __exit ion_system_heap_exit(void) - { -- struct ion_heap *heap; -- -- heap = __ion_system_heap_create(); -- if (IS_ERR(heap)) -- return PTR_ERR(heap); -- heap->name = "ion_system_heap"; -- -- ion_device_add_heap(heap); -- -- return 0; -+ ion_device_remove_heap(&system_heap.heap); -+ ion_system_heap_destroy_pools(system_heap.pools); - } --device_initcall(ion_system_heap_create); -+ -+module_init(ion_system_heap_init); -+module_exit(ion_system_heap_exit); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c -index b862bdfeca89..548d65dbd3ac 100644 ---- a/drivers/staging/android/ion/ion.c -+++ b/drivers/staging/android/ion/ion.c -@@ -222,28 +222,36 @@ static int debug_shrink_get(void *data, u64 *val) - DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, - debug_shrink_set, "%llu\n"); - --void ion_device_add_heap(struct ion_heap *heap) -+int __ion_device_add_heap(struct ion_heap *heap, struct module *owner) - { - struct ion_device *dev = internal_dev; - int ret; - struct dentry *heap_root; - char debug_name[64]; - -- if (!heap->ops->allocate || !heap->ops->free) -- pr_err("%s: can not add heap with invalid ops struct.\n", -- __func__); -+ if (!heap || !heap->ops || !heap->ops->allocate || !heap->ops->free) { -+ pr_err("%s: invalid heap or heap_ops\n", __func__); -+ ret = -EINVAL; -+ goto out; -+ } - -+ heap->owner = owner; - spin_lock_init(&heap->free_lock); - spin_lock_init(&heap->stat_lock); - heap->free_list_size = 0; - -- if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) -- ion_heap_init_deferred_free(heap); -+ if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) { -+ ret = ion_heap_init_deferred_free(heap); -+ if (ret) -+ goto out_heap_cleanup; -+ } - - if ((heap->flags & ION_HEAP_FLAG_DEFER_FREE) || heap->ops->shrink) { - ret = ion_heap_init_shrinker(heap); -- if (ret) -+ if (ret) { - pr_err("%s: Failed to register shrinker\n", __func__); -+ goto out_heap_cleanup; -+ } - } - - heap->num_of_buffers = 0; -@@ -273,6 +281,7 @@ void ion_device_add_heap(struct ion_heap *heap) - &debug_shrink_fops); - } - -+ heap->debugfs_dir = heap_root; - down_write(&dev->lock); - heap->id = heap_id++; - /* -@@ -284,8 +293,37 @@ void ion_device_add_heap(struct ion_heap *heap) - - dev->heap_cnt++; - up_write(&dev->lock); -+ -+ return 0; -+ -+out_heap_cleanup: -+ ion_heap_cleanup(heap); -+out: -+ return ret; -+} -+EXPORT_SYMBOL_GPL(__ion_device_add_heap); -+ -+void ion_device_remove_heap(struct ion_heap *heap) -+{ -+ struct ion_device *dev = internal_dev; -+ -+ if (!heap) { -+ pr_err("%s: Invalid argument\n", __func__); -+ return; -+ } -+ -+ // take semaphore and remove the heap from dev->heap list -+ down_write(&dev->lock); -+ /* So no new allocations can happen from this heap */ -+ plist_del(&heap->node, &dev->heaps); -+ if (ion_heap_cleanup(heap) != 0) { -+ pr_warn("%s: failed to cleanup heap (%s)\n", -+ __func__, heap->name); -+ } -+ debugfs_remove_recursive(heap->debugfs_dir); -+ up_write(&dev->lock); - } --EXPORT_SYMBOL(ion_device_add_heap); -+EXPORT_SYMBOL(ion_device_remove_heap); - - static int ion_device_create(void) - { -diff --git a/drivers/staging/android/ion/ion_buffer.c b/drivers/staging/android/ion/ion_buffer.c -index adce2d489f56..879b3ddb08c0 100644 ---- a/drivers/staging/android/ion/ion_buffer.c -+++ b/drivers/staging/android/ion/ion_buffer.c -@@ -6,6 +6,7 @@ - */ - - #include -+#include - #include - - #include "ion_private.h" -@@ -76,6 +77,14 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, - heap->num_of_alloc_bytes += len; - if (heap->num_of_alloc_bytes > heap->alloc_bytes_wm) - heap->alloc_bytes_wm = heap->num_of_alloc_bytes; -+ if (heap->num_of_buffers == 1) { -+ /* This module reference lasts as long as at least one -+ * buffer is allocated from the heap. We are protected -+ * against ion_device_remove_heap() with dev->lock, so we can -+ * safely assume the module reference is going to* succeed. -+ */ -+ __module_get(heap->owner); -+ } - spin_unlock(&heap->stat_lock); - - INIT_LIST_HEAD(&buffer->attachments); -@@ -184,6 +193,7 @@ int ion_buffer_zero(struct ion_buffer *buffer) - - return ion_sglist_zero(table->sgl, table->nents, pgprot); - } -+EXPORT_SYMBOL_GPL(ion_buffer_zero); - - void ion_buffer_release(struct ion_buffer *buffer) - { -@@ -196,7 +206,10 @@ void ion_buffer_release(struct ion_buffer *buffer) - spin_lock(&buffer->heap->stat_lock); - buffer->heap->num_of_buffers--; - buffer->heap->num_of_alloc_bytes -= buffer->size; -+ if (buffer->heap->num_of_buffers == 0) -+ module_put(buffer->heap->owner); - spin_unlock(&buffer->heap->stat_lock); -+ /* drop reference to the heap module */ - - kfree(buffer); - } -diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c -index 755548a4382d..e102f6a2ecf6 100644 ---- a/drivers/staging/android/ion/ion_heap.c -+++ b/drivers/staging/android/ion/ion_heap.c -@@ -101,12 +101,15 @@ static int ion_heap_deferred_free(void *data) - struct ion_buffer *buffer; - - wait_event_freezable(heap->waitqueue, -- ion_heap_freelist_size(heap) > 0); -+ (ion_heap_freelist_size(heap) > 0 || -+ kthread_should_stop())); - - spin_lock(&heap->free_lock); - if (list_empty(&heap->free_list)) { - spin_unlock(&heap->free_lock); -- continue; -+ if (!kthread_should_stop()) -+ continue; -+ break; - } - buffer = list_first_entry(&heap->free_list, struct ion_buffer, - list); -@@ -156,12 +159,14 @@ void *ion_heap_map_kernel(struct ion_heap *heap, - - return vaddr; - } -+EXPORT_SYMBOL_GPL(ion_heap_map_kernel); - - void ion_heap_unmap_kernel(struct ion_heap *heap, - struct ion_buffer *buffer) - { - vunmap(buffer->vaddr); - } -+EXPORT_SYMBOL_GPL(ion_heap_unmap_kernel); - - int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, - struct vm_area_struct *vma) -@@ -198,6 +203,7 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, - - return 0; - } -+EXPORT_SYMBOL_GPL(ion_heap_map_user); - - void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer) - { -@@ -256,3 +262,32 @@ int ion_heap_init_shrinker(struct ion_heap *heap) - - return register_shrinker(&heap->shrinker); - } -+ -+int ion_heap_cleanup(struct ion_heap *heap) -+{ -+ int ret; -+ -+ if (heap->flags & ION_HEAP_FLAG_DEFER_FREE && -+ !IS_ERR_OR_NULL(heap->task)) { -+ size_t free_list_size = ion_heap_freelist_size(heap); -+ size_t total_drained = ion_heap_freelist_drain(heap, 0); -+ -+ if (total_drained != free_list_size) { -+ pr_err("%s: %s heap drained %zu bytes, requested %zu\n", -+ __func__, heap->name, free_list_size, -+ total_drained); -+ return -EBUSY; -+ } -+ ret = kthread_stop(heap->task); -+ if (ret < 0) { -+ pr_err("%s: failed to stop heap free thread\n", -+ __func__); -+ return ret; -+ } -+ } -+ -+ if ((heap->flags & ION_HEAP_FLAG_DEFER_FREE) || heap->ops->shrink) -+ unregister_shrinker(&heap->shrinker); -+ -+ return 0; -+} -diff --git a/drivers/staging/android/ion/ion_private.h b/drivers/staging/android/ion/ion_private.h -index ed7ed39d0df1..5cc09fbfbefe 100644 ---- a/drivers/staging/android/ion/ion_private.h -+++ b/drivers/staging/android/ion/ion_private.h -@@ -51,4 +51,7 @@ extern struct dma_buf *ion_dmabuf_alloc(struct ion_device *dev, size_t len, - unsigned int flags); - extern int ion_free(struct ion_buffer *buffer); - -+/* ion heap helpers */ -+extern int ion_heap_cleanup(struct ion_heap *heap); -+ - #endif /* _ION_PRIVATE_H */ -diff --git a/include/linux/ion.h b/include/linux/ion.h -index 775e948a362c..fe0d2cb1ef25 100644 ---- a/include/linux/ion.h -+++ b/include/linux/ion.h -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -105,6 +106,7 @@ struct ion_heap_ops { - * allocating. These are specified by platform data and - * MUST be unique - * @name: used for debugging -+ * @owner: kernel module that implements this heap - * @shrinker: a shrinker for the heap - * @free_list: free list head if deferred free is used - * @free_list_size size of the deferred free list in bytes -@@ -127,6 +129,7 @@ struct ion_heap { - unsigned long flags; - unsigned int id; - const char *name; -+ struct module *owner; - - /* deferred free support */ - struct shrinker shrinker; -@@ -143,16 +146,30 @@ struct ion_heap { - - /* protect heap statistics */ - spinlock_t stat_lock; -+ -+ /* heap's debugfs root */ -+ struct dentry *debugfs_dir; - }; - -+#define ion_device_add_heap(heap) __ion_device_add_heap(heap, THIS_MODULE) -+ - #ifdef CONFIG_ION - - /** -- * ion_device_add_heap - adds a heap to the ion device -+ * __ion_device_add_heap - adds a heap to the ion device - * - * @heap: the heap to add -+ * -+ * Returns 0 on success, negative error otherwise. -+ */ -+int __ion_device_add_heap(struct ion_heap *heap, struct module *owner); -+ -+/** -+ * ion_device_remove_heap - removes a heap from ion device -+ * -+ * @heap: pointer to the heap to be removed - */ --void ion_device_add_heap(struct ion_heap *heap); -+void ion_device_remove_heap(struct ion_heap *heap); - - /** - * ion_heap_init_shrinker -@@ -283,7 +300,8 @@ struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, - - #else - --static inline int ion_device_add_heap(struct ion_heap *heap) -+static inline int __ion_device_add_heap(struct ion_heap *heap, -+ struct module *owner) - { - return -ENODEV; - } diff --git a/patches/ANDROID-staging-ion-move-uapi-ion.h-to-uapi-linux-ion.h.patch b/patches/ANDROID-staging-ion-move-uapi-ion.h-to-uapi-linux-ion.h.patch deleted file mode 100644 index f998db874068..000000000000 --- a/patches/ANDROID-staging-ion-move-uapi-ion.h-to-uapi-linux-ion.h.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Mon, 26 Aug 2019 12:39:52 -0700 -Subject: ANDROID: staging: ion: move uapi/ion.h to uapi/linux/ion.h - -Bug: 133508579 -Test: builds - -Change-Id: I599a78e1acd2eed909f40e5a5b6a62813610990c -Signed-off-by: Sandeep Patil ---- - include/linux/ion.h | 2 +- - include/uapi/{ => linux}/ion.h | 0 - 2 files changed, 1 insertion(+), 1 deletion(-) - rename include/uapi/{ => linux}/ion.h (100%) - -diff --git a/include/linux/ion.h b/include/linux/ion.h -index fe0d2cb1ef25..5d68674b015a 100644 ---- a/include/linux/ion.h -+++ b/include/linux/ion.h -@@ -18,7 +18,7 @@ - #include - #include - #include --#include -+#include - - /** - * struct ion_buffer - metadata for a particular buffer -diff --git a/include/uapi/ion.h b/include/uapi/linux/ion.h -similarity index 100% -rename from include/uapi/ion.h -rename to include/uapi/linux/ion.h diff --git a/patches/ANDROID-staging-ion-refactor-ion-s-buffer-manipulators-into-a-separate-file.patch b/patches/ANDROID-staging-ion-refactor-ion-s-buffer-manipulators-into-a-separate-file.patch deleted file mode 100644 index 3a7c17e3a2ec..000000000000 --- a/patches/ANDROID-staging-ion-refactor-ion-s-buffer-manipulators-into-a-separate-file.patch +++ /dev/null @@ -1,552 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Wed, 7 Aug 2019 12:12:47 -0700 -Subject: ANDROID: staging: ion: refactor ion's buffer manipulators into a - separate file. - -This patch is preparatory work for making ion heaps modular. The patch -itself doesn't make any significant changes except for re-organizing the -buffer manipulator functions in a single file. This will be helpful -later when we specifically export some of these functions to be used by -a heap module. - -Bug: 133508579 -Test: ion-unit-tests - -Change-Id: I7438bd529a3e9c7a90910979e26bd754a8292e9a -Co-developed-by: Isaac J. Manjarres -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/Makefile | 2 +- - drivers/staging/android/ion/ion.c | 143 +--------------- - drivers/staging/android/ion/ion.h | 15 -- - drivers/staging/android/ion/ion_buffer.c | 198 ++++++++++++++++++++++ - drivers/staging/android/ion/ion_heap.c | 6 +- - drivers/staging/android/ion/ion_private.h | 47 +++++ - 6 files changed, 254 insertions(+), 157 deletions(-) - create mode 100644 drivers/staging/android/ion/ion_buffer.c - create mode 100644 drivers/staging/android/ion/ion_private.h - -diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile -index 5f4487b1a224..da386dbf3ffd 100644 ---- a/drivers/staging/android/ion/Makefile -+++ b/drivers/staging/android/ion/Makefile -@@ -1,4 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0 --obj-$(CONFIG_ION) += ion.o ion_heap.o -+obj-$(CONFIG_ION) += ion.o ion_buffer.o ion_heap.o - obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o - obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o -diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c -index 2e5c6ae2f3fc..19d3e82b2f5b 100644 ---- a/drivers/staging/android/ion/ion.c -+++ b/drivers/staging/android/ion/ion.c -@@ -26,119 +26,11 @@ - #include - #include - --#include "ion.h" -+#include "ion_private.h" - - static struct ion_device *internal_dev; - static int heap_id; - --/* this function should only be called while dev->lock is held */ --static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, -- struct ion_device *dev, -- unsigned long len, -- unsigned long flags) --{ -- struct ion_buffer *buffer; -- int ret; -- -- buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); -- if (!buffer) -- return ERR_PTR(-ENOMEM); -- -- buffer->heap = heap; -- buffer->flags = flags; -- buffer->dev = dev; -- buffer->size = len; -- -- ret = heap->ops->allocate(heap, buffer, len, flags); -- -- if (ret) { -- if (!(heap->flags & ION_HEAP_FLAG_DEFER_FREE)) -- goto err2; -- -- ion_heap_freelist_drain(heap, 0); -- ret = heap->ops->allocate(heap, buffer, len, flags); -- if (ret) -- goto err2; -- } -- -- if (!buffer->sg_table) { -- WARN_ONCE(1, "This heap needs to set the sgtable"); -- ret = -EINVAL; -- goto err1; -- } -- -- spin_lock(&heap->stat_lock); -- heap->num_of_buffers++; -- heap->num_of_alloc_bytes += len; -- if (heap->num_of_alloc_bytes > heap->alloc_bytes_wm) -- heap->alloc_bytes_wm = heap->num_of_alloc_bytes; -- spin_unlock(&heap->stat_lock); -- -- INIT_LIST_HEAD(&buffer->attachments); -- mutex_init(&buffer->lock); -- return buffer; -- --err1: -- heap->ops->free(buffer); --err2: -- kfree(buffer); -- return ERR_PTR(ret); --} -- --void ion_buffer_destroy(struct ion_buffer *buffer) --{ -- if (buffer->kmap_cnt > 0) { -- pr_warn_once("%s: buffer still mapped in the kernel\n", -- __func__); -- buffer->heap->ops->unmap_kernel(buffer->heap, buffer); -- } -- buffer->heap->ops->free(buffer); -- spin_lock(&buffer->heap->stat_lock); -- buffer->heap->num_of_buffers--; -- buffer->heap->num_of_alloc_bytes -= buffer->size; -- spin_unlock(&buffer->heap->stat_lock); -- -- kfree(buffer); --} -- --static void _ion_buffer_destroy(struct ion_buffer *buffer) --{ -- struct ion_heap *heap = buffer->heap; -- -- if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) -- ion_heap_freelist_add(heap, buffer); -- else -- ion_buffer_destroy(buffer); --} -- --static void *ion_buffer_kmap_get(struct ion_buffer *buffer) --{ -- void *vaddr; -- -- if (buffer->kmap_cnt) { -- buffer->kmap_cnt++; -- return buffer->vaddr; -- } -- vaddr = buffer->heap->ops->map_kernel(buffer->heap, buffer); -- if (WARN_ONCE(!vaddr, -- "heap->ops->map_kernel should return ERR_PTR on error")) -- return ERR_PTR(-EINVAL); -- if (IS_ERR(vaddr)) -- return vaddr; -- buffer->vaddr = vaddr; -- buffer->kmap_cnt++; -- return vaddr; --} -- --static void ion_buffer_kmap_put(struct ion_buffer *buffer) --{ -- buffer->kmap_cnt--; -- if (!buffer->kmap_cnt) { -- buffer->heap->ops->unmap_kernel(buffer->heap, buffer); -- buffer->vaddr = NULL; -- } --} -- - static struct sg_table *dup_sg_table(struct sg_table *table) - { - struct sg_table *new_table; -@@ -273,7 +165,7 @@ static void ion_dma_buf_release(struct dma_buf *dmabuf) - { - struct ion_buffer *buffer = dmabuf->priv; - -- _ion_buffer_destroy(buffer); -+ ion_buffer_destroy(internal_dev, buffer); - } - - static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) -@@ -358,39 +250,14 @@ static const struct dma_buf_ops dma_buf_ops = { - static struct dma_buf *ion_alloc_dmabuf(size_t len, unsigned int heap_id_mask, - unsigned int flags) - { -- struct ion_device *dev = internal_dev; -- struct ion_buffer *buffer = NULL; -- struct ion_heap *heap; -+ struct ion_buffer *buffer; - DEFINE_DMA_BUF_EXPORT_INFO(exp_info); - struct dma_buf *dmabuf; - - pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__, - len, heap_id_mask, flags); -- /* -- * traverse the list of heaps available in this system in priority -- * order. If the heap type is supported by the client, and matches the -- * request of the caller allocate from it. Repeat until allocate has -- * succeeded or all heaps have been tried -- */ -- len = PAGE_ALIGN(len); -- -- if (!len) -- return ERR_PTR(-EINVAL); -- -- down_read(&dev->lock); -- plist_for_each_entry(heap, &dev->heaps, node) { -- /* if the caller didn't specify this heap id */ -- if (!((1 << heap->id) & heap_id_mask)) -- continue; -- buffer = ion_buffer_create(heap, dev, len, flags); -- if (!IS_ERR(buffer)) -- break; -- } -- up_read(&dev->lock); -- -- if (!buffer) -- return ERR_PTR(-ENODEV); - -+ buffer = ion_buffer_alloc(internal_dev, len, heap_id_mask, flags); - if (IS_ERR(buffer)) - return ERR_CAST(buffer); - -@@ -401,7 +268,7 @@ static struct dma_buf *ion_alloc_dmabuf(size_t len, unsigned int heap_id_mask, - - dmabuf = dma_buf_export(&exp_info); - if (IS_ERR(dmabuf)) -- _ion_buffer_destroy(buffer); -+ ion_buffer_destroy(internal_dev, buffer); - - return dmabuf; - } -diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h -index 6f9f7c365f38..d2d18f03ac77 100644 ---- a/drivers/staging/android/ion/ion.h -+++ b/drivers/staging/android/ion/ion.h -@@ -17,7 +17,6 @@ - #include - #include - #include --#include - - #include "../uapi/ion.h" - -@@ -39,7 +38,6 @@ - */ - struct ion_buffer { - struct list_head list; -- struct ion_device *dev; - struct ion_heap *heap; - unsigned long flags; - unsigned long private_flags; -@@ -54,19 +52,6 @@ struct ion_buffer { - - void ion_buffer_destroy(struct ion_buffer *buffer); - --/** -- * struct ion_device - the metadata of the ion device node -- * @dev: the actual misc device -- * @lock: rwsem protecting the tree of heaps and clients -- */ --struct ion_device { -- struct miscdevice dev; -- struct rw_semaphore lock; -- struct plist_head heaps; -- struct dentry *debug_root; -- int heap_cnt; --}; -- - /** - * struct ion_heap_ops - ops to operate on a given heap - * @allocate: allocate memory -diff --git a/drivers/staging/android/ion/ion_buffer.c b/drivers/staging/android/ion/ion_buffer.c -new file mode 100644 -index 000000000000..8b8dd1e216d4 ---- /dev/null -+++ b/drivers/staging/android/ion/ion_buffer.c -@@ -0,0 +1,198 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * ION Memory Allocator - buffer interface -+ * -+ * Copyright (c) 2019, Google, Inc. -+ */ -+ -+#include -+#include -+ -+#include "ion_private.h" -+ -+/* this function should only be called while dev->lock is held */ -+static void ion_buffer_add(struct ion_device *dev, -+ struct ion_buffer *buffer) -+{ -+ struct rb_node **p = &dev->buffers.rb_node; -+ struct rb_node *parent = NULL; -+ struct ion_buffer *entry; -+ -+ while (*p) { -+ parent = *p; -+ entry = rb_entry(parent, struct ion_buffer, node); -+ -+ if (buffer < entry) { -+ p = &(*p)->rb_left; -+ } else if (buffer > entry) { -+ p = &(*p)->rb_right; -+ } else { -+ pr_err("%s: buffer already found.", __func__); -+ BUG(); -+ } -+ } -+ -+ rb_link_node(&buffer->node, parent, p); -+ rb_insert_color(&buffer->node, &dev->buffers); -+} -+ -+/* this function should only be called while dev->lock is held */ -+static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, -+ struct ion_device *dev, -+ unsigned long len, -+ unsigned long flags) -+{ -+ struct ion_buffer *buffer; -+ int ret; -+ -+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); -+ if (!buffer) -+ return ERR_PTR(-ENOMEM); -+ -+ buffer->heap = heap; -+ buffer->flags = flags; -+ buffer->size = len; -+ -+ ret = heap->ops->allocate(heap, buffer, len, flags); -+ -+ if (ret) { -+ if (!(heap->flags & ION_HEAP_FLAG_DEFER_FREE)) -+ goto err2; -+ -+ ion_heap_freelist_drain(heap, 0); -+ ret = heap->ops->allocate(heap, buffer, len, flags); -+ if (ret) -+ goto err2; -+ } -+ -+ if (!buffer->sg_table) { -+ WARN_ONCE(1, "This heap needs to set the sgtable"); -+ ret = -EINVAL; -+ goto err1; -+ } -+ -+ spin_lock(&heap->stat_lock); -+ heap->num_of_buffers++; -+ heap->num_of_alloc_bytes += len; -+ if (heap->num_of_alloc_bytes > heap->alloc_bytes_wm) -+ heap->alloc_bytes_wm = heap->num_of_alloc_bytes; -+ spin_unlock(&heap->stat_lock); -+ -+ INIT_LIST_HEAD(&buffer->attachments); -+ mutex_init(&buffer->lock); -+ mutex_lock(&dev->buffer_lock); -+ ion_buffer_add(dev, buffer); -+ mutex_unlock(&dev->buffer_lock); -+ return buffer; -+ -+err1: -+ heap->ops->free(buffer); -+err2: -+ kfree(buffer); -+ return ERR_PTR(ret); -+} -+ -+struct ion_buffer *ion_buffer_alloc(struct ion_device *dev, size_t len, -+ unsigned int heap_id_mask, -+ unsigned int flags) -+{ -+ struct ion_buffer *buffer = NULL; -+ struct ion_heap *heap; -+ -+ if (!dev || !len) { -+ return ERR_PTR(-EINVAL); -+ } -+ -+ /* -+ * traverse the list of heaps available in this system in priority -+ * order. If the heap type is supported by the client, and matches the -+ * request of the caller allocate from it. Repeat until allocate has -+ * succeeded or all heaps have been tried -+ */ -+ len = PAGE_ALIGN(len); -+ if (!len) -+ return ERR_PTR(-EINVAL); -+ -+ down_read(&dev->lock); -+ plist_for_each_entry(heap, &dev->heaps, node) { -+ /* if the caller didn't specify this heap id */ -+ if (!((1 << heap->id) & heap_id_mask)) -+ continue; -+ buffer = ion_buffer_create(heap, dev, len, flags); -+ if (!IS_ERR(buffer)) -+ break; -+ } -+ up_read(&dev->lock); -+ -+ if (!buffer) -+ return ERR_PTR(-ENODEV); -+ -+ if (IS_ERR(buffer)) -+ return ERR_CAST(buffer); -+ -+ return buffer; -+} -+ -+void ion_buffer_release(struct ion_buffer *buffer) -+{ -+ if (buffer->kmap_cnt > 0) { -+ pr_warn_once("%s: buffer still mapped in the kernel\n", -+ __func__); -+ buffer->heap->ops->unmap_kernel(buffer->heap, buffer); -+ } -+ buffer->heap->ops->free(buffer); -+ spin_lock(&buffer->heap->stat_lock); -+ buffer->heap->num_of_buffers--; -+ buffer->heap->num_of_alloc_bytes -= buffer->size; -+ spin_unlock(&buffer->heap->stat_lock); -+ -+ kfree(buffer); -+} -+ -+void ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer) -+{ -+ struct ion_heap *heap; -+ -+ if (!dev || !buffer) { -+ pr_warn("%s: invalid argument\n", __func__); -+ return; -+ } -+ -+ heap = buffer->heap; -+ mutex_lock(&dev->buffer_lock); -+ rb_erase(&buffer->node, &dev->buffers); -+ mutex_unlock(&dev->buffer_lock); -+ -+ if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) -+ ion_heap_freelist_add(heap, buffer); -+ else -+ ion_buffer_release(buffer); -+} -+ -+void *ion_buffer_kmap_get(struct ion_buffer *buffer) -+{ -+ void *vaddr; -+ -+ if (buffer->kmap_cnt) { -+ buffer->kmap_cnt++; -+ return buffer->vaddr; -+ } -+ vaddr = buffer->heap->ops->map_kernel(buffer->heap, buffer); -+ if (WARN_ONCE(!vaddr, -+ "heap->ops->map_kernel should return ERR_PTR on error")) -+ return ERR_PTR(-EINVAL); -+ if (IS_ERR(vaddr)) -+ return vaddr; -+ buffer->vaddr = vaddr; -+ buffer->kmap_cnt++; -+ return vaddr; -+} -+ -+void ion_buffer_kmap_put(struct ion_buffer *buffer) -+{ -+ buffer->kmap_cnt--; -+ if (!buffer->kmap_cnt) { -+ buffer->heap->ops->unmap_kernel(buffer->heap, buffer); -+ buffer->vaddr = NULL; -+ } -+} -diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c -index 473b465724f1..3b4f32b9cd2d 100644 ---- a/drivers/staging/android/ion/ion_heap.c -+++ b/drivers/staging/android/ion/ion_heap.c -@@ -15,7 +15,7 @@ - #include - #include - --#include "ion.h" -+#include "ion_private.h" - - void *ion_heap_map_kernel(struct ion_heap *heap, - struct ion_buffer *buffer) -@@ -198,7 +198,7 @@ static size_t _ion_heap_freelist_drain(struct ion_heap *heap, size_t size, - buffer->private_flags |= ION_PRIV_FLAG_SHRINKER_FREE; - total_drained += buffer->size; - spin_unlock(&heap->free_lock); -- ion_buffer_destroy(buffer); -+ ion_buffer_release(buffer); - spin_lock(&heap->free_lock); - } - spin_unlock(&heap->free_lock); -@@ -236,7 +236,7 @@ static int ion_heap_deferred_free(void *data) - list_del(&buffer->list); - heap->free_list_size -= buffer->size; - spin_unlock(&heap->free_lock); -- ion_buffer_destroy(buffer); -+ ion_buffer_release(buffer); - } - - return 0; -diff --git a/drivers/staging/android/ion/ion_private.h b/drivers/staging/android/ion/ion_private.h -new file mode 100644 -index 000000000000..e80692c885b4 ---- /dev/null -+++ b/drivers/staging/android/ion/ion_private.h -@@ -0,0 +1,47 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * ION Memory Allocator - Internal header -+ * -+ * Copyright (C) 2019 Google, Inc. -+ */ -+ -+#ifndef _ION_PRIVATE_H -+#define _ION_PRIVATE_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "ion.h" -+ -+/** -+ * struct ion_device - the metadata of the ion device node -+ * @dev: the actual misc device -+ * @buffers: an rb tree of all the existing buffers -+ * @buffer_lock: lock protecting the tree of buffers -+ * @lock: rwsem protecting the tree of heaps and clients -+ */ -+struct ion_device { -+ struct miscdevice dev; -+ struct rb_root buffers; -+ struct mutex buffer_lock; -+ struct rw_semaphore lock; -+ struct plist_head heaps; -+ struct dentry *debug_root; -+ int heap_cnt; -+}; -+ -+/* ion_buffer manipulators */ -+extern struct ion_buffer *ion_buffer_alloc(struct ion_device *dev, size_t len, -+ unsigned int heap_id_mask, -+ unsigned int flags); -+extern void ion_buffer_release(struct ion_buffer *buffer); -+extern void ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer); -+extern void *ion_buffer_kmap_get(struct ion_buffer *buffer); -+extern void ion_buffer_kmap_put(struct ion_buffer *buffer); -+ -+#endif /* _ION_PRIVATE_H */ diff --git a/patches/ANDROID-staging-ion-refactor-ion-s-dmabuf-manipulators-into-a-separate-file.patch b/patches/ANDROID-staging-ion-refactor-ion-s-dmabuf-manipulators-into-a-separate-file.patch deleted file mode 100644 index d4666692f175..000000000000 --- a/patches/ANDROID-staging-ion-refactor-ion-s-dmabuf-manipulators-into-a-separate-file.patch +++ /dev/null @@ -1,677 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Wed, 7 Aug 2019 15:01:24 -0700 -Subject: ANDROID: staging: ion: refactor ion's dmabuf manipulators into a - separate file. - -This patch is preparatory work for making ion heaps modular. The patch -itself doesn't make any significant changes except for re-organizing the -buffer manipulator functions in a single file. This will be helpful -later when we specifically export some of these functions to be used by -a heap module. - -Bug: 133508579 -Test: ion-unit-tests - -Change-Id: I52ecea78a179c936006a21beb7630009984cb22f -Co-developed-by: Isaac J. Manjarres -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/Makefile | 2 +- - drivers/staging/android/ion/ion.c | 254 +--------------------- - drivers/staging/android/ion/ion_buffer.c | 6 +- - drivers/staging/android/ion/ion_dma_buf.c | 252 +++++++++++++++++++++ - drivers/staging/android/ion/ion_private.h | 11 +- - include/linux/ion.h | 16 +- - 6 files changed, 289 insertions(+), 252 deletions(-) - create mode 100644 drivers/staging/android/ion/ion_dma_buf.c - -diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile -index da386dbf3ffd..b6fab2816781 100644 ---- a/drivers/staging/android/ion/Makefile -+++ b/drivers/staging/android/ion/Makefile -@@ -1,4 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0 --obj-$(CONFIG_ION) += ion.o ion_buffer.o ion_heap.o -+obj-$(CONFIG_ION) += ion.o ion_buffer.o ion_dma_buf.o ion_heap.o - obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o - obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o -diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c -index 19d3e82b2f5b..c80a31da371b 100644 ---- a/drivers/staging/android/ion/ion.c -+++ b/drivers/staging/android/ion/ion.c -@@ -17,276 +17,38 @@ - #include - #include - #include --#include - #include - #include - #include - #include - #include - #include --#include - - #include "ion_private.h" - - static struct ion_device *internal_dev; - static int heap_id; - --static struct sg_table *dup_sg_table(struct sg_table *table) --{ -- struct sg_table *new_table; -- int ret, i; -- struct scatterlist *sg, *new_sg; -- -- new_table = kzalloc(sizeof(*new_table), GFP_KERNEL); -- if (!new_table) -- return ERR_PTR(-ENOMEM); -- -- ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); -- if (ret) { -- kfree(new_table); -- return ERR_PTR(-ENOMEM); -- } -- -- new_sg = new_table->sgl; -- for_each_sg(table->sgl, sg, table->nents, i) { -- memcpy(new_sg, sg, sizeof(*sg)); -- new_sg->dma_address = 0; -- new_sg = sg_next(new_sg); -- } -- -- return new_table; --} -- --static void free_duped_table(struct sg_table *table) --{ -- sg_free_table(table); -- kfree(table); --} -- --struct ion_dma_buf_attachment { -- struct device *dev; -- struct sg_table *table; -- struct list_head list; --}; -- --static int ion_dma_buf_attach(struct dma_buf *dmabuf, -- struct dma_buf_attachment *attachment) --{ -- struct ion_dma_buf_attachment *a; -- struct sg_table *table; -- struct ion_buffer *buffer = dmabuf->priv; -- -- a = kzalloc(sizeof(*a), GFP_KERNEL); -- if (!a) -- return -ENOMEM; -- -- table = dup_sg_table(buffer->sg_table); -- if (IS_ERR(table)) { -- kfree(a); -- return -ENOMEM; -- } -- -- a->table = table; -- a->dev = attachment->dev; -- INIT_LIST_HEAD(&a->list); -- -- attachment->priv = a; -- -- mutex_lock(&buffer->lock); -- list_add(&a->list, &buffer->attachments); -- mutex_unlock(&buffer->lock); -- -- return 0; --} -- --static void ion_dma_buf_detatch(struct dma_buf *dmabuf, -- struct dma_buf_attachment *attachment) --{ -- struct ion_dma_buf_attachment *a = attachment->priv; -- struct ion_buffer *buffer = dmabuf->priv; -- -- mutex_lock(&buffer->lock); -- list_del(&a->list); -- mutex_unlock(&buffer->lock); -- free_duped_table(a->table); -- -- kfree(a); --} -- --static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment, -- enum dma_data_direction direction) --{ -- struct ion_dma_buf_attachment *a = attachment->priv; -- struct sg_table *table; -- -- table = a->table; -- -- if (!dma_map_sg(attachment->dev, table->sgl, table->nents, -- direction)) -- return ERR_PTR(-ENOMEM); -- -- return table; --} -- --static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment, -- struct sg_table *table, -- enum dma_data_direction direction) --{ -- dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); --} -- --static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) --{ -- struct ion_buffer *buffer = dmabuf->priv; -- int ret = 0; -- -- if (!buffer->heap->ops->map_user) { -- pr_err("%s: this heap does not define a method for mapping to userspace\n", -- __func__); -- return -EINVAL; -- } -- -- if (!(buffer->flags & ION_FLAG_CACHED)) -- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); -- -- mutex_lock(&buffer->lock); -- /* now map it to userspace */ -- ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma); -- mutex_unlock(&buffer->lock); -- -- if (ret) -- pr_err("%s: failure mapping buffer to userspace\n", -- __func__); -- -- return ret; --} -- --static void ion_dma_buf_release(struct dma_buf *dmabuf) --{ -- struct ion_buffer *buffer = dmabuf->priv; -- -- ion_buffer_destroy(internal_dev, buffer); --} -- --static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) --{ -- struct ion_buffer *buffer = dmabuf->priv; -- -- return buffer->vaddr + offset * PAGE_SIZE; --} -- --static void ion_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset, -- void *ptr) --{ --} -- --static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, -- enum dma_data_direction direction) --{ -- struct ion_buffer *buffer = dmabuf->priv; -- void *vaddr; -- struct ion_dma_buf_attachment *a; -- int ret = 0; -- -- /* -- * TODO: Move this elsewhere because we don't always need a vaddr -- */ -- if (buffer->heap->ops->map_kernel) { -- mutex_lock(&buffer->lock); -- vaddr = ion_buffer_kmap_get(buffer); -- if (IS_ERR(vaddr)) { -- ret = PTR_ERR(vaddr); -- goto unlock; -- } -- mutex_unlock(&buffer->lock); -- } -- -- mutex_lock(&buffer->lock); -- list_for_each_entry(a, &buffer->attachments, list) { -- dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, -- direction); -- } -- --unlock: -- mutex_unlock(&buffer->lock); -- return ret; --} -- --static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, -- enum dma_data_direction direction) --{ -- struct ion_buffer *buffer = dmabuf->priv; -- struct ion_dma_buf_attachment *a; -- -- if (buffer->heap->ops->map_kernel) { -- mutex_lock(&buffer->lock); -- ion_buffer_kmap_put(buffer); -- mutex_unlock(&buffer->lock); -- } -- -- mutex_lock(&buffer->lock); -- list_for_each_entry(a, &buffer->attachments, list) { -- dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, -- direction); -- } -- mutex_unlock(&buffer->lock); -- -- return 0; --} -- --static const struct dma_buf_ops dma_buf_ops = { -- .map_dma_buf = ion_map_dma_buf, -- .unmap_dma_buf = ion_unmap_dma_buf, -- .mmap = ion_mmap, -- .release = ion_dma_buf_release, -- .attach = ion_dma_buf_attach, -- .detach = ion_dma_buf_detatch, -- .begin_cpu_access = ion_dma_buf_begin_cpu_access, -- .end_cpu_access = ion_dma_buf_end_cpu_access, -- .map = ion_dma_buf_kmap, -- .unmap = ion_dma_buf_kunmap, --}; -- --static struct dma_buf *ion_alloc_dmabuf(size_t len, unsigned int heap_id_mask, -- unsigned int flags) --{ -- struct ion_buffer *buffer; -- DEFINE_DMA_BUF_EXPORT_INFO(exp_info); -- struct dma_buf *dmabuf; -- -- pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__, -- len, heap_id_mask, flags); -- -- buffer = ion_buffer_alloc(internal_dev, len, heap_id_mask, flags); -- if (IS_ERR(buffer)) -- return ERR_CAST(buffer); -- -- exp_info.ops = &dma_buf_ops; -- exp_info.size = buffer->size; -- exp_info.flags = O_RDWR; -- exp_info.priv = buffer; -- -- dmabuf = dma_buf_export(&exp_info); -- if (IS_ERR(dmabuf)) -- ion_buffer_destroy(internal_dev, buffer); -- -- return dmabuf; --} -- -+/* Entry into ION allocator for rest of the kernel */ - struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, - unsigned int flags) - { -- return ion_alloc_dmabuf(len, heap_id_mask, flags); -+ return ion_dmabuf_alloc(internal_dev, len, heap_id_mask, flags); - } - EXPORT_SYMBOL_GPL(ion_alloc); - -+int ion_free(struct ion_buffer *buffer) -+{ -+ return ion_buffer_destroy(internal_dev, buffer); -+} -+ - static int ion_alloc_fd(size_t len, unsigned int heap_id_mask, - unsigned int flags) - { - int fd; - struct dma_buf *dmabuf; - -- dmabuf = ion_alloc_dmabuf(len, heap_id_mask, flags); -+ dmabuf = ion_dmabuf_alloc(internal_dev, len, heap_id_mask, flags); - if (IS_ERR(dmabuf)) - return PTR_ERR(dmabuf); - -diff --git a/drivers/staging/android/ion/ion_buffer.c b/drivers/staging/android/ion/ion_buffer.c -index 8b8dd1e216d4..c10ea6672f1a 100644 ---- a/drivers/staging/android/ion/ion_buffer.c -+++ b/drivers/staging/android/ion/ion_buffer.c -@@ -149,13 +149,13 @@ void ion_buffer_release(struct ion_buffer *buffer) - kfree(buffer); - } - --void ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer) -+int ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer) - { - struct ion_heap *heap; - - if (!dev || !buffer) { - pr_warn("%s: invalid argument\n", __func__); -- return; -+ return -EINVAL; - } - - heap = buffer->heap; -@@ -167,6 +167,8 @@ void ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer) - ion_heap_freelist_add(heap, buffer); - else - ion_buffer_release(buffer); -+ -+ return 0; - } - - void *ion_buffer_kmap_get(struct ion_buffer *buffer) -diff --git a/drivers/staging/android/ion/ion_dma_buf.c b/drivers/staging/android/ion/ion_dma_buf.c -new file mode 100644 -index 000000000000..0de08e6f1af5 ---- /dev/null -+++ b/drivers/staging/android/ion/ion_dma_buf.c -@@ -0,0 +1,252 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * ION Memory Allocator - dmabuf interface -+ * -+ * Copyright (c) 2019, Google, Inc. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "ion_private.h" -+ -+static struct sg_table *dup_sg_table(struct sg_table *table) -+{ -+ struct sg_table *new_table; -+ int ret, i; -+ struct scatterlist *sg, *new_sg; -+ -+ new_table = kzalloc(sizeof(*new_table), GFP_KERNEL); -+ if (!new_table) -+ return ERR_PTR(-ENOMEM); -+ -+ ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); -+ if (ret) { -+ kfree(new_table); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ new_sg = new_table->sgl; -+ for_each_sg(table->sgl, sg, table->nents, i) { -+ memcpy(new_sg, sg, sizeof(*sg)); -+ new_sg->dma_address = 0; -+ new_sg = sg_next(new_sg); -+ } -+ -+ return new_table; -+} -+ -+static void free_duped_table(struct sg_table *table) -+{ -+ sg_free_table(table); -+ kfree(table); -+} -+ -+struct ion_dma_buf_attachment { -+ struct device *dev; -+ struct sg_table *table; -+ struct list_head list; -+}; -+ -+static int ion_dma_buf_attach(struct dma_buf *dmabuf, -+ struct dma_buf_attachment *attachment) -+{ -+ struct ion_dma_buf_attachment *a; -+ struct sg_table *table; -+ struct ion_buffer *buffer = dmabuf->priv; -+ -+ a = kzalloc(sizeof(*a), GFP_KERNEL); -+ if (!a) -+ return -ENOMEM; -+ -+ table = dup_sg_table(buffer->sg_table); -+ if (IS_ERR(table)) { -+ kfree(a); -+ return -ENOMEM; -+ } -+ -+ a->table = table; -+ a->dev = attachment->dev; -+ INIT_LIST_HEAD(&a->list); -+ -+ attachment->priv = a; -+ -+ mutex_lock(&buffer->lock); -+ list_add(&a->list, &buffer->attachments); -+ mutex_unlock(&buffer->lock); -+ -+ return 0; -+} -+ -+static void ion_dma_buf_detatch(struct dma_buf *dmabuf, -+ struct dma_buf_attachment *attachment) -+{ -+ struct ion_dma_buf_attachment *a = attachment->priv; -+ struct ion_buffer *buffer = dmabuf->priv; -+ -+ mutex_lock(&buffer->lock); -+ list_del(&a->list); -+ mutex_unlock(&buffer->lock); -+ free_duped_table(a->table); -+ -+ kfree(a); -+} -+ -+static struct sg_table *ion_dma_buf_map(struct dma_buf_attachment *attachment, -+ enum dma_data_direction direction) -+{ -+ struct ion_dma_buf_attachment *a = attachment->priv; -+ struct sg_table *table; -+ -+ table = a->table; -+ -+ if (!dma_map_sg(attachment->dev, table->sgl, table->nents, -+ direction)) -+ return ERR_PTR(-ENOMEM); -+ -+ return table; -+} -+ -+static void ion_dma_buf_unmap(struct dma_buf_attachment *attachment, -+ struct sg_table *table, -+ enum dma_data_direction direction) -+{ -+ dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); -+} -+ -+static int ion_dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) -+{ -+ struct ion_buffer *buffer = dmabuf->priv; -+ int ret = 0; -+ -+ if (!buffer->heap->ops->map_user) { -+ pr_err("%s: this heap does not define a method for mapping to userspace\n", -+ __func__); -+ return -EINVAL; -+ } -+ -+ if (!(buffer->flags & ION_FLAG_CACHED)) -+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); -+ -+ mutex_lock(&buffer->lock); -+ /* now map it to userspace */ -+ ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma); -+ mutex_unlock(&buffer->lock); -+ -+ if (ret) -+ pr_err("%s: failure mapping buffer to userspace\n", -+ __func__); -+ -+ return ret; -+} -+ -+static void ion_dma_buf_release(struct dma_buf *dmabuf) -+{ -+ struct ion_buffer *buffer = dmabuf->priv; -+ -+ ion_free(buffer); -+} -+ -+static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) -+{ -+ struct ion_buffer *buffer = dmabuf->priv; -+ -+ return buffer->vaddr + offset * PAGE_SIZE; -+} -+ -+static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, -+ enum dma_data_direction direction) -+{ -+ struct ion_buffer *buffer = dmabuf->priv; -+ void *vaddr; -+ struct ion_dma_buf_attachment *a; -+ int ret = 0; -+ -+ /* -+ * TODO: Move this elsewhere because we don't always need a vaddr -+ */ -+ if (buffer->heap->ops->map_kernel) { -+ mutex_lock(&buffer->lock); -+ vaddr = ion_buffer_kmap_get(buffer); -+ if (IS_ERR(vaddr)) { -+ ret = PTR_ERR(vaddr); -+ goto unlock; -+ } -+ mutex_unlock(&buffer->lock); -+ } -+ -+ mutex_lock(&buffer->lock); -+ list_for_each_entry(a, &buffer->attachments, list) { -+ dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, -+ direction); -+ } -+ -+unlock: -+ mutex_unlock(&buffer->lock); -+ return ret; -+} -+ -+static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, -+ enum dma_data_direction direction) -+{ -+ struct ion_buffer *buffer = dmabuf->priv; -+ struct ion_dma_buf_attachment *a; -+ -+ if (buffer->heap->ops->map_kernel) { -+ mutex_lock(&buffer->lock); -+ ion_buffer_kmap_put(buffer); -+ mutex_unlock(&buffer->lock); -+ } -+ -+ mutex_lock(&buffer->lock); -+ list_for_each_entry(a, &buffer->attachments, list) { -+ dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, -+ direction); -+ } -+ mutex_unlock(&buffer->lock); -+ -+ return 0; -+} -+ -+static const struct dma_buf_ops dma_buf_ops = { -+ .map_dma_buf = ion_dma_buf_map, -+ .unmap_dma_buf = ion_dma_buf_unmap, -+ .mmap = ion_dma_buf_mmap, -+ .release = ion_dma_buf_release, -+ .attach = ion_dma_buf_attach, -+ .detach = ion_dma_buf_detatch, -+ .begin_cpu_access = ion_dma_buf_begin_cpu_access, -+ .end_cpu_access = ion_dma_buf_end_cpu_access, -+ .map = ion_dma_buf_kmap, -+}; -+ -+struct dma_buf *ion_dmabuf_alloc(struct ion_device *dev, size_t len, -+ unsigned int heap_id_mask, -+ unsigned int flags) -+{ -+ struct ion_buffer *buffer; -+ DEFINE_DMA_BUF_EXPORT_INFO(exp_info); -+ struct dma_buf *dmabuf; -+ -+ pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__, -+ len, heap_id_mask, flags); -+ -+ buffer = ion_buffer_alloc(dev, len, heap_id_mask, flags); -+ if (IS_ERR(buffer)) -+ return ERR_CAST(buffer); -+ -+ exp_info.ops = &dma_buf_ops; -+ exp_info.size = buffer->size; -+ exp_info.flags = O_RDWR; -+ exp_info.priv = buffer; -+ -+ dmabuf = dma_buf_export(&exp_info); -+ if (IS_ERR(dmabuf)) -+ ion_buffer_destroy(dev, buffer); -+ -+ return dmabuf; -+} -diff --git a/drivers/staging/android/ion/ion_private.h b/drivers/staging/android/ion/ion_private.h -index e80692c885b4..b3c8b55788db 100644 ---- a/drivers/staging/android/ion/ion_private.h -+++ b/drivers/staging/android/ion/ion_private.h -@@ -9,6 +9,7 @@ - #define _ION_PRIVATE_H - - #include -+#include - #include - #include - #include -@@ -40,8 +41,16 @@ extern struct ion_buffer *ion_buffer_alloc(struct ion_device *dev, size_t len, - unsigned int heap_id_mask, - unsigned int flags); - extern void ion_buffer_release(struct ion_buffer *buffer); --extern void ion_buffer_destroy(struct ion_device *dev, struct ion_buffer *buffer); -+extern int ion_buffer_destroy(struct ion_device *dev, -+ struct ion_buffer *buffer); - extern void *ion_buffer_kmap_get(struct ion_buffer *buffer); - extern void ion_buffer_kmap_put(struct ion_buffer *buffer); - -+/* ion dmabuf allocator */ -+extern struct dma_buf *ion_dmabuf_alloc(struct ion_device *dev, size_t len, -+ unsigned int heap_id_mask, -+ unsigned int flags); -+extern int ion_free(struct ion_buffer *buffer); -+ -+ - #endif /* _ION_PRIVATE_H */ -diff --git a/include/linux/ion.h b/include/linux/ion.h -index 7bec77d98224..66a694b875ca 100644 ---- a/include/linux/ion.h -+++ b/include/linux/ion.h -@@ -10,8 +10,18 @@ - #include - - #ifdef CONFIG_ION --/* -- * Allocates an ION buffer. -+ -+ -+/** -+ * ion_alloc - Allocates an ion buffer of given size from given heap -+ * -+ * @len: size of the buffer to be allocated. -+ * @heap_id_mask: a bitwise maks of heap ids to allocate from -+ * @flags: ION_BUFFER_XXXX flags for the new buffer. -+ * -+ * The function exports a dma_buf object for the new ion buffer internally -+ * and returns that to the caller. So, the buffer is ready to be used by other -+ * drivers immediately. Returns ERR_PTR in case of failure. - */ - struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, - unsigned int flags); -@@ -22,5 +32,7 @@ static inline struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, - { - return ERR_PTR(-ENOMEM); - } -+ -+ - #endif /* CONFIG_ION */ - #endif /* _ION_KERNEL_H */ diff --git a/patches/ANDROID-staging-ion-refactor-ion-s-heap-API-into-linux-ion.h.patch b/patches/ANDROID-staging-ion-refactor-ion-s-heap-API-into-linux-ion.h.patch deleted file mode 100644 index 00a9df0371e5..000000000000 --- a/patches/ANDROID-staging-ion-refactor-ion-s-heap-API-into-linux-ion.h.patch +++ /dev/null @@ -1,871 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Thu, 8 Aug 2019 08:35:46 -0700 -Subject: ANDROID: staging: ion: refactor ion's heap API into linux/ion.h - -Now that we know the APIs needed by system and cma heaps, -refactor and move all those into linux/ion.h. - -Unfortunately, the UAPI of ion is now split into linux/ion.h -and drivers/staging/android/uapi/ion.h since some of the UAPI -leaks into heap implementation (ion flags). It can all be moved -into linux/ion.h eventually for all android kernels. - -Bug: 133508579 -Test: ion-unit-tests - -Change-Id: I73ea59b410c46a02e23f2da5c6bdc15182a50b32 -Co-developed-by: Isaac J. Manjarres -Signed-off-by: Sandeep Patil ---- - .../staging/android/ion/heaps/ion_cma_heap.c | 3 +- - .../android/ion/heaps/ion_system_heap.c | 2 +- - drivers/staging/android/ion/ion.c | 1 - - drivers/staging/android/ion/ion.h | 246 -------------- - drivers/staging/android/ion/ion_buffer.c | 37 ++- - drivers/staging/android/ion/ion_heap.c | 44 --- - drivers/staging/android/ion/ion_private.h | 3 +- - include/linux/ion.h | 312 +++++++++++++++++- - .../staging/android => include}/uapi/ion.h | 35 +- - 9 files changed, 367 insertions(+), 316 deletions(-) - delete mode 100644 drivers/staging/android/ion/ion.h - rename {drivers/staging/android => include}/uapi/ion.h (74%) - -diff --git a/drivers/staging/android/ion/heaps/ion_cma_heap.c b/drivers/staging/android/ion/heaps/ion_cma_heap.c -index 0872e5d630f8..83f7dce74f18 100644 ---- a/drivers/staging/android/ion/heaps/ion_cma_heap.c -+++ b/drivers/staging/android/ion/heaps/ion_cma_heap.c -@@ -7,6 +7,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -14,8 +15,6 @@ - #include - #include - --#include "../ion.h" -- - struct ion_cma_heap { - struct ion_heap heap; - struct cma *cma; -diff --git a/drivers/staging/android/ion/heaps/ion_system_heap.c b/drivers/staging/android/ion/heaps/ion_system_heap.c -index 8e26016082d4..afb2a6385705 100644 ---- a/drivers/staging/android/ion/heaps/ion_system_heap.c -+++ b/drivers/staging/android/ion/heaps/ion_system_heap.c -@@ -9,12 +9,12 @@ - #include - #include - #include -+#include - #include - #include - #include - #include - --#include "../ion.h" - #include "ion_page_pool.h" - - #define NUM_ORDERS ARRAY_SIZE(orders) -diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c -index c80a31da371b..b862bdfeca89 100644 ---- a/drivers/staging/android/ion/ion.c -+++ b/drivers/staging/android/ion/ion.c -@@ -246,7 +246,6 @@ void ion_device_add_heap(struct ion_heap *heap) - pr_err("%s: Failed to register shrinker\n", __func__); - } - -- heap->dev = dev; - heap->num_of_buffers = 0; - heap->num_of_alloc_bytes = 0; - heap->alloc_bytes_wm = 0; -diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h -deleted file mode 100644 -index b5b5412507fd..000000000000 ---- a/drivers/staging/android/ion/ion.h -+++ /dev/null -@@ -1,246 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0 */ --/* -- * ION Memory Allocator kernel interface header -- * -- * Copyright (C) 2011 Google, Inc. -- */ -- --#ifndef _ION_H --#define _ION_H -- --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "../uapi/ion.h" -- --/** -- * struct ion_buffer - metadata for a particular buffer -- * @list: element in list of deferred freeable buffers -- * @dev: back pointer to the ion_device -- * @heap: back pointer to the heap the buffer came from -- * @flags: buffer specific flags -- * @private_flags: internal buffer specific flags -- * @size: size of the buffer -- * @priv_virt: private data to the buffer representable as -- * a void * -- * @lock: protects the buffers cnt fields -- * @kmap_cnt: number of times the buffer is mapped to the kernel -- * @vaddr: the kernel mapping if kmap_cnt is not zero -- * @sg_table: the sg table for the buffer -- * @attachments: list of devices attached to this buffer -- */ --struct ion_buffer { -- struct list_head list; -- struct ion_heap *heap; -- unsigned long flags; -- unsigned long private_flags; -- size_t size; -- void *priv_virt; -- struct mutex lock; -- int kmap_cnt; -- void *vaddr; -- struct sg_table *sg_table; -- struct list_head attachments; --}; -- --void ion_buffer_destroy(struct ion_buffer *buffer); -- --/** -- * struct ion_heap_ops - ops to operate on a given heap -- * @allocate: allocate memory -- * @free: free memory -- * @map_kernel map memory to the kernel -- * @unmap_kernel unmap memory to the kernel -- * @map_user map memory to userspace -- * -- * allocate, phys, and map_user return 0 on success, -errno on error. -- * map_dma and map_kernel return pointer on success, ERR_PTR on -- * error. @free will be called with ION_PRIV_FLAG_SHRINKER_FREE set in -- * the buffer's private_flags when called from a shrinker. In that -- * case, the pages being free'd must be truly free'd back to the -- * system, not put in a page pool or otherwise cached. -- */ --struct ion_heap_ops { -- int (*allocate)(struct ion_heap *heap, -- struct ion_buffer *buffer, unsigned long len, -- unsigned long flags); -- void (*free)(struct ion_buffer *buffer); -- void * (*map_kernel)(struct ion_heap *heap, struct ion_buffer *buffer); -- void (*unmap_kernel)(struct ion_heap *heap, struct ion_buffer *buffer); -- int (*map_user)(struct ion_heap *mapper, struct ion_buffer *buffer, -- struct vm_area_struct *vma); -- int (*shrink)(struct ion_heap *heap, gfp_t gfp_mask, int nr_to_scan); --}; -- --/** -- * heap flags - flags between the heaps and core ion code -- */ --#define ION_HEAP_FLAG_DEFER_FREE BIT(0) -- --/** -- * private flags - flags internal to ion -- */ --/* -- * Buffer is being freed from a shrinker function. Skip any possible -- * heap-specific caching mechanism (e.g. page pools). Guarantees that -- * any buffer storage that came from the system allocator will be -- * returned to the system allocator. -- */ --#define ION_PRIV_FLAG_SHRINKER_FREE BIT(0) -- --/** -- * struct ion_heap - represents a heap in the system -- * @node: rb node to put the heap on the device's tree of heaps -- * @dev: back pointer to the ion_device -- * @type: type of heap -- * @ops: ops struct as above -- * @flags: flags -- * @id: id of heap, also indicates priority of this heap when -- * allocating. These are specified by platform data and -- * MUST be unique -- * @name: used for debugging -- * @shrinker: a shrinker for the heap -- * @free_list: free list head if deferred free is used -- * @free_list_size size of the deferred free list in bytes -- * @lock: protects the free list -- * @waitqueue: queue to wait on from deferred free thread -- * @task: task struct of deferred free thread -- * @num_of_buffers the number of currently allocated buffers -- * @num_of_alloc_bytes the number of allocated bytes -- * @alloc_bytes_wm the number of allocated bytes watermark -- * -- * Represents a pool of memory from which buffers can be made. In some -- * systems the only heap is regular system memory allocated via vmalloc. -- * On others, some blocks might require large physically contiguous buffers -- * that are allocated from a specially reserved heap. -- */ --struct ion_heap { -- struct plist_node node; -- struct ion_device *dev; -- enum ion_heap_type type; -- struct ion_heap_ops *ops; -- unsigned long flags; -- unsigned int id; -- const char *name; -- -- /* deferred free support */ -- struct shrinker shrinker; -- struct list_head free_list; -- size_t free_list_size; -- spinlock_t free_lock; -- wait_queue_head_t waitqueue; -- struct task_struct *task; -- -- /* heap statistics */ -- u64 num_of_buffers; -- u64 num_of_alloc_bytes; -- u64 alloc_bytes_wm; -- -- /* protect heap statistics */ -- spinlock_t stat_lock; --}; -- --/** -- * ion_device_add_heap - adds a heap to the ion device -- * @heap: the heap to add -- */ --void ion_device_add_heap(struct ion_heap *heap); -- --/* ion_buffer_zero - zeroes out an ion buffer respecting the ION_FLAGs. -- * -- * @buffer: ion_buffer to zero -- * -- * Returns 0 on success, negative error otherwise. -- */ --int ion_buffer_zero(struct ion_buffer *buffer); -- --/** -- * some helpers for common operations on buffers using the sg_table -- * and vaddr fields -- */ --void *ion_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer); --void ion_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer); --int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, -- struct vm_area_struct *vma); --int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot); --int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, -- pgprot_t pgprot); -- --/** -- * ion_heap_init_shrinker -- * @heap: the heap -- * -- * If a heap sets the ION_HEAP_FLAG_DEFER_FREE flag or defines the shrink op -- * this function will be called to setup a shrinker to shrink the freelists -- * and call the heap's shrink op. -- */ --int ion_heap_init_shrinker(struct ion_heap *heap); -- --/** -- * ion_heap_init_deferred_free -- initialize deferred free functionality -- * @heap: the heap -- * -- * If a heap sets the ION_HEAP_FLAG_DEFER_FREE flag this function will -- * be called to setup deferred frees. Calls to free the buffer will -- * return immediately and the actual free will occur some time later -- */ --int ion_heap_init_deferred_free(struct ion_heap *heap); -- --/** -- * ion_heap_freelist_add - add a buffer to the deferred free list -- * @heap: the heap -- * @buffer: the buffer -- * -- * Adds an item to the deferred freelist. -- */ --void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer); -- --/** -- * ion_heap_freelist_drain - drain the deferred free list -- * @heap: the heap -- * @size: amount of memory to drain in bytes -- * -- * Drains the indicated amount of memory from the deferred freelist immediately. -- * Returns the total amount freed. The total freed may be higher depending -- * on the size of the items in the list, or lower if there is insufficient -- * total memory on the freelist. -- */ --size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size); -- --/** -- * ion_heap_freelist_shrink - drain the deferred free -- * list, skipping any heap-specific -- * pooling or caching mechanisms -- * -- * @heap: the heap -- * @size: amount of memory to drain in bytes -- * -- * Drains the indicated amount of memory from the deferred freelist immediately. -- * Returns the total amount freed. The total freed may be higher depending -- * on the size of the items in the list, or lower if there is insufficient -- * total memory on the freelist. -- * -- * Unlike with @ion_heap_freelist_drain, don't put any pages back into -- * page pools or otherwise cache the pages. Everything must be -- * genuinely free'd back to the system. If you're free'ing from a -- * shrinker you probably want to use this. Note that this relies on -- * the heap.ops.free callback honoring the ION_PRIV_FLAG_SHRINKER_FREE -- * flag. -- */ --size_t ion_heap_freelist_shrink(struct ion_heap *heap, -- size_t size); -- --/** -- * ion_heap_freelist_size - returns the size of the freelist in bytes -- * @heap: the heap -- */ --size_t ion_heap_freelist_size(struct ion_heap *heap); -- --#endif /* _ION_H */ -diff --git a/drivers/staging/android/ion/ion_buffer.c b/drivers/staging/android/ion/ion_buffer.c -index 50c2dbc3ebec..adce2d489f56 100644 ---- a/drivers/staging/android/ion/ion_buffer.c -+++ b/drivers/staging/android/ion/ion_buffer.c -@@ -92,6 +92,41 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, - return ERR_PTR(ret); - } - -+static int ion_clear_pages(struct page **pages, int num, pgprot_t pgprot) -+{ -+ void *addr = vm_map_ram(pages, num, -1, pgprot); -+ -+ if (!addr) -+ return -ENOMEM; -+ memset(addr, 0, PAGE_SIZE * num); -+ vm_unmap_ram(addr, num); -+ -+ return 0; -+} -+ -+static int ion_sglist_zero(struct scatterlist *sgl, unsigned int nents, -+ pgprot_t pgprot) -+{ -+ int p = 0; -+ int ret = 0; -+ struct sg_page_iter piter; -+ struct page *pages[32]; -+ -+ for_each_sg_page(sgl, &piter, nents, 0) { -+ pages[p++] = sg_page_iter_page(&piter); -+ if (p == ARRAY_SIZE(pages)) { -+ ret = ion_clear_pages(pages, p, pgprot); -+ if (ret) -+ return ret; -+ p = 0; -+ } -+ } -+ if (p) -+ ret = ion_clear_pages(pages, p, pgprot); -+ -+ return ret; -+} -+ - struct ion_buffer *ion_buffer_alloc(struct ion_device *dev, size_t len, - unsigned int heap_id_mask, - unsigned int flags) -@@ -147,7 +182,7 @@ int ion_buffer_zero(struct ion_buffer *buffer) - else - pgprot = pgprot_writecombine(PAGE_KERNEL); - -- return ion_heap_sglist_zero(table->sgl, table->nents, pgprot); -+ return ion_sglist_zero(table->sgl, table->nents, pgprot); - } - - void ion_buffer_release(struct ion_buffer *buffer) -diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c -index 39eb60e4842e..755548a4382d 100644 ---- a/drivers/staging/android/ion/ion_heap.c -+++ b/drivers/staging/android/ion/ion_heap.c -@@ -61,18 +61,6 @@ static unsigned long ion_heap_shrink_scan(struct shrinker *shrinker, - return freed; - } - --static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot) --{ -- void *addr = vm_map_ram(pages, num, -1, pgprot); -- -- if (!addr) -- return -ENOMEM; -- memset(addr, 0, PAGE_SIZE * num); -- vm_unmap_ram(addr, num); -- -- return 0; --} -- - static size_t _ion_heap_freelist_drain(struct ion_heap *heap, size_t size, - bool skip_pools) - { -@@ -211,38 +199,6 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, - return 0; - } - --int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, -- pgprot_t pgprot) --{ -- int p = 0; -- int ret = 0; -- struct sg_page_iter piter; -- struct page *pages[32]; -- -- for_each_sg_page(sgl, &piter, nents, 0) { -- pages[p++] = sg_page_iter_page(&piter); -- if (p == ARRAY_SIZE(pages)) { -- ret = ion_heap_clear_pages(pages, p, pgprot); -- if (ret) -- return ret; -- p = 0; -- } -- } -- if (p) -- ret = ion_heap_clear_pages(pages, p, pgprot); -- -- return ret; --} -- --int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot) --{ -- struct scatterlist sg; -- -- sg_init_table(&sg, 1); -- sg_set_page(&sg, page, size, 0); -- return ion_heap_sglist_zero(&sg, 1, pgprot); --} -- - void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer) - { - spin_lock(&heap->free_lock); -diff --git a/drivers/staging/android/ion/ion_private.h b/drivers/staging/android/ion/ion_private.h -index 9c8f482cd9d2..ed7ed39d0df1 100644 ---- a/drivers/staging/android/ion/ion_private.h -+++ b/drivers/staging/android/ion/ion_private.h -@@ -10,6 +10,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -17,8 +18,6 @@ - #include - #include - --#include "ion.h" -- - /** - * struct ion_device - the metadata of the ion device node - * @dev: the actual misc device -diff --git a/include/linux/ion.h b/include/linux/ion.h -index 66a694b875ca..775e948a362c 100644 ---- a/include/linux/ion.h -+++ b/include/linux/ion.h -@@ -8,9 +8,264 @@ - - #include - #include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/** -+ * struct ion_buffer - metadata for a particular buffer -+ * @node: node in the ion_device buffers tree -+ * @list: element in list of deferred freeable buffers -+ * @heap: back pointer to the heap the buffer came from -+ * @flags: buffer specific flags -+ * @private_flags: internal buffer specific flags -+ * @size: size of the buffer -+ * @priv_virt: private data to the buffer representable as -+ * a void * -+ * @lock: protects the buffers cnt fields -+ * @kmap_cnt: number of times the buffer is mapped to the kernel -+ * @vaddr: the kernel mapping if kmap_cnt is not zero -+ * @sg_table: the sg table for the buffer -+ * @attachments: list of devices attached to this buffer -+ */ -+struct ion_buffer { -+ union { -+ struct rb_node node; -+ struct list_head list; -+ }; -+ struct ion_heap *heap; -+ unsigned long flags; -+ unsigned long private_flags; -+ size_t size; -+ void *priv_virt; -+ struct mutex lock; -+ int kmap_cnt; -+ void *vaddr; -+ struct sg_table *sg_table; -+ struct list_head attachments; -+}; -+ -+/** -+ * struct ion_heap_ops - ops to operate on a given heap -+ * @allocate: allocate memory -+ * @free: free memory -+ * @map_kernel map memory to the kernel -+ * @unmap_kernel unmap memory to the kernel -+ * @map_user map memory to userspace -+ * -+ * allocate, phys, and map_user return 0 on success, -errno on error. -+ * map_dma and map_kernel return pointer on success, ERR_PTR on -+ * error. @free will be called with ION_PRIV_FLAG_SHRINKER_FREE set in -+ * the buffer's private_flags when called from a shrinker. In that -+ * case, the pages being free'd must be truly free'd back to the -+ * system, not put in a page pool or otherwise cached. -+ */ -+struct ion_heap_ops { -+ int (*allocate)(struct ion_heap *heap, -+ struct ion_buffer *buffer, unsigned long len, -+ unsigned long flags); -+ void (*free)(struct ion_buffer *buffer); -+ void * (*map_kernel)(struct ion_heap *heap, struct ion_buffer *buffer); -+ void (*unmap_kernel)(struct ion_heap *heap, struct ion_buffer *buffer); -+ int (*map_user)(struct ion_heap *mapper, struct ion_buffer *buffer, -+ struct vm_area_struct *vma); -+ int (*shrink)(struct ion_heap *heap, gfp_t gfp_mask, int nr_to_scan); -+}; -+ -+/** -+ * heap flags - flags between the heaps and core ion code -+ */ -+#define ION_HEAP_FLAG_DEFER_FREE BIT(0) -+ -+/** -+ * private flags - flags internal to ion -+ */ -+/* -+ * Buffer is being freed from a shrinker function. Skip any possible -+ * heap-specific caching mechanism (e.g. page pools). Guarantees that -+ * any buffer storage that came from the system allocator will be -+ * returned to the system allocator. -+ */ -+#define ION_PRIV_FLAG_SHRINKER_FREE BIT(0) -+ -+/** -+ * struct ion_heap - represents a heap in the system -+ * @node: rb node to put the heap on the device's tree of heaps -+ * @type: type of heap -+ * @ops: ops struct as above -+ * @flags: flags -+ * @id: id of heap, also indicates priority of this heap when -+ * allocating. These are specified by platform data and -+ * MUST be unique -+ * @name: used for debugging -+ * @shrinker: a shrinker for the heap -+ * @free_list: free list head if deferred free is used -+ * @free_list_size size of the deferred free list in bytes -+ * @lock: protects the free list -+ * @waitqueue: queue to wait on from deferred free thread -+ * @task: task struct of deferred free thread -+ * @num_of_buffers the number of currently allocated buffers -+ * @num_of_alloc_bytes the number of allocated bytes -+ * @alloc_bytes_wm the number of allocated bytes watermark -+ * -+ * Represents a pool of memory from which buffers can be made. In some -+ * systems the only heap is regular system memory allocated via vmalloc. -+ * On others, some blocks might require large physically contiguous buffers -+ * that are allocated from a specially reserved heap. -+ */ -+struct ion_heap { -+ struct plist_node node; -+ enum ion_heap_type type; -+ struct ion_heap_ops *ops; -+ unsigned long flags; -+ unsigned int id; -+ const char *name; -+ -+ /* deferred free support */ -+ struct shrinker shrinker; -+ struct list_head free_list; -+ size_t free_list_size; -+ spinlock_t free_lock; -+ wait_queue_head_t waitqueue; -+ struct task_struct *task; -+ -+ /* heap statistics */ -+ u64 num_of_buffers; -+ u64 num_of_alloc_bytes; -+ u64 alloc_bytes_wm; -+ -+ /* protect heap statistics */ -+ spinlock_t stat_lock; -+}; - - #ifdef CONFIG_ION - -+/** -+ * ion_device_add_heap - adds a heap to the ion device -+ * -+ * @heap: the heap to add -+ */ -+void ion_device_add_heap(struct ion_heap *heap); -+ -+/** -+ * ion_heap_init_shrinker -+ * @heap: the heap -+ * -+ * If a heap sets the ION_HEAP_FLAG_DEFER_FREE flag or defines the shrink op -+ * this function will be called to setup a shrinker to shrink the freelists -+ * and call the heap's shrink op. -+ */ -+int ion_heap_init_shrinker(struct ion_heap *heap); -+ -+/** -+ * ion_heap_init_deferred_free -- initialize deferred free functionality -+ * @heap: the heap -+ * -+ * If a heap sets the ION_HEAP_FLAG_DEFER_FREE flag this function will -+ * be called to setup deferred frees. Calls to free the buffer will -+ * return immediately and the actual free will occur some time later -+ */ -+int ion_heap_init_deferred_free(struct ion_heap *heap); -+ -+/** -+ * ion_heap_freelist_add - add a buffer to the deferred free list -+ * @heap: the heap -+ * @buffer: the buffer -+ * -+ * Adds an item to the deferred freelist. -+ */ -+void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer); -+ -+/** -+ * ion_heap_freelist_drain - drain the deferred free list -+ * @heap: the heap -+ * @size: amount of memory to drain in bytes -+ * -+ * Drains the indicated amount of memory from the deferred freelist immediately. -+ * Returns the total amount freed. The total freed may be higher depending -+ * on the size of the items in the list, or lower if there is insufficient -+ * total memory on the freelist. -+ */ -+size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size); -+ -+/** -+ * ion_heap_freelist_shrink - drain the deferred free -+ * list, skipping any heap-specific -+ * pooling or caching mechanisms -+ * -+ * @heap: the heap -+ * @size: amount of memory to drain in bytes -+ * -+ * Drains the indicated amount of memory from the deferred freelist immediately. -+ * Returns the total amount freed. The total freed may be higher depending -+ * on the size of the items in the list, or lower if there is insufficient -+ * total memory on the freelist. -+ * -+ * Unlike with @ion_heap_freelist_drain, don't put any pages back into -+ * page pools or otherwise cache the pages. Everything must be -+ * genuinely free'd back to the system. If you're free'ing from a -+ * shrinker you probably want to use this. Note that this relies on -+ * the heap.ops.free callback honoring the ION_PRIV_FLAG_SHRINKER_FREE -+ * flag. -+ */ -+size_t ion_heap_freelist_shrink(struct ion_heap *heap, -+ size_t size); -+ -+/** -+ * ion_heap_freelist_size - returns the size of the freelist in bytes -+ * @heap: the heap -+ */ -+size_t ion_heap_freelist_size(struct ion_heap *heap); -+ -+/** -+ * ion_heap_map_kernel - map the ion_buffer in kernel virtual address space. -+ * -+ * @heap: the heap -+ * @buffer: buffer to be mapped -+ * -+ * Maps the buffer using vmap(). The function respects cache flags for the -+ * buffer and creates the page table entries accordingly. Returns virtual -+ * address at the beginning of the buffer or ERR_PTR. -+ */ -+void *ion_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer); -+ -+/** -+ * ion_heap_unmap_kernel - unmap ion_buffer -+ * -+ * @buffer: buffer to be unmapped -+ * -+ * ION wrapper for vunmap() of the ion buffer. -+ */ -+void ion_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer); -+ -+/** -+ * ion_heap_map_user - map given ion buffer in provided vma -+ * -+ * @heap: the heap this buffer belongs to -+ * @buffer: Ion buffer to be mapped -+ * @vma: vma of the process where buffer should be mapped. -+ * -+ * Maps the buffer using remap_pfn_range() into specific process's vma starting -+ * with vma->vm_start. The vma size is expected to be >= ion buffer size. -+ * If not, a partial buffer mapping may be created. Returns 0 on success. -+ */ -+int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, -+ struct vm_area_struct *vma); -+ -+/* ion_buffer_zero - zeroes out an ion buffer respecting the ION_FLAGs. -+ * -+ * @buffer: ion_buffer to zero -+ * -+ * Returns 0 on success, negative error otherwise. -+ */ -+int ion_buffer_zero(struct ion_buffer *buffer); - - /** - * ion_alloc - Allocates an ion buffer of given size from given heap -@@ -27,12 +282,67 @@ struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, - unsigned int flags); - - #else -+ -+static inline int ion_device_add_heap(struct ion_heap *heap) -+{ -+ return -ENODEV; -+} -+ -+static inline int ion_heap_init_shrinker(struct ion_heap *heap) -+{ -+ return -ENODEV; -+} -+ -+static inline int ion_heap_init_deferred_free(struct ion_heap *heap) -+{ -+ return -ENODEV; -+} -+ -+static inline void ion_heap_freelist_add(struct ion_heap *heap, -+ struct ion_buffer *buffer) {} -+ -+static inline size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size) -+{ -+ return -ENODEV; -+} -+ -+static inline size_t ion_heap_freelist_shrink(struct ion_heap *heap, -+ size_t size) -+{ -+ return -ENODEV; -+} -+ -+static inline size_t ion_heap_freelist_size(struct ion_heap *heap) -+{ -+ return -ENODEV; -+} -+ -+static inline void *ion_heap_map_kernel(struct ion_heap *heap, -+ struct ion_buffer *buffer) -+{ -+ return ERR_PTR(-ENODEV); -+} -+ -+static inline void ion_heap_unmap_kernel(struct ion_heap *heap, -+ struct ion_buffer *buffer) {} -+ -+static inline int ion_heap_map_user(struct ion_heap *heap, -+ struct ion_buffer *buffer, -+ struct vm_area_struct *vma) -+{ -+ return -ENODEV; -+} -+ -+static inline int ion_buffer_zero(struct ion_buffer *buffer) -+{ -+ return -EINVAL; -+} -+ - static inline struct dma_buf *ion_alloc(size_t len, unsigned int heap_id_mask, - unsigned int flags) - { - return ERR_PTR(-ENOMEM); - } - -- - #endif /* CONFIG_ION */ - #endif /* _ION_KERNEL_H */ -diff --git a/drivers/staging/android/uapi/ion.h b/include/uapi/ion.h -similarity index 74% -rename from drivers/staging/android/uapi/ion.h -rename to include/uapi/ion.h -index 46c93fcb46d6..bfcbc0e70921 100644 ---- a/drivers/staging/android/uapi/ion.h -+++ b/include/uapi/ion.h -@@ -13,26 +13,25 @@ - - /** - * enum ion_heap_types - list of all possible types of heaps -- * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc -+ * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc - * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc -- * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved -- * carveout heap, allocations are physically -- * contiguous -- * @ION_HEAP_TYPE_DMA: memory allocated via DMA API -- * @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask -- * is used to identify the heaps, so only 32 -- * total heap types are supported -+ * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved -+ * carveout heap, allocations are physically -+ * contiguous -+ * @ION_HEAP_TYPE_DMA: memory allocated via DMA API -+ * @ION_HEAP_TYPE_MAX: helper for iterating over standard -+ * (not device specific) heaps -+ * @ION_NUM_HEAPS_IDS: helper for iterating over heaps, a bit mask -+ * is used to identify the heaps, so only 32 -+ * total heap types are supported - */ - enum ion_heap_type { -- ION_HEAP_TYPE_SYSTEM, -- ION_HEAP_TYPE_SYSTEM_CONTIG, -- ION_HEAP_TYPE_CARVEOUT, -- ION_HEAP_TYPE_CHUNK, -- ION_HEAP_TYPE_DMA, -- ION_HEAP_TYPE_CUSTOM, /* -- * must be last so device specific heaps always -- * are at the end of this enum -- */ -+ ION_HEAP_TYPE_SYSTEM = (1 << 0), -+ ION_HEAP_TYPE_SYSTEM_CONTIG = (1 << 1), -+ ION_HEAP_TYPE_CARVEOUT = (1 << 2), -+ ION_HEAP_TYPE_CHUNK = (1 << 3), -+ ION_HEAP_TYPE_DMA = (1 << 4), -+ ION_HEAP_TYPE_MAX = (1 << 15), - }; - - #define ION_NUM_HEAP_IDS (sizeof(unsigned int) * 8) -@@ -46,7 +45,7 @@ enum ion_heap_type { - * mappings of this buffer should be cached, ion will do cache maintenance - * when the buffer is mapped for dma - */ --#define ION_FLAG_CACHED 1 -+#define ION_FLAG_CACHED 1 - - /** - * DOC: Ion Userspace API diff --git a/patches/ANDROID-staging-ion-refactor-ion-s-heap-manipulators-into-a-separate-file.patch b/patches/ANDROID-staging-ion-refactor-ion-s-heap-manipulators-into-a-separate-file.patch deleted file mode 100644 index 195ffb58c615..000000000000 --- a/patches/ANDROID-staging-ion-refactor-ion-s-heap-manipulators-into-a-separate-file.patch +++ /dev/null @@ -1,398 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Thu, 8 Aug 2019 07:52:27 -0700 -Subject: ANDROID: staging: ion: refactor ion's heap manipulators into a - separate file. - -This patch is preparatory work for making ion heaps modular. The patch -itself doesn't make any significant changes except for re-organizing the -heap manipulator functions in a single file. This will be helpful -later when we specifically export some of these functions to be used by -a heap module. - -Bug: 133508579 -Test: ion-unit-tests - -Change-Id: I19205b4874a3bf52408f1fa14c3e145de1293fb4 -Co-developed-by: Isaac J. Manjarres -Signed-off-by: Sandeep Patil ---- - drivers/staging/android/ion/ion.h | 11 +- - drivers/staging/android/ion/ion_buffer.c | 17 ++ - drivers/staging/android/ion/ion_heap.c | 245 +++++++++--------- - drivers/staging/android/ion/ion_private.h | 1 - - drivers/staging/android/ion/ion_system_heap.c | 2 +- - 5 files changed, 144 insertions(+), 132 deletions(-) - -diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h -index d2d18f03ac77..b5b5412507fd 100644 ---- a/drivers/staging/android/ion/ion.h -+++ b/drivers/staging/android/ion/ion.h -@@ -153,6 +153,14 @@ struct ion_heap { - */ - void ion_device_add_heap(struct ion_heap *heap); - -+/* ion_buffer_zero - zeroes out an ion buffer respecting the ION_FLAGs. -+ * -+ * @buffer: ion_buffer to zero -+ * -+ * Returns 0 on success, negative error otherwise. -+ */ -+int ion_buffer_zero(struct ion_buffer *buffer); -+ - /** - * some helpers for common operations on buffers using the sg_table - * and vaddr fields -@@ -161,8 +169,9 @@ void *ion_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer); - void ion_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer); - int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, - struct vm_area_struct *vma); --int ion_heap_buffer_zero(struct ion_buffer *buffer); - int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot); -+int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, -+ pgprot_t pgprot); - - /** - * ion_heap_init_shrinker -diff --git a/drivers/staging/android/ion/ion_buffer.c b/drivers/staging/android/ion/ion_buffer.c -index c10ea6672f1a..50c2dbc3ebec 100644 ---- a/drivers/staging/android/ion/ion_buffer.c -+++ b/drivers/staging/android/ion/ion_buffer.c -@@ -133,6 +133,23 @@ struct ion_buffer *ion_buffer_alloc(struct ion_device *dev, size_t len, - return buffer; - } - -+int ion_buffer_zero(struct ion_buffer *buffer) -+{ -+ struct sg_table *table; -+ pgprot_t pgprot; -+ -+ if (!buffer) -+ return -EINVAL; -+ -+ table = buffer->sg_table; -+ if (buffer->flags & ION_FLAG_CACHED) -+ pgprot = PAGE_KERNEL; -+ else -+ pgprot = pgprot_writecombine(PAGE_KERNEL); -+ -+ return ion_heap_sglist_zero(table->sgl, table->nents, pgprot); -+} -+ - void ion_buffer_release(struct ion_buffer *buffer) - { - if (buffer->kmap_cnt > 0) { -diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c -index 3b4f32b9cd2d..39eb60e4842e 100644 ---- a/drivers/staging/android/ion/ion_heap.c -+++ b/drivers/staging/android/ion/ion_heap.c -@@ -17,6 +17,120 @@ - - #include "ion_private.h" - -+static unsigned long ion_heap_shrink_count(struct shrinker *shrinker, -+ struct shrink_control *sc) -+{ -+ struct ion_heap *heap = container_of(shrinker, struct ion_heap, -+ shrinker); -+ int total = 0; -+ -+ total = ion_heap_freelist_size(heap) / PAGE_SIZE; -+ -+ if (heap->ops->shrink) -+ total += heap->ops->shrink(heap, sc->gfp_mask, 0); -+ -+ return total; -+} -+ -+static unsigned long ion_heap_shrink_scan(struct shrinker *shrinker, -+ struct shrink_control *sc) -+{ -+ struct ion_heap *heap = container_of(shrinker, struct ion_heap, -+ shrinker); -+ int freed = 0; -+ int to_scan = sc->nr_to_scan; -+ -+ if (to_scan == 0) -+ return 0; -+ -+ /* -+ * shrink the free list first, no point in zeroing the memory if we're -+ * just going to reclaim it. Also, skip any possible page pooling. -+ */ -+ if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) -+ freed = ion_heap_freelist_shrink(heap, to_scan * PAGE_SIZE) / -+ PAGE_SIZE; -+ -+ to_scan -= freed; -+ if (to_scan <= 0) -+ return freed; -+ -+ if (heap->ops->shrink) -+ freed += heap->ops->shrink(heap, sc->gfp_mask, to_scan); -+ -+ return freed; -+} -+ -+static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot) -+{ -+ void *addr = vm_map_ram(pages, num, -1, pgprot); -+ -+ if (!addr) -+ return -ENOMEM; -+ memset(addr, 0, PAGE_SIZE * num); -+ vm_unmap_ram(addr, num); -+ -+ return 0; -+} -+ -+static size_t _ion_heap_freelist_drain(struct ion_heap *heap, size_t size, -+ bool skip_pools) -+{ -+ struct ion_buffer *buffer; -+ size_t total_drained = 0; -+ -+ if (ion_heap_freelist_size(heap) == 0) -+ return 0; -+ -+ spin_lock(&heap->free_lock); -+ if (size == 0) -+ size = heap->free_list_size; -+ -+ while (!list_empty(&heap->free_list)) { -+ if (total_drained >= size) -+ break; -+ buffer = list_first_entry(&heap->free_list, struct ion_buffer, -+ list); -+ list_del(&buffer->list); -+ heap->free_list_size -= buffer->size; -+ if (skip_pools) -+ buffer->private_flags |= ION_PRIV_FLAG_SHRINKER_FREE; -+ total_drained += buffer->size; -+ spin_unlock(&heap->free_lock); -+ ion_buffer_release(buffer); -+ spin_lock(&heap->free_lock); -+ } -+ spin_unlock(&heap->free_lock); -+ -+ return total_drained; -+} -+ -+static int ion_heap_deferred_free(void *data) -+{ -+ struct ion_heap *heap = data; -+ -+ while (true) { -+ struct ion_buffer *buffer; -+ -+ wait_event_freezable(heap->waitqueue, -+ ion_heap_freelist_size(heap) > 0); -+ -+ spin_lock(&heap->free_lock); -+ if (list_empty(&heap->free_list)) { -+ spin_unlock(&heap->free_lock); -+ continue; -+ } -+ buffer = list_first_entry(&heap->free_list, struct ion_buffer, -+ list); -+ list_del(&buffer->list); -+ heap->free_list_size -= buffer->size; -+ spin_unlock(&heap->free_lock); -+ ion_buffer_release(buffer); -+ } -+ -+ return 0; -+} -+ - void *ion_heap_map_kernel(struct ion_heap *heap, - struct ion_buffer *buffer) - { -@@ -97,20 +211,8 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, - return 0; - } - --static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot) --{ -- void *addr = vm_map_ram(pages, num, -1, pgprot); -- -- if (!addr) -- return -ENOMEM; -- memset(addr, 0, PAGE_SIZE * num); -- vm_unmap_ram(addr, num); -- -- return 0; --} -- --static int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, -- pgprot_t pgprot) -+int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, -+ pgprot_t pgprot) - { - int p = 0; - int ret = 0; -@@ -132,19 +234,6 @@ static int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, - return ret; - } - --int ion_heap_buffer_zero(struct ion_buffer *buffer) --{ -- struct sg_table *table = buffer->sg_table; -- pgprot_t pgprot; -- -- if (buffer->flags & ION_FLAG_CACHED) -- pgprot = PAGE_KERNEL; -- else -- pgprot = pgprot_writecombine(PAGE_KERNEL); -- -- return ion_heap_sglist_zero(table->sgl, table->nents, pgprot); --} -- - int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot) - { - struct scatterlist sg; -@@ -174,38 +263,6 @@ size_t ion_heap_freelist_size(struct ion_heap *heap) - return size; - } - --static size_t _ion_heap_freelist_drain(struct ion_heap *heap, size_t size, -- bool skip_pools) --{ -- struct ion_buffer *buffer; -- size_t total_drained = 0; -- -- if (ion_heap_freelist_size(heap) == 0) -- return 0; -- -- spin_lock(&heap->free_lock); -- if (size == 0) -- size = heap->free_list_size; -- -- while (!list_empty(&heap->free_list)) { -- if (total_drained >= size) -- break; -- buffer = list_first_entry(&heap->free_list, struct ion_buffer, -- list); -- list_del(&buffer->list); -- heap->free_list_size -= buffer->size; -- if (skip_pools) -- buffer->private_flags |= ION_PRIV_FLAG_SHRINKER_FREE; -- total_drained += buffer->size; -- spin_unlock(&heap->free_lock); -- ion_buffer_release(buffer); -- spin_lock(&heap->free_lock); -- } -- spin_unlock(&heap->free_lock); -- -- return total_drained; --} -- - size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size) - { - return _ion_heap_freelist_drain(heap, size, false); -@@ -216,32 +273,6 @@ size_t ion_heap_freelist_shrink(struct ion_heap *heap, size_t size) - return _ion_heap_freelist_drain(heap, size, true); - } - --static int ion_heap_deferred_free(void *data) --{ -- struct ion_heap *heap = data; -- -- while (true) { -- struct ion_buffer *buffer; -- -- wait_event_freezable(heap->waitqueue, -- ion_heap_freelist_size(heap) > 0); -- -- spin_lock(&heap->free_lock); -- if (list_empty(&heap->free_list)) { -- spin_unlock(&heap->free_lock); -- continue; -- } -- buffer = list_first_entry(&heap->free_list, struct ion_buffer, -- list); -- list_del(&buffer->list); -- heap->free_list_size -= buffer->size; -- spin_unlock(&heap->free_lock); -- ion_buffer_release(buffer); -- } -- -- return 0; --} -- - int ion_heap_init_deferred_free(struct ion_heap *heap) - { - struct sched_param param = { .sched_priority = 0 }; -@@ -260,50 +291,6 @@ int ion_heap_init_deferred_free(struct ion_heap *heap) - return 0; - } - --static unsigned long ion_heap_shrink_count(struct shrinker *shrinker, -- struct shrink_control *sc) --{ -- struct ion_heap *heap = container_of(shrinker, struct ion_heap, -- shrinker); -- int total = 0; -- -- total = ion_heap_freelist_size(heap) / PAGE_SIZE; -- -- if (heap->ops->shrink) -- total += heap->ops->shrink(heap, sc->gfp_mask, 0); -- -- return total; --} -- --static unsigned long ion_heap_shrink_scan(struct shrinker *shrinker, -- struct shrink_control *sc) --{ -- struct ion_heap *heap = container_of(shrinker, struct ion_heap, -- shrinker); -- int freed = 0; -- int to_scan = sc->nr_to_scan; -- -- if (to_scan == 0) -- return 0; -- -- /* -- * shrink the free list first, no point in zeroing the memory if we're -- * just going to reclaim it. Also, skip any possible page pooling. -- */ -- if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) -- freed = ion_heap_freelist_shrink(heap, to_scan * PAGE_SIZE) / -- PAGE_SIZE; -- -- to_scan -= freed; -- if (to_scan <= 0) -- return freed; -- -- if (heap->ops->shrink) -- freed += heap->ops->shrink(heap, sc->gfp_mask, to_scan); -- -- return freed; --} -- - int ion_heap_init_shrinker(struct ion_heap *heap) - { - heap->shrinker.count_objects = ion_heap_shrink_count; -diff --git a/drivers/staging/android/ion/ion_private.h b/drivers/staging/android/ion/ion_private.h -index b3c8b55788db..9c8f482cd9d2 100644 ---- a/drivers/staging/android/ion/ion_private.h -+++ b/drivers/staging/android/ion/ion_private.h -@@ -52,5 +52,4 @@ extern struct dma_buf *ion_dmabuf_alloc(struct ion_device *dev, size_t len, - unsigned int flags); - extern int ion_free(struct ion_buffer *buffer); - -- - #endif /* _ION_PRIVATE_H */ -diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c -index ee301df7b7b7..d1cb9e69399e 100644 ---- a/drivers/staging/android/ion/ion_system_heap.c -+++ b/drivers/staging/android/ion/ion_system_heap.c -@@ -161,7 +161,7 @@ static void ion_system_heap_free(struct ion_buffer *buffer) - - /* zero the buffer before goto page pool */ - if (!(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE)) -- ion_heap_buffer_zero(buffer); -+ ion_buffer_zero(buffer); - - for_each_sg(table->sgl, sg, table->nents, i) - free_buffer_page(sys_heap, buffer, sg_page(sg)); diff --git a/patches/ANDROID-staging-ion-reserve-specific-heap-ids-for-known-heap-types.patch b/patches/ANDROID-staging-ion-reserve-specific-heap-ids-for-known-heap-types.patch deleted file mode 100644 index e78cb8417250..000000000000 --- a/patches/ANDROID-staging-ion-reserve-specific-heap-ids-for-known-heap-types.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Mon, 26 Aug 2019 13:14:43 -0700 -Subject: ANDROID: staging: ion: reserve specific heap ids for known heap - types. - -Since its inception, ion used heap types and heap ids interchangeably. -The 'heap type' is not part of the UAPI but 'heap ids' are. The sad part -is that heap ids are dynamically generated and heap types aren't. This -causes all sorts of problems trying to support following things - 1. No UAPI breakage for ION in GKI - 2. Support multiple CMA heaps (i.e. heap with same type but - different ids) - 3. Allow Android system code to reliably talk to any ION - driver using the standard / reserved heap types. etc. - 4. Allow someone to override standard heap implementation. - 5. Allow for new heap types to register to ion core. - -With this change, we start the process of reserving heap ids for -long known heap types like system, carveout etc. In order to not -break ABI and UAPI, we continue to use 32-bits with following caveats - - 1. BIT(0)-BIT(15) are reserved for standard / GKI heap ids - that Android platform can use from now on reliably. - 2. BIT(16)-BIT(31) are reserved for custom heap types that - only vendor specific processes can rely upon. - 3. BIT(3)-BIT(7) are reserved for CARVEOUT heaps. - 4. BIT(8)-BIT(15) are reserved for CMA / DMA heaps that manage - different CMA regions. The heap ids will be allocated in ascending - order and are first come first served. - -Bug: 133508579 -Test:ion-unit-tests - -Change-Id: I53af694113b62d29e0d2933fbcf7079d845099e9 -Signed-off-by: Sandeep Patil ---- - include/uapi/linux/ion.h | 74 +++++++++++++++++++++++++++++----------- - 1 file changed, 55 insertions(+), 19 deletions(-) - -diff --git a/include/uapi/linux/ion.h b/include/uapi/linux/ion.h -index bfcbc0e70921..09dbbfaf3718 100644 ---- a/include/uapi/linux/ion.h -+++ b/include/uapi/linux/ion.h -@@ -12,29 +12,65 @@ - #include - - /** -- * enum ion_heap_types - list of all possible types of heaps -- * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc -- * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc -- * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved -- * carveout heap, allocations are physically -- * contiguous -- * @ION_HEAP_TYPE_DMA: memory allocated via DMA API -- * @ION_HEAP_TYPE_MAX: helper for iterating over standard -- * (not device specific) heaps -- * @ION_NUM_HEAPS_IDS: helper for iterating over heaps, a bit mask -- * is used to identify the heaps, so only 32 -- * total heap types are supported -+ * ion_heap_types - list of all possible types of heaps that Android can use -+ * -+ * @ION_HEAP_TYPE_SYSTEM: Reserved heap id for ion heap that allocates -+ * memory using alloc_page(). Also, supports -+ * deferred free and allocation pools. -+ * @ION_HEAP_TYPE_SYSTEM_CONTIG: Reserved heap id for ion heap that is the same -+ * as SYSTEM_HEAP, except doesn't support -+ * allocation pools. -+ * @ION_HEAP_TYPE_CARVEOUT: Reserved heap id for ion heap that allocates -+ * memory from a pre-reserved memory region -+ * aka 'carveout'. -+ * @ION_HEAP_TYPE_DMA: Reserved heap id for ion heap that manages -+ * single CMA (contiguous memory allocator) -+ * region. Uses standard DMA APIs for -+ * managing memory within the CMA region. - */ - enum ion_heap_type { -- ION_HEAP_TYPE_SYSTEM = (1 << 0), -- ION_HEAP_TYPE_SYSTEM_CONTIG = (1 << 1), -- ION_HEAP_TYPE_CARVEOUT = (1 << 2), -- ION_HEAP_TYPE_CHUNK = (1 << 3), -- ION_HEAP_TYPE_DMA = (1 << 4), -- ION_HEAP_TYPE_MAX = (1 << 15), -+ ION_HEAP_TYPE_SYSTEM = 0, -+ ION_HEAP_TYPE_SYSTEM_CONTIG = 1, -+ ION_HEAP_TYPE_CHUNK = 2, -+ ION_HEAP_TYPE_CARVEOUT = 3, -+ ION_HEAP_TYPE_DMA = 4, -+ /* reserved range for future standard heap types */ -+ ION_HEAP_TYPE_CUSTOM = 16, -+ ION_HEAP_TYPE_MAX = 31, -+}; -+ -+/** -+ * ion_heap_id - list of standard heap ids that Android can use -+ * -+ * @ION_HEAP_SYSTEM Id for the ION_HEAP_TYPE_SYSTEM -+ * @ION_HEAP_SYSTEM_CONTIG Id for the ION_HEAP_TYPE_SYSTEM_CONTIG -+ * @ION_HEAP_CHUNK Id for the ION_HEAP_TYPE_CHUNK -+ * @ION_HEAP_CARVEOUT_START Start of reserved id range for heaps of type -+ * ION_HEAP_TYPE_CARVEOUT -+ * @ION_HEAP_CARVEOUT_END End of reserved id range for heaps of type -+ * ION_HEAP_TYPE_CARVEOUT -+ * @ION_HEAP_DMA_START Start of reserved id range for heaps of type -+ * ION_HEAP_TYPE_DMA -+ * @ION_HEAP_DMA_END End of reserved id range for heaps of type -+ * ION_HEAP_TYPE_DMA -+ * @ION_HEAP_CUSTOM_START Start of reserved id range for heaps of custom -+ * type -+ * @ION_HEAP_CUSTOM_END End of reserved id range for heaps of custom -+ * type -+ */ -+enum ion_heap_id { -+ ION_HEAP_SYSTEM = (1 << ION_HEAP_TYPE_SYSTEM), -+ ION_HEAP_SYSTEM_CONTIG = (ION_HEAP_SYSTEM << 1), -+ ION_HEAP_CHUNK = (ION_HEAP_SYSTEM_CONTIG << 1), -+ ION_HEAP_CARVEOUT_START = (ION_HEAP_CHUNK << 1), -+ ION_HEAP_CARVEOUT_END = (ION_HEAP_CARVEOUT_START << 4), -+ ION_HEAP_DMA_START = (ION_HEAP_CARVEOUT_END << 1), -+ ION_HEAP_DMA_END = (ION_HEAP_DMA_START << 7), -+ ION_HEAP_CUSTOM_START = (ION_HEAP_DMA_END << 1), -+ ION_HEAP_CUSTOM_END = (ION_HEAP_CUSTOM_START << 15), - }; - --#define ION_NUM_HEAP_IDS (sizeof(unsigned int) * 8) -+#define ION_NUM_MAX_HEAPS (32) - - /** - * allocation flags - the lower 16 bits are used by core ion, the upper 16 diff --git a/patches/ANDROID-staging-ion-split-system-and-system-contig-heaps.patch b/patches/ANDROID-staging-ion-split-system-and-system-contig-heaps.patch deleted file mode 100644 index cc52e3510e35..000000000000 --- a/patches/ANDROID-staging-ion-split-system-and-system-contig-heaps.patch +++ /dev/null @@ -1,297 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Thu, 8 Aug 2019 08:50:56 -0700 -Subject: ANDROID: staging: ion: split system and system-contig heaps - -This will allows us to build and load them both as individual -kernel modules. - -Bug: 133508579 -Test: ion-unit-tests - -Change-Id: I8bdada5531fbf148e4d097e94e406a232874913a -Signed-off-by: Sandeep Patil ---- - arch/arm64/configs/gki_defconfig | 2 + - arch/x86/configs/gki_defconfig | 2 + - drivers/staging/android/ion/heaps/Kconfig | 8 ++ - drivers/staging/android/ion/heaps/Makefile | 1 + - .../ion/heaps/ion_system_contig_heap.c | 111 ++++++++++++++++++ - .../android/ion/heaps/ion_system_heap.c | 95 --------------- - 6 files changed, 124 insertions(+), 95 deletions(-) - create mode 100644 drivers/staging/android/ion/heaps/ion_system_contig_heap.c - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 539f42574383..73acbe383203 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -349,6 +349,8 @@ CONFIG_STAGING=y - CONFIG_ASHMEM=y - CONFIG_ANDROID_VSOC=y - CONFIG_ION=y -+CONFIG_ION_SYSTEM_HEAP=y -+CONFIG_ION_SYSTEM_CONTIG_HEAP=y - CONFIG_COMMON_CLK_SCPI=y - CONFIG_HWSPINLOCK=y - CONFIG_MAILBOX=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 2d5f55d7b966..ae3d165a79c3 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -289,6 +289,8 @@ CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y - CONFIG_STAGING=y - CONFIG_ASHMEM=y - CONFIG_ION=y -+CONFIG_ION_SYSTEM_HEAP=y -+CONFIG_ION_SYSTEM_CONTIG_HEAP=y - CONFIG_PM_DEVFREQ=y - CONFIG_ANDROID=y - CONFIG_ANDROID_BINDER_IPC=y -diff --git a/drivers/staging/android/ion/heaps/Kconfig b/drivers/staging/android/ion/heaps/Kconfig -index 7affa91ecabb..f1c7a6b79c01 100644 ---- a/drivers/staging/android/ion/heaps/Kconfig -+++ b/drivers/staging/android/ion/heaps/Kconfig -@@ -6,6 +6,14 @@ config ION_SYSTEM_HEAP - Choose this option to enable the Ion system heap. The system heap - is backed by pages from the buddy allocator. If in doubt, say Y. - -+config ION_SYSTEM_CONTIG_HEAP -+ bool "Ion system contig heap" -+ depends on ION -+ help -+ Choose this option to enable Ion system contig heap. The system contig heap -+ is backed by the pages from buddy allocator that are guaranteed to be physically -+ contiguous. If in doubt, say Y. -+ - config ION_CMA_HEAP - bool "Ion CMA heap support" - depends on ION && DMA_CMA -diff --git a/drivers/staging/android/ion/heaps/Makefile b/drivers/staging/android/ion/heaps/Makefile -index 127912629f0b..e2ee931100d0 100644 ---- a/drivers/staging/android/ion/heaps/Makefile -+++ b/drivers/staging/android/ion/heaps/Makefile -@@ -1,3 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0 - obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o -+obj-$(CONFIG_ION_SYSTEM_CONTIG_HEAP) += ion_system_contig_heap.o - obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o -diff --git a/drivers/staging/android/ion/heaps/ion_system_contig_heap.c b/drivers/staging/android/ion/heaps/ion_system_contig_heap.c -new file mode 100644 -index 000000000000..3a07ef931c2e ---- /dev/null -+++ b/drivers/staging/android/ion/heaps/ion_system_contig_heap.c -@@ -0,0 +1,111 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * ION Memory Allocator system contig heap exporter -+ * -+ * Copyright (C) 2019 Google, Inc. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static int ion_system_contig_heap_allocate(struct ion_heap *heap, -+ struct ion_buffer *buffer, -+ unsigned long len, -+ unsigned long flags) -+{ -+ int order = get_order(len); -+ struct page *page; -+ struct sg_table *table; -+ unsigned long i; -+ int ret; -+ -+ page = alloc_pages(GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN, order); -+ if (!page) -+ return -ENOMEM; -+ -+ split_page(page, order); -+ -+ len = PAGE_ALIGN(len); -+ for (i = len >> PAGE_SHIFT; i < (1 << order); i++) -+ __free_page(page + i); -+ -+ table = kmalloc(sizeof(*table), GFP_KERNEL); -+ if (!table) { -+ ret = -ENOMEM; -+ goto free_pages; -+ } -+ -+ ret = sg_alloc_table(table, 1, GFP_KERNEL); -+ if (ret) -+ goto free_table; -+ -+ sg_set_page(table->sgl, page, len, 0); -+ -+ buffer->sg_table = table; -+ -+ return 0; -+ -+free_table: -+ kfree(table); -+free_pages: -+ for (i = 0; i < len >> PAGE_SHIFT; i++) -+ __free_page(page + i); -+ -+ return ret; -+} -+ -+static void ion_system_contig_heap_free(struct ion_buffer *buffer) -+{ -+ struct sg_table *table = buffer->sg_table; -+ struct page *page = sg_page(table->sgl); -+ unsigned long pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT; -+ unsigned long i; -+ -+ for (i = 0; i < pages; i++) -+ __free_page(page + i); -+ sg_free_table(table); -+ kfree(table); -+} -+ -+static struct ion_heap_ops kmalloc_ops = { -+ .allocate = ion_system_contig_heap_allocate, -+ .free = ion_system_contig_heap_free, -+ .map_kernel = ion_heap_map_kernel, -+ .unmap_kernel = ion_heap_unmap_kernel, -+ .map_user = ion_heap_map_user, -+}; -+ -+static struct ion_heap *__ion_system_contig_heap_create(void) -+{ -+ struct ion_heap *heap; -+ -+ heap = kzalloc(sizeof(*heap), GFP_KERNEL); -+ if (!heap) -+ return ERR_PTR(-ENOMEM); -+ heap->ops = &kmalloc_ops; -+ heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; -+ heap->name = "ion_system_contig_heap"; -+ -+ return heap; -+} -+ -+static int ion_system_contig_heap_create(void) -+{ -+ struct ion_heap *heap; -+ -+ heap = __ion_system_contig_heap_create(); -+ if (IS_ERR(heap)) -+ return PTR_ERR(heap); -+ -+ ion_device_add_heap(heap); -+ -+ return 0; -+} -+device_initcall(ion_system_contig_heap_create); -+ -diff --git a/drivers/staging/android/ion/heaps/ion_system_heap.c b/drivers/staging/android/ion/heaps/ion_system_heap.c -index afb2a6385705..25ea31757578 100644 ---- a/drivers/staging/android/ion/heaps/ion_system_heap.c -+++ b/drivers/staging/android/ion/heaps/ion_system_heap.c -@@ -281,98 +281,3 @@ static int ion_system_heap_create(void) - return 0; - } - device_initcall(ion_system_heap_create); -- --static int ion_system_contig_heap_allocate(struct ion_heap *heap, -- struct ion_buffer *buffer, -- unsigned long len, -- unsigned long flags) --{ -- int order = get_order(len); -- struct page *page; -- struct sg_table *table; -- unsigned long i; -- int ret; -- -- page = alloc_pages(low_order_gfp_flags | __GFP_NOWARN, order); -- if (!page) -- return -ENOMEM; -- -- split_page(page, order); -- -- len = PAGE_ALIGN(len); -- for (i = len >> PAGE_SHIFT; i < (1 << order); i++) -- __free_page(page + i); -- -- table = kmalloc(sizeof(*table), GFP_KERNEL); -- if (!table) { -- ret = -ENOMEM; -- goto free_pages; -- } -- -- ret = sg_alloc_table(table, 1, GFP_KERNEL); -- if (ret) -- goto free_table; -- -- sg_set_page(table->sgl, page, len, 0); -- -- buffer->sg_table = table; -- -- return 0; -- --free_table: -- kfree(table); --free_pages: -- for (i = 0; i < len >> PAGE_SHIFT; i++) -- __free_page(page + i); -- -- return ret; --} -- --static void ion_system_contig_heap_free(struct ion_buffer *buffer) --{ -- struct sg_table *table = buffer->sg_table; -- struct page *page = sg_page(table->sgl); -- unsigned long pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT; -- unsigned long i; -- -- for (i = 0; i < pages; i++) -- __free_page(page + i); -- sg_free_table(table); -- kfree(table); --} -- --static struct ion_heap_ops kmalloc_ops = { -- .allocate = ion_system_contig_heap_allocate, -- .free = ion_system_contig_heap_free, -- .map_kernel = ion_heap_map_kernel, -- .unmap_kernel = ion_heap_unmap_kernel, -- .map_user = ion_heap_map_user, --}; -- --static struct ion_heap *__ion_system_contig_heap_create(void) --{ -- struct ion_heap *heap; -- -- heap = kzalloc(sizeof(*heap), GFP_KERNEL); -- if (!heap) -- return ERR_PTR(-ENOMEM); -- heap->ops = &kmalloc_ops; -- heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; -- heap->name = "ion_system_contig_heap"; -- -- return heap; --} -- --static int ion_system_contig_heap_create(void) --{ -- struct ion_heap *heap; -- -- heap = __ion_system_contig_heap_create(); -- if (IS_ERR(heap)) -- return PTR_ERR(heap); -- -- ion_device_add_heap(heap); -- -- return 0; --} --device_initcall(ion_system_contig_heap_create); diff --git a/patches/ANDROID-staging-ion-uapi-match-the-existing-heap-type-enums.patch b/patches/ANDROID-staging-ion-uapi-match-the-existing-heap-type-enums.patch deleted file mode 100644 index 20602bd7e258..000000000000 --- a/patches/ANDROID-staging-ion-uapi-match-the-existing-heap-type-enums.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sandeep Patil -Date: Mon, 9 Sep 2019 08:34:43 -0700 -Subject: ANDROID: staging: ion: uapi: match the existing heap type enums - -Change the enup order for ion heap types to match how it was before so -as to not break any userspace code that depends on them. - -Bug: 140507100 -Test: ion-unit-tests - -Change-Id: Id68c50a9bd3eda2ce46bc88a326a120c52d1110f -Signed-off-by: Sandeep Patil ---- - include/uapi/linux/ion.h | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/include/uapi/linux/ion.h b/include/uapi/linux/ion.h -index 09dbbfaf3718..ad773e5fa4d2 100644 ---- a/include/uapi/linux/ion.h -+++ b/include/uapi/linux/ion.h -@@ -31,8 +31,8 @@ - enum ion_heap_type { - ION_HEAP_TYPE_SYSTEM = 0, - ION_HEAP_TYPE_SYSTEM_CONTIG = 1, -- ION_HEAP_TYPE_CHUNK = 2, -- ION_HEAP_TYPE_CARVEOUT = 3, -+ ION_HEAP_TYPE_CARVEOUT = 2, -+ ION_HEAP_TYPE_CHUNK = 3, - ION_HEAP_TYPE_DMA = 4, - /* reserved range for future standard heap types */ - ION_HEAP_TYPE_CUSTOM = 16, -@@ -61,10 +61,10 @@ enum ion_heap_type { - enum ion_heap_id { - ION_HEAP_SYSTEM = (1 << ION_HEAP_TYPE_SYSTEM), - ION_HEAP_SYSTEM_CONTIG = (ION_HEAP_SYSTEM << 1), -- ION_HEAP_CHUNK = (ION_HEAP_SYSTEM_CONTIG << 1), -- ION_HEAP_CARVEOUT_START = (ION_HEAP_CHUNK << 1), -+ ION_HEAP_CARVEOUT_START = (ION_HEAP_SYSTEM_CONTIG << 1), - ION_HEAP_CARVEOUT_END = (ION_HEAP_CARVEOUT_START << 4), -- ION_HEAP_DMA_START = (ION_HEAP_CARVEOUT_END << 1), -+ ION_HEAP_CHUNK = (ION_HEAP_CARVEOUT_END << 1), -+ ION_HEAP_DMA_START = (ION_HEAP_CHUNK << 1), - ION_HEAP_DMA_END = (ION_HEAP_DMA_START << 7), - ION_HEAP_CUSTOM_START = (ION_HEAP_DMA_END << 1), - ION_HEAP_CUSTOM_END = (ION_HEAP_CUSTOM_START << 15), diff --git a/patches/ANDROID-sync-defconfigs-with-savedefconfig.patch b/patches/ANDROID-sync-defconfigs-with-savedefconfig.patch deleted file mode 100644 index f0f92c8ab6a3..000000000000 --- a/patches/ANDROID-sync-defconfigs-with-savedefconfig.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Mon, 20 May 2019 11:54:22 -0700 -Subject: ANDROID: sync defconfigs with savedefconfig - -Test: boot gki_defconfig and cuttlefish_defconfig on arm64 cuttlefish -Signed-off-by: Tri Vo -Change-Id: Ie0b518c0fd5100a39312069fe3b193684feb634d ---- - arch/arm64/configs/gki_defconfig | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 04f531ef2511..c9720858fd9a 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -35,13 +35,13 @@ CONFIG_PROFILING=y - CONFIG_SCHED_MC=y - CONFIG_SECCOMP=y - CONFIG_PARAVIRT=y -+CONFIG_COMPAT=y - CONFIG_ARMV8_DEPRECATED=y - CONFIG_SWP_EMULATION=y - CONFIG_CP15_BARRIER_EMULATION=y - CONFIG_SETEND_EMULATION=y - CONFIG_RANDOMIZE_BASE=y - # CONFIG_EFI is not set --CONFIG_COMPAT=y - CONFIG_PM_WAKELOCKS=y - CONFIG_PM_WAKELOCKS_LIMIT=0 - # CONFIG_PM_WAKELOCKS_GC is not set -@@ -81,7 +81,6 @@ CONFIG_IP_MULTIPLE_TABLES=y - CONFIG_NET_IPGRE_DEMUX=y - CONFIG_NET_IPVTI=y - CONFIG_INET_ESP=y --# CONFIG_INET_XFRM_MODE_BEET is not set - CONFIG_INET_UDP_DIAG=y - CONFIG_INET_DIAG_DESTROY=y - CONFIG_IPV6_ROUTER_PREF=y -@@ -180,7 +179,6 @@ CONFIG_MAC80211=y - CONFIG_RFKILL=y - CONFIG_PCI=y - CONFIG_PCI_HOST_GENERIC=y --# CONFIG_UEVENT_HELPER is not set - # CONFIG_ALLOW_DEV_COREDUMP is not set - CONFIG_DEBUG_DEVRES=y - CONFIG_ZRAM=y -@@ -282,7 +280,6 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y - CONFIG_DRM=y - # CONFIG_DRM_FBDEV_EMULATION is not set - CONFIG_DRM_VIRTIO_GPU=y --CONFIG_BACKLIGHT_LCD_SUPPORT=y - # CONFIG_LCD_CLASS_DEVICE is not set - CONFIG_BACKLIGHT_CLASS_DEVICE=y - CONFIG_SOUND=y diff --git a/patches/ANDROID-taskstats-track-fsync-syscalls.patch b/patches/ANDROID-taskstats-track-fsync-syscalls.patch deleted file mode 100644 index a3d423616b0a..000000000000 --- a/patches/ANDROID-taskstats-track-fsync-syscalls.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jin Qian -Date: Thu, 2 Mar 2017 13:32:59 -0800 -Subject: ANDROID: taskstats: track fsync syscalls - -This adds a counter to the taskstats extended accounting fields, which -tracks the number of times fsync is called, and then plumbs it through -to the uid_sys_stats driver. - -Bug: 120442023 -Change-Id: I6c138de5b2332eea70f57e098134d1d141247b3f -Signed-off-by: Jin Qian -[AmitP: Refactored changes to align with changes from upstream commit - 9a07000400c8 ("sched/headers: Move CONFIG_TASK_XACCT bits from to ")] -Signed-off-by: Amit Pundir -[tkjos: Needed for storaged fsync accounting ("storaged --uid" and - "storaged --task").] -[astrachan: This is modifying a userspace interface and should probably - be reworked] -Signed-off-by: Alistair Strachan ---- - drivers/misc/Kconfig | 2 +- - drivers/misc/uid_sys_stats.c | 2 ++ - fs/sync.c | 3 ++- - include/linux/sched/xacct.h | 9 +++++++++ - include/linux/task_io_accounting.h | 2 ++ - include/linux/task_io_accounting_ops.h | 1 + - 6 files changed, 17 insertions(+), 2 deletions(-) - -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index a067f988d0f4..ca90dacfb016 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -460,7 +460,7 @@ config MISC_RTSX - - config UID_SYS_STATS - bool "Per-UID statistics" -- depends on PROFILING && TASK_IO_ACCOUNTING -+ depends on PROFILING && TASK_XACCT && TASK_IO_ACCOUNTING - help - Per UID based cpu time statistics exported to /proc/uid_cputime - Per UID based io statistics exported to /proc/uid_io -diff --git a/drivers/misc/uid_sys_stats.c b/drivers/misc/uid_sys_stats.c -index ea23f5d0af43..36b5f37fca2f 100644 ---- a/drivers/misc/uid_sys_stats.c -+++ b/drivers/misc/uid_sys_stats.c -@@ -249,6 +249,7 @@ static void add_uid_tasks_io_stats(struct uid_entry *uid_entry, - task_io_slot->write_bytes += compute_write_bytes(task); - task_io_slot->rchar += task->ioac.rchar; - task_io_slot->wchar += task->ioac.wchar; -+ task_io_slot->fsync += task->ioac.syscfs; - } - - static void compute_io_uid_tasks(struct uid_entry *uid_entry) -@@ -452,6 +453,7 @@ static void add_uid_io_stats(struct uid_entry *uid_entry, - io_slot->write_bytes += compute_write_bytes(task); - io_slot->rchar += task->ioac.rchar; - io_slot->wchar += task->ioac.wchar; -+ io_slot->fsync += task->ioac.syscfs; - - add_uid_tasks_io_stats(uid_entry, task, slot); - } -diff --git a/fs/sync.c b/fs/sync.c -index 4d1ff010bc5a..cc475d8be0c1 100644 ---- a/fs/sync.c -+++ b/fs/sync.c -@@ -9,7 +9,7 @@ - #include - #include - #include --#include -+#include - #include - #include - #include -@@ -220,6 +220,7 @@ static int do_fsync(unsigned int fd, int datasync) - if (f.file) { - ret = vfs_fsync(f.file, datasync); - fdput(f); -+ inc_syscfs(current); - } - return ret; - } -diff --git a/include/linux/sched/xacct.h b/include/linux/sched/xacct.h -index c078f0a94cec..9544c9d9d534 100644 ---- a/include/linux/sched/xacct.h -+++ b/include/linux/sched/xacct.h -@@ -28,6 +28,11 @@ static inline void inc_syscw(struct task_struct *tsk) - { - tsk->ioac.syscw++; - } -+ -+static inline void inc_syscfs(struct task_struct *tsk) -+{ -+ tsk->ioac.syscfs++; -+} - #else - static inline void add_rchar(struct task_struct *tsk, ssize_t amt) - { -@@ -44,6 +49,10 @@ static inline void inc_syscr(struct task_struct *tsk) - static inline void inc_syscw(struct task_struct *tsk) - { - } -+ -+static inline void inc_syscfs(struct task_struct *tsk) -+{ -+} - #endif - - #endif /* _LINUX_SCHED_XACCT_H */ -diff --git a/include/linux/task_io_accounting.h b/include/linux/task_io_accounting.h -index 6f6acce064de..bb26108ca23c 100644 ---- a/include/linux/task_io_accounting.h -+++ b/include/linux/task_io_accounting.h -@@ -19,6 +19,8 @@ struct task_io_accounting { - u64 syscr; - /* # of write syscalls */ - u64 syscw; -+ /* # of fsync syscalls */ -+ u64 syscfs; - #endif /* CONFIG_TASK_XACCT */ - - #ifdef CONFIG_TASK_IO_ACCOUNTING -diff --git a/include/linux/task_io_accounting_ops.h b/include/linux/task_io_accounting_ops.h -index bb5498bcdd96..733ab62ae141 100644 ---- a/include/linux/task_io_accounting_ops.h -+++ b/include/linux/task_io_accounting_ops.h -@@ -97,6 +97,7 @@ static inline void task_chr_io_accounting_add(struct task_io_accounting *dst, - dst->wchar += src->wchar; - dst->syscr += src->syscr; - dst->syscw += src->syscw; -+ dst->syscfs += src->syscfs; - } - #else - static inline void task_chr_io_accounting_add(struct task_io_accounting *dst, diff --git a/patches/ANDROID-uid_cputime-Adds-accounting-for-the-cputimes-per-uid.patch b/patches/ANDROID-uid_cputime-Adds-accounting-for-the-cputimes-per-uid.patch deleted file mode 100644 index a0dea29a5ecb..000000000000 --- a/patches/ANDROID-uid_cputime-Adds-accounting-for-the-cputimes-per-uid.patch +++ /dev/null @@ -1,314 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jin Qian -Date: Wed, 11 Mar 2015 10:44:50 -0700 -Subject: ANDROID: uid_cputime: Adds accounting for the cputimes per uid. - -Adds proc files /proc/uid_cputime/show_uid_stat and -/proc/uid_cputime/remove_uid_range. - -show_uid_stat lists the total utime and stime for the active as well as -terminated processes for each of the uids. - -Writing a range of uids to remove_uid_range will delete the accounting -for all the uids within that range. - -Bug: 120442023 -Change-Id: I21d9210379da730b33ddc1a0ea663c8c9d2ac15b -Signed-off-by: Jin Qian -[AmitP: Refactored the original patch because upstream commit - 605dc2b31a2a ("tsacct: Convert obsolete cputime type to nsecs") - made cputime_t type obsolete, so use u64 nanoseconds directly instead. - Also folded following android-4.9 changes into this patch - 48a9906c0fd8 ("ANDROID: proc: uid_cputime: create uids from kuids") - 453ac31cab34 ("ANDROID: proc: uid_cputime: fix show_uid_stat permission")] -Signed-off-by: Amit Pundir -[connoro: Used by batterystats.] -[astrachan: Folded in the file/kconfig rename and the following changes: - da3687fbc393 ("ANDROID: uid_cputime: fix cputime overflow") - 71e3eb512d00 ("ANDROID: uid_cputime: Iterates over all the threads instead of processes.") - c65f0080c300 ("ANDROID: uid_cputime: Check for the range while removing range of UIDs.") - c8212458e3a5 ("ANDROID: uid_sys_stats: fix access of task_uid(task)") - bb5ee21cc4dd ("ANDROID: uid_sys_stats: change to use rt_mutex") - 6dc5d8173a8c ("ANDROID: uid_sys_stats: check previous uid_entry before call find_or_register_uid") - 82b9872b3894 ("ANDROID: uid_sys_stats: Replace tasklist lock with RCU in uid_cputime_show")] -Signed-off-by: Alistair Strachan ---- - drivers/misc/Kconfig | 6 + - drivers/misc/Makefile | 1 + - drivers/misc/uid_sys_stats.c | 241 +++++++++++++++++++++++++++++++++++ - 3 files changed, 248 insertions(+) - create mode 100644 drivers/misc/uid_sys_stats.c - -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index c55b63750757..ef553e6eb1cd 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -458,6 +458,12 @@ config MISC_RTSX - tristate - default MISC_RTSX_PCI || MISC_RTSX_USB - -+config UID_SYS_STATS -+ bool "Per-UID statistics" -+ depends on PROFILING -+ help -+ Per UID based cpu time statistics exported to /proc/uid_cputime -+ - config PVPANIC - tristate "pvpanic device support" - depends on HAS_IOMEM && (ACPI || OF) -diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index c1860d35dc7e..9a3dda3a9d06 100644 ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -57,3 +57,4 @@ obj-y += cardreader/ - obj-$(CONFIG_PVPANIC) += pvpanic.o - obj-$(CONFIG_HABANA_AI) += habanalabs/ - obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o -+obj-$(CONFIG_UID_SYS_STATS) += uid_sys_stats.o -diff --git a/drivers/misc/uid_sys_stats.c b/drivers/misc/uid_sys_stats.c -new file mode 100644 -index 000000000000..e1a9ef29468f ---- /dev/null -+++ b/drivers/misc/uid_sys_stats.c -@@ -0,0 +1,241 @@ -+/* drivers/misc/uid_sys_stats.c -+ * -+ * Copyright (C) 2014 - 2015 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#define UID_HASH_BITS 10 -+DECLARE_HASHTABLE(hash_table, UID_HASH_BITS); -+ -+static DEFINE_RT_MUTEX(uid_lock); -+static struct proc_dir_entry *parent; -+ -+struct uid_entry { -+ uid_t uid; -+ u64 utime; -+ u64 stime; -+ u64 active_utime; -+ u64 active_stime; -+ struct hlist_node hash; -+}; -+ -+static struct uid_entry *find_uid_entry(uid_t uid) -+{ -+ struct uid_entry *uid_entry; -+ hash_for_each_possible(hash_table, uid_entry, hash, uid) { -+ if (uid_entry->uid == uid) -+ return uid_entry; -+ } -+ return NULL; -+} -+ -+static struct uid_entry *find_or_register_uid(uid_t uid) -+{ -+ struct uid_entry *uid_entry; -+ -+ uid_entry = find_uid_entry(uid); -+ if (uid_entry) -+ return uid_entry; -+ -+ uid_entry = kzalloc(sizeof(struct uid_entry), GFP_ATOMIC); -+ if (!uid_entry) -+ return NULL; -+ -+ uid_entry->uid = uid; -+ -+ hash_add(hash_table, &uid_entry->hash, uid); -+ -+ return uid_entry; -+} -+ -+static int uid_stat_show(struct seq_file *m, void *v) -+{ -+ struct uid_entry *uid_entry = NULL; -+ struct task_struct *task, *temp; -+ struct user_namespace *user_ns = current_user_ns(); -+ u64 utime; -+ u64 stime; -+ unsigned long bkt; -+ uid_t uid; -+ -+ rt_mutex_lock(&uid_lock); -+ -+ hash_for_each(hash_table, bkt, uid_entry, hash) { -+ uid_entry->active_stime = 0; -+ uid_entry->active_utime = 0; -+ } -+ -+ rcu_read_lock(); -+ do_each_thread(temp, task) { -+ uid = from_kuid_munged(user_ns, task_uid(task)); -+ if (!uid_entry || uid_entry->uid != uid) -+ uid_entry = find_or_register_uid(uid); -+ if (!uid_entry) { -+ rcu_read_unlock(); -+ rt_mutex_unlock(&uid_lock); -+ pr_err("%s: failed to find the uid_entry for uid %d\n", -+ __func__, uid); -+ return -ENOMEM; -+ } -+ task_cputime_adjusted(task, &utime, &stime); -+ uid_entry->active_utime += utime; -+ uid_entry->active_stime += stime; -+ } while_each_thread(temp, task); -+ rcu_read_unlock(); -+ -+ hash_for_each(hash_table, bkt, uid_entry, hash) { -+ u64 total_utime = uid_entry->utime + -+ uid_entry->active_utime; -+ u64 total_stime = uid_entry->stime + -+ uid_entry->active_stime; -+ seq_printf(m, "%d: %llu %llu\n", uid_entry->uid, -+ ktime_to_ms(total_utime), ktime_to_ms(total_stime)); -+ } -+ -+ rt_mutex_unlock(&uid_lock); -+ return 0; -+} -+ -+static int uid_stat_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, uid_stat_show, PDE_DATA(inode)); -+} -+ -+static const struct file_operations uid_stat_fops = { -+ .open = uid_stat_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static int uid_remove_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, NULL, NULL); -+} -+ -+static ssize_t uid_remove_write(struct file *file, -+ const char __user *buffer, size_t count, loff_t *ppos) -+{ -+ struct uid_entry *uid_entry; -+ struct hlist_node *tmp; -+ char uids[128]; -+ char *start_uid, *end_uid = NULL; -+ long int uid_start = 0, uid_end = 0; -+ -+ if (count >= sizeof(uids)) -+ count = sizeof(uids) - 1; -+ -+ if (copy_from_user(uids, buffer, count)) -+ return -EFAULT; -+ -+ uids[count] = '\0'; -+ end_uid = uids; -+ start_uid = strsep(&end_uid, "-"); -+ -+ if (!start_uid || !end_uid) -+ return -EINVAL; -+ -+ if (kstrtol(start_uid, 10, &uid_start) != 0 || -+ kstrtol(end_uid, 10, &uid_end) != 0) { -+ return -EINVAL; -+ } -+ rt_mutex_lock(&uid_lock); -+ -+ for (; uid_start <= uid_end; uid_start++) { -+ hash_for_each_possible_safe(hash_table, uid_entry, tmp, -+ hash, (uid_t)uid_start) { -+ if (uid_start == uid_entry->uid) { -+ hash_del(&uid_entry->hash); -+ kfree(uid_entry); -+ } -+ } -+ } -+ -+ rt_mutex_unlock(&uid_lock); -+ return count; -+} -+ -+static const struct file_operations uid_remove_fops = { -+ .open = uid_remove_open, -+ .release = single_release, -+ .write = uid_remove_write, -+}; -+ -+static int process_notifier(struct notifier_block *self, -+ unsigned long cmd, void *v) -+{ -+ struct task_struct *task = v; -+ struct uid_entry *uid_entry; -+ u64 utime, stime; -+ uid_t uid; -+ -+ if (!task) -+ return NOTIFY_OK; -+ -+ rt_mutex_lock(&uid_lock); -+ uid = from_kuid_munged(current_user_ns(), task_uid(task)); -+ uid_entry = find_or_register_uid(uid); -+ if (!uid_entry) { -+ pr_err("%s: failed to find uid %d\n", __func__, uid); -+ goto exit; -+ } -+ -+ task_cputime_adjusted(task, &utime, &stime); -+ uid_entry->utime += utime; -+ uid_entry->stime += stime; -+ -+exit: -+ rt_mutex_unlock(&uid_lock); -+ return NOTIFY_OK; -+} -+ -+static struct notifier_block process_notifier_block = { -+ .notifier_call = process_notifier, -+}; -+ -+static int __init proc_uid_cputime_init(void) -+{ -+ hash_init(hash_table); -+ -+ parent = proc_mkdir("uid_cputime", NULL); -+ if (!parent) { -+ pr_err("%s: failed to create proc entry\n", __func__); -+ return -ENOMEM; -+ } -+ -+ proc_create_data("remove_uid_range", S_IWUGO, parent, &uid_remove_fops, -+ NULL); -+ -+ proc_create_data("show_uid_stat", S_IRUGO, parent, &uid_stat_fops, -+ NULL); -+ -+ profile_event_register(PROFILE_TASK_EXIT, &process_notifier_block); -+ -+ return 0; -+} -+ -+early_initcall(proc_uid_cputime_init); diff --git a/patches/ANDROID-uid_cputime-add-per-uid-IO-usage-accounting.patch b/patches/ANDROID-uid_cputime-add-per-uid-IO-usage-accounting.patch deleted file mode 100644 index aaadda4015a4..000000000000 --- a/patches/ANDROID-uid_cputime-add-per-uid-IO-usage-accounting.patch +++ /dev/null @@ -1,647 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jin Qian -Date: Tue, 10 Jan 2017 16:10:35 -0800 -Subject: ANDROID: uid_cputime: add per-uid IO usage accounting - -IO usages are accounted in foreground and background buckets. -For each uid, io usage is calculated in two steps. - -delta = current total of all uid tasks - previus total -current bucket += delta - -Bucket is determined by current uid stat. Userspace writes to -/proc/uid_procstat/set when uid stat is updated. - -/proc/uid_io/stats shows IO usage in this format. - - -Bug: 34198239 -Bug: 120442023 -Change-Id: Ib8bebda53e7a56f45ea3eb0ec9a3153d44188102 -Signed-off-by: Jin Qian -[connoro: Used by storaged.] -[astrachan: Note: this version does not track fsync syscalls; this is - implemented in a follow up due to the fact it depends on - modifications to the task_xacct feature.] -[astrachan: Folded in the following changes: - e003a91d8f42 ("ANDROID: uid_sys_stats: allow writing same state") - 89b984bf2efd ("ANDROID: uid_sys_stats: fix negative write bytes.") - bb5ee21cc4dd ("ANDROID: uid_sys_stats: change to use rt_mutex") - 9297d5a160c7 ("ANDROID: uid_sys_stats: reduce update_io_stats overhead") - 89402d07fe91 ("ANDROID: uid_sys_stats: defer io stats calulation for dead tasks") - 6dc5d8173a8c ("ANDROID: uid_sys_stats: check previous uid_entry before call find_or_register_uid") - 0ca2ece8f7ec ("ANDROID: uid_sys_stats: log task io with a debug flag") - c9c096ef0e67 ("ANDROID: uid_sys_stats: Copy task_struct comm field to bigger buffer")] -Signed-off-by: Alistair Strachan ---- - drivers/misc/Kconfig | 11 +- - drivers/misc/uid_sys_stats.c | 490 +++++++++++++++++++++++++++++++++-- - 2 files changed, 483 insertions(+), 18 deletions(-) - -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index ef553e6eb1cd..a067f988d0f4 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -460,9 +460,18 @@ config MISC_RTSX - - config UID_SYS_STATS - bool "Per-UID statistics" -- depends on PROFILING -+ depends on PROFILING && TASK_IO_ACCOUNTING - help - Per UID based cpu time statistics exported to /proc/uid_cputime -+ Per UID based io statistics exported to /proc/uid_io -+ Per UID based procstat control in /proc/uid_procstat -+ -+config UID_SYS_STATS_DEBUG -+ bool "Per-TASK statistics" -+ depends on UID_SYS_STATS -+ default n -+ help -+ Per TASK based io statistics exported to /proc/uid_io - - config PVPANIC - tristate "pvpanic device support" -diff --git a/drivers/misc/uid_sys_stats.c b/drivers/misc/uid_sys_stats.c -index e1a9ef29468f..ea23f5d0af43 100644 ---- a/drivers/misc/uid_sys_stats.c -+++ b/drivers/misc/uid_sys_stats.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -32,7 +33,35 @@ - DECLARE_HASHTABLE(hash_table, UID_HASH_BITS); - - static DEFINE_RT_MUTEX(uid_lock); --static struct proc_dir_entry *parent; -+static struct proc_dir_entry *cpu_parent; -+static struct proc_dir_entry *io_parent; -+static struct proc_dir_entry *proc_parent; -+ -+struct io_stats { -+ u64 read_bytes; -+ u64 write_bytes; -+ u64 rchar; -+ u64 wchar; -+ u64 fsync; -+}; -+ -+#define UID_STATE_FOREGROUND 0 -+#define UID_STATE_BACKGROUND 1 -+#define UID_STATE_BUCKET_SIZE 2 -+ -+#define UID_STATE_TOTAL_CURR 2 -+#define UID_STATE_TOTAL_LAST 3 -+#define UID_STATE_DEAD_TASKS 4 -+#define UID_STATE_SIZE 5 -+ -+#define MAX_TASK_COMM_LEN 256 -+ -+struct task_entry { -+ char comm[MAX_TASK_COMM_LEN]; -+ pid_t pid; -+ struct io_stats io[UID_STATE_SIZE]; -+ struct hlist_node hash; -+}; - - struct uid_entry { - uid_t uid; -@@ -40,9 +69,233 @@ struct uid_entry { - u64 stime; - u64 active_utime; - u64 active_stime; -+ int state; -+ struct io_stats io[UID_STATE_SIZE]; - struct hlist_node hash; -+#ifdef CONFIG_UID_SYS_STATS_DEBUG -+ DECLARE_HASHTABLE(task_entries, UID_HASH_BITS); -+#endif - }; - -+static u64 compute_write_bytes(struct task_struct *task) -+{ -+ if (task->ioac.write_bytes <= task->ioac.cancelled_write_bytes) -+ return 0; -+ -+ return task->ioac.write_bytes - task->ioac.cancelled_write_bytes; -+} -+ -+static void compute_io_bucket_stats(struct io_stats *io_bucket, -+ struct io_stats *io_curr, -+ struct io_stats *io_last, -+ struct io_stats *io_dead) -+{ -+ /* tasks could switch to another uid group, but its io_last in the -+ * previous uid group could still be positive. -+ * therefore before each update, do an overflow check first -+ */ -+ int64_t delta; -+ -+ delta = io_curr->read_bytes + io_dead->read_bytes - -+ io_last->read_bytes; -+ io_bucket->read_bytes += delta > 0 ? delta : 0; -+ delta = io_curr->write_bytes + io_dead->write_bytes - -+ io_last->write_bytes; -+ io_bucket->write_bytes += delta > 0 ? delta : 0; -+ delta = io_curr->rchar + io_dead->rchar - io_last->rchar; -+ io_bucket->rchar += delta > 0 ? delta : 0; -+ delta = io_curr->wchar + io_dead->wchar - io_last->wchar; -+ io_bucket->wchar += delta > 0 ? delta : 0; -+ delta = io_curr->fsync + io_dead->fsync - io_last->fsync; -+ io_bucket->fsync += delta > 0 ? delta : 0; -+ -+ io_last->read_bytes = io_curr->read_bytes; -+ io_last->write_bytes = io_curr->write_bytes; -+ io_last->rchar = io_curr->rchar; -+ io_last->wchar = io_curr->wchar; -+ io_last->fsync = io_curr->fsync; -+ -+ memset(io_dead, 0, sizeof(struct io_stats)); -+} -+ -+#ifdef CONFIG_UID_SYS_STATS_DEBUG -+static void get_full_task_comm(struct task_entry *task_entry, -+ struct task_struct *task) -+{ -+ int i = 0, offset = 0, len = 0; -+ /* save one byte for terminating null character */ -+ int unused_len = MAX_TASK_COMM_LEN - TASK_COMM_LEN - 1; -+ char buf[unused_len]; -+ struct mm_struct *mm = task->mm; -+ -+ /* fill the first TASK_COMM_LEN bytes with thread name */ -+ __get_task_comm(task_entry->comm, TASK_COMM_LEN, task); -+ i = strlen(task_entry->comm); -+ while (i < TASK_COMM_LEN) -+ task_entry->comm[i++] = ' '; -+ -+ /* next the executable file name */ -+ if (mm) { -+ down_read(&mm->mmap_sem); -+ if (mm->exe_file) { -+ char *pathname = d_path(&mm->exe_file->f_path, buf, -+ unused_len); -+ -+ if (!IS_ERR(pathname)) { -+ len = strlcpy(task_entry->comm + i, pathname, -+ unused_len); -+ i += len; -+ task_entry->comm[i++] = ' '; -+ unused_len--; -+ } -+ } -+ up_read(&mm->mmap_sem); -+ } -+ unused_len -= len; -+ -+ /* fill the rest with command line argument -+ * replace each null or new line character -+ * between args in argv with whitespace */ -+ len = get_cmdline(task, buf, unused_len); -+ while (offset < len) { -+ if (buf[offset] != '\0' && buf[offset] != '\n') -+ task_entry->comm[i++] = buf[offset]; -+ else -+ task_entry->comm[i++] = ' '; -+ offset++; -+ } -+ -+ /* get rid of trailing whitespaces in case when arg is memset to -+ * zero before being reset in userspace -+ */ -+ while (task_entry->comm[i-1] == ' ') -+ i--; -+ task_entry->comm[i] = '\0'; -+} -+ -+static struct task_entry *find_task_entry(struct uid_entry *uid_entry, -+ struct task_struct *task) -+{ -+ struct task_entry *task_entry; -+ -+ hash_for_each_possible(uid_entry->task_entries, task_entry, hash, -+ task->pid) { -+ if (task->pid == task_entry->pid) { -+ /* if thread name changed, update the entire command */ -+ int len = strnchr(task_entry->comm, ' ', TASK_COMM_LEN) -+ - task_entry->comm; -+ -+ if (strncmp(task_entry->comm, task->comm, len)) -+ get_full_task_comm(task_entry, task); -+ return task_entry; -+ } -+ } -+ return NULL; -+} -+ -+static struct task_entry *find_or_register_task(struct uid_entry *uid_entry, -+ struct task_struct *task) -+{ -+ struct task_entry *task_entry; -+ pid_t pid = task->pid; -+ -+ task_entry = find_task_entry(uid_entry, task); -+ if (task_entry) -+ return task_entry; -+ -+ task_entry = kzalloc(sizeof(struct task_entry), GFP_ATOMIC); -+ if (!task_entry) -+ return NULL; -+ -+ get_full_task_comm(task_entry, task); -+ -+ task_entry->pid = pid; -+ hash_add(uid_entry->task_entries, &task_entry->hash, (unsigned int)pid); -+ -+ return task_entry; -+} -+ -+static void remove_uid_tasks(struct uid_entry *uid_entry) -+{ -+ struct task_entry *task_entry; -+ unsigned long bkt_task; -+ struct hlist_node *tmp_task; -+ -+ hash_for_each_safe(uid_entry->task_entries, bkt_task, -+ tmp_task, task_entry, hash) { -+ hash_del(&task_entry->hash); -+ kfree(task_entry); -+ } -+} -+ -+static void set_io_uid_tasks_zero(struct uid_entry *uid_entry) -+{ -+ struct task_entry *task_entry; -+ unsigned long bkt_task; -+ -+ hash_for_each(uid_entry->task_entries, bkt_task, task_entry, hash) { -+ memset(&task_entry->io[UID_STATE_TOTAL_CURR], 0, -+ sizeof(struct io_stats)); -+ } -+} -+ -+static void add_uid_tasks_io_stats(struct uid_entry *uid_entry, -+ struct task_struct *task, int slot) -+{ -+ struct task_entry *task_entry = find_or_register_task(uid_entry, task); -+ struct io_stats *task_io_slot = &task_entry->io[slot]; -+ -+ task_io_slot->read_bytes += task->ioac.read_bytes; -+ task_io_slot->write_bytes += compute_write_bytes(task); -+ task_io_slot->rchar += task->ioac.rchar; -+ task_io_slot->wchar += task->ioac.wchar; -+} -+ -+static void compute_io_uid_tasks(struct uid_entry *uid_entry) -+{ -+ struct task_entry *task_entry; -+ unsigned long bkt_task; -+ -+ hash_for_each(uid_entry->task_entries, bkt_task, task_entry, hash) { -+ compute_io_bucket_stats(&task_entry->io[uid_entry->state], -+ &task_entry->io[UID_STATE_TOTAL_CURR], -+ &task_entry->io[UID_STATE_TOTAL_LAST], -+ &task_entry->io[UID_STATE_DEAD_TASKS]); -+ } -+} -+ -+static void show_io_uid_tasks(struct seq_file *m, struct uid_entry *uid_entry) -+{ -+ struct task_entry *task_entry; -+ unsigned long bkt_task; -+ -+ hash_for_each(uid_entry->task_entries, bkt_task, task_entry, hash) { -+ /* Separated by comma because space exists in task comm */ -+ seq_printf(m, "task,%s,%lu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu,%llu\n", -+ task_entry->comm, -+ (unsigned long)task_entry->pid, -+ task_entry->io[UID_STATE_FOREGROUND].rchar, -+ task_entry->io[UID_STATE_FOREGROUND].wchar, -+ task_entry->io[UID_STATE_FOREGROUND].read_bytes, -+ task_entry->io[UID_STATE_FOREGROUND].write_bytes, -+ task_entry->io[UID_STATE_BACKGROUND].rchar, -+ task_entry->io[UID_STATE_BACKGROUND].wchar, -+ task_entry->io[UID_STATE_BACKGROUND].read_bytes, -+ task_entry->io[UID_STATE_BACKGROUND].write_bytes, -+ task_entry->io[UID_STATE_FOREGROUND].fsync, -+ task_entry->io[UID_STATE_BACKGROUND].fsync); -+ } -+} -+#else -+static void remove_uid_tasks(struct uid_entry *uid_entry) {}; -+static void set_io_uid_tasks_zero(struct uid_entry *uid_entry) {}; -+static void add_uid_tasks_io_stats(struct uid_entry *uid_entry, -+ struct task_struct *task, int slot) {}; -+static void compute_io_uid_tasks(struct uid_entry *uid_entry) {}; -+static void show_io_uid_tasks(struct seq_file *m, -+ struct uid_entry *uid_entry) {} -+#endif -+ - static struct uid_entry *find_uid_entry(uid_t uid) - { - struct uid_entry *uid_entry; -@@ -66,13 +319,15 @@ static struct uid_entry *find_or_register_uid(uid_t uid) - return NULL; - - uid_entry->uid = uid; -- -+#ifdef CONFIG_UID_SYS_STATS_DEBUG -+ hash_init(uid_entry->task_entries); -+#endif - hash_add(hash_table, &uid_entry->hash, uid); - - return uid_entry; - } - --static int uid_stat_show(struct seq_file *m, void *v) -+static int uid_cputime_show(struct seq_file *m, void *v) - { - struct uid_entry *uid_entry = NULL; - struct task_struct *task, *temp; -@@ -120,13 +375,13 @@ static int uid_stat_show(struct seq_file *m, void *v) - return 0; - } - --static int uid_stat_open(struct inode *inode, struct file *file) -+static int uid_cputime_open(struct inode *inode, struct file *file) - { -- return single_open(file, uid_stat_show, PDE_DATA(inode)); -+ return single_open(file, uid_cputime_show, PDE_DATA(inode)); - } - --static const struct file_operations uid_stat_fops = { -- .open = uid_stat_open, -+static const struct file_operations uid_cputime_fops = { -+ .open = uid_cputime_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -@@ -163,12 +418,14 @@ static ssize_t uid_remove_write(struct file *file, - kstrtol(end_uid, 10, &uid_end) != 0) { - return -EINVAL; - } -+ - rt_mutex_lock(&uid_lock); - - for (; uid_start <= uid_end; uid_start++) { - hash_for_each_possible_safe(hash_table, uid_entry, tmp, - hash, (uid_t)uid_start) { - if (uid_start == uid_entry->uid) { -+ remove_uid_tasks(uid_entry); - hash_del(&uid_entry->hash); - kfree(uid_entry); - } -@@ -185,6 +442,177 @@ static const struct file_operations uid_remove_fops = { - .write = uid_remove_write, - }; - -+ -+static void add_uid_io_stats(struct uid_entry *uid_entry, -+ struct task_struct *task, int slot) -+{ -+ struct io_stats *io_slot = &uid_entry->io[slot]; -+ -+ io_slot->read_bytes += task->ioac.read_bytes; -+ io_slot->write_bytes += compute_write_bytes(task); -+ io_slot->rchar += task->ioac.rchar; -+ io_slot->wchar += task->ioac.wchar; -+ -+ add_uid_tasks_io_stats(uid_entry, task, slot); -+} -+ -+static void update_io_stats_all_locked(void) -+{ -+ struct uid_entry *uid_entry = NULL; -+ struct task_struct *task, *temp; -+ struct user_namespace *user_ns = current_user_ns(); -+ unsigned long bkt; -+ uid_t uid; -+ -+ hash_for_each(hash_table, bkt, uid_entry, hash) { -+ memset(&uid_entry->io[UID_STATE_TOTAL_CURR], 0, -+ sizeof(struct io_stats)); -+ set_io_uid_tasks_zero(uid_entry); -+ } -+ -+ rcu_read_lock(); -+ do_each_thread(temp, task) { -+ uid = from_kuid_munged(user_ns, task_uid(task)); -+ if (!uid_entry || uid_entry->uid != uid) -+ uid_entry = find_or_register_uid(uid); -+ if (!uid_entry) -+ continue; -+ add_uid_io_stats(uid_entry, task, UID_STATE_TOTAL_CURR); -+ } while_each_thread(temp, task); -+ rcu_read_unlock(); -+ -+ hash_for_each(hash_table, bkt, uid_entry, hash) { -+ compute_io_bucket_stats(&uid_entry->io[uid_entry->state], -+ &uid_entry->io[UID_STATE_TOTAL_CURR], -+ &uid_entry->io[UID_STATE_TOTAL_LAST], -+ &uid_entry->io[UID_STATE_DEAD_TASKS]); -+ compute_io_uid_tasks(uid_entry); -+ } -+} -+ -+static void update_io_stats_uid_locked(struct uid_entry *uid_entry) -+{ -+ struct task_struct *task, *temp; -+ struct user_namespace *user_ns = current_user_ns(); -+ -+ memset(&uid_entry->io[UID_STATE_TOTAL_CURR], 0, -+ sizeof(struct io_stats)); -+ set_io_uid_tasks_zero(uid_entry); -+ -+ rcu_read_lock(); -+ do_each_thread(temp, task) { -+ if (from_kuid_munged(user_ns, task_uid(task)) != uid_entry->uid) -+ continue; -+ add_uid_io_stats(uid_entry, task, UID_STATE_TOTAL_CURR); -+ } while_each_thread(temp, task); -+ rcu_read_unlock(); -+ -+ compute_io_bucket_stats(&uid_entry->io[uid_entry->state], -+ &uid_entry->io[UID_STATE_TOTAL_CURR], -+ &uid_entry->io[UID_STATE_TOTAL_LAST], -+ &uid_entry->io[UID_STATE_DEAD_TASKS]); -+ compute_io_uid_tasks(uid_entry); -+} -+ -+ -+static int uid_io_show(struct seq_file *m, void *v) -+{ -+ struct uid_entry *uid_entry; -+ unsigned long bkt; -+ -+ rt_mutex_lock(&uid_lock); -+ -+ update_io_stats_all_locked(); -+ -+ hash_for_each(hash_table, bkt, uid_entry, hash) { -+ seq_printf(m, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", -+ uid_entry->uid, -+ uid_entry->io[UID_STATE_FOREGROUND].rchar, -+ uid_entry->io[UID_STATE_FOREGROUND].wchar, -+ uid_entry->io[UID_STATE_FOREGROUND].read_bytes, -+ uid_entry->io[UID_STATE_FOREGROUND].write_bytes, -+ uid_entry->io[UID_STATE_BACKGROUND].rchar, -+ uid_entry->io[UID_STATE_BACKGROUND].wchar, -+ uid_entry->io[UID_STATE_BACKGROUND].read_bytes, -+ uid_entry->io[UID_STATE_BACKGROUND].write_bytes, -+ uid_entry->io[UID_STATE_FOREGROUND].fsync, -+ uid_entry->io[UID_STATE_BACKGROUND].fsync); -+ -+ show_io_uid_tasks(m, uid_entry); -+ } -+ -+ rt_mutex_unlock(&uid_lock); -+ return 0; -+} -+ -+static int uid_io_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, uid_io_show, PDE_DATA(inode)); -+} -+ -+static const struct file_operations uid_io_fops = { -+ .open = uid_io_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static int uid_procstat_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, NULL, NULL); -+} -+ -+static ssize_t uid_procstat_write(struct file *file, -+ const char __user *buffer, size_t count, loff_t *ppos) -+{ -+ struct uid_entry *uid_entry; -+ uid_t uid; -+ int argc, state; -+ char input[128]; -+ -+ if (count >= sizeof(input)) -+ return -EINVAL; -+ -+ if (copy_from_user(input, buffer, count)) -+ return -EFAULT; -+ -+ input[count] = '\0'; -+ -+ argc = sscanf(input, "%u %d", &uid, &state); -+ if (argc != 2) -+ return -EINVAL; -+ -+ if (state != UID_STATE_BACKGROUND && state != UID_STATE_FOREGROUND) -+ return -EINVAL; -+ -+ rt_mutex_lock(&uid_lock); -+ -+ uid_entry = find_or_register_uid(uid); -+ if (!uid_entry) { -+ rt_mutex_unlock(&uid_lock); -+ return -EINVAL; -+ } -+ -+ if (uid_entry->state == state) { -+ rt_mutex_unlock(&uid_lock); -+ return count; -+ } -+ -+ update_io_stats_uid_locked(uid_entry); -+ -+ uid_entry->state = state; -+ -+ rt_mutex_unlock(&uid_lock); -+ -+ return count; -+} -+ -+static const struct file_operations uid_procstat_fops = { -+ .open = uid_procstat_open, -+ .release = single_release, -+ .write = uid_procstat_write, -+}; -+ - static int process_notifier(struct notifier_block *self, - unsigned long cmd, void *v) - { -@@ -208,6 +636,8 @@ static int process_notifier(struct notifier_block *self, - uid_entry->utime += utime; - uid_entry->stime += stime; - -+ add_uid_io_stats(uid_entry, task, UID_STATE_DEAD_TASKS); -+ - exit: - rt_mutex_unlock(&uid_lock); - return NOTIFY_OK; -@@ -217,25 +647,51 @@ static struct notifier_block process_notifier_block = { - .notifier_call = process_notifier, - }; - --static int __init proc_uid_cputime_init(void) -+static int __init proc_uid_sys_stats_init(void) - { - hash_init(hash_table); - -- parent = proc_mkdir("uid_cputime", NULL); -- if (!parent) { -- pr_err("%s: failed to create proc entry\n", __func__); -- return -ENOMEM; -+ cpu_parent = proc_mkdir("uid_cputime", NULL); -+ if (!cpu_parent) { -+ pr_err("%s: failed to create uid_cputime proc entry\n", -+ __func__); -+ goto err; -+ } -+ -+ proc_create_data("remove_uid_range", 0222, cpu_parent, -+ &uid_remove_fops, NULL); -+ proc_create_data("show_uid_stat", 0444, cpu_parent, -+ &uid_cputime_fops, NULL); -+ -+ io_parent = proc_mkdir("uid_io", NULL); -+ if (!io_parent) { -+ pr_err("%s: failed to create uid_io proc entry\n", -+ __func__); -+ goto err; - } - -- proc_create_data("remove_uid_range", S_IWUGO, parent, &uid_remove_fops, -- NULL); -+ proc_create_data("stats", 0444, io_parent, -+ &uid_io_fops, NULL); - -- proc_create_data("show_uid_stat", S_IRUGO, parent, &uid_stat_fops, -- NULL); -+ proc_parent = proc_mkdir("uid_procstat", NULL); -+ if (!proc_parent) { -+ pr_err("%s: failed to create uid_procstat proc entry\n", -+ __func__); -+ goto err; -+ } -+ -+ proc_create_data("set", 0222, proc_parent, -+ &uid_procstat_fops, NULL); - - profile_event_register(PROFILE_TASK_EXIT, &process_notifier_block); - - return 0; -+ -+err: -+ remove_proc_subtree("uid_cputime", NULL); -+ remove_proc_subtree("uid_io", NULL); -+ remove_proc_subtree("uid_procstat", NULL); -+ return -ENOMEM; - } - --early_initcall(proc_uid_cputime_init); -+early_initcall(proc_uid_sys_stats_init); diff --git a/patches/ANDROID-unconditionally-compile-sig_ok-in-struct-module.patch b/patches/ANDROID-unconditionally-compile-sig_ok-in-struct-module.patch deleted file mode 100644 index 53fa59ffe57c..000000000000 --- a/patches/ANDROID-unconditionally-compile-sig_ok-in-struct-module.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Steve Muckle -Date: Thu, 17 Oct 2019 12:14:13 -0700 -Subject: ANDROID: unconditionally compile sig_ok in struct module - -The generic kernel image must have module signing disabled so it can -load kernel modules from all vendors. Unfortunately loading a signed -kernel module into a kernel with module signing disabled will fail -because struct module_layout (which appears in kernel modules) contains -struct module, and struct module contains the sig_ok field, which is -conditionally compiled depending on CONFIG_MODULE_SIG (module signing). - -Unconditionally compile the sig_ok field to work around this problem. - -Bug: 135940219 -Test: load a signed kernel module with module signing disabled -Change-Id: I5cc437c806f74f89c0e45ce4135136ca0c70738e -Signed-off-by: Steve Muckle ---- - include/linux/module.h | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/include/linux/module.h b/include/linux/module.h -index 6d20895e7739..6744ffe9a727 100644 ---- a/include/linux/module.h -+++ b/include/linux/module.h -@@ -389,10 +389,12 @@ struct module { - const s32 *unused_gpl_crcs; - #endif - --#ifdef CONFIG_MODULE_SIG -- /* Signature was verified. */ -+ /* -+ * Signature was verified. Unconditionally compiled in Android to -+ * preserve ABI compatibility between kernels without module -+ * signing enabled and signed modules. -+ */ - bool sig_ok; --#endif - - bool async_probe_requested; - diff --git a/patches/ANDROID-update-arm64-gki_defconfig.patch b/patches/ANDROID-update-arm64-gki_defconfig.patch deleted file mode 100644 index 312dc9a2fedf..000000000000 --- a/patches/ANDROID-update-arm64-gki_defconfig.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Mon, 23 Sep 2019 14:43:39 +0200 -Subject: ANDROID: update arm64 gki_defconfig - -Update the arm64 gki_defconfig for changes made during the merge of -upstream - -Signed-off-by: Greg Kroah-Hartman -Change-Id: I50d96aa097866a43f305c59954f1242e02d0dac6 ---- - arch/arm64/configs/gki_defconfig | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index ab1dd6d01ec8..01be7843c646 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -384,7 +384,6 @@ CONFIG_FUSE_FS=y - CONFIG_OVERLAY_FS=y - CONFIG_MSDOS_FS=y - CONFIG_VFAT_FS=y --CONFIG_TMPFS_POSIX_ACL=y - # CONFIG_EFIVAR_FS is not set - CONFIG_SDCARD_FS=y - CONFIG_PSTORE=y diff --git a/patches/ANDROID-update-gki_defconfig-2.patch b/patches/ANDROID-update-gki_defconfig-2.patch deleted file mode 100644 index c936b5fc71f7..000000000000 --- a/patches/ANDROID-update-gki_defconfig-2.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Mon, 30 Sep 2019 13:31:19 +0200 -Subject: ANDROID: update gki_defconfig - -Update the default gki_defconfig now that there were some config changes -in mainline. - -Signed-off-by: Greg Kroah-Hartman -Change-Id: Iafb8e2fa2d8027b2848e93d2d39b0ea42028289b ---- - arch/arm64/configs/gki_defconfig | 1 - - arch/x86/configs/gki_defconfig | 1 - - 2 files changed, 2 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index 01be7843c646..97e0e47767e2 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -298,7 +298,6 @@ CONFIG_MEDIA_CONTROLLER=y - CONFIG_DRM=y - # CONFIG_DRM_FBDEV_EMULATION is not set - CONFIG_DRM_VIRTIO_GPU=y --# CONFIG_LCD_CLASS_DEVICE is not set - CONFIG_BACKLIGHT_CLASS_DEVICE=y - CONFIG_SOUND=y - CONFIG_SND=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 73d513715ce7..7890c249bca9 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -255,7 +255,6 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y - CONFIG_DRM=y - # CONFIG_DRM_FBDEV_EMULATION is not set - CONFIG_DRM_VIRTIO_GPU=m --# CONFIG_LCD_CLASS_DEVICE is not set - CONFIG_BACKLIGHT_CLASS_DEVICE=y - CONFIG_SOUND=y - CONFIG_SND=y diff --git a/patches/ANDROID-update-gki_defconfig.patch b/patches/ANDROID-update-gki_defconfig.patch deleted file mode 100644 index 2dbf8ec62cbf..000000000000 --- a/patches/ANDROID-update-gki_defconfig.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Thu, 19 Sep 2019 23:21:24 +0200 -Subject: ANDROID: update gki_defconfig - -The 5.4-rc1-prerelease merge changed a few config options, so update -gki_defconfig so that the build will run properly. - -Signed-off-by: Greg Kroah-Hartman -Change-Id: I8feb0a501d60005a7973b1fa2f9d34bb87b64259 ---- - arch/arm64/configs/gki_defconfig | 1 - - arch/x86/configs/gki_defconfig | 1 - - 2 files changed, 2 deletions(-) - -diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig -index f964b81a1e4b..ab1dd6d01ec8 100644 ---- a/arch/arm64/configs/gki_defconfig -+++ b/arch/arm64/configs/gki_defconfig -@@ -397,7 +397,6 @@ CONFIG_HARDENED_USERCOPY=y - CONFIG_SECURITY_SELINUX=y - CONFIG_CRYPTO_ADIANTUM=y - CONFIG_CRYPTO_MD4=y --CONFIG_CRYPTO_SHA512=y - CONFIG_CRYPTO_LZ4=y - CONFIG_CRYPTO_ZSTD=y - CONFIG_CRYPTO_ANSI_CPRNG=y -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 642729662b04..73d513715ce7 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -328,7 +328,6 @@ CONFIG_SECURITY_NETWORK=y - CONFIG_HARDENED_USERCOPY=y - CONFIG_SECURITY_SELINUX=y - CONFIG_CRYPTO_ADIANTUM=y --CONFIG_CRYPTO_SHA512=y - CONFIG_CRYPTO_LZ4=y - CONFIG_CRYPTO_ZSTD=y - CONFIG_CRYPTO_ANSI_CPRNG=y diff --git a/patches/ANDROID-usb-gadget-Fix-dependency-for-f_accessory.patch b/patches/ANDROID-usb-gadget-Fix-dependency-for-f_accessory.patch deleted file mode 100644 index 0dcd7dfc934d..000000000000 --- a/patches/ANDROID-usb-gadget-Fix-dependency-for-f_accessory.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Quentin Perret -Date: Mon, 30 Sep 2019 15:27:24 +0100 -Subject: ANDROID: usb: gadget: Fix dependency for f_accessory - -The Android Accessory USB gadget functions use core HID functions. As -such, compiling with CONFIG_HID=m and CONFIG_USB_GADGET=y fails to link: - - drivers/usb/gadget/function/f_accessory.o: In function `acc_complete_send_hid_event': - f_accessory.c:(.text+0xd54): undefined reference to `hid_report_raw_event' - drivers/usb/gadget/function/f_accessory.o: In function `acc_hid_work': - f_accessory.c:(.text+0x2a98): undefined reference to `hid_destroy_device' - f_accessory.c:(.text+0x2ad4): undefined reference to `hid_allocate_device' - f_accessory.c:(.text+0x2b64): undefined reference to `hid_add_device' - f_accessory.c:(.text+0x2d04): undefined reference to `hid_destroy_device' - drivers/usb/gadget/function/f_accessory.o: In function `acc_hid_parse': - f_accessory.c:(.text+0x2e24): undefined reference to `hid_parse_report' - drivers/usb/gadget/function/f_accessory.o: In function `acc_function_bind_configfs': - f_accessory.c:(.text+0x2f8c): undefined reference to `__hid_register_driver' - drivers/usb/gadget/function/f_accessory.o: In function `acc_function_unbind': - f_accessory.c:(.text+0x3bc8): undefined reference to `hid_unregister_driver' - drivers/usb/gadget/function/f_accessory.o: In function `acc_hid_probe': - f_accessory.c:(.text+0x3ef4): undefined reference to `hid_open_report' - f_accessory.c:(.text+0x3f18): undefined reference to `hid_hw_start' - -Fix this by making the dependency on HID explicit. - -Bug: 140224784 -Fixes: 483cb5629ea7 ("ANDROID: usb: gadget: f_accessory: Add Android -Accessory function") -Signed-off-by: Quentin Perret -Change-Id: Ibd8640d7766cc7802d8275bfe3adfa007f3318fe ---- - drivers/usb/gadget/Kconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig -index 920ff2d2c557..bcd7f83c9ba0 100644 ---- a/drivers/usb/gadget/Kconfig -+++ b/drivers/usb/gadget/Kconfig -@@ -386,6 +386,7 @@ config USB_CONFIGFS_F_FS - config USB_CONFIGFS_F_ACC - bool "Accessory gadget" - depends on USB_CONFIGFS -+ depends on HID=y - select USB_F_ACC - help - USB gadget Accessory support diff --git a/patches/ANDROID-usb-gadget-configfs-Add-Uevent-to-notify-userspace.patch b/patches/ANDROID-usb-gadget-configfs-Add-Uevent-to-notify-userspace.patch deleted file mode 100644 index 46cce4ea0325..000000000000 --- a/patches/ANDROID-usb-gadget-configfs-Add-Uevent-to-notify-userspace.patch +++ /dev/null @@ -1,275 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Badhri Jagan Sridharan -Date: Mon, 15 Dec 2014 10:44:47 -0800 -Subject: ANDROID: usb: gadget: configfs: Add Uevent to notify userspace - -Android userspace UsbDeviceManager relies on the -uevents generated by the composition driver to -generate user notifications. This CL adds uevents -to be generated whenever USB changes its state -i.e. connected, disconnected, configured. - -This CL also intercepts the setup requests from -the usb_core anb routes it to the specific -usb function if required. - -Bug: 68755607 -Bug: 120441124 -Change-Id: Ib3d3a78255a532f7449dac286f776c2966caf8c1 -[badhri: Migrate to using udc uevents from upstream sysfs.] -Signed-off-by: Badhri Jagan Sridharan -[AmitP: Folded following android-4.9 commit changes into this patch - 9214c899f730 ("ANDROID: usb: gadget: configfs: handle gadget reset request for android")] -Signed-off-by: Amit Pundir -[astrachan: Folded change 5c899c9fd75d ("ANDROID: usb: gadget: configfs: - fix null ptr in android_disconnect") into this patch] -Signed-off-by: Alistair Strachan ---- - drivers/usb/gadget/Kconfig | 8 ++ - drivers/usb/gadget/configfs.c | 166 +++++++++++++++++++++++++++++++++- - 2 files changed, 171 insertions(+), 3 deletions(-) - -diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig -index 02ff850278b1..f5e82dcac583 100644 ---- a/drivers/usb/gadget/Kconfig -+++ b/drivers/usb/gadget/Kconfig -@@ -230,6 +230,14 @@ config USB_CONFIGFS - appropriate symbolic links. - For more information see Documentation/usb/gadget_configfs.rst. - -+config USB_CONFIGFS_UEVENT -+ bool "Uevent notification of Gadget state" -+ depends on USB_CONFIGFS -+ help -+ Enable uevent notifications to userspace when the gadget -+ state changes. The gadget can be in any of the following -+ three states: "CONNECTED/DISCONNECTED/CONFIGURED" -+ - config USB_CONFIGFS_SERIAL - bool "Generic serial bulk in/out" - depends on USB_CONFIGFS -diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c -index 025129942894..bbc166f99893 100644 ---- a/drivers/usb/gadget/configfs.c -+++ b/drivers/usb/gadget/configfs.c -@@ -10,6 +10,19 @@ - #include "u_f.h" - #include "u_os_desc.h" - -+#ifdef CONFIG_USB_CONFIGFS_UEVENT -+#include -+#include -+#include -+ -+#ifdef CONFIG_USB_CONFIGFS_F_ACC -+extern int acc_ctrlrequest(struct usb_composite_dev *cdev, -+ const struct usb_ctrlrequest *ctrl); -+void acc_disconnect(void); -+#endif -+static struct class *android_class; -+#endif -+ - int check_user_usb_string(const char *name, - struct usb_gadget_strings *stringtab_dev) - { -@@ -61,6 +74,12 @@ struct gadget_info { - bool use_os_desc; - char b_vendor_code; - char qw_sign[OS_STRING_QW_SIGN_LEN]; -+#ifdef CONFIG_USB_CONFIGFS_UEVENT -+ bool connected; -+ bool sw_connected; -+ struct work_struct work; -+ struct device *dev; -+#endif - }; - - static inline struct gadget_info *to_gadget_info(struct config_item *item) -@@ -266,7 +285,7 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item, - - mutex_lock(&gi->lock); - -- if (!strlen(name)) { -+ if (!strlen(name) || strcmp(name, "none") == 0) { - ret = unregister_gadget(gi); - if (ret) - goto err; -@@ -1372,6 +1391,57 @@ static int configfs_composite_bind(struct usb_gadget *gadget, - return ret; - } - -+#ifdef CONFIG_USB_CONFIGFS_UEVENT -+static void android_work(struct work_struct *data) -+{ -+ struct gadget_info *gi = container_of(data, struct gadget_info, work); -+ struct usb_composite_dev *cdev = &gi->cdev; -+ char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL }; -+ char *connected[2] = { "USB_STATE=CONNECTED", NULL }; -+ char *configured[2] = { "USB_STATE=CONFIGURED", NULL }; -+ /* 0-connected 1-configured 2-disconnected*/ -+ bool status[3] = { false, false, false }; -+ unsigned long flags; -+ bool uevent_sent = false; -+ -+ spin_lock_irqsave(&cdev->lock, flags); -+ if (cdev->config) -+ status[1] = true; -+ -+ if (gi->connected != gi->sw_connected) { -+ if (gi->connected) -+ status[0] = true; -+ else -+ status[2] = true; -+ gi->sw_connected = gi->connected; -+ } -+ spin_unlock_irqrestore(&cdev->lock, flags); -+ -+ if (status[0]) { -+ kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, connected); -+ pr_info("%s: sent uevent %s\n", __func__, connected[0]); -+ uevent_sent = true; -+ } -+ -+ if (status[1]) { -+ kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, configured); -+ pr_info("%s: sent uevent %s\n", __func__, configured[0]); -+ uevent_sent = true; -+ } -+ -+ if (status[2]) { -+ kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, disconnected); -+ pr_info("%s: sent uevent %s\n", __func__, disconnected[0]); -+ uevent_sent = true; -+ } -+ -+ if (!uevent_sent) { -+ pr_info("%s: did not send uevent (%d %d %p)\n", __func__, -+ gi->connected, gi->sw_connected, cdev->config); -+ } -+} -+#endif -+ - static void configfs_composite_unbind(struct usb_gadget *gadget) - { - struct usb_composite_dev *cdev; -@@ -1391,14 +1461,91 @@ static void configfs_composite_unbind(struct usb_gadget *gadget) - set_gadget_data(gadget, NULL); - } - -+#ifdef CONFIG_USB_CONFIGFS_UEVENT -+static int android_setup(struct usb_gadget *gadget, -+ const struct usb_ctrlrequest *c) -+{ -+ struct usb_composite_dev *cdev = get_gadget_data(gadget); -+ unsigned long flags; -+ struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev); -+ int value = -EOPNOTSUPP; -+ struct usb_function_instance *fi; -+ -+ spin_lock_irqsave(&cdev->lock, flags); -+ if (!gi->connected) { -+ gi->connected = 1; -+ schedule_work(&gi->work); -+ } -+ spin_unlock_irqrestore(&cdev->lock, flags); -+ list_for_each_entry(fi, &gi->available_func, cfs_list) { -+ if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) { -+ value = fi->f->setup(fi->f, c); -+ if (value >= 0) -+ break; -+ } -+ } -+ -+#ifdef CONFIG_USB_CONFIGFS_F_ACC -+ if (value < 0) -+ value = acc_ctrlrequest(cdev, c); -+#endif -+ -+ if (value < 0) -+ value = composite_setup(gadget, c); -+ -+ spin_lock_irqsave(&cdev->lock, flags); -+ if (c->bRequest == USB_REQ_SET_CONFIGURATION && -+ cdev->config) { -+ schedule_work(&gi->work); -+ } -+ spin_unlock_irqrestore(&cdev->lock, flags); -+ -+ return value; -+} -+ -+static void android_disconnect(struct usb_gadget *gadget) -+{ -+ struct usb_composite_dev *cdev = get_gadget_data(gadget); -+ struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev); -+ -+ /* FIXME: There's a race between usb_gadget_udc_stop() which is likely -+ * to set the gadget driver to NULL in the udc driver and this drivers -+ * gadget disconnect fn which likely checks for the gadget driver to -+ * be a null ptr. It happens that unbind (doing set_gadget_data(NULL)) -+ * is called before the gadget driver is set to NULL and the udc driver -+ * calls disconnect fn which results in cdev being a null ptr. -+ */ -+ if (cdev == NULL) { -+ WARN(1, "%s: gadget driver already disconnected\n", __func__); -+ return; -+ } -+ -+ /* accessory HID support can be active while the -+ accessory function is not actually enabled, -+ so we need to inform it when we are disconnected. -+ */ -+ -+#ifdef CONFIG_USB_CONFIGFS_F_ACC -+ acc_disconnect(); -+#endif -+ gi->connected = 0; -+ schedule_work(&gi->work); -+ composite_disconnect(gadget); -+} -+#endif -+ - static const struct usb_gadget_driver configfs_driver_template = { - .bind = configfs_composite_bind, - .unbind = configfs_composite_unbind, -- -+#ifdef CONFIG_USB_CONFIGFS_UEVENT -+ .setup = android_setup, -+ .reset = android_disconnect, -+ .disconnect = android_disconnect, -+#else - .setup = composite_setup, - .reset = composite_disconnect, - .disconnect = composite_disconnect, -- -+#endif - .suspend = composite_suspend, - .resume = composite_resume, - -@@ -1458,6 +1605,12 @@ static struct config_group *gadgets_make( - gi->composite.gadget_driver.function = kstrdup(name, GFP_KERNEL); - gi->composite.name = gi->composite.gadget_driver.function; - -+#ifdef CONFIG_USB_CONFIGFS_UEVENT -+ INIT_WORK(&gi->work, android_work); -+ gi->dev = device_create(android_class, NULL, -+ MKDEV(0, 0), NULL, "android0"); -+#endif -+ - if (!gi->composite.gadget_driver.function) - goto err; - -@@ -1509,6 +1662,13 @@ static int __init gadget_cfs_init(void) - config_group_init(&gadget_subsys.su_group); - - ret = configfs_register_subsystem(&gadget_subsys); -+ -+#ifdef CONFIG_USB_CONFIGFS_UEVENT -+ android_class = class_create(THIS_MODULE, "android_usb"); -+ if (IS_ERR(android_class)) -+ return PTR_ERR(android_class); -+#endif -+ - return ret; - } - module_init(gadget_cfs_init); diff --git a/patches/ANDROID-usb-gadget-configfs-Add-device-attribute-to-determine-gadget-state.patch b/patches/ANDROID-usb-gadget-configfs-Add-device-attribute-to-determine-gadget-state.patch deleted file mode 100644 index 7241be4a3522..000000000000 --- a/patches/ANDROID-usb-gadget-configfs-Add-device-attribute-to-determine-gadget-state.patch +++ /dev/null @@ -1,151 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Badhri Jagan Sridharan -Date: Sun, 9 Aug 2015 15:12:50 -0700 -Subject: ANDROID: usb: gadget: configfs: Add device attribute to determine - gadget state - -Android frameworks (UsbDeviceManager) relies on gadget state exported -through device attributes. This CL adds the device attribute to export -USB gadget state. - -Bug: 68755607 -Bug: 120441124 -Change-Id: Id0391810d75b58c579610fbec6e37ab22f28886d -[badhri: Migrate to using udc uevents from upstream sysfs.] -Signed-off-by: Badhri Jagan Sridharan -[AmitP: Folded following android-4.9 commit changes into this patch - Parts of e45c769fa7af ("ANDROID: usb: gadget: cleanup: fix unused variable and function warnings") -Signed-off-by: Amit Pundir ---- - drivers/usb/gadget/configfs.c | 91 ++++++++++++++++++++--------------- - 1 file changed, 52 insertions(+), 39 deletions(-) - -diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c -index da151de74e1d..b0148a449306 100644 ---- a/drivers/usb/gadget/configfs.c -+++ b/drivers/usb/gadget/configfs.c -@@ -1605,6 +1605,54 @@ static struct device_attribute *android_usb_attributes[] = { - &dev_attr_state, - NULL - }; -+ -+static int android_device_create(struct gadget_info *gi) -+{ -+ struct device_attribute **attrs; -+ struct device_attribute *attr; -+ -+ INIT_WORK(&gi->work, android_work); -+ android_device = device_create(android_class, NULL, -+ MKDEV(0, 0), NULL, "android0"); -+ if (IS_ERR(android_device)) -+ return PTR_ERR(android_device); -+ -+ dev_set_drvdata(android_device, gi); -+ -+ attrs = android_usb_attributes; -+ while ((attr = *attrs++)) { -+ int err; -+ -+ err = device_create_file(android_device, attr); -+ if (err) { -+ device_destroy(android_device->class, -+ android_device->devt); -+ return err; -+ } -+ } -+ -+ return 0; -+} -+ -+static void android_device_destroy(void) -+{ -+ struct device_attribute **attrs; -+ struct device_attribute *attr; -+ -+ attrs = android_usb_attributes; -+ while ((attr = *attrs++)) -+ device_remove_file(android_device, attr); -+ device_destroy(android_device->class, android_device->devt); -+} -+#else -+static inline int android_device_create(struct gadget_info *gi) -+{ -+ return 0; -+} -+ -+static inline void android_device_destroy(void) -+{ -+} - #endif - - static struct config_group *gadgets_make( -@@ -1612,9 +1660,6 @@ static struct config_group *gadgets_make( - const char *name) - { - struct gadget_info *gi; -- struct device_attribute **attrs; -- struct device_attribute *attr; -- int err; - - gi = kzalloc(sizeof(*gi), GFP_KERNEL); - if (!gi) -@@ -1658,37 +1703,14 @@ static struct config_group *gadgets_make( - gi->composite.gadget_driver.function = kstrdup(name, GFP_KERNEL); - gi->composite.name = gi->composite.gadget_driver.function; - --#ifdef CONFIG_USB_CONFIGFS_UEVENT -- INIT_WORK(&gi->work, android_work); -- android_device = device_create(android_class, NULL, -- MKDEV(0, 0), NULL, "android0"); -- if (IS_ERR(android_device)) -+ if (!gi->composite.gadget_driver.function) - goto err; - -- dev_set_drvdata(android_device, gi); -- -- attrs = android_usb_attributes; -- while ((attr = *attrs++)) { -- err = device_create_file(android_device, attr); -- if (err) -- goto err1; -- } --#endif -- -- if (!gi->composite.gadget_driver.function) -- goto err1; -+ if (android_device_create(gi) < 0) -+ goto err; - - return &gi->group; - --err1: --#ifdef CONFIG_USB_CONFIGFS_UEVENT -- attrs = android_usb_attributes; -- while ((attr = *attrs++)) -- device_remove_file(android_device, attr); -- -- device_destroy(android_device->class, -- android_device->devt); --#endif - err: - kfree(gi); - return ERR_PTR(-ENOMEM); -@@ -1696,17 +1718,8 @@ static struct config_group *gadgets_make( - - static void gadgets_drop(struct config_group *group, struct config_item *item) - { -- struct device_attribute **attrs; -- struct device_attribute *attr; -- - config_item_put(item); -- --#ifdef CONFIG_USB_CONFIGFS_UEVENT -- attrs = android_usb_attributes; -- while ((attr = *attrs++)) -- device_remove_file(android_device, attr); -- device_destroy(android_device->class, android_device->devt); --#endif -+ android_device_destroy(); - } - - static struct configfs_group_operations gadgets_ops = { diff --git a/patches/ANDROID-usb-gadget-configfs-Add-function-devices-to-the-parent.patch b/patches/ANDROID-usb-gadget-configfs-Add-function-devices-to-the-parent.patch deleted file mode 100644 index 754cd32a1b26..000000000000 --- a/patches/ANDROID-usb-gadget-configfs-Add-function-devices-to-the-parent.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Badhri Jagan Sridharan -Date: Fri, 27 Mar 2015 14:15:19 -0700 -Subject: ANDROID: usb: gadget: configfs: Add function devices to the parent - -Added create_function_device to create child -function devices for USB gadget functions. -Android UsbDeviceManager relies on communicating -to the devices created by the gadget functions -to implement functions such as audio_source. - -Bug: 63740241 -Bug: 68755607 -Bug: 78114713 -Bug: 120441124 -Change-Id: I0df9ad86ac32d8cdacdea164e9fed49891b45fc2 -[badhri: This is a supporting patch for other patches which have - replacements pipelined. It can be dropped when those - implementations land.] -Signed-off-by: Badhri Jagan Sridharan ---- - drivers/usb/gadget/configfs.c | 33 +++++++++++++++++++++++++++++---- - 1 file changed, 29 insertions(+), 4 deletions(-) - -diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c -index bbc166f99893..3237f450d4ab 100644 ---- a/drivers/usb/gadget/configfs.c -+++ b/drivers/usb/gadget/configfs.c -@@ -21,6 +21,18 @@ extern int acc_ctrlrequest(struct usb_composite_dev *cdev, - void acc_disconnect(void); - #endif - static struct class *android_class; -+static struct device *android_device; -+static int index; -+ -+struct device *create_function_device(char *name) -+{ -+ if (android_device && !IS_ERR(android_device)) -+ return device_create(android_class, android_device, -+ MKDEV(0, index++), NULL, name); -+ else -+ return ERR_PTR(-EINVAL); -+} -+EXPORT_SYMBOL_GPL(create_function_device); - #endif - - int check_user_usb_string(const char *name, -@@ -1418,19 +1430,22 @@ static void android_work(struct work_struct *data) - spin_unlock_irqrestore(&cdev->lock, flags); - - if (status[0]) { -- kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, connected); -+ kobject_uevent_env(&android_device->kobj, -+ KOBJ_CHANGE, connected); - pr_info("%s: sent uevent %s\n", __func__, connected[0]); - uevent_sent = true; - } - - if (status[1]) { -- kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, configured); -+ kobject_uevent_env(&android_device->kobj, -+ KOBJ_CHANGE, configured); - pr_info("%s: sent uevent %s\n", __func__, configured[0]); - uevent_sent = true; - } - - if (status[2]) { -- kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, disconnected); -+ kobject_uevent_env(&android_device->kobj, -+ KOBJ_CHANGE, disconnected); - pr_info("%s: sent uevent %s\n", __func__, disconnected[0]); - uevent_sent = true; - } -@@ -1607,8 +1622,10 @@ static struct config_group *gadgets_make( - - #ifdef CONFIG_USB_CONFIGFS_UEVENT - INIT_WORK(&gi->work, android_work); -- gi->dev = device_create(android_class, NULL, -+ android_device = device_create(android_class, NULL, - MKDEV(0, 0), NULL, "android0"); -+ if (IS_ERR(android_device)) -+ goto err; - #endif - - if (!gi->composite.gadget_driver.function) -@@ -1623,6 +1640,9 @@ static struct config_group *gadgets_make( - static void gadgets_drop(struct config_group *group, struct config_item *item) - { - config_item_put(item); -+#ifdef CONFIG_USB_CONFIGFS_UEVENT -+ device_destroy(android_device->class, android_device->devt); -+#endif - } - - static struct configfs_group_operations gadgets_ops = { -@@ -1676,5 +1696,10 @@ module_init(gadget_cfs_init); - static void __exit gadget_cfs_exit(void) - { - configfs_unregister_subsystem(&gadget_subsys); -+#ifdef CONFIG_USB_CONFIGFS_UEVENT -+ if (!IS_ERR(android_class)) -+ class_destroy(android_class); -+#endif -+ - } - module_exit(gadget_cfs_exit); diff --git a/patches/ANDROID-usb-gadget-configfs-Add-state-attribute-to-android_device.patch b/patches/ANDROID-usb-gadget-configfs-Add-state-attribute-to-android_device.patch deleted file mode 100644 index b0829d2397f7..000000000000 --- a/patches/ANDROID-usb-gadget-configfs-Add-state-attribute-to-android_device.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Badhri Jagan Sridharan -Date: Tue, 14 Jul 2015 15:46:11 -0700 -Subject: ANDROID: usb: gadget: configfs: Add "state" attribute to - android_device - -Added a device attribute to android_device to -determine USB_GADGET's state - -Bug: 68755607 -Bug: 120441124 -Change-Id: I17f8903120df96bf2f4bf441940b53a87b818230 -[badhri: Migrate to using udc uevents from upstream sysfs.] -Signed-off-by: Badhri Jagan Sridharan ---- - drivers/usb/gadget/configfs.c | 66 ++++++++++++++++++++++++++++++++++- - 1 file changed, 65 insertions(+), 1 deletion(-) - -diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c -index 3237f450d4ab..da151de74e1d 100644 ---- a/drivers/usb/gadget/configfs.c -+++ b/drivers/usb/gadget/configfs.c -@@ -1572,11 +1572,49 @@ static const struct usb_gadget_driver configfs_driver_template = { - .match_existing_only = 1, - }; - -+#ifdef CONFIG_USB_CONFIGFS_UEVENT -+static ssize_t state_show(struct device *pdev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct gadget_info *dev = dev_get_drvdata(pdev); -+ struct usb_composite_dev *cdev; -+ char *state = "DISCONNECTED"; -+ unsigned long flags; -+ -+ if (!dev) -+ goto out; -+ -+ cdev = &dev->cdev; -+ -+ if (!cdev) -+ goto out; -+ -+ spin_lock_irqsave(&cdev->lock, flags); -+ if (cdev->config) -+ state = "CONFIGURED"; -+ else if (dev->connected) -+ state = "CONNECTED"; -+ spin_unlock_irqrestore(&cdev->lock, flags); -+out: -+ return sprintf(buf, "%s\n", state); -+} -+ -+static DEVICE_ATTR(state, S_IRUGO, state_show, NULL); -+ -+static struct device_attribute *android_usb_attributes[] = { -+ &dev_attr_state, -+ NULL -+}; -+#endif -+ - static struct config_group *gadgets_make( - struct config_group *group, - const char *name) - { - struct gadget_info *gi; -+ struct device_attribute **attrs; -+ struct device_attribute *attr; -+ int err; - - gi = kzalloc(sizeof(*gi), GFP_KERNEL); - if (!gi) -@@ -1626,12 +1664,31 @@ static struct config_group *gadgets_make( - MKDEV(0, 0), NULL, "android0"); - if (IS_ERR(android_device)) - goto err; -+ -+ dev_set_drvdata(android_device, gi); -+ -+ attrs = android_usb_attributes; -+ while ((attr = *attrs++)) { -+ err = device_create_file(android_device, attr); -+ if (err) -+ goto err1; -+ } - #endif - - if (!gi->composite.gadget_driver.function) -- goto err; -+ goto err1; - - return &gi->group; -+ -+err1: -+#ifdef CONFIG_USB_CONFIGFS_UEVENT -+ attrs = android_usb_attributes; -+ while ((attr = *attrs++)) -+ device_remove_file(android_device, attr); -+ -+ device_destroy(android_device->class, -+ android_device->devt); -+#endif - err: - kfree(gi); - return ERR_PTR(-ENOMEM); -@@ -1639,8 +1696,15 @@ static struct config_group *gadgets_make( - - static void gadgets_drop(struct config_group *group, struct config_item *item) - { -+ struct device_attribute **attrs; -+ struct device_attribute *attr; -+ - config_item_put(item); -+ - #ifdef CONFIG_USB_CONFIGFS_UEVENT -+ attrs = android_usb_attributes; -+ while ((attr = *attrs++)) -+ device_remove_file(android_device, attr); - device_destroy(android_device->class, android_device->devt); - #endif - } diff --git a/patches/ANDROID-usb-gadget-configfs-Add-usb_function-ptr-to-fi-struct.patch b/patches/ANDROID-usb-gadget-configfs-Add-usb_function-ptr-to-fi-struct.patch deleted file mode 100644 index 012f790e79ee..000000000000 --- a/patches/ANDROID-usb-gadget-configfs-Add-usb_function-ptr-to-fi-struct.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Badhri Jagan Sridharan -Date: Mon, 15 Dec 2014 16:42:27 -0800 -Subject: ANDROID: usb: gadget: configfs: Add usb_function ptr to fi struct - -Add a pointer to the usb_function inside the -usb_function_instance structure to service -functions specific setup requests even before -the function gets added to the usb_gadget - -Bug: 63740241 -Bug: 68755607 -Bug: 78114713 -Bug: 120441124 -Change-Id: I6f457006f6c5516cc6986ec2acdf5b1ecf259d0c -[badhri: This is a supporting patch for other patches which have - replacements pipelined. It can be dropped when those - implementations land.] -Signed-off-by: Badhri Jagan Sridharan ---- - include/linux/usb/composite.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h -index 8675e145ea8b..af4396cc4ea8 100644 ---- a/include/linux/usb/composite.h -+++ b/include/linux/usb/composite.h -@@ -587,6 +587,7 @@ struct usb_function_instance { - struct config_group group; - struct list_head cfs_list; - struct usb_function_driver *fd; -+ struct usb_function *f; - int (*set_inst_name)(struct usb_function_instance *inst, - const char *name); - void (*free_func_inst)(struct usb_function_instance *inst); diff --git a/patches/ANDROID-usb-gadget-f_accessory-Add-Android-Accessory-function.patch b/patches/ANDROID-usb-gadget-f_accessory-Add-Android-Accessory-function.patch deleted file mode 100644 index 525978f38670..000000000000 --- a/patches/ANDROID-usb-gadget-f_accessory-Add-Android-Accessory-function.patch +++ /dev/null @@ -1,1625 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benoit Goby -Date: Mon, 19 Dec 2011 14:39:37 -0800 -Subject: ANDROID: usb: gadget: f_accessory: Add Android Accessory function - -USB accessory mode allows users to connect USB host hardware -specifically designed for Android-powered devices. The accessories -must adhere to the Android accessory protocol outlined in the -http://accessories.android.com documentation. This allows -Android devices that cannot act as a USB host to still interact with -USB hardware. When an Android device is in USB accessory mode, the -attached Android USB accessory acts as the host, provides power -to the USB bus, and enumerates connected devices. - -Bug: 63740241 -Bug: 120441124 -Change-Id: I67964b50d278f3c0471d47efbb7b0973a3502681 -[badhri: f_accessory is being migrated to userspace.] -Signed-off-by: Mike Lockwood -[AmitP: Folded following android-4.9 commit changes into this patch - ceb2f0aac624 ("ANDROID: usb: gadget: accessory: Fix section mismatch") - Parts of e27543931009 ("ANDROID: usb: gadget: Fixes and hacks to make android usb gadget compile on 3.8") - 1b07ec751563 ("ANDROID: drivers: usb: gadget: 64-bit related type fixes")] -Signed-off-by: Amit Pundir -[astrachan: Folded the following changes into this patch: - 9d5891d516e2 ("ANDROID: usb: gadget: f_accessory: Add ACCESSORY_SET_AUDIO_MODE control request and ioctl") - dc66cfce9622 ("ANDROID: usb: gadget: f_accessory: Add support for HID input devices") - 5f1ac9c2871b ("ANDROID: usb: gadget: f_accessory: move userspace interface to uapi") - 9a6241722cd8 ("ANDROID: usb: gadget: f_accessory: Enabled Zero Length Packet (ZLP) for acc_write") - 31a0ecd5a825 ("ANDROID: usb: gadget: f_accessory: check for accessory device before disconnecting HIDs") - 580721fa6cbc ("ANDROID: usb: gadget: f_accessory: Migrate to USB_FUNCTION API") - 7f407172fb28 ("ANDROID: usb: gadget: f_accessory: Fix for UsbAccessory clean unbind.") - ebc98ac5a22f ("ANDROID: usb: gadget: f_accessory: fix false disconnect due to a signal sent to the reading process") - 71c6dc5ffdab ("ANDROID: usb: gadget: f_accessory: assign no-op request complete callbacks") - 675047ee68e9 ("ANDROID: usb: gadget: f_accessory: Move gadget functions code") - b2bedaa5c7df ("CHROMIUM: usb: gadget: f_accessory: add .raw_request callback")] -Signed-off-by: Alistair Strachan ---- - drivers/usb/gadget/Kconfig | 10 + - drivers/usb/gadget/function/Makefile | 2 + - drivers/usb/gadget/function/f_accessory.c | 1352 +++++++++++++++++++++ - include/linux/usb/f_accessory.h | 23 + - include/uapi/linux/usb/f_accessory.h | 146 +++ - 5 files changed, 1533 insertions(+) - create mode 100644 drivers/usb/gadget/function/f_accessory.c - create mode 100644 include/linux/usb/f_accessory.h - create mode 100644 include/uapi/linux/usb/f_accessory.h - -diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig -index f5e82dcac583..7749fb1decb0 100644 ---- a/drivers/usb/gadget/Kconfig -+++ b/drivers/usb/gadget/Kconfig -@@ -216,6 +216,9 @@ config USB_F_PRINTER - config USB_F_TCM - tristate - -+config USB_F_ACC -+ tristate -+ - # this first set of drivers all depend on bulk-capable hardware. - - config USB_CONFIGFS -@@ -377,6 +380,13 @@ config USB_CONFIGFS_F_FS - implemented in kernel space (for instance Ethernet, serial or - mass storage) and other are implemented in user space. - -+config USB_CONFIGFS_F_ACC -+ bool "Accessory gadget" -+ depends on USB_CONFIGFS -+ select USB_F_ACC -+ help -+ USB gadget Accessory support -+ - config USB_CONFIGFS_F_UAC1 - bool "Audio Class 1.0" - depends on USB_CONFIGFS -diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile -index 5d3a6cf02218..2305360e5f22 100644 ---- a/drivers/usb/gadget/function/Makefile -+++ b/drivers/usb/gadget/function/Makefile -@@ -50,3 +50,5 @@ usb_f_printer-y := f_printer.o - obj-$(CONFIG_USB_F_PRINTER) += usb_f_printer.o - usb_f_tcm-y := f_tcm.o - obj-$(CONFIG_USB_F_TCM) += usb_f_tcm.o -+usb_f_accessory-y := f_accessory.o -+obj-$(CONFIG_USB_F_ACC) += usb_f_accessory.o -diff --git a/drivers/usb/gadget/function/f_accessory.c b/drivers/usb/gadget/function/f_accessory.c -new file mode 100644 -index 000000000000..7aa2656a2328 ---- /dev/null -+++ b/drivers/usb/gadget/function/f_accessory.c -@@ -0,0 +1,1352 @@ -+/* -+ * Gadget Function Driver for Android USB accessories -+ * -+ * Copyright (C) 2011 Google, Inc. -+ * Author: Mike Lockwood -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+/* #define DEBUG */ -+/* #define VERBOSE_DEBUG */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define MAX_INST_NAME_LEN 40 -+#define BULK_BUFFER_SIZE 16384 -+#define ACC_STRING_SIZE 256 -+ -+#define PROTOCOL_VERSION 2 -+ -+/* String IDs */ -+#define INTERFACE_STRING_INDEX 0 -+ -+/* number of tx and rx requests to allocate */ -+#define TX_REQ_MAX 4 -+#define RX_REQ_MAX 2 -+ -+struct acc_hid_dev { -+ struct list_head list; -+ struct hid_device *hid; -+ struct acc_dev *dev; -+ /* accessory defined ID */ -+ int id; -+ /* HID report descriptor */ -+ u8 *report_desc; -+ /* length of HID report descriptor */ -+ int report_desc_len; -+ /* number of bytes of report_desc we have received so far */ -+ int report_desc_offset; -+}; -+ -+struct acc_dev { -+ struct usb_function function; -+ struct usb_composite_dev *cdev; -+ spinlock_t lock; -+ -+ struct usb_ep *ep_in; -+ struct usb_ep *ep_out; -+ -+ /* online indicates state of function_set_alt & function_unbind -+ * set to 1 when we connect -+ */ -+ int online:1; -+ -+ /* disconnected indicates state of open & release -+ * Set to 1 when we disconnect. -+ * Not cleared until our file is closed. -+ */ -+ int disconnected:1; -+ -+ /* strings sent by the host */ -+ char manufacturer[ACC_STRING_SIZE]; -+ char model[ACC_STRING_SIZE]; -+ char description[ACC_STRING_SIZE]; -+ char version[ACC_STRING_SIZE]; -+ char uri[ACC_STRING_SIZE]; -+ char serial[ACC_STRING_SIZE]; -+ -+ /* for acc_complete_set_string */ -+ int string_index; -+ -+ /* set to 1 if we have a pending start request */ -+ int start_requested; -+ -+ int audio_mode; -+ -+ /* synchronize access to our device file */ -+ atomic_t open_excl; -+ -+ struct list_head tx_idle; -+ -+ wait_queue_head_t read_wq; -+ wait_queue_head_t write_wq; -+ struct usb_request *rx_req[RX_REQ_MAX]; -+ int rx_done; -+ -+ /* delayed work for handling ACCESSORY_START */ -+ struct delayed_work start_work; -+ -+ /* worker for registering and unregistering hid devices */ -+ struct work_struct hid_work; -+ -+ /* list of active HID devices */ -+ struct list_head hid_list; -+ -+ /* list of new HID devices to register */ -+ struct list_head new_hid_list; -+ -+ /* list of dead HID devices to unregister */ -+ struct list_head dead_hid_list; -+}; -+ -+static struct usb_interface_descriptor acc_interface_desc = { -+ .bLength = USB_DT_INTERFACE_SIZE, -+ .bDescriptorType = USB_DT_INTERFACE, -+ .bInterfaceNumber = 0, -+ .bNumEndpoints = 2, -+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC, -+ .bInterfaceSubClass = USB_SUBCLASS_VENDOR_SPEC, -+ .bInterfaceProtocol = 0, -+}; -+ -+static struct usb_endpoint_descriptor acc_highspeed_in_desc = { -+ .bLength = USB_DT_ENDPOINT_SIZE, -+ .bDescriptorType = USB_DT_ENDPOINT, -+ .bEndpointAddress = USB_DIR_IN, -+ .bmAttributes = USB_ENDPOINT_XFER_BULK, -+ .wMaxPacketSize = __constant_cpu_to_le16(512), -+}; -+ -+static struct usb_endpoint_descriptor acc_highspeed_out_desc = { -+ .bLength = USB_DT_ENDPOINT_SIZE, -+ .bDescriptorType = USB_DT_ENDPOINT, -+ .bEndpointAddress = USB_DIR_OUT, -+ .bmAttributes = USB_ENDPOINT_XFER_BULK, -+ .wMaxPacketSize = __constant_cpu_to_le16(512), -+}; -+ -+static struct usb_endpoint_descriptor acc_fullspeed_in_desc = { -+ .bLength = USB_DT_ENDPOINT_SIZE, -+ .bDescriptorType = USB_DT_ENDPOINT, -+ .bEndpointAddress = USB_DIR_IN, -+ .bmAttributes = USB_ENDPOINT_XFER_BULK, -+}; -+ -+static struct usb_endpoint_descriptor acc_fullspeed_out_desc = { -+ .bLength = USB_DT_ENDPOINT_SIZE, -+ .bDescriptorType = USB_DT_ENDPOINT, -+ .bEndpointAddress = USB_DIR_OUT, -+ .bmAttributes = USB_ENDPOINT_XFER_BULK, -+}; -+ -+static struct usb_descriptor_header *fs_acc_descs[] = { -+ (struct usb_descriptor_header *) &acc_interface_desc, -+ (struct usb_descriptor_header *) &acc_fullspeed_in_desc, -+ (struct usb_descriptor_header *) &acc_fullspeed_out_desc, -+ NULL, -+}; -+ -+static struct usb_descriptor_header *hs_acc_descs[] = { -+ (struct usb_descriptor_header *) &acc_interface_desc, -+ (struct usb_descriptor_header *) &acc_highspeed_in_desc, -+ (struct usb_descriptor_header *) &acc_highspeed_out_desc, -+ NULL, -+}; -+ -+static struct usb_string acc_string_defs[] = { -+ [INTERFACE_STRING_INDEX].s = "Android Accessory Interface", -+ { }, /* end of list */ -+}; -+ -+static struct usb_gadget_strings acc_string_table = { -+ .language = 0x0409, /* en-US */ -+ .strings = acc_string_defs, -+}; -+ -+static struct usb_gadget_strings *acc_strings[] = { -+ &acc_string_table, -+ NULL, -+}; -+ -+/* temporary variable used between acc_open() and acc_gadget_bind() */ -+static struct acc_dev *_acc_dev; -+ -+struct acc_instance { -+ struct usb_function_instance func_inst; -+ const char *name; -+}; -+ -+static inline struct acc_dev *func_to_dev(struct usb_function *f) -+{ -+ return container_of(f, struct acc_dev, function); -+} -+ -+static struct usb_request *acc_request_new(struct usb_ep *ep, int buffer_size) -+{ -+ struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); -+ -+ if (!req) -+ return NULL; -+ -+ /* now allocate buffers for the requests */ -+ req->buf = kmalloc(buffer_size, GFP_KERNEL); -+ if (!req->buf) { -+ usb_ep_free_request(ep, req); -+ return NULL; -+ } -+ -+ return req; -+} -+ -+static void acc_request_free(struct usb_request *req, struct usb_ep *ep) -+{ -+ if (req) { -+ kfree(req->buf); -+ usb_ep_free_request(ep, req); -+ } -+} -+ -+/* add a request to the tail of a list */ -+static void req_put(struct acc_dev *dev, struct list_head *head, -+ struct usb_request *req) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ list_add_tail(&req->list, head); -+ spin_unlock_irqrestore(&dev->lock, flags); -+} -+ -+/* remove a request from the head of a list */ -+static struct usb_request *req_get(struct acc_dev *dev, struct list_head *head) -+{ -+ unsigned long flags; -+ struct usb_request *req; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ if (list_empty(head)) { -+ req = 0; -+ } else { -+ req = list_first_entry(head, struct usb_request, list); -+ list_del(&req->list); -+ } -+ spin_unlock_irqrestore(&dev->lock, flags); -+ return req; -+} -+ -+static void acc_set_disconnected(struct acc_dev *dev) -+{ -+ dev->disconnected = 1; -+} -+ -+static void acc_complete_in(struct usb_ep *ep, struct usb_request *req) -+{ -+ struct acc_dev *dev = _acc_dev; -+ -+ if (req->status == -ESHUTDOWN) { -+ pr_debug("acc_complete_in set disconnected"); -+ acc_set_disconnected(dev); -+ } -+ -+ req_put(dev, &dev->tx_idle, req); -+ -+ wake_up(&dev->write_wq); -+} -+ -+static void acc_complete_out(struct usb_ep *ep, struct usb_request *req) -+{ -+ struct acc_dev *dev = _acc_dev; -+ -+ dev->rx_done = 1; -+ if (req->status == -ESHUTDOWN) { -+ pr_debug("acc_complete_out set disconnected"); -+ acc_set_disconnected(dev); -+ } -+ -+ wake_up(&dev->read_wq); -+} -+ -+static void acc_complete_set_string(struct usb_ep *ep, struct usb_request *req) -+{ -+ struct acc_dev *dev = ep->driver_data; -+ char *string_dest = NULL; -+ int length = req->actual; -+ -+ if (req->status != 0) { -+ pr_err("acc_complete_set_string, err %d\n", req->status); -+ return; -+ } -+ -+ switch (dev->string_index) { -+ case ACCESSORY_STRING_MANUFACTURER: -+ string_dest = dev->manufacturer; -+ break; -+ case ACCESSORY_STRING_MODEL: -+ string_dest = dev->model; -+ break; -+ case ACCESSORY_STRING_DESCRIPTION: -+ string_dest = dev->description; -+ break; -+ case ACCESSORY_STRING_VERSION: -+ string_dest = dev->version; -+ break; -+ case ACCESSORY_STRING_URI: -+ string_dest = dev->uri; -+ break; -+ case ACCESSORY_STRING_SERIAL: -+ string_dest = dev->serial; -+ break; -+ } -+ if (string_dest) { -+ unsigned long flags; -+ -+ if (length >= ACC_STRING_SIZE) -+ length = ACC_STRING_SIZE - 1; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ memcpy(string_dest, req->buf, length); -+ /* ensure zero termination */ -+ string_dest[length] = 0; -+ spin_unlock_irqrestore(&dev->lock, flags); -+ } else { -+ pr_err("unknown accessory string index %d\n", -+ dev->string_index); -+ } -+} -+ -+static void acc_complete_set_hid_report_desc(struct usb_ep *ep, -+ struct usb_request *req) -+{ -+ struct acc_hid_dev *hid = req->context; -+ struct acc_dev *dev = hid->dev; -+ int length = req->actual; -+ -+ if (req->status != 0) { -+ pr_err("acc_complete_set_hid_report_desc, err %d\n", -+ req->status); -+ return; -+ } -+ -+ memcpy(hid->report_desc + hid->report_desc_offset, req->buf, length); -+ hid->report_desc_offset += length; -+ if (hid->report_desc_offset == hid->report_desc_len) { -+ /* After we have received the entire report descriptor -+ * we schedule work to initialize the HID device -+ */ -+ schedule_work(&dev->hid_work); -+ } -+} -+ -+static void acc_complete_send_hid_event(struct usb_ep *ep, -+ struct usb_request *req) -+{ -+ struct acc_hid_dev *hid = req->context; -+ int length = req->actual; -+ -+ if (req->status != 0) { -+ pr_err("acc_complete_send_hid_event, err %d\n", req->status); -+ return; -+ } -+ -+ hid_report_raw_event(hid->hid, HID_INPUT_REPORT, req->buf, length, 1); -+} -+ -+static int acc_hid_parse(struct hid_device *hid) -+{ -+ struct acc_hid_dev *hdev = hid->driver_data; -+ -+ hid_parse_report(hid, hdev->report_desc, hdev->report_desc_len); -+ return 0; -+} -+ -+static int acc_hid_start(struct hid_device *hid) -+{ -+ return 0; -+} -+ -+static void acc_hid_stop(struct hid_device *hid) -+{ -+} -+ -+static int acc_hid_open(struct hid_device *hid) -+{ -+ return 0; -+} -+ -+static void acc_hid_close(struct hid_device *hid) -+{ -+} -+ -+static int acc_hid_raw_request(struct hid_device *hid, unsigned char reportnum, -+ __u8 *buf, size_t len, unsigned char rtype, int reqtype) -+{ -+ return 0; -+} -+ -+static struct hid_ll_driver acc_hid_ll_driver = { -+ .parse = acc_hid_parse, -+ .start = acc_hid_start, -+ .stop = acc_hid_stop, -+ .open = acc_hid_open, -+ .close = acc_hid_close, -+ .raw_request = acc_hid_raw_request, -+}; -+ -+static struct acc_hid_dev *acc_hid_new(struct acc_dev *dev, -+ int id, int desc_len) -+{ -+ struct acc_hid_dev *hdev; -+ -+ hdev = kzalloc(sizeof(*hdev), GFP_ATOMIC); -+ if (!hdev) -+ return NULL; -+ hdev->report_desc = kzalloc(desc_len, GFP_ATOMIC); -+ if (!hdev->report_desc) { -+ kfree(hdev); -+ return NULL; -+ } -+ hdev->dev = dev; -+ hdev->id = id; -+ hdev->report_desc_len = desc_len; -+ -+ return hdev; -+} -+ -+static struct acc_hid_dev *acc_hid_get(struct list_head *list, int id) -+{ -+ struct acc_hid_dev *hid; -+ -+ list_for_each_entry(hid, list, list) { -+ if (hid->id == id) -+ return hid; -+ } -+ return NULL; -+} -+ -+static int acc_register_hid(struct acc_dev *dev, int id, int desc_length) -+{ -+ struct acc_hid_dev *hid; -+ unsigned long flags; -+ -+ /* report descriptor length must be > 0 */ -+ if (desc_length <= 0) -+ return -EINVAL; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ /* replace HID if one already exists with this ID */ -+ hid = acc_hid_get(&dev->hid_list, id); -+ if (!hid) -+ hid = acc_hid_get(&dev->new_hid_list, id); -+ if (hid) -+ list_move(&hid->list, &dev->dead_hid_list); -+ -+ hid = acc_hid_new(dev, id, desc_length); -+ if (!hid) { -+ spin_unlock_irqrestore(&dev->lock, flags); -+ return -ENOMEM; -+ } -+ -+ list_add(&hid->list, &dev->new_hid_list); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ /* schedule work to register the HID device */ -+ schedule_work(&dev->hid_work); -+ return 0; -+} -+ -+static int acc_unregister_hid(struct acc_dev *dev, int id) -+{ -+ struct acc_hid_dev *hid; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ hid = acc_hid_get(&dev->hid_list, id); -+ if (!hid) -+ hid = acc_hid_get(&dev->new_hid_list, id); -+ if (!hid) { -+ spin_unlock_irqrestore(&dev->lock, flags); -+ return -EINVAL; -+ } -+ -+ list_move(&hid->list, &dev->dead_hid_list); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ schedule_work(&dev->hid_work); -+ return 0; -+} -+ -+static int create_bulk_endpoints(struct acc_dev *dev, -+ struct usb_endpoint_descriptor *in_desc, -+ struct usb_endpoint_descriptor *out_desc) -+{ -+ struct usb_composite_dev *cdev = dev->cdev; -+ struct usb_request *req; -+ struct usb_ep *ep; -+ int i; -+ -+ DBG(cdev, "create_bulk_endpoints dev: %p\n", dev); -+ -+ ep = usb_ep_autoconfig(cdev->gadget, in_desc); -+ if (!ep) { -+ DBG(cdev, "usb_ep_autoconfig for ep_in failed\n"); -+ return -ENODEV; -+ } -+ DBG(cdev, "usb_ep_autoconfig for ep_in got %s\n", ep->name); -+ ep->driver_data = dev; /* claim the endpoint */ -+ dev->ep_in = ep; -+ -+ ep = usb_ep_autoconfig(cdev->gadget, out_desc); -+ if (!ep) { -+ DBG(cdev, "usb_ep_autoconfig for ep_out failed\n"); -+ return -ENODEV; -+ } -+ DBG(cdev, "usb_ep_autoconfig for ep_out got %s\n", ep->name); -+ ep->driver_data = dev; /* claim the endpoint */ -+ dev->ep_out = ep; -+ -+ /* now allocate requests for our endpoints */ -+ for (i = 0; i < TX_REQ_MAX; i++) { -+ req = acc_request_new(dev->ep_in, BULK_BUFFER_SIZE); -+ if (!req) -+ goto fail; -+ req->complete = acc_complete_in; -+ req_put(dev, &dev->tx_idle, req); -+ } -+ for (i = 0; i < RX_REQ_MAX; i++) { -+ req = acc_request_new(dev->ep_out, BULK_BUFFER_SIZE); -+ if (!req) -+ goto fail; -+ req->complete = acc_complete_out; -+ dev->rx_req[i] = req; -+ } -+ -+ return 0; -+ -+fail: -+ pr_err("acc_bind() could not allocate requests\n"); -+ while ((req = req_get(dev, &dev->tx_idle))) -+ acc_request_free(req, dev->ep_in); -+ for (i = 0; i < RX_REQ_MAX; i++) -+ acc_request_free(dev->rx_req[i], dev->ep_out); -+ return -1; -+} -+ -+static ssize_t acc_read(struct file *fp, char __user *buf, -+ size_t count, loff_t *pos) -+{ -+ struct acc_dev *dev = fp->private_data; -+ struct usb_request *req; -+ ssize_t r = count; -+ unsigned xfer; -+ int ret = 0; -+ -+ pr_debug("acc_read(%zu)\n", count); -+ -+ if (dev->disconnected) { -+ pr_debug("acc_read disconnected"); -+ return -ENODEV; -+ } -+ -+ if (count > BULK_BUFFER_SIZE) -+ count = BULK_BUFFER_SIZE; -+ -+ /* we will block until we're online */ -+ pr_debug("acc_read: waiting for online\n"); -+ ret = wait_event_interruptible(dev->read_wq, dev->online); -+ if (ret < 0) { -+ r = ret; -+ goto done; -+ } -+ -+ if (dev->rx_done) { -+ // last req cancelled. try to get it. -+ req = dev->rx_req[0]; -+ goto copy_data; -+ } -+ -+requeue_req: -+ /* queue a request */ -+ req = dev->rx_req[0]; -+ req->length = count; -+ dev->rx_done = 0; -+ ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL); -+ if (ret < 0) { -+ r = -EIO; -+ goto done; -+ } else { -+ pr_debug("rx %p queue\n", req); -+ } -+ -+ /* wait for a request to complete */ -+ ret = wait_event_interruptible(dev->read_wq, dev->rx_done); -+ if (ret < 0) { -+ r = ret; -+ ret = usb_ep_dequeue(dev->ep_out, req); -+ if (ret != 0) { -+ // cancel failed. There can be a data already received. -+ // it will be retrieved in the next read. -+ pr_debug("acc_read: cancelling failed %d", ret); -+ } -+ goto done; -+ } -+ -+copy_data: -+ dev->rx_done = 0; -+ if (dev->online) { -+ /* If we got a 0-len packet, throw it back and try again. */ -+ if (req->actual == 0) -+ goto requeue_req; -+ -+ pr_debug("rx %p %u\n", req, req->actual); -+ xfer = (req->actual < count) ? req->actual : count; -+ r = xfer; -+ if (copy_to_user(buf, req->buf, xfer)) -+ r = -EFAULT; -+ } else -+ r = -EIO; -+ -+done: -+ pr_debug("acc_read returning %zd\n", r); -+ return r; -+} -+ -+static ssize_t acc_write(struct file *fp, const char __user *buf, -+ size_t count, loff_t *pos) -+{ -+ struct acc_dev *dev = fp->private_data; -+ struct usb_request *req = 0; -+ ssize_t r = count; -+ unsigned xfer; -+ int ret; -+ -+ pr_debug("acc_write(%zu)\n", count); -+ -+ if (!dev->online || dev->disconnected) { -+ pr_debug("acc_write disconnected or not online"); -+ return -ENODEV; -+ } -+ -+ while (count > 0) { -+ if (!dev->online) { -+ pr_debug("acc_write dev->error\n"); -+ r = -EIO; -+ break; -+ } -+ -+ /* get an idle tx request to use */ -+ req = 0; -+ ret = wait_event_interruptible(dev->write_wq, -+ ((req = req_get(dev, &dev->tx_idle)) || !dev->online)); -+ if (!req) { -+ r = ret; -+ break; -+ } -+ -+ if (count > BULK_BUFFER_SIZE) { -+ xfer = BULK_BUFFER_SIZE; -+ /* ZLP, They will be more TX requests so not yet. */ -+ req->zero = 0; -+ } else { -+ xfer = count; -+ /* If the data length is a multple of the -+ * maxpacket size then send a zero length packet(ZLP). -+ */ -+ req->zero = ((xfer % dev->ep_in->maxpacket) == 0); -+ } -+ if (copy_from_user(req->buf, buf, xfer)) { -+ r = -EFAULT; -+ break; -+ } -+ -+ req->length = xfer; -+ ret = usb_ep_queue(dev->ep_in, req, GFP_KERNEL); -+ if (ret < 0) { -+ pr_debug("acc_write: xfer error %d\n", ret); -+ r = -EIO; -+ break; -+ } -+ -+ buf += xfer; -+ count -= xfer; -+ -+ /* zero this so we don't try to free it on error exit */ -+ req = 0; -+ } -+ -+ if (req) -+ req_put(dev, &dev->tx_idle, req); -+ -+ pr_debug("acc_write returning %zd\n", r); -+ return r; -+} -+ -+static long acc_ioctl(struct file *fp, unsigned code, unsigned long value) -+{ -+ struct acc_dev *dev = fp->private_data; -+ char *src = NULL; -+ int ret; -+ -+ switch (code) { -+ case ACCESSORY_GET_STRING_MANUFACTURER: -+ src = dev->manufacturer; -+ break; -+ case ACCESSORY_GET_STRING_MODEL: -+ src = dev->model; -+ break; -+ case ACCESSORY_GET_STRING_DESCRIPTION: -+ src = dev->description; -+ break; -+ case ACCESSORY_GET_STRING_VERSION: -+ src = dev->version; -+ break; -+ case ACCESSORY_GET_STRING_URI: -+ src = dev->uri; -+ break; -+ case ACCESSORY_GET_STRING_SERIAL: -+ src = dev->serial; -+ break; -+ case ACCESSORY_IS_START_REQUESTED: -+ return dev->start_requested; -+ case ACCESSORY_GET_AUDIO_MODE: -+ return dev->audio_mode; -+ } -+ if (!src) -+ return -EINVAL; -+ -+ ret = strlen(src) + 1; -+ if (copy_to_user((void __user *)value, src, ret)) -+ ret = -EFAULT; -+ return ret; -+} -+ -+static int acc_open(struct inode *ip, struct file *fp) -+{ -+ printk(KERN_INFO "acc_open\n"); -+ if (atomic_xchg(&_acc_dev->open_excl, 1)) -+ return -EBUSY; -+ -+ _acc_dev->disconnected = 0; -+ fp->private_data = _acc_dev; -+ return 0; -+} -+ -+static int acc_release(struct inode *ip, struct file *fp) -+{ -+ printk(KERN_INFO "acc_release\n"); -+ -+ WARN_ON(!atomic_xchg(&_acc_dev->open_excl, 0)); -+ /* indicate that we are disconnected -+ * still could be online so don't touch online flag -+ */ -+ _acc_dev->disconnected = 1; -+ return 0; -+} -+ -+/* file operations for /dev/usb_accessory */ -+static const struct file_operations acc_fops = { -+ .owner = THIS_MODULE, -+ .read = acc_read, -+ .write = acc_write, -+ .unlocked_ioctl = acc_ioctl, -+ .open = acc_open, -+ .release = acc_release, -+}; -+ -+static int acc_hid_probe(struct hid_device *hdev, -+ const struct hid_device_id *id) -+{ -+ int ret; -+ -+ ret = hid_parse(hdev); -+ if (ret) -+ return ret; -+ return hid_hw_start(hdev, HID_CONNECT_DEFAULT); -+} -+ -+static struct miscdevice acc_device = { -+ .minor = MISC_DYNAMIC_MINOR, -+ .name = "usb_accessory", -+ .fops = &acc_fops, -+}; -+ -+static const struct hid_device_id acc_hid_table[] = { -+ { HID_USB_DEVICE(HID_ANY_ID, HID_ANY_ID) }, -+ { } -+}; -+ -+static struct hid_driver acc_hid_driver = { -+ .name = "USB accessory", -+ .id_table = acc_hid_table, -+ .probe = acc_hid_probe, -+}; -+ -+static void acc_complete_setup_noop(struct usb_ep *ep, struct usb_request *req) -+{ -+ /* -+ * Default no-op function when nothing needs to be done for the -+ * setup request -+ */ -+} -+ -+int acc_ctrlrequest(struct usb_composite_dev *cdev, -+ const struct usb_ctrlrequest *ctrl) -+{ -+ struct acc_dev *dev = _acc_dev; -+ int value = -EOPNOTSUPP; -+ struct acc_hid_dev *hid; -+ int offset; -+ u8 b_requestType = ctrl->bRequestType; -+ u8 b_request = ctrl->bRequest; -+ u16 w_index = le16_to_cpu(ctrl->wIndex); -+ u16 w_value = le16_to_cpu(ctrl->wValue); -+ u16 w_length = le16_to_cpu(ctrl->wLength); -+ unsigned long flags; -+ -+/* -+ printk(KERN_INFO "acc_ctrlrequest " -+ "%02x.%02x v%04x i%04x l%u\n", -+ b_requestType, b_request, -+ w_value, w_index, w_length); -+*/ -+ -+ if (b_requestType == (USB_DIR_OUT | USB_TYPE_VENDOR)) { -+ if (b_request == ACCESSORY_START) { -+ dev->start_requested = 1; -+ schedule_delayed_work( -+ &dev->start_work, msecs_to_jiffies(10)); -+ value = 0; -+ cdev->req->complete = acc_complete_setup_noop; -+ } else if (b_request == ACCESSORY_SEND_STRING) { -+ dev->string_index = w_index; -+ cdev->gadget->ep0->driver_data = dev; -+ cdev->req->complete = acc_complete_set_string; -+ value = w_length; -+ } else if (b_request == ACCESSORY_SET_AUDIO_MODE && -+ w_index == 0 && w_length == 0) { -+ dev->audio_mode = w_value; -+ cdev->req->complete = acc_complete_setup_noop; -+ value = 0; -+ } else if (b_request == ACCESSORY_REGISTER_HID) { -+ cdev->req->complete = acc_complete_setup_noop; -+ value = acc_register_hid(dev, w_value, w_index); -+ } else if (b_request == ACCESSORY_UNREGISTER_HID) { -+ cdev->req->complete = acc_complete_setup_noop; -+ value = acc_unregister_hid(dev, w_value); -+ } else if (b_request == ACCESSORY_SET_HID_REPORT_DESC) { -+ spin_lock_irqsave(&dev->lock, flags); -+ hid = acc_hid_get(&dev->new_hid_list, w_value); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ if (!hid) { -+ value = -EINVAL; -+ goto err; -+ } -+ offset = w_index; -+ if (offset != hid->report_desc_offset -+ || offset + w_length > hid->report_desc_len) { -+ value = -EINVAL; -+ goto err; -+ } -+ cdev->req->context = hid; -+ cdev->req->complete = acc_complete_set_hid_report_desc; -+ value = w_length; -+ } else if (b_request == ACCESSORY_SEND_HID_EVENT) { -+ spin_lock_irqsave(&dev->lock, flags); -+ hid = acc_hid_get(&dev->hid_list, w_value); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ if (!hid) { -+ value = -EINVAL; -+ goto err; -+ } -+ cdev->req->context = hid; -+ cdev->req->complete = acc_complete_send_hid_event; -+ value = w_length; -+ } -+ } else if (b_requestType == (USB_DIR_IN | USB_TYPE_VENDOR)) { -+ if (b_request == ACCESSORY_GET_PROTOCOL) { -+ *((u16 *)cdev->req->buf) = PROTOCOL_VERSION; -+ value = sizeof(u16); -+ cdev->req->complete = acc_complete_setup_noop; -+ /* clear any string left over from a previous session */ -+ memset(dev->manufacturer, 0, sizeof(dev->manufacturer)); -+ memset(dev->model, 0, sizeof(dev->model)); -+ memset(dev->description, 0, sizeof(dev->description)); -+ memset(dev->version, 0, sizeof(dev->version)); -+ memset(dev->uri, 0, sizeof(dev->uri)); -+ memset(dev->serial, 0, sizeof(dev->serial)); -+ dev->start_requested = 0; -+ dev->audio_mode = 0; -+ } -+ } -+ -+ if (value >= 0) { -+ cdev->req->zero = 0; -+ cdev->req->length = value; -+ value = usb_ep_queue(cdev->gadget->ep0, cdev->req, GFP_ATOMIC); -+ if (value < 0) -+ ERROR(cdev, "%s setup response queue error\n", -+ __func__); -+ } -+ -+err: -+ if (value == -EOPNOTSUPP) -+ VDBG(cdev, -+ "unknown class-specific control req " -+ "%02x.%02x v%04x i%04x l%u\n", -+ ctrl->bRequestType, ctrl->bRequest, -+ w_value, w_index, w_length); -+ return value; -+} -+EXPORT_SYMBOL_GPL(acc_ctrlrequest); -+ -+static int -+__acc_function_bind(struct usb_configuration *c, -+ struct usb_function *f, bool configfs) -+{ -+ struct usb_composite_dev *cdev = c->cdev; -+ struct acc_dev *dev = func_to_dev(f); -+ int id; -+ int ret; -+ -+ DBG(cdev, "acc_function_bind dev: %p\n", dev); -+ -+ if (configfs) { -+ if (acc_string_defs[INTERFACE_STRING_INDEX].id == 0) { -+ ret = usb_string_id(c->cdev); -+ if (ret < 0) -+ return ret; -+ acc_string_defs[INTERFACE_STRING_INDEX].id = ret; -+ acc_interface_desc.iInterface = ret; -+ } -+ dev->cdev = c->cdev; -+ } -+ ret = hid_register_driver(&acc_hid_driver); -+ if (ret) -+ return ret; -+ -+ dev->start_requested = 0; -+ -+ /* allocate interface ID(s) */ -+ id = usb_interface_id(c, f); -+ if (id < 0) -+ return id; -+ acc_interface_desc.bInterfaceNumber = id; -+ -+ /* allocate endpoints */ -+ ret = create_bulk_endpoints(dev, &acc_fullspeed_in_desc, -+ &acc_fullspeed_out_desc); -+ if (ret) -+ return ret; -+ -+ /* support high speed hardware */ -+ if (gadget_is_dualspeed(c->cdev->gadget)) { -+ acc_highspeed_in_desc.bEndpointAddress = -+ acc_fullspeed_in_desc.bEndpointAddress; -+ acc_highspeed_out_desc.bEndpointAddress = -+ acc_fullspeed_out_desc.bEndpointAddress; -+ } -+ -+ DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", -+ gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", -+ f->name, dev->ep_in->name, dev->ep_out->name); -+ return 0; -+} -+ -+static int -+acc_function_bind_configfs(struct usb_configuration *c, -+ struct usb_function *f) { -+ return __acc_function_bind(c, f, true); -+} -+ -+static void -+kill_all_hid_devices(struct acc_dev *dev) -+{ -+ struct acc_hid_dev *hid; -+ struct list_head *entry, *temp; -+ unsigned long flags; -+ -+ /* do nothing if usb accessory device doesn't exist */ -+ if (!dev) -+ return; -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ list_for_each_safe(entry, temp, &dev->hid_list) { -+ hid = list_entry(entry, struct acc_hid_dev, list); -+ list_del(&hid->list); -+ list_add(&hid->list, &dev->dead_hid_list); -+ } -+ list_for_each_safe(entry, temp, &dev->new_hid_list) { -+ hid = list_entry(entry, struct acc_hid_dev, list); -+ list_del(&hid->list); -+ list_add(&hid->list, &dev->dead_hid_list); -+ } -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ schedule_work(&dev->hid_work); -+} -+ -+static void -+acc_hid_unbind(struct acc_dev *dev) -+{ -+ hid_unregister_driver(&acc_hid_driver); -+ kill_all_hid_devices(dev); -+} -+ -+static void -+acc_function_unbind(struct usb_configuration *c, struct usb_function *f) -+{ -+ struct acc_dev *dev = func_to_dev(f); -+ struct usb_request *req; -+ int i; -+ -+ dev->online = 0; /* clear online flag */ -+ wake_up(&dev->read_wq); /* unblock reads on closure */ -+ wake_up(&dev->write_wq); /* likewise for writes */ -+ -+ while ((req = req_get(dev, &dev->tx_idle))) -+ acc_request_free(req, dev->ep_in); -+ for (i = 0; i < RX_REQ_MAX; i++) -+ acc_request_free(dev->rx_req[i], dev->ep_out); -+ -+ acc_hid_unbind(dev); -+} -+ -+static void acc_start_work(struct work_struct *data) -+{ -+ char *envp[2] = { "ACCESSORY=START", NULL }; -+ -+ kobject_uevent_env(&acc_device.this_device->kobj, KOBJ_CHANGE, envp); -+} -+ -+static int acc_hid_init(struct acc_hid_dev *hdev) -+{ -+ struct hid_device *hid; -+ int ret; -+ -+ hid = hid_allocate_device(); -+ if (IS_ERR(hid)) -+ return PTR_ERR(hid); -+ -+ hid->ll_driver = &acc_hid_ll_driver; -+ hid->dev.parent = acc_device.this_device; -+ -+ hid->bus = BUS_USB; -+ hid->vendor = HID_ANY_ID; -+ hid->product = HID_ANY_ID; -+ hid->driver_data = hdev; -+ ret = hid_add_device(hid); -+ if (ret) { -+ pr_err("can't add hid device: %d\n", ret); -+ hid_destroy_device(hid); -+ return ret; -+ } -+ -+ hdev->hid = hid; -+ return 0; -+} -+ -+static void acc_hid_delete(struct acc_hid_dev *hid) -+{ -+ kfree(hid->report_desc); -+ kfree(hid); -+} -+ -+static void acc_hid_work(struct work_struct *data) -+{ -+ struct acc_dev *dev = _acc_dev; -+ struct list_head *entry, *temp; -+ struct acc_hid_dev *hid; -+ struct list_head new_list, dead_list; -+ unsigned long flags; -+ -+ INIT_LIST_HEAD(&new_list); -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ /* copy hids that are ready for initialization to new_list */ -+ list_for_each_safe(entry, temp, &dev->new_hid_list) { -+ hid = list_entry(entry, struct acc_hid_dev, list); -+ if (hid->report_desc_offset == hid->report_desc_len) -+ list_move(&hid->list, &new_list); -+ } -+ -+ if (list_empty(&dev->dead_hid_list)) { -+ INIT_LIST_HEAD(&dead_list); -+ } else { -+ /* move all of dev->dead_hid_list to dead_list */ -+ dead_list.prev = dev->dead_hid_list.prev; -+ dead_list.next = dev->dead_hid_list.next; -+ dead_list.next->prev = &dead_list; -+ dead_list.prev->next = &dead_list; -+ INIT_LIST_HEAD(&dev->dead_hid_list); -+ } -+ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ /* register new HID devices */ -+ list_for_each_safe(entry, temp, &new_list) { -+ hid = list_entry(entry, struct acc_hid_dev, list); -+ if (acc_hid_init(hid)) { -+ pr_err("can't add HID device %p\n", hid); -+ acc_hid_delete(hid); -+ } else { -+ spin_lock_irqsave(&dev->lock, flags); -+ list_move(&hid->list, &dev->hid_list); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ } -+ } -+ -+ /* remove dead HID devices */ -+ list_for_each_safe(entry, temp, &dead_list) { -+ hid = list_entry(entry, struct acc_hid_dev, list); -+ list_del(&hid->list); -+ if (hid->hid) -+ hid_destroy_device(hid->hid); -+ acc_hid_delete(hid); -+ } -+} -+ -+static int acc_function_set_alt(struct usb_function *f, -+ unsigned intf, unsigned alt) -+{ -+ struct acc_dev *dev = func_to_dev(f); -+ struct usb_composite_dev *cdev = f->config->cdev; -+ int ret; -+ -+ DBG(cdev, "acc_function_set_alt intf: %d alt: %d\n", intf, alt); -+ -+ ret = config_ep_by_speed(cdev->gadget, f, dev->ep_in); -+ if (ret) -+ return ret; -+ -+ ret = usb_ep_enable(dev->ep_in); -+ if (ret) -+ return ret; -+ -+ ret = config_ep_by_speed(cdev->gadget, f, dev->ep_out); -+ if (ret) -+ return ret; -+ -+ ret = usb_ep_enable(dev->ep_out); -+ if (ret) { -+ usb_ep_disable(dev->ep_in); -+ return ret; -+ } -+ -+ dev->online = 1; -+ dev->disconnected = 0; /* if online then not disconnected */ -+ -+ /* readers may be blocked waiting for us to go online */ -+ wake_up(&dev->read_wq); -+ return 0; -+} -+ -+static void acc_function_disable(struct usb_function *f) -+{ -+ struct acc_dev *dev = func_to_dev(f); -+ struct usb_composite_dev *cdev = dev->cdev; -+ -+ DBG(cdev, "acc_function_disable\n"); -+ acc_set_disconnected(dev); /* this now only sets disconnected */ -+ dev->online = 0; /* so now need to clear online flag here too */ -+ usb_ep_disable(dev->ep_in); -+ usb_ep_disable(dev->ep_out); -+ -+ /* readers may be blocked waiting for us to go online */ -+ wake_up(&dev->read_wq); -+ -+ VDBG(cdev, "%s disabled\n", dev->function.name); -+} -+ -+static int acc_setup(void) -+{ -+ struct acc_dev *dev; -+ int ret; -+ -+ dev = kzalloc(sizeof(*dev), GFP_KERNEL); -+ if (!dev) -+ return -ENOMEM; -+ -+ spin_lock_init(&dev->lock); -+ init_waitqueue_head(&dev->read_wq); -+ init_waitqueue_head(&dev->write_wq); -+ atomic_set(&dev->open_excl, 0); -+ INIT_LIST_HEAD(&dev->tx_idle); -+ INIT_LIST_HEAD(&dev->hid_list); -+ INIT_LIST_HEAD(&dev->new_hid_list); -+ INIT_LIST_HEAD(&dev->dead_hid_list); -+ INIT_DELAYED_WORK(&dev->start_work, acc_start_work); -+ INIT_WORK(&dev->hid_work, acc_hid_work); -+ -+ /* _acc_dev must be set before calling usb_gadget_register_driver */ -+ _acc_dev = dev; -+ -+ ret = misc_register(&acc_device); -+ if (ret) -+ goto err; -+ -+ return 0; -+ -+err: -+ kfree(dev); -+ pr_err("USB accessory gadget driver failed to initialize\n"); -+ return ret; -+} -+ -+void acc_disconnect(void) -+{ -+ /* unregister all HID devices if USB is disconnected */ -+ kill_all_hid_devices(_acc_dev); -+} -+EXPORT_SYMBOL_GPL(acc_disconnect); -+ -+static void acc_cleanup(void) -+{ -+ misc_deregister(&acc_device); -+ kfree(_acc_dev); -+ _acc_dev = NULL; -+} -+static struct acc_instance *to_acc_instance(struct config_item *item) -+{ -+ return container_of(to_config_group(item), struct acc_instance, -+ func_inst.group); -+} -+ -+static void acc_attr_release(struct config_item *item) -+{ -+ struct acc_instance *fi_acc = to_acc_instance(item); -+ -+ usb_put_function_instance(&fi_acc->func_inst); -+} -+ -+static struct configfs_item_operations acc_item_ops = { -+ .release = acc_attr_release, -+}; -+ -+static struct config_item_type acc_func_type = { -+ .ct_item_ops = &acc_item_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct acc_instance *to_fi_acc(struct usb_function_instance *fi) -+{ -+ return container_of(fi, struct acc_instance, func_inst); -+} -+ -+static int acc_set_inst_name(struct usb_function_instance *fi, const char *name) -+{ -+ struct acc_instance *fi_acc; -+ char *ptr; -+ int name_len; -+ -+ name_len = strlen(name) + 1; -+ if (name_len > MAX_INST_NAME_LEN) -+ return -ENAMETOOLONG; -+ -+ ptr = kstrndup(name, name_len, GFP_KERNEL); -+ if (!ptr) -+ return -ENOMEM; -+ -+ fi_acc = to_fi_acc(fi); -+ fi_acc->name = ptr; -+ return 0; -+} -+ -+static void acc_free_inst(struct usb_function_instance *fi) -+{ -+ struct acc_instance *fi_acc; -+ -+ fi_acc = to_fi_acc(fi); -+ kfree(fi_acc->name); -+ acc_cleanup(); -+} -+ -+static struct usb_function_instance *acc_alloc_inst(void) -+{ -+ struct acc_instance *fi_acc; -+ struct acc_dev *dev; -+ int err; -+ -+ fi_acc = kzalloc(sizeof(*fi_acc), GFP_KERNEL); -+ if (!fi_acc) -+ return ERR_PTR(-ENOMEM); -+ fi_acc->func_inst.set_inst_name = acc_set_inst_name; -+ fi_acc->func_inst.free_func_inst = acc_free_inst; -+ -+ err = acc_setup(); -+ if (err) { -+ kfree(fi_acc); -+ pr_err("Error setting ACCESSORY\n"); -+ return ERR_PTR(err); -+ } -+ -+ config_group_init_type_name(&fi_acc->func_inst.group, -+ "", &acc_func_type); -+ dev = _acc_dev; -+ return &fi_acc->func_inst; -+} -+ -+static void acc_free(struct usb_function *f) -+{ -+/*NO-OP: no function specific resource allocation in mtp_alloc*/ -+} -+ -+int acc_ctrlrequest_configfs(struct usb_function *f, -+ const struct usb_ctrlrequest *ctrl) { -+ if (f->config != NULL && f->config->cdev != NULL) -+ return acc_ctrlrequest(f->config->cdev, ctrl); -+ else -+ return -1; -+} -+ -+static struct usb_function *acc_alloc(struct usb_function_instance *fi) -+{ -+ struct acc_dev *dev = _acc_dev; -+ -+ pr_info("acc_alloc\n"); -+ -+ dev->function.name = "accessory"; -+ dev->function.strings = acc_strings, -+ dev->function.fs_descriptors = fs_acc_descs; -+ dev->function.hs_descriptors = hs_acc_descs; -+ dev->function.bind = acc_function_bind_configfs; -+ dev->function.unbind = acc_function_unbind; -+ dev->function.set_alt = acc_function_set_alt; -+ dev->function.disable = acc_function_disable; -+ dev->function.free_func = acc_free; -+ dev->function.setup = acc_ctrlrequest_configfs; -+ -+ return &dev->function; -+} -+DECLARE_USB_FUNCTION_INIT(accessory, acc_alloc_inst, acc_alloc); -+MODULE_LICENSE("GPL"); -diff --git a/include/linux/usb/f_accessory.h b/include/linux/usb/f_accessory.h -new file mode 100644 -index 000000000000..ebe3c4d59309 ---- /dev/null -+++ b/include/linux/usb/f_accessory.h -@@ -0,0 +1,23 @@ -+/* -+ * Gadget Function Driver for Android USB accessories -+ * -+ * Copyright (C) 2011 Google, Inc. -+ * Author: Mike Lockwood -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef __LINUX_USB_F_ACCESSORY_H -+#define __LINUX_USB_F_ACCESSORY_H -+ -+#include -+ -+#endif /* __LINUX_USB_F_ACCESSORY_H */ -diff --git a/include/uapi/linux/usb/f_accessory.h b/include/uapi/linux/usb/f_accessory.h -new file mode 100644 -index 000000000000..0baeb7d0d74c ---- /dev/null -+++ b/include/uapi/linux/usb/f_accessory.h -@@ -0,0 +1,146 @@ -+/* -+ * Gadget Function Driver for Android USB accessories -+ * -+ * Copyright (C) 2011 Google, Inc. -+ * Author: Mike Lockwood -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef _UAPI_LINUX_USB_F_ACCESSORY_H -+#define _UAPI_LINUX_USB_F_ACCESSORY_H -+ -+/* Use Google Vendor ID when in accessory mode */ -+#define USB_ACCESSORY_VENDOR_ID 0x18D1 -+ -+ -+/* Product ID to use when in accessory mode */ -+#define USB_ACCESSORY_PRODUCT_ID 0x2D00 -+ -+/* Product ID to use when in accessory mode and adb is enabled */ -+#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01 -+ -+/* Indexes for strings sent by the host via ACCESSORY_SEND_STRING */ -+#define ACCESSORY_STRING_MANUFACTURER 0 -+#define ACCESSORY_STRING_MODEL 1 -+#define ACCESSORY_STRING_DESCRIPTION 2 -+#define ACCESSORY_STRING_VERSION 3 -+#define ACCESSORY_STRING_URI 4 -+#define ACCESSORY_STRING_SERIAL 5 -+ -+/* Control request for retrieving device's protocol version -+ * -+ * requestType: USB_DIR_IN | USB_TYPE_VENDOR -+ * request: ACCESSORY_GET_PROTOCOL -+ * value: 0 -+ * index: 0 -+ * data version number (16 bits little endian) -+ * 1 for original accessory support -+ * 2 adds HID and device to host audio support -+ */ -+#define ACCESSORY_GET_PROTOCOL 51 -+ -+/* Control request for host to send a string to the device -+ * -+ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR -+ * request: ACCESSORY_SEND_STRING -+ * value: 0 -+ * index: string ID -+ * data zero terminated UTF8 string -+ * -+ * The device can later retrieve these strings via the -+ * ACCESSORY_GET_STRING_* ioctls -+ */ -+#define ACCESSORY_SEND_STRING 52 -+ -+/* Control request for starting device in accessory mode. -+ * The host sends this after setting all its strings to the device. -+ * -+ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR -+ * request: ACCESSORY_START -+ * value: 0 -+ * index: 0 -+ * data none -+ */ -+#define ACCESSORY_START 53 -+ -+/* Control request for registering a HID device. -+ * Upon registering, a unique ID is sent by the accessory in the -+ * value parameter. This ID will be used for future commands for -+ * the device -+ * -+ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR -+ * request: ACCESSORY_REGISTER_HID_DEVICE -+ * value: Accessory assigned ID for the HID device -+ * index: total length of the HID report descriptor -+ * data none -+ */ -+#define ACCESSORY_REGISTER_HID 54 -+ -+/* Control request for unregistering a HID device. -+ * -+ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR -+ * request: ACCESSORY_REGISTER_HID -+ * value: Accessory assigned ID for the HID device -+ * index: 0 -+ * data none -+ */ -+#define ACCESSORY_UNREGISTER_HID 55 -+ -+/* Control request for sending the HID report descriptor. -+ * If the HID descriptor is longer than the endpoint zero max packet size, -+ * the descriptor will be sent in multiple ACCESSORY_SET_HID_REPORT_DESC -+ * commands. The data for the descriptor must be sent sequentially -+ * if multiple packets are needed. -+ * -+ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR -+ * request: ACCESSORY_SET_HID_REPORT_DESC -+ * value: Accessory assigned ID for the HID device -+ * index: offset of data in descriptor -+ * (needed when HID descriptor is too big for one packet) -+ * data the HID report descriptor -+ */ -+#define ACCESSORY_SET_HID_REPORT_DESC 56 -+ -+/* Control request for sending HID events. -+ * -+ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR -+ * request: ACCESSORY_SEND_HID_EVENT -+ * value: Accessory assigned ID for the HID device -+ * index: 0 -+ * data the HID report for the event -+ */ -+#define ACCESSORY_SEND_HID_EVENT 57 -+ -+/* Control request for setting the audio mode. -+ * -+ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR -+ * request: ACCESSORY_SET_AUDIO_MODE -+ * value: 0 - no audio -+ * 1 - device to host, 44100 16-bit stereo PCM -+ * index: 0 -+ * data none -+ */ -+#define ACCESSORY_SET_AUDIO_MODE 58 -+ -+/* ioctls for retrieving strings set by the host */ -+#define ACCESSORY_GET_STRING_MANUFACTURER _IOW('M', 1, char[256]) -+#define ACCESSORY_GET_STRING_MODEL _IOW('M', 2, char[256]) -+#define ACCESSORY_GET_STRING_DESCRIPTION _IOW('M', 3, char[256]) -+#define ACCESSORY_GET_STRING_VERSION _IOW('M', 4, char[256]) -+#define ACCESSORY_GET_STRING_URI _IOW('M', 5, char[256]) -+#define ACCESSORY_GET_STRING_SERIAL _IOW('M', 6, char[256]) -+/* returns 1 if there is a start request pending */ -+#define ACCESSORY_IS_START_REQUESTED _IO('M', 7) -+/* returns audio mode (set via the ACCESSORY_SET_AUDIO_MODE control request) */ -+#define ACCESSORY_GET_AUDIO_MODE _IO('M', 8) -+ -+#endif /* _UAPI_LINUX_USB_F_ACCESSORY_H */ diff --git a/patches/ANDROID-usb-gadget-f_audio_source-New-gadget-driver-for-audio-output.patch b/patches/ANDROID-usb-gadget-f_audio_source-New-gadget-driver-for-audio-output.patch deleted file mode 100644 index 40db7bb9e64e..000000000000 --- a/patches/ANDROID-usb-gadget-f_audio_source-New-gadget-driver-for-audio-output.patch +++ /dev/null @@ -1,1150 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mike Lockwood -Date: Fri, 11 May 2012 09:01:08 -0700 -Subject: ANDROID: usb: gadget: f_audio_source: New gadget driver for audio - output - -This driver presents a standard USB audio class interface to the host -and an ALSA PCM device to userspace - -Bug: 78114713 -Bug: 120441124 -[badhri: f_audio_source is being migrated to userspace.] -Change-Id: If16b14a5ff27045f9cb2daaf1ae9195c5eeab7d0 -Signed-off-by: Mike Lockwood -[AmitP: Folded following android-4.9 commit changes into this patch - Parts of e27543931009 ("ANDROID: usb: gadget: Fixes and hacks to make android usb gadget compile on 3.8") - i6d9285e2574a ("ANDROID: usb: gadget: f_audio_source:replace deprecated API")] -Signed-off-by: Amit Pundir -[astrachan: Folded the following changes into this patch: - ddfd0c4070c1 ("ANDROID: usb: gadget: f_audio_source: Move to USB_FUNCTION API") - a3ab81aaa19e ("ANDROID: usb: gadget: f_audio_source: Move gadget functions code") - 2095c953d894 ("ANDROID: usb: gadget: f_audio_source: change max ISO packet size") - 8671b3e53638 ("ANDROID: usb: gadget: f_audio_source: Fixed USB Audio Class Interface Descriptor") - af98f36edbe2 ("ANDROID: usb: gadget: f_audio_source: disable the CPU C-states upon playback") - a830751a338e ("CHROMIUM: usb: gadget: f_audio_source: add .free_func callback")] -Signed-off-by: Alistair Strachan ---- - drivers/usb/gadget/Kconfig | 12 + - drivers/usb/gadget/function/Makefile | 2 + - drivers/usb/gadget/function/f_audio_source.c | 1071 ++++++++++++++++++ - 3 files changed, 1085 insertions(+) - create mode 100644 drivers/usb/gadget/function/f_audio_source.c - -diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig -index 7749fb1decb0..920ff2d2c557 100644 ---- a/drivers/usb/gadget/Kconfig -+++ b/drivers/usb/gadget/Kconfig -@@ -219,6 +219,9 @@ config USB_F_TCM - config USB_F_ACC - tristate - -+config USB_F_AUDIO_SRC -+ tristate -+ - # this first set of drivers all depend on bulk-capable hardware. - - config USB_CONFIGFS -@@ -387,6 +390,15 @@ config USB_CONFIGFS_F_ACC - help - USB gadget Accessory support - -+config USB_CONFIGFS_F_AUDIO_SRC -+ bool "Audio Source gadget" -+ depends on USB_CONFIGFS -+ depends on SND -+ select SND_PCM -+ select USB_F_AUDIO_SRC -+ help -+ USB gadget Audio Source support -+ - config USB_CONFIGFS_F_UAC1 - bool "Audio Class 1.0" - depends on USB_CONFIGFS -diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile -index 2305360e5f22..dd33a1243342 100644 ---- a/drivers/usb/gadget/function/Makefile -+++ b/drivers/usb/gadget/function/Makefile -@@ -52,3 +52,5 @@ usb_f_tcm-y := f_tcm.o - obj-$(CONFIG_USB_F_TCM) += usb_f_tcm.o - usb_f_accessory-y := f_accessory.o - obj-$(CONFIG_USB_F_ACC) += usb_f_accessory.o -+usb_f_audio_source-y := f_audio_source.o -+obj-$(CONFIG_USB_F_AUDIO_SRC) += usb_f_audio_source.o -diff --git a/drivers/usb/gadget/function/f_audio_source.c b/drivers/usb/gadget/function/f_audio_source.c -new file mode 100644 -index 000000000000..8124af33b738 ---- /dev/null -+++ b/drivers/usb/gadget/function/f_audio_source.c -@@ -0,0 +1,1071 @@ -+/* -+ * Gadget Function Driver for USB audio source device -+ * -+ * Copyright (C) 2012 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#define SAMPLE_RATE 44100 -+#define FRAMES_PER_MSEC (SAMPLE_RATE / 1000) -+ -+#define IN_EP_MAX_PACKET_SIZE 256 -+ -+/* Number of requests to allocate */ -+#define IN_EP_REQ_COUNT 4 -+ -+#define AUDIO_AC_INTERFACE 0 -+#define AUDIO_AS_INTERFACE 1 -+#define AUDIO_NUM_INTERFACES 2 -+#define MAX_INST_NAME_LEN 40 -+ -+/* B.3.1 Standard AC Interface Descriptor */ -+static struct usb_interface_descriptor ac_interface_desc = { -+ .bLength = USB_DT_INTERFACE_SIZE, -+ .bDescriptorType = USB_DT_INTERFACE, -+ .bNumEndpoints = 0, -+ .bInterfaceClass = USB_CLASS_AUDIO, -+ .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, -+}; -+ -+DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); -+ -+#define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(AUDIO_NUM_INTERFACES) -+/* 1 input terminal, 1 output terminal and 1 feature unit */ -+#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH \ -+ + UAC_DT_INPUT_TERMINAL_SIZE + UAC_DT_OUTPUT_TERMINAL_SIZE \ -+ + UAC_DT_FEATURE_UNIT_SIZE(0)) -+/* B.3.2 Class-Specific AC Interface Descriptor */ -+static struct uac1_ac_header_descriptor_2 ac_header_desc = { -+ .bLength = UAC_DT_AC_HEADER_LENGTH, -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_HEADER, -+ .bcdADC = __constant_cpu_to_le16(0x0100), -+ .wTotalLength = __constant_cpu_to_le16(UAC_DT_TOTAL_LENGTH), -+ .bInCollection = AUDIO_NUM_INTERFACES, -+ .baInterfaceNr = { -+ [0] = AUDIO_AC_INTERFACE, -+ [1] = AUDIO_AS_INTERFACE, -+ } -+}; -+ -+#define INPUT_TERMINAL_ID 1 -+static struct uac_input_terminal_descriptor input_terminal_desc = { -+ .bLength = UAC_DT_INPUT_TERMINAL_SIZE, -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_INPUT_TERMINAL, -+ .bTerminalID = INPUT_TERMINAL_ID, -+ .wTerminalType = UAC_INPUT_TERMINAL_MICROPHONE, -+ .bAssocTerminal = 0, -+ .wChannelConfig = 0x3, -+}; -+ -+DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(0); -+ -+#define FEATURE_UNIT_ID 2 -+static struct uac_feature_unit_descriptor_0 feature_unit_desc = { -+ .bLength = UAC_DT_FEATURE_UNIT_SIZE(0), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_FEATURE_UNIT, -+ .bUnitID = FEATURE_UNIT_ID, -+ .bSourceID = INPUT_TERMINAL_ID, -+ .bControlSize = 2, -+}; -+ -+#define OUTPUT_TERMINAL_ID 3 -+static struct uac1_output_terminal_descriptor output_terminal_desc = { -+ .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, -+ .bTerminalID = OUTPUT_TERMINAL_ID, -+ .wTerminalType = UAC_TERMINAL_STREAMING, -+ .bAssocTerminal = FEATURE_UNIT_ID, -+ .bSourceID = FEATURE_UNIT_ID, -+}; -+ -+/* B.4.1 Standard AS Interface Descriptor */ -+static struct usb_interface_descriptor as_interface_alt_0_desc = { -+ .bLength = USB_DT_INTERFACE_SIZE, -+ .bDescriptorType = USB_DT_INTERFACE, -+ .bAlternateSetting = 0, -+ .bNumEndpoints = 0, -+ .bInterfaceClass = USB_CLASS_AUDIO, -+ .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, -+}; -+ -+static struct usb_interface_descriptor as_interface_alt_1_desc = { -+ .bLength = USB_DT_INTERFACE_SIZE, -+ .bDescriptorType = USB_DT_INTERFACE, -+ .bAlternateSetting = 1, -+ .bNumEndpoints = 1, -+ .bInterfaceClass = USB_CLASS_AUDIO, -+ .bInterfaceSubClass = USB_SUBCLASS_AUDIOSTREAMING, -+}; -+ -+/* B.4.2 Class-Specific AS Interface Descriptor */ -+static struct uac1_as_header_descriptor as_header_desc = { -+ .bLength = UAC_DT_AS_HEADER_SIZE, -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_AS_GENERAL, -+ .bTerminalLink = INPUT_TERMINAL_ID, -+ .bDelay = 1, -+ .wFormatTag = UAC_FORMAT_TYPE_I_PCM, -+}; -+ -+DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); -+ -+static struct uac_format_type_i_discrete_descriptor_1 as_type_i_desc = { -+ .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), -+ .bDescriptorType = USB_DT_CS_INTERFACE, -+ .bDescriptorSubtype = UAC_FORMAT_TYPE, -+ .bFormatType = UAC_FORMAT_TYPE_I, -+ .bSubframeSize = 2, -+ .bBitResolution = 16, -+ .bSamFreqType = 1, -+}; -+ -+/* Standard ISO IN Endpoint Descriptor for highspeed */ -+static struct usb_endpoint_descriptor hs_as_in_ep_desc = { -+ .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, -+ .bDescriptorType = USB_DT_ENDPOINT, -+ .bEndpointAddress = USB_DIR_IN, -+ .bmAttributes = USB_ENDPOINT_SYNC_SYNC -+ | USB_ENDPOINT_XFER_ISOC, -+ .wMaxPacketSize = __constant_cpu_to_le16(IN_EP_MAX_PACKET_SIZE), -+ .bInterval = 4, /* poll 1 per millisecond */ -+}; -+ -+/* Standard ISO IN Endpoint Descriptor for highspeed */ -+static struct usb_endpoint_descriptor fs_as_in_ep_desc = { -+ .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, -+ .bDescriptorType = USB_DT_ENDPOINT, -+ .bEndpointAddress = USB_DIR_IN, -+ .bmAttributes = USB_ENDPOINT_SYNC_SYNC -+ | USB_ENDPOINT_XFER_ISOC, -+ .wMaxPacketSize = __constant_cpu_to_le16(IN_EP_MAX_PACKET_SIZE), -+ .bInterval = 1, /* poll 1 per millisecond */ -+}; -+ -+/* Class-specific AS ISO OUT Endpoint Descriptor */ -+static struct uac_iso_endpoint_descriptor as_iso_in_desc = { -+ .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, -+ .bDescriptorType = USB_DT_CS_ENDPOINT, -+ .bDescriptorSubtype = UAC_EP_GENERAL, -+ .bmAttributes = 1, -+ .bLockDelayUnits = 1, -+ .wLockDelay = __constant_cpu_to_le16(1), -+}; -+ -+static struct usb_descriptor_header *hs_audio_desc[] = { -+ (struct usb_descriptor_header *)&ac_interface_desc, -+ (struct usb_descriptor_header *)&ac_header_desc, -+ -+ (struct usb_descriptor_header *)&input_terminal_desc, -+ (struct usb_descriptor_header *)&output_terminal_desc, -+ (struct usb_descriptor_header *)&feature_unit_desc, -+ -+ (struct usb_descriptor_header *)&as_interface_alt_0_desc, -+ (struct usb_descriptor_header *)&as_interface_alt_1_desc, -+ (struct usb_descriptor_header *)&as_header_desc, -+ -+ (struct usb_descriptor_header *)&as_type_i_desc, -+ -+ (struct usb_descriptor_header *)&hs_as_in_ep_desc, -+ (struct usb_descriptor_header *)&as_iso_in_desc, -+ NULL, -+}; -+ -+static struct usb_descriptor_header *fs_audio_desc[] = { -+ (struct usb_descriptor_header *)&ac_interface_desc, -+ (struct usb_descriptor_header *)&ac_header_desc, -+ -+ (struct usb_descriptor_header *)&input_terminal_desc, -+ (struct usb_descriptor_header *)&output_terminal_desc, -+ (struct usb_descriptor_header *)&feature_unit_desc, -+ -+ (struct usb_descriptor_header *)&as_interface_alt_0_desc, -+ (struct usb_descriptor_header *)&as_interface_alt_1_desc, -+ (struct usb_descriptor_header *)&as_header_desc, -+ -+ (struct usb_descriptor_header *)&as_type_i_desc, -+ -+ (struct usb_descriptor_header *)&fs_as_in_ep_desc, -+ (struct usb_descriptor_header *)&as_iso_in_desc, -+ NULL, -+}; -+ -+static struct snd_pcm_hardware audio_hw_info = { -+ .info = SNDRV_PCM_INFO_MMAP | -+ SNDRV_PCM_INFO_MMAP_VALID | -+ SNDRV_PCM_INFO_BATCH | -+ SNDRV_PCM_INFO_INTERLEAVED | -+ SNDRV_PCM_INFO_BLOCK_TRANSFER, -+ -+ .formats = SNDRV_PCM_FMTBIT_S16_LE, -+ .channels_min = 2, -+ .channels_max = 2, -+ .rate_min = SAMPLE_RATE, -+ .rate_max = SAMPLE_RATE, -+ -+ .buffer_bytes_max = 1024 * 1024, -+ .period_bytes_min = 64, -+ .period_bytes_max = 512 * 1024, -+ .periods_min = 2, -+ .periods_max = 1024, -+}; -+ -+/*-------------------------------------------------------------------------*/ -+ -+struct audio_source_config { -+ int card; -+ int device; -+}; -+ -+struct audio_dev { -+ struct usb_function func; -+ struct snd_card *card; -+ struct snd_pcm *pcm; -+ struct snd_pcm_substream *substream; -+ -+ struct list_head idle_reqs; -+ struct usb_ep *in_ep; -+ -+ spinlock_t lock; -+ -+ /* beginning, end and current position in our buffer */ -+ void *buffer_start; -+ void *buffer_end; -+ void *buffer_pos; -+ -+ /* byte size of a "period" */ -+ unsigned int period; -+ /* bytes sent since last call to snd_pcm_period_elapsed */ -+ unsigned int period_offset; -+ /* time we started playing */ -+ ktime_t start_time; -+ /* number of frames sent since start_time */ -+ s64 frames_sent; -+ struct audio_source_config *config; -+ /* for creating and issuing QoS requests */ -+ struct pm_qos_request pm_qos; -+}; -+ -+static inline struct audio_dev *func_to_audio(struct usb_function *f) -+{ -+ return container_of(f, struct audio_dev, func); -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+struct audio_source_instance { -+ struct usb_function_instance func_inst; -+ const char *name; -+ struct audio_source_config *config; -+ struct device *audio_device; -+}; -+ -+static void audio_source_attr_release(struct config_item *item); -+ -+static struct configfs_item_operations audio_source_item_ops = { -+ .release = audio_source_attr_release, -+}; -+ -+static struct config_item_type audio_source_func_type = { -+ .ct_item_ops = &audio_source_item_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static ssize_t audio_source_pcm_show(struct device *dev, -+ struct device_attribute *attr, char *buf); -+ -+static DEVICE_ATTR(pcm, S_IRUGO, audio_source_pcm_show, NULL); -+ -+static struct device_attribute *audio_source_function_attributes[] = { -+ &dev_attr_pcm, -+ NULL -+}; -+ -+/*--------------------------------------------------------------------------*/ -+ -+static struct usb_request *audio_request_new(struct usb_ep *ep, int buffer_size) -+{ -+ struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); -+ -+ if (!req) -+ return NULL; -+ -+ req->buf = kmalloc(buffer_size, GFP_KERNEL); -+ if (!req->buf) { -+ usb_ep_free_request(ep, req); -+ return NULL; -+ } -+ req->length = buffer_size; -+ return req; -+} -+ -+static void audio_request_free(struct usb_request *req, struct usb_ep *ep) -+{ -+ if (req) { -+ kfree(req->buf); -+ usb_ep_free_request(ep, req); -+ } -+} -+ -+static void audio_req_put(struct audio_dev *audio, struct usb_request *req) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&audio->lock, flags); -+ list_add_tail(&req->list, &audio->idle_reqs); -+ spin_unlock_irqrestore(&audio->lock, flags); -+} -+ -+static struct usb_request *audio_req_get(struct audio_dev *audio) -+{ -+ unsigned long flags; -+ struct usb_request *req; -+ -+ spin_lock_irqsave(&audio->lock, flags); -+ if (list_empty(&audio->idle_reqs)) { -+ req = 0; -+ } else { -+ req = list_first_entry(&audio->idle_reqs, struct usb_request, -+ list); -+ list_del(&req->list); -+ } -+ spin_unlock_irqrestore(&audio->lock, flags); -+ return req; -+} -+ -+/* send the appropriate number of packets to match our bitrate */ -+static void audio_send(struct audio_dev *audio) -+{ -+ struct snd_pcm_runtime *runtime; -+ struct usb_request *req; -+ int length, length1, length2, ret; -+ s64 msecs; -+ s64 frames; -+ ktime_t now; -+ -+ /* audio->substream will be null if we have been closed */ -+ if (!audio->substream) -+ return; -+ /* audio->buffer_pos will be null if we have been stopped */ -+ if (!audio->buffer_pos) -+ return; -+ -+ runtime = audio->substream->runtime; -+ -+ /* compute number of frames to send */ -+ now = ktime_get(); -+ msecs = div_s64((ktime_to_ns(now) - ktime_to_ns(audio->start_time)), -+ 1000000); -+ frames = div_s64((msecs * SAMPLE_RATE), 1000); -+ -+ /* Readjust our frames_sent if we fall too far behind. -+ * If we get too far behind it is better to drop some frames than -+ * to keep sending data too fast in an attempt to catch up. -+ */ -+ if (frames - audio->frames_sent > 10 * FRAMES_PER_MSEC) -+ audio->frames_sent = frames - FRAMES_PER_MSEC; -+ -+ frames -= audio->frames_sent; -+ -+ /* We need to send something to keep the pipeline going */ -+ if (frames <= 0) -+ frames = FRAMES_PER_MSEC; -+ -+ while (frames > 0) { -+ req = audio_req_get(audio); -+ if (!req) -+ break; -+ -+ length = frames_to_bytes(runtime, frames); -+ if (length > IN_EP_MAX_PACKET_SIZE) -+ length = IN_EP_MAX_PACKET_SIZE; -+ -+ if (audio->buffer_pos + length > audio->buffer_end) -+ length1 = audio->buffer_end - audio->buffer_pos; -+ else -+ length1 = length; -+ memcpy(req->buf, audio->buffer_pos, length1); -+ if (length1 < length) { -+ /* Wrap around and copy remaining length -+ * at beginning of buffer. -+ */ -+ length2 = length - length1; -+ memcpy(req->buf + length1, audio->buffer_start, -+ length2); -+ audio->buffer_pos = audio->buffer_start + length2; -+ } else { -+ audio->buffer_pos += length1; -+ if (audio->buffer_pos >= audio->buffer_end) -+ audio->buffer_pos = audio->buffer_start; -+ } -+ -+ req->length = length; -+ ret = usb_ep_queue(audio->in_ep, req, GFP_ATOMIC); -+ if (ret < 0) { -+ pr_err("usb_ep_queue failed ret: %d\n", ret); -+ audio_req_put(audio, req); -+ break; -+ } -+ -+ frames -= bytes_to_frames(runtime, length); -+ audio->frames_sent += bytes_to_frames(runtime, length); -+ } -+} -+ -+static void audio_control_complete(struct usb_ep *ep, struct usb_request *req) -+{ -+ /* nothing to do here */ -+} -+ -+static void audio_data_complete(struct usb_ep *ep, struct usb_request *req) -+{ -+ struct audio_dev *audio = req->context; -+ -+ pr_debug("audio_data_complete req->status %d req->actual %d\n", -+ req->status, req->actual); -+ -+ audio_req_put(audio, req); -+ -+ if (!audio->buffer_start || req->status) -+ return; -+ -+ audio->period_offset += req->actual; -+ if (audio->period_offset >= audio->period) { -+ snd_pcm_period_elapsed(audio->substream); -+ audio->period_offset = 0; -+ } -+ audio_send(audio); -+} -+ -+static int audio_set_endpoint_req(struct usb_function *f, -+ const struct usb_ctrlrequest *ctrl) -+{ -+ int value = -EOPNOTSUPP; -+ u16 ep = le16_to_cpu(ctrl->wIndex); -+ u16 len = le16_to_cpu(ctrl->wLength); -+ u16 w_value = le16_to_cpu(ctrl->wValue); -+ -+ pr_debug("bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", -+ ctrl->bRequest, w_value, len, ep); -+ -+ switch (ctrl->bRequest) { -+ case UAC_SET_CUR: -+ case UAC_SET_MIN: -+ case UAC_SET_MAX: -+ case UAC_SET_RES: -+ value = len; -+ break; -+ default: -+ break; -+ } -+ -+ return value; -+} -+ -+static int audio_get_endpoint_req(struct usb_function *f, -+ const struct usb_ctrlrequest *ctrl) -+{ -+ struct usb_composite_dev *cdev = f->config->cdev; -+ int value = -EOPNOTSUPP; -+ u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); -+ u16 len = le16_to_cpu(ctrl->wLength); -+ u16 w_value = le16_to_cpu(ctrl->wValue); -+ u8 *buf = cdev->req->buf; -+ -+ pr_debug("bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", -+ ctrl->bRequest, w_value, len, ep); -+ -+ if (w_value == UAC_EP_CS_ATTR_SAMPLE_RATE << 8) { -+ switch (ctrl->bRequest) { -+ case UAC_GET_CUR: -+ case UAC_GET_MIN: -+ case UAC_GET_MAX: -+ case UAC_GET_RES: -+ /* return our sample rate */ -+ buf[0] = (u8)SAMPLE_RATE; -+ buf[1] = (u8)(SAMPLE_RATE >> 8); -+ buf[2] = (u8)(SAMPLE_RATE >> 16); -+ value = 3; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ return value; -+} -+ -+static int -+audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) -+{ -+ struct usb_composite_dev *cdev = f->config->cdev; -+ struct usb_request *req = cdev->req; -+ int value = -EOPNOTSUPP; -+ u16 w_index = le16_to_cpu(ctrl->wIndex); -+ u16 w_value = le16_to_cpu(ctrl->wValue); -+ u16 w_length = le16_to_cpu(ctrl->wLength); -+ -+ /* composite driver infrastructure handles everything; interface -+ * activation uses set_alt(). -+ */ -+ switch (ctrl->bRequestType) { -+ case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: -+ value = audio_set_endpoint_req(f, ctrl); -+ break; -+ -+ case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: -+ value = audio_get_endpoint_req(f, ctrl); -+ break; -+ } -+ -+ /* respond with data transfer or status phase? */ -+ if (value >= 0) { -+ pr_debug("audio req%02x.%02x v%04x i%04x l%d\n", -+ ctrl->bRequestType, ctrl->bRequest, -+ w_value, w_index, w_length); -+ req->zero = 0; -+ req->length = value; -+ req->complete = audio_control_complete; -+ value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); -+ if (value < 0) -+ pr_err("audio response on err %d\n", value); -+ } -+ -+ /* device either stalls (value < 0) or reports success */ -+ return value; -+} -+ -+static int audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) -+{ -+ struct audio_dev *audio = func_to_audio(f); -+ struct usb_composite_dev *cdev = f->config->cdev; -+ int ret; -+ -+ pr_debug("audio_set_alt intf %d, alt %d\n", intf, alt); -+ -+ ret = config_ep_by_speed(cdev->gadget, f, audio->in_ep); -+ if (ret) -+ return ret; -+ -+ usb_ep_enable(audio->in_ep); -+ return 0; -+} -+ -+static void audio_disable(struct usb_function *f) -+{ -+ struct audio_dev *audio = func_to_audio(f); -+ -+ pr_debug("audio_disable\n"); -+ usb_ep_disable(audio->in_ep); -+} -+ -+static void audio_free_func(struct usb_function *f) -+{ -+ /* no-op */ -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+static void audio_build_desc(struct audio_dev *audio) -+{ -+ u8 *sam_freq; -+ int rate; -+ -+ /* Set channel numbers */ -+ input_terminal_desc.bNrChannels = 2; -+ as_type_i_desc.bNrChannels = 2; -+ -+ /* Set sample rates */ -+ rate = SAMPLE_RATE; -+ sam_freq = as_type_i_desc.tSamFreq[0]; -+ memcpy(sam_freq, &rate, 3); -+} -+ -+ -+static int snd_card_setup(struct usb_configuration *c, -+ struct audio_source_config *config); -+static struct audio_source_instance *to_fi_audio_source( -+ const struct usb_function_instance *fi); -+ -+ -+/* audio function driver setup/binding */ -+static int -+audio_bind(struct usb_configuration *c, struct usb_function *f) -+{ -+ struct usb_composite_dev *cdev = c->cdev; -+ struct audio_dev *audio = func_to_audio(f); -+ int status; -+ struct usb_ep *ep; -+ struct usb_request *req; -+ int i; -+ int err; -+ -+ if (IS_ENABLED(CONFIG_USB_CONFIGFS)) { -+ struct audio_source_instance *fi_audio = -+ to_fi_audio_source(f->fi); -+ struct audio_source_config *config = -+ fi_audio->config; -+ -+ err = snd_card_setup(c, config); -+ if (err) -+ return err; -+ } -+ -+ audio_build_desc(audio); -+ -+ /* allocate instance-specific interface IDs, and patch descriptors */ -+ status = usb_interface_id(c, f); -+ if (status < 0) -+ goto fail; -+ ac_interface_desc.bInterfaceNumber = status; -+ -+ /* AUDIO_AC_INTERFACE */ -+ ac_header_desc.baInterfaceNr[0] = status; -+ -+ status = usb_interface_id(c, f); -+ if (status < 0) -+ goto fail; -+ as_interface_alt_0_desc.bInterfaceNumber = status; -+ as_interface_alt_1_desc.bInterfaceNumber = status; -+ -+ /* AUDIO_AS_INTERFACE */ -+ ac_header_desc.baInterfaceNr[1] = status; -+ -+ status = -ENODEV; -+ -+ /* allocate our endpoint */ -+ ep = usb_ep_autoconfig(cdev->gadget, &fs_as_in_ep_desc); -+ if (!ep) -+ goto fail; -+ audio->in_ep = ep; -+ ep->driver_data = audio; /* claim */ -+ -+ if (gadget_is_dualspeed(c->cdev->gadget)) -+ hs_as_in_ep_desc.bEndpointAddress = -+ fs_as_in_ep_desc.bEndpointAddress; -+ -+ f->fs_descriptors = fs_audio_desc; -+ f->hs_descriptors = hs_audio_desc; -+ -+ for (i = 0, status = 0; i < IN_EP_REQ_COUNT && status == 0; i++) { -+ req = audio_request_new(ep, IN_EP_MAX_PACKET_SIZE); -+ if (req) { -+ req->context = audio; -+ req->complete = audio_data_complete; -+ audio_req_put(audio, req); -+ } else -+ status = -ENOMEM; -+ } -+ -+fail: -+ return status; -+} -+ -+static void -+audio_unbind(struct usb_configuration *c, struct usb_function *f) -+{ -+ struct audio_dev *audio = func_to_audio(f); -+ struct usb_request *req; -+ -+ while ((req = audio_req_get(audio))) -+ audio_request_free(req, audio->in_ep); -+ -+ snd_card_free_when_closed(audio->card); -+ audio->card = NULL; -+ audio->pcm = NULL; -+ audio->substream = NULL; -+ audio->in_ep = NULL; -+ -+ if (IS_ENABLED(CONFIG_USB_CONFIGFS)) { -+ struct audio_source_instance *fi_audio = -+ to_fi_audio_source(f->fi); -+ struct audio_source_config *config = -+ fi_audio->config; -+ -+ config->card = -1; -+ config->device = -1; -+ } -+} -+ -+static void audio_pcm_playback_start(struct audio_dev *audio) -+{ -+ audio->start_time = ktime_get(); -+ audio->frames_sent = 0; -+ audio_send(audio); -+} -+ -+static void audio_pcm_playback_stop(struct audio_dev *audio) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&audio->lock, flags); -+ audio->buffer_start = 0; -+ audio->buffer_end = 0; -+ audio->buffer_pos = 0; -+ spin_unlock_irqrestore(&audio->lock, flags); -+} -+ -+static int audio_pcm_open(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct audio_dev *audio = substream->private_data; -+ -+ runtime->private_data = audio; -+ runtime->hw = audio_hw_info; -+ snd_pcm_limit_hw_rates(runtime); -+ runtime->hw.channels_max = 2; -+ -+ audio->substream = substream; -+ -+ /* Add the QoS request and set the latency to 0 */ -+ pm_qos_add_request(&audio->pm_qos, PM_QOS_CPU_DMA_LATENCY, 0); -+ -+ return 0; -+} -+ -+static int audio_pcm_close(struct snd_pcm_substream *substream) -+{ -+ struct audio_dev *audio = substream->private_data; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&audio->lock, flags); -+ -+ /* Remove the QoS request */ -+ pm_qos_remove_request(&audio->pm_qos); -+ -+ audio->substream = NULL; -+ spin_unlock_irqrestore(&audio->lock, flags); -+ -+ return 0; -+} -+ -+static int audio_pcm_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ unsigned int channels = params_channels(params); -+ unsigned int rate = params_rate(params); -+ -+ if (rate != SAMPLE_RATE) -+ return -EINVAL; -+ if (channels != 2) -+ return -EINVAL; -+ -+ return snd_pcm_lib_alloc_vmalloc_buffer(substream, -+ params_buffer_bytes(params)); -+} -+ -+static int audio_pcm_hw_free(struct snd_pcm_substream *substream) -+{ -+ return snd_pcm_lib_free_vmalloc_buffer(substream); -+} -+ -+static int audio_pcm_prepare(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct audio_dev *audio = runtime->private_data; -+ -+ audio->period = snd_pcm_lib_period_bytes(substream); -+ audio->period_offset = 0; -+ audio->buffer_start = runtime->dma_area; -+ audio->buffer_end = audio->buffer_start -+ + snd_pcm_lib_buffer_bytes(substream); -+ audio->buffer_pos = audio->buffer_start; -+ -+ return 0; -+} -+ -+static snd_pcm_uframes_t audio_pcm_pointer(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ struct audio_dev *audio = runtime->private_data; -+ ssize_t bytes = audio->buffer_pos - audio->buffer_start; -+ -+ /* return offset of next frame to fill in our buffer */ -+ return bytes_to_frames(runtime, bytes); -+} -+ -+static int audio_pcm_playback_trigger(struct snd_pcm_substream *substream, -+ int cmd) -+{ -+ struct audio_dev *audio = substream->runtime->private_data; -+ int ret = 0; -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ case SNDRV_PCM_TRIGGER_RESUME: -+ audio_pcm_playback_start(audio); -+ break; -+ -+ case SNDRV_PCM_TRIGGER_STOP: -+ case SNDRV_PCM_TRIGGER_SUSPEND: -+ audio_pcm_playback_stop(audio); -+ break; -+ -+ default: -+ ret = -EINVAL; -+ } -+ -+ return ret; -+} -+ -+static struct audio_dev _audio_dev = { -+ .func = { -+ .name = "audio_source", -+ .bind = audio_bind, -+ .unbind = audio_unbind, -+ .set_alt = audio_set_alt, -+ .setup = audio_setup, -+ .disable = audio_disable, -+ .free_func = audio_free_func, -+ }, -+ .lock = __SPIN_LOCK_UNLOCKED(_audio_dev.lock), -+ .idle_reqs = LIST_HEAD_INIT(_audio_dev.idle_reqs), -+}; -+ -+static struct snd_pcm_ops audio_playback_ops = { -+ .open = audio_pcm_open, -+ .close = audio_pcm_close, -+ .ioctl = snd_pcm_lib_ioctl, -+ .hw_params = audio_pcm_hw_params, -+ .hw_free = audio_pcm_hw_free, -+ .prepare = audio_pcm_prepare, -+ .trigger = audio_pcm_playback_trigger, -+ .pointer = audio_pcm_pointer, -+}; -+ -+int audio_source_bind_config(struct usb_configuration *c, -+ struct audio_source_config *config) -+{ -+ struct audio_dev *audio; -+ int err; -+ -+ config->card = -1; -+ config->device = -1; -+ -+ audio = &_audio_dev; -+ -+ err = snd_card_setup(c, config); -+ if (err) -+ return err; -+ -+ err = usb_add_function(c, &audio->func); -+ if (err) -+ goto add_fail; -+ -+ return 0; -+ -+add_fail: -+ snd_card_free(audio->card); -+ return err; -+} -+ -+static int snd_card_setup(struct usb_configuration *c, -+ struct audio_source_config *config) -+{ -+ struct audio_dev *audio; -+ struct snd_card *card; -+ struct snd_pcm *pcm; -+ int err; -+ -+ audio = &_audio_dev; -+ -+ err = snd_card_new(&c->cdev->gadget->dev, -+ SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, -+ THIS_MODULE, 0, &card); -+ if (err) -+ return err; -+ -+ err = snd_pcm_new(card, "USB audio source", 0, 1, 0, &pcm); -+ if (err) -+ goto pcm_fail; -+ -+ pcm->private_data = audio; -+ pcm->info_flags = 0; -+ audio->pcm = pcm; -+ -+ strlcpy(pcm->name, "USB gadget audio", sizeof(pcm->name)); -+ -+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &audio_playback_ops); -+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, -+ NULL, 0, 64 * 1024); -+ -+ strlcpy(card->driver, "audio_source", sizeof(card->driver)); -+ strlcpy(card->shortname, card->driver, sizeof(card->shortname)); -+ strlcpy(card->longname, "USB accessory audio source", -+ sizeof(card->longname)); -+ -+ err = snd_card_register(card); -+ if (err) -+ goto register_fail; -+ -+ config->card = pcm->card->number; -+ config->device = pcm->device; -+ audio->card = card; -+ return 0; -+ -+register_fail: -+pcm_fail: -+ snd_card_free(audio->card); -+ return err; -+} -+ -+static struct audio_source_instance *to_audio_source_instance( -+ struct config_item *item) -+{ -+ return container_of(to_config_group(item), struct audio_source_instance, -+ func_inst.group); -+} -+ -+static struct audio_source_instance *to_fi_audio_source( -+ const struct usb_function_instance *fi) -+{ -+ return container_of(fi, struct audio_source_instance, func_inst); -+} -+ -+static void audio_source_attr_release(struct config_item *item) -+{ -+ struct audio_source_instance *fi_audio = to_audio_source_instance(item); -+ -+ usb_put_function_instance(&fi_audio->func_inst); -+} -+ -+static int audio_source_set_inst_name(struct usb_function_instance *fi, -+ const char *name) -+{ -+ struct audio_source_instance *fi_audio; -+ char *ptr; -+ int name_len; -+ -+ name_len = strlen(name) + 1; -+ if (name_len > MAX_INST_NAME_LEN) -+ return -ENAMETOOLONG; -+ -+ ptr = kstrndup(name, name_len, GFP_KERNEL); -+ if (!ptr) -+ return -ENOMEM; -+ -+ fi_audio = to_fi_audio_source(fi); -+ fi_audio->name = ptr; -+ -+ return 0; -+} -+ -+static void audio_source_free_inst(struct usb_function_instance *fi) -+{ -+ struct audio_source_instance *fi_audio; -+ -+ fi_audio = to_fi_audio_source(fi); -+ device_destroy(fi_audio->audio_device->class, -+ fi_audio->audio_device->devt); -+ kfree(fi_audio->name); -+ kfree(fi_audio->config); -+} -+ -+static ssize_t audio_source_pcm_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct audio_source_instance *fi_audio = dev_get_drvdata(dev); -+ struct audio_source_config *config = fi_audio->config; -+ -+ /* print PCM card and device numbers */ -+ return sprintf(buf, "%d %d\n", config->card, config->device); -+} -+ -+struct device *create_function_device(char *name); -+ -+static struct usb_function_instance *audio_source_alloc_inst(void) -+{ -+ struct audio_source_instance *fi_audio; -+ struct device_attribute **attrs; -+ struct device_attribute *attr; -+ struct device *dev; -+ void *err_ptr; -+ int err = 0; -+ -+ fi_audio = kzalloc(sizeof(*fi_audio), GFP_KERNEL); -+ if (!fi_audio) -+ return ERR_PTR(-ENOMEM); -+ -+ fi_audio->func_inst.set_inst_name = audio_source_set_inst_name; -+ fi_audio->func_inst.free_func_inst = audio_source_free_inst; -+ -+ fi_audio->config = kzalloc(sizeof(struct audio_source_config), -+ GFP_KERNEL); -+ if (!fi_audio->config) { -+ err_ptr = ERR_PTR(-ENOMEM); -+ goto fail_audio; -+ } -+ -+ config_group_init_type_name(&fi_audio->func_inst.group, "", -+ &audio_source_func_type); -+ dev = create_function_device("f_audio_source"); -+ -+ if (IS_ERR(dev)) { -+ err_ptr = dev; -+ goto fail_audio_config; -+ } -+ -+ fi_audio->config->card = -1; -+ fi_audio->config->device = -1; -+ fi_audio->audio_device = dev; -+ -+ attrs = audio_source_function_attributes; -+ if (attrs) { -+ while ((attr = *attrs++) && !err) -+ err = device_create_file(dev, attr); -+ if (err) { -+ err_ptr = ERR_PTR(-EINVAL); -+ goto fail_device; -+ } -+ } -+ -+ dev_set_drvdata(dev, fi_audio); -+ _audio_dev.config = fi_audio->config; -+ -+ return &fi_audio->func_inst; -+ -+fail_device: -+ device_destroy(dev->class, dev->devt); -+fail_audio_config: -+ kfree(fi_audio->config); -+fail_audio: -+ kfree(fi_audio); -+ return err_ptr; -+ -+} -+ -+static struct usb_function *audio_source_alloc(struct usb_function_instance *fi) -+{ -+ return &_audio_dev.func; -+} -+ -+DECLARE_USB_FUNCTION_INIT(audio_source, audio_source_alloc_inst, -+ audio_source_alloc); -+MODULE_LICENSE("GPL"); diff --git a/patches/ANDROID-usb-gadget-f_midi-create-F_midi-device.patch b/patches/ANDROID-usb-gadget-f_midi-create-F_midi-device.patch deleted file mode 100644 index cf8585458ee2..000000000000 --- a/patches/ANDROID-usb-gadget-f_midi-create-F_midi-device.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Badhri Jagan Sridharan -Date: Wed, 2 Sep 2015 22:49:10 -0700 -Subject: ANDROID: usb: gadget: f_midi: create F_midi device - -Android frameworks relies on the alsa -config reported by the f_midi device. - -Bug: 111003288 -Bug: 120441124 -Change-Id: I0695e00b166fd953f50acea93802245b0d5a5240 -[badhri: The framework should be moved away from this] -Signed-off-by: Badhri Jagan Sridharan ---- - drivers/usb/gadget/function/f_midi.c | 65 ++++++++++++++++++++++++++++ - 1 file changed, 65 insertions(+) - -diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c -index 46af0aa07e2e..2a86b3cf313f 100644 ---- a/drivers/usb/gadget/function/f_midi.c -+++ b/drivers/usb/gadget/function/f_midi.c -@@ -1216,6 +1216,65 @@ static void f_midi_free_inst(struct usb_function_instance *f) - } - } - -+#ifdef CONFIG_USB_CONFIGFS_UEVENT -+extern struct device *create_function_device(char *name); -+static ssize_t alsa_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct usb_function_instance *fi_midi = dev_get_drvdata(dev); -+ struct f_midi *midi; -+ -+ if (!fi_midi->f) -+ dev_warn(dev, "f_midi: function not set\n"); -+ -+ if (fi_midi && fi_midi->f) { -+ midi = func_to_midi(fi_midi->f); -+ if (midi->rmidi && midi->rmidi->card) -+ return sprintf(buf, "%d %d\n", -+ midi->rmidi->card->number, midi->rmidi->device); -+ } -+ -+ /* print PCM card and device numbers */ -+ return sprintf(buf, "%d %d\n", -1, -1); -+} -+ -+static DEVICE_ATTR(alsa, S_IRUGO, alsa_show, NULL); -+ -+static struct device_attribute *alsa_function_attributes[] = { -+ &dev_attr_alsa, -+ NULL -+}; -+ -+static int create_alsa_device(struct usb_function_instance *fi) -+{ -+ struct device *dev; -+ struct device_attribute **attrs; -+ struct device_attribute *attr; -+ int err = 0; -+ -+ dev = create_function_device("f_midi"); -+ if (IS_ERR(dev)) -+ return PTR_ERR(dev); -+ -+ attrs = alsa_function_attributes; -+ if (attrs) { -+ while ((attr = *attrs++) && !err) -+ err = device_create_file(dev, attr); -+ if (err) { -+ device_destroy(dev->class, dev->devt); -+ return -EINVAL; -+ } -+ } -+ dev_set_drvdata(dev, fi); -+ return 0; -+} -+#else -+static int create_alsa_device(struct usb_function_instance *fi) -+{ -+ return 0; -+} -+#endif -+ - static struct usb_function_instance *f_midi_alloc_inst(void) - { - struct f_midi_opts *opts; -@@ -1234,6 +1293,11 @@ static struct usb_function_instance *f_midi_alloc_inst(void) - opts->out_ports = 1; - opts->refcnt = 1; - -+ if (create_alsa_device(&opts->func_inst)) { -+ kfree(opts); -+ return ERR_PTR(-ENODEV); -+ } -+ - config_group_init_type_name(&opts->func_inst.group, "", - &midi_func_type); - -@@ -1341,6 +1405,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) - midi->func.disable = f_midi_disable; - midi->func.free_func = f_midi_free; - -+ fi->f = &midi->func; - return &midi->func; - - setup_fail: diff --git a/patches/ANDROID-usb-gadget-f_midi-set-fi-f-to-NULL-when-free-f_midi-function.patch b/patches/ANDROID-usb-gadget-f_midi-set-fi-f-to-NULL-when-free-f_midi-function.patch deleted file mode 100644 index 05fe9c48df43..000000000000 --- a/patches/ANDROID-usb-gadget-f_midi-set-fi-f-to-NULL-when-free-f_midi-function.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Winter Wang -Date: Fri, 20 May 2016 11:05:00 +0800 -Subject: ANDROID: usb: gadget: f_midi: set fi->f to NULL when free f_midi - function - -fi->f is set in f_midi's alloc_func, need to clean this to -NULL in free_func, otherwise on ConfigFS's function switch, -midi->usb_function it self is freed, fi->f will be a wild -pointer and run into below kernel panic: ---------------- -[ 58.950628] Unable to handle kernel paging request at virtual address 63697664 -[ 58.957869] pgd = c0004000 -[ 58.960583] [63697664] *pgd=00000000 -[ 58.964185] Internal error: Oops: 80000005 [#1] PREEMPT SMP ARM -[ 58.970111] Modules linked in: -[ 58.973191] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.1.15-03504-g34c857c-dirty #89 -[ 58.981024] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) -[ 58.987557] task: c110bd70 ti: c1100000 task.ti: c1100000 -[ 58.992962] PC is at 0x63697664 -[ 58.996120] LR is at android_setup+0x78/0x138 -<..snip..> -[ 60.044980] 1fc0: ffffffff ffffffff c1000684 00000000 00000000 c108ecd0 c11f7294 c11039c0 -[ 60.053181] 1fe0: c108eccc c110d148 1000406a 412fc09a 00000000 1000807c 00000000 00000000 -[ 60.061420] [] (android_setup) from [] (udc_irq+0x758/0x1034) -[ 60.068951] [] (udc_irq) from [] (handle_irq_event_percpu+0x50/0x254) -[ 60.077165] [] (handle_irq_event_percpu) from [] (handle_irq_event+0x3c/0x5c) -[ 60.086072] [] (handle_irq_event) from [] (handle_fasteoi_irq+0xe0/0x198) -[ 60.094630] [] (handle_fasteoi_irq) from [] (generic_handle_irq+0x2c/0x3c) -[ 60.103271] [] (generic_handle_irq) from [] (__handle_domain_irq+0x7c/0xec) -[ 60.112000] [] (__handle_domain_irq) from [] (gic_handle_irq+0x24/0x5c) --------------- - -Bug: 111003288 -Bug: 120441124 -Change-Id: Iaf7cc809379c184048a2d9ab1f59e71ebaa3416e -Signed-off-by: Winter Wang ---- - drivers/usb/gadget/function/f_midi.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c -index 2a86b3cf313f..4713a1c7f622 100644 ---- a/drivers/usb/gadget/function/f_midi.c -+++ b/drivers/usb/gadget/function/f_midi.c -@@ -1318,6 +1318,7 @@ static void f_midi_free(struct usb_function *f) - kfifo_free(&midi->in_req_fifo); - kfree(midi); - free = true; -+ opts->func_inst.f = NULL; - } - mutex_unlock(&opts->lock); - diff --git a/patches/ANDROID-vfs-Add-permission2-for-filesystems-with-per-mount-permissions.patch b/patches/ANDROID-vfs-Add-permission2-for-filesystems-with-per-mount-permissions.patch deleted file mode 100644 index cf21b50796a5..000000000000 --- a/patches/ANDROID-vfs-Add-permission2-for-filesystems-with-per-mount-permissions.patch +++ /dev/null @@ -1,892 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Rosenberg -Date: Wed, 26 Oct 2016 16:27:45 -0700 -Subject: ANDROID: vfs: Add permission2 for filesystems with per mount - permissions - -This allows filesystems to use their mount private data to -influence the permssions they return in permission2. It has -been separated into a new call to avoid disrupting current -permission users. - -Test: HiKey/X15 + Pie + android-mainline, - and HiKey + AOSP Maser + android-mainline, - directories under /sdcard created, - output of mount is right, - CTS test collecting device infor works - -Bug: 35848445 -Change-Id: I9d416e3b8b6eca84ef3e336bd2af89ddd51df6ca -Signed-off-by: Daniel Rosenberg -[AmitP: Minor refactoring of original patch to align with - changes from the following upstream commit - 4bfd054ae11e ("fs: fold __inode_permission() into inode_permission()"). - Also introduce vfs_mkobj2(), because do_create() - moved from using vfs_create() to vfs_mkobj() - eecec19d9e70 ("mqueue: switch to vfs_mkobj(), quit abusing ->d_fsdata") - do_create() is dropped/cleaned-up upstream so a - minor refactoring there as well. - 066cc813e94a ("do_mq_open(): move all work prior to dentry_open() into a helper")] -Signed-off-by: Amit Pundir -[astrachan: Folded the following changes into this patch: - f46c9d62dd81 ("ANDROID: fs: Export vfs_rmdir2") - 9992eb8b9a1e ("ANDROID: xattr: Pass EOPNOTSUPP to permission2")] -Signed-off-by: Alistair Strachan -Signed-off-by: Yongqin Liu ---- - fs/attr.c | 2 +- - fs/exec.c | 2 +- - fs/namei.c | 187 ++++++++++++++++++++--------- - fs/notify/fanotify/fanotify_user.c | 2 +- - fs/notify/inotify/inotify_user.c | 2 +- - fs/open.c | 13 +- - fs/xattr.c | 2 +- - include/linux/fs.h | 13 ++ - include/linux/namei.h | 1 + - ipc/mqueue.c | 14 +-- - security/inode.c | 2 +- - 11 files changed, 168 insertions(+), 72 deletions(-) - -diff --git a/fs/attr.c b/fs/attr.c -index 0a7f9d67bb35..be094ea6a330 100644 ---- a/fs/attr.c -+++ b/fs/attr.c -@@ -250,7 +250,7 @@ int notify_change2(struct vfsmount *mnt, struct dentry * dentry, struct iattr * - return -EPERM; - - if (!inode_owner_or_capable(inode)) { -- error = inode_permission(inode, MAY_WRITE); -+ error = inode_permission2(mnt, inode, MAY_WRITE); - if (error) - return error; - } -diff --git a/fs/exec.c b/fs/exec.c -index 555e93c7dec8..34df3b6cf448 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -1313,7 +1313,7 @@ EXPORT_SYMBOL(flush_old_exec); - void would_dump(struct linux_binprm *bprm, struct file *file) - { - struct inode *inode = file_inode(file); -- if (inode_permission(inode, MAY_READ) < 0) { -+ if (inode_permission2(file->f_path.mnt, inode, MAY_READ) < 0) { - struct user_namespace *old, *user_ns; - bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP; - -diff --git a/fs/namei.c b/fs/namei.c -index 8a77269e644f..819aa30eea6e 100644 ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -377,9 +377,11 @@ EXPORT_SYMBOL(generic_permission); - * flag in inode->i_opflags, that says "this has not special - * permission function, use the fast case". - */ --static inline int do_inode_permission(struct inode *inode, int mask) -+static inline int do_inode_permission(struct vfsmount *mnt, struct inode *inode, int mask) - { - if (unlikely(!(inode->i_opflags & IOP_FASTPERM))) { -+ if (likely(mnt && inode->i_op->permission2)) -+ return inode->i_op->permission2(mnt, inode, mask); - if (likely(inode->i_op->permission)) - return inode->i_op->permission(inode, mask); - -@@ -412,7 +414,8 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) - } - - /** -- * inode_permission - Check for access rights to a given inode -+ * inode_permission2 - Check for access rights to a given inode -+ * @mnt: - * @inode: Inode to check permission on - * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) - * -@@ -422,7 +425,7 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) - * - * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. - */ --int inode_permission(struct inode *inode, int mask) -+int inode_permission2(struct vfsmount *mnt, struct inode *inode, int mask) - { - int retval; - -@@ -446,7 +449,7 @@ int inode_permission(struct inode *inode, int mask) - return -EACCES; - } - -- retval = do_inode_permission(inode, mask); -+ retval = do_inode_permission(mnt, inode, mask); - if (retval) - return retval; - -@@ -454,7 +457,14 @@ int inode_permission(struct inode *inode, int mask) - if (retval) - return retval; - -- return security_inode_permission(inode, mask); -+ retval = security_inode_permission(inode, mask); -+ return retval; -+} -+EXPORT_SYMBOL(inode_permission2); -+ -+int inode_permission(struct inode *inode, int mask) -+{ -+ return inode_permission2(NULL, inode, mask); - } - EXPORT_SYMBOL(inode_permission); - -@@ -1685,13 +1695,13 @@ static struct dentry *lookup_slow(const struct qstr *name, - static inline int may_lookup(struct nameidata *nd) - { - if (nd->flags & LOOKUP_RCU) { -- int err = inode_permission(nd->inode, MAY_EXEC|MAY_NOT_BLOCK); -+ int err = inode_permission2(nd->path.mnt, nd->inode, MAY_EXEC|MAY_NOT_BLOCK); - if (err != -ECHILD) - return err; - if (unlazy_walk(nd)) - return -ECHILD; - } -- return inode_permission(nd->inode, MAY_EXEC); -+ return inode_permission2(nd->path.mnt, nd->inode, MAY_EXEC); - } - - static inline int handle_dots(struct nameidata *nd, int type) -@@ -2445,8 +2455,8 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, - } - EXPORT_SYMBOL(vfs_path_lookup); - --static int lookup_one_len_common(const char *name, struct dentry *base, -- int len, struct qstr *this) -+static int lookup_one_len_common(const char *name, struct vfsmount *mnt, -+ struct dentry *base, int len, struct qstr *this) - { - this->name = name; - this->len = len; -@@ -2474,7 +2484,7 @@ static int lookup_one_len_common(const char *name, struct dentry *base, - return err; - } - -- return inode_permission(base->d_inode, MAY_EXEC); -+ return inode_permission2(mnt, base->d_inode, MAY_EXEC); - } - - /** -@@ -2498,7 +2508,7 @@ struct dentry *try_lookup_one_len(const char *name, struct dentry *base, int len - - WARN_ON_ONCE(!inode_is_locked(base->d_inode)); - -- err = lookup_one_len_common(name, base, len, &this); -+ err = lookup_one_len_common(name, NULL, base, len, &this); - if (err) - return ERR_PTR(err); - -@@ -2517,7 +2527,7 @@ EXPORT_SYMBOL(try_lookup_one_len); - * - * The caller must hold base->i_mutex. - */ --struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) -+struct dentry *lookup_one_len2(const char *name, struct vfsmount *mnt, struct dentry *base, int len) - { - struct dentry *dentry; - struct qstr this; -@@ -2525,13 +2535,19 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) - - WARN_ON_ONCE(!inode_is_locked(base->d_inode)); - -- err = lookup_one_len_common(name, base, len, &this); -+ err = lookup_one_len_common(name, mnt, base, len, &this); - if (err) - return ERR_PTR(err); - - dentry = lookup_dcache(&this, base, 0); - return dentry ? dentry : __lookup_slow(&this, base, 0); - } -+EXPORT_SYMBOL(lookup_one_len2); -+ -+struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) -+{ -+ return lookup_one_len2(name, NULL, base, len); -+} - EXPORT_SYMBOL(lookup_one_len); - - /** -@@ -2553,7 +2569,7 @@ struct dentry *lookup_one_len_unlocked(const char *name, - int err; - struct dentry *ret; - -- err = lookup_one_len_common(name, base, len, &this); -+ err = lookup_one_len_common(name, NULL, base, len, &this); - if (err) - return ERR_PTR(err); - -@@ -2777,7 +2793,7 @@ EXPORT_SYMBOL(__check_sticky); - * 11. We don't allow removal of NFS sillyrenamed files; it's handled by - * nfs_async_unlink(). - */ --static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) -+static int may_delete(struct vfsmount *mnt, struct inode *dir, struct dentry *victim, bool isdir) - { - struct inode *inode = d_backing_inode(victim); - int error; -@@ -2794,7 +2810,7 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) - - audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); - -- error = inode_permission(dir, MAY_WRITE | MAY_EXEC); -+ error = inode_permission2(mnt, dir, MAY_WRITE | MAY_EXEC); - if (error) - return error; - if (IS_APPEND(dir)) -@@ -2826,7 +2842,7 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) - * 4. We should have write and exec permissions on dir - * 5. We can't do it if dir is immutable (done in permission()) - */ --static inline int may_create(struct inode *dir, struct dentry *child) -+static inline int may_create(struct vfsmount *mnt, struct inode *dir, struct dentry *child) - { - struct user_namespace *s_user_ns; - audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE); -@@ -2838,7 +2854,7 @@ static inline int may_create(struct inode *dir, struct dentry *child) - if (!kuid_has_mapping(s_user_ns, current_fsuid()) || - !kgid_has_mapping(s_user_ns, current_fsgid())) - return -EOVERFLOW; -- return inode_permission(dir, MAY_WRITE | MAY_EXEC); -+ return inode_permission2(mnt, dir, MAY_WRITE | MAY_EXEC); - } - - /* -@@ -2885,10 +2901,10 @@ void unlock_rename(struct dentry *p1, struct dentry *p2) - } - EXPORT_SYMBOL(unlock_rename); - --int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, -- bool want_excl) -+int vfs_create2(struct vfsmount *mnt, struct inode *dir, struct dentry *dentry, -+ umode_t mode, bool want_excl) - { -- int error = may_create(dir, dentry); -+ int error = may_create(mnt, dir, dentry); - if (error) - return error; - -@@ -2904,14 +2920,21 @@ int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, - fsnotify_create(dir, dentry); - return error; - } -+EXPORT_SYMBOL(vfs_create2); -+ -+int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, -+ bool want_excl) -+{ -+ return vfs_create2(NULL, dir, dentry, mode, want_excl); -+} - EXPORT_SYMBOL(vfs_create); - --int vfs_mkobj(struct dentry *dentry, umode_t mode, -+int vfs_mkobj2(struct vfsmount *mnt, struct dentry *dentry, umode_t mode, - int (*f)(struct dentry *, umode_t, void *), - void *arg) - { - struct inode *dir = dentry->d_parent->d_inode; -- int error = may_create(dir, dentry); -+ int error = may_create(mnt, dir, dentry); - if (error) - return error; - -@@ -2925,6 +2948,15 @@ int vfs_mkobj(struct dentry *dentry, umode_t mode, - fsnotify_create(dir, dentry); - return error; - } -+EXPORT_SYMBOL(vfs_mkobj2); -+ -+ -+int vfs_mkobj(struct dentry *dentry, umode_t mode, -+ int (*f)(struct dentry *, umode_t, void *), -+ void *arg) -+{ -+ return vfs_mkobj2(NULL, dentry, mode, f, arg); -+} - EXPORT_SYMBOL(vfs_mkobj); - - bool may_open_dev(const struct path *path) -@@ -2936,6 +2968,7 @@ bool may_open_dev(const struct path *path) - static int may_open(const struct path *path, int acc_mode, int flag) - { - struct dentry *dentry = path->dentry; -+ struct vfsmount *mnt = path->mnt; - struct inode *inode = dentry->d_inode; - int error; - -@@ -2960,7 +2993,7 @@ static int may_open(const struct path *path, int acc_mode, int flag) - break; - } - -- error = inode_permission(inode, MAY_OPEN | acc_mode); -+ error = inode_permission2(mnt, inode, MAY_OPEN | acc_mode); - if (error) - return error; - -@@ -3022,7 +3055,7 @@ static int may_o_create(const struct path *dir, struct dentry *dentry, umode_t m - !kgid_has_mapping(s_user_ns, current_fsgid())) - return -EOVERFLOW; - -- error = inode_permission(dir->dentry->d_inode, MAY_WRITE | MAY_EXEC); -+ error = inode_permission2(dir->mnt, dir->dentry->d_inode, MAY_WRITE | MAY_EXEC); - if (error) - return error; - -@@ -3430,7 +3463,8 @@ struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, int open_flag) - int error; - - /* we want directory to be writable */ -- error = inode_permission(dir, MAY_WRITE | MAY_EXEC); -+ error = inode_permission2(ERR_PTR(-EOPNOTSUPP), dir, -+ MAY_WRITE | MAY_EXEC); - if (error) - goto out_err; - error = -EOPNOTSUPP; -@@ -3685,9 +3719,9 @@ inline struct dentry *user_path_create(int dfd, const char __user *pathname, - } - EXPORT_SYMBOL(user_path_create); - --int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) -+int vfs_mknod2(struct vfsmount *mnt, struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) - { -- int error = may_create(dir, dentry); -+ int error = may_create(mnt, dir, dentry); - - if (error) - return error; -@@ -3711,6 +3745,12 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) - fsnotify_create(dir, dentry); - return error; - } -+EXPORT_SYMBOL(vfs_mknod2); -+ -+int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) -+{ -+ return vfs_mknod2(NULL, dir, dentry, mode, dev); -+} - EXPORT_SYMBOL(vfs_mknod); - - static int may_mknod(umode_t mode) -@@ -3753,12 +3793,12 @@ long do_mknodat(int dfd, const char __user *filename, umode_t mode, - goto out; - switch (mode & S_IFMT) { - case 0: case S_IFREG: -- error = vfs_create(path.dentry->d_inode,dentry,mode,true); -+ error = vfs_create2(path.mnt, path.dentry->d_inode,dentry,mode,true); - if (!error) - ima_post_path_mknod(dentry); - break; - case S_IFCHR: case S_IFBLK: -- error = vfs_mknod(path.dentry->d_inode,dentry,mode, -+ error = vfs_mknod2(path.mnt, path.dentry->d_inode,dentry,mode, - new_decode_dev(dev)); - break; - case S_IFIFO: case S_IFSOCK: -@@ -3785,9 +3825,9 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d - return do_mknodat(AT_FDCWD, filename, mode, dev); - } - --int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) -+int vfs_mkdir2(struct vfsmount *mnt, struct inode *dir, struct dentry *dentry, umode_t mode) - { -- int error = may_create(dir, dentry); -+ int error = may_create(mnt, dir, dentry); - unsigned max_links = dir->i_sb->s_max_links; - - if (error) -@@ -3809,6 +3849,12 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) - fsnotify_mkdir(dir, dentry); - return error; - } -+EXPORT_SYMBOL(vfs_mkdir2); -+ -+int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) -+{ -+ return vfs_mkdir2(NULL, dir, dentry, mode); -+} - EXPORT_SYMBOL(vfs_mkdir); - - long do_mkdirat(int dfd, const char __user *pathname, umode_t mode) -@@ -3827,7 +3873,7 @@ long do_mkdirat(int dfd, const char __user *pathname, umode_t mode) - mode &= ~current_umask(); - error = security_path_mkdir(&path, dentry, mode); - if (!error) -- error = vfs_mkdir(path.dentry->d_inode, dentry, mode); -+ error = vfs_mkdir2(path.mnt, path.dentry->d_inode, dentry, mode); - done_path_create(&path, dentry); - if (retry_estale(error, lookup_flags)) { - lookup_flags |= LOOKUP_REVAL; -@@ -3846,9 +3892,9 @@ SYSCALL_DEFINE2(mkdir, const char __user *, pathname, umode_t, mode) - return do_mkdirat(AT_FDCWD, pathname, mode); - } - --int vfs_rmdir(struct inode *dir, struct dentry *dentry) -+int vfs_rmdir2(struct vfsmount *mnt, struct inode *dir, struct dentry *dentry) - { -- int error = may_delete(dir, dentry, 1); -+ int error = may_delete(mnt, dir, dentry, 1); - - if (error) - return error; -@@ -3884,6 +3930,12 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) - d_delete(dentry); - return error; - } -+EXPORT_SYMBOL(vfs_rmdir2); -+ -+int vfs_rmdir(struct inode *dir, struct dentry *dentry) -+{ -+ return vfs_rmdir2(NULL, dir, dentry); -+} - EXPORT_SYMBOL(vfs_rmdir); - - long do_rmdir(int dfd, const char __user *pathname) -@@ -3929,7 +3981,7 @@ long do_rmdir(int dfd, const char __user *pathname) - error = security_path_rmdir(&path, dentry); - if (error) - goto exit3; -- error = vfs_rmdir(path.dentry->d_inode, dentry); -+ error = vfs_rmdir2(path.mnt, path.dentry->d_inode, dentry); - exit3: - dput(dentry); - exit2: -@@ -3968,10 +4020,10 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname) - * be appropriate for callers that expect the underlying filesystem not - * to be NFS exported. - */ --int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) -+int vfs_unlink2(struct vfsmount *mnt, struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) - { - struct inode *target = dentry->d_inode; -- int error = may_delete(dir, dentry, 0); -+ int error = may_delete(mnt, dir, dentry, 0); - - if (error) - return error; -@@ -4007,6 +4059,12 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegate - - return error; - } -+EXPORT_SYMBOL(vfs_unlink2); -+ -+int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) -+{ -+ return vfs_unlink2(NULL, dir, dentry, delegated_inode); -+} - EXPORT_SYMBOL(vfs_unlink); - - /* -@@ -4052,7 +4110,7 @@ long do_unlinkat(int dfd, struct filename *name) - error = security_path_unlink(&path, dentry); - if (error) - goto exit2; -- error = vfs_unlink(path.dentry->d_inode, dentry, &delegated_inode); -+ error = vfs_unlink2(path.mnt, path.dentry->d_inode, dentry, &delegated_inode); - exit2: - dput(dentry); - } -@@ -4102,9 +4160,9 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname) - return do_unlinkat(AT_FDCWD, getname(pathname)); - } - --int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) -+int vfs_symlink2(struct vfsmount *mnt, struct inode *dir, struct dentry *dentry, const char *oldname) - { -- int error = may_create(dir, dentry); -+ int error = may_create(mnt, dir, dentry); - - if (error) - return error; -@@ -4121,6 +4179,12 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) - fsnotify_create(dir, dentry); - return error; - } -+EXPORT_SYMBOL(vfs_symlink2); -+ -+int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) -+{ -+ return vfs_symlink2(NULL, dir, dentry, oldname); -+} - EXPORT_SYMBOL(vfs_symlink); - - long do_symlinkat(const char __user *oldname, int newdfd, -@@ -4143,7 +4207,7 @@ long do_symlinkat(const char __user *oldname, int newdfd, - - error = security_path_symlink(&path, dentry, from->name); - if (!error) -- error = vfs_symlink(path.dentry->d_inode, dentry, from->name); -+ error = vfs_symlink2(path.mnt, path.dentry->d_inode, dentry, from->name); - done_path_create(&path, dentry); - if (retry_estale(error, lookup_flags)) { - lookup_flags |= LOOKUP_REVAL; -@@ -4184,7 +4248,7 @@ SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newn - * be appropriate for callers that expect the underlying filesystem not - * to be NFS exported. - */ --int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry, struct inode **delegated_inode) -+int vfs_link2(struct vfsmount *mnt, struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry, struct inode **delegated_inode) - { - struct inode *inode = old_dentry->d_inode; - unsigned max_links = dir->i_sb->s_max_links; -@@ -4193,7 +4257,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de - if (!inode) - return -ENOENT; - -- error = may_create(dir, new_dentry); -+ error = may_create(mnt, dir, new_dentry); - if (error) - return error; - -@@ -4243,6 +4307,12 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de - fsnotify_link(dir, inode, new_dentry); - return error; - } -+EXPORT_SYMBOL(vfs_link2); -+ -+int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry, struct inode **delegated_inode) -+{ -+ return vfs_link2(NULL, old_dentry, dir, new_dentry, delegated_inode); -+} - EXPORT_SYMBOL(vfs_link); - - /* -@@ -4298,7 +4368,7 @@ int do_linkat(int olddfd, const char __user *oldname, int newdfd, - error = security_path_link(old_path.dentry, &new_path, new_dentry); - if (error) - goto out_dput; -- error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry, &delegated_inode); -+ error = vfs_link2(old_path.mnt, old_path.dentry, new_path.dentry->d_inode, new_dentry, &delegated_inode); - out_dput: - done_path_create(&new_path, new_dentry); - if (delegated_inode) { -@@ -4380,7 +4450,8 @@ SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname - * ->i_mutex on parents, which works but leads to some truly excessive - * locking]. - */ --int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+int vfs_rename2(struct vfsmount *mnt, -+ struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry, - struct inode **delegated_inode, unsigned int flags) - { -@@ -4395,19 +4466,19 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, - if (source == target) - return 0; - -- error = may_delete(old_dir, old_dentry, is_dir); -+ error = may_delete(mnt, old_dir, old_dentry, is_dir); - if (error) - return error; - - if (!target) { -- error = may_create(new_dir, new_dentry); -+ error = may_create(mnt, new_dir, new_dentry); - } else { - new_is_dir = d_is_dir(new_dentry); - - if (!(flags & RENAME_EXCHANGE)) -- error = may_delete(new_dir, new_dentry, is_dir); -+ error = may_delete(mnt, new_dir, new_dentry, is_dir); - else -- error = may_delete(new_dir, new_dentry, new_is_dir); -+ error = may_delete(mnt, new_dir, new_dentry, new_is_dir); - } - if (error) - return error; -@@ -4421,12 +4492,12 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, - */ - if (new_dir != old_dir) { - if (is_dir) { -- error = inode_permission(source, MAY_WRITE); -+ error = inode_permission2(mnt, source, MAY_WRITE); - if (error) - return error; - } - if ((flags & RENAME_EXCHANGE) && new_is_dir) { -- error = inode_permission(target, MAY_WRITE); -+ error = inode_permission2(mnt, target, MAY_WRITE); - if (error) - return error; - } -@@ -4503,6 +4574,14 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, - - return error; - } -+EXPORT_SYMBOL(vfs_rename2); -+ -+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct inode **delegated_inode, unsigned int flags) -+{ -+ return vfs_rename2(NULL, old_dir, old_dentry, new_dir, new_dentry, delegated_inode, flags); -+} - EXPORT_SYMBOL(vfs_rename); - - static int do_renameat2(int olddfd, const char __user *oldname, int newdfd, -@@ -4616,7 +4695,7 @@ static int do_renameat2(int olddfd, const char __user *oldname, int newdfd, - &new_path, new_dentry, flags); - if (error) - goto exit5; -- error = vfs_rename(old_path.dentry->d_inode, old_dentry, -+ error = vfs_rename2(old_path.mnt, old_path.dentry->d_inode, old_dentry, - new_path.dentry->d_inode, new_dentry, - &delegated_inode, flags); - exit5: -@@ -4667,7 +4746,7 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna - - int vfs_whiteout(struct inode *dir, struct dentry *dentry) - { -- int error = may_create(dir, dentry); -+ int error = may_create(NULL, dir, dentry); - if (error) - return error; - -diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c -index 8508ab575017..2e667cb8d69e 100644 ---- a/fs/notify/fanotify/fanotify_user.c -+++ b/fs/notify/fanotify/fanotify_user.c -@@ -567,7 +567,7 @@ static int fanotify_find_path(int dfd, const char __user *filename, - } - - /* you can only watch an inode if you have read permissions on it */ -- ret = inode_permission(path->dentry->d_inode, MAY_READ); -+ ret = inode_permission2(path->mnt, path->dentry->d_inode, MAY_READ); - if (ret) { - path_put(path); - goto out; -diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c -index 107537a543fd..3e66e6c8f53a 100644 ---- a/fs/notify/inotify/inotify_user.c -+++ b/fs/notify/inotify/inotify_user.c -@@ -341,7 +341,7 @@ static int inotify_find_inode(const char __user *dirname, struct path *path, - if (error) - return error; - /* you can only watch an inode if you have read permissions on it */ -- error = inode_permission(path->dentry->d_inode, MAY_READ); -+ error = inode_permission2(path->mnt, path->dentry->d_inode, MAY_READ); - if (error) { - path_put(path); - return error; -diff --git a/fs/open.c b/fs/open.c -index a189284464a0..681affa0cb37 100644 ---- a/fs/open.c -+++ b/fs/open.c -@@ -90,7 +90,7 @@ long vfs_truncate(const struct path *path, loff_t length) - if (error) - goto out; - -- error = inode_permission(inode, MAY_WRITE); -+ error = inode_permission2(mnt, inode, MAY_WRITE); - if (error) - goto mnt_drop_write_and_out; - -@@ -360,6 +360,7 @@ long do_faccessat(int dfd, const char __user *filename, int mode) - struct cred *override_cred; - struct path path; - struct inode *inode; -+ struct vfsmount *mnt; - int res; - unsigned int lookup_flags = LOOKUP_FOLLOW; - -@@ -409,6 +410,7 @@ long do_faccessat(int dfd, const char __user *filename, int mode) - goto out; - - inode = d_backing_inode(path.dentry); -+ mnt = path.mnt; - - if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) { - /* -@@ -420,7 +422,7 @@ long do_faccessat(int dfd, const char __user *filename, int mode) - goto out_path_release; - } - -- res = inode_permission(inode, mode | MAY_ACCESS); -+ res = inode_permission2(mnt, inode, mode | MAY_ACCESS); - /* SuS v2 requires we report a read only fs too */ - if (res || !(mode & S_IWOTH) || special_file(inode->i_mode)) - goto out_path_release; -@@ -469,7 +471,7 @@ int ksys_chdir(const char __user *filename) - if (error) - goto out; - -- error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR); -+ error = inode_permission2(path.mnt, path.dentry->d_inode, MAY_EXEC | MAY_CHDIR); - if (error) - goto dput_and_out; - -@@ -503,7 +505,8 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd) - if (!d_can_lookup(f.file->f_path.dentry)) - goto out_putf; - -- error = inode_permission(file_inode(f.file), MAY_EXEC | MAY_CHDIR); -+ error = inode_permission2(f.file->f_path.mnt, file_inode(f.file), -+ MAY_EXEC | MAY_CHDIR); - if (!error) - set_fs_pwd(current->fs, &f.file->f_path); - out_putf: -@@ -522,7 +525,7 @@ int ksys_chroot(const char __user *filename) - if (error) - goto out; - -- error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR); -+ error = inode_permission2(path.mnt, path.dentry->d_inode, MAY_EXEC | MAY_CHDIR); - if (error) - goto dput_and_out; - -diff --git a/fs/xattr.c b/fs/xattr.c -index 90dd78f0eb27..142fa44fa587 100644 ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -131,7 +131,7 @@ xattr_permission(struct inode *inode, const char *name, int mask) - return -EPERM; - } - -- return inode_permission(inode, mask); -+ return inode_permission2(ERR_PTR(-EOPNOTSUPP), inode, mask); - } - - int -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 35e662198dc5..42c2cfc33ce7 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1709,13 +1709,21 @@ extern bool inode_owner_or_capable(const struct inode *inode); - * VFS helper functions.. - */ - extern int vfs_create(struct inode *, struct dentry *, umode_t, bool); -+extern int vfs_create2(struct vfsmount *, struct inode *, struct dentry *, umode_t, bool); - extern int vfs_mkdir(struct inode *, struct dentry *, umode_t); -+extern int vfs_mkdir2(struct vfsmount *, struct inode *, struct dentry *, umode_t); - extern int vfs_mknod(struct inode *, struct dentry *, umode_t, dev_t); -+extern int vfs_mknod2(struct vfsmount *, struct inode *, struct dentry *, umode_t, dev_t); - extern int vfs_symlink(struct inode *, struct dentry *, const char *); -+extern int vfs_symlink2(struct vfsmount *, struct inode *, struct dentry *, const char *); - extern int vfs_link(struct dentry *, struct inode *, struct dentry *, struct inode **); -+extern int vfs_link2(struct vfsmount *, struct dentry *, struct inode *, struct dentry *, struct inode **); - extern int vfs_rmdir(struct inode *, struct dentry *); -+extern int vfs_rmdir2(struct vfsmount *, struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *, struct inode **); -+extern int vfs_unlink2(struct vfsmount *, struct inode *, struct dentry *, struct inode **); - extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **, unsigned int); -+extern int vfs_rename2(struct vfsmount *, struct inode *, struct dentry *, struct inode *, struct dentry *, struct inode **, unsigned int); - extern int vfs_whiteout(struct inode *, struct dentry *); - - extern struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, -@@ -1724,6 +1732,9 @@ extern struct dentry *vfs_tmpfile(struct dentry *dentry, umode_t mode, - int vfs_mkobj(struct dentry *, umode_t, - int (*f)(struct dentry *, umode_t, void *), - void *); -+int vfs_mkobj2(struct vfsmount *, struct dentry *, umode_t, -+ int (*f)(struct dentry *, umode_t, void *), -+ void *); - - extern long vfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); - -@@ -1857,6 +1868,7 @@ struct inode_operations { - struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int); - const char * (*get_link) (struct dentry *, struct inode *, struct delayed_call *); - int (*permission) (struct inode *, int); -+ int (*permission2) (struct vfsmount *, struct inode *, int); - struct posix_acl * (*get_acl)(struct inode *, int); - - int (*readlink) (struct dentry *, char __user *,int); -@@ -2871,6 +2883,7 @@ extern sector_t bmap(struct inode *, sector_t); - extern int notify_change(struct dentry *, struct iattr *, struct inode **); - extern int notify_change2(struct vfsmount *, struct dentry *, struct iattr *, struct inode **); - extern int inode_permission(struct inode *, int); -+extern int inode_permission2(struct vfsmount *, struct inode *, int); - extern int generic_permission(struct inode *, int); - extern int __check_sticky(struct inode *dir, struct inode *inode); - -diff --git a/include/linux/namei.h b/include/linux/namei.h -index 397a08ade6a2..cb288d62f1d6 100644 ---- a/include/linux/namei.h -+++ b/include/linux/namei.h -@@ -59,6 +59,7 @@ extern int kern_path_mountpoint(int, const char *, struct path *, unsigned int); - - extern struct dentry *try_lookup_one_len(const char *, struct dentry *, int); - extern struct dentry *lookup_one_len(const char *, struct dentry *, int); -+extern struct dentry *lookup_one_len2(const char *, struct vfsmount *mnt, struct dentry *, int); - extern struct dentry *lookup_one_len_unlocked(const char *, struct dentry *, int); - - extern int follow_down_one(struct path *); -diff --git a/ipc/mqueue.c b/ipc/mqueue.c -index 3d920ff15c80..948d116f3446 100644 ---- a/ipc/mqueue.c -+++ b/ipc/mqueue.c -@@ -768,7 +768,7 @@ static void remove_notification(struct mqueue_inode_info *info) - info->notify_user_ns = NULL; - } - --static int prepare_open(struct dentry *dentry, int oflag, int ro, -+static int prepare_open(struct vfsmount *mnt, struct dentry *dentry, int oflag, int ro, - umode_t mode, struct filename *name, - struct mq_attr *attr) - { -@@ -782,7 +782,7 @@ static int prepare_open(struct dentry *dentry, int oflag, int ro, - if (ro) - return ro; - audit_inode_parent_hidden(name, dentry->d_parent); -- return vfs_mkobj(dentry, mode & ~current_umask(), -+ return vfs_mkobj2(mnt, dentry, mode & ~current_umask(), - mqueue_create_attr, attr); - } - /* it already existed */ -@@ -792,7 +792,7 @@ static int prepare_open(struct dentry *dentry, int oflag, int ro, - if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) - return -EINVAL; - acc = oflag2acc[oflag & O_ACCMODE]; -- return inode_permission(d_inode(dentry), acc); -+ return inode_permission2(mnt, d_inode(dentry), acc); - } - - static int do_mq_open(const char __user *u_name, int oflag, umode_t mode, -@@ -816,13 +816,13 @@ static int do_mq_open(const char __user *u_name, int oflag, umode_t mode, - - ro = mnt_want_write(mnt); /* we'll drop it in any case */ - inode_lock(d_inode(root)); -- path.dentry = lookup_one_len(name->name, root, strlen(name->name)); -+ path.dentry = lookup_one_len2(name->name, mnt, root, strlen(name->name)); - if (IS_ERR(path.dentry)) { - error = PTR_ERR(path.dentry); - goto out_putfd; - } - path.mnt = mntget(mnt); -- error = prepare_open(path.dentry, oflag, ro, mode, name, attr); -+ error = prepare_open(path.mnt, path.dentry, oflag, ro, mode, name, attr); - if (!error) { - struct file *file = dentry_open(&path, oflag, current_cred()); - if (!IS_ERR(file)) -@@ -872,7 +872,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) - if (err) - goto out_name; - inode_lock_nested(d_inode(mnt->mnt_root), I_MUTEX_PARENT); -- dentry = lookup_one_len(name->name, mnt->mnt_root, -+ dentry = lookup_one_len2(name->name, mnt, mnt->mnt_root, - strlen(name->name)); - if (IS_ERR(dentry)) { - err = PTR_ERR(dentry); -@@ -884,7 +884,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) - err = -ENOENT; - } else { - ihold(inode); -- err = vfs_unlink(d_inode(dentry->d_parent), dentry, NULL); -+ err = vfs_unlink2(mnt, d_inode(dentry->d_parent), dentry, NULL); - } - dput(dentry); - -diff --git a/security/inode.c b/security/inode.c -index 6c326939750d..289504656ea9 100644 ---- a/security/inode.c -+++ b/security/inode.c -@@ -128,7 +128,7 @@ static struct dentry *securityfs_create_dentry(const char *name, umode_t mode, - dir = d_inode(parent); - - inode_lock(dir); -- dentry = lookup_one_len(name, parent, strlen(name)); -+ dentry = lookup_one_len2(name, mount, parent, strlen(name)); - if (IS_ERR(dentry)) - goto out; - diff --git a/patches/ANDROID-vfs-Add-setattr2-for-filesystems-with-per-mount-permissions.patch b/patches/ANDROID-vfs-Add-setattr2-for-filesystems-with-per-mount-permissions.patch deleted file mode 100644 index 2debdac52720..000000000000 --- a/patches/ANDROID-vfs-Add-setattr2-for-filesystems-with-per-mount-permissions.patch +++ /dev/null @@ -1,258 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Rosenberg -Date: Wed, 26 Oct 2016 16:33:11 -0700 -Subject: ANDROID: vfs: Add setattr2 for filesystems with per mount permissions - -This allows filesystems to use their mount private data to -influence the permssions they use in setattr2. It has -been separated into a new call to avoid disrupting current -setattr users. - -Test: HiKey/X15 + Pie + android-mainline, - and HiKey + AOSP Maser + android-mainline, - directories under /sdcard created, - output of mount is right, - CTS test collecting device infor works - -Change-Id: I19959038309284448f1b7f232d579674ef546385 -Signed-off-by: Daniel Rosenberg -Signed-off-by: Yongqin Liu ---- - fs/attr.c | 12 ++++++++++-- - fs/coredump.c | 2 +- - fs/inode.c | 6 +++--- - fs/namei.c | 2 +- - fs/open.c | 23 ++++++++++++++++------- - fs/utimes.c | 2 +- - include/linux/fs.h | 6 +++++- - 7 files changed, 37 insertions(+), 16 deletions(-) - -diff --git a/fs/attr.c b/fs/attr.c -index df28035aa23e..0a7f9d67bb35 100644 ---- a/fs/attr.c -+++ b/fs/attr.c -@@ -226,7 +226,7 @@ EXPORT_SYMBOL(setattr_copy); - * the file open for write, as there can be no conflicting delegation in - * that case. - */ --int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **delegated_inode) -+int notify_change2(struct vfsmount *mnt, struct dentry * dentry, struct iattr * attr, struct inode **delegated_inode) - { - struct inode *inode = dentry->d_inode; - umode_t mode = inode->i_mode; -@@ -333,7 +333,9 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de - if (error) - return error; - -- if (inode->i_op->setattr) -+ if (mnt && inode->i_op->setattr2) -+ error = inode->i_op->setattr2(mnt, dentry, attr); -+ else if (inode->i_op->setattr) - error = inode->i_op->setattr(dentry, attr); - else - error = simple_setattr(dentry, attr); -@@ -346,4 +348,10 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de - - return error; - } -+EXPORT_SYMBOL(notify_change2); -+ -+int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **delegated_inode) -+{ -+ return notify_change2(NULL, dentry, attr, delegated_inode); -+} - EXPORT_SYMBOL(notify_change); -diff --git a/fs/coredump.c b/fs/coredump.c -index b1ea7dfbd149..a6b542bb4d85 100644 ---- a/fs/coredump.c -+++ b/fs/coredump.c -@@ -775,7 +775,7 @@ void do_coredump(const kernel_siginfo_t *siginfo) - goto close_fail; - if (!(cprm.file->f_mode & FMODE_CAN_WRITE)) - goto close_fail; -- if (do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file)) -+ if (do_truncate2(cprm.file->f_path.mnt, cprm.file->f_path.dentry, 0, 0, cprm.file)) - goto close_fail; - } - -diff --git a/fs/inode.c b/fs/inode.c -index fef457a42882..853ce7aa6301 100644 ---- a/fs/inode.c -+++ b/fs/inode.c -@@ -1810,7 +1810,7 @@ int dentry_needs_remove_privs(struct dentry *dentry) - return mask; - } - --static int __remove_privs(struct dentry *dentry, int kill) -+static int __remove_privs(struct vfsmount *mnt, struct dentry *dentry, int kill) - { - struct iattr newattrs; - -@@ -1819,7 +1819,7 @@ static int __remove_privs(struct dentry *dentry, int kill) - * Note we call this on write, so notify_change will not - * encounter any conflicting delegations: - */ -- return notify_change(dentry, &newattrs, NULL); -+ return notify_change2(mnt, dentry, &newattrs, NULL); - } - - /* -@@ -1846,7 +1846,7 @@ int file_remove_privs(struct file *file) - if (kill < 0) - return kill; - if (kill) -- error = __remove_privs(dentry, kill); -+ error = __remove_privs(file->f_path.mnt, dentry, kill); - if (!error) - inode_has_no_xattr(inode); - -diff --git a/fs/namei.c b/fs/namei.c -index 671c3c1a3425..8a77269e644f 100644 ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -2995,7 +2995,7 @@ static int handle_truncate(struct file *filp) - if (!error) - error = security_path_truncate(path); - if (!error) { -- error = do_truncate(path->dentry, 0, -+ error = do_truncate2(path->mnt, path->dentry, 0, - ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, - filp); - } -diff --git a/fs/open.c b/fs/open.c -index b62f5c0923a8..a189284464a0 100644 ---- a/fs/open.c -+++ b/fs/open.c -@@ -35,8 +35,8 @@ - - #include "internal.h" - --int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, -- struct file *filp) -+int do_truncate2(struct vfsmount *mnt, struct dentry *dentry, loff_t length, -+ unsigned int time_attrs, struct file *filp) - { - int ret; - struct iattr newattrs; -@@ -61,17 +61,24 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, - - inode_lock(dentry->d_inode); - /* Note any delegations or leases have already been broken: */ -- ret = notify_change(dentry, &newattrs, NULL); -+ ret = notify_change2(mnt, dentry, &newattrs, NULL); - inode_unlock(dentry->d_inode); - return ret; - } -+int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, -+ struct file *filp) -+{ -+ return do_truncate2(NULL, dentry, length, time_attrs, filp); -+} - - long vfs_truncate(const struct path *path, loff_t length) - { - struct inode *inode; -+ struct vfsmount *mnt; - long error; - - inode = path->dentry->d_inode; -+ mnt = path->mnt; - - /* For directories it's -EISDIR, for other non-regulars - -EINVAL */ - if (S_ISDIR(inode->i_mode)) -@@ -107,7 +114,7 @@ long vfs_truncate(const struct path *path, loff_t length) - if (!error) - error = security_path_truncate(path); - if (!error) -- error = do_truncate(path->dentry, length, 0, NULL); -+ error = do_truncate2(mnt, path->dentry, length, 0, NULL); - - put_write_and_out: - put_write_access(inode); -@@ -156,6 +163,7 @@ long do_sys_ftruncate(unsigned int fd, loff_t length, int small) - { - struct inode *inode; - struct dentry *dentry; -+ struct vfsmount *mnt; - struct fd f; - int error; - -@@ -172,6 +180,7 @@ long do_sys_ftruncate(unsigned int fd, loff_t length, int small) - small = 0; - - dentry = f.file->f_path.dentry; -+ mnt = f.file->f_path.mnt; - inode = dentry->d_inode; - error = -EINVAL; - if (!S_ISREG(inode->i_mode) || !(f.file->f_mode & FMODE_WRITE)) -@@ -192,7 +201,7 @@ long do_sys_ftruncate(unsigned int fd, loff_t length, int small) - if (!error) - error = security_path_truncate(&f.file->f_path); - if (!error) -- error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, f.file); -+ error = do_truncate2(mnt, dentry, length, ATTR_MTIME|ATTR_CTIME, f.file); - sb_end_write(inode->i_sb); - out_putf: - fdput(f); -@@ -558,7 +567,7 @@ static int chmod_common(const struct path *path, umode_t mode) - goto out_unlock; - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -- error = notify_change(path->dentry, &newattrs, &delegated_inode); -+ error = notify_change2(path->mnt, path->dentry, &newattrs, &delegated_inode); - out_unlock: - inode_unlock(inode); - if (delegated_inode) { -@@ -649,7 +658,7 @@ static int chown_common(const struct path *path, uid_t user, gid_t group) - inode_lock(inode); - error = security_path_chown(path, uid, gid); - if (!error) -- error = notify_change(path->dentry, &newattrs, &delegated_inode); -+ error = notify_change2(path->mnt, path->dentry, &newattrs, &delegated_inode); - inode_unlock(inode); - if (delegated_inode) { - error = break_deleg_wait(&delegated_inode); -diff --git a/fs/utimes.c b/fs/utimes.c -index 1ba3f7883870..93a3a58a4f6d 100644 ---- a/fs/utimes.c -+++ b/fs/utimes.c -@@ -57,7 +57,7 @@ static int utimes_common(const struct path *path, struct timespec64 *times) - } - retry_deleg: - inode_lock(inode); -- error = notify_change(path->dentry, &newattrs, &delegated_inode); -+ error = notify_change2(path->mnt, path->dentry, &newattrs, &delegated_inode); - inode_unlock(inode); - if (delegated_inode) { - error = break_deleg_wait(&delegated_inode); -diff --git a/include/linux/fs.h b/include/linux/fs.h -index e0d909d35763..35e662198dc5 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1871,7 +1871,8 @@ struct inode_operations { - int (*rename) (struct inode *, struct dentry *, - struct inode *, struct dentry *, unsigned int); - int (*setattr) (struct dentry *, struct iattr *); -- int (*getattr) (const struct path *, struct kstat *, u32, unsigned int); -+ int (*setattr2) (struct vfsmount *, struct dentry *, struct iattr *); -+ int (*getattr) (const struct path *, struct kstat *, u32, unsigned int); - ssize_t (*listxattr) (struct dentry *, char *, size_t); - int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, - u64 len); -@@ -2519,6 +2520,8 @@ static_assert(offsetof(struct filename, iname) % sizeof(long) == 0); - extern long vfs_truncate(const struct path *, loff_t); - extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, - struct file *filp); -+extern int do_truncate2(struct vfsmount *, struct dentry *, loff_t start, -+ unsigned int time_attrs, struct file *filp); - extern int vfs_fallocate(struct file *file, int mode, loff_t offset, - loff_t len); - extern long do_sys_open(int dfd, const char __user *filename, int flags, -@@ -2866,6 +2869,7 @@ extern void emergency_remount(void); - extern sector_t bmap(struct inode *, sector_t); - #endif - extern int notify_change(struct dentry *, struct iattr *, struct inode **); -+extern int notify_change2(struct vfsmount *, struct dentry *, struct iattr *, struct inode **); - extern int inode_permission(struct inode *, int); - extern int generic_permission(struct inode *, int); - extern int __check_sticky(struct inode *dir, struct inode *inode); diff --git a/patches/ANDROID-vfs-add-d_canonical_path-for-stacked-filesystem-support.patch b/patches/ANDROID-vfs-add-d_canonical_path-for-stacked-filesystem-support.patch deleted file mode 100644 index 0b763c77f5b1..000000000000 --- a/patches/ANDROID-vfs-add-d_canonical_path-for-stacked-filesystem-support.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Rosenberg -Date: Thu, 11 Feb 2016 16:44:15 -0800 -Subject: ANDROID: vfs: add d_canonical_path for stacked filesystem support - -Inotify does not currently know when a filesystem -is acting as a wrapper around another fs. This means -that inotify watchers will miss any modifications to -the base file, as well as any made in a separate -stacked fs that points to the same file. -d_canonical_path solves this problem by allowing the fs -to map a dentry to a path in the lower fs. Inotify -can use it to find the appropriate place to watch to -be informed of all changes to a file. - -Test: HiKey/X15 + Pie + android-mainline, - and HiKey + AOSP Maser + android-mainline, - directories under /sdcard created, - output of mount is right, - CTS test collecting device infor works - -Bug: 70706497 -Change-Id: I09563baffad1711a045e45c1bd0bd8713c2cc0b6 -Signed-off-by: Daniel Rosenberg -[astrachan: Folded 34df4102216e ("ANDROID: fsnotify: Notify lower fs of - open") into this patch] -Signed-off-by: Alistair Strachan -Signed-off-by: Yongqin Liu ---- - fs/notify/inotify/inotify_user.c | 15 +++++++++++++-- - include/linux/dcache.h | 1 + - include/linux/fsnotify.h | 7 +++++++ - 3 files changed, 21 insertions(+), 2 deletions(-) - -diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c -index 3e66e6c8f53a..bd16ec03b5fd 100644 ---- a/fs/notify/inotify/inotify_user.c -+++ b/fs/notify/inotify/inotify_user.c -@@ -701,6 +701,8 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, - struct fsnotify_group *group; - struct inode *inode; - struct path path; -+ struct path alteredpath; -+ struct path *canonical_path = &path; - struct fd f; - int ret; - unsigned flags = 0; -@@ -747,13 +749,22 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, - if (ret) - goto fput_and_out; - -+ /* support stacked filesystems */ -+ if(path.dentry && path.dentry->d_op) { -+ if (path.dentry->d_op->d_canonical_path) { -+ path.dentry->d_op->d_canonical_path(&path, &alteredpath); -+ canonical_path = &alteredpath; -+ path_put(&path); -+ } -+ } -+ - /* inode held in place by reference to path; group by fget on fd */ -- inode = path.dentry->d_inode; -+ inode = canonical_path->dentry->d_inode; - group = f.file->private_data; - - /* create/update an inode mark */ - ret = inotify_update_watch(group, inode, mask); -- path_put(&path); -+ path_put(canonical_path); - fput_and_out: - fdput(f); - return ret; -diff --git a/include/linux/dcache.h b/include/linux/dcache.h -index 10090f11ab95..d59a73cdb10e 100644 ---- a/include/linux/dcache.h -+++ b/include/linux/dcache.h -@@ -147,6 +147,7 @@ struct dentry_operations { - struct vfsmount *(*d_automount)(struct path *); - int (*d_manage)(const struct path *, bool); - struct dentry *(*d_real)(struct dentry *, const struct inode *); -+ void (*d_canonical_path)(const struct path *, struct path *); - } ____cacheline_aligned; - - /* -diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h -index a2d5d175d3c1..e018872b047c 100644 ---- a/include/linux/fsnotify.h -+++ b/include/linux/fsnotify.h -@@ -262,6 +262,7 @@ static inline void fsnotify_modify(struct file *file) - static inline void fsnotify_open(struct file *file) - { - const struct path *path = &file->f_path; -+ struct path lower_path; - struct inode *inode = file_inode(file); - __u32 mask = FS_OPEN; - -@@ -270,6 +271,12 @@ static inline void fsnotify_open(struct file *file) - if (file->f_flags & __FMODE_EXEC) - mask |= FS_OPEN_EXEC; - -+ if (path->dentry->d_op && path->dentry->d_op->d_canonical_path) { -+ path->dentry->d_op->d_canonical_path(path, &lower_path); -+ fsnotify_parent(&lower_path, NULL, mask); -+ fsnotify(lower_path.dentry->d_inode, mask, &lower_path, FSNOTIFY_EVENT_PATH, NULL, 0); -+ path_put(&lower_path); -+ } - fsnotify_path(inode, path, mask); - } - diff --git a/patches/ANDROID-x86-Remove-a-useless-warning-message.patch b/patches/ANDROID-x86-Remove-a-useless-warning-message.patch deleted file mode 100644 index d2c837d7f9d2..000000000000 --- a/patches/ANDROID-x86-Remove-a-useless-warning-message.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alistair Strachan -Date: Mon, 29 Oct 2018 15:20:05 -0700 -Subject: ANDROID: x86: Remove a useless warning message - -While we wait for a clang prebuilt with asm-goto support, we have -removed the kbuild's detection of a clang without asm-goto (the -kernel builds fine without it), so we don't need to see the same -warning about not having the compiler feature fill the kernel build -log, which potentially hides other issues. - -This patch should be reverted when the new clang prebuilt lands and -we have reverted the other reverts. - -Bug: 120440614 -Test: make ARCH=x86_64 x86_64_cuttlefish_defconfig && make ARCH=x86_64 -Change-Id: I26aee5b9dd291f27b950dee4b0c64471d972ddb5 -Signed-off-by: Alistair Strachan ---- - arch/x86/include/asm/cpufeature.h | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h -index 59bf91c57aa8..48670eb3b4d7 100644 ---- a/arch/x86/include/asm/cpufeature.h -+++ b/arch/x86/include/asm/cpufeature.h -@@ -154,9 +154,6 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit); - * Workaround for the sake of BPF compilation which utilizes kernel - * headers, but clang does not support ASM GOTO and fails the build. - */ --#ifndef __BPF_TRACING__ --#warning "Compiler lacks ASM_GOTO support. Add -D __BPF_TRACING__ to your compiler arguments" --#endif - - #define static_cpu_has(bit) boot_cpu_has(bit) - diff --git a/patches/ANDROID-x86-gki_defconfig-enable-DMA_CMA.patch b/patches/ANDROID-x86-gki_defconfig-enable-DMA_CMA.patch deleted file mode 100644 index efdaf3f503eb..000000000000 --- a/patches/ANDROID-x86-gki_defconfig-enable-DMA_CMA.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ram Muthiah -Date: Wed, 12 Jun 2019 17:17:06 -0700 -Subject: ANDROID: x86 gki_defconfig: enable DMA_CMA - -Test: Boot x86 gki -Change-Id: Ic517f4de7865b9bb3f20fbd282a97dd7d8fa775e -Signed-off-by: Ram Muthiah ---- - arch/x86/configs/gki_defconfig | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig -index 94690e9d016a..7f4edee2b52d 100644 ---- a/arch/x86/configs/gki_defconfig -+++ b/arch/x86/configs/gki_defconfig -@@ -321,6 +321,7 @@ CONFIG_CRYPTO_ANSI_CPRNG=y - CONFIG_CRYPTO_DEV_VIRTIO=y - CONFIG_CRC8=y - CONFIG_XZ_DEC=y -+CONFIG_DMA_CMA=y - CONFIG_PRINTK_TIME=y - CONFIG_DEBUG_INFO=y - # CONFIG_ENABLE_MUST_CHECK is not set diff --git a/patches/ANDROID-xfrm-remove-in_compat_syscall-checks.patch b/patches/ANDROID-xfrm-remove-in_compat_syscall-checks.patch deleted file mode 100644 index 37ef2493360e..000000000000 --- a/patches/ANDROID-xfrm-remove-in_compat_syscall-checks.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tri Vo -Date: Thu, 25 Jul 2019 16:57:16 -0700 -Subject: ANDROID: xfrm: remove in_compat_syscall() checks - -This hack is needed to run 32-bit userspace on 64-bit kernel. - -Bug: 138147164 -Test: kernel_net_tests -Signed-off-by: Tri Vo -Change-Id: I083d32b45ca985cfadfe3ce57d253b63202befde ---- - net/xfrm/xfrm_state.c | 3 --- - net/xfrm/xfrm_user.c | 3 --- - 2 files changed, 6 deletions(-) - -diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c -index c6f3c4a1bd99..c023b27c70e1 100644 ---- a/net/xfrm/xfrm_state.c -+++ b/net/xfrm/xfrm_state.c -@@ -2266,9 +2266,6 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen - struct xfrm_mgr *km; - struct xfrm_policy *pol = NULL; - -- if (in_compat_syscall()) -- return -EOPNOTSUPP; -- - if (!optval && !optlen) { - xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL); - xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL); -diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c -index b88ba45ff1ac..ed6e6790b3e7 100644 ---- a/net/xfrm/xfrm_user.c -+++ b/net/xfrm/xfrm_user.c -@@ -2634,9 +2634,6 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, - const struct xfrm_link *link; - int type, err; - -- if (in_compat_syscall()) -- return -EOPNOTSUPP; -- - type = nlh->nlmsg_type; - if (type > XFRM_MSG_MAX) - return -EINVAL; diff --git a/patches/FROMGIT-driver-core-Add-fwnode_to_dev-to-look-up-device-from-fwnode.patch b/patches/FROMGIT-driver-core-Add-fwnode_to_dev-to-look-up-device-from-fwnode.patch deleted file mode 100644 index 217740268a81..000000000000 --- a/patches/FROMGIT-driver-core-Add-fwnode_to_dev-to-look-up-device-from-fwnode.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Saravana Kannan -Date: Wed, 4 Sep 2019 14:11:20 -0700 -Subject: FROMGIT: driver core: Add fwnode_to_dev() to look up device from - fwnode - -It's often useful to look up a device that corresponds to a fwnode. So -add an API to do that irrespective of the bus on which the device has -been added to. - -Signed-off-by: Saravana Kannan -Link: https://lore.kernel.org/r/20190904211126.47518-2-saravanak@google.com -Signed-off-by: Greg Kroah-Hartman - -(cherry-picked from commit 372a67c0c5ef63f55bd1eb480d9555328d8ec0f2 - https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git driver-core-next) - -Bug: 141703324 -Change-Id: I68c36177da083bfb04e73c1b754e740f40faf284 ---- - drivers/base/core.c | 7 +++++++ - include/linux/fwnode.h | 2 ++ - 2 files changed, 9 insertions(+) - -diff --git a/drivers/base/core.c b/drivers/base/core.c -index 2db62d98e395..510fabf8918c 100644 ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -2198,6 +2198,10 @@ int device_add(struct device *dev) - BUS_NOTIFY_ADD_DEVICE, dev); - - kobject_uevent(&dev->kobj, KOBJ_ADD); -+ -+ if (dev->fwnode && !dev->fwnode->dev) -+ dev->fwnode->dev = dev; -+ - bus_probe_device(dev); - if (parent) - klist_add_tail(&dev->p->knode_parent, -@@ -2342,6 +2346,9 @@ void device_del(struct device *dev) - kill_device(dev); - device_unlock(dev); - -+ if (dev->fwnode && dev->fwnode->dev == dev) -+ dev->fwnode->dev = NULL; -+ - /* Notify clients of device removal. This call must come - * before dpm_sysfs_remove(). - */ -diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h -index ababd6bc82f3..d8c6d231d577 100644 ---- a/include/linux/fwnode.h -+++ b/include/linux/fwnode.h -@@ -17,6 +17,7 @@ struct device; - struct fwnode_handle { - struct fwnode_handle *secondary; - const struct fwnode_operations *ops; -+ struct device *dev; - }; - - /** -@@ -123,5 +124,6 @@ struct fwnode_operations { - if (fwnode_has_op(fwnode, op)) \ - (fwnode)->ops->op(fwnode, ## __VA_ARGS__); \ - } while (false) -+#define get_dev_from_fwnode(fwnode) get_device((fwnode)->dev) - - #endif diff --git a/patches/FROMGIT-driver-core-Add-support-for-linking-devices-during-device-addition.patch b/patches/FROMGIT-driver-core-Add-support-for-linking-devices-during-device-addition.patch deleted file mode 100644 index 05de50e179dc..000000000000 --- a/patches/FROMGIT-driver-core-Add-support-for-linking-devices-during-device-addition.patch +++ /dev/null @@ -1,240 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Saravana Kannan -Date: Wed, 4 Sep 2019 14:11:21 -0700 -Subject: FROMGIT: driver core: Add support for linking devices during device - addition - -The firmware corresponding to a device (dev.fwnode) might be able to -provide functional dependency information between a device and its -supplier and consumer devices. Tracking this functional dependency -allows optimizing device probe order and informing a supplier when all -its consumers have probed (and thereby actively managing their -resources). - -The existing device links feature allows tracking and using -supplier-consumer relationships. So, this patch adds the add_links() -fwnode callback to allow firmware to create device links for each -device as the device is added. - -However, when consumer devices are added, they might not have a supplier -device to link to despite needing mandatory resources/functionality from -one or more suppliers. A waiting_for_suppliers list is created to track -such consumers and retry linking them when new devices get added. - -Signed-off-by: Saravana Kannan -Link: https://lore.kernel.org/r/20190904211126.47518-3-saravanak@google.com -Signed-off-by: Greg Kroah-Hartman - -(cherry-picked from commit e2ae9bcc4aaacda04edb75c4eea93384719efaa5 - https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git driver-core-next) - -Bug: 141703324 -Change-Id: I97ffa57fa71588bf198e78d8b5a313b860b17bf5 ---- - Documentation/driver-api/device_link.rst | 3 +- - drivers/base/core.c | 88 ++++++++++++++++++++++++ - include/linux/device.h | 2 + - include/linux/fwnode.h | 17 +++++ - 4 files changed, 109 insertions(+), 1 deletion(-) - -diff --git a/Documentation/driver-api/device_link.rst b/Documentation/driver-api/device_link.rst -index 1b5020ec6517..bc2d89af88ce 100644 ---- a/Documentation/driver-api/device_link.rst -+++ b/Documentation/driver-api/device_link.rst -@@ -281,7 +281,8 @@ State machine - :c:func:`driver_bound()`.) - - * Before a consumer device is probed, presence of supplier drivers is -- verified by checking that links to suppliers are in ``DL_STATE_AVAILABLE`` -+ verified by checking the consumer device is not in the wait_for_suppliers -+ list and by checking that links to suppliers are in ``DL_STATE_AVAILABLE`` - state. The state of the links is updated to ``DL_STATE_CONSUMER_PROBE``. - (Call to :c:func:`device_links_check_suppliers()` from - :c:func:`really_probe()`.) -diff --git a/drivers/base/core.c b/drivers/base/core.c -index 510fabf8918c..b3896da73b3d 100644 ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -44,6 +44,8 @@ early_param("sysfs.deprecated", sysfs_deprecated_setup); - #endif - - /* Device links support. */ -+static LIST_HEAD(wait_for_suppliers); -+static DEFINE_MUTEX(wfs_lock); - - #ifdef CONFIG_SRCU - static DEFINE_MUTEX(device_links_lock); -@@ -430,6 +432,58 @@ struct device_link *device_link_add(struct device *consumer, - } - EXPORT_SYMBOL_GPL(device_link_add); - -+/** -+ * device_link_wait_for_supplier - Add device to wait_for_suppliers list -+ * @consumer: Consumer device -+ * -+ * Marks the @consumer device as waiting for suppliers to become available by -+ * adding it to the wait_for_suppliers list. The consumer device will never be -+ * probed until it's removed from the wait_for_suppliers list. -+ * -+ * The caller is responsible for adding the links to the supplier devices once -+ * they are available and removing the @consumer device from the -+ * wait_for_suppliers list once links to all the suppliers have been created. -+ * -+ * This function is NOT meant to be called from the probe function of the -+ * consumer but rather from code that creates/adds the consumer device. -+ */ -+static void device_link_wait_for_supplier(struct device *consumer) -+{ -+ mutex_lock(&wfs_lock); -+ list_add_tail(&consumer->links.needs_suppliers, &wait_for_suppliers); -+ mutex_unlock(&wfs_lock); -+} -+ -+/** -+ * device_link_add_missing_supplier_links - Add links from consumer devices to -+ * supplier devices, leaving any -+ * consumer with inactive suppliers on -+ * the wait_for_suppliers list -+ * -+ * Loops through all consumers waiting on suppliers and tries to add all their -+ * supplier links. If that succeeds, the consumer device is removed from -+ * wait_for_suppliers list. Otherwise, they are left in the wait_for_suppliers -+ * list. Devices left on the wait_for_suppliers list will not be probed. -+ * -+ * The fwnode add_links callback is expected to return 0 if it has found and -+ * added all the supplier links for the consumer device. It should return an -+ * error if it isn't able to do so. -+ * -+ * The caller of device_link_wait_for_supplier() is expected to call this once -+ * it's aware of potential suppliers becoming available. -+ */ -+static void device_link_add_missing_supplier_links(void) -+{ -+ struct device *dev, *tmp; -+ -+ mutex_lock(&wfs_lock); -+ list_for_each_entry_safe(dev, tmp, &wait_for_suppliers, -+ links.needs_suppliers) -+ if (!fwnode_call_int_op(dev->fwnode, add_links, dev)) -+ list_del_init(&dev->links.needs_suppliers); -+ mutex_unlock(&wfs_lock); -+} -+ - static void device_link_free(struct device_link *link) - { - while (refcount_dec_not_one(&link->rpm_active)) -@@ -564,6 +618,17 @@ int device_links_check_suppliers(struct device *dev) - struct device_link *link; - int ret = 0; - -+ /* -+ * Device waiting for supplier to become available is not allowed to -+ * probe. -+ */ -+ mutex_lock(&wfs_lock); -+ if (!list_empty(&dev->links.needs_suppliers)) { -+ mutex_unlock(&wfs_lock); -+ return -EPROBE_DEFER; -+ } -+ mutex_unlock(&wfs_lock); -+ - device_links_write_lock(); - - list_for_each_entry(link, &dev->links.suppliers, c_node) { -@@ -848,6 +913,10 @@ static void device_links_purge(struct device *dev) - { - struct device_link *link, *ln; - -+ mutex_lock(&wfs_lock); -+ list_del(&dev->links.needs_suppliers); -+ mutex_unlock(&wfs_lock); -+ - /* - * Delete all of the remaining links from this device to any other - * devices (either consumers or suppliers). -@@ -1712,6 +1781,7 @@ void device_initialize(struct device *dev) - #endif - INIT_LIST_HEAD(&dev->links.consumers); - INIT_LIST_HEAD(&dev->links.suppliers); -+ INIT_LIST_HEAD(&dev->links.needs_suppliers); - dev->links.status = DL_DEV_NO_DRIVER; - } - EXPORT_SYMBOL_GPL(device_initialize); -@@ -2202,6 +2272,24 @@ int device_add(struct device *dev) - if (dev->fwnode && !dev->fwnode->dev) - dev->fwnode->dev = dev; - -+ /* -+ * Check if any of the other devices (consumers) have been waiting for -+ * this device (supplier) to be added so that they can create a device -+ * link to it. -+ * -+ * This needs to happen after device_pm_add() because device_link_add() -+ * requires the supplier be registered before it's called. -+ * -+ * But this also needs to happe before bus_probe_device() to make sure -+ * waiting consumers can link to it before the driver is bound to the -+ * device and the driver sync_state callback is called for this device. -+ */ -+ device_link_add_missing_supplier_links(); -+ -+ if (fwnode_has_op(dev->fwnode, add_links) -+ && fwnode_call_int_op(dev->fwnode, add_links, dev)) -+ device_link_wait_for_supplier(dev); -+ - bus_probe_device(dev); - if (parent) - klist_add_tail(&dev->p->knode_parent, -diff --git a/include/linux/device.h b/include/linux/device.h -index 297239a08bb7..c6fb5b3431b7 100644 ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -1135,11 +1135,13 @@ enum dl_dev_state { - * struct dev_links_info - Device data related to device links. - * @suppliers: List of links to supplier devices. - * @consumers: List of links to consumer devices. -+ * @needs_suppliers: Hook to global list of devices waiting for suppliers. - * @status: Driver status information. - */ - struct dev_links_info { - struct list_head suppliers; - struct list_head consumers; -+ struct list_head needs_suppliers; - enum dl_dev_state status; - }; - -diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h -index d8c6d231d577..6ae05b9ce359 100644 ---- a/include/linux/fwnode.h -+++ b/include/linux/fwnode.h -@@ -66,6 +66,21 @@ struct fwnode_reference_args { - * endpoint node. - * @graph_get_port_parent: Return the parent node of a port node. - * @graph_parse_endpoint: Parse endpoint for port and endpoint id. -+ * @add_links: Called after the device corresponding to the fwnode is added -+ * using device_add(). The function is expected to create device -+ * links to all the suppliers of the device that are available at -+ * the time this function is called. The function must NOT stop -+ * at the first failed device link if other unlinked supplier -+ * devices are present in the system. If some suppliers are not -+ * yet available, this function will be called again when other -+ * devices are added to allow creating device links to any newly -+ * available suppliers. -+ * -+ * Return 0 if device links have been successfully created to all -+ * the suppliers of this device or if the supplier information is -+ * not known. Return an error if and only if the supplier -+ * information is known but some of the suppliers are not yet -+ * available to create device links to. - */ - struct fwnode_operations { - struct fwnode_handle *(*get)(struct fwnode_handle *fwnode); -@@ -103,6 +118,8 @@ struct fwnode_operations { - (*graph_get_port_parent)(struct fwnode_handle *fwnode); - int (*graph_parse_endpoint)(const struct fwnode_handle *fwnode, - struct fwnode_endpoint *endpoint); -+ int (*add_links)(const struct fwnode_handle *fwnode, -+ struct device *dev); - }; - - #define fwnode_has_op(fwnode, op) \ diff --git a/patches/FROMGIT-driver-core-Add-sync_state-driver-bus-callback.patch b/patches/FROMGIT-driver-core-Add-sync_state-driver-bus-callback.patch deleted file mode 100644 index 5e5297a56011..000000000000 --- a/patches/FROMGIT-driver-core-Add-sync_state-driver-bus-callback.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Saravana Kannan -Date: Wed, 4 Sep 2019 14:11:23 -0700 -Subject: FROMGIT: driver core: Add sync_state driver/bus callback - -This sync_state driver/bus callback is called once all the consumers -of a supplier have probed successfully. - -This allows the supplier device's driver/bus to sync the supplier -device's state to the software state with the guarantee that all the -consumers are actively managing the resources provided by the supplier -device. - -To maintain backwards compatibility and ease transition from existing -frameworks and resource cleanup schemes, late_initcall_sync is the -earliest when the sync_state callback might be called. - -There is no upper bound on the time by which the sync_state callback -has to be called. This is because if a consumer device never probes, -the supplier has to maintain its resources in the state left by the -bootloader. For example, if the bootloader leaves the display -backlight at a fixed voltage and the backlight driver is never probed, -you don't want the backlight to ever be turned off after boot up. - -Also, when multiple devices are added after kernel init, some -suppliers could be added before their consumer devices get added. In -these instances, the supplier devices could get their sync_state -callback called right after they probe because the consumers devices -haven't had a chance to create device links to the suppliers. - -To handle this correctly, this change also provides APIs to -pause/resume sync state callbacks so that when multiple devices are -added, their sync_state callback evaluation can be postponed to happen -after all of them are added. - -kbuild test robot reported missing documentation for device.state_synced -Reported-by: kbuild test robot -Signed-off-by: Saravana Kannan -Link: https://lore.kernel.org/r/20190904211126.47518-5-saravanak@google.com -Signed-off-by: Greg Kroah-Hartman - -(cherry-picked from commit fc5a251d0fd7ca9038bab78a8c97932c8c6ca23b - https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git driver-core-next) - -Bug: 141703324 -Change-Id: I3e0a483c76d6ae3e5fe5aa6b3df65d0417c65ebb ---- - drivers/base/core.c | 72 ++++++++++++++++++++++++++++++++++++++++++ - include/linux/device.h | 24 ++++++++++++++ - 2 files changed, 96 insertions(+) - -diff --git a/drivers/base/core.c b/drivers/base/core.c -index b3896da73b3d..acbf0b1414ab 100644 ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -46,6 +46,8 @@ early_param("sysfs.deprecated", sysfs_deprecated_setup); - /* Device links support. */ - static LIST_HEAD(wait_for_suppliers); - static DEFINE_MUTEX(wfs_lock); -+static LIST_HEAD(deferred_sync); -+static unsigned int defer_sync_state_count = 1; - - #ifdef CONFIG_SRCU - static DEFINE_MUTEX(device_links_lock); -@@ -648,6 +650,69 @@ int device_links_check_suppliers(struct device *dev) - return ret; - } - -+static void __device_links_supplier_sync_state(struct device *dev) -+{ -+ struct device_link *link; -+ -+ if (dev->state_synced) -+ return; -+ -+ list_for_each_entry(link, &dev->links.consumers, s_node) { -+ if (!(link->flags & DL_FLAG_MANAGED)) -+ continue; -+ if (link->status != DL_STATE_ACTIVE) -+ return; -+ } -+ -+ if (dev->bus->sync_state) -+ dev->bus->sync_state(dev); -+ else if (dev->driver && dev->driver->sync_state) -+ dev->driver->sync_state(dev); -+ -+ dev->state_synced = true; -+} -+ -+void device_links_supplier_sync_state_pause(void) -+{ -+ device_links_write_lock(); -+ defer_sync_state_count++; -+ device_links_write_unlock(); -+} -+ -+void device_links_supplier_sync_state_resume(void) -+{ -+ struct device *dev, *tmp; -+ -+ device_links_write_lock(); -+ if (!defer_sync_state_count) { -+ WARN(true, "Unmatched sync_state pause/resume!"); -+ goto out; -+ } -+ defer_sync_state_count--; -+ if (defer_sync_state_count) -+ goto out; -+ -+ list_for_each_entry_safe(dev, tmp, &deferred_sync, links.defer_sync) { -+ __device_links_supplier_sync_state(dev); -+ list_del_init(&dev->links.defer_sync); -+ } -+out: -+ device_links_write_unlock(); -+} -+ -+static int sync_state_resume_initcall(void) -+{ -+ device_links_supplier_sync_state_resume(); -+ return 0; -+} -+late_initcall(sync_state_resume_initcall); -+ -+static void __device_links_supplier_defer_sync(struct device *sup) -+{ -+ if (list_empty(&sup->links.defer_sync)) -+ list_add_tail(&sup->links.defer_sync, &deferred_sync); -+} -+ - /** - * device_links_driver_bound - Update device links after probing its driver. - * @dev: Device to update the links for. -@@ -692,6 +757,11 @@ void device_links_driver_bound(struct device *dev) - - WARN_ON(link->status != DL_STATE_CONSUMER_PROBE); - WRITE_ONCE(link->status, DL_STATE_ACTIVE); -+ -+ if (defer_sync_state_count) -+ __device_links_supplier_defer_sync(link->supplier); -+ else -+ __device_links_supplier_sync_state(link->supplier); - } - - dev->links.status = DL_DEV_DRIVER_BOUND; -@@ -808,6 +878,7 @@ void device_links_driver_cleanup(struct device *dev) - WRITE_ONCE(link->status, DL_STATE_DORMANT); - } - -+ list_del_init(&dev->links.defer_sync); - __device_links_no_driver(dev); - - device_links_write_unlock(); -@@ -1782,6 +1853,7 @@ void device_initialize(struct device *dev) - INIT_LIST_HEAD(&dev->links.consumers); - INIT_LIST_HEAD(&dev->links.suppliers); - INIT_LIST_HEAD(&dev->links.needs_suppliers); -+ INIT_LIST_HEAD(&dev->links.defer_sync); - dev->links.status = DL_DEV_NO_DRIVER; - } - EXPORT_SYMBOL_GPL(device_initialize); -diff --git a/include/linux/device.h b/include/linux/device.h -index c6fb5b3431b7..6978bb471567 100644 ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -80,6 +80,13 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); - * that generate uevents to add the environment variables. - * @probe: Called when a new device or driver add to this bus, and callback - * the specific driver's probe to initial the matched device. -+ * @sync_state: Called to sync device state to software state after all the -+ * state tracking consumers linked to this device (present at -+ * the time of late_initcall) have successfully bound to a -+ * driver. If the device has no consumers, this function will -+ * be called at late_initcall_sync level. If the device has -+ * consumers that are never bound to a driver, this function -+ * will never get called until they do. - * @remove: Called when a device removed from this bus. - * @shutdown: Called at shut-down time to quiesce the device. - * -@@ -123,6 +130,7 @@ struct bus_type { - int (*match)(struct device *dev, struct device_driver *drv); - int (*uevent)(struct device *dev, struct kobj_uevent_env *env); - int (*probe)(struct device *dev); -+ void (*sync_state)(struct device *dev); - int (*remove)(struct device *dev); - void (*shutdown)(struct device *dev); - -@@ -340,6 +348,13 @@ enum probe_type { - * @probe: Called to query the existence of a specific device, - * whether this driver can work with it, and bind the driver - * to a specific device. -+ * @sync_state: Called to sync device state to software state after all the -+ * state tracking consumers linked to this device (present at -+ * the time of late_initcall) have successfully bound to a -+ * driver. If the device has no consumers, this function will -+ * be called at late_initcall_sync level. If the device has -+ * consumers that are never bound to a driver, this function -+ * will never get called until they do. - * @remove: Called when the device is removed from the system to - * unbind a device from this driver. - * @shutdown: Called at shut-down time to quiesce the device. -@@ -379,6 +394,7 @@ struct device_driver { - const struct acpi_device_id *acpi_match_table; - - int (*probe) (struct device *dev); -+ void (*sync_state)(struct device *dev); - int (*remove) (struct device *dev); - void (*shutdown) (struct device *dev); - int (*suspend) (struct device *dev, pm_message_t state); -@@ -1136,12 +1152,14 @@ enum dl_dev_state { - * @suppliers: List of links to supplier devices. - * @consumers: List of links to consumer devices. - * @needs_suppliers: Hook to global list of devices waiting for suppliers. -+ * @defer_sync: Hook to global list of devices that have deferred sync_state. - * @status: Driver status information. - */ - struct dev_links_info { - struct list_head suppliers; - struct list_head consumers; - struct list_head needs_suppliers; -+ struct list_head defer_sync; - enum dl_dev_state status; - }; - -@@ -1217,6 +1235,9 @@ struct dev_links_info { - * @offline: Set after successful invocation of bus type's .offline(). - * @of_node_reused: Set if the device-tree node is shared with an ancestor - * device. -+ * @state_synced: The hardware state of this device has been synced to match -+ * the software state of this device by calling the driver/bus -+ * sync_state() callback. - * @dma_coherent: this particular device is dma coherent, even if the - * architecture supports non-coherent devices. - * -@@ -1313,6 +1334,7 @@ struct device { - bool offline_disabled:1; - bool offline:1; - bool of_node_reused:1; -+ bool state_synced:1; - #if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \ - defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \ - defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL) -@@ -1655,6 +1677,8 @@ struct device_link *device_link_add(struct device *consumer, - struct device *supplier, u32 flags); - void device_link_del(struct device_link *link); - void device_link_remove(void *consumer, struct device *supplier); -+void device_links_supplier_sync_state_pause(void); -+void device_links_supplier_sync_state_resume(void); - - #ifndef dev_fmt - #define dev_fmt(fmt) fmt diff --git a/patches/FROMGIT-of-platform-Pause-resume-sync-state-during-init-and-of_platform_populate.patch b/patches/FROMGIT-of-platform-Pause-resume-sync-state-during-init-and-of_platform_populate.patch deleted file mode 100644 index cabfdfe2b84b..000000000000 --- a/patches/FROMGIT-of-platform-Pause-resume-sync-state-during-init-and-of_platform_populate.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Saravana Kannan -Date: Wed, 4 Sep 2019 14:11:24 -0700 -Subject: FROMGIT: of/platform: Pause/resume sync state during init and - of_platform_populate() - -When all the top level devices are populated from DT during kernel -init, the supplier devices could be added and probed before the -consumer devices are added and linked to the suppliers. To avoid the -sync_state() callback from being called prematurely, pause the -sync_state() callbacks before populating the devices and resume them -at late_initcall_sync(). - -Similarly, when children devices are populated from a module using -of_platform_populate(), there could be supplier-consumer dependencies -between the children devices that are populated. To avoid the same -problem with sync_state() being called prematurely, pause and resume -sync_state() callbacks across of_platform_populate(). - -Signed-off-by: Saravana Kannan -Link: https://lore.kernel.org/r/20190904211126.47518-6-saravanak@google.com -Signed-off-by: Greg Kroah-Hartman - -(cherry-picked from commit 5e6669387e2287f25f09fd0abd279dae104cfa7e - https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git driver-core-next) - -Bug: 141703324 -Change-Id: Ia43ebbc9071d4d6a59b347ccae99fcf0ab192269 ---- - drivers/of/platform.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/drivers/of/platform.c b/drivers/of/platform.c -index b47a2292fe8e..d93891a05f60 100644 ---- a/drivers/of/platform.c -+++ b/drivers/of/platform.c -@@ -480,6 +480,7 @@ int of_platform_populate(struct device_node *root, - pr_debug("%s()\n", __func__); - pr_debug(" starting at: %pOF\n", root); - -+ device_links_supplier_sync_state_pause(); - for_each_child_of_node(root, child) { - rc = of_platform_bus_create(child, matches, lookup, parent, true); - if (rc) { -@@ -487,6 +488,8 @@ int of_platform_populate(struct device_node *root, - break; - } - } -+ device_links_supplier_sync_state_resume(); -+ - of_node_set_flag(root, OF_POPULATED_BUS); - - of_node_put(root); -@@ -518,6 +521,7 @@ static int __init of_platform_default_populate_init(void) - if (!of_have_populated_dt()) - return -ENODEV; - -+ device_links_supplier_sync_state_pause(); - /* - * Handle certain compatibles explicitly, since we don't want to create - * platform_devices for every node in /reserved-memory with a -@@ -538,6 +542,14 @@ static int __init of_platform_default_populate_init(void) - return 0; - } - arch_initcall_sync(of_platform_default_populate_init); -+ -+static int __init of_platform_sync_state_init(void) -+{ -+ if (of_have_populated_dt()) -+ device_links_supplier_sync_state_resume(); -+ return 0; -+} -+late_initcall_sync(of_platform_sync_state_init); - #endif - - int of_platform_device_destroy(struct device *dev, void *data) diff --git a/patches/FROMGIT-of-property-Add-functional-dependency-link-from-DT-bindings.patch b/patches/FROMGIT-of-property-Add-functional-dependency-link-from-DT-bindings.patch deleted file mode 100644 index 036ccfde126b..000000000000 --- a/patches/FROMGIT-of-property-Add-functional-dependency-link-from-DT-bindings.patch +++ /dev/null @@ -1,362 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Saravana Kannan -Date: Wed, 4 Sep 2019 14:11:22 -0700 -Subject: FROMGIT: of: property: Add functional dependency link from DT - bindings - -Add device links after the devices are created (but before they are -probed) by looking at common DT bindings like clocks and -interconnects. - -Automatically adding device links for functional dependencies at the -framework level provides the following benefits: - -- Optimizes device probe order and avoids the useless work of - attempting probes of devices that will not probe successfully - (because their suppliers aren't present or haven't probed yet). - - For example, in a commonly available mobile SoC, registering just - one consumer device's driver at an initcall level earlier than the - supplier device's driver causes 11 failed probe attempts before the - consumer device probes successfully. This was with a kernel with all - the drivers statically compiled in. This problem gets a lot worse if - all the drivers are loaded as modules without direct symbol - dependencies. - -- Supplier devices like clock providers, interconnect providers, etc - need to keep the resources they provide active and at a particular - state(s) during boot up even if their current set of consumers don't - request the resource to be active. This is because the rest of the - consumers might not have probed yet and turning off the resource - before all the consumers have probed could lead to a hang or - undesired user experience. - - Some frameworks (Eg: regulator) handle this today by turning off - "unused" resources at late_initcall_sync and hoping all the devices - have probed by then. This is not a valid assumption for systems with - loadable modules. Other frameworks (Eg: clock) just don't handle - this due to the lack of a clear signal for when they can turn off - resources. This leads to downstream hacks to handle cases like this - that can easily be solved in the upstream kernel. - - By linking devices before they are probed, we give suppliers a clear - count of the number of dependent consumers. Once all of the - consumers are active, the suppliers can turn off the unused - resources without making assumptions about the number of consumers. - -By default we just add device-links to track "driver presence" (probe -succeeded) of the supplier device. If any other functionality provided -by device-links are needed, it is left to the consumer/supplier -devices to change the link when they probe. - -kbuild test robot reported clang error about missing const -Reported-by: kbuild test robot -Signed-off-by: Saravana Kannan -Link: https://lore.kernel.org/r/20190904211126.47518-4-saravanak@google.com -Signed-off-by: Greg Kroah-Hartman - -(cherry-picked from commit a3e1d1a7f5fcccaf1d252278425fea9a4a553100 - https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git driver-core-next) - -Bug: 141703324 -Change-Id: I54a2dc3c4e91e418bcf1895c16bb8658dcfe1bee ---- - .../admin-guide/kernel-parameters.rst | 1 + - .../admin-guide/kernel-parameters.txt | 6 + - drivers/of/property.c | 241 ++++++++++++++++++ - 3 files changed, 248 insertions(+) - -diff --git a/Documentation/admin-guide/kernel-parameters.rst b/Documentation/admin-guide/kernel-parameters.rst -index d05d531b4ec9..6d421694d98e 100644 ---- a/Documentation/admin-guide/kernel-parameters.rst -+++ b/Documentation/admin-guide/kernel-parameters.rst -@@ -127,6 +127,7 @@ parameter is applicable:: - NET Appropriate network support is enabled. - NUMA NUMA support is enabled. - NFS Appropriate NFS support is enabled. -+ OF Devicetree is enabled. - OSS OSS sound support is enabled. - PV_OPS A paravirtualized kernel is enabled. - PARIDE The ParIDE (parallel port IDE) subsystem is enabled. -diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt -index a84a83f8881e..dc727fa8c831 100644 ---- a/Documentation/admin-guide/kernel-parameters.txt -+++ b/Documentation/admin-guide/kernel-parameters.txt -@@ -3194,6 +3194,12 @@ - This can be set from sysctl after boot. - See Documentation/admin-guide/sysctl/vm.rst for details. - -+ of_devlink [OF, KNL] Create device links between consumer and -+ supplier devices by scanning the devictree to infer the -+ consumer/supplier relationships. A consumer device -+ will not be probed until all the supplier devices have -+ probed successfully. -+ - ohci1394_dma=early [HW] enable debugging via the ohci1394 driver. - See Documentation/debugging-via-ohci1394.txt for more - info. -diff --git a/drivers/of/property.c b/drivers/of/property.c -index d7fa75e31f22..23b5ee5b0570 100644 ---- a/drivers/of/property.c -+++ b/drivers/of/property.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #include "of_private.h" - -@@ -985,6 +986,245 @@ of_fwnode_device_get_match_data(const struct fwnode_handle *fwnode, - return of_device_get_match_data(dev); - } - -+static bool of_is_ancestor_of(struct device_node *test_ancestor, -+ struct device_node *child) -+{ -+ of_node_get(child); -+ while (child) { -+ if (child == test_ancestor) { -+ of_node_put(child); -+ return false; -+ } -+ child = of_get_next_parent(child); -+ } -+ return true; -+} -+ -+/** -+ * of_link_to_phandle - Add device link to supplier from supplier phandle -+ * @dev: consumer device -+ * @sup_np: phandle to supplier device tree node -+ * -+ * Given a phandle to a supplier device tree node (@sup_np), this function -+ * finds the device that owns the supplier device tree node and creates a -+ * device link from @dev consumer device to the supplier device. This function -+ * doesn't create device links for invalid scenarios such as trying to create a -+ * link with a parent device as the consumer of its child device. In such -+ * cases, it returns an error. -+ * -+ * Returns: -+ * - 0 if link successfully created to supplier -+ * - -EAGAIN if linking to the supplier should be reattempted -+ * - -EINVAL if the supplier link is invalid and should not be created -+ * - -ENODEV if there is no device that corresponds to the supplier phandle -+ */ -+static int of_link_to_phandle(struct device *dev, struct device_node *sup_np) -+{ -+ struct device *sup_dev; -+ u32 dl_flags = DL_FLAG_AUTOPROBE_CONSUMER; -+ int ret = 0; -+ struct device_node *tmp_np = sup_np; -+ -+ of_node_get(sup_np); -+ /* -+ * Find the device node that contains the supplier phandle. It may be -+ * @sup_np or it may be an ancestor of @sup_np. -+ */ -+ while (sup_np && !of_find_property(sup_np, "compatible", NULL)) -+ sup_np = of_get_next_parent(sup_np); -+ if (!sup_np) { -+ dev_dbg(dev, "Not linking to %pOFP - No device\n", tmp_np); -+ return -ENODEV; -+ } -+ -+ /* -+ * Don't allow linking a device node as a consumer of one of its -+ * descendant nodes. By definition, a child node can't be a functional -+ * dependency for the parent node. -+ */ -+ if (!of_is_ancestor_of(dev->of_node, sup_np)) { -+ dev_dbg(dev, "Not linking to %pOFP - is descendant\n", sup_np); -+ of_node_put(sup_np); -+ return -EINVAL; -+ } -+ sup_dev = get_dev_from_fwnode(&sup_np->fwnode); -+ of_node_put(sup_np); -+ if (!sup_dev) -+ return -EAGAIN; -+ if (!device_link_add(dev, sup_dev, dl_flags)) -+ ret = -EAGAIN; -+ put_device(sup_dev); -+ return ret; -+} -+ -+/** -+ * parse_prop_cells - Property parsing function for suppliers -+ * -+ * @np: Pointer to device tree node containing a list -+ * @prop_name: Name of property to be parsed. Expected to hold phandle values -+ * @index: For properties holding a list of phandles, this is the index -+ * into the list. -+ * @list_name: Property name that is known to contain list of phandle(s) to -+ * supplier(s) -+ * @cells_name: property name that specifies phandles' arguments count -+ * -+ * This is a helper function to parse properties that have a known fixed name -+ * and are a list of phandles and phandle arguments. -+ * -+ * Returns: -+ * - phandle node pointer with refcount incremented. Caller must of_node_put() -+ * on it when done. -+ * - NULL if no phandle found at index -+ */ -+static struct device_node *parse_prop_cells(struct device_node *np, -+ const char *prop_name, int index, -+ const char *list_name, -+ const char *cells_name) -+{ -+ struct of_phandle_args sup_args; -+ -+ if (strcmp(prop_name, list_name)) -+ return NULL; -+ -+ if (of_parse_phandle_with_args(np, list_name, cells_name, index, -+ &sup_args)) -+ return NULL; -+ -+ return sup_args.np; -+} -+ -+static struct device_node *parse_clocks(struct device_node *np, -+ const char *prop_name, int index) -+{ -+ return parse_prop_cells(np, prop_name, index, "clocks", "#clock-cells"); -+} -+ -+static struct device_node *parse_interconnects(struct device_node *np, -+ const char *prop_name, int index) -+{ -+ return parse_prop_cells(np, prop_name, index, "interconnects", -+ "#interconnect-cells"); -+} -+ -+static int strcmp_suffix(const char *str, const char *suffix) -+{ -+ unsigned int len, suffix_len; -+ -+ len = strlen(str); -+ suffix_len = strlen(suffix); -+ if (len <= suffix_len) -+ return -1; -+ return strcmp(str + len - suffix_len, suffix); -+} -+ -+static struct device_node *parse_regulators(struct device_node *np, -+ const char *prop_name, int index) -+{ -+ if (index || strcmp_suffix(prop_name, "-supply")) -+ return NULL; -+ -+ return of_parse_phandle(np, prop_name, 0); -+} -+ -+/** -+ * struct supplier_bindings - Property parsing functions for suppliers -+ * -+ * @parse_prop: function name -+ * parse_prop() finds the node corresponding to a supplier phandle -+ * @parse_prop.np: Pointer to device node holding supplier phandle property -+ * @parse_prop.prop_name: Name of property holding a phandle value -+ * @parse_prop.index: For properties holding a list of phandles, this is the -+ * index into the list -+ * -+ * Returns: -+ * parse_prop() return values are -+ * - phandle node pointer with refcount incremented. Caller must of_node_put() -+ * on it when done. -+ * - NULL if no phandle found at index -+ */ -+struct supplier_bindings { -+ struct device_node *(*parse_prop)(struct device_node *np, -+ const char *prop_name, int index); -+}; -+ -+static const struct supplier_bindings bindings[] = { -+ { .parse_prop = parse_clocks, }, -+ { .parse_prop = parse_interconnects, }, -+ { .parse_prop = parse_regulators, }, -+ {}, -+}; -+ -+/** -+ * of_link_property - Create device links to suppliers listed in a property -+ * @dev: Consumer device -+ * @con_np: The consumer device tree node which contains the property -+ * @prop_name: Name of property to be parsed -+ * -+ * This function checks if the property @prop_name that is present in the -+ * @con_np device tree node is one of the known common device tree bindings -+ * that list phandles to suppliers. If @prop_name isn't one, this function -+ * doesn't do anything. -+ * -+ * If @prop_name is one, this function attempts to create device links from the -+ * consumer device @dev to all the devices of the suppliers listed in -+ * @prop_name. -+ * -+ * Any failed attempt to create a device link will NOT result in an immediate -+ * return. of_link_property() must create links to all the available supplier -+ * devices even when attempts to create a link to one or more suppliers fail. -+ */ -+static int of_link_property(struct device *dev, struct device_node *con_np, -+ const char *prop_name) -+{ -+ struct device_node *phandle; -+ const struct supplier_bindings *s = bindings; -+ unsigned int i = 0; -+ bool matched = false; -+ int ret = 0; -+ -+ /* Do not stop at first failed link, link all available suppliers. */ -+ while (!matched && s->parse_prop) { -+ while ((phandle = s->parse_prop(con_np, prop_name, i))) { -+ matched = true; -+ i++; -+ if (of_link_to_phandle(dev, phandle) == -EAGAIN) -+ ret = -EAGAIN; -+ of_node_put(phandle); -+ } -+ s++; -+ } -+ return ret; -+} -+ -+static int __of_link_to_suppliers(struct device *dev, -+ struct device_node *con_np) -+{ -+ struct device_node *child; -+ struct property *p; -+ int ret = 0; -+ -+ for_each_property_of_node(con_np, p) -+ if (of_link_property(dev, con_np, p->name)) -+ ret = -EAGAIN; -+ -+ return ret; -+} -+ -+static bool of_devlink; -+core_param(of_devlink, of_devlink, bool, 0); -+ -+static int of_fwnode_add_links(const struct fwnode_handle *fwnode, -+ struct device *dev) -+{ -+ if (!of_devlink) -+ return 0; -+ -+ if (unlikely(!is_of_node(fwnode))) -+ return 0; -+ -+ return __of_link_to_suppliers(dev, to_of_node(fwnode)); -+} -+ - const struct fwnode_operations of_fwnode_ops = { - .get = of_fwnode_get, - .put = of_fwnode_put, -@@ -1001,5 +1241,6 @@ const struct fwnode_operations of_fwnode_ops = { - .graph_get_remote_endpoint = of_fwnode_graph_get_remote_endpoint, - .graph_get_port_parent = of_fwnode_graph_get_port_parent, - .graph_parse_endpoint = of_fwnode_graph_parse_endpoint, -+ .add_links = of_fwnode_add_links, - }; - EXPORT_SYMBOL_GPL(of_fwnode_ops); diff --git a/patches/FROMGIT-of-property-Create-device-links-for-all-child-supplier-depencencies.patch b/patches/FROMGIT-of-property-Create-device-links-for-all-child-supplier-depencencies.patch deleted file mode 100644 index ba97c8f0d2c9..000000000000 --- a/patches/FROMGIT-of-property-Create-device-links-for-all-child-supplier-depencencies.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Saravana Kannan -Date: Wed, 4 Sep 2019 14:11:25 -0700 -Subject: FROMGIT: of: property: Create device links for all child-supplier - depencencies - -A parent device can have child devices that it adds when it probes. But -this probing of the parent device can happen way after kernel init is done --- for example, when the parent device's driver is loaded as a module. - -In such cases, if the child devices depend on a supplier in the system, we -need to make sure the supplier gets the sync_state() callback only after -these child devices are added and probed. - -To achieve this, when creating device links for a device by looking at its -DT node, don't just look at DT references at the top node level. Look at DT -references in all the descendant nodes too and create device links from the -ancestor device to all these supplier devices. - -This way, when the parent device probes and adds child devices, the child -devices can then create their own device links to the suppliers and further -delay the supplier's sync_state() callback to after the child devices are -probed. - -Example: -In this illustration, -> denotes DT references and indentation -represents child status. - -Device node A - Device node B -> D - Device node C -> B, D - -Device node D - -Assume all these devices have their drivers loaded as modules. - -Without this patch, this is the sequence of events: -1. D is added. -2. A is added. -3. Device D probes. -4. Device D gets its sync_state() callback. -5. Device B and C might malfunction because their resources got - altered/turned off before they can make active requests for them. - -With this patch, this is the sequence of events: -1. D is added. -2. A is added and creates device links to D. -3. Device link from A to B is not added because A is a parent of B. -4. Device D probes. -5. Device D does not get it's sync_state() callback because consumer A - hasn't probed yet. -5. Device A probes. -5. a. Devices B and C are added. -5. b. Device links from B and C to D are added. -5. c. Device A's probe completes. -6. Device D does not get it's sync_state() callback because consumer A - has probed but consumers B and C haven't probed yet. -7. Device B and C probe. -8. Device D gets it's sync_state() callback because all its consumers - have probed. -9. None of the devices malfunction. - -Signed-off-by: Saravana Kannan -Link: https://lore.kernel.org/r/20190904211126.47518-7-saravanak@google.com -Signed-off-by: Greg Kroah-Hartman - -(cherry-picked from commit d4387cd117414ba80230f27a514be5ca4a09cfcc - https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git driver-core-next) - -Fixes: 141703324 -Change-Id: I38186d6cc4671bd8747dae8c440b09717a487088 ---- - drivers/of/property.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/of/property.c b/drivers/of/property.c -index 23b5ee5b0570..923d6f88a99c 100644 ---- a/drivers/of/property.c -+++ b/drivers/of/property.c -@@ -1207,6 +1207,10 @@ static int __of_link_to_suppliers(struct device *dev, - if (of_link_property(dev, con_np, p->name)) - ret = -EAGAIN; - -+ for_each_child_of_node(con_np, child) -+ if (__of_link_to_suppliers(dev, child)) -+ ret = -EAGAIN; -+ - return ret; - } - diff --git a/patches/UPSTREAM-base-soc-Handle-custom-soc-information-sysfs-entries.patch b/patches/UPSTREAM-base-soc-Handle-custom-soc-information-sysfs-entries.patch deleted file mode 100644 index 7e81da9a0c9c..000000000000 --- a/patches/UPSTREAM-base-soc-Handle-custom-soc-information-sysfs-entries.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Murali Nalajala -Date: Mon, 7 Oct 2019 13:37:42 -0700 -Subject: UPSTREAM: base: soc: Handle custom soc information sysfs entries - -Soc framework exposed sysfs entries are not sufficient for some -of the h/w platforms. Currently there is no interface where soc -drivers can expose further information about their SoCs via soc -framework. This change address this limitation where clients can -pass their custom entries as attribute group and soc framework -would expose them as sysfs properties. - -Bug: 141190076 -Signed-off-by: Murali Nalajala -Reviewed-by: Bjorn Andersson -Reviewed-by: Stephen Boyd -Link: https://lore.kernel.org/r/1570480662-25252-1-git-send-email-mnalajal@codeaurora.org -Signed-off-by: Greg Kroah-Hartman -(cherry-picked from c31e73121f4c1ec45a3e523ac6ce3ce6dafdcec1) -Signed-off-by: Greg Kroah-Hartman -Change-Id: Ia1c8d697e29052b4503da7c4b30c2c97d3b697f7 ---- - drivers/base/soc.c | 30 +++++++++++++++++------------- - include/linux/sys_soc.h | 1 + - 2 files changed, 18 insertions(+), 13 deletions(-) - -diff --git a/drivers/base/soc.c b/drivers/base/soc.c -index 7c0c5ca5953d..4af11a423475 100644 ---- a/drivers/base/soc.c -+++ b/drivers/base/soc.c -@@ -104,15 +104,12 @@ static const struct attribute_group soc_attr_group = { - .is_visible = soc_attribute_mode, - }; - --static const struct attribute_group *soc_attr_groups[] = { -- &soc_attr_group, -- NULL, --}; -- - static void soc_release(struct device *dev) - { - struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); - -+ ida_simple_remove(&soc_ida, soc_dev->soc_dev_num); -+ kfree(soc_dev->dev.groups); - kfree(soc_dev); - } - -@@ -121,6 +118,7 @@ static struct soc_device_attribute *early_soc_dev_attr; - struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr) - { - struct soc_device *soc_dev; -+ const struct attribute_group **soc_attr_groups; - int ret; - - if (!soc_bus_type.p) { -@@ -136,10 +134,18 @@ struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr - goto out1; - } - -+ soc_attr_groups = kcalloc(3, sizeof(*soc_attr_groups), GFP_KERNEL); -+ if (!soc_attr_groups) { -+ ret = -ENOMEM; -+ goto out2; -+ } -+ soc_attr_groups[0] = &soc_attr_group; -+ soc_attr_groups[1] = soc_dev_attr->custom_attr_group; -+ - /* Fetch a unique (reclaimable) SOC ID. */ - ret = ida_simple_get(&soc_ida, 0, 0, GFP_KERNEL); - if (ret < 0) -- goto out2; -+ goto out3; - soc_dev->soc_dev_num = ret; - - soc_dev->attr = soc_dev_attr; -@@ -150,15 +156,15 @@ struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr - dev_set_name(&soc_dev->dev, "soc%d", soc_dev->soc_dev_num); - - ret = device_register(&soc_dev->dev); -- if (ret) -- goto out3; -+ if (ret) { -+ put_device(&soc_dev->dev); -+ return ERR_PTR(ret); -+ } - - return soc_dev; - - out3: -- ida_simple_remove(&soc_ida, soc_dev->soc_dev_num); -- put_device(&soc_dev->dev); -- soc_dev = NULL; -+ kfree(soc_attr_groups); - out2: - kfree(soc_dev); - out1: -@@ -169,8 +175,6 @@ EXPORT_SYMBOL_GPL(soc_device_register); - /* Ensure soc_dev->attr is freed prior to calling soc_device_unregister. */ - void soc_device_unregister(struct soc_device *soc_dev) - { -- ida_simple_remove(&soc_ida, soc_dev->soc_dev_num); -- - device_unregister(&soc_dev->dev); - early_soc_dev_attr = NULL; - } -diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h -index 48ceea867dd6..d9b3cf0f410c 100644 ---- a/include/linux/sys_soc.h -+++ b/include/linux/sys_soc.h -@@ -15,6 +15,7 @@ struct soc_device_attribute { - const char *serial_number; - const char *soc_id; - const void *data; -+ const struct attribute_group *custom_attr_group; - }; - - /** diff --git a/patches/series b/patches/series deleted file mode 100644 index 372638712df3..000000000000 --- a/patches/series +++ /dev/null @@ -1,197 +0,0 @@ -# -# android-mainline patches -# -# Applies onto mainline 4f5cafb5cb84 Linux v5.4-rc3 -# Matches android-mainline 06dc94f19d2f "ANDROID: sched: Honor sync flag for energy-aware wakeups" -# -ANDROID-x86-Remove-a-useless-warning-message.patch -ANDROID-Kbuild-LLVMLinux-allow-overriding-clang-target-triple.patch -ANDROID-net-xfrm-make-PF_KEY-SHA256-use-RFC-compliant-truncation.patch -ANDROID-arm64-copy-CONFIG_CMDLINE_EXTEND-from-ARM.patch -ANDROID-of-Support-CONFIG_CMDLINE_EXTEND-config-option.patch -ANDROID-fs-epoll-use-freezable-blocking-call.patch -ANDROID-mm-add-a-field-to-store-names-for-private-anonymous-memory.patch -ANDROID-usb-gadget-configfs-Add-usb_function-ptr-to-fi-struct.patch -ANDROID-usb-gadget-configfs-Add-Uevent-to-notify-userspace.patch -ANDROID-usb-gadget-configfs-Add-function-devices-to-the-parent.patch -ANDROID-usb-gadget-configfs-Add-state-attribute-to-android_device.patch -ANDROID-usb-gadget-configfs-Add-device-attribute-to-determine-gadget-state.patch -ANDROID-usb-gadget-f_accessory-Add-Android-Accessory-function.patch -ANDROID-usb-gadget-f_midi-create-F_midi-device.patch -ANDROID-usb-gadget-f_midi-set-fi-f-to-NULL-when-free-f_midi-function.patch -ANDROID-usb-gadget-f_audio_source-New-gadget-driver-for-audio-output.patch -ANDROID-mmc-core-Add-ignore-mmc-pm-notify-functionality.patch -ANDROID-uid_cputime-Adds-accounting-for-the-cputimes-per-uid.patch -ANDROID-uid_cputime-add-per-uid-IO-usage-accounting.patch -ANDROID-taskstats-track-fsync-syscalls.patch -ANDROID-AVB-error-handler-to-invalidate-vbmeta-partition.patch -ANDROID-fs-FS-tracepoints-to-track-IO.patch -ANDROID-cpu-send-KOBJ_ONLINE-event-when-enabling-cpus.patch -ANDROID-add-extra-free-kbytes-tunable.patch -ANDROID-power-wakeup_reason-add-an-API-to-log-wakeup-reasons.patch -ANDROID-netfilter-xt_quota2-adding-the-original-quota2-from-xtables-addons.patch -ANDROID-netfilter-xt_IDLETIMER-Add-new-netlink-msg-type.patch -ANDROID-security-perf-Allow-further-restriction-of-perf_event_open.patch -ANDROID-net-ipv6-autoconf-routes-into-per-device-tables.patch -ANDROID-binder-add-support-for-RT-prio-inheritance.patch -ANDROID-cpufreq-track-per-task-time-in-state.patch -ANDROID-cpufreq-times-track-per-uid-time-in-state.patch -ANDROID-proc-Add-proc-uid-directory.patch -ANDROID-cpufreq-Add-time_in_state-to-proc-uid-directories.patch -ANDROID-cpufreq-times-add-proc-uid_concurrent_-active-policy-_time.patch -ANDROID-cpufreq-times-record-fast-switch-frequency-transitions.patch -ANDROID-cpufreq-times-optimize-proc-files.patch -ANDROID-dm-bow-Add-dm-bow-feature.patch -ANDROID-dm-bow-Fix-32-bit-compile-errors.patch -ANDROID-cpufreq-times-don-t-copy-invalid-freqs-from-freq-table.patch -ANDROID-gki_defconfig-initial-config-based-on-cuttlefish_defconfig.patch -ANDROID-gki_defconfig-Remove-recommended-configs-not-present-on-b1c1.patch -ANDROID-gki_defconfig-Remove-cuttlefish-specific-configs.patch -ANDROID-gki_defconfig-common-configs-for-device-DLKMs.patch -ANDROID-Expose-gki_defconfig-to-build.config.patch -ANDROID-Move-from-clang-r349610-to-r353983c.patch -ANDROID-gki_defconfig-disable-CONFIG_LCD_CLASS_DEVICE-module.patch -ANDROID-gki_defconfig-sync-with-savedefconfig.patch -ANDROID-gki_defconfig-remove-more-recommended-configs.patch -ANDROID-gki_defconfig-more-generic-configs-for-DLKMs.patch -ANDROID-sync-defconfigs-with-savedefconfig.patch -ANDROID-Four-part-revert-of-asm-goto-usage-1-4.patch -ANDROID-Four-part-revert-of-asm-goto-usage-2-4.patch -ANDROID-Four-part-revert-of-asm-goto-usage-3-4.patch -ANDROID-Four-part-revert-of-asm-goto-usage-4-4.patch -ANDROID-Removed-check-for-asm-goto.patch -ANDROID-Add-initial-x86_64-gki_defconfig.patch -ANDROID-added-configs-so-that-GKI-boots-on-x86-cuttlefish.patch -ANDROID-gki_defconfig-enable-CMA-and-increase-CMA_AREAS.patch -ANDROID-gki_defconfig-enable-SLAB_FREELIST_RANDOM-SLAB_FREELIST_HARDENED.patch -ANDROID-gki_defconfig-Enable-CMA-SLAB_FREELIST-RANDOM-and-HARDENED-on-x86.patch -ANDROID-gki_defconfig-enable-DMA_CMA.patch -ANDROID-Fixed-x86-regression.patch -ANDROID-x86-gki_defconfig-enable-DMA_CMA.patch -ANDROID-Removed-extraneous-configs-from-gki.patch -ANDROID-gki_defconfig-more-configs-for-partners.patch -ANDROID-gki_defconfig-workaround-to-enable-configs.patch -ANDROID-gki-cuttlefish-defconfigs-use-prebuilt-build-tools.patch -ANDROID-adding-usb-HCD-dummy-config-to-permit-usb-write-ops-on-init.patch -ANDROID-gki_defconfig-enable-more-configs.patch -ANDROID-gki_defconfig-disable-BRIDGE_NETFILTER.patch -ANDROID-sdcardfs-Enable-modular-sdcardfs.patch -ANDROID-vfs-Add-setattr2-for-filesystems-with-per-mount-permissions.patch -ANDROID-vfs-Add-permission2-for-filesystems-with-per-mount-permissions.patch -ANDROID-Add-show_options2-to-view-private-mount-data.patch -ANDROID-vfs-add-d_canonical_path-for-stacked-filesystem-support.patch -ANDROID-fs-Restore-vfs_path_lookup-export.patch -ANDROID-mnt-Add-filesystem-private-data-to-mount-points.patch -ANDROID-sdcardfs-Define-magic-value.patch -ANDROID-sdcardfs-Add-sdcardfs-filesystem.patch -ANDROID-cuttlefish-gki-_defconfig-Enable-CONFIG_SDCARD_FS.patch -ANDROID-mnt-Fix-null-pointer-dereference.patch -ANDROID-build-configs-switch-prebuilt-path-location.patch -ANDROID-Revert-x86-mm-Identify-the-end-of-the-kernel-area-to-be-reserved.patch -ANDROID-xfrm-remove-in_compat_syscall-checks.patch -ANDROID-Add-initial-rockpi4_defconfig.patch -ANDROID-label-cuttlefish-modules-for-gki.patch -ANDROID-staging-android-ion-Decouple-ION-page-pooling-from-ION-core.patch -ANDROID-staging-android-ion-Expose-ion_alloc-to-kernel-space.patch -ANDROID-dma-buf-Add-support-for-partial-cache-maintenance.patch -ANDROID-dma-buf-Add-support-for-mapping-buffers-with-DMA-attributes.patch -ANDROID-dma-buf-Add-support-to-get-flags-associated-with-a-buffer.patch -ANDROID-Removed-hardcoded-kernel-command-line-arguments.patch -ANDROID-gki_defconfig-disable-IP_PNP-ECRYPT_FS.patch -ANDROID-Removed-unnecessary-modules-from-cuttlefish.patch -ANDROID-Adding-GKI-Ramdisk-to-gki-config.patch -ANDROID-staging-ion-refactor-ion-s-buffer-manipulators-into-a-separate-file.patch -ANDROID-staging-ion-refactor-ion-s-dmabuf-manipulators-into-a-separate-file.patch -ANDROID-staging-ion-refactor-ion-s-heap-manipulators-into-a-separate-file.patch -ANDROID-staging-ion-Move-ion-heaps-into-their-own-directory.patch -ANDROID-staging-ion-refactor-ion-s-heap-API-into-linux-ion.h.patch -ANDROID-staging-ion-split-system-and-system-contig-heaps.patch -ANDROID-staging-ion-make-system-and-contig-heaps-modular.patch -ANDROID-staging-ion-Build-fix-for-mips.patch -ANDROID-fix-kernelci-build-break.patch -ANDROID-gki_defconfig-enable-CONFIG_TIPC.patch -ANDROID-gki_defconfig-set-CONFIG_NR_CPUS-32.patch -ANDROID-Revert-um-irq-don-t-set-the-chip-for-all-irqs.patch -ANDROID-Revert-um-remove-uses-of-variable-length-arrays.patch -ANDROID-sdcardfs-fix-fall-through-in-param-parsing.patch -ANDROID-gki_defconfig-Minimally-enable-EFI.patch -ANDROID-gki_defconfig-enable-CONFIG_SPARSEMEM_VMEMMAP.patch -ANDROID-gki_defconfig-enable-CONFIG_QCOM_-COMMAND_DB-RPMH-PDC.patch -ANDROID-refactor-build.config-files-to-remove-duplication.patch -ANDROID-staging-ion-move-uapi-ion.h-to-uapi-linux-ion.h.patch -ANDROID-staging-ion-reserve-specific-heap-ids-for-known-heap-types.patch -ANDROID-staging-ion-add-support-for-consistent-heap-ids.patch -ANDROID-staging-ion-Fix-uninitialized-variable-warning.patch -ANDROID-staging-ion-Add-support-for-heap-specific-dma_buf_ops.patch -ANDROID-staging-ion-Remove-unnecessary-ion-heap-ops.patch -ANDROID-create-build.configs-for-allmodconfig.patch -ANDROID-GKI-enable-CONFIG_SPI-for-x86.patch -ANDROID-GKI-enable-CONFIG_TIPC-for-x86.patch -ANDROID-Catch-rockpi4_defconfig-up-with-gki_defconfig.patch -ANDROID-first-pass-cuttlefish-GKI-modularization.patch -ANDROID-staging-ion-fix-off-by-1-error-in-heap-search.patch -ANDROID-staging-ion-uapi-match-the-existing-heap-type-enums.patch -ANDROID-staging-ion-export-ion_free-for-ion_heaps.patch -ANDROID-cuttlefish-overlayfs-regression.patch -ANDROID-Adding-SERIAL_OF_PLATFORM-module-to-gki.patch -ANDROID-Removed-extraneous-serial-8250-configs.patch -ANDROID-Log-which-device-failed-to-suspend-in-dpm_suspend_start.patch -ANDROID-CONFIG_MMC-m.patch -ANDROID-gki_defconfig-enable-CONFIG_UIO.patch -ANDROID-init-GKI-add-GKI_HACKS_TO_FIX.patch -ANDROID-init-GKI-enable-hidden-configs-for-DRM.patch -ANDROID-init-GKI-enable-hidden-configs-for-regmap.patch -ANDROID-init-GKI-enable-hidden-configs-for-SND_SOC.patch -ANDROID-init-GKI-enable-hidden-configs-for-GPIO.patch -ANDROID-gki_defconfig-Add-GKI_HACKS_to_FIX-config.patch -ANDROID-gki_defconfig-Enable-SERIAL_DEV_BUS.patch -ANDROID-gki_defconfig-Enable-HiSilicon-SoCs.patch -ANDROID-net-enable-wireless-core-features-with-GKI_LEGACY_WEXT_ALLCONFIG.patch -ANDROID-Remove-CONFIG_USELIB-from-x86-gki-config.patch -ANDROID-update-gki_defconfig.patch -ANDROID-update-arm64-gki_defconfig.patch -ANDROID-GKI-export-cma-symbols-for-cma-heap-as-a-module.patch -ANDROID-staging-ion-make-cma-heap-a-module.patch -ANDROID-usb-gadget-Fix-dependency-for-f_accessory.patch -ANDROID-allmodconfig-Force-gki_defconfig-as-base.patch -ANDROID-Fix-arm64-allmodconfig-build.patch -ANDROID-update-gki_defconfig-2.patch -ANDROID-sched-fair-EAS-Add-uclamp-support-to-find_energy_efficient_cpu.patch -ANDROID-sched-Unconditionally-honor-sync-flag-for-energy-aware-wakeups.patch -ANDROID-sched-fair-add-arch-scaling-function-for-max-frequency-capping.patch -ANDROID-cpufreq-arch_topology-implement-max-frequency-capping.patch -ANDROID-arm64-enable-max-frequency-capping.patch -ANDROID-arm-enable-max-frequency-capping.patch -ANDROID-sched-Update-max-cpu-capacity-in-case-of-max-frequency-constraints.patch -ANDROID-sched-Prevent-unnecessary-active-balance-of-single-task-in-sched-group.patch -ANDROID-sched-fair-Attempt-to-improve-throughput-for-asym-cap-systems.patch -ANDROID-sched-fair-Don-t-balance-misfits-if-it-would-overload-local-group.patch -ANDROID-sched-fair-Also-do-misfit-in-overloaded-groups.patch -ANDROID-arm64-defconfig-Enable-EAS-by-default.patch -ANDROID-sched-core-Add-a-latency-sensitive-flag-to-uclamp.patch -ANDROID-sched-Introduce-uclamp-latency-and-boost-wrapper.patch -ANDROID-sched-fair-Bias-EAS-placement-for-latency.patch -ANDROID-Initial-abi_gki_aarch64-definition.patch -ANDROID-Add-an-IOCTL-to-check-ION-ABI-version.patch -FROMGIT-driver-core-Add-fwnode_to_dev-to-look-up-device-from-fwnode.patch -FROMGIT-driver-core-Add-support-for-linking-devices-during-device-addition.patch -FROMGIT-of-property-Add-functional-dependency-link-from-DT-bindings.patch -FROMGIT-driver-core-Add-sync_state-driver-bus-callback.patch -FROMGIT-of-platform-Pause-resume-sync-state-during-init-and-of_platform_populate.patch -FROMGIT-of-property-Create-device-links-for-all-child-supplier-depencencies.patch -ANDROID-gki_defconfig-Enable-BPF_JIT-and-BPF_JIT_ALWAYS_ON.patch -ANDROID-gki_defconfig-enable-REGULATOR.patch -ANDROID-gki_defconfig-enable-CONFIG_NLS_.patch -ANDROID-Revert-kheaders-make-headers-archive-reproducible.patch -ANDROID-staging-ion-fix-sparse-warning-in-ion-system-heap.patch -ANDROID-gki_defconfig-enable-CONFIG_PARAVIRT-and-CONFIG_HYPERVISOR_GUEST.patch -ANDROID-gki_defconfig-enable-accelerated-AES-and-SHA-256.patch -ANDROID-gki_defconfig-enabled-CONFIG_TMPFS-explicitly.patch -ANDROID-gki_defconfig-Enable-CONFIG_DM_SNAPSHOT.patch -ANDROID-Fix-x86_64-allmodconfig-build.patch -ANDROID-clk-add-pre-and-post-change-rate-callbacks.patch -ANDROID-gki_defconfig-enable-fs-verity.patch -UPSTREAM-base-soc-Handle-custom-soc-information-sysfs-entries.patch -ANDROID-unconditionally-compile-sig_ok-in-struct-module.patch -ANDROID-gki_defconfig-remove-PWRSEQ_EMMC-and-PWRSEQ_SIMPLE.patch -ANDROID-sched-Honor-sync-flag-for-energy-aware-wakeups.patch -- GitLab From 692cc83d7c72455e1cddee4d4f814ee922e755e1 Mon Sep 17 00:00:00 2001 From: Ram Muthiah Date: Wed, 16 Oct 2019 15:54:46 -0700 Subject: [PATCH 641/993] ANDROID: Four part re-add of asm-goto usage [1/4] Re-add "x86 uaccess: Introduce __put_user_goto" This reverts commit 60f8cf9e65c98558d0fc76334b17688a8e396c8d. Bug: 120440614 Bug: 132629930 Signed-off-by: Ram Muthiah Change-Id: I1c5ca6ac430694cb46bb8b408e60338e88cbffd6 --- arch/x86/include/asm/uaccess.h | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index d3b6c3ba61d1..0b049e6baf31 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -463,17 +463,23 @@ struct __large_struct { unsigned long buf[100]; }; * we do not write to any memory gcc knows about, so there are no * aliasing issues. */ -#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ - asm volatile("\n" \ - "1: mov"itype" %"rtype"1,%2\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: mov %3,%0\n" \ - " jmp 2b\n" \ - ".previous\n" \ - _ASM_EXTABLE_UA(1b, 3b) \ - : "=r"(err) \ - : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err)) +#define __put_user_goto(x, addr, itype, rtype, ltype, label) \ + asm_volatile_goto("\n" \ + "1: mov"itype" %"rtype"0,%1\n" \ + _ASM_EXTABLE_UA(1b, %l2) \ + : : ltype(x), "m" (__m(addr)) \ + : : label) + +#define __put_user_failed(x, addr, itype, rtype, ltype, errret) \ + ({ __label__ __puflab; \ + int __pufret = errret; \ + __put_user_goto(x,addr,itype,rtype,ltype,__puflab); \ + __pufret = 0; \ + __puflab: __pufret; }) + +#define __put_user_asm(x, addr, retval, itype, rtype, ltype, errret) do { \ + retval = __put_user_failed(x, addr, itype, rtype, ltype, errret); \ +} while (0) #define __put_user_asm_ex(x, addr, itype, rtype, ltype) \ asm volatile("1: mov"itype" %"rtype"0,%1\n" \ -- GitLab From a6e5c4faabbe4b58923c0ffdf9807236a4f0b1bd Mon Sep 17 00:00:00 2001 From: Ram Muthiah Date: Wed, 16 Oct 2019 16:03:14 -0700 Subject: [PATCH 642/993] ANDROID: Four part re-add of asm-goto usage [2/4] Re-add "Use __put_user_goto in __put_user_size() and unsafe_put_user()" This reverts commit 7a71617410d6dbc89c66b9ee0166381a2b3b60b4. Bug: 120440614 Bug: 132629930 Signed-off-by: Ram Muthiah Change-Id: Ife28957c3e9f4e6a44d8e02bc43d683701953369 --- arch/x86/include/asm/uaccess.h | 57 ++++++++++++++-------------------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 0b049e6baf31..8fc40674c174 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -184,19 +184,14 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) #ifdef CONFIG_X86_32 -#define __put_user_asm_u64(x, addr, err, errret) \ - asm volatile("\n" \ - "1: movl %%eax,0(%2)\n" \ - "2: movl %%edx,4(%2)\n" \ - "3:" \ - ".section .fixup,\"ax\"\n" \ - "4: movl %3,%0\n" \ - " jmp 3b\n" \ - ".previous\n" \ - _ASM_EXTABLE_UA(1b, 4b) \ - _ASM_EXTABLE_UA(2b, 4b) \ - : "=r" (err) \ - : "A" (x), "r" (addr), "i" (errret), "0" (err)) +#define __put_user_goto_u64(x, addr, label) \ + asm_volatile_goto("\n" \ + "1: movl %%eax,0(%1)\n" \ + "2: movl %%edx,4(%1)\n" \ + _ASM_EXTABLE_UA(1b, %l2) \ + _ASM_EXTABLE_UA(2b, %l2) \ + : : "A" (x), "r" (addr) \ + : : label) #define __put_user_asm_ex_u64(x, addr) \ asm volatile("\n" \ @@ -211,8 +206,8 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) asm volatile("call __put_user_8" : "=a" (__ret_pu) \ : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx") #else -#define __put_user_asm_u64(x, ptr, retval, errret) \ - __put_user_asm(x, ptr, retval, "q", "", "er", errret) +#define __put_user_goto_u64(x, ptr, label) \ + __put_user_goto(x, ptr, "q", "", "er", label) #define __put_user_asm_ex_u64(x, addr) \ __put_user_asm_ex(x, addr, "q", "", "er") #define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu) @@ -273,23 +268,21 @@ extern void __put_user_8(void); __builtin_expect(__ret_pu, 0); \ }) -#define __put_user_size(x, ptr, size, retval, errret) \ +#define __put_user_size(x, ptr, size, label) \ do { \ - retval = 0; \ __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ - __put_user_asm(x, ptr, retval, "b", "b", "iq", errret); \ + __put_user_goto(x, ptr, "b", "b", "iq", label); \ break; \ case 2: \ - __put_user_asm(x, ptr, retval, "w", "w", "ir", errret); \ + __put_user_goto(x, ptr, "w", "w", "ir", label); \ break; \ case 4: \ - __put_user_asm(x, ptr, retval, "l", "k", "ir", errret); \ + __put_user_goto(x, ptr, "l", "k", "ir", label); \ break; \ case 8: \ - __put_user_asm_u64((__typeof__(*ptr))(x), ptr, retval, \ - errret); \ + __put_user_goto_u64((__typeof__(*ptr))(x), ptr, label); \ break; \ default: \ __put_user_bad(); \ @@ -434,9 +427,12 @@ do { \ #define __put_user_nocheck(x, ptr, size) \ ({ \ - int __pu_err; \ + __label__ __pu_label; \ + int __pu_err = -EFAULT; \ __uaccess_begin(); \ - __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \ + __put_user_size((x), (ptr), (size), __pu_label); \ + __pu_err = 0; \ +__pu_label: \ __uaccess_end(); \ __builtin_expect(__pu_err, 0); \ }) @@ -720,16 +716,11 @@ static __must_check __always_inline bool user_access_begin(const void __user *pt #define user_access_begin(a,b) user_access_begin(a,b) #define user_access_end() __uaccess_end() -#define user_access_save() smap_save() -#define user_access_restore(x) smap_restore(x) +#define user_access_save() smap_save() +#define user_access_restore(x) smap_restore(x) -#define unsafe_put_user(x, ptr, err_label) \ -do { \ - int __pu_err; \ - __typeof__(*(ptr)) __pu_val = (x); \ - __put_user_size(__pu_val, (ptr), sizeof(*(ptr)), __pu_err, -EFAULT); \ - if (unlikely(__pu_err)) goto err_label; \ -} while (0) +#define unsafe_put_user(x, ptr, label) \ + __put_user_size((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) #define unsafe_get_user(x, ptr, err_label) \ do { \ -- GitLab From 265694b7eca2de291c9d8a9aeb1fe8da1a6e3745 Mon Sep 17 00:00:00 2001 From: Ram Muthiah Date: Wed, 16 Oct 2019 16:05:34 -0700 Subject: [PATCH 643/993] ANDROID: Four part re-add of asm-goto usage [3/4] Re-add "x86/uaccess: Don't leak the AC flag into __put_user() value evaluation" This reverts commit a4bd9e975e0ea28242401200a4c2fd618aa2be9d. Bug: 120440614 Bug: 132629930 Signed-off-by: Ram Muthiah Change-Id: Iebfe5df8e2e09b6eeeaae343ec6deeda7f45c975 --- arch/x86/include/asm/uaccess.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 8fc40674c174..176c73385605 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -282,7 +282,7 @@ do { \ __put_user_goto(x, ptr, "l", "k", "ir", label); \ break; \ case 8: \ - __put_user_goto_u64((__typeof__(*ptr))(x), ptr, label); \ + __put_user_goto_u64(x, ptr, label); \ break; \ default: \ __put_user_bad(); \ @@ -429,8 +429,10 @@ do { \ ({ \ __label__ __pu_label; \ int __pu_err = -EFAULT; \ + __typeof__(*(ptr)) __pu_val; \ + __pu_val = x; \ __uaccess_begin(); \ - __put_user_size((x), (ptr), (size), __pu_label); \ + __put_user_size(__pu_val, (ptr), (size), __pu_label); \ __pu_err = 0; \ __pu_label: \ __uaccess_end(); \ -- GitLab From 5a7b085e71c0347fee6c094b4c855e2f12582992 Mon Sep 17 00:00:00 2001 From: Ram Muthiah Date: Wed, 16 Oct 2019 16:17:49 -0700 Subject: [PATCH 644/993] ANDROID: Four part re-add of asm-goto usage [4/4] Re-add "x86/uaccess: Dont leak the AC flag into __put_user() argument evaluation" This reverts commit 2c7164851ef24079bee51560a19ba10addc453b0. Bug: 120440614 Bug: 132629930 Signed-off-by: Ram Muthiah Change-Id: I74ea8dcb2f5c3661dc1657eb53872375aa9e6753 --- arch/x86/include/asm/uaccess.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 176c73385605..61d93f062a36 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -429,10 +429,11 @@ do { \ ({ \ __label__ __pu_label; \ int __pu_err = -EFAULT; \ - __typeof__(*(ptr)) __pu_val; \ - __pu_val = x; \ + __typeof__(*(ptr)) __pu_val = (x); \ + __typeof__(ptr) __pu_ptr = (ptr); \ + __typeof__(size) __pu_size = (size); \ __uaccess_begin(); \ - __put_user_size(__pu_val, (ptr), (size), __pu_label); \ + __put_user_size(__pu_val, __pu_ptr, __pu_size, __pu_label); \ __pu_err = 0; \ __pu_label: \ __uaccess_end(); \ -- GitLab From 146dc14c33e2aafac3dd247531514a23c65b19c7 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 9 Oct 2019 23:11:38 +0000 Subject: [PATCH 645/993] ANDROID: Kconfig.gki: Add extra GKI_HIDDEN_REGMAP_CONFIGS selections Add REGMAP_MMIO to GKI_HIDDEN_REGMAP_CONFIGS Bug: 142268770 Change-Id: I7e67afbd67f31b853abc3a4f7ba596b82a5febef Signed-off-by: John Stultz --- init/Kconfig.gki | 1 + 1 file changed, 1 insertion(+) diff --git a/init/Kconfig.gki b/init/Kconfig.gki index b2f3ecefd782..14265007d7e8 100644 --- a/init/Kconfig.gki +++ b/init/Kconfig.gki @@ -12,6 +12,7 @@ config GKI_HIDDEN_DRM_CONFIGS config GKI_HIDDEN_REGMAP_CONFIGS bool "Hidden Regmap configs needed for GKI" select REGMAP_IRQ + select REGMAP_MMIO help Dummy config option used to enable hidden regmap configs. These are normally selected implicitely when a module -- GitLab From b4750d3d2c2b3951d97d6b2e8c5cbd84c34eb52b Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 9 Oct 2019 23:12:21 +0000 Subject: [PATCH 646/993] ANDROID: Kconfig.gki: Add extra audio selections Add SND_PCM_IEC958 to GKI_HIDDEN_SND_SOC_CONFIGS Bug: 142268770 Change-Id: I0927c00ef476cb232a8f6c87534cadea62d4a21a Signed-off-by: John Stultz --- init/Kconfig.gki | 1 + 1 file changed, 1 insertion(+) diff --git a/init/Kconfig.gki b/init/Kconfig.gki index 14265007d7e8..8dc30bfadcdf 100644 --- a/init/Kconfig.gki +++ b/init/Kconfig.gki @@ -21,6 +21,7 @@ config GKI_HIDDEN_REGMAP_CONFIGS config GKI_HIDDEN_SND_SOC_CONFIGS bool "Hidden SND_SOC configs needed for GKI" select SND_SOC_GENERIC_DMAENGINE_PCM if (SND_SOC && SND) + select SND_PCM_IEC958 help Dummy config option used to enable hidden SND_SOC configs. These are normally selected implicitely when a module -- GitLab From 26a9b13feedfd8e6fd66bf26fd48e236f97437d0 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Tue, 22 Oct 2019 23:48:02 +0000 Subject: [PATCH 647/993] ANDROID: Kconfig.gki: Add SND_PCM_ELD to HIDDEN_DRM configs SND_PCM_ELD is used by DRM drivers for HDMI audio, so add it to the HIDDEN_DRM configs. Bug: 142268770 Change-Id: I914beef34b2cf5174da76a5d1a4d443117f1b687 Signed-off-by: John Stultz --- init/Kconfig.gki | 1 + 1 file changed, 1 insertion(+) diff --git a/init/Kconfig.gki b/init/Kconfig.gki index 8dc30bfadcdf..d8a2cf0adc61 100644 --- a/init/Kconfig.gki +++ b/init/Kconfig.gki @@ -4,6 +4,7 @@ config GKI_HIDDEN_DRM_CONFIGS select DRM_GEM_CMA_HELPER select DRM_KMS_CMA_HELPER select DRM_MIPI_DSI + select SND_PCM_ELD help Dummy config option used to enable hidden DRM configs. These are normally selected implicitely when including a -- GitLab From 612b6ac9ffab57d0b778b3c58afb909f9d4ea8b7 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 9 Oct 2019 23:13:39 +0000 Subject: [PATCH 648/993] ANDROID: Kconfig.gki: Add Hidden QCOM configs Enable hidden QCOM configs via CONFIG_GKI_HACKS_TO_FIX Bug: 142268770 Change-Id: I99e9a05ac631843dafcf33e9b4ceb8e54e40c117 Signed-off-by: John Stultz --- init/Kconfig.gki | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/init/Kconfig.gki b/init/Kconfig.gki index d8a2cf0adc61..85036c08fb7b 100644 --- a/init/Kconfig.gki +++ b/init/Kconfig.gki @@ -37,6 +37,15 @@ config GKI_HIDDEN_GPIO_CONFIGS These are normally selected implicitely when a module that relies on it is configured. +config GKI_HIDDEN_QCOM_CONFIGS + bool "Hidden QCOM configs needed for GKI" + select QCOM_SMEM_STATE + help + Dummy config option used to enable hidden QCOM configs. + These are normally selected implicitely when a module + that relies on it is configured. + + # LEGACY_WEXT_ALLCONFIG Discussed upstream, soundly rejected as a unique # problem for GKI to solve. It should be noted that these extensions are # in-effect deprecated and generally unsupported and we should pressure @@ -69,6 +78,7 @@ config GKI_HACKS_TO_FIX select GKI_HIDDEN_REGMAP_CONFIGS select GKI_HIDDEN_SND_SOC_CONFIGS select GKI_HIDDEN_GPIO_CONFIGS + select GKI_HIDDEN_QCOM_CONFIGS select GKI_LEGACY_WEXT_ALLCONFIG help Dummy config option used to enable core functionality used by -- GitLab From a025c3a713f5137d126d616d1f4c4f3bdd7b5d1a Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 9 Oct 2019 23:16:45 +0000 Subject: [PATCH 649/993] ANDROID: Kconfig.gki: Add hidden MMC config support Enable hidden MMC configs via CONFIG_GKI_HACKS_TO_FIX Bug: 142268770 Change-Id: Ibaba180c46708f1213055f44523b9e7b45eefee6 Signed-off-by: John Stultz --- init/Kconfig.gki | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/init/Kconfig.gki b/init/Kconfig.gki index 85036c08fb7b..4db995c2fe92 100644 --- a/init/Kconfig.gki +++ b/init/Kconfig.gki @@ -28,6 +28,14 @@ config GKI_HIDDEN_SND_SOC_CONFIGS These are normally selected implicitely when a module that relies on it is configured. +config GKI_HIDDEN_MMC_CONFIGS + bool "Hidden MMC configs needed for GKI" + select MMC_SDHCI_IO_ACCESSORS if (MMC_SDHCI) + help + Dummy config option used to enable hidden MMC configs. + These are normally selected implicitely when a module + that relies on it is configured. + config GKI_HIDDEN_GPIO_CONFIGS bool "Hidden GPIO configs needed for GKI" select PINCTRL_SINGLE if (PINCTRL && OF && HAS_IOMEM) @@ -77,6 +85,7 @@ config GKI_HACKS_TO_FIX select GKI_HIDDEN_DRM_CONFIGS select GKI_HIDDEN_REGMAP_CONFIGS select GKI_HIDDEN_SND_SOC_CONFIGS + select GKI_HIDDEN_MMC_CONFIGS select GKI_HIDDEN_GPIO_CONFIGS select GKI_HIDDEN_QCOM_CONFIGS select GKI_LEGACY_WEXT_ALLCONFIG -- GitLab From 91e5e077d8df662ec0e84855bc84bf2f11c803ca Mon Sep 17 00:00:00 2001 From: DongJoo Kim Date: Mon, 21 Oct 2019 11:48:00 +0900 Subject: [PATCH 650/993] ANDROID: move up spin_unlock_bh() ahead of remove_proc_entry() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It causes BUG because remove_proc_entry may sleep while holding spinlock. BUG: scheduling while atomic: ip6tables-resto/887/0x00000202 [] (wait_for_completion) from [] (proc_entry_rundown+0x74/0xd0) [] (proc_entry_rundown) from [] (remove_proc_entry+0xc0/0x18c) [] (remove_proc_entry) from [] (quota_mt2_destroy+0x88/0xa8) [] (quota_mt2_destroy) from [] (cleanup_entry+0x6c/0xf0) [] (cleanup_entry) from [] (do_replace.constprop.2+0x314/0x438) [] (do_replace.constprop.2) from [] (do_ip6t_set_ctl+0x11c/0x238) [] (do_ip6t_set_ctl) from [] (nf_setsockopt+0xd4/0xf0) [] (nf_setsockopt) from [] (ipv6_setsockopt+0x90/0xb8) [] (ipv6_setsockopt) from [] (rawv6_setsockopt+0x54/0x22c) [] (rawv6_setsockopt) from [] (sock_common_setsockopt+0x28/0x30) [] (sock_common_setsockopt) from [] (SyS_setsockopt+0xb8/0x110) [] (SyS_setsockopt) from [] (ret_fast_syscall+0x0/0x48) This is a fix for an Android specific feature which was imported from unofficial upstream (xtables-addons), which also has the same issue: https://sourceforge.net/p/xtables-addons/xtables-addons/ci/master/tree/extensions/xt_quota2.c#l235 After this change the proc entry may now be removed later, when we're already adding another one, potentially with the same name, this will simply fail during creation, see error path for this at: https://sourceforge.net/p/xtables-addons/xtables-addons/ci/master/tree/extensions/xt_quota2.c#l179 Bug: 143092160 Signed-off-by: Maciej Żenczykowski Signed-off-by: DongJoo Kim Change-Id: I3ff3883738353785f5792c5f06bf6b72985c4c68 --- net/netfilter/xt_quota2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/xt_quota2.c b/net/netfilter/xt_quota2.c index 24b774263aa6..c42724469759 100644 --- a/net/netfilter/xt_quota2.c +++ b/net/netfilter/xt_quota2.c @@ -296,8 +296,8 @@ static void quota_mt2_destroy(const struct xt_mtdtor_param *par) } list_del(&e->list); - remove_proc_entry(e->name, proc_xt_quota); spin_unlock_bh(&counter_list_lock); + remove_proc_entry(e->name, proc_xt_quota); kfree(e); } -- GitLab From 98261f39e992543a404353ba2d8f36cb739f329f Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 9 Oct 2019 14:35:48 -0700 Subject: [PATCH 651/993] ANDROID: fscrypt: add key removal notifier chain Add a notifier chain so that sdcardfs can evict its dentries when an fscrypt key is about to be removed. This is needed for the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl to properly "lock" the encrypted files underneath sdcardfs when an Android user is stopped. This is meant to be a temporary patch carried as part of the sdcardfs patchset until either we stop using sdcardfs, we get sdcardfs upstream, or we find a way to provide what sdcardfs needs while also benefitting a user upstream. Bug: 120446149 Bug: 142275883 Test: see I83b451a2bc40c72fcd01d24aa5c34ad8de427534 Change-Id: Iec79775a71057d05a371d77da4a6541cb8e09cb7 Signed-off-by: Eric Biggers --- fs/crypto/keyring.c | 22 ++++++++++++++++++++++ include/linux/fscrypt.h | 14 ++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c index c34fa7c61b43..b3ce0db8b9b8 100644 --- a/fs/crypto/keyring.c +++ b/fs/crypto/keyring.c @@ -704,12 +704,34 @@ static int check_for_busy_inodes(struct super_block *sb, return -EBUSY; } +static BLOCKING_NOTIFIER_HEAD(fscrypt_key_removal_notifiers); + +/* + * Register a function to be executed when the FS_IOC_REMOVE_ENCRYPTION_KEY + * ioctl has removed a key and is about to try evicting inodes. + */ +int fscrypt_register_key_removal_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&fscrypt_key_removal_notifiers, + nb); +} +EXPORT_SYMBOL_GPL(fscrypt_register_key_removal_notifier); + +int fscrypt_unregister_key_removal_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&fscrypt_key_removal_notifiers, + nb); +} +EXPORT_SYMBOL_GPL(fscrypt_unregister_key_removal_notifier); + static int try_to_lock_encrypted_files(struct super_block *sb, struct fscrypt_master_key *mk) { int err1; int err2; + blocking_notifier_call_chain(&fscrypt_key_removal_notifiers, 0, NULL); + /* * An inode can't be evicted while it is dirty or has dirty pages. * Thus, we first have to clean the inodes in ->mk_decrypted_inodes. diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index f622f7460ed8..4ce4a970bb56 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -146,6 +146,8 @@ extern int fscrypt_ioctl_remove_key(struct file *filp, void __user *arg); extern int fscrypt_ioctl_remove_key_all_users(struct file *filp, void __user *arg); extern int fscrypt_ioctl_get_key_status(struct file *filp, void __user *arg); +extern int fscrypt_register_key_removal_notifier(struct notifier_block *nb); +extern int fscrypt_unregister_key_removal_notifier(struct notifier_block *nb); /* keysetup.c */ extern int fscrypt_get_encryption_info(struct inode *); @@ -410,6 +412,18 @@ static inline int fscrypt_ioctl_get_key_status(struct file *filp, return -EOPNOTSUPP; } +static inline int fscrypt_register_key_removal_notifier( + struct notifier_block *nb) +{ + return 0; +} + +static inline int fscrypt_unregister_key_removal_notifier( + struct notifier_block *nb) +{ + return 0; +} + /* keysetup.c */ static inline int fscrypt_get_encryption_info(struct inode *inode) { -- GitLab From 2b6ff0224cbc2b713299c5357f254cbb772fb25e Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 9 Oct 2019 14:35:49 -0700 Subject: [PATCH 652/993] ANDROID: sdcardfs: evict dentries on fscrypt key removal Use the fscrypt key removal notifier chain to make sdcardfs evict its dentries when an fscrypt key is about to be removed. This is needed for the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl to properly "lock" the encrypted files underneath sdcardfs when an Android user is stopped. Test: pm create-user 10 am start-user 10 find /data/media/10/ # filenames are in plaintext form am stop-user 10 find /data/media/10/ # filenames are in ciphertext form (But currently the kernel and vold still warn about other files still being open, due to b/140762419) Bug: 120446149 Bug: 142275883 Change-Id: I83b451a2bc40c72fcd01d24aa5c34ad8de427534 Signed-off-by: Eric Biggers --- fs/sdcardfs/main.c | 7 +++++++ fs/sdcardfs/sdcardfs.h | 3 +++ fs/sdcardfs/super.c | 17 +++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c index 818122410bfe..19fa9c4af462 100644 --- a/fs/sdcardfs/main.c +++ b/fs/sdcardfs/main.c @@ -21,6 +21,7 @@ #include "sdcardfs.h" #include #include +#include #include #include #include @@ -293,6 +294,9 @@ static int __sdcardfs_fill_super( list_add(&sb_info->list, &sdcardfs_super_list); mutex_unlock(&sdcardfs_super_list_lock); + sb_info->fscrypt_nb.notifier_call = sdcardfs_on_fscrypt_key_removed; + fscrypt_register_key_removal_notifier(&sb_info->fscrypt_nb); + if (!(fc->sb_flags & SB_SILENT)) pr_info("sdcardfs: mounted on top of %s type %s\n", dev_name, lower_sb->s_type->name); @@ -331,6 +335,9 @@ void sdcardfs_kill_sb(struct super_block *sb) if (sb->s_magic == SDCARDFS_SUPER_MAGIC && sb->s_fs_info) { sbi = SDCARDFS_SB(sb); + + fscrypt_unregister_key_removal_notifier(&sbi->fscrypt_nb); + mutex_lock(&sdcardfs_super_list_lock); list_del(&sbi->list); mutex_unlock(&sdcardfs_super_list_lock); diff --git a/fs/sdcardfs/sdcardfs.h b/fs/sdcardfs/sdcardfs.h index f813d23cddcd..4af4f163399b 100644 --- a/fs/sdcardfs/sdcardfs.h +++ b/fs/sdcardfs/sdcardfs.h @@ -152,6 +152,8 @@ extern struct inode *sdcardfs_iget(struct super_block *sb, struct inode *lower_inode, userid_t id); extern int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb, struct path *lower_path, userid_t id); +extern int sdcardfs_on_fscrypt_key_removed(struct notifier_block *nb, + unsigned long action, void *data); /* file private data */ struct sdcardfs_file_info { @@ -231,6 +233,7 @@ struct sdcardfs_sb_info { struct path obbpath; void *pkgl_id; struct list_head list; + struct notifier_block fscrypt_nb; }; /* diff --git a/fs/sdcardfs/super.c b/fs/sdcardfs/super.c index 6b1d27e5067b..3d8762e012b8 100644 --- a/fs/sdcardfs/super.c +++ b/fs/sdcardfs/super.c @@ -282,6 +282,23 @@ static int sdcardfs_show_options(struct vfsmount *mnt, struct seq_file *m, return 0; }; +int sdcardfs_on_fscrypt_key_removed(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct sdcardfs_sb_info *sbi = container_of(nb, struct sdcardfs_sb_info, + fscrypt_nb); + + /* + * Evict any unused sdcardfs dentries (and hence any unused sdcardfs + * inodes, since sdcardfs doesn't cache unpinned inodes by themselves) + * so that the lower filesystem's encrypted inodes can be evicted. + * This is needed to make the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl + * properly "lock" the files underneath the sdcardfs mount. + */ + shrink_dcache_sb(sbi->sb); + return NOTIFY_OK; +} + const struct super_operations sdcardfs_sops = { .put_super = sdcardfs_put_super, .statfs = sdcardfs_statfs, -- GitLab From 90db7b220c9aea91948e82d51b99514f9398f9b5 Mon Sep 17 00:00:00 2001 From: David Abdurachmanov Date: Tue, 22 Oct 2019 19:21:35 +0300 Subject: [PATCH 653/993] riscv: fix fs/proc/kcore.c compilation with sparsemem enabled Failed to compile Fedora/RISCV kernel (5.4-rc3+) with sparsemem enabled: fs/proc/kcore.c: In function 'read_kcore': fs/proc/kcore.c:510:8: error: implicit declaration of function 'kern_addr_valid'; did you mean 'virt_addr_valid'? [-Werror=implicit-function-declaration] 510 | if (kern_addr_valid(start)) { | ^~~~~~~~~~~~~~~ | virt_addr_valid Looking at other architectures I don't see kern_addr_valid being guarded by CONFIG_FLATMEM. Fixes: d95f1a542c3d ("RISC-V: Implement sparsemem") Signed-off-by: David Abdurachmanov Tested-by: David Abdurachmanov Reviewed-by: Logan Gunthorpe Signed-off-by: Paul Walmsley --- arch/riscv/include/asm/pgtable.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 42292d99cc74..7110879358b8 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -428,9 +428,7 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma, #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) -#ifdef CONFIG_FLATMEM #define kern_addr_valid(addr) (1) /* FIXME */ -#endif extern void *dtb_early_va; extern void setup_bootmem(void); -- GitLab From 62103ece52360992a6799e9ec85628166a8477e8 Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Wed, 23 Oct 2019 11:23:01 +0800 Subject: [PATCH 654/993] riscv: Fix implicit declaration of 'page_to_section' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With CONFIG_SPARSEMEM and !CONFIG_SPARSEMEM_VMEMMAP, arch/riscv/include/asm/pgtable.h: In function ‘mk_pte’: include/asm-generic/memory_model.h:64:14: error: implicit declaration of function ‘page_to_section’; did you mean ‘present_section’? [-Werror=implicit-function-declaration] int __sec = page_to_section(__pg); \ ^~~~~~~~~~~~~~~ Fixed by changing mk_pte() from inline function to macro. Cc: Logan Gunthorpe Fixes: d95f1a542c3d ("RISC-V: Implement sparsemem") Signed-off-by: Kefeng Wang [paul.walmsley@sifive.com: fixed checkpatch errors] Signed-off-by: Paul Walmsley --- arch/riscv/include/asm/pgtable.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 7110879358b8..0352f20c29f4 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -184,10 +184,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) return __pte((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot)); } -static inline pte_t mk_pte(struct page *page, pgprot_t prot) -{ - return pfn_pte(page_to_pfn(page), prot); -} +#define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot) #define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) -- GitLab From 9fe57d8c575d7dc012bbfcf5698048304206a99d Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Wed, 23 Oct 2019 11:23:02 +0800 Subject: [PATCH 655/993] riscv: Fix undefined reference to vmemmap_populate_basepages Using CONFIG_SPARSEMEM_VMEMMAP instead of CONFIG_SPARSEMEM to fix following build issue. riscv64-linux-ld: arch/riscv/mm/init.o: in function 'vmemmap_populate': init.c:(.meminit.text+0x8): undefined reference to 'vmemmap_populate_basepages' Cc: Logan Gunthorpe Fixes: d95f1a542c3d ("RISC-V: Implement sparsemem") Signed-off-by: Kefeng Wang Reviewed-by: Logan Gunthorpe Signed-off-by: Paul Walmsley --- arch/riscv/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 83f7d12042fb..a1ca6200c31f 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -458,7 +458,7 @@ void __init paging_init(void) zone_sizes_init(); } -#ifdef CONFIG_SPARSEMEM +#ifdef CONFIG_SPARSEMEM_VMEMMAP int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, struct vmem_altmap *altmap) { -- GitLab From a6d9e2672609653146cd9f4063f3d30619828787 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 17 Oct 2019 19:37:29 +0200 Subject: [PATCH 656/993] riscv: cleanup Remove various not required ifdefs and externs. Signed-off-by: Christoph Hellwig Reviewed-by: Anup Patel Signed-off-by: Paul Walmsley --- arch/riscv/include/asm/bug.h | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/arch/riscv/include/asm/bug.h b/arch/riscv/include/asm/bug.h index 07ceee8b1747..75604fec1b1b 100644 --- a/arch/riscv/include/asm/bug.h +++ b/arch/riscv/include/asm/bug.h @@ -12,7 +12,6 @@ #include -#ifdef CONFIG_GENERIC_BUG #define __INSN_LENGTH_MASK _UL(0x3) #define __INSN_LENGTH_32 _UL(0x3) #define __COMPRESSED_INSN_MASK _UL(0xffff) @@ -20,7 +19,6 @@ #define __BUG_INSN_32 _UL(0x00100073) /* ebreak */ #define __BUG_INSN_16 _UL(0x9002) /* c.ebreak */ -#ifndef __ASSEMBLY__ typedef u32 bug_insn_t; #ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS @@ -43,6 +41,7 @@ typedef u32 bug_insn_t; RISCV_SHORT " %2" #endif +#ifdef CONFIG_GENERIC_BUG #define __BUG_FLAGS(flags) \ do { \ __asm__ __volatile__ ( \ @@ -58,14 +57,10 @@ do { \ "i" (flags), \ "i" (sizeof(struct bug_entry))); \ } while (0) - -#endif /* !__ASSEMBLY__ */ #else /* CONFIG_GENERIC_BUG */ -#ifndef __ASSEMBLY__ #define __BUG_FLAGS(flags) do { \ __asm__ __volatile__ ("ebreak\n"); \ } while (0) -#endif /* !__ASSEMBLY__ */ #endif /* CONFIG_GENERIC_BUG */ #define BUG() do { \ @@ -79,15 +74,10 @@ do { \ #include -#ifndef __ASSEMBLY__ - struct pt_regs; struct task_struct; -extern void die(struct pt_regs *regs, const char *str); -extern void do_trap(struct pt_regs *regs, int signo, int code, - unsigned long addr); - -#endif /* !__ASSEMBLY__ */ +void die(struct pt_regs *regs, const char *str); +void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr); #endif /* _ASM_RISCV_BUG_H */ -- GitLab From 780450bc364da413cde30b2cbf3b2d758c6cc098 Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Wed, 23 Oct 2019 22:46:04 +0100 Subject: [PATCH 657/993] ANDROID: Revert "ANDROID: Removed check for asm-goto" This reverts commit 7eb28048b00a3c1ee5cf29b6e416eaf61e79d705. Change-Id: Ibb4775f9d11d5a5e413204855f8ccbcad6777b3d Signed-off-by: Matthias Maennich --- arch/x86/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 408bb5532d1b..94df0868804b 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -298,6 +298,10 @@ vdso_install: archprepare: checkbin checkbin: +ifndef CONFIG_CC_HAS_ASM_GOTO + @echo Compiler lacks asm-goto support. + @exit 1 +endif ifdef CONFIG_RETPOLINE ifeq ($(RETPOLINE_CFLAGS),) @echo "You are building kernel with non-retpoline compiler." >&2 -- GitLab From d4267a57d384334c4b4937cac292bfb150439fc8 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Thu, 24 Oct 2019 10:05:10 +0800 Subject: [PATCH 658/993] MAINTAINERS: Update the Spreadtrum SoC maintainer Change my email address, and add more Spreadtrum SC27xx series PMIC drivers to maintain. Link: https://lore.kernel.org/r/a48483d13243450ecf3b777d49e741b6367f2c6b.1571881956.git.baolin.wang@linaro.org Signed-off-by: Baolin Wang Signed-off-by: Olof Johansson --- MAINTAINERS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 296de2b51c83..baac17ad16d6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2327,11 +2327,13 @@ F: drivers/edac/altera_edac. ARM/SPREADTRUM SoC SUPPORT M: Orson Zhai -M: Baolin Wang +M: Baolin Wang M: Chunyan Zhang S: Maintained F: arch/arm64/boot/dts/sprd N: sprd +N: sc27xx +N: sc2731 ARM/STI ARCHITECTURE M: Patrice Chotard -- GitLab From 55667441c84fa5e0911a0aac44fb059c15ba6da2 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 22 Oct 2019 07:57:46 -0700 Subject: [PATCH 659/993] net/flow_dissector: switch to siphash UDP IPv6 packets auto flowlabels are using a 32bit secret (static u32 hashrnd in net/core/flow_dissector.c) and apply jhash() over fields known by the receivers. Attackers can easily infer the 32bit secret and use this information to identify a device and/or user, since this 32bit secret is only set at boot time. Really, using jhash() to generate cookies sent on the wire is a serious security concern. Trying to change the rol32(hash, 16) in ip6_make_flowlabel() would be a dead end. Trying to periodically change the secret (like in sch_sfq.c) could change paths taken in the network for long lived flows. Let's switch to siphash, as we did in commit df453700e8d8 ("inet: switch IP ID generator to siphash") Using a cryptographically strong pseudo random function will solve this privacy issue and more generally remove other weak points in the stack. Packet schedulers using skb_get_hash_perturb() benefit from this change. Fixes: b56774163f99 ("ipv6: Enable auto flow labels by default") Fixes: 42240901f7c4 ("ipv6: Implement different admin modes for automatic flow labels") Fixes: 67800f9b1f4e ("ipv6: Call skb_get_hash_flowi6 to get skb->hash in ip6_make_flowlabel") Fixes: cb1ce2ef387b ("ipv6: Implement automatic flow label generation on transmit") Signed-off-by: Eric Dumazet Reported-by: Jonathan Berger Reported-by: Amit Klein Reported-by: Benny Pinkas Cc: Tom Herbert Signed-off-by: David S. Miller --- include/linux/skbuff.h | 3 ++- include/net/flow_dissector.h | 3 ++- include/net/fq.h | 2 +- include/net/fq_impl.h | 4 ++-- net/core/flow_dissector.c | 38 +++++++++++++++--------------------- net/sched/sch_hhf.c | 8 ++++---- net/sched/sch_sfb.c | 13 ++++++------ net/sched/sch_sfq.c | 14 +++++++------ 8 files changed, 42 insertions(+), 43 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 7914fdaf4226..a391147c03d4 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1354,7 +1354,8 @@ static inline __u32 skb_get_hash_flowi6(struct sk_buff *skb, const struct flowi6 return skb->hash; } -__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb); +__u32 skb_get_hash_perturb(const struct sk_buff *skb, + const siphash_key_t *perturb); static inline __u32 skb_get_hash_raw(const struct sk_buff *skb) { diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index 90bd210be060..5cd12276ae21 100644 --- a/include/net/flow_dissector.h +++ b/include/net/flow_dissector.h @@ -4,6 +4,7 @@ #include #include +#include #include /** @@ -276,7 +277,7 @@ struct flow_keys_basic { struct flow_keys { struct flow_dissector_key_control control; #define FLOW_KEYS_HASH_START_FIELD basic - struct flow_dissector_key_basic basic; + struct flow_dissector_key_basic basic __aligned(SIPHASH_ALIGNMENT); struct flow_dissector_key_tags tags; struct flow_dissector_key_vlan vlan; struct flow_dissector_key_vlan cvlan; diff --git a/include/net/fq.h b/include/net/fq.h index d126b5d20261..2ad85e683041 100644 --- a/include/net/fq.h +++ b/include/net/fq.h @@ -69,7 +69,7 @@ struct fq { struct list_head backlogs; spinlock_t lock; u32 flows_cnt; - u32 perturbation; + siphash_key_t perturbation; u32 limit; u32 memory_limit; u32 memory_usage; diff --git a/include/net/fq_impl.h b/include/net/fq_impl.h index be40a4b327e3..107c0d700ed6 100644 --- a/include/net/fq_impl.h +++ b/include/net/fq_impl.h @@ -108,7 +108,7 @@ static struct sk_buff *fq_tin_dequeue(struct fq *fq, static u32 fq_flow_idx(struct fq *fq, struct sk_buff *skb) { - u32 hash = skb_get_hash_perturb(skb, fq->perturbation); + u32 hash = skb_get_hash_perturb(skb, &fq->perturbation); return reciprocal_scale(hash, fq->flows_cnt); } @@ -308,7 +308,7 @@ static int fq_init(struct fq *fq, int flows_cnt) INIT_LIST_HEAD(&fq->backlogs); spin_lock_init(&fq->lock); fq->flows_cnt = max_t(u32, flows_cnt, 1); - fq->perturbation = prandom_u32(); + get_random_bytes(&fq->perturbation, sizeof(fq->perturbation)); fq->quantum = 300; fq->limit = 8192; fq->memory_limit = 16 << 20; /* 16 MBytes */ diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 7c09d87d3269..68eda10d0680 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -1350,30 +1350,21 @@ bool __skb_flow_dissect(const struct net *net, } EXPORT_SYMBOL(__skb_flow_dissect); -static u32 hashrnd __read_mostly; +static siphash_key_t hashrnd __read_mostly; static __always_inline void __flow_hash_secret_init(void) { net_get_random_once(&hashrnd, sizeof(hashrnd)); } -static __always_inline u32 __flow_hash_words(const u32 *words, u32 length, - u32 keyval) +static const void *flow_keys_hash_start(const struct flow_keys *flow) { - return jhash2(words, length, keyval); -} - -static inline const u32 *flow_keys_hash_start(const struct flow_keys *flow) -{ - const void *p = flow; - - BUILD_BUG_ON(FLOW_KEYS_HASH_OFFSET % sizeof(u32)); - return (const u32 *)(p + FLOW_KEYS_HASH_OFFSET); + BUILD_BUG_ON(FLOW_KEYS_HASH_OFFSET % SIPHASH_ALIGNMENT); + return &flow->FLOW_KEYS_HASH_START_FIELD; } static inline size_t flow_keys_hash_length(const struct flow_keys *flow) { size_t diff = FLOW_KEYS_HASH_OFFSET + sizeof(flow->addrs); - BUILD_BUG_ON((sizeof(*flow) - FLOW_KEYS_HASH_OFFSET) % sizeof(u32)); BUILD_BUG_ON(offsetof(typeof(*flow), addrs) != sizeof(*flow) - sizeof(flow->addrs)); @@ -1388,7 +1379,7 @@ static inline size_t flow_keys_hash_length(const struct flow_keys *flow) diff -= sizeof(flow->addrs.tipckey); break; } - return (sizeof(*flow) - diff) / sizeof(u32); + return sizeof(*flow) - diff; } __be32 flow_get_u32_src(const struct flow_keys *flow) @@ -1454,14 +1445,15 @@ static inline void __flow_hash_consistentify(struct flow_keys *keys) } } -static inline u32 __flow_hash_from_keys(struct flow_keys *keys, u32 keyval) +static inline u32 __flow_hash_from_keys(struct flow_keys *keys, + const siphash_key_t *keyval) { u32 hash; __flow_hash_consistentify(keys); - hash = __flow_hash_words(flow_keys_hash_start(keys), - flow_keys_hash_length(keys), keyval); + hash = siphash(flow_keys_hash_start(keys), + flow_keys_hash_length(keys), keyval); if (!hash) hash = 1; @@ -1471,12 +1463,13 @@ static inline u32 __flow_hash_from_keys(struct flow_keys *keys, u32 keyval) u32 flow_hash_from_keys(struct flow_keys *keys) { __flow_hash_secret_init(); - return __flow_hash_from_keys(keys, hashrnd); + return __flow_hash_from_keys(keys, &hashrnd); } EXPORT_SYMBOL(flow_hash_from_keys); static inline u32 ___skb_get_hash(const struct sk_buff *skb, - struct flow_keys *keys, u32 keyval) + struct flow_keys *keys, + const siphash_key_t *keyval) { skb_flow_dissect_flow_keys(skb, keys, FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL); @@ -1524,7 +1517,7 @@ u32 __skb_get_hash_symmetric(const struct sk_buff *skb) &keys, NULL, 0, 0, 0, FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL); - return __flow_hash_from_keys(&keys, hashrnd); + return __flow_hash_from_keys(&keys, &hashrnd); } EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric); @@ -1544,13 +1537,14 @@ void __skb_get_hash(struct sk_buff *skb) __flow_hash_secret_init(); - hash = ___skb_get_hash(skb, &keys, hashrnd); + hash = ___skb_get_hash(skb, &keys, &hashrnd); __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys)); } EXPORT_SYMBOL(__skb_get_hash); -__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb) +__u32 skb_get_hash_perturb(const struct sk_buff *skb, + const siphash_key_t *perturb) { struct flow_keys keys; diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c index 23cd1c873a2c..be35f03b657b 100644 --- a/net/sched/sch_hhf.c +++ b/net/sched/sch_hhf.c @@ -5,11 +5,11 @@ * Copyright (C) 2013 Nandita Dukkipati */ -#include #include #include #include #include +#include #include #include @@ -126,7 +126,7 @@ struct wdrr_bucket { struct hhf_sched_data { struct wdrr_bucket buckets[WDRR_BUCKET_CNT]; - u32 perturbation; /* hash perturbation */ + siphash_key_t perturbation; /* hash perturbation */ u32 quantum; /* psched_mtu(qdisc_dev(sch)); */ u32 drop_overlimit; /* number of times max qdisc packet * limit was hit @@ -264,7 +264,7 @@ static enum wdrr_bucket_idx hhf_classify(struct sk_buff *skb, struct Qdisc *sch) } /* Get hashed flow-id of the skb. */ - hash = skb_get_hash_perturb(skb, q->perturbation); + hash = skb_get_hash_perturb(skb, &q->perturbation); /* Check if this packet belongs to an already established HH flow. */ flow_pos = hash & HHF_BIT_MASK; @@ -582,7 +582,7 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt, sch->limit = 1000; q->quantum = psched_mtu(qdisc_dev(sch)); - q->perturbation = prandom_u32(); + get_random_bytes(&q->perturbation, sizeof(q->perturbation)); INIT_LIST_HEAD(&q->new_buckets); INIT_LIST_HEAD(&q->old_buckets); diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c index d448fe3068e5..4074c50ac3d7 100644 --- a/net/sched/sch_sfb.c +++ b/net/sched/sch_sfb.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -45,7 +45,7 @@ struct sfb_bucket { * (Section 4.4 of SFB reference : moving hash functions) */ struct sfb_bins { - u32 perturbation; /* jhash perturbation */ + siphash_key_t perturbation; /* siphash key */ struct sfb_bucket bins[SFB_LEVELS][SFB_NUMBUCKETS]; }; @@ -217,7 +217,8 @@ static u32 sfb_compute_qlen(u32 *prob_r, u32 *avgpm_r, const struct sfb_sched_da static void sfb_init_perturbation(u32 slot, struct sfb_sched_data *q) { - q->bins[slot].perturbation = prandom_u32(); + get_random_bytes(&q->bins[slot].perturbation, + sizeof(q->bins[slot].perturbation)); } static void sfb_swap_slot(struct sfb_sched_data *q) @@ -314,9 +315,9 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch, /* If using external classifiers, get result and record it. */ if (!sfb_classify(skb, fl, &ret, &salt)) goto other_drop; - sfbhash = jhash_1word(salt, q->bins[slot].perturbation); + sfbhash = siphash_1u32(salt, &q->bins[slot].perturbation); } else { - sfbhash = skb_get_hash_perturb(skb, q->bins[slot].perturbation); + sfbhash = skb_get_hash_perturb(skb, &q->bins[slot].perturbation); } @@ -352,7 +353,7 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch, /* Inelastic flow */ if (q->double_buffering) { sfbhash = skb_get_hash_perturb(skb, - q->bins[slot].perturbation); + &q->bins[slot].perturbation); if (!sfbhash) sfbhash = 1; sfb_skb_cb(skb)->hashes[slot] = sfbhash; diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 68404a9d2ce4..c787d4d46017 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -117,7 +117,7 @@ struct sfq_sched_data { u8 headdrop; u8 maxdepth; /* limit of packets per flow */ - u32 perturbation; + siphash_key_t perturbation; u8 cur_depth; /* depth of longest slot */ u8 flags; unsigned short scaled_quantum; /* SFQ_ALLOT_SIZE(quantum) */ @@ -157,7 +157,7 @@ static inline struct sfq_head *sfq_dep_head(struct sfq_sched_data *q, sfq_index static unsigned int sfq_hash(const struct sfq_sched_data *q, const struct sk_buff *skb) { - return skb_get_hash_perturb(skb, q->perturbation) & (q->divisor - 1); + return skb_get_hash_perturb(skb, &q->perturbation) & (q->divisor - 1); } static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch, @@ -607,9 +607,11 @@ static void sfq_perturbation(struct timer_list *t) struct sfq_sched_data *q = from_timer(q, t, perturb_timer); struct Qdisc *sch = q->sch; spinlock_t *root_lock = qdisc_lock(qdisc_root_sleeping(sch)); + siphash_key_t nkey; + get_random_bytes(&nkey, sizeof(nkey)); spin_lock(root_lock); - q->perturbation = prandom_u32(); + q->perturbation = nkey; if (!q->filter_list && q->tail) sfq_rehash(sch); spin_unlock(root_lock); @@ -688,7 +690,7 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt) del_timer(&q->perturb_timer); if (q->perturb_period) { mod_timer(&q->perturb_timer, jiffies + q->perturb_period); - q->perturbation = prandom_u32(); + get_random_bytes(&q->perturbation, sizeof(q->perturbation)); } sch_tree_unlock(sch); kfree(p); @@ -745,7 +747,7 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt, q->quantum = psched_mtu(qdisc_dev(sch)); q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum); q->perturb_period = 0; - q->perturbation = prandom_u32(); + get_random_bytes(&q->perturbation, sizeof(q->perturbation)); if (opt) { int err = sfq_change(sch, opt); -- GitLab From 2afd23f78f39da84937006ecd24aa664a4ab052b Mon Sep 17 00:00:00 2001 From: Magnus Karlsson Date: Mon, 21 Oct 2019 10:16:58 +0200 Subject: [PATCH 660/993] xsk: Fix registration of Rx-only sockets Having Rx-only AF_XDP sockets can potentially lead to a crash in the system by a NULL pointer dereference in xsk_umem_consume_tx(). This function iterates through a list of all sockets tied to a umem and checks if there are any packets to send on the Tx ring. Rx-only sockets do not have a Tx ring, so this will cause a NULL pointer dereference. This will happen if you have registered one or more Rx-only sockets to a umem and the driver is checking the Tx ring even on Rx, or if the XDP_SHARED_UMEM mode is used and there is a mix of Rx-only and other sockets tied to the same umem. Fixed by only putting sockets with a Tx component on the list that xsk_umem_consume_tx() iterates over. Fixes: ac98d8aab61b ("xsk: wire upp Tx zero-copy functions") Reported-by: Kal Cutter Conley Signed-off-by: Magnus Karlsson Signed-off-by: Alexei Starovoitov Acked-by: Jonathan Lemon Link: https://lore.kernel.org/bpf/1571645818-16244-1-git-send-email-magnus.karlsson@intel.com --- net/xdp/xdp_umem.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c index 16d5f353163a..3049af269fbf 100644 --- a/net/xdp/xdp_umem.c +++ b/net/xdp/xdp_umem.c @@ -27,6 +27,9 @@ void xdp_add_sk_umem(struct xdp_umem *umem, struct xdp_sock *xs) { unsigned long flags; + if (!xs->tx) + return; + spin_lock_irqsave(&umem->xsk_list_lock, flags); list_add_rcu(&xs->list, &umem->xsk_list); spin_unlock_irqrestore(&umem->xsk_list_lock, flags); @@ -36,6 +39,9 @@ void xdp_del_sk_umem(struct xdp_umem *umem, struct xdp_sock *xs) { unsigned long flags; + if (!xs->tx) + return; + spin_lock_irqsave(&umem->xsk_list_lock, flags); list_del_rcu(&xs->list); spin_unlock_irqrestore(&umem->xsk_list_lock, flags); -- GitLab From e4f5cb1a9b27c0f94ef4f5a0178a3fde2d3d0e9e Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 22 Oct 2019 21:11:00 +0200 Subject: [PATCH 661/993] MIPS: bmips: mark exception vectors as char arrays The vectors span more than one byte, so mark them as arrays. Fixes the following build error when building when using GCC 8.3: In file included from ./include/linux/string.h:19, from ./include/linux/bitmap.h:9, from ./include/linux/cpumask.h:12, from ./arch/mips/include/asm/processor.h:15, from ./arch/mips/include/asm/thread_info.h:16, from ./include/linux/thread_info.h:38, from ./include/asm-generic/preempt.h:5, from ./arch/mips/include/generated/asm/preempt.h:1, from ./include/linux/preempt.h:81, from ./include/linux/spinlock.h:51, from ./include/linux/mmzone.h:8, from ./include/linux/bootmem.h:8, from arch/mips/bcm63xx/prom.c:10: arch/mips/bcm63xx/prom.c: In function 'prom_init': ./arch/mips/include/asm/string.h:162:11: error: '__builtin_memcpy' forming offset [2, 32] is out of the bounds [0, 1] of object 'bmips_smp_movevec' with type 'char' [-Werror=array-bounds] __ret = __builtin_memcpy((dst), (src), __len); \ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/mips/bcm63xx/prom.c:97:3: note: in expansion of macro 'memcpy' memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20); ^~~~~~ In file included from arch/mips/bcm63xx/prom.c:14: ./arch/mips/include/asm/bmips.h:80:13: note: 'bmips_smp_movevec' declared here extern char bmips_smp_movevec; Fixes: 18a1eef92dcd ("MIPS: BMIPS: Introduce bmips.h") Signed-off-by: Jonas Gorski Reviewed-by: Florian Fainelli Signed-off-by: Paul Burton Cc: linux-mips@vger.kernel.org Cc: Ralf Baechle Cc: James Hogan --- arch/mips/bcm63xx/prom.c | 2 +- arch/mips/include/asm/bmips.h | 10 +++++----- arch/mips/kernel/smp-bmips.c | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c index 77a836e661c9..df69eaa453a1 100644 --- a/arch/mips/bcm63xx/prom.c +++ b/arch/mips/bcm63xx/prom.c @@ -84,7 +84,7 @@ void __init prom_init(void) * Here we will start up CPU1 in the background and ask it to * reconfigure itself then go back to sleep. */ - memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20); + memcpy((void *)0xa0000200, bmips_smp_movevec, 0x20); __sync(); set_c0_cause(C_SW0); cpumask_set_cpu(1, &bmips_booted_mask); diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h index bf6a8afd7ad2..581a6a3c66e4 100644 --- a/arch/mips/include/asm/bmips.h +++ b/arch/mips/include/asm/bmips.h @@ -75,11 +75,11 @@ static inline int register_bmips_smp_ops(void) #endif } -extern char bmips_reset_nmi_vec; -extern char bmips_reset_nmi_vec_end; -extern char bmips_smp_movevec; -extern char bmips_smp_int_vec; -extern char bmips_smp_int_vec_end; +extern char bmips_reset_nmi_vec[]; +extern char bmips_reset_nmi_vec_end[]; +extern char bmips_smp_movevec[]; +extern char bmips_smp_int_vec[]; +extern char bmips_smp_int_vec_end[]; extern int bmips_smp_enabled; extern int bmips_cpu_offset; diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 76fae9b79f13..712c15de6ab9 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -464,10 +464,10 @@ static void bmips_wr_vec(unsigned long dst, char *start, char *end) static inline void bmips_nmi_handler_setup(void) { - bmips_wr_vec(BMIPS_NMI_RESET_VEC, &bmips_reset_nmi_vec, - &bmips_reset_nmi_vec_end); - bmips_wr_vec(BMIPS_WARM_RESTART_VEC, &bmips_smp_int_vec, - &bmips_smp_int_vec_end); + bmips_wr_vec(BMIPS_NMI_RESET_VEC, bmips_reset_nmi_vec, + bmips_reset_nmi_vec_end); + bmips_wr_vec(BMIPS_WARM_RESTART_VEC, bmips_smp_int_vec, + bmips_smp_int_vec_end); } struct reset_vec_info { -- GitLab From bc808bced39f4e4b626c5ea8c63d5e41fce7205a Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 22 Oct 2019 13:14:37 -0600 Subject: [PATCH 662/993] io_uring: revert "io_uring: optimize submit_and_wait API" There are cases where it isn't always safe to block for submission, even if the caller asked to wait for events as well. Revert the previous optimization of doing that. This reverts two commits: bf7ec93c644cb c576666863b78 Fixes: c576666863b78 ("io_uring: optimize submit_and_wait API") Signed-off-by: Jens Axboe --- fs/io_uring.c | 63 ++++++++++++++------------------------------------- 1 file changed, 17 insertions(+), 46 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 67dbe0201e0d..08c2c428e212 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -2292,11 +2292,11 @@ static int io_req_set_file(struct io_ring_ctx *ctx, const struct sqe_submit *s, } static int __io_queue_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, - struct sqe_submit *s, bool force_nonblock) + struct sqe_submit *s) { int ret; - ret = __io_submit_sqe(ctx, req, s, force_nonblock); + ret = __io_submit_sqe(ctx, req, s, true); /* * We async punt it if the file wasn't marked NOWAIT, or if the file @@ -2343,7 +2343,7 @@ static int __io_queue_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, } static int io_queue_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, - struct sqe_submit *s, bool force_nonblock) + struct sqe_submit *s) { int ret; @@ -2356,18 +2356,17 @@ static int io_queue_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, return 0; } - return __io_queue_sqe(ctx, req, s, force_nonblock); + return __io_queue_sqe(ctx, req, s); } static int io_queue_link_head(struct io_ring_ctx *ctx, struct io_kiocb *req, - struct sqe_submit *s, struct io_kiocb *shadow, - bool force_nonblock) + struct sqe_submit *s, struct io_kiocb *shadow) { int ret; int need_submit = false; if (!shadow) - return io_queue_sqe(ctx, req, s, force_nonblock); + return io_queue_sqe(ctx, req, s); /* * Mark the first IO in link list as DRAIN, let all the following @@ -2396,7 +2395,7 @@ static int io_queue_link_head(struct io_ring_ctx *ctx, struct io_kiocb *req, spin_unlock_irq(&ctx->completion_lock); if (need_submit) - return __io_queue_sqe(ctx, req, s, force_nonblock); + return __io_queue_sqe(ctx, req, s); return 0; } @@ -2404,8 +2403,7 @@ static int io_queue_link_head(struct io_ring_ctx *ctx, struct io_kiocb *req, #define SQE_VALID_FLAGS (IOSQE_FIXED_FILE|IOSQE_IO_DRAIN|IOSQE_IO_LINK) static void io_submit_sqe(struct io_ring_ctx *ctx, struct sqe_submit *s, - struct io_submit_state *state, struct io_kiocb **link, - bool force_nonblock) + struct io_submit_state *state, struct io_kiocb **link) { struct io_uring_sqe *sqe_copy; struct io_kiocb *req; @@ -2458,7 +2456,7 @@ static void io_submit_sqe(struct io_ring_ctx *ctx, struct sqe_submit *s, INIT_LIST_HEAD(&req->link_list); *link = req; } else { - io_queue_sqe(ctx, req, s, force_nonblock); + io_queue_sqe(ctx, req, s); } } @@ -2562,8 +2560,7 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, struct sqe_submit *sqes, * that's the end of the chain. Submit the previous link. */ if (!prev_was_link && link) { - io_queue_link_head(ctx, link, &link->submit, shadow_req, - true); + io_queue_link_head(ctx, link, &link->submit, shadow_req); link = NULL; shadow_req = NULL; } @@ -2588,13 +2585,13 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, struct sqe_submit *sqes, sqes[i].has_user = has_user; sqes[i].needs_lock = true; sqes[i].needs_fixed_file = true; - io_submit_sqe(ctx, &sqes[i], statep, &link, true); + io_submit_sqe(ctx, &sqes[i], statep, &link); submitted++; } } if (link) - io_queue_link_head(ctx, link, &link->submit, shadow_req, true); + io_queue_link_head(ctx, link, &link->submit, shadow_req); if (statep) io_submit_state_end(&state); @@ -2726,8 +2723,7 @@ static int io_sq_thread(void *data) return 0; } -static int io_ring_submit(struct io_ring_ctx *ctx, unsigned int to_submit, - bool block_for_last) +static int io_ring_submit(struct io_ring_ctx *ctx, unsigned int to_submit) { struct io_submit_state state, *statep = NULL; struct io_kiocb *link = NULL; @@ -2741,7 +2737,6 @@ static int io_ring_submit(struct io_ring_ctx *ctx, unsigned int to_submit, } for (i = 0; i < to_submit; i++) { - bool force_nonblock = true; struct sqe_submit s; if (!io_get_sqring(ctx, &s)) @@ -2752,8 +2747,7 @@ static int io_ring_submit(struct io_ring_ctx *ctx, unsigned int to_submit, * that's the end of the chain. Submit the previous link. */ if (!prev_was_link && link) { - io_queue_link_head(ctx, link, &link->submit, shadow_req, - force_nonblock); + io_queue_link_head(ctx, link, &link->submit, shadow_req); link = NULL; shadow_req = NULL; } @@ -2775,24 +2769,12 @@ static int io_ring_submit(struct io_ring_ctx *ctx, unsigned int to_submit, s.needs_lock = false; s.needs_fixed_file = false; submit++; - - /* - * The caller will block for events after submit, submit the - * last IO non-blocking. This is either the only IO it's - * submitting, or it already submitted the previous ones. This - * improves performance by avoiding an async punt that we don't - * need to do. - */ - if (block_for_last && submit == to_submit) - force_nonblock = false; - - io_submit_sqe(ctx, &s, statep, &link, force_nonblock); + io_submit_sqe(ctx, &s, statep, &link); } io_commit_sqring(ctx); if (link) - io_queue_link_head(ctx, link, &link->submit, shadow_req, - !block_for_last); + io_queue_link_head(ctx, link, &link->submit, shadow_req); if (statep) io_submit_state_end(statep); @@ -3636,21 +3618,10 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit, wake_up(&ctx->sqo_wait); submitted = to_submit; } else if (to_submit) { - bool block_for_last = false; - to_submit = min(to_submit, ctx->sq_entries); - /* - * Allow last submission to block in a series, IFF the caller - * asked to wait for events and we don't currently have - * enough. This potentially avoids an async punt. - */ - if (to_submit == min_complete && - io_cqring_events(ctx->rings) < min_complete) - block_for_last = true; - mutex_lock(&ctx->uring_lock); - submitted = io_ring_submit(ctx, to_submit, block_for_last); + submitted = io_ring_submit(ctx, to_submit); mutex_unlock(&ctx->uring_lock); } if (flags & IORING_ENTER_GETEVENTS) { -- GitLab From ef03681ae8df770745978148a7fb84796ae99cba Mon Sep 17 00:00:00 2001 From: "zhangyi (F)" Date: Wed, 23 Oct 2019 15:10:08 +0800 Subject: [PATCH 663/993] io_uring : correct timeout req sequence when waiting timeout The sequence number of reqs on the timeout_list before the timeout req should be adjusted in io_timeout_fn(), because the current timeout req will consumes a slot in the cq_ring and cq_tail pointer will be increased, otherwise other timeout reqs may return in advance without waiting for enough wait_nr. Signed-off-by: zhangyi (F) Signed-off-by: Jens Axboe --- fs/io_uring.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 08c2c428e212..b65a68582a7c 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1877,7 +1877,7 @@ static int io_poll_add(struct io_kiocb *req, const struct io_uring_sqe *sqe) static enum hrtimer_restart io_timeout_fn(struct hrtimer *timer) { struct io_ring_ctx *ctx; - struct io_kiocb *req; + struct io_kiocb *req, *prev; unsigned long flags; req = container_of(timer, struct io_kiocb, timeout.timer); @@ -1885,6 +1885,15 @@ static enum hrtimer_restart io_timeout_fn(struct hrtimer *timer) atomic_inc(&ctx->cq_timeouts); spin_lock_irqsave(&ctx->completion_lock, flags); + /* + * Adjust the reqs sequence before the current one because it + * will consume a slot in the cq_ring and the the cq_tail pointer + * will be increased, otherwise other timeout reqs may return in + * advance without waiting for enough wait_nr. + */ + prev = req; + list_for_each_entry_continue_reverse(prev, &ctx->timeout_list, list) + prev->sequence++; list_del(&req->list); io_cqring_fill_event(ctx, req->user_data, -ETIME); -- GitLab From a1f58ba46f794b1168d1107befcf3d4b9f9fd453 Mon Sep 17 00:00:00 2001 From: "zhangyi (F)" Date: Wed, 23 Oct 2019 15:10:09 +0800 Subject: [PATCH 664/993] io_uring: correct timeout req sequence when inserting a new entry The sequence number of the timeout req (req->sequence) indicate the expected completion request. Because of each timeout req consume a sequence number, so the sequence of each timeout req on the timeout list shouldn't be the same. But now, we may get the same number (also incorrect) if we insert a new entry before the last one, such as submit such two timeout reqs on a new ring instance below. req->sequence req_1 (count = 2): 2 req_2 (count = 1): 2 Then, if we submit a nop req, req_2 will still timeout even the nop req finished. This patch fix this problem by adjust the sequence number of each reordered reqs when inserting a new entry. Signed-off-by: zhangyi (F) Signed-off-by: Jens Axboe --- fs/io_uring.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index b65a68582a7c..1b46c72f8975 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1912,6 +1912,7 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe) struct io_ring_ctx *ctx = req->ctx; struct list_head *entry; struct timespec64 ts; + unsigned span = 0; if (unlikely(ctx->flags & IORING_SETUP_IOPOLL)) return -EINVAL; @@ -1960,9 +1961,17 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe) if (ctx->cached_sq_head < nxt_sq_head) tmp += UINT_MAX; - if (tmp >= tmp_nxt) + if (tmp > tmp_nxt) break; + + /* + * Sequence of reqs after the insert one and itself should + * be adjusted because each timeout req consumes a slot. + */ + span++; + nxt->sequence++; } + req->sequence -= span; list_add(&req->list, entry); spin_unlock_irq(&ctx->completion_lock); -- GitLab From b42aa3fd5957e4daf4b69129e5ce752a2a53e7d6 Mon Sep 17 00:00:00 2001 From: Paul Burton Date: Fri, 18 Oct 2019 15:38:48 -0700 Subject: [PATCH 665/993] MIPS: tlbex: Fix build_restore_pagemask KScratch restore build_restore_pagemask() will restore the value of register $1/$at when its restore_scratch argument is non-zero, and aims to do so by filling a branch delay slot. Commit 0b24cae4d535 ("MIPS: Add missing EHB in mtc0 -> mfc0 sequence.") added an EHB instruction (Execution Hazard Barrier) prior to restoring $1 from a KScratch register, in order to resolve a hazard that can result in stale values of the KScratch register being observed. In particular, P-class CPUs from MIPS with out of order execution pipelines such as the P5600 & P6600 are affected. Unfortunately this EHB instruction was inserted in the branch delay slot causing the MFC0 instruction which performs the restoration to no longer execute along with the branch. The result is that the $1 register isn't actually restored, ie. the TLB refill exception handler clobbers it - which is exactly the problem the EHB is meant to avoid for the P-class CPUs. Similarly build_get_pgd_vmalloc() will restore the value of $1/$at when its mode argument equals refill_scratch, and suffers from the same problem. Fix this by in both cases moving the EHB earlier in the emitted code. There's no reason it needs to immediately precede the MFC0 - it simply needs to be between the MTC0 & MFC0. This bug only affects Cavium Octeon systems which use build_fast_tlb_refill_handler(). Signed-off-by: Paul Burton Fixes: 0b24cae4d535 ("MIPS: Add missing EHB in mtc0 -> mfc0 sequence.") Cc: Dmitry Korotin Cc: stable@vger.kernel.org # v3.15+ Cc: linux-mips@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- arch/mips/mm/tlbex.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index e01cb33bfa1a..41bb91f05688 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -653,6 +653,13 @@ static void build_restore_pagemask(u32 **p, struct uasm_reloc **r, int restore_scratch) { if (restore_scratch) { + /* + * Ensure the MFC0 below observes the value written to the + * KScratch register by the prior MTC0. + */ + if (scratch_reg >= 0) + uasm_i_ehb(p); + /* Reset default page size */ if (PM_DEFAULT_MASK >> 16) { uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16); @@ -667,12 +674,10 @@ static void build_restore_pagemask(u32 **p, struct uasm_reloc **r, uasm_i_mtc0(p, 0, C0_PAGEMASK); uasm_il_b(p, r, lid); } - if (scratch_reg >= 0) { - uasm_i_ehb(p); + if (scratch_reg >= 0) UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg); - } else { + else UASM_i_LW(p, 1, scratchpad_offset(0), 0); - } } else { /* Reset default page size */ if (PM_DEFAULT_MASK >> 16) { @@ -921,6 +926,10 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, } if (mode != not_refill && check_for_high_segbits) { uasm_l_large_segbits_fault(l, *p); + + if (mode == refill_scratch && scratch_reg >= 0) + uasm_i_ehb(p); + /* * We get here if we are an xsseg address, or if we are * an xuseg address above (PGDIR_SHIFT+PGDIR_BITS) boundary. @@ -939,12 +948,10 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, uasm_i_jr(p, ptr); if (mode == refill_scratch) { - if (scratch_reg >= 0) { - uasm_i_ehb(p); + if (scratch_reg >= 0) UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg); - } else { + else UASM_i_LW(p, 1, scratchpad_offset(0), 0); - } } else { uasm_i_nop(p); } -- GitLab From 76db2d466f6a929a04775f0f87d837e3bcba44e8 Mon Sep 17 00:00:00 2001 From: Martin Fuzzey Date: Wed, 23 Oct 2019 11:44:24 +0200 Subject: [PATCH 666/993] net: phy: smsc: LAN8740: add PHY_RST_AFTER_CLK_EN flag The LAN8740, like the 8720, also requires a reset after enabling clock. The datasheet [1] 3.8.5.1 says: "During a Hardware reset, an external clock must be supplied to the XTAL1/CLKIN signal." I have observed this issue on a custom i.MX6 based board with the LAN8740A. [1] http://ww1.microchip.com/downloads/en/DeviceDoc/8740a.pdf Signed-off-by: Martin Fuzzey Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/phy/smsc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index dc3d92d340c4..b73298250793 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -327,6 +327,7 @@ static struct phy_driver smsc_phy_driver[] = { .name = "SMSC LAN8740", /* PHY_BASIC_FEATURES */ + .flags = PHY_RST_AFTER_CLK_EN, .probe = smsc_phy_probe, -- GitLab From 603d9299da32955d49995738541f750f2ae74839 Mon Sep 17 00:00:00 2001 From: Frank Wunderlich Date: Thu, 3 Oct 2019 20:53:23 +0200 Subject: [PATCH 667/993] mfd: mt6397: Fix probe after changing mt6397-core Part 3 from this series [1] was not merged due to wrong splitting and breaks mt6323 pmic on bananapi-r2 dmesg prints this line and at least switch is not initialized on bananapi-r2 mt6397 1000d000.pwrap:mt6323: unsupported chip: 0x0 this patch contains only the probe-changes and chip_data structs from original part 3 by Hsin-Hsiung Wang [1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=164155 Fixes: a4872e80ce7d ("mfd: mt6397: Extract IRQ related code from core driver") Signed-off-by: Frank Wunderlich Signed-off-by: Lee Jones --- drivers/mfd/mt6397-core.c | 64 ++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c index 310dae26ddff..b2c325ead1c8 100644 --- a/drivers/mfd/mt6397-core.c +++ b/drivers/mfd/mt6397-core.c @@ -129,11 +129,27 @@ static int mt6397_irq_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend, mt6397_irq_resume); +struct chip_data { + u32 cid_addr; + u32 cid_shift; +}; + +static const struct chip_data mt6323_core = { + .cid_addr = MT6323_CID, + .cid_shift = 0, +}; + +static const struct chip_data mt6397_core = { + .cid_addr = MT6397_CID, + .cid_shift = 0, +}; + static int mt6397_probe(struct platform_device *pdev) { int ret; unsigned int id; struct mt6397_chip *pmic; + const struct chip_data *pmic_core; pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); if (!pmic) @@ -149,28 +165,30 @@ static int mt6397_probe(struct platform_device *pdev) if (!pmic->regmap) return -ENODEV; - platform_set_drvdata(pdev, pmic); + pmic_core = of_device_get_match_data(&pdev->dev); + if (!pmic_core) + return -ENODEV; - ret = regmap_read(pmic->regmap, MT6397_CID, &id); + ret = regmap_read(pmic->regmap, pmic_core->cid_addr, &id); if (ret) { - dev_err(pmic->dev, "Failed to read chip id: %d\n", ret); + dev_err(&pdev->dev, "Failed to read chip id: %d\n", ret); return ret; } + pmic->chip_id = (id >> pmic_core->cid_shift) & 0xff; + + platform_set_drvdata(pdev, pmic); + pmic->irq = platform_get_irq(pdev, 0); if (pmic->irq <= 0) return pmic->irq; - switch (id & 0xff) { - case MT6323_CHIP_ID: - pmic->int_con[0] = MT6323_INT_CON0; - pmic->int_con[1] = MT6323_INT_CON1; - pmic->int_status[0] = MT6323_INT_STATUS0; - pmic->int_status[1] = MT6323_INT_STATUS1; - ret = mt6397_irq_init(pmic); - if (ret) - return ret; + ret = mt6397_irq_init(pmic); + if (ret) + return ret; + switch (pmic->chip_id) { + case MT6323_CHIP_ID: ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs, ARRAY_SIZE(mt6323_devs), NULL, 0, pmic->irq_domain); @@ -178,21 +196,13 @@ static int mt6397_probe(struct platform_device *pdev) case MT6391_CHIP_ID: case MT6397_CHIP_ID: - pmic->int_con[0] = MT6397_INT_CON0; - pmic->int_con[1] = MT6397_INT_CON1; - pmic->int_status[0] = MT6397_INT_STATUS0; - pmic->int_status[1] = MT6397_INT_STATUS1; - ret = mt6397_irq_init(pmic); - if (ret) - return ret; - ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs, ARRAY_SIZE(mt6397_devs), NULL, 0, pmic->irq_domain); break; default: - dev_err(&pdev->dev, "unsupported chip: %d\n", id); + dev_err(&pdev->dev, "unsupported chip: %d\n", pmic->chip_id); return -ENODEV; } @@ -205,9 +215,15 @@ static int mt6397_probe(struct platform_device *pdev) } static const struct of_device_id mt6397_of_match[] = { - { .compatible = "mediatek,mt6397" }, - { .compatible = "mediatek,mt6323" }, - { } + { + .compatible = "mediatek,mt6323", + .data = &mt6323_core, + }, { + .compatible = "mediatek,mt6397", + .data = &mt6397_core, + }, { + /* sentinel */ + } }; MODULE_DEVICE_TABLE(of, mt6397_of_match); -- GitLab From 301b74470db3bdb17fe87c868cabf64db2ded909 Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Thu, 24 Oct 2019 09:48:15 +0100 Subject: [PATCH 668/993] ANDROID: drop patches/ symbolic link This is only valid in repo checkouts and caused issues when rebasing on top. Hence drop it for now until a better solution can be found. Change-Id: If06560c131a57f2e6d82966f9adf3ca628b2468a Signed-off-by: Matthias Maennich --- patches | 1 - 1 file changed, 1 deletion(-) delete mode 120000 patches diff --git a/patches b/patches deleted file mode 120000 index aa800371414b..000000000000 --- a/patches +++ /dev/null @@ -1 +0,0 @@ -../kernel/common-patches/android-mainline/ \ No newline at end of file -- GitLab From 62931f59ce9cbabb934a431f48f2f1f441c605ac Mon Sep 17 00:00:00 2001 From: Davide Caratti Date: Sat, 19 Oct 2019 17:34:35 +0200 Subject: [PATCH 669/993] ipvs: don't ignore errors in case refcounting ip_vs module fails if the IPVS module is removed while the sync daemon is starting, there is a small gap where try_module_get() might fail getting the refcount inside ip_vs_use_count_inc(). Then, the refcounts of IPVS module are unbalanced, and the subsequent call to stop_sync_thread() causes the following splat: WARNING: CPU: 0 PID: 4013 at kernel/module.c:1146 module_put.part.44+0x15b/0x290 Modules linked in: ip_vs(-) nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 veth ip6table_filter ip6_tables iptable_filter binfmt_misc intel_rapl_msr intel_rapl_common crct10dif_pclmul crc32_pclmul ext4 mbcache jbd2 ghash_clmulni_intel snd_hda_codec_generic ledtrig_audio snd_hda_intel snd_intel_nhlt snd_hda_codec snd_hda_core snd_hwdep snd_seq snd_seq_device snd_pcm aesni_intel crypto_simd cryptd glue_helper joydev pcspkr snd_timer virtio_balloon snd soundcore i2c_piix4 nfsd auth_rpcgss nfs_acl lockd grace sunrpc ip_tables xfs libcrc32c ata_generic pata_acpi virtio_net net_failover virtio_blk failover virtio_console qxl drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ata_piix ttm crc32c_intel serio_raw drm virtio_pci libata virtio_ring virtio floppy dm_mirror dm_region_hash dm_log dm_mod [last unloaded: nf_defrag_ipv6] CPU: 0 PID: 4013 Comm: modprobe Tainted: G W 5.4.0-rc1.upstream+ #741 Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 RIP: 0010:module_put.part.44+0x15b/0x290 Code: 04 25 28 00 00 00 0f 85 18 01 00 00 48 83 c4 68 5b 5d 41 5c 41 5d 41 5e 41 5f c3 89 44 24 28 83 e8 01 89 c5 0f 89 57 ff ff ff <0f> 0b e9 78 ff ff ff 65 8b 1d 67 83 26 4a 89 db be 08 00 00 00 48 RSP: 0018:ffff888050607c78 EFLAGS: 00010297 RAX: 0000000000000003 RBX: ffffffffc1420590 RCX: ffffffffb5db0ef9 RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffffffffc1420590 RBP: 00000000ffffffff R08: fffffbfff82840b3 R09: fffffbfff82840b3 R10: 0000000000000001 R11: fffffbfff82840b2 R12: 1ffff1100a0c0f90 R13: ffffffffc1420200 R14: ffff88804f533300 R15: ffff88804f533ca0 FS: 00007f8ea9720740(0000) GS:ffff888053800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f3245abe000 CR3: 000000004c28a006 CR4: 00000000001606f0 Call Trace: stop_sync_thread+0x3a3/0x7c0 [ip_vs] ip_vs_sync_net_cleanup+0x13/0x50 [ip_vs] ops_exit_list.isra.5+0x94/0x140 unregister_pernet_operations+0x29d/0x460 unregister_pernet_device+0x26/0x60 ip_vs_cleanup+0x11/0x38 [ip_vs] __x64_sys_delete_module+0x2d5/0x400 do_syscall_64+0xa5/0x4e0 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x7f8ea8bf0db7 Code: 73 01 c3 48 8b 0d b9 80 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 b8 b0 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 89 80 2c 00 f7 d8 64 89 01 48 RSP: 002b:00007ffcd38d2fe8 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0 RAX: ffffffffffffffda RBX: 0000000002436240 RCX: 00007f8ea8bf0db7 RDX: 0000000000000000 RSI: 0000000000000800 RDI: 00000000024362a8 RBP: 0000000000000000 R08: 00007f8ea8eba060 R09: 00007f8ea8c658a0 R10: 00007ffcd38d2a60 R11: 0000000000000206 R12: 0000000000000000 R13: 0000000000000001 R14: 00000000024362a8 R15: 0000000000000000 irq event stamp: 4538 hardirqs last enabled at (4537): [] quarantine_put+0x9e/0x170 hardirqs last disabled at (4538): [] trace_hardirqs_off_thunk+0x1a/0x20 softirqs last enabled at (4522): [] sk_common_release+0x169/0x2d0 softirqs last disabled at (4520): [] sk_common_release+0xbe/0x2d0 Check the return value of ip_vs_use_count_inc() and let its caller return proper error. Inside do_ip_vs_set_ctl() the module is already refcounted, we don't need refcount/derefcount there. Finally, in register_ip_vs_app() and start_sync_thread(), take the module refcount earlier and ensure it's released in the error path. Change since v1: - better return values in case of failure of ip_vs_use_count_inc(), thanks to Julian Anastasov - no need to increase/decrease the module refcount in ip_vs_set_ctl(), thanks to Julian Anastasov Signed-off-by: Davide Caratti Signed-off-by: Julian Anastasov Signed-off-by: Simon Horman --- net/netfilter/ipvs/ip_vs_app.c | 12 ++++++++++-- net/netfilter/ipvs/ip_vs_ctl.c | 14 ++++---------- net/netfilter/ipvs/ip_vs_pe.c | 3 ++- net/netfilter/ipvs/ip_vs_sched.c | 3 ++- net/netfilter/ipvs/ip_vs_sync.c | 13 ++++++++++--- 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c index 4515056ef1c2..f9b16f2b2219 100644 --- a/net/netfilter/ipvs/ip_vs_app.c +++ b/net/netfilter/ipvs/ip_vs_app.c @@ -193,21 +193,29 @@ struct ip_vs_app *register_ip_vs_app(struct netns_ipvs *ipvs, struct ip_vs_app * mutex_lock(&__ip_vs_app_mutex); + /* increase the module use count */ + if (!ip_vs_use_count_inc()) { + err = -ENOENT; + goto out_unlock; + } + list_for_each_entry(a, &ipvs->app_list, a_list) { if (!strcmp(app->name, a->name)) { err = -EEXIST; + /* decrease the module use count */ + ip_vs_use_count_dec(); goto out_unlock; } } a = kmemdup(app, sizeof(*app), GFP_KERNEL); if (!a) { err = -ENOMEM; + /* decrease the module use count */ + ip_vs_use_count_dec(); goto out_unlock; } INIT_LIST_HEAD(&a->incs_list); list_add(&a->a_list, &ipvs->app_list); - /* increase the module use count */ - ip_vs_use_count_inc(); out_unlock: mutex_unlock(&__ip_vs_app_mutex); diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 8b48e7ce1c2c..c8f81dd15c83 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -1275,7 +1275,8 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u, struct ip_vs_service *svc = NULL; /* increase the module use count */ - ip_vs_use_count_inc(); + if (!ip_vs_use_count_inc()) + return -ENOPROTOOPT; /* Lookup the scheduler by 'u->sched_name' */ if (strcmp(u->sched_name, "none")) { @@ -2435,9 +2436,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) if (copy_from_user(arg, user, len) != 0) return -EFAULT; - /* increase the module use count */ - ip_vs_use_count_inc(); - /* Handle daemons since they have another lock */ if (cmd == IP_VS_SO_SET_STARTDAEMON || cmd == IP_VS_SO_SET_STOPDAEMON) { @@ -2450,13 +2448,13 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) ret = -EINVAL; if (strscpy(cfg.mcast_ifn, dm->mcast_ifn, sizeof(cfg.mcast_ifn)) <= 0) - goto out_dec; + return ret; cfg.syncid = dm->syncid; ret = start_sync_thread(ipvs, &cfg, dm->state); } else { ret = stop_sync_thread(ipvs, dm->state); } - goto out_dec; + return ret; } mutex_lock(&__ip_vs_mutex); @@ -2551,10 +2549,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) out_unlock: mutex_unlock(&__ip_vs_mutex); - out_dec: - /* decrease the module use count */ - ip_vs_use_count_dec(); - return ret; } diff --git a/net/netfilter/ipvs/ip_vs_pe.c b/net/netfilter/ipvs/ip_vs_pe.c index 8e104dff7abc..166c669f0763 100644 --- a/net/netfilter/ipvs/ip_vs_pe.c +++ b/net/netfilter/ipvs/ip_vs_pe.c @@ -68,7 +68,8 @@ int register_ip_vs_pe(struct ip_vs_pe *pe) struct ip_vs_pe *tmp; /* increase the module use count */ - ip_vs_use_count_inc(); + if (!ip_vs_use_count_inc()) + return -ENOENT; mutex_lock(&ip_vs_pe_mutex); /* Make sure that the pe with this name doesn't exist diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c index 2f9d5cd5daee..d4903723be7e 100644 --- a/net/netfilter/ipvs/ip_vs_sched.c +++ b/net/netfilter/ipvs/ip_vs_sched.c @@ -179,7 +179,8 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler) } /* increase the module use count */ - ip_vs_use_count_inc(); + if (!ip_vs_use_count_inc()) + return -ENOENT; mutex_lock(&ip_vs_sched_mutex); diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index a4a78c4b06de..8dc892a9dc91 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c @@ -1762,6 +1762,10 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c, IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %zd bytes\n", sizeof(struct ip_vs_sync_conn_v0)); + /* increase the module use count */ + if (!ip_vs_use_count_inc()) + return -ENOPROTOOPT; + /* Do not hold one mutex and then to block on another */ for (;;) { rtnl_lock(); @@ -1892,9 +1896,6 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c, mutex_unlock(&ipvs->sync_mutex); rtnl_unlock(); - /* increase the module use count */ - ip_vs_use_count_inc(); - return 0; out: @@ -1924,11 +1925,17 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c, } kfree(ti); } + + /* decrease the module use count */ + ip_vs_use_count_dec(); return result; out_early: mutex_unlock(&ipvs->sync_mutex); rtnl_unlock(); + + /* decrease the module use count */ + ip_vs_use_count_dec(); return result; } -- GitLab From c24b75e0f9239e78105f81c5f03a751641eb07ef Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 23 Oct 2019 09:53:03 -0700 Subject: [PATCH 670/993] ipvs: move old_secure_tcp into struct netns_ipvs syzbot reported the following issue : BUG: KCSAN: data-race in update_defense_level / update_defense_level read to 0xffffffff861a6260 of 4 bytes by task 3006 on cpu 1: update_defense_level+0x621/0xb30 net/netfilter/ipvs/ip_vs_ctl.c:177 defense_work_handler+0x3d/0xd0 net/netfilter/ipvs/ip_vs_ctl.c:225 process_one_work+0x3d4/0x890 kernel/workqueue.c:2269 worker_thread+0xa0/0x800 kernel/workqueue.c:2415 kthread+0x1d4/0x200 drivers/block/aoe/aoecmd.c:1253 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:352 write to 0xffffffff861a6260 of 4 bytes by task 7333 on cpu 0: update_defense_level+0xa62/0xb30 net/netfilter/ipvs/ip_vs_ctl.c:205 defense_work_handler+0x3d/0xd0 net/netfilter/ipvs/ip_vs_ctl.c:225 process_one_work+0x3d4/0x890 kernel/workqueue.c:2269 worker_thread+0xa0/0x800 kernel/workqueue.c:2415 kthread+0x1d4/0x200 drivers/block/aoe/aoecmd.c:1253 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:352 Reported by Kernel Concurrency Sanitizer on: CPU: 0 PID: 7333 Comm: kworker/0:5 Not tainted 5.4.0-rc3+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: events defense_work_handler Indeed, old_secure_tcp is currently a static variable, while it needs to be a per netns variable. Fixes: a0840e2e165a ("IPVS: netns, ip_vs_ctl local vars moved to ipvs struct.") Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: Simon Horman --- include/net/ip_vs.h | 1 + net/netfilter/ipvs/ip_vs_ctl.c | 15 +++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 3759167f91f5..078887c8c586 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -889,6 +889,7 @@ struct netns_ipvs { struct delayed_work defense_work; /* Work handler */ int drop_rate; int drop_counter; + int old_secure_tcp; atomic_t dropentry; /* locks in ctl.c */ spinlock_t dropentry_lock; /* drop entry handling */ diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index c8f81dd15c83..3cccc88ef817 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -93,7 +93,6 @@ static bool __ip_vs_addr_is_local_v6(struct net *net, static void update_defense_level(struct netns_ipvs *ipvs) { struct sysinfo i; - static int old_secure_tcp = 0; int availmem; int nomem; int to_change = -1; @@ -174,35 +173,35 @@ static void update_defense_level(struct netns_ipvs *ipvs) spin_lock(&ipvs->securetcp_lock); switch (ipvs->sysctl_secure_tcp) { case 0: - if (old_secure_tcp >= 2) + if (ipvs->old_secure_tcp >= 2) to_change = 0; break; case 1: if (nomem) { - if (old_secure_tcp < 2) + if (ipvs->old_secure_tcp < 2) to_change = 1; ipvs->sysctl_secure_tcp = 2; } else { - if (old_secure_tcp >= 2) + if (ipvs->old_secure_tcp >= 2) to_change = 0; } break; case 2: if (nomem) { - if (old_secure_tcp < 2) + if (ipvs->old_secure_tcp < 2) to_change = 1; } else { - if (old_secure_tcp >= 2) + if (ipvs->old_secure_tcp >= 2) to_change = 0; ipvs->sysctl_secure_tcp = 1; } break; case 3: - if (old_secure_tcp < 2) + if (ipvs->old_secure_tcp < 2) to_change = 1; break; } - old_secure_tcp = ipvs->sysctl_secure_tcp; + ipvs->old_secure_tcp = ipvs->sysctl_secure_tcp; if (to_change >= 0) ip_vs_protocol_timeout_change(ipvs, ipvs->sysctl_secure_tcp > 1); -- GitLab From a69a85da458f79088c38a38db034a4d64d9c32c3 Mon Sep 17 00:00:00 2001 From: wenxu Date: Thu, 24 Oct 2019 15:52:45 +0800 Subject: [PATCH 671/993] netfilter: nft_payload: fix missing check for matching length in offloads Payload offload rule should also check the length of the match. Moreover, check for unsupported link-layer fields: nft --debug=netlink add rule firewall zones vlan id 100 ... [ payload load 2b @ link header + 0 => reg 1 ] this loads 2byte base on ll header and offset 0. This also fixes unsupported raw payload match. Fixes: 92ad6325cb89 ("netfilter: nf_tables: add hardware offload support") Signed-off-by: wenxu Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nft_payload.c | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c index 22a80eb60222..5cb2d8908d2a 100644 --- a/net/netfilter/nft_payload.c +++ b/net/netfilter/nft_payload.c @@ -161,13 +161,21 @@ static int nft_payload_offload_ll(struct nft_offload_ctx *ctx, switch (priv->offset) { case offsetof(struct ethhdr, h_source): + if (priv->len != ETH_ALEN) + return -EOPNOTSUPP; + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs, src, ETH_ALEN, reg); break; case offsetof(struct ethhdr, h_dest): + if (priv->len != ETH_ALEN) + return -EOPNOTSUPP; + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs, dst, ETH_ALEN, reg); break; + default: + return -EOPNOTSUPP; } return 0; @@ -181,14 +189,23 @@ static int nft_payload_offload_ip(struct nft_offload_ctx *ctx, switch (priv->offset) { case offsetof(struct iphdr, saddr): + if (priv->len != sizeof(struct in_addr)) + return -EOPNOTSUPP; + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, src, sizeof(struct in_addr), reg); break; case offsetof(struct iphdr, daddr): + if (priv->len != sizeof(struct in_addr)) + return -EOPNOTSUPP; + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, dst, sizeof(struct in_addr), reg); break; case offsetof(struct iphdr, protocol): + if (priv->len != sizeof(__u8)) + return -EOPNOTSUPP; + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto, sizeof(__u8), reg); nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT); @@ -208,14 +225,23 @@ static int nft_payload_offload_ip6(struct nft_offload_ctx *ctx, switch (priv->offset) { case offsetof(struct ipv6hdr, saddr): + if (priv->len != sizeof(struct in6_addr)) + return -EOPNOTSUPP; + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, src, sizeof(struct in6_addr), reg); break; case offsetof(struct ipv6hdr, daddr): + if (priv->len != sizeof(struct in6_addr)) + return -EOPNOTSUPP; + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, dst, sizeof(struct in6_addr), reg); break; case offsetof(struct ipv6hdr, nexthdr): + if (priv->len != sizeof(__u8)) + return -EOPNOTSUPP; + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto, sizeof(__u8), reg); nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT); @@ -255,10 +281,16 @@ static int nft_payload_offload_tcp(struct nft_offload_ctx *ctx, switch (priv->offset) { case offsetof(struct tcphdr, source): + if (priv->len != sizeof(__be16)) + return -EOPNOTSUPP; + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src, sizeof(__be16), reg); break; case offsetof(struct tcphdr, dest): + if (priv->len != sizeof(__be16)) + return -EOPNOTSUPP; + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst, sizeof(__be16), reg); break; @@ -277,10 +309,16 @@ static int nft_payload_offload_udp(struct nft_offload_ctx *ctx, switch (priv->offset) { case offsetof(struct udphdr, source): + if (priv->len != sizeof(__be16)) + return -EOPNOTSUPP; + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src, sizeof(__be16), reg); break; case offsetof(struct udphdr, dest): + if (priv->len != sizeof(__be16)) + return -EOPNOTSUPP; + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst, sizeof(__be16), reg); break; -- GitLab From e2995b95a914bbc6b5352be27d5d5f33ec802d2c Mon Sep 17 00:00:00 2001 From: Justin Song Date: Thu, 24 Oct 2019 12:27:14 +0200 Subject: [PATCH 672/993] ALSA: usb-audio: Add DSD support for Gustard U16/X26 USB Interface This patch adds native DSD support for Gustard U16/X26 USB Interface. Tested using VID and fp->dsd_raw method. Signed-off-by: Justin Song Cc: Link: https://lore.kernel.org/r/CA+9XP1ipsFn+r3bCBKRinQv-JrJ+EHOGBdZWZoMwxFv0R8Y1MQ@mail.gmail.com Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index fbfde996fee7..0bbe1201a6ac 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1657,6 +1657,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, case 0x23ba: /* Playback Designs */ case 0x25ce: /* Mytek devices */ case 0x278b: /* Rotel? */ + case 0x292b: /* Gustard/Ess based devices */ case 0x2ab6: /* T+A devices */ case 0x3842: /* EVGA */ case 0xc502: /* HiBy devices */ -- GitLab From f0778871a13889b86a65d4ad34bef8340af9d082 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Thu, 24 Oct 2019 15:13:32 +0800 Subject: [PATCH 673/993] ALSA: hda/realtek - Add support for ALC623 Support new codec ALC623. Signed-off-by: Kailang Yang Cc: Link: https://lore.kernel.org/r/ed97b6a8bd9445ecb48bc763d9aaba7a@realtek.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 085a2f95e076..a0c237cc13d4 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -409,6 +409,9 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) case 0x10ec0672: alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */ break; + case 0x10ec0623: + alc_update_coef_idx(codec, 0x19, 1<<13, 0); + break; case 0x10ec0668: alc_update_coef_idx(codec, 0x7, 3<<13, 0); break; @@ -2920,6 +2923,7 @@ enum { ALC269_TYPE_ALC225, ALC269_TYPE_ALC294, ALC269_TYPE_ALC300, + ALC269_TYPE_ALC623, ALC269_TYPE_ALC700, }; @@ -2955,6 +2959,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) case ALC269_TYPE_ALC225: case ALC269_TYPE_ALC294: case ALC269_TYPE_ALC300: + case ALC269_TYPE_ALC623: case ALC269_TYPE_ALC700: ssids = alc269_ssids; break; @@ -8017,6 +8022,9 @@ static int patch_alc269(struct hda_codec *codec) spec->codec_variant = ALC269_TYPE_ALC300; spec->gen.mixer_nid = 0; /* no loopback on ALC300 */ break; + case 0x10ec0623: + spec->codec_variant = ALC269_TYPE_ALC623; + break; case 0x10ec0700: case 0x10ec0701: case 0x10ec0703: @@ -9218,6 +9226,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = { HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269), HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269), HDA_CODEC_ENTRY(0x10ec0300, "ALC300", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0623, "ALC623", patch_alc269), HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861), HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd), HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861), -- GitLab From 8a6c55d0f883e9a7e7c91841434f3b6bbf932bb2 Mon Sep 17 00:00:00 2001 From: Aaron Ma Date: Thu, 24 Oct 2019 19:44:39 +0800 Subject: [PATCH 674/993] ALSA: hda/realtek - Fix 2 front mics of codec 0x623 These 2 ThinkCentres installed a new realtek codec ID 0x623, it has 2 front mics with the same location on pin 0x18 and 0x19. Apply fixup ALC283_FIXUP_HEADSET_MIC to change 1 front mic location to right, then pulseaudio can handle them. One "Front Mic" and one "Mic" will be shown, and audio output works fine. Signed-off-by: Aaron Ma Cc: Link: https://lore.kernel.org/r/20191024114439.31522-1-aaron.ma@canonical.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a0c237cc13d4..80f66ba85f87 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7221,6 +7221,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x17aa, 0x3176, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x17aa, 0x3178, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI), -- GitLab From 30aecae86e914f526a2ca8d552011960ef6a2615 Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Fri, 4 Oct 2019 11:51:58 -0500 Subject: [PATCH 675/993] gfs2: Fix memory leak when gfs2meta's fs_context is freed gfs2 and gfs2meta share an ->init_fs_context function which allocates an args structure stored in fc->fs_private. gfs2 registers a ->free function to free this memory when the fs_context is cleaned up, but there was not one registered for gfs2meta, causing a leak. Register a ->free function for gfs2meta. The existing gfs2_fc_free function does what we need. Reported-by: syzbot+c2fdfd2b783754878fb6@syzkaller.appspotmail.com Fixes: 1f52aa08d12f ("gfs2: Convert gfs2 to fs_context") Signed-off-by: Andrew Price Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/ops_fstype.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 681b44682b0d..dc61af2c4d5e 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1600,6 +1600,7 @@ static int gfs2_meta_get_tree(struct fs_context *fc) } static const struct fs_context_operations gfs2_meta_context_ops = { + .free = gfs2_fc_free, .get_tree = gfs2_meta_get_tree, }; -- GitLab From 808a504f394bdd68c282c461960ad94eb41e6502 Mon Sep 17 00:00:00 2001 From: Lina Iyer Date: Fri, 13 Sep 2019 15:59:09 -0600 Subject: [PATCH 676/993] FROMLIST: irqdomain: add bus token DOMAIN_BUS_WAKEUP A single controller can handle normal interrupts and wake-up interrupts independently, with a different numbering space. It is thus crucial to allow the driver for such a controller discriminate between the two. A simple way to do so is to tag the wake-up irqdomain with a "bus token" that indicates the wake-up domain. This slightly abuses the notion of bus, but also radically simplifies the design of such a driver. Between two evils, we choose the least damaging. Suggested-by: Stephen Boyd Signed-off-by: Lina Iyer BUG: 141169320 TEST: Build and boot Change-Id: I0fd6ccc288d1aa840d88392e5f57197c1e8d1afb Signed-off-by: Maulik Shah Link: https://patchwork.kernel.org/patch/11145365 --- include/linux/irqdomain.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 583e7abd07f9..3c340dbc5a1f 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -83,6 +83,7 @@ enum irq_domain_bus_token { DOMAIN_BUS_IPI, DOMAIN_BUS_FSL_MC_MSI, DOMAIN_BUS_TI_SCI_INTA_MSI, + DOMAIN_BUS_WAKEUP, }; /** -- GitLab From 68bb4012e210ef67a601480c3af887d1141be858 Mon Sep 17 00:00:00 2001 From: Lina Iyer Date: Fri, 13 Sep 2019 15:59:10 -0600 Subject: [PATCH 677/993] FROMLIST: drivers: irqchip: qcom-pdc: update max PDC interrupts Newer SoCs have increased the number of interrupts routed to the PDC interrupt controller. Update the definition of max PDC interrupts. Signed-off-by: Lina Iyer BUG: 141169320 TEST: Build and boot Change-Id: I97f548fcd42a5fef63b8f8cbea9470e83f5e8e3e Signed-off-by: Maulik Shah Link: https://patchwork.kernel.org/patch/11145363 --- drivers/irqchip/qcom-pdc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index faa7d61b9d6c..b230794e38c1 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. */ #include @@ -18,7 +18,7 @@ #include #include -#define PDC_MAX_IRQS 126 +#define PDC_MAX_IRQS 168 #define CLEAR_INTR(reg, intr) (reg & ~(1 << intr)) #define ENABLE_INTR(reg, intr) (reg | (1 << intr)) -- GitLab From 8c77c18adc5a07e67a50056034f4bc0cf3c039d0 Mon Sep 17 00:00:00 2001 From: Lina Iyer Date: Fri, 13 Sep 2019 15:59:11 -0600 Subject: [PATCH 678/993] FROMLIST: drivers: irqchip: pdc: Do not toggle IRQ_ENABLE during mask/unmask When an interrupt is to be serviced, the convention is to mask the interrupt at the chip and unmask after servicing the interrupt. Enabling and disabling the interrupt at the PDC irqchip causes an interrupt storm due to the way dual edge interrupts are handled in hardware. Skip configuring the PDC when the IRQ is masked and unmasked, instead use the irq_enable/irq_disable callbacks to toggle the IRQ_ENABLE register at the PDC. The PDC's IRQ_ENABLE register is only used during the monitoring mode when the system is asleep and is not needed for active mode detection. Signed-off-by: Lina Iyer BUG: 141169320 TEST: Build and boot Change-Id: Ia5827a509bfb47aaa18ed0ea8f61c74f643fa91f Signed-off-by: Maulik Shah Link: https://patchwork.kernel.org/patch/11145361 --- drivers/irqchip/qcom-pdc.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index b230794e38c1..5eef5eab78df 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -63,15 +63,25 @@ static void pdc_enable_intr(struct irq_data *d, bool on) raw_spin_unlock(&pdc_lock); } -static void qcom_pdc_gic_mask(struct irq_data *d) +static void qcom_pdc_gic_disable(struct irq_data *d) { pdc_enable_intr(d, false); + irq_chip_disable_parent(d); +} + +static void qcom_pdc_gic_enable(struct irq_data *d) +{ + pdc_enable_intr(d, true); + irq_chip_enable_parent(d); +} + +static void qcom_pdc_gic_mask(struct irq_data *d) +{ irq_chip_mask_parent(d); } static void qcom_pdc_gic_unmask(struct irq_data *d) { - pdc_enable_intr(d, true); irq_chip_unmask_parent(d); } @@ -148,6 +158,8 @@ static struct irq_chip qcom_pdc_gic_chip = { .irq_eoi = irq_chip_eoi_parent, .irq_mask = qcom_pdc_gic_mask, .irq_unmask = qcom_pdc_gic_unmask, + .irq_disable = qcom_pdc_gic_disable, + .irq_enable = qcom_pdc_gic_enable, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_set_type = qcom_pdc_gic_set_type, .flags = IRQCHIP_MASK_ON_SUSPEND | -- GitLab From 736036d73892136f620d3d544c9c01ec254c7596 Mon Sep 17 00:00:00 2001 From: Lina Iyer Date: Fri, 13 Sep 2019 15:59:12 -0600 Subject: [PATCH 679/993] FROMLIST: drivers: irqchip: add PDC irqdomain for wakeup capable GPIOs Introduce a new domain for wakeup capable GPIOs. The domain can be requested using the bus token DOMAIN_BUS_WAKEUP. In the following patches, we will specify PDC as the wakeup-parent for the TLMM GPIO irqchip. Requesting a wakeup GPIO will setup the GPIO and the corresponding PDC interrupt as its parent. Co-developed-by: Stephen Boyd Signed-off-by: Stephen Boyd Signed-off-by: Lina Iyer BUG: 141169320 TEST: Build and boot Change-Id: Iaec0f39c86776d3f8cebe869c4ccaaba541c7ad5 Signed-off-by: Maulik Shah Link: https://patchwork.kernel.org/patch/11145357 --- drivers/irqchip/qcom-pdc.c | 104 ++++++++++++++++++++++++++++++++--- include/linux/soc/qcom/irq.h | 19 +++++++ 2 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 include/linux/soc/qcom/irq.h diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index 5eef5eab78df..4abd775ef655 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -13,12 +13,13 @@ #include #include #include +#include #include -#include #include #include #define PDC_MAX_IRQS 168 +#define PDC_MAX_GPIO_IRQS 256 #define CLEAR_INTR(reg, intr) (reg & ~(1 << intr)) #define ENABLE_INTR(reg, intr) (reg | (1 << intr)) @@ -26,6 +27,8 @@ #define IRQ_ENABLE_BANK 0x10 #define IRQ_i_CFG 0x110 +#define PDC_NO_PARENT_IRQ ~0UL + struct pdc_pin_region { u32 pin_base; u32 parent_base; @@ -65,23 +68,35 @@ static void pdc_enable_intr(struct irq_data *d, bool on) static void qcom_pdc_gic_disable(struct irq_data *d) { + if (d->hwirq == GPIO_NO_WAKE_IRQ) + return; + pdc_enable_intr(d, false); irq_chip_disable_parent(d); } static void qcom_pdc_gic_enable(struct irq_data *d) { + if (d->hwirq == GPIO_NO_WAKE_IRQ) + return; + pdc_enable_intr(d, true); irq_chip_enable_parent(d); } static void qcom_pdc_gic_mask(struct irq_data *d) { + if (d->hwirq == GPIO_NO_WAKE_IRQ) + return; + irq_chip_mask_parent(d); } static void qcom_pdc_gic_unmask(struct irq_data *d) { + if (d->hwirq == GPIO_NO_WAKE_IRQ) + return; + irq_chip_unmask_parent(d); } @@ -124,6 +139,9 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) int pin_out = d->hwirq; enum pdc_irq_config_bits pdc_type; + if (pin_out == GPIO_NO_WAKE_IRQ) + return 0; + switch (type) { case IRQ_TYPE_EDGE_RISING: pdc_type = PDC_EDGE_RISING; @@ -181,8 +199,7 @@ static irq_hw_number_t get_parent_hwirq(int pin) return (region->parent_base + pin - region->pin_base); } - WARN_ON(1); - return ~0UL; + return PDC_NO_PARENT_IRQ; } static int qcom_pdc_translate(struct irq_domain *d, struct irq_fwspec *fwspec, @@ -211,17 +228,17 @@ static int qcom_pdc_alloc(struct irq_domain *domain, unsigned int virq, ret = qcom_pdc_translate(domain, fwspec, &hwirq, &type); if (ret) - return -EINVAL; - - parent_hwirq = get_parent_hwirq(hwirq); - if (parent_hwirq == ~0UL) - return -EINVAL; + return ret; ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, &qcom_pdc_gic_chip, NULL); if (ret) return ret; + parent_hwirq = get_parent_hwirq(hwirq); + if (parent_hwirq == PDC_NO_PARENT_IRQ) + return 0; + if (type & IRQ_TYPE_EDGE_BOTH) type = IRQ_TYPE_EDGE_RISING; @@ -244,6 +261,60 @@ static const struct irq_domain_ops qcom_pdc_ops = { .free = irq_domain_free_irqs_common, }; +static int qcom_pdc_gpio_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *data) +{ + struct irq_fwspec *fwspec = data; + struct irq_fwspec parent_fwspec; + irq_hw_number_t hwirq, parent_hwirq; + unsigned int type; + int ret; + + ret = qcom_pdc_translate(domain, fwspec, &hwirq, &type); + if (ret) + return ret; + + ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, + &qcom_pdc_gic_chip, NULL); + if (ret) + return ret; + + if (hwirq == GPIO_NO_WAKE_IRQ) + return 0; + + parent_hwirq = get_parent_hwirq(hwirq); + if (parent_hwirq == PDC_NO_PARENT_IRQ) + return 0; + + if (type & IRQ_TYPE_EDGE_BOTH) + type = IRQ_TYPE_EDGE_RISING; + + if (type & IRQ_TYPE_LEVEL_MASK) + type = IRQ_TYPE_LEVEL_HIGH; + + parent_fwspec.fwnode = domain->parent->fwnode; + parent_fwspec.param_count = 3; + parent_fwspec.param[0] = 0; + parent_fwspec.param[1] = parent_hwirq; + parent_fwspec.param[2] = type; + + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, + &parent_fwspec); +} + +static int qcom_pdc_gpio_domain_select(struct irq_domain *d, + struct irq_fwspec *fwspec, + enum irq_domain_bus_token bus_token) +{ + return bus_token == DOMAIN_BUS_WAKEUP; +} + +static const struct irq_domain_ops qcom_pdc_gpio_ops = { + .select = qcom_pdc_gpio_domain_select, + .alloc = qcom_pdc_gpio_alloc, + .free = irq_domain_free_irqs_common, +}; + static int pdc_setup_pin_mapping(struct device_node *np) { int ret, n; @@ -282,7 +353,7 @@ static int pdc_setup_pin_mapping(struct device_node *np) static int qcom_pdc_init(struct device_node *node, struct device_node *parent) { - struct irq_domain *parent_domain, *pdc_domain; + struct irq_domain *parent_domain, *pdc_domain, *pdc_gpio_domain; int ret; pdc_base = of_iomap(node, 0); @@ -313,8 +384,23 @@ static int qcom_pdc_init(struct device_node *node, struct device_node *parent) goto fail; } + pdc_gpio_domain = irq_domain_create_hierarchy(parent_domain, + IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP, + PDC_MAX_GPIO_IRQS, + of_fwnode_handle(node), + &qcom_pdc_gpio_ops, NULL); + if (!pdc_gpio_domain) { + pr_err("%pOF: PDC domain add failed for GPIO domain\n", node); + ret = -ENOMEM; + goto remove; + } + + irq_domain_update_bus_token(pdc_gpio_domain, DOMAIN_BUS_WAKEUP); + return 0; +remove: + irq_domain_remove(pdc_domain); fail: kfree(pdc_region); iounmap(pdc_base); diff --git a/include/linux/soc/qcom/irq.h b/include/linux/soc/qcom/irq.h new file mode 100644 index 000000000000..85ac4b6cf3fb --- /dev/null +++ b/include/linux/soc/qcom/irq.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __QCOM_IRQ_H +#define __QCOM_IRQ_H + +#define GPIO_NO_WAKE_IRQ ~0U + +/** + * QCOM specific IRQ domain flags that distinguishes the handling of wakeup + * capable interrupts by different interrupt controllers. + * + * IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP: Line must be masked at TLMM and the + * interrupt configuration is done at PDC + * IRQ_DOMAIN_FLAG_QCOM_MPM_WAKEUP: Interrupt configuration is handled at TLMM + */ +#define IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP (IRQ_DOMAIN_FLAG_NONCORE << 0) +#define IRQ_DOMAIN_FLAG_QCOM_MPM_WAKEUP (IRQ_DOMAIN_FLAG_NONCORE << 1) + +#endif -- GitLab From 18af63b34e2538bac56532281218bef7aa62403d Mon Sep 17 00:00:00 2001 From: Lina Iyer Date: Fri, 13 Sep 2019 15:59:13 -0600 Subject: [PATCH 680/993] FROMLIST: of: irq: document properties for wakeup interrupt parent Some interrupt controllers in a SoC, are always powered on and have a select interrupts routed to them, so that they can wakeup the SoC from suspend. Add wakeup-parent DT property to refer to these interrupt controllers. Cc: devicetree@vger.kernel.org Signed-off-by: Lina Iyer Reviewed-by: Rob Herring Reviewed-by: Linus Walleij BUG: 141169320 TEST: Build and boot Change-Id: Idf50e6db657e9d08e369878c261c0d781523ce35 Signed-off-by: Maulik Shah Link: https://patchwork.kernel.org/patch/11145359 --- .../bindings/interrupt-controller/interrupts.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt index 4a3ee253f7f0..4ebfa0008781 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt @@ -108,3 +108,15 @@ commonly used: sensitivity = <7>; }; }; + +3) Interrupt wakeup parent +-------------------------- + +Some interrupt controllers in a SoC, are always powered on and have a select +interrupts routed to them, so that they can wakeup the SoC from suspend. These +interrupt controllers do not fall into the category of a parent interrupt +controller and can be specified by the "wakeup-parent" property and contain a +single phandle referring to the wakeup capable interrupt controller. + + Example: + wakeup-parent = <&pdc_intc>; -- GitLab From 0c347bec826da0a3e2aa659a4aa1ad72ae40cf03 Mon Sep 17 00:00:00 2001 From: Lina Iyer Date: Fri, 13 Sep 2019 15:59:14 -0600 Subject: [PATCH 681/993] FROMLIST: dt-bindings/interrupt-controller: pdc: add SPI config register In addition to configuring the PDC, additional registers that interface the GIC have to be configured to match the GPIO type. The registers on some QCOM SoCs are access restricted, while on other SoCs are not. They SoCs with access restriction to these SPI registers need to be written from the firmware using the SCM interface. Add a flag to indicate if the register is to be written using SCM interface. Cc: devicetree@vger.kernel.org Signed-off-by: Lina Iyer Reviewed-by: Rob Herring BUG: 141169320 TEST: Build and boot Change-Id: I0f6dfc11fc4df4b0744b7c9372eaf4c7be3a82d6 Signed-off-by: Maulik Shah Link: https://patchwork.kernel.org/patch/11145355 --- .../bindings/interrupt-controller/qcom,pdc.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt b/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt index 8e0797cb1487..e329f8d27826 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/qcom,pdc.txt @@ -24,6 +24,9 @@ Properties: Usage: required Value type: Definition: Specifies the base physical address for PDC hardware. + Optionally, specify the PDC's GIC interface registers that + need to be configured for wakeup capable GPIOs routed to + the PDC. - interrupt-cells: Usage: required @@ -50,15 +53,23 @@ Properties: The second element is the GIC hwirq number for the PDC port. The third element is the number of interrupts in sequence. +- qcom,scm-spi-cfg: + Usage: optional + Value type: + Definition: Specifies if the SPI configuration registers have to be + written from the firmware. Sometimes the PDC interface + register to the GIC can only be written from the firmware. + Example: pdc: interrupt-controller@b220000 { compatible = "qcom,sdm845-pdc"; - reg = <0xb220000 0x30000>; + reg = <0 0x0b220000 0 0x30000>, <0 0x179900f0 0 0x60>; qcom,pdc-ranges = <0 512 94>, <94 641 15>, <115 662 7>; #interrupt-cells = <2>; interrupt-parent = <&intc>; interrupt-controller; + qcom,scm-spi-cfg; }; DT binding of a device that wants to use the GIC SPI 514 as a wakeup -- GitLab From 97b1fe8e6659c7666480dcf2ee7db0aa99e2553e Mon Sep 17 00:00:00 2001 From: Lina Iyer Date: Fri, 13 Sep 2019 15:59:15 -0600 Subject: [PATCH 682/993] FROMLIST: drivers: irqchip: pdc: additionally set type in SPI config registers GPIOs that can be configured as wakeup are routed to the PDC wakeup interrupt controller and from there to the GIC interrupt controller. On some QCOM SoCs, the interface to the GIC for wakeup capable GPIOs have additional hardware registers that need to be configured as well to match the trigger type of the GPIO. This register interfaces the PDC to the GIC and therefore updated from the PDC driver. Typically, the firmware intializes the interface registers for the wakeup capable GPIOs with commonly used GPIO trigger type, but it is possible that a platform may want to use the GPIO differently. So, in addition to configuring the PDC, configure the interface registers as well. Signed-off-by: Lina Iyer BUG: 141169320 TEST: Build and boot Change-Id: I73250a04f67549dbf75c40b3672b6b1b78ff8adb Signed-off-by: Maulik Shah Link: https://patchwork.kernel.org/patch/11145353 --- drivers/irqchip/qcom-pdc.c | 93 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index 4abd775ef655..affb0bfa1701 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -18,6 +18,8 @@ #include #include +#include + #define PDC_MAX_IRQS 168 #define PDC_MAX_GPIO_IRQS 256 @@ -35,10 +37,20 @@ struct pdc_pin_region { u32 cnt; }; +struct spi_cfg_regs { + union { + u64 start; + void __iomem *base; + }; + resource_size_t size; + bool scm_io; +}; + static DEFINE_RAW_SPINLOCK(pdc_lock); static void __iomem *pdc_base; static struct pdc_pin_region *pdc_region; static int pdc_region_cnt; +static struct spi_cfg_regs *spi_cfg; static void pdc_reg_write(int reg, u32 i, u32 val) { @@ -100,6 +112,57 @@ static void qcom_pdc_gic_unmask(struct irq_data *d) irq_chip_unmask_parent(d); } +static u32 __spi_pin_read(unsigned int pin) +{ + void __iomem *cfg_reg = spi_cfg->base + pin * 4; + u64 scm_cfg_reg = spi_cfg->start + pin * 4; + + if (spi_cfg->scm_io) { + unsigned int val; + + qcom_scm_io_readl(scm_cfg_reg, &val); + return val; + } else { + return readl(cfg_reg); + } +} + +static void __spi_pin_write(unsigned int pin, unsigned int val) +{ + void __iomem *cfg_reg = spi_cfg->base + pin * 4; + u64 scm_cfg_reg = spi_cfg->start + pin * 4; + + if (spi_cfg->scm_io) + qcom_scm_io_writel(scm_cfg_reg, val); + else + writel(val, cfg_reg); +} + +static int spi_configure_type(irq_hw_number_t hwirq, unsigned int type) +{ + int spi = hwirq - 32; + u32 pin = spi / 32; + u32 mask = BIT(spi % 32); + u32 val; + unsigned long flags; + + if (!spi_cfg) + return 0; + + if (pin * 4 > spi_cfg->size) + return -EFAULT; + + raw_spin_lock_irqsave(&pdc_lock, flags); + val = __spi_pin_read(pin); + val &= ~mask; + if (type & IRQ_TYPE_LEVEL_MASK) + val |= mask; + __spi_pin_write(pin, val); + raw_spin_unlock_irqrestore(&pdc_lock, flags); + + return 0; +} + /* * GIC does not handle falling edge or active low. To allow falling edge and * active low interrupts to be handled at GIC, PDC has an inverter that inverts @@ -137,7 +200,9 @@ enum pdc_irq_config_bits { static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) { int pin_out = d->hwirq; + int parent_hwirq = d->parent_data->hwirq; enum pdc_irq_config_bits pdc_type; + int ret; if (pin_out == GPIO_NO_WAKE_IRQ) return 0; @@ -168,6 +233,11 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) pdc_reg_write(IRQ_i_CFG, pin_out, pdc_type); + /* Additionally, configure (only) the GPIO in the f/w */ + ret = spi_configure_type(parent_hwirq, type); + if (ret) + return ret; + return irq_chip_set_type_parent(d, type); } @@ -354,6 +424,7 @@ static int pdc_setup_pin_mapping(struct device_node *np) static int qcom_pdc_init(struct device_node *node, struct device_node *parent) { struct irq_domain *parent_domain, *pdc_domain, *pdc_gpio_domain; + struct resource res; int ret; pdc_base = of_iomap(node, 0); @@ -384,6 +455,27 @@ static int qcom_pdc_init(struct device_node *node, struct device_node *parent) goto fail; } + ret = of_address_to_resource(node, 1, &res); + if (!ret) { + spi_cfg = kcalloc(1, sizeof(*spi_cfg), GFP_KERNEL); + if (!spi_cfg) { + ret = -ENOMEM; + goto remove; + } + spi_cfg->scm_io = of_find_property(node, + "qcom,scm-spi-cfg", NULL); + spi_cfg->size = resource_size(&res); + if (spi_cfg->scm_io) { + spi_cfg->start = res.start; + } else { + spi_cfg->base = ioremap(res.start, spi_cfg->size); + if (!spi_cfg->base) { + ret = -ENOMEM; + goto remove; + } + } + } + pdc_gpio_domain = irq_domain_create_hierarchy(parent_domain, IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP, PDC_MAX_GPIO_IRQS, @@ -401,6 +493,7 @@ static int qcom_pdc_init(struct device_node *node, struct device_node *parent) remove: irq_domain_remove(pdc_domain); + kfree(spi_cfg); fail: kfree(pdc_region); iounmap(pdc_base); -- GitLab From 2d4940748d007acd58e2fe9f4fb13973732b4fa3 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Fri, 13 Sep 2019 15:59:16 -0600 Subject: [PATCH 683/993] FROMLIST: genirq: Introduce irq_chip_get/set_parent_state calls On certain QTI chipsets some GPIOs are direct-connect interrupts to the GIC to be used as regular interrupt lines. When the GPIOs are not used for interrupt generation the interrupt line is disabled. But disabling the interrupt at GIC does not prevent the interrupt to be reported as pending at GIC_ISPEND. Later, when drivers call enable_irq() on the interrupt, an unwanted interrupt occurs. Introduce get and set methods for irqchip's parent to clear it's pending irq state. This then can be invoked by the GPIO interrupt controller on the parents in it hierarchy to clear the interrupt before enabling the interrupt. Signed-off-by: Maulik Shah [updated commit text and minor code fixes] Signed-off-by: Lina Iyer BUG: 141169320 TEST: Build and boot Change-Id: I8c849f89bebca892fc8a5c94f1ca9492f2a9d49c Signed-off-by: Maulik Shah Link: https://patchwork.kernel.org/patch/11145351 --- include/linux/irq.h | 6 ++++++ kernel/irq/chip.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/include/linux/irq.h b/include/linux/irq.h index fb301cf29148..7853eb9301f2 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -610,6 +610,12 @@ extern int irq_chip_pm_put(struct irq_data *data); #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY extern void handle_fasteoi_ack_irq(struct irq_desc *desc); extern void handle_fasteoi_mask_irq(struct irq_desc *desc); +extern int irq_chip_set_parent_state(struct irq_data *data, + enum irqchip_irq_state which, + bool val); +extern int irq_chip_get_parent_state(struct irq_data *data, + enum irqchip_irq_state which, + bool *state); extern void irq_chip_enable_parent(struct irq_data *data); extern void irq_chip_disable_parent(struct irq_data *data); extern void irq_chip_ack_parent(struct irq_data *data); diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index b76703b2c0af..b3fa2d87d2f3 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -1297,6 +1297,50 @@ EXPORT_SYMBOL_GPL(handle_fasteoi_mask_irq); #endif /* CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS */ +/** + * irq_chip_set_parent_state - set the state of a parent interrupt. + * + * @data: Pointer to interrupt specific data + * @which: State to be restored (one of IRQCHIP_STATE_*) + * @val: Value corresponding to @which + * + * Conditional success, if the underlying irqchip does not implement it. + */ +int irq_chip_set_parent_state(struct irq_data *data, + enum irqchip_irq_state which, + bool val) +{ + data = data->parent_data; + + if (!data || !data->chip->irq_set_irqchip_state) + return 0; + + return data->chip->irq_set_irqchip_state(data, which, val); +} +EXPORT_SYMBOL_GPL(irq_chip_set_parent_state); + +/** + * irq_chip_get_parent_state - get the state of a parent interrupt. + * + * @data: Pointer to interrupt specific data + * @which: one of IRQCHIP_STATE_* the caller wants to know + * @state: a pointer to a boolean where the state is to be stored + * + * Conditional success, if the underlying irqchip does not implement it. + */ +int irq_chip_get_parent_state(struct irq_data *data, + enum irqchip_irq_state which, + bool *state) +{ + data = data->parent_data; + + if (!data || !data->chip->irq_get_irqchip_state) + return 0; + + return data->chip->irq_get_irqchip_state(data, which, state); +} +EXPORT_SYMBOL_GPL(irq_chip_get_parent_state); + /** * irq_chip_enable_parent - Enable the parent interrupt (defaults to unmask if * NULL) -- GitLab From 25a0afd115990f5e379cb6e059cd3820a0ce105f Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Fri, 13 Sep 2019 15:59:17 -0600 Subject: [PATCH 684/993] FROMLIST: drivers: irqchip: pdc: Add irqchip set/get state calls Add irqchip calls to set/get interrupt state from the parent interrupt controller. When GPIOs are renabled as interrupt lines, it is desirable to clear the interrupt state at the GIC. This avoids any unwanted interrupt as a result of stale pending state recorded when the line was used as a GPIO. Signed-off-by: Maulik Shah [updated commit text] Signed-off-by: Lina Iyer BUG: 141169320 TEST: Build and boot Change-Id: Ie0042161727f2c8b1ebe0dd2165cbc4f20612f30 Signed-off-by: Maulik Shah Link: https://patchwork.kernel.org/patch/11145349 --- drivers/irqchip/qcom-pdc.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index affb0bfa1701..2b49e704178d 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -87,6 +88,24 @@ static void qcom_pdc_gic_disable(struct irq_data *d) irq_chip_disable_parent(d); } +static int qcom_pdc_gic_get_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, bool *state) +{ + if (d->hwirq == GPIO_NO_WAKE_IRQ) + return 0; + + return irq_chip_get_parent_state(d, which, state); +} + +static int qcom_pdc_gic_set_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, bool value) +{ + if (d->hwirq == GPIO_NO_WAKE_IRQ) + return 0; + + return irq_chip_set_parent_state(d, which, value); +} + static void qcom_pdc_gic_enable(struct irq_data *d) { if (d->hwirq == GPIO_NO_WAKE_IRQ) @@ -248,6 +267,8 @@ static struct irq_chip qcom_pdc_gic_chip = { .irq_unmask = qcom_pdc_gic_unmask, .irq_disable = qcom_pdc_gic_disable, .irq_enable = qcom_pdc_gic_enable, + .irq_get_irqchip_state = qcom_pdc_gic_get_irqchip_state, + .irq_set_irqchip_state = qcom_pdc_gic_set_irqchip_state, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_set_type = qcom_pdc_gic_set_type, .flags = IRQCHIP_MASK_ON_SUSPEND | -- GitLab From a59c2b66751530d33cfe5273dc5ceddb98f8ddb9 Mon Sep 17 00:00:00 2001 From: Lina Iyer Date: Fri, 13 Sep 2019 15:59:18 -0600 Subject: [PATCH 685/993] FROMLIST: drivers: pinctrl: msm: setup GPIO chip in hierarchy Some GPIOs are marked as wakeup capable and are routed to another interrupt controller that is an always-domain and can detect interrupts even most of the SoC is powered off. The wakeup interrupt controller wakes up the GIC and replays the interrupt at the GIC. Setup the TLMM irqchip in hierarchy with the wakeup interrupt controller and ensure the wakeup GPIOs are handled correctly. Signed-off-by: Maulik Shah Signed-off-by: Lina Iyer BUG: 141169320 TEST: Build and boot Change-Id: Ic37caf65e5d384234d8197d27b3d62cefa2bea7f Signed-off-by: Maulik Shah Link: https://patchwork.kernel.org/patch/11145345 --- drivers/pinctrl/qcom/pinctrl-msm.c | 119 +++++++++++++++++++++++++++++ drivers/pinctrl/qcom/pinctrl-msm.h | 16 ++++ include/linux/soc/qcom/irq.h | 13 ++++ 3 files changed, 148 insertions(+) diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 763da0be10d6..3c1dfcb84622 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -23,6 +23,8 @@ #include #include +#include + #include "../core.h" #include "../pinconf.h" #include "pinctrl-msm.h" @@ -44,6 +46,7 @@ * @enabled_irqs: Bitmap of currently enabled irqs. * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge * detection. + * @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt contrroller * @soc; Reference to soc_data of platform specific data. * @regs: Base addresses for the TLMM tiles. */ @@ -61,6 +64,7 @@ struct msm_pinctrl { DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO); DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO); + DECLARE_BITMAP(skip_wake_irqs, MAX_NR_GPIO); const struct msm_pinctrl_soc_data *soc; void __iomem *regs[MAX_NR_TILES]; @@ -707,6 +711,12 @@ static void msm_gpio_irq_mask(struct irq_data *d) unsigned long flags; u32 val; + if (d->parent_data) + irq_chip_mask_parent(d); + + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) + return; + g = &pctrl->soc->groups[d->hwirq]; raw_spin_lock_irqsave(&pctrl->lock, flags); @@ -751,6 +761,12 @@ static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear) unsigned long flags; u32 val; + if (d->parent_data) + irq_chip_unmask_parent(d); + + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) + return; + g = &pctrl->soc->groups[d->hwirq]; raw_spin_lock_irqsave(&pctrl->lock, flags); @@ -778,10 +794,37 @@ static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear) static void msm_gpio_irq_enable(struct irq_data *d) { + /* + * Clear the interrupt that may be pending before we enable + * the line. + * This is especially a problem with the GPIOs routed to the + * PDC. These GPIOs are direct-connect interrupts to the GIC. + * Disabling the interrupt line at the PDC does not prevent + * the interrupt from being latched at the GIC. The state at + * GIC needs to be cleared before enabling. + */ + if (d->parent_data) { + irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, 0); + irq_chip_enable_parent(d); + } msm_gpio_irq_clear_unmask(d, true); } +static void msm_gpio_irq_disable(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); + + if (d->parent_data) + irq_chip_disable_parent(d); + + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) + return; + + msm_gpio_irq_mask(d); +} + static void msm_gpio_irq_unmask(struct irq_data *d) { msm_gpio_irq_clear_unmask(d, false); @@ -795,6 +838,9 @@ static void msm_gpio_irq_ack(struct irq_data *d) unsigned long flags; u32 val; + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) + return; + g = &pctrl->soc->groups[d->hwirq]; raw_spin_lock_irqsave(&pctrl->lock, flags); @@ -820,6 +866,12 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type) unsigned long flags; u32 val; + if (d->parent_data) + irq_chip_set_type_parent(d, type); + + if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) + return 0; + g = &pctrl->soc->groups[d->hwirq]; raw_spin_lock_irqsave(&pctrl->lock, flags); @@ -912,6 +964,15 @@ static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on) struct msm_pinctrl *pctrl = gpiochip_get_data(gc); unsigned long flags; + if (d->parent_data) + irq_chip_set_wake_parent(d, on); + + /* + * While they may not wake up when the TLMM is powered off, + * some GPIOs would like to wakeup the system from suspend + * when TLMM is powered on. To allow that, enable the GPIO + * summary line to be wakeup capable at GIC. + */ raw_spin_lock_irqsave(&pctrl->lock, flags); irq_set_irq_wake(pctrl->irq, on); @@ -990,6 +1051,30 @@ static void msm_gpio_irq_handler(struct irq_desc *desc) chained_irq_exit(chip, desc); } +static int msm_gpio_wakeirq(struct gpio_chip *gc, + unsigned int child, + unsigned int child_type, + unsigned int *parent, + unsigned int *parent_type) +{ + struct msm_pinctrl *pctrl = gpiochip_get_data(gc); + const struct msm_gpio_wakeirq_map *map; + int i; + + *parent = GPIO_NO_WAKE_IRQ; + *parent_type = IRQ_TYPE_EDGE_RISING; + + for (i = 0; i < pctrl->soc->nwakeirq_map; i++) { + map = &pctrl->soc->wakeirq_map[i]; + if (map->gpio == child) { + *parent = map->wakeirq; + break; + } + } + + return 0; +} + static bool msm_gpio_needs_valid_mask(struct msm_pinctrl *pctrl) { if (pctrl->soc->reserved_gpios) @@ -1004,6 +1089,7 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) struct gpio_irq_chip *girq; int ret; unsigned ngpio = pctrl->soc->ngpios; + struct device_node *dn; if (WARN_ON(ngpio > MAX_NR_GPIO)) return -EINVAL; @@ -1020,17 +1106,40 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) pctrl->irq_chip.name = "msmgpio"; pctrl->irq_chip.irq_enable = msm_gpio_irq_enable; + pctrl->irq_chip.irq_disable = msm_gpio_irq_disable; pctrl->irq_chip.irq_mask = msm_gpio_irq_mask; pctrl->irq_chip.irq_unmask = msm_gpio_irq_unmask; pctrl->irq_chip.irq_ack = msm_gpio_irq_ack; + pctrl->irq_chip.irq_eoi = irq_chip_eoi_parent; pctrl->irq_chip.irq_set_type = msm_gpio_irq_set_type; pctrl->irq_chip.irq_set_wake = msm_gpio_irq_set_wake; pctrl->irq_chip.irq_request_resources = msm_gpio_irq_reqres; pctrl->irq_chip.irq_release_resources = msm_gpio_irq_relres; + dn = of_parse_phandle(pctrl->dev->of_node, "wakeup-parent", 0); + if (dn) { + int i; + bool skip; + unsigned int gpio; + + chip->irq.parent_domain = irq_find_matching_host(dn, + DOMAIN_BUS_WAKEUP); + of_node_put(dn); + if (!chip->irq.parent_domain) + return -EPROBE_DEFER; + chip->irq.child_to_parent_hwirq = msm_gpio_wakeirq; + + skip = irq_domain_qcom_handle_wakeup(chip->irq.parent_domain); + for (i = 0; skip && i < pctrl->soc->nwakeirq_map; i++) { + gpio = pctrl->soc->wakeirq_map[i].gpio; + set_bit(gpio, pctrl->skip_wake_irqs); + } + } + girq = &chip->irq; girq->chip = &pctrl->irq_chip; girq->parent_handler = msm_gpio_irq_handler; + girq->fwnode = pctrl->dev->fwnode; girq->num_parents = 1; girq->parents = devm_kcalloc(pctrl->dev, 1, sizeof(*girq->parents), GFP_KERNEL); @@ -1066,6 +1175,16 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) } } + /* + * Since we are chained to the GIC using the TLMM summary line + * and in hierarchy with the wakeup parent interrupt controller, + * explicitly set the chained summary line. We need to do this because + * the summary line is not routed to the wakeup parent but directly + * to the GIC. + */ + gpiochip_set_chained_irqchip(chip, &pctrl->irq_chip, pctrl->irq, + msm_gpio_irq_handler); + return 0; } diff --git a/drivers/pinctrl/qcom/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h index 48569cda8471..15470203b446 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.h +++ b/drivers/pinctrl/qcom/pinctrl-msm.h @@ -5,6 +5,8 @@ #ifndef __PINCTRL_MSM_H__ #define __PINCTRL_MSM_H__ +#include + struct pinctrl_pin_desc; /** @@ -91,6 +93,16 @@ struct msm_pingroup { unsigned intr_detection_width:5; }; +/** + * struct msm_gpio_wakeirq_map - Map of GPIOs and their wakeup pins + * @gpio: The GPIOs that are wakeup capable + * @wakeirq: The interrupt at the always-on interrupt controller + */ +struct msm_gpio_wakeirq_map { + unsigned int gpio; + unsigned int wakeirq; +}; + /** * struct msm_pinctrl_soc_data - Qualcomm pin controller driver configuration * @pins: An array describing all pins the pin controller affects. @@ -101,6 +113,8 @@ struct msm_pingroup { * @ngroups: The numbmer of entries in @groups. * @ngpio: The number of pingroups the driver should expose as GPIOs. * @pull_no_keeper: The SoC does not support keeper bias. + * @wakeirq_map: The map of wakeup capable GPIOs and the pin at PDC/MPM + * @nwakeirq_map: The number of entries in @hierarchy_map */ struct msm_pinctrl_soc_data { const struct pinctrl_pin_desc *pins; @@ -114,6 +128,8 @@ struct msm_pinctrl_soc_data { const char *const *tiles; unsigned int ntiles; const int *reserved_gpios; + const struct msm_gpio_wakeirq_map *wakeirq_map; + unsigned int nwakeirq_map; }; extern const struct dev_pm_ops msm_pinctrl_dev_pm_ops; diff --git a/include/linux/soc/qcom/irq.h b/include/linux/soc/qcom/irq.h index 85ac4b6cf3fb..098d57ca4a52 100644 --- a/include/linux/soc/qcom/irq.h +++ b/include/linux/soc/qcom/irq.h @@ -16,4 +16,17 @@ #define IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP (IRQ_DOMAIN_FLAG_NONCORE << 0) #define IRQ_DOMAIN_FLAG_QCOM_MPM_WAKEUP (IRQ_DOMAIN_FLAG_NONCORE << 1) +/** + * irq_domain_qcom_handle_wakeup: Return if the domain handles interrupt + * configuration + * @parent: irq domain + * + * This QCOM specific irq domain call returns if the interrupt controller + * requires the interrupt be masked at the child interrupt controller. + */ +static inline bool irq_domain_qcom_handle_wakeup(struct irq_domain *parent) +{ + return (parent->flags & IRQ_DOMAIN_FLAG_QCOM_PDC_WAKEUP); +} + #endif -- GitLab From 8424312516e5d9baeeb0a95d0e4523579b7aa395 Mon Sep 17 00:00:00 2001 From: Zenghui Yu Date: Wed, 23 Oct 2019 03:46:26 +0000 Subject: [PATCH 686/993] irqchip/gic-v3-its: Use the exact ITSList for VMOVP On a system without Single VMOVP support (say GITS_TYPER.VMOVP == 0), we will map vPEs only on ITSs that will actually control interrupts for the given VM. And when moving a vPE, the VMOVP command will be issued only for those ITSs. But when issuing VMOVPs we seemed fail to present the exact ITSList to ITSs who are actually included in the synchronization operation. The its_list_map we're currently using includes all ITSs in the system, even though some of them don't have the corresponding vPE mapping at all. Introduce get_its_list() to get the per-VM its_list_map, to indicate which ITSs have vPE mappings for the given VM, and use this map as the expected ITSList when building VMOVP. This is hopefully a performance gain not to do some synchronization with those unsuspecting ITSs. And initialize the whole command descriptor to zero at beginning, since the seq_num and its_list should be RES0 when GITS_TYPER.VMOVP == 1. Signed-off-by: Zenghui Yu Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/1571802386-2680-1-git-send-email-yuzenghui@huawei.com --- drivers/irqchip/irq-gic-v3-its.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 62e54f1a248b..787e8eec9a7f 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -175,6 +175,22 @@ static DEFINE_IDA(its_vpeid_ida); #define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base) #define gic_data_rdist_vlpi_base() (gic_data_rdist_rd_base() + SZ_128K) +static u16 get_its_list(struct its_vm *vm) +{ + struct its_node *its; + unsigned long its_list = 0; + + list_for_each_entry(its, &its_nodes, entry) { + if (!its->is_v4) + continue; + + if (vm->vlpi_count[its->list_nr]) + __set_bit(its->list_nr, &its_list); + } + + return (u16)its_list; +} + static struct its_collection *dev_event_to_col(struct its_device *its_dev, u32 event) { @@ -976,17 +992,15 @@ static void its_send_vmapp(struct its_node *its, static void its_send_vmovp(struct its_vpe *vpe) { - struct its_cmd_desc desc; + struct its_cmd_desc desc = {}; struct its_node *its; unsigned long flags; int col_id = vpe->col_idx; desc.its_vmovp_cmd.vpe = vpe; - desc.its_vmovp_cmd.its_list = (u16)its_list_map; if (!its_list_map) { its = list_first_entry(&its_nodes, struct its_node, entry); - desc.its_vmovp_cmd.seq_num = 0; desc.its_vmovp_cmd.col = &its->collections[col_id]; its_send_single_vcommand(its, its_build_vmovp_cmd, &desc); return; @@ -1003,6 +1017,7 @@ static void its_send_vmovp(struct its_vpe *vpe) raw_spin_lock_irqsave(&vmovp_lock, flags); desc.its_vmovp_cmd.seq_num = vmovp_seq_num++; + desc.its_vmovp_cmd.its_list = get_its_list(vpe->its_vm); /* Emit VMOVPs */ list_for_each_entry(its, &its_nodes, entry) { -- GitLab From a15542bb72a48042f5df7475893d46f725f5f9fb Mon Sep 17 00:00:00 2001 From: Mark Zhang Date: Sun, 20 Oct 2019 09:28:00 +0300 Subject: [PATCH 687/993] RDMA/nldev: Skip counter if port doesn't match The counter resource should return -EAGAIN if it was requested for a different port, this is similar to how QP works if the users provides a port filter. Otherwise port filtering in netlink will return broken counter nests. Fixes: c4ffee7c9bdb ("RDMA/netlink: Implement counter dumpit calback") Link: https://lore.kernel.org/r/20191020062800.8065-1-leon@kernel.org Signed-off-by: Mark Zhang Signed-off-by: Leon Romanovsky Reviewed-by: Jason Gunthorpe Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/nldev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c index 65b36548bc17..c03af08b80e7 100644 --- a/drivers/infiniband/core/nldev.c +++ b/drivers/infiniband/core/nldev.c @@ -778,7 +778,7 @@ static int fill_res_counter_entry(struct sk_buff *msg, bool has_cap_net_admin, container_of(res, struct rdma_counter, res); if (port && port != counter->port) - return 0; + return -EAGAIN; /* Dump it even query failed */ rdma_counter_query_stats(counter); -- GitLab From 62931ac2f9015ea38d80494ec37658ab3df6a6d7 Mon Sep 17 00:00:00 2001 From: Fabien Parent Date: Fri, 18 Oct 2019 19:32:13 +0200 Subject: [PATCH 688/993] i2c: mt65xx: fix NULL ptr dereference Since commit abf4923e97c3 ("i2c: mediatek: disable zero-length transfers for mt8183"), there is a NULL pointer dereference for all the SoCs that don't have any quirk. mtk_i2c_functionality is not checking that the quirks pointer is not NULL before starting to use it. This commit add a call to i2c_check_quirks which will check whether the quirks pointer is set, and if so will check if the IP has the NO_ZERO_LEN quirk. Fixes: abf4923e97c3 ("i2c: mediatek: disable zero-length transfers for mt8183") Signed-off-by: Fabien Parent Reviewed-by: Cengiz Can Reviewed-by: Hsin-Yi Wang Tested-by: Ulrich Hecht Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-mt65xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 29eae1bf4f86..2152ec5f535c 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -875,7 +875,7 @@ static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id) static u32 mtk_i2c_functionality(struct i2c_adapter *adap) { - if (adap->quirks->flags & I2C_AQ_NO_ZERO_LEN) + if (i2c_check_quirks(adap, I2C_AQ_NO_ZERO_LEN)) return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); else -- GitLab From 02e64276c6dbcc4c5f39844f33d18180832a58f3 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Mon, 30 Sep 2019 17:28:01 +0200 Subject: [PATCH 689/993] i2c: stm32f7: fix first byte to send in slave mode The slave-interface documentation [1] states "the bus driver should transmit the first byte" upon I2C_SLAVE_READ_REQUESTED slave event: - 'val': backend returns first byte to be sent The driver currently ignores the 1st byte to send on this event. [1] https://www.kernel.org/doc/Documentation/i2c/slave-interface Fixes: 60d609f30de2 ("i2c: i2c-stm32f7: Add slave support") Signed-off-by: Fabrice Gasnier Reviewed-by: Pierre-Yves MORDRET Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-stm32f7.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index d36cf08461f7..c8ce6c8dd404 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -1192,6 +1192,8 @@ static void stm32f7_i2c_slave_start(struct stm32f7_i2c_dev *i2c_dev) STM32F7_I2C_CR1_TXIE; stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask); + /* Write 1st data byte */ + writel_relaxed(value, base + STM32F7_I2C_TXDR); } else { /* Notify i2c slave that new write transfer is starting */ i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value); -- GitLab From 6d6b0d0d5afc8c4c84b08261260ba11dfa5206f2 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Tue, 1 Oct 2019 10:51:09 +0200 Subject: [PATCH 690/993] i2c: stm32f7: fix a race in slave mode with arbitration loss irq When in slave mode, an arbitration loss (ARLO) may be detected before the slave had a chance to detect the stop condition (STOPF in ISR). This is seen when two master + slave adapters switch their roles. It provokes the i2c bus to be stuck, busy as SCL line is stretched. - the I2C_SLAVE_STOP event is never generated due to STOPF flag is set but don't generate an irq (race with ARLO irq, STOPIE is masked). STOPF flag remains set until next master xfer (e.g. when STOPIE irq get unmasked). In this case, completion is generated too early: immediately upon new transfer request (then it doesn't send all data). - Some data get stuck in TXDR register. As a consequence, the controller stretches the SCL line: the bus gets busy until a future master transfer triggers the bus busy / recovery mechanism (this can take time... and may never happen at all) So choice is to let the STOPF being detected by the slave isr handler, to properly handle this stop condition. E.g. don't mask IRQs in error handler, when the slave is running. Fixes: 60d609f30de2 ("i2c: i2c-stm32f7: Add slave support") Signed-off-by: Fabrice Gasnier Reviewed-by: Pierre-Yves MORDRET Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-stm32f7.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index c8ce6c8dd404..073bf57a9821 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -1503,7 +1503,7 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data) void __iomem *base = i2c_dev->base; struct device *dev = i2c_dev->dev; struct stm32_i2c_dma *dma = i2c_dev->dma; - u32 mask, status; + u32 status; status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR); @@ -1528,12 +1528,15 @@ static irqreturn_t stm32f7_i2c_isr_error(int irq, void *data) f7_msg->result = -EINVAL; } - /* Disable interrupts */ - if (stm32f7_i2c_is_slave_registered(i2c_dev)) - mask = STM32F7_I2C_XFER_IRQ_MASK; - else - mask = STM32F7_I2C_ALL_IRQ_MASK; - stm32f7_i2c_disable_irq(i2c_dev, mask); + if (!i2c_dev->slave_running) { + u32 mask; + /* Disable interrupts */ + if (stm32f7_i2c_is_slave_registered(i2c_dev)) + mask = STM32F7_I2C_XFER_IRQ_MASK; + else + mask = STM32F7_I2C_ALL_IRQ_MASK; + stm32f7_i2c_disable_irq(i2c_dev, mask); + } /* Disable dma */ if (i2c_dev->use_dma) { -- GitLab From 348e46fbb4cdb2aead79aee1fd8bb25ec5fd25db Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Tue, 15 Oct 2019 15:11:58 +0200 Subject: [PATCH 691/993] i2c: stm32f7: remove warning when compiling with W=1 Remove the following warning: drivers/i2c/busses/i2c-stm32f7.c:315: warning: cannot understand function prototype: 'struct stm32f7_i2c_spec i2c_specs[] = Replace a comment starting with /** by simply /* to avoid having it interpreted as a kernel-doc comment. Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver") Signed-off-by: Alain Volmat Reviewed-by: Pierre-Yves MORDRET Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-stm32f7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index 073bf57a9821..b24e7b937f21 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -305,7 +305,7 @@ struct stm32f7_i2c_dev { struct regmap *regmap; }; -/** +/* * All these values are coming from I2C Specification, Version 6.0, 4th of * April 2014. * -- GitLab From e8f92ffd70794b80e2051c3e3be26201ac631c75 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Fri, 11 Oct 2019 12:15:19 -0700 Subject: [PATCH 692/993] FROMGIT: of: property: Minor code formatting/style clean ups Better variable and function names. Remove "," after the sentinel in an array initialization list. Signed-off-by: Saravana Kannan Acked-by: Rob Herring Link: https://lore.kernel.org/r/20191011191521.179614-2-saravanak@google.com Signed-off-by: Greg Kroah-Hartman (cherry-picked from commit af1b967af5ffb94aaed5b9b3259349cc2d398fa7 https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git driver-core-next) Conflicts: drivers/of/property.c [Fixed minor conflict due to 87337fb791b2fad85f6316ea6a31f5a9c0b2f50d] Bug: 142657042 Change-Id: I86356be325b17676452b9ad93fe4a96235dbef0b Signed-off-by: Saravana Kannan --- drivers/of/property.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/of/property.c b/drivers/of/property.c index 98c5042f352f..d2b908e6a3b2 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -1154,12 +1154,12 @@ struct supplier_bindings { const char *prop_name, int index); }; -static const struct supplier_bindings bindings[] = { +static const struct supplier_bindings of_supplier_bindings[] = { { .parse_prop = parse_clocks, }, { .parse_prop = parse_interconnects, }, { .parse_prop = parse_regulators, }, { .parse_prop = parse_iommus, }, - {}, + {} }; /** @@ -1185,7 +1185,7 @@ static int of_link_property(struct device *dev, struct device_node *con_np, const char *prop_name) { struct device_node *phandle; - const struct supplier_bindings *s = bindings; + const struct supplier_bindings *s = of_supplier_bindings; unsigned int i = 0; bool matched = false; int ret = 0; @@ -1204,7 +1204,7 @@ static int of_link_property(struct device *dev, struct device_node *con_np, return ret; } -static int __of_link_to_suppliers(struct device *dev, +static int of_link_to_suppliers(struct device *dev, struct device_node *con_np) { struct device_node *child; @@ -1216,7 +1216,7 @@ static int __of_link_to_suppliers(struct device *dev, ret = -EAGAIN; for_each_child_of_node(con_np, child) - if (__of_link_to_suppliers(dev, child)) + if (of_link_to_suppliers(dev, child)) ret = -EAGAIN; return ret; @@ -1234,7 +1234,7 @@ static int of_fwnode_add_links(const struct fwnode_handle *fwnode, if (unlikely(!is_of_node(fwnode))) return 0; - return __of_link_to_suppliers(dev, to_of_node(fwnode)); + return of_link_to_suppliers(dev, to_of_node(fwnode)); } const struct fwnode_operations of_fwnode_ops = { -- GitLab From 0e7ec28830e7125013136bb7dfdfb7f50a6d9cc8 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Fri, 11 Oct 2019 12:15:20 -0700 Subject: [PATCH 693/993] FROMGIT: driver: core: Improve documentation for fwnode_operations.add_links() The add_links() ops shouldn't return on the first failed device link add. It needs to continue trying to add device links to other suppliers that are available. The documentation didn't explain WHY this behavior is necessary. So, update the documentation with an example that explains why this is necessary. Signed-off-by: Saravana Kannan Link: https://lore.kernel.org/r/20191011191521.179614-3-saravanak@google.com Signed-off-by: Greg Kroah-Hartman (cherry-pick from commit 92df01e3601fe29eb3727a82705eafa6209053f5 https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git driver-core-next) Bug: 142657042 Change-Id: I58621ad08084fee1ab9725026e54abe7eb79b741 --- include/linux/fwnode.h | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index 6ae05b9ce359..97223e2410bd 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -71,8 +71,25 @@ struct fwnode_reference_args { * links to all the suppliers of the device that are available at * the time this function is called. The function must NOT stop * at the first failed device link if other unlinked supplier - * devices are present in the system. If some suppliers are not - * yet available, this function will be called again when other + * devices are present in the system. This is necessary for the + * driver/bus sync_state() callbacks to work correctly. + * + * For example, say Device-C depends on suppliers Device-S1 and + * Device-S2 and the dependency is listed in that order in the + * firmware. Say, S1 gets populated from the firmware after + * late_initcall_sync(). Say S2 is populated and probed way + * before that in device_initcall(). When C is populated, if this + * add_links() function doesn't continue past a "failed linking to + * S1" and continue linking C to S2, then S2 will get a + * sync_state() callback before C is probed. This is because from + * the perspective of S2, C was never a consumer when its + * sync_state() evaluation is done. To avoid this, the add_links() + * function has to go through all available suppliers of the + * device (that corresponds to this fwnode) and link to them + * before returning. + * + * If some suppliers are not yet available (indicated by an error + * return value), this function will be called again when other * devices are added to allow creating device links to any newly * available suppliers. * -- GitLab From 2d4a45a8388023a4a1f35813cad0e2bab225047b Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Fri, 11 Oct 2019 12:15:21 -0700 Subject: [PATCH 694/993] FROMGIT: docs: driver-model: Add documentation for sync_state The sync_state() driver callback was added recently, but the documentation was missing. Adding it now. Signed-off-by: Saravana Kannan Link: https://lore.kernel.org/r/20191011191521.179614-4-saravanak@google.com Signed-off-by: Greg Kroah-Hartman (cherry-pick from commit a3caeb8ffe5d2bbe01da66081f0ef28c26302d99 https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git driver-core-next) Bug: 142657042 Change-Id: I7ee9c61be93fb247759dbd6d90214c6994fe1bb0 --- .../driver-api/driver-model/driver.rst | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/Documentation/driver-api/driver-model/driver.rst b/Documentation/driver-api/driver-model/driver.rst index 11d281506a04..baa6a85c8287 100644 --- a/Documentation/driver-api/driver-model/driver.rst +++ b/Documentation/driver-api/driver-model/driver.rst @@ -169,6 +169,49 @@ A driver's probe() may return a negative errno value to indicate that the driver did not bind to this device, in which case it should have released all resources it allocated:: + void (*sync_state)(struct device *dev); + +sync_state is called only once for a device. It's called when all the consumer +devices of the device have successfully probed. The list of consumers of the +device is obtained by looking at the device links connecting that device to its +consumer devices. + +The first attempt to call sync_state() is made during late_initcall_sync() to +give firmware and drivers time to link devices to each other. During the first +attempt at calling sync_state(), if all the consumers of the device at that +point in time have already probed successfully, sync_state() is called right +away. If there are no consumers of the device during the first attempt, that +too is considered as "all consumers of the device have probed" and sync_state() +is called right away. + +If during the first attempt at calling sync_state() for a device, there are +still consumers that haven't probed successfully, the sync_state() call is +postponed and reattempted in the future only when one or more consumers of the +device probe successfully. If during the reattempt, the driver core finds that +there are one or more consumers of the device that haven't probed yet, then +sync_state() call is postponed again. + +A typical use case for sync_state() is to have the kernel cleanly take over +management of devices from the bootloader. For example, if a device is left on +and at a particular hardware configuration by the bootloader, the device's +driver might need to keep the device in the boot configuration until all the +consumers of the device have probed. Once all the consumers of the device have +probed, the device's driver can synchronize the hardware state of the device to +match the aggregated software state requested by all the consumers. Hence the +name sync_state(). + +While obvious examples of resources that can benefit from sync_state() include +resources such as regulator, sync_state() can also be useful for complex +resources like IOMMUs. For example, IOMMUs with multiple consumers (devices +whose addresses are remapped by the IOMMU) might need to keep their mappings +fixed at (or additive to) the boot configuration until all its consumers have +probed. + +While the typical use case for sync_state() is to have the kernel cleanly take +over management of devices from the bootloader, the usage of sync_state() is +not restricted to that. Use it whenever it makes sense to take an action after +all the consumers of a device have probed. + int (*remove) (struct device *dev); remove is called to unbind a driver from a device. This may be -- GitLab From 603dbeabed27c06ece6a5ed5819d98157bef0e10 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Mon, 14 Oct 2019 16:15:42 -0700 Subject: [PATCH 695/993] ANDROID: driver core: Add device link support for SYNC_STATE_ONLY flag Parent devices might need to create "proxy" device links from themselves to supplier devices to make sure the supplier devices don't get a sync_state() before the child consumer devices get a chance to add device links to the supplier devices. However, the parent device has no real dependency on the supplier device and probing, suspend/resume or runtime PM don't need to be affected by the supplier device. To capture these cases, create a SYNC_STATE_ONLY device link flag that only affects sync_state() behavior and doesn't affect probing, suspend/resume or runtime PM. Signed-off-by: Saravana Kannan Bug: 142657042 Change-Id: Ie709d3b6cd07ac9e09d1473fc0e0a21a8146a1dc --- drivers/base/core.c | 50 ++++++++++++++++++++++++++++++++++-------- include/linux/device.h | 2 ++ 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index acbf0b1414ab..d42e0f533ce4 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -130,6 +130,9 @@ static int device_is_dependent(struct device *dev, void *target) return ret; list_for_each_entry(link, &dev->links.consumers, s_node) { + if (link->flags == (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) + continue; + if (link->consumer == target) return 1; @@ -199,8 +202,11 @@ static int device_reorder_to_tail(struct device *dev, void *not_used) device_pm_move_last(dev); device_for_each_child(dev, NULL, device_reorder_to_tail); - list_for_each_entry(link, &dev->links.consumers, s_node) + list_for_each_entry(link, &dev->links.consumers, s_node) { + if (link->flags == (DL_FLAG_SYNC_STATE_ONLY | DL_FLAG_MANAGED)) + continue; device_reorder_to_tail(link->consumer, NULL); + } return 0; } @@ -227,7 +233,8 @@ void device_pm_move_to_tail(struct device *dev) #define DL_MANAGED_LINK_FLAGS (DL_FLAG_AUTOREMOVE_CONSUMER | \ DL_FLAG_AUTOREMOVE_SUPPLIER | \ - DL_FLAG_AUTOPROBE_CONSUMER) + DL_FLAG_AUTOPROBE_CONSUMER | \ + DL_FLAG_SYNC_STATE_ONLY) #define DL_ADD_VALID_FLAGS (DL_MANAGED_LINK_FLAGS | DL_FLAG_STATELESS | \ DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE) @@ -295,6 +302,8 @@ struct device_link *device_link_add(struct device *consumer, if (!consumer || !supplier || flags & ~DL_ADD_VALID_FLAGS || (flags & DL_FLAG_STATELESS && flags & DL_MANAGED_LINK_FLAGS) || + (flags & DL_FLAG_SYNC_STATE_ONLY && + flags != DL_FLAG_SYNC_STATE_ONLY) || (flags & DL_FLAG_AUTOPROBE_CONSUMER && flags & (DL_FLAG_AUTOREMOVE_CONSUMER | DL_FLAG_AUTOREMOVE_SUPPLIER))) @@ -315,11 +324,14 @@ struct device_link *device_link_add(struct device *consumer, /* * If the supplier has not been fully registered yet or there is a - * reverse dependency between the consumer and the supplier already in - * the graph, return NULL. + * reverse (non-SYNC_STATE_ONLY) dependency between the consumer and + * the supplier already in the graph, return NULL. If the link is a + * SYNC_STATE_ONLY link, we don't check for reverse dependencies + * because it only affects sync_state() callbacks. */ if (!device_pm_initialized(supplier) - || device_is_dependent(consumer, supplier)) { + || (!(flags & DL_FLAG_SYNC_STATE_ONLY) && + device_is_dependent(consumer, supplier))) { link = NULL; goto out; } @@ -346,9 +358,14 @@ struct device_link *device_link_add(struct device *consumer, } if (flags & DL_FLAG_STATELESS) { - link->flags |= DL_FLAG_STATELESS; kref_get(&link->kref); - goto out; + if (link->flags & DL_FLAG_SYNC_STATE_ONLY && + !(link->flags & DL_FLAG_STATELESS)) { + link->flags |= DL_FLAG_STATELESS; + goto reorder; + } else { + goto out; + } } /* @@ -370,6 +387,12 @@ struct device_link *device_link_add(struct device *consumer, link->flags |= DL_FLAG_MANAGED; device_link_init_status(link, consumer, supplier); } + if (link->flags & DL_FLAG_SYNC_STATE_ONLY && + !(flags & DL_FLAG_SYNC_STATE_ONLY)) { + link->flags &= ~DL_FLAG_SYNC_STATE_ONLY; + goto reorder; + } + goto out; } @@ -409,6 +432,13 @@ struct device_link *device_link_add(struct device *consumer, flags & DL_FLAG_PM_RUNTIME) pm_runtime_resume(supplier); + if (flags & DL_FLAG_SYNC_STATE_ONLY) { + dev_dbg(consumer, + "Linked as a sync state only consumer to %s\n", + dev_name(supplier)); + goto out; + } +reorder: /* * Move the consumer and all of the devices depending on it to the end * of dpm_list and the devices_kset list. @@ -634,7 +664,8 @@ int device_links_check_suppliers(struct device *dev) device_links_write_lock(); list_for_each_entry(link, &dev->links.suppliers, c_node) { - if (!(link->flags & DL_FLAG_MANAGED)) + if (!(link->flags & DL_FLAG_MANAGED) || + link->flags & DL_FLAG_SYNC_STATE_ONLY) continue; if (link->status != DL_STATE_AVAILABLE) { @@ -948,7 +979,8 @@ void device_links_unbind_consumers(struct device *dev) list_for_each_entry(link, &dev->links.consumers, s_node) { enum device_link_state status; - if (!(link->flags & DL_FLAG_MANAGED)) + if (!(link->flags & DL_FLAG_MANAGED) || + link->flags & DL_FLAG_SYNC_STATE_ONLY) continue; status = link->status; diff --git a/include/linux/device.h b/include/linux/device.h index 6978bb471567..82890e1b8f08 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1096,6 +1096,7 @@ enum device_link_state { * AUTOREMOVE_SUPPLIER: Remove the link automatically on supplier driver unbind. * AUTOPROBE_CONSUMER: Probe consumer driver automatically after supplier binds. * MANAGED: The core tracks presence of supplier/consumer drivers (internal). + * SYNC_STATE_ONLY: Link only affects sync_state() behavior. */ #define DL_FLAG_STATELESS BIT(0) #define DL_FLAG_AUTOREMOVE_CONSUMER BIT(1) @@ -1104,6 +1105,7 @@ enum device_link_state { #define DL_FLAG_AUTOREMOVE_SUPPLIER BIT(4) #define DL_FLAG_AUTOPROBE_CONSUMER BIT(5) #define DL_FLAG_MANAGED BIT(6) +#define DL_FLAG_SYNC_STATE_ONLY BIT(7) /** * struct device_link - Device link representation. -- GitLab From b713505f714d66cce35618badbb523324936db2b Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Tue, 15 Oct 2019 15:58:06 -0700 Subject: [PATCH 696/993] ANDROID: driver core: Allow a device to wait on optional suppliers Before this change, if a device is waiting on suppliers, it's assumed that all those suppliers are needed for the device to probe successfully. This change allows marking a devices as waiting only on optional suppliers. This allows a device to wait on suppliers (and link to them as soon as they are available) without preventing the device from being probed. Signed-off-by: Saravana Kannan Bug: 142657042 Change-Id: I86a764b67804ed889f17c55632e25d46a72912a8 --- drivers/base/core.c | 28 +++++++++++++++++++++++++--- include/linux/device.h | 3 +++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index d42e0f533ce4..8d86da80db1e 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -479,13 +479,25 @@ EXPORT_SYMBOL_GPL(device_link_add); * This function is NOT meant to be called from the probe function of the * consumer but rather from code that creates/adds the consumer device. */ -static void device_link_wait_for_supplier(struct device *consumer) +static void device_link_wait_for_supplier(struct device *consumer, + bool need_for_probe) { mutex_lock(&wfs_lock); list_add_tail(&consumer->links.needs_suppliers, &wait_for_suppliers); + consumer->links.need_for_probe = need_for_probe; mutex_unlock(&wfs_lock); } +static void device_link_wait_for_mandatory_supplier(struct device *consumer) +{ + device_link_wait_for_supplier(consumer, true); +} + +static void device_link_wait_for_optional_supplier(struct device *consumer) +{ + device_link_wait_for_supplier(consumer, false); +} + /** * device_link_add_missing_supplier_links - Add links from consumer devices to * supplier devices, leaving any @@ -655,7 +667,8 @@ int device_links_check_suppliers(struct device *dev) * probe. */ mutex_lock(&wfs_lock); - if (!list_empty(&dev->links.needs_suppliers)) { + if (!list_empty(&dev->links.needs_suppliers) && + dev->links.need_for_probe) { mutex_unlock(&wfs_lock); return -EPROBE_DEFER; } @@ -759,6 +772,15 @@ void device_links_driver_bound(struct device *dev) { struct device_link *link; + /* + * If a device probes successfully, it's expected to have created all + * the device links it needs to or make new device links as it needs + * them. So, it no longer needs to wait on any suppliers. + */ + mutex_lock(&wfs_lock); + list_del_init(&dev->links.needs_suppliers); + mutex_unlock(&wfs_lock); + device_links_write_lock(); list_for_each_entry(link, &dev->links.consumers, s_node) { @@ -2392,7 +2414,7 @@ int device_add(struct device *dev) if (fwnode_has_op(dev->fwnode, add_links) && fwnode_call_int_op(dev->fwnode, add_links, dev)) - device_link_wait_for_supplier(dev); + device_link_wait_for_mandatory_supplier(dev, true); bus_probe_device(dev); if (parent) diff --git a/include/linux/device.h b/include/linux/device.h index 82890e1b8f08..d1bcc8f122f6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1155,6 +1155,8 @@ enum dl_dev_state { * @consumers: List of links to consumer devices. * @needs_suppliers: Hook to global list of devices waiting for suppliers. * @defer_sync: Hook to global list of devices that have deferred sync_state. + * @need_for_probe: If needs_suppliers is on a list, this indicates if the + * suppliers are needed for probe or not. * @status: Driver status information. */ struct dev_links_info { @@ -1162,6 +1164,7 @@ struct dev_links_info { struct list_head consumers; struct list_head needs_suppliers; struct list_head defer_sync; + bool need_for_probe; enum dl_dev_state status; }; -- GitLab From 5415ddfa94293c5ec12f6f1ef27922c8358f8fae Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Tue, 15 Oct 2019 17:34:22 -0700 Subject: [PATCH 697/993] ANDROID: driver core: Allow fwnode_operations.add_links to differentiate errors When add_links() still has suppliers that it needs to link to in the future, this patch allows it to differentiate between suppliers that are needed for probing vs suppliers are needed for sync_state() correctness. Signed-off-by: Saravana Kannan Bug: 142657042 Change-Id: If8b2a11dc6d815287c9242aea0ee1c26ef316d96 --- drivers/base/core.c | 12 ++++++++---- include/linux/fwnode.h | 13 +++++++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 8d86da80db1e..2fd8a421b68c 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2296,7 +2296,7 @@ int device_add(struct device *dev) struct device *parent; struct kobject *kobj; struct class_interface *class_intf; - int error = -EINVAL; + int error = -EINVAL, fw_ret; struct kobject *glue_dir = NULL; dev = get_device(dev); @@ -2412,9 +2412,13 @@ int device_add(struct device *dev) */ device_link_add_missing_supplier_links(); - if (fwnode_has_op(dev->fwnode, add_links) - && fwnode_call_int_op(dev->fwnode, add_links, dev)) - device_link_wait_for_mandatory_supplier(dev, true); + if (fwnode_has_op(dev->fwnode, add_links)) { + fw_ret = fwnode_call_int_op(dev->fwnode, add_links, dev); + if (fw_ret == -ENODEV) + device_link_wait_for_mandatory_supplier(dev); + else if (fw_ret) + device_link_wait_for_optional_supplier(dev); + } bus_probe_device(dev); if (parent) diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index 97223e2410bd..766ff9bb5876 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -94,10 +94,15 @@ struct fwnode_reference_args { * available suppliers. * * Return 0 if device links have been successfully created to all - * the suppliers of this device or if the supplier information is - * not known. Return an error if and only if the supplier - * information is known but some of the suppliers are not yet - * available to create device links to. + * the suppliers this device needs to create device links to or if + * the supplier information is not known. + * + * Return -ENODEV if and only if the suppliers needed for probing + * the device are not yet available to create device links to. + * + * Return -EAGAIN if there are suppliers that need to be linked to + * that are not yet available but none of those suppliers are + * necessary for probing this device. */ struct fwnode_operations { struct fwnode_handle *(*get)(struct fwnode_handle *fwnode); -- GitLab From 454aa2ae22d1e638eb9120e2bf8de3d3b822ca4c Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Tue, 15 Oct 2019 21:49:50 -0700 Subject: [PATCH 698/993] ANDROID: of: property: Make sure child dependencies don't block probing of parent When creating device links to proxy the sync_state() needs of child dependencies, create SYNC_STATE_ONLY device links so that children dependencies don't block probing of the parent. Also, differentiate between missing suppliers of parent device vs missing suppliers of child devices so that driver core doesn't block parent device probing when only child supplier dependencies are missing. Signed-off-by: Saravana Kannan Bug: 142657042 Change-Id: Ifc63e36f6af6f48ec77215d0a2a609ff768e0fcb --- drivers/of/property.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/of/property.c b/drivers/of/property.c index d2b908e6a3b2..dfdc1604f4ad 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -1018,10 +1018,10 @@ static bool of_is_ancestor_of(struct device_node *test_ancestor, * - -EINVAL if the supplier link is invalid and should not be created * - -ENODEV if there is no device that corresponds to the supplier phandle */ -static int of_link_to_phandle(struct device *dev, struct device_node *sup_np) +static int of_link_to_phandle(struct device *dev, struct device_node *sup_np, + u32 dl_flags) { struct device *sup_dev; - u32 dl_flags = DL_FLAG_AUTOPROBE_CONSUMER; int ret = 0; struct device_node *tmp_np = sup_np; @@ -1189,13 +1189,20 @@ static int of_link_property(struct device *dev, struct device_node *con_np, unsigned int i = 0; bool matched = false; int ret = 0; + u32 dl_flags; + + if (dev->of_node == con_np) + dl_flags = DL_FLAG_AUTOPROBE_CONSUMER; + else + dl_flags = DL_FLAG_SYNC_STATE_ONLY; /* Do not stop at first failed link, link all available suppliers. */ while (!matched && s->parse_prop) { while ((phandle = s->parse_prop(con_np, prop_name, i))) { matched = true; i++; - if (of_link_to_phandle(dev, phandle) == -EAGAIN) + if (of_link_to_phandle(dev, phandle, dl_flags) + == -EAGAIN) ret = -EAGAIN; of_node_put(phandle); } @@ -1213,10 +1220,10 @@ static int of_link_to_suppliers(struct device *dev, for_each_property_of_node(con_np, p) if (of_link_property(dev, con_np, p->name)) - ret = -EAGAIN; + ret = -ENODEV; for_each_child_of_node(con_np, child) - if (of_link_to_suppliers(dev, child)) + if (of_link_to_suppliers(dev, child) && !ret) ret = -EAGAIN; return ret; -- GitLab From 82ecff655e7968151b0047f1b5de03b249e5c1c4 Mon Sep 17 00:00:00 2001 From: Takeshi Misawa Date: Sat, 19 Oct 2019 15:34:43 +0900 Subject: [PATCH 699/993] keys: Fix memory leak in copy_net_ns If copy_net_ns() failed after net_alloc(), net->key_domain is leaked. Fix this, by freeing key_domain in error path. syzbot report: BUG: memory leak unreferenced object 0xffff8881175007e0 (size 32): comm "syz-executor902", pid 7069, jiffies 4294944350 (age 28.400s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<00000000a83ed741>] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline] [<00000000a83ed741>] slab_post_alloc_hook mm/slab.h:439 [inline] [<00000000a83ed741>] slab_alloc mm/slab.c:3326 [inline] [<00000000a83ed741>] kmem_cache_alloc_trace+0x13d/0x280 mm/slab.c:3553 [<0000000059fc92b9>] kmalloc include/linux/slab.h:547 [inline] [<0000000059fc92b9>] kzalloc include/linux/slab.h:742 [inline] [<0000000059fc92b9>] net_alloc net/core/net_namespace.c:398 [inline] [<0000000059fc92b9>] copy_net_ns+0xb2/0x220 net/core/net_namespace.c:445 [<00000000a9d74bbc>] create_new_namespaces+0x141/0x2a0 kernel/nsproxy.c:103 [<000000008047d645>] unshare_nsproxy_namespaces+0x7f/0x100 kernel/nsproxy.c:202 [<000000005993ea6e>] ksys_unshare+0x236/0x490 kernel/fork.c:2674 [<0000000019417e75>] __do_sys_unshare kernel/fork.c:2742 [inline] [<0000000019417e75>] __se_sys_unshare kernel/fork.c:2740 [inline] [<0000000019417e75>] __x64_sys_unshare+0x16/0x20 kernel/fork.c:2740 [<00000000f4c5f2c8>] do_syscall_64+0x76/0x1a0 arch/x86/entry/common.c:296 [<0000000038550184>] entry_SYSCALL_64_after_hwframe+0x44/0xa9 syzbot also reported other leak in copy_net_ns -> setup_net. This problem is already fixed by cf47a0b882a4e5f6b34c7949d7b293e9287f1972. Fixes: 9b242610514f ("keys: Network namespace domain tag") Reported-and-tested-by: syzbot+3b3296d032353c33184b@syzkaller.appspotmail.com Signed-off-by: Takeshi Misawa Signed-off-by: David S. Miller --- net/core/net_namespace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 6d3e4821b02d..5a4ae0845bac 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -479,6 +479,7 @@ struct net *copy_net_ns(unsigned long flags, if (rv < 0) { put_userns: + key_remove_domain(net->key_domain); put_user_ns(user_ns); net_drop_ns(net); dec_ucounts: -- GitLab From 5343da4c17429efaa5fb1594ea96aee1a283e694 Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Mon, 21 Oct 2019 18:47:50 +0000 Subject: [PATCH 700/993] net: core: limit nested device depth Current code doesn't limit the number of nested devices. Nested devices would be handled recursively and this needs huge stack memory. So, unlimited nested devices could make stack overflow. This patch adds upper_level and lower_level, they are common variables and represent maximum lower/upper depth. When upper/lower device is attached or dettached, {lower/upper}_level are updated. and if maximum depth is bigger than 8, attach routine fails and returns -EMLINK. In addition, this patch converts recursive routine of netdev_walk_all_{lower/upper} to iterator routine. Test commands: ip link add dummy0 type dummy ip link add link dummy0 name vlan1 type vlan id 1 ip link set vlan1 up for i in {2..55} do let A=$i-1 ip link add vlan$i link vlan$A type vlan id $i done ip link del dummy0 Splat looks like: [ 155.513226][ T908] BUG: KASAN: use-after-free in __unwind_start+0x71/0x850 [ 155.514162][ T908] Write of size 88 at addr ffff8880608a6cc0 by task ip/908 [ 155.515048][ T908] [ 155.515333][ T908] CPU: 0 PID: 908 Comm: ip Not tainted 5.4.0-rc3+ #96 [ 155.516147][ T908] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 155.517233][ T908] Call Trace: [ 155.517627][ T908] [ 155.517918][ T908] Allocated by task 0: [ 155.518412][ T908] (stack is not available) [ 155.518955][ T908] [ 155.519228][ T908] Freed by task 0: [ 155.519885][ T908] (stack is not available) [ 155.520452][ T908] [ 155.520729][ T908] The buggy address belongs to the object at ffff8880608a6ac0 [ 155.520729][ T908] which belongs to the cache names_cache of size 4096 [ 155.522387][ T908] The buggy address is located 512 bytes inside of [ 155.522387][ T908] 4096-byte region [ffff8880608a6ac0, ffff8880608a7ac0) [ 155.523920][ T908] The buggy address belongs to the page: [ 155.524552][ T908] page:ffffea0001822800 refcount:1 mapcount:0 mapping:ffff88806c657cc0 index:0x0 compound_mapcount:0 [ 155.525836][ T908] flags: 0x100000000010200(slab|head) [ 155.526445][ T908] raw: 0100000000010200 ffffea0001813808 ffffea0001a26c08 ffff88806c657cc0 [ 155.527424][ T908] raw: 0000000000000000 0000000000070007 00000001ffffffff 0000000000000000 [ 155.528429][ T908] page dumped because: kasan: bad access detected [ 155.529158][ T908] [ 155.529410][ T908] Memory state around the buggy address: [ 155.530060][ T908] ffff8880608a6b80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 155.530971][ T908] ffff8880608a6c00: fb fb fb fb fb f1 f1 f1 f1 00 f2 f2 f2 f3 f3 f3 [ 155.531889][ T908] >ffff8880608a6c80: f3 fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 155.532806][ T908] ^ [ 155.533509][ T908] ffff8880608a6d00: fb fb fb fb fb fb fb fb fb f1 f1 f1 f1 00 00 00 [ 155.534436][ T908] ffff8880608a6d80: f2 f3 f3 f3 f3 fb fb fb 00 00 00 00 00 00 00 00 [ ... ] Signed-off-by: Taehee Yoo Signed-off-by: David S. Miller --- include/linux/netdevice.h | 4 + net/core/dev.c | 272 +++++++++++++++++++++++++++++++------- 2 files changed, 231 insertions(+), 45 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9eda1c31d1f7..38c5909e1c35 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1649,6 +1649,8 @@ enum netdev_priv_flags { * @perm_addr: Permanent hw address * @addr_assign_type: Hw address assignment type * @addr_len: Hardware address length + * @upper_level: Maximum depth level of upper devices. + * @lower_level: Maximum depth level of lower devices. * @neigh_priv_len: Used in neigh_alloc() * @dev_id: Used to differentiate devices that share * the same link layer address @@ -1875,6 +1877,8 @@ struct net_device { unsigned char perm_addr[MAX_ADDR_LEN]; unsigned char addr_assign_type; unsigned char addr_len; + unsigned char upper_level; + unsigned char lower_level; unsigned short neigh_priv_len; unsigned short dev_id; unsigned short dev_port; diff --git a/net/core/dev.c b/net/core/dev.c index bf3ed413abaf..ab0edfc4a422 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -146,6 +146,7 @@ #include "net-sysfs.h" #define MAX_GRO_SKBS 8 +#define MAX_NEST_DEV 8 /* This should be increased if a protocol with a bigger head is added. */ #define GRO_MAX_HEAD (MAX_HEADER + 128) @@ -6644,6 +6645,21 @@ struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev, } EXPORT_SYMBOL(netdev_upper_get_next_dev_rcu); +static struct net_device *netdev_next_upper_dev(struct net_device *dev, + struct list_head **iter) +{ + struct netdev_adjacent *upper; + + upper = list_entry((*iter)->next, struct netdev_adjacent, list); + + if (&upper->list == &dev->adj_list.upper) + return NULL; + + *iter = &upper->list; + + return upper->dev; +} + static struct net_device *netdev_next_upper_dev_rcu(struct net_device *dev, struct list_head **iter) { @@ -6661,28 +6677,93 @@ static struct net_device *netdev_next_upper_dev_rcu(struct net_device *dev, return upper->dev; } +static int netdev_walk_all_upper_dev(struct net_device *dev, + int (*fn)(struct net_device *dev, + void *data), + void *data) +{ + struct net_device *udev, *next, *now, *dev_stack[MAX_NEST_DEV + 1]; + struct list_head *niter, *iter, *iter_stack[MAX_NEST_DEV + 1]; + int ret, cur = 0; + + now = dev; + iter = &dev->adj_list.upper; + + while (1) { + if (now != dev) { + ret = fn(now, data); + if (ret) + return ret; + } + + next = NULL; + while (1) { + udev = netdev_next_upper_dev(now, &iter); + if (!udev) + break; + + next = udev; + niter = &udev->adj_list.upper; + dev_stack[cur] = now; + iter_stack[cur++] = iter; + break; + } + + if (!next) { + if (!cur) + return 0; + next = dev_stack[--cur]; + niter = iter_stack[cur]; + } + + now = next; + iter = niter; + } + + return 0; +} + int netdev_walk_all_upper_dev_rcu(struct net_device *dev, int (*fn)(struct net_device *dev, void *data), void *data) { - struct net_device *udev; - struct list_head *iter; - int ret; + struct net_device *udev, *next, *now, *dev_stack[MAX_NEST_DEV + 1]; + struct list_head *niter, *iter, *iter_stack[MAX_NEST_DEV + 1]; + int ret, cur = 0; - for (iter = &dev->adj_list.upper, - udev = netdev_next_upper_dev_rcu(dev, &iter); - udev; - udev = netdev_next_upper_dev_rcu(dev, &iter)) { - /* first is the upper device itself */ - ret = fn(udev, data); - if (ret) - return ret; + now = dev; + iter = &dev->adj_list.upper; - /* then look at all of its upper devices */ - ret = netdev_walk_all_upper_dev_rcu(udev, fn, data); - if (ret) - return ret; + while (1) { + if (now != dev) { + ret = fn(now, data); + if (ret) + return ret; + } + + next = NULL; + while (1) { + udev = netdev_next_upper_dev_rcu(now, &iter); + if (!udev) + break; + + next = udev; + niter = &udev->adj_list.upper; + dev_stack[cur] = now; + iter_stack[cur++] = iter; + break; + } + + if (!next) { + if (!cur) + return 0; + next = dev_stack[--cur]; + niter = iter_stack[cur]; + } + + now = next; + iter = niter; } return 0; @@ -6790,23 +6871,42 @@ int netdev_walk_all_lower_dev(struct net_device *dev, void *data), void *data) { - struct net_device *ldev; - struct list_head *iter; - int ret; + struct net_device *ldev, *next, *now, *dev_stack[MAX_NEST_DEV + 1]; + struct list_head *niter, *iter, *iter_stack[MAX_NEST_DEV + 1]; + int ret, cur = 0; - for (iter = &dev->adj_list.lower, - ldev = netdev_next_lower_dev(dev, &iter); - ldev; - ldev = netdev_next_lower_dev(dev, &iter)) { - /* first is the lower device itself */ - ret = fn(ldev, data); - if (ret) - return ret; + now = dev; + iter = &dev->adj_list.lower; - /* then look at all of its lower devices */ - ret = netdev_walk_all_lower_dev(ldev, fn, data); - if (ret) - return ret; + while (1) { + if (now != dev) { + ret = fn(now, data); + if (ret) + return ret; + } + + next = NULL; + while (1) { + ldev = netdev_next_lower_dev(now, &iter); + if (!ldev) + break; + + next = ldev; + niter = &ldev->adj_list.lower; + dev_stack[cur] = now; + iter_stack[cur++] = iter; + break; + } + + if (!next) { + if (!cur) + return 0; + next = dev_stack[--cur]; + niter = iter_stack[cur]; + } + + now = next; + iter = niter; } return 0; @@ -6827,28 +6927,93 @@ static struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev, return lower->dev; } -int netdev_walk_all_lower_dev_rcu(struct net_device *dev, - int (*fn)(struct net_device *dev, - void *data), - void *data) +static u8 __netdev_upper_depth(struct net_device *dev) +{ + struct net_device *udev; + struct list_head *iter; + u8 max_depth = 0; + + for (iter = &dev->adj_list.upper, + udev = netdev_next_upper_dev(dev, &iter); + udev; + udev = netdev_next_upper_dev(dev, &iter)) { + if (max_depth < udev->upper_level) + max_depth = udev->upper_level; + } + + return max_depth; +} + +static u8 __netdev_lower_depth(struct net_device *dev) { struct net_device *ldev; struct list_head *iter; - int ret; + u8 max_depth = 0; for (iter = &dev->adj_list.lower, - ldev = netdev_next_lower_dev_rcu(dev, &iter); + ldev = netdev_next_lower_dev(dev, &iter); ldev; - ldev = netdev_next_lower_dev_rcu(dev, &iter)) { - /* first is the lower device itself */ - ret = fn(ldev, data); - if (ret) - return ret; + ldev = netdev_next_lower_dev(dev, &iter)) { + if (max_depth < ldev->lower_level) + max_depth = ldev->lower_level; + } - /* then look at all of its lower devices */ - ret = netdev_walk_all_lower_dev_rcu(ldev, fn, data); - if (ret) - return ret; + return max_depth; +} + +static int __netdev_update_upper_level(struct net_device *dev, void *data) +{ + dev->upper_level = __netdev_upper_depth(dev) + 1; + return 0; +} + +static int __netdev_update_lower_level(struct net_device *dev, void *data) +{ + dev->lower_level = __netdev_lower_depth(dev) + 1; + return 0; +} + +int netdev_walk_all_lower_dev_rcu(struct net_device *dev, + int (*fn)(struct net_device *dev, + void *data), + void *data) +{ + struct net_device *ldev, *next, *now, *dev_stack[MAX_NEST_DEV + 1]; + struct list_head *niter, *iter, *iter_stack[MAX_NEST_DEV + 1]; + int ret, cur = 0; + + now = dev; + iter = &dev->adj_list.lower; + + while (1) { + if (now != dev) { + ret = fn(now, data); + if (ret) + return ret; + } + + next = NULL; + while (1) { + ldev = netdev_next_lower_dev_rcu(now, &iter); + if (!ldev) + break; + + next = ldev; + niter = &ldev->adj_list.lower; + dev_stack[cur] = now; + iter_stack[cur++] = iter; + break; + } + + if (!next) { + if (!cur) + return 0; + next = dev_stack[--cur]; + niter = iter_stack[cur]; + } + + now = next; + iter = niter; } return 0; @@ -7105,6 +7270,9 @@ static int __netdev_upper_dev_link(struct net_device *dev, if (netdev_has_upper_dev(upper_dev, dev)) return -EBUSY; + if ((dev->lower_level + upper_dev->upper_level) > MAX_NEST_DEV) + return -EMLINK; + if (!master) { if (netdev_has_upper_dev(dev, upper_dev)) return -EEXIST; @@ -7131,6 +7299,12 @@ static int __netdev_upper_dev_link(struct net_device *dev, if (ret) goto rollback; + __netdev_update_upper_level(dev, NULL); + netdev_walk_all_lower_dev(dev, __netdev_update_upper_level, NULL); + + __netdev_update_lower_level(upper_dev, NULL); + netdev_walk_all_upper_dev(upper_dev, __netdev_update_lower_level, NULL); + return 0; rollback: @@ -7213,6 +7387,12 @@ void netdev_upper_dev_unlink(struct net_device *dev, call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, &changeupper_info.info); + + __netdev_update_upper_level(dev, NULL); + netdev_walk_all_lower_dev(dev, __netdev_update_upper_level, NULL); + + __netdev_update_lower_level(upper_dev, NULL); + netdev_walk_all_upper_dev(upper_dev, __netdev_update_lower_level, NULL); } EXPORT_SYMBOL(netdev_upper_dev_unlink); @@ -9212,6 +9392,8 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, dev->gso_max_size = GSO_MAX_SIZE; dev->gso_max_segs = GSO_MAX_SEGS; + dev->upper_level = 1; + dev->lower_level = 1; INIT_LIST_HEAD(&dev->napi_list); INIT_LIST_HEAD(&dev->unreg_list); -- GitLab From ab92d68fc22f9afab480153bd82a20f6e2533769 Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Mon, 21 Oct 2019 18:47:51 +0000 Subject: [PATCH 701/993] net: core: add generic lockdep keys Some interface types could be nested. (VLAN, BONDING, TEAM, MACSEC, MACVLAN, IPVLAN, VIRT_WIFI, VXLAN, etc..) These interface types should set lockdep class because, without lockdep class key, lockdep always warn about unexisting circular locking. In the current code, these interfaces have their own lockdep class keys and these manage itself. So that there are so many duplicate code around the /driver/net and /net/. This patch adds new generic lockdep keys and some helper functions for it. This patch does below changes. a) Add lockdep class keys in struct net_device - qdisc_running, xmit, addr_list, qdisc_busylock - these keys are used as dynamic lockdep key. b) When net_device is being allocated, lockdep keys are registered. - alloc_netdev_mqs() c) When net_device is being free'd llockdep keys are unregistered. - free_netdev() d) Add generic lockdep key helper function - netdev_register_lockdep_key() - netdev_unregister_lockdep_key() - netdev_update_lockdep_key() e) Remove unnecessary generic lockdep macro and functions f) Remove unnecessary lockdep code of each interfaces. After this patch, each interface modules don't need to maintain their lockdep keys. Signed-off-by: Taehee Yoo Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 1 - .../net/ethernet/netronome/nfp/nfp_net_repr.c | 18 --- drivers/net/hamradio/bpqether.c | 22 --- drivers/net/hyperv/netvsc_drv.c | 2 - drivers/net/ipvlan/ipvlan_main.c | 2 - drivers/net/macsec.c | 5 - drivers/net/macvlan.c | 12 -- drivers/net/ppp/ppp_generic.c | 2 - drivers/net/team/team.c | 2 - drivers/net/vrf.c | 1 - .../net/wireless/intersil/hostap/hostap_hw.c | 25 ---- include/linux/netdevice.h | 35 ++--- net/8021q/vlan_dev.c | 27 ---- net/batman-adv/soft-interface.c | 32 ----- net/bluetooth/6lowpan.c | 8 -- net/bridge/br_device.c | 8 -- net/core/dev.c | 127 ++++++------------ net/core/rtnetlink.c | 1 + net/dsa/master.c | 5 - net/dsa/slave.c | 12 -- net/ieee802154/6lowpan/core.c | 8 -- net/l2tp/l2tp_eth.c | 1 - net/netrom/af_netrom.c | 23 ---- net/rose/af_rose.c | 23 ---- net/sched/sch_generic.c | 17 +-- 25 files changed, 63 insertions(+), 356 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 21d8fcc83c9c..ac1b09b56c77 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4769,7 +4769,6 @@ static int bond_init(struct net_device *bond_dev) return -ENOMEM; bond->nest_level = SINGLE_DEPTH_NESTING; - netdev_lockdep_set_classes(bond_dev); list_add_tail(&bond->bond_list, &bn->dev_list); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c index 1eef446036d6..79d72c88bbef 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c @@ -299,22 +299,6 @@ static void nfp_repr_clean(struct nfp_repr *repr) nfp_port_free(repr->port); } -static struct lock_class_key nfp_repr_netdev_xmit_lock_key; -static struct lock_class_key nfp_repr_netdev_addr_lock_key; - -static void nfp_repr_set_lockdep_class_one(struct net_device *dev, - struct netdev_queue *txq, - void *_unused) -{ - lockdep_set_class(&txq->_xmit_lock, &nfp_repr_netdev_xmit_lock_key); -} - -static void nfp_repr_set_lockdep_class(struct net_device *dev) -{ - lockdep_set_class(&dev->addr_list_lock, &nfp_repr_netdev_addr_lock_key); - netdev_for_each_tx_queue(dev, nfp_repr_set_lockdep_class_one, NULL); -} - int nfp_repr_init(struct nfp_app *app, struct net_device *netdev, u32 cmsg_port_id, struct nfp_port *port, struct net_device *pf_netdev) @@ -324,8 +308,6 @@ int nfp_repr_init(struct nfp_app *app, struct net_device *netdev, u32 repr_cap = nn->tlv_caps.repr_cap; int err; - nfp_repr_set_lockdep_class(netdev); - repr->port = port; repr->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, GFP_KERNEL); if (!repr->dst) diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index fbec711ff514..fbea6f232819 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -107,27 +107,6 @@ struct bpqdev { static LIST_HEAD(bpq_devices); -/* - * bpqether network devices are paired with ethernet devices below them, so - * form a special "super class" of normal ethernet devices; split their locks - * off into a separate class since they always nest. - */ -static struct lock_class_key bpq_netdev_xmit_lock_key; -static struct lock_class_key bpq_netdev_addr_lock_key; - -static void bpq_set_lockdep_class_one(struct net_device *dev, - struct netdev_queue *txq, - void *_unused) -{ - lockdep_set_class(&txq->_xmit_lock, &bpq_netdev_xmit_lock_key); -} - -static void bpq_set_lockdep_class(struct net_device *dev) -{ - lockdep_set_class(&dev->addr_list_lock, &bpq_netdev_addr_lock_key); - netdev_for_each_tx_queue(dev, bpq_set_lockdep_class_one, NULL); -} - /* ------------------------------------------------------------------------ */ @@ -498,7 +477,6 @@ static int bpq_new_device(struct net_device *edev) err = register_netdevice(ndev); if (err) goto error; - bpq_set_lockdep_class(ndev); /* List protected by RTNL */ list_add_rcu(&bpq->bpq_list, &bpq_devices); diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 39dddcd8b3cb..fd4fff57fd6e 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -2335,8 +2335,6 @@ static int netvsc_probe(struct hv_device *dev, NETIF_F_HW_VLAN_CTAG_RX; net->vlan_features = net->features; - netdev_lockdep_set_classes(net); - /* MTU range: 68 - 1500 or 65521 */ net->min_mtu = NETVSC_MTU_MIN; if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2) diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index 887bbba4631e..ba3dfac1d904 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -131,8 +131,6 @@ static int ipvlan_init(struct net_device *dev) dev->gso_max_segs = phy_dev->gso_max_segs; dev->hard_header_len = phy_dev->hard_header_len; - netdev_lockdep_set_classes(dev); - ipvlan->pcpu_stats = netdev_alloc_pcpu_stats(struct ipvl_pcpu_stats); if (!ipvlan->pcpu_stats) return -ENOMEM; diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index cb7637364b40..e2a3d1d5795f 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -2750,7 +2750,6 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb, #define MACSEC_FEATURES \ (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST) -static struct lock_class_key macsec_netdev_addr_lock_key; static int macsec_dev_init(struct net_device *dev) { @@ -3264,10 +3263,6 @@ static int macsec_newlink(struct net *net, struct net_device *dev, dev_hold(real_dev); macsec->nest_level = dev_get_nest_level(real_dev) + 1; - netdev_lockdep_set_classes(dev); - lockdep_set_class_and_subclass(&dev->addr_list_lock, - &macsec_netdev_addr_lock_key, - macsec_get_nest_level(dev)); err = netdev_upper_dev_link(real_dev, dev, extack); if (err < 0) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 940192c057b6..0354e9be2ca5 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -852,8 +852,6 @@ static int macvlan_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) * "super class" of normal network devices; split their locks off into a * separate class since they always nest. */ -static struct lock_class_key macvlan_netdev_addr_lock_key; - #define ALWAYS_ON_OFFLOADS \ (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE | \ NETIF_F_GSO_ROBUST | NETIF_F_GSO_ENCAP_ALL) @@ -874,14 +872,6 @@ static int macvlan_get_nest_level(struct net_device *dev) return ((struct macvlan_dev *)netdev_priv(dev))->nest_level; } -static void macvlan_set_lockdep_class(struct net_device *dev) -{ - netdev_lockdep_set_classes(dev); - lockdep_set_class_and_subclass(&dev->addr_list_lock, - &macvlan_netdev_addr_lock_key, - macvlan_get_nest_level(dev)); -} - static int macvlan_init(struct net_device *dev) { struct macvlan_dev *vlan = netdev_priv(dev); @@ -900,8 +890,6 @@ static int macvlan_init(struct net_device *dev) dev->gso_max_segs = lowerdev->gso_max_segs; dev->hard_header_len = lowerdev->hard_header_len; - macvlan_set_lockdep_class(dev); - vlan->pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); if (!vlan->pcpu_stats) return -ENOMEM; diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 9a1b006904a7..61824bbb5588 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -1324,8 +1324,6 @@ static int ppp_dev_init(struct net_device *dev) { struct ppp *ppp; - netdev_lockdep_set_classes(dev); - ppp = netdev_priv(dev); /* Let the netdevice take a reference on the ppp file. This ensures * that ppp_destroy_interface() won't run before the device gets diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index e8089def5a46..6cea83b48cad 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1642,8 +1642,6 @@ static int team_init(struct net_device *dev) goto err_options_register; netif_carrier_off(dev); - netdev_lockdep_set_classes(dev); - return 0; err_options_register: diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index ee52bde058df..b8228f50bc94 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -865,7 +865,6 @@ static int vrf_dev_init(struct net_device *dev) /* similarly, oper state is irrelevant; set to up to avoid confusion */ dev->operstate = IF_OPER_UP; - netdev_lockdep_set_classes(dev); return 0; out_rth: diff --git a/drivers/net/wireless/intersil/hostap/hostap_hw.c b/drivers/net/wireless/intersil/hostap/hostap_hw.c index 158a3d762e55..e323e9a5999f 100644 --- a/drivers/net/wireless/intersil/hostap/hostap_hw.c +++ b/drivers/net/wireless/intersil/hostap/hostap_hw.c @@ -3041,30 +3041,6 @@ static void prism2_clear_set_tim_queue(local_info_t *local) } } - -/* - * HostAP uses two layers of net devices, where the inner - * layer gets called all the time from the outer layer. - * This is a natural nesting, which needs a split lock type. - */ -static struct lock_class_key hostap_netdev_xmit_lock_key; -static struct lock_class_key hostap_netdev_addr_lock_key; - -static void prism2_set_lockdep_class_one(struct net_device *dev, - struct netdev_queue *txq, - void *_unused) -{ - lockdep_set_class(&txq->_xmit_lock, - &hostap_netdev_xmit_lock_key); -} - -static void prism2_set_lockdep_class(struct net_device *dev) -{ - lockdep_set_class(&dev->addr_list_lock, - &hostap_netdev_addr_lock_key); - netdev_for_each_tx_queue(dev, prism2_set_lockdep_class_one, NULL); -} - static struct net_device * prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx, struct device *sdev) @@ -3223,7 +3199,6 @@ while (0) if (ret >= 0) ret = register_netdevice(dev); - prism2_set_lockdep_class(dev); rtnl_unlock(); if (ret < 0) { printk(KERN_WARNING "%s: register netdevice failed!\n", diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 38c5909e1c35..c93df7cf187b 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -925,6 +925,7 @@ struct dev_ifalias { struct devlink; struct tlsdev_ops; + /* * This structure defines the management hooks for network devices. * The following hooks can be defined; unless noted otherwise, they are @@ -1760,9 +1761,13 @@ enum netdev_priv_flags { * @phydev: Physical device may attach itself * for hardware timestamping * @sfp_bus: attached &struct sfp_bus structure. - * - * @qdisc_tx_busylock: lockdep class annotating Qdisc->busylock spinlock - * @qdisc_running_key: lockdep class annotating Qdisc->running seqcount + * @qdisc_tx_busylock_key: lockdep class annotating Qdisc->busylock + spinlock + * @qdisc_running_key: lockdep class annotating Qdisc->running seqcount + * @qdisc_xmit_lock_key: lockdep class annotating + * netdev_queue->_xmit_lock spinlock + * @addr_list_lock_key: lockdep class annotating + * net_device->addr_list_lock spinlock * * @proto_down: protocol port state information can be sent to the * switch driver and used to set the phys state of the @@ -2049,8 +2054,10 @@ struct net_device { #endif struct phy_device *phydev; struct sfp_bus *sfp_bus; - struct lock_class_key *qdisc_tx_busylock; - struct lock_class_key *qdisc_running_key; + struct lock_class_key qdisc_tx_busylock_key; + struct lock_class_key qdisc_running_key; + struct lock_class_key qdisc_xmit_lock_key; + struct lock_class_key addr_list_lock_key; bool proto_down; unsigned wol_enabled:1; }; @@ -2128,23 +2135,6 @@ static inline void netdev_for_each_tx_queue(struct net_device *dev, f(dev, &dev->_tx[i], arg); } -#define netdev_lockdep_set_classes(dev) \ -{ \ - static struct lock_class_key qdisc_tx_busylock_key; \ - static struct lock_class_key qdisc_running_key; \ - static struct lock_class_key qdisc_xmit_lock_key; \ - static struct lock_class_key dev_addr_list_lock_key; \ - unsigned int i; \ - \ - (dev)->qdisc_tx_busylock = &qdisc_tx_busylock_key; \ - (dev)->qdisc_running_key = &qdisc_running_key; \ - lockdep_set_class(&(dev)->addr_list_lock, \ - &dev_addr_list_lock_key); \ - for (i = 0; i < (dev)->num_tx_queues; i++) \ - lockdep_set_class(&(dev)->_tx[i]._xmit_lock, \ - &qdisc_xmit_lock_key); \ -} - u16 netdev_pick_tx(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev); struct netdev_queue *netdev_core_pick_tx(struct net_device *dev, @@ -3143,6 +3133,7 @@ static inline void netif_stop_queue(struct net_device *dev) } void netif_tx_stop_all_queues(struct net_device *dev); +void netdev_update_lockdep_key(struct net_device *dev); static inline bool netif_tx_queue_stopped(const struct netdev_queue *dev_queue) { diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 93eadf179123..6e6f26bf6e73 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -489,31 +489,6 @@ static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); } -/* - * vlan network devices have devices nesting below it, and are a special - * "super class" of normal network devices; split their locks off into a - * separate class since they always nest. - */ -static struct lock_class_key vlan_netdev_xmit_lock_key; -static struct lock_class_key vlan_netdev_addr_lock_key; - -static void vlan_dev_set_lockdep_one(struct net_device *dev, - struct netdev_queue *txq, - void *_subclass) -{ - lockdep_set_class_and_subclass(&txq->_xmit_lock, - &vlan_netdev_xmit_lock_key, - *(int *)_subclass); -} - -static void vlan_dev_set_lockdep_class(struct net_device *dev, int subclass) -{ - lockdep_set_class_and_subclass(&dev->addr_list_lock, - &vlan_netdev_addr_lock_key, - subclass); - netdev_for_each_tx_queue(dev, vlan_dev_set_lockdep_one, &subclass); -} - static int vlan_dev_get_lock_subclass(struct net_device *dev) { return vlan_dev_priv(dev)->nest_level; @@ -609,8 +584,6 @@ static int vlan_dev_init(struct net_device *dev) SET_NETDEV_DEVTYPE(dev, &vlan_type); - vlan_dev_set_lockdep_class(dev, vlan_dev_get_lock_subclass(dev)); - vlan->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); if (!vlan->vlan_pcpu_stats) return -ENOMEM; diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 9cbed6f5a85a..5ee8e9a100f9 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -740,36 +740,6 @@ static int batadv_interface_kill_vid(struct net_device *dev, __be16 proto, return 0; } -/* batman-adv network devices have devices nesting below it and are a special - * "super class" of normal network devices; split their locks off into a - * separate class since they always nest. - */ -static struct lock_class_key batadv_netdev_xmit_lock_key; -static struct lock_class_key batadv_netdev_addr_lock_key; - -/** - * batadv_set_lockdep_class_one() - Set lockdep class for a single tx queue - * @dev: device which owns the tx queue - * @txq: tx queue to modify - * @_unused: always NULL - */ -static void batadv_set_lockdep_class_one(struct net_device *dev, - struct netdev_queue *txq, - void *_unused) -{ - lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key); -} - -/** - * batadv_set_lockdep_class() - Set txq and addr_list lockdep class - * @dev: network device to modify - */ -static void batadv_set_lockdep_class(struct net_device *dev) -{ - lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key); - netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL); -} - /** * batadv_softif_init_late() - late stage initialization of soft interface * @dev: registered network device to modify @@ -783,8 +753,6 @@ static int batadv_softif_init_late(struct net_device *dev) int ret; size_t cnt_len = sizeof(u64) * BATADV_CNT_NUM; - batadv_set_lockdep_class(dev); - bat_priv = netdev_priv(dev); bat_priv->soft_iface = dev; diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index bb55d92691b0..4febc82a7c76 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -571,15 +571,7 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev) return err < 0 ? NET_XMIT_DROP : err; } -static int bt_dev_init(struct net_device *dev) -{ - netdev_lockdep_set_classes(dev); - - return 0; -} - static const struct net_device_ops netdev_ops = { - .ndo_init = bt_dev_init, .ndo_start_xmit = bt_xmit, }; diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 681b72862c16..e804a3016902 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -24,8 +24,6 @@ const struct nf_br_ops __rcu *nf_br_ops __read_mostly; EXPORT_SYMBOL_GPL(nf_br_ops); -static struct lock_class_key bridge_netdev_addr_lock_key; - /* net device transmit always called with BH disabled */ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -108,11 +106,6 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } -static void br_set_lockdep_class(struct net_device *dev) -{ - lockdep_set_class(&dev->addr_list_lock, &bridge_netdev_addr_lock_key); -} - static int br_dev_init(struct net_device *dev) { struct net_bridge *br = netdev_priv(dev); @@ -150,7 +143,6 @@ static int br_dev_init(struct net_device *dev) br_mdb_hash_fini(br); br_fdb_hash_fini(br); } - br_set_lockdep_class(dev); return err; } diff --git a/net/core/dev.c b/net/core/dev.c index ab0edfc4a422..5722a81b6edd 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -277,88 +277,6 @@ static RAW_NOTIFIER_HEAD(netdev_chain); DEFINE_PER_CPU_ALIGNED(struct softnet_data, softnet_data); EXPORT_PER_CPU_SYMBOL(softnet_data); -#ifdef CONFIG_LOCKDEP -/* - * register_netdevice() inits txq->_xmit_lock and sets lockdep class - * according to dev->type - */ -static const unsigned short netdev_lock_type[] = { - ARPHRD_NETROM, ARPHRD_ETHER, ARPHRD_EETHER, ARPHRD_AX25, - ARPHRD_PRONET, ARPHRD_CHAOS, ARPHRD_IEEE802, ARPHRD_ARCNET, - ARPHRD_APPLETLK, ARPHRD_DLCI, ARPHRD_ATM, ARPHRD_METRICOM, - ARPHRD_IEEE1394, ARPHRD_EUI64, ARPHRD_INFINIBAND, ARPHRD_SLIP, - ARPHRD_CSLIP, ARPHRD_SLIP6, ARPHRD_CSLIP6, ARPHRD_RSRVD, - ARPHRD_ADAPT, ARPHRD_ROSE, ARPHRD_X25, ARPHRD_HWX25, - ARPHRD_PPP, ARPHRD_CISCO, ARPHRD_LAPB, ARPHRD_DDCMP, - ARPHRD_RAWHDLC, ARPHRD_TUNNEL, ARPHRD_TUNNEL6, ARPHRD_FRAD, - ARPHRD_SKIP, ARPHRD_LOOPBACK, ARPHRD_LOCALTLK, ARPHRD_FDDI, - ARPHRD_BIF, ARPHRD_SIT, ARPHRD_IPDDP, ARPHRD_IPGRE, - ARPHRD_PIMREG, ARPHRD_HIPPI, ARPHRD_ASH, ARPHRD_ECONET, - ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, - ARPHRD_FCFABRIC, ARPHRD_IEEE80211, ARPHRD_IEEE80211_PRISM, - ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, ARPHRD_PHONET_PIPE, - ARPHRD_IEEE802154, ARPHRD_VOID, ARPHRD_NONE}; - -static const char *const netdev_lock_name[] = { - "_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25", - "_xmit_PRONET", "_xmit_CHAOS", "_xmit_IEEE802", "_xmit_ARCNET", - "_xmit_APPLETLK", "_xmit_DLCI", "_xmit_ATM", "_xmit_METRICOM", - "_xmit_IEEE1394", "_xmit_EUI64", "_xmit_INFINIBAND", "_xmit_SLIP", - "_xmit_CSLIP", "_xmit_SLIP6", "_xmit_CSLIP6", "_xmit_RSRVD", - "_xmit_ADAPT", "_xmit_ROSE", "_xmit_X25", "_xmit_HWX25", - "_xmit_PPP", "_xmit_CISCO", "_xmit_LAPB", "_xmit_DDCMP", - "_xmit_RAWHDLC", "_xmit_TUNNEL", "_xmit_TUNNEL6", "_xmit_FRAD", - "_xmit_SKIP", "_xmit_LOOPBACK", "_xmit_LOCALTLK", "_xmit_FDDI", - "_xmit_BIF", "_xmit_SIT", "_xmit_IPDDP", "_xmit_IPGRE", - "_xmit_PIMREG", "_xmit_HIPPI", "_xmit_ASH", "_xmit_ECONET", - "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL", - "_xmit_FCFABRIC", "_xmit_IEEE80211", "_xmit_IEEE80211_PRISM", - "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", "_xmit_PHONET_PIPE", - "_xmit_IEEE802154", "_xmit_VOID", "_xmit_NONE"}; - -static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; -static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)]; - -static inline unsigned short netdev_lock_pos(unsigned short dev_type) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(netdev_lock_type); i++) - if (netdev_lock_type[i] == dev_type) - return i; - /* the last key is used by default */ - return ARRAY_SIZE(netdev_lock_type) - 1; -} - -static inline void netdev_set_xmit_lockdep_class(spinlock_t *lock, - unsigned short dev_type) -{ - int i; - - i = netdev_lock_pos(dev_type); - lockdep_set_class_and_name(lock, &netdev_xmit_lock_key[i], - netdev_lock_name[i]); -} - -static inline void netdev_set_addr_lockdep_class(struct net_device *dev) -{ - int i; - - i = netdev_lock_pos(dev->type); - lockdep_set_class_and_name(&dev->addr_list_lock, - &netdev_addr_lock_key[i], - netdev_lock_name[i]); -} -#else -static inline void netdev_set_xmit_lockdep_class(spinlock_t *lock, - unsigned short dev_type) -{ -} -static inline void netdev_set_addr_lockdep_class(struct net_device *dev) -{ -} -#endif - /******************************************************************************* * * Protocol management and registration routines @@ -8799,7 +8717,7 @@ static void netdev_init_one_queue(struct net_device *dev, { /* Initialize queue lock */ spin_lock_init(&queue->_xmit_lock); - netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type); + lockdep_set_class(&queue->_xmit_lock, &dev->qdisc_xmit_lock_key); queue->xmit_lock_owner = -1; netdev_queue_numa_node_write(queue, NUMA_NO_NODE); queue->dev = dev; @@ -8846,6 +8764,43 @@ void netif_tx_stop_all_queues(struct net_device *dev) } EXPORT_SYMBOL(netif_tx_stop_all_queues); +static void netdev_register_lockdep_key(struct net_device *dev) +{ + lockdep_register_key(&dev->qdisc_tx_busylock_key); + lockdep_register_key(&dev->qdisc_running_key); + lockdep_register_key(&dev->qdisc_xmit_lock_key); + lockdep_register_key(&dev->addr_list_lock_key); +} + +static void netdev_unregister_lockdep_key(struct net_device *dev) +{ + lockdep_unregister_key(&dev->qdisc_tx_busylock_key); + lockdep_unregister_key(&dev->qdisc_running_key); + lockdep_unregister_key(&dev->qdisc_xmit_lock_key); + lockdep_unregister_key(&dev->addr_list_lock_key); +} + +void netdev_update_lockdep_key(struct net_device *dev) +{ + struct netdev_queue *queue; + int i; + + lockdep_unregister_key(&dev->qdisc_xmit_lock_key); + lockdep_unregister_key(&dev->addr_list_lock_key); + + lockdep_register_key(&dev->qdisc_xmit_lock_key); + lockdep_register_key(&dev->addr_list_lock_key); + + lockdep_set_class(&dev->addr_list_lock, &dev->addr_list_lock_key); + for (i = 0; i < dev->num_tx_queues; i++) { + queue = netdev_get_tx_queue(dev, i); + + lockdep_set_class(&queue->_xmit_lock, + &dev->qdisc_xmit_lock_key); + } +} +EXPORT_SYMBOL(netdev_update_lockdep_key); + /** * register_netdevice - register a network device * @dev: device to register @@ -8880,7 +8835,7 @@ int register_netdevice(struct net_device *dev) BUG_ON(!net); spin_lock_init(&dev->addr_list_lock); - netdev_set_addr_lockdep_class(dev); + lockdep_set_class(&dev->addr_list_lock, &dev->addr_list_lock_key); ret = dev_get_valid_name(net, dev, dev->name); if (ret < 0) @@ -9390,6 +9345,8 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, dev_net_set(dev, &init_net); + netdev_register_lockdep_key(dev); + dev->gso_max_size = GSO_MAX_SIZE; dev->gso_max_segs = GSO_MAX_SEGS; dev->upper_level = 1; @@ -9474,6 +9431,8 @@ void free_netdev(struct net_device *dev) free_percpu(dev->pcpu_refcnt); dev->pcpu_refcnt = NULL; + netdev_unregister_lockdep_key(dev); + /* Compatibility with error handling in drivers */ if (dev->reg_state == NETREG_UNINITIALIZED) { netdev_freemem(dev); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 1ee6460f8275..13493aae4e6c 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -2355,6 +2355,7 @@ static int do_set_master(struct net_device *dev, int ifindex, err = ops->ndo_del_slave(upper_dev, dev); if (err) return err; + netdev_update_lockdep_key(dev); } else { return -EOPNOTSUPP; } diff --git a/net/dsa/master.c b/net/dsa/master.c index a8e52c9967f4..3255dfc97f86 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -310,8 +310,6 @@ static void dsa_master_reset_mtu(struct net_device *dev) rtnl_unlock(); } -static struct lock_class_key dsa_master_addr_list_lock_key; - int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp) { int ret; @@ -325,9 +323,6 @@ int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp) wmb(); dev->dsa_ptr = cpu_dp; - lockdep_set_class(&dev->addr_list_lock, - &dsa_master_addr_list_lock_key); - ret = dsa_master_ethtool_setup(dev); if (ret) return ret; diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 75d58229a4bd..028e65f4b5ba 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -1341,15 +1341,6 @@ static int dsa_slave_phy_setup(struct net_device *slave_dev) return ret; } -static struct lock_class_key dsa_slave_netdev_xmit_lock_key; -static void dsa_slave_set_lockdep_class_one(struct net_device *dev, - struct netdev_queue *txq, - void *_unused) -{ - lockdep_set_class(&txq->_xmit_lock, - &dsa_slave_netdev_xmit_lock_key); -} - int dsa_slave_suspend(struct net_device *slave_dev) { struct dsa_port *dp = dsa_slave_to_port(slave_dev); @@ -1433,9 +1424,6 @@ int dsa_slave_create(struct dsa_port *port) slave_dev->max_mtu = ETH_MAX_MTU; SET_NETDEV_DEVTYPE(slave_dev, &dsa_type); - netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one, - NULL); - SET_NETDEV_DEV(slave_dev, port->ds->dev); slave_dev->dev.of_node = port->dn; slave_dev->vlan_features = master->vlan_features; diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c index 3297e7fa9945..c0b107cdd715 100644 --- a/net/ieee802154/6lowpan/core.c +++ b/net/ieee802154/6lowpan/core.c @@ -58,13 +58,6 @@ static const struct header_ops lowpan_header_ops = { .create = lowpan_header_create, }; -static int lowpan_dev_init(struct net_device *ldev) -{ - netdev_lockdep_set_classes(ldev); - - return 0; -} - static int lowpan_open(struct net_device *dev) { if (!open_count) @@ -96,7 +89,6 @@ static int lowpan_get_iflink(const struct net_device *dev) } static const struct net_device_ops lowpan_netdev_ops = { - .ndo_init = lowpan_dev_init, .ndo_start_xmit = lowpan_xmit, .ndo_open = lowpan_open, .ndo_stop = lowpan_stop, diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index fd5ac2788e45..d3b520b9b2c9 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -56,7 +56,6 @@ static int l2tp_eth_dev_init(struct net_device *dev) { eth_hw_addr_random(dev); eth_broadcast_addr(dev->broadcast); - netdev_lockdep_set_classes(dev); return 0; } diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index c4f54ad2b98a..58d5373c513c 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -63,28 +63,6 @@ static DEFINE_SPINLOCK(nr_list_lock); static const struct proto_ops nr_proto_ops; -/* - * NETROM network devices are virtual network devices encapsulating NETROM - * frames into AX.25 which will be sent through an AX.25 device, so form a - * special "super class" of normal net devices; split their locks off into a - * separate class since they always nest. - */ -static struct lock_class_key nr_netdev_xmit_lock_key; -static struct lock_class_key nr_netdev_addr_lock_key; - -static void nr_set_lockdep_one(struct net_device *dev, - struct netdev_queue *txq, - void *_unused) -{ - lockdep_set_class(&txq->_xmit_lock, &nr_netdev_xmit_lock_key); -} - -static void nr_set_lockdep_key(struct net_device *dev) -{ - lockdep_set_class(&dev->addr_list_lock, &nr_netdev_addr_lock_key); - netdev_for_each_tx_queue(dev, nr_set_lockdep_one, NULL); -} - /* * Socket removal during an interrupt is now safe. */ @@ -1414,7 +1392,6 @@ static int __init nr_proto_init(void) free_netdev(dev); goto fail; } - nr_set_lockdep_key(dev); dev_nr[i] = dev; } diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index f0e9ccf472a9..6a0df7c8a939 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -64,28 +64,6 @@ static const struct proto_ops rose_proto_ops; ax25_address rose_callsign; -/* - * ROSE network devices are virtual network devices encapsulating ROSE - * frames into AX.25 which will be sent through an AX.25 device, so form a - * special "super class" of normal net devices; split their locks off into a - * separate class since they always nest. - */ -static struct lock_class_key rose_netdev_xmit_lock_key; -static struct lock_class_key rose_netdev_addr_lock_key; - -static void rose_set_lockdep_one(struct net_device *dev, - struct netdev_queue *txq, - void *_unused) -{ - lockdep_set_class(&txq->_xmit_lock, &rose_netdev_xmit_lock_key); -} - -static void rose_set_lockdep_key(struct net_device *dev) -{ - lockdep_set_class(&dev->addr_list_lock, &rose_netdev_addr_lock_key); - netdev_for_each_tx_queue(dev, rose_set_lockdep_one, NULL); -} - /* * Convert a ROSE address into text. */ @@ -1533,7 +1511,6 @@ static int __init rose_proto_init(void) free_netdev(dev); goto fail; } - rose_set_lockdep_key(dev); dev_rose[i] = dev; } diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 17bd8f539bc7..b2d34c49cbe6 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -799,9 +799,6 @@ struct Qdisc_ops pfifo_fast_ops __read_mostly = { }; EXPORT_SYMBOL(pfifo_fast_ops); -static struct lock_class_key qdisc_tx_busylock; -static struct lock_class_key qdisc_running_key; - struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, const struct Qdisc_ops *ops, struct netlink_ext_ack *extack) @@ -854,17 +851,9 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, } spin_lock_init(&sch->busylock); - lockdep_set_class(&sch->busylock, - dev->qdisc_tx_busylock ?: &qdisc_tx_busylock); - /* seqlock has the same scope of busylock, for NOLOCK qdisc */ spin_lock_init(&sch->seqlock); - lockdep_set_class(&sch->busylock, - dev->qdisc_tx_busylock ?: &qdisc_tx_busylock); - seqcount_init(&sch->running); - lockdep_set_class(&sch->running, - dev->qdisc_running_key ?: &qdisc_running_key); sch->ops = ops; sch->flags = ops->static_flags; @@ -875,6 +864,12 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, dev_hold(dev); refcount_set(&sch->refcnt, 1); + if (sch != &noop_qdisc) { + lockdep_set_class(&sch->busylock, &dev->qdisc_tx_busylock_key); + lockdep_set_class(&sch->seqlock, &dev->qdisc_tx_busylock_key); + lockdep_set_class(&sch->running, &dev->qdisc_running_key); + } + return sch; errout1: kfree(p); -- GitLab From 65de65d9033750d2cf1b336c9d6e9da3a8b5cc6e Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Mon, 21 Oct 2019 18:47:52 +0000 Subject: [PATCH 702/993] bonding: fix unexpected IFF_BONDING bit unset The IFF_BONDING means bonding master or bonding slave device. ->ndo_add_slave() sets IFF_BONDING flag and ->ndo_del_slave() unsets IFF_BONDING flag. bond0<--bond1 Both bond0 and bond1 are bonding device and these should keep having IFF_BONDING flag until they are removed. But bond1 would lose IFF_BONDING at ->ndo_del_slave() because that routine do not check whether the slave device is the bonding type or not. This patch adds the interface type check routine before removing IFF_BONDING flag. Test commands: ip link add bond0 type bond ip link add bond1 type bond ip link set bond1 master bond0 ip link set bond1 nomaster ip link del bond1 type bond ip link add bond1 type bond Splat looks like: [ 226.665555] proc_dir_entry 'bonding/bond1' already registered [ 226.666440] WARNING: CPU: 0 PID: 737 at fs/proc/generic.c:361 proc_register+0x2a9/0x3e0 [ 226.667571] Modules linked in: bonding af_packet sch_fq_codel ip_tables x_tables unix [ 226.668662] CPU: 0 PID: 737 Comm: ip Not tainted 5.4.0-rc3+ #96 [ 226.669508] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 226.670652] RIP: 0010:proc_register+0x2a9/0x3e0 [ 226.671612] Code: 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 39 01 00 00 48 8b 04 24 48 89 ea 48 c7 c7 a0 0b 14 9f 48 8b b0 e 0 00 00 00 e8 07 e7 88 ff <0f> 0b 48 c7 c7 40 2d a5 9f e8 59 d6 23 01 48 8b 4c 24 10 48 b8 00 [ 226.675007] RSP: 0018:ffff888050e17078 EFLAGS: 00010282 [ 226.675761] RAX: dffffc0000000008 RBX: ffff88805fdd0f10 RCX: ffffffff9dd344e2 [ 226.676757] RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffff88806c9f6b8c [ 226.677751] RBP: ffff8880507160f3 R08: ffffed100d940019 R09: ffffed100d940019 [ 226.678761] R10: 0000000000000001 R11: ffffed100d940018 R12: ffff888050716008 [ 226.679757] R13: ffff8880507160f2 R14: dffffc0000000000 R15: ffffed100a0e2c1e [ 226.680758] FS: 00007fdc217cc0c0(0000) GS:ffff88806c800000(0000) knlGS:0000000000000000 [ 226.681886] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 226.682719] CR2: 00007f49313424d0 CR3: 0000000050e46001 CR4: 00000000000606f0 [ 226.683727] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 226.684725] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 226.685681] Call Trace: [ 226.687089] proc_create_seq_private+0xb3/0xf0 [ 226.687778] bond_create_proc_entry+0x1b3/0x3f0 [bonding] [ 226.691458] bond_netdev_event+0x433/0x970 [bonding] [ 226.692139] ? __module_text_address+0x13/0x140 [ 226.692779] notifier_call_chain+0x90/0x160 [ 226.693401] register_netdevice+0x9b3/0xd80 [ 226.694010] ? alloc_netdev_mqs+0x854/0xc10 [ 226.694629] ? netdev_change_features+0xa0/0xa0 [ 226.695278] ? rtnl_create_link+0x2ed/0xad0 [ 226.695849] bond_newlink+0x2a/0x60 [bonding] [ 226.696422] __rtnl_newlink+0xb9f/0x11b0 [ 226.696968] ? rtnl_link_unregister+0x220/0x220 [ ... ] Fixes: 0b680e753724 ("[PATCH] bonding: Add priv_flag to avoid event mishandling") Signed-off-by: Taehee Yoo Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index ac1b09b56c77..92713b93f66f 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1816,7 +1816,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, slave_disable_netpoll(new_slave); err_close: - slave_dev->priv_flags &= ~IFF_BONDING; + if (!netif_is_bond_master(slave_dev)) + slave_dev->priv_flags &= ~IFF_BONDING; dev_close(slave_dev); err_restore_mac: @@ -2017,7 +2018,8 @@ static int __bond_release_one(struct net_device *bond_dev, else dev_set_mtu(slave_dev, slave->original_mtu); - slave_dev->priv_flags &= ~IFF_BONDING; + if (!netif_is_bond_master(slave_dev)) + slave_dev->priv_flags &= ~IFF_BONDING; bond_free_slave(slave); -- GitLab From 089bca2caed0d0dea7da235ce1fe245808f5ec02 Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Mon, 21 Oct 2019 18:47:53 +0000 Subject: [PATCH 703/993] bonding: use dynamic lockdep key instead of subclass All bonding device has same lockdep key and subclass is initialized with nest_level. But actual nest_level value can be changed when a lower device is attached. And at this moment, the subclass should be updated but it seems to be unsafe. So this patch makes bonding use dynamic lockdep key instead of the subclass. Test commands: ip link add bond0 type bond for i in {1..5} do let A=$i-1 ip link add bond$i type bond ip link set bond$i master bond$A done ip link set bond5 master bond0 Splat looks like: [ 307.992912] WARNING: possible recursive locking detected [ 307.993656] 5.4.0-rc3+ #96 Tainted: G W [ 307.994367] -------------------------------------------- [ 307.995092] ip/761 is trying to acquire lock: [ 307.995710] ffff8880513aac60 (&(&bond->stats_lock)->rlock#2/2){+.+.}, at: bond_get_stats+0xb8/0x500 [bonding] [ 307.997045] but task is already holding lock: [ 307.997923] ffff88805fcbac60 (&(&bond->stats_lock)->rlock#2/2){+.+.}, at: bond_get_stats+0xb8/0x500 [bonding] [ 307.999215] other info that might help us debug this: [ 308.000251] Possible unsafe locking scenario: [ 308.001137] CPU0 [ 308.001533] ---- [ 308.001915] lock(&(&bond->stats_lock)->rlock#2/2); [ 308.002609] lock(&(&bond->stats_lock)->rlock#2/2); [ 308.003302] *** DEADLOCK *** [ 308.004310] May be due to missing lock nesting notation [ 308.005319] 3 locks held by ip/761: [ 308.005830] #0: ffffffff9fcc42b0 (rtnl_mutex){+.+.}, at: rtnetlink_rcv_msg+0x466/0x8a0 [ 308.006894] #1: ffff88805fcbac60 (&(&bond->stats_lock)->rlock#2/2){+.+.}, at: bond_get_stats+0xb8/0x500 [bonding] [ 308.008243] #2: ffffffff9f9219c0 (rcu_read_lock){....}, at: bond_get_stats+0x9f/0x500 [bonding] [ 308.009422] stack backtrace: [ 308.010124] CPU: 0 PID: 761 Comm: ip Tainted: G W 5.4.0-rc3+ #96 [ 308.011097] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 308.012179] Call Trace: [ 308.012601] dump_stack+0x7c/0xbb [ 308.013089] __lock_acquire+0x269d/0x3de0 [ 308.013669] ? register_lock_class+0x14d0/0x14d0 [ 308.014318] lock_acquire+0x164/0x3b0 [ 308.014858] ? bond_get_stats+0xb8/0x500 [bonding] [ 308.015520] _raw_spin_lock_nested+0x2e/0x60 [ 308.016129] ? bond_get_stats+0xb8/0x500 [bonding] [ 308.017215] bond_get_stats+0xb8/0x500 [bonding] [ 308.018454] ? bond_arp_rcv+0xf10/0xf10 [bonding] [ 308.019710] ? rcu_read_lock_held+0x90/0xa0 [ 308.020605] ? rcu_read_lock_sched_held+0xc0/0xc0 [ 308.021286] ? bond_get_stats+0x9f/0x500 [bonding] [ 308.021953] dev_get_stats+0x1ec/0x270 [ 308.022508] bond_get_stats+0x1d1/0x500 [bonding] Fixes: d3fff6c443fe ("net: add netdev_lockdep_set_classes() helper") Signed-off-by: Taehee Yoo Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 10 +++++++--- include/net/bonding.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 92713b93f66f..6a6273590288 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3459,7 +3459,7 @@ static void bond_get_stats(struct net_device *bond_dev, struct list_head *iter; struct slave *slave; - spin_lock_nested(&bond->stats_lock, bond_get_nest_level(bond_dev)); + spin_lock(&bond->stats_lock); memcpy(stats, &bond->bond_stats, sizeof(*stats)); rcu_read_lock(); @@ -4297,8 +4297,6 @@ void bond_setup(struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); - spin_lock_init(&bond->mode_lock); - spin_lock_init(&bond->stats_lock); bond->params = bonding_defaults; /* Initialize pointers */ @@ -4367,6 +4365,7 @@ static void bond_uninit(struct net_device *bond_dev) list_del(&bond->bond_list); + lockdep_unregister_key(&bond->stats_lock_key); bond_debug_unregister(bond); } @@ -4772,6 +4771,11 @@ static int bond_init(struct net_device *bond_dev) bond->nest_level = SINGLE_DEPTH_NESTING; + spin_lock_init(&bond->mode_lock); + spin_lock_init(&bond->stats_lock); + lockdep_register_key(&bond->stats_lock_key); + lockdep_set_class(&bond->stats_lock, &bond->stats_lock_key); + list_add_tail(&bond->bond_list, &bn->dev_list); bond_prepare_sysfs_group(bond); diff --git a/include/net/bonding.h b/include/net/bonding.h index f7fe45689142..334909feb2bb 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -239,6 +239,7 @@ struct bonding { struct dentry *debug_dir; #endif /* CONFIG_DEBUG_FS */ struct rtnl_link_stats64 bond_stats; + struct lock_class_key stats_lock_key; }; #define bond_slave_get_rcu(dev) \ -- GitLab From 369f61bee0f584aee09f0736431eb9b330c98571 Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Mon, 21 Oct 2019 18:47:54 +0000 Subject: [PATCH 704/993] team: fix nested locking lockdep warning team interface could be nested and it's lock variable could be nested too. But this lock uses static lockdep key and there is no nested locking handling code such as mutex_lock_nested() and so on. so the Lockdep would warn about the circular locking scenario that couldn't happen. In order to fix, this patch makes the team module to use dynamic lock key instead of static key. Test commands: ip link add team0 type team ip link add team1 type team ip link set team0 master team1 ip link set team0 nomaster ip link set team1 master team0 ip link set team1 nomaster Splat that looks like: [ 40.364352] WARNING: possible recursive locking detected [ 40.364964] 5.4.0-rc3+ #96 Not tainted [ 40.365405] -------------------------------------------- [ 40.365973] ip/750 is trying to acquire lock: [ 40.366542] ffff888060b34c40 (&team->lock){+.+.}, at: team_set_mac_address+0x151/0x290 [team] [ 40.367689] but task is already holding lock: [ 40.368729] ffff888051201c40 (&team->lock){+.+.}, at: team_del_slave+0x29/0x60 [team] [ 40.370280] other info that might help us debug this: [ 40.371159] Possible unsafe locking scenario: [ 40.371942] CPU0 [ 40.372338] ---- [ 40.372673] lock(&team->lock); [ 40.373115] lock(&team->lock); [ 40.373549] *** DEADLOCK *** [ 40.374432] May be due to missing lock nesting notation [ 40.375338] 2 locks held by ip/750: [ 40.375851] #0: ffffffffabcc42b0 (rtnl_mutex){+.+.}, at: rtnetlink_rcv_msg+0x466/0x8a0 [ 40.376927] #1: ffff888051201c40 (&team->lock){+.+.}, at: team_del_slave+0x29/0x60 [team] [ 40.377989] stack backtrace: [ 40.378650] CPU: 0 PID: 750 Comm: ip Not tainted 5.4.0-rc3+ #96 [ 40.379368] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 40.380574] Call Trace: [ 40.381208] dump_stack+0x7c/0xbb [ 40.381959] __lock_acquire+0x269d/0x3de0 [ 40.382817] ? register_lock_class+0x14d0/0x14d0 [ 40.383784] ? check_chain_key+0x236/0x5d0 [ 40.384518] lock_acquire+0x164/0x3b0 [ 40.385074] ? team_set_mac_address+0x151/0x290 [team] [ 40.385805] __mutex_lock+0x14d/0x14c0 [ 40.386371] ? team_set_mac_address+0x151/0x290 [team] [ 40.387038] ? team_set_mac_address+0x151/0x290 [team] [ 40.387632] ? mutex_lock_io_nested+0x1380/0x1380 [ 40.388245] ? team_del_slave+0x60/0x60 [team] [ 40.388752] ? rcu_read_lock_sched_held+0x90/0xc0 [ 40.389304] ? rcu_read_lock_bh_held+0xa0/0xa0 [ 40.389819] ? lock_acquire+0x164/0x3b0 [ 40.390285] ? lockdep_rtnl_is_held+0x16/0x20 [ 40.390797] ? team_port_get_rtnl+0x90/0xe0 [team] [ 40.391353] ? __module_text_address+0x13/0x140 [ 40.391886] ? team_set_mac_address+0x151/0x290 [team] [ 40.392547] team_set_mac_address+0x151/0x290 [team] [ 40.393111] dev_set_mac_address+0x1f0/0x3f0 [ ... ] Fixes: 3d249d4ca7d0 ("net: introduce ethernet teaming device") Signed-off-by: Taehee Yoo Signed-off-by: David S. Miller --- drivers/net/team/team.c | 16 +++++++++++++--- include/linux/if_team.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 6cea83b48cad..8156b33ee3e7 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1615,7 +1615,6 @@ static int team_init(struct net_device *dev) int err; team->dev = dev; - mutex_init(&team->lock); team_set_no_mode(team); team->pcpu_stats = netdev_alloc_pcpu_stats(struct team_pcpu_stats); @@ -1642,6 +1641,9 @@ static int team_init(struct net_device *dev) goto err_options_register; netif_carrier_off(dev); + lockdep_register_key(&team->team_lock_key); + __mutex_init(&team->lock, "team->team_lock_key", &team->team_lock_key); + return 0; err_options_register: @@ -1671,6 +1673,7 @@ static void team_uninit(struct net_device *dev) team_queue_override_fini(team); mutex_unlock(&team->lock); netdev_change_features(dev); + lockdep_unregister_key(&team->team_lock_key); } static void team_destructor(struct net_device *dev) @@ -1974,8 +1977,15 @@ static int team_del_slave(struct net_device *dev, struct net_device *port_dev) err = team_port_del(team, port_dev); mutex_unlock(&team->lock); - if (!err) - netdev_change_features(dev); + if (err) + return err; + + if (netif_is_team_master(port_dev)) { + lockdep_unregister_key(&team->team_lock_key); + lockdep_register_key(&team->team_lock_key); + lockdep_set_class(&team->lock, &team->team_lock_key); + } + netdev_change_features(dev); return err; } diff --git a/include/linux/if_team.h b/include/linux/if_team.h index 06faa066496f..ec7e4bd07f82 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h @@ -223,6 +223,7 @@ struct team { atomic_t count_pending; struct delayed_work dw; } mcast_rejoin; + struct lock_class_key team_lock_key; long mode_priv[TEAM_MODE_PRIV_LONGS]; }; -- GitLab From 2bce1ebed17da54c65042ec2b962e3234bad5b47 Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Mon, 21 Oct 2019 18:47:55 +0000 Subject: [PATCH 705/993] macsec: fix refcnt leak in module exit routine When a macsec interface is created, it increases a refcnt to a lower device(real device). when macsec interface is deleted, the refcnt is decreased in macsec_free_netdev(), which is ->priv_destructor() of macsec interface. The problem scenario is this. When nested macsec interfaces are exiting, the exit routine of the macsec module makes refcnt leaks. Test commands: ip link add dummy0 type dummy ip link add macsec0 link dummy0 type macsec ip link add macsec1 link macsec0 type macsec modprobe -rv macsec [ 208.629433] unregister_netdevice: waiting for macsec0 to become free. Usage count = 1 Steps of exit routine of macsec module are below. 1. Calls ->dellink() in __rtnl_link_unregister(). 2. Checks refcnt and wait refcnt to be 0 if refcnt is not 0 in netdev_run_todo(). 3. Calls ->priv_destruvtor() in netdev_run_todo(). Step2 checks refcnt, but step3 decreases refcnt. So, step2 waits forever. This patch makes the macsec module do not hold a refcnt of the lower device because it already holds a refcnt of the lower device with netdev_upper_dev_link(). Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") Signed-off-by: Taehee Yoo Signed-off-by: David S. Miller --- drivers/net/macsec.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index e2a3d1d5795f..9e97b66b26d3 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -3000,12 +3000,10 @@ static const struct nla_policy macsec_rtnl_policy[IFLA_MACSEC_MAX + 1] = { static void macsec_free_netdev(struct net_device *dev) { struct macsec_dev *macsec = macsec_priv(dev); - struct net_device *real_dev = macsec->real_dev; free_percpu(macsec->stats); free_percpu(macsec->secy.tx_sc.stats); - dev_put(real_dev); } static void macsec_setup(struct net_device *dev) @@ -3260,8 +3258,6 @@ static int macsec_newlink(struct net *net, struct net_device *dev, if (err < 0) return err; - dev_hold(real_dev); - macsec->nest_level = dev_get_nest_level(real_dev) + 1; err = netdev_upper_dev_link(real_dev, dev, extack); -- GitLab From 32b6d34fedc2229cdf6a047fdbc0704085441915 Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Mon, 21 Oct 2019 18:47:56 +0000 Subject: [PATCH 706/993] net: core: add ignore flag to netdev_adjacent structure In order to link an adjacent node, netdev_upper_dev_link() is used and in order to unlink an adjacent node, netdev_upper_dev_unlink() is used. unlink operation does not fail, but link operation can fail. In order to exchange adjacent nodes, we should unlink an old adjacent node first. then, link a new adjacent node. If link operation is failed, we should link an old adjacent node again. But this link operation can fail too. It eventually breaks the adjacent link relationship. This patch adds an ignore flag into the netdev_adjacent structure. If this flag is set, netdev_upper_dev_link() ignores an old adjacent node for a moment. This patch also adds new functions for other modules. netdev_adjacent_change_prepare() netdev_adjacent_change_commit() netdev_adjacent_change_abort() netdev_adjacent_change_prepare() inserts new device into adjacent list but new device is not allowed to use immediately. If netdev_adjacent_change_prepare() fails, it internally rollbacks adjacent list so that we don't need any other action. netdev_adjacent_change_commit() deletes old device in the adjacent list and allows new device to use. netdev_adjacent_change_abort() rollbacks adjacent list. Signed-off-by: Taehee Yoo Signed-off-by: David S. Miller --- include/linux/netdevice.h | 10 ++ net/core/dev.c | 230 ++++++++++++++++++++++++++++++++++---- 2 files changed, 219 insertions(+), 21 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c93df7cf187b..6c6490e15cd4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -4324,6 +4324,16 @@ int netdev_master_upper_dev_link(struct net_device *dev, struct netlink_ext_ack *extack); void netdev_upper_dev_unlink(struct net_device *dev, struct net_device *upper_dev); +int netdev_adjacent_change_prepare(struct net_device *old_dev, + struct net_device *new_dev, + struct net_device *dev, + struct netlink_ext_ack *extack); +void netdev_adjacent_change_commit(struct net_device *old_dev, + struct net_device *new_dev, + struct net_device *dev); +void netdev_adjacent_change_abort(struct net_device *old_dev, + struct net_device *new_dev, + struct net_device *dev); void netdev_adjacent_rename_links(struct net_device *dev, char *oldname); void *netdev_lower_dev_get_private(struct net_device *dev, struct net_device *lower_dev); diff --git a/net/core/dev.c b/net/core/dev.c index 5722a81b6edd..092c094038b6 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6408,6 +6408,9 @@ struct netdev_adjacent { /* upper master flag, there can only be one master device per list */ bool master; + /* lookup ignore flag */ + bool ignore; + /* counter for the number of times this device was added to us */ u16 ref_nr; @@ -6430,7 +6433,7 @@ static struct netdev_adjacent *__netdev_find_adj(struct net_device *adj_dev, return NULL; } -static int __netdev_has_upper_dev(struct net_device *upper_dev, void *data) +static int ____netdev_has_upper_dev(struct net_device *upper_dev, void *data) { struct net_device *dev = data; @@ -6451,7 +6454,7 @@ bool netdev_has_upper_dev(struct net_device *dev, { ASSERT_RTNL(); - return netdev_walk_all_upper_dev_rcu(dev, __netdev_has_upper_dev, + return netdev_walk_all_upper_dev_rcu(dev, ____netdev_has_upper_dev, upper_dev); } EXPORT_SYMBOL(netdev_has_upper_dev); @@ -6469,7 +6472,7 @@ EXPORT_SYMBOL(netdev_has_upper_dev); bool netdev_has_upper_dev_all_rcu(struct net_device *dev, struct net_device *upper_dev) { - return !!netdev_walk_all_upper_dev_rcu(dev, __netdev_has_upper_dev, + return !!netdev_walk_all_upper_dev_rcu(dev, ____netdev_has_upper_dev, upper_dev); } EXPORT_SYMBOL(netdev_has_upper_dev_all_rcu); @@ -6513,6 +6516,22 @@ struct net_device *netdev_master_upper_dev_get(struct net_device *dev) } EXPORT_SYMBOL(netdev_master_upper_dev_get); +static struct net_device *__netdev_master_upper_dev_get(struct net_device *dev) +{ + struct netdev_adjacent *upper; + + ASSERT_RTNL(); + + if (list_empty(&dev->adj_list.upper)) + return NULL; + + upper = list_first_entry(&dev->adj_list.upper, + struct netdev_adjacent, list); + if (likely(upper->master) && !upper->ignore) + return upper->dev; + return NULL; +} + /** * netdev_has_any_lower_dev - Check if device is linked to some device * @dev: device @@ -6563,8 +6582,9 @@ struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev, } EXPORT_SYMBOL(netdev_upper_get_next_dev_rcu); -static struct net_device *netdev_next_upper_dev(struct net_device *dev, - struct list_head **iter) +static struct net_device *__netdev_next_upper_dev(struct net_device *dev, + struct list_head **iter, + bool *ignore) { struct netdev_adjacent *upper; @@ -6574,6 +6594,7 @@ static struct net_device *netdev_next_upper_dev(struct net_device *dev, return NULL; *iter = &upper->list; + *ignore = upper->ignore; return upper->dev; } @@ -6595,14 +6616,15 @@ static struct net_device *netdev_next_upper_dev_rcu(struct net_device *dev, return upper->dev; } -static int netdev_walk_all_upper_dev(struct net_device *dev, - int (*fn)(struct net_device *dev, - void *data), - void *data) +static int __netdev_walk_all_upper_dev(struct net_device *dev, + int (*fn)(struct net_device *dev, + void *data), + void *data) { struct net_device *udev, *next, *now, *dev_stack[MAX_NEST_DEV + 1]; struct list_head *niter, *iter, *iter_stack[MAX_NEST_DEV + 1]; int ret, cur = 0; + bool ignore; now = dev; iter = &dev->adj_list.upper; @@ -6616,9 +6638,11 @@ static int netdev_walk_all_upper_dev(struct net_device *dev, next = NULL; while (1) { - udev = netdev_next_upper_dev(now, &iter); + udev = __netdev_next_upper_dev(now, &iter, &ignore); if (!udev) break; + if (ignore) + continue; next = udev; niter = &udev->adj_list.upper; @@ -6688,6 +6712,15 @@ int netdev_walk_all_upper_dev_rcu(struct net_device *dev, } EXPORT_SYMBOL_GPL(netdev_walk_all_upper_dev_rcu); +static bool __netdev_has_upper_dev(struct net_device *dev, + struct net_device *upper_dev) +{ + ASSERT_RTNL(); + + return __netdev_walk_all_upper_dev(dev, ____netdev_has_upper_dev, + upper_dev); +} + /** * netdev_lower_get_next_private - Get the next ->private from the * lower neighbour list @@ -6784,6 +6817,23 @@ static struct net_device *netdev_next_lower_dev(struct net_device *dev, return lower->dev; } +static struct net_device *__netdev_next_lower_dev(struct net_device *dev, + struct list_head **iter, + bool *ignore) +{ + struct netdev_adjacent *lower; + + lower = list_entry((*iter)->next, struct netdev_adjacent, list); + + if (&lower->list == &dev->adj_list.lower) + return NULL; + + *iter = &lower->list; + *ignore = lower->ignore; + + return lower->dev; +} + int netdev_walk_all_lower_dev(struct net_device *dev, int (*fn)(struct net_device *dev, void *data), @@ -6831,6 +6881,55 @@ int netdev_walk_all_lower_dev(struct net_device *dev, } EXPORT_SYMBOL_GPL(netdev_walk_all_lower_dev); +static int __netdev_walk_all_lower_dev(struct net_device *dev, + int (*fn)(struct net_device *dev, + void *data), + void *data) +{ + struct net_device *ldev, *next, *now, *dev_stack[MAX_NEST_DEV + 1]; + struct list_head *niter, *iter, *iter_stack[MAX_NEST_DEV + 1]; + int ret, cur = 0; + bool ignore; + + now = dev; + iter = &dev->adj_list.lower; + + while (1) { + if (now != dev) { + ret = fn(now, data); + if (ret) + return ret; + } + + next = NULL; + while (1) { + ldev = __netdev_next_lower_dev(now, &iter, &ignore); + if (!ldev) + break; + if (ignore) + continue; + + next = ldev; + niter = &ldev->adj_list.lower; + dev_stack[cur] = now; + iter_stack[cur++] = iter; + break; + } + + if (!next) { + if (!cur) + return 0; + next = dev_stack[--cur]; + niter = iter_stack[cur]; + } + + now = next; + iter = niter; + } + + return 0; +} + static struct net_device *netdev_next_lower_dev_rcu(struct net_device *dev, struct list_head **iter) { @@ -6850,11 +6949,14 @@ static u8 __netdev_upper_depth(struct net_device *dev) struct net_device *udev; struct list_head *iter; u8 max_depth = 0; + bool ignore; for (iter = &dev->adj_list.upper, - udev = netdev_next_upper_dev(dev, &iter); + udev = __netdev_next_upper_dev(dev, &iter, &ignore); udev; - udev = netdev_next_upper_dev(dev, &iter)) { + udev = __netdev_next_upper_dev(dev, &iter, &ignore)) { + if (ignore) + continue; if (max_depth < udev->upper_level) max_depth = udev->upper_level; } @@ -6867,11 +6969,14 @@ static u8 __netdev_lower_depth(struct net_device *dev) struct net_device *ldev; struct list_head *iter; u8 max_depth = 0; + bool ignore; for (iter = &dev->adj_list.lower, - ldev = netdev_next_lower_dev(dev, &iter); + ldev = __netdev_next_lower_dev(dev, &iter, &ignore); ldev; - ldev = netdev_next_lower_dev(dev, &iter)) { + ldev = __netdev_next_lower_dev(dev, &iter, &ignore)) { + if (ignore) + continue; if (max_depth < ldev->lower_level) max_depth = ldev->lower_level; } @@ -7035,6 +7140,7 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev, adj->master = master; adj->ref_nr = 1; adj->private = private; + adj->ignore = false; dev_hold(adj_dev); pr_debug("Insert adjacency: dev %s adj_dev %s adj->ref_nr %d; dev_hold on %s\n", @@ -7185,17 +7291,17 @@ static int __netdev_upper_dev_link(struct net_device *dev, return -EBUSY; /* To prevent loops, check if dev is not upper device to upper_dev. */ - if (netdev_has_upper_dev(upper_dev, dev)) + if (__netdev_has_upper_dev(upper_dev, dev)) return -EBUSY; if ((dev->lower_level + upper_dev->upper_level) > MAX_NEST_DEV) return -EMLINK; if (!master) { - if (netdev_has_upper_dev(dev, upper_dev)) + if (__netdev_has_upper_dev(dev, upper_dev)) return -EEXIST; } else { - master_dev = netdev_master_upper_dev_get(dev); + master_dev = __netdev_master_upper_dev_get(dev); if (master_dev) return master_dev == upper_dev ? -EEXIST : -EBUSY; } @@ -7218,10 +7324,11 @@ static int __netdev_upper_dev_link(struct net_device *dev, goto rollback; __netdev_update_upper_level(dev, NULL); - netdev_walk_all_lower_dev(dev, __netdev_update_upper_level, NULL); + __netdev_walk_all_lower_dev(dev, __netdev_update_upper_level, NULL); __netdev_update_lower_level(upper_dev, NULL); - netdev_walk_all_upper_dev(upper_dev, __netdev_update_lower_level, NULL); + __netdev_walk_all_upper_dev(upper_dev, __netdev_update_lower_level, + NULL); return 0; @@ -7307,13 +7414,94 @@ void netdev_upper_dev_unlink(struct net_device *dev, &changeupper_info.info); __netdev_update_upper_level(dev, NULL); - netdev_walk_all_lower_dev(dev, __netdev_update_upper_level, NULL); + __netdev_walk_all_lower_dev(dev, __netdev_update_upper_level, NULL); __netdev_update_lower_level(upper_dev, NULL); - netdev_walk_all_upper_dev(upper_dev, __netdev_update_lower_level, NULL); + __netdev_walk_all_upper_dev(upper_dev, __netdev_update_lower_level, + NULL); } EXPORT_SYMBOL(netdev_upper_dev_unlink); +static void __netdev_adjacent_dev_set(struct net_device *upper_dev, + struct net_device *lower_dev, + bool val) +{ + struct netdev_adjacent *adj; + + adj = __netdev_find_adj(lower_dev, &upper_dev->adj_list.lower); + if (adj) + adj->ignore = val; + + adj = __netdev_find_adj(upper_dev, &lower_dev->adj_list.upper); + if (adj) + adj->ignore = val; +} + +static void netdev_adjacent_dev_disable(struct net_device *upper_dev, + struct net_device *lower_dev) +{ + __netdev_adjacent_dev_set(upper_dev, lower_dev, true); +} + +static void netdev_adjacent_dev_enable(struct net_device *upper_dev, + struct net_device *lower_dev) +{ + __netdev_adjacent_dev_set(upper_dev, lower_dev, false); +} + +int netdev_adjacent_change_prepare(struct net_device *old_dev, + struct net_device *new_dev, + struct net_device *dev, + struct netlink_ext_ack *extack) +{ + int err; + + if (!new_dev) + return 0; + + if (old_dev && new_dev != old_dev) + netdev_adjacent_dev_disable(dev, old_dev); + + err = netdev_upper_dev_link(new_dev, dev, extack); + if (err) { + if (old_dev && new_dev != old_dev) + netdev_adjacent_dev_enable(dev, old_dev); + return err; + } + + return 0; +} +EXPORT_SYMBOL(netdev_adjacent_change_prepare); + +void netdev_adjacent_change_commit(struct net_device *old_dev, + struct net_device *new_dev, + struct net_device *dev) +{ + if (!new_dev || !old_dev) + return; + + if (new_dev == old_dev) + return; + + netdev_adjacent_dev_enable(dev, old_dev); + netdev_upper_dev_unlink(old_dev, dev); +} +EXPORT_SYMBOL(netdev_adjacent_change_commit); + +void netdev_adjacent_change_abort(struct net_device *old_dev, + struct net_device *new_dev, + struct net_device *dev) +{ + if (!new_dev) + return; + + if (old_dev && new_dev != old_dev) + netdev_adjacent_dev_enable(dev, old_dev); + + netdev_upper_dev_unlink(new_dev, dev); +} +EXPORT_SYMBOL(netdev_adjacent_change_abort); + /** * netdev_bonding_info_change - Dispatch event about slave change * @dev: device -- GitLab From 0ce1822c2a08f6e05e22239bcb1778dcc916c7bc Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Mon, 21 Oct 2019 18:47:57 +0000 Subject: [PATCH 707/993] vxlan: add adjacent link to limit depth level Current vxlan code doesn't limit the number of nested devices. Nested devices would be handled recursively and this routine needs huge stack memory. So, unlimited nested devices could make stack overflow. In order to fix this issue, this patch adds adjacent links. The adjacent link APIs internally check the depth level. Test commands: ip link add dummy0 type dummy ip link add vxlan0 type vxlan id 0 group 239.1.1.1 dev dummy0 \ dstport 4789 for i in {1..100} do let A=$i-1 ip link add vxlan$i type vxlan id $i group 239.1.1.1 \ dev vxlan$A dstport 4789 done ip link del dummy0 The top upper link is vxlan100 and the lowest link is vxlan0. When vxlan0 is deleting, the upper devices will be deleted recursively. It needs huge stack memory so it makes stack overflow. Splat looks like: [ 229.628477] ============================================================================= [ 229.629785] BUG page->ptl (Not tainted): Padding overwritten. 0x0000000026abf214-0x0000000091f6abb2 [ 229.629785] ----------------------------------------------------------------------------- [ 229.629785] [ 229.655439] ================================================================== [ 229.629785] INFO: Slab 0x00000000ff7cfda8 objects=19 used=19 fp=0x00000000fe33776c flags=0x200000000010200 [ 229.655688] BUG: KASAN: stack-out-of-bounds in unmap_single_vma+0x25a/0x2e0 [ 229.655688] Read of size 8 at addr ffff888113076928 by task vlan-network-in/2334 [ 229.655688] [ 229.629785] Padding 0000000026abf214: 00 80 14 0d 81 88 ff ff 68 91 81 14 81 88 ff ff ........h....... [ 229.629785] Padding 0000000001e24790: 38 91 81 14 81 88 ff ff 68 91 81 14 81 88 ff ff 8.......h....... [ 229.629785] Padding 00000000b39397c8: 33 30 62 a7 ff ff ff ff ff eb 60 22 10 f1 ff 1f 30b.......`".... [ 229.629785] Padding 00000000bc98f53a: 80 60 07 13 81 88 ff ff 00 80 14 0d 81 88 ff ff .`.............. [ 229.629785] Padding 000000002aa8123d: 68 91 81 14 81 88 ff ff f7 21 17 a7 ff ff ff ff h........!...... [ 229.629785] Padding 000000001c8c2369: 08 81 14 0d 81 88 ff ff 03 02 00 00 00 00 00 00 ................ [ 229.629785] Padding 000000004e290c5d: 21 90 a2 21 10 ed ff ff 00 00 00 00 00 fc ff df !..!............ [ 229.629785] Padding 000000000e25d731: 18 60 07 13 81 88 ff ff c0 8b 13 05 81 88 ff ff .`.............. [ 229.629785] Padding 000000007adc7ab3: b3 8a b5 41 00 00 00 00 ...A.... [ 229.629785] FIX page->ptl: Restoring 0x0000000026abf214-0x0000000091f6abb2=0x5a [ ... ] Fixes: acaf4e70997f ("net: vxlan: when lower dev unregisters remove vxlan dev as well") Signed-off-by: Taehee Yoo Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 53 ++++++++++++++++++++++++++++++++++++--------- include/net/vxlan.h | 1 + 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 3d9bcc957f7d..fcf028220bca 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -3566,10 +3566,13 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev, { struct vxlan_net *vn = net_generic(net, vxlan_net_id); struct vxlan_dev *vxlan = netdev_priv(dev); + struct net_device *remote_dev = NULL; struct vxlan_fdb *f = NULL; bool unregister = false; + struct vxlan_rdst *dst; int err; + dst = &vxlan->default_dst; err = vxlan_dev_configure(net, dev, conf, false, extack); if (err) return err; @@ -3577,14 +3580,14 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev, dev->ethtool_ops = &vxlan_ethtool_ops; /* create an fdb entry for a valid default destination */ - if (!vxlan_addr_any(&vxlan->default_dst.remote_ip)) { + if (!vxlan_addr_any(&dst->remote_ip)) { err = vxlan_fdb_create(vxlan, all_zeros_mac, - &vxlan->default_dst.remote_ip, + &dst->remote_ip, NUD_REACHABLE | NUD_PERMANENT, vxlan->cfg.dst_port, - vxlan->default_dst.remote_vni, - vxlan->default_dst.remote_vni, - vxlan->default_dst.remote_ifindex, + dst->remote_vni, + dst->remote_vni, + dst->remote_ifindex, NTF_SELF, &f); if (err) return err; @@ -3595,26 +3598,41 @@ static int __vxlan_dev_create(struct net *net, struct net_device *dev, goto errout; unregister = true; + if (dst->remote_ifindex) { + remote_dev = __dev_get_by_index(net, dst->remote_ifindex); + if (!remote_dev) + goto errout; + + err = netdev_upper_dev_link(remote_dev, dev, extack); + if (err) + goto errout; + } + err = rtnl_configure_link(dev, NULL); if (err) - goto errout; + goto unlink; if (f) { - vxlan_fdb_insert(vxlan, all_zeros_mac, - vxlan->default_dst.remote_vni, f); + vxlan_fdb_insert(vxlan, all_zeros_mac, dst->remote_vni, f); /* notify default fdb entry */ err = vxlan_fdb_notify(vxlan, f, first_remote_rtnl(f), RTM_NEWNEIGH, true, extack); if (err) { vxlan_fdb_destroy(vxlan, f, false, false); + if (remote_dev) + netdev_upper_dev_unlink(remote_dev, dev); goto unregister; } } list_add(&vxlan->next, &vn->vxlan_list); + if (remote_dev) + dst->remote_dev = remote_dev; return 0; - +unlink: + if (remote_dev) + netdev_upper_dev_unlink(remote_dev, dev); errout: /* unregister_netdevice() destroys the default FDB entry with deletion * notification. But the addition notification was not sent yet, so @@ -3932,11 +3950,12 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], struct netlink_ext_ack *extack) { struct vxlan_dev *vxlan = netdev_priv(dev); - struct vxlan_rdst *dst = &vxlan->default_dst; struct net_device *lowerdev; struct vxlan_config conf; + struct vxlan_rdst *dst; int err; + dst = &vxlan->default_dst; err = vxlan_nl2conf(tb, data, dev, &conf, true, extack); if (err) return err; @@ -3946,6 +3965,11 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], if (err) return err; + err = netdev_adjacent_change_prepare(dst->remote_dev, lowerdev, dev, + extack); + if (err) + return err; + /* handle default dst entry */ if (!vxlan_addr_equal(&conf.remote_ip, &dst->remote_ip)) { u32 hash_index = fdb_head_index(vxlan, all_zeros_mac, conf.vni); @@ -3962,6 +3986,8 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], NTF_SELF, true, extack); if (err) { spin_unlock_bh(&vxlan->hash_lock[hash_index]); + netdev_adjacent_change_abort(dst->remote_dev, + lowerdev, dev); return err; } } @@ -3979,6 +4005,11 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], if (conf.age_interval != vxlan->cfg.age_interval) mod_timer(&vxlan->age_timer, jiffies); + netdev_adjacent_change_commit(dst->remote_dev, lowerdev, dev); + if (lowerdev && lowerdev != dst->remote_dev) + dst->remote_dev = lowerdev; + + netdev_update_lockdep_key(lowerdev); vxlan_config_apply(dev, &conf, lowerdev, vxlan->net, true); return 0; } @@ -3991,6 +4022,8 @@ static void vxlan_dellink(struct net_device *dev, struct list_head *head) list_del(&vxlan->next); unregister_netdevice_queue(dev, head); + if (vxlan->default_dst.remote_dev) + netdev_upper_dev_unlink(vxlan->default_dst.remote_dev, dev); } static size_t vxlan_get_size(const struct net_device *dev) diff --git a/include/net/vxlan.h b/include/net/vxlan.h index 335283dbe9b3..373aadcfea21 100644 --- a/include/net/vxlan.h +++ b/include/net/vxlan.h @@ -197,6 +197,7 @@ struct vxlan_rdst { u8 offloaded:1; __be32 remote_vni; u32 remote_ifindex; + struct net_device *remote_dev; struct list_head list; struct rcu_head rcu; struct dst_cache dst_cache; -- GitLab From f3b0a18bb6cb07a9abb75e21b1f08eeaefa78e81 Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Mon, 21 Oct 2019 18:47:58 +0000 Subject: [PATCH 708/993] net: remove unnecessary variables and callback This patch removes variables and callback these are related to the nested device structure. devices that can be nested have their own nest_level variable that represents the depth of nested devices. In the previous patch, new {lower/upper}_level variables are added and they replace old private nest_level variable. So, this patch removes all 'nest_level' variables. In order to avoid lockdep warning, ->ndo_get_lock_subclass() was added to get lockdep subclass value, which is actually lower nested depth value. But now, they use the dynamic lockdep key to avoid lockdep warning instead of the subclass. So, this patch removes ->ndo_get_lock_subclass() callback. Signed-off-by: Taehee Yoo Signed-off-by: David S. Miller --- drivers/net/bonding/bond_alb.c | 2 +- drivers/net/bonding/bond_main.c | 15 --------------- .../net/ethernet/mellanox/mlx5/core/en_tc.c | 2 +- drivers/net/macsec.c | 9 --------- drivers/net/macvlan.c | 7 ------- include/linux/if_macvlan.h | 1 - include/linux/if_vlan.h | 11 ----------- include/linux/netdevice.h | 12 ------------ include/net/bonding.h | 1 - net/8021q/vlan.c | 1 - net/8021q/vlan_dev.c | 6 ------ net/core/dev.c | 19 ------------------- net/core/dev_addr_lists.c | 12 ++++++------ net/smc/smc_core.c | 2 +- net/smc/smc_pnet.c | 2 +- 15 files changed, 10 insertions(+), 92 deletions(-) diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 8c79bad2a9a5..4f2e6910c623 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -952,7 +952,7 @@ static int alb_upper_dev_walk(struct net_device *upper, void *_data) struct bond_vlan_tag *tags; if (is_vlan_dev(upper) && - bond->nest_level == vlan_get_encap_level(upper) - 1) { + bond->dev->lower_level == upper->lower_level - 1) { if (upper->addr_assign_type == NET_ADDR_STOLEN) { alb_send_lp_vid(slave, mac_addr, vlan_dev_vlan_proto(upper), diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6a6273590288..a48950b81434 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1733,8 +1733,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, goto err_upper_unlink; } - bond->nest_level = dev_get_nest_level(bond_dev) + 1; - /* If the mode uses primary, then the following is handled by * bond_change_active_slave(). */ @@ -1957,9 +1955,6 @@ static int __bond_release_one(struct net_device *bond_dev, if (!bond_has_slaves(bond)) { bond_set_carrier(bond); eth_hw_addr_random(bond_dev); - bond->nest_level = SINGLE_DEPTH_NESTING; - } else { - bond->nest_level = dev_get_nest_level(bond_dev) + 1; } unblock_netpoll_tx(); @@ -3444,13 +3439,6 @@ static void bond_fold_stats(struct rtnl_link_stats64 *_res, } } -static int bond_get_nest_level(struct net_device *bond_dev) -{ - struct bonding *bond = netdev_priv(bond_dev); - - return bond->nest_level; -} - static void bond_get_stats(struct net_device *bond_dev, struct rtnl_link_stats64 *stats) { @@ -4270,7 +4258,6 @@ static const struct net_device_ops bond_netdev_ops = { .ndo_neigh_setup = bond_neigh_setup, .ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid, - .ndo_get_lock_subclass = bond_get_nest_level, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_netpoll_setup = bond_netpoll_setup, .ndo_netpoll_cleanup = bond_netpoll_cleanup, @@ -4769,8 +4756,6 @@ static int bond_init(struct net_device *bond_dev) if (!bond->wq) return -ENOMEM; - bond->nest_level = SINGLE_DEPTH_NESTING; - spin_lock_init(&bond->mode_lock); spin_lock_init(&bond->stats_lock); lockdep_register_key(&bond->stats_lock_key); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 3e78a727f3e6..c4c59d2e676e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -3160,7 +3160,7 @@ static int add_vlan_pop_action(struct mlx5e_priv *priv, struct mlx5_esw_flow_attr *attr, u32 *action) { - int nest_level = vlan_get_encap_level(attr->parse_attr->filter_dev); + int nest_level = attr->parse_attr->filter_dev->lower_level; struct flow_action_entry vlan_act = { .id = FLOW_ACTION_VLAN_POP, }; diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 9e97b66b26d3..afd8b2a08245 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -267,7 +267,6 @@ struct macsec_dev { struct pcpu_secy_stats __percpu *stats; struct list_head secys; struct gro_cells gro_cells; - unsigned int nest_level; }; /** @@ -2957,11 +2956,6 @@ static int macsec_get_iflink(const struct net_device *dev) return macsec_priv(dev)->real_dev->ifindex; } -static int macsec_get_nest_level(struct net_device *dev) -{ - return macsec_priv(dev)->nest_level; -} - static const struct net_device_ops macsec_netdev_ops = { .ndo_init = macsec_dev_init, .ndo_uninit = macsec_dev_uninit, @@ -2975,7 +2969,6 @@ static const struct net_device_ops macsec_netdev_ops = { .ndo_start_xmit = macsec_start_xmit, .ndo_get_stats64 = macsec_get_stats64, .ndo_get_iflink = macsec_get_iflink, - .ndo_get_lock_subclass = macsec_get_nest_level, }; static const struct device_type macsec_type = { @@ -3258,8 +3251,6 @@ static int macsec_newlink(struct net *net, struct net_device *dev, if (err < 0) return err; - macsec->nest_level = dev_get_nest_level(real_dev) + 1; - err = netdev_upper_dev_link(real_dev, dev, extack); if (err < 0) goto unregister; diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 0354e9be2ca5..34fc59bd1e20 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -867,11 +867,6 @@ static int macvlan_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) #define MACVLAN_STATE_MASK \ ((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT)) -static int macvlan_get_nest_level(struct net_device *dev) -{ - return ((struct macvlan_dev *)netdev_priv(dev))->nest_level; -} - static int macvlan_init(struct net_device *dev) { struct macvlan_dev *vlan = netdev_priv(dev); @@ -1149,7 +1144,6 @@ static const struct net_device_ops macvlan_netdev_ops = { .ndo_fdb_add = macvlan_fdb_add, .ndo_fdb_del = macvlan_fdb_del, .ndo_fdb_dump = ndo_dflt_fdb_dump, - .ndo_get_lock_subclass = macvlan_get_nest_level, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = macvlan_dev_poll_controller, .ndo_netpoll_setup = macvlan_dev_netpoll_setup, @@ -1433,7 +1427,6 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, vlan->dev = dev; vlan->port = port; vlan->set_features = MACVLAN_FEATURES; - vlan->nest_level = dev_get_nest_level(lowerdev) + 1; vlan->mode = MACVLAN_MODE_VEPA; if (data && data[IFLA_MACVLAN_MODE]) diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h index 2e55e4cdbd8a..a367ead4bf4b 100644 --- a/include/linux/if_macvlan.h +++ b/include/linux/if_macvlan.h @@ -29,7 +29,6 @@ struct macvlan_dev { netdev_features_t set_features; enum macvlan_mode mode; u16 flags; - int nest_level; unsigned int macaddr_count; #ifdef CONFIG_NET_POLL_CONTROLLER struct netpoll *netpoll; diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 244278d5c222..b05e855f1ddd 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -182,7 +182,6 @@ struct vlan_dev_priv { #ifdef CONFIG_NET_POLL_CONTROLLER struct netpoll *netpoll; #endif - unsigned int nest_level; }; static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev) @@ -221,11 +220,6 @@ extern void vlan_vids_del_by_dev(struct net_device *dev, extern bool vlan_uses_dev(const struct net_device *dev); -static inline int vlan_get_encap_level(struct net_device *dev) -{ - BUG_ON(!is_vlan_dev(dev)); - return vlan_dev_priv(dev)->nest_level; -} #else static inline struct net_device * __vlan_find_dev_deep_rcu(struct net_device *real_dev, @@ -295,11 +289,6 @@ static inline bool vlan_uses_dev(const struct net_device *dev) { return false; } -static inline int vlan_get_encap_level(struct net_device *dev) -{ - BUG(); - return 0; -} #endif /** diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 6c6490e15cd4..c20f190b4c18 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1422,7 +1422,6 @@ struct net_device_ops { void (*ndo_dfwd_del_station)(struct net_device *pdev, void *priv); - int (*ndo_get_lock_subclass)(struct net_device *dev); int (*ndo_set_tx_maxrate)(struct net_device *dev, int queue_index, u32 maxrate); @@ -4051,16 +4050,6 @@ static inline void netif_addr_lock(struct net_device *dev) spin_lock(&dev->addr_list_lock); } -static inline void netif_addr_lock_nested(struct net_device *dev) -{ - int subclass = SINGLE_DEPTH_NESTING; - - if (dev->netdev_ops->ndo_get_lock_subclass) - subclass = dev->netdev_ops->ndo_get_lock_subclass(dev); - - spin_lock_nested(&dev->addr_list_lock, subclass); -} - static inline void netif_addr_lock_bh(struct net_device *dev) { spin_lock_bh(&dev->addr_list_lock); @@ -4345,7 +4334,6 @@ void netdev_lower_state_changed(struct net_device *lower_dev, extern u8 netdev_rss_key[NETDEV_RSS_KEY_LEN] __read_mostly; void netdev_rss_key_fill(void *buffer, size_t len); -int dev_get_nest_level(struct net_device *dev); int skb_checksum_help(struct sk_buff *skb); int skb_crc32c_csum_help(struct sk_buff *skb); int skb_csum_hwoffload_help(struct sk_buff *skb, diff --git a/include/net/bonding.h b/include/net/bonding.h index 334909feb2bb..1afc125014da 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -203,7 +203,6 @@ struct bonding { struct slave __rcu *primary_slave; struct bond_up_slave __rcu *slave_arr; /* Array of usable slaves */ bool force_primary; - u32 nest_level; s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ int (*recv_probe)(const struct sk_buff *, struct bonding *, struct slave *); diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 54728d2eda18..d4bcfd8f95bf 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -172,7 +172,6 @@ int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack) if (err < 0) goto out_uninit_mvrp; - vlan->nest_level = dev_get_nest_level(real_dev) + 1; err = register_netdevice(dev); if (err < 0) goto out_uninit_mvrp; diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 6e6f26bf6e73..e5bff5cc6f97 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -489,11 +489,6 @@ static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); } -static int vlan_dev_get_lock_subclass(struct net_device *dev) -{ - return vlan_dev_priv(dev)->nest_level; -} - static const struct header_ops vlan_header_ops = { .create = vlan_dev_hard_header, .parse = eth_header_parse, @@ -785,7 +780,6 @@ static const struct net_device_ops vlan_netdev_ops = { .ndo_netpoll_cleanup = vlan_dev_netpoll_cleanup, #endif .ndo_fix_features = vlan_dev_fix_features, - .ndo_get_lock_subclass = vlan_dev_get_lock_subclass, .ndo_get_iflink = vlan_dev_get_iflink, }; diff --git a/net/core/dev.c b/net/core/dev.c index 092c094038b6..1482e2ef2d25 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -7615,25 +7615,6 @@ void *netdev_lower_dev_get_private(struct net_device *dev, EXPORT_SYMBOL(netdev_lower_dev_get_private); -int dev_get_nest_level(struct net_device *dev) -{ - struct net_device *lower = NULL; - struct list_head *iter; - int max_nest = -1; - int nest; - - ASSERT_RTNL(); - - netdev_for_each_lower_dev(dev, lower, iter) { - nest = dev_get_nest_level(lower); - if (max_nest < nest) - max_nest = nest; - } - - return max_nest + 1; -} -EXPORT_SYMBOL(dev_get_nest_level); - /** * netdev_lower_change - Dispatch event about lower device state change * @lower_dev: device diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index 6393ba930097..2f949b5a1eb9 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -637,7 +637,7 @@ int dev_uc_sync(struct net_device *to, struct net_device *from) if (to->addr_len != from->addr_len) return -EINVAL; - netif_addr_lock_nested(to); + netif_addr_lock(to); err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); if (!err) __dev_set_rx_mode(to); @@ -667,7 +667,7 @@ int dev_uc_sync_multiple(struct net_device *to, struct net_device *from) if (to->addr_len != from->addr_len) return -EINVAL; - netif_addr_lock_nested(to); + netif_addr_lock(to); err = __hw_addr_sync_multiple(&to->uc, &from->uc, to->addr_len); if (!err) __dev_set_rx_mode(to); @@ -691,7 +691,7 @@ void dev_uc_unsync(struct net_device *to, struct net_device *from) return; netif_addr_lock_bh(from); - netif_addr_lock_nested(to); + netif_addr_lock(to); __hw_addr_unsync(&to->uc, &from->uc, to->addr_len); __dev_set_rx_mode(to); netif_addr_unlock(to); @@ -858,7 +858,7 @@ int dev_mc_sync(struct net_device *to, struct net_device *from) if (to->addr_len != from->addr_len) return -EINVAL; - netif_addr_lock_nested(to); + netif_addr_lock(to); err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len); if (!err) __dev_set_rx_mode(to); @@ -888,7 +888,7 @@ int dev_mc_sync_multiple(struct net_device *to, struct net_device *from) if (to->addr_len != from->addr_len) return -EINVAL; - netif_addr_lock_nested(to); + netif_addr_lock(to); err = __hw_addr_sync_multiple(&to->mc, &from->mc, to->addr_len); if (!err) __dev_set_rx_mode(to); @@ -912,7 +912,7 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) return; netif_addr_lock_bh(from); - netif_addr_lock_nested(to); + netif_addr_lock(to); __hw_addr_unsync(&to->mc, &from->mc, to->addr_len); __dev_set_rx_mode(to); netif_addr_unlock(to); diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index 88556f0251ab..2ba97ff325a5 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -561,7 +561,7 @@ int smc_vlan_by_tcpsk(struct socket *clcsock, struct smc_init_info *ini) } rtnl_lock(); - nest_lvl = dev_get_nest_level(ndev); + nest_lvl = ndev->lower_level; for (i = 0; i < nest_lvl; i++) { struct list_head *lower = &ndev->adj_list.lower; diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c index bab2da8cf17a..2920b006f65c 100644 --- a/net/smc/smc_pnet.c +++ b/net/smc/smc_pnet.c @@ -718,7 +718,7 @@ static struct net_device *pnet_find_base_ndev(struct net_device *ndev) int i, nest_lvl; rtnl_lock(); - nest_lvl = dev_get_nest_level(ndev); + nest_lvl = ndev->lower_level; for (i = 0; i < nest_lvl; i++) { struct list_head *lower = &ndev->adj_list.lower; -- GitLab From 1962f86b42ed06ea6af9ff09390243b99d9eb83a Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Mon, 21 Oct 2019 18:47:59 +0000 Subject: [PATCH 709/993] virt_wifi: fix refcnt leak in module exit routine virt_wifi_newlink() calls netdev_upper_dev_link() and it internally holds reference count of lower interface. Current code does not release a reference count of the lower interface when the lower interface is being deleted. So, reference count leaks occur. Test commands: ip link add dummy0 type dummy ip link add vw1 link dummy0 type virt_wifi ip link del dummy0 Splat looks like: [ 133.787526][ T788] WARNING: CPU: 1 PID: 788 at net/core/dev.c:8274 rollback_registered_many+0x835/0xc80 [ 133.788355][ T788] Modules linked in: virt_wifi cfg80211 dummy team af_packet sch_fq_codel ip_tables x_tables unix [ 133.789377][ T788] CPU: 1 PID: 788 Comm: ip Not tainted 5.4.0-rc3+ #96 [ 133.790069][ T788] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 133.791167][ T788] RIP: 0010:rollback_registered_many+0x835/0xc80 [ 133.791906][ T788] Code: 00 4d 85 ff 0f 84 b5 fd ff ff ba c0 0c 00 00 48 89 de 4c 89 ff e8 9b 58 04 00 48 89 df e8 30 [ 133.794317][ T788] RSP: 0018:ffff88805ba3f338 EFLAGS: 00010202 [ 133.795080][ T788] RAX: ffff88805e57e801 RBX: ffff88805ba34000 RCX: ffffffffa9294723 [ 133.796045][ T788] RDX: 1ffff1100b746816 RSI: 0000000000000008 RDI: ffffffffabcc4240 [ 133.797006][ T788] RBP: ffff88805ba3f4c0 R08: fffffbfff5798849 R09: fffffbfff5798849 [ 133.797993][ T788] R10: 0000000000000001 R11: fffffbfff5798848 R12: dffffc0000000000 [ 133.802514][ T788] R13: ffff88805ba3f440 R14: ffff88805ba3f400 R15: ffff88805ed622c0 [ 133.803237][ T788] FS: 00007f2e9608c0c0(0000) GS:ffff88806cc00000(0000) knlGS:0000000000000000 [ 133.804002][ T788] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 133.804664][ T788] CR2: 00007f2e95610603 CR3: 000000005f68c004 CR4: 00000000000606e0 [ 133.805363][ T788] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 133.806073][ T788] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 133.806787][ T788] Call Trace: [ 133.807069][ T788] ? generic_xdp_install+0x310/0x310 [ 133.807612][ T788] ? lock_acquire+0x164/0x3b0 [ 133.808077][ T788] ? is_bpf_text_address+0x5/0xf0 [ 133.808640][ T788] ? deref_stack_reg+0x9c/0xd0 [ 133.809138][ T788] ? __nla_validate_parse+0x98/0x1ab0 [ 133.809944][ T788] unregister_netdevice_many.part.122+0x13/0x1b0 [ 133.810599][ T788] rtnl_delete_link+0xbc/0x100 [ 133.811073][ T788] ? rtnl_af_register+0xc0/0xc0 [ 133.811672][ T788] rtnl_dellink+0x30e/0x8a0 [ 133.812205][ T788] ? is_bpf_text_address+0x5/0xf0 [ ... ] [ 144.110530][ T788] unregister_netdevice: waiting for dummy0 to become free. Usage count = 1 This patch adds notifier routine to delete upper interface before deleting lower interface. Fixes: c7cdba31ed8b ("mac80211-next: rtnetlink wifi simulation device") Signed-off-by: Taehee Yoo Signed-off-by: David S. Miller --- drivers/net/wireless/virt_wifi.c | 54 ++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/virt_wifi.c b/drivers/net/wireless/virt_wifi.c index be92e1220284..7997cc6de334 100644 --- a/drivers/net/wireless/virt_wifi.c +++ b/drivers/net/wireless/virt_wifi.c @@ -548,6 +548,7 @@ static int virt_wifi_newlink(struct net *src_net, struct net_device *dev, priv->is_connected = false; priv->is_up = false; INIT_DELAYED_WORK(&priv->connect, virt_wifi_connect_complete); + __module_get(THIS_MODULE); return 0; unregister_netdev: @@ -578,6 +579,7 @@ static void virt_wifi_dellink(struct net_device *dev, netdev_upper_dev_unlink(priv->lowerdev, dev); unregister_netdevice_queue(dev, head); + module_put(THIS_MODULE); /* Deleting the wiphy is handled in the module destructor. */ } @@ -590,6 +592,42 @@ static struct rtnl_link_ops virt_wifi_link_ops = { .priv_size = sizeof(struct virt_wifi_netdev_priv), }; +static bool netif_is_virt_wifi_dev(const struct net_device *dev) +{ + return rcu_access_pointer(dev->rx_handler) == virt_wifi_rx_handler; +} + +static int virt_wifi_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + struct net_device *lower_dev = netdev_notifier_info_to_dev(ptr); + struct virt_wifi_netdev_priv *priv; + struct net_device *upper_dev; + LIST_HEAD(list_kill); + + if (!netif_is_virt_wifi_dev(lower_dev)) + return NOTIFY_DONE; + + switch (event) { + case NETDEV_UNREGISTER: + priv = rtnl_dereference(lower_dev->rx_handler_data); + if (!priv) + return NOTIFY_DONE; + + upper_dev = priv->upperdev; + + upper_dev->rtnl_link_ops->dellink(upper_dev, &list_kill); + unregister_netdevice_many(&list_kill); + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block virt_wifi_notifier = { + .notifier_call = virt_wifi_event, +}; + /* Acquires and releases the rtnl lock. */ static int __init virt_wifi_init_module(void) { @@ -598,14 +636,25 @@ static int __init virt_wifi_init_module(void) /* Guaranteed to be locallly-administered and not multicast. */ eth_random_addr(fake_router_bssid); + err = register_netdevice_notifier(&virt_wifi_notifier); + if (err) + return err; + + err = -ENOMEM; common_wiphy = virt_wifi_make_wiphy(); if (!common_wiphy) - return -ENOMEM; + goto notifier; err = rtnl_link_register(&virt_wifi_link_ops); if (err) - virt_wifi_destroy_wiphy(common_wiphy); + goto destroy_wiphy; + return 0; + +destroy_wiphy: + virt_wifi_destroy_wiphy(common_wiphy); +notifier: + unregister_netdevice_notifier(&virt_wifi_notifier); return err; } @@ -615,6 +664,7 @@ static void __exit virt_wifi_cleanup_module(void) /* Will delete any devices that depend on the wiphy. */ rtnl_link_unregister(&virt_wifi_link_ops); virt_wifi_destroy_wiphy(common_wiphy); + unregister_netdevice_notifier(&virt_wifi_notifier); } module_init(virt_wifi_init_module); -- GitLab From f4d0973e4fb044bf83609db079a8bd02bfaaa668 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Thu, 24 Oct 2019 14:46:06 -0700 Subject: [PATCH 710/993] ANDROID: of: property: Enable of_devlink by default The of_devlink feature creates device links between devices based on the common device tree bindings listed in their device node. This allows improved probe ordering and also makes sure the sync_state() calls to the device drivers come only after all the consumers of a device have probed successfully. Enable this by default on Android since this is required to ease modularization efforts for GKI. Bug: 143308885 Signed-off-by: Saravana Kannan Change-Id: I57c44e74e35d829ae2ae3145dc241ccf348f2eea --- drivers/of/property.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/property.c b/drivers/of/property.c index dfdc1604f4ad..0fc89e31e087 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -1229,7 +1229,7 @@ static int of_link_to_suppliers(struct device *dev, return ret; } -static bool of_devlink; +static bool of_devlink = true; core_param(of_devlink, of_devlink, bool, 0); static int of_fwnode_add_links(const struct fwnode_handle *fwnode, -- GitLab From 549af00833028b5803528553a4743e0cd1fdbee9 Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Tue, 15 Oct 2019 11:07:33 +0300 Subject: [PATCH 711/993] IB/core: Avoid deadlock during netlink message handling When rdmacm module is not loaded, and when netlink message is received to get char device info, it results into a deadlock due to recursive locking of rdma_nl_mutex with the below call sequence. [..] rdma_nl_rcv() mutex_lock() [..] rdma_nl_rcv_msg() ib_get_client_nl_info() request_module() iw_cm_init() rdma_nl_register() mutex_lock(); <- Deadlock, acquiring mutex again Due to above call sequence, following call trace and deadlock is observed. kernel: __mutex_lock+0x35e/0x860 kernel: ? __mutex_lock+0x129/0x860 kernel: ? rdma_nl_register+0x1a/0x90 [ib_core] kernel: rdma_nl_register+0x1a/0x90 [ib_core] kernel: ? 0xffffffffc029b000 kernel: iw_cm_init+0x34/0x1000 [iw_cm] kernel: do_one_initcall+0x67/0x2d4 kernel: ? kmem_cache_alloc_trace+0x1ec/0x2a0 kernel: do_init_module+0x5a/0x223 kernel: load_module+0x1998/0x1e10 kernel: ? __symbol_put+0x60/0x60 kernel: __do_sys_finit_module+0x94/0xe0 kernel: do_syscall_64+0x5a/0x270 kernel: entry_SYSCALL_64_after_hwframe+0x49/0xbe process stack trace: [<0>] __request_module+0x1c9/0x460 [<0>] ib_get_client_nl_info+0x5e/0xb0 [ib_core] [<0>] nldev_get_chardev+0x1ac/0x320 [ib_core] [<0>] rdma_nl_rcv_msg+0xeb/0x1d0 [ib_core] [<0>] rdma_nl_rcv+0xcd/0x120 [ib_core] [<0>] netlink_unicast+0x179/0x220 [<0>] netlink_sendmsg+0x2f6/0x3f0 [<0>] sock_sendmsg+0x30/0x40 [<0>] ___sys_sendmsg+0x27a/0x290 [<0>] __sys_sendmsg+0x58/0xa0 [<0>] do_syscall_64+0x5a/0x270 [<0>] entry_SYSCALL_64_after_hwframe+0x49/0xbe To overcome this deadlock and to allow multiple netlink messages to progress in parallel, following scheme is implemented. 1. Split the lock protecting the cb_table into a per-index lock, and make it a rwlock. This lock is used to ensure no callbacks are running after unregistration returns. Since a module will not be registered once it is already running callbacks, this avoids the deadlock. 2. Use smp_store_release() to update the cb_table during registration so that no lock is required. This avoids lockdep problems with thinking all the rwsems are the same lock class. Fixes: 0e2d00eb6fd45 ("RDMA: Add NLDEV_GET_CHARDEV to allow char dev discovery and autoload") Link: https://lore.kernel.org/r/20191015080733.18625-1-leon@kernel.org Signed-off-by: Parav Pandit Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/core_priv.h | 1 + drivers/infiniband/core/device.c | 2 + drivers/infiniband/core/netlink.c | 107 ++++++++++++++-------------- 3 files changed, 56 insertions(+), 54 deletions(-) diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index 3a8b0911c3bc..9d07378b5b42 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h @@ -199,6 +199,7 @@ void ib_mad_cleanup(void); int ib_sa_init(void); void ib_sa_cleanup(void); +void rdma_nl_init(void); void rdma_nl_exit(void); int ib_nl_handle_resolve_resp(struct sk_buff *skb, diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 2dd2cfe9b561..50a92442c4f7 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -2716,6 +2716,8 @@ static int __init ib_core_init(void) goto err_comp_unbound; } + rdma_nl_init(); + ret = addr_init(); if (ret) { pr_warn("Could't init IB address resolution\n"); diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c index 81dbd5f41bed..8cd31ef25eff 100644 --- a/drivers/infiniband/core/netlink.c +++ b/drivers/infiniband/core/netlink.c @@ -42,9 +42,12 @@ #include #include "core_priv.h" -static DEFINE_MUTEX(rdma_nl_mutex); static struct { - const struct rdma_nl_cbs *cb_table; + const struct rdma_nl_cbs *cb_table; + /* Synchronizes between ongoing netlink commands and netlink client + * unregistration. + */ + struct rw_semaphore sem; } rdma_nl_types[RDMA_NL_NUM_CLIENTS]; bool rdma_nl_chk_listeners(unsigned int group) @@ -75,70 +78,53 @@ static bool is_nl_msg_valid(unsigned int type, unsigned int op) return (op < max_num_ops[type]) ? true : false; } -static bool -is_nl_valid(const struct sk_buff *skb, unsigned int type, unsigned int op) +static const struct rdma_nl_cbs * +get_cb_table(const struct sk_buff *skb, unsigned int type, unsigned int op) { const struct rdma_nl_cbs *cb_table; - if (!is_nl_msg_valid(type, op)) - return false; - /* * Currently only NLDEV client is supporting netlink commands in * non init_net net namespace. */ if (sock_net(skb->sk) != &init_net && type != RDMA_NL_NLDEV) - return false; + return NULL; - if (!rdma_nl_types[type].cb_table) { - mutex_unlock(&rdma_nl_mutex); - request_module("rdma-netlink-subsys-%d", type); - mutex_lock(&rdma_nl_mutex); - } + cb_table = READ_ONCE(rdma_nl_types[type].cb_table); + if (!cb_table) { + /* + * Didn't get valid reference of the table, attempt module + * load once. + */ + up_read(&rdma_nl_types[type].sem); - cb_table = rdma_nl_types[type].cb_table; + request_module("rdma-netlink-subsys-%d", type); + down_read(&rdma_nl_types[type].sem); + cb_table = READ_ONCE(rdma_nl_types[type].cb_table); + } if (!cb_table || (!cb_table[op].dump && !cb_table[op].doit)) - return false; - return true; + return NULL; + return cb_table; } void rdma_nl_register(unsigned int index, const struct rdma_nl_cbs cb_table[]) { - mutex_lock(&rdma_nl_mutex); - if (!is_nl_msg_valid(index, 0)) { - /* - * All clients are not interesting in success/failure of - * this call. They want to see the print to error log and - * continue their initialization. Print warning for them, - * because it is programmer's error to be here. - */ - mutex_unlock(&rdma_nl_mutex); - WARN(true, - "The not-valid %u index was supplied to RDMA netlink\n", - index); + if (WARN_ON(!is_nl_msg_valid(index, 0)) || + WARN_ON(READ_ONCE(rdma_nl_types[index].cb_table))) return; - } - - if (rdma_nl_types[index].cb_table) { - mutex_unlock(&rdma_nl_mutex); - WARN(true, - "The %u index is already registered in RDMA netlink\n", - index); - return; - } - rdma_nl_types[index].cb_table = cb_table; - mutex_unlock(&rdma_nl_mutex); + /* Pairs with the READ_ONCE in is_nl_valid() */ + smp_store_release(&rdma_nl_types[index].cb_table, cb_table); } EXPORT_SYMBOL(rdma_nl_register); void rdma_nl_unregister(unsigned int index) { - mutex_lock(&rdma_nl_mutex); + down_write(&rdma_nl_types[index].sem); rdma_nl_types[index].cb_table = NULL; - mutex_unlock(&rdma_nl_mutex); + up_write(&rdma_nl_types[index].sem); } EXPORT_SYMBOL(rdma_nl_unregister); @@ -170,15 +156,21 @@ static int rdma_nl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, unsigned int index = RDMA_NL_GET_CLIENT(type); unsigned int op = RDMA_NL_GET_OP(type); const struct rdma_nl_cbs *cb_table; + int err = -EINVAL; - if (!is_nl_valid(skb, index, op)) + if (!is_nl_msg_valid(index, op)) return -EINVAL; - cb_table = rdma_nl_types[index].cb_table; + down_read(&rdma_nl_types[index].sem); + cb_table = get_cb_table(skb, index, op); + if (!cb_table) + goto done; if ((cb_table[op].flags & RDMA_NL_ADMIN_PERM) && - !netlink_capable(skb, CAP_NET_ADMIN)) - return -EPERM; + !netlink_capable(skb, CAP_NET_ADMIN)) { + err = -EPERM; + goto done; + } /* * LS responses overload the 0x100 (NLM_F_ROOT) flag. Don't @@ -186,8 +178,8 @@ static int rdma_nl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, */ if (index == RDMA_NL_LS) { if (cb_table[op].doit) - return cb_table[op].doit(skb, nlh, extack); - return -EINVAL; + err = cb_table[op].doit(skb, nlh, extack); + goto done; } /* FIXME: Convert IWCM to properly handle doit callbacks */ if ((nlh->nlmsg_flags & NLM_F_DUMP) || index == RDMA_NL_IWCM) { @@ -195,14 +187,15 @@ static int rdma_nl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, .dump = cb_table[op].dump, }; if (c.dump) - return netlink_dump_start(skb->sk, skb, nlh, &c); - return -EINVAL; + err = netlink_dump_start(skb->sk, skb, nlh, &c); + goto done; } if (cb_table[op].doit) - return cb_table[op].doit(skb, nlh, extack); - - return 0; + err = cb_table[op].doit(skb, nlh, extack); +done: + up_read(&rdma_nl_types[index].sem); + return err; } /* @@ -263,9 +256,7 @@ static int rdma_nl_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *, static void rdma_nl_rcv(struct sk_buff *skb) { - mutex_lock(&rdma_nl_mutex); rdma_nl_rcv_skb(skb, &rdma_nl_rcv_msg); - mutex_unlock(&rdma_nl_mutex); } int rdma_nl_unicast(struct net *net, struct sk_buff *skb, u32 pid) @@ -297,6 +288,14 @@ int rdma_nl_multicast(struct net *net, struct sk_buff *skb, } EXPORT_SYMBOL(rdma_nl_multicast); +void rdma_nl_init(void) +{ + int idx; + + for (idx = 0; idx < RDMA_NL_NUM_CLIENTS; idx++) + init_rwsem(&rdma_nl_types[idx].sem); +} + void rdma_nl_exit(void) { int idx; -- GitLab From fc5b220b2dcf8b512d9bd46fd17f82257e49bf89 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 23 Oct 2019 13:21:50 -0700 Subject: [PATCH 712/993] scsi: target: cxgbit: Fix cxgbit_fw4_ack() Use the pointer 'p' after having tested that pointer instead of before. Fixes: 5cadafb236df ("target/cxgbit: Fix endianness annotations") Cc: Varun Prakash Cc: Nicholas Bellinger Cc: Link: https://lore.kernel.org/r/20191023202150.22173-1-bvanassche@acm.org Reported-by: Dan Carpenter Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/target/iscsi/cxgbit/cxgbit_cm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/target/iscsi/cxgbit/cxgbit_cm.c b/drivers/target/iscsi/cxgbit/cxgbit_cm.c index 22dd4c457d6a..23a90c685dc6 100644 --- a/drivers/target/iscsi/cxgbit/cxgbit_cm.c +++ b/drivers/target/iscsi/cxgbit/cxgbit_cm.c @@ -1829,7 +1829,7 @@ static void cxgbit_fw4_ack(struct cxgbit_sock *csk, struct sk_buff *skb) while (credits) { struct sk_buff *p = cxgbit_sock_peek_wr(csk); - const u32 csum = (__force u32)p->csum; + u32 csum; if (unlikely(!p)) { pr_err("csk 0x%p,%u, cr %u,%u+%u, empty.\n", @@ -1838,6 +1838,7 @@ static void cxgbit_fw4_ack(struct cxgbit_sock *csk, struct sk_buff *skb) break; } + csum = (__force u32)p->csum; if (unlikely(credits < csum)) { pr_warn("csk 0x%p,%u, cr %u,%u+%u, < %u.\n", csk, csk->tid, -- GitLab From 584739f5dd25829e2aa0cd19f546cae86b7a2999 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Thu, 24 Oct 2019 13:08:09 -0700 Subject: [PATCH 713/993] ANDROID: v4l2-compat-ioctl32.c: copy reserved fields Copy reserved fields along with other fields in v4l2_plane for userspace clients and drivers to use reserved fields when required. Bug: 143160749 Change-Id: I0c7e7485961ab50188cda6ae81998473500bb07b Signed-off-by: Maheshwar Ajja --- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 13 +++++++++++-- include/uapi/linux/videodev2.h | 5 ++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index e1eaf1135c7f..e4e454db2560 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -465,6 +465,11 @@ struct v4l2_plane32 { __s32 fd; } m; __u32 data_offset; + /* + * few userspace clients and drivers use reserved fields + * and it is up to them how these fields are used. v4l2 + * simply copy reserved fields between them. + */ __u32 reserved[11]; }; @@ -499,7 +504,9 @@ static int get_v4l2_plane32(struct v4l2_plane __user *p64, if (copy_in_user(p64, p32, 2 * sizeof(__u32)) || copy_in_user(&p64->data_offset, &p32->data_offset, - sizeof(p64->data_offset))) + sizeof(p64->data_offset)) || + copy_in_user(p64->reserved, p32->reserved, + sizeof(p64->reserved))) return -EFAULT; switch (memory) { @@ -531,7 +538,9 @@ static int put_v4l2_plane32(struct v4l2_plane __user *p64, if (copy_in_user(p32, p64, 2 * sizeof(__u32)) || copy_in_user(&p32->data_offset, &p64->data_offset, - sizeof(p64->data_offset))) + sizeof(p64->data_offset)) || + copy_in_user(p32->reserved, p64->reserved, + sizeof(p32->reserved))) return -EFAULT; switch (memory) { diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 530638dffd93..c3671c633dca 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -935,7 +935,9 @@ struct v4l2_requestbuffers { * descriptor associated with this plane * @data_offset: offset in the plane to the start of data; usually 0, * unless there is a header in front of the data - * + * @reserved: few userspace clients and drivers use reserved fields + * and it is up to them how these fields are used. v4l2 + * simply copy reserved fields between them. * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer * with two planes can have one plane for Y, and another for interleaved CbCr * components. Each plane can reside in a separate memory buffer, or even in @@ -950,6 +952,7 @@ struct v4l2_plane { __s32 fd; } m; __u32 data_offset; + /* reserved fields used by few userspace clients and drivers */ __u32 reserved[11]; }; -- GitLab From 0cf9f4e547cebb5f5d2d046437c71ddcc8ea4a39 Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Tue, 22 Oct 2019 14:27:08 +0800 Subject: [PATCH 714/993] scsi: sd: define variable dif as unsigned int instead of bool Variable dif in function sd_setup_read_write_cmnd() is the return value of function scsi_host_dif_capable() which returns dif capability of disks. If define it as bool, even for the disks which support DIF3, the function still return dif=1, which causes IO error. So define variable dif as unsigned int instead of bool. Fixes: e249e42d277e ("scsi: sd: Clean up sd_setup_read_write_cmnd()") Link: https://lore.kernel.org/r/1571725628-132736-1-git-send-email-chenxiang66@hisilicon.com Signed-off-by: Xiang Chen Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 0f96eb0ddbfa..fe05475ce5dc 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1166,11 +1166,12 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *cmd) sector_t lba = sectors_to_logical(sdp, blk_rq_pos(rq)); sector_t threshold; unsigned int nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq)); - bool dif, dix; unsigned int mask = logical_to_sectors(sdp, 1) - 1; bool write = rq_data_dir(rq) == WRITE; unsigned char protect, fua; blk_status_t ret; + unsigned int dif; + bool dix; ret = scsi_init_io(cmd); if (ret != BLK_STS_OK) -- GitLab From abe57073d08c13b95a46ccf48cc9dc957d5c6fdb Mon Sep 17 00:00:00 2001 From: Pavel Shilovsky Date: Tue, 22 Oct 2019 08:41:42 -0700 Subject: [PATCH 715/993] CIFS: Fix retry mid list corruption on reconnects 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 Reviewed-and-tested-by: David Wysochanski Signed-off-by: Pavel Shilovsky Signed-off-by: Steve French --- 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 bdea4b3e8005..ccaa8bad336f 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -564,9 +564,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); @@ -576,6 +578,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); } if (cifs_rdma_enabled(server)) { @@ -895,8 +898,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); } @@ -966,8 +971,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); @@ -977,6 +984,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 308ad0f495e1..ca3de62688d6 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -86,22 +86,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; __u16 smb_cmd = le16_to_cpu(midEntry->command); @@ -166,6 +152,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); } @@ -173,8 +172,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); @@ -872,7 +873,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_server_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n", __func__, mid->mid, mid->mid_state); rc = -EIO; -- GitLab From 1a67c415965752879e2e9fad407bc44fc7f25f23 Mon Sep 17 00:00:00 2001 From: Pavel Shilovsky Date: Wed, 23 Oct 2019 15:37:19 -0700 Subject: [PATCH 716/993] CIFS: Fix use after free of file info structures Currently the code assumes that if a file info entry belongs to lists of open file handles of an inode and a tcon then it has non-zero reference. The recent changes broke that assumption when putting the last reference of the file info. There may be a situation when a file is being deleted but nothing prevents another thread to reference it again and start using it. This happens because we do not hold the inode list lock while checking the number of references of the file info structure. Fix this by doing the proper locking when doing the check. Fixes: 487317c99477d ("cifs: add spinlock for the openFileList to cifsInodeInfo") Fixes: cb248819d209d ("cifs: use cifsInodeInfo->open_file_lock while iterating to avoid a panic") Cc: Stable Reviewed-by: Ronnie Sahlberg Signed-off-by: Pavel Shilovsky Signed-off-by: Steve French --- fs/cifs/file.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5ad15de2bb4f..64827938ecf7 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -405,10 +405,11 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_handler) bool oplock_break_cancelled; spin_lock(&tcon->open_file_lock); - + spin_lock(&cifsi->open_file_lock); spin_lock(&cifs_file->file_info_lock); if (--cifs_file->count > 0) { spin_unlock(&cifs_file->file_info_lock); + spin_unlock(&cifsi->open_file_lock); spin_unlock(&tcon->open_file_lock); return; } @@ -421,9 +422,7 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_handler) cifs_add_pending_open_locked(&fid, cifs_file->tlink, &open); /* remove it from the lists */ - spin_lock(&cifsi->open_file_lock); list_del(&cifs_file->flist); - spin_unlock(&cifsi->open_file_lock); list_del(&cifs_file->tlist); atomic_dec(&tcon->num_local_opens); @@ -440,6 +439,7 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_handler) cifs_set_oplock_level(cifsi, 0); } + spin_unlock(&cifsi->open_file_lock); spin_unlock(&tcon->open_file_lock); oplock_break_cancelled = wait_oplock_handler ? -- GitLab From d46b0da7a33dd8c99d969834f682267a45444ab3 Mon Sep 17 00:00:00 2001 From: Dave Wysochanski Date: Wed, 23 Oct 2019 05:02:33 -0400 Subject: [PATCH 717/993] cifs: Fix cifsInodeInfo lock_sem deadlock when reconnect occurs There's a deadlock that is possible and can easily be seen with a test where multiple readers open/read/close of the same file and a disruption occurs causing reconnect. The deadlock is due a reader thread inside cifs_strict_readv calling down_read and obtaining lock_sem, and then after reconnect inside cifs_reopen_file calling down_read a second time. If in between the two down_read calls, a down_write comes from another process, deadlock occurs. CPU0 CPU1 ---- ---- cifs_strict_readv() down_read(&cifsi->lock_sem); _cifsFileInfo_put OR cifs_new_fileinfo down_write(&cifsi->lock_sem); cifs_reopen_file() down_read(&cifsi->lock_sem); Fix the above by changing all down_write(lock_sem) calls to down_write_trylock(lock_sem)/msleep() loop, which in turn makes the second down_read call benign since it will never block behind the writer while holding lock_sem. Signed-off-by: Dave Wysochanski Suggested-by: Ronnie Sahlberg Reviewed--by: Ronnie Sahlberg Reviewed-by: Pavel Shilovsky --- fs/cifs/cifsglob.h | 5 +++++ fs/cifs/cifsproto.h | 1 + fs/cifs/file.c | 23 +++++++++++++++-------- fs/cifs/smb2file.c | 2 +- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 50dfd9049370..d78bfcc19156 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1391,6 +1391,11 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file); struct cifsInodeInfo { bool can_cache_brlcks; struct list_head llist; /* locks helb by this inode */ + /* + * NOTE: Some code paths call down_read(lock_sem) twice, so + * we must always use use cifs_down_write() instead of down_write() + * for this semaphore to avoid deadlocks. + */ struct rw_semaphore lock_sem; /* protect the fields above */ /* BB add in lists for dirty pages i.e. write caching info for oplock */ struct list_head openFileList; diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index e53e9f62b87b..fe597d3d5208 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -170,6 +170,7 @@ extern int cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, const unsigned int xid); extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile); +extern void cifs_down_write(struct rw_semaphore *sem); extern struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, struct tcon_link *tlink, diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 64827938ecf7..fa7b0fa72bb3 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -281,6 +281,13 @@ cifs_has_mand_locks(struct cifsInodeInfo *cinode) return has_locks; } +void +cifs_down_write(struct rw_semaphore *sem) +{ + while (!down_write_trylock(sem)) + msleep(10); +} + struct cifsFileInfo * cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, struct tcon_link *tlink, __u32 oplock) @@ -306,7 +313,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, INIT_LIST_HEAD(&fdlocks->locks); fdlocks->cfile = cfile; cfile->llist = fdlocks; - down_write(&cinode->lock_sem); + cifs_down_write(&cinode->lock_sem); list_add(&fdlocks->llist, &cinode->llist); up_write(&cinode->lock_sem); @@ -464,7 +471,7 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_handler) * Delete any outstanding lock records. We'll lose them when the file * is closed anyway. */ - down_write(&cifsi->lock_sem); + cifs_down_write(&cifsi->lock_sem); list_for_each_entry_safe(li, tmp, &cifs_file->llist->locks, llist) { list_del(&li->llist); cifs_del_lock_waiters(li); @@ -1027,7 +1034,7 @@ static void cifs_lock_add(struct cifsFileInfo *cfile, struct cifsLockInfo *lock) { struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry)); - down_write(&cinode->lock_sem); + cifs_down_write(&cinode->lock_sem); list_add_tail(&lock->llist, &cfile->llist->locks); up_write(&cinode->lock_sem); } @@ -1049,7 +1056,7 @@ cifs_lock_add_if(struct cifsFileInfo *cfile, struct cifsLockInfo *lock, try_again: exist = false; - down_write(&cinode->lock_sem); + cifs_down_write(&cinode->lock_sem); exist = cifs_find_lock_conflict(cfile, lock->offset, lock->length, lock->type, lock->flags, &conf_lock, @@ -1072,7 +1079,7 @@ cifs_lock_add_if(struct cifsFileInfo *cfile, struct cifsLockInfo *lock, (lock->blist.next == &lock->blist)); if (!rc) goto try_again; - down_write(&cinode->lock_sem); + cifs_down_write(&cinode->lock_sem); list_del_init(&lock->blist); } @@ -1125,7 +1132,7 @@ cifs_posix_lock_set(struct file *file, struct file_lock *flock) return rc; try_again: - down_write(&cinode->lock_sem); + cifs_down_write(&cinode->lock_sem); if (!cinode->can_cache_brlcks) { up_write(&cinode->lock_sem); return rc; @@ -1331,7 +1338,7 @@ cifs_push_locks(struct cifsFileInfo *cfile) int rc = 0; /* we are going to update can_cache_brlcks here - need a write access */ - down_write(&cinode->lock_sem); + cifs_down_write(&cinode->lock_sem); if (!cinode->can_cache_brlcks) { up_write(&cinode->lock_sem); return rc; @@ -1522,7 +1529,7 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, if (!buf) return -ENOMEM; - down_write(&cinode->lock_sem); + cifs_down_write(&cinode->lock_sem); for (i = 0; i < 2; i++) { cur = buf; num = 0; diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c index e6a1fc72018f..8b0b512c5792 100644 --- a/fs/cifs/smb2file.c +++ b/fs/cifs/smb2file.c @@ -145,7 +145,7 @@ smb2_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, cur = buf; - down_write(&cinode->lock_sem); + cifs_down_write(&cinode->lock_sem); list_for_each_entry_safe(li, tmp, &cfile->llist->locks, llist) { if (flock->fl_start > li->offset || (flock->fl_start + length) < -- GitLab From a1bb46c36ce389d4a24a42e5b6047b0626caa3ea Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 25 Oct 2019 02:41:40 +0200 Subject: [PATCH 718/993] ACPI: processor: Add QoS requests for all CPUs The _PPC change notifications from the platform firmware are per-CPU, so acpi_processor_ppc_init() needs to add a frequency QoS request for each CPU covered by a cpufreq policy to take all of them into account. Even though ACPI thermal control of CPUs sets frequency limits per processor package, it also needs a frequency QoS request for each CPU in a cpufreq policy in case some of them are taken offline and the frequency limit needs to be set through the remaining online ones (this is slightly excessive, because all CPUs covered by one cpufreq policy will set the same frequency limit through their QoS requests, but it is not incorrect). Modify the code in accordance with the above observations. Fixes: d15ce412737a ("ACPI: cpufreq: Switch to QoS requests instead of cpufreq notifier") Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar --- drivers/acpi/processor_perflib.c | 34 ++++++++++++++++++++------------ drivers/acpi/processor_thermal.c | 34 ++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 753e171de006..5909e8fa4013 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -159,26 +159,34 @@ void acpi_processor_ignore_ppc_init(void) void acpi_processor_ppc_init(struct cpufreq_policy *policy) { - int cpu = policy->cpu; - struct acpi_processor *pr = per_cpu(processors, cpu); - int ret; + unsigned int cpu; - if (!pr) - return; + for_each_cpu(cpu, policy->related_cpus) { + struct acpi_processor *pr = per_cpu(processors, cpu); + int ret; + + if (!pr) + continue; - ret = freq_qos_add_request(&policy->constraints, &pr->perflib_req, - FREQ_QOS_MAX, INT_MAX); - if (ret < 0) - pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, - ret); + ret = freq_qos_add_request(&policy->constraints, + &pr->perflib_req, + FREQ_QOS_MAX, INT_MAX); + if (ret < 0) + pr_err("Failed to add freq constraint for CPU%d (%d)\n", + cpu, ret); + } } void acpi_processor_ppc_exit(struct cpufreq_policy *policy) { - struct acpi_processor *pr = per_cpu(processors, policy->cpu); + unsigned int cpu; - if (pr) - freq_qos_remove_request(&pr->perflib_req); + for_each_cpu(cpu, policy->related_cpus) { + struct acpi_processor *pr = per_cpu(processors, cpu); + + if (pr) + freq_qos_remove_request(&pr->perflib_req); + } } static int acpi_processor_get_performance_control(struct acpi_processor *pr) diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index c77a5b1fb107..41feb88ee92d 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -127,26 +127,34 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy) { - int cpu = policy->cpu; - struct acpi_processor *pr = per_cpu(processors, cpu); - int ret; + unsigned int cpu; - if (!pr) - return; + for_each_cpu(cpu, policy->related_cpus) { + struct acpi_processor *pr = per_cpu(processors, cpu); + int ret; + + if (!pr) + continue; - ret = freq_qos_add_request(&policy->constraints, &pr->thermal_req, - FREQ_QOS_MAX, INT_MAX); - if (ret < 0) - pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, - ret); + ret = freq_qos_add_request(&policy->constraints, + &pr->thermal_req, + FREQ_QOS_MAX, INT_MAX); + if (ret < 0) + pr_err("Failed to add freq constraint for CPU%d (%d)\n", + cpu, ret); + } } void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy) { - struct acpi_processor *pr = per_cpu(processors, policy->cpu); + unsigned int cpu; + + for_each_cpu(cpu, policy->related_cpus) { + struct acpi_processor *pr = per_cpu(processors, policy->cpu); - if (pr) - freq_qos_remove_request(&pr->thermal_req); + if (pr) + freq_qos_remove_request(&pr->thermal_req); + } } #else /* ! CONFIG_CPU_FREQ */ static int cpufreq_get_max_state(unsigned int cpu) -- GitLab From 7bb134695480b6440b27d7ecf16faa91b49389d1 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Fri, 25 Oct 2019 11:12:35 +0530 Subject: [PATCH 719/993] ANDROID: soc: qcom: Add required header to irq.h Add required header file to fix compiler reported errors. BUG: 141169320 TEST: Build and boot Fixes: 736036d73892 ("FROMLIST: drivers: irqchip: add PDC irqdomain for wakeup capable GPIOs") Signed-off-by: Maulik Shah Change-Id: Ie1503213bdc7432f36d065f8487e71e37cfe8532 --- include/linux/soc/qcom/irq.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/soc/qcom/irq.h b/include/linux/soc/qcom/irq.h index 098d57ca4a52..fcb799c887b9 100644 --- a/include/linux/soc/qcom/irq.h +++ b/include/linux/soc/qcom/irq.h @@ -3,6 +3,8 @@ #ifndef __QCOM_IRQ_H #define __QCOM_IRQ_H +#include + #define GPIO_NO_WAKE_IRQ ~0U /** -- GitLab From 41860cc447045c811ce6d5a92f93a065a691fe8e Mon Sep 17 00:00:00 2001 From: Alan Mikhak Date: Thu, 24 Oct 2019 09:11:43 -0700 Subject: [PATCH 720/993] irqchip/sifive-plic: Skip contexts except supervisor in plic_init() Modify plic_init() to skip .dts interrupt contexts other than supervisor external interrupt. The .dts entry for plic may specify multiple interrupt contexts. For example, it may assign two entries IRQ_M_EXT and IRQ_S_EXT, in that order, to the same interrupt controller. This patch modifies plic_init() to skip the IRQ_M_EXT context since IRQ_S_EXT is currently the only supported context. If IRQ_M_EXT is not skipped, plic_init() will report "handler already present for context" when it comes across the IRQ_S_EXT context in the next iteration of its loop. Without this patch, .dts would have to be edited to replace the value of IRQ_M_EXT with -1 for it to be skipped. Signed-off-by: Alan Mikhak Signed-off-by: Marc Zyngier Reviewed-by: Christoph Hellwig Acked-by: Paul Walmsley # arch/riscv Link: https://lkml.kernel.org/r/1571933503-21504-1-git-send-email-alan.mikhak@sifive.com --- drivers/irqchip/irq-sifive-plic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c index 3e51deedbcc8..b1a33f97db03 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -251,8 +251,8 @@ static int __init plic_init(struct device_node *node, continue; } - /* skip context holes */ - if (parent.args[0] == -1) + /* skip contexts other than supervisor external interrupt */ + if (parent.args[0] != IRQ_S_EXT) continue; hartid = plic_find_hart_id(parent.np); -- GitLab From a8a30219ba78b1abb92091102b632f8e9bbdbf03 Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Wed, 16 Oct 2019 18:28:33 +0200 Subject: [PATCH 721/993] powerpc/powernv/eeh: Fix oops when probing cxl devices Recent cleanup in the way EEH support is added to a device causes a kernel oops when the cxl driver probes a device and creates virtual devices discovered on the FPGA: BUG: Kernel NULL pointer dereference at 0x000000a0 Faulting instruction address: 0xc000000000048070 Oops: Kernel access of bad area, sig: 7 [#1] ... NIP eeh_add_device_late.part.9+0x50/0x1e0 LR eeh_add_device_late.part.9+0x3c/0x1e0 Call Trace: _dev_info+0x5c/0x6c (unreliable) pnv_pcibios_bus_add_device+0x60/0xb0 pcibios_bus_add_device+0x40/0x60 pci_bus_add_device+0x30/0x100 pci_bus_add_devices+0x64/0xd0 cxl_pci_vphb_add+0xe0/0x130 [cxl] cxl_probe+0x504/0x5b0 [cxl] local_pci_probe+0x6c/0x110 work_for_cpu_fn+0x38/0x60 The root cause is that those cxl virtual devices don't have a representation in the device tree and therefore no associated pci_dn structure. In eeh_add_device_late(), pdn is NULL, so edev is NULL and we oops. We never had explicit support for EEH for those virtual devices. Instead, EEH events are reported to the (real) pci device and handled by the cxl driver. Which can then forward to the virtual devices and handle dependencies. The fact that we try adding EEH support for the virtual devices is new and a side-effect of the recent cleanup. This patch fixes it by skipping adding EEH support on powernv for devices which don't have a pci_dn structure. The cxl driver doesn't create virtual devices on pseries so this patch doesn't fix it there intentionally. Fixes: b905f8cdca77 ("powerpc/eeh: EEH for pSeries hot plug") Signed-off-by: Frederic Barrat Reviewed-by: Sam Bobroff Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191016162833.22509-1-fbarrat@linux.ibm.com --- arch/powerpc/platforms/powernv/eeh-powernv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 6bc24a47e9ef..6f300ab7f0e9 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -42,7 +42,7 @@ void pnv_pcibios_bus_add_device(struct pci_dev *pdev) { struct pci_dn *pdn = pci_get_pdn(pdev); - if (eeh_has_flag(EEH_FORCE_DISABLED)) + if (!pdn || eeh_has_flag(EEH_FORCE_DISABLED)) return; dev_dbg(&pdev->dev, "EEH: Setting up device\n"); -- GitLab From 9121923c457d1d8667a6e3a67302c29e5c5add6b Mon Sep 17 00:00:00 2001 From: Jim Mattson Date: Thu, 24 Oct 2019 16:03:26 -0700 Subject: [PATCH 722/993] kvm: Allocate memslots and buses before calling kvm_arch_init_vm This reorganization will allow us to call kvm_arch_destroy_vm in the event that kvm_create_vm fails after calling kvm_arch_init_vm. Suggested-by: Junaid Shahid Signed-off-by: Jim Mattson Reviewed-by: Junaid Shahid Signed-off-by: Paolo Bonzini --- virt/kvm/kvm_main.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 67ef3f2e19e8..ec14dae2f538 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -627,8 +627,9 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd) static struct kvm *kvm_create_vm(unsigned long type) { - int r, i; struct kvm *kvm = kvm_arch_alloc_vm(); + int r = -ENOMEM; + int i; if (!kvm) return ERR_PTR(-ENOMEM); @@ -643,6 +644,25 @@ static struct kvm *kvm_create_vm(unsigned long type) refcount_set(&kvm->users_count, 1); INIT_LIST_HEAD(&kvm->devices); + BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX); + + for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { + struct kvm_memslots *slots = kvm_alloc_memslots(); + + if (!slots) + goto out_err_no_disable; + /* Generations must be different for each address space. */ + slots->generation = i; + rcu_assign_pointer(kvm->memslots[i], slots); + } + + for (i = 0; i < KVM_NR_BUSES; i++) { + rcu_assign_pointer(kvm->buses[i], + kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL_ACCOUNT)); + if (!kvm->buses[i]) + goto out_err_no_disable; + } + r = kvm_arch_init_vm(kvm, type); if (r) goto out_err_no_disable; @@ -655,28 +675,10 @@ static struct kvm *kvm_create_vm(unsigned long type) INIT_HLIST_HEAD(&kvm->irq_ack_notifier_list); #endif - BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX); - - r = -ENOMEM; - for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { - struct kvm_memslots *slots = kvm_alloc_memslots(); - if (!slots) - goto out_err_no_srcu; - /* Generations must be different for each address space. */ - slots->generation = i; - rcu_assign_pointer(kvm->memslots[i], slots); - } - if (init_srcu_struct(&kvm->srcu)) goto out_err_no_srcu; if (init_srcu_struct(&kvm->irq_srcu)) goto out_err_no_irq_srcu; - for (i = 0; i < KVM_NR_BUSES; i++) { - rcu_assign_pointer(kvm->buses[i], - kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL_ACCOUNT)); - if (!kvm->buses[i]) - goto out_err; - } r = kvm_init_mmu_notifier(kvm); if (r) -- GitLab From 6ccae60d014d5d1f89c40e7e4b619f343ca24b03 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Fri, 25 Oct 2019 09:38:58 +0200 Subject: [PATCH 723/993] xen: issue deprecation warning for 32-bit pv guest Support for the kernel as Xen 32-bit PV guest will soon be removed. Issue a warning when booted as such. Signed-off-by: Juergen Gross Signed-off-by: Boris Ostrovsky --- arch/x86/xen/enlighten_pv.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 7ceb32821093..bd5a61f2c9f1 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -117,6 +117,14 @@ static void __init xen_banner(void) printk(KERN_INFO "Xen version: %d.%d%s%s\n", version >> 16, version & 0xffff, extra.extraversion, xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); + +#ifdef CONFIG_X86_32 + pr_warn("WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!\n" + "Support for running as 32-bit PV-guest under Xen will soon be removed\n" + "from the Linux kernel!\n" + "Please use either a 64-bit kernel or switch to HVM or PVH mode!\n" + "WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!\n"); +#endif } static void __init xen_pv_init_platform(void) -- GitLab From 84d55dc5b9e57b513a702fbc358e1b5489651590 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Fri, 25 Oct 2019 12:31:29 +0300 Subject: [PATCH 724/993] io_uring: Fix corrupted user_data There is a bug, where failed linked requests are returned not with specified @user_data, but with garbage from a kernel stack. The reason is that io_fail_links() uses req->user_data, which is uninitialised when called from io_queue_sqe() on fail path. Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/io_uring.c b/fs/io_uring.c index 1b46c72f8975..0e141d905a5b 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -2448,6 +2448,8 @@ static void io_submit_sqe(struct io_ring_ctx *ctx, struct sqe_submit *s, return; } + req->user_data = s->sqe->user_data; + /* * If we already have a head request, queue this one for async * submittal once the head completes. If we don't have a head but -- GitLab From fb5ccc98782f654778cb8d96ba8a998304f9a51f Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Fri, 25 Oct 2019 12:31:30 +0300 Subject: [PATCH 725/993] io_uring: Fix broken links with offloading io_sq_thread() processes sqes by 8 without considering links. As a result, links will be randomely subdivided. The easiest way to fix it is to call io_get_sqring() inside io_submit_sqes() as do io_ring_submit(). Downsides: 1. This removes optimisation of not grabbing mm_struct for fixed files 2. It submitting all sqes in one go, without finer-grained sheduling with cq processing. Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 62 +++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 0e141d905a5b..949c82a40d16 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -735,6 +735,14 @@ static unsigned io_cqring_events(struct io_rings *rings) return READ_ONCE(rings->cq.tail) - READ_ONCE(rings->cq.head); } +static inline unsigned int io_sqring_entries(struct io_ring_ctx *ctx) +{ + struct io_rings *rings = ctx->rings; + + /* make sure SQ entry isn't read before tail */ + return smp_load_acquire(&rings->sq.tail) - ctx->cached_sq_head; +} + /* * Find and free completed poll iocbs */ @@ -2560,8 +2568,8 @@ static bool io_get_sqring(struct io_ring_ctx *ctx, struct sqe_submit *s) return false; } -static int io_submit_sqes(struct io_ring_ctx *ctx, struct sqe_submit *sqes, - unsigned int nr, bool has_user, bool mm_fault) +static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr, + bool has_user, bool mm_fault) { struct io_submit_state state, *statep = NULL; struct io_kiocb *link = NULL; @@ -2575,6 +2583,11 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, struct sqe_submit *sqes, } for (i = 0; i < nr; i++) { + struct sqe_submit s; + + if (!io_get_sqring(ctx, &s)) + break; + /* * If previous wasn't linked and we have a linked command, * that's the end of the chain. Submit the previous link. @@ -2584,9 +2597,9 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, struct sqe_submit *sqes, link = NULL; shadow_req = NULL; } - prev_was_link = (sqes[i].sqe->flags & IOSQE_IO_LINK) != 0; + prev_was_link = (s.sqe->flags & IOSQE_IO_LINK) != 0; - if (link && (sqes[i].sqe->flags & IOSQE_IO_DRAIN)) { + if (link && (s.sqe->flags & IOSQE_IO_DRAIN)) { if (!shadow_req) { shadow_req = io_get_req(ctx, NULL); if (unlikely(!shadow_req)) @@ -2594,18 +2607,18 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, struct sqe_submit *sqes, shadow_req->flags |= (REQ_F_IO_DRAIN | REQ_F_SHADOW_DRAIN); refcount_dec(&shadow_req->refs); } - shadow_req->sequence = sqes[i].sequence; + shadow_req->sequence = s.sequence; } out: if (unlikely(mm_fault)) { - io_cqring_add_event(ctx, sqes[i].sqe->user_data, + io_cqring_add_event(ctx, s.sqe->user_data, -EFAULT); } else { - sqes[i].has_user = has_user; - sqes[i].needs_lock = true; - sqes[i].needs_fixed_file = true; - io_submit_sqe(ctx, &sqes[i], statep, &link); + s.has_user = has_user; + s.needs_lock = true; + s.needs_fixed_file = true; + io_submit_sqe(ctx, &s, statep, &link); submitted++; } } @@ -2620,7 +2633,6 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, struct sqe_submit *sqes, static int io_sq_thread(void *data) { - struct sqe_submit sqes[IO_IOPOLL_BATCH]; struct io_ring_ctx *ctx = data; struct mm_struct *cur_mm = NULL; mm_segment_t old_fs; @@ -2635,8 +2647,8 @@ static int io_sq_thread(void *data) timeout = inflight = 0; while (!kthread_should_park()) { - bool all_fixed, mm_fault = false; - int i; + bool mm_fault = false; + unsigned int to_submit; if (inflight) { unsigned nr_events = 0; @@ -2656,7 +2668,8 @@ static int io_sq_thread(void *data) timeout = jiffies + ctx->sq_thread_idle; } - if (!io_get_sqring(ctx, &sqes[0])) { + to_submit = io_sqring_entries(ctx); + if (!to_submit) { /* * We're polling. If we're within the defined idle * period, then let us spin without work before going @@ -2687,7 +2700,8 @@ static int io_sq_thread(void *data) /* make sure to read SQ tail after writing flags */ smp_mb(); - if (!io_get_sqring(ctx, &sqes[0])) { + to_submit = io_sqring_entries(ctx); + if (!to_submit) { if (kthread_should_park()) { finish_wait(&ctx->sqo_wait, &wait); break; @@ -2705,19 +2719,8 @@ static int io_sq_thread(void *data) ctx->rings->sq_flags &= ~IORING_SQ_NEED_WAKEUP; } - i = 0; - all_fixed = true; - do { - if (all_fixed && io_sqe_needs_user(sqes[i].sqe)) - all_fixed = false; - - i++; - if (i == ARRAY_SIZE(sqes)) - break; - } while (io_get_sqring(ctx, &sqes[i])); - /* Unless all new commands are FIXED regions, grab mm */ - if (!all_fixed && !cur_mm) { + if (!cur_mm) { mm_fault = !mmget_not_zero(ctx->sqo_mm); if (!mm_fault) { use_mm(ctx->sqo_mm); @@ -2725,8 +2728,9 @@ static int io_sq_thread(void *data) } } - inflight += io_submit_sqes(ctx, sqes, i, cur_mm != NULL, - mm_fault); + to_submit = min(to_submit, ctx->sq_entries); + inflight += io_submit_sqes(ctx, to_submit, cur_mm != NULL, + mm_fault); /* Commit SQ ring head once we've consumed all SQEs */ io_commit_sqring(ctx); -- GitLab From 935d1e45908afb8853c497f2c2bbbb685dec51dc Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Fri, 25 Oct 2019 12:31:31 +0300 Subject: [PATCH 726/993] io_uring: Fix race for sqes with userspace io_ring_submit() finalises with 1. io_commit_sqring(), which releases sqes to the userspace 2. Then calls to io_queue_link_head(), accessing released head's sqe Reorder them. Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 949c82a40d16..32f6598ecae9 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -2795,13 +2795,14 @@ static int io_ring_submit(struct io_ring_ctx *ctx, unsigned int to_submit) submit++; io_submit_sqe(ctx, &s, statep, &link); } - io_commit_sqring(ctx); if (link) io_queue_link_head(ctx, link, &link->submit, shadow_req); if (statep) io_submit_state_end(statep); + io_commit_sqring(ctx); + return submit; } -- GitLab From 86ec2e1739aa1d6565888b4b2059fa47354e1a89 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Fri, 25 Oct 2019 15:01:22 +0200 Subject: [PATCH 727/993] ARM: dts: stm32: relax qspi pins slew-rate for stm32mp157 Relax qspi pins slew-rate to minimize peak currents. Fixes: 844030057339 ("ARM: dts: stm32: add flash nor support on stm32mp157c eval board") Link: https://lore.kernel.org/r/20191025130122.11407-1-alexandre.torgue@st.com Signed-off-by: Patrice Chotard Signed-off-by: Alexandre Torgue Signed-off-by: Olof Johansson --- arch/arm/boot/dts/stm32mp157-pinctrl.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi index e4a0d51ec3a8..0a3a7d66737b 100644 --- a/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi +++ b/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi @@ -609,13 +609,13 @@ ; /* QSPI_BK1_IO3 */ bias-disable; drive-push-pull; - slew-rate = <3>; + slew-rate = <1>; }; pins2 { pinmux = ; /* QSPI_BK1_NCS */ bias-pull-up; drive-push-pull; - slew-rate = <3>; + slew-rate = <1>; }; }; @@ -637,13 +637,13 @@ ; /* QSPI_BK2_IO3 */ bias-disable; drive-push-pull; - slew-rate = <3>; + slew-rate = <1>; }; pins2 { pinmux = ; /* QSPI_BK2_NCS */ bias-pull-up; drive-push-pull; - slew-rate = <3>; + slew-rate = <1>; }; }; -- GitLab From ebc7824f47ae5d95448e2758562491c3c68c05ed Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Tue, 10 Sep 2019 15:42:05 -0700 Subject: [PATCH 728/993] FROMLIST: of: Export of_phandle_iterator_args() to modules Kernel modules may want to use of_phandle_iterator_args(), so export it. Change-Id: Ic42b0917834669dd4dc6930081581d66381c7d5a Signed-off-by: Isaac J. Manjarres Acked-by: Rob Herring Bug: 140290589 Link: https://patchwork.kernel.org/patch/10948415/ --- drivers/of/base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/of/base.c b/drivers/of/base.c index 1d667eb730e1..ff896fcc8efa 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1404,6 +1404,7 @@ int of_phandle_iterator_args(struct of_phandle_iterator *it, return count; } +EXPORT_SYMBOL_GPL(of_phandle_iterator_args); static int __of_parse_phandle_with_args(const struct device_node *np, const char *list_name, -- GitLab From c32fef399dc04a181a25b01186b827d968f0e23a Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Tue, 10 Sep 2019 15:44:23 -0700 Subject: [PATCH 729/993] FROMLIST: PCI: Export PCI ACS and DMA searching functions to modules IOMMU drivers that can be compiled as modules may want to use pci_for_each_dma_alias() and pci_request_acs(), so export those functions. Change-Id: I8fab4075d151cc3d07a6594685895a189565bb3d Signed-off-by: Isaac J. Manjarres Acked-by: Bjorn Helgaas Bug: 140290589 Link: https://patchwork.kernel.org/patch/10948411/ --- drivers/pci/pci.c | 1 + drivers/pci/search.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e7982af9a5d8..25794efb4076 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3173,6 +3173,7 @@ void pci_request_acs(void) { pci_acs_enable = 1; } +EXPORT_SYMBOL_GPL(pci_request_acs); static const char *disable_acs_redir_param; diff --git a/drivers/pci/search.c b/drivers/pci/search.c index bade14002fd8..58b3997a2886 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -106,6 +106,7 @@ int pci_for_each_dma_alias(struct pci_dev *pdev, return ret; } +EXPORT_SYMBOL_GPL(pci_for_each_dma_alias); static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr) { -- GitLab From 82047fdd5d9dd59eda4182f38af0a26e263c569e Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Tue, 10 Sep 2019 15:41:16 -0700 Subject: [PATCH 730/993] FROMLIST: iommu: Export core IOMMU functions to kernel modules IOMMU drivers that can be compiled as modules need to use some of the IOMMU core functions, so expose them. Change-Id: I84004fdcd7eee3f56d08db76c3b0421990179810 Signed-off-by: Isaac J. Manjarres Bug: 140290589 Link: https://patchwork.kernel.org/patch/10948413/ --- drivers/iommu/iommu-sysfs.c | 3 +++ drivers/iommu/iommu.c | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/drivers/iommu/iommu-sysfs.c b/drivers/iommu/iommu-sysfs.c index e436ff813e7e..7af76473b3e3 100644 --- a/drivers/iommu/iommu-sysfs.c +++ b/drivers/iommu/iommu-sysfs.c @@ -87,6 +87,7 @@ int iommu_device_sysfs_add(struct iommu_device *iommu, put_device(iommu->dev); return ret; } +EXPORT_SYMBOL_GPL(iommu_device_sysfs_add); void iommu_device_sysfs_remove(struct iommu_device *iommu) { @@ -119,6 +120,7 @@ int iommu_device_link(struct iommu_device *iommu, struct device *link) return ret; } +EXPORT_SYMBOL_GPL(iommu_device_link); void iommu_device_unlink(struct iommu_device *iommu, struct device *link) { @@ -128,3 +130,4 @@ void iommu_device_unlink(struct iommu_device *iommu, struct device *link) sysfs_remove_link(&link->kobj, "iommu"); sysfs_remove_link_from_group(&iommu->dev->kobj, "devices", dev_name(link)); } +EXPORT_SYMBOL_GPL(iommu_device_unlink); diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index d658c7c6a2ab..4985e1ab05db 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -141,6 +141,7 @@ int iommu_device_register(struct iommu_device *iommu) spin_unlock(&iommu_device_lock); return 0; } +EXPORT_SYMBOL_GPL(iommu_device_register); void iommu_device_unregister(struct iommu_device *iommu) { @@ -886,6 +887,7 @@ struct iommu_group *iommu_group_ref_get(struct iommu_group *group) kobject_get(group->devices_kobj); return group; } +EXPORT_SYMBOL_GPL(iommu_group_ref_get); /** * iommu_group_put - Decrement group reference @@ -1259,6 +1261,7 @@ struct iommu_group *generic_device_group(struct device *dev) { return iommu_group_alloc(); } +EXPORT_SYMBOL_GPL(generic_device_group); /* * Use standard PCI bus topology, isolation features, and DMA alias quirks @@ -1326,6 +1329,7 @@ struct iommu_group *pci_device_group(struct device *dev) /* No shared group found, allocate new */ return iommu_group_alloc(); } +EXPORT_SYMBOL_GPL(pci_device_group); /* Get the IOMMU group for device on fsl-mc bus */ struct iommu_group *fsl_mc_device_group(struct device *dev) @@ -1406,6 +1410,7 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev) return group; } +EXPORT_SYMBOL_GPL(iommu_group_get_for_dev); struct iommu_domain *iommu_group_default_domain(struct iommu_group *group) { @@ -2185,6 +2190,7 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start, region->type = type; return region; } +EXPORT_SYMBOL_GPL(iommu_alloc_resv_region); static int request_default_domain_for_dev(struct device *dev, unsigned long type) -- GitLab From 498ccd9eda49117c34e0041563d0da6ac40e52b8 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 25 Oct 2019 10:04:25 -0600 Subject: [PATCH 731/993] io_uring: used cached copies of sq->dropped and cq->overflow We currently use the ring values directly, but that can lead to issues if the application is malicious and changes these values on our behalf. Created in-kernel cached versions of them, and just overwrite the user side when we update them. This is similar to how we treat the sq/cq ring tail/head updates. Reported-by: Pavel Begunkov Reviewed-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 32f6598ecae9..292c4c733cbe 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -197,6 +197,7 @@ struct io_ring_ctx { unsigned sq_entries; unsigned sq_mask; unsigned sq_thread_idle; + unsigned cached_sq_dropped; struct io_uring_sqe *sq_sqes; struct list_head defer_list; @@ -212,6 +213,7 @@ struct io_ring_ctx { struct { unsigned cached_cq_tail; + atomic_t cached_cq_overflow; unsigned cq_entries; unsigned cq_mask; struct wait_queue_head cq_wait; @@ -420,7 +422,8 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p) static inline bool __io_sequence_defer(struct io_ring_ctx *ctx, struct io_kiocb *req) { - return req->sequence != ctx->cached_cq_tail + ctx->rings->sq_dropped; + return req->sequence != ctx->cached_cq_tail + ctx->cached_sq_dropped + + atomic_read(&ctx->cached_cq_overflow); } static inline bool io_sequence_defer(struct io_ring_ctx *ctx, @@ -567,9 +570,8 @@ static void io_cqring_fill_event(struct io_ring_ctx *ctx, u64 ki_user_data, WRITE_ONCE(cqe->res, res); WRITE_ONCE(cqe->flags, 0); } else { - unsigned overflow = READ_ONCE(ctx->rings->cq_overflow); - - WRITE_ONCE(ctx->rings->cq_overflow, overflow + 1); + WRITE_ONCE(ctx->rings->cq_overflow, + atomic_inc_return(&ctx->cached_cq_overflow)); } } @@ -2564,7 +2566,8 @@ static bool io_get_sqring(struct io_ring_ctx *ctx, struct sqe_submit *s) /* drop invalid entries */ ctx->cached_sq_head++; - rings->sq_dropped++; + ctx->cached_sq_dropped++; + WRITE_ONCE(rings->sq_dropped, ctx->cached_sq_dropped); return false; } -- GitLab From 2b2ed9750fc9d040b9f6d076afcef6f00b6f1f7c Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 25 Oct 2019 10:06:15 -0600 Subject: [PATCH 732/993] io_uring: fix bad inflight accounting for SETUP_IOPOLL|SETUP_SQTHREAD We currently assume that submissions from the sqthread are successful, and if IO polling is enabled, we use that value for knowing how many completions to look for. But if we overflowed the CQ ring or some requests simply got errored and already completed, they won't be available for polling. For the case of IO polling and SQTHREAD usage, look at the pending poll list. If it ever hits empty then we know that we don't have anymore pollable requests inflight. For that case, simply reset the inflight count to zero. Reported-by: Pavel Begunkov Reviewed-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 292c4c733cbe..a30c4f622cb3 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -874,19 +874,11 @@ static void io_iopoll_reap_events(struct io_ring_ctx *ctx) mutex_unlock(&ctx->uring_lock); } -static int io_iopoll_check(struct io_ring_ctx *ctx, unsigned *nr_events, - long min) +static int __io_iopoll_check(struct io_ring_ctx *ctx, unsigned *nr_events, + long min) { - int iters, ret = 0; + int iters = 0, ret = 0; - /* - * We disallow the app entering submit/complete with polling, but we - * still need to lock the ring to prevent racing with polled issue - * that got punted to a workqueue. - */ - mutex_lock(&ctx->uring_lock); - - iters = 0; do { int tmin = 0; @@ -922,6 +914,21 @@ static int io_iopoll_check(struct io_ring_ctx *ctx, unsigned *nr_events, ret = 0; } while (min && !*nr_events && !need_resched()); + return ret; +} + +static int io_iopoll_check(struct io_ring_ctx *ctx, unsigned *nr_events, + long min) +{ + int ret; + + /* + * We disallow the app entering submit/complete with polling, but we + * still need to lock the ring to prevent racing with polled issue + * that got punted to a workqueue. + */ + mutex_lock(&ctx->uring_lock); + ret = __io_iopoll_check(ctx, nr_events, min); mutex_unlock(&ctx->uring_lock); return ret; } @@ -2657,7 +2664,20 @@ static int io_sq_thread(void *data) unsigned nr_events = 0; if (ctx->flags & IORING_SETUP_IOPOLL) { - io_iopoll_check(ctx, &nr_events, 0); + /* + * inflight is the count of the maximum possible + * entries we submitted, but it can be smaller + * if we dropped some of them. If we don't have + * poll entries available, then we know that we + * have nothing left to poll for. Reset the + * inflight count to zero in that case. + */ + mutex_lock(&ctx->uring_lock); + if (!list_empty(&ctx->poll_list)) + __io_iopoll_check(ctx, &nr_events, 0); + else + inflight = 0; + mutex_unlock(&ctx->uring_lock); } else { /* * Normal IO, just pretend everything completed. -- GitLab From 51a518ad9034b6021f0d49feeb9ac52eff281b30 Mon Sep 17 00:00:00 2001 From: Xiaojun Sang Date: Wed, 1 Jun 2016 11:26:45 +0800 Subject: [PATCH 733/993] ANDROID: ASoC: compress: fix unsigned integer overflow check Parameter fragments and fragment_size are type of u32. U32_MAX is the correct check. CRs-Fixed: 1014726 Bug: 142489397 Change-Id: Ia6d4755408646ac4a75724f3c6f2177651875da3 Signed-off-by: Xiaojun Sang Signed-off-by: Meng Wang --- sound/core/compress_offload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index 41905afada63..f34ce564d92c 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -528,7 +528,7 @@ static int snd_compress_check_input(struct snd_compr_params *params) { /* first let's check the buffer parameter's */ if (params->buffer.fragment_size == 0 || - params->buffer.fragments > INT_MAX / params->buffer.fragment_size || + params->buffer.fragments > U32_MAX / params->buffer.fragment_size || params->buffer.fragments == 0) return -EINVAL; -- GitLab From 3cf5c714221300214767e62afd28d66248f44d20 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Mon, 21 Nov 2016 17:39:12 -0800 Subject: [PATCH 734/993] ANDROID: ALSA: jack: Update supported jack switch types Change adds support for jack switch types supported by platform. This change also squashes the below changes- include: increase allowed SW INPUT device ID from 15 to 32 Increase the Input device SW ID from 15 to 32. This is needed to accommodate more input devices. Bug: 142489397 Change-Id: If77f8b37b4db72ada2b5d8a3095265eef90ab62b Signed-off-by: Gopikrishnaiah Anandan Signed-off-by: Banajit Goswami Signed-off-by: Sudheer Papothi Signed-off-by: Meng Wang --- include/linux/mod_devicetable.h | 2 +- include/sound/jack.h | 3 --- include/uapi/linux/input-event-codes.h | 5 ++++- sound/core/jack.c | 7 +++++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 5714fd35a83c..3dbed7e030df 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -318,7 +318,7 @@ struct pcmcia_device_id { #define INPUT_DEVICE_ID_LED_MAX 0x0f #define INPUT_DEVICE_ID_SND_MAX 0x07 #define INPUT_DEVICE_ID_FF_MAX 0x7f -#define INPUT_DEVICE_ID_SW_MAX 0x0f +#define INPUT_DEVICE_ID_SW_MAX 0x20 #define INPUT_DEVICE_ID_PROP_MAX 0x1f #define INPUT_DEVICE_ID_MATCH_BUS 1 diff --git a/include/sound/jack.h b/include/sound/jack.h index 9eb2b5ec1ec4..9c2ed0aa7948 100644 --- a/include/sound/jack.h +++ b/include/sound/jack.h @@ -53,9 +53,6 @@ enum snd_jack_types { SND_JACK_BTN_5 = 0x0200, }; -/* Keep in sync with definitions above */ -#define SND_JACK_SWITCH_TYPES 6 - struct snd_jack { struct list_head kctl_list; struct snd_card *card; diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h index 85387c76c24f..35125b6c30de 100644 --- a/include/uapi/linux/input-event-codes.h +++ b/include/uapi/linux/input-event-codes.h @@ -808,7 +808,10 @@ #define SW_LINEIN_INSERT 0x0d /* set = inserted */ #define SW_MUTE_DEVICE 0x0e /* set = device disabled */ #define SW_PEN_INSERTED 0x0f /* set = pen inserted */ -#define SW_MAX 0x0f +#define SW_HPHL_OVERCURRENT 0x10 /* set = over current on left hph */ +#define SW_HPHR_OVERCURRENT 0x11 /* set = over current on right hph */ +#define SW_UNSUPPORT_INSERT 0x12 /* set = unsupported device inserted */ +#define SW_MAX 0x20 #define SW_CNT (SW_MAX+1) /* diff --git a/sound/core/jack.c b/sound/core/jack.c index fb26196571a7..e1594d0ca61f 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c @@ -19,13 +19,16 @@ struct snd_jack_kctl { }; #ifdef CONFIG_SND_JACK_INPUT_DEV -static int jack_switch_types[SND_JACK_SWITCH_TYPES] = { +static int jack_switch_types[] = { SW_HEADPHONE_INSERT, SW_MICROPHONE_INSERT, SW_LINEOUT_INSERT, SW_JACK_PHYSICAL_INSERT, SW_VIDEOOUT_INSERT, SW_LINEIN_INSERT, + SW_HPHL_OVERCURRENT, + SW_HPHR_OVERCURRENT, + SW_UNSUPPORT_INSERT, }; #endif /* CONFIG_SND_JACK_INPUT_DEV */ @@ -236,7 +239,7 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, jack->type = type; - for (i = 0; i < SND_JACK_SWITCH_TYPES; i++) + for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) if (type & (1 << i)) input_set_capability(jack->input_dev, EV_SW, jack_switch_types[i]); -- GitLab From 7a5e47a1a89af4eb773d3a314302620ec66842c1 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Wed, 7 Aug 2019 15:24:33 -0700 Subject: [PATCH 735/993] build.config.*: Link android-mainline kernels with LLD We've been building mainline x86_64 with LLD for months now, and don't plan to upgrade Android's binutils to work around issues upstream related to: commit c603a309cc75 ("x86/mm: Identify the end of the kernel area to be reserved") Bug: 138463564 Signed-off-by: Nick Desaulniers Signed-off-by: Alistair Delva Change-Id: Ic52f7f374c494e5d39efb758a7739ebd33799f49 --- build.config.common | 1 + 1 file changed, 1 insertion(+) diff --git a/build.config.common b/build.config.common index a879f6282c0f..d9895bb9ad64 100644 --- a/build.config.common +++ b/build.config.common @@ -2,6 +2,7 @@ BRANCH=android-mainline KERNEL_DIR=common CC=clang +LD=ld.lld CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r365631c/bin BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 -- GitLab From 9d6c0b6fbb95bbf793c44625fd39b3a583028ada Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Wed, 7 Aug 2019 15:27:33 -0700 Subject: [PATCH 736/993] Revert "Revert "Revert "Revert "x86/mm: Identify the end of the kernel area to be reserved"""" This reverts commit e78f95acac98aa2bc8b655a8873f7b8755f72b70. This adds back the original commit c603a309cc75 ("x86/mm: Identify the end of the kernel area to be reserved") Bug: 138463564 Signed-off-by: Nick Desaulniers Change-Id: Ia01a9b914beebf392a670f8b8238ebceeb361a1d --- arch/x86/include/asm/sections.h | 2 ++ arch/x86/kernel/setup.c | 8 +++++++- arch/x86/kernel/vmlinux.lds.S | 9 ++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h index 8ea1cfdbeabc..71b32f2570ab 100644 --- a/arch/x86/include/asm/sections.h +++ b/arch/x86/include/asm/sections.h @@ -13,4 +13,6 @@ extern char __end_rodata_aligned[]; extern char __end_rodata_hpage_align[]; #endif +extern char __end_of_kernel_reserve[]; + #endif /* _ASM_X86_SECTIONS_H */ diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index f007d910a6e6..77ea96b794bd 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -836,8 +836,14 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p) void __init setup_arch(char **cmdline_p) { + /* + * Reserve the memory occupied by the kernel between _text and + * __end_of_kernel_reserve symbols. Any kernel sections after the + * __end_of_kernel_reserve symbol must be explicitly reserved with a + * separate memblock_reserve() or they will be discarded. + */ memblock_reserve(__pa_symbol(_text), - (unsigned long)__bss_stop - (unsigned long)_text); + (unsigned long)__end_of_kernel_reserve - (unsigned long)_text); /* * Make sure page 0 is always reserved because on systems with diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 4f062d33ef73..e2feacf921a0 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -368,6 +368,14 @@ SECTIONS __bss_stop = .; } + /* + * The memory occupied from _text to here, __end_of_kernel_reserve, is + * automatically reserved in setup_arch(). Anything after here must be + * explicitly reserved using memblock_reserve() or it will be discarded + * and treated as available memory. + */ + __end_of_kernel_reserve = .; + . = ALIGN(PAGE_SIZE); .brk : AT(ADDR(.brk) - LOAD_OFFSET) { __brk_base = .; @@ -407,7 +415,6 @@ SECTIONS STABS_DEBUG DWARF_DEBUG - /* Sections to be discarded */ DISCARDS /DISCARD/ : { *(.eh_frame) -- GitLab From 6f2fe74a1b296286a65547150b733dc36837fd8d Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Fri, 25 Oct 2019 10:48:55 -0700 Subject: [PATCH 737/993] ANDROID: gki_defconfig: add FORTIFY_SOURCE, remove SPMI_MSM_PMIC_ARB Force SPMI_MSM_PMIC_ARB off and enable FORTIFY_SOURCE for GKI Bug: 142896904 Bug: 134087016 Test: Build/Boot on cuttlefish Change-Id: Ib6e501f1efee2349d750010a53572dddcb5457c5 Signed-off-by: Todd Kjos --- arch/arm64/configs/gki_defconfig | 2 ++ arch/x86/configs/gki_defconfig | 1 + 2 files changed, 3 insertions(+) diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index 80ebf75319a1..10f8ca213484 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -284,6 +284,7 @@ CONFIG_HW_RANDOM_VIRTIO=y # CONFIG_I2C_HELPER_AUTO is not set CONFIG_SPI=y CONFIG_SPMI=y +# CONFIG_SPMI_MSM_PMIC_ARB is not set CONFIG_PINCTRL_AMD=y CONFIG_POWER_AVS=y CONFIG_POWER_RESET_HISI=y @@ -449,6 +450,7 @@ CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_HARDENED_USERCOPY=y +CONFIG_FORTIFY_SOURCE=y CONFIG_SECURITY_SELINUX=y CONFIG_CRYPTO_ADIANTUM=y CONFIG_CRYPTO_MD4=y diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index 949c449b9d1f..306ad5331a48 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -384,6 +384,7 @@ CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_HARDENED_USERCOPY=y +CONFIG_FORTIFY_SOURCE=y CONFIG_SECURITY_SELINUX=y CONFIG_CRYPTO_ADIANTUM=y CONFIG_CRYPTO_SHA256_SSSE3=y -- GitLab From 649238947d688eea17d27825fdc651d693e48a33 Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Fri, 25 Oct 2019 11:39:57 -0700 Subject: [PATCH 738/993] ANDROID: init: GKI: enable hidden configs for media Add hidden configs to GKI_HACKS_to_fIX so they are enabled for loadable media modules build out-of-tree Bug: 142892658 Test: Built for arm64/x86_64. Boot on cuttlefish Change-Id: I137a89f69822332324a1f4a3a1150be9cd66709d Signed-off-by: Todd Kjos --- init/Kconfig.gki | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/init/Kconfig.gki b/init/Kconfig.gki index 4db995c2fe92..c9505a791280 100644 --- a/init/Kconfig.gki +++ b/init/Kconfig.gki @@ -53,6 +53,13 @@ config GKI_HIDDEN_QCOM_CONFIGS These are normally selected implicitely when a module that relies on it is configured. +config GKI_HIDDEN_MEDIA_CONFIGS + bool "Hidden Media configs needed for GKI" + select VIDEOBUF2_CORE + help + Dummy config option used to enable hidden media configs. + These are normally selected implicitely when a module + that relies on it is configured. # LEGACY_WEXT_ALLCONFIG Discussed upstream, soundly rejected as a unique # problem for GKI to solve. It should be noted that these extensions are @@ -89,6 +96,7 @@ config GKI_HACKS_TO_FIX select GKI_HIDDEN_GPIO_CONFIGS select GKI_HIDDEN_QCOM_CONFIGS select GKI_LEGACY_WEXT_ALLCONFIG + select GKI_HIDDEN_MEDIA_CONFIGS help Dummy config option used to enable core functionality used by modules that may not be selectable in this config. -- GitLab From 0a39c7fe727bc182ad08bfa42f1ec6324554da78 Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Fri, 25 Oct 2019 17:28:28 +0100 Subject: [PATCH 739/993] Revert "ANDROID: x86: Remove a useless warning message" This reverts commit 1f1098e0a3f04acca33961b0b352f023baf127e4. Signed-off-by: Matthias Maennich --- arch/x86/include/asm/cpufeature.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 48670eb3b4d7..59bf91c57aa8 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -154,6 +154,9 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit); * Workaround for the sake of BPF compilation which utilizes kernel * headers, but clang does not support ASM GOTO and fails the build. */ +#ifndef __BPF_TRACING__ +#warning "Compiler lacks ASM_GOTO support. Add -D __BPF_TRACING__ to your compiler arguments" +#endif #define static_cpu_has(bit) boot_cpu_has(bit) -- GitLab From de6346ecbc8f5591ebd6c44ac164e8b8671d71d7 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 21 Oct 2019 15:56:27 -0400 Subject: [PATCH 740/993] nbd: protect cmd->status with cmd->lock We already do this for the most part, except in timeout and clear_req. For the timeout case we take the lock after we grab a ref on the config, but that isn't really necessary because we're safe to touch the cmd at this point, so just move the order around. For the clear_req cause this is initiated by the user, so again is safe. Reviewed-by: Mike Christie Signed-off-by: Josef Bacik Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 478aa86fc1f2..f9e189534304 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -385,17 +385,16 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req, struct nbd_device *nbd = cmd->nbd; struct nbd_config *config; + if (!mutex_trylock(&cmd->lock)) + return BLK_EH_RESET_TIMER; + if (!refcount_inc_not_zero(&nbd->config_refs)) { cmd->status = BLK_STS_TIMEOUT; + mutex_unlock(&cmd->lock); goto done; } config = nbd->config; - if (!mutex_trylock(&cmd->lock)) { - nbd_config_put(nbd); - return BLK_EH_RESET_TIMER; - } - if (config->num_connections > 1) { dev_err_ratelimited(nbd_to_dev(nbd), "Connection timed out, retrying (%d/%d alive)\n", @@ -792,7 +791,10 @@ static bool nbd_clear_req(struct request *req, void *data, bool reserved) { struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req); + mutex_lock(&cmd->lock); cmd->status = BLK_STS_IOERR; + mutex_unlock(&cmd->lock); + blk_mq_complete_request(req); return true; } -- GitLab From 7ce23e8e0a9cd38338fc8316ac5772666b565ca9 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 21 Oct 2019 15:56:28 -0400 Subject: [PATCH 741/993] nbd: handle racing with error'ed out commands We hit the following warning in production print_req_error: I/O error, dev nbd0, sector 7213934408 flags 80700 ------------[ cut here ]------------ refcount_t: underflow; use-after-free. WARNING: CPU: 25 PID: 32407 at lib/refcount.c:190 refcount_sub_and_test_checked+0x53/0x60 Workqueue: knbd-recv recv_work [nbd] RIP: 0010:refcount_sub_and_test_checked+0x53/0x60 Call Trace: blk_mq_free_request+0xb7/0xf0 blk_mq_complete_request+0x62/0xf0 recv_work+0x29/0xa1 [nbd] process_one_work+0x1f5/0x3f0 worker_thread+0x2d/0x3d0 ? rescuer_thread+0x340/0x340 kthread+0x111/0x130 ? kthread_create_on_node+0x60/0x60 ret_from_fork+0x1f/0x30 ---[ end trace b079c3c67f98bb7c ]--- This was preceded by us timing out everything and shutting down the sockets for the device. The problem is we had a request in the queue at the same time, so we completed the request twice. This can actually happen in a lot of cases, we fail to get a ref on our config, we only have one connection and just error out the command, etc. Fix this by checking cmd->status in nbd_read_stat. We only change this under the cmd->lock, so we are safe to check this here and see if we've already error'ed this command out, which would indicate that we've completed it as well. Reviewed-by: Mike Christie Signed-off-by: Josef Bacik Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index f9e189534304..e200c7c9ddc4 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -710,6 +710,12 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) ret = -ENOENT; goto out; } + if (cmd->status != BLK_STS_OK) { + dev_err(disk_to_dev(nbd->disk), "Command already handled %p\n", + req); + ret = -ENOENT; + goto out; + } if (test_bit(NBD_CMD_REQUEUED, &cmd->flags)) { dev_err(disk_to_dev(nbd->disk), "Raced with timeout on req %p\n", req); -- GitLab From 962399bb7fbf5ce0c5b768ca7115614f31ff8f3f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 16 Oct 2019 11:51:05 +0100 Subject: [PATCH 742/993] ata: libahci_platform: Fix regulator_get_optional() misuse This driver is using regulator_get_optional() to handle all the supplies that it handles, and only ever enables and disables all supplies en masse without ever doing any other configuration of the device to handle missing power. These are clear signs that the API is being misused - it should only be used for supplies that may be physically absent from the system and in these cases the hardware usually needs different configuration if the supply is missing. Instead use normal regualtor_get(), if the supply is not described in DT then the framework will substitute a dummy regulator in so no special handling is needed by the consumer driver. In the case of the PHY regulator the handling in the driver is a hack to deal with integrated PHYs; the supplies are only optional in the sense that that there's some confusion in the code about where they're bound to. From a code point of view they function exactly as normal supplies so can be treated as such. It'd probably be better to model this by instantiating a PHY object for integrated PHYs. Reviewed-by: Hans de Goede Signed-off-by: Mark Brown Signed-off-by: Jens Axboe --- drivers/ata/libahci_platform.c | 38 +++++++++++++--------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index e742780950de..8befce036af8 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c @@ -153,17 +153,13 @@ int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv) { int rc, i; - if (hpriv->ahci_regulator) { - rc = regulator_enable(hpriv->ahci_regulator); - if (rc) - return rc; - } + rc = regulator_enable(hpriv->ahci_regulator); + if (rc) + return rc; - if (hpriv->phy_regulator) { - rc = regulator_enable(hpriv->phy_regulator); - if (rc) - goto disable_ahci_pwrs; - } + rc = regulator_enable(hpriv->phy_regulator); + if (rc) + goto disable_ahci_pwrs; for (i = 0; i < hpriv->nports; i++) { if (!hpriv->target_pwrs[i]) @@ -181,11 +177,9 @@ int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv) if (hpriv->target_pwrs[i]) regulator_disable(hpriv->target_pwrs[i]); - if (hpriv->phy_regulator) - regulator_disable(hpriv->phy_regulator); + regulator_disable(hpriv->phy_regulator); disable_ahci_pwrs: - if (hpriv->ahci_regulator) - regulator_disable(hpriv->ahci_regulator); + regulator_disable(hpriv->ahci_regulator); return rc; } EXPORT_SYMBOL_GPL(ahci_platform_enable_regulators); @@ -207,10 +201,8 @@ void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv) regulator_disable(hpriv->target_pwrs[i]); } - if (hpriv->ahci_regulator) - regulator_disable(hpriv->ahci_regulator); - if (hpriv->phy_regulator) - regulator_disable(hpriv->phy_regulator); + regulator_disable(hpriv->ahci_regulator); + regulator_disable(hpriv->phy_regulator); } EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators); /** @@ -359,7 +351,7 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port, struct regulator *target_pwr; int rc = 0; - target_pwr = regulator_get_optional(dev, "target"); + target_pwr = regulator_get(dev, "target"); if (!IS_ERR(target_pwr)) hpriv->target_pwrs[port] = target_pwr; @@ -436,16 +428,14 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev, hpriv->clks[i] = clk; } - hpriv->ahci_regulator = devm_regulator_get_optional(dev, "ahci"); + hpriv->ahci_regulator = devm_regulator_get(dev, "ahci"); if (IS_ERR(hpriv->ahci_regulator)) { rc = PTR_ERR(hpriv->ahci_regulator); - if (rc == -EPROBE_DEFER) + if (rc != 0) goto err_out; - rc = 0; - hpriv->ahci_regulator = NULL; } - hpriv->phy_regulator = devm_regulator_get_optional(dev, "phy"); + hpriv->phy_regulator = devm_regulator_get(dev, "phy"); if (IS_ERR(hpriv->phy_regulator)) { rc = PTR_ERR(hpriv->phy_regulator); if (rc == -EPROBE_DEFER) -- GitLab From cf1b2326b734896734c6e167e41766f9cee7686a Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Thu, 17 Oct 2019 16:27:34 -0500 Subject: [PATCH 743/993] nbd: verify socket is supported during setup nbd requires socket families to support the shutdown method so the nbd recv workqueue can be woken up from its sock_recvmsg call. If the socket does not support the callout we will leave recv works running or get hangs later when the device or module is removed. This adds a check during socket connection/reconnection to make sure the socket being passed in supports the needed callout. Reported-by: syzbot+24c12fa8d218ed26011a@syzkaller.appspotmail.com Fixes: e9e006f5fcf2 ("nbd: fix max number of supported devs") Tested-by: Richard W.M. Jones Signed-off-by: Mike Christie Signed-off-by: Jens Axboe --- drivers/block/nbd.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index e200c7c9ddc4..a94ee45440b3 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -980,6 +980,25 @@ static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx, return ret; } +static struct socket *nbd_get_socket(struct nbd_device *nbd, unsigned long fd, + int *err) +{ + struct socket *sock; + + *err = 0; + sock = sockfd_lookup(fd, err); + if (!sock) + return NULL; + + if (sock->ops->shutdown == sock_no_shutdown) { + dev_err(disk_to_dev(nbd->disk), "Unsupported socket: shutdown callout must be supported.\n"); + *err = -EINVAL; + return NULL; + } + + return sock; +} + static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, bool netlink) { @@ -989,7 +1008,7 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, struct nbd_sock *nsock; int err; - sock = sockfd_lookup(arg, &err); + sock = nbd_get_socket(nbd, arg, &err); if (!sock) return err; @@ -1041,7 +1060,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg) int i; int err; - sock = sockfd_lookup(arg, &err); + sock = nbd_get_socket(nbd, arg, &err); if (!sock) return err; -- GitLab From fa784f2ac00e19edc0d6eb77ac791bc1eb366d7e Mon Sep 17 00:00:00 2001 From: Vincent Prince Date: Tue, 22 Oct 2019 17:09:50 +0200 Subject: [PATCH 744/993] net: sch_generic: Use pfifo_fast as fallback scheduler for CAN hardware There is networking hardware that isn't based on Ethernet for layers 1 and 2. For example CAN. CAN is a multi-master serial bus standard for connecting Electronic Control Units [ECUs] also known as nodes. A frame on the CAN bus carries up to 8 bytes of payload. Frame corruption is detected by a CRC. However frame loss due to corruption is possible, but a quite unusual phenomenon. While fq_codel works great for TCP/IP, it doesn't for CAN. There are a lot of legacy protocols on top of CAN, which are not build with flow control or high CAN frame drop rates in mind. When using fq_codel, as soon as the queue reaches a certain delay based length, skbs from the head of the queue are silently dropped. Silently meaning that the user space using a send() or similar syscall doesn't get an error. However TCP's flow control algorithm will detect dropped packages and adjust the bandwidth accordingly. When using fq_codel and sending raw frames over CAN, which is the common use case, the user space thinks the package has been sent without problems, because send() returned without an error. pfifo_fast will drop skbs, if the queue length exceeds the maximum. But with this scheduler the skbs at the tail are dropped, an error (-ENOBUFS) is propagated to user space. So that the user space can slow down the package generation. On distributions, where fq_codel is made default via CONFIG_DEFAULT_NET_SCH during compile time, or set default during runtime with sysctl net.core.default_qdisc (see [1]), we get a bad user experience. In my test case with pfifo_fast, I can transfer thousands of million CAN frames without a frame drop. On the other hand with fq_codel there is more then one lost CAN frame per thousand frames. As pointed out fq_codel is not suited for CAN hardware, so this patch changes attach_one_default_qdisc() to use pfifo_fast for "ARPHRD_CAN" network devices. During transition of a netdev from down to up state the default queuing discipline is attached by attach_default_qdiscs() with the help of attach_one_default_qdisc(). This patch modifies attach_one_default_qdisc() to attach the pfifo_fast (pfifo_fast_ops) if the network device type is "ARPHRD_CAN". [1] https://github.com/systemd/systemd/issues/9194 Signed-off-by: Vincent Prince Signed-off-by: David S. Miller --- net/sched/sch_generic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index b2d34c49cbe6..8769b4b8807d 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -1038,6 +1038,8 @@ static void attach_one_default_qdisc(struct net_device *dev, if (dev->priv_flags & IFF_NO_QUEUE) ops = &noqueue_qdisc_ops; + else if(dev->type == ARPHRD_CAN) + ops = &pfifo_fast_ops; qdisc = qdisc_create_dflt(dev_queue, ops, TC_H_ROOT, NULL); if (!qdisc) { -- GitLab From 3f6b2c4420610cf0882b395338c0daee15dc102d Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Wed, 23 Oct 2019 11:01:08 +0100 Subject: [PATCH 745/993] net: mvneta: make stub functions static inline If the CONFIG_MVNET_BA is not set, then make the stub functions static inline to avoid trying to export them, and remove hte following sparse warnings: drivers/net/ethernet/marvell/mvneta_bm.h:163:6: warning: symbol 'mvneta_bm_pool_destroy' was not declared. Should it be static? drivers/net/ethernet/marvell/mvneta_bm.h:165:6: warning: symbol 'mvneta_bm_bufs_free' was not declared. Should it be static? drivers/net/ethernet/marvell/mvneta_bm.h:167:5: warning: symbol 'mvneta_bm_construct' was not declared. Should it be static? drivers/net/ethernet/marvell/mvneta_bm.h:168:5: warning: symbol 'mvneta_bm_pool_refill' was not declared. Should it be static? drivers/net/ethernet/marvell/mvneta_bm.h:170:23: warning: symbol 'mvneta_bm_pool_use' was not declared. Should it be static? drivers/net/ethernet/marvell/mvneta_bm.h:181:18: warning: symbol 'mvneta_bm_get' was not declared. Should it be static? drivers/net/ethernet/marvell/mvneta_bm.h:182:6: warning: symbol 'mvneta_bm_put' was not declared. Should it be static? Signed-off-by: Ben Dooks (Codethink) Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta_bm.h | 32 +++++++++++++++--------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvneta_bm.h b/drivers/net/ethernet/marvell/mvneta_bm.h index c8425d35c049..e47783ce77e0 100644 --- a/drivers/net/ethernet/marvell/mvneta_bm.h +++ b/drivers/net/ethernet/marvell/mvneta_bm.h @@ -160,16 +160,23 @@ static inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv, (bm_pool->id << MVNETA_BM_POOL_ACCESS_OFFS)); } #else -void mvneta_bm_pool_destroy(struct mvneta_bm *priv, - struct mvneta_bm_pool *bm_pool, u8 port_map) {} -void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, - u8 port_map) {} -int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf) { return 0; } -int mvneta_bm_pool_refill(struct mvneta_bm *priv, - struct mvneta_bm_pool *bm_pool) {return 0; } -struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id, - enum mvneta_bm_type type, u8 port_id, - int pkt_size) { return NULL; } +static inline void mvneta_bm_pool_destroy(struct mvneta_bm *priv, + struct mvneta_bm_pool *bm_pool, + u8 port_map) {} +static inline void mvneta_bm_bufs_free(struct mvneta_bm *priv, + struct mvneta_bm_pool *bm_pool, + u8 port_map) {} +static inline int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf) +{ return 0; } +static inline int mvneta_bm_pool_refill(struct mvneta_bm *priv, + struct mvneta_bm_pool *bm_pool) +{ return 0; } +static inline struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, + u8 pool_id, + enum mvneta_bm_type type, + u8 port_id, + int pkt_size) +{ return NULL; } static inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, @@ -178,7 +185,8 @@ static inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv, static inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool) { return 0; } -struct mvneta_bm *mvneta_bm_get(struct device_node *node) { return NULL; } -void mvneta_bm_put(struct mvneta_bm *priv) {} +static inline struct mvneta_bm *mvneta_bm_get(struct device_node *node) +{ return NULL; } +static inline void mvneta_bm_put(struct mvneta_bm *priv) {} #endif /* CONFIG_MVNETA_BM */ #endif -- GitLab From 18b7a1479ed8c9ac9ecc40171a445c371a2eca79 Mon Sep 17 00:00:00 2001 From: Connor O'Brien Date: Tue, 19 Feb 2019 17:36:53 -0800 Subject: [PATCH 746/993] ANDROID: cpufreq: create dummy cpufreq driver /proc/uid_time_in_state has no data on cuttlefish because its cpu frequency tables are empty. Because time in state & concurrent time accounting are intertwined this causes the /proc/uid_concurrent_{policy,active}_time files to also not contain any data. Add a minimal, fake cpufreq driver that creates a freq table with 2 frequencies per policy, to allow testing time in state functionality. Test: all 3 proc files show reasonable data on cuttlefish Test: log shows no errors from bad /proc/uid_time_in_state format Bug: 139763108 Bug: 140796321 Bug: 141206930 Change-Id: I8c7fe1007a80c21a9bcba9455bf837947cf42963 Signed-off-by: Connor O'Brien --- arch/arm64/configs/gki_defconfig | 1 + arch/x86/configs/gki_defconfig | 1 + drivers/cpufreq/Kconfig | 9 ++++++ drivers/cpufreq/Makefile | 2 ++ drivers/cpufreq/dummy-cpufreq.c | 54 ++++++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+) create mode 100644 drivers/cpufreq/dummy-cpufreq.c diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index 10f8ca213484..74858518d011 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -61,6 +61,7 @@ CONFIG_CPU_FREQ_TIMES=y CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPUFREQ_DUMMY=m CONFIG_ARM_SCPI_CPUFREQ=y CONFIG_ARM_SCMI_CPUFREQ=y CONFIG_ARM_SCMI_PROTOCOL=y diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index 306ad5331a48..ba629336a4f2 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -46,6 +46,7 @@ CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set CONFIG_CPU_FREQ_TIMES=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPUFREQ_DUMMY=m CONFIG_IA32_EMULATION=y CONFIG_KPROBES=y CONFIG_MODULES=y diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index f711715aa579..2075100319fb 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -229,6 +229,15 @@ config CPUFREQ_DT_PLATDEV If in doubt, say N. +config CPUFREQ_DUMMY + tristate "Dummy CPU frequency driver" + help + This option adds a generic dummy CPUfreq driver, which sets a fake + 2-frequency table when initializing each policy and otherwise does + nothing. + + If in doubt, say N + if X86 source "drivers/cpufreq/Kconfig.x86" endif diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 93d52a112cab..33d6b64f9203 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -20,6 +20,8 @@ obj-$(CONFIG_CPU_FREQ_GOV_ATTR_SET) += cpufreq_governor_attr_set.o obj-$(CONFIG_CPUFREQ_DT) += cpufreq-dt.o obj-$(CONFIG_CPUFREQ_DT_PLATDEV) += cpufreq-dt-platdev.o +obj-$(CONFIG_CPUFREQ_DUMMY) += dummy-cpufreq.o + ################################################################################## # x86 drivers. # Link order matters. K8 is preferred to ACPI because of firmware bugs in early diff --git a/drivers/cpufreq/dummy-cpufreq.c b/drivers/cpufreq/dummy-cpufreq.c new file mode 100644 index 000000000000..914f3e39ca9b --- /dev/null +++ b/drivers/cpufreq/dummy-cpufreq.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 Google, Inc. + */ +#include +#include + +static struct cpufreq_frequency_table freq_table[] = { + { .frequency = 1 }, + { .frequency = 2 }, + { .frequency = CPUFREQ_TABLE_END }, +}; + +static int dummy_cpufreq_target_index(struct cpufreq_policy *policy, + unsigned int index) +{ + return 0; +} + +static int dummy_cpufreq_driver_init(struct cpufreq_policy *policy) +{ + policy->freq_table = freq_table; + return 0; +} + +static int dummy_cpufreq_verify(struct cpufreq_policy *policy) +{ + return 0; +} + +static struct cpufreq_driver dummy_cpufreq_driver = { + .name = "dummy", + .target_index = dummy_cpufreq_target_index, + .init = dummy_cpufreq_driver_init, + .verify = dummy_cpufreq_verify, + .attr = cpufreq_generic_attr, +}; + +static int __init dummy_cpufreq_init(void) +{ + return cpufreq_register_driver(&dummy_cpufreq_driver); +} + +static void __exit dummy_cpufreq_exit(void) +{ + cpufreq_unregister_driver(&dummy_cpufreq_driver); +} + +module_init(dummy_cpufreq_init); +module_exit(dummy_cpufreq_exit); + +MODULE_AUTHOR("Connor O'Brien "); +MODULE_DESCRIPTION("dummy cpufreq driver"); +MODULE_LICENSE("GPL"); -- GitLab From 91e2e57636f163837e1aea2ce6c4995b8a2a6f10 Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Wed, 23 Oct 2019 11:01:39 +0100 Subject: [PATCH 747/993] net: hwbm: if CONFIG_NET_HWBM unset, make stub functions static If CONFIG_NET_HWBM is not set, then these stub functions in should be declared static to avoid trying to export them from any driver that includes this. Fixes the following sparse warnings: ./include/net/hwbm.h:24:6: warning: symbol 'hwbm_buf_free' was not declared. Should it be static? ./include/net/hwbm.h:25:5: warning: symbol 'hwbm_pool_refill' was not declared. Should it be static? ./include/net/hwbm.h:26:5: warning: symbol 'hwbm_pool_add' was not declared. Should it be static? Signed-off-by: Ben Dooks (Codethink) Signed-off-by: David S. Miller --- include/net/hwbm.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/include/net/hwbm.h b/include/net/hwbm.h index 81643cf8a1c4..c81444611a22 100644 --- a/include/net/hwbm.h +++ b/include/net/hwbm.h @@ -21,9 +21,13 @@ void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf); int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp); int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num); #else -void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf) {} -int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp) { return 0; } -int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num) +static inline void hwbm_buf_free(struct hwbm_pool *bm_pool, void *buf) {} + +static inline int hwbm_pool_refill(struct hwbm_pool *bm_pool, gfp_t gfp) +{ return 0; } + +static inline int hwbm_pool_add(struct hwbm_pool *bm_pool, + unsigned int buf_num) { return 0; } #endif /* CONFIG_HWBM */ #endif /* _HWBM_H */ -- GitLab From e8f44c50dfe75315d1ff6efc837d62cbe7368c9b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 17 Oct 2019 19:37:30 +0200 Subject: [PATCH 748/993] riscv: cleanup do_trap_break If we always compile the get_break_insn_length inline function we can remove the ifdefs and let dead code elimination take care of the warn branch that is now unreadable because the report_bug stub always returns BUG_TRAP_TYPE_BUG. Signed-off-by: Christoph Hellwig Reviewed-by: Anup Patel Signed-off-by: Paul Walmsley --- arch/riscv/kernel/traps.c | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index 1ac75f7d0bff..10a17e545f43 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -111,7 +111,6 @@ DO_ERROR_INFO(do_trap_ecall_s, DO_ERROR_INFO(do_trap_ecall_m, SIGILL, ILL_ILLTRP, "environment call from M-mode"); -#ifdef CONFIG_GENERIC_BUG static inline unsigned long get_break_insn_length(unsigned long pc) { bug_insn_t insn; @@ -120,28 +119,15 @@ static inline unsigned long get_break_insn_length(unsigned long pc) return 0; return (((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) ? 4UL : 2UL); } -#endif /* CONFIG_GENERIC_BUG */ asmlinkage void do_trap_break(struct pt_regs *regs) { - if (user_mode(regs)) { - force_sig_fault(SIGTRAP, TRAP_BRKPT, - (void __user *)(regs->sepc)); - return; - } -#ifdef CONFIG_GENERIC_BUG - { - enum bug_trap_type type; - - type = report_bug(regs->sepc, regs); - if (type == BUG_TRAP_TYPE_WARN) { - regs->sepc += get_break_insn_length(regs->sepc); - return; - } - } -#endif /* CONFIG_GENERIC_BUG */ - - die(regs, "Kernel BUG"); + if (user_mode(regs)) + force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->sepc); + else if (report_bug(regs->sepc, regs) == BUG_TRAP_TYPE_WARN) + regs->sepc += get_break_insn_length(regs->sepc); + else + die(regs, "Kernel BUG"); } #ifdef CONFIG_GENERIC_BUG -- GitLab From 6e1eaaea3c36672d0ae7ae0d531449b7917d8078 Mon Sep 17 00:00:00 2001 From: Jason Macnak Date: Fri, 25 Oct 2019 13:40:37 -0700 Subject: [PATCH 749/993] ANDROID: Allow DRM_IOCTL_MODE_*_DUMB for render clients. Minigbm uses dumb ioctls when the virtio gpu is in 2D mode. This changes allows those calls to pass the permission checks in drm_ioctl_permit(). Bug: b/123764798 Test: booted cuttlefish on drm stack w/o 3d Change-Id: I872ba8f6d0a284127178dd60f8a2048e5e7397fb Signed-off-by: Jason Macnak Signed-off-by: Alistair Delva --- drivers/gpu/drm/drm_ioctl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index fcd728d7cf72..e293cf7bc35c 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -676,9 +676,9 @@ static const struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb_ioctl, 0), DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, 0), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, 0), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, 0), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, 0), DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER), -- GitLab From 39bb6b4242ff4426bb9f2d032e5a1e4e5f8c2db8 Mon Sep 17 00:00:00 2001 From: lesl Date: Tue, 1 Oct 2019 17:56:50 +0800 Subject: [PATCH 750/993] ANDROID: virt_wifi: Add data ops for scan data simulation Bug: 139421123 Signed-off-by: lesl Change-Id: Ib686dffe23cc234937af7e383182834721f01d78 Signed-off-by: Alistair Delva --- drivers/net/wireless/virt_wifi.c | 48 ++++++++++++++++++++++++++++++-- include/net/virt_wifi.h | 25 +++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 include/net/virt_wifi.h diff --git a/drivers/net/wireless/virt_wifi.c b/drivers/net/wireless/virt_wifi.c index be92e1220284..355cc629190c 100644 --- a/drivers/net/wireless/virt_wifi.c +++ b/drivers/net/wireless/virt_wifi.c @@ -13,6 +13,7 @@ #include #include #include +#include static struct wiphy *common_wiphy; @@ -20,6 +21,7 @@ struct virt_wifi_wiphy_priv { struct delayed_work scan_result; struct cfg80211_scan_request *scan_request; bool being_deleted; + struct virt_wifi_network_simulation *network_simulation; }; static struct ieee80211_channel channel_2ghz = { @@ -148,6 +150,9 @@ static int virt_wifi_scan(struct wiphy *wiphy, priv->scan_request = request; schedule_delayed_work(&priv->scan_result, HZ * 2); + if (priv->network_simulation && + priv->network_simulation->notify_scan_trigger) + priv->network_simulation->notify_scan_trigger(wiphy, request); return 0; } @@ -178,6 +183,12 @@ static void virt_wifi_scan_result(struct work_struct *work) DBM_TO_MBM(-50), GFP_KERNEL); cfg80211_put_bss(wiphy, informed_bss); + if(priv->network_simulation && + priv->network_simulation->generate_virt_scan_result) { + if(priv->network_simulation->generate_virt_scan_result(wiphy)) + wiphy_err(wiphy, "Fail to generater the simulated scan result.\n"); + } + /* Schedules work which acquires and releases the rtnl lock. */ cfg80211_scan_done(priv->scan_request, &scan_info); priv->scan_request = NULL; @@ -365,6 +376,8 @@ static struct wiphy *virt_wifi_make_wiphy(void) priv = wiphy_priv(wiphy); priv->being_deleted = false; priv->scan_request = NULL; + priv->network_simulation = NULL; + INIT_DELAYED_WORK(&priv->scan_result, virt_wifi_scan_result); err = wiphy_register(wiphy); @@ -380,7 +393,6 @@ static struct wiphy *virt_wifi_make_wiphy(void) static void virt_wifi_destroy_wiphy(struct wiphy *wiphy) { struct virt_wifi_wiphy_priv *priv; - WARN(!wiphy, "%s called with null wiphy", __func__); if (!wiphy) return; @@ -414,8 +426,13 @@ static netdev_tx_t virt_wifi_start_xmit(struct sk_buff *skb, static int virt_wifi_net_device_open(struct net_device *dev) { struct virt_wifi_netdev_priv *priv = netdev_priv(dev); - + struct virt_wifi_wiphy_priv *w_priv; priv->is_up = true; + w_priv = wiphy_priv(dev->ieee80211_ptr->wiphy); + if(w_priv->network_simulation && + w_priv->network_simulation->notify_device_open) + w_priv->network_simulation->notify_device_open(dev); + return 0; } @@ -423,16 +440,22 @@ static int virt_wifi_net_device_open(struct net_device *dev) static int virt_wifi_net_device_stop(struct net_device *dev) { struct virt_wifi_netdev_priv *n_priv = netdev_priv(dev); + struct virt_wifi_wiphy_priv *w_priv; n_priv->is_up = false; if (!dev->ieee80211_ptr) return 0; + w_priv = wiphy_priv(dev->ieee80211_ptr->wiphy); virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy); virt_wifi_cancel_connect(dev); netif_carrier_off(dev); + if (w_priv->network_simulation && + w_priv->network_simulation->notify_device_stop) + w_priv->network_simulation->notify_device_stop(dev); + return 0; } @@ -617,6 +640,27 @@ static void __exit virt_wifi_cleanup_module(void) virt_wifi_destroy_wiphy(common_wiphy); } +int virt_wifi_register_network_simulation + (struct virt_wifi_network_simulation *ops) +{ + struct virt_wifi_wiphy_priv *priv = wiphy_priv(common_wiphy); + if (priv->network_simulation) + return -EEXIST; + priv->network_simulation = ops; + return 0; +} +EXPORT_SYMBOL(virt_wifi_register_network_simulation); + +int virt_wifi_unregister_network_simulation(void) +{ + struct virt_wifi_wiphy_priv *priv = wiphy_priv(common_wiphy); + if(!priv->network_simulation) + return -ENODATA; + priv->network_simulation = NULL; + return 0; +} +EXPORT_SYMBOL(virt_wifi_unregister_network_simulation); + module_init(virt_wifi_init_module); module_exit(virt_wifi_cleanup_module); diff --git a/include/net/virt_wifi.h b/include/net/virt_wifi.h new file mode 100644 index 000000000000..343e73968d41 --- /dev/null +++ b/include/net/virt_wifi.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* include/net/virt_wifi.h + * + * Define the extension interface for the network data simulation + * + * Copyright (C) 2019 Google, Inc. + * + * Author: lesl@google.com + */ +#ifndef __VIRT_WIFI_H +#define __VIRT_WIFI_H + +struct virt_wifi_network_simulation { + void (*notify_device_open)(struct net_device *dev); + void (*notify_device_stop)(struct net_device *dev); + void (*notify_scan_trigger)(struct wiphy *wiphy, + struct cfg80211_scan_request *request); + int (*generate_virt_scan_result)(struct wiphy *wiphy); +}; + +int virt_wifi_register_network_simulation( + struct virt_wifi_network_simulation *ops); +int virt_wifi_unregister_network_simulation(void); +#endif + -- GitLab From f536dffc0b79738c3104af999318279dccbaa261 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Wed, 23 Oct 2019 15:44:05 +0200 Subject: [PATCH 751/993] net/smc: fix closing of fallback SMC sockets For SMC sockets forced to fallback to TCP, the file is propagated from the outer SMC to the internal TCP socket. When closing the SMC socket, the internal TCP socket file pointer must be restored to the original NULL value, otherwise memory leaks may show up (found with CONFIG_DEBUG_KMEMLEAK). The internal TCP socket is released in smc_clcsock_release(), which calls __sock_release() function in net/socket.c. This calls the needed iput(SOCK_INODE(sock)) only, if the file pointer has been reset to the original NULL-value. Fixes: 07603b230895 ("net/smc: propagate file from SMC to TCP socket") Signed-off-by: Ursula Braun Signed-off-by: Karsten Graul Signed-off-by: David S. Miller --- net/smc/af_smc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 5b932583e407..d9566e84f2f9 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -123,6 +123,12 @@ struct proto smc_proto6 = { }; EXPORT_SYMBOL_GPL(smc_proto6); +static void smc_restore_fallback_changes(struct smc_sock *smc) +{ + smc->clcsock->file->private_data = smc->sk.sk_socket; + smc->clcsock->file = NULL; +} + static int __smc_release(struct smc_sock *smc) { struct sock *sk = &smc->sk; @@ -141,6 +147,7 @@ static int __smc_release(struct smc_sock *smc) } sk->sk_state = SMC_CLOSED; sk->sk_state_change(sk); + smc_restore_fallback_changes(smc); } sk->sk_prot->unhash(sk); -- GitLab From ca5f8d2dd5229ccacdd5cfde1ce4d32b0810e454 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Wed, 23 Oct 2019 15:44:06 +0200 Subject: [PATCH 752/993] net/smc: keep vlan_id for SMC-R in smc_listen_work() Creating of an SMC-R connection with vlan-id fails, because smc_listen_work() determines the vlan_id of the connection, saves it in struct smc_init_info ini, but clears the ini area again if SMC-D is not applicable. This patch just resets the ISM device before investigating SMC-R availability. Fixes: bc36d2fc93eb ("net/smc: consolidate function parameters") Signed-off-by: Ursula Braun Signed-off-by: Karsten Graul Signed-off-by: David S. Miller --- net/smc/af_smc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index d9566e84f2f9..cea3c36ea0da 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -1298,8 +1298,8 @@ static void smc_listen_work(struct work_struct *work) /* check if RDMA is available */ if (!ism_supported) { /* SMC_TYPE_R or SMC_TYPE_B */ /* prepare RDMA check */ - memset(&ini, 0, sizeof(ini)); ini.is_smcd = false; + ini.ism_dev = NULL; ini.ib_lcl = &pclc->lcl; rc = smc_find_rdma_device(new_smc, &ini); if (rc) { -- GitLab From 16d65287927e06b5c6c522d8d479def36c19844b Mon Sep 17 00:00:00 2001 From: Nishad Kamdar Date: Wed, 23 Oct 2019 20:56:38 +0530 Subject: [PATCH 753/993] net: ethernet: Use the correct style for SPDX License Identifier This patch corrects the SPDX License Identifier style in header file related to ethernet driver for Cortina Gemini devices. For C header files Documentation/process/license-rules.rst mandates C-like comments (opposed to C source files where C++ style should be used) Changes made by using a script provided by Joe Perches here: https://lkml.org/lkml/2019/2/7/46. Suggested-by: Joe Perches Signed-off-by: Nishad Kamdar Acked-by: Linus Walleij Signed-off-by: David S. Miller --- drivers/net/ethernet/cortina/gemini.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cortina/gemini.h b/drivers/net/ethernet/cortina/gemini.h index 0b12f89bf89a..9fdf77d5eb37 100644 --- a/drivers/net/ethernet/cortina/gemini.h +++ b/drivers/net/ethernet/cortina/gemini.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* Register definitions for Gemini GMAC Ethernet device driver * * Copyright (C) 2006 Storlink, Corp. -- GitLab From d4e4fdf9e4a27c87edb79b1478955075be141f67 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Wed, 23 Oct 2019 18:39:04 +0200 Subject: [PATCH 754/993] netns: fix GFP flags in rtnl_net_notifyid() In rtnl_net_notifyid(), we certainly can't pass a null GFP flag to rtnl_notify(). A GFP_KERNEL flag would be fine in most circumstances, but there are a few paths calling rtnl_net_notifyid() from atomic context or from RCU critical sections. The later also precludes the use of gfp_any() as it wouldn't detect the RCU case. Also, the nlmsg_new() call is wrong too, as it uses GFP_KERNEL unconditionally. Therefore, we need to pass the GFP flags as parameter and propagate it through function calls until the proper flags can be determined. In most cases, GFP_KERNEL is fine. The exceptions are: * openvswitch: ovs_vport_cmd_get() and ovs_vport_cmd_dump() indirectly call rtnl_net_notifyid() from RCU critical section, * rtnetlink: rtmsg_ifinfo_build_skb() already receives GFP flags as parameter. Also, in ovs_vport_cmd_build_info(), let's change the GFP flags used by nlmsg_new(). The function is allowed to sleep, so better make the flags consistent with the ones used in the following ovs_vport_cmd_fill_info() call. Found by code inspection. Fixes: 9a9634545c70 ("netns: notify netns id events") Signed-off-by: Guillaume Nault Acked-by: Nicolas Dichtel Acked-by: Pravin B Shelar Signed-off-by: David S. Miller --- include/net/net_namespace.h | 2 +- net/core/dev.c | 2 +- net/core/net_namespace.c | 17 +++++++++-------- net/core/rtnetlink.c | 14 +++++++------- net/openvswitch/datapath.c | 20 +++++++++++--------- 5 files changed, 29 insertions(+), 26 deletions(-) diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 4c2cd9378699..c7e15a213ef2 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -342,7 +342,7 @@ static inline struct net *read_pnet(const possible_net_t *pnet) #define __net_initconst __initconst #endif -int peernet2id_alloc(struct net *net, struct net *peer); +int peernet2id_alloc(struct net *net, struct net *peer, gfp_t gfp); int peernet2id(struct net *net, struct net *peer); bool peernet_has_id(struct net *net, struct net *peer); struct net *get_net_ns_by_id(struct net *net, int id); diff --git a/net/core/dev.c b/net/core/dev.c index 1482e2ef2d25..96afd464284a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -9770,7 +9770,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char call_netdevice_notifiers(NETDEV_UNREGISTER, dev); rcu_barrier(); - new_nsid = peernet2id_alloc(dev_net(dev), net); + new_nsid = peernet2id_alloc(dev_net(dev), net, GFP_KERNEL); /* If there is an ifindex conflict assign a new one */ if (__dev_get_by_index(net, dev->ifindex)) new_ifindex = dev_new_index(net); diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 5a4ae0845bac..39402840025e 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -246,11 +246,11 @@ static int __peernet2id(struct net *net, struct net *peer) } static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid, - struct nlmsghdr *nlh); + struct nlmsghdr *nlh, gfp_t gfp); /* This function returns the id of a peer netns. If no id is assigned, one will * be allocated and returned. */ -int peernet2id_alloc(struct net *net, struct net *peer) +int peernet2id_alloc(struct net *net, struct net *peer, gfp_t gfp) { bool alloc = false, alive = false; int id; @@ -269,7 +269,7 @@ int peernet2id_alloc(struct net *net, struct net *peer) id = __peernet2id_alloc(net, peer, &alloc); spin_unlock_bh(&net->nsid_lock); if (alloc && id >= 0) - rtnl_net_notifyid(net, RTM_NEWNSID, id, 0, NULL); + rtnl_net_notifyid(net, RTM_NEWNSID, id, 0, NULL, gfp); if (alive) put_net(peer); return id; @@ -534,7 +534,8 @@ static void unhash_nsid(struct net *net, struct net *last) idr_remove(&tmp->netns_ids, id); spin_unlock_bh(&tmp->nsid_lock); if (id >= 0) - rtnl_net_notifyid(tmp, RTM_DELNSID, id, 0, NULL); + rtnl_net_notifyid(tmp, RTM_DELNSID, id, 0, NULL, + GFP_KERNEL); if (tmp == last) break; } @@ -767,7 +768,7 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh, spin_unlock_bh(&net->nsid_lock); if (err >= 0) { rtnl_net_notifyid(net, RTM_NEWNSID, err, NETLINK_CB(skb).portid, - nlh); + nlh, GFP_KERNEL); err = 0; } else if (err == -ENOSPC && nsid >= 0) { err = -EEXIST; @@ -1055,7 +1056,7 @@ static int rtnl_net_dumpid(struct sk_buff *skb, struct netlink_callback *cb) } static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid, - struct nlmsghdr *nlh) + struct nlmsghdr *nlh, gfp_t gfp) { struct net_fill_args fillargs = { .portid = portid, @@ -1066,7 +1067,7 @@ static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid, struct sk_buff *msg; int err = -ENOMEM; - msg = nlmsg_new(rtnl_net_get_size(), GFP_KERNEL); + msg = nlmsg_new(rtnl_net_get_size(), gfp); if (!msg) goto out; @@ -1074,7 +1075,7 @@ static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid, if (err < 0) goto err_out; - rtnl_notify(msg, net, portid, RTNLGRP_NSID, nlh, 0); + rtnl_notify(msg, net, portid, RTNLGRP_NSID, nlh, gfp); return; err_out: diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 13493aae4e6c..ba4b4048ec3e 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1523,7 +1523,7 @@ static noinline_for_stack int nla_put_ifalias(struct sk_buff *skb, static int rtnl_fill_link_netnsid(struct sk_buff *skb, const struct net_device *dev, - struct net *src_net) + struct net *src_net, gfp_t gfp) { bool put_iflink = false; @@ -1531,7 +1531,7 @@ static int rtnl_fill_link_netnsid(struct sk_buff *skb, struct net *link_net = dev->rtnl_link_ops->get_link_net(dev); if (!net_eq(dev_net(dev), link_net)) { - int id = peernet2id_alloc(src_net, link_net); + int id = peernet2id_alloc(src_net, link_net, gfp); if (nla_put_s32(skb, IFLA_LINK_NETNSID, id)) return -EMSGSIZE; @@ -1589,7 +1589,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, int type, u32 pid, u32 seq, u32 change, unsigned int flags, u32 ext_filter_mask, u32 event, int *new_nsid, int new_ifindex, - int tgt_netnsid) + int tgt_netnsid, gfp_t gfp) { struct ifinfomsg *ifm; struct nlmsghdr *nlh; @@ -1681,7 +1681,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, goto nla_put_failure; } - if (rtnl_fill_link_netnsid(skb, dev, src_net)) + if (rtnl_fill_link_netnsid(skb, dev, src_net, gfp)) goto nla_put_failure; if (new_nsid && @@ -2001,7 +2001,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) NETLINK_CB(cb->skb).portid, nlh->nlmsg_seq, 0, flags, ext_filter_mask, 0, NULL, 0, - netnsid); + netnsid, GFP_KERNEL); if (err < 0) { if (likely(skb->len)) @@ -3360,7 +3360,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh, err = rtnl_fill_ifinfo(nskb, dev, net, RTM_NEWLINK, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0, 0, ext_filter_mask, - 0, NULL, 0, netnsid); + 0, NULL, 0, netnsid, GFP_KERNEL); if (err < 0) { /* -EMSGSIZE implies BUG in if_nlmsg_size */ WARN_ON(err == -EMSGSIZE); @@ -3472,7 +3472,7 @@ struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev, err = rtnl_fill_ifinfo(skb, dev, dev_net(dev), type, 0, 0, change, 0, 0, event, - new_nsid, new_ifindex, -1); + new_nsid, new_ifindex, -1, flags); if (err < 0) { /* -EMSGSIZE implies BUG in if_nlmsg_size() */ WARN_ON(err == -EMSGSIZE); diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index f30e406fbec5..d8c364d637b1 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -1881,7 +1881,7 @@ static struct genl_family dp_datapath_genl_family __ro_after_init = { /* Called with ovs_mutex or RCU read lock. */ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, struct net *net, u32 portid, u32 seq, - u32 flags, u8 cmd) + u32 flags, u8 cmd, gfp_t gfp) { struct ovs_header *ovs_header; struct ovs_vport_stats vport_stats; @@ -1902,7 +1902,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, goto nla_put_failure; if (!net_eq(net, dev_net(vport->dev))) { - int id = peernet2id_alloc(net, dev_net(vport->dev)); + int id = peernet2id_alloc(net, dev_net(vport->dev), gfp); if (nla_put_s32(skb, OVS_VPORT_ATTR_NETNSID, id)) goto nla_put_failure; @@ -1943,11 +1943,12 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, struct net *net, struct sk_buff *skb; int retval; - skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!skb) return ERR_PTR(-ENOMEM); - retval = ovs_vport_cmd_fill_info(vport, skb, net, portid, seq, 0, cmd); + retval = ovs_vport_cmd_fill_info(vport, skb, net, portid, seq, 0, cmd, + GFP_KERNEL); BUG_ON(retval < 0); return skb; @@ -2089,7 +2090,7 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info), info->snd_portid, info->snd_seq, 0, - OVS_VPORT_CMD_NEW); + OVS_VPORT_CMD_NEW, GFP_KERNEL); new_headroom = netdev_get_fwd_headroom(vport->dev); @@ -2150,7 +2151,7 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info) err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info), info->snd_portid, info->snd_seq, 0, - OVS_VPORT_CMD_SET); + OVS_VPORT_CMD_SET, GFP_KERNEL); BUG_ON(err < 0); ovs_unlock(); @@ -2190,7 +2191,7 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info) err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info), info->snd_portid, info->snd_seq, 0, - OVS_VPORT_CMD_DEL); + OVS_VPORT_CMD_DEL, GFP_KERNEL); BUG_ON(err < 0); /* the vport deletion may trigger dp headroom update */ @@ -2237,7 +2238,7 @@ static int ovs_vport_cmd_get(struct sk_buff *skb, struct genl_info *info) goto exit_unlock_free; err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info), info->snd_portid, info->snd_seq, 0, - OVS_VPORT_CMD_GET); + OVS_VPORT_CMD_GET, GFP_ATOMIC); BUG_ON(err < 0); rcu_read_unlock(); @@ -2273,7 +2274,8 @@ static int ovs_vport_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, NLM_F_MULTI, - OVS_VPORT_CMD_GET) < 0) + OVS_VPORT_CMD_GET, + GFP_ATOMIC) < 0) goto out; j++; -- GitLab From 7c3bebc3d8688b84795c11848c314a2fbfe045e0 Mon Sep 17 00:00:00 2001 From: Raju Rangoju Date: Wed, 23 Oct 2019 23:03:55 +0530 Subject: [PATCH 755/993] cxgb4: request the TX CIDX updates to status page For adapters which support the SGE Doorbell Queue Timer facility, we configured the Ethernet TX Queues to send CIDX Updates to the Associated Ethernet RX Response Queue with CPL_SGE_EGR_UPDATE messages to allow us to respond more quickly to the CIDX Updates. But, this was adding load to PCIe Link RX bandwidth and, potentially, resulting in higher CPU Interrupt load. This patch requests the HW to deliver the CIDX updates to the TX queue status page rather than generating an ingress queue message (as an interrupt). With this patch, the load on RX bandwidth is reduced and a substantial improvement in BW is noticed at lower IO sizes. Fixes: d429005fdf2c ("cxgb4/cxgb4vf: Add support for SGE doorbell queue timer") Signed-off-by: Raju Rangoju Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/sge.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index b3da81e90132..928bfea5457b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -3791,15 +3791,11 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, * write the CIDX Updates into the Status Page at the end of the * TX Queue. */ - c.autoequiqe_to_viid = htonl((dbqt - ? FW_EQ_ETH_CMD_AUTOEQUIQE_F - : FW_EQ_ETH_CMD_AUTOEQUEQE_F) | + c.autoequiqe_to_viid = htonl(FW_EQ_ETH_CMD_AUTOEQUEQE_F | FW_EQ_ETH_CMD_VIID_V(pi->viid)); c.fetchszm_to_iqid = - htonl(FW_EQ_ETH_CMD_HOSTFCMODE_V(dbqt - ? HOSTFCMODE_INGRESS_QUEUE_X - : HOSTFCMODE_STATUS_PAGE_X) | + htonl(FW_EQ_ETH_CMD_HOSTFCMODE_V(HOSTFCMODE_STATUS_PAGE_X) | FW_EQ_ETH_CMD_PCIECHN_V(pi->tx_chan) | FW_EQ_ETH_CMD_FETCHRO_F | FW_EQ_ETH_CMD_IQID_V(iqid)); -- GitLab From f2bbdbcb075f3977a53da3bdcb7cd460bc8ae5f2 Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Sat, 26 Oct 2019 12:06:20 +0900 Subject: [PATCH 756/993] ALSA: bebob: Fix prototype of helper function to return negative value A helper function of ALSA bebob driver returns negative value in a function which has a prototype to return unsigned value. This commit fixes it by changing the prototype. Fixes: eb7b3a056cd8 ("ALSA: bebob: Add commands and connections/streams management") Cc: # v3.16+ Signed-off-by: Takashi Sakamoto Link: https://lore.kernel.org/r/20191026030620.12077-1-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai --- sound/firewire/bebob/bebob_stream.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c index 73fee991bd75..6c1497d9f52b 100644 --- a/sound/firewire/bebob/bebob_stream.c +++ b/sound/firewire/bebob/bebob_stream.c @@ -252,8 +252,7 @@ int snd_bebob_stream_get_clock_src(struct snd_bebob *bebob, return err; } -static unsigned int -map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s) +static int map_data_channels(struct snd_bebob *bebob, struct amdtp_stream *s) { unsigned int sec, sections, ch, channels; unsigned int pcm, midi, location; -- GitLab From 5ff223e86f5addbfae26419cbb5d61d98f6fbf7d Mon Sep 17 00:00:00 2001 From: zhanglin Date: Sat, 26 Oct 2019 15:54:16 +0800 Subject: [PATCH 757/993] net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol() memset() the structure ethtool_wolinfo that has padded bytes but the padded bytes have not been zeroed out. Signed-off-by: zhanglin Signed-off-by: David S. Miller --- net/core/ethtool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index c763106c73fc..cd9bc67381b2 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1396,11 +1396,13 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr) static int ethtool_get_wol(struct net_device *dev, char __user *useraddr) { - struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; + struct ethtool_wolinfo wol; if (!dev->ethtool_ops->get_wol) return -EOPNOTSUPP; + memset(&wol, 0, sizeof(struct ethtool_wolinfo)); + wol.cmd = ETHTOOL_GWOL; dev->ethtool_ops->get_wol(dev, &wol); if (copy_to_user(useraddr, &wol, sizeof(wol))) -- GitLab From 0b834ba00ab5337e938c727e216e1f5249794717 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Sat, 26 Oct 2019 11:53:39 +0200 Subject: [PATCH 758/993] ipv4: fix route update on metric change. Since commit af4d768ad28c ("net/ipv4: Add support for specifying metric of connected routes"), when updating an IP address with a different metric, the associated connected route is updated, too. Still, the mentioned commit doesn't handle properly some corner cases: $ ip addr add dev eth0 192.168.1.0/24 $ ip addr add dev eth0 192.168.2.1/32 peer 192.168.2.2 $ ip addr add dev eth0 192.168.3.1/24 $ ip addr change dev eth0 192.168.1.0/24 metric 10 $ ip addr change dev eth0 192.168.2.1/32 peer 192.168.2.2 metric 10 $ ip addr change dev eth0 192.168.3.1/24 metric 10 $ ip -4 route 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.0 192.168.2.2 dev eth0 proto kernel scope link src 192.168.2.1 192.168.3.0/24 dev eth0 proto kernel scope link src 192.168.2.1 metric 10 Only the last route is correctly updated. The problem is the current test in fib_modify_prefix_metric(): if (!(dev->flags & IFF_UP) || ifa->ifa_flags & (IFA_F_SECONDARY | IFA_F_NOPREFIXROUTE) || ipv4_is_zeronet(prefix) || prefix == ifa->ifa_local || ifa->ifa_prefixlen == 32) Which should be the logical 'not' of the pre-existing test in fib_add_ifaddr(): if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags & IFA_F_SECONDARY) && (prefix != addr || ifa->ifa_prefixlen < 32)) To properly negate the original expression, we need to change the last logical 'or' to a logical 'and'. Fixes: af4d768ad28c ("net/ipv4: Add support for specifying metric of connected routes") Reported-and-suggested-by: Beniamino Galvani Signed-off-by: Paolo Abeni Reviewed-by: David Ahern Signed-off-by: David S. Miller --- net/ipv4/fib_frontend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index dde77f72e03e..71c78d223dfd 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -1148,7 +1148,7 @@ void fib_modify_prefix_metric(struct in_ifaddr *ifa, u32 new_metric) if (!(dev->flags & IFF_UP) || ifa->ifa_flags & (IFA_F_SECONDARY | IFA_F_NOPREFIXROUTE) || ipv4_is_zeronet(prefix) || - prefix == ifa->ifa_local || ifa->ifa_prefixlen == 32) + (prefix == ifa->ifa_local && ifa->ifa_prefixlen == 32)) return; /* add the new */ -- GitLab From 37de3b354150450ba12275397155e68113e99901 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Sat, 26 Oct 2019 11:53:40 +0200 Subject: [PATCH 759/993] selftests: fib_tests: add more tests for metric update This patch adds two more tests to ipv4_addr_metric_test() to explicitly cover the scenarios fixed by the previous patch. Suggested-by: David Ahern Signed-off-by: Paolo Abeni Reviewed-by: David Ahern Signed-off-by: David S. Miller --- tools/testing/selftests/net/fib_tests.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh index c4ba0ff4a53f..76c1897e6352 100755 --- a/tools/testing/selftests/net/fib_tests.sh +++ b/tools/testing/selftests/net/fib_tests.sh @@ -1438,6 +1438,27 @@ ipv4_addr_metric_test() fi log_test $rc 0 "Prefix route with metric on link up" + # explicitly check for metric changes on edge scenarios + run_cmd "$IP addr flush dev dummy2" + run_cmd "$IP addr add dev dummy2 172.16.104.0/24 metric 259" + run_cmd "$IP addr change dev dummy2 172.16.104.0/24 metric 260" + rc=$? + if [ $rc -eq 0 ]; then + check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.0 metric 260" + rc=$? + fi + log_test $rc 0 "Modify metric of .0/24 address" + + run_cmd "$IP addr flush dev dummy2" + run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260" + run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 261" + rc=$? + if [ $rc -eq 0 ]; then + check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261" + rc=$? + fi + log_test $rc 0 "Modify metric of address with peer route" + $IP li del dummy1 $IP li del dummy2 cleanup -- GitLab From f8978f4f6a5ed1babb76f7f98c98050a73c666bc Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Thu, 24 Oct 2019 17:07:24 -0700 Subject: [PATCH 760/993] ANDROID: add README.md Add md file to communicate requirements for patches submitted to common kernel Change-Id: I92c3d8a6c40d8a8e5e9cfc9cb42887a5a858faf9 Signed-off-by: Todd Kjos --- README.md | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000000..8a2dd85e5a3f --- /dev/null +++ b/README.md @@ -0,0 +1,142 @@ +# How do I submit patches to Android Common Kernels + +1. BEST: Make all of your changes to upstream Linux. If appropriate, backport to the stable releases. + These patches will be merged automatically in the corresponding common kernels. If the patch is already + in upstream Linux, post a backport of the patch that conforms to the patch requirements below. + +2. LESS GOOD: Develop your patches out-of-tree (from an upstream Linux point-of-view). Unless these are + fixing an Android-specific bug, these are very unlikely to be accepted unless they have been + coordinated with kernel-team@android.com. If you want to proceed, post a patch that conforms to the + patch requirements below. + +# Common Kernel patch requirements + +- All patches must conform to the Linux kernel coding standards and pass `script/checkpatch.pl` +- Patches shall not break gki_defconfig or allmodconfig builds for arm, arm64, x86, x86_64 architectures +(see https://source.android.com/setup/build/building-kernels) +- If the patch is not merged from an upstream branch, the subject must be tagged with the type of patch: +`UPSTREAM:`, `BACKPORT:`, `FROMGIT:`, `FROMLIST:`, or `ANDROID:`. +- All patches must have a `Change-Id:` tag (see https://gerrit-review.googlesource.com/Documentation/user-changeid.html) +- If an Android bug has been assigned, there must be a `Bug:` tag. +- All patches must have a `Signed-off-by:` tag by the author and the submitter + +Additional requirements are listed below based on patch type + +## Requirements for backports from mainline Linux: `UPSTREAM:`, `BACKPORT:` + +- If the patch is a cherry-pick from Linux mainline with no changes at all + - tag the patch subject with `UPSTREAM:`. + - add upstream commit information with a `(cherry-picked from ...)` line + - Example: + - if the upstream commit message is +``` + important patch from upstream + + This is the detailed description of the important patch + + Signed-off-by: Fred Jones +``` + - then Joe Smith would upload the patch for the common kernel as +``` + UPSTREAM: important patch from upstream + + This is the detailed description of the important patch + + Signed-off-by: Fred Jones + + Bug: 135791357 + Change-Id: I4caaaa566ea080fa148c5e768bb1a0b6f7201c01 + (cherry-picked from c31e73121f4c1ec41143423ac6ce3ce6dafdcec1) + Signed-off-by: Joe Smith +``` + +- If the patch requires any changes from the upstream version, tag the patch with `BACKPORT:` +instead of `UPSTREAM:`. + - use the same tags as `UPSTREAM:` + - add comments about the changes under the `(cherry-picked from ...)` line + - Example: +``` + BACKPORT: important patch from upstream + + This is the detailed description of the important patch + + Signed-off-by: Fred Jones + + Bug: 135791357 + Change-Id: I4caaaa566ea080fa148c5e768bb1a0b6f7201c01 + (cherry-picked from c31e73121f4c1ec41143423ac6ce3ce6dafdcec1) + [ Resolved minor conflict in drivers/foo/bar.c ] + Signed-off-by: Joe Smith +``` + +## Requirements for other backports: `FROMGIT:`, `FROMLIST:`, + +- If the patch has been merged into an upstream maintainer tree, but has not yet +been merged into Linux mainline + - tag the patch subject with `FROMGIT:` + - add info on where the patch came from as `(cherry picked from commit )`. This +must be a stable maintainer branch (not rebased, so don't use `linux-next` for example). + - if changes were required, use `BACKPORT: FROMGIT:` + - Example: + - if the commit message in the maintainer tree is +``` + important patch from upstream + + This is the detailed description of the important patch + + Signed-off-by: Fred Jones +``` + - then Joe Smith would upload the patch for the common kernel as +``` + FROMGIT: important patch from upstream + + This is the detailed description of the important patch + + Signed-off-by: Fred Jones + + Bug: 135791357 + (cherry picked from commit 878a2fd9de10b03d11d2f622250285c7e63deace + https://git.kernel.org/pub/scm/linux/kernel/git/foo/bar.git test-branch) + Change-Id: I4caaaa566ea080fa148c5e768bb1a0b6f7201c01 + Signed-off-by: Joe Smith +``` + + +- If the patch has been submitted to LKML, but not accepted into any maintainer tree + - tag the patch subject with `FROMLIST:` + - add a `List:` tag with a link to the submittal on lore.kernel.org + - if changes were required, use `BACKPORT: FROMLIST:` + - Example: +``` + FROMLIST: important patch from upstream + + This is the detailed description of the important patch + + Signed-off-by: Fred Jones + + Bug: 135791357 + Link: https://lore.kernel.org/lkml/20190619171517.GA17557@someone.com/ + Change-Id: I4caaaa566ea080fa148c5e768bb1a0b6f7201c01 + Signed-off-by: Joe Smith +``` + +## Requirements for Android-specific patches: `ANDROID:` + +- If the patch is fixing a bug to Android-specific code + - tag the patch subject with `ANDROID:` + - add a `Fixes:` tag that cites the patch with the bug + - Example: +``` + ANDROID: fix android-specific bug in foobar.c + + This is the detailed description of the important fix + + Fixes: 1234abcd2468 ("foobar: add cool feature") + Change-Id: I4caaaa566ea080fa148c5e768bb1a0b6f7201c01 + Signed-off-by: Joe Smith +``` + +- If the patch is a new feature + - tag the patch subject with `ANDROID:` + - add a `Bug:` tag with the Android bug (required for android-specific features) + -- GitLab From a51bab592fbbef10f0e42a8aed86adfbf6a68fa7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 21 Oct 2019 16:18:36 +0200 Subject: [PATCH 761/993] usb: dwc3: select CONFIG_REGMAP_MMIO After many randconfig builds, one configuration caused a link error with dwc3-meson-g12a lacking the regmap-mmio code: drivers/usb/dwc3/dwc3-meson-g12a.o: In function `dwc3_meson_g12a_probe': dwc3-meson-g12a.c:(.text+0x9f): undefined reference to `__devm_regmap_init_mmio_clk' Add the select statement that we have for all other users of that dependency. Fixes: c99993376f72 ("usb: dwc3: Add Amlogic G12A DWC3 glue") Acked-by: Neil Armstrong Signed-off-by: Arnd Bergmann Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 89abc6078703..556a876c7896 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -102,6 +102,7 @@ config USB_DWC3_MESON_G12A depends on ARCH_MESON || COMPILE_TEST default USB_DWC3 select USB_ROLE_SWITCH + select REGMAP_MMIO help Support USB2/3 functionality in Amlogic G12A platforms. Say 'Y' or 'M' if you have one such device. -- GitLab From bc1e3a2dd0c9954fd956ac43ca2876bbea018c01 Mon Sep 17 00:00:00 2001 From: Nikhil Badola Date: Mon, 21 Oct 2019 18:21:51 +0800 Subject: [PATCH 762/993] usb: fsl: Check memory resource before releasing it Check memory resource existence before releasing it to avoid NULL pointer dereference Signed-off-by: Nikhil Badola Reviewed-by: Ran Wang Reviewed-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/fsl_udc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index 20141c3096f6..9a05863b2876 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -2576,7 +2576,7 @@ static int fsl_udc_remove(struct platform_device *pdev) dma_pool_destroy(udc_controller->td_pool); free_irq(udc_controller->irq, udc_controller); iounmap(dr_regs); - if (pdata->operating_mode == FSL_USB2_DR_DEVICE) + if (res && (pdata->operating_mode == FSL_USB2_DR_DEVICE)) release_mem_region(res->start, resource_size(res)); /* free udc --wait for the release() finished */ -- GitLab From b26a4052cf9a93672f154976de14705fbf8a8179 Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Thu, 17 Oct 2019 18:27:17 +0100 Subject: [PATCH 763/993] usb: mtu3: fix missing include of mtu3_dr.h The declarations of ssusb_gadget_{init,exit} are in the mtu3_dr.h file but the code does that implements them does not include this. Add the include to fix the following sparse warnigns: drivers/usb/mtu3/mtu3_core.c:825:5: warning: symbol 'ssusb_gadget_init' was not declared. Should it be static? drivers/usb/mtu3/mtu3_core.c:925:6: warning: symbol 'ssusb_gadget_exit' was not declared. Should it be static? Acked-by: Chunfeng Yun Signed-off-by: Ben Dooks Signed-off-by: Felipe Balbi --- drivers/usb/mtu3/mtu3_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c index c3d5c1206eec..9dd02160cca9 100644 --- a/drivers/usb/mtu3/mtu3_core.c +++ b/drivers/usb/mtu3/mtu3_core.c @@ -16,6 +16,7 @@ #include #include "mtu3.h" +#include "mtu3_dr.h" #include "mtu3_debug.h" #include "mtu3_trace.h" -- GitLab From 5053691a7d62a4ad1566aa923e33f5d21a8016f0 Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Thu, 17 Oct 2019 13:44:27 +0100 Subject: [PATCH 764/993] usb: cdns3: include host-export,h for cdns3_host_init The cdns3_host_init() function is declared in host-export.h but host.c does not include it. Add the include to have the declaration present (and remove the declaration of cdns3_host_exit which is now static). Fixes the following sparse warning: drivers/usb/cdns3/host.c:58:5: warning: symbol 'cdns3_host_init' was not declared. Should it be static? Signed-off-by: Ben Dooks Signed-off-by: Felipe Balbi --- drivers/usb/cdns3/host-export.h | 1 - drivers/usb/cdns3/host.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/cdns3/host-export.h b/drivers/usb/cdns3/host-export.h index b498a170b7e8..ae11810f8826 100644 --- a/drivers/usb/cdns3/host-export.h +++ b/drivers/usb/cdns3/host-export.h @@ -12,7 +12,6 @@ #ifdef CONFIG_USB_CDNS3_HOST int cdns3_host_init(struct cdns3 *cdns); -void cdns3_host_exit(struct cdns3 *cdns); #else diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c index 2733a8f71fcd..ad788bf3fe4f 100644 --- a/drivers/usb/cdns3/host.c +++ b/drivers/usb/cdns3/host.c @@ -12,6 +12,7 @@ #include #include "core.h" #include "drd.h" +#include "host-export.h" static int __cdns3_host_init(struct cdns3 *cdns) { -- GitLab From 2457b2c1b44eeb022308bd524b34fa9b3ac3da11 Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Tue, 15 Oct 2019 16:50:44 +0100 Subject: [PATCH 765/993] usb: renesas_usbhs: fix __le16 warnings Fix the warnings generated by casting to/from __le16 without using the correct functions. Fixes the following sparse warnings: drivers/usb/renesas_usbhs/common.c:165:25: warning: incorrect type in assignment (different base types) drivers/usb/renesas_usbhs/common.c:165:25: expected restricted __le16 [usertype] wValue drivers/usb/renesas_usbhs/common.c:165:25: got unsigned short drivers/usb/renesas_usbhs/common.c:166:25: warning: incorrect type in assignment (different base types) drivers/usb/renesas_usbhs/common.c:166:25: expected restricted __le16 [usertype] wIndex drivers/usb/renesas_usbhs/common.c:166:25: got unsigned short drivers/usb/renesas_usbhs/common.c:167:25: warning: incorrect type in assignment (different base types) drivers/usb/renesas_usbhs/common.c:167:25: expected restricted __le16 [usertype] wLength drivers/usb/renesas_usbhs/common.c:167:25: got unsigned short drivers/usb/renesas_usbhs/common.c:173:39: warning: incorrect type in argument 3 (different base types) drivers/usb/renesas_usbhs/common.c:173:39: expected unsigned short [usertype] data drivers/usb/renesas_usbhs/common.c:173:39: got restricted __le16 [usertype] wValue drivers/usb/renesas_usbhs/common.c:174:39: warning: incorrect type in argument 3 (different base types) drivers/usb/renesas_usbhs/common.c:174:39: expected unsigned short [usertype] data drivers/usb/renesas_usbhs/common.c:174:39: got restricted __le16 [usertype] wIndex drivers/usb/renesas_usbhs/common.c:175:39: warning: incorrect type in argument 3 (different base types) drivers/usb/renesas_usbhs/common.c:175:39: expected unsigned short [usertype] data Note. I belive this to be correct, and should be a no-op on arm. Reviewed-by: Geert Uytterhoeven Reviewed-by: Yoshihiro Shimoda Signed-off-by: Ben Dooks Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/common.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 4c3de777ef6c..a3c30b609433 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -162,17 +162,17 @@ void usbhs_usbreq_get_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req) req->bRequest = (val >> 8) & 0xFF; req->bRequestType = (val >> 0) & 0xFF; - req->wValue = usbhs_read(priv, USBVAL); - req->wIndex = usbhs_read(priv, USBINDX); - req->wLength = usbhs_read(priv, USBLENG); + req->wValue = cpu_to_le16(usbhs_read(priv, USBVAL)); + req->wIndex = cpu_to_le16(usbhs_read(priv, USBINDX)); + req->wLength = cpu_to_le16(usbhs_read(priv, USBLENG)); } void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req) { usbhs_write(priv, USBREQ, (req->bRequest << 8) | req->bRequestType); - usbhs_write(priv, USBVAL, req->wValue); - usbhs_write(priv, USBINDX, req->wIndex); - usbhs_write(priv, USBLENG, req->wLength); + usbhs_write(priv, USBVAL, le16_to_cpu(req->wValue)); + usbhs_write(priv, USBINDX, le16_to_cpu(req->wIndex)); + usbhs_write(priv, USBLENG, le16_to_cpu(req->wLength)); usbhs_bset(priv, DCPCTR, SUREQ, SUREQ); } -- GitLab From ef48aacf860bc0bf24a0e9afee1f1a12cebf1155 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 16 Oct 2019 13:38:28 +0900 Subject: [PATCH 766/993] usb: gadget: udc: renesas_usb3: Fix __le16 warnings This patch fixes the following sparse warnings by using a macro and a suitable variable type. drivers/usb/gadget/udc/renesas_usb3.c:1547:17: warning: restricted __le16 degrades to integer drivers/usb/gadget/udc/renesas_usb3.c:1550:43: warning: incorrect type in argument 2 (different base types) drivers/usb/gadget/udc/renesas_usb3.c:1550:43: expected unsigned short [usertype] addr drivers/usb/gadget/udc/renesas_usb3.c:1550:43: got restricted __le16 [usertype] wValue drivers/usb/gadget/udc/renesas_usb3.c:1607:24: warning: incorrect type in assignment (different base types) drivers/usb/gadget/udc/renesas_usb3.c:1607:24: expected unsigned short [assigned] [usertype] status drivers/usb/gadget/udc/renesas_usb3.c:1607:24: got restricted __le16 [usertype] drivers/usb/gadget/udc/renesas_usb3.c:1775:17: warning: restricted __le16 degrades to integer Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/renesas_usb3.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index e098f16c01cb..33703140233a 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -1544,10 +1544,10 @@ static void usb3_set_device_address(struct renesas_usb3 *usb3, u16 addr) static bool usb3_std_req_set_address(struct renesas_usb3 *usb3, struct usb_ctrlrequest *ctrl) { - if (ctrl->wValue >= 128) + if (le16_to_cpu(ctrl->wValue) >= 128) return true; /* stall */ - usb3_set_device_address(usb3, ctrl->wValue); + usb3_set_device_address(usb3, le16_to_cpu(ctrl->wValue)); usb3_set_p0_con_for_no_data(usb3); return false; @@ -1582,6 +1582,7 @@ static bool usb3_std_req_get_status(struct renesas_usb3 *usb3, struct renesas_usb3_ep *usb3_ep; int num; u16 status = 0; + __le16 tx_data; switch (ctrl->bRequestType & USB_RECIP_MASK) { case USB_RECIP_DEVICE: @@ -1604,10 +1605,10 @@ static bool usb3_std_req_get_status(struct renesas_usb3 *usb3, } if (!stall) { - status = cpu_to_le16(status); + tx_data = cpu_to_le16(status); dev_dbg(usb3_to_dev(usb3), "get_status: req = %p\n", usb_req_to_usb3_req(usb3->ep0_req)); - usb3_pipe0_internal_xfer(usb3, &status, sizeof(status), + usb3_pipe0_internal_xfer(usb3, &tx_data, sizeof(tx_data), usb3_pipe0_get_status_completion); } @@ -1772,7 +1773,7 @@ static bool usb3_std_req_set_sel(struct renesas_usb3 *usb3, static bool usb3_std_req_set_configuration(struct renesas_usb3 *usb3, struct usb_ctrlrequest *ctrl) { - if (ctrl->wValue > 0) + if (le16_to_cpu(ctrl->wValue) > 0) usb3_set_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON); else usb3_clear_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON); -- GitLab From 20ee71cc374a4933808f735354cb4fd949d657c7 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 16 Oct 2019 13:14:33 +0900 Subject: [PATCH 767/993] usb: renesas_usbhs: Fix warnings in usbhsg_recip_handler_std_set_device() This patch fixes the following sparse warnings by shifting 8-bits after le16_to_cpu(). drivers/usb/renesas_usbhs/mod_gadget.c:268:47: warning: restricted __le16 degrades to integer drivers/usb/renesas_usbhs/mod_gadget.c:268:47: warning: cast to restricted __le16 Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/mod_gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index e5ef56991dba..efc40bc1f68c 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -265,7 +265,7 @@ static int usbhsg_recip_handler_std_set_device(struct usbhs_priv *priv, case USB_DEVICE_TEST_MODE: usbhsg_recip_handler_std_control_done(priv, uep, ctrl); udelay(100); - usbhs_sys_set_test_mode(priv, le16_to_cpu(ctrl->wIndex >> 8)); + usbhs_sys_set_test_mode(priv, le16_to_cpu(ctrl->wIndex) >> 8); break; default: usbhsg_recip_handler_std_control_done(priv, uep, ctrl); -- GitLab From e92f30ac37d12756aeb733538ad85df2be7e139f Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Tue, 15 Oct 2019 16:30:17 +0100 Subject: [PATCH 768/993] usb: renesas_usbhs: fix type of buf Fix the type of buf in __usbhsg_recip_send_status to be __le16 to avoid the following sparse warning: drivers/usb/renesas_usbhs/mod_gadget.c:335:14: warning: incorrect type in assignment (different base types) drivers/usb/renesas_usbhs/mod_gadget.c:335:14: expected unsigned short drivers/usb/renesas_usbhs/mod_gadget.c:335:14: got restricted __le16 [usertype] Reviewed-by: Yoshihiro Shimoda Signed-off-by: Ben Dooks Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/mod_gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index efc40bc1f68c..cd38d74b3223 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -315,7 +315,7 @@ static void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv, struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); struct device *dev = usbhsg_gpriv_to_dev(gpriv); struct usb_request *req; - unsigned short *buf; + __le16 *buf; /* alloc new usb_request for recip */ req = usb_ep_alloc_request(&dcp->ep, GFP_ATOMIC); -- GitLab From ba3a1a915c49cc3023e4ddfc88f21e7514e82aa4 Mon Sep 17 00:00:00 2001 From: Cristian Birsan Date: Fri, 4 Oct 2019 20:10:54 +0300 Subject: [PATCH 769/993] usb: gadget: udc: atmel: Fix interrupt storm in FIFO mode. Fix interrupt storm generated by endpoints when working in FIFO mode. The TX_COMPLETE interrupt is used only by control endpoints processing. Do not enable it for other types of endpoints. Fixes: 914a3f3b3754 ("USB: add atmel_usba_udc driver") Signed-off-by: Cristian Birsan Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/atmel_usba_udc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 86ffc8307864..1d0d8952a74b 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -449,9 +449,11 @@ static void submit_request(struct usba_ep *ep, struct usba_request *req) next_fifo_transaction(ep, req); if (req->last_transaction) { usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY); - usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE); + if (ep_is_control(ep)) + usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE); } else { - usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); + if (ep_is_control(ep)) + usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY); } } -- GitLab From 1c20c89b0421b52b2417bb0f62a611bc669eda1d Mon Sep 17 00:00:00 2001 From: Chandana Kishori Chiluveru Date: Tue, 1 Oct 2019 13:16:48 +0530 Subject: [PATCH 770/993] usb: gadget: composite: Fix possible double free memory bug composite_dev_cleanup call from the failure of configfs_composite_bind frees up the cdev->os_desc_req and cdev->req. If the previous calls of bind and unbind is successful these will carry stale values. Consider the below sequence of function calls: configfs_composite_bind() composite_dev_prepare() - Allocate cdev->req, cdev->req->buf composite_os_desc_req_prepare() - Allocate cdev->os_desc_req, cdev->os_desc_req->buf configfs_composite_unbind() composite_dev_cleanup() - free the cdev->os_desc_req->buf and cdev->req->buf Next composition switch configfs_composite_bind() - If it fails goto err_comp_cleanup will call the composite_dev_cleanup() function composite_dev_cleanup() - calls kfree up with the stale values of cdev->req->buf and cdev->os_desc_req from the previous configfs_composite_bind call. The free call on these stale values leads to double free. Hence, Fix this issue by setting request and buffer pointer to NULL after kfree. Signed-off-by: Chandana Kishori Chiluveru Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index d516e8d6cd7f..5ec54b69c29c 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2170,14 +2170,18 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev) usb_ep_dequeue(cdev->gadget->ep0, cdev->os_desc_req); kfree(cdev->os_desc_req->buf); + cdev->os_desc_req->buf = NULL; usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req); + cdev->os_desc_req = NULL; } if (cdev->req) { if (cdev->setup_pending) usb_ep_dequeue(cdev->gadget->ep0, cdev->req); kfree(cdev->req->buf); + cdev->req->buf = NULL; usb_ep_free_request(cdev->gadget->ep0, cdev->req); + cdev->req = NULL; } cdev->next_string_id = 0; device_remove_file(&cdev->gadget->dev, &dev_attr_suspended); -- GitLab From 9bbfceea12a8f145097a27d7c7267af25893c060 Mon Sep 17 00:00:00 2001 From: Navid Emamdoost Date: Sun, 29 Sep 2019 21:41:45 -0500 Subject: [PATCH 771/993] usb: dwc3: pci: prevent memory leak in dwc3_pci_probe In dwc3_pci_probe a call to platform_device_alloc allocates a device which is correctly put in case of error except one case: when the call to platform_device_add_properties fails it directly returns instead of going to error handling. This commit replaces return with the goto. Fixes: 1a7b12f69a94 ("usb: dwc3: pci: Supply device properties via driver data") Signed-off-by: Navid Emamdoost Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 5e8e18222f92..023f0357efd7 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -258,7 +258,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) ret = platform_device_add_properties(dwc->dwc3, p); if (ret < 0) - return ret; + goto err; ret = dwc3_pci_quirks(dwc); if (ret) -- GitLab From 1a1c851bbd706ea9f3a9756c2d3db28523506d3b Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Mon, 26 Aug 2019 15:10:55 -0400 Subject: [PATCH 772/993] usb: gadget: configfs: fix concurrent issue between composite APIs We meet several NULL pointer issues if configfs_composite_unbind and composite_setup (or composite_disconnect) are running together. These issues occur when do the function switch stress test, the configfs_compsoite_unbind is called from user mode by echo "" to /sys/../UDC entry, and meanwhile, the setup interrupt or disconnect interrupt occurs by hardware. The composite_setup will get the cdev from get_gadget_data, but configfs_composite_unbind will set gadget data as NULL, so the NULL pointer issue occurs. This concurrent is hard to reproduce by native kernel, but can be reproduced by android kernel. In this commit, we introduce one spinlock belongs to structure gadget_info since we can't use the same spinlock in usb_composite_dev due to exclusive running together between composite_setup and configfs_composite_unbind. And one bit flag 'unbind' to indicate the code is at unbind routine, this bit is needed due to we release the lock at during configfs_composite_unbind sometimes, and composite_setup may be run at that time. Several oops: oops 1: android_work: sent uevent USB_STATE=CONNECTED configfs-gadget gadget: super-speed config #1: b android_work: sent uevent USB_STATE=CONFIGURED init: Received control message 'start' for 'adbd' from pid: 3515 (system_server) Unable to handle kernel NULL pointer dereference at virtual address 0000002a init: Received control message 'stop' for 'adbd' from pid: 3375 (/vendor/bin/hw/android.hardware.usb@1.1-servic) Mem abort info: Exception class = DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 Data abort info: ISV = 0, ISS = 0x00000004 CM = 0, WnR = 0 user pgtable: 4k pages, 48-bit VAs, pgd = ffff8008f1b7f000 [000000000000002a] *pgd=0000000000000000 Internal error: Oops: 96000004 [#1] PREEMPT SMP Modules linked in: CPU: 4 PID: 2457 Comm: irq/125-5b11000 Not tainted 4.14.98-07846-g0b40a9b-dirty #16 Hardware name: Freescale i.MX8QM MEK (DT) task: ffff8008f2a98000 task.stack: ffff00000b7b8000 PC is at composite_setup+0x44/0x1508 LR is at android_setup+0xb8/0x13c pc : [] lr : [] pstate: 800001c5 sp : ffff00000b7bbb80 x29: ffff00000b7bbb80 x28: ffff8008f2a3c010 x27: 0000000000000001 x26: 0000000000000000 [1232/1897] audit: audit_lost=25791 audit_rate_limit=5 audit_backlog_limit=64 x25: 00000000ffffffa1 x24: ffff8008f2a3c010 audit: rate limit exceeded x23: 0000000000000409 x22: ffff000009c8e000 x21: ffff8008f7a8b428 x20: ffff00000afae000 x19: ffff0000089ff000 x18: 0000000000000000 x17: 0000000000000000 x16: ffff0000082b7c9c x15: 0000000000000000 x14: f1866f5b952aca46 x13: e35502e30d44349c x12: 0000000000000008 x11: 0000000000000008 x10: 0000000000000a30 x9 : ffff00000b7bbd00 x8 : ffff8008f2a98a90 x7 : ffff8008f27a9c90 x6 : 0000000000000001 x5 : 0000000000000000 x4 : 0000000000000001 x3 : 0000000000000000 x2 : 0000000000000006 x1 : ffff0000089ff8d0 x0 : 732a010310b9ed00 X7: 0xffff8008f27a9c10: 9c10 00000002 00000000 00000001 00000000 13110000 ffff0000 00000002 00208040 9c30 00000000 00000000 00000000 00000000 00000000 00000005 00000029 00000000 9c50 00051778 00000001 f27a8e00 ffff8008 00000005 00000000 00000078 00000078 9c70 00000078 00000000 09031d48 ffff0000 00100000 00000000 00400000 00000000 9c90 00000001 00000000 00000000 00000000 00000000 00000000 ffefb1a0 ffff8008 9cb0 f27a9ca8 ffff8008 00000000 00000000 b9d88037 00000173 1618a3eb 00000001 9cd0 870a792a 0000002e 16188fe6 00000001 0000242b 00000000 00000000 00000000 using random self ethernet address 9cf0 019a4646 00000000 000547f3 00000000 ecfd6c33 00000002 00000000 using random host ethernet address 00000000 X8: 0xffff8008f2a98a10: 8a10 00000000 00000000 f7788d00 ffff8008 00000001 00000000 00000000 00000000 8a30 eb218000 ffff8008 f2a98000 ffff8008 f2a98000 ffff8008 09885000 ffff0000 8a50 f34df480 ffff8008 00000000 00000000 f2a98648 ffff8008 09c8e000 ffff0000 8a70 fff2c800 ffff8008 09031d48 ffff0000 0b7bbd00 ffff0000 0b7bbd00 ffff0000 8a90 080861bc ffff0000 00000000 00000000 00000000 00000000 00000000 00000000 8ab0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 8ad0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 8af0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 X21: 0xffff8008f7a8b3a8: b3a8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b3c8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b3e8 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b408 00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000000 b428 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b448 0053004d 00540046 00300031 00010030 eb07b520 ffff8008 20011201 00000003 b468 e418d109 0104404e 00010302 00000000 eb07b558 ffff8008 eb07b558 ffff8008 b488 f7a8b488 ffff8008 f7a8b488 ffff8008 f7a8b300 ffff8008 00000000 00000000 X24: 0xffff8008f2a3bf90: bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008 c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000 c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008 c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000 c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008 X28: 0xffff8008f2a3bf90: bf90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bfb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bfd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008 c010 00000000 00000000 f2a3c018 ffff8008 f2a3c018 ffff8008 08a067dc ffff0000 c030 f2a5a000 ffff8008 091c3650 ffff0000 f716fd18 ffff8008 f716fe30 ffff8008 c050 f2ce4a30 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000 c070 f76c8010 ffff8008 f2ce4b00 ffff8008 095cac68 ffff0000 f2a5a028 ffff8008 Process irq/125-5b11000 (pid: 2457, stack limit = 0xffff00000b7b8000) Call trace: Exception stack(0xffff00000b7bba40 to 0xffff00000b7bbb80) ba40: 732a010310b9ed00 ffff0000089ff8d0 0000000000000006 0000000000000000 ba60: 0000000000000001 0000000000000000 0000000000000001 ffff8008f27a9c90 ba80: ffff8008f2a98a90 ffff00000b7bbd00 0000000000000a30 0000000000000008 baa0: 0000000000000008 e35502e30d44349c f1866f5b952aca46 0000000000000000 bac0: ffff0000082b7c9c 0000000000000000 0000000000000000 ffff0000089ff000 bae0: ffff00000afae000 ffff8008f7a8b428 ffff000009c8e000 0000000000000409 bb00: ffff8008f2a3c010 00000000ffffffa1 0000000000000000 0000000000000001 bb20: ffff8008f2a3c010 ffff00000b7bbb80 ffff000008a032fc ffff00000b7bbb80 bb40: ffff0000089ffb3c 00000000800001c5 ffff00000b7bbb80 732a010310b9ed00 bb60: ffffffffffffffff ffff0000080f777c ffff00000b7bbb80 ffff0000089ffb3c [] composite_setup+0x44/0x1508 [] android_setup+0xb8/0x13c [] cdns3_ep0_delegate_req+0x44/0x70 [] cdns3_check_ep0_interrupt_proceed+0x33c/0x654 [] cdns3_device_thread_irq_handler+0x4b0/0x4bc [] cdns3_thread_irq+0x48/0x68 [] irq_thread_fn+0x28/0x88 [] irq_thread+0x13c/0x228 [] kthread+0x104/0x130 [] ret_from_fork+0x10/0x18 oops2: composite_disconnect: Calling disconnect on a Gadget that is not connected android_work: did not send uevent (0 0 (null)) init: Received control message 'stop' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx) init: Sending signal 9 to service 'adbd' (pid 22343) process group... ------------[ cut here ]------------ audit: audit_lost=180038 audit_rate_limit=5 audit_backlog_limit=64 audit: rate limit exceeded WARNING: CPU: 0 PID: 3468 at kernel_imx/drivers/usb/gadget/composite.c:2009 composite_disconnect+0x80/0x88 Modules linked in: CPU: 0 PID: 3468 Comm: HWC-UEvent-Thre Not tainted 4.14.98-07846-g0b40a9b-dirty #16 Hardware name: Freescale i.MX8QM MEK (DT) task: ffff8008f2349c00 task.stack: ffff00000b0a8000 PC is at composite_disconnect+0x80/0x88 LR is at composite_disconnect+0x80/0x88 pc : [] lr : [] pstate: 600001c5 sp : ffff000008003dd0 x29: ffff000008003dd0 x28: ffff8008f2349c00 x27: ffff000009885018 x26: ffff000008004000 Timeout for IPC response! x25: ffff000009885018 x24: ffff000009c8e280 x23: ffff8008f2d98010 x22: 00000000000001c0 x21: ffff8008f2d98394 x20: ffff8008f2d98010 x19: 0000000000000000 x18: 0000e3956f4f075a fxos8700 4-001e: i2c block read acc failed x17: 0000e395735727e8 x16: ffff00000829f4d4 x15: ffffffffffffffff x14: 7463656e6e6f6320 x13: 746f6e2009090920 x12: 7369207461687420 x11: 7465676461472061 x10: 206e6f207463656e x9 : 6e6f637369642067 x8 : ffff000009c8e280 x7 : ffff0000086ca6cc x6 : ffff000009f15e78 x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffffffffffffffff x2 : c3f28b86000c3900 x1 : c3f28b86000c3900 x0 : 000000000000004e X20: 0xffff8008f2d97f90: 7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 libprocessgroup: Failed to kill process cgroup uid 0 pid 22343 in 215ms, 1 processes remain 7fd0 Timeout for IPC response! 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 using random self ethernet address 7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008 8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc using random host ethernet address ffff0000 8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008 8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000 8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008 X21: 0xffff8008f2d98314: 8314 ffff8008 00000000 00000000 00000000 00000000 00000000 00000000 00000000 8334 00000000 00000000 00000000 00000000 00000000 08a04cf4 ffff0000 00000000 8354 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 8374 00000000 00000000 00000000 00001001 00000000 00000000 00000000 00000000 8394 e4bbe4bb 0f230000 ffff0000 0afae000 ffff0000 ae001000 00000000 f206d400 Timeout for IPC response! 83b4 ffff8008 00000000 00000000 f7957b18 ffff8008 f7957718 ffff8008 f7957018 83d4 ffff8008 f7957118 ffff8008 f7957618 ffff8008 f7957818 ffff8008 f7957918 83f4 ffff8008 f7957d18 ffff8008 00000000 00000000 00000000 00000000 00000000 X23: 0xffff8008f2d97f90: 7f90 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 7fb0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 7fd0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 7ff0 00000000 00000000 00000000 00000000 f76c8010 ffff8008 f76c8010 ffff8008 8010 00000100 00000000 f2d98018 ffff8008 f2d98018 ffff8008 08a067dc ffff0000 8030 f206d800 ffff8008 091c3650 ffff0000 f7957b18 ffff8008 f7957730 ffff8008 8050 f716a630 ffff8008 00000000 00000005 00000000 00000000 095d1568 ffff0000 8070 f76c8010 ffff8008 f716a800 ffff8008 095cac68 ffff0000 f206d828 ffff8008 X28: 0xffff8008f2349b80: 9b80 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9ba0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9bc0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9be0 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9c00 00000022 00000000 ffffffff ffffffff 00010001 00000000 00000000 00000000 9c20 0b0a8000 ffff0000 00000002 00404040 00000000 00000000 00000000 00000000 9c40 00000001 00000000 00000001 00000000 001ebd44 00000001 f390b800 ffff8008 9c60 00000000 00000001 00000070 00000070 00000070 00000000 09031d48 ffff0000 Call trace: Exception stack(0xffff000008003c90 to 0xffff000008003dd0) 3c80: 000000000000004e c3f28b86000c3900 3ca0: c3f28b86000c3900 ffffffffffffffff 0000000000000000 0000000000000000 3cc0: ffff000009f15e78 ffff0000086ca6cc ffff000009c8e280 6e6f637369642067 3ce0: 206e6f207463656e 7465676461472061 7369207461687420 746f6e2009090920 3d00: 7463656e6e6f6320 ffffffffffffffff ffff00000829f4d4 0000e395735727e8 3d20: 0000e3956f4f075a 0000000000000000 ffff8008f2d98010 ffff8008f2d98394 3d40: 00000000000001c0 ffff8008f2d98010 ffff000009c8e280 ffff000009885018 3d60: ffff000008004000 ffff000009885018 ffff8008f2349c00 ffff000008003dd0 3d80: ffff0000089ff9b0 ffff000008003dd0 ffff0000089ff9b0 00000000600001c5 3da0: ffff8008f33f2cd8 0000000000000000 0000ffffffffffff 0000000000000000 init: Received control message 'start' for 'adbd' from pid: 3359 (/vendor/bin/hw/android.hardware.usb@1.1-service.imx) 3dc0: ffff000008003dd0 ffff0000089ff9b0 [] composite_disconnect+0x80/0x88 [] android_disconnect+0x3c/0x68 [] cdns3_device_irq_handler+0xfc/0x2c8 [] cdns3_irq+0x44/0x94 [] __handle_irq_event_percpu+0x60/0x24c [] handle_irq_event+0x58/0xc0 [] handle_fasteoi_irq+0x98/0x180 [] generic_handle_irq+0x24/0x38 [] __handle_domain_irq+0x60/0xac [] gic_handle_irq+0xd4/0x17c Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/configfs.c | 110 ++++++++++++++++++++++++++++++++-- 1 file changed, 105 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 025129942894..33852c2b29d1 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -61,6 +61,8 @@ struct gadget_info { bool use_os_desc; char b_vendor_code; char qw_sign[OS_STRING_QW_SIGN_LEN]; + spinlock_t spinlock; + bool unbind; }; static inline struct gadget_info *to_gadget_info(struct config_item *item) @@ -1244,6 +1246,7 @@ static int configfs_composite_bind(struct usb_gadget *gadget, int ret; /* the gi->lock is hold by the caller */ + gi->unbind = 0; cdev->gadget = gadget; set_gadget_data(gadget, cdev); ret = composite_dev_prepare(composite, cdev); @@ -1376,31 +1379,128 @@ static void configfs_composite_unbind(struct usb_gadget *gadget) { struct usb_composite_dev *cdev; struct gadget_info *gi; + unsigned long flags; /* the gi->lock is hold by the caller */ cdev = get_gadget_data(gadget); gi = container_of(cdev, struct gadget_info, cdev); + spin_lock_irqsave(&gi->spinlock, flags); + gi->unbind = 1; + spin_unlock_irqrestore(&gi->spinlock, flags); kfree(otg_desc[0]); otg_desc[0] = NULL; purge_configs_funcs(gi); composite_dev_cleanup(cdev); usb_ep_autoconfig_reset(cdev->gadget); + spin_lock_irqsave(&gi->spinlock, flags); cdev->gadget = NULL; set_gadget_data(gadget, NULL); + spin_unlock_irqrestore(&gi->spinlock, flags); +} + +static int configfs_composite_setup(struct usb_gadget *gadget, + const struct usb_ctrlrequest *ctrl) +{ + struct usb_composite_dev *cdev; + struct gadget_info *gi; + unsigned long flags; + int ret; + + cdev = get_gadget_data(gadget); + if (!cdev) + return 0; + + gi = container_of(cdev, struct gadget_info, cdev); + spin_lock_irqsave(&gi->spinlock, flags); + cdev = get_gadget_data(gadget); + if (!cdev || gi->unbind) { + spin_unlock_irqrestore(&gi->spinlock, flags); + return 0; + } + + ret = composite_setup(gadget, ctrl); + spin_unlock_irqrestore(&gi->spinlock, flags); + return ret; +} + +static void configfs_composite_disconnect(struct usb_gadget *gadget) +{ + struct usb_composite_dev *cdev; + struct gadget_info *gi; + unsigned long flags; + + cdev = get_gadget_data(gadget); + if (!cdev) + return; + + gi = container_of(cdev, struct gadget_info, cdev); + spin_lock_irqsave(&gi->spinlock, flags); + cdev = get_gadget_data(gadget); + if (!cdev || gi->unbind) { + spin_unlock_irqrestore(&gi->spinlock, flags); + return; + } + + composite_disconnect(gadget); + spin_unlock_irqrestore(&gi->spinlock, flags); +} + +static void configfs_composite_suspend(struct usb_gadget *gadget) +{ + struct usb_composite_dev *cdev; + struct gadget_info *gi; + unsigned long flags; + + cdev = get_gadget_data(gadget); + if (!cdev) + return; + + gi = container_of(cdev, struct gadget_info, cdev); + spin_lock_irqsave(&gi->spinlock, flags); + cdev = get_gadget_data(gadget); + if (!cdev || gi->unbind) { + spin_unlock_irqrestore(&gi->spinlock, flags); + return; + } + + composite_suspend(gadget); + spin_unlock_irqrestore(&gi->spinlock, flags); +} + +static void configfs_composite_resume(struct usb_gadget *gadget) +{ + struct usb_composite_dev *cdev; + struct gadget_info *gi; + unsigned long flags; + + cdev = get_gadget_data(gadget); + if (!cdev) + return; + + gi = container_of(cdev, struct gadget_info, cdev); + spin_lock_irqsave(&gi->spinlock, flags); + cdev = get_gadget_data(gadget); + if (!cdev || gi->unbind) { + spin_unlock_irqrestore(&gi->spinlock, flags); + return; + } + + composite_resume(gadget); + spin_unlock_irqrestore(&gi->spinlock, flags); } static const struct usb_gadget_driver configfs_driver_template = { .bind = configfs_composite_bind, .unbind = configfs_composite_unbind, - .setup = composite_setup, - .reset = composite_disconnect, - .disconnect = composite_disconnect, + .setup = configfs_composite_setup, + .reset = configfs_composite_disconnect, + .disconnect = configfs_composite_disconnect, - .suspend = composite_suspend, - .resume = composite_resume, + .suspend = configfs_composite_suspend, + .resume = configfs_composite_resume, .max_speed = USB_SPEED_SUPER, .driver = { -- GitLab From a7d9874c6f3fbc8d25cd9ceba35b6822612c4ebf Mon Sep 17 00:00:00 2001 From: Yinbo Zhu Date: Mon, 29 Jul 2019 14:46:07 +0800 Subject: [PATCH 773/993] usb: dwc3: remove the call trace of USBx_GFLADJ layerscape board sometimes reported some usb call trace, that is due to kernel sent LPM tokerns automatically when it has no pending transfers and think that the link is idle enough to enter L1, which procedure will ask usb register has a recovery,then kernel will compare USBx_GFLADJ and set GFLADJ_30MHZ, GFLADJ_30MHZ_REG until GFLADJ_30MHZ is equal 0x20, if the conditions were met then issue occur, but whatever the conditions whether were met that usb is all need keep GFLADJ_30MHZ of value is 0x20 (xhci spec ask use GFLADJ_30MHZ to adjust any offset from clock source that generates the clock that drives the SOF counter, 0x20 is default value of it)That is normal logic, so need remove the call trace. Signed-off-by: Yinbo Zhu Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 999ce5e84d3c..97d6ae3c4df2 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -312,8 +312,7 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc) reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); dft = reg & DWC3_GFLADJ_30MHZ_MASK; - if (!dev_WARN_ONCE(dwc->dev, dft == dwc->fladj, - "request value same as default, ignoring\n")) { + if (dft != dwc->fladj) { reg &= ~DWC3_GFLADJ_30MHZ_MASK; reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj; dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); -- GitLab From f3fb802efaef3662744a2215a51294d52a7cfc0e Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 23 Oct 2019 12:02:32 +0300 Subject: [PATCH 774/993] usb: cdns3: gadget: Don't manage pullups The USB gadget core is supposed to manage pullups of the controller. Don't manage pullups from within the controller driver. Otherwise, function drivers are not able to keep the controller disconnected from the bus till they are ready. (e.g. g_webcam) Reviewed-by: Pawel Laszczak Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/cdns3/gadget.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c index 9050b380ab83..d9e7f2d06098 100644 --- a/drivers/usb/cdns3/gadget.c +++ b/drivers/usb/cdns3/gadget.c @@ -2329,8 +2329,6 @@ static void cdns3_gadget_config(struct cdns3_device *priv_dev) writel(USB_CONF_CLK2OFFDS | USB_CONF_L1DS, ®s->usb_conf); cdns3_configure_dmult(priv_dev, NULL); - - cdns3_gadget_pullup(&priv_dev->gadget, 1); } /** @@ -2713,8 +2711,6 @@ static int cdns3_gadget_suspend(struct cdns3 *cdns, bool do_wakeup) /* disable interrupt for device */ writel(0, &priv_dev->regs->usb_ien); - cdns3_gadget_pullup(&priv_dev->gadget, 0); - return 0; } -- GitLab From d6d5df1db6e9d7f8f76d2911707f7d5877251b02 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 27 Oct 2019 13:19:19 -0400 Subject: [PATCH 775/993] Linux 5.4-rc5 --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5475cdb6d57d..79be70bf2899 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,8 @@ VERSION = 5 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -rc4 -NAME = Nesting Opossum +EXTRAVERSION = -rc5 +NAME = Kleptomaniac Octopus # *DOCUMENTATION* # To see a list of typical targets execute "make help" -- GitLab From a08d897bc04f23c608dadde5c31ef194911e78bb Mon Sep 17 00:00:00 2001 From: Steve French Date: Sat, 26 Oct 2019 16:00:44 -0500 Subject: [PATCH 776/993] fix memory leak in large read decrypt offload Spotted by Ronnie. Reviewed-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/smb2ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 4c0922596467..cd55af9b7cc5 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -4084,6 +4084,7 @@ static void smb2_decrypt_offload(struct work_struct *work) kfree(dw->ppages); cifs_small_buf_release(dw->buf); + kfree(dw); } @@ -4157,7 +4158,7 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid, dw->server = server; dw->ppages = pages; dw->len = len; - queue_work(cifsiod_wq, &dw->decrypt); + queue_work(decrypt_wq, &dw->decrypt); *num_mids = 0; /* worker thread takes care of finding mid */ return -1; } -- GitLab From 7b20238d28da46f394d37d4d51cc420e1ff9414a Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Sun, 27 Oct 2019 22:10:36 +0300 Subject: [PATCH 777/993] io_uring: Fix leaked shadow_req io_queue_link_head() owns shadow_req after taking it as an argument. By not freeing it in case of an error, it can leak the request along with taken ctx->refs. Reviewed-by: Jackie Liu Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- fs/io_uring.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/io_uring.c b/fs/io_uring.c index a30c4f622cb3..ba1431046c98 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -2413,6 +2413,7 @@ static int io_queue_link_head(struct io_ring_ctx *ctx, struct io_kiocb *req, if (ret) { if (ret != -EIOCBQUEUED) { io_free_req(req); + __io_free_req(shadow); io_cqring_add_event(ctx, s->sqe->user_data, ret); return 0; } -- GitLab From ffaee2728f9b276fc8829abb90f290b5b4b96282 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 17 Oct 2019 15:00:17 -0700 Subject: [PATCH 778/993] riscv: add prototypes for assembly language functions from head.S Add prototypes for assembly language functions defined in head.S, and include these prototypes into C source files that call those functions. This patch resolves the following warnings from sparse: arch/riscv/kernel/setup.c:39:10: warning: symbol 'hart_lottery' was not declared. Should it be static? arch/riscv/kernel/setup.c:42:13: warning: symbol 'parse_dtb' was not declared. Should it be static? arch/riscv/kernel/smpboot.c:33:6: warning: symbol '__cpu_up_stack_pointer' was not declared. Should it be static? arch/riscv/kernel/smpboot.c:34:6: warning: symbol '__cpu_up_task_pointer' was not declared. Should it be static? arch/riscv/mm/fault.c:25:17: warning: symbol 'do_page_fault' was not declared. Should it be static? This change should have no functional impact. Signed-off-by: Paul Walmsley --- arch/riscv/kernel/head.h | 21 +++++++++++++++++++++ arch/riscv/kernel/setup.c | 2 ++ arch/riscv/kernel/smpboot.c | 2 ++ arch/riscv/mm/fault.c | 2 ++ arch/riscv/mm/init.c | 2 ++ 5 files changed, 29 insertions(+) create mode 100644 arch/riscv/kernel/head.h diff --git a/arch/riscv/kernel/head.h b/arch/riscv/kernel/head.h new file mode 100644 index 000000000000..105fb0496b24 --- /dev/null +++ b/arch/riscv/kernel/head.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 SiFive, Inc. + */ +#ifndef __ASM_HEAD_H +#define __ASM_HEAD_H + +#include +#include + +extern atomic_t hart_lottery; + +asmlinkage void do_page_fault(struct pt_regs *regs); +asmlinkage void __init setup_vm(uintptr_t dtb_pa); + +extern void *__cpu_up_stack_pointer[]; +extern void *__cpu_up_task_pointer[]; + +void __init parse_dtb(void); + +#endif /* __ASM_HEAD_H */ diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index a990a6cb184f..845ae0e12115 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -24,6 +24,8 @@ #include #include +#include "head.h" + #ifdef CONFIG_DUMMY_CONSOLE struct screen_info screen_info = { .orig_video_lines = 30, diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index 18ae6da5115e..59fa59e013d4 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -30,6 +30,8 @@ #include #include +#include "head.h" + void *__cpu_up_stack_pointer[NR_CPUS]; void *__cpu_up_task_pointer[NR_CPUS]; static DECLARE_COMPLETION(cpu_running); diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c index 96add1427a75..247b8c859c44 100644 --- a/arch/riscv/mm/fault.c +++ b/arch/riscv/mm/fault.c @@ -18,6 +18,8 @@ #include #include +#include "../kernel/head.h" + /* * This routine handles page faults. It determines the address and the * problem, and then passes it off to one of the appropriate routines. diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index a1ca6200c31f..07af7b1e4069 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -19,6 +19,8 @@ #include #include +#include "../kernel/head.h" + unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] __page_aligned_bss; EXPORT_SYMBOL(empty_zero_page); -- GitLab From 6a527b6785ba1d19d6338439352de6c21e8847c3 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 17 Oct 2019 14:45:58 -0700 Subject: [PATCH 779/993] riscv: init: merge split string literals in preprocessor directive sparse complains loudly when string literals associated with preprocessor directives are split into multiple, separately quoted strings across different lines: arch/riscv/mm/init.c:341:9: error: Expected ; at the end of type declaration arch/riscv/mm/init.c:341:9: error: got "not use absolute addressing." arch/riscv/mm/init.c:358:9: error: Trying to use reserved word 'do' as identifier arch/riscv/mm/init.c:358:9: error: Expected ; at end of declaration [ ... ] It turns out this doesn't compile. The existing Linux practice for this situation is simply to use a single long line. So, fix by concatenating the strings. This patch should have no functional impact. This version incorporates changes based on feedback from Luc Van Oostenryck . Signed-off-by: Paul Walmsley Reviewed-by: Luc Van Oostenryck Reviewed-by: Christoph Hellwig Link: https://lore.kernel.org/linux-riscv/CAAhSdy2nX2LwEEAZuMtW_ByGTkHO6KaUEvVxRnba_ENEjmFayQ@mail.gmail.com/T/#mc1a58bc864f71278123d19a7abc083a9c8e37033 Fixes: 387181dcdb6c1 ("RISC-V: Always compile mm/init.c with cmodel=medany and notrace") Cc: Anup Patel --- arch/riscv/mm/init.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 07af7b1e4069..573463d1c799 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -339,8 +339,7 @@ static uintptr_t __init best_map_size(phys_addr_t base, phys_addr_t size) */ #ifndef __riscv_cmodel_medany -#error "setup_vm() is called from head.S before relocate so it should " - "not use absolute addressing." +#error "setup_vm() is called from head.S before relocate so it should not use absolute addressing." #endif asmlinkage void __init setup_vm(uintptr_t dtb_pa) -- GitLab From bf6df5dd25b74400424f3ff5a61edad2fd6904e6 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 17 Oct 2019 15:08:48 -0700 Subject: [PATCH 780/993] riscv: mark some code and data as file-static Several functions and arrays which are only used in the files in which they are declared are missing "static" qualifiers. Warnings for these symbols are reported by sparse: arch/riscv/kernel/vdso.c:28:18: warning: symbol 'vdso_data' was not declared. Should it be static? arch/riscv/mm/sifive_l2_cache.c:145:12: warning: symbol 'sifive_l2_init' was not declared. Should it be static? Resolve these warnings by marking them as static. This version incorporates feedback from Greentime Hu . Signed-off-by: Paul Walmsley Reviewed-by: Christoph Hellwig Cc: Greentime Hu --- arch/riscv/kernel/vdso.c | 2 +- arch/riscv/mm/sifive_l2_cache.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c index c9c21e0d5641..e24fccab8185 100644 --- a/arch/riscv/kernel/vdso.c +++ b/arch/riscv/kernel/vdso.c @@ -25,7 +25,7 @@ static union { struct vdso_data data; u8 page[PAGE_SIZE]; } vdso_data_store __page_aligned_data; -struct vdso_data *vdso_data = &vdso_data_store.data; +static struct vdso_data *vdso_data = &vdso_data_store.data; static int __init vdso_init(void) { diff --git a/arch/riscv/mm/sifive_l2_cache.c b/arch/riscv/mm/sifive_l2_cache.c index 2e637ad71c05..a9ffff3277c7 100644 --- a/arch/riscv/mm/sifive_l2_cache.c +++ b/arch/riscv/mm/sifive_l2_cache.c @@ -142,7 +142,7 @@ static irqreturn_t l2_int_handler(int irq, void *device) return IRQ_HANDLED; } -int __init sifive_l2_init(void) +static int __init sifive_l2_init(void) { struct device_node *np; struct resource res; -- GitLab From 5ed881bc3afc40d7a23c2211ead1aeb4980dda20 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 17 Oct 2019 15:21:28 -0700 Subject: [PATCH 781/993] riscv: add missing header file includes sparse identifies several missing prototypes caused by missing preprocessor include directives: arch/riscv/kernel/cpufeature.c:16:6: warning: symbol 'has_fpu' was not declared. Should it be static? arch/riscv/kernel/process.c:26:6: warning: symbol 'arch_cpu_idle' was not declared. Should it be static? arch/riscv/kernel/reset.c:15:6: warning: symbol 'pm_power_off' was not declared. Should it be static? arch/riscv/kernel/syscall_table.c:15:6: warning: symbol 'sys_call_table' was not declared. Should it be static? arch/riscv/kernel/traps.c:149:13: warning: symbol 'trap_init' was not declared. Should it be static? arch/riscv/kernel/vdso.c:54:5: warning: symbol 'arch_setup_additional_pages' was not declared. Should it be static? arch/riscv/kernel/smp.c:64:6: warning: symbol 'arch_match_cpu_phys_id' was not declared. Should it be static? arch/riscv/kernel/module-sections.c:89:5: warning: symbol 'module_frob_arch_sections' was not declared. Should it be static? arch/riscv/mm/context.c:42:6: warning: symbol 'switch_mm' was not declared. Should it be static? Fix by including the appropriate header files in the appropriate source files. This patch should have no functional impact. Signed-off-by: Paul Walmsley Reviewed-by: Christoph Hellwig --- arch/riscv/include/asm/irq.h | 3 +++ arch/riscv/include/asm/switch_to.h | 1 + arch/riscv/kernel/cpufeature.c | 1 + arch/riscv/kernel/module-sections.c | 1 + arch/riscv/kernel/process.c | 2 ++ arch/riscv/kernel/reset.c | 1 + arch/riscv/kernel/smp.c | 2 ++ arch/riscv/kernel/smpboot.c | 1 + arch/riscv/kernel/syscall_table.c | 1 + arch/riscv/kernel/time.c | 1 + arch/riscv/kernel/traps.c | 1 + arch/riscv/kernel/vdso.c | 1 + arch/riscv/mm/context.c | 1 + 13 files changed, 17 insertions(+) diff --git a/arch/riscv/include/asm/irq.h b/arch/riscv/include/asm/irq.h index 75576424c0f7..6e1b0e0325eb 100644 --- a/arch/riscv/include/asm/irq.h +++ b/arch/riscv/include/asm/irq.h @@ -7,6 +7,9 @@ #ifndef _ASM_RISCV_IRQ_H #define _ASM_RISCV_IRQ_H +#include +#include + #define NR_IRQS 0 void riscv_timer_interrupt(void); diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h index f0227bdce0f0..ee4f0ac62c9d 100644 --- a/arch/riscv/include/asm/switch_to.h +++ b/arch/riscv/include/asm/switch_to.h @@ -6,6 +6,7 @@ #ifndef _ASM_RISCV_SWITCH_TO_H #define _ASM_RISCV_SWITCH_TO_H +#include #include #include #include diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index b1ade9a49347..a5ad00043104 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -10,6 +10,7 @@ #include #include #include +#include unsigned long elf_hwcap __read_mostly; #ifdef CONFIG_FPU diff --git a/arch/riscv/kernel/module-sections.c b/arch/riscv/kernel/module-sections.c index c9ae48333114..e264e59e596e 100644 --- a/arch/riscv/kernel/module-sections.c +++ b/arch/riscv/kernel/module-sections.c @@ -8,6 +8,7 @@ #include #include #include +#include unsigned long module_emit_got_entry(struct module *mod, unsigned long val) { diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c index fb3a082362eb..85e3c39bb60b 100644 --- a/arch/riscv/kernel/process.c +++ b/arch/riscv/kernel/process.c @@ -7,6 +7,7 @@ * Copyright (C) 2017 SiFive */ +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include extern asmlinkage void ret_from_fork(void); extern asmlinkage void ret_from_kernel_thread(void); diff --git a/arch/riscv/kernel/reset.c b/arch/riscv/kernel/reset.c index d0fe623bfb8f..aa56bb135ec4 100644 --- a/arch/riscv/kernel/reset.c +++ b/arch/riscv/kernel/reset.c @@ -4,6 +4,7 @@ */ #include +#include #include static void default_power_off(void) diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c index b18cd6c8e8fb..5c9ec78422c2 100644 --- a/arch/riscv/kernel/smp.c +++ b/arch/riscv/kernel/smp.c @@ -8,7 +8,9 @@ * Copyright (C) 2017 SiFive */ +#include #include +#include #include #include #include diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index 59fa59e013d4..ec0be2f6a2e8 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "head.h" diff --git a/arch/riscv/kernel/syscall_table.c b/arch/riscv/kernel/syscall_table.c index e5dd52d8f633..f1ead9df96ca 100644 --- a/arch/riscv/kernel/syscall_table.c +++ b/arch/riscv/kernel/syscall_table.c @@ -8,6 +8,7 @@ #include #include #include +#include #undef __SYSCALL #define __SYSCALL(nr, call) [nr] = (call), diff --git a/arch/riscv/kernel/time.c b/arch/riscv/kernel/time.c index 9dd1f2e64db1..6a53c02e9c73 100644 --- a/arch/riscv/kernel/time.c +++ b/arch/riscv/kernel/time.c @@ -7,6 +7,7 @@ #include #include #include +#include unsigned long riscv_timebase; EXPORT_SYMBOL_GPL(riscv_timebase); diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index 10a17e545f43..0b6e271efc43 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -3,6 +3,7 @@ * Copyright (C) 2012 Regents of the University of California */ +#include #include #include #include diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c index e24fccab8185..484d95a70907 100644 --- a/arch/riscv/kernel/vdso.c +++ b/arch/riscv/kernel/vdso.c @@ -6,6 +6,7 @@ * Copyright (C) 2015 Regents of the University of California */ +#include #include #include #include diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c index beeb5d7f92ea..ca66d44156b6 100644 --- a/arch/riscv/mm/context.c +++ b/arch/riscv/mm/context.c @@ -7,6 +7,7 @@ #include #include #include +#include /* * When necessary, performs a deferred icache flush for the given MM context, -- GitLab From a48dac448d85712dbc827cdfeb29f720f2c345ff Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 17 Oct 2019 15:41:25 -0700 Subject: [PATCH 782/993] riscv: fp: add missing __user pointer annotations The __user annotations were removed from the {save,restore}_fp_state() function signatures by commit 007f5c358957 ("Refactor FPU code in signal setup/return procedures"), but should be present, and sparse warns when they are not applied. Add them back in. This change should have no functional impact. Signed-off-by: Paul Walmsley Fixes: 007f5c358957 ("Refactor FPU code in signal setup/return procedures") Cc: Alan Kao Reviewed-by: Christoph Hellwig --- arch/riscv/kernel/signal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c index b14d7647d800..64bc914ce9ff 100644 --- a/arch/riscv/kernel/signal.c +++ b/arch/riscv/kernel/signal.c @@ -26,7 +26,7 @@ struct rt_sigframe { #ifdef CONFIG_FPU static long restore_fp_state(struct pt_regs *regs, - union __riscv_fp_state *sc_fpregs) + union __riscv_fp_state __user *sc_fpregs) { long err; struct __riscv_d_ext_state __user *state = &sc_fpregs->d; @@ -53,7 +53,7 @@ static long restore_fp_state(struct pt_regs *regs, } static long save_fp_state(struct pt_regs *regs, - union __riscv_fp_state *sc_fpregs) + union __riscv_fp_state __user *sc_fpregs) { long err; struct __riscv_d_ext_state __user *state = &sc_fpregs->d; -- GitLab From f307307992bf63e609fe5395953048e81c9ebc54 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 17 Oct 2019 22:20:05 -0700 Subject: [PATCH 783/993] riscv: for C functions called only from assembly, mark with __visible Rather than adding prototypes for C functions called only by assembly code, mark them as __visible. This avoids adding prototypes that will never be used by the callers. Resolves the following sparse warnings: arch/riscv/kernel/irq.c:27:29: warning: symbol 'do_IRQ' was not declared. Should it be static? arch/riscv/kernel/ptrace.c:151:6: warning: symbol 'do_syscall_trace_enter' was not declared. Should it be static? arch/riscv/kernel/ptrace.c:165:6: warning: symbol 'do_syscall_trace_exit' was not declared. Should it be static? arch/riscv/kernel/signal.c:295:17: warning: symbol 'do_notify_resume' was not declared. Should it be static? arch/riscv/kernel/traps.c:92:1: warning: symbol 'do_trap_unknown' was not declared. Should it be static? arch/riscv/kernel/traps.c:94:1: warning: symbol 'do_trap_insn_misaligned' was not declared. Should it be static? arch/riscv/kernel/traps.c:96:1: warning: symbol 'do_trap_insn_fault' was not declared. Should it be static? arch/riscv/kernel/traps.c:98:1: warning: symbol 'do_trap_insn_illegal' was not declared. Should it be static? arch/riscv/kernel/traps.c:100:1: warning: symbol 'do_trap_load_misaligned' was not declared. Should it be static? arch/riscv/kernel/traps.c:102:1: warning: symbol 'do_trap_load_fault' was not declared. Should it be static? arch/riscv/kernel/traps.c:104:1: warning: symbol 'do_trap_store_misaligned' was not declared. Should it be static? arch/riscv/kernel/traps.c:106:1: warning: symbol 'do_trap_store_fault' was not declared. Should it be static? arch/riscv/kernel/traps.c:108:1: warning: symbol 'do_trap_ecall_u' was not declared. Should it be static? arch/riscv/kernel/traps.c:110:1: warning: symbol 'do_trap_ecall_s' was not declared. Should it be static? arch/riscv/kernel/traps.c:112:1: warning: symbol 'do_trap_ecall_m' was not declared. Should it be static? arch/riscv/kernel/traps.c:124:17: warning: symbol 'do_trap_break' was not declared. Should it be static? arch/riscv/kernel/smpboot.c:136:24: warning: symbol 'smp_callin' was not declared. Should it be static? Based on a suggestion from Luc Van Oostenryck. This version includes changes based on feedback from Christoph Hellwig . Signed-off-by: Paul Walmsley Cc: Luc Van Oostenryck Reviewed-by: Christoph Hellwig # for do_syscall_trace_* --- arch/riscv/kernel/irq.c | 2 +- arch/riscv/kernel/ptrace.c | 4 ++-- arch/riscv/kernel/signal.c | 4 ++-- arch/riscv/kernel/smpboot.c | 2 +- arch/riscv/kernel/traps.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c index 6d8659388c49..fffac6ddb0e0 100644 --- a/arch/riscv/kernel/irq.c +++ b/arch/riscv/kernel/irq.c @@ -24,7 +24,7 @@ int arch_show_interrupts(struct seq_file *p, int prec) return 0; } -asmlinkage void __irq_entry do_IRQ(struct pt_regs *regs) +asmlinkage __visible void __irq_entry do_IRQ(struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c index 368751438366..1252113ef8b2 100644 --- a/arch/riscv/kernel/ptrace.c +++ b/arch/riscv/kernel/ptrace.c @@ -148,7 +148,7 @@ long arch_ptrace(struct task_struct *child, long request, * Allows PTRACE_SYSCALL to work. These are called from entry.S in * {handle,ret_from}_syscall. */ -void do_syscall_trace_enter(struct pt_regs *regs) +__visible void do_syscall_trace_enter(struct pt_regs *regs) { if (test_thread_flag(TIF_SYSCALL_TRACE)) if (tracehook_report_syscall_entry(regs)) @@ -162,7 +162,7 @@ void do_syscall_trace_enter(struct pt_regs *regs) audit_syscall_entry(regs->a7, regs->a0, regs->a1, regs->a2, regs->a3); } -void do_syscall_trace_exit(struct pt_regs *regs) +__visible void do_syscall_trace_exit(struct pt_regs *regs) { audit_syscall_exit(regs); diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c index 64bc914ce9ff..d0f6f212f5df 100644 --- a/arch/riscv/kernel/signal.c +++ b/arch/riscv/kernel/signal.c @@ -292,8 +292,8 @@ static void do_signal(struct pt_regs *regs) * notification of userspace execution resumption * - triggered by the _TIF_WORK_MASK flags */ -asmlinkage void do_notify_resume(struct pt_regs *regs, - unsigned long thread_info_flags) +asmlinkage __visible void do_notify_resume(struct pt_regs *regs, + unsigned long thread_info_flags) { /* Handle pending signal delivery */ if (thread_info_flags & _TIF_SIGPENDING) diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index ec0be2f6a2e8..261f4087cc39 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -133,7 +133,7 @@ void __init smp_cpus_done(unsigned int max_cpus) /* * C entry point for a secondary processor. */ -asmlinkage void __init smp_callin(void) +asmlinkage __visible void __init smp_callin(void) { struct mm_struct *mm = &init_mm; diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index 0b6e271efc43..473de3ae8bb7 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -84,7 +84,7 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code, } #define DO_ERROR_INFO(name, signo, code, str) \ -asmlinkage void name(struct pt_regs *regs) \ +asmlinkage __visible void name(struct pt_regs *regs) \ { \ do_trap_error(regs, signo, code, regs->sepc, "Oops - " str); \ } @@ -121,7 +121,7 @@ static inline unsigned long get_break_insn_length(unsigned long pc) return (((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) ? 4UL : 2UL); } -asmlinkage void do_trap_break(struct pt_regs *regs) +asmlinkage __visible void do_trap_break(struct pt_regs *regs) { if (user_mode(regs)) force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->sepc); -- GitLab From 40ce7919d8730f5936da2bc8a21b46bd07db6411 Mon Sep 17 00:00:00 2001 From: Marvin Liu Date: Tue, 22 Oct 2019 01:10:04 +0800 Subject: [PATCH 784/993] virtio_ring: fix stalls for packed rings When VIRTIO_F_RING_EVENT_IDX is negotiated, virtio devices can use virtqueue_enable_cb_delayed_packed to reduce the number of device interrupts. At the moment, this is the case for virtio-net when the napi_tx module parameter is set to false. In this case, the virtio driver selects an event offset and expects that the device will send a notification when rolling over the event offset in the ring. However, if this roll-over happens before the event suppression structure update, the notification won't be sent. To address this race condition the driver needs to check wether the device rolled over the offset after updating the event suppression structure. With VIRTIO_F_RING_PACKED, the virtio driver did this by reading the flags field of the descriptor at the specified offset. Unfortunately, checking at the event offset isn't reliable: if descriptors are chained (e.g. when INDIRECT is off) not all descriptors are overwritten by the device, so it's possible that the device skipped the specific descriptor driver is checking when writing out used descriptors. If this happens, the driver won't detect the race condition and will incorrectly expect the device to send a notification. For virtio-net, the result will be a TX queue stall, with the transmission getting blocked forever. With the packed ring, it isn't easy to find a location which is guaranteed to change upon the roll-over, except the next device descriptor, as described in the spec: Writes of device and driver descriptors can generally be reordered, but each side (driver and device) are only required to poll (or test) a single location in memory: the next device descriptor after the one they processed previously, in circular order. while this might be sub-optimal, let's do exactly this for now. Cc: stable@vger.kernel.org Cc: Jason Wang Fixes: f51f982682e2a ("virtio_ring: leverage event idx in packed ring") Signed-off-by: Marvin Liu Signed-off-by: Michael S. Tsirkin --- drivers/virtio/virtio_ring.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index bdc08244a648..a8041e451e9e 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -1499,9 +1499,6 @@ static bool virtqueue_enable_cb_delayed_packed(struct virtqueue *_vq) * counter first before updating event flags. */ virtio_wmb(vq->weak_barriers); - } else { - used_idx = vq->last_used_idx; - wrap_counter = vq->packed.used_wrap_counter; } if (vq->packed.event_flags_shadow == VRING_PACKED_EVENT_FLAG_DISABLE) { @@ -1518,7 +1515,9 @@ static bool virtqueue_enable_cb_delayed_packed(struct virtqueue *_vq) */ virtio_mb(vq->weak_barriers); - if (is_used_desc_packed(vq, used_idx, wrap_counter)) { + if (is_used_desc_packed(vq, + vq->last_used_idx, + vq->packed.used_wrap_counter)) { END_USE(vq); return false; } -- GitLab From 6771596169bf585d8d7218f1dc5eb7c2d2663275 Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Tue, 15 Oct 2019 17:00:51 +0200 Subject: [PATCH 785/993] vsock/virtio: remove unused 'work' field from 'struct virtio_vsock_pkt' The 'work' field was introduced with commit 06a8fc78367d0 ("VSOCK: Introduce virtio_vsock_common.ko") but it is never used in the code, so we can remove it to save memory allocated in the per-packet 'struct virtio_vsock_pkt' Suggested-by: Michael S. Tsirkin Signed-off-by: Stefano Garzarella Signed-off-by: Michael S. Tsirkin --- include/linux/virtio_vsock.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h index 4c7781f4b29b..07875ccc7bb5 100644 --- a/include/linux/virtio_vsock.h +++ b/include/linux/virtio_vsock.h @@ -48,7 +48,6 @@ struct virtio_vsock_sock { struct virtio_vsock_pkt { struct virtio_vsock_hdr hdr; - struct work_struct work; struct list_head list; /* socket refcnt not held, only use for cancellation */ struct vsock_sock *vsk; -- GitLab From b3683dee840274e9997d958b9d82e5de95950f0b Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Thu, 24 Oct 2019 11:57:18 +0800 Subject: [PATCH 786/993] vringh: fix copy direction of vringh_iov_push_kern() We want to copy from iov to buf, so the direction was wrong. Note: no real user for the helper, but it will be used by future features. Signed-off-by: Jason Wang Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vringh.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c index 08ad0d1f0476..a0a2d74967ef 100644 --- a/drivers/vhost/vringh.c +++ b/drivers/vhost/vringh.c @@ -852,6 +852,12 @@ static inline int xfer_kern(void *src, void *dst, size_t len) return 0; } +static inline int kern_xfer(void *dst, void *src, size_t len) +{ + memcpy(dst, src, len); + return 0; +} + /** * vringh_init_kern - initialize a vringh for a kernelspace vring. * @vrh: the vringh to initialize. @@ -958,7 +964,7 @@ EXPORT_SYMBOL(vringh_iov_pull_kern); ssize_t vringh_iov_push_kern(struct vringh_kiov *wiov, const void *src, size_t len) { - return vringh_iov_xfer(wiov, (void *)src, len, xfer_kern); + return vringh_iov_xfer(wiov, (void *)src, len, kern_xfer); } EXPORT_SYMBOL(vringh_iov_push_kern); -- GitLab From 8c7e975667fbc3b7c816119dd56104739899f125 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Fri, 25 Oct 2019 15:16:36 +0300 Subject: [PATCH 787/993] perf/core: Start rejecting the syscall with attr.__reserved_2 set Commit: 1a5941312414c ("perf: Add wakeup watermark control to the AUX area") added attr.__reserved_2 padding, but forgot to add an ABI check to reject attributes with this field set. Fix that. Signed-off-by: Alexander Shishkin Signed-off-by: Peter Zijlstra (Intel) Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Mark Rutland Cc: Namhyung Kim Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Cc: adrian.hunter@intel.com Cc: mathieu.poirier@linaro.org Link: https://lkml.kernel.org/r/20191025121636.75182-1-alexander.shishkin@linux.intel.com Signed-off-by: Ingo Molnar --- kernel/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index bb3748d29b04..aec8dba2bea4 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -10635,7 +10635,7 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr, attr->size = size; - if (attr->__reserved_1) + if (attr->__reserved_1 || attr->__reserved_2) return -EINVAL; if (attr->sample_type & ~(PERF_SAMPLE_MAX-1)) -- GitLab From 317b96bb14303c7998dbcd5bc606bd8038fdd4b4 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Wed, 23 Oct 2019 10:09:54 -0500 Subject: [PATCH 788/993] perf/x86/amd/ibs: Fix reading of the IBS OpData register and thus precise RIP validity The loop that reads all the IBS MSRs into *buf stopped one MSR short of reading the IbsOpData register, which contains the RipInvalid status bit. Fix the offset_max assignment so the MSR gets read, so the RIP invalid evaluation is based on what the IBS h/w output, instead of what was left in memory. Signed-off-by: Kim Phillips Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Arnaldo Carvalho de Melo Cc: Borislav Petkov Cc: H. Peter Anvin Cc: Jiri Olsa Cc: Linus Torvalds Cc: Mark Rutland Cc: Namhyung Kim Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Fixes: d47e8238cd76 ("perf/x86-ibs: Take instruction pointer from ibs sample") Link: https://lkml.kernel.org/r/20191023150955.30292-1-kim.phillips@amd.com Signed-off-by: Ingo Molnar --- arch/x86/events/amd/ibs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c index 5b35b7ea5d72..98ba21a588a1 100644 --- a/arch/x86/events/amd/ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -614,7 +614,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) if (event->attr.sample_type & PERF_SAMPLE_RAW) offset_max = perf_ibs->offset_max; else if (check_rip) - offset_max = 2; + offset_max = 3; else offset_max = 1; do { -- GitLab From e431e79b60603079d269e0c2a5177943b95fa4b6 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Wed, 23 Oct 2019 10:09:55 -0500 Subject: [PATCH 789/993] perf/x86/amd/ibs: Handle erratum #420 only on the affected CPU family (10h) This saves us writing the IBS control MSR twice when disabling the event. I searched revision guides for all families since 10h, and did not find occurrence of erratum #420, nor anything remotely similar: so we isolate the secondary MSR write to family 10h only. Also unconditionally update the count mask for IBS Op implementations that have read & writeable current count (CurCnt) fields in addition to the MaxCnt field. These bits were reserved on prior implementations, and therefore shouldn't have negative impact. Signed-off-by: Kim Phillips Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Arnaldo Carvalho de Melo Cc: Borislav Petkov Cc: H. Peter Anvin Cc: Jiri Olsa Cc: Linus Torvalds Cc: Mark Rutland Cc: Namhyung Kim Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Fixes: c9574fe0bdb9 ("perf/x86-ibs: Implement workaround for IBS erratum #420") Link: https://lkml.kernel.org/r/20191023150955.30292-2-kim.phillips@amd.com Signed-off-by: Ingo Molnar --- arch/x86/events/amd/ibs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c index 98ba21a588a1..26c36357c4c9 100644 --- a/arch/x86/events/amd/ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -377,7 +377,8 @@ static inline void perf_ibs_disable_event(struct perf_ibs *perf_ibs, struct hw_perf_event *hwc, u64 config) { config &= ~perf_ibs->cnt_mask; - wrmsrl(hwc->config_base, config); + if (boot_cpu_data.x86 == 0x10) + wrmsrl(hwc->config_base, config); config &= ~perf_ibs->enable_mask; wrmsrl(hwc->config_base, config); } @@ -553,7 +554,8 @@ static struct perf_ibs perf_ibs_op = { }, .msr = MSR_AMD64_IBSOPCTL, .config_mask = IBS_OP_CONFIG_MASK, - .cnt_mask = IBS_OP_MAX_CNT, + .cnt_mask = IBS_OP_MAX_CNT | IBS_OP_CUR_CNT | + IBS_OP_CUR_CNT_RAND, .enable_mask = IBS_OP_ENABLE, .valid_mask = IBS_OP_VAL, .max_period = IBS_OP_MAX_CNT << 4, -- GitLab From 75be6f703a141b048590d659a3954c4fedd30bba Mon Sep 17 00:00:00 2001 From: Kan Liang Date: Fri, 25 Oct 2019 07:43:13 -0700 Subject: [PATCH 790/993] perf/x86/uncore: Fix event group support The events in the same group don't start or stop simultaneously. Here is the ftrace when enabling event group for uncore_iio_0: # perf stat -e "{uncore_iio_0/event=0x1/,uncore_iio_0/event=0xe/}" -0 [000] d.h. 8959.064832: read_msr: a41, value b2b0b030 //Read counter reg of IIO unit0 counter0 -0 [000] d.h. 8959.064835: write_msr: a48, value 400001 //Write Ctrl reg of IIO unit0 counter0 to enable counter0. <------ Although counter0 is enabled, Unit Ctrl is still freezed. Nothing will count. We are still good here. -0 [000] d.h. 8959.064836: read_msr: a40, value 30100 //Read Unit Ctrl reg of IIO unit0 -0 [000] d.h. 8959.064838: write_msr: a40, value 30000 //Write Unit Ctrl reg of IIO unit0 to enable all counters in the unit by clear Freeze bit <------Unit0 is un-freezed. Counter0 has been enabled. Now it starts counting. But counter1 has not been enabled yet. The issue starts here. -0 [000] d.h. 8959.064846: read_msr: a42, value 0 //Read counter reg of IIO unit0 counter1 -0 [000] d.h. 8959.064847: write_msr: a49, value 40000e //Write Ctrl reg of IIO unit0 counter1 to enable counter1. <------ Now, counter1 just starts to count. Counter0 has been running for a while. Current code un-freezes the Unit Ctrl right after the first counter is enabled. The subsequent group events always loses some counter values. Implement pmu_enable and pmu_disable support for uncore, which can help to batch hardware accesses. No one uses uncore_enable_box and uncore_disable_box. Remove them. Signed-off-by: Kan Liang Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Mark Rutland Cc: Namhyung Kim Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Cc: linux-drivers-review@eclists.intel.com Cc: linux-perf@eclists.intel.com Fixes: 087bfbb03269 ("perf/x86: Add generic Intel uncore PMU support") Link: https://lkml.kernel.org/r/1572014593-31591-1-git-send-email-kan.liang@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/events/intel/uncore.c | 44 +++++++++++++++++++++++++++++----- arch/x86/events/intel/uncore.h | 12 ---------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index 6fc2e06ab4c6..86467f85c383 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -502,10 +502,8 @@ void uncore_pmu_event_start(struct perf_event *event, int flags) local64_set(&event->hw.prev_count, uncore_read_counter(box, event)); uncore_enable_event(box, event); - if (box->n_active == 1) { - uncore_enable_box(box); + if (box->n_active == 1) uncore_pmu_start_hrtimer(box); - } } void uncore_pmu_event_stop(struct perf_event *event, int flags) @@ -529,10 +527,8 @@ void uncore_pmu_event_stop(struct perf_event *event, int flags) WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); hwc->state |= PERF_HES_STOPPED; - if (box->n_active == 0) { - uncore_disable_box(box); + if (box->n_active == 0) uncore_pmu_cancel_hrtimer(box); - } } if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { @@ -778,6 +774,40 @@ static int uncore_pmu_event_init(struct perf_event *event) return ret; } +static void uncore_pmu_enable(struct pmu *pmu) +{ + struct intel_uncore_pmu *uncore_pmu; + struct intel_uncore_box *box; + + uncore_pmu = container_of(pmu, struct intel_uncore_pmu, pmu); + if (!uncore_pmu) + return; + + box = uncore_pmu_to_box(uncore_pmu, smp_processor_id()); + if (!box) + return; + + if (uncore_pmu->type->ops->enable_box) + uncore_pmu->type->ops->enable_box(box); +} + +static void uncore_pmu_disable(struct pmu *pmu) +{ + struct intel_uncore_pmu *uncore_pmu; + struct intel_uncore_box *box; + + uncore_pmu = container_of(pmu, struct intel_uncore_pmu, pmu); + if (!uncore_pmu) + return; + + box = uncore_pmu_to_box(uncore_pmu, smp_processor_id()); + if (!box) + return; + + if (uncore_pmu->type->ops->disable_box) + uncore_pmu->type->ops->disable_box(box); +} + static ssize_t uncore_get_attr_cpumask(struct device *dev, struct device_attribute *attr, char *buf) { @@ -803,6 +833,8 @@ static int uncore_pmu_register(struct intel_uncore_pmu *pmu) pmu->pmu = (struct pmu) { .attr_groups = pmu->type->attr_groups, .task_ctx_nr = perf_invalid_context, + .pmu_enable = uncore_pmu_enable, + .pmu_disable = uncore_pmu_disable, .event_init = uncore_pmu_event_init, .add = uncore_pmu_event_add, .del = uncore_pmu_event_del, diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h index f36f7bebbc1b..bbfdaa720b45 100644 --- a/arch/x86/events/intel/uncore.h +++ b/arch/x86/events/intel/uncore.h @@ -441,18 +441,6 @@ static inline int uncore_freerunning_hw_config(struct intel_uncore_box *box, return -EINVAL; } -static inline void uncore_disable_box(struct intel_uncore_box *box) -{ - if (box->pmu->type->ops->disable_box) - box->pmu->type->ops->disable_box(box); -} - -static inline void uncore_enable_box(struct intel_uncore_box *box) -{ - if (box->pmu->type->ops->enable_box) - box->pmu->type->ops->enable_box(box); -} - static inline void uncore_disable_event(struct intel_uncore_box *box, struct perf_event *event) { -- GitLab From 652521d460cbfa24ef27717b4b28acfac4281be6 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 24 Oct 2019 14:29:04 +0200 Subject: [PATCH 791/993] perf/headers: Fix spelling s/EACCESS/EACCES/, s/privilidge/privilege/ As per POSIX, the correct spelling of the error code is EACCES: include/uapi/asm-generic/errno-base.h:#define EACCES 13 /* Permission denied */ Signed-off-by: Geert Uytterhoeven Signed-off-by: Peter Zijlstra (Intel) Cc: Alexander Shishkin Cc: Arnaldo Carvalho de Melo Cc: Arnaldo Carvalho de Melo Cc: Jiri Kosina Cc: Jiri Olsa Cc: Linus Torvalds Cc: Mark Rutland Cc: Namhyung Kim Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Link: https://lkml.kernel.org/r/20191024122904.12463-1-geert+renesas@glider.be Signed-off-by: Ingo Molnar --- include/linux/perf_event.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 61448c19a132..68ccc5b1913b 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -292,7 +292,7 @@ struct pmu { * -EBUSY -- @event is for this PMU but PMU temporarily unavailable * -EINVAL -- @event is for this PMU but @event is not valid * -EOPNOTSUPP -- @event is for this PMU, @event is valid, but not supported - * -EACCESS -- @event is for this PMU, @event is valid, but no privilidges + * -EACCES -- @event is for this PMU, @event is valid, but no privileges * * 0 -- @event is for this PMU and valid * -- GitLab From 1a7f60b9df614bb36d14dc0c0bc898a31b2b506f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 28 Oct 2019 09:10:56 +0100 Subject: [PATCH 792/993] Revert "ALSA: hda: Flush interrupts on disabling" This reverts commit caa8422d01e983782548648e125fd617cadcec3f. It turned out that this commit caused a regression at shutdown / reboot, as the synchronize_irq() calls seems blocking the whole shutdown. Also another part of the change about shuffling the call order looks suspicious; the azx_stop_chip() call disables the CORB / RIRB while the others may still need the CORB/RIRB update. Since the original commit itself was a cargo-fix, let's revert the whole patch. Fixes: caa8422d01e9 ("ALSA: hda: Flush interrupts on disabling") BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=205333 BugLinK: https://bugs.freedesktop.org/show_bug.cgi?id=111174 Signed-off-by: Takashi Iwai Cc: Chris Wilson Link: https://lore.kernel.org/r/20191028081056.22010-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/hda/hdac_controller.c | 2 -- sound/pci/hda/hda_intel.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c index d3999e7b0705..7e7be8e4dcf9 100644 --- a/sound/hda/hdac_controller.c +++ b/sound/hda/hdac_controller.c @@ -447,8 +447,6 @@ static void azx_int_disable(struct hdac_bus *bus) list_for_each_entry(azx_dev, &bus->stream_list, list) snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0); - synchronize_irq(bus->irq); - /* disable SIE for all streams */ snd_hdac_chip_writeb(bus, INTCTL, 0); diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index a815bc811799..cf53fbd872ee 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1348,9 +1348,9 @@ static int azx_free(struct azx *chip) } if (bus->chip_init) { - azx_stop_chip(chip); azx_clear_irq_pending(chip); azx_stop_all_streams(chip); + azx_stop_chip(chip); } if (bus->irq >= 0) -- GitLab From 54087918b8d5d43ca0515c60170e2453b84d9f83 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 28 Oct 2019 14:45:22 +0100 Subject: [PATCH 793/993] ANDROID: modpost: fix up merge issues due to namespace removal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit module namespaces are ripped out at the moment, so the 5.4-rc5 merge didn't quite go "well" because of that. This should resolve those issues. Cc: Matthias Männich Signed-off-by: Greg Kroah-Hartman Change-Id: I56eccc6e9bce6eaf805e84f34e67975284efb05a --- scripts/mod/modpost.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 15c0eaf1ae4c..a244ae109562 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1987,16 +1987,6 @@ static void read_symbols(const char *modname) handle_moddevtable(mod, &info, sym, symname); } - /* Apply symbol namespaces from __kstrtabns_ entries. */ - for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { - symname = remove_dot(info.strtab + sym->st_name); - - if (strstarts(symname, "__kstrtabns_")) - sym_update_namespace(symname + strlen("__kstrtabns_"), - namespace_from_kstrtabns(&info, - sym)); - } - // check for static EXPORT_SYMBOL_* functions && global vars for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { unsigned char bind = ELF_ST_BIND(sym->st_info); @@ -2398,7 +2388,6 @@ static void read_dump(const char *fname, unsigned int kernel) s->preloaded = 1; s->is_static = 0; sym_update_crc(symname, mod, crc, export_no(export)); - sym_update_namespace(symname, namespace); } release_file(file, size); return; -- GitLab From 044c1ab399afbe9f2ebef49a3204ef1509826dc7 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 28 Oct 2019 09:15:33 -0600 Subject: [PATCH 794/993] io_uring: don't touch ctx in setup after ring fd install syzkaller reported an issue where it looks like a malicious app can trigger a use-after-free of reading the ctx ->sq_array and ->rings value right after having installed the ring fd in the process file table. Defer ring fd installation until after we're done reading those values. Fixes: 75b28affdd6a ("io_uring: allocate the two rings together") Reported-by: syzbot+6f03d895a6cd0d06187f@syzkaller.appspotmail.com Signed-off-by: Jens Axboe --- fs/io_uring.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index ba1431046c98..c11c4157a4c2 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -3829,10 +3829,6 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p) if (ret) goto err; - ret = io_uring_get_fd(ctx); - if (ret < 0) - goto err; - memset(&p->sq_off, 0, sizeof(p->sq_off)); p->sq_off.head = offsetof(struct io_rings, sq.head); p->sq_off.tail = offsetof(struct io_rings, sq.tail); @@ -3850,6 +3846,14 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p) p->cq_off.overflow = offsetof(struct io_rings, cq_overflow); p->cq_off.cqes = offsetof(struct io_rings, cqes); + /* + * Install ring fd as the very last thing, so we don't risk someone + * having closed it before we finish setup + */ + ret = io_uring_get_fd(ctx); + if (ret < 0) + goto err; + p->features = IORING_FEAT_SINGLE_MMAP; return ret; err: -- GitLab From d482c7bb0541d19dea8bff437a9f3c5563b5b2d2 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 28 Oct 2019 10:52:35 -0400 Subject: [PATCH 795/993] USB: Skip endpoints with 0 maxpacket length Endpoints with a maxpacket length of 0 are probably useless. They can't transfer any data, and it's not at all unlikely that an HCD will crash or hang when trying to handle an URB for such an endpoint. Currently the USB core does not check for endpoints having a maxpacket value of 0. This patch adds a check, printing a warning and skipping over any endpoints it catches. Now, the USB spec does not rule out endpoints having maxpacket = 0. But since they wouldn't have any practical use, there doesn't seem to be any good reason for us to accept them. Signed-off-by: Alan Stern Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.1910281050420.1485-100000@iolanthe.rowland.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 151a74a54386..1ac1095bfeac 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -348,6 +348,11 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, /* Validate the wMaxPacketSize field */ maxp = usb_endpoint_maxp(&endpoint->desc); + if (maxp == 0) { + dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has wMaxPacketSize 0, skipping\n", + cfgno, inum, asnum, d->bEndpointAddress); + goto skip_to_next_endpoint_or_interface_descriptor; + } /* Find the highest legal maxpacket size for this endpoint */ i = 0; /* additional transactions per microframe */ -- GitLab From d98ee2a19c3334e9343df3ce254b496f1fc428eb Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Oct 2019 16:32:02 +0200 Subject: [PATCH 796/993] USB: ldusb: fix ring-buffer locking The custom ring-buffer implementation was merged without any locking or explicit memory barriers, but a spinlock was later added by commit 9d33efd9a791 ("USB: ldusb bugfix"). The lock did not cover the update of the tail index once the entry had been processed, something which could lead to memory corruption on weakly ordered architectures or due to compiler optimisations. Specifically, a completion handler running on another CPU might observe the incremented tail index and update the entry before ld_usb_read() is done with it. Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") Fixes: 9d33efd9a791 ("USB: ldusb bugfix") Cc: stable # 2.6.13 Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20191022143203.5260-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ldusb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 15b5f06fb0b3..c3e764909fd0 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -495,11 +495,11 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, retval = -EFAULT; goto unlock_exit; } - dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size; - retval = bytes_to_read; spin_lock_irq(&dev->rbsl); + dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size; + if (dev->buffer_overflow) { dev->buffer_overflow = 0; spin_unlock_irq(&dev->rbsl); -- GitLab From 88f6bf3846ee90bf33aa1ce848cd3bfb3229f4a4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Oct 2019 16:32:03 +0200 Subject: [PATCH 797/993] USB: ldusb: use unsigned size format specifiers A recent info-leak bug manifested itself along with warning about a negative buffer overflow: ldusb 1-1:0.28: Read buffer overflow, -131383859965943 bytes dropped when it was really a rather large positive one. A sanity check that prevents this has now been put in place, but let's fix up the size format specifiers, which should all be unsigned. Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20191022143203.5260-3-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ldusb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index c3e764909fd0..dd1ea25e42b1 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -487,7 +487,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, } bytes_to_read = min(count, *actual_buffer); if (bytes_to_read < *actual_buffer) - dev_warn(&dev->intf->dev, "Read buffer overflow, %zd bytes dropped\n", + dev_warn(&dev->intf->dev, "Read buffer overflow, %zu bytes dropped\n", *actual_buffer-bytes_to_read); /* copy one interrupt_in_buffer from ring_buffer into userspace */ @@ -562,8 +562,9 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer, /* write the data into interrupt_out_buffer from userspace */ bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size); if (bytes_to_write < count) - dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n", count-bytes_to_write); - dev_dbg(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", + dev_warn(&dev->intf->dev, "Write buffer overflow, %zu bytes dropped\n", + count - bytes_to_write); + dev_dbg(&dev->intf->dev, "%s: count = %zu, bytes_to_write = %zu\n", __func__, count, bytes_to_write); if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) { -- GitLab From 52403cfbc635d28195167618690595013776ebde Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 22 Oct 2019 17:31:27 +0200 Subject: [PATCH 798/993] USB: ldusb: fix control-message timeout USB control-message timeouts are specified in milliseconds, not jiffies. Waiting 83 minutes for a transfer to complete is a bit excessive. Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") Cc: stable # 2.6.13 Reported-by: syzbot+a4fbb3bb76cda0ea4e58@syzkaller.appspotmail.com Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20191022153127.22295-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ldusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index dd1ea25e42b1..8f86b4ebca89 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -581,7 +581,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer, 1 << 8, 0, dev->interrupt_out_buffer, bytes_to_write, - USB_CTRL_SET_TIMEOUT * HZ); + USB_CTRL_SET_TIMEOUT); if (retval < 0) dev_err(&dev->intf->dev, "Couldn't submit HID_REQ_SET_REPORT %d\n", -- GitLab From 18b74067ac78a2dea65783314c13df98a53d071c Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Fri, 25 Oct 2019 17:30:27 +0300 Subject: [PATCH 799/993] xhci: Fix use-after-free regression in xhci clear hub TT implementation commit ef513be0a905 ("usb: xhci: Add Clear_TT_Buffer") schedules work to clear TT buffer, but causes a use-after-free regression at the same time Make sure hub_tt_work finishes before endpoint is disabled, otherwise the work will dereference already freed endpoint and device related pointers. This was triggered when usb core failed to read the configuration descriptor of a FS/LS device during enumeration. xhci driver queued clear_tt_work while usb core freed and reallocated a new device for the next enumeration attempt. EHCI driver implents ehci_endpoint_disable() that makes sure clear_tt_work has finished before it returns, but xhci lacks this support. usb core will call hcd->driver->endpoint_disable() callback before disabling endpoints, so we want this in xhci as well. The added xhci_endpoint_disable() is based on ehci_endpoint_disable() Fixes: ef513be0a905 ("usb: xhci: Add Clear_TT_Buffer") Cc: # v5.3 Reported-by: Johan Hovold Suggested-by: Johan Hovold Reviewed-by: Johan Hovold Tested-by: Johan Hovold Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/1572013829-14044-2-git-send-email-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 54 ++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 517ec3206f6e..6c17e3fe181a 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3071,6 +3071,48 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci, unsigned int ep_index, } } +static void xhci_endpoint_disable(struct usb_hcd *hcd, + struct usb_host_endpoint *host_ep) +{ + struct xhci_hcd *xhci; + struct xhci_virt_device *vdev; + struct xhci_virt_ep *ep; + struct usb_device *udev; + unsigned long flags; + unsigned int ep_index; + + xhci = hcd_to_xhci(hcd); +rescan: + spin_lock_irqsave(&xhci->lock, flags); + + udev = (struct usb_device *)host_ep->hcpriv; + if (!udev || !udev->slot_id) + goto done; + + vdev = xhci->devs[udev->slot_id]; + if (!vdev) + goto done; + + ep_index = xhci_get_endpoint_index(&host_ep->desc); + ep = &vdev->eps[ep_index]; + if (!ep) + goto done; + + /* wait for hub_tt_work to finish clearing hub TT */ + if (ep->ep_state & EP_CLEARING_TT) { + spin_unlock_irqrestore(&xhci->lock, flags); + schedule_timeout_uninterruptible(1); + goto rescan; + } + + if (ep->ep_state) + xhci_dbg(xhci, "endpoint disable with ep_state 0x%x\n", + ep->ep_state); +done: + host_ep->hcpriv = NULL; + spin_unlock_irqrestore(&xhci->lock, flags); +} + /* * Called after usb core issues a clear halt control message. * The host side of the halt should already be cleared by a reset endpoint @@ -5238,20 +5280,13 @@ static void xhci_clear_tt_buffer_complete(struct usb_hcd *hcd, unsigned int ep_index; unsigned long flags; - /* - * udev might be NULL if tt buffer is cleared during a failed device - * enumeration due to a halted control endpoint. Usb core might - * have allocated a new udev for the next enumeration attempt. - */ - xhci = hcd_to_xhci(hcd); + + spin_lock_irqsave(&xhci->lock, flags); udev = (struct usb_device *)ep->hcpriv; - if (!udev) - return; slot_id = udev->slot_id; ep_index = xhci_get_endpoint_index(&ep->desc); - spin_lock_irqsave(&xhci->lock, flags); xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_CLEARING_TT; xhci_ring_doorbell_for_active_rings(xhci, slot_id, ep_index); spin_unlock_irqrestore(&xhci->lock, flags); @@ -5288,6 +5323,7 @@ static const struct hc_driver xhci_hc_driver = { .free_streams = xhci_free_streams, .add_endpoint = xhci_add_endpoint, .drop_endpoint = xhci_drop_endpoint, + .endpoint_disable = xhci_endpoint_disable, .endpoint_reset = xhci_endpoint_reset, .check_bandwidth = xhci_check_bandwidth, .reset_bandwidth = xhci_reset_bandwidth, -- GitLab From bfa3dbb343f664573292afb9e44f9abeb81a19de Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Fri, 25 Oct 2019 17:30:28 +0300 Subject: [PATCH 800/993] usb: xhci: fix Immediate Data Transfer endianness The arguments to queue_trb are always byteswapped to LE for placement in the ring, but this should not happen in the case of immediate data; the bytes copied out of transfer_buffer are already in the correct order. Add a complementary byteswap so the bytes end up in the ring correctly. This was observed on BE ppc64 with a "Texas Instruments TUSB73x0 SuperSpeed USB 3.0 xHCI Host Controller [104c:8241]" as a ch341 usb-serial adapter ("1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter") always transmitting the same character (generally NUL) over the serial link regardless of the key pressed. Cc: # 5.2+ Fixes: 33e39350ebd2 ("usb: xhci: add Immediate Data Transfer support") Signed-off-by: Samuel Holland Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/1572013829-14044-3-git-send-email-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 85ceb43e3405..e7aab31fd9a5 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3330,6 +3330,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, if (xhci_urb_suitable_for_idt(urb)) { memcpy(&send_addr, urb->transfer_buffer, trb_buff_len); + le64_to_cpus(&send_addr); field |= TRB_IDT; } } @@ -3475,6 +3476,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, if (xhci_urb_suitable_for_idt(urb)) { memcpy(&addr, urb->transfer_buffer, urb->transfer_buffer_length); + le64_to_cpus(&addr); field |= TRB_IDT; } else { addr = (u64) urb->transfer_dma; -- GitLab From d5501d5c29a2e684640507cfee428178d6fd82ca Mon Sep 17 00:00:00 2001 From: "Ben Dooks (Codethink)" Date: Fri, 25 Oct 2019 17:30:29 +0300 Subject: [PATCH 801/993] usb: xhci: fix __le32/__le64 accessors in debugfs code It looks like some of the xhci debug code is passing u32 to functions directly from __le32/__le64 fields. Fix this by using le{32,64}_to_cpu() on these to fix the following sparse warnings; xhci-debugfs.c:205:62: warning: incorrect type in argument 1 (different base types) xhci-debugfs.c:205:62: expected unsigned int [usertype] field0 xhci-debugfs.c:205:62: got restricted __le32 xhci-debugfs.c:206:62: warning: incorrect type in argument 2 (different base types) xhci-debugfs.c:206:62: expected unsigned int [usertype] field1 xhci-debugfs.c:206:62: got restricted __le32 ... [Trim down commit message, sparse warnings were similar -Mathias] Cc: # 4.15+ Signed-off-by: Ben Dooks Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/1572013829-14044-4-git-send-email-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-debugfs.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c index 7ba6afc7ef23..76c3f29562d2 100644 --- a/drivers/usb/host/xhci-debugfs.c +++ b/drivers/usb/host/xhci-debugfs.c @@ -202,10 +202,10 @@ static void xhci_ring_dump_segment(struct seq_file *s, trb = &seg->trbs[i]; dma = seg->dma + i * sizeof(*trb); seq_printf(s, "%pad: %s\n", &dma, - xhci_decode_trb(trb->generic.field[0], - trb->generic.field[1], - trb->generic.field[2], - trb->generic.field[3])); + xhci_decode_trb(le32_to_cpu(trb->generic.field[0]), + le32_to_cpu(trb->generic.field[1]), + le32_to_cpu(trb->generic.field[2]), + le32_to_cpu(trb->generic.field[3]))); } } @@ -263,10 +263,10 @@ static int xhci_slot_context_show(struct seq_file *s, void *unused) xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus)); slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx); seq_printf(s, "%pad: %s\n", &dev->out_ctx->dma, - xhci_decode_slot_context(slot_ctx->dev_info, - slot_ctx->dev_info2, - slot_ctx->tt_info, - slot_ctx->dev_state)); + xhci_decode_slot_context(le32_to_cpu(slot_ctx->dev_info), + le32_to_cpu(slot_ctx->dev_info2), + le32_to_cpu(slot_ctx->tt_info), + le32_to_cpu(slot_ctx->dev_state))); return 0; } @@ -286,10 +286,10 @@ static int xhci_endpoint_context_show(struct seq_file *s, void *unused) ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, dci); dma = dev->out_ctx->dma + dci * CTX_SIZE(xhci->hcc_params); seq_printf(s, "%pad: %s\n", &dma, - xhci_decode_ep_context(ep_ctx->ep_info, - ep_ctx->ep_info2, - ep_ctx->deq, - ep_ctx->tx_info)); + xhci_decode_ep_context(le32_to_cpu(ep_ctx->ep_info), + le32_to_cpu(ep_ctx->ep_info2), + le64_to_cpu(ep_ctx->deq), + le32_to_cpu(ep_ctx->tx_info))); } return 0; -- GitLab From 28df0642abbf6d66908a2858922a7e4b21cdd8c2 Mon Sep 17 00:00:00 2001 From: GwanYeong Kim Date: Fri, 18 Oct 2019 03:22:23 +0000 Subject: [PATCH 802/993] usbip: tools: Fix read_usb_vudc_device() error path handling This isn't really accurate right. fread() doesn't always return 0 in error. It could return < number of elements and set errno. Signed-off-by: GwanYeong Kim Acked-by: Shuah Khan Link: https://lore.kernel.org/r/20191018032223.4644-1-gy741.kim@gmail.com Signed-off-by: Greg Kroah-Hartman --- tools/usb/usbip/libsrc/usbip_device_driver.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/usb/usbip/libsrc/usbip_device_driver.c b/tools/usb/usbip/libsrc/usbip_device_driver.c index 051d7d3f443b..927a151fa9aa 100644 --- a/tools/usb/usbip/libsrc/usbip_device_driver.c +++ b/tools/usb/usbip/libsrc/usbip_device_driver.c @@ -69,7 +69,7 @@ int read_usb_vudc_device(struct udev_device *sdev, struct usbip_usb_device *dev) FILE *fd = NULL; struct udev_device *plat; const char *speed; - int ret = 0; + size_t ret; plat = udev_device_get_parent(sdev); path = udev_device_get_syspath(plat); @@ -79,8 +79,10 @@ int read_usb_vudc_device(struct udev_device *sdev, struct usbip_usb_device *dev) if (!fd) return -1; ret = fread((char *) &descr, sizeof(descr), 1, fd); - if (ret < 0) + if (ret != 1) { + err("Cannot read vudc device descr file: %s", strerror(errno)); goto err; + } fclose(fd); copy_descr_attr(dev, &descr, bDeviceClass); -- GitLab From d4d8257754c3300ea2a465dadf8d2b02c713c920 Mon Sep 17 00:00:00 2001 From: Suwan Kim Date: Tue, 22 Oct 2019 18:30:17 +0900 Subject: [PATCH 803/993] usbip: Fix free of unallocated memory in vhci tx iso_buffer should be set to NULL after use and free in the while loop. In the case of isochronous URB in the while loop, iso_buffer is allocated and after sending it to server, buffer is deallocated. And then, if the next URB in the while loop is not a isochronous pipe, iso_buffer still holds the previously deallocated buffer address and kfree tries to free wrong buffer address. Fixes: ea44d190764b ("usbip: Implement SG support to vhci-hcd and stub driver") Reported-by: kbuild test robot Reported-by: Julia Lawall Signed-off-by: Suwan Kim Reviewed-by: Julia Lawall Acked-by: Shuah Khan Link: https://lore.kernel.org/r/20191022093017.8027-1-suwan.kim027@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/vhci_tx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/usbip/vhci_tx.c b/drivers/usb/usbip/vhci_tx.c index c3803785f6ef..0ae40a13a9fe 100644 --- a/drivers/usb/usbip/vhci_tx.c +++ b/drivers/usb/usbip/vhci_tx.c @@ -147,7 +147,10 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev) } kfree(iov); + /* This is only for isochronous case */ kfree(iso_buffer); + iso_buffer = NULL; + usbip_dbg_vhci_tx("send txdata\n"); total_size += txsize; -- GitLab From 9a976949613132977098fc49510b46fa8678d864 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 21 Oct 2019 11:48:06 -0400 Subject: [PATCH 804/993] usb-storage: Revert commit 747668dbc061 ("usb-storage: Set virt_boundary_mask to avoid SG overflows") Commit 747668dbc061 ("usb-storage: Set virt_boundary_mask to avoid SG overflows") attempted to solve a problem involving scatter-gather I/O and USB/IP by setting the virt_boundary_mask for mass-storage devices. However, it now turns out that this interacts badly with commit 09324d32d2a0 ("block: force an unlimited segment size on queues with a virt boundary"), which was added later. A typical error message is: ehci-pci 0000:00:13.2: swiotlb buffer is full (sz: 327680 bytes), total 32768 (slots), used 97 (slots) There is no longer any reason to keep the virt_boundary_mask setting for usb-storage. It was needed in the first place only for handling devices with a block size smaller than the maxpacket size and where the host controller was not capable of fully general scatter-gather operation (that is, able to merge two SG segments into a single USB packet). But: High-speed or slower connections never use a bulk maxpacket value larger than 512; The SCSI layer does not handle block devices with a block size smaller than 512 bytes; All the host controllers capable of SuperSpeed operation can handle fully general SG; Since commit ea44d190764b ("usbip: Implement SG support to vhci-hcd and stub driver") was merged, the USB/IP driver can also handle SG. Therefore all supported device/controller combinations should be okay with no need for any special virt_boundary_mask. So in order to fix the swiotlb problem, this patch reverts commit 747668dbc061. Reported-and-tested-by: Piergiorgio Sartor Link: https://marc.info/?l=linux-usb&m=157134199501202&w=2 Signed-off-by: Alan Stern CC: Seth Bollinger CC: Fixes: 747668dbc061 ("usb-storage: Set virt_boundary_mask to avoid SG overflows") Acked-by: Christoph Hellwig Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.1910211145520.1673-100000@iolanthe.rowland.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/scsiglue.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 6737fab94959..54a3c8195c96 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -68,7 +68,6 @@ static const char* host_info(struct Scsi_Host *host) static int slave_alloc (struct scsi_device *sdev) { struct us_data *us = host_to_us(sdev->host); - int maxp; /* * Set the INQUIRY transfer length to 36. We don't use any of @@ -77,15 +76,6 @@ static int slave_alloc (struct scsi_device *sdev) */ sdev->inquiry_len = 36; - /* - * USB has unusual scatter-gather requirements: the length of each - * scatterlist element except the last must be divisible by the - * Bulk maxpacket value. Fortunately this value is always a - * power of 2. Inform the block layer about this requirement. - */ - maxp = usb_maxpacket(us->pusb_dev, us->recv_bulk_pipe, 0); - blk_queue_virt_boundary(sdev->request_queue, maxp - 1); - /* * Some host controllers may have alignment requirements. * We'll play it safe by requiring 512-byte alignment always. -- GitLab From 1186f86a71130a7635a20843e355bb880c7349b2 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 23 Oct 2019 11:34:33 -0400 Subject: [PATCH 805/993] UAS: Revert commit 3ae62a42090f ("UAS: fix alignment of scatter/gather segments") Commit 3ae62a42090f ("UAS: fix alignment of scatter/gather segments"), copying a similar commit for usb-storage, attempted to solve a problem involving scatter-gather I/O and USB/IP by setting the virt_boundary_mask for mass-storage devices. However, it now turns out that the analogous change in usb-storage interacted badly with commit 09324d32d2a0 ("block: force an unlimited segment size on queues with a virt boundary"), which was added later. A typical error message is: ehci-pci 0000:00:13.2: swiotlb buffer is full (sz: 327680 bytes), total 32768 (slots), used 97 (slots) There is no longer any reason to keep the virt_boundary_mask setting in the uas driver. It was needed in the first place only for handling devices with a block size smaller than the maxpacket size and where the host controller was not capable of fully general scatter-gather operation (that is, able to merge two SG segments into a single USB packet). But: High-speed or slower connections never use a bulk maxpacket value larger than 512; The SCSI layer does not handle block devices with a block size smaller than 512 bytes; All the host controllers capable of SuperSpeed operation can handle fully general SG; Since commit ea44d190764b ("usbip: Implement SG support to vhci-hcd and stub driver") was merged, the USB/IP driver can also handle SG. Therefore all supported device/controller combinations should be okay with no need for any special virt_boundary_mask. So in order to head off potential problems similar to those affecting usb-storage, this patch reverts commit 3ae62a42090f. Signed-off-by: Alan Stern CC: Oliver Neukum CC: Acked-by: Christoph Hellwig Fixes: 3ae62a42090f ("UAS: fix alignment of scatter/gather segments") Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.1910231132470.1878-100000@iolanthe.rowland.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index bf80d6f81f58..34538253f12c 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -789,29 +789,9 @@ static int uas_slave_alloc(struct scsi_device *sdev) { struct uas_dev_info *devinfo = (struct uas_dev_info *)sdev->host->hostdata; - int maxp; sdev->hostdata = devinfo; - /* - * We have two requirements here. We must satisfy the requirements - * of the physical HC and the demands of the protocol, as we - * definitely want no additional memory allocation in this path - * ruling out using bounce buffers. - * - * For a transmission on USB to continue we must never send - * a package that is smaller than maxpacket. Hence the length of each - * scatterlist element except the last must be divisible by the - * Bulk maxpacket value. - * If the HC does not ensure that through SG, - * the upper layer must do that. We must assume nothing - * about the capabilities off the HC, so we use the most - * pessimistic requirement. - */ - - maxp = usb_maxpacket(devinfo->udev, devinfo->data_in_pipe, 0); - blk_queue_virt_boundary(sdev->request_queue, maxp - 1); - /* * The protocol has no requirements on alignment in the strict sense. * Controllers may or may not have alignment restrictions. -- GitLab From 5e3c82a0dd076c68164bb10649fbaa2af29f636d Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Mon, 28 Oct 2019 09:44:36 -0700 Subject: [PATCH 806/993] ANDROID: fix VIDEOBUF2_CORE dependency in 'allmodconfig' builds Fix missing dependency for CONFIG_VIDEOBUF2_CORE for 'allmodconfig' builds. Since CONFIG_MEDIA_SUPPORT is always selected, drop it from gki_defconfig Fixes: 649238947d688 ("ANDROID: init: GKI: enable hidden configs for media") Test: successful 'allmodconfig' build Change-Id: I1dd5ff154c1aeb90457c23dc233cb32595bd9bed Signed-off-by: Todd Kjos --- arch/arm64/configs/gki_defconfig | 1 - arch/x86/configs/gki_defconfig | 1 - init/Kconfig.gki | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index 74858518d011..0933c134a2d0 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -298,7 +298,6 @@ CONFIG_WATCHDOG=y CONFIG_MFD_ACT8945A=y CONFIG_MFD_SYSCON=y CONFIG_REGULATOR=y -CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y # CONFIG_VGA_ARB is not set diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index ba629336a4f2..277b0069671e 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -257,7 +257,6 @@ CONFIG_GPIOLIB=y CONFIG_DEVFREQ_THERMAL=y # CONFIG_X86_PKG_TEMP_THERMAL is not set CONFIG_REGULATOR=y -CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_DRM=y # CONFIG_DRM_FBDEV_EMULATION is not set diff --git a/init/Kconfig.gki b/init/Kconfig.gki index c9505a791280..c5a080e7784b 100644 --- a/init/Kconfig.gki +++ b/init/Kconfig.gki @@ -56,6 +56,7 @@ config GKI_HIDDEN_QCOM_CONFIGS config GKI_HIDDEN_MEDIA_CONFIGS bool "Hidden Media configs needed for GKI" select VIDEOBUF2_CORE + select MEDIA_SUPPORT help Dummy config option used to enable hidden media configs. These are normally selected implicitely when a module -- GitLab From 1524b12a6e02a85264af4ed208b034a2239ef374 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Thu, 24 Oct 2019 23:49:13 +0000 Subject: [PATCH 807/993] RDMA/mlx5: Use irq xarray locking for mkey_table The mkey_table xarray is touched by the reg_mr_callback() function which is called from a hard irq. Thus all other uses of xa_lock must use the _irq variants. WARNING: inconsistent lock state 5.4.0-rc1 #12 Not tainted -------------------------------- inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. python3/343 [HC0[0]:SC0[0]:HE1:SE1] takes: ffff888182be1d40 (&(&xa->xa_lock)->rlock#3){?.-.}, at: xa_erase+0x12/0x30 {IN-HARDIRQ-W} state was registered at: lock_acquire+0xe1/0x200 _raw_spin_lock_irqsave+0x35/0x50 reg_mr_callback+0x2dd/0x450 [mlx5_ib] mlx5_cmd_exec_cb_handler+0x2c/0x70 [mlx5_core] mlx5_cmd_comp_handler+0x355/0x840 [mlx5_core] [..] Possible unsafe locking scenario: CPU0 ---- lock(&(&xa->xa_lock)->rlock#3); lock(&(&xa->xa_lock)->rlock#3); *** DEADLOCK *** 2 locks held by python3/343: #0: ffff88818eb4bd38 (&uverbs_dev->disassociate_srcu){....}, at: ib_uverbs_ioctl+0xe5/0x1e0 [ib_uverbs] #1: ffff888176c76d38 (&file->hw_destroy_rwsem){++++}, at: uobj_destroy+0x2d/0x90 [ib_uverbs] stack backtrace: CPU: 3 PID: 343 Comm: python3 Not tainted 5.4.0-rc1 #12 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 Call Trace: dump_stack+0x86/0xca print_usage_bug.cold.50+0x2e5/0x355 mark_lock+0x871/0xb50 ? match_held_lock+0x20/0x250 ? check_usage_forwards+0x240/0x240 __lock_acquire+0x7de/0x23a0 ? __kasan_check_read+0x11/0x20 ? mark_lock+0xae/0xb50 ? mark_held_locks+0xb0/0xb0 ? find_held_lock+0xca/0xf0 lock_acquire+0xe1/0x200 ? xa_erase+0x12/0x30 _raw_spin_lock+0x2a/0x40 ? xa_erase+0x12/0x30 xa_erase+0x12/0x30 mlx5_ib_dealloc_mw+0x55/0xa0 [mlx5_ib] uverbs_dealloc_mw+0x3c/0x70 [ib_uverbs] uverbs_free_mw+0x1a/0x20 [ib_uverbs] destroy_hw_idr_uobject+0x49/0xa0 [ib_uverbs] [..] Fixes: 0417791536ae ("RDMA/mlx5: Add missing synchronize_srcu() for MW cases") Link: https://lore.kernel.org/r/20191024234910.GA9038@ziepe.ca Acked-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/mlx5/mr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 630599311586..7019c12005f4 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -1967,8 +1967,8 @@ int mlx5_ib_dealloc_mw(struct ib_mw *mw) int err; if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING)) { - xa_erase(&dev->mdev->priv.mkey_table, - mlx5_base_mkey(mmw->mmkey.key)); + xa_erase_irq(&dev->mdev->priv.mkey_table, + mlx5_base_mkey(mmw->mmkey.key)); /* * pagefault_single_data_segment() may be accessing mmw under * SRCU if the user bound an ODP MR to this MW. -- GitLab From d4934f45693651ea15357dd6c7c36be28b6da884 Mon Sep 17 00:00:00 2001 From: Potnuri Bharat Teja Date: Fri, 25 Oct 2019 18:04:40 +0530 Subject: [PATCH 808/993] RDMA/iw_cxgb4: Avoid freeing skb twice in arp failure case _put_ep_safe() and _put_pass_ep_safe() free the skb before it is freed by process_work(). fix double free by freeing the skb only in process_work(). Fixes: 1dad0ebeea1c ("iw_cxgb4: Avoid touch after free error in ARP failure handlers") Link: https://lore.kernel.org/r/1572006880-5800-1-git-send-email-bharat@chelsio.com Signed-off-by: Dakshaja Uppalapati Signed-off-by: Potnuri Bharat Teja Reviewed-by: Jason Gunthorpe Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/cxgb4/cm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 9e8eca7b613c..347dc242fb88 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -495,7 +495,6 @@ static int _put_ep_safe(struct c4iw_dev *dev, struct sk_buff *skb) ep = *((struct c4iw_ep **)(skb->cb + 2 * sizeof(void *))); release_ep_resources(ep); - kfree_skb(skb); return 0; } @@ -506,7 +505,6 @@ static int _put_pass_ep_safe(struct c4iw_dev *dev, struct sk_buff *skb) ep = *((struct c4iw_ep **)(skb->cb + 2 * sizeof(void *))); c4iw_put_ep(&ep->parent_ep->com); release_ep_resources(ep); - kfree_skb(skb); return 0; } -- GitLab From 00a5bf3a8ca30d19f24219fc3cfb74f4eab3600d Mon Sep 17 00:00:00 2001 From: Yash Shah Date: Fri, 25 Oct 2019 08:30:03 +0000 Subject: [PATCH 809/993] RISC-V: Add PCIe I/O BAR memory mapping For legacy I/O BARs (non-MMIO BARs) to work correctly on RISC-V Linux, we need to establish a reserved memory region for them, so that drivers that wish to use the legacy I/O BARs can issue reads and writes against a memory region that is mapped to the host PCIe controller's I/O BAR mapping. Signed-off-by: Yash Shah Signed-off-by: Paul Walmsley --- arch/riscv/include/asm/io.h | 7 +++++++ arch/riscv/include/asm/pgtable.h | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h index fc1189ad3777..3ba4d93721d3 100644 --- a/arch/riscv/include/asm/io.h +++ b/arch/riscv/include/asm/io.h @@ -13,6 +13,7 @@ #include #include +#include extern void __iomem *ioremap(phys_addr_t offset, unsigned long size); @@ -161,6 +162,12 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) #define writeq(v,c) ({ __io_bw(); writeq_cpu((v),(c)); __io_aw(); }) #endif +/* + * I/O port access constants. + */ +#define IO_SPACE_LIMIT (PCI_IO_SIZE - 1) +#define PCI_IOBASE ((void __iomem *)PCI_IO_START) + /* * Emulation routines for the port-mapped IO space used by some PCI drivers. * These are defined as being "fully synchronous", but also "not guaranteed to diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h index 0352f20c29f4..d3221017194d 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -7,6 +7,7 @@ #define _ASM_RISCV_PGTABLE_H #include +#include #include @@ -86,6 +87,7 @@ extern pgd_t swapper_pg_dir[]; #define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1) #define VMALLOC_END (PAGE_OFFSET - 1) #define VMALLOC_START (PAGE_OFFSET - VMALLOC_SIZE) +#define PCI_IO_SIZE SZ_16M /* * Roughly size the vmemmap space to be large enough to fit enough @@ -100,7 +102,10 @@ extern pgd_t swapper_pg_dir[]; #define vmemmap ((struct page *)VMEMMAP_START) -#define FIXADDR_TOP (VMEMMAP_START) +#define PCI_IO_END VMEMMAP_START +#define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE) +#define FIXADDR_TOP PCI_IO_START + #ifdef CONFIG_64BIT #define FIXADDR_SIZE PMD_SIZE #else -- GitLab From b681a0529968d2261aa15d7a1e78801b2c06bb07 Mon Sep 17 00:00:00 2001 From: Lijun Ou Date: Sat, 26 Oct 2019 14:56:35 +0800 Subject: [PATCH 810/993] RDMA/hns: Prevent memory leaks of eq->buf_list eq->buf_list->buf and eq->buf_list should also be freed when eqe_hop_num is set to 0, or there will be memory leaks. Fixes: a5073d6054f7 ("RDMA/hns: Add eq support of hip08") Link: https://lore.kernel.org/r/1572072995-11277-3-git-send-email-liweihang@hisilicon.com Signed-off-by: Lijun Ou Signed-off-by: Weihang Li Signed-off-by: Jason Gunthorpe --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 7a89d669f8bf..e82567fcdeb7 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -5389,9 +5389,9 @@ static void hns_roce_v2_free_eq(struct hns_roce_dev *hr_dev, return; } - if (eq->buf_list) - dma_free_coherent(hr_dev->dev, buf_chk_sz, - eq->buf_list->buf, eq->buf_list->map); + dma_free_coherent(hr_dev->dev, buf_chk_sz, eq->buf_list->buf, + eq->buf_list->map); + kfree(eq->buf_list); } static void hns_roce_config_eqc(struct hns_roce_dev *hr_dev, -- GitLab From feaba17c2fd036cd93eec04e2227dfd3e2778a87 Mon Sep 17 00:00:00 2001 From: Ram Muthiah Date: Mon, 28 Oct 2019 12:48:06 -0700 Subject: [PATCH 811/993] ANDROID: gki_defconfig: enable CONFIG_CPU_FREQ_GOV_CONSERVATIVE Bug: 135217602 Test: local boot on cuttlefish Change-Id: Icd2afaea9e1231735d2ab4f9588a44f7cbc584a5 Signed-off-by: Ram Muthiah --- arch/x86/configs/gki_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index 277b0069671e..5c304350fb68 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -46,6 +46,7 @@ CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set CONFIG_CPU_FREQ_TIMES=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y CONFIG_CPUFREQ_DUMMY=m CONFIG_IA32_EMULATION=y CONFIG_KPROBES=y -- GitLab From d7d16a89350ab263484c0aa2b523dd3a234e4a80 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 23 Oct 2019 22:44:48 -0700 Subject: [PATCH 812/993] net: add skb_queue_empty_lockless() Some paths call skb_queue_empty() without holding the queue lock. We must use a barrier in order to not let the compiler do strange things, and avoid KCSAN splats. Adding a barrier in skb_queue_empty() might be overkill, I prefer adding a new helper to clearly identify points where the callers might be lockless. This might help us finding real bugs. The corresponding WRITE_ONCE() should add zero cost for current compilers. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/skbuff.h | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index a391147c03d4..64a395c7f689 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1495,6 +1495,19 @@ static inline int skb_queue_empty(const struct sk_buff_head *list) return list->next == (const struct sk_buff *) list; } +/** + * skb_queue_empty_lockless - check if a queue is empty + * @list: queue head + * + * Returns true if the queue is empty, false otherwise. + * This variant can be used in lockless contexts. + */ +static inline bool skb_queue_empty_lockless(const struct sk_buff_head *list) +{ + return READ_ONCE(list->next) == (const struct sk_buff *) list; +} + + /** * skb_queue_is_last - check if skb is the last entry in the queue * @list: queue head @@ -1848,9 +1861,11 @@ static inline void __skb_insert(struct sk_buff *newsk, struct sk_buff *prev, struct sk_buff *next, struct sk_buff_head *list) { - newsk->next = next; - newsk->prev = prev; - next->prev = prev->next = newsk; + /* see skb_queue_empty_lockless() for the opposite READ_ONCE() */ + WRITE_ONCE(newsk->next, next); + WRITE_ONCE(newsk->prev, prev); + WRITE_ONCE(next->prev, newsk); + WRITE_ONCE(prev->next, newsk); list->qlen++; } @@ -1861,11 +1876,11 @@ static inline void __skb_queue_splice(const struct sk_buff_head *list, struct sk_buff *first = list->next; struct sk_buff *last = list->prev; - first->prev = prev; - prev->next = first; + WRITE_ONCE(first->prev, prev); + WRITE_ONCE(prev->next, first); - last->next = next; - next->prev = last; + WRITE_ONCE(last->next, next); + WRITE_ONCE(next->prev, last); } /** @@ -2006,8 +2021,8 @@ static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list) next = skb->next; prev = skb->prev; skb->next = skb->prev = NULL; - next->prev = prev; - prev->next = next; + WRITE_ONCE(next->prev, prev); + WRITE_ONCE(prev->next, next); } /** -- GitLab From 137a0dbe3426fd7bcfe3f8117b36a87b3590e4eb Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 23 Oct 2019 22:44:49 -0700 Subject: [PATCH 813/993] udp: use skb_queue_empty_lockless() syzbot reported a data-race [1]. We should use skb_queue_empty_lockless() to document that we are not ensuring a mutual exclusion and silence KCSAN. [1] BUG: KCSAN: data-race in __skb_recv_udp / __udp_enqueue_schedule_skb write to 0xffff888122474b50 of 8 bytes by interrupt on cpu 0: __skb_insert include/linux/skbuff.h:1852 [inline] __skb_queue_before include/linux/skbuff.h:1958 [inline] __skb_queue_tail include/linux/skbuff.h:1991 [inline] __udp_enqueue_schedule_skb+0x2c1/0x410 net/ipv4/udp.c:1470 __udp_queue_rcv_skb net/ipv4/udp.c:1940 [inline] udp_queue_rcv_one_skb+0x7bd/0xc70 net/ipv4/udp.c:2057 udp_queue_rcv_skb+0xb5/0x400 net/ipv4/udp.c:2074 udp_unicast_rcv_skb.isra.0+0x7e/0x1c0 net/ipv4/udp.c:2233 __udp4_lib_rcv+0xa44/0x17c0 net/ipv4/udp.c:2300 udp_rcv+0x2b/0x40 net/ipv4/udp.c:2470 ip_protocol_deliver_rcu+0x4d/0x420 net/ipv4/ip_input.c:204 ip_local_deliver_finish+0x110/0x140 net/ipv4/ip_input.c:231 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_local_deliver+0x133/0x210 net/ipv4/ip_input.c:252 dst_input include/net/dst.h:442 [inline] ip_rcv_finish+0x121/0x160 net/ipv4/ip_input.c:413 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_rcv+0x18f/0x1a0 net/ipv4/ip_input.c:523 __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5010 __netif_receive_skb+0x37/0xf0 net/core/dev.c:5124 process_backlog+0x1d3/0x420 net/core/dev.c:5955 read to 0xffff888122474b50 of 8 bytes by task 8921 on cpu 1: skb_queue_empty include/linux/skbuff.h:1494 [inline] __skb_recv_udp+0x18d/0x500 net/ipv4/udp.c:1653 udp_recvmsg+0xe1/0xb10 net/ipv4/udp.c:1712 inet_recvmsg+0xbb/0x250 net/ipv4/af_inet.c:838 sock_recvmsg_nosec+0x5c/0x70 net/socket.c:871 ___sys_recvmsg+0x1a0/0x3e0 net/socket.c:2480 do_recvmmsg+0x19a/0x5c0 net/socket.c:2601 __sys_recvmmsg+0x1ef/0x200 net/socket.c:2680 __do_sys_recvmmsg net/socket.c:2703 [inline] __se_sys_recvmmsg net/socket.c:2696 [inline] __x64_sys_recvmmsg+0x89/0xb0 net/socket.c:2696 do_syscall_64+0xcc/0x370 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Reported by Kernel Concurrency Sanitizer on: CPU: 1 PID: 8921 Comm: syz-executor.4 Not tainted 5.4.0-rc3+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: David S. Miller --- net/ipv4/udp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 14bc654b6842..2cc259736c2e 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1577,7 +1577,7 @@ static int first_packet_length(struct sock *sk) spin_lock_bh(&rcvq->lock); skb = __first_packet_length(sk, rcvq, &total); - if (!skb && !skb_queue_empty(sk_queue)) { + if (!skb && !skb_queue_empty_lockless(sk_queue)) { spin_lock(&sk_queue->lock); skb_queue_splice_tail_init(sk_queue, rcvq); spin_unlock(&sk_queue->lock); @@ -1650,7 +1650,7 @@ struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned int flags, return skb; } - if (skb_queue_empty(sk_queue)) { + if (skb_queue_empty_lockless(sk_queue)) { spin_unlock_bh(&queue->lock); goto busy_check; } @@ -1676,7 +1676,7 @@ struct sk_buff *__skb_recv_udp(struct sock *sk, unsigned int flags, break; sk_busy_loop(sk, flags & MSG_DONTWAIT); - } while (!skb_queue_empty(sk_queue)); + } while (!skb_queue_empty_lockless(sk_queue)); /* sk_queue is empty, reader_queue may contain peeked packets */ } while (timeo && -- GitLab From 3ef7cf57c72f32f61e97f8fa401bc39ea1f1a5d4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 23 Oct 2019 22:44:50 -0700 Subject: [PATCH 814/993] net: use skb_queue_empty_lockless() in poll() handlers Many poll() handlers are lockless. Using skb_queue_empty_lockless() instead of skb_queue_empty() is more appropriate. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/isdn/capi/capi.c | 2 +- net/atm/common.c | 2 +- net/bluetooth/af_bluetooth.c | 4 ++-- net/caif/caif_socket.c | 2 +- net/core/datagram.c | 4 ++-- net/decnet/af_decnet.c | 2 +- net/ipv4/tcp.c | 2 +- net/ipv4/udp.c | 2 +- net/nfc/llcp_sock.c | 4 ++-- net/phonet/socket.c | 4 ++-- net/sctp/socket.c | 4 ++-- net/tipc/socket.c | 4 ++-- net/unix/af_unix.c | 6 +++--- net/vmw_vsock/af_vsock.c | 2 +- 14 files changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index c92b405b7646..ba8619524231 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -744,7 +744,7 @@ capi_poll(struct file *file, poll_table *wait) poll_wait(file, &(cdev->recvwait), wait); mask = EPOLLOUT | EPOLLWRNORM; - if (!skb_queue_empty(&cdev->recvqueue)) + if (!skb_queue_empty_lockless(&cdev->recvqueue)) mask |= EPOLLIN | EPOLLRDNORM; return mask; } diff --git a/net/atm/common.c b/net/atm/common.c index b7528e77997c..0ce530af534d 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -668,7 +668,7 @@ __poll_t vcc_poll(struct file *file, struct socket *sock, poll_table *wait) mask |= EPOLLHUP; /* readable? */ - if (!skb_queue_empty(&sk->sk_receive_queue)) + if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) mask |= EPOLLIN | EPOLLRDNORM; /* writable? */ diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 94ddf19998c7..5f508c50649d 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -460,7 +460,7 @@ __poll_t bt_sock_poll(struct file *file, struct socket *sock, if (sk->sk_state == BT_LISTEN) return bt_accept_poll(sk); - if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) + if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue)) mask |= EPOLLERR | (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0); @@ -470,7 +470,7 @@ __poll_t bt_sock_poll(struct file *file, struct socket *sock, if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= EPOLLHUP; - if (!skb_queue_empty(&sk->sk_receive_queue)) + if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) mask |= EPOLLIN | EPOLLRDNORM; if (sk->sk_state == BT_CLOSED) diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 13ea920600ae..ef14da50a981 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -953,7 +953,7 @@ static __poll_t caif_poll(struct file *file, mask |= EPOLLRDHUP; /* readable? */ - if (!skb_queue_empty(&sk->sk_receive_queue) || + if (!skb_queue_empty_lockless(&sk->sk_receive_queue) || (sk->sk_shutdown & RCV_SHUTDOWN)) mask |= EPOLLIN | EPOLLRDNORM; diff --git a/net/core/datagram.c b/net/core/datagram.c index c210fc116103..5b685e110aff 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -767,7 +767,7 @@ __poll_t datagram_poll(struct file *file, struct socket *sock, mask = 0; /* exceptional events? */ - if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) + if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue)) mask |= EPOLLERR | (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0); @@ -777,7 +777,7 @@ __poll_t datagram_poll(struct file *file, struct socket *sock, mask |= EPOLLHUP; /* readable? */ - if (!skb_queue_empty(&sk->sk_receive_queue)) + if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) mask |= EPOLLIN | EPOLLRDNORM; /* Connection-based need to check for termination and startup */ diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index 0ea75286abf4..3349ea81f901 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -1205,7 +1205,7 @@ static __poll_t dn_poll(struct file *file, struct socket *sock, poll_table *wai struct dn_scp *scp = DN_SK(sk); __poll_t mask = datagram_poll(file, sock, wait); - if (!skb_queue_empty(&scp->other_receive_queue)) + if (!skb_queue_empty_lockless(&scp->other_receive_queue)) mask |= EPOLLRDBAND; return mask; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 42187a3b82f4..ffef502f5292 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -584,7 +584,7 @@ __poll_t tcp_poll(struct file *file, struct socket *sock, poll_table *wait) } /* This barrier is coupled with smp_wmb() in tcp_reset() */ smp_rmb(); - if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) + if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue)) mask |= EPOLLERR; return mask; diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 2cc259736c2e..345a3d43f5a6 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -2712,7 +2712,7 @@ __poll_t udp_poll(struct file *file, struct socket *sock, poll_table *wait) __poll_t mask = datagram_poll(file, sock, wait); struct sock *sk = sock->sk; - if (!skb_queue_empty(&udp_sk(sk)->reader_queue)) + if (!skb_queue_empty_lockless(&udp_sk(sk)->reader_queue)) mask |= EPOLLIN | EPOLLRDNORM; /* Check for false positives due to checksum errors */ diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c index ccdd790e163a..28604414dec1 100644 --- a/net/nfc/llcp_sock.c +++ b/net/nfc/llcp_sock.c @@ -554,11 +554,11 @@ static __poll_t llcp_sock_poll(struct file *file, struct socket *sock, if (sk->sk_state == LLCP_LISTEN) return llcp_accept_poll(sk); - if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) + if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue)) mask |= EPOLLERR | (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0); - if (!skb_queue_empty(&sk->sk_receive_queue)) + if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) mask |= EPOLLIN | EPOLLRDNORM; if (sk->sk_state == LLCP_CLOSED) diff --git a/net/phonet/socket.c b/net/phonet/socket.c index 96ea9f254ae9..76d499f6af9a 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c @@ -338,9 +338,9 @@ static __poll_t pn_socket_poll(struct file *file, struct socket *sock, if (sk->sk_state == TCP_CLOSE) return EPOLLERR; - if (!skb_queue_empty(&sk->sk_receive_queue)) + if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) mask |= EPOLLIN | EPOLLRDNORM; - if (!skb_queue_empty(&pn->ctrlreq_queue)) + if (!skb_queue_empty_lockless(&pn->ctrlreq_queue)) mask |= EPOLLPRI; if (!mask && sk->sk_state == TCP_CLOSE_WAIT) return EPOLLHUP; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 5ca0ec0e823c..cfb25391b8b0 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -8476,7 +8476,7 @@ __poll_t sctp_poll(struct file *file, struct socket *sock, poll_table *wait) mask = 0; /* Is there any exceptional events? */ - if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) + if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue)) mask |= EPOLLERR | (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0); if (sk->sk_shutdown & RCV_SHUTDOWN) @@ -8485,7 +8485,7 @@ __poll_t sctp_poll(struct file *file, struct socket *sock, poll_table *wait) mask |= EPOLLHUP; /* Is it readable? Reconsider this code with TCP-style support. */ - if (!skb_queue_empty(&sk->sk_receive_queue)) + if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) mask |= EPOLLIN | EPOLLRDNORM; /* The association is either gone or not ready. */ diff --git a/net/tipc/socket.c b/net/tipc/socket.c index f8bbc4aab213..4b92b196cfa6 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -740,7 +740,7 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock, /* fall through */ case TIPC_LISTEN: case TIPC_CONNECTING: - if (!skb_queue_empty(&sk->sk_receive_queue)) + if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) revents |= EPOLLIN | EPOLLRDNORM; break; case TIPC_OPEN: @@ -748,7 +748,7 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock, revents |= EPOLLOUT; if (!tipc_sk_type_connectionless(sk)) break; - if (skb_queue_empty(&sk->sk_receive_queue)) + if (skb_queue_empty_lockless(&sk->sk_receive_queue)) break; revents |= EPOLLIN | EPOLLRDNORM; break; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 67e87db5877f..0d8da809bea2 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -2599,7 +2599,7 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wa mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM; /* readable? */ - if (!skb_queue_empty(&sk->sk_receive_queue)) + if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) mask |= EPOLLIN | EPOLLRDNORM; /* Connection-based need to check for termination and startup */ @@ -2628,7 +2628,7 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock, mask = 0; /* exceptional events? */ - if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) + if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue)) mask |= EPOLLERR | (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0); @@ -2638,7 +2638,7 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock, mask |= EPOLLHUP; /* readable? */ - if (!skb_queue_empty(&sk->sk_receive_queue)) + if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) mask |= EPOLLIN | EPOLLRDNORM; /* Connection-based need to check for termination and startup */ diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 2ab43b2bba31..582a3e4dfce2 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -870,7 +870,7 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock, * the queue and write as long as the socket isn't shutdown for * sending. */ - if (!skb_queue_empty(&sk->sk_receive_queue) || + if (!skb_queue_empty_lockless(&sk->sk_receive_queue) || (sk->sk_shutdown & RCV_SHUTDOWN)) { mask |= EPOLLIN | EPOLLRDNORM; } -- GitLab From 3f926af3f4d688e2e11e7f8ed04e277a14d4d4a4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 23 Oct 2019 22:44:51 -0700 Subject: [PATCH 815/993] net: use skb_queue_empty_lockless() in busy poll contexts Busy polling usually runs without locks. Let's use skb_queue_empty_lockless() instead of skb_queue_empty() Also uses READ_ONCE() in __skb_try_recv_datagram() to address a similar potential problem. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/crypto/chelsio/chtls/chtls_io.c | 2 +- drivers/nvme/host/tcp.c | 2 +- net/core/datagram.c | 2 +- net/core/sock.c | 2 +- net/ipv4/tcp.c | 2 +- net/sctp/socket.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/chelsio/chtls/chtls_io.c b/drivers/crypto/chelsio/chtls/chtls_io.c index 0891ab829b1b..98bc5a4cd5e7 100644 --- a/drivers/crypto/chelsio/chtls/chtls_io.c +++ b/drivers/crypto/chelsio/chtls/chtls_io.c @@ -1702,7 +1702,7 @@ int chtls_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, return peekmsg(sk, msg, len, nonblock, flags); if (sk_can_busy_loop(sk) && - skb_queue_empty(&sk->sk_receive_queue) && + skb_queue_empty_lockless(&sk->sk_receive_queue) && sk->sk_state == TCP_ESTABLISHED) sk_busy_loop(sk, nonblock); diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 770dbcbc999e..7544be84ab35 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -2219,7 +2219,7 @@ static int nvme_tcp_poll(struct blk_mq_hw_ctx *hctx) struct nvme_tcp_queue *queue = hctx->driver_data; struct sock *sk = queue->sock->sk; - if (sk_can_busy_loop(sk) && skb_queue_empty(&sk->sk_receive_queue)) + if (sk_can_busy_loop(sk) && skb_queue_empty_lockless(&sk->sk_receive_queue)) sk_busy_loop(sk, true); nvme_tcp_try_recv(queue); return queue->nr_cqe; diff --git a/net/core/datagram.c b/net/core/datagram.c index 5b685e110aff..03515e46a49a 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -278,7 +278,7 @@ struct sk_buff *__skb_try_recv_datagram(struct sock *sk, unsigned int flags, break; sk_busy_loop(sk, flags & MSG_DONTWAIT); - } while (sk->sk_receive_queue.prev != *last); + } while (READ_ONCE(sk->sk_receive_queue.prev) != *last); error = -EAGAIN; diff --git a/net/core/sock.c b/net/core/sock.c index a515392ba84b..b8e758bcb6ad 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -3600,7 +3600,7 @@ bool sk_busy_loop_end(void *p, unsigned long start_time) { struct sock *sk = p; - return !skb_queue_empty(&sk->sk_receive_queue) || + return !skb_queue_empty_lockless(&sk->sk_receive_queue) || sk_busy_loop_timeout(sk, start_time); } EXPORT_SYMBOL(sk_busy_loop_end); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index ffef502f5292..d8876f0e9672 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1964,7 +1964,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, if (unlikely(flags & MSG_ERRQUEUE)) return inet_recv_error(sk, msg, len, addr_len); - if (sk_can_busy_loop(sk) && skb_queue_empty(&sk->sk_receive_queue) && + if (sk_can_busy_loop(sk) && skb_queue_empty_lockless(&sk->sk_receive_queue) && (sk->sk_state == TCP_ESTABLISHED)) sk_busy_loop(sk, nonblock); diff --git a/net/sctp/socket.c b/net/sctp/socket.c index cfb25391b8b0..ca81e06df165 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -8871,7 +8871,7 @@ struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, if (sk_can_busy_loop(sk)) { sk_busy_loop(sk, noblock); - if (!skb_queue_empty(&sk->sk_receive_queue)) + if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) continue; } -- GitLab From 7c422d0ce97552dde4a97e6290de70ec6efb0fc6 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 23 Oct 2019 22:44:52 -0700 Subject: [PATCH 816/993] net: add READ_ONCE() annotation in __skb_wait_for_more_packets() __skb_wait_for_more_packets() can be called while other cpus can feed packets to the socket receive queue. KCSAN reported : BUG: KCSAN: data-race in __skb_wait_for_more_packets / __udp_enqueue_schedule_skb write to 0xffff888102e40b58 of 8 bytes by interrupt on cpu 0: __skb_insert include/linux/skbuff.h:1852 [inline] __skb_queue_before include/linux/skbuff.h:1958 [inline] __skb_queue_tail include/linux/skbuff.h:1991 [inline] __udp_enqueue_schedule_skb+0x2d7/0x410 net/ipv4/udp.c:1470 __udp_queue_rcv_skb net/ipv4/udp.c:1940 [inline] udp_queue_rcv_one_skb+0x7bd/0xc70 net/ipv4/udp.c:2057 udp_queue_rcv_skb+0xb5/0x400 net/ipv4/udp.c:2074 udp_unicast_rcv_skb.isra.0+0x7e/0x1c0 net/ipv4/udp.c:2233 __udp4_lib_rcv+0xa44/0x17c0 net/ipv4/udp.c:2300 udp_rcv+0x2b/0x40 net/ipv4/udp.c:2470 ip_protocol_deliver_rcu+0x4d/0x420 net/ipv4/ip_input.c:204 ip_local_deliver_finish+0x110/0x140 net/ipv4/ip_input.c:231 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_local_deliver+0x133/0x210 net/ipv4/ip_input.c:252 dst_input include/net/dst.h:442 [inline] ip_rcv_finish+0x121/0x160 net/ipv4/ip_input.c:413 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_rcv+0x18f/0x1a0 net/ipv4/ip_input.c:523 __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5010 __netif_receive_skb+0x37/0xf0 net/core/dev.c:5124 process_backlog+0x1d3/0x420 net/core/dev.c:5955 read to 0xffff888102e40b58 of 8 bytes by task 13035 on cpu 1: __skb_wait_for_more_packets+0xfa/0x320 net/core/datagram.c:100 __skb_recv_udp+0x374/0x500 net/ipv4/udp.c:1683 udp_recvmsg+0xe1/0xb10 net/ipv4/udp.c:1712 inet_recvmsg+0xbb/0x250 net/ipv4/af_inet.c:838 sock_recvmsg_nosec+0x5c/0x70 net/socket.c:871 ___sys_recvmsg+0x1a0/0x3e0 net/socket.c:2480 do_recvmmsg+0x19a/0x5c0 net/socket.c:2601 __sys_recvmmsg+0x1ef/0x200 net/socket.c:2680 __do_sys_recvmmsg net/socket.c:2703 [inline] __se_sys_recvmmsg net/socket.c:2696 [inline] __x64_sys_recvmmsg+0x89/0xb0 net/socket.c:2696 do_syscall_64+0xcc/0x370 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Reported by Kernel Concurrency Sanitizer on: CPU: 1 PID: 13035 Comm: syz-executor.3 Not tainted 5.4.0-rc3+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: David S. Miller --- net/core/datagram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/datagram.c b/net/core/datagram.c index 03515e46a49a..da3c24ed129c 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -97,7 +97,7 @@ int __skb_wait_for_more_packets(struct sock *sk, int *err, long *timeo_p, if (error) goto out_err; - if (sk->sk_receive_queue.prev != skb) + if (READ_ONCE(sk->sk_receive_queue.prev) != skb) goto out; /* Socket shut down? */ -- GitLab From 7de4344f2abbaeda5c62211a8314dbd5da2bac6c Mon Sep 17 00:00:00 2001 From: Nishad Kamdar Date: Thu, 24 Oct 2019 20:42:00 +0530 Subject: [PATCH 817/993] net: dpaa2: Use the correct style for SPDX License Identifier This patch corrects the SPDX License Identifier style in header files related to DPAA2 Ethernet driver supporting Freescale SoCs with DPAA2. For C header files Documentation/process/license-rules.rst mandates C-like comments (opposed to C source files where C++ style should be used) Changes made by using a script provided by Joe Perches here: https://lkml.org/lkml/2019/2/7/46. Suggested-by: Joe Perches Signed-off-by: Nishad Kamdar Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h | 2 +- drivers/net/ethernet/freescale/dpaa2/dprtc-cmd.h | 2 +- drivers/net/ethernet/freescale/dpaa2/dprtc.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h index ff2e177395d4..df2458a5e9ef 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2018 NXP */ diff --git a/drivers/net/ethernet/freescale/dpaa2/dprtc-cmd.h b/drivers/net/ethernet/freescale/dpaa2/dprtc-cmd.h index 720cd50f5895..4ac05bfef338 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dprtc-cmd.h +++ b/drivers/net/ethernet/freescale/dpaa2/dprtc-cmd.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2013-2016 Freescale Semiconductor Inc. * Copyright 2016-2018 NXP diff --git a/drivers/net/ethernet/freescale/dpaa2/dprtc.h b/drivers/net/ethernet/freescale/dpaa2/dprtc.h index be7914c1634d..311c184e1aef 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dprtc.h +++ b/drivers/net/ethernet/freescale/dpaa2/dprtc.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0 +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2013-2016 Freescale Semiconductor Inc. * Copyright 2016-2018 NXP -- GitLab From a793183caa9afae907a0d7ddd2ffd57329369bf5 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 24 Oct 2019 11:43:31 -0700 Subject: [PATCH 818/993] udp: fix data-race in udp_set_dev_scratch() KCSAN reported a data-race in udp_set_dev_scratch() [1] The issue here is that we must not write over skb fields if skb is shared. A similar issue has been fixed in commit 89c22d8c3b27 ("net: Fix skb csum races when peeking") While we are at it, use a helper only dealing with udp_skb_scratch(skb)->csum_unnecessary, as this allows udp_set_dev_scratch() to be called once and thus inlined. [1] BUG: KCSAN: data-race in udp_set_dev_scratch / udpv6_recvmsg write to 0xffff888120278317 of 1 bytes by task 10411 on cpu 1: udp_set_dev_scratch+0xea/0x200 net/ipv4/udp.c:1308 __first_packet_length+0x147/0x420 net/ipv4/udp.c:1556 first_packet_length+0x68/0x2a0 net/ipv4/udp.c:1579 udp_poll+0xea/0x110 net/ipv4/udp.c:2720 sock_poll+0xed/0x250 net/socket.c:1256 vfs_poll include/linux/poll.h:90 [inline] do_select+0x7d0/0x1020 fs/select.c:534 core_sys_select+0x381/0x550 fs/select.c:677 do_pselect.constprop.0+0x11d/0x160 fs/select.c:759 __do_sys_pselect6 fs/select.c:784 [inline] __se_sys_pselect6 fs/select.c:769 [inline] __x64_sys_pselect6+0x12e/0x170 fs/select.c:769 do_syscall_64+0xcc/0x370 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x44/0xa9 read to 0xffff888120278317 of 1 bytes by task 10413 on cpu 0: udp_skb_csum_unnecessary include/net/udp.h:358 [inline] udpv6_recvmsg+0x43e/0xe90 net/ipv6/udp.c:310 inet6_recvmsg+0xbb/0x240 net/ipv6/af_inet6.c:592 sock_recvmsg_nosec+0x5c/0x70 net/socket.c:871 ___sys_recvmsg+0x1a0/0x3e0 net/socket.c:2480 do_recvmmsg+0x19a/0x5c0 net/socket.c:2601 __sys_recvmmsg+0x1ef/0x200 net/socket.c:2680 __do_sys_recvmmsg net/socket.c:2703 [inline] __se_sys_recvmmsg net/socket.c:2696 [inline] __x64_sys_recvmmsg+0x89/0xb0 net/socket.c:2696 do_syscall_64+0xcc/0x370 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Reported by Kernel Concurrency Sanitizer on: CPU: 0 PID: 10413 Comm: syz-executor.0 Not tainted 5.4.0-rc3+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Fixes: 2276f58ac589 ("udp: use a separate rx queue for packet reception") Signed-off-by: Eric Dumazet Reported-by: syzbot Cc: Paolo Abeni Reviewed-by: Paolo Abeni Signed-off-by: David S. Miller --- net/ipv4/udp.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 345a3d43f5a6..d1ed160af202 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1316,6 +1316,20 @@ static void udp_set_dev_scratch(struct sk_buff *skb) scratch->_tsize_state |= UDP_SKB_IS_STATELESS; } +static void udp_skb_csum_unnecessary_set(struct sk_buff *skb) +{ + /* We come here after udp_lib_checksum_complete() returned 0. + * This means that __skb_checksum_complete() might have + * set skb->csum_valid to 1. + * On 64bit platforms, we can set csum_unnecessary + * to true, but only if the skb is not shared. + */ +#if BITS_PER_LONG == 64 + if (!skb_shared(skb)) + udp_skb_scratch(skb)->csum_unnecessary = true; +#endif +} + static int udp_skb_truesize(struct sk_buff *skb) { return udp_skb_scratch(skb)->_tsize_state & ~UDP_SKB_IS_STATELESS; @@ -1550,10 +1564,7 @@ static struct sk_buff *__first_packet_length(struct sock *sk, *total += skb->truesize; kfree_skb(skb); } else { - /* the csum related bits could be changed, refresh - * the scratch area - */ - udp_set_dev_scratch(skb); + udp_skb_csum_unnecessary_set(skb); break; } } -- GitLab From 20eb4f29b60286e0d6dc01d9c260b4bd383c58fb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 24 Oct 2019 13:50:27 -0700 Subject: [PATCH 819/993] net: fix sk_page_frag() recursion from memory reclaim sk_page_frag() optimizes skb_frag allocations by using per-task skb_frag cache when it knows it's the only user. The condition is determined by seeing whether the socket allocation mask allows blocking - if the allocation may block, it obviously owns the task's context and ergo exclusively owns current->task_frag. Unfortunately, this misses recursion through memory reclaim path. Please take a look at the following backtrace. [2] RIP: 0010:tcp_sendmsg_locked+0xccf/0xe10 ... tcp_sendmsg+0x27/0x40 sock_sendmsg+0x30/0x40 sock_xmit.isra.24+0xa1/0x170 [nbd] nbd_send_cmd+0x1d2/0x690 [nbd] nbd_queue_rq+0x1b5/0x3b0 [nbd] __blk_mq_try_issue_directly+0x108/0x1b0 blk_mq_request_issue_directly+0xbd/0xe0 blk_mq_try_issue_list_directly+0x41/0xb0 blk_mq_sched_insert_requests+0xa2/0xe0 blk_mq_flush_plug_list+0x205/0x2a0 blk_flush_plug_list+0xc3/0xf0 [1] blk_finish_plug+0x21/0x2e _xfs_buf_ioapply+0x313/0x460 __xfs_buf_submit+0x67/0x220 xfs_buf_read_map+0x113/0x1a0 xfs_trans_read_buf_map+0xbf/0x330 xfs_btree_read_buf_block.constprop.42+0x95/0xd0 xfs_btree_lookup_get_block+0x95/0x170 xfs_btree_lookup+0xcc/0x470 xfs_bmap_del_extent_real+0x254/0x9a0 __xfs_bunmapi+0x45c/0xab0 xfs_bunmapi+0x15/0x30 xfs_itruncate_extents_flags+0xca/0x250 xfs_free_eofblocks+0x181/0x1e0 xfs_fs_destroy_inode+0xa8/0x1b0 destroy_inode+0x38/0x70 dispose_list+0x35/0x50 prune_icache_sb+0x52/0x70 super_cache_scan+0x120/0x1a0 do_shrink_slab+0x120/0x290 shrink_slab+0x216/0x2b0 shrink_node+0x1b6/0x4a0 do_try_to_free_pages+0xc6/0x370 try_to_free_mem_cgroup_pages+0xe3/0x1e0 try_charge+0x29e/0x790 mem_cgroup_charge_skmem+0x6a/0x100 __sk_mem_raise_allocated+0x18e/0x390 __sk_mem_schedule+0x2a/0x40 [0] tcp_sendmsg_locked+0x8eb/0xe10 tcp_sendmsg+0x27/0x40 sock_sendmsg+0x30/0x40 ___sys_sendmsg+0x26d/0x2b0 __sys_sendmsg+0x57/0xa0 do_syscall_64+0x42/0x100 entry_SYSCALL_64_after_hwframe+0x44/0xa9 In [0], tcp_send_msg_locked() was using current->page_frag when it called sk_wmem_schedule(). It already calculated how many bytes can be fit into current->page_frag. Due to memory pressure, sk_wmem_schedule() called into memory reclaim path which called into xfs and then IO issue path. Because the filesystem in question is backed by nbd, the control goes back into the tcp layer - back into tcp_sendmsg_locked(). nbd sets sk_allocation to (GFP_NOIO | __GFP_MEMALLOC) which makes sense - it's in the process of freeing memory and wants to be able to, e.g., drop clean pages to make forward progress. However, this confused sk_page_frag() called from [2]. Because it only tests whether the allocation allows blocking which it does, it now thinks current->page_frag can be used again although it already was being used in [0]. After [2] used current->page_frag, the offset would be increased by the used amount. When the control returns to [0], current->page_frag's offset is increased and the previously calculated number of bytes now may overrun the end of allocated memory leading to silent memory corruptions. Fix it by adding gfpflags_normal_context() which tests sleepable && !reclaim and use it to determine whether to use current->task_frag. v2: Eric didn't like gfp flags being tested twice. Introduce a new helper gfpflags_normal_context() and combine the two tests. Signed-off-by: Tejun Heo Cc: Josef Bacik Cc: Eric Dumazet Cc: stable@vger.kernel.org Signed-off-by: David S. Miller --- include/linux/gfp.h | 23 +++++++++++++++++++++++ include/net/sock.h | 11 ++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index fb07b503dc45..61f2f6ff9467 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -325,6 +325,29 @@ static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags) return !!(gfp_flags & __GFP_DIRECT_RECLAIM); } +/** + * gfpflags_normal_context - is gfp_flags a normal sleepable context? + * @gfp_flags: gfp_flags to test + * + * Test whether @gfp_flags indicates that the allocation is from the + * %current context and allowed to sleep. + * + * An allocation being allowed to block doesn't mean it owns the %current + * context. When direct reclaim path tries to allocate memory, the + * allocation context is nested inside whatever %current was doing at the + * time of the original allocation. The nested allocation may be allowed + * to block but modifying anything %current owns can corrupt the outer + * context's expectations. + * + * %true result from this function indicates that the allocation context + * can sleep and use anything that's associated with %current. + */ +static inline bool gfpflags_normal_context(const gfp_t gfp_flags) +{ + return (gfp_flags & (__GFP_DIRECT_RECLAIM | __GFP_MEMALLOC)) == + __GFP_DIRECT_RECLAIM; +} + #ifdef CONFIG_HIGHMEM #define OPT_ZONE_HIGHMEM ZONE_HIGHMEM #else diff --git a/include/net/sock.h b/include/net/sock.h index f69b58bff7e5..c31a9ed86d5a 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2242,12 +2242,17 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp, * sk_page_frag - return an appropriate page_frag * @sk: socket * - * If socket allocation mode allows current thread to sleep, it means its - * safe to use the per task page_frag instead of the per socket one. + * Use the per task page_frag instead of the per socket one for + * optimization when we know that we're in the normal context and owns + * everything that's associated with %current. + * + * gfpflags_allow_blocking() isn't enough here as direct reclaim may nest + * inside other socket operations and end up recursing into sk_page_frag() + * while it's already in use. */ static inline struct page_frag *sk_page_frag(struct sock *sk) { - if (gfpflags_allow_blocking(sk->sk_allocation)) + if (gfpflags_normal_context(sk->sk_allocation)) return ¤t->task_frag; return &sk->sk_frag; -- GitLab From 88824e3bf29a2fcacfd9ebbfe03063649f0f3254 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 25 Oct 2019 13:47:24 +1100 Subject: [PATCH 820/993] net: ethernet: ftgmac100: Fix DMA coherency issue with SW checksum We are calling the checksum helper after the dma_map_single() call to map the packet. This is incorrect as the checksumming code will touch the packet from the CPU. This means the cache won't be properly flushes (or the bounce buffering will leave us with the unmodified packet to DMA). This moves the calculation of the checksum & vlan tags to before the DMA mapping. This also has the side effect of fixing another bug: If the checksum helper fails, we goto "drop" to drop the packet, which will not unmap the DMA mapping. Signed-off-by: Benjamin Herrenschmidt Fixes: 05690d633f30 ("ftgmac100: Upgrade to NETIF_F_HW_CSUM") Reviewed-by: Vijay Khemka Tested-by: Vijay Khemka Signed-off-by: David S. Miller --- drivers/net/ethernet/faraday/ftgmac100.c | 25 ++++++++++++------------ 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index 9b7af94a40bb..96e9565f1e08 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -727,6 +727,18 @@ static netdev_tx_t ftgmac100_hard_start_xmit(struct sk_buff *skb, */ nfrags = skb_shinfo(skb)->nr_frags; + /* Setup HW checksumming */ + csum_vlan = 0; + if (skb->ip_summed == CHECKSUM_PARTIAL && + !ftgmac100_prep_tx_csum(skb, &csum_vlan)) + goto drop; + + /* Add VLAN tag */ + if (skb_vlan_tag_present(skb)) { + csum_vlan |= FTGMAC100_TXDES1_INS_VLANTAG; + csum_vlan |= skb_vlan_tag_get(skb) & 0xffff; + } + /* Get header len */ len = skb_headlen(skb); @@ -753,19 +765,6 @@ static netdev_tx_t ftgmac100_hard_start_xmit(struct sk_buff *skb, if (nfrags == 0) f_ctl_stat |= FTGMAC100_TXDES0_LTS; txdes->txdes3 = cpu_to_le32(map); - - /* Setup HW checksumming */ - csum_vlan = 0; - if (skb->ip_summed == CHECKSUM_PARTIAL && - !ftgmac100_prep_tx_csum(skb, &csum_vlan)) - goto drop; - - /* Add VLAN tag */ - if (skb_vlan_tag_present(skb)) { - csum_vlan |= FTGMAC100_TXDES1_INS_VLANTAG; - csum_vlan |= skb_vlan_tag_get(skb) & 0xffff; - } - txdes->txdes1 = cpu_to_le32(csum_vlan); /* Next descriptor */ -- GitLab From 5d294fc483405de9c0913ab744a31e6fa7cb0f40 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 25 Oct 2019 09:26:35 +0200 Subject: [PATCH 821/993] net: dsa: sja1105: improve NET_DSA_SJA1105_TAS dependency An earlier bugfix introduced a dependency on CONFIG_NET_SCH_TAPRIO, but this missed the case of NET_SCH_TAPRIO=m and NET_DSA_SJA1105=y, which still causes a link error: drivers/net/dsa/sja1105/sja1105_tas.o: In function `sja1105_setup_tc_taprio': sja1105_tas.c:(.text+0x5c): undefined reference to `taprio_offload_free' sja1105_tas.c:(.text+0x3b4): undefined reference to `taprio_offload_get' drivers/net/dsa/sja1105/sja1105_tas.o: In function `sja1105_tas_teardown': sja1105_tas.c:(.text+0x6ec): undefined reference to `taprio_offload_free' Change the dependency to only allow selecting the TAS code when it can link against the taprio code. Fixes: a8d570de0cc6 ("net: dsa: sja1105: Add dependency for NET_DSA_SJA1105_TAS") Fixes: 317ab5b86c8e ("net: dsa: sja1105: Configure the Time-Aware Scheduler via tc-taprio offload") Signed-off-by: Arnd Bergmann Signed-off-by: David S. Miller --- drivers/net/dsa/sja1105/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/sja1105/Kconfig b/drivers/net/dsa/sja1105/Kconfig index f40b248f0b23..ffac0ea4e8d5 100644 --- a/drivers/net/dsa/sja1105/Kconfig +++ b/drivers/net/dsa/sja1105/Kconfig @@ -26,8 +26,8 @@ config NET_DSA_SJA1105_PTP config NET_DSA_SJA1105_TAS bool "Support for the Time-Aware Scheduler on NXP SJA1105" - depends on NET_DSA_SJA1105 - depends on NET_SCH_TAPRIO + depends on NET_DSA_SJA1105 && NET_SCH_TAPRIO + depends on NET_SCH_TAPRIO=y || NET_DSA_SJA1105=m help This enables support for the TTEthernet-based egress scheduling engine in the SJA1105 DSA driver, which is controlled using a -- GitLab From 3a6402a0824a12c7853fba6076f5c971cbc31ff9 Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Mon, 28 Oct 2019 23:29:16 +0000 Subject: [PATCH 822/993] Revert "ANDROID: Revert "kheaders: make headers archive reproducible"" This reverts commit 35e8b5100df4b80a440c3137d57a299970135eaa. The revert of the original commit had been partially done by merging 5.4-rc4, this is the left over piece to get back to the mainline version. Change-Id: I9e82048210062fd7ae0eb918167e4607009487c4 Signed-off-by: Matthias Maennich --- Documentation/kbuild/reproducible-builds.rst | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Documentation/kbuild/reproducible-builds.rst b/Documentation/kbuild/reproducible-builds.rst index ab92e98c89c8..503393854e2e 100644 --- a/Documentation/kbuild/reproducible-builds.rst +++ b/Documentation/kbuild/reproducible-builds.rst @@ -16,16 +16,21 @@ the kernel may be unreproducible, and how to avoid them. Timestamps ---------- -The kernel embeds a timestamp in two places: +The kernel embeds timestamps in three places: * The version string exposed by ``uname()`` and included in ``/proc/version`` * File timestamps in the embedded initramfs -By default the timestamp is the current time. This must be overridden -using the `KBUILD_BUILD_TIMESTAMP`_ variable. If you are building -from a git commit, you could use its commit date. +* If enabled via ``CONFIG_IKHEADERS``, file timestamps of kernel + headers embedded in the kernel or respective module, + exposed via ``/sys/kernel/kheaders.tar.xz`` + +By default the timestamp is the current time and in the case of +``kheaders`` the various files' modification times. This must +be overridden using the `KBUILD_BUILD_TIMESTAMP`_ variable. +If you are building from a git commit, you could use its commit date. The kernel does *not* use the ``__DATE__`` and ``__TIME__`` macros, and enables warnings if they are used. If you incorporate external -- GitLab From 0a29ac5bd3a988dc151c8d26910dec2557421f64 Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Fri, 25 Oct 2019 10:04:13 +0200 Subject: [PATCH 823/993] net: usb: lan78xx: Disable interrupts before calling generic_handle_irq() lan78xx_status() will run with interrupts enabled due to the change in ed194d136769 ("usb: core: remove local_irq_save() around ->complete() handler"). generic_handle_irq() expects to be run with IRQs disabled. [ 4.886203] 000: irq 79 handler irq_default_primary_handler+0x0/0x8 enabled interrupts [ 4.886243] 000: WARNING: CPU: 0 PID: 0 at kernel/irq/handle.c:152 __handle_irq_event_percpu+0x154/0x168 [ 4.896294] 000: Modules linked in: [ 4.896301] 000: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.3.6 #39 [ 4.896310] 000: Hardware name: Raspberry Pi 3 Model B+ (DT) [ 4.896315] 000: pstate: 60000005 (nZCv daif -PAN -UAO) [ 4.896321] 000: pc : __handle_irq_event_percpu+0x154/0x168 [ 4.896331] 000: lr : __handle_irq_event_percpu+0x154/0x168 [ 4.896339] 000: sp : ffff000010003cc0 [ 4.896346] 000: x29: ffff000010003cc0 x28: 0000000000000060 [ 4.896355] 000: x27: ffff000011021980 x26: ffff00001189c72b [ 4.896364] 000: x25: ffff000011702bc0 x24: ffff800036d6e400 [ 4.896373] 000: x23: 000000000000004f x22: ffff000010003d64 [ 4.896381] 000: x21: 0000000000000000 x20: 0000000000000002 [ 4.896390] 000: x19: ffff8000371c8480 x18: 0000000000000060 [ 4.896398] 000: x17: 0000000000000000 x16: 00000000000000eb [ 4.896406] 000: x15: ffff000011712d18 x14: 7265746e69206465 [ 4.896414] 000: x13: ffff000010003ba0 x12: ffff000011712df0 [ 4.896422] 000: x11: 0000000000000001 x10: ffff000011712e08 [ 4.896430] 000: x9 : 0000000000000001 x8 : 000000000003c920 [ 4.896437] 000: x7 : ffff0000118cc410 x6 : ffff0000118c7f00 [ 4.896445] 000: x5 : 000000000003c920 x4 : 0000000000004510 [ 4.896453] 000: x3 : ffff000011712dc8 x2 : 0000000000000000 [ 4.896461] 000: x1 : 73a3f67df94c1500 x0 : 0000000000000000 [ 4.896466] 000: Call trace: [ 4.896471] 000: __handle_irq_event_percpu+0x154/0x168 [ 4.896481] 000: handle_irq_event_percpu+0x50/0xb0 [ 4.896489] 000: handle_irq_event+0x40/0x98 [ 4.896497] 000: handle_simple_irq+0xa4/0xf0 [ 4.896505] 000: generic_handle_irq+0x24/0x38 [ 4.896513] 000: intr_complete+0xb0/0xe0 [ 4.896525] 000: __usb_hcd_giveback_urb+0x58/0xd8 [ 4.896533] 000: usb_giveback_urb_bh+0xd0/0x170 [ 4.896539] 000: tasklet_action_common.isra.0+0x9c/0x128 [ 4.896549] 000: tasklet_hi_action+0x24/0x30 [ 4.896556] 000: __do_softirq+0x120/0x23c [ 4.896564] 000: irq_exit+0xb8/0xd8 [ 4.896571] 000: __handle_domain_irq+0x64/0xb8 [ 4.896579] 000: bcm2836_arm_irqchip_handle_irq+0x60/0xc0 [ 4.896586] 000: el1_irq+0xb8/0x140 [ 4.896592] 000: arch_cpu_idle+0x10/0x18 [ 4.896601] 000: do_idle+0x200/0x280 [ 4.896608] 000: cpu_startup_entry+0x20/0x28 [ 4.896615] 000: rest_init+0xb4/0xc0 [ 4.896623] 000: arch_call_rest_init+0xc/0x14 [ 4.896632] 000: start_kernel+0x454/0x480 Fixes: ed194d136769 ("usb: core: remove local_irq_save() around ->complete() handler") Cc: Woojung Huh Cc: Marc Zyngier Cc: Andrew Lunn Cc: Stefan Wahren Cc: Jisheng Zhang Cc: Sebastian Andrzej Siewior Cc: Thomas Gleixner Cc: David Miller Signed-off-by: Daniel Wagner Tested-by: Stefan Wahren Signed-off-by: David S. Miller --- drivers/net/usb/lan78xx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 62948098191f..f24a1b0b801f 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -1264,8 +1264,11 @@ static void lan78xx_status(struct lan78xx_net *dev, struct urb *urb) netif_dbg(dev, link, dev->net, "PHY INTR: 0x%08x\n", intdata); lan78xx_defer_kevent(dev, EVENT_LINK_RESET); - if (dev->domain_data.phyirq > 0) + if (dev->domain_data.phyirq > 0) { + local_irq_disable(); generic_handle_irq(dev->domain_data.phyirq); + local_irq_enable(); + } } else netdev_warn(dev->net, "unexpected interrupt: 0x%08x\n", intdata); -- GitLab From 2ccb4f16d013a0954459061d38172b1c53553ba6 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Mon, 21 Oct 2019 17:59:22 -0700 Subject: [PATCH 824/993] hwmon: (ina3221) Fix read timeout issue After introducing "samples" to the calculation of wait time, the driver might timeout at the regmap_field_read_poll_timeout call, because the wait time could be longer than the 100000 usec limit due to a large "samples" number. So this patch sets the timeout limit to 2 times of the wait time in order to fix this issue. Fixes: 5c090abf945b ("hwmon: (ina3221) Add averaging mode support") Signed-off-by: Nicolin Chen Link: https://lore.kernel.org/r/20191022005922.30239-1-nicoleotsuka@gmail.com Signed-off-by: Guenter Roeck --- drivers/hwmon/ina3221.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c index 0037e2bdacd6..8a51dcf055ea 100644 --- a/drivers/hwmon/ina3221.c +++ b/drivers/hwmon/ina3221.c @@ -170,7 +170,7 @@ static inline int ina3221_wait_for_data(struct ina3221_data *ina) /* Polling the CVRF bit to make sure read data is ready */ return regmap_field_read_poll_timeout(ina->fields[F_CVRF], - cvrf, cvrf, wait, 100000); + cvrf, cvrf, wait, wait * 2); } static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg, -- GitLab From d3566abb1a1e7772116e4d50fb6a58d19c9802e5 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Thu, 24 Oct 2019 16:38:04 +1000 Subject: [PATCH 825/993] scsi: qla2xxx: stop timer in shutdown path In shutdown/reboot paths, the timer is not stopped: qla2x00_shutdown pci_device_shutdown device_shutdown kernel_restart_prepare kernel_restart sys_reboot This causes lockups (on powerpc) when firmware config space access calls are interrupted by smp_send_stop later in reboot. Fixes: e30d1756480dc ("[SCSI] qla2xxx: Addition of shutdown callback handler.") Link: https://lore.kernel.org/r/20191024063804.14538-1-npiggin@gmail.com Signed-off-by: Nicholas Piggin Acked-by: Himanshu Madhani Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index e4d765fc03ea..39f7782a133b 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3529,6 +3529,10 @@ qla2x00_shutdown(struct pci_dev *pdev) qla2x00_try_to_stop_firmware(vha); } + /* Disable timer */ + if (vha->timer_active) + qla2x00_stop_timer(vha); + /* Turn adapter off line */ vha->flags.online = 0; -- GitLab From af5cf146e4adae1dda52b006a86bab9d26e49a0e Mon Sep 17 00:00:00 2001 From: Roman Kiryanov Date: Mon, 28 Oct 2019 14:34:48 -0700 Subject: [PATCH 826/993] ANDROID: virtio: virtio_input: Set the amount of multitouch slots in virtio input Virtio input was missing the the amount of multitouch slots and kernel was filtering out ABS_MT_SLOT events for a screen is touched in more than one place. Bug: 143488374 Signed-off-by: Roman Kiryanov Change-Id: I617099435af311e6b0ee127b76eafe13834ea8f8 --- drivers/virtio/virtio_input.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/virtio/virtio_input.c b/drivers/virtio/virtio_input.c index 5ae529671b3d..c68134c5a2e6 100644 --- a/drivers/virtio/virtio_input.c +++ b/drivers/virtio/virtio_input.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -164,6 +165,12 @@ static void virtinput_cfg_abs(struct virtio_input *vi, int abs) virtio_cread(vi->vdev, struct virtio_input_config, u.abs.flat, &fl); input_set_abs_params(vi->idev, abs, mi, ma, fu, fl); input_abs_set_res(vi->idev, abs, re); + if (abs == ABS_MT_TRACKING_ID) + input_mt_init_slots(vi->idev, + ma, /* input max finger */ + INPUT_MT_DIRECT + | INPUT_MT_DROP_UNUSED + | INPUT_MT_TRACK); } static int virtinput_init_vqs(struct virtio_input *vi) -- GitLab From aed39c535edfe8705e9ea878a8ca644b20f87bc2 Mon Sep 17 00:00:00 2001 From: Ram Muthiah Date: Mon, 28 Oct 2019 18:00:45 -0700 Subject: [PATCH 827/993] ANDROID: gki_defconfig: enable CONFIG_CPUSETS Test: local boot on cuttlefish Change-Id: I96834945eb904a0dce47b8c95a5431a83bdea492 Signed-off-by: Ram Muthiah --- arch/x86/configs/gki_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index 5c304350fb68..0654f2381a0e 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -14,6 +14,7 @@ CONFIG_MEMCG=y CONFIG_MEMCG_SWAP=y CONFIG_RT_GROUP_SCHED=y CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_BPF=y CONFIG_SCHED_AUTOGROUP=y -- GitLab From 50118fa88e6a86ce362b50ac99c2139ad29b057e Mon Sep 17 00:00:00 2001 From: Alistair Delva Date: Mon, 28 Oct 2019 15:07:10 -0700 Subject: [PATCH 828/993] ANDROID: dummy_cpufreq: Implement get() Fixes panic in time_cpufreq_notifier+0x94 caused by notifying the x86 TSC synchronization code that a CPU frequency change has occurred, but not properly updating policy->cur beforehand, causing a division by zero. Link: https://github.com/ClangBuiltLinux/linux/issues/756 Change-Id: I687093bbdb402a13341762bf9d91dd7f9daffe8b Signed-off-by: Alistair Delva --- drivers/cpufreq/dummy-cpufreq.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/cpufreq/dummy-cpufreq.c b/drivers/cpufreq/dummy-cpufreq.c index 914f3e39ca9b..ea40d5c7a9fa 100644 --- a/drivers/cpufreq/dummy-cpufreq.c +++ b/drivers/cpufreq/dummy-cpufreq.c @@ -23,6 +23,11 @@ static int dummy_cpufreq_driver_init(struct cpufreq_policy *policy) return 0; } +static unsigned int dummy_cpufreq_get(unsigned int cpu) +{ + return 1; +} + static int dummy_cpufreq_verify(struct cpufreq_policy *policy) { return 0; @@ -32,6 +37,7 @@ static struct cpufreq_driver dummy_cpufreq_driver = { .name = "dummy", .target_index = dummy_cpufreq_target_index, .init = dummy_cpufreq_driver_init, + .get = dummy_cpufreq_get, .verify = dummy_cpufreq_verify, .attr = cpufreq_generic_attr, }; -- GitLab From 05d9a952832cb206a32e3705eff6edebdb2207e7 Mon Sep 17 00:00:00 2001 From: Thiago Jung Bauermann Date: Wed, 11 Sep 2019 13:34:33 -0300 Subject: [PATCH 829/993] powerpc/prom_init: Undo relocation before entering secure mode The ultravisor will do an integrity check of the kernel image but we relocated it so the check will fail. Restore the original image by relocating it back to the kernel virtual base address. This works because during build vmlinux is linked with an expected virtual runtime address of KERNELBASE. Fixes: 6a9c930bd775 ("powerpc/prom_init: Add the ESM call to prom_init") Signed-off-by: Thiago Jung Bauermann Tested-by: Michael Anderson [mpe: Add IS_ENABLED() to fix the CONFIG_RELOCATABLE=n build] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190911163433.12822-1-bauerman@linux.ibm.com --- arch/powerpc/include/asm/elf.h | 3 +++ arch/powerpc/kernel/prom_init.c | 13 +++++++++++++ arch/powerpc/kernel/prom_init_check.sh | 3 ++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h index 409c9bfb43d9..57c229a86f08 100644 --- a/arch/powerpc/include/asm/elf.h +++ b/arch/powerpc/include/asm/elf.h @@ -175,4 +175,7 @@ do { \ ARCH_DLINFO_CACHE_GEOMETRY; \ } while (0) +/* Relocate the kernel image to @final_address */ +void relocate(unsigned long final_address); + #endif /* _ASM_POWERPC_ELF_H */ diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index a4e7762dd286..100f1b57ec2f 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -3249,7 +3249,20 @@ static void setup_secure_guest(unsigned long kbase, unsigned long fdt) /* Switch to secure mode. */ prom_printf("Switching to secure mode.\n"); + /* + * The ultravisor will do an integrity check of the kernel image but we + * relocated it so the check will fail. Restore the original image by + * relocating it back to the kernel virtual base address. + */ + if (IS_ENABLED(CONFIG_RELOCATABLE)) + relocate(KERNELBASE); + ret = enter_secure_mode(kbase, fdt); + + /* Relocate the kernel again. */ + if (IS_ENABLED(CONFIG_RELOCATABLE)) + relocate(kbase); + if (ret != U_SUCCESS) { prom_printf("Returned %d from switching to secure mode.\n", ret); prom_rtas_os_term("Switch to secure mode failed.\n"); diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh index 78bab17b1396..b183ab9c5107 100644 --- a/arch/powerpc/kernel/prom_init_check.sh +++ b/arch/powerpc/kernel/prom_init_check.sh @@ -26,7 +26,8 @@ _end enter_prom $MEM_FUNCS reloc_offset __secondary_hold __secondary_hold_acknowledge __secondary_hold_spinloop __start logo_linux_clut224 btext_prepare_BAT reloc_got2 kernstart_addr memstart_addr linux_banner _stext -__prom_init_toc_start __prom_init_toc_end btext_setup_display TOC." +__prom_init_toc_start __prom_init_toc_end btext_setup_display TOC. +relocate" NM="$1" OBJ="$2" -- GitLab From 54f83b8c8ea9b22082a496deadf90447a326954e Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 28 Oct 2019 10:54:26 -0400 Subject: [PATCH 830/993] USB: gadget: Reject endpoints with 0 maxpacket value Endpoints with a maxpacket length of 0 are probably useless. They can't transfer any data, and it's not at all unlikely that a UDC will crash or hang when trying to handle a non-zero-length usb_request for such an endpoint. Indeed, dummy-hcd gets a divide error when trying to calculate the remainder of a transfer length by the maxpacket value, as discovered by the syzbot fuzzer. Currently the gadget core does not check for endpoints having a maxpacket value of 0. This patch adds a check to usb_ep_enable(), preventing such endpoints from being used. As far as I know, none of the gadget drivers in the kernel tries to create an endpoint with maxpacket = 0, but until now there has been nothing to prevent userspace programs under gadgetfs or configfs from doing it. Signed-off-by: Alan Stern Reported-and-tested-by: syzbot+8ab8bf161038a8768553@syzkaller.appspotmail.com CC: Acked-by: Felipe Balbi Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.1910281052370.1485-100000@iolanthe.rowland.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/core.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 92af8dc98c3d..51fa614b4079 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -98,6 +98,17 @@ int usb_ep_enable(struct usb_ep *ep) if (ep->enabled) goto out; + /* UDC drivers can't handle endpoints with maxpacket size 0 */ + if (usb_endpoint_maxp(ep->desc) == 0) { + /* + * We should log an error message here, but we can't call + * dev_err() because there's no way to find the gadget + * given only ep. + */ + ret = -EINVAL; + goto out; + } + ret = ep->ops->enable(ep, ep->desc); if (ret) goto out; -- GitLab From cd1cb3350561d2bf544ddfef76fbf0b1c9c7178f Mon Sep 17 00:00:00 2001 From: Valentin Schneider Date: Wed, 23 Oct 2019 16:37:44 +0100 Subject: [PATCH 831/993] sched/topology: Don't try to build empty sched domains Turns out hotplugging CPUs that are in exclusive cpusets can lead to the cpuset code feeding empty cpumasks to the sched domain rebuild machinery. This leads to the following splat: Internal error: Oops: 96000004 [#1] PREEMPT SMP Modules linked in: CPU: 0 PID: 235 Comm: kworker/5:2 Not tainted 5.4.0-rc1-00005-g8d495477d62e #23 Hardware name: ARM Juno development board (r0) (DT) Workqueue: events cpuset_hotplug_workfn pstate: 60000005 (nZCv daif -PAN -UAO) pc : build_sched_domains (./include/linux/arch_topology.h:23 kernel/sched/topology.c:1898 kernel/sched/topology.c:1969) lr : build_sched_domains (kernel/sched/topology.c:1966) Call trace: build_sched_domains (./include/linux/arch_topology.h:23 kernel/sched/topology.c:1898 kernel/sched/topology.c:1969) partition_sched_domains_locked (kernel/sched/topology.c:2250) rebuild_sched_domains_locked (./include/linux/bitmap.h:370 ./include/linux/cpumask.h:538 kernel/cgroup/cpuset.c:955 kernel/cgroup/cpuset.c:978 kernel/cgroup/cpuset.c:1019) rebuild_sched_domains (kernel/cgroup/cpuset.c:1032) cpuset_hotplug_workfn (kernel/cgroup/cpuset.c:3205 (discriminator 2)) process_one_work (./arch/arm64/include/asm/jump_label.h:21 ./include/linux/jump_label.h:200 ./include/trace/events/workqueue.h:114 kernel/workqueue.c:2274) worker_thread (./include/linux/compiler.h:199 ./include/linux/list.h:268 kernel/workqueue.c:2416) kthread (kernel/kthread.c:255) ret_from_fork (arch/arm64/kernel/entry.S:1167) Code: f860dae2 912802d6 aa1603e1 12800000 (f8616853) The faulty line in question is: cap = arch_scale_cpu_capacity(cpumask_first(cpu_map)); and we're not checking the return value against nr_cpu_ids (we shouldn't have to!), which leads to the above. Prevent generate_sched_domains() from returning empty cpumasks, and add some assertion in build_sched_domains() to scream bloody murder if it happens again. The above splat was obtained on my Juno r0 with the following reproducer: $ cgcreate -g cpuset:asym $ cgset -r cpuset.cpus=0-3 asym $ cgset -r cpuset.mems=0 asym $ cgset -r cpuset.cpu_exclusive=1 asym $ cgcreate -g cpuset:smp $ cgset -r cpuset.cpus=4-5 smp $ cgset -r cpuset.mems=0 smp $ cgset -r cpuset.cpu_exclusive=1 smp $ cgset -r cpuset.sched_load_balance=0 . $ echo 0 > /sys/devices/system/cpu/cpu4/online $ echo 0 > /sys/devices/system/cpu/cpu5/online Signed-off-by: Valentin Schneider Signed-off-by: Peter Zijlstra (Intel) Cc: Dietmar.Eggemann@arm.com Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: hannes@cmpxchg.org Cc: lizefan@huawei.com Cc: morten.rasmussen@arm.com Cc: qperret@google.com Cc: tj@kernel.org Cc: vincent.guittot@linaro.org Fixes: 05484e098448 ("sched/topology: Add SD_ASYM_CPUCAPACITY flag detection") Link: https://lkml.kernel.org/r/20191023153745.19515-2-valentin.schneider@arm.com Signed-off-by: Ingo Molnar --- kernel/cgroup/cpuset.c | 3 ++- kernel/sched/topology.c | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index c52bc91f882b..c87ee6412b36 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -798,7 +798,8 @@ static int generate_sched_domains(cpumask_var_t **domains, cpumask_subset(cp->cpus_allowed, top_cpuset.effective_cpus)) continue; - if (is_sched_load_balance(cp)) + if (is_sched_load_balance(cp) && + !cpumask_empty(cp->effective_cpus)) csa[csn++] = cp; /* skip @cp's subtree if not a partition root */ diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c index b5667a273bf6..9318acf1d1fe 100644 --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c @@ -1948,7 +1948,7 @@ static struct sched_domain_topology_level static int build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *attr) { - enum s_alloc alloc_state; + enum s_alloc alloc_state = sa_none; struct sched_domain *sd; struct s_data d; struct rq *rq = NULL; @@ -1956,6 +1956,9 @@ build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *att struct sched_domain_topology_level *tl_asym; bool has_asym = false; + if (WARN_ON(cpumask_empty(cpu_map))) + goto error; + alloc_state = __visit_domain_allocation_hell(&d, cpu_map); if (alloc_state != sa_rootdomain) goto error; -- GitLab From e284df705cf1eeedb5ec3a66ed82d17a64659150 Mon Sep 17 00:00:00 2001 From: Valentin Schneider Date: Wed, 23 Oct 2019 16:37:45 +0100 Subject: [PATCH 832/993] sched/topology: Allow sched_asym_cpucapacity to be disabled While the static key is correctly initialized as being disabled, it will remain forever enabled once turned on. This means that if we start with an asymmetric system and hotplug out enough CPUs to end up with an SMP system, the static key will remain set - which is obviously wrong. We should detect this and turn off things like misfit migration and capacity aware wakeups. As Quentin pointed out, having separate root domains makes this slightly trickier. We could have exclusive cpusets that create an SMP island - IOW, the domains within this root domain will not see any asymmetry. This means we can't just disable the key on domain destruction, we need to count how many asymmetric root domains we have. Consider the following example using Juno r0 which is 2+4 big.LITTLE, where two identical cpusets are created: they both span both big and LITTLE CPUs: asym0 asym1 [ ][ ] L L B L L B $ cgcreate -g cpuset:asym0 $ cgset -r cpuset.cpus=0,1,3 asym0 $ cgset -r cpuset.mems=0 asym0 $ cgset -r cpuset.cpu_exclusive=1 asym0 $ cgcreate -g cpuset:asym1 $ cgset -r cpuset.cpus=2,4,5 asym1 $ cgset -r cpuset.mems=0 asym1 $ cgset -r cpuset.cpu_exclusive=1 asym1 $ cgset -r cpuset.sched_load_balance=0 . (the CPU numbering may look odd because on the Juno LITTLEs are CPUs 0,3-5 and bigs are CPUs 1-2) If we make one of those SMP (IOW remove asymmetry) by e.g. hotplugging its big core, we would end up with an SMP cpuset and an asymmetric cpuset - the static key must remain set, because we still have one asymmetric root domain. With the above example, this could be done with: $ echo 0 > /sys/devices/system/cpu/cpu2/online Which would result in: asym0 asym1 [ ][ ] L L B L L When both SMP and asymmetric cpusets are present, all CPUs will observe sched_asym_cpucapacity being set (it is system-wide), but not all CPUs observe asymmetry in their sched domain hierarchy: per_cpu(sd_asym_cpucapacity, ) == per_cpu(sd_asym_cpucapacity, ) == NULL Change the simple key enablement to an increment, and decrement the key counter when destroying domains that cover asymmetric CPUs. Signed-off-by: Valentin Schneider Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Dietmar Eggemann Cc: Dietmar.Eggemann@arm.com Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: hannes@cmpxchg.org Cc: lizefan@huawei.com Cc: morten.rasmussen@arm.com Cc: qperret@google.com Cc: tj@kernel.org Cc: vincent.guittot@linaro.org Fixes: df054e8445a4 ("sched/topology: Add static_key for asymmetric CPU capacity optimizations") Link: https://lkml.kernel.org/r/20191023153745.19515-3-valentin.schneider@arm.com Signed-off-by: Ingo Molnar --- kernel/sched/topology.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c index 9318acf1d1fe..49b835f1305f 100644 --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c @@ -2029,7 +2029,7 @@ build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *att rcu_read_unlock(); if (has_asym) - static_branch_enable_cpuslocked(&sched_asym_cpucapacity); + static_branch_inc_cpuslocked(&sched_asym_cpucapacity); if (rq && sched_debug_enabled) { pr_info("root domain span: %*pbl (max cpu_capacity = %lu)\n", @@ -2124,8 +2124,12 @@ int sched_init_domains(const struct cpumask *cpu_map) */ static void detach_destroy_domains(const struct cpumask *cpu_map) { + unsigned int cpu = cpumask_any(cpu_map); int i; + if (rcu_access_pointer(per_cpu(sd_asym_cpucapacity, cpu))) + static_branch_dec_cpuslocked(&sched_asym_cpucapacity); + rcu_read_lock(); for_each_cpu(i, cpu_map) cpu_attach_domain(NULL, &def_root_domain, i); -- GitLab From 7d6475051fb3d9339c5c760ed9883bc0a9048b21 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Tue, 22 Oct 2019 21:58:14 +1000 Subject: [PATCH 833/993] powerpc/powernv: Fix CPU idle to be called with IRQs disabled Commit e78a7614f3876 ("idle: Prevent late-arriving interrupts from disrupting offline") changes arch_cpu_idle_dead to be called with interrupts disabled, which triggers the WARN in pnv_smp_cpu_kill_self. Fix this by fixing up irq_happened after hard disabling, rather than requiring there are no pending interrupts, similarly to what was done done until commit 2525db04d1cc5 ("powerpc/powernv: Simplify lazy IRQ handling in CPU offline"). Fixes: e78a7614f3876 ("idle: Prevent late-arriving interrupts from disrupting offline") Reported-by: Paul Mackerras Signed-off-by: Nicholas Piggin [mpe: Add unexpected_mask rather than checking for known bad values, change the WARN_ON() to a WARN_ON_ONCE()] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20191022115814.22456-1-npiggin@gmail.com --- arch/powerpc/platforms/powernv/smp.c | 53 +++++++++++++++++++--------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index fbd6e6b7bbf2..13e251699346 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -146,20 +146,25 @@ static int pnv_smp_cpu_disable(void) return 0; } +static void pnv_flush_interrupts(void) +{ + if (cpu_has_feature(CPU_FTR_ARCH_300)) { + if (xive_enabled()) + xive_flush_interrupt(); + else + icp_opal_flush_interrupt(); + } else { + icp_native_flush_interrupt(); + } +} + static void pnv_smp_cpu_kill_self(void) { + unsigned long srr1, unexpected_mask, wmask; unsigned int cpu; - unsigned long srr1, wmask; u64 lpcr_val; /* Standard hot unplug procedure */ - /* - * This hard disables local interurpts, ensuring we have no lazy - * irqs pending. - */ - WARN_ON(irqs_disabled()); - hard_irq_disable(); - WARN_ON(lazy_irq_pending()); idle_task_exit(); current->active_mm = NULL; /* for sanity */ @@ -172,6 +177,27 @@ static void pnv_smp_cpu_kill_self(void) if (cpu_has_feature(CPU_FTR_ARCH_207S)) wmask = SRR1_WAKEMASK_P8; + /* + * This turns the irq soft-disabled state we're called with, into a + * hard-disabled state with pending irq_happened interrupts cleared. + * + * PACA_IRQ_DEC - Decrementer should be ignored. + * PACA_IRQ_HMI - Can be ignored, processing is done in real mode. + * PACA_IRQ_DBELL, EE, PMI - Unexpected. + */ + hard_irq_disable(); + if (generic_check_cpu_restart(cpu)) + goto out; + + unexpected_mask = ~(PACA_IRQ_DEC | PACA_IRQ_HMI | PACA_IRQ_HARD_DIS); + if (local_paca->irq_happened & unexpected_mask) { + if (local_paca->irq_happened & PACA_IRQ_EE) + pnv_flush_interrupts(); + DBG("CPU%d Unexpected exit while offline irq_happened=%lx!\n", + cpu, local_paca->irq_happened); + } + local_paca->irq_happened = PACA_IRQ_HARD_DIS; + /* * We don't want to take decrementer interrupts while we are * offline, so clear LPCR:PECE1. We keep PECE2 (and @@ -197,6 +223,7 @@ static void pnv_smp_cpu_kill_self(void) srr1 = pnv_cpu_offline(cpu); + WARN_ON_ONCE(!irqs_disabled()); WARN_ON(lazy_irq_pending()); /* @@ -212,13 +239,7 @@ static void pnv_smp_cpu_kill_self(void) */ if (((srr1 & wmask) == SRR1_WAKEEE) || ((srr1 & wmask) == SRR1_WAKEHVI)) { - if (cpu_has_feature(CPU_FTR_ARCH_300)) { - if (xive_enabled()) - xive_flush_interrupt(); - else - icp_opal_flush_interrupt(); - } else - icp_native_flush_interrupt(); + pnv_flush_interrupts(); } else if ((srr1 & wmask) == SRR1_WAKEHDBELL) { unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER); asm volatile(PPC_MSGCLR(%0) : : "r" (msg)); @@ -266,7 +287,7 @@ static void pnv_smp_cpu_kill_self(void) */ lpcr_val = mfspr(SPRN_LPCR) | (u64)LPCR_PECE1; pnv_program_cpu_hotplug_lpcr(cpu, lpcr_val); - +out: DBG("CPU%d coming online...\n", cpu); } -- GitLab From af8fd0424713a2adb812d10d55e86718152cf656 Mon Sep 17 00:00:00 2001 From: Anton Eidelman Date: Fri, 18 Oct 2019 11:32:50 -0700 Subject: [PATCH 834/993] nvme-multipath: fix possible io hang after ctrl reconnect The following scenario results in an IO hang: 1) ctrl completes a request with NVME_SC_ANA_TRANSITION. NVME_NS_ANA_PENDING bit in ns->flags is set and ana_work is triggered. 2) ana_work: nvme_read_ana_log() tries to get the ANA log page from the ctrl. This fails because ctrl disconnects. Therefore nvme_update_ns_ana_state() is not called and NVME_NS_ANA_PENDING bit in ns->flags is not cleared. 3) ctrl reconnects: nvme_mpath_init(ctrl,...) calls nvme_read_ana_log(ctrl, groups_only=true). However, nvme_update_ana_state() does not update namespaces because nr_nsids = 0 (due to groups_only mode). 4) scan_work calls nvme_validate_ns() finds the ns and re-validates OK. Result: The ctrl is now live but NVME_NS_ANA_PENDING bit in ns->flags is still set. Consequently ctrl will never be considered a viable path by __nvme_find_path(). IO will hang if ctrl is the only or the last path to the namespace. More generally, while ctrl is reconnecting, its ANA state may change. And because nvme_mpath_init() requests ANA log in groups_only mode, these changes are not propagated to the existing ctrl namespaces. This may result in a mal-function or an IO hang. Solution: nvme_mpath_init() will nvme_read_ana_log() with groups_only set to false. This will not harm the new ctrl case (no namespaces present), and will make sure the ANA state of namespaces gets updated after reconnect. Note: Another option would be for nvme_mpath_init() to invoke nvme_parse_ana_log(..., nvme_set_ns_ana_state) for each existing namespace. Reviewed-by: Sagi Grimberg Signed-off-by: Anton Eidelman Signed-off-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/nvme/host/multipath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 30de7efef003..d320684d25b2 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -715,7 +715,7 @@ int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) goto out; } - error = nvme_read_ana_log(ctrl, true); + error = nvme_read_ana_log(ctrl, false); if (error) goto out_free_ana_log_buf; return 0; -- GitLab From 86cccfbf773fafb88898c5627aa3727b02bc4708 Mon Sep 17 00:00:00 2001 From: Anton Eidelman Date: Fri, 18 Oct 2019 11:32:51 -0700 Subject: [PATCH 835/993] nvme-multipath: remove unused groups_only mode in ana log groups_only mode in nvme_read_ana_log() is no longer used: remove it. Reviewed-by: Sagi Grimberg Signed-off-by: Anton Eidelman Signed-off-by: Keith Busch Signed-off-by: Jens Axboe --- drivers/nvme/host/multipath.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index d320684d25b2..fc99a40c1ec4 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -522,14 +522,13 @@ static int nvme_update_ana_state(struct nvme_ctrl *ctrl, return 0; } -static int nvme_read_ana_log(struct nvme_ctrl *ctrl, bool groups_only) +static int nvme_read_ana_log(struct nvme_ctrl *ctrl) { u32 nr_change_groups = 0; int error; mutex_lock(&ctrl->ana_lock); - error = nvme_get_log(ctrl, NVME_NSID_ALL, NVME_LOG_ANA, - groups_only ? NVME_ANA_LOG_RGO : 0, + error = nvme_get_log(ctrl, NVME_NSID_ALL, NVME_LOG_ANA, 0, ctrl->ana_log_buf, ctrl->ana_log_size, 0); if (error) { dev_warn(ctrl->device, "Failed to get ANA log: %d\n", error); @@ -565,7 +564,7 @@ static void nvme_ana_work(struct work_struct *work) { struct nvme_ctrl *ctrl = container_of(work, struct nvme_ctrl, ana_work); - nvme_read_ana_log(ctrl, false); + nvme_read_ana_log(ctrl); } static void nvme_anatt_timeout(struct timer_list *t) @@ -715,7 +714,7 @@ int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) goto out; } - error = nvme_read_ana_log(ctrl, false); + error = nvme_read_ana_log(ctrl); if (error) goto out_free_ana_log_buf; return 0; -- GitLab From d848074b2f1eb11a38691285f7366bce83087014 Mon Sep 17 00:00:00 2001 From: Anton Ivanov Date: Tue, 29 Oct 2019 09:13:34 +0000 Subject: [PATCH 836/993] um-ubd: Entrust re-queue to the upper layers Fixes crashes due to ubd requeue logic conflicting with the block-mq logic. Crash is reproducible in 5.0 - 5.3. Fixes: 53766defb8c8 ("um: Clean-up command processing in UML UBD driver") Cc: stable@vger.kernel.org # v5.0+ Signed-off-by: Anton Ivanov Signed-off-by: Jens Axboe --- arch/um/drivers/ubd_kern.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 612535cd9706..6627d7c30f37 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1403,8 +1403,12 @@ static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx, spin_unlock_irq(&ubd_dev->lock); - if (ret < 0) - blk_mq_requeue_request(req, true); + if (ret < 0) { + if (ret == -ENOMEM) + res = BLK_STS_RESOURCE; + else + res = BLK_STS_DEV_RESOURCE; + } return res; } -- GitLab From aa57157be69fb599bd4c38a4b75c5aad74a60ec0 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Tue, 29 Oct 2019 15:30:51 +0000 Subject: [PATCH 837/993] arm64: Ensure VM_WRITE|VM_SHARED ptes are clean by default Shared and writable mappings (__S.1.) should be clean (!dirty) initially and made dirty on a subsequent write either through the hardware DBM (dirty bit management) mechanism or through a write page fault. A clean pte for the arm64 kernel is one that has PTE_RDONLY set and PTE_DIRTY clear. The PAGE_SHARED{,_EXEC} attributes have PTE_WRITE set (PTE_DBM) and PTE_DIRTY clear. Prior to commit 73e86cb03cf2 ("arm64: Move PTE_RDONLY bit handling out of set_pte_at()"), it was the responsibility of set_pte_at() to set the PTE_RDONLY bit and mark the pte clean if the software PTE_DIRTY bit was not set. However, the above commit removed the pte_sw_dirty() check and the subsequent setting of PTE_RDONLY in set_pte_at() while leaving the PAGE_SHARED{,_EXEC} definitions unchanged. The result is that shared+writable mappings are now dirty by default Fix the above by explicitly setting PTE_RDONLY in PAGE_SHARED{,_EXEC}. In addition, remove the superfluous PTE_DIRTY bit from the kernel PROT_* attributes. Fixes: 73e86cb03cf2 ("arm64: Move PTE_RDONLY bit handling out of set_pte_at()") Cc: # 4.14.x- Cc: Will Deacon Signed-off-by: Catalin Marinas Signed-off-by: Will Deacon --- arch/arm64/include/asm/pgtable-prot.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h index 9a21b84536f2..8dc6c5cdabe6 100644 --- a/arch/arm64/include/asm/pgtable-prot.h +++ b/arch/arm64/include/asm/pgtable-prot.h @@ -32,11 +32,11 @@ #define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG) #define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG) -#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE)) -#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE)) -#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC)) -#define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT)) -#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL)) +#define PROT_DEVICE_nGnRnE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE)) +#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE)) +#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC)) +#define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT)) +#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL)) #define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE)) #define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL)) @@ -80,8 +80,9 @@ #define PAGE_S2_DEVICE __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_S2_XN) #define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN) -#define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) -#define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE) +/* shared+writable pages are clean by default, hence PTE_RDONLY|PTE_WRITE */ +#define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) +#define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE) #define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN) #define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN) #define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN) -- GitLab From ca8cb69580236f47041dd045c08f82cb7bb50d7c Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 16 Oct 2019 15:37:06 +0200 Subject: [PATCH 838/993] drm/etnaviv: fix deadlock in GPU coredump The GPU coredump function violates the locking order by holding the MMU context lock while trying to acquire the etnaviv_gem_object lock. This results in a possible ABBA deadlock with other codepaths which follow the established locking order. Fortunately this is easy to fix by dropping the MMU context lock earlier, as the BO dumping doesn't need the MMU context to be stable. The only thing the BO dumping cares about are the BO mappings, which are stable across the lifetime of the job. Fixes: 27b67278e007 (drm/etnaviv: rework MMU handling) [ Not really the first bad commit, but the one where this fix applies cleanly. Stable kernels need a manual backport. ] Reported-by: Christian Gmeiner Signed-off-by: Lucas Stach Tested-by: Christian Gmeiner --- drivers/gpu/drm/etnaviv/etnaviv_dump.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.c b/drivers/gpu/drm/etnaviv/etnaviv_dump.c index 698db540972c..648cf0207309 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_dump.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.c @@ -180,6 +180,8 @@ void etnaviv_core_dump(struct etnaviv_gem_submit *submit) etnaviv_cmdbuf_get_va(&submit->cmdbuf, &gpu->mmu_context->cmdbuf_mapping)); + mutex_unlock(&gpu->mmu_context->lock); + /* Reserve space for the bomap */ if (n_bomap_pages) { bomap_start = bomap = iter.data; @@ -221,8 +223,6 @@ void etnaviv_core_dump(struct etnaviv_gem_submit *submit) obj->base.size); } - mutex_unlock(&gpu->mmu_context->lock); - etnaviv_core_dump_header(&iter, ETDUMP_BUF_END, iter.data); dev_coredumpv(gpu->dev, iter.start, iter.data - iter.start, GFP_KERNEL); -- GitLab From 18fa692d8020083cd57ce031a4b5a7a4ec8bc50a Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 16 Oct 2019 16:10:21 +0200 Subject: [PATCH 839/993] drm/etnaviv: reinstate MMUv1 command buffer window check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The switch to per-process address spaces erroneously dropped the check which validated that the command buffer is mapped through the linear apperture as required by the hardware. This turned a system misconfiguration with a helpful error message into a very hard to debug issue. Reinstate the check at the appropriate location. Fixes: 17e4660ae3d7 (drm/etnaviv: implement per-process address spaces on MMUv2) Signed-off-by: Lucas Stach Reviewed-by: Guido Günther --- drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c index 35ebae6a1be7..3607d348c298 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -328,12 +328,23 @@ etnaviv_iommu_context_init(struct etnaviv_iommu_global *global, ret = etnaviv_cmdbuf_suballoc_map(suballoc, ctx, &ctx->cmdbuf_mapping, global->memory_base); - if (ret) { - global->ops->free(ctx); - return NULL; + if (ret) + goto out_free; + + if (global->version == ETNAVIV_IOMMU_V1 && + ctx->cmdbuf_mapping.iova > 0x80000000) { + dev_err(global->dev, + "command buffer outside valid memory window\n"); + goto out_unmap; } return ctx; + +out_unmap: + etnaviv_cmdbuf_suballoc_unmap(ctx, &ctx->cmdbuf_mapping); +out_free: + global->ops->free(ctx); + return NULL; } void etnaviv_iommu_restore(struct etnaviv_gpu *gpu, -- GitLab From a2f10d4a3069fee666dab20fab5458757ba1f22d Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Fri, 25 Oct 2019 12:39:10 +0200 Subject: [PATCH 840/993] drm/etnaviv: fix dumping of iommuv2 etnaviv_iommuv2_dump_size(..) returns the number of PTE * SZ_4K but etnaviv_iommuv2_dump(..) increments buf pointer even if there is no PTE. This results in a bad buf pointer which gets used for memcpy(..), when copying the MMU state in the coredump buffer. Fixes: afb7b3b1deb4 ("drm/etnaviv: implement IOMMUv2 translation") Cc: stable@vger.kernel.org Signed-off-by: Christian Gmeiner Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c index 043111a1d60c..f8bf488e9d71 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c @@ -155,9 +155,11 @@ static void etnaviv_iommuv2_dump(struct etnaviv_iommu_context *context, void *bu memcpy(buf, v2_context->mtlb_cpu, SZ_4K); buf += SZ_4K; - for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++, buf += SZ_4K) - if (v2_context->mtlb_cpu[i] & MMUv2_PTE_PRESENT) + for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++) + if (v2_context->mtlb_cpu[i] & MMUv2_PTE_PRESENT) { memcpy(buf, v2_context->stlb_cpu[i], SZ_4K); + buf += SZ_4K; + } } static void etnaviv_iommuv2_restore_nonsec(struct etnaviv_gpu *gpu, -- GitLab From d4af3c4b81f4cd5662baa6f1492f998d89783318 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Tue, 29 Oct 2019 10:15:39 -0700 Subject: [PATCH 841/993] arm64: cpufeature: Enable Qualcomm Falkor/Kryo errata 1003 With the introduction of 'cce360b54ce6 ("arm64: capabilities: Filter the entries based on a given mask")' the Qualcomm Falkor/Kryo errata 1003 is no long applied. The result of not applying errata 1003 is that MSM8996 runs into various RCU stalls and fails to boot most of the times. Give 1003 a "type" to ensure they are not filtered out in update_cpu_capabilities(). Fixes: cce360b54ce6 ("arm64: capabilities: Filter the entries based on a given mask") Cc: stable@vger.kernel.org Reported-by: Mark Brown Suggested-by: Will Deacon Signed-off-by: Bjorn Andersson Signed-off-by: Will Deacon --- arch/arm64/kernel/cpu_errata.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 6c3b10a41bd8..7f9b699969c7 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -816,6 +816,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = { { .desc = "Qualcomm Technologies Falkor/Kryo erratum 1003", .capability = ARM64_WORKAROUND_QCOM_FALKOR_E1003, + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .matches = cpucap_multi_entry_cap_matches, .match_list = qcom_erratum_1003_list, }, -- GitLab From 9acb7c07b6b988ef42959e74d045656483b57486 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 28 Oct 2019 15:16:40 +0000 Subject: [PATCH 842/993] Revert "sched: Rework pick_next_task() slow-path" This reverts commit 67692435c411e5c53a1c588ecca2037aebd81f2e temporarily in order to avoid the following splat: [ 222.515957] BUG: kernel NULL pointer dereference, address: 0000000000000040 [ 222.518871] #PF: supervisor read access in kernel mode [ 222.518871] #PF: error_code(0x0000) - not-present page [ 222.518871] PGD 800000007cdf7067 P4D 800000007cdf7067 PUD 7c868067 PMD 0 [ 222.518871] Oops: 0000 [#1] PREEMPT SMP PTI [ 222.518871] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 5.4.0-rc4-mainline-g6a9b34166c05 #1 [ 222.518871] Hardware name: ChromiumOS crosvm, BIOS 0 [ 222.518871] RIP: 0010:set_next_entity+0xf/0xf0 [ 222.518871] Code: 42 0b e5 85 31 c0 e8 90 1a fc ff 0f 0b eb 9b 66 90 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 e5 41 57 41 56 53 48 89 f3 49 89 fe <83> 7e 40 00 74 3d 4c 89 f7 48 89 de e8 80 f9 ff ff 4c 8d 7b 18 4d [ 222.518871] RSP: 0018:ffffb95040073de8 EFLAGS: 00010046 [ 222.518871] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff85ec0c30 [ 222.518871] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff9ec44c728500 [ 222.518871] RBP: ffffb95040073e00 R08: 0000000000000000 R09: 0000000000000000 [ 222.518871] R10: 0000000000000000 R11: ffffffff84ef0a30 R12: 0000000000000000 [ 222.518871] R13: 0000000000000000 R14: ffff9ec44c728500 R15: ffffb95040073e60 [ 222.518871] FS: 0000000000000000(0000) GS:ffff9ec44c700000(0000) knlGS:0000000000000000 [ 222.518871] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 222.518871] CR2: 0000000000000040 CR3: 000000007c87a002 CR4: 00000000003606e0 [ 222.518871] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 222.518871] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 222.518871] Call Trace: [ 222.518871] pick_next_task_fair+0xe8/0x410 [ 222.518871] ? rcu_note_context_switch+0x3ef/0x520 [ 222.518871] ? finish_task_switch+0x10d/0x250 [ 222.518871] __schedule+0x1f8/0x6e0 [ 222.518871] schedule_idle+0x27/0x40 [ 222.518871] do_idle+0x21c/0x240 [ 222.518871] cpu_startup_entry+0x25/0x30 [ 222.518871] start_secondary+0x18d/0x1b0 [ 222.518871] secondary_startup_64+0xa4/0xb0 [ 222.518871] Modules linked in: vmw_vsock_virtio_transport vmw_vsock_virtio_transport_common vsock_diag vsock can_raw can snd_intel8x0 snd_ac97_codec ac97_bus virtio_input virtio_pci virtio_mmio virtio_crypto mmc_block mmc_core dummy_cpufreq rtc_test dummy_hcd can_dev vcan virtio_net net_failover failover virt_wifi virtio_blk virtio_gpu ttm virtio_rng virtio_ring virtio 8250_of crypto_engine [ 222.518871] CR2: 0000000000000040 [ 222.518871] ---[ end trace ae741809965b22f2 ]--- [ 222.518871] RIP: 0010:set_next_entity+0xf/0xf0 [ 222.518871] Code: 42 0b e5 85 31 c0 e8 90 1a fc ff 0f 0b eb 9b 66 90 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 e5 41 57 41 56 53 48 89 f3 49 89 fe <83> 7e 40 00 74 3d 4c 89 f7 48 89 de e8 80 f9 ff ff 4c 8d 7b 18 4d [ 222.518871] RSP: 0018:ffffb95040073de8 EFLAGS: 00010046 [ 222.518871] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff85ec0c30 [ 222.518871] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff9ec44c728500 [ 222.518871] RBP: ffffb95040073e00 R08: 0000000000000000 R09: 0000000000000000 [ 222.518871] R10: 0000000000000000 R11: ffffffff84ef0a30 R12: 0000000000000000 [ 222.518871] R13: 0000000000000000 R14: ffff9ec44c728500 R15: ffffb95040073e60 [ 222.518871] FS: 0000000000000000(0000) GS:ffff9ec44c700000(0000) knlGS:0000000000000000 [ 222.518871] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 222.518871] CR2: 0000000000000040 CR3: 000000007c87a002 CR4: 00000000003606e0 [ 222.518871] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 222.518871] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 222.518871] Kernel panic - not syncing: Fatal exception [ 222.518871] Kernel Offset: 0x3e00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) Bug: 142182814 Test: 20/20 avd/avd_boot_test_kernel_triggered passing Signed-off-by: Quentin Perret Change-Id: I62bb09b4710fdc593cbf1f42bf4bbc066e401458 --- kernel/sched/core.c | 19 +++++++------------ kernel/sched/deadline.c | 30 ++++++++++++++++++++++++++++-- kernel/sched/fair.c | 9 +++------ kernel/sched/idle.c | 4 +--- kernel/sched/rt.c | 29 ++++++++++++++++++++++++++++- kernel/sched/sched.h | 13 +++++-------- kernel/sched/stop_task.c | 3 +-- 7 files changed, 73 insertions(+), 34 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index c05d05094e70..eb3a7b8bd3cb 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -3919,7 +3919,7 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) p = fair_sched_class.pick_next_task(rq, prev, rf); if (unlikely(p == RETRY_TASK)) - goto restart; + goto again; /* Assumes fair_sched_class->next == idle_sched_class */ if (unlikely(!p)) @@ -3928,19 +3928,14 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) return p; } -restart: - /* - * Ensure that we put DL/RT tasks before the pick loop, such that they - * can PULL higher prio tasks when we lower the RQ 'priority'. - */ - prev->sched_class->put_prev_task(rq, prev, rf); - if (!rq->nr_running) - newidle_balance(rq, rf); - +again: for_each_class(class) { - p = class->pick_next_task(rq, NULL, NULL); - if (p) + p = class->pick_next_task(rq, prev, rf); + if (p) { + if (unlikely(p == RETRY_TASK)) + goto again; return p; + } } /* The idle class should always have a runnable task: */ diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 2dc48720f189..4ed2d10c196c 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -1761,13 +1761,39 @@ pick_next_task_dl(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) struct task_struct *p; struct dl_rq *dl_rq; - WARN_ON_ONCE(prev || rf); - dl_rq = &rq->dl; + if (need_pull_dl_task(rq, prev)) { + /* + * This is OK, because current is on_cpu, which avoids it being + * picked for load-balance and preemption/IRQs are still + * disabled avoiding further scheduler activity on it and we're + * being very careful to re-start the picking loop. + */ + rq_unpin_lock(rq, rf); + pull_dl_task(rq); + rq_repin_lock(rq, rf); + /* + * pull_dl_task() can drop (and re-acquire) rq->lock; this + * means a stop task can slip in, in which case we need to + * re-start task selection. + */ + if (rq->stop && task_on_rq_queued(rq->stop)) + return RETRY_TASK; + } + + /* + * When prev is DL, we may throttle it in put_prev_task(). + * So, we update time before we check for dl_nr_running. + */ + if (prev->sched_class == &dl_sched_class) + update_curr_dl(rq); + if (unlikely(!dl_rq->dl_nr_running)) return NULL; + put_prev_task(rq, prev); + dl_se = pick_next_dl_entity(rq, dl_rq); BUG_ON(!dl_se); diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 8f8692baa679..31b3e1a10bb3 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6810,7 +6810,7 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf goto idle; #ifdef CONFIG_FAIR_GROUP_SCHED - if (!prev || prev->sched_class != &fair_sched_class) + if (prev->sched_class != &fair_sched_class) goto simple; /* @@ -6887,8 +6887,8 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf goto done; simple: #endif - if (prev) - put_prev_task(rq, prev); + + put_prev_task(rq, prev); do { se = pick_next_entity(cfs_rq, NULL); @@ -6916,9 +6916,6 @@ done: __maybe_unused; return p; idle: - if (!rf) - return NULL; - new_tasks = newidle_balance(rq, rf); /* diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index 8dad5aa600ea..e397a165b408 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -390,9 +390,7 @@ pick_next_task_idle(struct rq *rq, struct task_struct *prev, struct rq_flags *rf { struct task_struct *next = rq->idle; - if (prev) - put_prev_task(rq, prev); - + put_prev_task(rq, prev); set_next_task_idle(rq, next); return next; diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index ebaa4e619684..f65653b139bc 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -1554,11 +1554,38 @@ pick_next_task_rt(struct rq *rq, struct task_struct *prev, struct rq_flags *rf) struct task_struct *p; struct rt_rq *rt_rq = &rq->rt; - WARN_ON_ONCE(prev || rf); + if (need_pull_rt_task(rq, prev)) { + /* + * This is OK, because current is on_cpu, which avoids it being + * picked for load-balance and preemption/IRQs are still + * disabled avoiding further scheduler activity on it and we're + * being very careful to re-start the picking loop. + */ + rq_unpin_lock(rq, rf); + pull_rt_task(rq); + rq_repin_lock(rq, rf); + /* + * pull_rt_task() can drop (and re-acquire) rq->lock; this + * means a dl or stop task can slip in, in which case we need + * to re-start task selection. + */ + if (unlikely((rq->stop && task_on_rq_queued(rq->stop)) || + rq->dl.dl_nr_running)) + return RETRY_TASK; + } + + /* + * We may dequeue prev's rt_rq in put_prev_task(). + * So, we update time before rt_queued check. + */ + if (prev->sched_class == &rt_sched_class) + update_curr_rt(rq); if (!rt_rq->rt_queued) return NULL; + put_prev_task(rq, prev); + p = _pick_next_task_rt(rq); set_next_task_rt(rq, p); diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 4f0d1668c283..e14ae174e0d1 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1724,15 +1724,12 @@ struct sched_class { void (*check_preempt_curr)(struct rq *rq, struct task_struct *p, int flags); /* - * Both @prev and @rf are optional and may be NULL, in which case the - * caller must already have invoked put_prev_task(rq, prev, rf). + * It is the responsibility of the pick_next_task() method that will + * return the next task to call put_prev_task() on the @prev task or + * something equivalent. * - * Otherwise it is the responsibility of the pick_next_task() to call - * put_prev_task() on the @prev task or something equivalent, IFF it - * returns a next task. - * - * In that case (@rf != NULL) it may return RETRY_TASK when it finds a - * higher prio class has runnable tasks. + * May return RETRY_TASK when it finds a higher prio class has runnable + * tasks. */ struct task_struct * (*pick_next_task)(struct rq *rq, struct task_struct *prev, diff --git a/kernel/sched/stop_task.c b/kernel/sched/stop_task.c index 7e1cee4e65b2..8f414018d5e0 100644 --- a/kernel/sched/stop_task.c +++ b/kernel/sched/stop_task.c @@ -33,11 +33,10 @@ pick_next_task_stop(struct rq *rq, struct task_struct *prev, struct rq_flags *rf { struct task_struct *stop = rq->stop; - WARN_ON_ONCE(prev || rf); - if (!stop || !task_on_rq_queued(stop)) return NULL; + put_prev_task(rq, prev); set_next_task_stop(rq, stop); return stop; -- GitLab From 85ac30fa2e24f628e9f4f9344460f4015d33fd7d Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 25 Oct 2019 12:06:02 +0100 Subject: [PATCH 843/993] fjes: Handle workqueue allocation failure In the highly unlikely event that we fail to allocate either of the "/txrx" or "/control" workqueues, we should bail cleanly rather than blindly march on with NULL queue pointer(s) installed in the 'fjes_adapter' instance. Cc: "David S. Miller" Reported-by: Nicolas Waisman Link: https://lore.kernel.org/lkml/CADJ_3a8WFrs5NouXNqS5WYe7rebFP+_A5CheeqAyD_p7DFJJcg@mail.gmail.com/ Signed-off-by: Will Deacon Signed-off-by: David S. Miller --- drivers/net/fjes/fjes_main.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/fjes/fjes_main.c b/drivers/net/fjes/fjes_main.c index bbbc1dcb6ab5..b517c1af9de0 100644 --- a/drivers/net/fjes/fjes_main.c +++ b/drivers/net/fjes/fjes_main.c @@ -1237,8 +1237,17 @@ static int fjes_probe(struct platform_device *plat_dev) adapter->open_guard = false; adapter->txrx_wq = alloc_workqueue(DRV_NAME "/txrx", WQ_MEM_RECLAIM, 0); + if (unlikely(!adapter->txrx_wq)) { + err = -ENOMEM; + goto err_free_netdev; + } + adapter->control_wq = alloc_workqueue(DRV_NAME "/control", WQ_MEM_RECLAIM, 0); + if (unlikely(!adapter->control_wq)) { + err = -ENOMEM; + goto err_free_txrx_wq; + } INIT_WORK(&adapter->tx_stall_task, fjes_tx_stall_task); INIT_WORK(&adapter->raise_intr_rxdata_task, @@ -1255,7 +1264,7 @@ static int fjes_probe(struct platform_device *plat_dev) hw->hw_res.irq = platform_get_irq(plat_dev, 0); err = fjes_hw_init(&adapter->hw); if (err) - goto err_free_netdev; + goto err_free_control_wq; /* setup MAC address (02:00:00:00:00:[epid])*/ netdev->dev_addr[0] = 2; @@ -1277,6 +1286,10 @@ static int fjes_probe(struct platform_device *plat_dev) err_hw_exit: fjes_hw_exit(&adapter->hw); +err_free_control_wq: + destroy_workqueue(adapter->control_wq); +err_free_txrx_wq: + destroy_workqueue(adapter->txrx_wq); err_free_netdev: free_netdev(netdev); err_out: -- GitLab From 63a41746827cb16dc6ad0d4d761ab4e7dda7a0c3 Mon Sep 17 00:00:00 2001 From: Jiangfeng Xiao Date: Fri, 25 Oct 2019 21:48:22 +0800 Subject: [PATCH 844/993] net: hisilicon: Fix "Trying to free already-free IRQ" When rmmod hip04_eth.ko, we can get the following warning: Task track: rmmod(1623)>bash(1591)>login(1581)>init(1) ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1623 at kernel/irq/manage.c:1557 __free_irq+0xa4/0x2ac() Trying to free already-free IRQ 200 Modules linked in: ping(O) pramdisk(O) cpuinfo(O) rtos_snapshot(O) interrupt_ctrl(O) mtdblock mtd_blkdevrtfs nfs_acl nfs lockd grace sunrpc xt_tcpudp ipt_REJECT iptable_filter ip_tables x_tables nf_reject_ipv CPU: 0 PID: 1623 Comm: rmmod Tainted: G O 4.4.193 #1 Hardware name: Hisilicon A15 [] (rtos_unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0xa0/0xd8) [] (dump_stack) from [] (warn_slowpath_common+0x84/0xb0) [] (warn_slowpath_common) from [] (warn_slowpath_fmt+0x3c/0x68) [] (warn_slowpath_fmt) from [] (__free_irq+0xa4/0x2ac) [] (__free_irq) from [] (free_irq+0x60/0x7c) [] (free_irq) from [] (release_nodes+0x1c4/0x1ec) [] (release_nodes) from [] (__device_release_driver+0xa8/0x104) [] (__device_release_driver) from [] (driver_detach+0xd0/0xf8) [] (driver_detach) from [] (bus_remove_driver+0x64/0x8c) [] (bus_remove_driver) from [] (SyS_delete_module+0x198/0x1e0) [] (SyS_delete_module) from [] (__sys_trace_return+0x0/0x10) ---[ end trace bb25d6123d849b44 ]--- Currently "rmmod hip04_eth.ko" call free_irq more than once as devres_release_all and hip04_remove both call free_irq. This results in a 'Trying to free already-free IRQ' warning. To solve the problem free_irq has been moved out of hip04_remove. Signed-off-by: Jiangfeng Xiao Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hip04_eth.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hip04_eth.c b/drivers/net/ethernet/hisilicon/hip04_eth.c index c84167447abe..ad6d91219daf 100644 --- a/drivers/net/ethernet/hisilicon/hip04_eth.c +++ b/drivers/net/ethernet/hisilicon/hip04_eth.c @@ -1038,7 +1038,6 @@ static int hip04_remove(struct platform_device *pdev) hip04_free_ring(ndev, d); unregister_netdev(ndev); - free_irq(ndev->irq, ndev); of_node_put(priv->phy_node); cancel_work_sync(&priv->tx_timeout_task); free_netdev(ndev); -- GitLab From 6f39188c9d5f81af7a3bc687636b7abc9629ee27 Mon Sep 17 00:00:00 2001 From: Yi Wang Date: Fri, 25 Oct 2019 09:30:15 +0800 Subject: [PATCH 845/993] drm/panfrost: fix -Wmissing-prototypes warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We get these warnings when build kernel W=1: drivers/gpu/drm/panfrost/panfrost_perfcnt.c:35:6: warning: no previous prototype for ‘panfrost_perfcnt_clean_cache_done’ [-Wmissing-prototypes] drivers/gpu/drm/panfrost/panfrost_perfcnt.c:40:6: warning: no previous prototype for ‘panfrost_perfcnt_sample_done’ [-Wmissing-prototypes] drivers/gpu/drm/panfrost/panfrost_perfcnt.c:190:5: warning: no previous prototype for ‘panfrost_ioctl_perfcnt_enable’ [-Wmissing-prototypes] drivers/gpu/drm/panfrost/panfrost_perfcnt.c:218:5: warning: no previous prototype for ‘panfrost_ioctl_perfcnt_dump’ [-Wmissing-prototypes] drivers/gpu/drm/panfrost/panfrost_perfcnt.c:250:6: warning: no previous prototype for ‘panfrost_perfcnt_close’ [-Wmissing-prototypes] drivers/gpu/drm/panfrost/panfrost_perfcnt.c:264:5: warning: no previous prototype for ‘panfrost_perfcnt_init’ [-Wmissing-prototypes] drivers/gpu/drm/panfrost/panfrost_perfcnt.c:320:6: warning: no previous prototype for ‘panfrost_perfcnt_fini’ [-Wmissing-prototypes] drivers/gpu/drm/panfrost/panfrost_mmu.c:227:6: warning: no previous prototype for ‘panfrost_mmu_flush_range’ [-Wmissing-prototypes] drivers/gpu/drm/panfrost/panfrost_mmu.c:435:5: warning: no previous prototype for ‘panfrost_mmu_map_fault_addr’ [-Wmissing-prototypes] For file panfrost_mmu.c, make functions static to fix this. For file panfrost_perfcnt.c, include header file can fix this. Signed-off-by: Yi Wang Reviewed-by: Steven Price Cc: stable@vger.kernel.org [robh: fixup function parameter alignment] Signed-off-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/1571967015-42854-1-git-send-email-wang.yi59@zte.com.cn --- drivers/gpu/drm/panfrost/panfrost_mmu.c | 9 +++++---- drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c index bdd990568476..87e7963b8adf 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -224,9 +224,9 @@ static size_t get_pgsize(u64 addr, size_t size) return SZ_2M; } -void panfrost_mmu_flush_range(struct panfrost_device *pfdev, - struct panfrost_mmu *mmu, - u64 iova, size_t size) +static void panfrost_mmu_flush_range(struct panfrost_device *pfdev, + struct panfrost_mmu *mmu, + u64 iova, size_t size) { if (mmu->as < 0) return; @@ -432,7 +432,8 @@ addr_to_drm_mm_node(struct panfrost_device *pfdev, int as, u64 addr) #define NUM_FAULT_PAGES (SZ_2M / PAGE_SIZE) -int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, u64 addr) +static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, + u64 addr) { int ret, i; struct panfrost_gem_object *bo; diff --git a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c index 83c57d325ca8..2dba192bf198 100644 --- a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c +++ b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c @@ -16,6 +16,7 @@ #include "panfrost_issues.h" #include "panfrost_job.h" #include "panfrost_mmu.h" +#include "panfrost_perfcnt.h" #include "panfrost_regs.h" #define COUNTERS_PER_BLOCK 64 -- GitLab From e81694723af1c2d89edcd1948e77a8d53126d5a5 Mon Sep 17 00:00:00 2001 From: Maheshwar Ajja Date: Fri, 25 Oct 2019 15:12:53 -0700 Subject: [PATCH 846/993] ANDROID: media: increase video max frame number Few userspace clients and drivers need more frames and hence increase video max frame number from 32 to 64. Bug: 143356419 Change-Id: Ib5394b7b71d75177234333dae23ec30fea01450f Signed-off-by: Maheshwar Ajja --- include/media/videobuf2-core.h | 2 +- include/uapi/linux/videodev2.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 640aabe69450..1168ed938f8c 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -19,7 +19,7 @@ #include #include -#define VB2_MAX_FRAME (32) +#define VB2_MAX_FRAME (64) #define VB2_MAX_PLANES (8) /** diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index c3671c633dca..ebb9755ed9d7 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -70,7 +70,7 @@ * Common stuff for both V4L1 and V4L2 * Moved from videodev.h */ -#define VIDEO_MAX_FRAME 32 +#define VIDEO_MAX_FRAME 64 #define VIDEO_MAX_PLANES 8 /* -- GitLab From f70744c68779c8a72a0c82294e3233b994af656d Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Mon, 28 Oct 2019 20:08:25 +0000 Subject: [PATCH 847/993] drm/panfrost: Don't dereference bogus MMU pointers It seems that killing an application while faults are occurring (particularly with a GPU in FPGA at a whopping 40MHz) can lead to handling a lingering page fault after all the address space contexts have already been freed. In this situation, the LRU list is empty so addr_to_drm_mm_node() ends up dereferencing the list head as if it were a struct panfrost_mmu entry; this leaves "mmu->as" actually pointing at the pfdev->alloc_mask bitmap, which is also empty, and given that the fault has a high likelihood of being in AS0, hilarity ensues. Sadly, the cleanest solution seems to involve another goto. Oh well, at least it's robust... Fixes: 65e51e30d862 ("drm/panfrost: Prevent race when handling page fault") Signed-off-by: Robin Murphy Signed-off-by: Rob Herring Link: https://patchwork.freedesktop.org/patch/msgid/9a0b09e6b5851f0d4428b72dd6b8b4c0d0ef4206.1572293305.git.robin.murphy@arm.com --- drivers/gpu/drm/panfrost/panfrost_mmu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c index 87e7963b8adf..a3ed64a1f15e 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -406,11 +406,11 @@ addr_to_drm_mm_node(struct panfrost_device *pfdev, int as, u64 addr) spin_lock(&pfdev->as_lock); list_for_each_entry(mmu, &pfdev->as_lru_list, list) { if (as == mmu->as) - break; + goto found_mmu; } - if (as != mmu->as) - goto out; + goto out; +found_mmu: priv = container_of(mmu, struct panfrost_file_priv, mmu); spin_lock(&priv->mm_lock); -- GitLab From 511b851f8057141dd0f89df3643a2b946908d41f Mon Sep 17 00:00:00 2001 From: Matthias Maennich Date: Mon, 28 Oct 2019 23:46:05 +0000 Subject: [PATCH 848/993] ANDROID: Fix typo for FROMLIST: section Signed-off-by: Matthias Maennich Change-Id: Id51ce99c78aa033468064e23996f476ca879cb69 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a2dd85e5a3f..7012373fe98d 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ must be a stable maintainer branch (not rebased, so don't use `linux-next` for e - If the patch has been submitted to LKML, but not accepted into any maintainer tree - tag the patch subject with `FROMLIST:` - - add a `List:` tag with a link to the submittal on lore.kernel.org + - add a `Link:` tag with a link to the submittal on lore.kernel.org - if changes were required, use `BACKPORT: FROMLIST:` - Example: ``` -- GitLab From 226a0a7161c319b0892c49a59dafa7de9056039d Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Thu, 5 Sep 2019 14:55:28 -0700 Subject: [PATCH 849/993] ANDROID: staging: ion: Fix dynamic heap ID assignment The current implementation derives the heap ID using ffs(), which is one-indexed, and then proceeds to use this value with functions such as find_next_zero_bit() and test_and_set_bit() which operate under a zero-indexing scheme. This can lead to some clumsy/erroneous handling when dynamically allocating a heap ID, as follows: CMA heap bits range: [8, 15] First CMA heap without a heap ID registration: start_bit = ffs(ION_HEAP_DMA_START) /* 9 */ end_bit = ffs(ION_HEAP_DMA_END) /* 16 */ id_bit = find_next_zero_bit(dev->heap_ids, 16 + 1, 9) /* 9 */ test_and_set_bit(9 - 1, dev->heap_ids) /* Succeeds */ Second CMA heap without a heap ID registration: start_bit = ffs(ION_HEAP_DMA_START) /* 9 */ end_bit = ffs(ION_HEAP_DMA_END) == 16 /* 16 */ id_bit = find_next_zero_bit(dev->heap_ids, 16 + 1, 9) /* 9 */ test_and_set_bit(9 - 1, dev->heap_ids) /* Fails */ Thus, switch to a zero-indexing scheme when deriving the heap ID parameters to simplify the logic, as well as correct the dynamic heap ID assignment logic. Fixes: acbfdf321afb ("ANDROID: staging: ion: add support for consistent heap ids") Change-Id: I66d0f3838a3ef4dc4ff8537f23dd4e226472b9e2 Signed-off-by: Isaac J. Manjarres --- drivers/staging/android/ion/ion.c | 33 ++++++++++++++----------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index a499a76453ee..1f9096f13877 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -231,33 +231,30 @@ DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, static int ion_assign_heap_id(struct ion_heap *heap, struct ion_device *dev) { - int id_bit; - int start_bit, end_bit = -1; + int id_bit = -EINVAL; + int start_bit = -1, end_bit = -1; switch (heap->type) { case ION_HEAP_TYPE_SYSTEM: - id_bit = ffs(ION_HEAP_SYSTEM); + id_bit = __ffs(ION_HEAP_SYSTEM); break; case ION_HEAP_TYPE_SYSTEM_CONTIG: - id_bit = ffs(ION_HEAP_SYSTEM_CONTIG); + id_bit = __ffs(ION_HEAP_SYSTEM_CONTIG); break; case ION_HEAP_TYPE_CHUNK: - id_bit = ffs(ION_HEAP_CHUNK); + id_bit = __ffs(ION_HEAP_CHUNK); break; case ION_HEAP_TYPE_CARVEOUT: - id_bit = 0; - start_bit = ffs(ION_HEAP_CARVEOUT_START); - end_bit = ffs(ION_HEAP_CARVEOUT_END); + start_bit = __ffs(ION_HEAP_CARVEOUT_START); + end_bit = __ffs(ION_HEAP_CARVEOUT_END); break; case ION_HEAP_TYPE_DMA: - id_bit = 0; - start_bit = ffs(ION_HEAP_DMA_START); - end_bit = ffs(ION_HEAP_DMA_END); + start_bit = __ffs(ION_HEAP_DMA_START); + end_bit = __ffs(ION_HEAP_DMA_END); break; case ION_HEAP_TYPE_CUSTOM ... ION_HEAP_TYPE_MAX: - id_bit = 0; - start_bit = ffs(ION_HEAP_CUSTOM_START); - end_bit = ffs(ION_HEAP_CUSTOM_END); + start_bit = __ffs(ION_HEAP_CUSTOM_START); + end_bit = __ffs(ION_HEAP_CUSTOM_END); break; default: return -EINVAL; @@ -271,9 +268,9 @@ static int ion_assign_heap_id(struct ion_heap *heap, struct ion_device *dev) * If the heap hasn't picked an id by itself, then we assign it * one. */ - if (!id_bit) { + if (id_bit < 0) { if (heap->id) { - id_bit = ffs(heap->id); + id_bit = __ffs(heap->id); if (id_bit < start_bit || id_bit > end_bit) return -EINVAL; } else { @@ -284,9 +281,9 @@ static int ion_assign_heap_id(struct ion_heap *heap, struct ion_device *dev) } } - if (test_and_set_bit(id_bit - 1, dev->heap_ids)) + if (test_and_set_bit(id_bit, dev->heap_ids)) return -EEXIST; - heap->id = id_bit - 1; + heap->id = id_bit; dev->heap_cnt++; return 0; -- GitLab From dd7ebe6787328dec8b45f97c93d3dfdc4a4e4fde Mon Sep 17 00:00:00 2001 From: Anna Karas Date: Thu, 26 Sep 2019 15:35:59 +0300 Subject: [PATCH 850/993] drm/i915/tgl: Fix doc not corresponding to code Replace PLLs names used in documentation to that used in the code. Cc: Vandita Kulkarni Fixes: 68ff39c3f8c0 ("drm/i915/tgl: Add new pll ids") Signed-off-by: Anna Karas Reviewed-by: Vandita Kulkarni Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190926123559.15717-1-anna.karas@intel.com (cherry picked from commit d328bd4f905834c7d87a49962ebc96e397aab7b9) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h index e7588799fce5..104cf6d42333 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h @@ -147,11 +147,11 @@ enum intel_dpll_id { */ DPLL_ID_ICL_MGPLL4 = 6, /** - * @DPLL_ID_TGL_TCPLL5: TGL TC PLL port 5 (TC5) + * @DPLL_ID_TGL_MGPLL5: TGL TC PLL port 5 (TC5) */ DPLL_ID_TGL_MGPLL5 = 7, /** - * @DPLL_ID_TGL_TCPLL6: TGL TC PLL port 6 (TC6) + * @DPLL_ID_TGL_MGPLL6: TGL TC PLL port 6 (TC6) */ DPLL_ID_TGL_MGPLL6 = 8, }; -- GitLab From 6f3ef5c25cc762687a7341c18cbea5af54461407 Mon Sep 17 00:00:00 2001 From: Navid Emamdoost Date: Fri, 25 Oct 2019 23:53:30 -0500 Subject: [PATCH 851/993] wimax: i2400: Fix memory leak in i2400m_op_rfkill_sw_toggle In the implementation of i2400m_op_rfkill_sw_toggle() the allocated buffer for cmd should be released before returning. The documentation for i2400m_msg_to_dev() says when it returns the buffer can be reused. Meaning cmd should be released in either case. Move kfree(cmd) before return to be reached by all execution paths. Fixes: 2507e6ab7a9a ("wimax: i2400: fix memory leak") Signed-off-by: Navid Emamdoost Signed-off-by: David S. Miller --- drivers/net/wimax/i2400m/op-rfkill.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wimax/i2400m/op-rfkill.c b/drivers/net/wimax/i2400m/op-rfkill.c index 8efb493ceec2..5c79f052cad2 100644 --- a/drivers/net/wimax/i2400m/op-rfkill.c +++ b/drivers/net/wimax/i2400m/op-rfkill.c @@ -127,12 +127,12 @@ int i2400m_op_rfkill_sw_toggle(struct wimax_dev *wimax_dev, "%d\n", result); result = 0; error_cmd: - kfree(cmd); kfree_skb(ack_skb); error_msg_to_dev: error_alloc: d_fnend(4, dev, "(wimax_dev %p state %d) = %d\n", wimax_dev, state, result); + kfree(cmd); return result; } -- GitLab From 1c44ce560b4de639f237b458be1729489ff44d0a Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Sat, 26 Oct 2019 21:04:26 +0300 Subject: [PATCH 852/993] net: mscc: ocelot: fix vlan_filtering when enslaving to bridge before link is up Background information: the driver operates the hardware in a mode where a single VLAN can be transmitted as untagged on a particular egress port. That is the "native VLAN on trunk port" use case. Its value is held in port->vid. Consider the following command sequence (no network manager, all interfaces are down, debugging prints added by me): $ ip link add dev br0 type bridge vlan_filtering 1 $ ip link set dev swp0 master br0 Kernel code path during last command: br_add_slave -> ocelot_netdevice_port_event (NETDEV_CHANGEUPPER): [ 21.401901] ocelot_vlan_port_apply: port 0 vlan aware 0 pvid 0 vid 0 br_add_slave -> nbp_vlan_init -> switchdev_port_attr_set -> ocelot_port_attr_set (SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING): [ 21.413335] ocelot_vlan_port_apply: port 0 vlan aware 1 pvid 0 vid 0 br_add_slave -> nbp_vlan_init -> nbp_vlan_add -> br_switchdev_port_vlan_add -> switchdev_port_obj_add -> ocelot_port_obj_add -> ocelot_vlan_vid_add [ 21.667421] ocelot_vlan_port_apply: port 0 vlan aware 1 pvid 1 vid 1 So far so good. The bridge has replaced the driver's default pvid used in standalone mode (0) with its own default_pvid (1). The port's vid (native VLAN) has also changed from 0 to 1. $ ip link set dev swp0 up [ 31.722956] 8021q: adding VLAN 0 to HW filter on device swp0 do_setlink -> dev_change_flags -> vlan_vid_add -> ocelot_vlan_rx_add_vid -> ocelot_vlan_vid_add: [ 31.728700] ocelot_vlan_port_apply: port 0 vlan aware 1 pvid 1 vid 0 The 8021q module uses the .ndo_vlan_rx_add_vid API on .ndo_open to make ports be able to transmit and receive 802.1p-tagged traffic by default. This API is supposed to offload a VLAN sub-interface, which for a switch port means to add a VLAN that is not a pvid, and tagged on egress. But the driver implementation of .ndo_vlan_rx_add_vid is wrong: it adds back vid 0 as "egress untagged". Now back to the initial paragraph: there is a single untagged VID that the driver keeps track of, and that has just changed from 1 (the pvid) to 0. So this breaks the bridge core's expectation, because it has changed vid 1 from untagged to tagged, when what the user sees is. $ bridge vlan port vlan ids swp0 1 PVID Egress Untagged br0 1 PVID Egress Untagged But curiously, instead of manifesting itself as "untagged and pvid-tagged traffic gets sent as tagged on egress", the bug: - is hidden when vlan_filtering=0 - manifests as dropped traffic when vlan_filtering=1, due to this setting: if (port->vlan_aware && !port->vid) /* If port is vlan-aware and tagged, drop untagged and priority * tagged frames. */ val |= ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA | ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA | ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA; which would have made sense if it weren't for this bug. The setting's intention was "this is a trunk port with no native VLAN, so don't accept untagged traffic". So the driver was never expecting to set VLAN 0 as the value of the native VLAN, 0 was just encoding for "invalid". So the fix is to not send 802.1p traffic as untagged, because that would change the port's native vlan to 0, unbeknownst to the bridge, and trigger unexpected code paths in the driver. Cc: Antoine Tenart Cc: Alexandre Belloni Fixes: 7142529f1688 ("net: mscc: ocelot: add VLAN filtering") Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli Acked-by: Alexandre Belloni Reviewed-by: Horatiu Vultur Signed-off-by: David S. Miller --- drivers/net/ethernet/mscc/ocelot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index 4d1bce4389c7..a891bccb3a41 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -934,7 +934,7 @@ static int ocelot_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, static int ocelot_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) { - return ocelot_vlan_vid_add(dev, vid, false, true); + return ocelot_vlan_vid_add(dev, vid, false, false); } static int ocelot_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, -- GitLab From b9cd75e6689560140dadaed98eb4b41aad75d55d Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Sat, 26 Oct 2019 21:04:27 +0300 Subject: [PATCH 853/993] net: mscc: ocelot: refuse to overwrite the port's native vlan The switch driver keeps a "vid" variable per port, which signifies _the_ VLAN ID that is stripped on that port's egress (aka the native VLAN on a trunk port). That is the way the hardware is designed (mostly). The port->vid is programmed into REW:PORT:PORT_VLAN_CFG:PORT_VID and the rewriter is told to send all traffic as tagged except the one having port->vid. There exists a possibility of finer-grained egress untagging decisions: using the VCAP IS1 engine, one rule can be added to match every VLAN-tagged frame whose VLAN should be untagged, and set POP_CNT=1 as action. However, the IS1 can hold at most 512 entries, and the VLANs are in the order of 6 * 4096. So the code is fine for now. But this sequence of commands: $ bridge vlan add dev swp0 vid 1 pvid untagged $ bridge vlan add dev swp0 vid 2 untagged makes untagged and pvid-tagged traffic be sent out of swp0 as tagged with VID 1, despite user's request. Prevent that from happening. The user should temporarily remove the existing untagged VLAN (1 in this case), add it back as tagged, and then add the new untagged VLAN (2 in this case). Cc: Antoine Tenart Cc: Alexandre Belloni Fixes: 7142529f1688 ("net: mscc: ocelot: add VLAN filtering") Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli Acked-by: Alexandre Belloni Signed-off-by: David S. Miller --- drivers/net/ethernet/mscc/ocelot.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index a891bccb3a41..344539c0d3aa 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -261,8 +261,15 @@ static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid, port->pvid = vid; /* Untagged egress vlan clasification */ - if (untagged) + if (untagged && port->vid != vid) { + if (port->vid) { + dev_err(ocelot->dev, + "Port already has a native VLAN: %d\n", + port->vid); + return -EBUSY; + } port->vid = vid; + } ocelot_vlan_port_apply(ocelot, port); -- GitLab From 6dfef396ea13873ae9066ee2e0ad6ee364031fe2 Mon Sep 17 00:00:00 2001 From: Roi Dayan Date: Wed, 11 Sep 2019 14:44:50 +0300 Subject: [PATCH 854/993] net/mlx5: Fix flow counter list auto bits struct The union should contain the extended dest and counter list. Remove the resevered 0x40 bits which is redundant. This change doesn't break any functionally. Everything works today because the code in fs_cmd.c is using the correct structs if extended dest or the basic dest. Fixes: 1b115498598f ("net/mlx5: Introduce extended destination fields") Signed-off-by: Roi Dayan Reviewed-by: Mark Bloch Signed-off-by: Saeed Mahameed --- include/linux/mlx5/mlx5_ifc.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index 138c50d5a353..0836fe232f97 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -1545,9 +1545,8 @@ struct mlx5_ifc_extended_dest_format_bits { }; union mlx5_ifc_dest_format_struct_flow_counter_list_auto_bits { - struct mlx5_ifc_dest_format_struct_bits dest_format_struct; + struct mlx5_ifc_extended_dest_format_bits extended_dest_format; struct mlx5_ifc_flow_counter_list_bits flow_counter_list; - u8 reserved_at_0[0x40]; }; struct mlx5_ifc_fte_match_param_bits { -- GitLab From d5dbcc4e87bc8444bd2f1ca4b8f787e1e5677ec2 Mon Sep 17 00:00:00 2001 From: Dmytro Linkin Date: Wed, 4 Sep 2019 12:32:49 +0000 Subject: [PATCH 855/993] net/mlx5e: Determine source port properly for vlan push action Termination tables are used for vlan push actions on uplink ports. To support RoCE dual port the source port value was placed in a register. Fix the code to use an API method returning the source port according to the FW capabilities. Fixes: 10caabdaad5a ("net/mlx5e: Use termination table for VLAN push actions") Signed-off-by: Dmytro Linkin Reviewed-by: Jianbo Liu Reviewed-by: Oz Shlomo Reviewed-by: Roi Dayan Signed-off-by: Saeed Mahameed --- .../mlx5/core/eswitch_offloads_termtbl.c | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c index 1d55a324a17e..7879e1746297 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c @@ -177,22 +177,32 @@ mlx5_eswitch_termtbl_actions_move(struct mlx5_flow_act *src, memset(&src->vlan[1], 0, sizeof(src->vlan[1])); } +static bool mlx5_eswitch_offload_is_uplink_port(const struct mlx5_eswitch *esw, + const struct mlx5_flow_spec *spec) +{ + u32 port_mask, port_value; + + if (MLX5_CAP_ESW_FLOWTABLE(esw->dev, flow_source)) + return spec->flow_context.flow_source == MLX5_VPORT_UPLINK; + + port_mask = MLX5_GET(fte_match_param, spec->match_criteria, + misc_parameters.source_port); + port_value = MLX5_GET(fte_match_param, spec->match_value, + misc_parameters.source_port); + return (port_mask & port_value & 0xffff) == MLX5_VPORT_UPLINK; +} + bool mlx5_eswitch_termtbl_required(struct mlx5_eswitch *esw, struct mlx5_flow_act *flow_act, struct mlx5_flow_spec *spec) { - u32 port_mask = MLX5_GET(fte_match_param, spec->match_criteria, - misc_parameters.source_port); - u32 port_value = MLX5_GET(fte_match_param, spec->match_value, - misc_parameters.source_port); - if (!MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, termination_table)) return false; /* push vlan on RX */ return (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH) && - ((port_mask & port_value) == MLX5_VPORT_UPLINK); + mlx5_eswitch_offload_is_uplink_port(esw, spec); } struct mlx5_flow_handle * -- GitLab From 752d3dc06d6936d5a357a18b6b51d91c7e134e88 Mon Sep 17 00:00:00 2001 From: Dmytro Linkin Date: Thu, 29 Aug 2019 15:24:27 +0000 Subject: [PATCH 856/993] net/mlx5e: Remove incorrect match criteria assignment line Driver have function, which enable match criteria for misc parameters in dependence of eswitch capabilities. Fixes: 4f5d1beadc10 ("Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux") Signed-off-by: Dmytro Linkin Reviewed-by: Jianbo Liu Reviewed-by: Roi Dayan Reviewed-by: Saeed Mahameed Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 00d71db15f22..369499e88fe8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -285,7 +285,6 @@ mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw, mlx5_eswitch_set_rule_source_port(esw, spec, attr); - spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS; if (attr->outer_match_level != MLX5_MATCH_NONE) spec->match_criteria_enable |= MLX5_MATCH_OUTER_HEADERS; -- GitLab From 5dfb6335cbecbd59040275c8396c2d0af0bbd549 Mon Sep 17 00:00:00 2001 From: Maor Gottlieb Date: Mon, 16 Sep 2019 13:17:33 +0300 Subject: [PATCH 857/993] net/mlx5e: Replace kfree with kvfree when free vhca stats Memory allocated by kvzalloc should be freed by kvfree. Fixes: cef35af34d6d ("net/mlx5e: Add mlx5e HV VHCA stats agent") Signed-off-by: Maor Gottlieb Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c index b3a249b2a482..ac44bbe95c5c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/hv_vhca_stats.c @@ -141,7 +141,7 @@ int mlx5e_hv_vhca_stats_create(struct mlx5e_priv *priv) "Failed to create hv vhca stats agent, err = %ld\n", PTR_ERR(agent)); - kfree(priv->stats_agent.buf); + kvfree(priv->stats_agent.buf); return IS_ERR_OR_NULL(agent); } @@ -157,5 +157,5 @@ void mlx5e_hv_vhca_stats_destroy(struct mlx5e_priv *priv) return; mlx5_hv_vhca_agent_destroy(priv->stats_agent.agent); - kfree(priv->stats_agent.buf); + kvfree(priv->stats_agent.buf); } -- GitLab From 64d7b68577130ae00f954a28ea9d6bc51025caf9 Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Tue, 24 Sep 2019 10:19:16 +0300 Subject: [PATCH 858/993] net/mlx5e: Only skip encap flows update when encap init failed When encap entry initialization completes successfully e->compl_result is set to positive value and not zero, like mlx5e_rep_update_flows() assumes at the moment. Fix the conditional to only skip encap flows update when e->compl_result < 0. Fixes: 2a1f1768fa17 ("net/mlx5e: Refactor neigh update for concurrent execution") Signed-off-by: Vlad Buslov Reviewed-by: Roi Dayan Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 95892a3b63a1..cd9bb7c7b341 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -611,8 +611,8 @@ static void mlx5e_rep_update_flows(struct mlx5e_priv *priv, mutex_lock(&esw->offloads.encap_tbl_lock); encap_connected = !!(e->flags & MLX5_ENCAP_ENTRY_VALID); - if (e->compl_result || (encap_connected == neigh_connected && - ether_addr_equal(e->h_dest, ha))) + if (e->compl_result < 0 || (encap_connected == neigh_connected && + ether_addr_equal(e->h_dest, ha))) goto unlock; mlx5e_take_all_encap_flows(e, &flow_list); -- GitLab From 2347cee83b2bd868bde2d283db0fac89f22be4e0 Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Thu, 19 Sep 2019 15:58:14 -0500 Subject: [PATCH 859/993] net/mlx5: Fix rtable reference leak If the rt entry gateway family is not AF_INET for multipath device, rtable reference is leaked. Hence, fix it by releasing the reference. Fixes: 5fb091e8130b ("net/mlx5e: Use hint to resolve route when in HW multipath mode") Fixes: e32ee6c78efa ("net/mlx5e: Support tunnel encap over tagged Ethernet") Signed-off-by: Parav Pandit Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c index f8ee18b4da6f..13af72556987 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c @@ -97,15 +97,19 @@ static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv, if (ret) return ret; - if (mlx5_lag_is_multipath(mdev) && rt->rt_gw_family != AF_INET) + if (mlx5_lag_is_multipath(mdev) && rt->rt_gw_family != AF_INET) { + ip_rt_put(rt); return -ENETUNREACH; + } #else return -EOPNOTSUPP; #endif ret = get_route_and_out_devs(priv, rt->dst.dev, route_dev, out_dev); - if (ret < 0) + if (ret < 0) { + ip_rt_put(rt); return ret; + } if (!(*out_ttl)) *out_ttl = ip4_dst_hoplimit(&rt->dst); @@ -149,8 +153,10 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv, *out_ttl = ip6_dst_hoplimit(dst); ret = get_route_and_out_devs(priv, dst->dev, route_dev, out_dev); - if (ret < 0) + if (ret < 0) { + dst_release(dst); return ret; + } #else return -EOPNOTSUPP; #endif -- GitLab From 0fd79b1e17bec8460039f6bdb57163a0442110d9 Mon Sep 17 00:00:00 2001 From: Eli Britstein Date: Tue, 15 Oct 2019 12:44:18 +0000 Subject: [PATCH 860/993] net/mlx5: Fix NULL pointer dereference in extended destination The cited commit refactored the encap id into a struct pointed from the destination. Bug fix for the case there is no encap for one of the destinations. Fixes: 2b688ea5efde ("net/mlx5: Add flow steering actions to fs_cmd shim layer") Signed-off-by: Eli Britstein Reviewed-by: Roi Dayan Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c index 579c306caa7b..3c816e81f8d9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c @@ -507,7 +507,8 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev, MLX5_SET(dest_format_struct, in_dests, destination_eswitch_owner_vhca_id, dst->dest_attr.vport.vhca_id); - if (extended_dest) { + if (extended_dest && + dst->dest_attr.vport.pkt_reformat) { MLX5_SET(dest_format_struct, in_dests, packet_reformat, !!(dst->dest_attr.vport.flags & -- GitLab From 2a4b6526236791a1bb8092079ad87a1629e78db5 Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Tue, 10 Sep 2019 14:38:17 +0300 Subject: [PATCH 861/993] net/mlx5e: Don't store direct pointer to action's tunnel info Geneve implementation changed mlx5 tc to user direct pointer to tunnel_key action's internal struct ip_tunnel_info instance. However, this leads to use-after-free error when initial filter that caused creation of new encap entry is deleted or when tunnel_key action is manually overwritten through action API. Moreover, with recent TC offloads API unlocking change struct flow_action_entry->tunnel point to temporal copy of tunnel info that is deallocated after filter is offloaded to hardware which causes bug to reproduce every time new filter is attached to existing encap entry with following KASAN bug: [ 314.885555] ================================================================== [ 314.886641] BUG: KASAN: use-after-free in memcmp+0x2c/0x60 [ 314.886864] Read of size 1 at addr ffff88886c746280 by task tc/2682 [ 314.887179] CPU: 22 PID: 2682 Comm: tc Not tainted 5.3.0-rc7+ #703 [ 314.887188] Hardware name: Supermicro SYS-2028TP-DECR/X10DRT-P, BIOS 2.0b 03/30/2017 [ 314.887195] Call Trace: [ 314.887215] dump_stack+0x9a/0xf0 [ 314.887236] print_address_description+0x67/0x323 [ 314.887248] ? memcmp+0x2c/0x60 [ 314.887257] ? memcmp+0x2c/0x60 [ 314.887272] __kasan_report.cold+0x1a/0x3d [ 314.887474] ? __mlx5e_tc_del_fdb_peer_flow+0x100/0x1b0 [mlx5_core] [ 314.887484] ? memcmp+0x2c/0x60 [ 314.887509] kasan_report+0xe/0x12 [ 314.887521] memcmp+0x2c/0x60 [ 314.887662] mlx5e_tc_add_fdb_flow+0x51b/0xbe0 [mlx5_core] [ 314.887838] ? mlx5e_encap_take+0x110/0x110 [mlx5_core] [ 314.887902] ? lockdep_init_map+0x87/0x2c0 [ 314.887924] ? __init_waitqueue_head+0x4f/0x60 [ 314.888062] ? mlx5e_alloc_flow.isra.0+0x18c/0x1c0 [mlx5_core] [ 314.888207] __mlx5e_add_fdb_flow+0x2d7/0x440 [mlx5_core] [ 314.888359] ? mlx5e_tc_update_neigh_used_value+0x6f0/0x6f0 [mlx5_core] [ 314.888374] ? match_held_lock+0x2e/0x240 [ 314.888537] mlx5e_configure_flower+0x830/0x16a0 [mlx5_core] [ 314.888702] ? __mlx5e_add_fdb_flow+0x440/0x440 [mlx5_core] [ 314.888713] ? down_read+0x118/0x2c0 [ 314.888728] ? down_read_killable+0x300/0x300 [ 314.888882] ? mlx5e_rep_get_ethtool_stats+0x180/0x180 [mlx5_core] [ 314.888899] tc_setup_cb_add+0x127/0x270 [ 314.888937] fl_hw_replace_filter+0x2ac/0x380 [cls_flower] [ 314.888976] ? fl_hw_destroy_filter+0x1b0/0x1b0 [cls_flower] [ 314.888990] ? fl_change+0xbcf/0x27ef [cls_flower] [ 314.889030] ? fl_change+0xa57/0x27ef [cls_flower] [ 314.889069] fl_change+0x16bd/0x27ef [cls_flower] [ 314.889135] ? __rhashtable_insert_fast.constprop.0+0xa00/0xa00 [cls_flower] [ 314.889167] ? __radix_tree_lookup+0xa4/0x130 [ 314.889200] ? fl_get+0x169/0x240 [cls_flower] [ 314.889218] ? fl_walk+0x230/0x230 [cls_flower] [ 314.889249] tc_new_tfilter+0x5e1/0xd40 [ 314.889281] ? __rhashtable_insert_fast.constprop.0+0xa00/0xa00 [cls_flower] [ 314.889309] ? tc_del_tfilter+0xa30/0xa30 [ 314.889335] ? __lock_acquire+0x5b5/0x2460 [ 314.889378] ? find_held_lock+0x85/0xa0 [ 314.889442] ? tc_del_tfilter+0xa30/0xa30 [ 314.889465] rtnetlink_rcv_msg+0x4ab/0x5f0 [ 314.889488] ? rtnl_dellink+0x490/0x490 [ 314.889518] ? lockdep_hardirqs_on+0x260/0x260 [ 314.889538] ? netlink_deliver_tap+0xab/0x5a0 [ 314.889550] ? match_held_lock+0x1b/0x240 [ 314.889575] netlink_rcv_skb+0xd0/0x200 [ 314.889588] ? rtnl_dellink+0x490/0x490 [ 314.889605] ? netlink_ack+0x440/0x440 [ 314.889635] ? netlink_deliver_tap+0x161/0x5a0 [ 314.889648] ? lock_downgrade+0x360/0x360 [ 314.889657] ? lock_acquire+0xe5/0x210 [ 314.889686] netlink_unicast+0x296/0x350 [ 314.889707] ? netlink_attachskb+0x390/0x390 [ 314.889726] ? _copy_from_iter_full+0xe0/0x3a0 [ 314.889738] ? __virt_addr_valid+0xbb/0x130 [ 314.889771] netlink_sendmsg+0x394/0x600 [ 314.889800] ? netlink_unicast+0x350/0x350 [ 314.889817] ? move_addr_to_kernel.part.0+0x90/0x90 [ 314.889852] ? netlink_unicast+0x350/0x350 [ 314.889872] sock_sendmsg+0x96/0xa0 [ 314.889891] ___sys_sendmsg+0x482/0x520 [ 314.889919] ? copy_msghdr_from_user+0x250/0x250 [ 314.889930] ? __fput+0x1fa/0x390 [ 314.889941] ? task_work_run+0xb7/0xf0 [ 314.889957] ? exit_to_usermode_loop+0x117/0x120 [ 314.889972] ? entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 314.889982] ? do_syscall_64+0x74/0xe0 [ 314.889992] ? entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 314.890012] ? mark_lock+0xac/0x9a0 [ 314.890028] ? __lock_acquire+0x5b5/0x2460 [ 314.890053] ? mark_lock+0xac/0x9a0 [ 314.890083] ? __lock_acquire+0x5b5/0x2460 [ 314.890112] ? match_held_lock+0x1b/0x240 [ 314.890144] ? __fget_light+0xa1/0xf0 [ 314.890166] ? sockfd_lookup_light+0x91/0xb0 [ 314.890187] __sys_sendmsg+0xba/0x130 [ 314.890201] ? __sys_sendmsg_sock+0xb0/0xb0 [ 314.890225] ? __blkcg_punt_bio_submit+0xd0/0xd0 [ 314.890264] ? lockdep_hardirqs_off+0xbe/0x100 [ 314.890274] ? mark_held_locks+0x24/0x90 [ 314.890286] ? do_syscall_64+0x1e/0xe0 [ 314.890308] do_syscall_64+0x74/0xe0 [ 314.890325] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 314.890336] RIP: 0033:0x7f00ca33d7b8 [ 314.890348] Code: 89 02 48 c7 c0 ff ff ff ff eb bb 0f 1f 80 00 00 00 00 f3 0f 1e fa 48 8d 05 65 8f 0c 00 8b 00 85 c0 75 17 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 48 83 ec 28 89 5 4 [ 314.890356] RSP: 002b:00007ffea2983928 EFLAGS: 00000246 ORIG_RAX: 000000000000002e [ 314.890369] RAX: ffffffffffffffda RBX: 000000005d777d5b RCX: 00007f00ca33d7b8 [ 314.890377] RDX: 0000000000000000 RSI: 00007ffea2983990 RDI: 0000000000000003 [ 314.890384] RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000006 [ 314.890392] R10: 0000000000404eda R11: 0000000000000246 R12: 0000000000000001 [ 314.890400] R13: 000000000047f640 R14: 00007ffea2987b58 R15: 0000000000000021 [ 314.890529] Allocated by task 2687: [ 314.890684] save_stack+0x1b/0x80 [ 314.890694] __kasan_kmalloc.constprop.0+0xc2/0xd0 [ 314.890705] __kmalloc_track_caller+0x102/0x340 [ 314.890721] kmemdup+0x1d/0x40 [ 314.890730] tc_setup_flow_action+0x731/0x2c27 [ 314.890743] fl_hw_replace_filter+0x23b/0x380 [cls_flower] [ 314.890756] fl_change+0x16bd/0x27ef [cls_flower] [ 314.890765] tc_new_tfilter+0x5e1/0xd40 [ 314.890776] rtnetlink_rcv_msg+0x4ab/0x5f0 [ 314.890786] netlink_rcv_skb+0xd0/0x200 [ 314.890796] netlink_unicast+0x296/0x350 [ 314.890805] netlink_sendmsg+0x394/0x600 [ 314.890815] sock_sendmsg+0x96/0xa0 [ 314.890825] ___sys_sendmsg+0x482/0x520 [ 314.890834] __sys_sendmsg+0xba/0x130 [ 314.890844] do_syscall_64+0x74/0xe0 [ 314.890854] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 314.890937] Freed by task 2687: [ 314.891076] save_stack+0x1b/0x80 [ 314.891086] __kasan_slab_free+0x12c/0x170 [ 314.891095] kfree+0xeb/0x2f0 [ 314.891106] tc_cleanup_flow_action+0x69/0xa0 [ 314.891119] fl_hw_replace_filter+0x2c5/0x380 [cls_flower] [ 314.891132] fl_change+0x16bd/0x27ef [cls_flower] [ 314.891140] tc_new_tfilter+0x5e1/0xd40 [ 314.891151] rtnetlink_rcv_msg+0x4ab/0x5f0 [ 314.891161] netlink_rcv_skb+0xd0/0x200 [ 314.891170] netlink_unicast+0x296/0x350 [ 314.891180] netlink_sendmsg+0x394/0x600 [ 314.891190] sock_sendmsg+0x96/0xa0 [ 314.891200] ___sys_sendmsg+0x482/0x520 [ 314.891208] __sys_sendmsg+0xba/0x130 [ 314.891218] do_syscall_64+0x74/0xe0 [ 314.891228] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 314.891315] The buggy address belongs to the object at ffff88886c746280 which belongs to the cache kmalloc-96 of size 96 [ 314.891762] The buggy address is located 0 bytes inside of 96-byte region [ffff88886c746280, ffff88886c7462e0) [ 314.892196] The buggy address belongs to the page: [ 314.892387] page:ffffea0021b1d180 refcount:1 mapcount:0 mapping:ffff88835d00ef80 index:0x0 [ 314.892398] flags: 0x57ffffc0000200(slab) [ 314.892413] raw: 0057ffffc0000200 ffffea00219e0340 0000000800000008 ffff88835d00ef80 [ 314.892423] raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000 [ 314.892430] page dumped because: kasan: bad access detected [ 314.892515] Memory state around the buggy address: [ 314.892707] ffff88886c746180: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc [ 314.892976] ffff88886c746200: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc [ 314.893251] >ffff88886c746280: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc [ 314.893522] ^ [ 314.893657] ffff88886c746300: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc [ 314.893924] ffff88886c746380: 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc [ 314.894189] ================================================================== Fix the issue by duplicating tunnel info into per-encap copy that is deallocated with encap structure. Also, duplicate tunnel info in flow parse attribute to support cases when flow might be attached asynchronously. Fixes: 1f6da30697d0 ("net/mlx5e: Geneve, Keep tunnel info as pointer to the original struct") Signed-off-by: Vlad Buslov Reviewed-by: Yevgeny Kliteynik Reviewed-by: Roi Dayan Signed-off-by: Saeed Mahameed --- .../net/ethernet/mellanox/mlx5/core/en_tc.c | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index c4c59d2e676e..fda0b37075e8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -1278,8 +1278,10 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, mlx5_eswitch_del_vlan_action(esw, attr); for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) - if (attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP) + if (attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP) { mlx5e_detach_encap(priv, flow, out_index); + kfree(attr->parse_attr->tun_info[out_index]); + } kvfree(attr->parse_attr); if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) @@ -1559,6 +1561,7 @@ static void mlx5e_encap_dealloc(struct mlx5e_priv *priv, struct mlx5e_encap_entr mlx5_packet_reformat_dealloc(priv->mdev, e->pkt_reformat); } + kfree(e->tun_info); kfree(e->encap_header); kfree_rcu(e, rcu); } @@ -2972,6 +2975,13 @@ mlx5e_encap_get(struct mlx5e_priv *priv, struct encap_key *key, return NULL; } +static struct ip_tunnel_info *dup_tun_info(const struct ip_tunnel_info *tun_info) +{ + size_t tun_size = sizeof(*tun_info) + tun_info->options_len; + + return kmemdup(tun_info, tun_size, GFP_KERNEL); +} + static int mlx5e_attach_encap(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow, struct net_device *mirred_dev, @@ -3028,13 +3038,15 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, refcount_set(&e->refcnt, 1); init_completion(&e->res_ready); + tun_info = dup_tun_info(tun_info); + if (!tun_info) { + err = -ENOMEM; + goto out_err_init; + } e->tun_info = tun_info; err = mlx5e_tc_tun_init_encap_attr(mirred_dev, priv, e, extack); - if (err) { - kfree(e); - e = NULL; - goto out_err; - } + if (err) + goto out_err_init; INIT_LIST_HEAD(&e->flows); hash_add_rcu(esw->offloads.encap_tbl, &e->encap_hlist, hash_key); @@ -3075,6 +3087,12 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, if (e) mlx5e_encap_put(priv, e); return err; + +out_err_init: + mutex_unlock(&esw->offloads.encap_tbl_lock); + kfree(tun_info); + kfree(e); + return err; } static int parse_tc_vlan_action(struct mlx5e_priv *priv, @@ -3295,7 +3313,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, } else if (encap) { parse_attr->mirred_ifindex[attr->out_count] = out_dev->ifindex; - parse_attr->tun_info[attr->out_count] = info; + parse_attr->tun_info[attr->out_count] = dup_tun_info(info); + if (!parse_attr->tun_info[attr->out_count]) + return -ENOMEM; encap = false; attr->dests[attr->out_count].flags |= MLX5_ESW_DEST_ENCAP; -- GitLab From 9df86bdb6746d7fcfc2fda715f7a7c3d0ddb2654 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Mon, 16 Sep 2019 14:54:20 +0300 Subject: [PATCH 862/993] net/mlx5e: Fix handling of compressed CQEs in case of low NAPI budget When CQE compression is enabled, compressed CQEs use the following structure: a title is followed by one or many blocks, each containing 8 mini CQEs (except the last, which may contain fewer mini CQEs). Due to NAPI budget restriction, a complete structure is not always parsed in one NAPI run, and some blocks with mini CQEs may be deferred to the next NAPI poll call - we have the mlx5e_decompress_cqes_cont call in the beginning of mlx5e_poll_rx_cq. However, if the budget is extremely low, some blocks may be left even after that, but the code that follows the mlx5e_decompress_cqes_cont call doesn't check it and assumes that a new CQE begins, which may not be the case. In such cases, random memory corruptions occur. An extremely low NAPI budget of 8 is used when busy_poll or busy_read is active. This commit adds a check to make sure that the previous compressed CQE has been completely parsed after mlx5e_decompress_cqes_cont, otherwise it prevents a new CQE from being fetched in the middle of a compressed CQE. This commit fixes random crashes in __build_skb, __page_pool_put_page and other not-related-directly places, that used to happen when both CQE compression and busy_poll/busy_read were enabled. Fixes: 7219ab34f184 ("net/mlx5e: CQE compression") Signed-off-by: Maxim Mikityanskiy Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index d6a547238de0..82cffb3a9964 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c @@ -1386,8 +1386,11 @@ int mlx5e_poll_rx_cq(struct mlx5e_cq *cq, int budget) if (unlikely(!test_bit(MLX5E_RQ_STATE_ENABLED, &rq->state))) return 0; - if (rq->cqd.left) + if (rq->cqd.left) { work_done += mlx5e_decompress_cqes_cont(rq, cqwq, 0, budget); + if (rq->cqd.left || work_done >= budget) + goto out; + } cqe = mlx5_cqwq_get_cqe(cqwq); if (!cqe) { -- GitLab From 534e7366f41b0c689b01af4375aefcd1462adedf Mon Sep 17 00:00:00 2001 From: Aya Levin Date: Wed, 2 Oct 2019 16:53:21 +0300 Subject: [PATCH 863/993] net/mlx5e: Fix ethtool self test: link speed Ethtool self test contains a test for link speed. This test reads the PTYS register and determines whether the current speed is valid or not. Change current implementation to use the function mlx5e_port_linkspeed() that does the same check and fails when speed is invalid. This code redundancy lead to a bug when mlx5e_port_linkspeed() was updated with expended speeds and the self test was not. Fixes: 2c81bfd5ae56 ("net/mlx5e: Move port speed code from en_ethtool.c to en/port.c") Signed-off-by: Aya Levin Reviewed-by: Moshe Shemesh Signed-off-by: Saeed Mahameed --- .../net/ethernet/mellanox/mlx5/core/en_selftest.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c index 840ec945ccba..bbff8d8ded76 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c @@ -35,6 +35,7 @@ #include #include #include "en.h" +#include "en/port.h" enum { MLX5E_ST_LINK_STATE, @@ -80,22 +81,12 @@ static int mlx5e_test_link_state(struct mlx5e_priv *priv) static int mlx5e_test_link_speed(struct mlx5e_priv *priv) { - u32 out[MLX5_ST_SZ_DW(ptys_reg)]; - u32 eth_proto_oper; - int i; + u32 speed; if (!netif_carrier_ok(priv->netdev)) return 1; - if (mlx5_query_port_ptys(priv->mdev, out, sizeof(out), MLX5_PTYS_EN, 1)) - return 1; - - eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper); - for (i = 0; i < MLX5E_LINK_MODES_NUMBER; i++) { - if (eth_proto_oper & MLX5E_PROT_MASK(i)) - return 0; - } - return 1; + return mlx5e_port_linkspeed(priv->mdev, &speed); } struct mlx5ehdr { -- GitLab From 926b37f76fb0a22fe93c8873c819fd167180e85c Mon Sep 17 00:00:00 2001 From: Aya Levin Date: Wed, 23 Oct 2019 12:57:54 +0300 Subject: [PATCH 864/993] net/mlx5e: Initialize on stack link modes bitmap Initialize link modes bitmap on stack before using it, otherwise the outcome of ethtool set link ksettings might have unexpected values. Fixes: 4b95840a6ced ("net/mlx5e: Fix matching of speed to PRM link modes") Signed-off-by: Aya Levin Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index c5a9c20d7f00..327c93a7bd55 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c @@ -1021,7 +1021,7 @@ static bool ext_link_mode_requested(const unsigned long *adver) { #define MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT ETHTOOL_LINK_MODE_50000baseKR_Full_BIT int size = __ETHTOOL_LINK_MODE_MASK_NBITS - MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT; - __ETHTOOL_DECLARE_LINK_MODE_MASK(modes); + __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = {0,}; bitmap_set(modes, MLX5E_MIN_PTYS_EXT_LINK_MODE_BIT, size); return bitmap_intersects(modes, adver, __ETHTOOL_LINK_MODE_MASK_NBITS); -- GitLab From e19868efea0c103f23b4b7e986fd0a703822111f Mon Sep 17 00:00:00 2001 From: Eran Ben Elisha Date: Sun, 27 Oct 2019 16:39:15 +0200 Subject: [PATCH 865/993] net/mlx4_core: Dynamically set guaranteed amount of counters per VF Prior to this patch, the amount of counters guaranteed per VF in the resource tracker was MLX4_VF_COUNTERS_PER_PORT * MLX4_MAX_PORTS. It was set regardless if the VF was single or dual port. This caused several VFs to have no guaranteed counters although the system could satisfy their request. The fix is to dynamically guarantee counters, based on each VF specification. Fixes: 9de92c60beaa ("net/mlx4_core: Adjust counter grant policy in the resource tracker") Signed-off-by: Eran Ben Elisha Signed-off-by: Jack Morgenstein Signed-off-by: Tariq Toukan Signed-off-by: David S. Miller --- .../ethernet/mellanox/mlx4/resource_tracker.c | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 4356f3a58002..1187ef1375e2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -471,12 +471,31 @@ void mlx4_init_quotas(struct mlx4_dev *dev) priv->mfunc.master.res_tracker.res_alloc[RES_MPT].quota[pf]; } -static int get_max_gauranteed_vfs_counter(struct mlx4_dev *dev) +static int +mlx4_calc_res_counter_guaranteed(struct mlx4_dev *dev, + struct resource_allocator *res_alloc, + int vf) { - /* reduce the sink counter */ - return (dev->caps.max_counters - 1 - - (MLX4_PF_COUNTERS_PER_PORT * MLX4_MAX_PORTS)) - / MLX4_MAX_PORTS; + struct mlx4_active_ports actv_ports; + int ports, counters_guaranteed; + + /* For master, only allocate according to the number of phys ports */ + if (vf == mlx4_master_func_num(dev)) + return MLX4_PF_COUNTERS_PER_PORT * dev->caps.num_ports; + + /* calculate real number of ports for the VF */ + actv_ports = mlx4_get_active_ports(dev, vf); + ports = bitmap_weight(actv_ports.ports, dev->caps.num_ports); + counters_guaranteed = ports * MLX4_VF_COUNTERS_PER_PORT; + + /* If we do not have enough counters for this VF, do not + * allocate any for it. '-1' to reduce the sink counter. + */ + if ((res_alloc->res_reserved + counters_guaranteed) > + (dev->caps.max_counters - 1)) + return 0; + + return counters_guaranteed; } int mlx4_init_resource_tracker(struct mlx4_dev *dev) @@ -484,7 +503,6 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev) struct mlx4_priv *priv = mlx4_priv(dev); int i, j; int t; - int max_vfs_guarantee_counter = get_max_gauranteed_vfs_counter(dev); priv->mfunc.master.res_tracker.slave_list = kcalloc(dev->num_slaves, sizeof(struct slave_list), @@ -603,16 +621,8 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev) break; case RES_COUNTER: res_alloc->quota[t] = dev->caps.max_counters; - if (t == mlx4_master_func_num(dev)) - res_alloc->guaranteed[t] = - MLX4_PF_COUNTERS_PER_PORT * - MLX4_MAX_PORTS; - else if (t <= max_vfs_guarantee_counter) - res_alloc->guaranteed[t] = - MLX4_VF_COUNTERS_PER_PORT * - MLX4_MAX_PORTS; - else - res_alloc->guaranteed[t] = 0; + res_alloc->guaranteed[t] = + mlx4_calc_res_counter_guaranteed(dev, res_alloc, t); break; default: break; -- GitLab From e56bd641ca61beb92b135298d5046905f920b734 Mon Sep 17 00:00:00 2001 From: Jiangfeng Xiao Date: Mon, 28 Oct 2019 13:09:46 +0800 Subject: [PATCH 866/993] net: hisilicon: Fix ping latency when deal with high throughput This is due to error in over budget processing. When dealing with high throughput, the used buffers that exceeds the budget is not cleaned up. In addition, it takes a lot of cycles to clean up the used buffer, and then the buffer where the valid data is located can take effect. Signed-off-by: Jiangfeng Xiao Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hip04_eth.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hip04_eth.c b/drivers/net/ethernet/hisilicon/hip04_eth.c index ad6d91219daf..4606a7e4a6d1 100644 --- a/drivers/net/ethernet/hisilicon/hip04_eth.c +++ b/drivers/net/ethernet/hisilicon/hip04_eth.c @@ -237,6 +237,7 @@ struct hip04_priv { dma_addr_t rx_phys[RX_DESC_NUM]; unsigned int rx_head; unsigned int rx_buf_size; + unsigned int rx_cnt_remaining; struct device_node *phy_node; struct phy_device *phy; @@ -575,7 +576,6 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget) struct hip04_priv *priv = container_of(napi, struct hip04_priv, napi); struct net_device *ndev = priv->ndev; struct net_device_stats *stats = &ndev->stats; - unsigned int cnt = hip04_recv_cnt(priv); struct rx_desc *desc; struct sk_buff *skb; unsigned char *buf; @@ -588,8 +588,8 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget) /* clean up tx descriptors */ tx_remaining = hip04_tx_reclaim(ndev, false); - - while (cnt && !last) { + priv->rx_cnt_remaining += hip04_recv_cnt(priv); + while (priv->rx_cnt_remaining && !last) { buf = priv->rx_buf[priv->rx_head]; skb = build_skb(buf, priv->rx_buf_size); if (unlikely(!skb)) { @@ -635,11 +635,13 @@ static int hip04_rx_poll(struct napi_struct *napi, int budget) hip04_set_recv_desc(priv, phys); priv->rx_head = RX_NEXT(priv->rx_head); - if (rx >= budget) + if (rx >= budget) { + --priv->rx_cnt_remaining; goto done; + } - if (--cnt == 0) - cnt = hip04_recv_cnt(priv); + if (--priv->rx_cnt_remaining == 0) + priv->rx_cnt_remaining += hip04_recv_cnt(priv); } if (!(priv->reg_inten & RCV_INT)) { @@ -724,6 +726,7 @@ static int hip04_mac_open(struct net_device *ndev) int i; priv->rx_head = 0; + priv->rx_cnt_remaining = 0; priv->tx_head = 0; priv->tx_tail = 0; hip04_reset_ppe(priv); -- GitLab From 2eb8d6d2910cfe3dc67dc056f26f3dd9c63d47cd Mon Sep 17 00:00:00 2001 From: Xin Long Date: Mon, 28 Oct 2019 23:19:35 +0800 Subject: [PATCH 867/993] erspan: fix the tun_info options_len check for erspan The check for !md doens't really work for ip_tunnel_info_opts(info) which only does info + 1. Also to avoid out-of-bounds access on info, it should ensure options_len is not less than erspan_metadata in both erspan_xmit() and ip6erspan_tunnel_xmit(). Fixes: 1a66a836da ("gre: add collect_md mode to ERSPAN tunnel") Signed-off-by: Xin Long Signed-off-by: David S. Miller --- net/ipv4/ip_gre.c | 4 ++-- net/ipv6/ip6_gre.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 52690bb3e40f..10636fb6093e 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -509,9 +509,9 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev) key = &tun_info->key; if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT)) goto err_free_skb; - md = ip_tunnel_info_opts(tun_info); - if (!md) + if (tun_info->options_len < sizeof(*md)) goto err_free_skb; + md = ip_tunnel_info_opts(tun_info); /* ERSPAN has fixed 8 byte GRE header */ version = md->version; diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 787d9f2a6e99..923034c52ce4 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -980,9 +980,9 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, dsfield = key->tos; if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT)) goto tx_err; - md = ip_tunnel_info_opts(tun_info); - if (!md) + if (tun_info->options_len < sizeof(*md)) goto tx_err; + md = ip_tunnel_info_opts(tun_info); tun_id = tunnel_id_to_key32(key->tun_id); if (md->version == 1) { -- GitLab From eadf52cf1852196a1363044dcda22fa5d7f296f7 Mon Sep 17 00:00:00 2001 From: Xin Long Date: Tue, 29 Oct 2019 01:24:32 +0800 Subject: [PATCH 868/993] vxlan: check tun_info options_len properly This patch is to improve the tun_info options_len by dropping the skb when TUNNEL_VXLAN_OPT is set but options_len is less than vxlan_metadata. This can void a potential out-of-bounds access on ip_tun_info. Fixes: ee122c79d422 ("vxlan: Flow based tunneling") Signed-off-by: Xin Long Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index fcf028220bca..ac5c597aa703 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2487,9 +2487,11 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, vni = tunnel_id_to_key32(info->key.tun_id); ifindex = 0; dst_cache = &info->dst_cache; - if (info->options_len && - info->key.tun_flags & TUNNEL_VXLAN_OPT) + if (info->key.tun_flags & TUNNEL_VXLAN_OPT) { + if (info->options_len < sizeof(*md)) + goto drop; md = ip_tunnel_info_opts(info); + } ttl = info->key.ttl; tos = info->key.tos; label = info->key.label; -- GitLab From f9f2933842ecd11e9df4b99d96540ee128266402 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Mon, 28 Oct 2019 15:11:31 -0700 Subject: [PATCH 869/993] MAINTAINERS: remove Dave Watson as TLS maintainer Dave's Facebook email address is not working, and my attempts to contact him are failing. Let's remove it to trim down the list of TLS maintainers. Signed-off-by: Jakub Kicinski Reviewed-by: Simon Horman Signed-off-by: David S. Miller --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index e51a68bf8ca8..b6b6c75f7e6f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11407,7 +11407,6 @@ F: include/trace/events/tcp.h NETWORKING [TLS] M: Boris Pismenny M: Aviad Yehezkel -M: Dave Watson M: John Fastabend M: Daniel Borkmann M: Jakub Kicinski -- GitLab From 3b56be218f65e26bb651095d7a5b107f67a6c5c2 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Tue, 29 Oct 2019 09:53:18 +0800 Subject: [PATCH 870/993] net: fec_main: Use platform_get_irq_byname_optional() to avoid error message Failed to get irq using name is NOT fatal as driver will use index to get irq instead, use platform_get_irq_byname_optional() instead of platform_get_irq_byname() to avoid below error message during probe: [ 0.819312] fec 30be0000.ethernet: IRQ int0 not found [ 0.824433] fec 30be0000.ethernet: IRQ int1 not found [ 0.829539] fec 30be0000.ethernet: IRQ int2 not found Signed-off-by: Anson Huang Acked-by: Fugang Duan Reviewed-by: Stephen Boyd Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index d4d4c72adf49..22c01b224baa 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3558,7 +3558,7 @@ fec_probe(struct platform_device *pdev) for (i = 0; i < irq_cnt; i++) { snprintf(irq_name, sizeof(irq_name), "int%d", i); - irq = platform_get_irq_byname(pdev, irq_name); + irq = platform_get_irq_byname_optional(pdev, irq_name); if (irq < 0) irq = platform_get_irq(pdev, i); if (irq < 0) { -- GitLab From b86bcb299092c1d5cd30f6188d58f73526ec9ada Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Tue, 29 Oct 2019 09:53:19 +0800 Subject: [PATCH 871/993] net: fec_ptp: Use platform_get_irq_xxx_optional() to avoid error message Use platform_get_irq_byname_optional() and platform_get_irq_optional() instead of platform_get_irq_byname() and platform_get_irq() for optional IRQs to avoid below error message during probe: [ 0.795803] fec 30be0000.ethernet: IRQ pps not found [ 0.800787] fec 30be0000.ethernet: IRQ index 3 not found Signed-off-by: Anson Huang Acked-by: Fugang Duan Reviewed-by: Stephen Boyd Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec_ptp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 19e2365be7d8..945643c02615 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -600,9 +600,9 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx) INIT_DELAYED_WORK(&fep->time_keep, fec_time_keep); - irq = platform_get_irq_byname(pdev, "pps"); + irq = platform_get_irq_byname_optional(pdev, "pps"); if (irq < 0) - irq = platform_get_irq(pdev, irq_idx); + irq = platform_get_irq_optional(pdev, irq_idx); /* Failure to get an irq is not fatal, * only the PTP_CLOCK_PPS clock events should stop */ -- GitLab From ad9bd8daf2f9938572b0604e1280fefa8f338581 Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Tue, 29 Oct 2019 09:12:32 +0000 Subject: [PATCH 872/993] bonding: fix using uninitialized mode_lock When a bonding interface is being created, it setups its mode and options. At that moment, it uses mode_lock so mode_lock should be initialized before that moment. rtnl_newlink() rtnl_create_link() alloc_netdev_mqs() ->setup() //bond_setup() ->newlink //bond_newlink bond_changelink() register_netdevice() ->ndo_init() //bond_init() After commit 089bca2caed0 ("bonding: use dynamic lockdep key instead of subclass"), mode_lock is initialized in bond_init(). So in the bond_changelink(), un-initialized mode_lock can be used. mode_lock should be initialized in bond_setup(). This patch partially reverts commit 089bca2caed0 ("bonding: use dynamic lockdep key instead of subclass") Test command: ip link add bond0 type bond mode 802.3ad lacp_rate 0 Splat looks like: [ 60.615127] INFO: trying to register non-static key. [ 60.615900] the code is fine but needs lockdep annotation. [ 60.616697] turning off the locking correctness validator. [ 60.617490] CPU: 1 PID: 957 Comm: ip Not tainted 5.4.0-rc3+ #109 [ 60.618350] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 60.619481] Call Trace: [ 60.619918] dump_stack+0x7c/0xbb [ 60.620453] register_lock_class+0x1215/0x14d0 [ 60.621131] ? alloc_netdev_mqs+0x7b3/0xcc0 [ 60.621771] ? is_bpf_text_address+0x86/0xf0 [ 60.622416] ? is_dynamic_key+0x230/0x230 [ 60.623032] ? unwind_get_return_address+0x5f/0xa0 [ 60.623757] ? create_prof_cpu_mask+0x20/0x20 [ 60.624408] ? arch_stack_walk+0x83/0xb0 [ 60.625023] __lock_acquire+0xd8/0x3de0 [ 60.625616] ? stack_trace_save+0x82/0xb0 [ 60.626225] ? stack_trace_consume_entry+0x160/0x160 [ 60.626957] ? deactivate_slab.isra.80+0x2c5/0x800 [ 60.627668] ? register_lock_class+0x14d0/0x14d0 [ 60.628380] ? alloc_netdev_mqs+0x7b3/0xcc0 [ 60.629020] ? save_stack+0x69/0x80 [ 60.629574] ? save_stack+0x19/0x80 [ 60.630121] ? __kasan_kmalloc.constprop.4+0xa0/0xd0 [ 60.630859] ? __kmalloc_node+0x16f/0x480 [ 60.631472] ? alloc_netdev_mqs+0x7b3/0xcc0 [ 60.632121] ? rtnl_create_link+0x2ed/0xad0 [ 60.634388] ? __rtnl_newlink+0xad4/0x11b0 [ 60.635024] lock_acquire+0x164/0x3b0 [ 60.635608] ? bond_3ad_update_lacp_rate+0x91/0x200 [bonding] [ 60.636463] _raw_spin_lock_bh+0x38/0x70 [ 60.637084] ? bond_3ad_update_lacp_rate+0x91/0x200 [bonding] [ 60.637930] bond_3ad_update_lacp_rate+0x91/0x200 [bonding] [ 60.638753] ? bond_3ad_lacpdu_recv+0xb30/0xb30 [bonding] [ 60.639552] ? bond_opt_get_val+0x180/0x180 [bonding] [ 60.640307] ? ___slab_alloc+0x5aa/0x610 [ 60.640925] bond_option_lacp_rate_set+0x71/0x140 [bonding] [ 60.641751] __bond_opt_set+0x1ff/0xbb0 [bonding] [ 60.643217] ? kasan_unpoison_shadow+0x30/0x40 [ 60.643924] bond_changelink+0x9a4/0x1700 [bonding] [ 60.644653] ? memset+0x1f/0x40 [ 60.742941] ? bond_slave_changelink+0x1a0/0x1a0 [bonding] [ 60.752694] ? alloc_netdev_mqs+0x8ea/0xcc0 [ 60.753330] ? rtnl_create_link+0x2ed/0xad0 [ 60.753964] bond_newlink+0x1e/0x60 [bonding] [ 60.754612] __rtnl_newlink+0xb9f/0x11b0 [ ... ] Reported-by: syzbot+8da67f407bcba2c72e6e@syzkaller.appspotmail.com Reported-by: syzbot+0d083911ab18b710da71@syzkaller.appspotmail.com Fixes: 089bca2caed0 ("bonding: use dynamic lockdep key instead of subclass") Signed-off-by: Taehee Yoo Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index a48950b81434..480f9459b402 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4284,6 +4284,7 @@ void bond_setup(struct net_device *bond_dev) { struct bonding *bond = netdev_priv(bond_dev); + spin_lock_init(&bond->mode_lock); bond->params = bonding_defaults; /* Initialize pointers */ @@ -4756,7 +4757,6 @@ static int bond_init(struct net_device *bond_dev) if (!bond->wq) return -ENOMEM; - spin_lock_init(&bond->mode_lock); spin_lock_init(&bond->stats_lock); lockdep_register_key(&bond->stats_lock_key); lockdep_set_class(&bond->stats_lock, &bond->stats_lock_key); -- GitLab From 301428ea3708188dc4a243e6e6b46c03b46a0fbc Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Tue, 29 Oct 2019 12:41:26 +0100 Subject: [PATCH 873/993] net/smc: fix refcounting for non-blocking connect() If a nonblocking socket is immediately closed after connect(), the connect worker may not have started. This results in a refcount problem, since sock_hold() is called from the connect worker. This patch moves the sock_hold in front of the connect worker scheduling. Reported-by: syzbot+4c063e6dea39e4b79f29@syzkaller.appspotmail.com Fixes: 50717a37db03 ("net/smc: nonblocking connect rework") Reviewed-by: Karsten Graul Signed-off-by: Ursula Braun Signed-off-by: David S. Miller --- net/smc/af_smc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index cea3c36ea0da..47946f489fd4 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -707,8 +707,6 @@ static int __smc_connect(struct smc_sock *smc) int smc_type; int rc = 0; - sock_hold(&smc->sk); /* sock put in passive closing */ - if (smc->use_fallback) return smc_connect_fallback(smc, smc->fallback_rsn); @@ -853,6 +851,8 @@ static int smc_connect(struct socket *sock, struct sockaddr *addr, rc = kernel_connect(smc->clcsock, addr, alen, flags); if (rc && rc != -EINPROGRESS) goto out; + + sock_hold(&smc->sk); /* sock put in passive closing */ if (flags & O_NONBLOCK) { if (schedule_work(&smc->connect_work)) smc->connect_nonblock = 1; -- GitLab From 8b73018fe44521c1cf59d7bac53624c87d3f10e2 Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Tue, 29 Oct 2019 13:59:32 +0200 Subject: [PATCH 874/993] net: rtnetlink: fix a typo fbd -> fdb A simple typo fix in the nl error message (fbd -> fdb). CC: David Ahern Fixes: 8c6e137fbc7f ("rtnetlink: Update rtnl_fdb_dump for strict data checking") Signed-off-by: Nikolay Aleksandrov Reviewed-by: David Ahern Signed-off-by: David S. Miller --- net/core/rtnetlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index ba4b4048ec3e..c81cd80114d9 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -3917,7 +3917,7 @@ static int valid_fdb_dump_strict(const struct nlmsghdr *nlh, ndm = nlmsg_data(nlh); if (ndm->ndm_pad1 || ndm->ndm_pad2 || ndm->ndm_state || ndm->ndm_flags || ndm->ndm_type) { - NL_SET_ERR_MSG(extack, "Invalid values in header for fbd dump request"); + NL_SET_ERR_MSG(extack, "Invalid values in header for fdb dump request"); return -EINVAL; } -- GitLab From 59cd826fb5e7889515bf5771e295e0624c348571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 22 Oct 2019 21:56:43 +0300 Subject: [PATCH 875/993] drm/i915: Fix PCH reference clock for FDI on HSW/BDW MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The change to skip the PCH reference initialization during fastboot did end up breaking FDI. To fix that let's try to do the PCH reference init whenever we're disabling a DPLL that was using said reference previously. Cc: stable@vger.kernel.org Tested-by: Andrija Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=112084 Fixes: b16c7ed95caf ("drm/i915: Do not touch the PCH SSC reference if a PLL is using it") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20191022185643.1483-1-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak (cherry picked from commit dd5279c71405533d4ddbb9453effc60f0f5bf211) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/intel_display.c | 11 ++++++----- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 15 +++++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 2 ++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index aa54bb22796d..dfff6f4357b8 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -9315,7 +9315,6 @@ static bool wrpll_uses_pch_ssc(struct drm_i915_private *dev_priv, static void lpt_init_pch_refclk(struct drm_i915_private *dev_priv) { struct intel_encoder *encoder; - bool pch_ssc_in_use = false; bool has_fdi = false; for_each_intel_encoder(&dev_priv->drm, encoder) { @@ -9343,22 +9342,24 @@ static void lpt_init_pch_refclk(struct drm_i915_private *dev_priv) * clock hierarchy. That would also allow us to do * clock bending finally. */ + dev_priv->pch_ssc_use = 0; + if (spll_uses_pch_ssc(dev_priv)) { DRM_DEBUG_KMS("SPLL using PCH SSC\n"); - pch_ssc_in_use = true; + dev_priv->pch_ssc_use |= BIT(DPLL_ID_SPLL); } if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL1)) { DRM_DEBUG_KMS("WRPLL1 using PCH SSC\n"); - pch_ssc_in_use = true; + dev_priv->pch_ssc_use |= BIT(DPLL_ID_WRPLL1); } if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL2)) { DRM_DEBUG_KMS("WRPLL2 using PCH SSC\n"); - pch_ssc_in_use = true; + dev_priv->pch_ssc_use |= BIT(DPLL_ID_WRPLL2); } - if (pch_ssc_in_use) + if (dev_priv->pch_ssc_use) return; if (has_fdi) { diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index b8148f838354..d5a298c3c83b 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -525,16 +525,31 @@ static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv, val = I915_READ(WRPLL_CTL(id)); I915_WRITE(WRPLL_CTL(id), val & ~WRPLL_PLL_ENABLE); POSTING_READ(WRPLL_CTL(id)); + + /* + * Try to set up the PCH reference clock once all DPLLs + * that depend on it have been shut down. + */ + if (dev_priv->pch_ssc_use & BIT(id)) + intel_init_pch_refclk(dev_priv); } static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv, struct intel_shared_dpll *pll) { + enum intel_dpll_id id = pll->info->id; u32 val; val = I915_READ(SPLL_CTL); I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE); POSTING_READ(SPLL_CTL); + + /* + * Try to set up the PCH reference clock once all DPLLs + * that depend on it have been shut down. + */ + if (dev_priv->pch_ssc_use & BIT(id)) + intel_init_pch_refclk(dev_priv); } static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 772154e4073e..953e1d12c23c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1723,6 +1723,8 @@ struct drm_i915_private { struct work_struct idle_work; } gem; + u8 pch_ssc_use; + /* For i945gm vblank irq vs. C3 workaround */ struct { struct work_struct work; -- GitLab From 1d9b0b66c3ef03e42db63068e1a4e7250992e2b1 Mon Sep 17 00:00:00 2001 From: Palmer Dabbelt Date: Tue, 29 Oct 2019 21:39:16 -0700 Subject: [PATCH 876/993] MAINTAINERS: Change to my personal email address I'm leaving SiFive in a bit less than two weeks, which means I'll be losing my @sifive email address. I don't have my new email address yet, so I'm switching over to my personal address instead. Signed-off-by: Palmer Dabbelt Signed-off-by: Palmer Dabbelt Signed-off-by: Paul Walmsley --- MAINTAINERS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index c6c34d04ce95..f97f35163033 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13906,7 +13906,7 @@ F: drivers/mtd/nand/raw/r852.h RISC-V ARCHITECTURE M: Paul Walmsley -M: Palmer Dabbelt +M: Palmer Dabbelt M: Albert Ou L: linux-riscv@lists.infradead.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux.git @@ -14783,7 +14783,7 @@ F: drivers/media/usb/siano/ F: drivers/media/mmc/siano/ SIFIVE DRIVERS -M: Palmer Dabbelt +M: Palmer Dabbelt M: Paul Walmsley L: linux-riscv@lists.infradead.org T: git git://github.com/sifive/riscv-linux.git @@ -14793,7 +14793,7 @@ N: sifive SIFIVE FU540 SYSTEM-ON-CHIP M: Paul Walmsley -M: Palmer Dabbelt +M: Palmer Dabbelt L: linux-riscv@lists.infradead.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/pjw/sifive.git S: Supported -- GitLab From 1251dab9e0a2c4d0d2d48370ba5baa095a5e8774 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Oct 2019 11:23:53 +0100 Subject: [PATCH 877/993] USB: serial: whiteheat: fix potential slab corruption Fix a user-controlled slab buffer overflow due to a missing sanity check on the bulk-out transfer buffer used for control requests. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20191029102354.2733-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/whiteheat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 79314d8c94a4..76cabcb30d21 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -559,6 +559,10 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command, command_port = port->serial->port[COMMAND_PORT]; command_info = usb_get_serial_port_data(command_port); + + if (command_port->bulk_out_size < datasize + 1) + return -EIO; + mutex_lock(&command_info->mutex); command_info->command_finished = false; -- GitLab From 84968291d7924261c6a0624b9a72f952398e258b Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Oct 2019 11:23:54 +0100 Subject: [PATCH 878/993] USB: serial: whiteheat: fix line-speed endianness Add missing endianness conversion when setting the line speed so that this driver might work also on big-endian machines. Also use an unsigned format specifier in the corresponding debug message. Signed-off-by: Johan Hovold Cc: stable Link: https://lore.kernel.org/r/20191029102354.2733-3-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/whiteheat.c | 9 ++++++--- drivers/usb/serial/whiteheat.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 76cabcb30d21..ca3bd58f2025 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -636,6 +636,7 @@ static void firm_setup_port(struct tty_struct *tty) struct device *dev = &port->dev; struct whiteheat_port_settings port_settings; unsigned int cflag = tty->termios.c_cflag; + speed_t baud; port_settings.port = port->port_number + 1; @@ -696,11 +697,13 @@ static void firm_setup_port(struct tty_struct *tty) dev_dbg(dev, "%s - XON = %2x, XOFF = %2x\n", __func__, port_settings.xon, port_settings.xoff); /* get the baud rate wanted */ - port_settings.baud = tty_get_baud_rate(tty); - dev_dbg(dev, "%s - baud rate = %d\n", __func__, port_settings.baud); + baud = tty_get_baud_rate(tty); + port_settings.baud = cpu_to_le32(baud); + dev_dbg(dev, "%s - baud rate = %u\n", __func__, baud); /* fixme: should set validated settings */ - tty_encode_baud_rate(tty, port_settings.baud, port_settings.baud); + tty_encode_baud_rate(tty, baud, baud); + /* handle any settings that aren't specified in the tty structure */ port_settings.lloop = 0; diff --git a/drivers/usb/serial/whiteheat.h b/drivers/usb/serial/whiteheat.h index 00398149cd8d..269e727a92f9 100644 --- a/drivers/usb/serial/whiteheat.h +++ b/drivers/usb/serial/whiteheat.h @@ -87,7 +87,7 @@ struct whiteheat_simple { struct whiteheat_port_settings { __u8 port; /* port number (1 to N) */ - __u32 baud; /* any value 7 - 460800, firmware calculates + __le32 baud; /* any value 7 - 460800, firmware calculates best fit; arrives little endian */ __u8 bits; /* 5, 6, 7, or 8 */ __u8 stop; /* 1 or 2, default 1 (2 = 1.5 if bits = 5) */ -- GitLab From ec649fed66bb242cca145ab364485c5a126efc53 Mon Sep 17 00:00:00 2001 From: Masashi Honma Date: Mon, 21 Oct 2019 16:50:45 +0900 Subject: [PATCH 879/993] nl80211: Disallow setting of HT for channel 14 This patch disables setting of HT20 and more for channel 14 because the channel is only for IEEE 802.11b. The patch for net/wireless/util.c was unit-tested. The patch for net/wireless/chan.c was tested with iw command. Before this patch. $ sudo iw dev set channel 14 HT20 $ After this patch. $ sudo iw dev set channel 14 HT20 kernel reports: invalid channel definition command failed: Invalid argument (-22) $ Signed-off-by: Masashi Honma Link: https://lore.kernel.org/r/20191021075045.2719-1-masashi.honma@gmail.com [clean up the code, use != instead of equivalent >] Signed-off-by: Johannes Berg --- net/wireless/chan.c | 5 +++++ net/wireless/util.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/net/wireless/chan.c b/net/wireless/chan.c index e851cafd8e2f..fcac5c6366e1 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -204,6 +204,11 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef) return false; } + /* channel 14 is only for IEEE 802.11b */ + if (chandef->center_freq1 == 2484 && + chandef->width != NL80211_CHAN_WIDTH_20_NOHT) + return false; + if (cfg80211_chandef_is_edmg(chandef) && !cfg80211_edmg_chandef_valid(chandef)) return false; diff --git a/net/wireless/util.c b/net/wireless/util.c index 419eb12c1e93..5b4ed5bbc542 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1559,7 +1559,8 @@ bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef, } if (freq == 2484) { - if (chandef->width > NL80211_CHAN_WIDTH_40) + /* channel 14 is only for IEEE 802.11b */ + if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT) return false; *op_class = 82; /* channel 14 */ -- GitLab From 1fab1b89e2e8f01204a9c05a39fd0b6411a48593 Mon Sep 17 00:00:00 2001 From: Markus Theil Date: Tue, 29 Oct 2019 10:30:03 +0100 Subject: [PATCH 880/993] nl80211: fix validation of mesh path nexthop Mesh path nexthop should be a ethernet address, but current validation checks against 4 byte integers. Cc: stable@vger.kernel.org Fixes: 2ec600d672e74 ("nl80211/cfg80211: support for mesh, sta dumping") Signed-off-by: Markus Theil Link: https://lore.kernel.org/r/20191029093003.10355-1-markus.theil@tu-ilmenau.de Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 4453dd375de9..7b72286922f7 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -393,7 +393,7 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ }, [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, .len = IEEE80211_MAX_MESH_ID_LEN }, - [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 }, + [NL80211_ATTR_MPATH_NEXT_HOP] = NLA_POLICY_ETH_ADDR_COMPAT, [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 }, [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED }, -- GitLab From 565d454280f85c0a4f204fb160f3d90f8418c080 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Wed, 23 Oct 2019 21:59:41 +0800 Subject: [PATCH 881/993] iommu/ipmmu-vmsa: Remove dev_err() on platform_get_irq() failure platform_get_irq() will call dev_err() itself on failure, so there is no need for the driver to also do this. This is detected by coccinelle. Signed-off-by: YueHaibing Reviewed-by: Geert Uytterhoeven Signed-off-by: Joerg Roedel --- drivers/iommu/ipmmu-vmsa.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 237103465b82..2639fc718117 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -1105,10 +1105,8 @@ static int ipmmu_probe(struct platform_device *pdev) /* Root devices have mandatory IRQs */ if (ipmmu_is_root(mmu)) { irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "no IRQ found\n"); + if (irq < 0) return irq; - } ret = devm_request_irq(&pdev->dev, irq, ipmmu_irq, 0, dev_name(&pdev->dev), mmu); -- GitLab From ad3e8da2d422c63c13819a53d3c5ea9312cc0b9d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 21 Oct 2019 17:17:21 +0200 Subject: [PATCH 882/993] iommu/amd: Apply the same IVRS IOAPIC workaround to Acer Aspire A315-41 Acer Aspire A315-41 requires the very same workaround as the existing quirk for Dell Latitude 5495. Add the new entry for that. BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1137799 Signed-off-by: Takashi Iwai Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu_quirks.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/iommu/amd_iommu_quirks.c b/drivers/iommu/amd_iommu_quirks.c index c235f79b7a20..5120ce4fdce3 100644 --- a/drivers/iommu/amd_iommu_quirks.c +++ b/drivers/iommu/amd_iommu_quirks.c @@ -73,6 +73,19 @@ static const struct dmi_system_id ivrs_quirks[] __initconst = { }, .driver_data = (void *)&ivrs_ioapic_quirks[DELL_LATITUDE_5495], }, + { + /* + * Acer Aspire A315-41 requires the very same workaround as + * Dell Latitude 5495 + */ + .callback = ivrs_ioapic_quirk_cb, + .ident = "Acer Aspire A315-41", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A315-41"), + }, + .driver_data = (void *)&ivrs_ioapic_quirks[DELL_LATITUDE_5495], + }, { .callback = ivrs_ioapic_quirk_cb, .ident = "Lenovo ideapad 330S-15ARR", -- GitLab From 160c63f909ffbc797c0bbe23310ac1eaf2349d2f Mon Sep 17 00:00:00 2001 From: John Donnelly Date: Mon, 21 Oct 2019 21:48:10 -0500 Subject: [PATCH 883/993] iommu/vt-d: Fix panic after kexec -p for kdump This cures a panic on restart after a kexec operation on 5.3 and 5.4 kernels. The underlying state of the iommu registers (iommu->flags & VTD_FLAG_TRANS_PRE_ENABLED) on a restart results in a domain being marked as "DEFER_DEVICE_DOMAIN_INFO" that produces an Oops in identity_mapping(). [ 43.654737] BUG: kernel NULL pointer dereference, address: 0000000000000056 [ 43.655720] #PF: supervisor read access in kernel mode [ 43.655720] #PF: error_code(0x0000) - not-present page [ 43.655720] PGD 0 P4D 0 [ 43.655720] Oops: 0000 [#1] SMP PTI [ 43.655720] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.3.2-1940.el8uek.x86_64 #1 [ 43.655720] Hardware name: Oracle Corporation ORACLE SERVER X5-2/ASM,MOTHERBOARD,1U, BIOS 30140300 09/20/2018 [ 43.655720] RIP: 0010:iommu_need_mapping+0x29/0xd0 [ 43.655720] Code: 00 0f 1f 44 00 00 48 8b 97 70 02 00 00 48 83 fa ff 74 53 48 8d 4a ff b8 01 00 00 00 48 83 f9 fd 76 01 c3 48 8b 35 7f 58 e0 01 <48> 39 72 58 75 f2 55 48 89 e5 41 54 53 48 8b 87 28 02 00 00 4c 8b [ 43.655720] RSP: 0018:ffffc9000001b9b0 EFLAGS: 00010246 [ 43.655720] RAX: 0000000000000001 RBX: 0000000000001000 RCX: fffffffffffffffd [ 43.655720] RDX: fffffffffffffffe RSI: ffff8880719b8000 RDI: ffff8880477460b0 [ 43.655720] RBP: ffffc9000001b9e8 R08: 0000000000000000 R09: ffff888047c01700 [ 43.655720] R10: 00002194036fc692 R11: 0000000000000000 R12: 0000000000000000 [ 43.655720] R13: ffff8880477460b0 R14: 0000000000000cc0 R15: ffff888072d2b558 [ 43.655720] FS: 0000000000000000(0000) GS:ffff888071c00000(0000) knlGS:0000000000000000 [ 43.655720] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 43.655720] CR2: 0000000000000056 CR3: 000000007440a002 CR4: 00000000001606b0 [ 43.655720] Call Trace: [ 43.655720] ? intel_alloc_coherent+0x2a/0x180 [ 43.655720] ? __schedule+0x2c2/0x650 [ 43.655720] dma_alloc_attrs+0x8c/0xd0 [ 43.655720] dma_pool_alloc+0xdf/0x200 [ 43.655720] ehci_qh_alloc+0x58/0x130 [ 43.655720] ehci_setup+0x287/0x7ba [ 43.655720] ? _dev_info+0x6c/0x83 [ 43.655720] ehci_pci_setup+0x91/0x436 [ 43.655720] usb_add_hcd.cold.48+0x1d4/0x754 [ 43.655720] usb_hcd_pci_probe+0x2bc/0x3f0 [ 43.655720] ehci_pci_probe+0x39/0x40 [ 43.655720] local_pci_probe+0x47/0x80 [ 43.655720] pci_device_probe+0xff/0x1b0 [ 43.655720] really_probe+0xf5/0x3a0 [ 43.655720] driver_probe_device+0xbb/0x100 [ 43.655720] device_driver_attach+0x58/0x60 [ 43.655720] __driver_attach+0x8f/0x150 [ 43.655720] ? device_driver_attach+0x60/0x60 [ 43.655720] bus_for_each_dev+0x74/0xb0 [ 43.655720] driver_attach+0x1e/0x20 [ 43.655720] bus_add_driver+0x151/0x1f0 [ 43.655720] ? ehci_hcd_init+0xb2/0xb2 [ 43.655720] ? do_early_param+0x95/0x95 [ 43.655720] driver_register+0x70/0xc0 [ 43.655720] ? ehci_hcd_init+0xb2/0xb2 [ 43.655720] __pci_register_driver+0x57/0x60 [ 43.655720] ehci_pci_init+0x6a/0x6c [ 43.655720] do_one_initcall+0x4a/0x1fa [ 43.655720] ? do_early_param+0x95/0x95 [ 43.655720] kernel_init_freeable+0x1bd/0x262 [ 43.655720] ? rest_init+0xb0/0xb0 [ 43.655720] kernel_init+0xe/0x110 [ 43.655720] ret_from_fork+0x24/0x50 Fixes: 8af46c784ecfe ("iommu/vt-d: Implement is_attach_deferred iommu ops entry") Cc: stable@vger.kernel.org # v5.3+ Signed-off-by: John Donnelly Reviewed-by: Lu Baolu Signed-off-by: Joerg Roedel --- drivers/iommu/intel-iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 79e35b3180ac..6db6d969e31c 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -2794,7 +2794,7 @@ static int identity_mapping(struct device *dev) struct device_domain_info *info; info = dev->archdata.iommu; - if (info && info != DUMMY_DEVICE_DOMAIN_INFO) + if (info && info != DUMMY_DEVICE_DOMAIN_INFO && info != DEFER_DEVICE_DOMAIN_INFO) return (info->domain == si_domain); return 0; -- GitLab From d5798141fd54cea074c3429d5803f6c41ade0ca8 Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Wed, 30 Oct 2019 08:16:43 +0000 Subject: [PATCH 884/993] gfs2: Fix initialisation of args for remount When gfs2 was converted to use fs_context, the initialisation of the mount args structure to the currently active args was lost with the removal of gfs2_remount_fs(), so the checks of the new args on remount became checks against the default values instead of the current ones. This caused unexpected remount behaviour and test failures (xfstests generic/294, generic/306 and generic/452). Reinstate the args initialisation, this time in gfs2_init_fs_context() and conditional upon fc->purpose, as that's the only time we get control before the mount args are parsed in the remount process. Fixes: 1f52aa08d12f ("gfs2: Convert gfs2 to fs_context") Signed-off-by: Andrew Price Signed-off-by: Andreas Gruenbacher --- fs/gfs2/ops_fstype.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index dc61af2c4d5e..18daf494abab 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1540,17 +1540,23 @@ static int gfs2_init_fs_context(struct fs_context *fc) { struct gfs2_args *args; - args = kzalloc(sizeof(*args), GFP_KERNEL); + args = kmalloc(sizeof(*args), GFP_KERNEL); if (args == NULL) return -ENOMEM; - args->ar_quota = GFS2_QUOTA_DEFAULT; - args->ar_data = GFS2_DATA_DEFAULT; - args->ar_commit = 30; - args->ar_statfs_quantum = 30; - args->ar_quota_quantum = 60; - args->ar_errors = GFS2_ERRORS_DEFAULT; + if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) { + struct gfs2_sbd *sdp = fc->root->d_sb->s_fs_info; + *args = sdp->sd_args; + } else { + memset(args, 0, sizeof(*args)); + args->ar_quota = GFS2_QUOTA_DEFAULT; + args->ar_data = GFS2_DATA_DEFAULT; + args->ar_commit = 30; + args->ar_statfs_quantum = 30; + args->ar_quota_quantum = 60; + args->ar_errors = GFS2_ERRORS_DEFAULT; + } fc->fs_private = args; fc->ops = &gfs2_context_ops; return 0; -- GitLab From f5c8d290634a470600e1ce61733ec54d05a897e8 Mon Sep 17 00:00:00 2001 From: Sanket Parmar Date: Tue, 29 Oct 2019 12:24:41 +0000 Subject: [PATCH 885/993] usb: cdns3: gadget: reset EP_CLAIMED flag while unloading EP_CLAIMED flag is used to track the claimed endpoints. While unloading the module, Reset EP_CLAIMED flag for all enabled endpoints. So that it can be reused. Signed-off-by: Sanket Parmar Acked-by: Peter Chen Reviewed-by: Roger Quadros Acked-by: Felipe Balbi Link: https://lore.kernel.org/r/20191029122441.5816-1-sparmar@cadence.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/gadget.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c index d9e7f2d06098..8421fc028c40 100644 --- a/drivers/usb/cdns3/gadget.c +++ b/drivers/usb/cdns3/gadget.c @@ -2379,6 +2379,8 @@ static int cdns3_gadget_udc_stop(struct usb_gadget *gadget) writel(EP_CMD_EPRST, &priv_dev->regs->ep_cmd); readl_poll_timeout_atomic(&priv_dev->regs->ep_cmd, val, !(val & EP_CMD_EPRST), 1, 100); + + priv_ep->flags &= ~EP_CLAIMED; } /* disable interrupt for device */ -- GitLab From 94e259f81a714c96f381d362228fc4743db49742 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 30 Oct 2019 14:16:07 +0200 Subject: [PATCH 886/993] usb: cdns3: gadget: Fix g_audio use case when connected to Super-Speed host Take into account gadget driver's speed limit when programming controller speed. Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") Signed-off-by: Roger Quadros Acked-by: Peter Chen Link: https://lore.kernel.org/r/20191030121607.21739-1-rogerq@ti.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/gadget.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c index 8421fc028c40..4c1e75509303 100644 --- a/drivers/usb/cdns3/gadget.c +++ b/drivers/usb/cdns3/gadget.c @@ -2343,9 +2343,35 @@ static int cdns3_gadget_udc_start(struct usb_gadget *gadget, { struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); unsigned long flags; + enum usb_device_speed max_speed = driver->max_speed; spin_lock_irqsave(&priv_dev->lock, flags); priv_dev->gadget_driver = driver; + + /* limit speed if necessary */ + max_speed = min(driver->max_speed, gadget->max_speed); + + switch (max_speed) { + case USB_SPEED_FULL: + writel(USB_CONF_SFORCE_FS, &priv_dev->regs->usb_conf); + writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf); + break; + case USB_SPEED_HIGH: + writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf); + break; + case USB_SPEED_SUPER: + break; + default: + dev_err(priv_dev->dev, + "invalid maximum_speed parameter %d\n", + max_speed); + /* fall through */ + case USB_SPEED_UNKNOWN: + /* default to superspeed */ + max_speed = USB_SPEED_SUPER; + break; + } + cdns3_gadget_config(priv_dev); spin_unlock_irqrestore(&priv_dev->lock, flags); return 0; @@ -2575,12 +2601,7 @@ static int cdns3_gadget_start(struct cdns3 *cdns) /* Check the maximum_speed parameter */ switch (max_speed) { case USB_SPEED_FULL: - writel(USB_CONF_SFORCE_FS, &priv_dev->regs->usb_conf); - writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf); - break; case USB_SPEED_HIGH: - writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf); - break; case USB_SPEED_SUPER: break; default: -- GitLab From 302d5a80d232134246032bc4263fd7facdddb8f1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 29 Oct 2019 21:41:20 +0100 Subject: [PATCH 887/993] ALSA: hda - Fix mutex deadlock in HDMI codec driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The commit ade49db337a9 ("ALSA: hda/hdmi - Allow audio component for AMD/ATI and Nvidia HDMI") introduced the spec->pcm_lock mutex lock to the whole generic_hdmi_init() function for avoiding the race with the audio component registration. However, this caused a dead lock when the unsolicited event is handled without the audio component, as the codec gets runtime-resumed in hdmi_present_sense() which is already inside the spec->pcm_lock in its caller. For avoiding this deadlock, add a new mutex only for the audio component binding that is used in both generic_hdmi_init() and the audio notifier registration where the jack callbacks are handled / re-registered. Fixes: ade49db337a9 ("ALSA: hda/hdmi - Allow audio component for AMD/ATI and Nvidia HDMI") Reported-and-tested-by: Ville Syrjälä Link: https://lore.kernel.org/r/s5himo7i89i.wl-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 795cbda32cbb..b72553710ffb 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -145,6 +145,7 @@ struct hdmi_spec { struct snd_array pins; /* struct hdmi_spec_per_pin */ struct hdmi_pcm pcm_rec[16]; struct mutex pcm_lock; + struct mutex bind_lock; /* for audio component binding */ /* pcm_bitmap means which pcms have been assigned to pins*/ unsigned long pcm_bitmap; int pcm_used; /* counter of pcm_rec[] */ @@ -2258,7 +2259,7 @@ static int generic_hdmi_init(struct hda_codec *codec) struct hdmi_spec *spec = codec->spec; int pin_idx; - mutex_lock(&spec->pcm_lock); + mutex_lock(&spec->bind_lock); spec->use_jack_detect = !codec->jackpoll_interval; for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); @@ -2275,7 +2276,7 @@ static int generic_hdmi_init(struct hda_codec *codec) snd_hda_jack_detect_enable_callback(codec, pin_nid, jack_callback); } - mutex_unlock(&spec->pcm_lock); + mutex_unlock(&spec->bind_lock); return 0; } @@ -2382,6 +2383,7 @@ static int alloc_generic_hdmi(struct hda_codec *codec) spec->ops = generic_standard_hdmi_ops; spec->dev_num = 1; /* initialize to 1 */ mutex_init(&spec->pcm_lock); + mutex_init(&spec->bind_lock); snd_hdac_register_chmap_ops(&codec->core, &spec->chmap); spec->chmap.ops.get_chmap = hdmi_get_chmap; @@ -2451,7 +2453,7 @@ static void generic_acomp_notifier_set(struct drm_audio_component *acomp, int i; spec = container_of(acomp->audio_ops, struct hdmi_spec, drm_audio_ops); - mutex_lock(&spec->pcm_lock); + mutex_lock(&spec->bind_lock); spec->use_acomp_notifier = use_acomp; spec->codec->relaxed_resume = use_acomp; /* reprogram each jack detection logic depending on the notifier */ @@ -2461,7 +2463,7 @@ static void generic_acomp_notifier_set(struct drm_audio_component *acomp, get_pin(spec, i)->pin_nid, use_acomp); } - mutex_unlock(&spec->pcm_lock); + mutex_unlock(&spec->bind_lock); } /* enable / disable the notifier via master bind / unbind */ -- GitLab From f37f05503575c59020dacd36e999f4e8b3dbc115 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 27 Oct 2019 20:53:08 +0100 Subject: [PATCH 888/993] mt76: mt76x2e: disable pcie_aspm by default On same device (e.g. U7612E-H1) PCIE_ASPM causes continuous mcu hangs and instability. Since mt76x2 series does not manage PCIE PS states, first we try to disable ASPM using pci_disable_link_state. If it fails, we will disable PCIE PS configuring PCI registers. This patch has been successfully tested on U7612E-H1 mini-pice card Tested-by: Oleksandr Natalenko Signed-off-by: Felix Fietkau Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/Makefile | 2 + drivers/net/wireless/mediatek/mt76/mt76.h | 1 + .../net/wireless/mediatek/mt76/mt76x2/pci.c | 2 + drivers/net/wireless/mediatek/mt76/pci.c | 46 +++++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 drivers/net/wireless/mediatek/mt76/pci.c diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile index 4d03596e891f..d7a1ddc9e407 100644 --- a/drivers/net/wireless/mediatek/mt76/Makefile +++ b/drivers/net/wireless/mediatek/mt76/Makefile @@ -8,6 +8,8 @@ mt76-y := \ mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o \ tx.o agg-rx.o mcu.o +mt76-$(CONFIG_PCI) += pci.o + mt76-usb-y := usb.o usb_trace.o CFLAGS_trace.o := -I$(src) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 570c159515a0..dc468ed9434a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -578,6 +578,7 @@ bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, #define mt76_poll_msec(dev, ...) __mt76_poll_msec(&((dev)->mt76), __VA_ARGS__) void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); +void mt76_pci_disable_aspm(struct pci_dev *pdev); static inline u16 mt76_chip(struct mt76_dev *dev) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c index 73c3104f8858..cf611d1b817c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c @@ -81,6 +81,8 @@ mt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* RG_SSUSB_CDR_BR_PE1D = 0x3 */ mt76_rmw_field(dev, 0x15c58, 0x3 << 6, 0x3); + mt76_pci_disable_aspm(pdev); + return 0; error: diff --git a/drivers/net/wireless/mediatek/mt76/pci.c b/drivers/net/wireless/mediatek/mt76/pci.c new file mode 100644 index 000000000000..04c5a692bc85 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/pci.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: ISC +/* + * Copyright (C) 2019 Lorenzo Bianconi + */ + +#include + +void mt76_pci_disable_aspm(struct pci_dev *pdev) +{ + struct pci_dev *parent = pdev->bus->self; + u16 aspm_conf, parent_aspm_conf = 0; + + pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &aspm_conf); + aspm_conf &= PCI_EXP_LNKCTL_ASPMC; + if (parent) { + pcie_capability_read_word(parent, PCI_EXP_LNKCTL, + &parent_aspm_conf); + parent_aspm_conf &= PCI_EXP_LNKCTL_ASPMC; + } + + if (!aspm_conf && (!parent || !parent_aspm_conf)) { + /* aspm already disabled */ + return; + } + + dev_info(&pdev->dev, "disabling ASPM %s %s\n", + (aspm_conf & PCI_EXP_LNKCTL_ASPM_L0S) ? "L0s" : "", + (aspm_conf & PCI_EXP_LNKCTL_ASPM_L1) ? "L1" : ""); + + if (IS_ENABLED(CONFIG_PCIEASPM)) { + int err; + + err = pci_disable_link_state(pdev, aspm_conf); + if (!err) + return; + } + + /* both device and parent should have the same ASPM setting. + * disable ASPM in downstream component first and then upstream. + */ + pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, aspm_conf); + if (parent) + pcie_capability_clear_word(parent, PCI_EXP_LNKCTL, + aspm_conf); +} +EXPORT_SYMBOL_GPL(mt76_pci_disable_aspm); -- GitLab From 7bd0650be63cbb9e45e394d689c81365fe48e495 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 27 Oct 2019 20:53:09 +0100 Subject: [PATCH 889/993] mt76: dma: fix buffer unmap with non-linear skbs mt76 dma layer is supposed to unmap skb data buffers while keep txwi mapped on hw dma ring. At the moment mt76 wrongly unmap txwi or does not unmap data fragments in even positions for non-linear skbs. This issue may result in hw hangs with A-MSDU if the system relies on IOMMU or SWIOTLB. Fix this behaviour properly unmapping data fragments on non-linear skbs. Fixes: 17f1de56df05 ("mt76: add common code shared between multiple chipsets") Signed-off-by: Lorenzo Bianconi Signed-off-by: Kalle Valo --- drivers/net/wireless/mediatek/mt76/dma.c | 6 ++++-- drivers/net/wireless/mediatek/mt76/mt76.h | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index c747eb24581c..8f69d00bd940 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -53,8 +53,10 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, u32 ctrl; int i, idx = -1; - if (txwi) + if (txwi) { q->entry[q->head].txwi = DMA_DUMMY_DATA; + q->entry[q->head].skip_buf0 = true; + } for (i = 0; i < nbufs; i += 2, buf += 2) { u32 buf0 = buf[0].addr, buf1 = 0; @@ -97,7 +99,7 @@ mt76_dma_tx_cleanup_idx(struct mt76_dev *dev, struct mt76_queue *q, int idx, __le32 __ctrl = READ_ONCE(q->desc[idx].ctrl); u32 ctrl = le32_to_cpu(__ctrl); - if (!e->txwi || !e->skb) { + if (!e->skip_buf0) { __le32 addr = READ_ONCE(q->desc[idx].buf0); u32 len = FIELD_GET(MT_DMA_CTL_SD_LEN0, ctrl); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index dc468ed9434a..8aec7ccf2d79 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -93,8 +93,9 @@ struct mt76_queue_entry { struct urb *urb; }; enum mt76_txq_id qid; - bool schedule; - bool done; + bool skip_buf0:1; + bool schedule:1; + bool done:1; }; struct mt76_queue_regs { -- GitLab From 3d206e6899a07fe853f703f7e68f84b48b919129 Mon Sep 17 00:00:00 2001 From: Ayala Beker Date: Tue, 29 Oct 2019 17:47:20 +0200 Subject: [PATCH 890/993] iwlwifi: fw api: support new API for scan config cmd The API was reduced to include only knowledge currently needed by the FW scan logic, the rest is legacy. Support the new, reduced version. Using the old API with newer firmwares (starting from iwlwifi-*-50.ucode, which implements and requires the new API version) causes an assertion failure similar to this one: [ 2.854505] iwlwifi 0000:00:14.3: 0x20000038 | BAD_COMMAND Signed-off-by: Ayala Beker Signed-off-by: Luca Coelho Signed-off-by: Kalle Valo --- .../net/wireless/intel/iwlwifi/fw/api/scan.h | 22 +++++++++- drivers/net/wireless/intel/iwlwifi/fw/file.h | 3 ++ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 6 +++ drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 40 +++++++++++++++---- 4 files changed, 61 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h index 39c64850cb6f..c0750ced5ac2 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h @@ -520,7 +520,7 @@ struct iwl_scan_dwell { } __packed; /** - * struct iwl_scan_config + * struct iwl_scan_config_v1 * @flags: enum scan_config_flags * @tx_chains: valid_tx antenna - ANT_* definitions * @rx_chains: valid_rx antenna - ANT_* definitions @@ -552,7 +552,7 @@ struct iwl_scan_config_v1 { #define SCAN_LB_LMAC_IDX 0 #define SCAN_HB_LMAC_IDX 1 -struct iwl_scan_config { +struct iwl_scan_config_v2 { __le32 flags; __le32 tx_chains; __le32 rx_chains; @@ -564,6 +564,24 @@ struct iwl_scan_config { u8 bcast_sta_id; u8 channel_flags; u8 channel_array[]; +} __packed; /* SCAN_CONFIG_DB_CMD_API_S_2 */ + +/** + * struct iwl_scan_config + * @enable_cam_mode: whether to enable CAM mode. + * @enable_promiscouos_mode: whether to enable promiscouos mode + * @bcast_sta_id: the index of the station in the fw + * @reserved: reserved + * @tx_chains: valid_tx antenna - ANT_* definitions + * @rx_chains: valid_rx antenna - ANT_* definitions + */ +struct iwl_scan_config { + u8 enable_cam_mode; + u8 enable_promiscouos_mode; + u8 bcast_sta_id; + u8 reserved; + __le32 tx_chains; + __le32 rx_chains; } __packed; /* SCAN_CONFIG_DB_CMD_API_S_3 */ /** diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 423cc0cf8e78..0d5bc4ce5c07 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h @@ -288,6 +288,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t; * STA_CONTEXT_DOT11AX_API_S * @IWL_UCODE_TLV_CAPA_SAR_TABLE_VER: This ucode supports different sar * version tables. + * @IWL_UCODE_TLV_API_REDUCED_SCAN_CONFIG: This ucode supports v3 of + * SCAN_CONFIG_DB_CMD_API_S. * * @NUM_IWL_UCODE_TLV_API: number of bits used */ @@ -321,6 +323,7 @@ enum iwl_ucode_tlv_api { IWL_UCODE_TLV_API_WOWLAN_TCP_SYN_WAKE = (__force iwl_ucode_tlv_api_t)53, IWL_UCODE_TLV_API_FTM_RTT_ACCURACY = (__force iwl_ucode_tlv_api_t)54, IWL_UCODE_TLV_API_SAR_TABLE_VER = (__force iwl_ucode_tlv_api_t)55, + IWL_UCODE_TLV_API_REDUCED_SCAN_CONFIG = (__force iwl_ucode_tlv_api_t)56, IWL_UCODE_TLV_API_ADWELL_HB_DEF_N_AP = (__force iwl_ucode_tlv_api_t)57, IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER = (__force iwl_ucode_tlv_api_t)58, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 843d00bf2bd5..5ca50f39a023 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1405,6 +1405,12 @@ static inline bool iwl_mvm_is_scan_ext_chan_supported(struct iwl_mvm *mvm) IWL_UCODE_TLV_API_SCAN_EXT_CHAN_VER); } +static inline bool iwl_mvm_is_reduced_config_scan_supported(struct iwl_mvm *mvm) +{ + return fw_has_api(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_API_REDUCED_SCAN_CONFIG); +} + static inline bool iwl_mvm_has_new_rx_stats_api(struct iwl_mvm *mvm) { return fw_has_api(&mvm->fw->ucode_capa, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index f6b3045badbd..fcafa22ec6ce 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -1137,11 +1137,11 @@ static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config, iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels); } -static void iwl_mvm_fill_scan_config(struct iwl_mvm *mvm, void *config, - u32 flags, u8 channel_flags, - u32 max_channels) +static void iwl_mvm_fill_scan_config_v2(struct iwl_mvm *mvm, void *config, + u32 flags, u8 channel_flags, + u32 max_channels) { - struct iwl_scan_config *cfg = config; + struct iwl_scan_config_v2 *cfg = config; cfg->flags = cpu_to_le32(flags); cfg->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm)); @@ -1185,7 +1185,7 @@ static void iwl_mvm_fill_scan_config(struct iwl_mvm *mvm, void *config, iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels); } -int iwl_mvm_config_scan(struct iwl_mvm *mvm) +static int iwl_mvm_legacy_config_scan(struct iwl_mvm *mvm) { void *cfg; int ret, cmd_size; @@ -1217,7 +1217,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm) } if (iwl_mvm_cdb_scan_api(mvm)) - cmd_size = sizeof(struct iwl_scan_config); + cmd_size = sizeof(struct iwl_scan_config_v2); else cmd_size = sizeof(struct iwl_scan_config_v1); cmd_size += num_channels; @@ -1254,8 +1254,8 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm) flags |= (iwl_mvm_is_scan_fragmented(hb_type)) ? SCAN_CONFIG_FLAG_SET_LMAC2_FRAGMENTED : SCAN_CONFIG_FLAG_CLEAR_LMAC2_FRAGMENTED; - iwl_mvm_fill_scan_config(mvm, cfg, flags, channel_flags, - num_channels); + iwl_mvm_fill_scan_config_v2(mvm, cfg, flags, channel_flags, + num_channels); } else { iwl_mvm_fill_scan_config_v1(mvm, cfg, flags, channel_flags, num_channels); @@ -1277,6 +1277,30 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm) return ret; } +int iwl_mvm_config_scan(struct iwl_mvm *mvm) +{ + struct iwl_scan_config cfg; + struct iwl_host_cmd cmd = { + .id = iwl_cmd_id(SCAN_CFG_CMD, IWL_ALWAYS_LONG_GROUP, 0), + .len[0] = sizeof(cfg), + .data[0] = &cfg, + .dataflags[0] = IWL_HCMD_DFL_NOCOPY, + }; + + if (!iwl_mvm_is_reduced_config_scan_supported(mvm)) + return iwl_mvm_legacy_config_scan(mvm); + + memset(&cfg, 0, sizeof(cfg)); + + cfg.bcast_sta_id = mvm->aux_sta.sta_id; + cfg.tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm)); + cfg.rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm)); + + IWL_DEBUG_SCAN(mvm, "Sending UMAC scan config\n"); + + return iwl_mvm_send_cmd(mvm, &cmd); +} + static int iwl_mvm_scan_uid_by_status(struct iwl_mvm *mvm, int status) { int i; -- GitLab From e5574f61e9d8274c49e9a5d943abde8e938d57e1 Mon Sep 17 00:00:00 2001 From: chen gong Date: Wed, 23 Oct 2019 13:54:32 +0800 Subject: [PATCH 891/993] drm/amdgpu: Fix SDMA hang when performing VKexample test VKexample test hang during Occlusion/SDMA/Varia runs. Clear XNACK_WATERMK in reg SDMA0_UTCL1_WATERMK to fix this issue. Signed-off-by: chen gong Reviewed-by: Aaron Liu Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 78452cf0115d..4554e72c8378 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -254,6 +254,7 @@ static const struct soc15_reg_golden golden_settings_sdma_4_3[] = { SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0), + SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x00000000) }; static u32 sdma_v4_0_get_reg_offset(struct amdgpu_device *adev, -- GitLab From 9bdf63d3579e36942f4b91d3558a90da8116bb40 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 22 Oct 2019 19:22:11 +0200 Subject: [PATCH 892/993] drm/amdgpu/sdma5: do not execute 0-sized IBs (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This seems to help with https://bugs.freedesktop.org/show_bug.cgi?id=111481. v2: insert a NOP instead of skipping all 0-sized IBs to avoid breaking older hw Signed-off-by: Pierre-Eric Pelloux-Prayer Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c index 241a4e57cf4a..354e6200ca9a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c @@ -309,6 +309,7 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, job->vm_pd_addr = amdgpu_gmc_pd_addr(adev->gart.bo); job->vm_needs_flush = true; + job->ibs->ptr[job->ibs->length_dw++] = ring->funcs->nop; amdgpu_ring_pad_ib(ring, &job->ibs[0]); r = amdgpu_job_submit(job, &adev->mman.entity, AMDGPU_FENCE_OWNER_UNDEFINED, &fence); -- GitLab From 40ba9796983bfd202619ffb7518d0fbdc9547d53 Mon Sep 17 00:00:00 2001 From: Zhan liu Date: Tue, 22 Oct 2019 10:50:21 -0400 Subject: [PATCH 893/993] drm/amd/display: Change Navi14's DWB flag to 1 [Why] DWB (Display Writeback) flag needs to be enabled as 1, or system will throw out a few warnings when creating dcn20 resource pool. Also, Navi14's dwb setting needs to match Navi10's, which has already been set to 1. [How] Change value of num_dwb from 0 to 1. Signed-off-by: Zhan Liu Reviewed-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 5a2763daff4d..dfb208285a9c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -814,7 +814,7 @@ static const struct resource_caps res_cap_nv14 = { .num_audio = 6, .num_stream_encoder = 5, .num_pll = 5, - .num_dwb = 0, + .num_dwb = 1, .num_ddc = 5, }; -- GitLab From f52ebe1f888dfae68d7cffabf5ac898f8cb64fb3 Mon Sep 17 00:00:00 2001 From: "Tianci.Yin" Date: Thu, 24 Oct 2019 18:03:17 +0800 Subject: [PATCH 894/993] drm/amdgpu/gfx10: update gfx golden settings update registers: mmCGTT_SPI_CLK_CTRL Reviewed-by: Feifei Xu Signed-off-by: Tianci.Yin Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index 957811b73672..63f2a340ce27 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -93,7 +93,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_1[] = { SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x00400014), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_CPF_CLK_CTRL, 0xfcff8fff, 0xf8000100), - SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xc0000000, 0xc0000100), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xcd000000, 0x0d000100), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQ_CLK_CTRL, 0x60000ff0, 0x60000100), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQG_CLK_CTRL, 0x40000000, 0x40000100), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_VGT_CLK_CTRL, 0xffff8fff, 0xffff8100), -- GitLab From 3dde767f14dcdbe8231645cac01051cebb4feb57 Mon Sep 17 00:00:00 2001 From: "Tianci.Yin" Date: Thu, 24 Oct 2019 18:04:52 +0800 Subject: [PATCH 895/993] drm/amdgpu/gfx10: update gfx golden settings for navi14 update registers: mmCGTT_SPI_CLK_CTRL Reviewed-by: Feifei Xu Signed-off-by: Tianci.Yin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index 63f2a340ce27..d846ba9db1c4 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -140,7 +140,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_1_1[] = SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x003c0014), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_GS_NGG_CLK_CTRL, 0xffff8fff, 0xffff8100), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_IA_CLK_CTRL, 0xffff0fff, 0xffff0100), - SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xc0000000, 0xc0000100), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xcd000000, 0x0d000100), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQ_CLK_CTRL, 0xf8ff0fff, 0x60000100), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQG_CLK_CTRL, 0x40000ff0, 0x40000100), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_VGT_CLK_CTRL, 0xffff8fff, 0xffff8100), -- GitLab From 47661f6dad42e1241cdef82c5e06cfb7027a3f59 Mon Sep 17 00:00:00 2001 From: "Tianci.Yin" Date: Thu, 24 Oct 2019 18:06:06 +0800 Subject: [PATCH 896/993] drm/amdgpu/gfx10: update gfx golden settings for navi12 update registers: mmCGTT_SPI_CLK_CTRL Reviewed-by: Feifei Xu Signed-off-by: Tianci.Yin Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index d846ba9db1c4..8dfc775626a7 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -179,7 +179,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_1_2[] = SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0x003e001f, 0x003c0014), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_GS_NGG_CLK_CTRL, 0xffff8fff, 0xffff8100), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_IA_CLK_CTRL, 0xffff0fff, 0xffff0100), - SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xff7f0fff, 0xc0000100), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SPI_CLK_CTRL, 0xff7f0fff, 0x0d000100), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQ_CLK_CTRL, 0xffffcfff, 0x60000100), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_SQG_CLK_CTRL, 0xffff0fff, 0x40000100), SOC15_REG_GOLDEN_VALUE(GC, 0, mmCGTT_VGT_CLK_CTRL, 0xffff8fff, 0xffff8100), -- GitLab From 167bf96014a095753053595f3224fcdeb49ac3c8 Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Thu, 24 Oct 2019 15:39:06 -0400 Subject: [PATCH 897/993] drm/sched: Set error to s_fence if HW job submission failed. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: When run_job fails and HW fence returned is NULL we still signal the s_fence to avoid hangs but the user has no way of knowing if the actual HW job was ran and finished. Fix: Allow .run_job implementations to return ERR_PTR in the fence pointer returned and then set this error for s_fence->finished fence so whoever wait on this fence can inspect the signaled fence for an error. Signed-off-by: Andrey Grodzovsky Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/scheduler/sched_main.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 9a0ee74d82dc..f39b97ed4ade 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -479,6 +479,7 @@ void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched) struct drm_sched_job *s_job, *tmp; uint64_t guilty_context; bool found_guilty = false; + struct dma_fence *fence; list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) { struct drm_sched_fence *s_fence = s_job->s_fence; @@ -492,7 +493,16 @@ void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched) dma_fence_set_error(&s_fence->finished, -ECANCELED); dma_fence_put(s_job->s_fence->parent); - s_job->s_fence->parent = sched->ops->run_job(s_job); + fence = sched->ops->run_job(s_job); + + if (IS_ERR_OR_NULL(fence)) { + s_job->s_fence->parent = NULL; + dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); + } else { + s_job->s_fence->parent = fence; + } + + } } EXPORT_SYMBOL(drm_sched_resubmit_jobs); @@ -720,7 +730,7 @@ static int drm_sched_main(void *param) fence = sched->ops->run_job(sched_job); drm_sched_fence_scheduled(s_fence); - if (fence) { + if (!IS_ERR_OR_NULL(fence)) { s_fence->parent = dma_fence_get(fence); r = dma_fence_add_callback(fence, &sched_job->cb, drm_sched_process_job); @@ -730,8 +740,11 @@ static int drm_sched_main(void *param) DRM_ERROR("fence add callback failed (%d)\n", r); dma_fence_put(fence); - } else + } else { + + dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); drm_sched_process_job(NULL, &sched_job->cb); + } wake_up(&sched->job_scheduled); } -- GitLab From 57c0f58e9f562089de5f0b60da103677d232374c Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Thu, 24 Oct 2019 15:44:10 -0400 Subject: [PATCH 898/993] drm/amdgpu: If amdgpu_ib_schedule fails return back the error. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use ERR_PTR to return back the error happened during amdgpu_ib_schedule. Signed-off-by: Andrey Grodzovsky Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 9d76e0923a5a..96b2a31ccfed 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -218,7 +218,7 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job) struct amdgpu_ring *ring = to_amdgpu_ring(sched_job->sched); struct dma_fence *fence = NULL, *finished; struct amdgpu_job *job; - int r; + int r = 0; job = to_amdgpu_job(sched_job); finished = &job->base.s_fence->finished; @@ -243,6 +243,8 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job) job->fence = dma_fence_get(fence); amdgpu_job_free_resources(job); + + fence = r ? ERR_PTR(r) : fence; return fence; } -- GitLab From 8775e89fa7121535d2da738c95167b8c65aa6e90 Mon Sep 17 00:00:00 2001 From: Jun Lei Date: Thu, 3 Oct 2019 15:09:53 -0400 Subject: [PATCH 899/993] drm/amd/display: do not synchronize "drr" displays [why] A display that supports DRR can never really be considered "synchronized" with any other display because we can dynamically enable DRR (i.e. without modeset). this will cause their relative CRTC positions to drift and lose sync. this will disrupt features such as MCLK switching that assume and depend on their permanent alignment (that can only change with modeset) [how] check for ignore_msa in stream when considered synchronizability this ignore_msa is basically actually implemented as "supports drr" Signed-off-by: Jun Lei Reviewed-by: Yongqiang Sun Acked-by: Anthony Koo Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 8f70295179ff..f25ac17f47fa 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -404,6 +404,9 @@ bool resource_are_streams_timing_synchronizable( if (stream1->view_format != stream2->view_format) return false; + if (stream1->ignore_msa_timing_param || stream2->ignore_msa_timing_param) + return false; + return true; } static bool is_dp_and_hdmi_sharable( @@ -1540,6 +1543,9 @@ bool dc_is_stream_unchanged( if (!are_stream_backends_same(old_stream, stream)) return false; + if (old_stream->ignore_msa_timing_param != stream->ignore_msa_timing_param) + return false; + return true; } -- GitLab From ceba1a0128a68b0a045bbd0c020994e5c5c737a8 Mon Sep 17 00:00:00 2001 From: Aidan Yang Date: Wed, 2 Oct 2019 10:47:31 -0400 Subject: [PATCH 900/993] drm/amd/display: Allow inverted gamma [why] There's a use case for inverted gamma and it's been confirmed that negative slopes are ok. [how] Remove code for blocking non-monotonically increasing gamma Signed-off-by: Aidan Yang Reviewed-by: Krunoslav Kovac Acked-by: Leo Li Acked-by: Reza Amini Signed-off-by: Alex Deucher --- .../amd/display/dc/dcn10/dcn10_cm_common.c | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c index 01c7e30b9ce1..bbd6e01b3eca 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c @@ -393,6 +393,10 @@ bool cm_helper_translate_curve_to_hw_format( rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; + rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red; + rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green; + rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue; + // All 3 color channels have same x corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), dc_fixpt_from_int(region_start)); @@ -464,13 +468,6 @@ bool cm_helper_translate_curve_to_hw_format( i = 1; while (i != hw_points + 1) { - if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) - rgb_plus_1->red = rgb->red; - if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) - rgb_plus_1->green = rgb->green; - if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) - rgb_plus_1->blue = rgb->blue; - rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red); rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue); @@ -562,6 +559,10 @@ bool cm_helper_translate_curve_to_degamma_hw_format( rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; + rgb_resulted[hw_points].red = rgb_resulted[hw_points - 1].red; + rgb_resulted[hw_points].green = rgb_resulted[hw_points - 1].green; + rgb_resulted[hw_points].blue = rgb_resulted[hw_points - 1].blue; + corner_points[0].red.x = dc_fixpt_pow(dc_fixpt_from_int(2), dc_fixpt_from_int(region_start)); corner_points[0].green.x = corner_points[0].red.x; @@ -624,13 +625,6 @@ bool cm_helper_translate_curve_to_degamma_hw_format( i = 1; while (i != hw_points + 1) { - if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) - rgb_plus_1->red = rgb->red; - if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) - rgb_plus_1->green = rgb->green; - if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) - rgb_plus_1->blue = rgb->blue; - rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red); rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue); -- GitLab From 7c37d399c2b84d4b79de4d512a38373f1d71ab90 Mon Sep 17 00:00:00 2001 From: Jun Lei Date: Thu, 19 Sep 2019 17:43:45 -0400 Subject: [PATCH 901/993] drm/amd/display: add 50us buffer as WA for pstate switch in active Signed-off-by: Jun Lei Reviewed-by: Aric Cyr Acked-by: Leo Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c index 649883777f62..6c6c486b774a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c @@ -2577,7 +2577,8 @@ static void dml20_DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPer mode_lib->vba.MinActiveDRAMClockChangeMargin + mode_lib->vba.DRAMClockChangeLatency; - if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 0) { + if (mode_lib->vba.MinActiveDRAMClockChangeMargin > 50) { + mode_lib->vba.DRAMClockChangeWatermark += 25; mode_lib->vba.DRAMClockChangeSupport[0][0] = dm_dram_clock_change_vactive; } else { if (mode_lib->vba.SynchronizedVBlank || mode_lib->vba.NumberOfActivePlanes == 1) { -- GitLab From bc2fde42e2418808dbfc04de1a6da91d7d31cf1a Mon Sep 17 00:00:00 2001 From: Michael Strauss Date: Thu, 3 Oct 2019 11:54:15 -0400 Subject: [PATCH 902/993] drm/amd/display: Passive DP->HDMI dongle detection fix [WHY] i2c_read is called to differentiate passive DP->HDMI and DP->DVI-D dongles The call is expected to fail in DVI-D case but pass in HDMI case Some HDMI dongles have a chance to fail as well, causing misdetection as DVI-D [HOW] Retry i2c_read to ensure failed result is valid Signed-off-by: Michael Strauss Reviewed-by: Tony Cheng Acked-by: Leo Li Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/core/dc_link_ddc.c | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c index 505967b48e14..51991bf26a93 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c @@ -374,6 +374,7 @@ void dal_ddc_service_i2c_query_dp_dual_mode_adaptor( enum display_dongle_type *dongle = &sink_cap->dongle_type; uint8_t type2_dongle_buf[DP_ADAPTOR_TYPE2_SIZE]; bool is_type2_dongle = false; + int retry_count = 2; struct dp_hdmi_dongle_signature_data *dongle_signature; /* Assume we have no valid DP passive dongle connected */ @@ -386,13 +387,24 @@ void dal_ddc_service_i2c_query_dp_dual_mode_adaptor( DP_HDMI_DONGLE_ADDRESS, type2_dongle_buf, sizeof(type2_dongle_buf))) { - *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE; - sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK; + /* Passive HDMI dongles can sometimes fail here without retrying*/ + while (retry_count > 0) { + if (i2c_read(ddc, + DP_HDMI_DONGLE_ADDRESS, + type2_dongle_buf, + sizeof(type2_dongle_buf))) + break; + retry_count--; + } + if (retry_count == 0) { + *dongle = DISPLAY_DONGLE_DP_DVI_DONGLE; + sink_cap->max_hdmi_pixel_clock = DP_ADAPTOR_DVI_MAX_TMDS_CLK; - CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf), - "DP-DVI passive dongle %dMhz: ", - DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000); - return; + CONN_DATA_DETECT(ddc->link, type2_dongle_buf, sizeof(type2_dongle_buf), + "DP-DVI passive dongle %dMhz: ", + DP_ADAPTOR_DVI_MAX_TMDS_CLK / 1000); + return; + } } /* Check if Type 2 dongle.*/ -- GitLab From 385857adb8154563840e5b0f200254126618f464 Mon Sep 17 00:00:00 2001 From: Zhan liu Date: Thu, 17 Oct 2019 14:55:56 -0400 Subject: [PATCH 903/993] drm/amd/display: setting the DIG_MODE to the correct value. [Why] This patch is for fixing Navi14 HDMI display pink screen issue. [How] Call stream->link->link_enc->funcs->setup twice. This is setting the DIG_MODE to the correct value after having been overridden by the call to transmitter control. Signed-off-by: Zhan Liu Reviewed-by: Nicholas Kazlauskas Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index ca20b150afcc..9c58670d5414 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -2767,6 +2767,15 @@ void core_link_enable_stream( CONTROLLER_DP_TEST_PATTERN_VIDEOMODE, COLOR_DEPTH_UNDEFINED); + /* This second call is needed to reconfigure the DIG + * as a workaround for the incorrect value being applied + * from transmitter control. + */ + if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) + stream->link->link_enc->funcs->setup( + stream->link->link_enc, + pipe_ctx->stream->signal); + #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT if (pipe_ctx->stream->timing.flags.DSC) { if (dc_is_dp_signal(pipe_ctx->stream->signal) || -- GitLab From 364593f3ee5fdefc6efd89475e1804c928b4e6ba Mon Sep 17 00:00:00 2001 From: zhongshiqi Date: Wed, 23 Oct 2019 16:32:23 +0800 Subject: [PATCH 904/993] dc.c:use kzalloc without test dc.c:583:null check is needed after using kzalloc function Reviewed-by: Harry Wentland Signed-off-by: zhongshiqi Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 5d1adeda4d90..4b8819c27fcd 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -580,6 +580,10 @@ static bool construct(struct dc *dc, #ifdef CONFIG_DRM_AMD_DC_DCN2_0 // Allocate memory for the vm_helper dc->vm_helper = kzalloc(sizeof(struct vm_helper), GFP_KERNEL); + if (!dc->vm_helper) { + dm_error("%s: failed to create dc->vm_helper\n", __func__); + goto fail; + } #endif memcpy(&dc->bb_overrides, &init_params->bb_overrides, sizeof(dc->bb_overrides)); -- GitLab From e6f4e274c1e52d1f0bfe293fb44ddf59de6c0374 Mon Sep 17 00:00:00 2001 From: Pelle van Gils Date: Thu, 24 Oct 2019 16:04:31 +0200 Subject: [PATCH 905/993] drm/amdgpu/powerplay/vega10: allow undervolting in p7 The vega10_odn_update_soc_table() function does not allow the SCLK dependent voltage to be set for power-state 7 to a value below the default in pptable. Change the for-loop condition to allow undervolting in the highest state. Bug: https://bugzilla.kernel.org/show_bug.cgi?id=205277 Signed-off-by: Pelle van Gils Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c index d08493b67b67..beacfffbdc3e 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -5098,9 +5098,7 @@ static void vega10_odn_update_soc_table(struct pp_hwmgr *hwmgr, if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) { podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk; - for (i = 0; i < podn_vdd_dep->count - 1; i++) - od_vddc_lookup_table->entries[i].us_vdd = podn_vdd_dep->entries[i].vddc; - if (od_vddc_lookup_table->entries[i].us_vdd < podn_vdd_dep->entries[i].vddc) + for (i = 0; i < podn_vdd_dep->count; i++) od_vddc_lookup_table->entries[i].us_vdd = podn_vdd_dep->entries[i].vddc; } else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) { podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk; -- GitLab From 30ef5c7eaba0ddafc6c23eca65ebe52169dfcc60 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 29 Oct 2019 17:14:15 -0400 Subject: [PATCH 906/993] drm/amdgpu/gmc10: properly set BANK_SELECT and FRAGMENT_SIZE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These were not aligned for optimal performance for GPUVM. Acked-by: Christian König Reviewed-by: Tianci Yin Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c | 9 +++++++++ drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c index 8b789f750b72..db10640a3b2f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c @@ -151,6 +151,15 @@ static void gfxhub_v2_0_init_cache_regs(struct amdgpu_device *adev) WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL2, tmp); tmp = mmGCVM_L2_CNTL3_DEFAULT; + if (adev->gmc.translate_further) { + tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 12); + tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, + L2_CACHE_BIGK_FRAGMENT_SIZE, 9); + } else { + tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, BANK_SELECT, 9); + tmp = REG_SET_FIELD(tmp, GCVM_L2_CNTL3, + L2_CACHE_BIGK_FRAGMENT_SIZE, 6); + } WREG32_SOC15(GC, 0, mmGCVM_L2_CNTL3, tmp); tmp = mmGCVM_L2_CNTL4_DEFAULT; diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c index 3542c203c3c8..b39bea6f54e9 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c @@ -137,6 +137,15 @@ static void mmhub_v2_0_init_cache_regs(struct amdgpu_device *adev) WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL2, tmp); tmp = mmMMVM_L2_CNTL3_DEFAULT; + if (adev->gmc.translate_further) { + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 12); + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, + L2_CACHE_BIGK_FRAGMENT_SIZE, 9); + } else { + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, BANK_SELECT, 9); + tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL3, + L2_CACHE_BIGK_FRAGMENT_SIZE, 6); + } WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL3, tmp); tmp = mmMMVM_L2_CNTL4_DEFAULT; -- GitLab From 722608433c945c52b9ccb649c716a6c6c9012ce2 Mon Sep 17 00:00:00 2001 From: Kyle Mahlkuch Date: Fri, 25 Oct 2019 15:40:50 -0500 Subject: [PATCH 907/993] drm/radeon: Fix EEH during kexec During kexec some adapters hit an EEH since they are not properly shut down in the radeon_pci_shutdown() function. Adding radeon_suspend_kms() fixes this issue. Enabled only on PPC because this patch causes issues on some other boards. Signed-off-by: Kyle Mahlkuch Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_drv.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 9e55076578c6..4528f4dc0b2d 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -379,11 +379,25 @@ radeon_pci_remove(struct pci_dev *pdev) static void radeon_pci_shutdown(struct pci_dev *pdev) { +#ifdef CONFIG_PPC64 + struct drm_device *ddev = pci_get_drvdata(pdev); +#endif + /* if we are running in a VM, make sure the device * torn down properly on reboot/shutdown */ if (radeon_device_is_virtual()) radeon_pci_remove(pdev); + +#ifdef CONFIG_PPC64 + /* Some adapters need to be suspended before a + * shutdown occurs in order to prevent an error + * during kexec. + * Make this power specific becauase it breaks + * some non-power boards. + */ + radeon_suspend_kms(ddev, true, true, false); +#endif } static int radeon_pmops_suspend(struct device *dev) -- GitLab From c868868f6b6a5272350781f9a19b3a5ba1c00b02 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Wed, 16 Oct 2019 16:02:07 -0700 Subject: [PATCH 908/993] drm/amdgpu: fix stack alignment ABI mismatch for Clang The x86 kernel is compiled with an 8B stack alignment via `-mpreferred-stack-boundary=3` for GCC since 3.6-rc1 via commit d9b0cde91c60 ("x86-64, gcc: Use -mpreferred-stack-boundary=3 if supported") or `-mstack-alignment=8` for Clang. Parts of the AMDGPU driver are compiled with 16B stack alignment. Generally, the stack alignment is part of the ABI. Linking together two different translation units with differing stack alignment is dangerous, particularly when the translation unit with the smaller stack alignment makes calls into the translation unit with the larger stack alignment. While 8B aligned stacks are sometimes also 16B aligned, they are not always. Multiple users have reported General Protection Faults (GPF) when using the AMDGPU driver compiled with Clang. Clang is placing objects in stack slots assuming the stack is 16B aligned, and selecting instructions that require 16B aligned memory operands. At runtime, syscall handlers with 8B aligned stack call into code that assumes 16B stack alignment. When the stack is a multiple of 8B but not 16B, these instructions result in a GPF. Remove the code that added compatibility between the differing compiler flags, as it will result in runtime GPFs when built with Clang. Cleanups for GCC will be sent in later patches in the series. Link: https://github.com/ClangBuiltLinux/linux/issues/735 Debugged-by: Yuxuan Shui Reported-by: Shirish S Reported-by: Yuxuan Shui Suggested-by: Andrew Cooper Signed-off-by: Nick Desaulniers Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/calcs/Makefile | 10 ++++------ drivers/gpu/drm/amd/display/dc/dcn20/Makefile | 10 ++++------ drivers/gpu/drm/amd/display/dc/dcn21/Makefile | 10 ++++------ drivers/gpu/drm/amd/display/dc/dml/Makefile | 10 ++++------ drivers/gpu/drm/amd/display/dc/dsc/Makefile | 10 ++++------ 5 files changed, 20 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile b/drivers/gpu/drm/amd/display/dc/calcs/Makefile index 985633c08a26..4b1a8a08a5de 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile +++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile @@ -24,13 +24,11 @@ # It calculates Bandwidth and Watermarks values for HW programming # -ifneq ($(call cc-option, -mpreferred-stack-boundary=4),) - cc_stack_align := -mpreferred-stack-boundary=4 -else ifneq ($(call cc-option, -mstack-alignment=16),) - cc_stack_align := -mstack-alignment=16 -endif +calcs_ccflags := -mhard-float -msse -calcs_ccflags := -mhard-float -msse $(cc_stack_align) +ifdef CONFIG_CC_IS_GCC +calcs_ccflags += -mpreferred-stack-boundary=4 +endif ifdef CONFIG_CC_IS_CLANG calcs_ccflags += -msse2 diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile index ddb8d5649e79..5fe3eb80075d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile @@ -10,13 +10,11 @@ ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT DCN20 += dcn20_dsc.o endif -ifneq ($(call cc-option, -mpreferred-stack-boundary=4),) - cc_stack_align := -mpreferred-stack-boundary=4 -else ifneq ($(call cc-option, -mstack-alignment=16),) - cc_stack_align := -mstack-alignment=16 -endif +CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mhard-float -msse -CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mhard-float -msse $(cc_stack_align) +ifdef CONFIG_CC_IS_GCC +CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o += -mpreferred-stack-boundary=4 +endif ifdef CONFIG_CC_IS_CLANG CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o += -msse2 diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile index ef673bffc241..7057e20748b9 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile @@ -3,13 +3,11 @@ DCN21 = dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o -ifneq ($(call cc-option, -mpreferred-stack-boundary=4),) - cc_stack_align := -mpreferred-stack-boundary=4 -else ifneq ($(call cc-option, -mstack-alignment=16),) - cc_stack_align := -mstack-alignment=16 -endif +CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -msse -CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -msse $(cc_stack_align) +ifdef CONFIG_CC_IS_GCC +CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o += -mpreferred-stack-boundary=4 +endif ifdef CONFIG_CC_IS_CLANG CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o += -msse2 diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index 5b2a65b42403..1bd6e307b7f8 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -24,13 +24,11 @@ # It provides the general basic services required by other DAL # subcomponents. -ifneq ($(call cc-option, -mpreferred-stack-boundary=4),) - cc_stack_align := -mpreferred-stack-boundary=4 -else ifneq ($(call cc-option, -mstack-alignment=16),) - cc_stack_align := -mstack-alignment=16 -endif +dml_ccflags := -mhard-float -msse -dml_ccflags := -mhard-float -msse $(cc_stack_align) +ifdef CONFIG_CC_IS_GCC +dml_ccflags += -mpreferred-stack-boundary=4 +endif ifdef CONFIG_CC_IS_CLANG dml_ccflags += -msse2 diff --git a/drivers/gpu/drm/amd/display/dc/dsc/Makefile b/drivers/gpu/drm/amd/display/dc/dsc/Makefile index b456cd23c6fa..932c3055230e 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dsc/Makefile @@ -1,13 +1,11 @@ # # Makefile for the 'dsc' sub-component of DAL. -ifneq ($(call cc-option, -mpreferred-stack-boundary=4),) - cc_stack_align := -mpreferred-stack-boundary=4 -else ifneq ($(call cc-option, -mstack-alignment=16),) - cc_stack_align := -mstack-alignment=16 -endif +dsc_ccflags := -mhard-float -msse -dsc_ccflags := -mhard-float -msse $(cc_stack_align) +ifdef CONFIG_CC_IS_GCC +dsc_ccflags += -mpreferred-stack-boundary=4 +endif ifdef CONFIG_CC_IS_CLANG dsc_ccflags += -msse2 -- GitLab From 00db297106e81770e7c4319014a67896053b5a22 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Wed, 16 Oct 2019 16:02:08 -0700 Subject: [PATCH 909/993] drm/amdgpu: fix stack alignment ABI mismatch for GCC 7.1+ GCC earlier than 7.1 errors when compiling code that makes use of `double`s and sets a stack alignment outside of the range of [2^4-2^12]: $ cat foo.c double foo(double x, double y) { return x + y; } $ gcc-4.9 -mpreferred-stack-boundary=3 foo.c error: -mpreferred-stack-boundary=3 is not between 4 and 12 This is likely why the AMDGPU driver was ever compiled with a different stack alignment (and thus different ABI) than the rest of the x86 kernel. The kernel uses 8B stack alignment, while the driver was using 16B stack alignment in a few places. Since GCC 7.1+ doesn't error, fix the ABI mismatch for users of newer versions of GCC. There was discussion about whether to mark the driver broken or not for users of GCC earlier than 7.1, but since the driver currently is working, don't explicitly break the driver for them here. Relying on differing stack alignment is unspecified behavior, and brittle, and may break in the future. This patch is no functional change for GCC users earlier than 7.1. It's been compile tested on GCC 4.9 and 8.3 to check the correct flags. It should be boot tested when built with GCC 7.1+. -mincoming-stack-boundary= or -mstackrealign may help keep this code building for pre-GCC 7.1 users. The version check for GCC is broken into two conditionals, both because cc-ifversion is currently GCC specific, and it simplifies a subsequent patch. Signed-off-by: Nick Desaulniers Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/calcs/Makefile | 9 +++++++++ drivers/gpu/drm/amd/display/dc/dcn20/Makefile | 9 +++++++++ drivers/gpu/drm/amd/display/dc/dcn21/Makefile | 9 +++++++++ drivers/gpu/drm/amd/display/dc/dml/Makefile | 9 +++++++++ drivers/gpu/drm/amd/display/dc/dsc/Makefile | 9 +++++++++ 5 files changed, 45 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile b/drivers/gpu/drm/amd/display/dc/calcs/Makefile index 4b1a8a08a5de..a1af55a86508 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile +++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile @@ -27,6 +27,15 @@ calcs_ccflags := -mhard-float -msse ifdef CONFIG_CC_IS_GCC +ifeq ($(call cc-ifversion, -lt, 0701, y), y) +IS_OLD_GCC = 1 +endif +endif + +ifdef IS_OLD_GCC +# Stack alignment mismatch, proceed with caution. +# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 +# (8B stack alignment). calcs_ccflags += -mpreferred-stack-boundary=4 endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile index 5fe3eb80075d..cb0ac131f74a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile @@ -13,6 +13,15 @@ endif CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o := -mhard-float -msse ifdef CONFIG_CC_IS_GCC +ifeq ($(call cc-ifversion, -lt, 0701, y), y) +IS_OLD_GCC = 1 +endif +endif + +ifdef IS_OLD_GCC +# Stack alignment mismatch, proceed with caution. +# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 +# (8B stack alignment). CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o += -mpreferred-stack-boundary=4 endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile index 7057e20748b9..f92320ddd27f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile @@ -6,6 +6,15 @@ DCN21 = dcn21_hubp.o dcn21_hubbub.o dcn21_resource.o CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o := -mhard-float -msse ifdef CONFIG_CC_IS_GCC +ifeq ($(call cc-ifversion, -lt, 0701, y), y) +IS_OLD_GCC = 1 +endif +endif + +ifdef IS_OLD_GCC +# Stack alignment mismatch, proceed with caution. +# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 +# (8B stack alignment). CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o += -mpreferred-stack-boundary=4 endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index 1bd6e307b7f8..ef1bdd20b425 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -27,6 +27,15 @@ dml_ccflags := -mhard-float -msse ifdef CONFIG_CC_IS_GCC +ifeq ($(call cc-ifversion, -lt, 0701, y), y) +IS_OLD_GCC = 1 +endif +endif + +ifdef IS_OLD_GCC +# Stack alignment mismatch, proceed with caution. +# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 +# (8B stack alignment). dml_ccflags += -mpreferred-stack-boundary=4 endif diff --git a/drivers/gpu/drm/amd/display/dc/dsc/Makefile b/drivers/gpu/drm/amd/display/dc/dsc/Makefile index 932c3055230e..3f7840828a9f 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dsc/Makefile @@ -4,6 +4,15 @@ dsc_ccflags := -mhard-float -msse ifdef CONFIG_CC_IS_GCC +ifeq ($(call cc-ifversion, -lt, 0701, y), y) +IS_OLD_GCC = 1 +endif +endif + +ifdef IS_OLD_GCC +# Stack alignment mismatch, proceed with caution. +# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 +# (8B stack alignment). dsc_ccflags += -mpreferred-stack-boundary=4 endif -- GitLab From e8a170ff9a3576730e43c0dbdd27b7cd3dc56848 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Wed, 16 Oct 2019 16:02:09 -0700 Subject: [PATCH 910/993] drm/amdgpu: enable -msse2 for GCC 7.1+ users A final attempt at enabling sse2 for GCC users. Orininally attempted in: commit 10117450735c ("drm/amd/display: add -msse2 to prevent Clang from emitting libcalls to undefined SW FP routines") Reverted due to "reported instability" in: commit 193392ed9f69 ("Revert "drm/amd/display: add -msse2 to prevent Clang from emitting libcalls to undefined SW FP routines"") Re-added just for Clang in: commit 0f0727d971f6 ("drm/amd/display: readd -msse2 to prevent Clang from emitting libcalls to undefined SW FP routines") The original report didn't have enough information to know if the GPF was due to misalignment, but I suspect that it was. (The missing information was the disassembly of the function at the bottom of the trace, to see if the instruction pointer pointed to an instruction with 16B alignment memory operand requirements. The stack trace does show the stack was only 8B but not 16B aligned though, which makes this a strong possibility). Now that the stack misalignment issue has been fixed for users of GCC 7.1+, reattempt adding -msse2. This matches Clang. It will likely never be safe to enable this for pre-GCC 7.1 AND use a 16B aligned stack in these translation units. This is only a functional change for GCC 7.1+ users, and should be boot tested. Link: https://bugs.freedesktop.org/show_bug.cgi?id=109487 Signed-off-by: Nick Desaulniers Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/calcs/Makefile | 4 +--- drivers/gpu/drm/amd/display/dc/dcn20/Makefile | 4 +--- drivers/gpu/drm/amd/display/dc/dcn21/Makefile | 4 +--- drivers/gpu/drm/amd/display/dc/dml/Makefile | 4 +--- drivers/gpu/drm/amd/display/dc/dsc/Makefile | 4 +--- 5 files changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/calcs/Makefile b/drivers/gpu/drm/amd/display/dc/calcs/Makefile index a1af55a86508..26c6d735cdc7 100644 --- a/drivers/gpu/drm/amd/display/dc/calcs/Makefile +++ b/drivers/gpu/drm/amd/display/dc/calcs/Makefile @@ -37,9 +37,7 @@ ifdef IS_OLD_GCC # GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 # (8B stack alignment). calcs_ccflags += -mpreferred-stack-boundary=4 -endif - -ifdef CONFIG_CC_IS_CLANG +else calcs_ccflags += -msse2 endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile index cb0ac131f74a..63f3bddba7da 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn20/Makefile @@ -23,9 +23,7 @@ ifdef IS_OLD_GCC # GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 # (8B stack alignment). CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o += -mpreferred-stack-boundary=4 -endif - -ifdef CONFIG_CC_IS_CLANG +else CFLAGS_$(AMDDALPATH)/dc/dcn20/dcn20_resource.o += -msse2 endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile index f92320ddd27f..ff50ae71fe27 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dcn21/Makefile @@ -16,9 +16,7 @@ ifdef IS_OLD_GCC # GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 # (8B stack alignment). CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o += -mpreferred-stack-boundary=4 -endif - -ifdef CONFIG_CC_IS_CLANG +else CFLAGS_$(AMDDALPATH)/dc/dcn21/dcn21_resource.o += -msse2 endif diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile index ef1bdd20b425..8df251626e22 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile @@ -37,9 +37,7 @@ ifdef IS_OLD_GCC # GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 # (8B stack alignment). dml_ccflags += -mpreferred-stack-boundary=4 -endif - -ifdef CONFIG_CC_IS_CLANG +else dml_ccflags += -msse2 endif diff --git a/drivers/gpu/drm/amd/display/dc/dsc/Makefile b/drivers/gpu/drm/amd/display/dc/dsc/Makefile index 3f7840828a9f..970737217e53 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dsc/Makefile @@ -14,9 +14,7 @@ ifdef IS_OLD_GCC # GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 # (8B stack alignment). dsc_ccflags += -mpreferred-stack-boundary=4 -endif - -ifdef CONFIG_CC_IS_CLANG +else dsc_ccflags += -msse2 endif -- GitLab From 875f0706accd6501c3209bb99df8573171fb5d75 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 17 Oct 2019 09:02:19 -0400 Subject: [PATCH 911/993] SUNRPC: The TCP back channel mustn't disappear while requests are outstanding If there are TCP back channel requests being processed by the server threads, then we should hold a reference to the transport to ensure it doesn't get freed from underneath us. Reported-by: Neil Brown Fixes: 2ea24497a1b3 ("SUNRPC: RPC callbacks may be split across several..") Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- net/sunrpc/backchannel_rqst.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 339e8c077c2d..7eb251372f94 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c @@ -307,8 +307,8 @@ void xprt_free_bc_rqst(struct rpc_rqst *req) */ dprintk("RPC: Last session removed req=%p\n", req); xprt_free_allocation(req); - return; } + xprt_put(xprt); } /* @@ -339,7 +339,7 @@ struct rpc_rqst *xprt_lookup_bc_request(struct rpc_xprt *xprt, __be32 xid) spin_unlock(&xprt->bc_pa_lock); if (new) { if (req != new) - xprt_free_bc_rqst(new); + xprt_free_allocation(new); break; } else if (req) break; @@ -368,6 +368,7 @@ void xprt_complete_bc_request(struct rpc_rqst *req, uint32_t copied) set_bit(RPC_BC_PA_IN_USE, &req->rq_bc_pa_state); dprintk("RPC: add callback request to list\n"); + xprt_get(xprt); spin_lock(&bc_serv->sv_cb_lock); list_add(&req->rq_bc_list, &bc_serv->sv_cb_list); wake_up(&bc_serv->sv_cb_waitq); -- GitLab From 9edb455e6797bb50aa38ef71e62668966065ede8 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 17 Oct 2019 09:02:20 -0400 Subject: [PATCH 912/993] SUNRPC: The RDMA back channel mustn't disappear while requests are outstanding If there are RDMA back channel requests being processed by the server threads, then we should hold a reference to the transport to ensure it doesn't get freed from underneath us. Reported-by: Neil Brown Fixes: 63cae47005af ("xprtrdma: Handle incoming backward direction RPC calls") Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- net/sunrpc/xprtrdma/backchannel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c index 50e075fcdd8f..b458bf53ca69 100644 --- a/net/sunrpc/xprtrdma/backchannel.c +++ b/net/sunrpc/xprtrdma/backchannel.c @@ -163,6 +163,7 @@ void xprt_rdma_bc_free_rqst(struct rpc_rqst *rqst) spin_lock(&xprt->bc_pa_lock); list_add_tail(&rqst->rq_bc_pa_list, &xprt->bc_pa_list); spin_unlock(&xprt->bc_pa_lock); + xprt_put(xprt); } static struct rpc_rqst *rpcrdma_bc_rqst_get(struct rpcrdma_xprt *r_xprt) @@ -259,6 +260,7 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt, /* Queue rqst for ULP's callback service */ bc_serv = xprt->bc_serv; + xprt_get(xprt); spin_lock(&bc_serv->sv_cb_lock); list_add(&rqst->rq_bc_list, &bc_serv->sv_cb_list); spin_unlock(&bc_serv->sv_cb_lock); -- GitLab From 669996add4c92476e0f8d6b4cd2bb308d1939fd7 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 17 Oct 2019 09:02:21 -0400 Subject: [PATCH 913/993] SUNRPC: Destroy the back channel when we destroy the host transport When we're destroying the host transport mechanism, we should ensure that we do not leak memory by failing to release any back channel slots that might still exist. Reported-by: Neil Brown Reported-by: kbuild test robot Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- include/linux/sunrpc/bc_xprt.h | 5 +++++ net/sunrpc/backchannel_rqst.c | 2 +- net/sunrpc/xprt.c | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/linux/sunrpc/bc_xprt.h b/include/linux/sunrpc/bc_xprt.h index 87d27e13d885..d796058cdff2 100644 --- a/include/linux/sunrpc/bc_xprt.h +++ b/include/linux/sunrpc/bc_xprt.h @@ -64,6 +64,11 @@ static inline int xprt_setup_backchannel(struct rpc_xprt *xprt, return 0; } +static inline void xprt_destroy_backchannel(struct rpc_xprt *xprt, + unsigned int max_reqs) +{ +} + static inline bool svc_is_backchannel(const struct svc_rqst *rqstp) { return false; diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 7eb251372f94..195b40c5dae4 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c @@ -220,7 +220,7 @@ void xprt_destroy_bc(struct rpc_xprt *xprt, unsigned int max_reqs) goto out; spin_lock_bh(&xprt->bc_pa_lock); - xprt->bc_alloc_max -= max_reqs; + xprt->bc_alloc_max -= min(max_reqs, xprt->bc_alloc_max); list_for_each_entry_safe(req, tmp, &xprt->bc_pa_list, rq_bc_pa_list) { dprintk("RPC: req=%p\n", req); list_del(&req->rq_bc_pa_list); diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 8a45b3ccc313..41df4c507193 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -1942,6 +1942,11 @@ static void xprt_destroy_cb(struct work_struct *work) rpc_destroy_wait_queue(&xprt->sending); rpc_destroy_wait_queue(&xprt->backlog); kfree(xprt->servername); + /* + * Destroy any existing back channel + */ + xprt_destroy_backchannel(xprt, UINT_MAX); + /* * Tear down transport state and free the rpc_xprt */ -- GitLab From dc99da4f31ce48d15684bde7916104064520025c Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 30 Oct 2019 08:59:22 +0100 Subject: [PATCH 914/993] qed: fix spelling mistake "queuess" -> "queues" There is a spelling misake in a DP_NOTICE message. Fix it. Signed-off-by: Colin Ian King Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_sriov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c b/drivers/net/ethernet/qlogic/qed/qed_sriov.c index 78f77b712b10..dcb5c917f373 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c +++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c @@ -2005,7 +2005,7 @@ static void qed_iov_vf_mbx_stop_vport(struct qed_hwfn *p_hwfn, (qed_iov_validate_active_txq(p_hwfn, vf))) { vf->b_malicious = true; DP_NOTICE(p_hwfn, - "VF [%02x] - considered malicious; Unable to stop RX/TX queuess\n", + "VF [%02x] - considered malicious; Unable to stop RX/TX queues\n", vf->abs_vf_id); status = PFVF_STATUS_MALICIOUS; goto out; -- GitLab From c6761cf521f9bffbdcbb619dba665ebf3bcefb1e Mon Sep 17 00:00:00 2001 From: Taehee Yoo Date: Wed, 30 Oct 2019 08:15:12 +0000 Subject: [PATCH 915/993] vxlan: fix unexpected failure of vxlan_changelink() After commit 0ce1822c2a08 ("vxlan: add adjacent link to limit depth level"), vxlan_changelink() could fail because of netdev_adjacent_change_prepare(). netdev_adjacent_change_prepare() returns -EEXIST when old lower device and new lower device are same. (old lower device is "dst->remote_dev" and new lower device is "lowerdev") So, before calling it, lowerdev should be NULL if these devices are same. Test command1: ip link add dummy0 type dummy ip link add vxlan0 type vxlan dev dummy0 dstport 4789 vni 1 ip link set vxlan0 type vxlan ttl 5 RTNETLINK answers: File exists Reported-by: Dan Carpenter Fixes: 0ce1822c2a08 ("vxlan: add adjacent link to limit depth level") Signed-off-by: Taehee Yoo Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index ac5c597aa703..8869154fad88 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -3967,6 +3967,9 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], if (err) return err; + if (dst->remote_dev == lowerdev) + lowerdev = NULL; + err = netdev_adjacent_change_prepare(dst->remote_dev, lowerdev, dev, extack); if (err) @@ -4008,10 +4011,10 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], mod_timer(&vxlan->age_timer, jiffies); netdev_adjacent_change_commit(dst->remote_dev, lowerdev, dev); - if (lowerdev && lowerdev != dst->remote_dev) + if (lowerdev && lowerdev != dst->remote_dev) { dst->remote_dev = lowerdev; - - netdev_update_lockdep_key(lowerdev); + netdev_update_lockdep_key(lowerdev); + } vxlan_config_apply(dev, &conf, lowerdev, vxlan->net, true); return 0; } -- GitLab From c63b0968946b2d72178a92793bcc9439e19b385f Mon Sep 17 00:00:00 2001 From: Sudarsana Reddy Kalluru Date: Wed, 30 Oct 2019 01:39:58 -0700 Subject: [PATCH 916/993] qed: Optimize execution time for nvm attributes configuration. Current implementation for nvm_attr configuration instructs the management FW to load/unload the nvm-cfg image for each user-provided attribute in the input file. This consumes lot of cycles even for few tens of attributes. This patch updates the implementation to perform load/commit of the config for every 50 attributes. After loading the nvm-image, MFW expects that config should be committed in a predefined timer value (5 sec), hence it's not possible to write large number of attributes in a single load/commit window. Hence performing the commits in chunks. Fixes: 0dabbe1bb3a4 ("qed: Add driver API for flashing the config attributes.") Signed-off-by: Sudarsana Reddy Kalluru Signed-off-by: Ariel Elior Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_main.c | 27 +++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 2ce70097d018..38f7f40b3a4d 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -67,10 +67,9 @@ #define QED_ROCE_QPS (8192) #define QED_ROCE_DPIS (8) #define QED_RDMA_SRQS QED_ROCE_QPS -#define QED_NVM_CFG_SET_FLAGS 0xE -#define QED_NVM_CFG_SET_PF_FLAGS 0x1E #define QED_NVM_CFG_GET_FLAGS 0xA #define QED_NVM_CFG_GET_PF_FLAGS 0x1A +#define QED_NVM_CFG_MAX_ATTRS 50 static char version[] = "QLogic FastLinQ 4xxxx Core Module qed " DRV_MODULE_VERSION "\n"; @@ -2255,6 +2254,7 @@ static int qed_nvm_flash_cfg_write(struct qed_dev *cdev, const u8 **data) { struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); u8 entity_id, len, buf[32]; + bool need_nvm_init = true; struct qed_ptt *ptt; u16 cfg_id, count; int rc = 0, i; @@ -2271,8 +2271,10 @@ static int qed_nvm_flash_cfg_write(struct qed_dev *cdev, const u8 **data) DP_VERBOSE(cdev, NETIF_MSG_DRV, "Read config ids: num_attrs = %0d\n", count); - /* NVM CFG ID attributes */ - for (i = 0; i < count; i++) { + /* NVM CFG ID attributes. Start loop index from 1 to avoid additional + * arithmetic operations in the implementation. + */ + for (i = 1; i <= count; i++) { cfg_id = *((u16 *)*data); *data += 2; entity_id = **data; @@ -2282,8 +2284,21 @@ static int qed_nvm_flash_cfg_write(struct qed_dev *cdev, const u8 **data) memcpy(buf, *data, len); *data += len; - flags = entity_id ? QED_NVM_CFG_SET_PF_FLAGS : - QED_NVM_CFG_SET_FLAGS; + flags = 0; + if (need_nvm_init) { + flags |= QED_NVM_CFG_OPTION_INIT; + need_nvm_init = false; + } + + /* Commit to flash and free the resources */ + if (!(i % QED_NVM_CFG_MAX_ATTRS) || i == count) { + flags |= QED_NVM_CFG_OPTION_COMMIT | + QED_NVM_CFG_OPTION_FREE; + need_nvm_init = true; + } + + if (entity_id) + flags |= QED_NVM_CFG_OPTION_ENTITY_SEL; DP_VERBOSE(cdev, NETIF_MSG_DRV, "cfg_id = %d entity = %d len = %d\n", cfg_id, -- GitLab From b7265a0df82c1716bf788096217083ed65a8bb14 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 30 Oct 2019 11:04:22 +0200 Subject: [PATCH 917/993] mlxsw: core: Unpublish devlink parameters during reload The devlink parameter "acl_region_rehash_interval" is a runtime parameter whose value is stored in a dynamically allocated memory. While reloading the driver, this memory is freed and then allocated again. A use-after-free might happen if during this time frame someone tries to retrieve its value. Since commit 070c63f20f6c ("net: devlink: allow to change namespaces during reload") the use-after-free can be reliably triggered when reloading the driver into a namespace, as after freeing the memory (via reload_down() callback) all the parameters are notified. Fix this by unpublishing and then re-publishing the parameters during reload. Fixes: 98bbf70c1c41 ("mlxsw: spectrum: add "acl_region_rehash_interval" devlink param") Fixes: 7c62cfb8c574 ("devlink: publish params only after driver init is done") Signed-off-by: Jiri Pirko Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index 14dcc786926d..4421ab22182f 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -1186,7 +1186,7 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info, if (err) goto err_thermal_init; - if (mlxsw_driver->params_register && !reload) + if (mlxsw_driver->params_register) devlink_params_publish(devlink); return 0; @@ -1259,7 +1259,7 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core, return; } - if (mlxsw_core->driver->params_unregister && !reload) + if (mlxsw_core->driver->params_unregister) devlink_params_unpublish(devlink); mlxsw_thermal_fini(mlxsw_core->thermal); mlxsw_hwmon_fini(mlxsw_core->hwmon); -- GitLab From 0208947ce8da91ac728b07b0611ddc8c16b0478e Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 9 Oct 2019 16:34:16 -0700 Subject: [PATCH 918/993] FROMLIST: fscrypt: invoke crypto API for ESSIV handling Instead of open-coding the calculations for ESSIV handling, use an ESSIV skcipher which does all of this under the hood. ESSIV was added to the crypto API in v5.4. This is based on a patch from Ard Biesheuvel, but reworked to apply after all the fscrypt changes that went into v5.4. Tested with 'kvm-xfstests -c ext4,f2fs -g encrypt', including the ciphertext verification tests for v1 and v2 encryption policies. Change-Id: I1b09160c0135a2d8b16db7b4139d22b903ec6a8e Originally-from: Ard Biesheuvel Acked-by: Ard Biesheuvel Signed-off-by: Eric Biggers Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11182383/ --- Documentation/filesystems/fscrypt.rst | 5 +- fs/crypto/crypto.c | 4 - fs/crypto/fscrypt_private.h | 7 -- fs/crypto/keysetup.c | 110 +++----------------------- fs/crypto/keysetup_v1.c | 4 - 5 files changed, 14 insertions(+), 116 deletions(-) diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index 8a0700af9596..6ec459be3de1 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -308,8 +308,9 @@ If unsure, you should use the (AES-256-XTS, AES-256-CTS-CBC) pair. AES-128-CBC was added only for low-powered embedded devices with crypto accelerators such as CAAM or CESA that do not support XTS. To -use AES-128-CBC, CONFIG_CRYPTO_SHA256 (or another SHA-256 -implementation) must be enabled so that ESSIV can be used. +use AES-128-CBC, CONFIG_CRYPTO_ESSIV and CONFIG_CRYPTO_SHA256 (or +another SHA-256 implementation) must be enabled so that ESSIV can be +used. Adiantum is a (primarily) stream cipher-based mode that is fast even on CPUs without dedicated crypto instructions. It's also a true diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 32a7ad0098cc..6bc3e4f1e657 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include "fscrypt_private.h" @@ -143,9 +142,6 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num, if (fscrypt_is_direct_key_policy(&ci->ci_policy)) memcpy(iv->nonce, ci->ci_nonce, FS_KEY_DERIVATION_NONCE_SIZE); - - if (ci->ci_essiv_tfm != NULL) - crypto_cipher_encrypt_one(ci->ci_essiv_tfm, iv->raw, iv->raw); } /* Encrypt or decrypt a single filesystem block of file contents */ diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index e84efc01512e..76c64297ce18 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -163,12 +163,6 @@ struct fscrypt_info { /* The actual crypto transform used for encryption and decryption */ struct crypto_skcipher *ci_ctfm; - /* - * Cipher for ESSIV IV generation. Only set for CBC contents - * encryption, otherwise is NULL. - */ - struct crypto_cipher *ci_essiv_tfm; - /* * Encryption mode used for this inode. It corresponds to either the * contents or filenames encryption mode, depending on the inode type. @@ -444,7 +438,6 @@ struct fscrypt_mode { int keysize; int ivsize; bool logged_impl_name; - bool needs_essiv; }; static inline bool diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index d71c2d6dd162..8eb5a0e762ec 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -8,15 +8,11 @@ * Heavily modified since then. */ -#include -#include #include #include #include "fscrypt_private.h" -static struct crypto_shash *essiv_hash_tfm; - static struct fscrypt_mode available_modes[] = { [FSCRYPT_MODE_AES_256_XTS] = { .friendly_name = "AES-256-XTS", @@ -31,11 +27,10 @@ static struct fscrypt_mode available_modes[] = { .ivsize = 16, }, [FSCRYPT_MODE_AES_128_CBC] = { - .friendly_name = "AES-128-CBC", - .cipher_str = "cbc(aes)", + .friendly_name = "AES-128-CBC-ESSIV", + .cipher_str = "essiv(cbc(aes),sha256)", .keysize = 16, .ivsize = 16, - .needs_essiv = true, }, [FSCRYPT_MODE_AES_128_CTS] = { .friendly_name = "AES-128-CTS-CBC", @@ -111,97 +106,16 @@ struct crypto_skcipher *fscrypt_allocate_skcipher(struct fscrypt_mode *mode, return ERR_PTR(err); } -static int derive_essiv_salt(const u8 *key, int keysize, u8 *salt) -{ - struct crypto_shash *tfm = READ_ONCE(essiv_hash_tfm); - - /* init hash transform on demand */ - if (unlikely(!tfm)) { - struct crypto_shash *prev_tfm; - - tfm = crypto_alloc_shash("sha256", 0, 0); - if (IS_ERR(tfm)) { - if (PTR_ERR(tfm) == -ENOENT) { - fscrypt_warn(NULL, - "Missing crypto API support for SHA-256"); - return -ENOPKG; - } - fscrypt_err(NULL, - "Error allocating SHA-256 transform: %ld", - PTR_ERR(tfm)); - return PTR_ERR(tfm); - } - prev_tfm = cmpxchg(&essiv_hash_tfm, NULL, tfm); - if (prev_tfm) { - crypto_free_shash(tfm); - tfm = prev_tfm; - } - } - - { - SHASH_DESC_ON_STACK(desc, tfm); - desc->tfm = tfm; - - return crypto_shash_digest(desc, key, keysize, salt); - } -} - -static int init_essiv_generator(struct fscrypt_info *ci, const u8 *raw_key, - int keysize) -{ - int err; - struct crypto_cipher *essiv_tfm; - u8 salt[SHA256_DIGEST_SIZE]; - - if (WARN_ON(ci->ci_mode->ivsize != AES_BLOCK_SIZE)) - return -EINVAL; - - essiv_tfm = crypto_alloc_cipher("aes", 0, 0); - if (IS_ERR(essiv_tfm)) - return PTR_ERR(essiv_tfm); - - ci->ci_essiv_tfm = essiv_tfm; - - err = derive_essiv_salt(raw_key, keysize, salt); - if (err) - goto out; - - /* - * Using SHA256 to derive the salt/key will result in AES-256 being - * used for IV generation. File contents encryption will still use the - * configured keysize (AES-128) nevertheless. - */ - err = crypto_cipher_setkey(essiv_tfm, salt, sizeof(salt)); - if (err) - goto out; - -out: - memzero_explicit(salt, sizeof(salt)); - return err; -} - -/* Given the per-file key, set up the file's crypto transform object(s) */ +/* Given the per-file key, set up the file's crypto transform object */ int fscrypt_set_derived_key(struct fscrypt_info *ci, const u8 *derived_key) { - struct fscrypt_mode *mode = ci->ci_mode; - struct crypto_skcipher *ctfm; - int err; - - ctfm = fscrypt_allocate_skcipher(mode, derived_key, ci->ci_inode); - if (IS_ERR(ctfm)) - return PTR_ERR(ctfm); + struct crypto_skcipher *tfm; - ci->ci_ctfm = ctfm; + tfm = fscrypt_allocate_skcipher(ci->ci_mode, derived_key, ci->ci_inode); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); - if (mode->needs_essiv) { - err = init_essiv_generator(ci, derived_key, mode->keysize); - if (err) { - fscrypt_warn(ci->ci_inode, - "Error initializing ESSIV generator: %d", - err); - return err; - } - } + ci->ci_ctfm = tfm; return 0; } @@ -388,13 +302,11 @@ static void put_crypt_info(struct fscrypt_info *ci) if (!ci) return; - if (ci->ci_direct_key) { + if (ci->ci_direct_key) fscrypt_put_direct_key(ci->ci_direct_key); - } else if ((ci->ci_ctfm != NULL || ci->ci_essiv_tfm != NULL) && - !fscrypt_is_direct_key_policy(&ci->ci_policy)) { + else if (ci->ci_ctfm != NULL && + !fscrypt_is_direct_key_policy(&ci->ci_policy)) crypto_free_skcipher(ci->ci_ctfm); - crypto_free_cipher(ci->ci_essiv_tfm); - } key = ci->ci_master_key; if (key) { diff --git a/fs/crypto/keysetup_v1.c b/fs/crypto/keysetup_v1.c index ad1a36c370c3..5298ef22aa85 100644 --- a/fs/crypto/keysetup_v1.c +++ b/fs/crypto/keysetup_v1.c @@ -270,10 +270,6 @@ static int setup_v1_file_key_direct(struct fscrypt_info *ci, return -EINVAL; } - /* ESSIV implies 16-byte IVs which implies !DIRECT_KEY */ - if (WARN_ON(mode->needs_essiv)) - return -EINVAL; - dk = fscrypt_get_direct_key(ci, raw_master_key); if (IS_ERR(dk)) return PTR_ERR(dk); -- GitLab From bd07f40b0d49f0e320914aa933036350600f4b9f Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 9 Oct 2019 16:34:17 -0700 Subject: [PATCH 919/993] FROMLIST: fscrypt: remove struct fscrypt_ctx Now that ext4 and f2fs implement their own post-read workflow that supports both fscrypt and fsverity, the fscrypt-only workflow based around struct fscrypt_ctx is no longer used. So remove the unused code. This is based on a patch from Chandan Rajendra's "Consolidate FS read I/O callbacks code" patchset, but rebased onto the latest kernel, folded __fscrypt_decrypt_bio() into fscrypt_decrypt_bio(), cleaned up fscrypt_initialize(), and updated the commit message. Change-Id: I811addfc89f0d0f7f87f0fe2102dd276ba07e437 Originally-from: Chandan Rajendra Signed-off-by: Eric Biggers Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11182387/ --- fs/crypto/bio.c | 29 +--------- fs/crypto/crypto.c | 110 +++--------------------------------- fs/crypto/fscrypt_private.h | 2 - include/linux/fscrypt.h | 32 ----------- 4 files changed, 10 insertions(+), 163 deletions(-) diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c index 82da2510721f..1f4b8a277060 100644 --- a/fs/crypto/bio.c +++ b/fs/crypto/bio.c @@ -26,7 +26,7 @@ #include #include "fscrypt_private.h" -static void __fscrypt_decrypt_bio(struct bio *bio, bool done) +void fscrypt_decrypt_bio(struct bio *bio) { struct bio_vec *bv; struct bvec_iter_all iter_all; @@ -37,37 +37,10 @@ static void __fscrypt_decrypt_bio(struct bio *bio, bool done) bv->bv_offset); if (ret) SetPageError(page); - else if (done) - SetPageUptodate(page); - if (done) - unlock_page(page); } } - -void fscrypt_decrypt_bio(struct bio *bio) -{ - __fscrypt_decrypt_bio(bio, false); -} EXPORT_SYMBOL(fscrypt_decrypt_bio); -static void completion_pages(struct work_struct *work) -{ - struct fscrypt_ctx *ctx = container_of(work, struct fscrypt_ctx, work); - struct bio *bio = ctx->bio; - - __fscrypt_decrypt_bio(bio, true); - fscrypt_release_ctx(ctx); - bio_put(bio); -} - -void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx, struct bio *bio) -{ - INIT_WORK(&ctx->work, completion_pages); - ctx->bio = bio; - fscrypt_enqueue_decrypt_work(&ctx->work); -} -EXPORT_SYMBOL(fscrypt_enqueue_decrypt_bio); - int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, sector_t pblk, unsigned int len) { diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 6bc3e4f1e657..ced8ad9f2d01 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -31,24 +31,16 @@ #include "fscrypt_private.h" static unsigned int num_prealloc_crypto_pages = 32; -static unsigned int num_prealloc_crypto_ctxs = 128; module_param(num_prealloc_crypto_pages, uint, 0444); MODULE_PARM_DESC(num_prealloc_crypto_pages, "Number of crypto pages to preallocate"); -module_param(num_prealloc_crypto_ctxs, uint, 0444); -MODULE_PARM_DESC(num_prealloc_crypto_ctxs, - "Number of crypto contexts to preallocate"); static mempool_t *fscrypt_bounce_page_pool = NULL; -static LIST_HEAD(fscrypt_free_ctxs); -static DEFINE_SPINLOCK(fscrypt_ctx_lock); - static struct workqueue_struct *fscrypt_read_workqueue; static DEFINE_MUTEX(fscrypt_init_mutex); -static struct kmem_cache *fscrypt_ctx_cachep; struct kmem_cache *fscrypt_info_cachep; void fscrypt_enqueue_decrypt_work(struct work_struct *work) @@ -57,62 +49,6 @@ void fscrypt_enqueue_decrypt_work(struct work_struct *work) } EXPORT_SYMBOL(fscrypt_enqueue_decrypt_work); -/** - * fscrypt_release_ctx() - Release a decryption context - * @ctx: The decryption context to release. - * - * If the decryption context was allocated from the pre-allocated pool, return - * it to that pool. Else, free it. - */ -void fscrypt_release_ctx(struct fscrypt_ctx *ctx) -{ - unsigned long flags; - - if (ctx->flags & FS_CTX_REQUIRES_FREE_ENCRYPT_FL) { - kmem_cache_free(fscrypt_ctx_cachep, ctx); - } else { - spin_lock_irqsave(&fscrypt_ctx_lock, flags); - list_add(&ctx->free_list, &fscrypt_free_ctxs); - spin_unlock_irqrestore(&fscrypt_ctx_lock, flags); - } -} -EXPORT_SYMBOL(fscrypt_release_ctx); - -/** - * fscrypt_get_ctx() - Get a decryption context - * @gfp_flags: The gfp flag for memory allocation - * - * Allocate and initialize a decryption context. - * - * Return: A new decryption context on success; an ERR_PTR() otherwise. - */ -struct fscrypt_ctx *fscrypt_get_ctx(gfp_t gfp_flags) -{ - struct fscrypt_ctx *ctx; - unsigned long flags; - - /* - * First try getting a ctx from the free list so that we don't have to - * call into the slab allocator. - */ - spin_lock_irqsave(&fscrypt_ctx_lock, flags); - ctx = list_first_entry_or_null(&fscrypt_free_ctxs, - struct fscrypt_ctx, free_list); - if (ctx) - list_del(&ctx->free_list); - spin_unlock_irqrestore(&fscrypt_ctx_lock, flags); - if (!ctx) { - ctx = kmem_cache_zalloc(fscrypt_ctx_cachep, gfp_flags); - if (!ctx) - return ERR_PTR(-ENOMEM); - ctx->flags |= FS_CTX_REQUIRES_FREE_ENCRYPT_FL; - } else { - ctx->flags &= ~FS_CTX_REQUIRES_FREE_ENCRYPT_FL; - } - return ctx; -} -EXPORT_SYMBOL(fscrypt_get_ctx); - struct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags) { return mempool_alloc(fscrypt_bounce_page_pool, gfp_flags); @@ -392,17 +328,6 @@ const struct dentry_operations fscrypt_d_ops = { .d_revalidate = fscrypt_d_revalidate, }; -static void fscrypt_destroy(void) -{ - struct fscrypt_ctx *pos, *n; - - list_for_each_entry_safe(pos, n, &fscrypt_free_ctxs, free_list) - kmem_cache_free(fscrypt_ctx_cachep, pos); - INIT_LIST_HEAD(&fscrypt_free_ctxs); - mempool_destroy(fscrypt_bounce_page_pool); - fscrypt_bounce_page_pool = NULL; -} - /** * fscrypt_initialize() - allocate major buffers for fs encryption. * @cop_flags: fscrypt operations flags @@ -410,11 +335,11 @@ static void fscrypt_destroy(void) * We only call this when we start accessing encrypted files, since it * results in memory getting allocated that wouldn't otherwise be used. * - * Return: Zero on success, non-zero otherwise. + * Return: 0 on success; -errno on failure */ int fscrypt_initialize(unsigned int cop_flags) { - int i, res = -ENOMEM; + int err = 0; /* No need to allocate a bounce page pool if this FS won't use it. */ if (cop_flags & FS_CFLG_OWN_PAGES) @@ -422,29 +347,18 @@ int fscrypt_initialize(unsigned int cop_flags) mutex_lock(&fscrypt_init_mutex); if (fscrypt_bounce_page_pool) - goto already_initialized; - - for (i = 0; i < num_prealloc_crypto_ctxs; i++) { - struct fscrypt_ctx *ctx; - - ctx = kmem_cache_zalloc(fscrypt_ctx_cachep, GFP_NOFS); - if (!ctx) - goto fail; - list_add(&ctx->free_list, &fscrypt_free_ctxs); - } + goto out_unlock; + err = -ENOMEM; fscrypt_bounce_page_pool = mempool_create_page_pool(num_prealloc_crypto_pages, 0); if (!fscrypt_bounce_page_pool) - goto fail; + goto out_unlock; -already_initialized: - mutex_unlock(&fscrypt_init_mutex); - return 0; -fail: - fscrypt_destroy(); + err = 0; +out_unlock: mutex_unlock(&fscrypt_init_mutex); - return res; + return err; } void fscrypt_msg(const struct inode *inode, const char *level, @@ -490,13 +404,9 @@ static int __init fscrypt_init(void) if (!fscrypt_read_workqueue) goto fail; - fscrypt_ctx_cachep = KMEM_CACHE(fscrypt_ctx, SLAB_RECLAIM_ACCOUNT); - if (!fscrypt_ctx_cachep) - goto fail_free_queue; - fscrypt_info_cachep = KMEM_CACHE(fscrypt_info, SLAB_RECLAIM_ACCOUNT); if (!fscrypt_info_cachep) - goto fail_free_ctx; + goto fail_free_queue; err = fscrypt_init_keyring(); if (err) @@ -506,8 +416,6 @@ static int __init fscrypt_init(void) fail_free_info: kmem_cache_destroy(fscrypt_info_cachep); -fail_free_ctx: - kmem_cache_destroy(fscrypt_ctx_cachep); fail_free_queue: destroy_workqueue(fscrypt_read_workqueue); fail: diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index 76c64297ce18..dacf8fcbac3b 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -203,8 +203,6 @@ typedef enum { FS_ENCRYPT, } fscrypt_direction_t; -#define FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001 - static inline bool fscrypt_valid_enc_modes(u32 contents_mode, u32 filenames_mode) { diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 4ce4a970bb56..367fe16f6cc8 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -20,7 +20,6 @@ #define FS_CRYPTO_BLOCK_SIZE 16 -struct fscrypt_ctx; struct fscrypt_info; struct fscrypt_str { @@ -64,18 +63,6 @@ struct fscrypt_operations { unsigned int max_namelen; }; -/* Decryption work */ -struct fscrypt_ctx { - union { - struct { - struct bio *bio; - struct work_struct work; - }; - struct list_head free_list; /* Free list */ - }; - u8 flags; /* Flags */ -}; - static inline bool fscrypt_has_encryption_key(const struct inode *inode) { /* pairs with cmpxchg_release() in fscrypt_get_encryption_info() */ @@ -102,8 +89,6 @@ static inline void fscrypt_handle_d_move(struct dentry *dentry) /* crypto.c */ extern void fscrypt_enqueue_decrypt_work(struct work_struct *); -extern struct fscrypt_ctx *fscrypt_get_ctx(gfp_t); -extern void fscrypt_release_ctx(struct fscrypt_ctx *); extern struct page *fscrypt_encrypt_pagecache_blocks(struct page *page, unsigned int len, @@ -246,8 +231,6 @@ static inline bool fscrypt_match_name(const struct fscrypt_name *fname, /* bio.c */ extern void fscrypt_decrypt_bio(struct bio *); -extern void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx, - struct bio *bio); extern int fscrypt_zeroout_range(const struct inode *, pgoff_t, sector_t, unsigned int); @@ -297,16 +280,6 @@ static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work) { } -static inline struct fscrypt_ctx *fscrypt_get_ctx(gfp_t gfp_flags) -{ - return ERR_PTR(-EOPNOTSUPP); -} - -static inline void fscrypt_release_ctx(struct fscrypt_ctx *ctx) -{ - return; -} - static inline struct page *fscrypt_encrypt_pagecache_blocks(struct page *page, unsigned int len, unsigned int offs, @@ -498,11 +471,6 @@ static inline void fscrypt_decrypt_bio(struct bio *bio) { } -static inline void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx, - struct bio *bio) -{ -} - static inline int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, sector_t pblk, unsigned int len) { -- GitLab From 7ab69374a588fbf71aa9fec5c429b80123c004e0 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 9 Oct 2019 16:34:17 -0700 Subject: [PATCH 920/993] FROMLIST: fscrypt: zeroize fscrypt_info before freeing memset the struct fscrypt_info to zero before freeing. This isn't really needed currently, since there's no secret key directly in the fscrypt_info. But there's a decent chance that someone will add such a field in the future, e.g. in order to use an API that takes a raw key such as siphash(). So it's good to do this as a hardening measure. Change-Id: I0fadabcf72d36a0aa786fd5bcc5153c5dbfec8ba Signed-off-by: Eric Biggers Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11182405/ --- fs/crypto/keysetup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index 8eb5a0e762ec..b03b33643e4b 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -327,6 +327,7 @@ static void put_crypt_info(struct fscrypt_info *ci) key_invalidate(key); key_put(key); } + memzero_explicit(ci, sizeof(*ci)); kmem_cache_free(fscrypt_info_cachep, ci); } -- GitLab From 915547794eafde0885d4d60828a3e86cd3ebd114 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 9 Oct 2019 16:34:18 -0700 Subject: [PATCH 921/993] FROMLIST: docs: ioctl-number: document fscrypt ioctl numbers The 'f' ioctls with numbers 19-26 decimal are currently used for fscrypt (a.k.a. ext4/f2fs/ubifs encryption), and up to 39 decimal is reserved for future fscrypt use, as per the comment in fs/ext4/ext4.h. So the reserved range is 13-27 hex. Document this in ioctl-number.rst. Change-Id: Id106c59de21d1585c22729bd5b4339b27c298c9c Signed-off-by: Eric Biggers Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11182409/ --- Documentation/ioctl/ioctl-number.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/ioctl/ioctl-number.rst b/Documentation/ioctl/ioctl-number.rst index bef79cd4c6b4..4ef86433bd67 100644 --- a/Documentation/ioctl/ioctl-number.rst +++ b/Documentation/ioctl/ioctl-number.rst @@ -233,6 +233,7 @@ Code Seq# Include File Comments 'f' 00-0F fs/ext4/ext4.h conflict! 'f' 00-0F linux/fs.h conflict! 'f' 00-0F fs/ocfs2/ocfs2_fs.h conflict! +'f' 13-27 linux/fscrypt.h 'f' 81-8F linux/fsverity.h 'g' 00-0F linux/usb/gadgetfs.h 'g' 20-2F linux/usb/g_printer.h -- GitLab From afca03cbbbce7345010e7661a704b89a47ed7a23 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 24 Oct 2019 14:43:36 -0700 Subject: [PATCH 922/993] FROMLIST: fscrypt: add support for IV_INO_LBLK_64 policies Inline encryption hardware compliant with the UFS v2.1 standard or with the upcoming version of the eMMC standard has the following properties: (1) Per I/O request, the encryption key is specified by a previously loaded keyslot. There might be only a small number of keyslots. (2) Per I/O request, the starting IV is specified by a 64-bit "data unit number" (DUN). IV bits 64-127 are assumed to be 0. The hardware automatically increments the DUN for each "data unit" of configurable size in the request, e.g. for each filesystem block. Property (1) makes it inefficient to use the traditional fscrypt per-file keys. Property (2) precludes the use of the existing DIRECT_KEY fscrypt policy flag, which needs at least 192 IV bits. Therefore, add a new fscrypt policy flag IV_INO_LBLK_64 which causes the encryption to modified as follows: - The encryption keys are derived from the master key, encryption mode number, and filesystem UUID. - The IVs are chosen as (inode_number << 32) | file_logical_block_num. For filenames encryption, file_logical_block_num is 0. Since the file nonces aren't used in the key derivation, many files may share the same encryption key. This is much more efficient on the target hardware. Including the inode number in the IVs and mixing the filesystem UUID into the keys ensures that data in different files is nevertheless still encrypted differently. Additionally, limiting the inode and block numbers to 32 bits and placing the block number in the low bits maintains compatibility with the 64-bit DUN convention (property (2) above). Since this scheme assumes that inode numbers are stable (which may preclude filesystem shrinking) and that inode and file logical block numbers are at most 32-bit, IV_INO_LBLK_64 will only be allowed on filesystems that meet these constraints. These are acceptable limitations for the cases where this format would actually be used. Note that IV_INO_LBLK_64 is an on-disk format, not an implementation. This patch just adds support for it using the existing filesystem layer encryption. A later patch will add support for inline encryption. Co-developed-by: Satya Tangirala Signed-off-by: Satya Tangirala Signed-off-by: Eric Biggers Change-Id: If97607ae4c111c2630d3cf337bd6fbc51abec896 Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11210909/ --- Documentation/filesystems/fscrypt.rst | 63 +++++++++++++++++---------- fs/crypto/crypto.c | 10 ++++- fs/crypto/fscrypt_private.h | 16 +++++-- fs/crypto/keyring.c | 6 ++- fs/crypto/keysetup.c | 45 ++++++++++++++----- fs/crypto/policy.c | 41 ++++++++++++++++- include/linux/fscrypt.h | 3 ++ include/uapi/linux/fscrypt.h | 3 +- 8 files changed, 146 insertions(+), 41 deletions(-) diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index 6ec459be3de1..471a511c7508 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -256,13 +256,8 @@ alternative master keys or to support rotating master keys. Instead, the master keys may be wrapped in userspace, e.g. as is done by the `fscrypt `_ tool. -Including the inode number in the IVs was considered. However, it was -rejected as it would have prevented ext4 filesystems from being -resized, and by itself still wouldn't have been sufficient to prevent -the same key from being directly reused for both XTS and CTS-CBC. - -DIRECT_KEY and per-mode keys ----------------------------- +DIRECT_KEY policies +------------------- The Adiantum encryption mode (see `Encryption modes and usage`_) is suitable for both contents and filenames encryption, and it accepts @@ -285,6 +280,21 @@ IV. Moreover: key derived using the KDF. Users may use the same master key for other v2 encryption policies. +IV_INO_LBLK_64 policies +----------------------- + +When FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 is set in the fscrypt policy, +the encryption keys are derived from the master key, encryption mode +number, and filesystem UUID. This normally results in all files +protected by the same master key sharing a single contents encryption +key and a single filenames encryption key. To still encrypt different +files' data differently, inode numbers are included in the IVs. +Consequently, shrinking the filesystem may not be allowed. + +This format is optimized for use with inline encryption hardware +compliant with the UFS or eMMC standards, which support only 64 IV +bits per I/O request and may have only a small number of keyslots. + Key identifiers --------------- @@ -342,10 +352,16 @@ a little endian number, except that: is encrypted with AES-256 where the AES-256 key is the SHA-256 hash of the file's data encryption key. -- In the "direct key" configuration (FSCRYPT_POLICY_FLAG_DIRECT_KEY - set in the fscrypt_policy), the file's nonce is also appended to the - IV. Currently this is only allowed with the Adiantum encryption - mode. +- With `DIRECT_KEY policies`_, the file's nonce is appended to the IV. + Currently this is only allowed with the Adiantum encryption mode. + +- With `IV_INO_LBLK_64 policies`_, the logical block number is limited + to 32 bits and is placed in bits 0-31 of the IV. The inode number + (which is also limited to 32 bits) is placed in bits 32-63. + +Note that because file logical block numbers are included in the IVs, +filesystems must enforce that blocks are never shifted around within +encrypted files, e.g. via "collapse range" or "insert range". Filenames encryption -------------------- @@ -355,10 +371,10 @@ the requirements to retain support for efficient directory lookups and filenames of up to 255 bytes, the same IV is used for every filename in a directory. -However, each encrypted directory still uses a unique key; or -alternatively (for the "direct key" configuration) has the file's -nonce included in the IVs. Thus, IV reuse is limited to within a -single directory. +However, each encrypted directory still uses a unique key, or +alternatively has the file's nonce (for `DIRECT_KEY policies`_) or +inode number (for `IV_INO_LBLK_64 policies`_) included in the IVs. +Thus, IV reuse is limited to within a single directory. With CTS-CBC, the IV reuse means that when the plaintext filenames share a common prefix at least as long as the cipher block size (16 @@ -432,12 +448,15 @@ This structure must be initialized as follows: (1) for ``contents_encryption_mode`` and FSCRYPT_MODE_AES_256_CTS (4) for ``filenames_encryption_mode``. -- ``flags`` must contain a value from ```` which - identifies the amount of NUL-padding to use when encrypting - filenames. If unsure, use FSCRYPT_POLICY_FLAGS_PAD_32 (0x3). - Additionally, if the encryption modes are both - FSCRYPT_MODE_ADIANTUM, this can contain - FSCRYPT_POLICY_FLAG_DIRECT_KEY; see `DIRECT_KEY and per-mode keys`_. +- ``flags`` contains optional flags from ````: + + - FSCRYPT_POLICY_FLAGS_PAD_*: The amount of NUL padding to use when + encrypting filenames. If unsure, use FSCRYPT_POLICY_FLAGS_PAD_32 + (0x3). + - FSCRYPT_POLICY_FLAG_DIRECT_KEY: See `DIRECT_KEY policies`_. + - FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64: See `IV_INO_LBLK_64 + policies`_. This is mutually exclusive with DIRECT_KEY and is not + supported on v1 policies. - For v2 encryption policies, ``__reserved`` must be zeroed. @@ -1090,7 +1109,7 @@ policy structs (see `Setting an encryption policy`_), except that the context structs also contain a nonce. The nonce is randomly generated by the kernel and is used as KDF input or as a tweak to cause different files to be encrypted differently; see `Per-file keys`_ and -`DIRECT_KEY and per-mode keys`_. +`DIRECT_KEY policies`_. Data path changes ----------------- diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index ced8ad9f2d01..3719efa546c6 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -73,11 +73,17 @@ EXPORT_SYMBOL(fscrypt_free_bounce_page); void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num, const struct fscrypt_info *ci) { + u8 flags = fscrypt_policy_flags(&ci->ci_policy); + memset(iv, 0, ci->ci_mode->ivsize); - iv->lblk_num = cpu_to_le64(lblk_num); - if (fscrypt_is_direct_key_policy(&ci->ci_policy)) + if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) { + WARN_ON_ONCE((u32)lblk_num != lblk_num); + lblk_num |= (u64)ci->ci_inode->i_ino << 32; + } else if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) { memcpy(iv->nonce, ci->ci_nonce, FS_KEY_DERIVATION_NONCE_SIZE); + } + iv->lblk_num = cpu_to_le64(lblk_num); } /* Encrypt or decrypt a single filesystem block of file contents */ diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index dacf8fcbac3b..b44e445b43a8 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -163,6 +163,9 @@ struct fscrypt_info { /* The actual crypto transform used for encryption and decryption */ struct crypto_skcipher *ci_ctfm; + /* True if the key should be freed when this fscrypt_info is freed */ + bool ci_owns_key; + /* * Encryption mode used for this inode. It corresponds to either the * contents or filenames encryption mode, depending on the inode type. @@ -281,7 +284,8 @@ extern int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 *master_key, */ #define HKDF_CONTEXT_KEY_IDENTIFIER 1 #define HKDF_CONTEXT_PER_FILE_KEY 2 -#define HKDF_CONTEXT_PER_MODE_KEY 3 +#define HKDF_CONTEXT_DIRECT_KEY 3 +#define HKDF_CONTEXT_IV_INO_LBLK_64_KEY 4 extern int fscrypt_hkdf_expand(struct fscrypt_hkdf *hkdf, u8 context, const u8 *info, unsigned int infolen, @@ -378,8 +382,14 @@ struct fscrypt_master_key { struct list_head mk_decrypted_inodes; spinlock_t mk_decrypted_inodes_lock; - /* Per-mode tfms for DIRECT_KEY policies, allocated on-demand */ - struct crypto_skcipher *mk_mode_keys[__FSCRYPT_MODE_MAX + 1]; + /* Crypto API transforms for DIRECT_KEY policies, allocated on-demand */ + struct crypto_skcipher *mk_direct_tfms[__FSCRYPT_MODE_MAX + 1]; + + /* + * Crypto API transforms for filesystem-layer implementation of + * IV_INO_LBLK_64 policies, allocated on-demand. + */ + struct crypto_skcipher *mk_iv_ino_lblk_64_tfms[__FSCRYPT_MODE_MAX + 1]; } __randomize_layout; diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c index b3ce0db8b9b8..f9cf62590e98 100644 --- a/fs/crypto/keyring.c +++ b/fs/crypto/keyring.c @@ -43,8 +43,10 @@ static void free_master_key(struct fscrypt_master_key *mk) wipe_master_key_secret(&mk->mk_secret); - for (i = 0; i < ARRAY_SIZE(mk->mk_mode_keys); i++) - crypto_free_skcipher(mk->mk_mode_keys[i]); + for (i = 0; i <= __FSCRYPT_MODE_MAX; i++) { + crypto_free_skcipher(mk->mk_direct_tfms[i]); + crypto_free_skcipher(mk->mk_iv_ino_lblk_64_tfms[i]); + } key_put(mk->mk_users); kzfree(mk); diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index b03b33643e4b..f87ab930b92a 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -116,40 +116,54 @@ int fscrypt_set_derived_key(struct fscrypt_info *ci, const u8 *derived_key) return PTR_ERR(tfm); ci->ci_ctfm = tfm; + ci->ci_owns_key = true; return 0; } static int setup_per_mode_key(struct fscrypt_info *ci, - struct fscrypt_master_key *mk) + struct fscrypt_master_key *mk, + struct crypto_skcipher **tfms, + u8 hkdf_context, bool include_fs_uuid) { + const struct inode *inode = ci->ci_inode; + const struct super_block *sb = inode->i_sb; struct fscrypt_mode *mode = ci->ci_mode; u8 mode_num = mode - available_modes; struct crypto_skcipher *tfm, *prev_tfm; u8 mode_key[FSCRYPT_MAX_KEY_SIZE]; + u8 hkdf_info[sizeof(mode_num) + sizeof(sb->s_uuid)]; + unsigned int hkdf_infolen = 0; int err; - if (WARN_ON(mode_num >= ARRAY_SIZE(mk->mk_mode_keys))) + if (WARN_ON(mode_num > __FSCRYPT_MODE_MAX)) return -EINVAL; /* pairs with cmpxchg() below */ - tfm = READ_ONCE(mk->mk_mode_keys[mode_num]); + tfm = READ_ONCE(tfms[mode_num]); if (likely(tfm != NULL)) goto done; BUILD_BUG_ON(sizeof(mode_num) != 1); + BUILD_BUG_ON(sizeof(sb->s_uuid) != 16); + BUILD_BUG_ON(sizeof(hkdf_info) != 17); + hkdf_info[hkdf_infolen++] = mode_num; + if (include_fs_uuid) { + memcpy(&hkdf_info[hkdf_infolen], &sb->s_uuid, + sizeof(sb->s_uuid)); + hkdf_infolen += sizeof(sb->s_uuid); + } err = fscrypt_hkdf_expand(&mk->mk_secret.hkdf, - HKDF_CONTEXT_PER_MODE_KEY, - &mode_num, sizeof(mode_num), + hkdf_context, hkdf_info, hkdf_infolen, mode_key, mode->keysize); if (err) return err; - tfm = fscrypt_allocate_skcipher(mode, mode_key, ci->ci_inode); + tfm = fscrypt_allocate_skcipher(mode, mode_key, inode); memzero_explicit(mode_key, mode->keysize); if (IS_ERR(tfm)) return PTR_ERR(tfm); /* pairs with READ_ONCE() above */ - prev_tfm = cmpxchg(&mk->mk_mode_keys[mode_num], NULL, tfm); + prev_tfm = cmpxchg(&tfms[mode_num], NULL, tfm); if (prev_tfm != NULL) { crypto_free_skcipher(tfm); tfm = prev_tfm; @@ -180,7 +194,19 @@ static int fscrypt_setup_v2_file_key(struct fscrypt_info *ci, ci->ci_mode->friendly_name); return -EINVAL; } - return setup_per_mode_key(ci, mk); + return setup_per_mode_key(ci, mk, mk->mk_direct_tfms, + HKDF_CONTEXT_DIRECT_KEY, false); + } else if (ci->ci_policy.v2.flags & + FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) { + /* + * IV_INO_LBLK_64: encryption keys are derived from (master_key, + * mode_num, filesystem_uuid), and inode number is included in + * the IVs. This format is optimized for use with inline + * encryption hardware compliant with the UFS or eMMC standards. + */ + return setup_per_mode_key(ci, mk, mk->mk_iv_ino_lblk_64_tfms, + HKDF_CONTEXT_IV_INO_LBLK_64_KEY, + true); } err = fscrypt_hkdf_expand(&mk->mk_secret.hkdf, @@ -304,8 +330,7 @@ static void put_crypt_info(struct fscrypt_info *ci) if (ci->ci_direct_key) fscrypt_put_direct_key(ci->ci_direct_key); - else if (ci->ci_ctfm != NULL && - !fscrypt_is_direct_key_policy(&ci->ci_policy)) + else if (ci->ci_owns_key) crypto_free_skcipher(ci->ci_ctfm); key = ci->ci_master_key; diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index 4072ba644595..96f528071bed 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -29,6 +29,40 @@ bool fscrypt_policies_equal(const union fscrypt_policy *policy1, return !memcmp(policy1, policy2, fscrypt_policy_size(policy1)); } +static bool supported_iv_ino_lblk_64_policy( + const struct fscrypt_policy_v2 *policy, + const struct inode *inode) +{ + struct super_block *sb = inode->i_sb; + int ino_bits = 64, lblk_bits = 64; + + if (policy->flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) { + fscrypt_warn(inode, + "The DIRECT_KEY and IV_INO_LBLK_64 flags are mutually exclusive"); + return false; + } + /* + * It's unsafe to include inode numbers in the IVs if the filesystem can + * potentially renumber inodes, e.g. via filesystem shrinking. + */ + if (!sb->s_cop->has_stable_inodes || + !sb->s_cop->has_stable_inodes(sb)) { + fscrypt_warn(inode, + "Can't use IV_INO_LBLK_64 policy on filesystem '%s' because it doesn't have stable inode numbers", + sb->s_id); + return false; + } + if (sb->s_cop->get_ino_and_lblk_bits) + sb->s_cop->get_ino_and_lblk_bits(sb, &ino_bits, &lblk_bits); + if (ino_bits > 32 || lblk_bits > 32) { + fscrypt_warn(inode, + "Can't use IV_INO_LBLK_64 policy on filesystem '%s' because it doesn't use 32-bit inode and block numbers", + sb->s_id); + return false; + } + return true; +} + /** * fscrypt_supported_policy - check whether an encryption policy is supported * @@ -55,7 +89,8 @@ bool fscrypt_supported_policy(const union fscrypt_policy *policy_u, return false; } - if (policy->flags & ~FSCRYPT_POLICY_FLAGS_VALID) { + if (policy->flags & ~(FSCRYPT_POLICY_FLAGS_PAD_MASK | + FSCRYPT_POLICY_FLAG_DIRECT_KEY)) { fscrypt_warn(inode, "Unsupported encryption flags (0x%02x)", policy->flags); @@ -83,6 +118,10 @@ bool fscrypt_supported_policy(const union fscrypt_policy *policy_u, return false; } + if ((policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) && + !supported_iv_ino_lblk_64_policy(policy, inode)) + return false; + if (memchr_inv(policy->__reserved, 0, sizeof(policy->__reserved))) { fscrypt_warn(inode, diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 367fe16f6cc8..f5037d8e2412 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -61,6 +61,9 @@ struct fscrypt_operations { bool (*dummy_context)(struct inode *); bool (*empty_dir)(struct inode *); unsigned int max_namelen; + bool (*has_stable_inodes)(struct super_block *sb); + void (*get_ino_and_lblk_bits)(struct super_block *sb, + int *ino_bits_ret, int *lblk_bits_ret); }; static inline bool fscrypt_has_encryption_key(const struct inode *inode) diff --git a/include/uapi/linux/fscrypt.h b/include/uapi/linux/fscrypt.h index 39ccfe9311c3..1beb174ad950 100644 --- a/include/uapi/linux/fscrypt.h +++ b/include/uapi/linux/fscrypt.h @@ -17,7 +17,8 @@ #define FSCRYPT_POLICY_FLAGS_PAD_32 0x03 #define FSCRYPT_POLICY_FLAGS_PAD_MASK 0x03 #define FSCRYPT_POLICY_FLAG_DIRECT_KEY 0x04 -#define FSCRYPT_POLICY_FLAGS_VALID 0x07 +#define FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 0x08 +#define FSCRYPT_POLICY_FLAGS_VALID 0x0F /* Encryption algorithms */ #define FSCRYPT_MODE_AES_256_XTS 1 -- GitLab From 2735b44d172f4a246cd65a9aca5537fbcdcf9665 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 24 Oct 2019 14:43:37 -0700 Subject: [PATCH 923/993] FROMLIST: ext4: add support for IV_INO_LBLK_64 encryption policies IV_INO_LBLK_64 encryption policies have special requirements from the filesystem beyond those of the existing encryption policies: - Inode numbers must never change, even if the filesystem is resized. - Inode numbers must be <= 32 bits. - File logical block numbers must be <= 32 bits. ext4 has 32-bit inode and file logical block numbers. However, resize2fs can re-number inodes when shrinking an ext4 filesystem. However, typically the people who would want to use this format don't care about filesystem shrinking. They'd be fine with a solution that just prevents the filesystem from being shrunk. Therefore, add a new feature flag EXT4_FEATURE_COMPAT_STABLE_INODES that will do exactly that. Then wire up the fscrypt_operations to expose this flag to fs/crypto/, so that it allows IV_INO_LBLK_64 policies when this flag is set. Signed-off-by: Eric Biggers Change-Id: Iff0f96b3869a907d0539eaf130df8f5e633d0b19 Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11210907/ --- fs/ext4/ext4.h | 2 ++ fs/ext4/super.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 03db3e71676c..b3a2cc7c0252 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1678,6 +1678,7 @@ static inline bool ext4_verity_in_progress(struct inode *inode) #define EXT4_FEATURE_COMPAT_RESIZE_INODE 0x0010 #define EXT4_FEATURE_COMPAT_DIR_INDEX 0x0020 #define EXT4_FEATURE_COMPAT_SPARSE_SUPER2 0x0200 +#define EXT4_FEATURE_COMPAT_STABLE_INODES 0x0800 #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 @@ -1779,6 +1780,7 @@ EXT4_FEATURE_COMPAT_FUNCS(xattr, EXT_ATTR) EXT4_FEATURE_COMPAT_FUNCS(resize_inode, RESIZE_INODE) EXT4_FEATURE_COMPAT_FUNCS(dir_index, DIR_INDEX) EXT4_FEATURE_COMPAT_FUNCS(sparse_super2, SPARSE_SUPER2) +EXT4_FEATURE_COMPAT_FUNCS(stable_inodes, STABLE_INODES) EXT4_FEATURE_RO_COMPAT_FUNCS(sparse_super, SPARSE_SUPER) EXT4_FEATURE_RO_COMPAT_FUNCS(large_file, LARGE_FILE) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index dd654e53ba3d..b3cbf8622eab 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1345,6 +1345,18 @@ static bool ext4_dummy_context(struct inode *inode) return DUMMY_ENCRYPTION_ENABLED(EXT4_SB(inode->i_sb)); } +static bool ext4_has_stable_inodes(struct super_block *sb) +{ + return ext4_has_feature_stable_inodes(sb); +} + +static void ext4_get_ino_and_lblk_bits(struct super_block *sb, + int *ino_bits_ret, int *lblk_bits_ret) +{ + *ino_bits_ret = 8 * sizeof(EXT4_SB(sb)->s_es->s_inodes_count); + *lblk_bits_ret = 8 * sizeof(ext4_lblk_t); +} + static const struct fscrypt_operations ext4_cryptops = { .key_prefix = "ext4:", .get_context = ext4_get_context, @@ -1352,6 +1364,8 @@ static const struct fscrypt_operations ext4_cryptops = { .dummy_context = ext4_dummy_context, .empty_dir = ext4_empty_dir, .max_namelen = EXT4_NAME_LEN, + .has_stable_inodes = ext4_has_stable_inodes, + .get_ino_and_lblk_bits = ext4_get_ino_and_lblk_bits, }; #endif -- GitLab From a62a18ccb1526c7f72b6d119be794456f9119919 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 24 Oct 2019 14:43:37 -0700 Subject: [PATCH 924/993] FROMLIST: f2fs: add support for IV_INO_LBLK_64 encryption policies f2fs inode numbers are stable across filesystem resizing, and f2fs inode and file logical block numbers are always 32-bit. So f2fs can always support IV_INO_LBLK_64 encryption policies. Wire up the needed fscrypt_operations to declare support. Signed-off-by: Eric Biggers Change-Id: I15c9b0f277df106701c4aacdf9456dbb3f8876a1 Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11210903/ --- fs/f2fs/super.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 1443cee15863..851ac9522926 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2308,13 +2308,27 @@ static bool f2fs_dummy_context(struct inode *inode) return DUMMY_ENCRYPTION_ENABLED(F2FS_I_SB(inode)); } +static bool f2fs_has_stable_inodes(struct super_block *sb) +{ + return true; +} + +static void f2fs_get_ino_and_lblk_bits(struct super_block *sb, + int *ino_bits_ret, int *lblk_bits_ret) +{ + *ino_bits_ret = 8 * sizeof(nid_t); + *lblk_bits_ret = 8 * sizeof(block_t); +} + static const struct fscrypt_operations f2fs_cryptops = { - .key_prefix = "f2fs:", - .get_context = f2fs_get_context, - .set_context = f2fs_set_context, - .dummy_context = f2fs_dummy_context, - .empty_dir = f2fs_empty_dir, - .max_namelen = F2FS_NAME_LEN, + .key_prefix = "f2fs:", + .get_context = f2fs_get_context, + .set_context = f2fs_set_context, + .dummy_context = f2fs_dummy_context, + .empty_dir = f2fs_empty_dir, + .max_namelen = F2FS_NAME_LEN, + .has_stable_inodes = f2fs_has_stable_inodes, + .get_ino_and_lblk_bits = f2fs_get_ino_and_lblk_bits, }; #endif -- GitLab From aac6c3decdf94fb2236fff884a69797855317d04 Mon Sep 17 00:00:00 2001 From: Satya Tangirala Date: Thu, 24 Oct 2019 14:44:23 -0700 Subject: [PATCH 925/993] FROMLIST: block: Keyslot Manager for Inline Encryption Inline Encryption hardware allows software to specify an encryption context (an encryption key, crypto algorithm, data unit num, data unit size, etc.) along with a data transfer request to a storage device, and the inline encryption hardware will use that context to en/decrypt the data. The inline encryption hardware is part of the storage device, and it conceptually sits on the data path between system memory and the storage device. Inline Encryption hardware implementations often function around the concept of "keyslots". These implementations often have a limited number of "keyslots", each of which can hold an encryption context (we say that an encryption context can be "programmed" into a keyslot). Requests made to the storage device may have a keyslot associated with them, and the inline encryption hardware will en/decrypt the data in the requests using the encryption context programmed into that associated keyslot. As keyslots are limited, and programming keys may be expensive in many implementations, and multiple requests may use exactly the same encryption contexts, we introduce a Keyslot Manager to efficiently manage keyslots. The keyslot manager also functions as the interface that upper layers will use to program keys into inline encryption hardware. For more information on the Keyslot Manager, refer to documentation found in block/keyslot-manager.c and linux/keyslot-manager.h. Bug: 137270441 Test: tested as series; see Ie1b77f7615d6a7a60fdc9105c7ab2200d17636a8 Change-Id: Iea1ee5a7eec46cb50d33cf1e2d20dfb7335af4ed Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11214713/ --- block/Kconfig | 8 + block/Makefile | 1 + block/keyslot-manager.c | 352 ++++++++++++++++++++++++++++++++ include/linux/bio.h | 5 + include/linux/blkdev.h | 6 + include/linux/keyslot-manager.h | 98 +++++++++ 6 files changed, 470 insertions(+) create mode 100644 block/keyslot-manager.c create mode 100644 include/linux/keyslot-manager.h diff --git a/block/Kconfig b/block/Kconfig index 41c0917ce622..ae52d42b783b 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -177,6 +177,14 @@ config BLK_SED_OPAL Enabling this option enables users to setup/unlock/lock Locking ranges for SED devices using the Opal protocol. +config BLK_INLINE_ENCRYPTION + bool "Enable inline encryption support in block layer" + help + Build the blk-crypto subsystem. + Enabling this lets the block layer handle encryption, + so users can take advantage of inline encryption + hardware if present. + menu "Partition Types" source "block/partitions/Kconfig" diff --git a/block/Makefile b/block/Makefile index 9ef57ace90d4..e922844219c2 100644 --- a/block/Makefile +++ b/block/Makefile @@ -36,3 +36,4 @@ obj-$(CONFIG_BLK_DEBUG_FS) += blk-mq-debugfs.o obj-$(CONFIG_BLK_DEBUG_FS_ZONED)+= blk-mq-debugfs-zoned.o obj-$(CONFIG_BLK_SED_OPAL) += sed-opal.o obj-$(CONFIG_BLK_PM) += blk-pm.o +obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += keyslot-manager.o diff --git a/block/keyslot-manager.c b/block/keyslot-manager.c new file mode 100644 index 000000000000..020931fc9f7d --- /dev/null +++ b/block/keyslot-manager.c @@ -0,0 +1,352 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * keyslot-manager.c + * + * Copyright 2019 Google LLC + */ + +/** + * DOC: The Keyslot Manager + * + * Many devices with inline encryption support have a limited number of "slots" + * into which encryption contexts may be programmed, and requests can be tagged + * with a slot number to specify the key to use for en/decryption. + * + * As the number of slots are limited, and programming keys is expensive on + * many inline encryption hardware, we don't want to program the same key into + * multiple slots - if multiple requests are using the same key, we want to + * program just one slot with that key and use that slot for all requests. + * + * The keyslot manager manages these keyslots appropriately, and also acts as + * an abstraction between the inline encryption hardware and the upper layers. + * + * Lower layer devices will set up a keyslot manager in their request queue + * and tell it how to perform device specific operations like programming/ + * evicting keys from keyslots. + * + * Upper layers will call keyslot_manager_get_slot_for_key() to program a + * key into some slot in the inline encryption hardware. + */ +#include +#include +#include +#include +#include + +struct keyslot { + atomic_t slot_refs; + struct list_head idle_slot_node; +}; + +struct keyslot_manager { + unsigned int num_slots; + atomic_t num_idle_slots; + struct keyslot_mgmt_ll_ops ksm_ll_ops; + void *ll_priv_data; + + /* Protects programming and evicting keys from the device */ + struct rw_semaphore lock; + + /* List of idle slots, with least recently used slot at front */ + wait_queue_head_t idle_slots_wait_queue; + struct list_head idle_slots; + spinlock_t idle_slots_lock; + + /* Per-keyslot data */ + struct keyslot slots[]; +}; + +/** + * keyslot_manager_create() - Create a keyslot manager + * @num_slots: The number of key slots to manage. + * @ksm_ll_ops: The struct keyslot_mgmt_ll_ops for the device that this keyslot + * manager will use to perform operations like programming and + * evicting keys. + * @ll_priv_data: Private data passed as is to the functions in ksm_ll_ops. + * + * Allocate memory for and initialize a keyslot manager. Called by e.g. + * storage drivers to set up a keyslot manager in their request_queue. + * + * Context: May sleep + * Return: Pointer to constructed keyslot manager or NULL on error. + */ +struct keyslot_manager *keyslot_manager_create(unsigned int num_slots, + const struct keyslot_mgmt_ll_ops *ksm_ll_ops, + void *ll_priv_data) +{ + struct keyslot_manager *ksm; + int slot; + + if (num_slots == 0) + return NULL; + + /* Check that all ops are specified */ + if (ksm_ll_ops->keyslot_program == NULL || + ksm_ll_ops->keyslot_evict == NULL || + ksm_ll_ops->crypto_mode_supported == NULL || + ksm_ll_ops->keyslot_find == NULL) + return NULL; + + ksm = kvzalloc(struct_size(ksm, slots, num_slots), GFP_KERNEL); + if (!ksm) + return NULL; + + ksm->num_slots = num_slots; + atomic_set(&ksm->num_idle_slots, num_slots); + ksm->ksm_ll_ops = *ksm_ll_ops; + ksm->ll_priv_data = ll_priv_data; + + init_rwsem(&ksm->lock); + + init_waitqueue_head(&ksm->idle_slots_wait_queue); + INIT_LIST_HEAD(&ksm->idle_slots); + + for (slot = 0; slot < num_slots; slot++) { + list_add_tail(&ksm->slots[slot].idle_slot_node, + &ksm->idle_slots); + } + + spin_lock_init(&ksm->idle_slots_lock); + + return ksm; +} +EXPORT_SYMBOL(keyslot_manager_create); + +static void remove_slot_from_lru_list(struct keyslot_manager *ksm, int slot) +{ + unsigned long flags; + + spin_lock_irqsave(&ksm->idle_slots_lock, flags); + list_del(&ksm->slots[slot].idle_slot_node); + spin_unlock_irqrestore(&ksm->idle_slots_lock, flags); + + atomic_dec(&ksm->num_idle_slots); +} + +static int find_and_grab_keyslot(struct keyslot_manager *ksm, const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size) +{ + int slot; + + slot = ksm->ksm_ll_ops.keyslot_find(ksm->ll_priv_data, key, + crypto_mode, data_unit_size); + if (slot < 0) + return slot; + if (WARN_ON(slot >= ksm->num_slots)) + return -EINVAL; + if (atomic_inc_return(&ksm->slots[slot].slot_refs) == 1) { + /* Took first reference to this slot; remove it from LRU list */ + remove_slot_from_lru_list(ksm, slot); + } + return slot; +} + +/** + * keyslot_manager_get_slot_for_key() - Program a key into a keyslot. + * @ksm: The keyslot manager to program the key into. + * @key: Pointer to the bytes of the key to program. Must be the correct length + * for the chosen @crypto_mode; see blk_crypto_modes in blk-crypto.c. + * @crypto_mode: Identifier for the encryption algorithm to use. + * @data_unit_size: The data unit size to use for en/decryption. + * + * Get a keyslot that's been programmed with the specified key, crypto_mode, and + * data_unit_size. If one already exists, return it with incremented refcount. + * Otherwise, wait for a keyslot to become idle and program it. + * + * Context: Process context. Takes and releases ksm->lock. + * Return: The keyslot on success, else a -errno value. + */ +int keyslot_manager_get_slot_for_key(struct keyslot_manager *ksm, + const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size) +{ + int slot; + int err; + struct keyslot *idle_slot; + + down_read(&ksm->lock); + slot = find_and_grab_keyslot(ksm, key, crypto_mode, data_unit_size); + up_read(&ksm->lock); + if (slot != -ENOKEY) + return slot; + + for (;;) { + down_write(&ksm->lock); + slot = find_and_grab_keyslot(ksm, key, crypto_mode, + data_unit_size); + if (slot != -ENOKEY) { + up_write(&ksm->lock); + return slot; + } + + /* + * If we're here, that means there wasn't a slot that was + * already programmed with the key. So try to program it. + */ + if (atomic_read(&ksm->num_idle_slots) > 0) + break; + + up_write(&ksm->lock); + wait_event(ksm->idle_slots_wait_queue, + (atomic_read(&ksm->num_idle_slots) > 0)); + } + + idle_slot = list_first_entry(&ksm->idle_slots, struct keyslot, + idle_slot_node); + slot = idle_slot - ksm->slots; + + err = ksm->ksm_ll_ops.keyslot_program(ksm->ll_priv_data, key, + crypto_mode, + data_unit_size, + slot); + + if (err) { + wake_up(&ksm->idle_slots_wait_queue); + up_write(&ksm->lock); + return err; + } + + atomic_set(&ksm->slots[slot].slot_refs, 1); + remove_slot_from_lru_list(ksm, slot); + + up_write(&ksm->lock); + return slot; + +} +EXPORT_SYMBOL(keyslot_manager_get_slot_for_key); + +/** + * keyslot_manager_get_slot() - Increment the refcount on the specified slot. + * @ksm - The keyslot manager that we want to modify. + * @slot - The slot to increment the refcount of. + * + * This function assumes that there is already an active reference to that slot + * and simply increments the refcount. This is useful when cloning a bio that + * already has a reference to a keyslot, and we want the cloned bio to also have + * its own reference. + * + * Context: Any context. + */ +void keyslot_manager_get_slot(struct keyslot_manager *ksm, unsigned int slot) +{ + if (WARN_ON(slot >= ksm->num_slots)) + return; + + WARN_ON(atomic_inc_return(&ksm->slots[slot].slot_refs) < 2); +} +EXPORT_SYMBOL(keyslot_manager_get_slot); + +/** + * keyslot_manager_put_slot() - Release a reference to a slot + * @ksm: The keyslot manager to release the reference from. + * @slot: The slot to release the reference from. + * + * Context: Any context. + */ +void keyslot_manager_put_slot(struct keyslot_manager *ksm, unsigned int slot) +{ + unsigned long flags; + + if (WARN_ON(slot >= ksm->num_slots)) + return; + + if (atomic_dec_and_lock_irqsave(&ksm->slots[slot].slot_refs, + &ksm->idle_slots_lock, flags)) { + list_add_tail(&ksm->slots[slot].idle_slot_node, + &ksm->idle_slots); + spin_unlock_irqrestore(&ksm->idle_slots_lock, flags); + atomic_inc(&ksm->num_idle_slots); + wake_up(&ksm->idle_slots_wait_queue); + } +} +EXPORT_SYMBOL(keyslot_manager_put_slot); + +/** + * keyslot_manager_crypto_mode_supported() - Find out if a crypto_mode/data + * unit size combination is supported + * by a ksm. + * @ksm - The keyslot manager to check + * @crypto_mode - The crypto mode to check for. + * @data_unit_size - The data_unit_size for the mode. + * + * Calls and returns the result of the crypto_mode_supported function specified + * by the ksm. + * + * Context: Process context. + * Return: Whether or not this ksm supports the specified crypto_mode/ + * data_unit_size combo. + */ +bool keyslot_manager_crypto_mode_supported(struct keyslot_manager *ksm, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size) +{ + if (!ksm) + return false; + return ksm->ksm_ll_ops.crypto_mode_supported(ksm->ll_priv_data, + crypto_mode, + data_unit_size); +} +EXPORT_SYMBOL(keyslot_manager_crypto_mode_supported); + +bool keyslot_manager_rq_crypto_mode_supported(struct request_queue *q, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size) +{ + return keyslot_manager_crypto_mode_supported(q->ksm, crypto_mode, + data_unit_size); +} +EXPORT_SYMBOL(keyslot_manager_rq_crypto_mode_supported); + +/** + * keyslot_manager_evict_key() - Evict a key from the lower layer device. + * @ksm - The keyslot manager to evict from + * @key - The key to evict + * @crypto_mode - The crypto algorithm the key was programmed with. + * @data_unit_size - The data_unit_size the key was programmed with. + * + * Finds the slot that the specified key, crypto_mode, data_unit_size combo + * was programmed into, and evicts that slot from the lower layer device if + * the refcount on the slot is 0. Returns -EBUSY if the refcount is not 0, and + * -errno on error. + * + * Context: Process context. Takes and releases ksm->lock. + */ +int keyslot_manager_evict_key(struct keyslot_manager *ksm, + const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size) +{ + int slot; + int err = 0; + + down_write(&ksm->lock); + slot = ksm->ksm_ll_ops.keyslot_find(ksm->ll_priv_data, key, + crypto_mode, + data_unit_size); + + if (slot < 0) { + up_write(&ksm->lock); + return slot; + } + + if (atomic_read(&ksm->slots[slot].slot_refs) == 0) { + err = ksm->ksm_ll_ops.keyslot_evict(ksm->ll_priv_data, key, + crypto_mode, + data_unit_size, + slot); + } else { + err = -EBUSY; + } + + up_write(&ksm->lock); + return err; +} +EXPORT_SYMBOL(keyslot_manager_evict_key); + +void keyslot_manager_destroy(struct keyslot_manager *ksm) +{ + kvfree(ksm); +} +EXPORT_SYMBOL(keyslot_manager_destroy); diff --git a/include/linux/bio.h b/include/linux/bio.h index 3cdb84cdc488..d0cb7c350cdc 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -564,6 +564,11 @@ static inline void bvec_kunmap_irq(char *buffer, unsigned long *flags) } #endif +enum blk_crypto_mode_num { + BLK_ENCRYPTION_MODE_INVALID = 0, + BLK_ENCRYPTION_MODE_AES_256_XTS = 1, +}; + /* * BIO list management for use by remapping drivers (e.g. DM or MD) and loop. * diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index f3ea78b0c91c..244e81a8f5d2 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -43,6 +43,7 @@ struct pr_ops; struct rq_qos; struct blk_queue_stats; struct blk_stat_callback; +struct keyslot_manager; #define BLKDEV_MIN_RQ 4 #define BLKDEV_MAX_RQ 128 /* Default maximum */ @@ -481,6 +482,11 @@ struct request_queue { unsigned int dma_pad_mask; unsigned int dma_alignment; +#ifdef CONFIG_BLK_INLINE_ENCRYPTION + /* Inline crypto capabilities */ + struct keyslot_manager *ksm; +#endif + unsigned int rq_timeout; int poll_nsec; diff --git a/include/linux/keyslot-manager.h b/include/linux/keyslot-manager.h new file mode 100644 index 000000000000..0777ade7907c --- /dev/null +++ b/include/linux/keyslot-manager.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2019 Google LLC + */ + +#include + +#ifdef CONFIG_BLOCK + +#ifndef __LINUX_KEYSLOT_MANAGER_H +#define __LINUX_KEYSLOT_MANAGER_H + +/** + * struct keyslot_mgmt_ll_ops - functions to manage keyslots in hardware + * @keyslot_program: Program the specified key and algorithm into the + * specified slot in the inline encryption hardware. + * @keyslot_evict: Evict key from the specified keyslot in the hardware. + * The key, crypto_mode and data_unit_size are also passed + * down so that e.g. dm layers can evict keys from + * the devices that they map over. + * Returns 0 on success, -errno otherwise. + * @crypto_mode_supported: Check whether a crypto_mode and data_unit_size + * combo is supported. + * @keyslot_find: Returns the slot number that matches the key, + * or -ENOKEY if no match found, or -errno on + * error. + * + * This structure should be provided by storage device drivers when they set up + * a keyslot manager - this structure holds the function ptrs that the keyslot + * manager will use to manipulate keyslots in the hardware. + */ +struct keyslot_mgmt_ll_ops { + int (*keyslot_program)(void *ll_priv_data, const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size, + unsigned int slot); + int (*keyslot_evict)(void *ll_priv_data, const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size, + unsigned int slot); + bool (*crypto_mode_supported)(void *ll_priv_data, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size); + int (*keyslot_find)(void *ll_priv_data, const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size); +}; + +#ifdef CONFIG_BLK_INLINE_ENCRYPTION +struct keyslot_manager; + +extern struct keyslot_manager *keyslot_manager_create(unsigned int num_slots, + const struct keyslot_mgmt_ll_ops *ksm_ops, + void *ll_priv_data); + +extern int +keyslot_manager_get_slot_for_key(struct keyslot_manager *ksm, + const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size); + +extern void keyslot_manager_get_slot(struct keyslot_manager *ksm, + unsigned int slot); + +extern void keyslot_manager_put_slot(struct keyslot_manager *ksm, + unsigned int slot); + +extern bool +keyslot_manager_crypto_mode_supported(struct keyslot_manager *ksm, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size); + +extern bool +keyslot_manager_rq_crypto_mode_supported(struct request_queue *q, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size); + +extern int keyslot_manager_evict_key(struct keyslot_manager *ksm, + const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size); + +extern void keyslot_manager_destroy(struct keyslot_manager *ksm); + +#else /* CONFIG_BLK_INLINE_ENCRYPTION */ + +static inline bool +keyslot_manager_rq_crypto_mode_supported(struct request_queue *q, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size) +{ + return false; +} +#endif /* CONFIG_BLK_INLINE_ENCRYPTION */ + +#endif /* __LINUX_KEYSLOT_MANAGER_H */ + +#endif /* CONFIG_BLOCK */ -- GitLab From 7170a977743b72cf3eb46ef6ef89885dc7ad3621 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 30 Oct 2019 13:00:04 -0700 Subject: [PATCH 926/993] net: annotate accesses to sk->sk_incoming_cpu This socket field can be read and written by concurrent cpus. Use READ_ONCE() and WRITE_ONCE() annotations to document this, and avoid some compiler 'optimizations'. KCSAN reported : BUG: KCSAN: data-race in tcp_v4_rcv / tcp_v4_rcv write to 0xffff88812220763c of 4 bytes by interrupt on cpu 0: sk_incoming_cpu_update include/net/sock.h:953 [inline] tcp_v4_rcv+0x1b3c/0x1bb0 net/ipv4/tcp_ipv4.c:1934 ip_protocol_deliver_rcu+0x4d/0x420 net/ipv4/ip_input.c:204 ip_local_deliver_finish+0x110/0x140 net/ipv4/ip_input.c:231 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_local_deliver+0x133/0x210 net/ipv4/ip_input.c:252 dst_input include/net/dst.h:442 [inline] ip_rcv_finish+0x121/0x160 net/ipv4/ip_input.c:413 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_rcv+0x18f/0x1a0 net/ipv4/ip_input.c:523 __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5010 __netif_receive_skb+0x37/0xf0 net/core/dev.c:5124 process_backlog+0x1d3/0x420 net/core/dev.c:5955 napi_poll net/core/dev.c:6392 [inline] net_rx_action+0x3ae/0xa90 net/core/dev.c:6460 __do_softirq+0x115/0x33f kernel/softirq.c:292 do_softirq_own_stack+0x2a/0x40 arch/x86/entry/entry_64.S:1082 do_softirq.part.0+0x6b/0x80 kernel/softirq.c:337 do_softirq kernel/softirq.c:329 [inline] __local_bh_enable_ip+0x76/0x80 kernel/softirq.c:189 read to 0xffff88812220763c of 4 bytes by interrupt on cpu 1: sk_incoming_cpu_update include/net/sock.h:952 [inline] tcp_v4_rcv+0x181a/0x1bb0 net/ipv4/tcp_ipv4.c:1934 ip_protocol_deliver_rcu+0x4d/0x420 net/ipv4/ip_input.c:204 ip_local_deliver_finish+0x110/0x140 net/ipv4/ip_input.c:231 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_local_deliver+0x133/0x210 net/ipv4/ip_input.c:252 dst_input include/net/dst.h:442 [inline] ip_rcv_finish+0x121/0x160 net/ipv4/ip_input.c:413 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_rcv+0x18f/0x1a0 net/ipv4/ip_input.c:523 __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5010 __netif_receive_skb+0x37/0xf0 net/core/dev.c:5124 process_backlog+0x1d3/0x420 net/core/dev.c:5955 napi_poll net/core/dev.c:6392 [inline] net_rx_action+0x3ae/0xa90 net/core/dev.c:6460 __do_softirq+0x115/0x33f kernel/softirq.c:292 run_ksoftirqd+0x46/0x60 kernel/softirq.c:603 smpboot_thread_fn+0x37d/0x4a0 kernel/smpboot.c:165 Reported by Kernel Concurrency Sanitizer on: CPU: 1 PID: 16 Comm: ksoftirqd/1 Not tainted 5.4.0-rc3+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: David S. Miller --- include/net/sock.h | 4 ++-- net/core/sock.c | 4 ++-- net/ipv4/inet_hashtables.c | 2 +- net/ipv4/udp.c | 2 +- net/ipv6/inet6_hashtables.c | 2 +- net/ipv6/udp.c | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index c31a9ed86d5a..8f9adcfac41b 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -954,8 +954,8 @@ static inline void sk_incoming_cpu_update(struct sock *sk) { int cpu = raw_smp_processor_id(); - if (unlikely(sk->sk_incoming_cpu != cpu)) - sk->sk_incoming_cpu = cpu; + if (unlikely(READ_ONCE(sk->sk_incoming_cpu) != cpu)) + WRITE_ONCE(sk->sk_incoming_cpu, cpu); } static inline void sock_rps_record_flow_hash(__u32 hash) diff --git a/net/core/sock.c b/net/core/sock.c index b8e758bcb6ad..ac78a570e43a 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1127,7 +1127,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, break; } case SO_INCOMING_CPU: - sk->sk_incoming_cpu = val; + WRITE_ONCE(sk->sk_incoming_cpu, val); break; case SO_CNX_ADVICE: @@ -1476,7 +1476,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, break; case SO_INCOMING_CPU: - v.val = sk->sk_incoming_cpu; + v.val = READ_ONCE(sk->sk_incoming_cpu); break; case SO_MEMINFO: diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 97824864e40d..83fb00153018 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -240,7 +240,7 @@ static inline int compute_score(struct sock *sk, struct net *net, return -1; score = sk->sk_family == PF_INET ? 2 : 1; - if (sk->sk_incoming_cpu == raw_smp_processor_id()) + if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) score++; } return score; diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index d1ed160af202..1d58ce829dca 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -388,7 +388,7 @@ static int compute_score(struct sock *sk, struct net *net, return -1; score += 4; - if (sk->sk_incoming_cpu == raw_smp_processor_id()) + if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) score++; return score; } diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index cf60fae9533b..fbe9d4295eac 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c @@ -105,7 +105,7 @@ static inline int compute_score(struct sock *sk, struct net *net, return -1; score = 1; - if (sk->sk_incoming_cpu == raw_smp_processor_id()) + if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) score++; } return score; diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 6324d3a8cb53..9fec580c968e 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -135,7 +135,7 @@ static int compute_score(struct sock *sk, struct net *net, return -1; score++; - if (sk->sk_incoming_cpu == raw_smp_processor_id()) + if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) score++; return score; -- GitLab From 3d252454edd0fe88c8250cb7f9dfb9ec12d208d7 Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Wed, 30 Oct 2019 09:17:18 +0100 Subject: [PATCH 927/993] parisc: fix frame pointer in ftrace_regs_caller() The current code in ftrace_regs_caller() doesn't assign %r3 to contain the address of the current frame. This is hidden if the kernel is compiled with FRAME_POINTER, but without it just crashes because it tries to dereference an arbitrary address. Fix this by always setting %r3 to the current stack frame. Signed-off-by: Sven Schnelle Signed-off-by: Helge Deller --- arch/parisc/kernel/entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 1d1d748c227f..b96d74496977 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -2125,7 +2125,7 @@ ftrace_regs_caller: copy %rp, %r26 LDREG -FTRACE_FRAME_SIZE-PT_SZ_ALGN(%sp), %r25 ldo -8(%r25), %r25 - copy %r3, %arg2 + ldo -FTRACE_FRAME_SIZE(%r1), %arg2 b,l ftrace_function_trampoline, %rp copy %r1, %arg3 /* struct pt_regs */ -- GitLab From 6873e0bd6a9cb14ecfadd89d9ed9698ff1761902 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 30 Oct 2019 13:53:09 -0600 Subject: [PATCH 928/993] io_uring: ensure we clear io_kiocb->result before each issue We use io_kiocb->result == -EAGAIN as a way to know if we need to re-submit a polled request, as -EAGAIN reporting happens out-of-line for IO submission failures. This field is cleared when we originally allocate the request, but it isn't reset when we retry the submission from async context. This can cause issues where we think something needs a re-issue, but we're really just reading stale data. Reset ->result whenever we re-prep a request for polled submission. Cc: stable@vger.kernel.org Fixes: 9e645e1105ca ("io_uring: add support for sqe links") Reported-by: Bijan Mottahedeh Signed-off-by: Jens Axboe --- fs/io_uring.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/io_uring.c b/fs/io_uring.c index c11c4157a4c2..f9a38998f2fc 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1124,6 +1124,7 @@ static int io_prep_rw(struct io_kiocb *req, const struct sqe_submit *s, kiocb->ki_flags |= IOCB_HIPRI; kiocb->ki_complete = io_complete_rw_iopoll; + req->result = 0; } else { if (kiocb->ki_flags & IOCB_HIPRI) return -EINVAL; -- GitLab From 10f1b43cbcfb5cef05fcf41f23423318a015360d Mon Sep 17 00:00:00 2001 From: Satya Tangirala Date: Thu, 24 Oct 2019 14:44:24 -0700 Subject: [PATCH 929/993] FROMLIST: block: Add encryption context to struct bio We must have some way of letting a storage device driver know what encryption context it should use for en/decrypting a request. However, it's the filesystem/fscrypt that knows about and manages encryption contexts. As such, when the filesystem layer submits a bio to the block layer, and this bio eventually reaches a device driver with support for inline encryption, the device driver will need to have been told the encryption context for that bio. We want to communicate the encryption context from the filesystem layer to the storage device along with the bio, when the bio is submitted to the block layer. To do this, we add a struct bio_crypt_ctx to struct bio, which can represent an encryption context (note that we can't use the bi_private field in struct bio to do this because that field does not function to pass information across layers in the storage stack). We also introduce various functions to manipulate the bio_crypt_ctx and make the bio/request merging logic aware of the bio_crypt_ctx. Bug: 137270441 Test: tested as series; see Ie1b77f7615d6a7a60fdc9105c7ab2200d17636a8 Change-Id: I479de9ec13758f1978b34d897e6956e680caeb92 Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11214719/ --- block/Makefile | 2 +- block/bio-crypt-ctx.c | 137 +++++++++++++++++++++ block/bio.c | 18 +-- block/blk-core.c | 3 + block/blk-merge.c | 35 +++++- block/bounce.c | 15 +-- drivers/md/dm.c | 15 ++- include/linux/bio-crypt-ctx.h | 219 ++++++++++++++++++++++++++++++++++ include/linux/bio.h | 6 +- include/linux/blk_types.h | 6 + 10 files changed, 426 insertions(+), 30 deletions(-) create mode 100644 block/bio-crypt-ctx.c create mode 100644 include/linux/bio-crypt-ctx.h diff --git a/block/Makefile b/block/Makefile index e922844219c2..f39611ed151f 100644 --- a/block/Makefile +++ b/block/Makefile @@ -36,4 +36,4 @@ obj-$(CONFIG_BLK_DEBUG_FS) += blk-mq-debugfs.o obj-$(CONFIG_BLK_DEBUG_FS_ZONED)+= blk-mq-debugfs-zoned.o obj-$(CONFIG_BLK_SED_OPAL) += sed-opal.o obj-$(CONFIG_BLK_PM) += blk-pm.o -obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += keyslot-manager.o +obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += keyslot-manager.o bio-crypt-ctx.o diff --git a/block/bio-crypt-ctx.c b/block/bio-crypt-ctx.c new file mode 100644 index 000000000000..aa3571f72ee7 --- /dev/null +++ b/block/bio-crypt-ctx.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +#include +#include +#include +#include + +static int num_prealloc_crypt_ctxs = 128; +static struct kmem_cache *bio_crypt_ctx_cache; +static mempool_t *bio_crypt_ctx_pool; + +int bio_crypt_ctx_init(void) +{ + bio_crypt_ctx_cache = KMEM_CACHE(bio_crypt_ctx, 0); + if (!bio_crypt_ctx_cache) + return -ENOMEM; + + bio_crypt_ctx_pool = mempool_create_slab_pool( + num_prealloc_crypt_ctxs, + bio_crypt_ctx_cache); + + if (!bio_crypt_ctx_pool) + return -ENOMEM; + + return 0; +} + +struct bio_crypt_ctx *bio_crypt_alloc_ctx(gfp_t gfp_mask) +{ + return mempool_alloc(bio_crypt_ctx_pool, gfp_mask); +} +EXPORT_SYMBOL(bio_crypt_alloc_ctx); + +void bio_crypt_free_ctx(struct bio *bio) +{ + mempool_free(bio->bi_crypt_context, bio_crypt_ctx_pool); + bio->bi_crypt_context = NULL; +} +EXPORT_SYMBOL(bio_crypt_free_ctx); + +int bio_crypt_clone(struct bio *dst, struct bio *src, gfp_t gfp_mask) +{ + if (!bio_has_crypt_ctx(src)) + return 0; + + dst->bi_crypt_context = bio_crypt_alloc_ctx(gfp_mask); + if (!dst->bi_crypt_context) + return -ENOMEM; + + *dst->bi_crypt_context = *src->bi_crypt_context; + + if (bio_crypt_has_keyslot(src)) + keyslot_manager_get_slot(src->bi_crypt_context->processing_ksm, + src->bi_crypt_context->keyslot); + + return 0; +} +EXPORT_SYMBOL(bio_crypt_clone); + +bool bio_crypt_should_process(struct bio *bio, struct request_queue *q) +{ + if (!bio_has_crypt_ctx(bio)) + return false; + + WARN_ON(!bio_crypt_has_keyslot(bio)); + return q->ksm == bio->bi_crypt_context->processing_ksm; +} +EXPORT_SYMBOL(bio_crypt_should_process); + +/* + * Checks that two bio crypt contexts are compatible - i.e. that + * they are mergeable except for data_unit_num continuity. + */ +bool bio_crypt_ctx_compatible(struct bio *b_1, struct bio *b_2) +{ + struct bio_crypt_ctx *bc1 = b_1->bi_crypt_context; + struct bio_crypt_ctx *bc2 = b_2->bi_crypt_context; + + if (bio_has_crypt_ctx(b_1) != bio_has_crypt_ctx(b_2)) + return false; + + if (!bio_has_crypt_ctx(b_1)) + return true; + + return bc1->keyslot == bc2->keyslot && + bc1->data_unit_size_bits == bc2->data_unit_size_bits; +} + +/* + * Checks that two bio crypt contexts are compatible, and also + * that their data_unit_nums are continuous (and can hence be merged) + */ +bool bio_crypt_ctx_back_mergeable(struct bio *b_1, + unsigned int b1_sectors, + struct bio *b_2) +{ + struct bio_crypt_ctx *bc1 = b_1->bi_crypt_context; + struct bio_crypt_ctx *bc2 = b_2->bi_crypt_context; + + if (!bio_crypt_ctx_compatible(b_1, b_2)) + return false; + + return !bio_has_crypt_ctx(b_1) || + (bc1->data_unit_num + + (b1_sectors >> (bc1->data_unit_size_bits - 9)) == + bc2->data_unit_num); +} + +void bio_crypt_ctx_release_keyslot(struct bio *bio) +{ + struct bio_crypt_ctx *crypt_ctx = bio->bi_crypt_context; + + keyslot_manager_put_slot(crypt_ctx->processing_ksm, crypt_ctx->keyslot); + bio->bi_crypt_context->processing_ksm = NULL; + bio->bi_crypt_context->keyslot = -1; +} + +int bio_crypt_ctx_acquire_keyslot(struct bio *bio, struct keyslot_manager *ksm) +{ + int slot; + enum blk_crypto_mode_num crypto_mode = bio_crypto_mode(bio); + + if (!ksm) + return -ENOMEM; + + slot = keyslot_manager_get_slot_for_key(ksm, + bio_crypt_raw_key(bio), crypto_mode, + 1 << bio->bi_crypt_context->data_unit_size_bits); + if (slot < 0) + return slot; + + bio_crypt_set_keyslot(bio, slot, ksm); + return 0; +} diff --git a/block/bio.c b/block/bio.c index 8f0ed6228fc5..ce8003aadf07 100644 --- a/block/bio.c +++ b/block/bio.c @@ -241,6 +241,7 @@ static void bio_free(struct bio *bio) struct bio_set *bs = bio->bi_pool; void *p; + bio_crypt_free_ctx(bio); bio_uninit(bio); if (bs) { @@ -612,15 +613,15 @@ struct bio *bio_clone_fast(struct bio *bio, gfp_t gfp_mask, struct bio_set *bs) __bio_clone_fast(b, bio); - if (bio_integrity(bio)) { - int ret; - - ret = bio_integrity_clone(b, bio, gfp_mask); + if (bio_crypt_clone(b, bio, gfp_mask) < 0) { + bio_put(b); + return NULL; + } - if (ret < 0) { - bio_put(b); - return NULL; - } + if (bio_integrity(bio) && + bio_integrity_clone(b, bio, gfp_mask) < 0) { + bio_put(b); + return NULL; } return b; @@ -992,6 +993,7 @@ void bio_advance(struct bio *bio, unsigned bytes) if (bio_integrity(bio)) bio_integrity_advance(bio, bytes); + bio_crypt_advance(bio, bytes); bio_advance_iter(bio, &bio->bi_iter, bytes); } EXPORT_SYMBOL(bio_advance); diff --git a/block/blk-core.c b/block/blk-core.c index d5e668ec751b..3b5959d386fb 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1807,5 +1807,8 @@ int __init blk_dev_init(void) blk_debugfs_root = debugfs_create_dir("block", NULL); #endif + if (bio_crypt_ctx_init() < 0) + panic("Failed to allocate mem for bio crypt ctxs\n"); + return 0; } diff --git a/block/blk-merge.c b/block/blk-merge.c index 48e6725b32ee..c97c02a20c6a 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -557,6 +557,9 @@ static inline int ll_new_hw_segment(struct request *req, struct bio *bio, if (blk_integrity_merge_bio(req->q, req, bio) == false) goto no_merge; + if (WARN_ON_ONCE(!bio_crypt_ctx_compatible(bio, req->bio))) + goto no_merge; + /* * This will form the start of a new hw segment. Bump both * counters. @@ -711,8 +714,14 @@ static enum elv_merge blk_try_req_merge(struct request *req, { if (blk_discard_mergable(req)) return ELEVATOR_DISCARD_MERGE; - else if (blk_rq_pos(req) + blk_rq_sectors(req) == blk_rq_pos(next)) + else if (blk_rq_pos(req) + blk_rq_sectors(req) == blk_rq_pos(next)) { + if (!bio_crypt_ctx_back_mergeable(req->bio, + blk_rq_sectors(req), + next->bio)) { + return ELEVATOR_NO_MERGE; + } return ELEVATOR_BACK_MERGE; + } return ELEVATOR_NO_MERGE; } @@ -748,6 +757,9 @@ static struct request *attempt_merge(struct request_queue *q, if (req->ioprio != next->ioprio) return NULL; + if (!bio_crypt_ctx_compatible(req->bio, next->bio)) + return NULL; + /* * If we are allowed to merge, then append bio list * from next to rq and release next. merge_requests_fn @@ -880,16 +892,31 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio) if (rq->ioprio != bio_prio(bio)) return false; + /* Only merge if the crypt contexts are compatible */ + if (!bio_crypt_ctx_compatible(bio, rq->bio)) + return false; + return true; } enum elv_merge blk_try_merge(struct request *rq, struct bio *bio) { - if (blk_discard_mergable(rq)) + if (blk_discard_mergable(rq)) { return ELEVATOR_DISCARD_MERGE; - else if (blk_rq_pos(rq) + blk_rq_sectors(rq) == bio->bi_iter.bi_sector) + } else if (blk_rq_pos(rq) + blk_rq_sectors(rq) == + bio->bi_iter.bi_sector) { + if (!bio_crypt_ctx_back_mergeable(rq->bio, + blk_rq_sectors(rq), bio)) { + return ELEVATOR_NO_MERGE; + } return ELEVATOR_BACK_MERGE; - else if (blk_rq_pos(rq) - bio_sectors(bio) == bio->bi_iter.bi_sector) + } else if (blk_rq_pos(rq) - bio_sectors(bio) == + bio->bi_iter.bi_sector) { + if (!bio_crypt_ctx_back_mergeable(bio, + bio_sectors(bio), rq->bio)) { + return ELEVATOR_NO_MERGE; + } return ELEVATOR_FRONT_MERGE; + } return ELEVATOR_NO_MERGE; } diff --git a/block/bounce.c b/block/bounce.c index f8ed677a1bf7..6f9a2359b22a 100644 --- a/block/bounce.c +++ b/block/bounce.c @@ -267,14 +267,15 @@ static struct bio *bounce_clone_bio(struct bio *bio_src, gfp_t gfp_mask, break; } - if (bio_integrity(bio_src)) { - int ret; + if (bio_crypt_clone(bio, bio_src, gfp_mask) < 0) { + bio_put(bio); + return NULL; + } - ret = bio_integrity_clone(bio, bio_src, gfp_mask); - if (ret < 0) { - bio_put(bio); - return NULL; - } + if (bio_integrity(bio_src) && + bio_integrity_clone(bio, bio_src, gfp_mask) < 0) { + bio_put(bio); + return NULL; } bio_clone_blkg_association(bio, bio_src); diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 1a5e328c443a..67c24294d7c8 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1322,12 +1322,15 @@ static int clone_bio(struct dm_target_io *tio, struct bio *bio, sector_t sector, unsigned len) { struct bio *clone = &tio->clone; + int ret; __bio_clone_fast(clone, bio); - if (bio_integrity(bio)) { - int r; + ret = bio_crypt_clone(clone, bio, GFP_NOIO); + if (ret < 0) + return ret; + if (bio_integrity(bio)) { if (unlikely(!dm_target_has_integrity(tio->ti->type) && !dm_target_passes_integrity(tio->ti->type))) { DMWARN("%s: the target %s doesn't support integrity data.", @@ -1336,9 +1339,11 @@ static int clone_bio(struct dm_target_io *tio, struct bio *bio, return -EIO; } - r = bio_integrity_clone(clone, bio, GFP_NOIO); - if (r < 0) - return r; + ret = bio_integrity_clone(clone, bio, GFP_NOIO); + if (ret < 0) { + bio_crypt_free_ctx(clone); + return ret; + } } bio_advance(clone, to_bytes(sector - clone->bi_iter.bi_sector)); diff --git a/include/linux/bio-crypt-ctx.h b/include/linux/bio-crypt-ctx.h new file mode 100644 index 000000000000..5cd569f77c31 --- /dev/null +++ b/include/linux/bio-crypt-ctx.h @@ -0,0 +1,219 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2019 Google LLC + */ +#ifndef __LINUX_BIO_CRYPT_CTX_H +#define __LINUX_BIO_CRYPT_CTX_H + +enum blk_crypto_mode_num { + BLK_ENCRYPTION_MODE_INVALID = 0, + BLK_ENCRYPTION_MODE_AES_256_XTS = 1, +}; + +#ifdef CONFIG_BLOCK +#include + +#ifdef CONFIG_BLK_INLINE_ENCRYPTION +struct bio_crypt_ctx { + int keyslot; + const u8 *raw_key; + enum blk_crypto_mode_num crypto_mode; + u64 data_unit_num; + unsigned int data_unit_size_bits; + + /* + * The keyslot manager where the key has been programmed + * with keyslot. + */ + struct keyslot_manager *processing_ksm; + + /* + * Copy of the bvec_iter when this bio was submitted. + * We only want to en/decrypt the part of the bio + * as described by the bvec_iter upon submission because + * bio might be split before being resubmitted + */ + struct bvec_iter crypt_iter; + u64 sw_data_unit_num; +}; + +extern int bio_crypt_clone(struct bio *dst, struct bio *src, + gfp_t gfp_mask); + +static inline bool bio_has_crypt_ctx(struct bio *bio) +{ + return bio->bi_crypt_context; +} + +static inline void bio_crypt_advance(struct bio *bio, unsigned int bytes) +{ + if (bio_has_crypt_ctx(bio)) { + bio->bi_crypt_context->data_unit_num += + bytes >> bio->bi_crypt_context->data_unit_size_bits; + } +} + +static inline bool bio_crypt_has_keyslot(struct bio *bio) +{ + return bio->bi_crypt_context->keyslot >= 0; +} + +extern int bio_crypt_ctx_init(void); + +extern struct bio_crypt_ctx *bio_crypt_alloc_ctx(gfp_t gfp_mask); + +extern void bio_crypt_free_ctx(struct bio *bio); + +static inline int bio_crypt_set_ctx(struct bio *bio, + const u8 *raw_key, + enum blk_crypto_mode_num crypto_mode, + u64 dun, + unsigned int dun_bits, + gfp_t gfp_mask) +{ + struct bio_crypt_ctx *crypt_ctx; + + crypt_ctx = bio_crypt_alloc_ctx(gfp_mask); + if (!crypt_ctx) + return -ENOMEM; + + crypt_ctx->raw_key = raw_key; + crypt_ctx->data_unit_num = dun; + crypt_ctx->data_unit_size_bits = dun_bits; + crypt_ctx->crypto_mode = crypto_mode; + crypt_ctx->processing_ksm = NULL; + crypt_ctx->keyslot = -1; + bio->bi_crypt_context = crypt_ctx; + + return 0; +} + +static inline void bio_set_data_unit_num(struct bio *bio, u64 dun) +{ + bio->bi_crypt_context->data_unit_num = dun; +} + +static inline int bio_crypt_get_keyslot(struct bio *bio) +{ + return bio->bi_crypt_context->keyslot; +} + +static inline void bio_crypt_set_keyslot(struct bio *bio, + unsigned int keyslot, + struct keyslot_manager *ksm) +{ + bio->bi_crypt_context->keyslot = keyslot; + bio->bi_crypt_context->processing_ksm = ksm; +} + +extern void bio_crypt_ctx_release_keyslot(struct bio *bio); + +extern int bio_crypt_ctx_acquire_keyslot(struct bio *bio, + struct keyslot_manager *ksm); + +static inline const u8 *bio_crypt_raw_key(struct bio *bio) +{ + return bio->bi_crypt_context->raw_key; +} + +static inline enum blk_crypto_mode_num bio_crypto_mode(struct bio *bio) +{ + return bio->bi_crypt_context->crypto_mode; +} + +static inline u64 bio_crypt_data_unit_num(struct bio *bio) +{ + return bio->bi_crypt_context->data_unit_num; +} + +static inline u64 bio_crypt_sw_data_unit_num(struct bio *bio) +{ + return bio->bi_crypt_context->sw_data_unit_num; +} + +extern bool bio_crypt_should_process(struct bio *bio, struct request_queue *q); + +extern bool bio_crypt_ctx_compatible(struct bio *b_1, struct bio *b_2); + +extern bool bio_crypt_ctx_back_mergeable(struct bio *b_1, + unsigned int b1_sectors, + struct bio *b_2); + +#else /* CONFIG_BLK_INLINE_ENCRYPTION */ +struct keyslot_manager; + +static inline int bio_crypt_ctx_init(void) +{ + return 0; +} + +static inline int bio_crypt_clone(struct bio *dst, struct bio *src, + gfp_t gfp_mask) +{ + return 0; +} + +static inline void bio_crypt_advance(struct bio *bio, + unsigned int bytes) { } + +static inline bool bio_has_crypt_ctx(struct bio *bio) +{ + return false; +} + +static inline void bio_crypt_free_ctx(struct bio *bio) { } + +static inline void bio_crypt_set_ctx(struct bio *bio, + u8 *raw_key, + enum blk_crypto_mode_num crypto_mode, + u64 dun, + unsigned int dun_bits, + gfp_t gfp_mask) { } + +static inline void bio_set_data_unit_num(struct bio *bio, u64 dun) { } + +static inline bool bio_crypt_has_keyslot(struct bio *bio) +{ + return false; +} + +static inline void bio_crypt_set_keyslot(struct bio *bio, + unsigned int keyslot, + struct keyslot_manager *ksm) { } + +static inline int bio_crypt_get_keyslot(struct bio *bio) +{ + return -1; +} + +static inline u8 *bio_crypt_raw_key(struct bio *bio) +{ + return NULL; +} + +static inline u64 bio_crypt_data_unit_num(struct bio *bio) +{ + return 0; +} + +static inline bool bio_crypt_should_process(struct bio *bio, + struct request_queue *q) +{ + return false; +} + +static inline bool bio_crypt_ctx_compatible(struct bio *b_1, struct bio *b_2) +{ + return true; +} + +static inline bool bio_crypt_ctx_back_mergeable(struct bio *b_1, + unsigned int b1_sectors, + struct bio *b_2) +{ + return true; +} + +#endif /* CONFIG_BLK_INLINE_ENCRYPTION */ +#endif /* CONFIG_BLOCK */ +#endif /* __LINUX_BIO_CRYPT_CTX_H */ diff --git a/include/linux/bio.h b/include/linux/bio.h index d0cb7c350cdc..63d0fee423fa 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -8,6 +8,7 @@ #include #include #include +#include #ifdef CONFIG_BLOCK /* struct bio, bio_vec and BIO_* flags are defined in blk_types.h */ @@ -564,11 +565,6 @@ static inline void bvec_kunmap_irq(char *buffer, unsigned long *flags) } #endif -enum blk_crypto_mode_num { - BLK_ENCRYPTION_MODE_INVALID = 0, - BLK_ENCRYPTION_MODE_AES_256_XTS = 1, -}; - /* * BIO list management for use by remapping drivers (e.g. DM or MD) and loop. * diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index d688b96d1d63..d3ee2dcb634d 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -18,6 +18,7 @@ struct block_device; struct io_context; struct cgroup_subsys_state; typedef void (bio_end_io_t) (struct bio *); +struct bio_crypt_ctx; /* * Block error status values. See block/blk-core:blk_errors for the details. @@ -173,6 +174,11 @@ struct bio { u64 bi_iocost_cost; #endif #endif + +#ifdef CONFIG_BLK_INLINE_ENCRYPTION + struct bio_crypt_ctx *bi_crypt_context; +#endif + union { #if defined(CONFIG_BLK_DEV_INTEGRITY) struct bio_integrity_payload *bi_integrity; /* data integrity */ -- GitLab From a39331867335d4a94b6165e306265c9e24aca073 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 30 Oct 2019 22:42:57 +0100 Subject: [PATCH 930/993] ALSA: timer: Fix mutex deadlock at releasing card When a card is disconnected while in use, the system waits until all opened files are closed then releases the card. This is done via put_device() of the card device in each device release code. The recently reported mutex deadlock bug happens in this code path; snd_timer_close() for the timer device deals with the global register_mutex and it calls put_device() there. When this timer device is the last one, the card gets freed and it eventually calls snd_timer_free(), which has again the protection with the global register_mutex -- boom. Basically put_device() call itself is race-free, so a relative simple workaround is to move this put_device() call out of the mutex. For achieving that, in this patch, snd_timer_close_locked() got a new argument to store the card device pointer in return, and each caller invokes put_device() with the returned object after the mutex unlock. Reported-and-tested-by: Kirill A. Shutemov Cc: Signed-off-by: Takashi Iwai --- sound/core/timer.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index 5c9fbf3f4340..6b724d2ee2de 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -226,7 +226,8 @@ static int snd_timer_check_master(struct snd_timer_instance *master) return 0; } -static int snd_timer_close_locked(struct snd_timer_instance *timeri); +static int snd_timer_close_locked(struct snd_timer_instance *timeri, + struct device **card_devp_to_put); /* * open a timer instance @@ -238,6 +239,7 @@ int snd_timer_open(struct snd_timer_instance **ti, { struct snd_timer *timer; struct snd_timer_instance *timeri = NULL; + struct device *card_dev_to_put = NULL; int err; mutex_lock(®ister_mutex); @@ -261,7 +263,7 @@ int snd_timer_open(struct snd_timer_instance **ti, list_add_tail(&timeri->open_list, &snd_timer_slave_list); err = snd_timer_check_slave(timeri); if (err < 0) { - snd_timer_close_locked(timeri); + snd_timer_close_locked(timeri, &card_dev_to_put); timeri = NULL; } goto unlock; @@ -313,7 +315,7 @@ int snd_timer_open(struct snd_timer_instance **ti, timeri = NULL; if (timer->card) - put_device(&timer->card->card_dev); + card_dev_to_put = &timer->card->card_dev; module_put(timer->module); goto unlock; } @@ -323,12 +325,15 @@ int snd_timer_open(struct snd_timer_instance **ti, timer->num_instances++; err = snd_timer_check_master(timeri); if (err < 0) { - snd_timer_close_locked(timeri); + snd_timer_close_locked(timeri, &card_dev_to_put); timeri = NULL; } unlock: mutex_unlock(®ister_mutex); + /* put_device() is called after unlock for avoiding deadlock */ + if (card_dev_to_put) + put_device(card_dev_to_put); *ti = timeri; return err; } @@ -338,7 +343,8 @@ EXPORT_SYMBOL(snd_timer_open); * close a timer instance * call this with register_mutex down. */ -static int snd_timer_close_locked(struct snd_timer_instance *timeri) +static int snd_timer_close_locked(struct snd_timer_instance *timeri, + struct device **card_devp_to_put) { struct snd_timer *timer = timeri->timer; struct snd_timer_instance *slave, *tmp; @@ -395,7 +401,7 @@ static int snd_timer_close_locked(struct snd_timer_instance *timeri) timer->hw.close(timer); /* release a card refcount for safe disconnection */ if (timer->card) - put_device(&timer->card->card_dev); + *card_devp_to_put = &timer->card->card_dev; module_put(timer->module); } @@ -407,14 +413,18 @@ static int snd_timer_close_locked(struct snd_timer_instance *timeri) */ int snd_timer_close(struct snd_timer_instance *timeri) { + struct device *card_dev_to_put = NULL; int err; if (snd_BUG_ON(!timeri)) return -ENXIO; mutex_lock(®ister_mutex); - err = snd_timer_close_locked(timeri); + err = snd_timer_close_locked(timeri, &card_dev_to_put); mutex_unlock(®ister_mutex); + /* put_device() is called after unlock for avoiding deadlock */ + if (card_dev_to_put) + put_device(card_dev_to_put); return err; } EXPORT_SYMBOL(snd_timer_close); -- GitLab From d85bf5e127857bcc0bf04c873af658a946fdf614 Mon Sep 17 00:00:00 2001 From: Satya Tangirala Date: Wed, 30 Oct 2019 14:14:33 -0700 Subject: [PATCH 931/993] ANDROID: block: Fix bio_crypt_should_process WARN_ON bio_crypt_should_process would WARN that the bio did not have a keyslot in any keyslot manager even when we were on the decrypt path of blk-crypto, which is a bug. The WARN is now conditional on the caller being responible for handling encryption rather than blk-crypto (i.e. the WARN happens only if this function return true). Bug: 137270441 Test: tested as series; see Ie1b77f7615d6a7a60fdc9105c7ab2200d17636a8 Change-Id: I01aa7a04a5ab9c9e579bde8a06d095916d880e2c Signed-off-by: Satya Tangirala --- block/bio-crypt-ctx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/block/bio-crypt-ctx.c b/block/bio-crypt-ctx.c index aa3571f72ee7..95fd57896466 100644 --- a/block/bio-crypt-ctx.c +++ b/block/bio-crypt-ctx.c @@ -65,8 +65,11 @@ bool bio_crypt_should_process(struct bio *bio, struct request_queue *q) if (!bio_has_crypt_ctx(bio)) return false; + if (q->ksm != bio->bi_crypt_context->processing_ksm) + return false; + WARN_ON(!bio_crypt_has_keyslot(bio)); - return q->ksm == bio->bi_crypt_context->processing_ksm; + return true; } EXPORT_SYMBOL(bio_crypt_should_process); -- GitLab From 600e29fce0892253b08f858e56b5852494fbd93f Mon Sep 17 00:00:00 2001 From: Satya Tangirala Date: Thu, 24 Oct 2019 14:44:25 -0700 Subject: [PATCH 932/993] FROMLIST: block: blk-crypto for Inline Encryption We introduce blk-crypto, which manages programming keyslots for struct bios. With blk-crypto, filesystems only need to call bio_crypt_set_ctx with the encryption key, algorithm and data_unit_num; they don't have to worry about getting a keyslot for each encryption context, as blk-crypto handles that. Blk-crypto also makes it possible for layered devices like device mapper to make use of inline encryption hardware. Blk-crypto delegates crypto operations to inline encryption hardware when available, and also contains a software fallback to the kernel crypto API. For more details, refer to Documentation/block/inline-encryption.rst. Bug: 137270441 Test: tested as series; see Ie1b77f7615d6a7a60fdc9105c7ab2200d17636a8 Change-Id: I7df59fef0c1e90043b1899c5a95973e23afac0c5 Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11214731/ --- Documentation/block/index.rst | 1 + Documentation/block/inline-encryption.rst | 183 +++++ block/Kconfig | 2 + block/Makefile | 3 +- block/bio-crypt-ctx.c | 7 +- block/bio.c | 5 + block/blk-core.c | 11 +- block/blk-crypto.c | 798 ++++++++++++++++++++++ include/linux/bio-crypt-ctx.h | 7 + include/linux/blk-crypto.h | 62 ++ 10 files changed, 1076 insertions(+), 3 deletions(-) create mode 100644 Documentation/block/inline-encryption.rst create mode 100644 block/blk-crypto.c create mode 100644 include/linux/blk-crypto.h diff --git a/Documentation/block/index.rst b/Documentation/block/index.rst index 3fa7a52fafa4..026addfc69bc 100644 --- a/Documentation/block/index.rst +++ b/Documentation/block/index.rst @@ -14,6 +14,7 @@ Block cmdline-partition data-integrity deadline-iosched + inline-encryption ioprio kyber-iosched null_blk diff --git a/Documentation/block/inline-encryption.rst b/Documentation/block/inline-encryption.rst new file mode 100644 index 000000000000..202826cee95e --- /dev/null +++ b/Documentation/block/inline-encryption.rst @@ -0,0 +1,183 @@ +.. SPDX-License-Identifier: GPL-2.0 + +================= +Inline Encryption +================= + +Objective +========= + +We want to support inline encryption (IE) in the kernel. +To allow for testing, we also want a crypto API fallback when actual +IE hardware is absent. We also want IE to work with layered devices +like dm and loopback (i.e. we want to be able to use the IE hardware +of the underlying devices if present, or else fall back to crypto API +en/decryption). + + +Constraints and notes +===================== + +- IE hardware have a limited number of "keyslots" that can be programmed + with an encryption context (key, algorithm, data unit size, etc.) at any time. + One can specify a keyslot in a data request made to the device, and the + device will en/decrypt the data using the encryption context programmed into + that specified keyslot. When possible, we want to make multiple requests with + the same encryption context share the same keyslot. + +- We need a way for filesystems to specify an encryption context to use for + en/decrypting a struct bio, and a device driver (like UFS) needs to be able + to use that encryption context when it processes the bio. + +- We need a way for device drivers to expose their capabilities in a unified + way to the upper layers. + + +Design +====== + +We add a struct bio_crypt_ctx to struct bio that can represent an +encryption context, because we need to be able to pass this encryption +context from the FS layer to the device driver to act upon. + +While IE hardware works on the notion of keyslots, the FS layer has no +knowledge of keyslots - it simply wants to specify an encryption context to +use while en/decrypting a bio. + +We introduce a keyslot manager (KSM) that handles the translation from +encryption contexts specified by the FS to keyslots on the IE hardware. +This KSM also serves as the way IE hardware can expose their capabilities to +upper layers. The generic mode of operation is: each device driver that wants +to support IE will construct a KSM and set it up in its struct request_queue. +Upper layers that want to use IE on this device can then use this KSM in +the device's struct request_queue to translate an encryption context into +a keyslot. The presence of the KSM in the request queue shall be used to mean +that the device supports IE. + +On the device driver end of the interface, the device driver needs to tell the +KSM how to actually manipulate the IE hardware in the device to do things like +programming the crypto key into the IE hardware into a particular keyslot. All +this is achieved through the :c:type:`struct keyslot_mgmt_ll_ops` that the +device driver passes to the KSM when creating it. + +It uses refcounts to track which keyslots are idle (either they have no +encryption context programmed, or there are no in-flight struct bios +referencing that keyslot). When a new encryption context needs a keyslot, it +tries to find a keyslot that has already been programmed with the same +encryption context, and if there is no such keyslot, it evicts the least +recently used idle keyslot and programs the new encryption context into that +one. If no idle keyslots are available, then the caller will sleep until there +is at least one. + + +Blk-crypto +========== + +The above is sufficient for simple cases, but does not work if there is a +need for a crypto API fallback, or if we are want to use IE with layered +devices. To these ends, we introduce blk-crypto. Blk-crypto allows us to +present a unified view of encryption to the FS (so FS only needs to specify +an encryption context and not worry about keyslots at all), and blk-crypto +can decide whether to delegate the en/decryption to IE hardware or to the +crypto API. Blk-crypto maintains an internal KSM that serves as the crypto +API fallback. + +Blk-crypto needs to ensure that the encryption context is programmed into the +"correct" keyslot manager for IE. If a bio is submitted to a layered device +that eventually passes the bio down to a device that really does support IE, we +want the encryption context to be programmed into a keyslot for the KSM of the +device with IE support. However, blk-crypto does not know a priori whether a +particular device is the final device in the layering structure for a bio or +not. So in the case that a particular device does not support IE, since it is +possibly the final destination device for the bio, if the bio requires +encryption (i.e. the bio is doing a write operation), blk-crypto must fallback +to the crypto API *before* sending the bio to the device. + +Blk-crypto ensures that: + +- The bio's encryption context is programmed into a keyslot in the KSM of the + request queue that the bio is being submitted to (or the crypto API fallback + KSM if the request queue doesn't have a KSM), and that the ``processing_ksm`` + in the ``bi_crypt_context`` is set to this KSM + +- That the bio has its own individual reference to the keyslot in this KSM. + Once the bio passes through blk-crypto, its encryption context is programmed + in some KSM. The "its own individual reference to the keyslot" ensures that + keyslots can be released by each bio independently of other bios while + ensuring that the bio has a valid reference to the keyslot when, for e.g., the + crypto API fallback KSM in blk-crypto performs crypto on the device's behalf. + The individual references are ensured by increasing the refcount for the + keyslot in the ``processing_ksm`` when a bio with a programmed encryption + context is cloned. + + +What blk-crypto does on bio submission +-------------------------------------- + +**Case 1:** blk-crypto is given a bio with only an encryption context that hasn't +been programmed into any keyslot in any KSM (for e.g. a bio from the FS). + In this case, blk-crypto will program the encryption context into the KSM of the + request queue the bio is being submitted to (and if this KSM does not exist, + then it will program it into blk-crypto's internal KSM for crypto API + fallback). The KSM that this encryption context was programmed into is stored + as the ``processing_ksm`` in the bio's ``bi_crypt_context``. + +**Case 2:** blk-crypto is given a bio whose encryption context has already been +programmed into a keyslot in the *crypto API fallback* KSM. + In this case, blk-crypto does nothing; it treats the bio as not having + specified an encryption context. Note that we cannot do here what we will do + in Case 3 because we would have already encrypted the bio via the crypto API + by this point. + +**Case 3:** blk-crypto is given a bio whose encryption context has already been +programmed into a keyslot in some KSM (that is *not* the crypto API fallback +KSM). + In this case, blk-crypto first releases that keyslot from that KSM and then + treats the bio as in Case 1. + +This way, when a device driver is processing a bio, it can be sure that +the bio's encryption context has been programmed into some KSM (either the +device driver's request queue's KSM, or blk-crypto's crypto API fallback KSM). +It then simply needs to check if the bio's processing_ksm is the device's +request queue's KSM. If so, then it should proceed with IE. If not, it should +simply do nothing with respect to crypto, because some other KSM (perhaps the +blk-crypto crypto API fallback KSM) is handling the en/decryption. + +Blk-crypto will release the keyslot that is being held by the bio (and also +decrypt it if the bio is using the crypto API fallback KSM) once +``bio_remaining_done`` returns true for the bio. + + +Layered Devices +=============== + +Layered devices that wish to support IE need to create their own keyslot +manager for their request queue, and expose whatever functionality they choose. +When a layered device wants to pass a bio to another layer (either by +resubmitting the same bio, or by submitting a clone), it doesn't need to do +anything special because the bio (or the clone) will once again pass through +blk-crypto, which will work as described in Case 3. If a layered device wants +for some reason to do the IO by itself instead of passing it on to a child +device, but it also chose to expose IE capabilities by setting up a KSM in its +request queue, it is then responsible for en/decrypting the data itself. In +such cases, the device can choose to call the blk-crypto function +``blk_crypto_fallback_to_kernel_crypto_api`` (TODO: Not yet implemented), which will +cause the en/decryption to be done via the crypto API fallback. + + +Future Optimizations for layered devices +======================================== + +Creating a keyslot manager for the layered device uses up memory for each +keyslot, and in general, a layered device (like dm-linear) merely passes the +request on to a "child" device, so the keyslots in the layered device itself +might be completely unused. We can instead define a new type of KSM; the +"passthrough KSM", that layered devices can use to let blk-crypto know that +this layered device *will* pass the bio to some child device (and hence +through blk-crypto again, at which point blk-crypto can program the encryption +context, instead of programming it into the layered device's KSM). Again, if +the device "lies" and decides to do the IO itself instead of passing it on to +a child device, it is responsible for doing the en/decryption (and can choose +to call ``blk_crypto_fallback_to_kernel_crypto_api``). Another use case for the +"passthrough KSM" is for IE devices that want to manage their own keyslots/do +not have a limited number of keyslots. diff --git a/block/Kconfig b/block/Kconfig index ae52d42b783b..606a67e47e68 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -179,6 +179,8 @@ config BLK_SED_OPAL config BLK_INLINE_ENCRYPTION bool "Enable inline encryption support in block layer" + select CRYPTO + select CRYPTO_BLKCIPHER help Build the blk-crypto subsystem. Enabling this lets the block layer handle encryption, diff --git a/block/Makefile b/block/Makefile index f39611ed151f..8932c7e4fd07 100644 --- a/block/Makefile +++ b/block/Makefile @@ -36,4 +36,5 @@ obj-$(CONFIG_BLK_DEBUG_FS) += blk-mq-debugfs.o obj-$(CONFIG_BLK_DEBUG_FS_ZONED)+= blk-mq-debugfs-zoned.o obj-$(CONFIG_BLK_SED_OPAL) += sed-opal.o obj-$(CONFIG_BLK_PM) += blk-pm.o -obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += keyslot-manager.o bio-crypt-ctx.o +obj-$(CONFIG_BLK_INLINE_ENCRYPTION) += keyslot-manager.o bio-crypt-ctx.o \ + blk-crypto.o diff --git a/block/bio-crypt-ctx.c b/block/bio-crypt-ctx.c index 95fd57896466..0f7641b875e9 100644 --- a/block/bio-crypt-ctx.c +++ b/block/bio-crypt-ctx.c @@ -43,7 +43,12 @@ EXPORT_SYMBOL(bio_crypt_free_ctx); int bio_crypt_clone(struct bio *dst, struct bio *src, gfp_t gfp_mask) { - if (!bio_has_crypt_ctx(src)) + /* + * If a bio is swhandled, then it will be decrypted when bio_endio + * is called. As we only want the data to be decrypted once, copies + * of the bio must not have have a crypt context. + */ + if (!bio_has_crypt_ctx(src) || bio_crypt_swhandled(src)) return 0; dst->bi_crypt_context = bio_crypt_alloc_ctx(gfp_mask); diff --git a/block/bio.c b/block/bio.c index ce8003aadf07..36a1712328d0 100644 --- a/block/bio.c +++ b/block/bio.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "blk.h" @@ -1788,6 +1789,10 @@ void bio_endio(struct bio *bio) again: if (!bio_remaining_done(bio)) return; + + if (!blk_crypto_endio(bio)) + return; + if (!bio_integrity_endio(bio)) return; diff --git a/block/blk-core.c b/block/blk-core.c index 3b5959d386fb..0f7e81dbe2ee 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -38,6 +38,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -1061,7 +1062,9 @@ blk_qc_t generic_make_request(struct bio *bio) /* Create a fresh bio_list for all subordinate requests */ bio_list_on_stack[1] = bio_list_on_stack[0]; bio_list_init(&bio_list_on_stack[0]); - ret = q->make_request_fn(q, bio); + + if (!blk_crypto_submit_bio(&bio)) + ret = q->make_request_fn(q, bio); blk_queue_exit(q); @@ -1114,6 +1117,9 @@ blk_qc_t direct_make_request(struct bio *bio) if (!generic_make_request_checks(bio)) return BLK_QC_T_NONE; + if (blk_crypto_submit_bio(&bio)) + return BLK_QC_T_NONE; + if (unlikely(blk_queue_enter(q, nowait ? BLK_MQ_REQ_NOWAIT : 0))) { if (nowait && !blk_queue_dying(q)) bio->bi_status = BLK_STS_AGAIN; @@ -1810,5 +1816,8 @@ int __init blk_dev_init(void) if (bio_crypt_ctx_init() < 0) panic("Failed to allocate mem for bio crypt ctxs\n"); + if (blk_crypto_init() < 0) + panic("Failed to init blk-crypto\n"); + return 0; } diff --git a/block/blk-crypto.c b/block/blk-crypto.c new file mode 100644 index 000000000000..89649655bf4b --- /dev/null +++ b/block/blk-crypto.c @@ -0,0 +1,798 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +/* + * Refer to Documentation/block/inline-encryption.rst for detailed explanation. + */ + +#define pr_fmt(fmt) "blk-crypto: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Represents a crypto mode supported by blk-crypto */ +struct blk_crypto_mode { + const char *cipher_str; /* crypto API name (for fallback case) */ + size_t keysize; /* key size in bytes */ +}; + +static const struct blk_crypto_mode blk_crypto_modes[] = { + [BLK_ENCRYPTION_MODE_AES_256_XTS] = { + .cipher_str = "xts(aes)", + .keysize = 64, + }, +}; + +static unsigned int num_prealloc_bounce_pg = 32; +module_param(num_prealloc_bounce_pg, uint, 0); +MODULE_PARM_DESC(num_prealloc_bounce_pg, + "Number of preallocated bounce pages for blk-crypto to use during crypto API fallback encryption"); + +#define BLK_CRYPTO_MAX_KEY_SIZE 64 +static int blk_crypto_num_keyslots = 100; +module_param_named(num_keyslots, blk_crypto_num_keyslots, int, 0); +MODULE_PARM_DESC(num_keyslots, + "Number of keyslots for crypto API fallback in blk-crypto."); + +static struct blk_crypto_keyslot { + struct crypto_skcipher *tfm; + enum blk_crypto_mode_num crypto_mode; + u8 key[BLK_CRYPTO_MAX_KEY_SIZE]; + struct crypto_skcipher *tfms[ARRAY_SIZE(blk_crypto_modes)]; +} *blk_crypto_keyslots; + +/* + * Allocating a crypto tfm during I/O can deadlock, so we have to preallocate + * all of a mode's tfms when that mode starts being used. Since each mode may + * need all the keyslots at some point, each mode needs its own tfm for each + * keyslot; thus, a keyslot may contain tfms for multiple modes. However, to + * match the behavior of real inline encryption hardware (which only supports a + * single encryption context per keyslot), we only allow one tfm per keyslot to + * be used at a time - the rest of the unused tfms have their keys cleared. + */ +static struct mutex tfms_lock[ARRAY_SIZE(blk_crypto_modes)]; +static bool tfms_inited[ARRAY_SIZE(blk_crypto_modes)]; + +struct work_mem { + struct work_struct crypto_work; + struct bio *bio; +}; + +/* The following few vars are only used during the crypto API fallback */ +static struct keyslot_manager *blk_crypto_ksm; +static struct workqueue_struct *blk_crypto_wq; +static mempool_t *blk_crypto_page_pool; +static struct kmem_cache *blk_crypto_work_mem_cache; + +bool bio_crypt_swhandled(struct bio *bio) +{ + return bio_has_crypt_ctx(bio) && + bio->bi_crypt_context->processing_ksm == blk_crypto_ksm; +} + +static u8 blank_key[BLK_CRYPTO_MAX_KEY_SIZE]; +static void evict_keyslot(unsigned int slot) +{ + struct blk_crypto_keyslot *slotp = &blk_crypto_keyslots[slot]; + enum blk_crypto_mode_num crypto_mode = slotp->crypto_mode; + int err; + + WARN_ON(slotp->crypto_mode == BLK_ENCRYPTION_MODE_INVALID); + + /* Clear the key in the skcipher */ + err = crypto_skcipher_setkey(slotp->tfms[crypto_mode], blank_key, + blk_crypto_modes[crypto_mode].keysize); + WARN_ON(err); + memzero_explicit(slotp->key, BLK_CRYPTO_MAX_KEY_SIZE); + slotp->crypto_mode = BLK_ENCRYPTION_MODE_INVALID; +} + +static int blk_crypto_keyslot_program(void *priv, const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size, + unsigned int slot) +{ + struct blk_crypto_keyslot *slotp = &blk_crypto_keyslots[slot]; + const struct blk_crypto_mode *mode = &blk_crypto_modes[crypto_mode]; + size_t keysize = mode->keysize; + int err; + + if (crypto_mode != slotp->crypto_mode && + slotp->crypto_mode != BLK_ENCRYPTION_MODE_INVALID) { + evict_keyslot(slot); + } + + if (!slotp->tfms[crypto_mode]) + return -ENOMEM; + slotp->crypto_mode = crypto_mode; + err = crypto_skcipher_setkey(slotp->tfms[crypto_mode], key, keysize); + + if (err) { + evict_keyslot(slot); + return err; + } + + memcpy(slotp->key, key, keysize); + + return 0; +} + +static int blk_crypto_keyslot_evict(void *priv, const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size, + unsigned int slot) +{ + evict_keyslot(slot); + return 0; +} + +static int blk_crypto_keyslot_find(void *priv, + const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size_bytes) +{ + int slot; + const size_t keysize = blk_crypto_modes[crypto_mode].keysize; + + for (slot = 0; slot < blk_crypto_num_keyslots; slot++) { + if (blk_crypto_keyslots[slot].crypto_mode == crypto_mode && + !crypto_memneq(blk_crypto_keyslots[slot].key, key, keysize)) + return slot; + } + + return -ENOKEY; +} + +static bool blk_crypto_mode_supported(void *priv, + enum blk_crypto_mode_num crypt_mode, + unsigned int data_unit_size) +{ + /* All blk_crypto_modes are required to have a crypto API fallback. */ + return true; +} + +/* + * The crypto API fallback KSM ops - only used for a bio when it specifies a + * blk_crypto_mode for which we failed to get a keyslot in the device's inline + * encryption hardware (which probably means the device doesn't have inline + * encryption hardware that supports that crypto mode). + */ +static const struct keyslot_mgmt_ll_ops blk_crypto_ksm_ll_ops = { + .keyslot_program = blk_crypto_keyslot_program, + .keyslot_evict = blk_crypto_keyslot_evict, + .keyslot_find = blk_crypto_keyslot_find, + .crypto_mode_supported = blk_crypto_mode_supported, +}; + +static void blk_crypto_encrypt_endio(struct bio *enc_bio) +{ + struct bio *src_bio = enc_bio->bi_private; + int i; + + for (i = 0; i < enc_bio->bi_vcnt; i++) + mempool_free(enc_bio->bi_io_vec[i].bv_page, + blk_crypto_page_pool); + + src_bio->bi_status = enc_bio->bi_status; + + bio_put(enc_bio); + bio_endio(src_bio); +} + +static struct bio *blk_crypto_clone_bio(struct bio *bio_src) +{ + struct bvec_iter iter; + struct bio_vec bv; + struct bio *bio; + + bio = bio_alloc_bioset(GFP_NOIO, bio_segments(bio_src), NULL); + if (!bio) + return NULL; + bio->bi_disk = bio_src->bi_disk; + bio->bi_opf = bio_src->bi_opf; + bio->bi_ioprio = bio_src->bi_ioprio; + bio->bi_write_hint = bio_src->bi_write_hint; + bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector; + bio->bi_iter.bi_size = bio_src->bi_iter.bi_size; + + bio_for_each_segment(bv, bio_src, iter) + bio->bi_io_vec[bio->bi_vcnt++] = bv; + + if (bio_integrity(bio_src) && + bio_integrity_clone(bio, bio_src, GFP_NOIO) < 0) { + bio_put(bio); + return NULL; + } + + bio_clone_blkg_association(bio, bio_src); + blkcg_bio_issue_init(bio); + + return bio; +} + +/* Check that all I/O segments are data unit aligned */ +static int bio_crypt_check_alignment(struct bio *bio) +{ + int data_unit_size = 1 << bio->bi_crypt_context->data_unit_size_bits; + struct bvec_iter iter; + struct bio_vec bv; + + bio_for_each_segment(bv, bio, iter) { + if (!IS_ALIGNED(bv.bv_len | bv.bv_offset, data_unit_size)) + return -EIO; + } + return 0; +} + +static int blk_crypto_alloc_cipher_req(struct bio *src_bio, + struct skcipher_request **ciph_req_ptr, + struct crypto_wait *wait) +{ + int slot; + struct skcipher_request *ciph_req; + struct blk_crypto_keyslot *slotp; + + slot = bio_crypt_get_keyslot(src_bio); + slotp = &blk_crypto_keyslots[slot]; + ciph_req = skcipher_request_alloc(slotp->tfms[slotp->crypto_mode], + GFP_NOIO); + if (!ciph_req) { + src_bio->bi_status = BLK_STS_RESOURCE; + return -ENOMEM; + } + + skcipher_request_set_callback(ciph_req, + CRYPTO_TFM_REQ_MAY_BACKLOG | + CRYPTO_TFM_REQ_MAY_SLEEP, + crypto_req_done, wait); + *ciph_req_ptr = ciph_req; + return 0; +} + +static int blk_crypto_split_bio_if_needed(struct bio **bio_ptr) +{ + struct bio *bio = *bio_ptr; + unsigned int i = 0; + unsigned int num_sectors = 0; + struct bio_vec bv; + struct bvec_iter iter; + + bio_for_each_segment(bv, bio, iter) { + num_sectors += bv.bv_len >> SECTOR_SHIFT; + if (++i == BIO_MAX_PAGES) + break; + } + if (num_sectors < bio_sectors(bio)) { + struct bio *split_bio; + + split_bio = bio_split(bio, num_sectors, GFP_NOIO, NULL); + if (!split_bio) { + bio->bi_status = BLK_STS_RESOURCE; + return -ENOMEM; + } + bio_chain(split_bio, bio); + generic_make_request(bio); + *bio_ptr = split_bio; + } + return 0; +} + +/* + * The crypto API fallback's encryption routine. + * Allocate a bounce bio for encryption, encrypt the input bio using + * crypto API, and replace *bio_ptr with the bounce bio. May split input + * bio if it's too large. + */ +static int blk_crypto_encrypt_bio(struct bio **bio_ptr) +{ + struct bio *src_bio; + struct skcipher_request *ciph_req = NULL; + DECLARE_CRYPTO_WAIT(wait); + int err = 0; + u64 curr_dun; + union { + __le64 dun; + u8 bytes[16]; + } iv; + struct scatterlist src, dst; + struct bio *enc_bio; + struct bio_vec *enc_bvec; + int i, j; + int data_unit_size; + + /* Split the bio if it's too big for single page bvec */ + err = blk_crypto_split_bio_if_needed(bio_ptr); + if (err) + return err; + + src_bio = *bio_ptr; + data_unit_size = 1 << src_bio->bi_crypt_context->data_unit_size_bits; + + /* Allocate bounce bio for encryption */ + enc_bio = blk_crypto_clone_bio(src_bio); + if (!enc_bio) { + src_bio->bi_status = BLK_STS_RESOURCE; + return -ENOMEM; + } + + /* + * Use the crypto API fallback keyslot manager to get a crypto_skcipher + * for the algorithm and key specified for this bio. + */ + err = bio_crypt_ctx_acquire_keyslot(src_bio, blk_crypto_ksm); + if (err) { + src_bio->bi_status = BLK_STS_IOERR; + goto out_put_enc_bio; + } + + /* and then allocate an skcipher_request for it */ + err = blk_crypto_alloc_cipher_req(src_bio, &ciph_req, &wait); + if (err) + goto out_release_keyslot; + + curr_dun = bio_crypt_data_unit_num(src_bio); + sg_init_table(&src, 1); + sg_init_table(&dst, 1); + + skcipher_request_set_crypt(ciph_req, &src, &dst, + data_unit_size, iv.bytes); + + /* Encrypt each page in the bounce bio */ + for (i = 0, enc_bvec = enc_bio->bi_io_vec; i < enc_bio->bi_vcnt; + enc_bvec++, i++) { + struct page *plaintext_page = enc_bvec->bv_page; + struct page *ciphertext_page = + mempool_alloc(blk_crypto_page_pool, GFP_NOIO); + + enc_bvec->bv_page = ciphertext_page; + + if (!ciphertext_page) { + src_bio->bi_status = BLK_STS_RESOURCE; + err = -ENOMEM; + goto out_free_bounce_pages; + } + + sg_set_page(&src, plaintext_page, data_unit_size, + enc_bvec->bv_offset); + sg_set_page(&dst, ciphertext_page, data_unit_size, + enc_bvec->bv_offset); + + /* Encrypt each data unit in this page */ + for (j = 0; j < enc_bvec->bv_len; j += data_unit_size) { + memset(&iv, 0, sizeof(iv)); + iv.dun = cpu_to_le64(curr_dun); + + err = crypto_wait_req(crypto_skcipher_encrypt(ciph_req), + &wait); + if (err) { + i++; + src_bio->bi_status = BLK_STS_RESOURCE; + goto out_free_bounce_pages; + } + curr_dun++; + src.offset += data_unit_size; + dst.offset += data_unit_size; + } + } + + enc_bio->bi_private = src_bio; + enc_bio->bi_end_io = blk_crypto_encrypt_endio; + *bio_ptr = enc_bio; + + enc_bio = NULL; + err = 0; + goto out_free_ciph_req; + +out_free_bounce_pages: + while (i > 0) + mempool_free(enc_bio->bi_io_vec[--i].bv_page, + blk_crypto_page_pool); +out_free_ciph_req: + skcipher_request_free(ciph_req); +out_release_keyslot: + bio_crypt_ctx_release_keyslot(src_bio); +out_put_enc_bio: + if (enc_bio) + bio_put(enc_bio); + + return err; +} + +/* + * The crypto API fallback's main decryption routine. + * Decrypts input bio in place. + */ +static void blk_crypto_decrypt_bio(struct work_struct *w) +{ + struct work_mem *work_mem = + container_of(w, struct work_mem, crypto_work); + struct bio *bio = work_mem->bio; + struct skcipher_request *ciph_req = NULL; + DECLARE_CRYPTO_WAIT(wait); + struct bio_vec bv; + struct bvec_iter iter; + u64 curr_dun; + union { + __le64 dun; + u8 bytes[16]; + } iv; + struct scatterlist sg; + int data_unit_size = 1 << bio->bi_crypt_context->data_unit_size_bits; + int i; + int err; + + /* + * Use the crypto API fallback keyslot manager to get a crypto_skcipher + * for the algorithm and key specified for this bio. + */ + if (bio_crypt_ctx_acquire_keyslot(bio, blk_crypto_ksm)) { + bio->bi_status = BLK_STS_RESOURCE; + goto out_no_keyslot; + } + + /* and then allocate an skcipher_request for it */ + err = blk_crypto_alloc_cipher_req(bio, &ciph_req, &wait); + if (err) + goto out; + + curr_dun = bio_crypt_sw_data_unit_num(bio); + sg_init_table(&sg, 1); + skcipher_request_set_crypt(ciph_req, &sg, &sg, data_unit_size, + iv.bytes); + + /* Decrypt each segment in the bio */ + __bio_for_each_segment(bv, bio, iter, + bio->bi_crypt_context->crypt_iter) { + struct page *page = bv.bv_page; + + sg_set_page(&sg, page, data_unit_size, bv.bv_offset); + + /* Decrypt each data unit in the segment */ + for (i = 0; i < bv.bv_len; i += data_unit_size) { + memset(&iv, 0, sizeof(iv)); + iv.dun = cpu_to_le64(curr_dun); + if (crypto_wait_req(crypto_skcipher_decrypt(ciph_req), + &wait)) { + bio->bi_status = BLK_STS_IOERR; + goto out; + } + curr_dun++; + sg.offset += data_unit_size; + } + } + +out: + skcipher_request_free(ciph_req); + bio_crypt_ctx_release_keyslot(bio); +out_no_keyslot: + kmem_cache_free(blk_crypto_work_mem_cache, work_mem); + bio_endio(bio); +} + +/* Queue bio for decryption */ +static void blk_crypto_queue_decrypt_bio(struct bio *bio) +{ + struct work_mem *work_mem = + kmem_cache_zalloc(blk_crypto_work_mem_cache, GFP_ATOMIC); + + if (!work_mem) { + bio->bi_status = BLK_STS_RESOURCE; + bio_endio(bio); + return; + } + + INIT_WORK(&work_mem->crypto_work, blk_crypto_decrypt_bio); + work_mem->bio = bio; + queue_work(blk_crypto_wq, &work_mem->crypto_work); +} + +/** + * blk_crypto_submit_bio - handle submitting bio for inline encryption + * + * @bio_ptr: pointer to original bio pointer + * + * If the bio doesn't have inline encryption enabled or the submitter already + * specified a keyslot for the target device, do nothing. Else, a raw key must + * have been provided, so acquire a device keyslot for it if supported. Else, + * use the crypto API fallback. + * + * When the crypto API fallback is used for encryption, blk-crypto may choose to + * split the bio into 2 - the first one that will continue to be processed and + * the second one that will be resubmitted via generic_make_request. + * A bounce bio will be allocated to encrypt the contents of the aforementioned + * "first one", and *bio_ptr will be updated to this bounce bio. + * + * Return: 0 if bio submission should continue; nonzero if bio_endio() was + * already called so bio submission should abort. + */ +int blk_crypto_submit_bio(struct bio **bio_ptr) +{ + struct bio *bio = *bio_ptr; + struct request_queue *q; + int err; + struct bio_crypt_ctx *crypt_ctx; + + if (!bio_has_crypt_ctx(bio) || !bio_has_data(bio)) + return 0; + + /* + * When a read bio is marked for sw decryption, its bi_iter is saved + * so that when we decrypt the bio later, we know what part of it was + * marked for sw decryption (when the bio is passed down after + * blk_crypto_submit bio, it may be split or advanced so we cannot rely + * on the bi_iter while decrypting in blk_crypto_endio) + */ + if (bio_crypt_swhandled(bio)) + return 0; + + err = bio_crypt_check_alignment(bio); + if (err) { + bio->bi_status = BLK_STS_IOERR; + goto out; + } + + crypt_ctx = bio->bi_crypt_context; + q = bio->bi_disk->queue; + + if (bio_crypt_has_keyslot(bio)) { + /* Key already programmed into device? */ + if (q->ksm == crypt_ctx->processing_ksm) + return 0; + + /* Nope, release the existing keyslot. */ + bio_crypt_ctx_release_keyslot(bio); + } + + /* Get device keyslot if supported */ + if (q->ksm) { + err = bio_crypt_ctx_acquire_keyslot(bio, q->ksm); + if (!err) + return 0; + + pr_warn_once("Failed to acquire keyslot for %s (err=%d). Falling back to crypto API.\n", + bio->bi_disk->disk_name, err); + } + + /* Fallback to crypto API */ + if (!READ_ONCE(tfms_inited[bio->bi_crypt_context->crypto_mode])) { + err = -EIO; + bio->bi_status = BLK_STS_IOERR; + goto out; + } + + if (bio_data_dir(bio) == WRITE) { + /* Encrypt the data now */ + err = blk_crypto_encrypt_bio(bio_ptr); + if (err) + goto out; + } else { + /* Mark bio as swhandled */ + bio->bi_crypt_context->processing_ksm = blk_crypto_ksm; + bio->bi_crypt_context->crypt_iter = bio->bi_iter; + bio->bi_crypt_context->sw_data_unit_num = + bio->bi_crypt_context->data_unit_num; + } + return 0; +out: + bio_endio(*bio_ptr); + return err; +} + +/** + * blk_crypto_endio - clean up bio w.r.t inline encryption during bio_endio + * + * @bio - the bio to clean up + * + * If blk_crypto_submit_bio decided to fallback to crypto API for this + * bio, we queue the bio for decryption into a workqueue and return false, + * and call bio_endio(bio) at a later time (after the bio has been decrypted). + * + * If the bio is not to be decrypted by the crypto API, this function releases + * the reference to the keyslot that blk_crypto_submit_bio got. + * + * Return: true if bio_endio should continue; false otherwise (bio_endio will + * be called again when bio has been decrypted). + */ +bool blk_crypto_endio(struct bio *bio) +{ + if (!bio_has_crypt_ctx(bio)) + return true; + + if (bio_crypt_swhandled(bio)) { + /* + * The only bios that are swhandled when they reach here + * are those with bio_data_dir(bio) == READ, since WRITE + * bios that are encrypted by the crypto API fallback are + * handled by blk_crypto_encrypt_endio. + */ + + /* If there was an IO error, don't decrypt. */ + if (bio->bi_status) + return true; + + blk_crypto_queue_decrypt_bio(bio); + return false; + } + + if (bio_crypt_has_keyslot(bio)) + bio_crypt_ctx_release_keyslot(bio); + + return true; +} + +/** + * blk_crypto_start_using_mode() - Allocate skciphers for a + * mode_num for all keyslots + * @mode_num - the blk_crypto_mode we want to allocate ciphers for. + * + * Upper layers (filesystems) should call this function to ensure that a + * the crypto API fallback has transforms for this algorithm, if they become + * necessary. + * + * Return: 0 on success and -err on error. + */ +int blk_crypto_start_using_mode(enum blk_crypto_mode_num mode_num, + unsigned int data_unit_size, + struct request_queue *q) +{ + struct blk_crypto_keyslot *slotp; + int err = 0; + int i; + + /* + * Fast path + * Ensure that updates to blk_crypto_keyslots[i].tfms[mode_num] + * for each i are visible before we try to access them. + */ + if (likely(smp_load_acquire(&tfms_inited[mode_num]))) + return 0; + + /* + * If the keyslot manager of the request queue supports this + * crypto mode, then we don't need to allocate this mode. + */ + if (keyslot_manager_crypto_mode_supported(q->ksm, mode_num, + data_unit_size)) { + return 0; + } + + mutex_lock(&tfms_lock[mode_num]); + if (likely(tfms_inited[mode_num])) + goto out; + + for (i = 0; i < blk_crypto_num_keyslots; i++) { + slotp = &blk_crypto_keyslots[i]; + slotp->tfms[mode_num] = crypto_alloc_skcipher( + blk_crypto_modes[mode_num].cipher_str, + 0, 0); + if (IS_ERR(slotp->tfms[mode_num])) { + err = PTR_ERR(slotp->tfms[mode_num]); + slotp->tfms[mode_num] = NULL; + goto out_free_tfms; + } + + crypto_skcipher_set_flags(slotp->tfms[mode_num], + CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); + } + + /* + * Ensure that updates to blk_crypto_keyslots[i].tfms[mode_num] + * for each i are visible before we set tfms_inited[mode_num]. + */ + smp_store_release(&tfms_inited[mode_num], true); + goto out; + +out_free_tfms: + for (i = 0; i < blk_crypto_num_keyslots; i++) { + slotp = &blk_crypto_keyslots[i]; + crypto_free_skcipher(slotp->tfms[mode_num]); + slotp->tfms[mode_num] = NULL; + } +out: + mutex_unlock(&tfms_lock[mode_num]); + return err; +} +EXPORT_SYMBOL(blk_crypto_start_using_mode); + +/** + * blk_crypto_evict_key() - Evict a key from any inline encryption hardware + * it may have been programmed into + * @q - The request queue who's keyslot manager this key might have been + * programmed into + * @key - The key to evict + * @mode - The blk_crypto_mode_num used with this key + * @data_unit_size - The data unit size used with this key + * + * Upper layers (filesystems) should call this function to ensure that a key + * is evicted from hardware that it might have been programmed into. This + * will call keyslot_manager_evict_key on the queue's keyslot manager, if one + * exists, and supports the crypto algorithm with the specified data unit size. + * Otherwise, it will evict the key from the blk_crypto_ksm. + * + * Return: 0 on success, -err on error. + */ +int blk_crypto_evict_key(struct request_queue *q, const u8 *key, + enum blk_crypto_mode_num mode, + unsigned int data_unit_size) +{ + struct keyslot_manager *ksm = blk_crypto_ksm; + + if (q && q->ksm && keyslot_manager_crypto_mode_supported(q->ksm, mode, + data_unit_size)) { + ksm = q->ksm; + } + + return keyslot_manager_evict_key(ksm, key, mode, data_unit_size); +} +EXPORT_SYMBOL(blk_crypto_evict_key); + +int __init blk_crypto_init(void) +{ + int i; + int err = -ENOMEM; + + prandom_bytes(blank_key, BLK_CRYPTO_MAX_KEY_SIZE); + + blk_crypto_ksm = keyslot_manager_create(blk_crypto_num_keyslots, + &blk_crypto_ksm_ll_ops, + NULL); + if (!blk_crypto_ksm) + goto out; + + blk_crypto_wq = alloc_workqueue("blk_crypto_wq", + WQ_UNBOUND | WQ_HIGHPRI | + WQ_MEM_RECLAIM, + num_online_cpus()); + if (!blk_crypto_wq) + goto out_free_ksm; + + blk_crypto_keyslots = kcalloc(blk_crypto_num_keyslots, + sizeof(*blk_crypto_keyslots), + GFP_KERNEL); + if (!blk_crypto_keyslots) + goto out_free_workqueue; + + for (i = 0; i < blk_crypto_num_keyslots; i++) { + blk_crypto_keyslots[i].crypto_mode = + BLK_ENCRYPTION_MODE_INVALID; + } + + for (i = 0; i < ARRAY_SIZE(blk_crypto_modes); i++) + mutex_init(&tfms_lock[i]); + + blk_crypto_page_pool = + mempool_create_page_pool(num_prealloc_bounce_pg, 0); + if (!blk_crypto_page_pool) + goto out_free_keyslots; + + blk_crypto_work_mem_cache = KMEM_CACHE(work_mem, SLAB_RECLAIM_ACCOUNT); + if (!blk_crypto_work_mem_cache) + goto out_free_page_pool; + + return 0; + +out_free_page_pool: + mempool_destroy(blk_crypto_page_pool); + blk_crypto_page_pool = NULL; +out_free_keyslots: + kzfree(blk_crypto_keyslots); + blk_crypto_keyslots = NULL; +out_free_workqueue: + destroy_workqueue(blk_crypto_wq); + blk_crypto_wq = NULL; +out_free_ksm: + keyslot_manager_destroy(blk_crypto_ksm); + blk_crypto_ksm = NULL; +out: + pr_warn("No memory for blk-crypto crypto API fallback."); + return err; +} diff --git a/include/linux/bio-crypt-ctx.h b/include/linux/bio-crypt-ctx.h index 5cd569f77c31..7c389f310bab 100644 --- a/include/linux/bio-crypt-ctx.h +++ b/include/linux/bio-crypt-ctx.h @@ -53,6 +53,8 @@ static inline void bio_crypt_advance(struct bio *bio, unsigned int bytes) } } +extern bool bio_crypt_swhandled(struct bio *bio); + static inline bool bio_crypt_has_keyslot(struct bio *bio) { return bio->bi_crypt_context->keyslot >= 0; @@ -170,6 +172,11 @@ static inline void bio_crypt_set_ctx(struct bio *bio, unsigned int dun_bits, gfp_t gfp_mask) { } +static inline bool bio_crypt_swhandled(struct bio *bio) +{ + return false; +} + static inline void bio_set_data_unit_num(struct bio *bio, u64 dun) { } static inline bool bio_crypt_has_keyslot(struct bio *bio) diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h new file mode 100644 index 000000000000..2a07401244a6 --- /dev/null +++ b/include/linux/blk-crypto.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2019 Google LLC + */ + +#ifndef __LINUX_BLK_CRYPTO_H +#define __LINUX_BLK_CRYPTO_H + +#include +#include + +#ifdef CONFIG_BLK_INLINE_ENCRYPTION + +int blk_crypto_init(void); + +int blk_crypto_submit_bio(struct bio **bio_ptr); + +bool blk_crypto_endio(struct bio *bio); + +int blk_crypto_start_using_mode(enum blk_crypto_mode_num mode_num, + unsigned int data_unit_size, + struct request_queue *q); + +int blk_crypto_evict_key(struct request_queue *q, const u8 *key, + enum blk_crypto_mode_num mode, + unsigned int data_unit_size); + +#else /* CONFIG_BLK_INLINE_ENCRYPTION */ + +static inline int blk_crypto_init(void) +{ + return 0; +} + +static inline int blk_crypto_submit_bio(struct bio **bio_ptr) +{ + return 0; +} + +static inline bool blk_crypto_endio(struct bio *bio) +{ + return true; +} + +static inline int +blk_crypto_start_using_mode(enum blk_crypto_mode_num mode_num, + unsigned int data_unit_size, + struct request_queue *q) +{ + return -EOPNOTSUPP; +} + +static inline int blk_crypto_evict_key(struct request_queue *q, const u8 *key, + enum blk_crypto_mode_num mode, + unsigned int data_unit_size) +{ + return 0; +} + +#endif /* CONFIG_BLK_INLINE_ENCRYPTION */ + +#endif /* __LINUX_BLK_CRYPTO_H */ -- GitLab From 3737246b7b2d6d64e8dfeb16a32f964801dc83fb Mon Sep 17 00:00:00 2001 From: Satya Tangirala Date: Thu, 24 Oct 2019 14:44:26 -0700 Subject: [PATCH 933/993] FROMLIST: scsi: ufs: UFS driver v2.1 spec crypto additions Add the crypto registers and structs defined in v2.1 of the JEDEC UFSHCI specification in preparation to add support for inline encryption to UFS. Bug: 137270441 Test: tested as series; see Ie1b77f7615d6a7a60fdc9105c7ab2200d17636a8 Change-Id: I8e4006bfd69692f7d5c1c37f660d90b9e2fa1274 Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11214737/ --- drivers/scsi/ufs/ufshcd.c | 2 ++ drivers/scsi/ufs/ufshcd.h | 5 +++ drivers/scsi/ufs/ufshci.h | 67 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 11a87f51c442..e66eb7a39a02 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4769,6 +4769,8 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) case OCS_MISMATCH_RESP_UPIU_SIZE: case OCS_PEER_COMM_FAILURE: case OCS_FATAL_ERROR: + case OCS_INVALID_CRYPTO_CONFIG: + case OCS_GENERAL_CRYPTO_ERROR: default: result |= DID_ERROR << 16; dev_err(hba->dev, diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index c94cfda52829..8f2329b4fe79 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -716,6 +716,11 @@ struct ufs_hba { * the performance of ongoing read/write operations. */ #define UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND (1 << 5) + /* + * This capability allows the host controller driver to use the + * inline crypto engine, if it is present + */ +#define UFSHCD_CAP_CRYPTO (1 << 6) struct devfreq *devfreq; struct ufs_clk_scaling clk_scaling; diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h index dbb75cd28dc8..291f6c3e79db 100644 --- a/drivers/scsi/ufs/ufshci.h +++ b/drivers/scsi/ufs/ufshci.h @@ -90,6 +90,7 @@ enum { MASK_64_ADDRESSING_SUPPORT = 0x01000000, MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT = 0x02000000, MASK_UIC_DME_TEST_MODE_SUPPORT = 0x04000000, + MASK_CRYPTO_SUPPORT = 0x10000000, }; #define UFS_MASK(mask, offset) ((mask) << (offset)) @@ -143,6 +144,7 @@ enum { #define DEVICE_FATAL_ERROR 0x800 #define CONTROLLER_FATAL_ERROR 0x10000 #define SYSTEM_BUS_FATAL_ERROR 0x20000 +#define CRYPTO_ENGINE_FATAL_ERROR 0x40000 #define UFSHCD_UIC_HIBERN8_MASK (UIC_HIBERNATE_ENTER |\ UIC_HIBERNATE_EXIT) @@ -155,11 +157,13 @@ enum { #define UFSHCD_ERROR_MASK (UIC_ERROR |\ DEVICE_FATAL_ERROR |\ CONTROLLER_FATAL_ERROR |\ - SYSTEM_BUS_FATAL_ERROR) + SYSTEM_BUS_FATAL_ERROR |\ + CRYPTO_ENGINE_FATAL_ERROR) #define INT_FATAL_ERRORS (DEVICE_FATAL_ERROR |\ CONTROLLER_FATAL_ERROR |\ - SYSTEM_BUS_FATAL_ERROR) + SYSTEM_BUS_FATAL_ERROR |\ + CRYPTO_ENGINE_FATAL_ERROR) /* HCS - Host Controller Status 30h */ #define DEVICE_PRESENT 0x1 @@ -318,6 +322,61 @@ enum { INTERRUPT_MASK_ALL_VER_21 = 0x71FFF, }; +/* CCAP - Crypto Capability 100h */ +union ufs_crypto_capabilities { + __le32 reg_val; + struct { + u8 num_crypto_cap; + u8 config_count; + u8 reserved; + u8 config_array_ptr; + }; +}; + +enum ufs_crypto_key_size { + UFS_CRYPTO_KEY_SIZE_INVALID = 0x0, + UFS_CRYPTO_KEY_SIZE_128 = 0x1, + UFS_CRYPTO_KEY_SIZE_192 = 0x2, + UFS_CRYPTO_KEY_SIZE_256 = 0x3, + UFS_CRYPTO_KEY_SIZE_512 = 0x4, +}; + +enum ufs_crypto_alg { + UFS_CRYPTO_ALG_AES_XTS = 0x0, + UFS_CRYPTO_ALG_BITLOCKER_AES_CBC = 0x1, + UFS_CRYPTO_ALG_AES_ECB = 0x2, + UFS_CRYPTO_ALG_ESSIV_AES_CBC = 0x3, +}; + +/* x-CRYPTOCAP - Crypto Capability X */ +union ufs_crypto_cap_entry { + __le32 reg_val; + struct { + u8 algorithm_id; + u8 sdus_mask; /* Supported data unit size mask */ + u8 key_size; + u8 reserved; + }; +}; + +#define UFS_CRYPTO_CONFIGURATION_ENABLE (1 << 7) +#define UFS_CRYPTO_KEY_MAX_SIZE 64 +/* x-CRYPTOCFG - Crypto Configuration X */ +union ufs_crypto_cfg_entry { + __le32 reg_val[32]; + struct { + u8 crypto_key[UFS_CRYPTO_KEY_MAX_SIZE]; + u8 data_unit_size; + u8 crypto_cap_idx; + u8 reserved_1; + u8 config_enable; + u8 reserved_multi_host; + u8 reserved_2; + u8 vsb[2]; + u8 reserved_3[56]; + }; +}; + /* * Request Descriptor Definitions */ @@ -339,6 +398,7 @@ enum { UTP_NATIVE_UFS_COMMAND = 0x10000000, UTP_DEVICE_MANAGEMENT_FUNCTION = 0x20000000, UTP_REQ_DESC_INT_CMD = 0x01000000, + UTP_REQ_DESC_CRYPTO_ENABLE_CMD = 0x00800000, }; /* UTP Transfer Request Data Direction (DD) */ @@ -358,6 +418,9 @@ enum { OCS_PEER_COMM_FAILURE = 0x5, OCS_ABORTED = 0x6, OCS_FATAL_ERROR = 0x7, + OCS_DEVICE_FATAL_ERROR = 0x8, + OCS_INVALID_CRYPTO_CONFIG = 0x9, + OCS_GENERAL_CRYPTO_ERROR = 0xA, OCS_INVALID_COMMAND_STATUS = 0x0F, MASK_OCS = 0x0F, }; -- GitLab From 4bac1109a10c55d49c0aa4f7ebdc4bc53cc368e8 Mon Sep 17 00:00:00 2001 From: Satya Tangirala Date: Thu, 24 Oct 2019 14:44:27 -0700 Subject: [PATCH 934/993] FROMLIST: scsi: ufs: UFS crypto API Introduce functions to manipulate UFS inline encryption hardware in line with the JEDEC UFSHCI v2.1 specification and to work with the block keyslot manager. Bug: 137270441 Test: tested as series; see Ie1b77f7615d6a7a60fdc9105c7ab2200d17636a8 Change-Id: I98d2512858a231f11a6bf868198446378d3aa491 Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11214745/ --- drivers/scsi/ufs/Kconfig | 9 + drivers/scsi/ufs/Makefile | 1 + drivers/scsi/ufs/ufshcd-crypto.c | 391 +++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufshcd-crypto.h | 86 +++++++ drivers/scsi/ufs/ufshcd.h | 14 ++ 5 files changed, 501 insertions(+) create mode 100644 drivers/scsi/ufs/ufshcd-crypto.c create mode 100644 drivers/scsi/ufs/ufshcd-crypto.h diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index 0b845ab7c3bf..3ee5cede823e 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -150,3 +150,12 @@ config SCSI_UFS_BSG Select this if you need a bsg device node for your UFS controller. If unsure, say N. + +config SCSI_UFS_CRYPTO + bool "UFS Crypto Engine Support" + depends on SCSI_UFSHCD && BLK_INLINE_ENCRYPTION + help + Enable Crypto Engine Support in UFS. + Enabling this makes it possible for the kernel to use the crypto + capabilities of the UFS device (if present) to perform crypto + operations on data being transferred to/from the device. diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 2a9097939bcb..094c39989a37 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o obj-$(CONFIG_SCSI_UFS_MEDIATEK) += ufs-mediatek.o +ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO) += ufshcd-crypto.o diff --git a/drivers/scsi/ufs/ufshcd-crypto.c b/drivers/scsi/ufs/ufshcd-crypto.c new file mode 100644 index 000000000000..3900a07a7e9b --- /dev/null +++ b/drivers/scsi/ufs/ufshcd-crypto.c @@ -0,0 +1,391 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +#include + +#include "ufshcd.h" +#include "ufshcd-crypto.h" + +static bool ufshcd_cap_idx_valid(struct ufs_hba *hba, unsigned int cap_idx) +{ + return cap_idx < hba->crypto_capabilities.num_crypto_cap; +} + +static u8 get_data_unit_size_mask(unsigned int data_unit_size) +{ + if (data_unit_size < 512 || data_unit_size > 65536 || + !is_power_of_2(data_unit_size)) + return 0; + + return data_unit_size / 512; +} + +static size_t get_keysize_bytes(enum ufs_crypto_key_size size) +{ + switch (size) { + case UFS_CRYPTO_KEY_SIZE_128: return 16; + case UFS_CRYPTO_KEY_SIZE_192: return 24; + case UFS_CRYPTO_KEY_SIZE_256: return 32; + case UFS_CRYPTO_KEY_SIZE_512: return 64; + default: return 0; + } +} + +static int ufshcd_crypto_cap_find(void *hba_p, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size) +{ + struct ufs_hba *hba = hba_p; + enum ufs_crypto_alg ufs_alg; + u8 data_unit_mask; + int cap_idx; + enum ufs_crypto_key_size ufs_key_size; + union ufs_crypto_cap_entry *ccap_array = hba->crypto_cap_array; + + if (!ufshcd_hba_is_crypto_supported(hba)) + return -EINVAL; + + switch (crypto_mode) { + case BLK_ENCRYPTION_MODE_AES_256_XTS: + ufs_alg = UFS_CRYPTO_ALG_AES_XTS; + ufs_key_size = UFS_CRYPTO_KEY_SIZE_256; + break; + default: return -EINVAL; + } + + data_unit_mask = get_data_unit_size_mask(data_unit_size); + + for (cap_idx = 0; cap_idx < hba->crypto_capabilities.num_crypto_cap; + cap_idx++) { + if (ccap_array[cap_idx].algorithm_id == ufs_alg && + (ccap_array[cap_idx].sdus_mask & data_unit_mask) && + ccap_array[cap_idx].key_size == ufs_key_size) + return cap_idx; + } + + return -EINVAL; +} + +/** + * ufshcd_crypto_cfg_entry_write_key - Write a key into a crypto_cfg_entry + * + * Writes the key with the appropriate format - for AES_XTS, + * the first half of the key is copied as is, the second half is + * copied with an offset halfway into the cfg->crypto_key array. + * For the other supported crypto algs, the key is just copied. + * + * @cfg: The crypto config to write to + * @key: The key to write + * @cap: The crypto capability (which specifies the crypto alg and key size) + * + * Returns 0 on success, or -EINVAL + */ +static int ufshcd_crypto_cfg_entry_write_key(union ufs_crypto_cfg_entry *cfg, + const u8 *key, + union ufs_crypto_cap_entry cap) +{ + size_t key_size_bytes = get_keysize_bytes(cap.key_size); + + if (key_size_bytes == 0) + return -EINVAL; + + switch (cap.algorithm_id) { + case UFS_CRYPTO_ALG_AES_XTS: + key_size_bytes *= 2; + if (key_size_bytes > UFS_CRYPTO_KEY_MAX_SIZE) + return -EINVAL; + + memcpy(cfg->crypto_key, key, key_size_bytes/2); + memcpy(cfg->crypto_key + UFS_CRYPTO_KEY_MAX_SIZE/2, + key + key_size_bytes/2, key_size_bytes/2); + return 0; + case UFS_CRYPTO_ALG_BITLOCKER_AES_CBC: // fallthrough + case UFS_CRYPTO_ALG_AES_ECB: // fallthrough + case UFS_CRYPTO_ALG_ESSIV_AES_CBC: + memcpy(cfg->crypto_key, key, key_size_bytes); + return 0; + } + + return -EINVAL; +} + +static void program_key(struct ufs_hba *hba, + const union ufs_crypto_cfg_entry *cfg, + int slot) +{ + int i; + u32 slot_offset = hba->crypto_cfg_register + slot * sizeof(*cfg); + + /* Clear the dword 16 */ + ufshcd_writel(hba, 0, slot_offset + 16 * sizeof(cfg->reg_val[0])); + /* Ensure that CFGE is cleared before programming the key */ + wmb(); + for (i = 0; i < 16; i++) { + ufshcd_writel(hba, le32_to_cpu(cfg->reg_val[i]), + slot_offset + i * sizeof(cfg->reg_val[0])); + /* Spec says each dword in key must be written sequentially */ + wmb(); + } + /* Write dword 17 */ + ufshcd_writel(hba, le32_to_cpu(cfg->reg_val[17]), + slot_offset + 17 * sizeof(cfg->reg_val[0])); + /* Dword 16 must be written last */ + wmb(); + /* Write dword 16 */ + ufshcd_writel(hba, le32_to_cpu(cfg->reg_val[16]), + slot_offset + 16 * sizeof(cfg->reg_val[0])); + wmb(); +} + +static int ufshcd_crypto_keyslot_program(void *hba_p, const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size, + unsigned int slot) +{ + struct ufs_hba *hba = hba_p; + int err = 0; + u8 data_unit_mask; + union ufs_crypto_cfg_entry cfg; + union ufs_crypto_cfg_entry *cfg_arr = hba->crypto_cfgs; + int cap_idx; + + cap_idx = ufshcd_crypto_cap_find(hba_p, crypto_mode, + data_unit_size); + + if (!ufshcd_is_crypto_enabled(hba) || + !ufshcd_keyslot_valid(hba, slot) || + !ufshcd_cap_idx_valid(hba, cap_idx)) + return -EINVAL; + + data_unit_mask = get_data_unit_size_mask(data_unit_size); + + if (!(data_unit_mask & hba->crypto_cap_array[cap_idx].sdus_mask)) + return -EINVAL; + + memset(&cfg, 0, sizeof(cfg)); + cfg.data_unit_size = data_unit_mask; + cfg.crypto_cap_idx = cap_idx; + cfg.config_enable |= UFS_CRYPTO_CONFIGURATION_ENABLE; + + err = ufshcd_crypto_cfg_entry_write_key(&cfg, key, + hba->crypto_cap_array[cap_idx]); + if (err) + return err; + + program_key(hba, &cfg, slot); + + memcpy(&cfg_arr[slot], &cfg, sizeof(cfg)); + memzero_explicit(&cfg, sizeof(cfg)); + + return 0; +} + +static int ufshcd_crypto_keyslot_find(void *hba_p, + const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size) +{ + struct ufs_hba *hba = hba_p; + int err = 0; + int slot; + u8 data_unit_mask; + union ufs_crypto_cfg_entry cfg; + union ufs_crypto_cfg_entry *cfg_arr = hba->crypto_cfgs; + int cap_idx; + + cap_idx = ufshcd_crypto_cap_find(hba_p, crypto_mode, + data_unit_size); + + if (!ufshcd_is_crypto_enabled(hba) || + !ufshcd_cap_idx_valid(hba, cap_idx)) + return -EINVAL; + + data_unit_mask = get_data_unit_size_mask(data_unit_size); + + if (!(data_unit_mask & hba->crypto_cap_array[cap_idx].sdus_mask)) + return -EINVAL; + + memset(&cfg, 0, sizeof(cfg)); + err = ufshcd_crypto_cfg_entry_write_key(&cfg, key, + hba->crypto_cap_array[cap_idx]); + + if (err) + return -EINVAL; + + for (slot = 0; slot < NUM_KEYSLOTS(hba); slot++) { + if ((cfg_arr[slot].config_enable & + UFS_CRYPTO_CONFIGURATION_ENABLE) && + data_unit_mask == cfg_arr[slot].data_unit_size && + cap_idx == cfg_arr[slot].crypto_cap_idx && + !crypto_memneq(&cfg.crypto_key, cfg_arr[slot].crypto_key, + UFS_CRYPTO_KEY_MAX_SIZE)) { + memzero_explicit(&cfg, sizeof(cfg)); + return slot; + } + } + + memzero_explicit(&cfg, sizeof(cfg)); + return -ENOKEY; +} + +static int ufshcd_crypto_keyslot_evict(void *hba_p, const u8 *key, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size, + unsigned int slot) +{ + struct ufs_hba *hba = hba_p; + int i = 0; + u32 reg_base; + union ufs_crypto_cfg_entry *cfg_arr = hba->crypto_cfgs; + + if (!ufshcd_is_crypto_enabled(hba) || + !ufshcd_keyslot_valid(hba, slot)) + return -EINVAL; + + memset(&cfg_arr[slot], 0, sizeof(cfg_arr[slot])); + reg_base = hba->crypto_cfg_register + slot * sizeof(cfg_arr[0]); + + /* + * Clear the crypto cfg on the device. Clearing CFGE + * might not be sufficient, so just clear the entire cfg. + */ + for (i = 0; i < sizeof(cfg_arr[0]); i += sizeof(__le32)) + ufshcd_writel(hba, 0, reg_base + i); + wmb(); + + return 0; +} + +static bool ufshcd_crypto_mode_supported(void *hba_p, + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size) +{ + return ufshcd_crypto_cap_find(hba_p, crypto_mode, data_unit_size) >= 0; +} + +void ufshcd_crypto_enable(struct ufs_hba *hba) +{ + union ufs_crypto_cfg_entry *cfg_arr = hba->crypto_cfgs; + int slot; + + if (!ufshcd_hba_is_crypto_supported(hba)) + return; + + hba->caps |= UFSHCD_CAP_CRYPTO; + /* + * Reset might clear all keys, so reprogram all the keys. + * Also serves to clear keys on driver init. + */ + for (slot = 0; slot < NUM_KEYSLOTS(hba); slot++) + program_key(hba, &cfg_arr[slot], slot); +} + +void ufshcd_crypto_disable(struct ufs_hba *hba) +{ + hba->caps &= ~UFSHCD_CAP_CRYPTO; +} + +static const struct keyslot_mgmt_ll_ops ufshcd_ksm_ops = { + .keyslot_program = ufshcd_crypto_keyslot_program, + .keyslot_evict = ufshcd_crypto_keyslot_evict, + .keyslot_find = ufshcd_crypto_keyslot_find, + .crypto_mode_supported = ufshcd_crypto_mode_supported, +}; + +/** + * ufshcd_hba_init_crypto - Read crypto capabilities, init crypto fields in hba + * @hba: Per adapter instance + * + * Returns 0 on success. Returns -ENODEV if such capabilities don't exist, and + * -ENOMEM upon OOM. + */ +int ufshcd_hba_init_crypto(struct ufs_hba *hba) +{ + int cap_idx = 0; + int err = 0; + + /* Default to disabling crypto */ + hba->caps &= ~UFSHCD_CAP_CRYPTO; + + if (!(hba->capabilities & MASK_CRYPTO_SUPPORT)) { + err = -ENODEV; + goto out; + } + + /* + * Crypto Capabilities should never be 0, because the + * config_array_ptr > 04h. So we use a 0 value to indicate that + * crypto init failed, and can't be enabled. + */ + hba->crypto_capabilities.reg_val = + cpu_to_le32(ufshcd_readl(hba, REG_UFS_CCAP)); + hba->crypto_cfg_register = + (u32)hba->crypto_capabilities.config_array_ptr * 0x100; + hba->crypto_cap_array = + devm_kcalloc(hba->dev, + hba->crypto_capabilities.num_crypto_cap, + sizeof(hba->crypto_cap_array[0]), + GFP_KERNEL); + if (!hba->crypto_cap_array) { + err = -ENOMEM; + goto out; + } + + hba->crypto_cfgs = + devm_kcalloc(hba->dev, + NUM_KEYSLOTS(hba), + sizeof(hba->crypto_cfgs[0]), + GFP_KERNEL); + if (!hba->crypto_cfgs) { + err = -ENOMEM; + goto out_free_cfg_mem; + } + + /* + * Store all the capabilities now so that we don't need to repeatedly + * access the device each time we want to know its capabilities + */ + for (cap_idx = 0; cap_idx < hba->crypto_capabilities.num_crypto_cap; + cap_idx++) { + hba->crypto_cap_array[cap_idx].reg_val = + cpu_to_le32(ufshcd_readl(hba, + REG_UFS_CRYPTOCAP + + cap_idx * sizeof(__le32))); + } + + hba->ksm = keyslot_manager_create(NUM_KEYSLOTS(hba), &ufshcd_ksm_ops, + hba); + + if (!hba->ksm) { + err = -ENOMEM; + goto out_free_crypto_cfgs; + } + + return 0; +out_free_crypto_cfgs: + devm_kfree(hba->dev, hba->crypto_cfgs); +out_free_cfg_mem: + devm_kfree(hba->dev, hba->crypto_cap_array); +out: + // TODO: print error? + /* Indicate that init failed by setting crypto_capabilities to 0 */ + hba->crypto_capabilities.reg_val = 0; + return err; +} + +void ufshcd_crypto_setup_rq_keyslot_manager(struct ufs_hba *hba, + struct request_queue *q) +{ + if (!ufshcd_hba_is_crypto_supported(hba) || !q) + return; + + q->ksm = hba->ksm; +} + +void ufshcd_crypto_destroy_rq_keyslot_manager(struct ufs_hba *hba, + struct request_queue *q) +{ + keyslot_manager_destroy(hba->ksm); +} diff --git a/drivers/scsi/ufs/ufshcd-crypto.h b/drivers/scsi/ufs/ufshcd-crypto.h new file mode 100644 index 000000000000..73ddc8e493fb --- /dev/null +++ b/drivers/scsi/ufs/ufshcd-crypto.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2019 Google LLC + */ + +#ifndef _UFSHCD_CRYPTO_H +#define _UFSHCD_CRYPTO_H + +struct ufs_hba; + +#ifdef CONFIG_SCSI_UFS_CRYPTO +#include + +#include "ufshci.h" + +#define NUM_KEYSLOTS(hba) (hba->crypto_capabilities.config_count + 1) + +static inline bool ufshcd_keyslot_valid(struct ufs_hba *hba, unsigned int slot) +{ + /* + * The actual number of configurations supported is (CFGC+1), so slot + * numbers range from 0 to config_count inclusive. + */ + return slot < NUM_KEYSLOTS(hba); +} + +static inline bool ufshcd_hba_is_crypto_supported(struct ufs_hba *hba) +{ + return hba->crypto_capabilities.reg_val != 0; +} + +static inline bool ufshcd_is_crypto_enabled(struct ufs_hba *hba) +{ + return hba->caps & UFSHCD_CAP_CRYPTO; +} + +void ufshcd_crypto_enable(struct ufs_hba *hba); + +void ufshcd_crypto_disable(struct ufs_hba *hba); + +int ufshcd_hba_init_crypto(struct ufs_hba *hba); + +void ufshcd_crypto_setup_rq_keyslot_manager(struct ufs_hba *hba, + struct request_queue *q); + +void ufshcd_crypto_destroy_rq_keyslot_manager(struct ufs_hba *hba, + struct request_queue *q); + +#else /* CONFIG_SCSI_UFS_CRYPTO */ + +static inline bool ufshcd_keyslot_valid(struct ufs_hba *hba, + unsigned int slot) +{ + return false; +} + +static inline bool ufshcd_hba_is_crypto_supported(struct ufs_hba *hba) +{ + return false; +} + +static inline bool ufshcd_is_crypto_enabled(struct ufs_hba *hba) +{ + return false; +} + +static inline void ufshcd_crypto_enable(struct ufs_hba *hba) { } + +static inline void ufshcd_crypto_disable(struct ufs_hba *hba) { } + +static inline int ufshcd_hba_init_crypto(struct ufs_hba *hba) +{ + return 0; +} + +static inline void ufshcd_crypto_setup_rq_keyslot_manager( + struct ufs_hba *hba, + struct request_queue *q) { } + +static inline void ufshcd_crypto_destroy_rq_keyslot_manager( + struct ufs_hba *hba, + struct request_queue *q) { } + +#endif /* CONFIG_SCSI_UFS_CRYPTO */ + +#endif /* _UFSHCD_CRYPTO_H */ diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 8f2329b4fe79..31e64f4267dd 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -525,6 +525,11 @@ struct ufs_stats { * @is_urgent_bkops_lvl_checked: keeps track if the urgent bkops level for * device is known or not. * @scsi_block_reqs_cnt: reference counting for scsi block requests + * @crypto_capabilities: Content of crypto capabilities register (0x100) + * @crypto_cap_array: Array of crypto capabilities + * @crypto_cfg_register: Start of the crypto cfg array + * @crypto_cfgs: Array of crypto configurations (i.e. config for each slot) + * @ksm: the keyslot manager tied to this hba */ struct ufs_hba { void __iomem *mmio_base; @@ -735,6 +740,15 @@ struct ufs_hba { struct device bsg_dev; struct request_queue *bsg_queue; + +#ifdef CONFIG_SCSI_UFS_CRYPTO + /* crypto */ + union ufs_crypto_capabilities crypto_capabilities; + union ufs_crypto_cap_entry *crypto_cap_array; + u32 crypto_cfg_register; + union ufs_crypto_cfg_entry *crypto_cfgs; + struct keyslot_manager *ksm; +#endif /* CONFIG_SCSI_UFS_CRYPTO */ }; /* Returns true if clocks can be gated. Otherwise false */ -- GitLab From 53d5b29a5802ee80a1efec4803b77d17fe993b41 Mon Sep 17 00:00:00 2001 From: Satya Tangirala Date: Thu, 24 Oct 2019 14:44:28 -0700 Subject: [PATCH 935/993] FROMLIST: scsi: ufs: Add inline encryption support to UFS Wire up ufshcd.c with the UFS Crypto API, the block layer inline encryption additions and the keyslot manager. Bug: 137270441 Test: tested as series; see Ie1b77f7615d6a7a60fdc9105c7ab2200d17636a8 Change-Id: Idc703c9617497e368ce83af36587708968660b23 Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11214753/ --- drivers/scsi/ufs/ufshcd.c | 83 ++++++++++++++++++++++++++++++++++++--- drivers/scsi/ufs/ufshcd.h | 6 +++ 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index e66eb7a39a02..3a1190f0c672 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -47,6 +47,7 @@ #include "unipro.h" #include "ufs-sysfs.h" #include "ufs_bsg.h" +#include "ufshcd-crypto.h" #define CREATE_TRACE_POINTS #include @@ -857,7 +858,14 @@ static void ufshcd_enable_run_stop_reg(struct ufs_hba *hba) */ static inline void ufshcd_hba_start(struct ufs_hba *hba) { - ufshcd_writel(hba, CONTROLLER_ENABLE, REG_CONTROLLER_ENABLE); + u32 val = CONTROLLER_ENABLE; + + if (ufshcd_hba_is_crypto_supported(hba)) { + ufshcd_crypto_enable(hba); + val |= CRYPTO_GENERAL_ENABLE; + } + + ufshcd_writel(hba, val, REG_CONTROLLER_ENABLE); } /** @@ -2211,9 +2219,21 @@ static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp, dword_0 |= UTP_REQ_DESC_INT_CMD; /* Transfer request descriptor header fields */ + if (lrbp->crypto_enable) { + dword_0 |= UTP_REQ_DESC_CRYPTO_ENABLE_CMD; + dword_0 |= lrbp->crypto_key_slot; + req_desc->header.dword_1 = + cpu_to_le32((u32)lrbp->data_unit_num); + req_desc->header.dword_3 = + cpu_to_le32((u32)(lrbp->data_unit_num >> 32)); + } else { + /* dword_1 and dword_3 are reserved, hence they are set to 0 */ + req_desc->header.dword_1 = 0; + req_desc->header.dword_3 = 0; + } + req_desc->header.dword_0 = cpu_to_le32(dword_0); - /* dword_1 is reserved, hence it is set to 0 */ - req_desc->header.dword_1 = 0; + /* * assigning invalid value for command status. Controller * updates OCS on command completion, with the command @@ -2221,8 +2241,6 @@ static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp, */ req_desc->header.dword_2 = cpu_to_le32(OCS_INVALID_COMMAND_STATUS); - /* dword_3 is reserved, hence it is set to 0 */ - req_desc->header.dword_3 = 0; req_desc->prd_table_length = 0; } @@ -2382,6 +2400,37 @@ static inline u16 ufshcd_upiu_wlun_to_scsi_wlun(u8 upiu_wlun_id) return (upiu_wlun_id & ~UFS_UPIU_WLUN_ID) | SCSI_W_LUN_BASE; } +static inline int ufshcd_prepare_lrbp_crypto(struct ufs_hba *hba, + struct scsi_cmnd *cmd, + struct ufshcd_lrb *lrbp) +{ + int key_slot; + + if (!cmd->request->bio || + !bio_crypt_should_process(cmd->request->bio, cmd->request->q)) { + lrbp->crypto_enable = false; + return 0; + } + + if (WARN_ON(!ufshcd_is_crypto_enabled(hba))) { + /* + * Upper layer asked us to do inline encryption + * but that isn't enabled, so we fail this request. + */ + return -EINVAL; + } + key_slot = bio_crypt_get_keyslot(cmd->request->bio); + if (!ufshcd_keyslot_valid(hba, key_slot)) + return -EINVAL; + + lrbp->crypto_enable = true; + lrbp->crypto_key_slot = key_slot; + lrbp->data_unit_num = bio_crypt_data_unit_num(cmd->request->bio); + + return 0; +} + + /** * ufshcd_queuecommand - main entry point for SCSI requests * @host: SCSI host pointer @@ -2469,6 +2518,13 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp->task_tag = tag; lrbp->lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); lrbp->intr_cmd = !ufshcd_is_intr_aggr_allowed(hba) ? true : false; + + err = ufshcd_prepare_lrbp_crypto(hba, cmd, lrbp); + if (err) { + lrbp->cmd = NULL; + clear_bit_unlock(tag, &hba->lrb_in_use); + goto out; + } lrbp->req_abort_skip = false; ufshcd_comp_scsi_upiu(hba, lrbp); @@ -2502,6 +2558,7 @@ static int ufshcd_compose_dev_cmd(struct ufs_hba *hba, lrbp->task_tag = tag; lrbp->lun = 0; /* device management cmd is not specific to any LUN */ lrbp->intr_cmd = true; /* No interrupt aggregation */ + lrbp->crypto_enable = false; /* No crypto operations */ hba->dev_cmd.type = cmd_type; return ufshcd_comp_devman_upiu(hba, lrbp); @@ -4229,6 +4286,8 @@ static inline void ufshcd_hba_stop(struct ufs_hba *hba, bool can_sleep) { int err; + ufshcd_crypto_disable(hba); + ufshcd_writel(hba, CONTROLLER_DISABLE, REG_CONTROLLER_ENABLE); err = ufshcd_wait_for_register(hba, REG_CONTROLLER_ENABLE, CONTROLLER_ENABLE, CONTROLLER_DISABLE, @@ -4632,8 +4691,12 @@ static int ufshcd_change_queue_depth(struct scsi_device *sdev, int depth) static int ufshcd_slave_configure(struct scsi_device *sdev) { struct request_queue *q = sdev->request_queue; + struct ufs_hba *hba = shost_priv(sdev->host); blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1); + + ufshcd_crypto_setup_rq_keyslot_manager(hba, q); + return 0; } @@ -4644,6 +4707,7 @@ static int ufshcd_slave_configure(struct scsi_device *sdev) static void ufshcd_slave_destroy(struct scsi_device *sdev) { struct ufs_hba *hba; + struct request_queue *q = sdev->request_queue; hba = shost_priv(sdev->host); /* Drop the reference as it won't be needed anymore */ @@ -4654,6 +4718,8 @@ static void ufshcd_slave_destroy(struct scsi_device *sdev) hba->sdev_ufs_device = NULL; spin_unlock_irqrestore(hba->host->host_lock, flags); } + + ufshcd_crypto_destroy_rq_keyslot_manager(hba, q); } /** @@ -8380,6 +8446,13 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) /* Reset the attached device */ ufshcd_vops_device_reset(hba); + /* Init crypto */ + err = ufshcd_hba_init_crypto(hba); + if (err) { + dev_err(hba->dev, "crypto setup failed\n"); + goto out_remove_scsi_host; + } + /* Host controller enable */ err = ufshcd_hba_enable(hba); if (err) { diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 31e64f4267dd..a106b45f8358 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -167,6 +167,9 @@ struct ufs_pm_lvl_states { * @intr_cmd: Interrupt command (doesn't participate in interrupt aggregation) * @issue_time_stamp: time stamp for debug purposes * @compl_time_stamp: time stamp for statistics + * @crypto_enable: whether or not the request needs inline crypto operations + * @crypto_key_slot: the key slot to use for inline crypto + * @data_unit_num: the data unit number for the first block for inline crypto * @req_abort_skip: skip request abort task flag */ struct ufshcd_lrb { @@ -191,6 +194,9 @@ struct ufshcd_lrb { bool intr_cmd; ktime_t issue_time_stamp; ktime_t compl_time_stamp; + bool crypto_enable; + u8 crypto_key_slot; + u64 data_unit_num; bool req_abort_skip; }; -- GitLab From f5f6acfb1cd8afada18d556a40a200e7072b4d33 Mon Sep 17 00:00:00 2001 From: Satya Tangirala Date: Thu, 24 Oct 2019 14:44:29 -0700 Subject: [PATCH 936/993] FROMLIST: fscrypt: add inline encryption support Add support for inline encryption to fs/crypto/. With "inline encryption", the block layer handles the decryption/encryption as part of the bio, instead of the filesystem doing the crypto itself via Linux's crypto API. This model is needed in order to take advantage of the inline encryption hardware present on most modern mobile SoCs. To use inline encryption, the filesystem needs to be mounted with '-o inlinecrypt'. The contents of any AES-256-XTS encrypted files will then be encrypted using blk-crypto, instead of using the traditional filesystem-layer crypto. fscrypt still provides the key and IV to use, and the actual ciphertext on-disk is still the same; therefore it's testable using the existing fscrypt ciphertext verification tests. Note that since blk-crypto has a fallack to Linux's crypto API, this feature is usable and testable even without actual inline encryption hardware. Per-filesystem changes will be needed to set encryption contexts when submitting bios and to implement the 'inlinecrypt' mount option. This patch just adds the common code. Bug: 137270441 Test: tested as series; see Ie1b77f7615d6a7a60fdc9105c7ab2200d17636a8 Change-Id: I72e7e29db017404cdf7b5125718b5ba9590d31b4 Co-developed-by: Eric Biggers Signed-off-by: Eric Biggers Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11214761/ --- fs/crypto/Kconfig | 6 + fs/crypto/Makefile | 1 + fs/crypto/bio.c | 31 ++- fs/crypto/fscrypt_private.h | 72 +++++++ fs/crypto/inline_crypt.c | 390 ++++++++++++++++++++++++++++++++++++ fs/crypto/keyring.c | 2 + fs/crypto/keysetup.c | 18 +- include/linux/fscrypt.h | 60 ++++++ 8 files changed, 566 insertions(+), 14 deletions(-) create mode 100644 fs/crypto/inline_crypt.c diff --git a/fs/crypto/Kconfig b/fs/crypto/Kconfig index ff5a1746cbae..5061aa546202 100644 --- a/fs/crypto/Kconfig +++ b/fs/crypto/Kconfig @@ -16,3 +16,9 @@ config FS_ENCRYPTION efficient since it avoids caching the encrypted and decrypted pages in the page cache. Currently Ext4, F2FS and UBIFS make use of this feature. + +config FS_ENCRYPTION_INLINE_CRYPT + bool "Enable fscrypt to use inline crypto" + depends on FS_ENCRYPTION && BLK_INLINE_ENCRYPTION + help + Enable fscrypt to use inline encryption hardware if available. diff --git a/fs/crypto/Makefile b/fs/crypto/Makefile index 232e2bb5a337..652c7180ec6d 100644 --- a/fs/crypto/Makefile +++ b/fs/crypto/Makefile @@ -11,3 +11,4 @@ fscrypto-y := crypto.o \ policy.o fscrypto-$(CONFIG_BLOCK) += bio.o +fscrypto-$(CONFIG_FS_ENCRYPTION_INLINE_CRYPT) += inline_crypt.o diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c index 1f4b8a277060..956798debf71 100644 --- a/fs/crypto/bio.c +++ b/fs/crypto/bio.c @@ -46,26 +46,38 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, { const unsigned int blockbits = inode->i_blkbits; const unsigned int blocksize = 1 << blockbits; + const bool inlinecrypt = fscrypt_inode_uses_inline_crypto(inode); struct page *ciphertext_page; struct bio *bio; int ret, err = 0; - ciphertext_page = fscrypt_alloc_bounce_page(GFP_NOWAIT); - if (!ciphertext_page) - return -ENOMEM; + if (inlinecrypt) { + ciphertext_page = ZERO_PAGE(0); + } else { + ciphertext_page = fscrypt_alloc_bounce_page(GFP_NOWAIT); + if (!ciphertext_page) + return -ENOMEM; + } while (len--) { - err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk, - ZERO_PAGE(0), ciphertext_page, - blocksize, 0, GFP_NOFS); - if (err) - goto errout; + if (!inlinecrypt) { + err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk, + ZERO_PAGE(0), ciphertext_page, + blocksize, 0, GFP_NOFS); + if (err) + goto errout; + } bio = bio_alloc(GFP_NOWAIT, 1); if (!bio) { err = -ENOMEM; goto errout; } + err = fscrypt_set_bio_crypt_ctx(bio, inode, lblk, GFP_NOIO); + if (err) { + bio_put(bio); + goto errout; + } bio_set_dev(bio, inode->i_sb->s_bdev); bio->bi_iter.bi_sector = pblk << (blockbits - 9); bio_set_op_attrs(bio, REQ_OP_WRITE, 0); @@ -87,7 +99,8 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, } err = 0; errout: - fscrypt_free_bounce_page(ciphertext_page); + if (!inlinecrypt) + fscrypt_free_bounce_page(ciphertext_page); return err; } EXPORT_SYMBOL(fscrypt_zeroout_range); diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index b44e445b43a8..c731bd4245c5 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -13,6 +13,9 @@ #include #include +#include + +struct fscrypt_master_key; #define CONST_STRLEN(str) (sizeof(str) - 1) @@ -163,6 +166,14 @@ struct fscrypt_info { /* The actual crypto transform used for encryption and decryption */ struct crypto_skcipher *ci_ctfm; +#ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT + /* + * The raw key for inline encryption, if this file is using inline + * encryption rather than the traditional filesystem layer encryption. + */ + const u8 *ci_inline_crypt_key; +#endif + /* True if the key should be freed when this fscrypt_info is freed */ bool ci_owns_key; @@ -293,6 +304,54 @@ extern int fscrypt_hkdf_expand(struct fscrypt_hkdf *hkdf, u8 context, extern void fscrypt_destroy_hkdf(struct fscrypt_hkdf *hkdf); +/* inline_crypt.c */ +#ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT +extern bool fscrypt_should_use_inline_encryption(const struct fscrypt_info *ci); + +extern int fscrypt_set_inline_crypt_key(struct fscrypt_info *ci, + const u8 *derived_key); + +extern void fscrypt_free_inline_crypt_key(struct fscrypt_info *ci); + +extern int fscrypt_setup_per_mode_inline_crypt_key( + struct fscrypt_info *ci, + struct fscrypt_master_key *mk); + +extern void fscrypt_evict_inline_crypt_keys(struct fscrypt_master_key *mk); + +#else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ + +static inline bool fscrypt_should_use_inline_encryption( + const struct fscrypt_info *ci) +{ + return false; +} + +static inline int fscrypt_set_inline_crypt_key(struct fscrypt_info *ci, + const u8 *derived_key) +{ + WARN_ON(1); + return -EOPNOTSUPP; +} + +static inline void fscrypt_free_inline_crypt_key(struct fscrypt_info *ci) +{ +} + +static inline int fscrypt_setup_per_mode_inline_crypt_key( + struct fscrypt_info *ci, + struct fscrypt_master_key *mk) +{ + WARN_ON(1); + return -EOPNOTSUPP; +} + +static inline void fscrypt_evict_inline_crypt_keys( + struct fscrypt_master_key *mk) +{ +} +#endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ + /* keyring.c */ /* @@ -391,6 +450,16 @@ struct fscrypt_master_key { */ struct crypto_skcipher *mk_iv_ino_lblk_64_tfms[__FSCRYPT_MODE_MAX + 1]; +#ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT + /* Raw keys for IV_INO_LBLK_64 policies, allocated on-demand */ + u8 *mk_iv_ino_lblk_64_raw_keys[__FSCRYPT_MODE_MAX + 1]; + + /* The data unit size being used for inline encryption */ + unsigned int mk_data_unit_size; + + /* The filesystem's block device */ + struct block_device *mk_bdev; +#endif } __randomize_layout; static inline bool @@ -445,9 +514,12 @@ struct fscrypt_mode { const char *cipher_str; int keysize; int ivsize; + enum blk_crypto_mode_num blk_crypto_mode; bool logged_impl_name; }; +extern struct fscrypt_mode fscrypt_modes[]; + static inline bool fscrypt_mode_supports_direct_key(const struct fscrypt_mode *mode) { diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c new file mode 100644 index 000000000000..e41c6d66ff0d --- /dev/null +++ b/fs/crypto/inline_crypt.c @@ -0,0 +1,390 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Inline encryption support for fscrypt + * + * Copyright 2019 Google LLC + */ + +/* + * With "inline encryption", the block layer handles the decryption/encryption + * as part of the bio, instead of the filesystem doing the crypto itself via + * crypto API. See Documentation/block/inline-encryption.rst. fscrypt still + * provides the key and IV to use. + */ + +#include +#include +#include +#include + +#include "fscrypt_private.h" + +/* Return true iff inline encryption should be used for this file */ +bool fscrypt_should_use_inline_encryption(const struct fscrypt_info *ci) +{ + const struct inode *inode = ci->ci_inode; + struct super_block *sb = inode->i_sb; + + /* The file must need contents encryption, not filenames encryption */ + if (!S_ISREG(inode->i_mode)) + return false; + + /* blk-crypto must implement the needed encryption algorithm */ + if (ci->ci_mode->blk_crypto_mode == BLK_ENCRYPTION_MODE_INVALID) + return false; + + /* DIRECT_KEY needs a 24+ byte IV, so it can't work with 8-byte DUNs */ + if (fscrypt_is_direct_key_policy(&ci->ci_policy)) + return false; + + /* The filesystem must be mounted with -o inlinecrypt */ + if (!sb->s_cop->inline_crypt_enabled || + !sb->s_cop->inline_crypt_enabled(sb)) + return false; + + return true; +} + +/* Set a per-file inline encryption key (for passing to blk-crypto) */ +int fscrypt_set_inline_crypt_key(struct fscrypt_info *ci, const u8 *derived_key) +{ + const struct fscrypt_mode *mode = ci->ci_mode; + const struct super_block *sb = ci->ci_inode->i_sb; + + ci->ci_inline_crypt_key = kmemdup(derived_key, mode->keysize, GFP_NOFS); + if (!ci->ci_inline_crypt_key) + return -ENOMEM; + ci->ci_owns_key = true; + + return blk_crypto_start_using_mode(mode->blk_crypto_mode, + sb->s_blocksize, + sb->s_bdev->bd_queue); +} + +/* Free a per-file inline encryption key and evict it from blk-crypto */ +void fscrypt_free_inline_crypt_key(struct fscrypt_info *ci) +{ + if (ci->ci_inline_crypt_key != NULL) { + const struct fscrypt_mode *mode = ci->ci_mode; + const struct super_block *sb = ci->ci_inode->i_sb; + + blk_crypto_evict_key(sb->s_bdev->bd_queue, + ci->ci_inline_crypt_key, + mode->blk_crypto_mode, sb->s_blocksize); + kzfree(ci->ci_inline_crypt_key); + } +} + +/* + * Set up ->inline_crypt_key (for passing to blk-crypto) for inodes which use an + * IV_INO_LBLK_64 encryption policy. + * + * Return: 0 on success, -errno on failure + */ +int fscrypt_setup_per_mode_inline_crypt_key(struct fscrypt_info *ci, + struct fscrypt_master_key *mk) +{ + static DEFINE_MUTEX(inline_crypt_setup_mutex); + const struct super_block *sb = ci->ci_inode->i_sb; + struct block_device *bdev = sb->s_bdev; + const struct fscrypt_mode *mode = ci->ci_mode; + const u8 mode_num = mode - fscrypt_modes; + u8 *raw_key; + u8 hkdf_info[sizeof(mode_num) + sizeof(sb->s_uuid)]; + int err; + + if (WARN_ON(mode_num > __FSCRYPT_MODE_MAX)) + return -EINVAL; + + /* pairs with smp_store_release() below */ + raw_key = smp_load_acquire(&mk->mk_iv_ino_lblk_64_raw_keys[mode_num]); + if (raw_key) { + err = 0; + goto out; + } + + mutex_lock(&inline_crypt_setup_mutex); + + raw_key = mk->mk_iv_ino_lblk_64_raw_keys[mode_num]; + if (raw_key) { + err = 0; + goto out_unlock; + } + + raw_key = kmalloc(mode->keysize, GFP_NOFS); + if (!raw_key) { + err = -ENOMEM; + goto out_unlock; + } + + BUILD_BUG_ON(sizeof(mode_num) != 1); + BUILD_BUG_ON(sizeof(sb->s_uuid) != 16); + BUILD_BUG_ON(sizeof(hkdf_info) != 17); + hkdf_info[0] = mode_num; + memcpy(&hkdf_info[1], &sb->s_uuid, sizeof(sb->s_uuid)); + + err = fscrypt_hkdf_expand(&mk->mk_secret.hkdf, + HKDF_CONTEXT_IV_INO_LBLK_64_KEY, + hkdf_info, sizeof(hkdf_info), + raw_key, mode->keysize); + if (err) + goto out_unlock; + + err = blk_crypto_start_using_mode(mode->blk_crypto_mode, + sb->s_blocksize, bdev->bd_queue); + if (err) + goto out_unlock; + + /* + * When a master key's first inline encryption key is set up, save a + * reference to the filesystem's block device so that the inline + * encryption keys can be evicted when the master key is destroyed. + */ + if (!mk->mk_bdev) { + mk->mk_bdev = bdgrab(bdev); + mk->mk_data_unit_size = sb->s_blocksize; + } + + /* pairs with smp_load_acquire() above */ + smp_store_release(&mk->mk_iv_ino_lblk_64_raw_keys[mode_num], raw_key); + err = 0; +out_unlock: + mutex_unlock(&inline_crypt_setup_mutex); +out: + if (err == 0) { + ci->ci_inline_crypt_key = raw_key; + /* + * Since each struct fscrypt_master_key belongs to a particular + * filesystem (a struct super_block), there should be only one + * block device, and only one data unit size as it should equal + * the filesystem's blocksize (i.e. s_blocksize). + */ + if (WARN_ON(mk->mk_bdev != bdev)) + err = -EINVAL; + if (WARN_ON(mk->mk_data_unit_size != sb->s_blocksize)) + err = -EINVAL; + } else { + kzfree(raw_key); + } + return err; +} + +/* + * Evict per-mode inline encryption keys from blk-crypto when a master key is + * destroyed. + */ +void fscrypt_evict_inline_crypt_keys(struct fscrypt_master_key *mk) +{ + struct block_device *bdev = mk->mk_bdev; + size_t i; + + if (!bdev) /* No inline encryption keys? */ + return; + + for (i = 0; i < ARRAY_SIZE(mk->mk_iv_ino_lblk_64_raw_keys); i++) { + u8 *raw_key = mk->mk_iv_ino_lblk_64_raw_keys[i]; + + if (raw_key != NULL) { + blk_crypto_evict_key(bdev->bd_queue, raw_key, + fscrypt_modes[i].blk_crypto_mode, + mk->mk_data_unit_size); + kzfree(raw_key); + } + } + bdput(bdev); +} + +/** + * fscrypt_inode_uses_inline_crypto - test whether an inode uses inline encryption + * @inode: an inode + * + * Return: true if the inode requires file contents encryption and if the + * encryption should be done in the block layer via blk-crypto rather + * than in the filesystem layer. + */ +bool fscrypt_inode_uses_inline_crypto(const struct inode *inode) +{ + return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode) && + inode->i_crypt_info->ci_inline_crypt_key != NULL; +} +EXPORT_SYMBOL_GPL(fscrypt_inode_uses_inline_crypto); + +/** + * fscrypt_inode_uses_fs_layer_crypto - test whether an inode uses fs-layer encryption + * @inode: an inode + * + * Return: true if the inode requires file contents encryption and if the + * encryption should be done in the filesystem layer rather than in the + * block layer via blk-crypto. + */ +bool fscrypt_inode_uses_fs_layer_crypto(const struct inode *inode) +{ + return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode) && + inode->i_crypt_info->ci_inline_crypt_key == NULL; +} +EXPORT_SYMBOL_GPL(fscrypt_inode_uses_fs_layer_crypto); + +static inline u64 fscrypt_generate_dun(const struct fscrypt_info *ci, + u64 lblk_num) +{ + union fscrypt_iv iv; + + fscrypt_generate_iv(&iv, lblk_num, ci); + /* + * fscrypt_should_use_inline_encryption() ensures we never get here if + * more than the first 8 bytes of the IV are nonzero. + */ + BUG_ON(memchr_inv(&iv.raw[8], 0, ci->ci_mode->ivsize - 8)); + return le64_to_cpu(iv.lblk_num); +} + +/** + * fscrypt_set_bio_crypt_ctx - prepare a file contents bio for inline encryption + * @bio: a bio which will eventually be submitted to the file + * @inode: the file's inode + * @first_lblk: the first file logical block number in the I/O + * @gfp_mask: memory allocation flags + * + * If the contents of the file should be encrypted (or decrypted) with inline + * encryption, then assign the appropriate encryption context to the bio. + * + * Normally the bio should be newly allocated (i.e. no pages added yet), as + * otherwise fscrypt_mergeable_bio() won't work as intended. + * + * The encryption context will be freed automatically when the bio is freed. + * + * Return: 0 on success, -errno on failure. If __GFP_NOFAIL is specified, this + * is guaranteed to succeed. + */ +int fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, + u64 first_lblk, gfp_t gfp_mask) +{ + const struct fscrypt_info *ci = inode->i_crypt_info; + u64 dun; + + if (!fscrypt_inode_uses_inline_crypto(inode)) + return 0; + + dun = fscrypt_generate_dun(ci, first_lblk); + + return bio_crypt_set_ctx(bio, ci->ci_inline_crypt_key, + ci->ci_mode->blk_crypto_mode, + dun, inode->i_blkbits, gfp_mask); +} +EXPORT_SYMBOL_GPL(fscrypt_set_bio_crypt_ctx); + +/* Extract the inode and logical block number from a buffer_head. */ +static bool bh_get_inode_and_lblk_num(const struct buffer_head *bh, + const struct inode **inode_ret, + u64 *lblk_num_ret) +{ + struct page *page = bh->b_page; + const struct address_space *mapping; + const struct inode *inode; + + /* + * The ext4 journal (jbd2) can submit a buffer_head it directly created + * for a non-pagecache page. fscrypt doesn't care about these. + */ + mapping = page_mapping(page); + if (!mapping) + return false; + inode = mapping->host; + + *inode_ret = inode; + *lblk_num_ret = ((u64)page->index << (PAGE_SHIFT - inode->i_blkbits)) + + (bh_offset(bh) >> inode->i_blkbits); + return true; +} + +/** + * fscrypt_set_bio_crypt_ctx_bh - prepare a file contents bio for inline encryption + * @bio: a bio which will eventually be submitted to the file + * @first_bh: the first buffer_head for which I/O will be submitted + * @gfp_mask: memory allocation flags + * + * Same as fscrypt_set_bio_crypt_ctx(), except this takes a buffer_head instead + * of an inode and block number directly. + * + * Return: 0 on success, -errno on failure + */ +int fscrypt_set_bio_crypt_ctx_bh(struct bio *bio, + const struct buffer_head *first_bh, + gfp_t gfp_mask) +{ + const struct inode *inode; + u64 first_lblk; + + if (!bh_get_inode_and_lblk_num(first_bh, &inode, &first_lblk)) + return 0; + + return fscrypt_set_bio_crypt_ctx(bio, inode, first_lblk, gfp_mask); +} +EXPORT_SYMBOL_GPL(fscrypt_set_bio_crypt_ctx_bh); + +/** + * fscrypt_mergeable_bio - test whether data can be added to a bio + * @bio: the bio being built up + * @inode: the inode for the next part of the I/O + * @next_lblk: the next file logical block number in the I/O + * + * When building a bio which may contain data which should undergo inline + * encryption (or decryption) via fscrypt, filesystems should call this function + * to ensure that the resulting bio contains only logically contiguous data. + * This will return false if the next part of the I/O cannot be merged with the + * bio because either the encryption key would be different or the encryption + * data unit numbers would be discontiguous. + * + * fscrypt_set_bio_crypt_ctx() must have already been called on the bio. + * + * Return: true iff the I/O is mergeable + */ +bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, + u64 next_lblk) +{ + const struct bio_crypt_ctx *bc; + const u8 *next_key; + u64 next_dun; + + if (bio_has_crypt_ctx(bio) != fscrypt_inode_uses_inline_crypto(inode)) + return false; + if (!bio_has_crypt_ctx(bio)) + return true; + bc = bio->bi_crypt_context; + next_key = inode->i_crypt_info->ci_inline_crypt_key; + next_dun = fscrypt_generate_dun(inode->i_crypt_info, next_lblk); + + /* + * Comparing the key pointers is good enough, as all I/O for each key + * uses the same pointer. I.e., there's currently no need to support + * merging requests where the keys are the same but the pointers differ. + */ + return next_key == bc->raw_key && + next_dun == bc->data_unit_num + + (bio_sectors(bio) >> + (bc->data_unit_size_bits - SECTOR_SHIFT)); +} +EXPORT_SYMBOL_GPL(fscrypt_mergeable_bio); + +/** + * fscrypt_mergeable_bio_bh - test whether data can be added to a bio + * @bio: the bio being built up + * @next_bh: the next buffer_head for which I/O will be submitted + * + * Same as fscrypt_mergeable_bio(), except this takes a buffer_head instead of + * an inode and block number directly. + * + * Return: true iff the I/O is mergeable + */ +bool fscrypt_mergeable_bio_bh(struct bio *bio, + const struct buffer_head *next_bh) +{ + const struct inode *inode; + u64 next_lblk; + + if (!bh_get_inode_and_lblk_num(next_bh, &inode, &next_lblk)) + return !bio_has_crypt_ctx(bio); + + return fscrypt_mergeable_bio(bio, inode, next_lblk); +} +EXPORT_SYMBOL_GPL(fscrypt_mergeable_bio_bh); diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c index f9cf62590e98..05cc274e5c13 100644 --- a/fs/crypto/keyring.c +++ b/fs/crypto/keyring.c @@ -48,6 +48,8 @@ static void free_master_key(struct fscrypt_master_key *mk) crypto_free_skcipher(mk->mk_iv_ino_lblk_64_tfms[i]); } + fscrypt_evict_inline_crypt_keys(mk); + key_put(mk->mk_users); kzfree(mk); } diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index f87ab930b92a..8070dad9a541 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -13,12 +13,13 @@ #include "fscrypt_private.h" -static struct fscrypt_mode available_modes[] = { +struct fscrypt_mode fscrypt_modes[] = { [FSCRYPT_MODE_AES_256_XTS] = { .friendly_name = "AES-256-XTS", .cipher_str = "xts(aes)", .keysize = 64, .ivsize = 16, + .blk_crypto_mode = BLK_ENCRYPTION_MODE_AES_256_XTS, }, [FSCRYPT_MODE_AES_256_CTS] = { .friendly_name = "AES-256-CTS-CBC", @@ -51,10 +52,10 @@ select_encryption_mode(const union fscrypt_policy *policy, const struct inode *inode) { if (S_ISREG(inode->i_mode)) - return &available_modes[fscrypt_policy_contents_mode(policy)]; + return &fscrypt_modes[fscrypt_policy_contents_mode(policy)]; if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) - return &available_modes[fscrypt_policy_fnames_mode(policy)]; + return &fscrypt_modes[fscrypt_policy_fnames_mode(policy)]; WARN_ONCE(1, "fscrypt: filesystem tried to load encryption info for inode %lu, which is not encryptable (file type %d)\n", inode->i_ino, (inode->i_mode & S_IFMT)); @@ -111,6 +112,9 @@ int fscrypt_set_derived_key(struct fscrypt_info *ci, const u8 *derived_key) { struct crypto_skcipher *tfm; + if (fscrypt_should_use_inline_encryption(ci)) + return fscrypt_set_inline_crypt_key(ci, derived_key); + tfm = fscrypt_allocate_skcipher(ci->ci_mode, derived_key, ci->ci_inode); if (IS_ERR(tfm)) return PTR_ERR(tfm); @@ -128,7 +132,7 @@ static int setup_per_mode_key(struct fscrypt_info *ci, const struct inode *inode = ci->ci_inode; const struct super_block *sb = inode->i_sb; struct fscrypt_mode *mode = ci->ci_mode; - u8 mode_num = mode - available_modes; + const u8 mode_num = mode - fscrypt_modes; struct crypto_skcipher *tfm, *prev_tfm; u8 mode_key[FSCRYPT_MAX_KEY_SIZE]; u8 hkdf_info[sizeof(mode_num) + sizeof(sb->s_uuid)]; @@ -204,6 +208,8 @@ static int fscrypt_setup_v2_file_key(struct fscrypt_info *ci, * the IVs. This format is optimized for use with inline * encryption hardware compliant with the UFS or eMMC standards. */ + if (fscrypt_should_use_inline_encryption(ci)) + return fscrypt_setup_per_mode_inline_crypt_key(ci, mk); return setup_per_mode_key(ci, mk, mk->mk_iv_ino_lblk_64_tfms, HKDF_CONTEXT_IV_INO_LBLK_64_KEY, true); @@ -330,8 +336,10 @@ static void put_crypt_info(struct fscrypt_info *ci) if (ci->ci_direct_key) fscrypt_put_direct_key(ci->ci_direct_key); - else if (ci->ci_owns_key) + else if (ci->ci_owns_key) { crypto_free_skcipher(ci->ci_ctfm); + fscrypt_free_inline_crypt_key(ci); + } key = ci->ci_master_key; if (key) { diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index f5037d8e2412..607076207f73 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -64,6 +64,7 @@ struct fscrypt_operations { bool (*has_stable_inodes)(struct super_block *sb); void (*get_ino_and_lblk_bits)(struct super_block *sb, int *ino_bits_ret, int *lblk_bits_ret); + bool (*inline_crypt_enabled)(struct super_block *sb); }; static inline bool fscrypt_has_encryption_key(const struct inode *inode) @@ -543,6 +544,65 @@ static inline void fscrypt_set_ops(struct super_block *sb, #endif /* !CONFIG_FS_ENCRYPTION */ +/* inline_crypt.c */ +#ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT +extern bool fscrypt_inode_uses_inline_crypto(const struct inode *inode); + +extern bool fscrypt_inode_uses_fs_layer_crypto(const struct inode *inode); + +extern int fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, + u64 first_lblk, gfp_t gfp_mask); + +extern int fscrypt_set_bio_crypt_ctx_bh(struct bio *bio, + const struct buffer_head *first_bh, + gfp_t gfp_mask); + +extern bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, + u64 next_lblk); + +extern bool fscrypt_mergeable_bio_bh(struct bio *bio, + const struct buffer_head *next_bh); + +#else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ +static inline bool fscrypt_inode_uses_inline_crypto(const struct inode *inode) +{ + return false; +} + +static inline bool fscrypt_inode_uses_fs_layer_crypto(const struct inode *inode) +{ + return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode); +} + +static inline int fscrypt_set_bio_crypt_ctx(struct bio *bio, + const struct inode *inode, + u64 first_lblk, gfp_t gfp_mask) +{ + return 0; +} + +static inline int fscrypt_set_bio_crypt_ctx_bh( + struct bio *bio, + const struct buffer_head *first_bh, + gfp_t gfp_mask) +{ + return 0; +} + +static inline bool fscrypt_mergeable_bio(struct bio *bio, + const struct inode *inode, + u64 next_lblk) +{ + return true; +} + +static inline bool fscrypt_mergeable_bio_bh(struct bio *bio, + const struct buffer_head *next_bh) +{ + return true; +} +#endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ + /** * fscrypt_require_key - require an inode's encryption key * @inode: the inode we need the key for -- GitLab From fb710731b64bbe32f6e9abd16c462711da11663c Mon Sep 17 00:00:00 2001 From: Satya Tangirala Date: Thu, 24 Oct 2019 14:44:30 -0700 Subject: [PATCH 937/993] FROMLIST: f2fs: add inline encryption support Wire up f2fs to support inline encryption via the helper functions which fs/crypto/ now provides. This includes: - Adding a mount option 'inlinecrypt' which enables inline encryption on encrypted files where it can be used. - Setting the bio_crypt_ctx on bios that will be submitted to an inline-encrypted file. - Not adding logically discontiguous data to bios that will be submitted to an inline-encrypted file. - Not doing filesystem-layer crypto on inline-encrypted files. Bug: 137270441 Test: tested as series; see Ie1b77f7615d6a7a60fdc9105c7ab2200d17636a8 Change-Id: I2ea4da9e251e668b908408ecc091f09ebf8be8f4 Co-developed-by: Eric Biggers Signed-off-by: Eric Biggers Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11214785/ --- fs/f2fs/data.c | 76 +++++++++++++++++++++++++++++++++++++++++++------ fs/f2fs/f2fs.h | 3 ++ fs/f2fs/super.c | 20 +++++++++++++ 3 files changed, 91 insertions(+), 8 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 9155256779bf..f981bb4a18b8 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -307,6 +307,35 @@ static struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages) return bio; } +static int f2fs_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, + pgoff_t first_idx, + const struct f2fs_io_info *fio, + gfp_t gfp_mask) +{ + /* + * The f2fs garbage collector sets ->encrypted_page when it wants to + * read/write raw data without encryption. + */ + if (fio && fio->encrypted_page) + return 0; + + return fscrypt_set_bio_crypt_ctx(bio, inode, first_idx, gfp_mask); +} + +static bool f2fs_crypt_mergeable_bio(struct bio *bio, const struct inode *inode, + pgoff_t next_idx, + const struct f2fs_io_info *fio) +{ + /* + * The f2fs garbage collector sets ->encrypted_page when it wants to + * read/write raw data without encryption. + */ + if (fio && fio->encrypted_page) + return true; + + return fscrypt_mergeable_bio(bio, inode, next_idx); +} + static inline void __submit_bio(struct f2fs_sb_info *sbi, struct bio *bio, enum page_type type) { @@ -478,6 +507,7 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio) struct bio *bio; struct page *page = fio->encrypted_page ? fio->encrypted_page : fio->page; + int err; if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr, fio->is_por ? META_POR : (__is_meta_io(fio) ? @@ -490,6 +520,13 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio) /* Allocate a new bio */ bio = __bio_alloc(fio, 1); + err = f2fs_set_bio_crypt_ctx(bio, fio->page->mapping->host, + fio->page->index, fio, GFP_NOIO); + if (err) { + bio_put(bio); + return err; + } + if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { bio_put(bio); return -EFAULT; @@ -557,14 +594,19 @@ int f2fs_merge_page_bio(struct f2fs_io_info *fio) trace_f2fs_submit_page_bio(page, fio); f2fs_trace_ios(fio, 0); - if (bio && !page_is_mergeable(fio->sbi, bio, *fio->last_block, - fio->new_blkaddr)) { + if (bio && (!page_is_mergeable(fio->sbi, bio, *fio->last_block, + fio->new_blkaddr) || + !f2fs_crypt_mergeable_bio(bio, fio->page->mapping->host, + fio->page->index, fio))) { __submit_bio(fio->sbi, bio, fio->type); bio = NULL; } alloc_new: if (!bio) { bio = __bio_alloc(fio, BIO_MAX_PAGES); + f2fs_set_bio_crypt_ctx(bio, fio->page->mapping->host, + fio->page->index, fio, + GFP_NOIO | __GFP_NOFAIL); bio_set_op_attrs(bio, fio->op, fio->op_flags); } @@ -630,8 +672,11 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio) inc_page_count(sbi, WB_DATA_TYPE(bio_page)); - if (io->bio && !io_is_mergeable(sbi, io->bio, io, fio, - io->last_block_in_bio, fio->new_blkaddr)) + if (io->bio && + (!io_is_mergeable(sbi, io->bio, io, fio, io->last_block_in_bio, + fio->new_blkaddr) || + !f2fs_crypt_mergeable_bio(io->bio, fio->page->mapping->host, + fio->page->index, fio))) __submit_merged_bio(io); alloc_new: if (io->bio == NULL) { @@ -643,6 +688,9 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio) goto skip; } io->bio = __bio_alloc(fio, BIO_MAX_PAGES); + f2fs_set_bio_crypt_ctx(io->bio, fio->page->mapping->host, + fio->page->index, fio, + GFP_NOIO | __GFP_NOFAIL); io->fio = *fio; } @@ -682,15 +730,23 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr, struct bio *bio; struct bio_post_read_ctx *ctx; unsigned int post_read_steps = 0; + int err; bio = f2fs_bio_alloc(sbi, min_t(int, nr_pages, BIO_MAX_PAGES), false); if (!bio) return ERR_PTR(-ENOMEM); + + err = f2fs_set_bio_crypt_ctx(bio, inode, first_idx, NULL, GFP_NOFS); + if (err) { + bio_put(bio); + return ERR_PTR(err); + } + f2fs_target_device(sbi, blkaddr, bio); bio->bi_end_io = f2fs_read_end_io; bio_set_op_attrs(bio, REQ_OP_READ, op_flag); - if (f2fs_encrypted_file(inode)) + if (fscrypt_inode_uses_fs_layer_crypto(inode)) post_read_steps |= 1 << STEP_DECRYPT; if (f2fs_need_verity(inode, first_idx)) @@ -1727,8 +1783,9 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page, * This page will go to BIO. Do we need to send this * BIO off first? */ - if (bio && !page_is_mergeable(F2FS_I_SB(inode), bio, - *last_block_in_bio, block_nr)) { + if (bio && (!page_is_mergeable(F2FS_I_SB(inode), bio, + *last_block_in_bio, block_nr) || + !f2fs_crypt_mergeable_bio(bio, inode, page->index, NULL))) { submit_and_realloc: __submit_bio(F2FS_I_SB(inode), bio, DATA); bio = NULL; @@ -1868,6 +1925,9 @@ static int encrypt_one_page(struct f2fs_io_info *fio) /* wait for GCed page writeback via META_MAPPING */ f2fs_wait_on_block_writeback(inode, fio->old_blkaddr); + if (fscrypt_inode_uses_inline_crypto(inode)) + return 0; + retry_encrypt: fio->encrypted_page = fscrypt_encrypt_pagecache_blocks(fio->page, PAGE_SIZE, 0, @@ -2042,7 +2102,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) f2fs_unlock_op(fio->sbi); err = f2fs_inplace_write_data(fio); if (err) { - if (f2fs_encrypted_file(inode)) + if (fscrypt_inode_uses_fs_layer_crypto(inode)) fscrypt_finalize_bounce_page(&fio->encrypted_page); if (PageWriteback(page)) end_page_writeback(page); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 4024790028aa..e04fda00b4ef 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -137,6 +137,9 @@ struct f2fs_mount_info { int alloc_mode; /* segment allocation policy */ int fsync_mode; /* fsync policy */ bool test_dummy_encryption; /* test dummy encryption */ +#ifdef CONFIG_FS_ENCRYPTION + bool inlinecrypt; /* inline encryption enabled */ +#endif block_t unusable_cap; /* Amount of space allowed to be * unusable when disabling checkpoint */ diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 851ac9522926..850a2a2394d8 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -137,6 +137,7 @@ enum { Opt_alloc, Opt_fsync, Opt_test_dummy_encryption, + Opt_inlinecrypt, Opt_checkpoint_disable, Opt_checkpoint_disable_cap, Opt_checkpoint_disable_cap_perc, @@ -199,6 +200,7 @@ static match_table_t f2fs_tokens = { {Opt_alloc, "alloc_mode=%s"}, {Opt_fsync, "fsync_mode=%s"}, {Opt_test_dummy_encryption, "test_dummy_encryption"}, + {Opt_inlinecrypt, "inlinecrypt"}, {Opt_checkpoint_disable, "checkpoint=disable"}, {Opt_checkpoint_disable_cap, "checkpoint=disable:%u"}, {Opt_checkpoint_disable_cap_perc, "checkpoint=disable:%u%%"}, @@ -783,6 +785,13 @@ static int parse_options(struct super_block *sb, char *options) f2fs_info(sbi, "Test dummy encryption mode enabled"); #else f2fs_info(sbi, "Test dummy encryption mount option ignored"); +#endif + break; + case Opt_inlinecrypt: +#ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT + F2FS_OPTION(sbi).inlinecrypt = true; +#else + f2fs_info(sbi, "inline encryption not supported"); #endif break; case Opt_checkpoint_disable_cap_perc: @@ -1438,6 +1447,8 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) #ifdef CONFIG_FS_ENCRYPTION if (F2FS_OPTION(sbi).test_dummy_encryption) seq_puts(seq, ",test_dummy_encryption"); + if (F2FS_OPTION(sbi).inlinecrypt) + seq_puts(seq, ",inlinecrypt"); #endif if (F2FS_OPTION(sbi).alloc_mode == ALLOC_MODE_DEFAULT) @@ -1466,6 +1477,9 @@ static void default_options(struct f2fs_sb_info *sbi) F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_DEFAULT; F2FS_OPTION(sbi).fsync_mode = FSYNC_MODE_POSIX; F2FS_OPTION(sbi).test_dummy_encryption = false; +#ifdef CONFIG_FS_ENCRYPTION + F2FS_OPTION(sbi).inlinecrypt = false; +#endif F2FS_OPTION(sbi).s_resuid = make_kuid(&init_user_ns, F2FS_DEF_RESUID); F2FS_OPTION(sbi).s_resgid = make_kgid(&init_user_ns, F2FS_DEF_RESGID); @@ -2320,6 +2334,11 @@ static void f2fs_get_ino_and_lblk_bits(struct super_block *sb, *lblk_bits_ret = 8 * sizeof(block_t); } +static bool f2fs_inline_crypt_enabled(struct super_block *sb) +{ + return F2FS_OPTION(F2FS_SB(sb)).inlinecrypt; +} + static const struct fscrypt_operations f2fs_cryptops = { .key_prefix = "f2fs:", .get_context = f2fs_get_context, @@ -2329,6 +2348,7 @@ static const struct fscrypt_operations f2fs_cryptops = { .max_namelen = F2FS_NAME_LEN, .has_stable_inodes = f2fs_has_stable_inodes, .get_ino_and_lblk_bits = f2fs_get_ino_and_lblk_bits, + .inline_crypt_enabled = f2fs_inline_crypt_enabled, }; #endif -- GitLab From 9d8d0512b8286f5e164ddc00f1fe3d1d1ad2afe0 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 24 Oct 2019 14:44:31 -0700 Subject: [PATCH 938/993] FROMLIST: ext4: add inline encryption support Wire up ext4 to support inline encryption via the helper functions which fs/crypto/ now provides. This includes: - Adding a mount option 'inlinecrypt' which enables inline encryption on encrypted files where it can be used. - Setting the bio_crypt_ctx on bios that will be submitted to an inline-encrypted file. Note: submit_bh_wbc() in fs/buffer.c also needed to be patched for this part, since ext4 sometimes uses ll_rw_block() on file data. - Not adding logically discontiguous data to bios that will be submitted to an inline-encrypted file. - Not doing filesystem-layer crypto on inline-encrypted files. Bug: 137270441 Test: tested as series; see Ie1b77f7615d6a7a60fdc9105c7ab2200d17636a8 Change-Id: I73dac46ff1eba56a13975c387b20554416ddbad8 Signed-off-by: Eric Biggers Signed-off-by: Satya Tangirala Link: https://patchwork.kernel.org/patch/11214781/ --- fs/buffer.c | 3 +++ fs/ext4/ext4.h | 1 + fs/ext4/inode.c | 4 ++-- fs/ext4/page-io.c | 11 +++++++++-- fs/ext4/readpage.c | 15 ++++++++++++--- fs/ext4/super.c | 13 +++++++++++++ 6 files changed, 40 insertions(+), 7 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 86a38b979323..5d1f420de95b 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -47,6 +47,7 @@ #include #include #include +#include static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, @@ -3068,6 +3069,8 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, */ bio = bio_alloc(GFP_NOIO, 1); + fscrypt_set_bio_crypt_ctx_bh(bio, bh, GFP_NOIO | __GFP_NOFAIL); + bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); bio_set_dev(bio, bh->b_bdev); bio->bi_write_hint = write_hint; diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index b3a2cc7c0252..ce493e360814 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1148,6 +1148,7 @@ struct ext4_inode_info { #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ #define EXT4_MOUNT_WARN_ON_ERROR 0x2000000 /* Trigger WARN_ON on error */ +#define EXT4_MOUNT_INLINECRYPT 0x4000000 /* Inline encryption support */ #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ac409eb63100..a32c8755b6da 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1238,7 +1238,7 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len, } if (unlikely(err)) { page_zero_new_buffers(page, from, to); - } else if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode)) { + } else if (fscrypt_inode_uses_fs_layer_crypto(inode)) { for (i = 0; i < nr_wait; i++) { int err2; @@ -4089,7 +4089,7 @@ static int __ext4_block_zero_page_range(handle_t *handle, /* Uhhuh. Read error. Complain and punt. */ if (!buffer_uptodate(bh)) goto unlock; - if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode)) { + if (fscrypt_inode_uses_fs_layer_crypto(inode)) { /* We expect the key to be set. */ BUG_ON(!fscrypt_has_encryption_key(inode)); WARN_ON_ONCE(fscrypt_decrypt_pagecache_blocks( diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 12ceadef32c5..46a4aeef8275 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -362,10 +362,16 @@ static int io_submit_init_bio(struct ext4_io_submit *io, struct buffer_head *bh) { struct bio *bio; + int err; bio = bio_alloc(GFP_NOIO, BIO_MAX_PAGES); if (!bio) return -ENOMEM; + err = fscrypt_set_bio_crypt_ctx_bh(bio, bh, GFP_NOIO); + if (err) { + bio_put(bio); + return err; + } bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); bio_set_dev(bio, bh->b_bdev); bio->bi_end_io = ext4_end_bio; @@ -383,7 +389,8 @@ static int io_submit_add_bh(struct ext4_io_submit *io, { int ret; - if (io->io_bio && bh->b_blocknr != io->io_next_block) { + if (io->io_bio && (bh->b_blocknr != io->io_next_block || + !fscrypt_mergeable_bio_bh(io->io_bio, bh))) { submit_and_retry: ext4_io_submit(io); } @@ -474,7 +481,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, * (e.g. holes) to be unnecessarily encrypted, but this is rare and * can't happen in the common case of blocksize == PAGE_SIZE. */ - if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode) && nr_to_submit) { + if (fscrypt_inode_uses_fs_layer_crypto(inode) && nr_to_submit) { gfp_t gfp_flags = GFP_NOFS; unsigned int enc_bytes = round_up(len, i_blocksize(inode)); diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c index 0d88b82a5929..e21216e7ae24 100644 --- a/fs/ext4/readpage.c +++ b/fs/ext4/readpage.c @@ -198,7 +198,7 @@ static struct bio_post_read_ctx *get_bio_post_read_ctx(struct inode *inode, unsigned int post_read_steps = 0; struct bio_post_read_ctx *ctx = NULL; - if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode)) + if (fscrypt_inode_uses_fs_layer_crypto(inode)) post_read_steps |= 1 << STEP_DECRYPT; if (ext4_need_verity(inode, first_idx)) @@ -259,6 +259,7 @@ int ext4_mpage_readpages(struct address_space *mapping, const unsigned blkbits = inode->i_blkbits; const unsigned blocks_per_page = PAGE_SIZE >> blkbits; const unsigned blocksize = 1 << blkbits; + sector_t next_block; sector_t block_in_file; sector_t last_block; sector_t last_block_in_file; @@ -291,7 +292,8 @@ int ext4_mpage_readpages(struct address_space *mapping, if (page_has_buffers(page)) goto confused; - block_in_file = (sector_t)page->index << (PAGE_SHIFT - blkbits); + block_in_file = next_block = + (sector_t)page->index << (PAGE_SHIFT - blkbits); last_block = block_in_file + nr_pages * blocks_per_page; last_block_in_file = (ext4_readpage_limit(inode) + blocksize - 1) >> blkbits; @@ -391,7 +393,8 @@ int ext4_mpage_readpages(struct address_space *mapping, * This page will go to BIO. Do we need to send this * BIO off first? */ - if (bio && (last_block_in_bio != blocks[0] - 1)) { + if (bio && (last_block_in_bio != blocks[0] - 1 || + !fscrypt_mergeable_bio(bio, inode, next_block))) { submit_and_realloc: ext4_submit_bio_read(bio); bio = NULL; @@ -403,6 +406,12 @@ int ext4_mpage_readpages(struct address_space *mapping, min_t(int, nr_pages, BIO_MAX_PAGES)); if (!bio) goto set_error_page; + if (fscrypt_set_bio_crypt_ctx(bio, inode, next_block, + GFP_KERNEL) != 0) { + bio_put(bio); + bio = NULL; + goto set_error_page; + } ctx = get_bio_post_read_ctx(inode, bio, page->index); if (IS_ERR(ctx)) { bio_put(bio); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index b3cbf8622eab..3415bce51a36 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1357,6 +1357,11 @@ static void ext4_get_ino_and_lblk_bits(struct super_block *sb, *lblk_bits_ret = 8 * sizeof(ext4_lblk_t); } +static bool ext4_inline_crypt_enabled(struct super_block *sb) +{ + return test_opt(sb, INLINECRYPT); +} + static const struct fscrypt_operations ext4_cryptops = { .key_prefix = "ext4:", .get_context = ext4_get_context, @@ -1366,6 +1371,7 @@ static const struct fscrypt_operations ext4_cryptops = { .max_namelen = EXT4_NAME_LEN, .has_stable_inodes = ext4_has_stable_inodes, .get_ino_and_lblk_bits = ext4_get_ino_and_lblk_bits, + .inline_crypt_enabled = ext4_inline_crypt_enabled, }; #endif @@ -1461,6 +1467,7 @@ enum { Opt_journal_path, Opt_journal_checksum, Opt_journal_async_commit, Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, Opt_data_err_abort, Opt_data_err_ignore, Opt_test_dummy_encryption, + Opt_inlinecrypt, Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err, @@ -1557,6 +1564,7 @@ static const match_table_t tokens = { {Opt_noinit_itable, "noinit_itable"}, {Opt_max_dir_size_kb, "max_dir_size_kb=%u"}, {Opt_test_dummy_encryption, "test_dummy_encryption"}, + {Opt_inlinecrypt, "inlinecrypt"}, {Opt_nombcache, "nombcache"}, {Opt_nombcache, "no_mbcache"}, /* for backward compatibility */ {Opt_removed, "check=none"}, /* mount option from ext2/3 */ @@ -1768,6 +1776,11 @@ static const struct mount_opts { {Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT}, {Opt_max_dir_size_kb, 0, MOPT_GTE0}, {Opt_test_dummy_encryption, 0, MOPT_GTE0}, +#ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT + {Opt_inlinecrypt, EXT4_MOUNT_INLINECRYPT, MOPT_SET}, +#else + {Opt_inlinecrypt, EXT4_MOUNT_INLINECRYPT, MOPT_NOSUPPORT}, +#endif {Opt_nombcache, EXT4_MOUNT_NO_MBCACHE, MOPT_SET}, {Opt_err, 0, 0} }; -- GitLab From 3b6c31f9c08d9ea03f3a24e6a311cec8b2a76988 Mon Sep 17 00:00:00 2001 From: Satya Tangirala Date: Tue, 15 Oct 2019 23:59:55 -0700 Subject: [PATCH 939/993] ANDROID: gki_defconfig: enable inline encryption enable CONFIG_BLK_INLINE_ENCRYPTION and CONFIG_FS_ENCRYPTION_INLINE_CRYPT Bug: 137270441 Test: Test cuttlefish boots both with and without inlinecrypt mount option specified in fstab, while using both F2FS and EXT4 for userdata.img. Also tested by running gce-xfstests on both the auto and encrypt test groups on EXT4 and F2FS both with and without the inlinecrypt mount option. The UFS changes were tested on a Pixel 4 device. Change-Id: Ie1b77f7615d6a7a60fdc9105c7ab2200d17636a8 Signed-off-by: Satya Tangirala --- arch/arm64/configs/gki_defconfig | 3 +++ arch/x86/configs/gki_defconfig | 2 ++ 2 files changed, 5 insertions(+) diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index 0933c134a2d0..c83c3041f90b 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -76,6 +76,7 @@ CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y +CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_GKI_HACKS_TO_FIX=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_MEMORY_HOTPLUG=y @@ -214,6 +215,7 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SCSI_UFSHCD=y CONFIG_SCSI_UFSHCD_PLATFORM=y +CONFIG_SCSI_UFS_CRYPTO=y CONFIG_MD=y CONFIG_BLK_DEV_DM=y CONFIG_DM_CRYPT=y @@ -382,6 +384,7 @@ CONFIG_EXT4_FS_SECURITY=y CONFIG_F2FS_FS=y CONFIG_F2FS_FS_SECURITY=y CONFIG_FS_ENCRYPTION=y +CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_FS_VERITY=y CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y # CONFIG_DNOTIFY is not set diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index 0654f2381a0e..ac4097e334d4 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -54,6 +54,7 @@ CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y +CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_GKI_HACKS_TO_FIX=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_TRANSPARENT_HUGEPAGE=y @@ -317,6 +318,7 @@ CONFIG_EXT4_FS_SECURITY=y CONFIG_F2FS_FS=y CONFIG_F2FS_FS_SECURITY=y CONFIG_FS_ENCRYPTION=y +CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_FS_VERITY=y CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y # CONFIG_DNOTIFY is not set -- GitLab From ecdebfe423e725f1ef502021f7e9cbe9069b930d Mon Sep 17 00:00:00 2001 From: Satya Tangirala Date: Wed, 8 May 2019 03:44:29 -0700 Subject: [PATCH 940/993] ANDROID: scsi: ufs: UFS crypto variant operations API Introduce UFS crypto variant operations to handle quirks in individual UFS inline encryption hardware. We also expose a default implementation for crypto operations that conforms to the UFSHCI v2.1 specification, so that any user of crypto variant operations can fall back on the default implementation whenever there aren't any special quirks to handle. Bug: 137270441 Change-Id: I8bd9bced66b50cfdd0483bbc3e999b00c0f11386 Signed-off-by: Satya Tangirala --- drivers/scsi/ufs/ufshcd-crypto.c | 152 +++++++++++++++++++++++++++++-- drivers/scsi/ufs/ufshcd-crypto.h | 83 +++++++++++++++-- drivers/scsi/ufs/ufshcd.c | 48 ++++------ drivers/scsi/ufs/ufshcd.h | 23 +++++ 4 files changed, 256 insertions(+), 50 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd-crypto.c b/drivers/scsi/ufs/ufshcd-crypto.c index 3900a07a7e9b..988d8df8f394 100644 --- a/drivers/scsi/ufs/ufshcd-crypto.c +++ b/drivers/scsi/ufs/ufshcd-crypto.c @@ -34,8 +34,8 @@ static size_t get_keysize_bytes(enum ufs_crypto_key_size size) } static int ufshcd_crypto_cap_find(void *hba_p, - enum blk_crypto_mode_num crypto_mode, - unsigned int data_unit_size) + enum blk_crypto_mode_num crypto_mode, + unsigned int data_unit_size) { struct ufs_hba *hba = hba_p; enum ufs_crypto_alg ufs_alg; @@ -265,7 +265,8 @@ static bool ufshcd_crypto_mode_supported(void *hba_p, return ufshcd_crypto_cap_find(hba_p, crypto_mode, data_unit_size) >= 0; } -void ufshcd_crypto_enable(struct ufs_hba *hba) +/* Functions implementing UFSHCI v2.1 specification behaviour */ +void ufshcd_crypto_enable_spec(struct ufs_hba *hba) { union ufs_crypto_cfg_entry *cfg_arr = hba->crypto_cfgs; int slot; @@ -281,11 +282,13 @@ void ufshcd_crypto_enable(struct ufs_hba *hba) for (slot = 0; slot < NUM_KEYSLOTS(hba); slot++) program_key(hba, &cfg_arr[slot], slot); } +EXPORT_SYMBOL(ufshcd_crypto_enable_spec); -void ufshcd_crypto_disable(struct ufs_hba *hba) +void ufshcd_crypto_disable_spec(struct ufs_hba *hba) { hba->caps &= ~UFSHCD_CAP_CRYPTO; } +EXPORT_SYMBOL(ufshcd_crypto_disable_spec); static const struct keyslot_mgmt_ll_ops ufshcd_ksm_ops = { .keyslot_program = ufshcd_crypto_keyslot_program, @@ -301,7 +304,8 @@ static const struct keyslot_mgmt_ll_ops ufshcd_ksm_ops = { * Returns 0 on success. Returns -ENODEV if such capabilities don't exist, and * -ENOMEM upon OOM. */ -int ufshcd_hba_init_crypto(struct ufs_hba *hba) +int ufshcd_hba_init_crypto_spec(struct ufs_hba *hba, + const struct keyslot_mgmt_ll_ops *ksm_ops) { int cap_idx = 0; int err = 0; @@ -355,8 +359,7 @@ int ufshcd_hba_init_crypto(struct ufs_hba *hba) cap_idx * sizeof(__le32))); } - hba->ksm = keyslot_manager_create(NUM_KEYSLOTS(hba), &ufshcd_ksm_ops, - hba); + hba->ksm = keyslot_manager_create(NUM_KEYSLOTS(hba), ksm_ops, hba); if (!hba->ksm) { err = -ENOMEM; @@ -374,18 +377,147 @@ int ufshcd_hba_init_crypto(struct ufs_hba *hba) hba->crypto_capabilities.reg_val = 0; return err; } +EXPORT_SYMBOL(ufshcd_hba_init_crypto_spec); -void ufshcd_crypto_setup_rq_keyslot_manager(struct ufs_hba *hba, - struct request_queue *q) +void ufshcd_crypto_setup_rq_keyslot_manager_spec(struct ufs_hba *hba, + struct request_queue *q) { if (!ufshcd_hba_is_crypto_supported(hba) || !q) return; q->ksm = hba->ksm; } +EXPORT_SYMBOL(ufshcd_crypto_setup_rq_keyslot_manager_spec); + +void ufshcd_crypto_destroy_rq_keyslot_manager_spec(struct ufs_hba *hba, + struct request_queue *q) +{ + keyslot_manager_destroy(hba->ksm); +} +EXPORT_SYMBOL(ufshcd_crypto_destroy_rq_keyslot_manager_spec); + +int ufshcd_prepare_lrbp_crypto_spec(struct ufs_hba *hba, + struct scsi_cmnd *cmd, + struct ufshcd_lrb *lrbp) +{ + int key_slot; + + if (!cmd->request->bio || + !bio_crypt_should_process(cmd->request->bio, cmd->request->q)) { + lrbp->crypto_enable = false; + return 0; + } + + if (WARN_ON(!ufshcd_is_crypto_enabled(hba))) { + /* + * Upper layer asked us to do inline encryption + * but that isn't enabled, so we fail this request. + */ + return -EINVAL; + } + key_slot = bio_crypt_get_keyslot(cmd->request->bio); + if (!ufshcd_keyslot_valid(hba, key_slot)) + return -EINVAL; + + lrbp->crypto_enable = true; + lrbp->crypto_key_slot = key_slot; + lrbp->data_unit_num = bio_crypt_data_unit_num(cmd->request->bio); + + return 0; +} +EXPORT_SYMBOL(ufshcd_prepare_lrbp_crypto_spec); + +/* Crypto Variant Ops Support */ + +void ufshcd_crypto_enable(struct ufs_hba *hba) +{ + if (hba->crypto_vops && hba->crypto_vops->enable) + return hba->crypto_vops->enable(hba); + + return ufshcd_crypto_enable_spec(hba); +} + +void ufshcd_crypto_disable(struct ufs_hba *hba) +{ + if (hba->crypto_vops && hba->crypto_vops->disable) + return hba->crypto_vops->disable(hba); + + return ufshcd_crypto_disable_spec(hba); +} + +int ufshcd_hba_init_crypto(struct ufs_hba *hba) +{ + if (hba->crypto_vops && hba->crypto_vops->hba_init_crypto) + return hba->crypto_vops->hba_init_crypto(hba, + &ufshcd_ksm_ops); + + return ufshcd_hba_init_crypto_spec(hba, &ufshcd_ksm_ops); +} + +void ufshcd_crypto_setup_rq_keyslot_manager(struct ufs_hba *hba, + struct request_queue *q) +{ + if (hba->crypto_vops && hba->crypto_vops->setup_rq_keyslot_manager) + return hba->crypto_vops->setup_rq_keyslot_manager(hba, q); + + return ufshcd_crypto_setup_rq_keyslot_manager_spec(hba, q); +} void ufshcd_crypto_destroy_rq_keyslot_manager(struct ufs_hba *hba, struct request_queue *q) { - keyslot_manager_destroy(hba->ksm); + if (hba->crypto_vops && hba->crypto_vops->destroy_rq_keyslot_manager) + return hba->crypto_vops->destroy_rq_keyslot_manager(hba, q); + + return ufshcd_crypto_destroy_rq_keyslot_manager_spec(hba, q); +} + +int ufshcd_prepare_lrbp_crypto(struct ufs_hba *hba, + struct scsi_cmnd *cmd, + struct ufshcd_lrb *lrbp) +{ + if (hba->crypto_vops && hba->crypto_vops->prepare_lrbp_crypto) + return hba->crypto_vops->prepare_lrbp_crypto(hba, cmd, lrbp); + + return ufshcd_prepare_lrbp_crypto_spec(hba, cmd, lrbp); +} + +int ufshcd_complete_lrbp_crypto(struct ufs_hba *hba, + struct scsi_cmnd *cmd, + struct ufshcd_lrb *lrbp) +{ + if (hba->crypto_vops && hba->crypto_vops->complete_lrbp_crypto) + return hba->crypto_vops->complete_lrbp_crypto(hba, cmd, lrbp); + + return 0; +} + +void ufshcd_crypto_debug(struct ufs_hba *hba) +{ + if (hba->crypto_vops && hba->crypto_vops->debug) + hba->crypto_vops->debug(hba); +} + +int ufshcd_crypto_suspend(struct ufs_hba *hba, + enum ufs_pm_op pm_op) +{ + if (hba->crypto_vops && hba->crypto_vops->suspend) + return hba->crypto_vops->suspend(hba, pm_op); + + return 0; +} + +int ufshcd_crypto_resume(struct ufs_hba *hba, + enum ufs_pm_op pm_op) +{ + if (hba->crypto_vops && hba->crypto_vops->resume) + return hba->crypto_vops->resume(hba, pm_op); + + return 0; +} + +void ufshcd_crypto_set_vops(struct ufs_hba *hba, + struct ufs_hba_crypto_variant_ops *crypto_vops) +{ + hba->crypto_vops = crypto_vops; } diff --git a/drivers/scsi/ufs/ufshcd-crypto.h b/drivers/scsi/ufs/ufshcd-crypto.h index 73ddc8e493fb..3c03d0e23e87 100644 --- a/drivers/scsi/ufs/ufshcd-crypto.h +++ b/drivers/scsi/ufs/ufshcd-crypto.h @@ -6,11 +6,9 @@ #ifndef _UFSHCD_CRYPTO_H #define _UFSHCD_CRYPTO_H -struct ufs_hba; - #ifdef CONFIG_SCSI_UFS_CRYPTO #include - +#include "ufshcd.h" #include "ufshci.h" #define NUM_KEYSLOTS(hba) (hba->crypto_capabilities.config_count + 1) @@ -34,6 +32,26 @@ static inline bool ufshcd_is_crypto_enabled(struct ufs_hba *hba) return hba->caps & UFSHCD_CAP_CRYPTO; } +/* Functions implementing UFSHCI v2.1 specification behaviour */ +int ufshcd_prepare_lrbp_crypto_spec(struct ufs_hba *hba, + struct scsi_cmnd *cmd, + struct ufshcd_lrb *lrbp); + +void ufshcd_crypto_enable_spec(struct ufs_hba *hba); + +void ufshcd_crypto_disable_spec(struct ufs_hba *hba); + +struct keyslot_mgmt_ll_ops; +int ufshcd_hba_init_crypto_spec(struct ufs_hba *hba, + const struct keyslot_mgmt_ll_ops *ksm_ops); + +void ufshcd_crypto_setup_rq_keyslot_manager_spec(struct ufs_hba *hba, + struct request_queue *q); + +void ufshcd_crypto_destroy_rq_keyslot_manager_spec(struct ufs_hba *hba, + struct request_queue *q); + +/* Crypto Variant Ops Support */ void ufshcd_crypto_enable(struct ufs_hba *hba); void ufshcd_crypto_disable(struct ufs_hba *hba); @@ -46,6 +64,23 @@ void ufshcd_crypto_setup_rq_keyslot_manager(struct ufs_hba *hba, void ufshcd_crypto_destroy_rq_keyslot_manager(struct ufs_hba *hba, struct request_queue *q); +int ufshcd_prepare_lrbp_crypto(struct ufs_hba *hba, + struct scsi_cmnd *cmd, + struct ufshcd_lrb *lrbp); + +int ufshcd_complete_lrbp_crypto(struct ufs_hba *hba, + struct scsi_cmnd *cmd, + struct ufshcd_lrb *lrbp); + +void ufshcd_crypto_debug(struct ufs_hba *hba); + +int ufshcd_crypto_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op); + +int ufshcd_crypto_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op); + +void ufshcd_crypto_set_vops(struct ufs_hba *hba, + struct ufs_hba_crypto_variant_ops *crypto_vops); + #else /* CONFIG_SCSI_UFS_CRYPTO */ static inline bool ufshcd_keyslot_valid(struct ufs_hba *hba, @@ -73,13 +108,43 @@ static inline int ufshcd_hba_init_crypto(struct ufs_hba *hba) return 0; } -static inline void ufshcd_crypto_setup_rq_keyslot_manager( - struct ufs_hba *hba, - struct request_queue *q) { } +static inline void ufshcd_crypto_setup_rq_keyslot_manager(struct ufs_hba *hba, + struct request_queue *q) { } + +static inline void ufshcd_crypto_destroy_rq_keyslot_manager(struct ufs_hba *hba, + struct request_queue *q) { } + +static inline int ufshcd_prepare_lrbp_crypto(struct ufs_hba *hba, + struct scsi_cmnd *cmd, + struct ufshcd_lrb *lrbp) +{ + lrbp->crypto_enable = false; + return 0; +} + +static inline int ufshcd_complete_lrbp_crypto(struct ufs_hba *hba, + struct scsi_cmnd *cmd, + struct ufshcd_lrb *lrbp) +{ + return 0; +} + +static inline void ufshcd_crypto_debug(struct ufs_hba *hba) { } + +static inline int ufshcd_crypto_suspend(struct ufs_hba *hba, + enum ufs_pm_op pm_op) +{ + return 0; +} + +static inline int ufshcd_crypto_resume(struct ufs_hba *hba, + enum ufs_pm_op pm_op) +{ + return 0; +} -static inline void ufshcd_crypto_destroy_rq_keyslot_manager( - struct ufs_hba *hba, - struct request_queue *q) { } +static inline void ufshcd_crypto_set_vops(struct ufs_hba *hba, + struct ufs_hba_crypto_variant_ops *crypto_vops) { } #endif /* CONFIG_SCSI_UFS_CRYPTO */ diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3a1190f0c672..8ac0157ba9d8 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -436,6 +436,8 @@ static void ufshcd_print_host_regs(struct ufs_hba *hba) if (hba->vops && hba->vops->dbg_register_dump) hba->vops->dbg_register_dump(hba); + + ufshcd_crypto_debug(hba); } static @@ -2400,37 +2402,6 @@ static inline u16 ufshcd_upiu_wlun_to_scsi_wlun(u8 upiu_wlun_id) return (upiu_wlun_id & ~UFS_UPIU_WLUN_ID) | SCSI_W_LUN_BASE; } -static inline int ufshcd_prepare_lrbp_crypto(struct ufs_hba *hba, - struct scsi_cmnd *cmd, - struct ufshcd_lrb *lrbp) -{ - int key_slot; - - if (!cmd->request->bio || - !bio_crypt_should_process(cmd->request->bio, cmd->request->q)) { - lrbp->crypto_enable = false; - return 0; - } - - if (WARN_ON(!ufshcd_is_crypto_enabled(hba))) { - /* - * Upper layer asked us to do inline encryption - * but that isn't enabled, so we fail this request. - */ - return -EINVAL; - } - key_slot = bio_crypt_get_keyslot(cmd->request->bio); - if (!ufshcd_keyslot_valid(hba, key_slot)) - return -EINVAL; - - lrbp->crypto_enable = true; - lrbp->crypto_key_slot = key_slot; - lrbp->data_unit_num = bio_crypt_data_unit_num(cmd->request->bio); - - return 0; -} - - /** * ufshcd_queuecommand - main entry point for SCSI requests * @host: SCSI host pointer @@ -4892,6 +4863,7 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, result = ufshcd_transfer_rsp_status(hba, lrbp); scsi_dma_unmap(cmd); cmd->result = result; + ufshcd_complete_lrbp_crypto(hba, cmd, lrbp); /* Mark completed command as NULL in LRB */ lrbp->cmd = NULL; clear_bit_unlock(index, &hba->lrb_in_use); @@ -7830,6 +7802,10 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) req_link_state = UIC_LINK_OFF_STATE; } + ret = ufshcd_crypto_suspend(hba, pm_op); + if (ret) + goto out; + /* * If we can't transition into any of the low power modes * just gate the clocks. @@ -7933,6 +7909,7 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) ufshcd_resume_clkscaling(hba); hba->clk_gating.is_suspended = false; ufshcd_release(hba); + ufshcd_crypto_resume(hba, pm_op); out: hba->pm_op_in_progress = 0; if (ret) @@ -7954,9 +7931,11 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) { int ret; enum uic_link_state old_link_state; + enum ufs_dev_pwr_mode old_pwr_mode; hba->pm_op_in_progress = 1; old_link_state = hba->uic_link_state; + old_pwr_mode = hba->curr_dev_pwr_mode; ufshcd_hba_vreg_set_hpm(hba); /* Make sure clocks are enabled before accessing controller */ @@ -8004,6 +7983,10 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) goto set_old_link_state; } + ret = ufshcd_crypto_resume(hba, pm_op); + if (ret) + goto set_old_dev_pwr_mode; + if (ufshcd_keep_autobkops_enabled_except_suspend(hba)) ufshcd_enable_auto_bkops(hba); else @@ -8026,6 +8009,9 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) goto out; +set_old_dev_pwr_mode: + if (old_pwr_mode != hba->curr_dev_pwr_mode) + ufshcd_set_dev_pwr_mode(hba, old_pwr_mode); set_old_link_state: ufshcd_link_state_transition(hba, old_link_state, 0); vendor_suspend: diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index a106b45f8358..64736a15cf17 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -336,6 +336,28 @@ struct ufs_hba_variant_ops { void (*device_reset)(struct ufs_hba *hba); }; +struct keyslot_mgmt_ll_ops; +struct ufs_hba_crypto_variant_ops { + void (*setup_rq_keyslot_manager)(struct ufs_hba *hba, + struct request_queue *q); + void (*destroy_rq_keyslot_manager)(struct ufs_hba *hba, + struct request_queue *q); + int (*hba_init_crypto)(struct ufs_hba *hba, + const struct keyslot_mgmt_ll_ops *ksm_ops); + void (*enable)(struct ufs_hba *hba); + void (*disable)(struct ufs_hba *hba); + int (*suspend)(struct ufs_hba *hba, enum ufs_pm_op pm_op); + int (*resume)(struct ufs_hba *hba, enum ufs_pm_op pm_op); + int (*debug)(struct ufs_hba *hba); + int (*prepare_lrbp_crypto)(struct ufs_hba *hba, + struct scsi_cmnd *cmd, + struct ufshcd_lrb *lrbp); + int (*complete_lrbp_crypto)(struct ufs_hba *hba, + struct scsi_cmnd *cmd, + struct ufshcd_lrb *lrbp); + void *priv; +}; + /* clock gating state */ enum clk_gating_state { CLKS_OFF, @@ -583,6 +605,7 @@ struct ufs_hba { u32 ufs_version; const struct ufs_hba_variant_ops *vops; void *priv; + const struct ufs_hba_crypto_variant_ops *crypto_vops; unsigned int irq; bool is_irq_enabled; enum ufs_ref_clk_freq dev_ref_clk_freq; -- GitLab From 38c1605e7555e996f78d3a7427dc09eef486767e Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Tue, 22 Oct 2019 18:03:02 -0700 Subject: [PATCH 941/993] FROMLIST: scsi: ufs: export hibern8 entry and exit Qualcomm controllers need to be in hibern8 before scaling up or down the clocks. Hence, export the hibern8 entry and exit functions. Bug: 143136976 Link: https://lore.kernel.org/lkml/1571849351-819-1-git-send-email-asutoshd@codeaurora.org/ Change-Id: Ie7dc3b953790642e6d2893de6e6cc8c9cfb8be6d Signed-off-by: Asutosh Das --- drivers/scsi/ufs/ufshcd.c | 8 ++++---- drivers/scsi/ufs/ufshcd.h | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 8ac0157ba9d8..126af87ab6d3 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -248,8 +248,6 @@ static int ufshcd_probe_hba(struct ufs_hba *hba); static int __ufshcd_setup_clocks(struct ufs_hba *hba, bool on, bool skip_ref_clk); static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on); -static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba); -static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba); static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba); static int ufshcd_host_reset_and_restore(struct ufs_hba *hba); static void ufshcd_resume_clkscaling(struct ufs_hba *hba); @@ -3929,7 +3927,7 @@ static int __ufshcd_uic_hibern8_enter(struct ufs_hba *hba) return ret; } -static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba) +int ufshcd_uic_hibern8_enter(struct ufs_hba *hba) { int ret = 0, retries; @@ -3941,8 +3939,9 @@ static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba) out: return ret; } +EXPORT_SYMBOL_GPL(ufshcd_uic_hibern8_enter); -static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba) +int ufshcd_uic_hibern8_exit(struct ufs_hba *hba) { struct uic_command uic_cmd = {0}; int ret; @@ -3968,6 +3967,7 @@ static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba) return ret; } +EXPORT_SYMBOL_GPL(ufshcd_uic_hibern8_exit); static void ufshcd_auto_hibern8_enable(struct ufs_hba *hba) { diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 64736a15cf17..b724a6cfe5af 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1145,5 +1145,6 @@ static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun) int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len, const char *prefix); - +int ufshcd_uic_hibern8_enter(struct ufs_hba *hba); +int ufshcd_uic_hibern8_exit(struct ufs_hba *hba); #endif /* End of Header */ -- GitLab From 8e57dcda431f60c845252fb1d3a2712b6c08be60 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Tue, 22 Oct 2019 18:20:21 -0700 Subject: [PATCH 942/993] FROMLIST: scsi: ufs-qcom: enter and exit hibern8 during clock scaling Qualcomm controller needs to be in hibern8 before scaling clocks. This change puts the controller in hibern8 state before scaling and brings it out after scaling of clocks. Bug: 143136976 Link: https://lore.kernel.org/lkml/1571849351-819-2-git-send-email-asutoshd@codeaurora.org/ Change-Id: I0a0903ff1dcc6edef1ac5ab32c3e943828b42a7e Signed-off-by: Asutosh Das --- drivers/scsi/ufs/ufs-qcom.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index a5b71487a206..55b1de5d95a0 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -1305,18 +1305,27 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba, int err = 0; if (status == PRE_CHANGE) { + err = ufshcd_uic_hibern8_enter(hba); + if (err) + return err; if (scale_up) err = ufs_qcom_clk_scale_up_pre_change(hba); else err = ufs_qcom_clk_scale_down_pre_change(hba); + if (err) + ufshcd_uic_hibern8_exit(hba); + } else { if (scale_up) err = ufs_qcom_clk_scale_up_post_change(hba); else err = ufs_qcom_clk_scale_down_post_change(hba); - if (err || !dev_req_params) + + if (err || !dev_req_params) { + ufshcd_uic_hibern8_exit(hba); goto out; + } ufs_qcom_cfg_timers(hba, dev_req_params->gear_rx, @@ -1324,6 +1333,7 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba, dev_req_params->hs_rate, false); ufs_qcom_update_bus_bw_vote(host); + ufshcd_uic_hibern8_exit(hba); } out: -- GitLab From ee8d153d46a3b98c064ee15c0c0a3bbf1450e5a1 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 29 Oct 2019 10:54:44 -0700 Subject: [PATCH 943/993] net: annotate lockless accesses to sk->sk_napi_id We already annotated most accesses to sk->sk_napi_id We missed sk_mark_napi_id() and sk_mark_napi_id_once() which might be called without socket lock held in UDP stack. KCSAN reported : BUG: KCSAN: data-race in udpv6_queue_rcv_one_skb / udpv6_queue_rcv_one_skb write to 0xffff888121c6d108 of 4 bytes by interrupt on cpu 0: sk_mark_napi_id include/net/busy_poll.h:125 [inline] __udpv6_queue_rcv_skb net/ipv6/udp.c:571 [inline] udpv6_queue_rcv_one_skb+0x70c/0xb40 net/ipv6/udp.c:672 udpv6_queue_rcv_skb+0xb5/0x400 net/ipv6/udp.c:689 udp6_unicast_rcv_skb.isra.0+0xd7/0x180 net/ipv6/udp.c:832 __udp6_lib_rcv+0x69c/0x1770 net/ipv6/udp.c:913 udpv6_rcv+0x2b/0x40 net/ipv6/udp.c:1015 ip6_protocol_deliver_rcu+0x22a/0xbe0 net/ipv6/ip6_input.c:409 ip6_input_finish+0x30/0x50 net/ipv6/ip6_input.c:450 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip6_input+0x177/0x190 net/ipv6/ip6_input.c:459 dst_input include/net/dst.h:442 [inline] ip6_rcv_finish+0x110/0x140 net/ipv6/ip6_input.c:76 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ipv6_rcv+0x1a1/0x1b0 net/ipv6/ip6_input.c:284 __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5010 __netif_receive_skb+0x37/0xf0 net/core/dev.c:5124 process_backlog+0x1d3/0x420 net/core/dev.c:5955 napi_poll net/core/dev.c:6392 [inline] net_rx_action+0x3ae/0xa90 net/core/dev.c:6460 write to 0xffff888121c6d108 of 4 bytes by interrupt on cpu 1: sk_mark_napi_id include/net/busy_poll.h:125 [inline] __udpv6_queue_rcv_skb net/ipv6/udp.c:571 [inline] udpv6_queue_rcv_one_skb+0x70c/0xb40 net/ipv6/udp.c:672 udpv6_queue_rcv_skb+0xb5/0x400 net/ipv6/udp.c:689 udp6_unicast_rcv_skb.isra.0+0xd7/0x180 net/ipv6/udp.c:832 __udp6_lib_rcv+0x69c/0x1770 net/ipv6/udp.c:913 udpv6_rcv+0x2b/0x40 net/ipv6/udp.c:1015 ip6_protocol_deliver_rcu+0x22a/0xbe0 net/ipv6/ip6_input.c:409 ip6_input_finish+0x30/0x50 net/ipv6/ip6_input.c:450 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip6_input+0x177/0x190 net/ipv6/ip6_input.c:459 dst_input include/net/dst.h:442 [inline] ip6_rcv_finish+0x110/0x140 net/ipv6/ip6_input.c:76 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ipv6_rcv+0x1a1/0x1b0 net/ipv6/ip6_input.c:284 __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5010 __netif_receive_skb+0x37/0xf0 net/core/dev.c:5124 process_backlog+0x1d3/0x420 net/core/dev.c:5955 Reported by Kernel Concurrency Sanitizer on: CPU: 1 PID: 10890 Comm: syz-executor.0 Not tainted 5.4.0-rc3+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Fixes: e68b6e50fa35 ("udp: enable busy polling for all sockets") Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: David S. Miller --- include/net/busy_poll.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/net/busy_poll.h b/include/net/busy_poll.h index 127a5c4e3699..86e028388bad 100644 --- a/include/net/busy_poll.h +++ b/include/net/busy_poll.h @@ -122,7 +122,7 @@ static inline void skb_mark_napi_id(struct sk_buff *skb, static inline void sk_mark_napi_id(struct sock *sk, const struct sk_buff *skb) { #ifdef CONFIG_NET_RX_BUSY_POLL - sk->sk_napi_id = skb->napi_id; + WRITE_ONCE(sk->sk_napi_id, skb->napi_id); #endif sk_rx_queue_set(sk, skb); } @@ -132,8 +132,8 @@ static inline void sk_mark_napi_id_once(struct sock *sk, const struct sk_buff *skb) { #ifdef CONFIG_NET_RX_BUSY_POLL - if (!sk->sk_napi_id) - sk->sk_napi_id = skb->napi_id; + if (!READ_ONCE(sk->sk_napi_id)) + WRITE_ONCE(sk->sk_napi_id, skb->napi_id); #endif } -- GitLab From fc89cc358fb64e2429aeae0f37906126636507ec Mon Sep 17 00:00:00 2001 From: Vishal Kulkarni Date: Wed, 30 Oct 2019 20:17:57 +0530 Subject: [PATCH 944/993] cxgb4: fix panic when attaching to ULD fail Release resources when attaching to ULD fail. Otherwise, data mismatch is seen between LLD and ULD later on, which lead to kernel panic when accessing resources that should not even exist in the first place. Fixes: 94cdb8bb993a ("cxgb4: Add support for dynamic allocation of resources for ULD") Signed-off-by: Shahjada Abul Husain Signed-off-by: Vishal Kulkarni Signed-off-by: David S. Miller --- .../net/ethernet/chelsio/cxgb4/cxgb4_uld.c | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c index a4dead4ab0ed..86b528d8364c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c @@ -695,10 +695,10 @@ static void uld_init(struct adapter *adap, struct cxgb4_lld_info *lld) lld->write_cmpl_support = adap->params.write_cmpl_support; } -static void uld_attach(struct adapter *adap, unsigned int uld) +static int uld_attach(struct adapter *adap, unsigned int uld) { - void *handle; struct cxgb4_lld_info lli; + void *handle; uld_init(adap, &lli); uld_queue_init(adap, uld, &lli); @@ -708,7 +708,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld) dev_warn(adap->pdev_dev, "could not attach to the %s driver, error %ld\n", adap->uld[uld].name, PTR_ERR(handle)); - return; + return PTR_ERR(handle); } adap->uld[uld].handle = handle; @@ -716,22 +716,22 @@ static void uld_attach(struct adapter *adap, unsigned int uld) if (adap->flags & CXGB4_FULL_INIT_DONE) adap->uld[uld].state_change(handle, CXGB4_STATE_UP); + + return 0; } -/** - * cxgb4_register_uld - register an upper-layer driver - * @type: the ULD type - * @p: the ULD methods +/* cxgb4_register_uld - register an upper-layer driver + * @type: the ULD type + * @p: the ULD methods * - * Registers an upper-layer driver with this driver and notifies the ULD - * about any presently available devices that support its type. Returns - * %-EBUSY if a ULD of the same type is already registered. + * Registers an upper-layer driver with this driver and notifies the ULD + * about any presently available devices that support its type. */ void cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p) { - int ret = 0; struct adapter *adap; + int ret = 0; if (type >= CXGB4_ULD_MAX) return; @@ -763,8 +763,12 @@ void cxgb4_register_uld(enum cxgb4_uld type, if (ret) goto free_irq; adap->uld[type] = *p; - uld_attach(adap, type); + ret = uld_attach(adap, type); + if (ret) + goto free_txq; continue; +free_txq: + release_sge_txq_uld(adap, type); free_irq: if (adap->flags & CXGB4_FULL_INIT_DONE) quiesce_rx_uld(adap, type); -- GitLab From c4509a5ac0ace94d5b1f0092dc4d36933c1d896e Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Wed, 30 Oct 2019 15:32:11 +0000 Subject: [PATCH 945/993] hv_netvsc: Fix error handling in netvsc_set_features() When an error is returned by rndis_filter_set_offload_params(), we should still assign the unaffected features to ndev->features. Otherwise, these features will be missing. Fixes: d6792a5a0747 ("hv_netvsc: Add handler for LRO setting change") Signed-off-by: Haiyang Zhang Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index fd4fff57fd6e..bab7c1f84dfd 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -1807,8 +1807,10 @@ static int netvsc_set_features(struct net_device *ndev, ret = rndis_filter_set_offload_params(ndev, nvdev, &offloads); - if (ret) + if (ret) { features ^= NETIF_F_LRO; + ndev->features = features; + } syncvf: if (!vf_netdev) -- GitLab From 719b85c336ed35565d0f3982269d6f684087bb00 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Wed, 30 Oct 2019 15:32:13 +0000 Subject: [PATCH 946/993] hv_netvsc: Fix error handling in netvsc_attach() If rndis_filter_open() fails, we need to remove the rndis device created in earlier steps, before returning an error code. Otherwise, the retry of netvsc_attach() from its callers will fail and hang. Fixes: 7b2ee50c0cd5 ("hv_netvsc: common detach logic") Signed-off-by: Haiyang Zhang Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index bab7c1f84dfd..963509add611 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -982,7 +982,7 @@ static int netvsc_attach(struct net_device *ndev, if (netif_running(ndev)) { ret = rndis_filter_open(nvdev); if (ret) - return ret; + goto err; rdev = nvdev->extension; if (!rdev->link_state) @@ -990,6 +990,13 @@ static int netvsc_attach(struct net_device *ndev, } return 0; + +err: + netif_device_detach(ndev); + + rndis_filter_device_remove(hdev, nvdev); + + return ret; } static int netvsc_set_channels(struct net_device *net, -- GitLab From 0b6b30c65621fc11a799ca71241f52d8fd9e334c Mon Sep 17 00:00:00 2001 From: Narendra K Date: Tue, 29 Oct 2019 18:37:50 +0100 Subject: [PATCH 947/993] efi: Make CONFIG_EFI_RCI2_TABLE selectable on x86 only For the EFI_RCI2_TABLE Kconfig option, 'make oldconfig' asks the user for input on platforms where the option may not be applicable. This patch modifies the Kconfig option to ask the user for input only when CONFIG_X86 or CONFIG_COMPILE_TEST is set to y. Suggested-by: Geert Uytterhoeven Reported-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Signed-off-by: Narendra K Signed-off-by: Ard Biesheuvel Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: https://lkml.kernel.org/r/20191029173755.27149-2-ardb@kernel.org Signed-off-by: Ingo Molnar --- drivers/firmware/efi/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 178ee8106828..b248870a9806 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -182,6 +182,7 @@ config RESET_ATTACK_MITIGATION config EFI_RCI2_TABLE bool "EFI Runtime Configuration Interface Table Version 2 Support" + depends on X86 || COMPILE_TEST help Displays the content of the Runtime Configuration Interface Table version 2 on Dell EMC PowerEdge systems as a binary -- GitLab From 2bb6a81633cb47dcba4c9f75605cbe49e6b73d60 Mon Sep 17 00:00:00 2001 From: Jerry Snitselaar Date: Tue, 29 Oct 2019 18:37:51 +0100 Subject: [PATCH 948/993] efi/tpm: Return -EINVAL when determining tpm final events log size fails Currently nothing checks the return value of efi_tpm_eventlog_init(), but in case that changes in the future make sure an error is returned when it fails to determine the tpm final events log size. Suggested-by: Dan Carpenter Signed-off-by: Jerry Snitselaar Signed-off-by: Ard Biesheuvel Reviewed-by: Jarkko Sakkinen Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Fixes: e658c82be556 ("efi/tpm: Only set 'efi_tpm_final_log_size' after ...") Link: https://lkml.kernel.org/r/20191029173755.27149-3-ardb@kernel.org Signed-off-by: Ingo Molnar --- drivers/firmware/efi/tpm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c index ebd7977653a8..31f9f0e369b9 100644 --- a/drivers/firmware/efi/tpm.c +++ b/drivers/firmware/efi/tpm.c @@ -88,6 +88,7 @@ int __init efi_tpm_eventlog_init(void) if (tbl_size < 0) { pr_err(FW_BUG "Failed to parse event in TPM Final Events Log\n"); + ret = -EINVAL; goto out_calc; } -- GitLab From 18b915ac6b0ac5ba7ded03156860f60a9f16df2b Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 29 Oct 2019 18:37:52 +0100 Subject: [PATCH 949/993] efi/random: Treat EFI_RNG_PROTOCOL output as bootloader randomness Commit 428826f5358c ("fdt: add support for rng-seed") introduced add_bootloader_randomness(), permitting randomness provided by the bootloader or firmware to be credited as entropy. However, the fact that the UEFI support code was already wired into the RNG subsystem via a call to add_device_randomness() was overlooked, and so it was not converted at the same time. Note that this UEFI (v2.4 or newer) feature is currently only implemented for EFI stub booting on ARM, and further note that CONFIG_RANDOM_TRUST_BOOTLOADER must be enabled, and this should be done only if there indeed is sufficient trust in the bootloader _and_ its source of randomness. [ ardb: update commit log ] Tested-by: Bhupesh Sharma Signed-off-by: Dominik Brodowski Signed-off-by: Ard Biesheuvel Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: https://lkml.kernel.org/r/20191029173755.27149-4-ardb@kernel.org Signed-off-by: Ingo Molnar --- drivers/firmware/efi/efi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 69f00f7453a3..e98bbf8e56d9 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -554,7 +554,7 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz, sizeof(*seed) + size); if (seed != NULL) { pr_notice("seeding entropy pool\n"); - add_device_randomness(seed->bits, seed->size); + add_bootloader_randomness(seed->bits, seed->size); early_memunmap(seed, sizeof(*seed) + size); } else { pr_err("Could not map UEFI random seed!\n"); -- GitLab From 41cd96fa149b29684ebd38759fefb07f9c7d5276 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 29 Oct 2019 18:37:53 +0100 Subject: [PATCH 950/993] efi: libstub/arm: Account for firmware reserved memory at the base of RAM The EFI stubloader for ARM starts out by allocating a 32 MB window at the base of RAM, in order to ensure that the decompressor (which blindly copies the uncompressed kernel into that window) does not overwrite other allocations that are made while running in the context of the EFI firmware. In some cases, (e.g., U-Boot running on the Raspberry Pi 2), this is causing boot failures because this initial allocation conflicts with a page of reserved memory at the base of RAM that contains the SMP spin tables and other pieces of firmware data and which was put there by the bootloader under the assumption that the TEXT_OFFSET window right below the kernel is only used partially during early boot, and will be left alone once the memory reservations are processed and taken into account. So let's permit reserved memory regions to exist in the region starting at the base of RAM, and ending at TEXT_OFFSET - 5 * PAGE_SIZE, which is the window below the kernel that is not touched by the early boot code. Tested-by: Guillaume Gardet Signed-off-by: Ard Biesheuvel Acked-by: Chester Lin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: https://lkml.kernel.org/r/20191029173755.27149-5-ardb@kernel.org Signed-off-by: Ingo Molnar --- drivers/firmware/efi/libstub/Makefile | 1 + drivers/firmware/efi/libstub/arm32-stub.c | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 0460c7581220..ee0661ddb25b 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -52,6 +52,7 @@ lib-$(CONFIG_EFI_ARMSTUB) += arm-stub.o fdt.o string.o random.o \ lib-$(CONFIG_ARM) += arm32-stub.o lib-$(CONFIG_ARM64) += arm64-stub.o +CFLAGS_arm32-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) CFLAGS_arm64-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) # diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c index e8f7aefb6813..ffa242ad0a82 100644 --- a/drivers/firmware/efi/libstub/arm32-stub.c +++ b/drivers/firmware/efi/libstub/arm32-stub.c @@ -195,6 +195,7 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table, unsigned long dram_base, efi_loaded_image_t *image) { + unsigned long kernel_base; efi_status_t status; /* @@ -204,9 +205,18 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table, * loaded. These assumptions are made by the decompressor, * before any memory map is available. */ - dram_base = round_up(dram_base, SZ_128M); + kernel_base = round_up(dram_base, SZ_128M); - status = reserve_kernel_base(sys_table, dram_base, reserve_addr, + /* + * Note that some platforms (notably, the Raspberry Pi 2) put + * spin-tables and other pieces of firmware at the base of RAM, + * abusing the fact that the window of TEXT_OFFSET bytes at the + * base of the kernel image is only partially used at the moment. + * (Up to 5 pages are used for the swapper page tables) + */ + kernel_base += TEXT_OFFSET - 5 * PAGE_SIZE; + + status = reserve_kernel_base(sys_table, kernel_base, reserve_addr, reserve_size); if (status != EFI_SUCCESS) { pr_efi_err(sys_table, "Unable to allocate memory for uncompressed kernel.\n"); @@ -220,7 +230,7 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table, *image_size = image->image_size; status = efi_relocate_kernel(sys_table, image_addr, *image_size, *image_size, - dram_base + MAX_UNCOMP_KERNEL_SIZE, 0); + kernel_base + MAX_UNCOMP_KERNEL_SIZE, 0); if (status != EFI_SUCCESS) { pr_efi_err(sys_table, "Failed to relocate kernel.\n"); efi_free(sys_table, *reserve_size, *reserve_addr); -- GitLab From 220dd7699c46d5940115bd797b01b2ab047c87b8 Mon Sep 17 00:00:00 2001 From: Kairui Song Date: Tue, 29 Oct 2019 18:37:54 +0100 Subject: [PATCH 951/993] x86, efi: Never relocate kernel below lowest acceptable address Currently, kernel fails to boot on some HyperV VMs when using EFI. And it's a potential issue on all x86 platforms. It's caused by broken kernel relocation on EFI systems, when below three conditions are met: 1. Kernel image is not loaded to the default address (LOAD_PHYSICAL_ADDR) by the loader. 2. There isn't enough room to contain the kernel, starting from the default load address (eg. something else occupied part the region). 3. In the memmap provided by EFI firmware, there is a memory region starts below LOAD_PHYSICAL_ADDR, and suitable for containing the kernel. EFI stub will perform a kernel relocation when condition 1 is met. But due to condition 2, EFI stub can't relocate kernel to the preferred address, so it fallback to ask EFI firmware to alloc lowest usable memory region, got the low region mentioned in condition 3, and relocated kernel there. It's incorrect to relocate the kernel below LOAD_PHYSICAL_ADDR. This is the lowest acceptable kernel relocation address. The first thing goes wrong is in arch/x86/boot/compressed/head_64.S. Kernel decompression will force use LOAD_PHYSICAL_ADDR as the output address if kernel is located below it. Then the relocation before decompression, which move kernel to the end of the decompression buffer, will overwrite other memory region, as there is no enough memory there. To fix it, just don't let EFI stub relocate the kernel to any address lower than lowest acceptable address. [ ardb: introduce efi_low_alloc_above() to reduce the scope of the change ] Signed-off-by: Kairui Song Signed-off-by: Ard Biesheuvel Acked-by: Jarkko Sakkinen Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: https://lkml.kernel.org/r/20191029173755.27149-6-ardb@kernel.org Signed-off-by: Ingo Molnar --- arch/x86/boot/compressed/eboot.c | 4 +++- drivers/firmware/efi/libstub/arm32-stub.c | 2 +- .../firmware/efi/libstub/efi-stub-helper.c | 24 ++++++++----------- include/linux/efi.h | 18 ++++++++++++-- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index d6662fdef300..82bc60c8acb2 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "../string.h" #include "eboot.h" @@ -813,7 +814,8 @@ efi_main(struct efi_config *c, struct boot_params *boot_params) status = efi_relocate_kernel(sys_table, &bzimage_addr, hdr->init_size, hdr->init_size, hdr->pref_address, - hdr->kernel_alignment); + hdr->kernel_alignment, + LOAD_PHYSICAL_ADDR); if (status != EFI_SUCCESS) { efi_printk(sys_table, "efi_relocate_kernel() failed!\n"); goto fail; diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c index ffa242ad0a82..41213bf5fcf5 100644 --- a/drivers/firmware/efi/libstub/arm32-stub.c +++ b/drivers/firmware/efi/libstub/arm32-stub.c @@ -230,7 +230,7 @@ efi_status_t handle_kernel_image(efi_system_table_t *sys_table, *image_size = image->image_size; status = efi_relocate_kernel(sys_table, image_addr, *image_size, *image_size, - kernel_base + MAX_UNCOMP_KERNEL_SIZE, 0); + kernel_base + MAX_UNCOMP_KERNEL_SIZE, 0, 0); if (status != EFI_SUCCESS) { pr_efi_err(sys_table, "Failed to relocate kernel.\n"); efi_free(sys_table, *reserve_size, *reserve_addr); diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 3caae7f2cf56..35dbc2791c97 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -260,11 +260,11 @@ efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg, } /* - * Allocate at the lowest possible address. + * Allocate at the lowest possible address that is not below 'min'. */ -efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, - unsigned long size, unsigned long align, - unsigned long *addr) +efi_status_t efi_low_alloc_above(efi_system_table_t *sys_table_arg, + unsigned long size, unsigned long align, + unsigned long *addr, unsigned long min) { unsigned long map_size, desc_size, buff_size; efi_memory_desc_t *map; @@ -311,13 +311,8 @@ efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, start = desc->phys_addr; end = start + desc->num_pages * EFI_PAGE_SIZE; - /* - * Don't allocate at 0x0. It will confuse code that - * checks pointers against NULL. Skip the first 8 - * bytes so we start at a nice even number. - */ - if (start == 0x0) - start += 8; + if (start < min) + start = min; start = round_up(start, align); if ((start + size) > end) @@ -698,7 +693,8 @@ efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg, unsigned long image_size, unsigned long alloc_size, unsigned long preferred_addr, - unsigned long alignment) + unsigned long alignment, + unsigned long min_addr) { unsigned long cur_image_addr; unsigned long new_addr = 0; @@ -731,8 +727,8 @@ efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg, * possible. */ if (status != EFI_SUCCESS) { - status = efi_low_alloc(sys_table_arg, alloc_size, alignment, - &new_addr); + status = efi_low_alloc_above(sys_table_arg, alloc_size, + alignment, &new_addr, min_addr); } if (status != EFI_SUCCESS) { pr_efi_err(sys_table_arg, "Failed to allocate usable memory for kernel.\n"); diff --git a/include/linux/efi.h b/include/linux/efi.h index bd3837022307..d87acf62958e 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1579,9 +1579,22 @@ char *efi_convert_cmdline(efi_system_table_t *sys_table_arg, efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg, struct efi_boot_memmap *map); +efi_status_t efi_low_alloc_above(efi_system_table_t *sys_table_arg, + unsigned long size, unsigned long align, + unsigned long *addr, unsigned long min); + +static inline efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, unsigned long size, unsigned long align, - unsigned long *addr); + unsigned long *addr) +{ + /* + * Don't allocate at 0x0. It will confuse code that + * checks pointers against NULL. Skip the first 8 + * bytes so we start at a nice even number. + */ + return efi_low_alloc_above(sys_table_arg, size, align, addr, 0x8); +} efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg, unsigned long size, unsigned long align, @@ -1592,7 +1605,8 @@ efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg, unsigned long image_size, unsigned long alloc_size, unsigned long preferred_addr, - unsigned long alignment); + unsigned long alignment, + unsigned long min_addr); efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg, efi_loaded_image_t *image, -- GitLab From 359efcc2c910117d2faf704ce154e91fc976d37f Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 29 Oct 2019 18:37:55 +0100 Subject: [PATCH 952/993] efi/efi_test: Lock down /dev/efi_test and require CAP_SYS_ADMIN The driver exposes EFI runtime services to user-space through an IOCTL interface, calling the EFI services function pointers directly without using the efivar API. Disallow access to the /dev/efi_test character device when the kernel is locked down to prevent arbitrary user-space to call EFI runtime services. Also require CAP_SYS_ADMIN to open the chardev to prevent unprivileged users to call the EFI runtime services, instead of just relying on the chardev file mode bits for this. The main user of this driver is the fwts [0] tool that already checks if the effective user ID is 0 and fails otherwise. So this change shouldn't cause any regression to this tool. [0]: https://wiki.ubuntu.com/FirmwareTestSuite/Reference/uefivarinfo Signed-off-by: Javier Martinez Canillas Signed-off-by: Ard Biesheuvel Acked-by: Laszlo Ersek Acked-by: Matthew Garrett Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: linux-efi@vger.kernel.org Link: https://lkml.kernel.org/r/20191029173755.27149-7-ardb@kernel.org Signed-off-by: Ingo Molnar --- drivers/firmware/efi/test/efi_test.c | 8 ++++++++ include/linux/security.h | 1 + security/lockdown/lockdown.c | 1 + 3 files changed, 10 insertions(+) diff --git a/drivers/firmware/efi/test/efi_test.c b/drivers/firmware/efi/test/efi_test.c index 877745c3aaf2..7baf48c01e72 100644 --- a/drivers/firmware/efi/test/efi_test.c +++ b/drivers/firmware/efi/test/efi_test.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -717,6 +718,13 @@ static long efi_test_ioctl(struct file *file, unsigned int cmd, static int efi_test_open(struct inode *inode, struct file *file) { + int ret = security_locked_down(LOCKDOWN_EFI_TEST); + + if (ret) + return ret; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; /* * nothing special to do here * We do accept multiple open files at the same time as we diff --git a/include/linux/security.h b/include/linux/security.h index a8d59d612d27..9df7547afc0c 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -105,6 +105,7 @@ enum lockdown_reason { LOCKDOWN_NONE, LOCKDOWN_MODULE_SIGNATURE, LOCKDOWN_DEV_MEM, + LOCKDOWN_EFI_TEST, LOCKDOWN_KEXEC, LOCKDOWN_HIBERNATION, LOCKDOWN_PCI_ACCESS, diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c index 8a10b43daf74..40b790536def 100644 --- a/security/lockdown/lockdown.c +++ b/security/lockdown/lockdown.c @@ -20,6 +20,7 @@ static const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = { [LOCKDOWN_NONE] = "none", [LOCKDOWN_MODULE_SIGNATURE] = "unsigned module loading", [LOCKDOWN_DEV_MEM] = "/dev/mem,kmem,port", + [LOCKDOWN_EFI_TEST] = "/dev/efi_test access", [LOCKDOWN_KEXEC] = "kexec of unsigned images", [LOCKDOWN_HIBERNATION] = "hibernation", [LOCKDOWN_PCI_ACCESS] = "direct PCI access", -- GitLab From a97b0e773e492ae319a7e981e98962a1060215f9 Mon Sep 17 00:00:00 2001 From: Jim Mattson Date: Fri, 25 Oct 2019 13:34:58 +0200 Subject: [PATCH 953/993] kvm: call kvm_arch_destroy_vm if vm creation fails In kvm_create_vm(), if we've successfully called kvm_arch_init_vm(), but then fail later in the function, we need to call kvm_arch_destroy_vm() so that it can do any necessary cleanup (like freeing memory). Fixes: 44a95dae1d229a ("KVM: x86: Detect and Initialize AVIC support") Signed-off-by: John Sperbeck Signed-off-by: Jim Mattson Reviewed-by: Junaid Shahid [Remove dependency on "kvm: Don't clear reference count on kvm_create_vm() error path" which was not committed. - Paolo] Signed-off-by: Paolo Bonzini --- virt/kvm/kvm_main.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index ec14dae2f538..d6f0696d98ef 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -641,7 +641,6 @@ static struct kvm *kvm_create_vm(unsigned long type) mutex_init(&kvm->lock); mutex_init(&kvm->irq_lock); mutex_init(&kvm->slots_lock); - refcount_set(&kvm->users_count, 1); INIT_LIST_HEAD(&kvm->devices); BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX); @@ -650,7 +649,7 @@ static struct kvm *kvm_create_vm(unsigned long type) struct kvm_memslots *slots = kvm_alloc_memslots(); if (!slots) - goto out_err_no_disable; + goto out_err_no_arch_destroy_vm; /* Generations must be different for each address space. */ slots->generation = i; rcu_assign_pointer(kvm->memslots[i], slots); @@ -660,12 +659,13 @@ static struct kvm *kvm_create_vm(unsigned long type) rcu_assign_pointer(kvm->buses[i], kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL_ACCOUNT)); if (!kvm->buses[i]) - goto out_err_no_disable; + goto out_err_no_arch_destroy_vm; } + refcount_set(&kvm->users_count, 1); r = kvm_arch_init_vm(kvm, type); if (r) - goto out_err_no_disable; + goto out_err_no_arch_destroy_vm; r = hardware_enable_all(); if (r) @@ -699,7 +699,9 @@ static struct kvm *kvm_create_vm(unsigned long type) out_err_no_srcu: hardware_disable_all(); out_err_no_disable: - refcount_set(&kvm->users_count, 0); + kvm_arch_destroy_vm(kvm); + WARN_ON_ONCE(!refcount_dec_and_test(&kvm->users_count)); +out_err_no_arch_destroy_vm: for (i = 0; i < KVM_NR_BUSES; i++) kfree(kvm_get_bus(kvm, i)); for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) -- GitLab From 9167ab79936206118cc60e47dcb926c3489f3bd5 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sun, 27 Oct 2019 16:23:23 +0100 Subject: [PATCH 954/993] KVM: vmx, svm: always run with EFER.NXE=1 when shadow paging is active VMX already does so if the host has SMEP, in order to support the combination of CR0.WP=1 and CR4.SMEP=1. However, it is perfectly safe to always do so, and in fact VMX already ends up running with EFER.NXE=1 on old processors that lack the "load EFER" controls, because it may help avoiding a slow MSR write. Removing all the conditionals simplifies the code. SVM does not have similar code, but it should since recent AMD processors do support SMEP. So this patch also makes the code for the two vendors more similar while fixing NPT=0, CR0.WP=1 and CR4.SMEP=1 on AMD processors. Cc: stable@vger.kernel.org Cc: Joerg Roedel Signed-off-by: Paolo Bonzini --- arch/x86/kvm/svm.c | 10 ++++++++-- arch/x86/kvm/vmx/vmx.c | 14 +++----------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index ca200b50cde4..c5673bda4b66 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -734,8 +734,14 @@ static int get_npt_level(struct kvm_vcpu *vcpu) static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) { vcpu->arch.efer = efer; - if (!npt_enabled && !(efer & EFER_LMA)) - efer &= ~EFER_LME; + + if (!npt_enabled) { + /* Shadow paging assumes NX to be available. */ + efer |= EFER_NX; + + if (!(efer & EFER_LMA)) + efer &= ~EFER_LME; + } to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME; mark_dirty(to_svm(vcpu)->vmcb, VMCB_CR); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 8f01019295a1..5d21a4ab28cf 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -969,17 +969,9 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset) u64 guest_efer = vmx->vcpu.arch.efer; u64 ignore_bits = 0; - if (!enable_ept) { - /* - * NX is needed to handle CR0.WP=1, CR4.SMEP=1. Testing - * host CPUID is more efficient than testing guest CPUID - * or CR4. Host SMEP is anyway a requirement for guest SMEP. - */ - if (boot_cpu_has(X86_FEATURE_SMEP)) - guest_efer |= EFER_NX; - else if (!(guest_efer & EFER_NX)) - ignore_bits |= EFER_NX; - } + /* Shadow paging assumes NX to be available. */ + if (!enable_ept) + guest_efer |= EFER_NX; /* * LMA and LME handled by hardware; SCE meaningless outside long mode. -- GitLab From 36c602dcdd872e9f9b91aae5266b6d7d72b69b96 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Tue, 29 Oct 2019 16:27:38 -0700 Subject: [PATCH 955/993] arm64: cpufeature: Enable Qualcomm Falkor errata 1009 for Kryo The Kryo cores share errata 1009 with Falkor, so add their model definitions and enable it for them as well. Signed-off-by: Bjorn Andersson [will: Update entry in silicon-errata.rst] Signed-off-by: Will Deacon --- Documentation/arm64/silicon-errata.rst | 2 +- arch/arm64/kernel/cpu_errata.c | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index ab7ed2fd072f..25d62272de73 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -126,7 +126,7 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | +----------------+-----------------+-----------------+-----------------------------+ -| Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 | +| Qualcomm Tech. | Kryo/Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 | +----------------+-----------------+-----------------+-----------------------------+ | Qualcomm Tech. | QDF2400 ITS | E0065 | QCOM_QDF2400_ERRATUM_0065 | +----------------+-----------------+-----------------+-----------------------------+ diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 7f9b699969c7..091e3ec0f420 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -659,17 +659,23 @@ static const struct midr_range arm64_harden_el2_vectors[] = { #endif #ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI - -static const struct midr_range arm64_repeat_tlbi_cpus[] = { +static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = { #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1009 - MIDR_RANGE(MIDR_QCOM_FALKOR_V1, 0, 0, 0, 0), + { + ERRATA_MIDR_REV(MIDR_QCOM_FALKOR_V1, 0, 0) + }, + { + .midr_range.model = MIDR_QCOM_KRYO, + .matches = is_kryo_midr, + }, #endif #ifdef CONFIG_ARM64_ERRATUM_1286807 - MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 0), + { + ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 0), + }, #endif {}, }; - #endif #ifdef CONFIG_CAVIUM_ERRATUM_27456 @@ -825,7 +831,9 @@ const struct arm64_cpu_capabilities arm64_errata[] = { { .desc = "Qualcomm erratum 1009, ARM erratum 1286807", .capability = ARM64_WORKAROUND_REPEAT_TLBI, - ERRATA_MIDR_RANGE_LIST(arm64_repeat_tlbi_cpus), + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + .matches = cpucap_multi_entry_cap_matches, + .match_list = arm64_repeat_tlbi_list, }, #endif #ifdef CONFIG_ARM64_ERRATUM_858921 -- GitLab From b8e51a6a9db94bc1fb18ae831b3dab106b5a4b5f Mon Sep 17 00:00:00 2001 From: Yihui ZENG Date: Fri, 25 Oct 2019 12:31:48 +0300 Subject: [PATCH 956/993] s390/cmm: fix information leak in cmm_timeout_handler() The problem is that we were putting the NUL terminator too far: buf[sizeof(buf) - 1] = '\0'; If the user input isn't NUL terminated and they haven't initialized the whole buffer then it leads to an info leak. The NUL terminator should be: buf[len - 1] = '\0'; Signed-off-by: Yihui Zeng Cc: stable@vger.kernel.org Signed-off-by: Dan Carpenter [heiko.carstens@de.ibm.com: keep semantics of how *lenp and *ppos are handled] Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- arch/s390/mm/cmm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index 510a18299196..a51c892f14f3 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c @@ -298,16 +298,16 @@ static int cmm_timeout_handler(struct ctl_table *ctl, int write, } if (write) { - len = *lenp; - if (copy_from_user(buf, buffer, - len > sizeof(buf) ? sizeof(buf) : len)) + len = min(*lenp, sizeof(buf)); + if (copy_from_user(buf, buffer, len)) return -EFAULT; - buf[sizeof(buf) - 1] = '\0'; + buf[len - 1] = '\0'; cmm_skip_blanks(buf, &p); nr = simple_strtoul(p, &p, 0); cmm_skip_blanks(p, &p); seconds = simple_strtoul(p, &p, 0); cmm_set_timeout(nr, seconds); + *ppos += *lenp; } else { len = sprintf(buf, "%ld %ld\n", cmm_timeout_pages, cmm_timeout_seconds); @@ -315,9 +315,9 @@ static int cmm_timeout_handler(struct ctl_table *ctl, int write, len = *lenp; if (copy_to_user(buffer, buf, len)) return -EFAULT; + *lenp = len; + *ppos += len; } - *lenp = len; - *ppos += len; return 0; } -- GitLab From a1d863ac3e1085e1fea9caafd87252d08731de2e Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Wed, 2 Oct 2019 13:29:57 +0200 Subject: [PATCH 957/993] s390/unwind: fix mixing regs and sp unwind_for_each_frame stops after the first frame if regs->gprs[15] <= sp. The reason is that in case regs are specified, the first frame should be regs->psw.addr and the second frame should be sp->gprs[8]. However, currently the second frame is regs->gprs[15], which confuses outside_of_stack(). Fix by introducing a flag to distinguish this special case from unwinding the interrupt handler, for which the current behavior is appropriate. Fixes: 78c98f907413 ("s390/unwind: introduce stack unwind API") Signed-off-by: Ilya Leoshkevich Cc: stable@vger.kernel.org # v5.2+ Reviewed-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- arch/s390/include/asm/unwind.h | 1 + arch/s390/kernel/unwind_bc.c | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/arch/s390/include/asm/unwind.h b/arch/s390/include/asm/unwind.h index d827b5b9a32c..eaaefeceef6f 100644 --- a/arch/s390/include/asm/unwind.h +++ b/arch/s390/include/asm/unwind.h @@ -35,6 +35,7 @@ struct unwind_state { struct task_struct *task; struct pt_regs *regs; unsigned long sp, ip; + bool reuse_sp; int graph_idx; bool reliable; bool error; diff --git a/arch/s390/kernel/unwind_bc.c b/arch/s390/kernel/unwind_bc.c index 8fc9daae47a2..a8204f952315 100644 --- a/arch/s390/kernel/unwind_bc.c +++ b/arch/s390/kernel/unwind_bc.c @@ -46,10 +46,15 @@ bool unwind_next_frame(struct unwind_state *state) regs = state->regs; if (unlikely(regs)) { - sp = READ_ONCE_NOCHECK(regs->gprs[15]); - if (unlikely(outside_of_stack(state, sp))) { - if (!update_stack_info(state, sp)) - goto out_err; + if (state->reuse_sp) { + sp = state->sp; + state->reuse_sp = false; + } else { + sp = READ_ONCE_NOCHECK(regs->gprs[15]); + if (unlikely(outside_of_stack(state, sp))) { + if (!update_stack_info(state, sp)) + goto out_err; + } } sf = (struct stack_frame *) sp; ip = READ_ONCE_NOCHECK(sf->gprs[8]); @@ -107,9 +112,9 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, { struct stack_info *info = &state->stack_info; unsigned long *mask = &state->stack_mask; + bool reliable, reuse_sp; struct stack_frame *sf; unsigned long ip; - bool reliable; memset(state, 0, sizeof(*state)); state->task = task; @@ -134,10 +139,12 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, if (regs) { ip = READ_ONCE_NOCHECK(regs->psw.addr); reliable = true; + reuse_sp = true; } else { sf = (struct stack_frame *) sp; ip = READ_ONCE_NOCHECK(sf->gprs[8]); reliable = false; + reuse_sp = false; } #ifdef CONFIG_FUNCTION_GRAPH_TRACER @@ -151,5 +158,6 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task, state->sp = sp; state->ip = ip; state->reliable = reliable; + state->reuse_sp = reuse_sp; } EXPORT_SYMBOL_GPL(__unwind_start); -- GitLab From 3d7efa4edd07be5c5c3ffa95ba63e97e070e1f3f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 28 Oct 2019 11:03:27 +0100 Subject: [PATCH 958/993] s390/idle: fix cpu idle time calculation The idle time reported in /proc/stat sometimes incorrectly contains huge values on s390. This is caused by a bug in arch_cpu_idle_time(). The kernel tries to figure out when a different cpu entered idle by accessing its per-cpu data structure. There is an ordering problem: if the remote cpu has an idle_enter value which is not zero, and an idle_exit value which is zero, it is assumed it is idle since "now". The "now" timestamp however is taken before the idle_enter value is read. Which in turn means that "now" can be smaller than idle_enter of the remote cpu. Unconditionally subtracting idle_enter from "now" can thus lead to a negative value (aka large unsigned value). Fix this by moving the get_tod_clock() invocation out of the loop. While at it also make the code a bit more readable. A similar bug also exists for show_idle_time(). Fix this is as well. Cc: Signed-off-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- arch/s390/kernel/idle.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/arch/s390/kernel/idle.c b/arch/s390/kernel/idle.c index b9d8fe45737a..8f8456816d83 100644 --- a/arch/s390/kernel/idle.c +++ b/arch/s390/kernel/idle.c @@ -69,18 +69,26 @@ DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL); static ssize_t show_idle_time(struct device *dev, struct device_attribute *attr, char *buf) { + unsigned long long now, idle_time, idle_enter, idle_exit, in_idle; struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); - unsigned long long now, idle_time, idle_enter, idle_exit; unsigned int seq; do { - now = get_tod_clock(); seq = read_seqcount_begin(&idle->seqcount); idle_time = READ_ONCE(idle->idle_time); idle_enter = READ_ONCE(idle->clock_idle_enter); idle_exit = READ_ONCE(idle->clock_idle_exit); } while (read_seqcount_retry(&idle->seqcount, seq)); - idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0; + in_idle = 0; + now = get_tod_clock(); + if (idle_enter) { + if (idle_exit) { + in_idle = idle_exit - idle_enter; + } else if (now > idle_enter) { + in_idle = now - idle_enter; + } + } + idle_time += in_idle; return sprintf(buf, "%llu\n", idle_time >> 12); } DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL); @@ -88,17 +96,24 @@ DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL); u64 arch_cpu_idle_time(int cpu) { struct s390_idle_data *idle = &per_cpu(s390_idle, cpu); - unsigned long long now, idle_enter, idle_exit; + unsigned long long now, idle_enter, idle_exit, in_idle; unsigned int seq; do { - now = get_tod_clock(); seq = read_seqcount_begin(&idle->seqcount); idle_enter = READ_ONCE(idle->clock_idle_enter); idle_exit = READ_ONCE(idle->clock_idle_exit); } while (read_seqcount_retry(&idle->seqcount, seq)); - - return cputime_to_nsecs(idle_enter ? ((idle_exit ?: now) - idle_enter) : 0); + in_idle = 0; + now = get_tod_clock(); + if (idle_enter) { + if (idle_exit) { + in_idle = idle_exit - idle_enter; + } else if (now > idle_enter) { + in_idle = now - idle_enter; + } + } + return cputime_to_nsecs(in_idle); } void arch_cpu_idle_enter(void) -- GitLab From 41591a51f00d2dc7bb9dc6e9bedf56c5cf6f2392 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 31 Oct 2019 13:53:41 +0300 Subject: [PATCH 959/993] iocost: don't nest spin_lock_irq in ioc_weight_write() This code causes a static analysis warning: block/blk-iocost.c:2113 ioc_weight_write() error: double lock 'irq' We disable IRQs in blkg_conf_prep() and re-enable them in blkg_conf_finish(). IRQ disable/enable should not be nested because that means the IRQs will be enabled at the first unlock instead of the second one. Fixes: 7caa47151ab2 ("blkcg: implement blk-iocost") Acked-by: Tejun Heo Signed-off-by: Dan Carpenter Signed-off-by: Jens Axboe --- block/blk-iocost.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block/blk-iocost.c b/block/blk-iocost.c index 2a3db80c1dce..a7ed434eae03 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -2110,10 +2110,10 @@ static ssize_t ioc_weight_write(struct kernfs_open_file *of, char *buf, goto einval; } - spin_lock_irq(&iocg->ioc->lock); + spin_lock(&iocg->ioc->lock); iocg->cfg_weight = v; weight_updated(iocg); - spin_unlock_irq(&iocg->ioc->lock); + spin_unlock(&iocg->ioc->lock); blkg_conf_finish(&ctx); return nbytes; -- GitLab From dd88a4a1d5785c2fa9115de5e461491e0b6dcc8e Mon Sep 17 00:00:00 2001 From: Alistair Delva Date: Thu, 31 Oct 2019 10:23:42 -0700 Subject: [PATCH 960/993] ANDROID: Fix x86_64 allmodconfig build The kernel is now being linked with ld.ldd, but this linker will discard the __memcat_p symbol, even if it is exported, if there are no in-kernel users. Since the STM driver and test code can be built as a module, they will fail at modpost time. While the solution to this bug is still being discussed, keep the allmodconfig build going by suppressing these options. Bug: 140224784 Link: https://github.com/ClangBuiltLinux/linux/issues/515 Test: make -j64 ARCH=x86_64 allmodconfig + tweaks Change-Id: I2942e4b3443180e6bff9820a7c5174c03347ae8a Signed-off-by: Alistair Delva --- build.config.allmodconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build.config.allmodconfig b/build.config.allmodconfig index 854a8f8aa3f2..f91c03b85737 100644 --- a/build.config.allmodconfig +++ b/build.config.allmodconfig @@ -9,7 +9,10 @@ function update_config() { -d TEST_KMOD \ -d XFS_FS \ -d CPU_BIG_ENDIAN \ - -d KVM_INTEL + -d KVM_INTEL \ + -d STM \ + -d TEST_MEMCAT_P \ + (cd ${OUT_DIR} && \ make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig) } -- GitLab From a3b88509ac9839caac31f067321eba7b1a491c7a Mon Sep 17 00:00:00 2001 From: Alistair Delva Date: Thu, 31 Oct 2019 10:40:13 -0700 Subject: [PATCH 961/993] ANDROID: Remove KVM_INTEL allmodconfig workaround This was blocked on upgrading clang for asm goto support, we can re-enable this working driver. Bug: 140224784 Change-Id: I715c3611b2aff2b8a898ae85e45cce1dc149deef Signed-off-by: Alistair Delva --- build.config.allmodconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/build.config.allmodconfig b/build.config.allmodconfig index f91c03b85737..b39bc1b877c7 100644 --- a/build.config.allmodconfig +++ b/build.config.allmodconfig @@ -9,7 +9,6 @@ function update_config() { -d TEST_KMOD \ -d XFS_FS \ -d CPU_BIG_ENDIAN \ - -d KVM_INTEL \ -d STM \ -d TEST_MEMCAT_P \ -- GitLab From d8eca64eec7103ab1fbabc0a187dbf6acfb2af93 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 31 Oct 2019 11:07:13 +0200 Subject: [PATCH 962/993] usb: dwc3: gadget: fix race when disabling ep with cancelled xfers When disabling an endpoint which has cancelled requests, we should make sure to giveback requests that are currently pending in the cancelled list, otherwise we may fall into a situation where command completion interrupt fires after endpoint has been disabled, therefore causing a splat. Fixes: fec9095bdef4 "usb: dwc3: gadget: remove wait_end_transfer" Reported-by: Roger Quadros Signed-off-by: Felipe Balbi Link: https://lore.kernel.org/r/20191031090713.1452818-1-felipe.balbi@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/gadget.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 86dc1db788a9..a9aba716bf80 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -707,6 +707,12 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep) dwc3_gadget_giveback(dep, req, -ESHUTDOWN); } + + while (!list_empty(&dep->cancelled_list)) { + req = next_request(&dep->cancelled_list); + + dwc3_gadget_giveback(dep, req, -ESHUTDOWN); + } } /** -- GitLab From f9c32435ab7221d1d6cb35738fa85a2da012b23e Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 31 Oct 2019 12:13:46 +0000 Subject: [PATCH 963/993] rxrpc: Fix handling of last subpacket of jumbo packet When rxrpc_recvmsg_data() sets the return value to 1 because it's drained all the data for the last packet, it checks the last-packet flag on the whole packet - but this is wrong, since the last-packet flag is only set on the final subpacket of the last jumbo packet. This means that a call that receives its last packet in a jumbo packet won't complete properly. Fix this by having rxrpc_locate_data() determine the last-packet state of the subpacket it's looking at and passing that back to the caller rather than having the caller look in the packet header. The caller then needs to cache this in the rxrpc_call struct as rxrpc_locate_data() isn't then called again for this packet. Fixes: 248f219cb8bc ("rxrpc: Rewrite the data and ack handling code") Fixes: e2de6c404898 ("rxrpc: Use info in skbuff instead of reparsing a jumbo packet") Signed-off-by: David Howells Signed-off-by: David S. Miller --- net/rxrpc/ar-internal.h | 1 + net/rxrpc/recvmsg.c | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index ecc17dabec8f..7c7d10f2e0c1 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -601,6 +601,7 @@ struct rxrpc_call { int debug_id; /* debug ID for printks */ unsigned short rx_pkt_offset; /* Current recvmsg packet offset */ unsigned short rx_pkt_len; /* Current recvmsg packet len */ + bool rx_pkt_last; /* Current recvmsg packet is last */ /* Rx/Tx circular buffer, depending on phase. * diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c index a4090797c9b2..8578c39ec839 100644 --- a/net/rxrpc/recvmsg.c +++ b/net/rxrpc/recvmsg.c @@ -267,11 +267,13 @@ static int rxrpc_verify_packet(struct rxrpc_call *call, struct sk_buff *skb, */ static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb, u8 *_annotation, - unsigned int *_offset, unsigned int *_len) + unsigned int *_offset, unsigned int *_len, + bool *_last) { struct rxrpc_skb_priv *sp = rxrpc_skb(skb); unsigned int offset = sizeof(struct rxrpc_wire_header); unsigned int len; + bool last = false; int ret; u8 annotation = *_annotation; u8 subpacket = annotation & RXRPC_RX_ANNO_SUBPACKET; @@ -281,6 +283,8 @@ static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb, len = skb->len - offset; if (subpacket < sp->nr_subpackets - 1) len = RXRPC_JUMBO_DATALEN; + else if (sp->rx_flags & RXRPC_SKB_INCL_LAST) + last = true; if (!(annotation & RXRPC_RX_ANNO_VERIFIED)) { ret = rxrpc_verify_packet(call, skb, annotation, offset, len); @@ -291,6 +295,7 @@ static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb, *_offset = offset; *_len = len; + *_last = last; call->security->locate_data(call, skb, _offset, _len); return 0; } @@ -309,7 +314,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, rxrpc_serial_t serial; rxrpc_seq_t hard_ack, top, seq; size_t remain; - bool last; + bool rx_pkt_last; unsigned int rx_pkt_offset, rx_pkt_len; int ix, copy, ret = -EAGAIN, ret2; @@ -319,6 +324,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, rx_pkt_offset = call->rx_pkt_offset; rx_pkt_len = call->rx_pkt_len; + rx_pkt_last = call->rx_pkt_last; if (call->state >= RXRPC_CALL_SERVER_ACK_REQUEST) { seq = call->rx_hard_ack; @@ -329,6 +335,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, /* Barriers against rxrpc_input_data(). */ hard_ack = call->rx_hard_ack; seq = hard_ack + 1; + while (top = smp_load_acquire(&call->rx_top), before_eq(seq, top) ) { @@ -356,7 +363,8 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, if (rx_pkt_offset == 0) { ret2 = rxrpc_locate_data(call, skb, &call->rxtx_annotations[ix], - &rx_pkt_offset, &rx_pkt_len); + &rx_pkt_offset, &rx_pkt_len, + &rx_pkt_last); trace_rxrpc_recvmsg(call, rxrpc_recvmsg_next, seq, rx_pkt_offset, rx_pkt_len, ret2); if (ret2 < 0) { @@ -396,13 +404,12 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, } /* The whole packet has been transferred. */ - last = sp->hdr.flags & RXRPC_LAST_PACKET; if (!(flags & MSG_PEEK)) rxrpc_rotate_rx_window(call); rx_pkt_offset = 0; rx_pkt_len = 0; - if (last) { + if (rx_pkt_last) { ASSERTCMP(seq, ==, READ_ONCE(call->rx_top)); ret = 1; goto out; @@ -415,6 +422,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call, if (!(flags & MSG_PEEK)) { call->rx_pkt_offset = rx_pkt_offset; call->rx_pkt_len = rx_pkt_len; + call->rx_pkt_last = rx_pkt_last; } done: trace_rxrpc_recvmsg(call, rxrpc_recvmsg_data_return, seq, -- GitLab From 6d6f0383b697f004c65823c2b64240912f18515d Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Thu, 31 Oct 2019 18:20:30 +0200 Subject: [PATCH 964/993] netdevsim: Fix use-after-free during device dismantle Commit da58f90f11f5 ("netdevsim: Add devlink-trap support") added delayed work to netdevsim that periodically iterates over the registered netdevsim ports and reports various packet traps via devlink. While the delayed work takes the 'port_list_lock' mutex to protect against concurrent addition / deletion of ports, during device creation / dismantle ports are added / deleted without this lock, which can result in a use-after-free [1]. Fix this by making sure that the ports list is always modified under the lock. [1] [ 59.205543] ================================================================== [ 59.207748] BUG: KASAN: use-after-free in nsim_dev_trap_report_work+0xa67/0xad0 [ 59.210247] Read of size 8 at addr ffff8883cbdd3398 by task kworker/3:1/38 [ 59.212584] [ 59.213148] CPU: 3 PID: 38 Comm: kworker/3:1 Not tainted 5.4.0-rc3-custom-16119-ge6abb5f0261e #2013 [ 59.215896] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20180724_192412-buildhw-07.phx2.fedoraproject.org-1.fc29 04/01/2014 [ 59.218384] Workqueue: events nsim_dev_trap_report_work [ 59.219428] Call Trace: [ 59.219924] dump_stack+0xa9/0x10e [ 59.220623] print_address_description.constprop.4+0x21/0x340 [ 59.221976] ? vprintk_func+0x66/0x240 [ 59.222752] __kasan_report.cold.8+0x78/0x91 [ 59.223602] ? nsim_dev_trap_report_work+0xa67/0xad0 [ 59.224603] kasan_report+0xe/0x20 [ 59.225296] nsim_dev_trap_report_work+0xa67/0xad0 [ 59.226435] ? rcu_read_lock_sched_held+0xaf/0xe0 [ 59.227512] ? trace_event_raw_event_rcu_quiescent_state_report+0x360/0x360 [ 59.228851] process_one_work+0x98f/0x1760 [ 59.229684] ? pwq_dec_nr_in_flight+0x330/0x330 [ 59.230656] worker_thread+0x91/0xc40 [ 59.231587] ? process_one_work+0x1760/0x1760 [ 59.232451] kthread+0x34a/0x410 [ 59.233104] ? __kthread_queue_delayed_work+0x240/0x240 [ 59.234141] ret_from_fork+0x3a/0x50 [ 59.234982] [ 59.235371] Allocated by task 187: [ 59.236189] save_stack+0x19/0x80 [ 59.236853] __kasan_kmalloc.constprop.5+0xc1/0xd0 [ 59.237822] kmem_cache_alloc_trace+0x14c/0x380 [ 59.238769] __nsim_dev_port_add+0xaf/0x5c0 [ 59.239627] nsim_dev_probe+0x4fc/0x1140 [ 59.240550] really_probe+0x264/0xc00 [ 59.241418] driver_probe_device+0x208/0x2e0 [ 59.242255] __device_attach_driver+0x215/0x2d0 [ 59.243150] bus_for_each_drv+0x154/0x1d0 [ 59.243944] __device_attach+0x1ba/0x2b0 [ 59.244923] bus_probe_device+0x1dd/0x290 [ 59.245805] device_add+0xbac/0x1550 [ 59.246528] new_device_store+0x1f4/0x400 [ 59.247306] bus_attr_store+0x7b/0xa0 [ 59.248047] sysfs_kf_write+0x10f/0x170 [ 59.248941] kernfs_fop_write+0x283/0x430 [ 59.249843] __vfs_write+0x81/0x100 [ 59.250546] vfs_write+0x1ce/0x510 [ 59.251190] ksys_write+0x104/0x200 [ 59.251873] do_syscall_64+0xa4/0x4e0 [ 59.252642] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 59.253837] [ 59.254203] Freed by task 187: [ 59.254811] save_stack+0x19/0x80 [ 59.255463] __kasan_slab_free+0x125/0x170 [ 59.256265] kfree+0x100/0x440 [ 59.256870] nsim_dev_remove+0x98/0x100 [ 59.257651] nsim_bus_remove+0x16/0x20 [ 59.258382] device_release_driver_internal+0x20b/0x4d0 [ 59.259588] bus_remove_device+0x2e9/0x5a0 [ 59.260551] device_del+0x410/0xad0 [ 59.263777] device_unregister+0x26/0xc0 [ 59.264616] nsim_bus_dev_del+0x16/0x60 [ 59.265381] del_device_store+0x2d6/0x3c0 [ 59.266295] bus_attr_store+0x7b/0xa0 [ 59.267192] sysfs_kf_write+0x10f/0x170 [ 59.267960] kernfs_fop_write+0x283/0x430 [ 59.268800] __vfs_write+0x81/0x100 [ 59.269551] vfs_write+0x1ce/0x510 [ 59.270252] ksys_write+0x104/0x200 [ 59.270910] do_syscall_64+0xa4/0x4e0 [ 59.271680] entry_SYSCALL_64_after_hwframe+0x49/0xbe [ 59.272812] [ 59.273211] The buggy address belongs to the object at ffff8883cbdd3200 [ 59.273211] which belongs to the cache kmalloc-512 of size 512 [ 59.275838] The buggy address is located 408 bytes inside of [ 59.275838] 512-byte region [ffff8883cbdd3200, ffff8883cbdd3400) [ 59.278151] The buggy address belongs to the page: [ 59.279215] page:ffffea000f2f7400 refcount:1 mapcount:0 mapping:ffff8883ecc0ce00 index:0x0 compound_mapcount: 0 [ 59.281449] flags: 0x200000000010200(slab|head) [ 59.282356] raw: 0200000000010200 ffffea000f2f3a08 ffffea000f2fd608 ffff8883ecc0ce00 [ 59.283949] raw: 0000000000000000 0000000000150015 00000001ffffffff 0000000000000000 [ 59.285608] page dumped because: kasan: bad access detected [ 59.286981] [ 59.287337] Memory state around the buggy address: [ 59.288310] ffff8883cbdd3280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 59.289763] ffff8883cbdd3300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 59.291452] >ffff8883cbdd3380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 59.292945] ^ [ 59.293815] ffff8883cbdd3400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 59.295220] ffff8883cbdd3480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 59.296872] ================================================================== Fixes: da58f90f11f5 ("netdevsim: Add devlink-trap support") Signed-off-by: Ido Schimmel Reported-by: syzbot+9ed8f68ab30761f3678e@syzkaller.appspotmail.com Acked-by: Jakub Kicinski Signed-off-by: David S. Miller --- drivers/net/netdevsim/dev.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c index 56576d4f34a5..54ca6681ba31 100644 --- a/drivers/net/netdevsim/dev.c +++ b/drivers/net/netdevsim/dev.c @@ -806,9 +806,11 @@ static void nsim_dev_port_del_all(struct nsim_dev *nsim_dev) { struct nsim_dev_port *nsim_dev_port, *tmp; + mutex_lock(&nsim_dev->port_list_lock); list_for_each_entry_safe(nsim_dev_port, tmp, &nsim_dev->port_list, list) __nsim_dev_port_del(nsim_dev_port); + mutex_unlock(&nsim_dev->port_list_lock); } int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev) @@ -822,14 +824,17 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev) return PTR_ERR(nsim_dev); dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev); + mutex_lock(&nsim_dev->port_list_lock); for (i = 0; i < nsim_bus_dev->port_count; i++) { err = __nsim_dev_port_add(nsim_dev, i); if (err) goto err_port_del_all; } + mutex_unlock(&nsim_dev->port_list_lock); return 0; err_port_del_all: + mutex_unlock(&nsim_dev->port_list_lock); nsim_dev_port_del_all(nsim_dev); nsim_dev_destroy(nsim_dev); return err; -- GitLab From 19f92a030ca6d772ab44b22ee6a01378a8cb32d4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 30 Oct 2019 09:36:20 -0700 Subject: [PATCH 965/993] net: increase SOMAXCONN to 4096 SOMAXCONN is /proc/sys/net/core/somaxconn default value. It has been defined as 128 more than 20 years ago. Since it caps the listen() backlog values, the very small value has caused numerous problems over the years, and many people had to raise it on their hosts after beeing hit by problems. Google has been using 1024 for at least 15 years, and we increased this to 4096 after TCP listener rework has been completed, more than 4 years ago. We got no complain of this change breaking any legacy application. Many applications indeed setup a TCP listener with listen(fd, -1); meaning they let the system select the backlog. Raising SOMAXCONN lowers chance of the port being unavailable under even small SYNFLOOD attack, and reduces possibilities of side channel vulnerabilities. Signed-off-by: Eric Dumazet Cc: Willy Tarreau Cc: Yue Cao Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 4 ++-- include/linux/socket.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 49e95f438ed7..0e6653471c0e 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -207,8 +207,8 @@ TCP variables: somaxconn - INTEGER Limit of socket listen() backlog, known in userspace as SOMAXCONN. - Defaults to 128. See also tcp_max_syn_backlog for additional tuning - for TCP sockets. + Defaults to 4096. (Was 128 before linux-5.4) + See also tcp_max_syn_backlog for additional tuning for TCP sockets. tcp_abort_on_overflow - BOOLEAN If listening service is too slow to accept new connections, diff --git a/include/linux/socket.h b/include/linux/socket.h index fc0bed59fc84..4049d9755cf1 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -263,7 +263,7 @@ struct ucred { #define PF_MAX AF_MAX /* Maximum queue length specifiable by listen. */ -#define SOMAXCONN 128 +#define SOMAXCONN 4096 /* Flags we can use with send/ and recv. Added those for 1003.1g not all are supported yet -- GitLab From 623d0c2db02043e43b698fdd8de1bd398b8e7b37 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 30 Oct 2019 10:05:46 -0700 Subject: [PATCH 966/993] tcp: increase tcp_max_syn_backlog max value tcp_max_syn_backlog default value depends on memory size and TCP ehash size. Before this patch, the max value was 2048 [1], which is considered too small nowadays. Increase it to 4096 to match the recent SOMAXCONN change. [1] This is with TCP ehash size being capped to 524288 buckets. Signed-off-by: Eric Dumazet Cc: Willy Tarreau Cc: Yue Cao Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 7 +++++-- net/ipv4/tcp_ipv4.c | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 0e6653471c0e..8d4ad1d1ae26 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -408,11 +408,14 @@ tcp_max_orphans - INTEGER up to ~64K of unswappable memory. tcp_max_syn_backlog - INTEGER - Maximal number of remembered connection requests, which have not - received an acknowledgment from connecting client. + Maximal number of remembered connection requests (SYN_RECV), + which have not received an acknowledgment from connecting client. + This is a per-listener limit. The minimal value is 128 for low memory machines, and it will increase in proportion to the memory of machine. If server suffers from overload, try increasing this number. + Remember to also check /proc/sys/net/core/somaxconn + A SYN_RECV request socket consumes about 304 bytes of memory. tcp_max_tw_buckets - INTEGER Maximal number of timewait sockets held by system simultaneously. diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 6be568334848..b74192695955 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2681,7 +2681,7 @@ static int __net_init tcp_sk_init(struct net *net) net->ipv4.tcp_death_row.sysctl_max_tw_buckets = cnt / 2; net->ipv4.tcp_death_row.hashinfo = &tcp_hashinfo; - net->ipv4.sysctl_max_syn_backlog = max(128, cnt / 256); + net->ipv4.sysctl_max_syn_backlog = max(128, cnt / 128); net->ipv4.sysctl_tcp_sack = 1; net->ipv4.sysctl_tcp_window_scaling = 1; net->ipv4.sysctl_tcp_timestamps = 1; -- GitLab From 94bc1e522b32c866d85b5af0ede55026b585ae73 Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Thu, 22 Aug 2019 14:33:18 -0400 Subject: [PATCH 967/993] igb/igc: Don't warn on fatal read failures when the device is removed Fatal read errors are worth warning about, unless of course the device was just unplugged from the machine - something that's a rather normal occurrence when the igb/igc adapter is located on a Thunderbolt dock. So, let's only WARN() if there's a fatal read error while the device is still present. This fixes the following WARN splat that's been appearing whenever I unplug my Caldigit TS3 Thunderbolt dock from my laptop: igb 0000:09:00.0 enp9s0: PCIe link lost ------------[ cut here ]------------ igb: Failed to read reg 0x18! WARNING: CPU: 7 PID: 516 at drivers/net/ethernet/intel/igb/igb_main.c:756 igb_rd32+0x57/0x6a [igb] Modules linked in: igb dca thunderbolt fuse vfat fat elan_i2c mei_wdt mei_hdcp i915 wmi_bmof intel_wmi_thunderbolt iTCO_wdt iTCO_vendor_support x86_pkg_temp_thermal intel_powerclamp joydev coretemp crct10dif_pclmul crc32_pclmul i2c_algo_bit ghash_clmulni_intel intel_cstate drm_kms_helper intel_uncore syscopyarea sysfillrect sysimgblt fb_sys_fops intel_rapl_perf intel_xhci_usb_role_switch mei_me drm roles idma64 i2c_i801 ucsi_acpi typec_ucsi mei intel_lpss_pci processor_thermal_device typec intel_pch_thermal intel_soc_dts_iosf intel_lpss int3403_thermal thinkpad_acpi wmi int340x_thermal_zone ledtrig_audio int3400_thermal acpi_thermal_rel acpi_pad video pcc_cpufreq ip_tables serio_raw nvme nvme_core crc32c_intel uas usb_storage e1000e i2c_dev CPU: 7 PID: 516 Comm: kworker/u16:3 Not tainted 5.2.0-rc1Lyude-Test+ #14 Hardware name: LENOVO 20L8S2N800/20L8S2N800, BIOS N22ET35W (1.12 ) 04/09/2018 Workqueue: kacpi_hotplug acpi_hotplug_work_fn RIP: 0010:igb_rd32+0x57/0x6a [igb] Code: 87 b8 fc ff ff 48 c7 47 08 00 00 00 00 48 c7 c6 33 42 9b c0 4c 89 c7 e8 47 45 cd dc 89 ee 48 c7 c7 43 42 9b c0 e8 c1 94 71 dc <0f> 0b eb 08 8b 00 ff c0 75 b0 eb c8 44 89 e0 5d 41 5c c3 0f 1f 44 RSP: 0018:ffffba5801cf7c48 EFLAGS: 00010286 RAX: 0000000000000000 RBX: ffff9e7956608840 RCX: 0000000000000007 RDX: 0000000000000000 RSI: ffffba5801cf7b24 RDI: ffff9e795e3d6a00 RBP: 0000000000000018 R08: 000000009dec4a01 R09: ffffffff9e61018f R10: 0000000000000000 R11: ffffba5801cf7ae5 R12: 00000000ffffffff R13: ffff9e7956608840 R14: ffff9e795a6f10b0 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff9e795e3c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000564317bc4088 CR3: 000000010e00a006 CR4: 00000000003606e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: igb_release_hw_control+0x1a/0x30 [igb] igb_remove+0xc5/0x14b [igb] pci_device_remove+0x3b/0x93 device_release_driver_internal+0xd7/0x17e pci_stop_bus_device+0x36/0x75 pci_stop_bus_device+0x66/0x75 pci_stop_bus_device+0x66/0x75 pci_stop_and_remove_bus_device+0xf/0x19 trim_stale_devices+0xc5/0x13a ? __pm_runtime_resume+0x6e/0x7b trim_stale_devices+0x103/0x13a ? __pm_runtime_resume+0x6e/0x7b trim_stale_devices+0x103/0x13a acpiphp_check_bridge+0xd8/0xf5 acpiphp_hotplug_notify+0xf7/0x14b ? acpiphp_check_bridge+0xf5/0xf5 acpi_device_hotplug+0x357/0x3b5 acpi_hotplug_work_fn+0x1a/0x23 process_one_work+0x1a7/0x296 worker_thread+0x1a8/0x24c ? process_scheduled_works+0x2c/0x2c kthread+0xe9/0xee ? kthread_destroy_worker+0x41/0x41 ret_from_fork+0x35/0x40 ---[ end trace 252bf10352c63d22 ]--- Signed-off-by: Lyude Paul Fixes: 47e16692b26b ("igb/igc: warn when fatal read failure happens") Acked-by: Sasha Neftin Tested-by: Aaron Brown Acked-by: Feng Tang Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb_main.c | 3 ++- drivers/net/ethernet/intel/igc/igc_main.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 105b0624081a..31b9e02875cc 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -753,7 +753,8 @@ u32 igb_rd32(struct e1000_hw *hw, u32 reg) struct net_device *netdev = igb->netdev; hw->hw_addr = NULL; netdev_err(netdev, "PCIe link lost\n"); - WARN(1, "igb: Failed to read reg 0x%x!\n", reg); + WARN(pci_device_is_present(igb->pdev), + "igb: Failed to read reg 0x%x!\n", reg); } return value; diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 63b62d74f961..8e424dfab12e 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -4047,7 +4047,8 @@ u32 igc_rd32(struct igc_hw *hw, u32 reg) hw->hw_addr = NULL; netif_device_detach(netdev); netdev_err(netdev, "PCIe link lost, device now detached\n"); - WARN(1, "igc: Failed to read reg 0x%x!\n", reg); + WARN(pci_device_is_present(igc->pdev), + "igc: Failed to read reg 0x%x!\n", reg); } return value; -- GitLab From fb2308ba16bf1fd2cc3635172381e265fbfcb76d Mon Sep 17 00:00:00 2001 From: Manfred Rudigier Date: Thu, 15 Aug 2019 13:55:19 -0700 Subject: [PATCH 968/993] igb: Enable media autosense for the i350. This patch enables the hardware feature "Media Auto Sense" also on the i350. It works in the same way as on the 82850 devices. Hardware designs using dual PHYs (fiber/copper) can enable this feature by setting the MAS enable bits in the NVM_COMPAT register (0x03) in the EEPROM. Signed-off-by: Manfred Rudigier Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/e1000_82575.c | 2 +- drivers/net/ethernet/intel/igb/igb_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 3ec2ce0725d5..8a6ef3514129 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -466,7 +466,7 @@ static s32 igb_init_mac_params_82575(struct e1000_hw *hw) ? igb_setup_copper_link_82575 : igb_setup_serdes_link_82575; - if (mac->type == e1000_82580) { + if (mac->type == e1000_82580 || mac->type == e1000_i350) { switch (hw->device_id) { /* feature not supported on these id's */ case E1000_DEV_ID_DH89XXCC_SGMII: diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 31b9e02875cc..17a961c3d6e4 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -2371,7 +2371,7 @@ void igb_reset(struct igb_adapter *adapter) adapter->ei.get_invariants(hw); adapter->flags &= ~IGB_FLAG_MEDIA_RESET; } - if ((mac->type == e1000_82575) && + if ((mac->type == e1000_82575 || mac->type == e1000_i350) && (adapter->flags & IGB_FLAG_MAS_ENABLE)) { igb_enable_mas(adapter); } -- GitLab From bfc97f9f199cb041cf897af3af096540948cc705 Mon Sep 17 00:00:00 2001 From: Doug Berger Date: Thu, 31 Oct 2019 14:47:23 -0700 Subject: [PATCH 969/993] arm64: apply ARM64_ERRATUM_845719 workaround for Brahma-B53 core The Broadcom Brahma-B53 core is susceptible to the issue described by ARM64_ERRATUM_845719 so this commit enables the workaround to be applied when executing on that core. Since there are now multiple entries to match, we must convert the existing ARM64_ERRATUM_845719 into an erratum list. Signed-off-by: Doug Berger Signed-off-by: Florian Fainelli Signed-off-by: Will Deacon --- Documentation/arm64/silicon-errata.rst | 3 +++ arch/arm64/include/asm/cputype.h | 2 ++ arch/arm64/kernel/cpu_errata.c | 13 +++++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index 25d62272de73..189a1768e26a 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -91,6 +91,9 @@ stable kernels. | ARM | MMU-500 | #841119,826419 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ +| Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 | ++----------------+-----------------+-----------------+-----------------------------+ ++----------------+-----------------+-----------------+-----------------------------+ | Cavium | ThunderX ITS | #22375,24313 | CAVIUM_ERRATUM_22375 | +----------------+-----------------+-----------------+-----------------------------+ | Cavium | ThunderX ITS | #23144 | CAVIUM_ERRATUM_23144 | diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index b1454d117cd2..aca07c2f6e6e 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -79,6 +79,7 @@ #define CAVIUM_CPU_PART_THUNDERX_83XX 0x0A3 #define CAVIUM_CPU_PART_THUNDERX2 0x0AF +#define BRCM_CPU_PART_BRAHMA_B53 0x100 #define BRCM_CPU_PART_VULCAN 0x516 #define QCOM_CPU_PART_FALKOR_V1 0x800 @@ -105,6 +106,7 @@ #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) #define MIDR_CAVIUM_THUNDERX2 MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX2) +#define MIDR_BRAHMA_B53 MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_BRAHMA_B53) #define MIDR_BRCM_VULCAN MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_VULCAN) #define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1) #define MIDR_QCOM_FALKOR MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR) diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 091e3ec0f420..b5eeba7f5d84 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -743,6 +743,16 @@ static const struct midr_range erratum_1418040_list[] = { }; #endif +#ifdef CONFIG_ARM64_ERRATUM_845719 +static const struct midr_range erratum_845719_list[] = { + /* Cortex-A53 r0p[01234] */ + MIDR_REV_RANGE(MIDR_CORTEX_A53, 0, 0, 4), + /* Brahma-B53 r0p[0] */ + MIDR_REV(MIDR_BRAHMA_B53, 0, 0), + {}, +}; +#endif + const struct arm64_cpu_capabilities arm64_errata[] = { #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE { @@ -783,10 +793,9 @@ const struct arm64_cpu_capabilities arm64_errata[] = { #endif #ifdef CONFIG_ARM64_ERRATUM_845719 { - /* Cortex-A53 r0p[01234] */ .desc = "ARM erratum 845719", .capability = ARM64_WORKAROUND_845719, - ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A53, 0, 0, 4), + ERRATA_MIDR_RANGE_LIST(erratum_845719_list), }, #endif #ifdef CONFIG_CAVIUM_ERRATUM_23154 -- GitLab From e059770cb1cdfbcbe3f1748f76005861cc79dd1a Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 31 Oct 2019 14:47:24 -0700 Subject: [PATCH 970/993] arm64: Brahma-B53 is SSB and spectre v2 safe Add the Brahma-B53 CPU (all versions) to the whitelists of CPUs for the SSB and spectre v2 mitigations. Signed-off-by: Florian Fainelli Signed-off-by: Will Deacon --- arch/arm64/kernel/cpu_errata.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index b5eeba7f5d84..a1983c0a872b 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -489,6 +489,7 @@ static const struct midr_range arm64_ssb_cpus[] = { MIDR_ALL_VERSIONS(MIDR_CORTEX_A35), MIDR_ALL_VERSIONS(MIDR_CORTEX_A53), MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), + MIDR_ALL_VERSIONS(MIDR_BRAHMA_B53), {}, }; @@ -573,6 +574,7 @@ static const struct midr_range spectre_v2_safe_list[] = { MIDR_ALL_VERSIONS(MIDR_CORTEX_A35), MIDR_ALL_VERSIONS(MIDR_CORTEX_A53), MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), + MIDR_ALL_VERSIONS(MIDR_BRAHMA_B53), { /* sentinel */ } }; -- GitLab From 1cf45b8fdbb87040e1d1bd793891089f4678aa41 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 31 Oct 2019 14:47:25 -0700 Subject: [PATCH 971/993] arm64: apply ARM64_ERRATUM_843419 workaround for Brahma-B53 core The Broadcom Brahma-B53 core is susceptible to the issue described by ARM64_ERRATUM_843419 so this commit enables the workaround to be applied when executing on that core. Since there are now multiple entries to match, we must convert the existing ARM64_ERRATUM_843419 into an erratum list and use cpucap_multi_entry_cap_matches to match our entries. Signed-off-by: Florian Fainelli Signed-off-by: Will Deacon --- Documentation/arm64/silicon-errata.rst | 2 ++ arch/arm64/kernel/cpu_errata.c | 23 ++++++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index 189a1768e26a..5a09661330fc 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -93,6 +93,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_845719 | +----------------+-----------------+-----------------+-----------------------------+ +| Broadcom | Brahma-B53 | N/A | ARM64_ERRATUM_843419 | ++----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Cavium | ThunderX ITS | #22375,24313 | CAVIUM_ERRATUM_22375 | +----------------+-----------------+-----------------+-----------------------------+ diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index a1983c0a872b..93f34b4eca25 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -755,6 +755,23 @@ static const struct midr_range erratum_845719_list[] = { }; #endif +#ifdef CONFIG_ARM64_ERRATUM_843419 +static const struct arm64_cpu_capabilities erratum_843419_list[] = { + { + /* Cortex-A53 r0p[01234] */ + .matches = is_affected_midr_range, + ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A53, 0, 0, 4), + MIDR_FIXED(0x4, BIT(8)), + }, + { + /* Brahma-B53 r0p[0] */ + .matches = is_affected_midr_range, + ERRATA_MIDR_REV(MIDR_BRAHMA_B53, 0, 0), + }, + {}, +}; +#endif + const struct arm64_cpu_capabilities arm64_errata[] = { #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE { @@ -786,11 +803,11 @@ const struct arm64_cpu_capabilities arm64_errata[] = { #endif #ifdef CONFIG_ARM64_ERRATUM_843419 { - /* Cortex-A53 r0p[01234] */ .desc = "ARM erratum 843419", .capability = ARM64_WORKAROUND_843419, - ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A53, 0, 0, 4), - MIDR_FIXED(0x4, BIT(8)), + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + .matches = cpucap_multi_entry_cap_matches, + .match_list = erratum_843419_list, }, #endif #ifdef CONFIG_ARM64_ERRATUM_845719 -- GitLab From be3df3dd4c70ee020587a943a31b98a0fb4b6424 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 31 Oct 2019 18:40:32 -0400 Subject: [PATCH 972/993] NFSv4: Don't allow a cached open with a revoked delegation If the delegation is marked as being revoked, we must not use it for cached opens. Fixes: 869f9dfa4d6d ("NFSv4: Fix races between nfs_remove_bad_delegation() and delegation return") Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- fs/nfs/delegation.c | 10 ++++++++++ fs/nfs/delegation.h | 1 + fs/nfs/nfs4proc.c | 7 ++----- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 071b90a45933..ccdfb5f98f35 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -53,6 +53,16 @@ nfs4_is_valid_delegation(const struct nfs_delegation *delegation, return false; } +struct nfs_delegation *nfs4_get_valid_delegation(const struct inode *inode) +{ + struct nfs_delegation *delegation; + + delegation = rcu_dereference(NFS_I(inode)->delegation); + if (nfs4_is_valid_delegation(delegation, 0)) + return delegation; + return NULL; +} + static int nfs4_do_check_delegation(struct inode *inode, fmode_t flags, bool mark) { diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h index 9eb87ae4c982..8b14d441e699 100644 --- a/fs/nfs/delegation.h +++ b/fs/nfs/delegation.h @@ -68,6 +68,7 @@ int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags, nfs4_stateid *dst, const struct cred **cred); bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode); +struct nfs_delegation *nfs4_get_valid_delegation(const struct inode *inode); void nfs_mark_delegation_referenced(struct nfs_delegation *delegation); int nfs4_have_delegation(struct inode *inode, fmode_t flags); int nfs4_check_delegation(struct inode *inode, fmode_t flags); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index ab8ca20fd579..caacf5e7f5e1 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1440,8 +1440,6 @@ static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode, return 0; if ((delegation->type & fmode) != fmode) return 0; - if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) - return 0; switch (claim) { case NFS4_OPEN_CLAIM_NULL: case NFS4_OPEN_CLAIM_FH: @@ -1810,7 +1808,6 @@ static void nfs4_return_incompatible_delegation(struct inode *inode, fmode_t fmo static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) { struct nfs4_state *state = opendata->state; - struct nfs_inode *nfsi = NFS_I(state->inode); struct nfs_delegation *delegation; int open_mode = opendata->o_arg.open_flags; fmode_t fmode = opendata->o_arg.fmode; @@ -1827,7 +1824,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) } spin_unlock(&state->owner->so_lock); rcu_read_lock(); - delegation = rcu_dereference(nfsi->delegation); + delegation = nfs4_get_valid_delegation(state->inode); if (!can_open_delegated(delegation, fmode, claim)) { rcu_read_unlock(); break; @@ -2371,7 +2368,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) data->o_arg.open_flags, claim)) goto out_no_action; rcu_read_lock(); - delegation = rcu_dereference(NFS_I(data->state->inode)->delegation); + delegation = nfs4_get_valid_delegation(data->state->inode); if (can_open_delegated(delegation, data->o_arg.fmode, claim)) goto unlock_no_action; rcu_read_unlock(); -- GitLab From 79cc55422ce99be5964bde208ba8557174720893 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 31 Oct 2019 18:40:33 -0400 Subject: [PATCH 973/993] NFS: Fix an RCU lock leak in nfs4_refresh_delegation_stateid() A typo in nfs4_refresh_delegation_stateid() means we're leaking an RCU lock, and always returning a value of 'false'. As the function description states, we were always supposed to return 'true' if a matching delegation was found. Fixes: 12f275cdd163 ("NFSv4: Retry CLOSE and DELEGRETURN on NFS4ERR_OLD_STATEID.") Cc: stable@vger.kernel.org # v4.15+ Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- fs/nfs/delegation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index ccdfb5f98f35..af549d70ec50 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -1191,7 +1191,7 @@ bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode) if (delegation != NULL && nfs4_stateid_match_other(dst, &delegation->stateid)) { dst->seqid = delegation->stateid.seqid; - return ret; + ret = true; } rcu_read_unlock(); out: -- GitLab From 94234501f492ad67063ffa5c3d597782301e8378 Mon Sep 17 00:00:00 2001 From: Steve Muckle Date: Thu, 31 Oct 2019 15:38:06 -0700 Subject: [PATCH 974/993] ANDROID: gki_defconfig: enable CONFIG_KEYBOARD_GPIO This driver is very commonly used in Android. Statically compile it into the GKI. Bug: 143314501 Change-Id: I12e2dd04bdde2affef1f6be9f33033d87096ec89 Signed-off-by: Steve Muckle --- arch/arm64/configs/gki_defconfig | 1 + arch/x86/configs/gki_defconfig | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index c83c3041f90b..441e6228082f 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -263,6 +263,7 @@ CONFIG_USB_USBNET=y # CONFIG_WLAN_VENDOR_QUANTENNA is not set CONFIG_VIRT_WIFI=y CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_JOYSTICK=y CONFIG_INPUT_MISC=y diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index ac4097e334d4..dc8c330bd775 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -237,7 +237,7 @@ CONFIG_USB_USBNET=y # CONFIG_WLAN_VENDOR_QUANTENNA is not set CONFIG_VIRT_WIFI=m CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_KEYBOARD is not set +CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_JOYSTICK=y CONFIG_INPUT_MISC=y -- GitLab From 4202e219edd6cc164c042e16fa327525410705ae Mon Sep 17 00:00:00 2001 From: Chuhong Yuan Date: Fri, 1 Nov 2019 20:17:25 +0800 Subject: [PATCH 975/993] net: ethernet: arc: add the missed clk_disable_unprepare The remove misses to disable and unprepare priv->macclk like what is done when probe fails. Add the missed call in remove. Signed-off-by: Chuhong Yuan Signed-off-by: David S. Miller --- drivers/net/ethernet/arc/emac_rockchip.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/arc/emac_rockchip.c b/drivers/net/ethernet/arc/emac_rockchip.c index 42d2e1b02c44..664d664e0925 100644 --- a/drivers/net/ethernet/arc/emac_rockchip.c +++ b/drivers/net/ethernet/arc/emac_rockchip.c @@ -256,6 +256,9 @@ static int emac_rockchip_remove(struct platform_device *pdev) if (priv->regulator) regulator_disable(priv->regulator); + if (priv->soc_data->need_div_macclk) + clk_disable_unprepare(priv->macclk); + free_netdev(ndev); return err; } -- GitLab From 8d5cfd7f76a2414e23c74bb8858af7540365d985 Mon Sep 17 00:00:00 2001 From: Manfred Rudigier Date: Thu, 15 Aug 2019 13:55:20 -0700 Subject: [PATCH 976/993] igb: Fix constant media auto sense switching when no cable is connected At least on the i350 there is an annoying behavior that is maybe also present on 82580 devices, but was probably not noticed yet as MAS is not widely used. If no cable is connected on both fiber/copper ports the media auto sense code will constantly swap between them as part of the watchdog task and produce many unnecessary kernel log messages. The swap code responsible for this behavior (switching to fiber) should not be executed if the current media type is copper and there is no signal detected on the fiber port. In this case we can safely wait until the AUTOSENSE_EN bit is cleared. Signed-off-by: Manfred Rudigier Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 17a961c3d6e4..9148c62d9ac5 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -2065,7 +2065,8 @@ static void igb_check_swap_media(struct igb_adapter *adapter) if ((hw->phy.media_type == e1000_media_type_copper) && (!(connsw & E1000_CONNSW_AUTOSENSE_EN))) { swap_now = true; - } else if (!(connsw & E1000_CONNSW_SERDESD)) { + } else if ((hw->phy.media_type != e1000_media_type_copper) && + !(connsw & E1000_CONNSW_SERDESD)) { /* copper signal takes time to appear */ if (adapter->copper_tries < 4) { adapter->copper_tries++; -- GitLab From 2c19e395e061a1c1442e0623ce5ec88ecc6c5a9b Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Mon, 7 Oct 2019 15:07:24 -0700 Subject: [PATCH 977/993] i40e: Fix receive buffer starvation for AF_XDP Magnus's fix to resolve a potential receive buffer starvation for AF_XDP got applied to both the i40e_xsk_umem_enable/disable() functions, when it should have only been applied to the "enable". So clean up the undesired code in the disable function. CC: Magnus Karlsson Fixes: 1f459bdc2007 ("i40e: fix potential RX buffer starvation for AF_XDP") Signed-off-by: Jeff Kirsher Tested-by: Andrew Bowers --- drivers/net/ethernet/intel/i40e/i40e_xsk.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.c b/drivers/net/ethernet/intel/i40e/i40e_xsk.c index b1c3227ae4ab..a05dfecdd9b4 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_xsk.c +++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.c @@ -157,11 +157,6 @@ static int i40e_xsk_umem_disable(struct i40e_vsi *vsi, u16 qid) err = i40e_queue_pair_enable(vsi, qid); if (err) return err; - - /* Kick start the NAPI context so that receiving will start */ - err = i40e_xsk_wakeup(vsi->netdev, qid, XDP_WAKEUP_RX); - if (err) - return err; } return 0; -- GitLab From 8472ba62154058b64ebb83d5f57259a352d28697 Mon Sep 17 00:00:00 2001 From: Wenwen Wang Date: Mon, 12 Aug 2019 00:59:21 -0500 Subject: [PATCH 978/993] e1000: fix memory leaks In e1000_set_ringparam(), 'tx_old' and 'rx_old' are not deallocated if e1000_up() fails, leading to memory leaks. Refactor the code to fix this issue. Signed-off-by: Wenwen Wang Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000/e1000_ethtool.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c index 71d3d8854d8f..be56e631d693 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c +++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c @@ -607,6 +607,7 @@ static int e1000_set_ringparam(struct net_device *netdev, for (i = 0; i < adapter->num_rx_queues; i++) rxdr[i].count = rxdr->count; + err = 0; if (netif_running(adapter->netdev)) { /* Try to get new resources before deleting old */ err = e1000_setup_all_rx_resources(adapter); @@ -627,14 +628,13 @@ static int e1000_set_ringparam(struct net_device *netdev, adapter->rx_ring = rxdr; adapter->tx_ring = txdr; err = e1000_up(adapter); - if (err) - goto err_setup; } kfree(tx_old); kfree(rx_old); clear_bit(__E1000_RESETTING, &adapter->flags); - return 0; + return err; + err_setup_tx: e1000_free_all_rx_resources(adapter); err_setup_rx: @@ -646,7 +646,6 @@ static int e1000_set_ringparam(struct net_device *netdev, err_alloc_tx: if (netif_running(adapter->netdev)) e1000_up(adapter); -err_setup: clear_bit(__E1000_RESETTING, &adapter->flags); return err; } -- GitLab From 17df5ae1b3e186338c6f584eaa32a9eed5460991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Neusch=C3=A4fer?= Date: Wed, 2 Oct 2019 17:09:55 +0200 Subject: [PATCH 979/993] Documentation: networking: device drivers: Remove stray asterisks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These asterisks were once references to a line that said: "* Other names and brands may be claimed as the property of others." But now, they serve no purpose; they can only irritate the reader. Fixes: de3edab4276c ("e1000: update README for e1000") Fixes: a3fb65680f65 ("e100.txt: Cleanup license info in kernel doc") Fixes: da8c01c4502a ("e1000e.txt: Add e1000e documentation") Fixes: f12a84a9f650 ("Documentation: fm10k: Add kernel documentation") Fixes: b55c52b1938c ("igb.txt: Add igb documentation") Fixes: c4e9b56e2442 ("igbvf.txt: Add igbvf Documentation") Fixes: d7064f4c192c ("Documentation/networking/: Update Intel wired LAN driver documentation") Fixes: c4b8c01112a1 ("ixgbevf.txt: Update ixgbevf documentation") Fixes: 1e06edcc2f22 ("Documentation: i40e: Prepare documentation for RST conversion") Fixes: 105bf2fe6b32 ("i40evf: add driver to kernel build system") Fixes: 1fae869bcf3d ("Documentation: ice: Prepare documentation for RST conversion") Fixes: df69ba43217d ("ionic: Add basic framework for IONIC Network device driver") Signed-off-by: Jonathan Neuschäfer Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- .../networking/device_drivers/intel/e100.rst | 14 +++++++------- .../networking/device_drivers/intel/e1000.rst | 12 ++++++------ .../networking/device_drivers/intel/e1000e.rst | 14 +++++++------- .../networking/device_drivers/intel/fm10k.rst | 10 +++++----- .../networking/device_drivers/intel/i40e.rst | 8 ++++---- .../networking/device_drivers/intel/iavf.rst | 8 ++++---- .../networking/device_drivers/intel/ice.rst | 6 +++--- .../networking/device_drivers/intel/igb.rst | 12 ++++++------ .../networking/device_drivers/intel/igbvf.rst | 6 +++--- .../networking/device_drivers/intel/ixgbe.rst | 10 +++++----- .../networking/device_drivers/intel/ixgbevf.rst | 6 +++--- .../networking/device_drivers/pensando/ionic.rst | 6 +++--- 12 files changed, 56 insertions(+), 56 deletions(-) diff --git a/Documentation/networking/device_drivers/intel/e100.rst b/Documentation/networking/device_drivers/intel/e100.rst index 2b9f4887beda..caf023cc88de 100644 --- a/Documentation/networking/device_drivers/intel/e100.rst +++ b/Documentation/networking/device_drivers/intel/e100.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: GPL-2.0+ -============================================================== -Linux* Base Driver for the Intel(R) PRO/100 Family of Adapters -============================================================== +============================================================= +Linux Base Driver for the Intel(R) PRO/100 Family of Adapters +============================================================= June 1, 2018 @@ -21,7 +21,7 @@ Contents In This Release =============== -This file describes the Linux* Base Driver for the Intel(R) PRO/100 Family of +This file describes the Linux Base Driver for the Intel(R) PRO/100 Family of Adapters. This driver includes support for Itanium(R)2-based systems. For questions related to hardware requirements, refer to the documentation @@ -138,9 +138,9 @@ version 1.6 or later is required for this functionality. The latest release of ethtool can be found from https://www.kernel.org/pub/software/network/ethtool/ -Enabling Wake on LAN* (WoL) ---------------------------- -WoL is provided through the ethtool* utility. For instructions on +Enabling Wake on LAN (WoL) +-------------------------- +WoL is provided through the ethtool utility. For instructions on enabling WoL with ethtool, refer to the ethtool man page. WoL will be enabled on the system during the next shut down or reboot. For this driver version, in order to enable WoL, the e100 driver must be loaded diff --git a/Documentation/networking/device_drivers/intel/e1000.rst b/Documentation/networking/device_drivers/intel/e1000.rst index 956560b6e745..4aaae0f7d6ba 100644 --- a/Documentation/networking/device_drivers/intel/e1000.rst +++ b/Documentation/networking/device_drivers/intel/e1000.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: GPL-2.0+ -=========================================================== -Linux* Base Driver for Intel(R) Ethernet Network Connection -=========================================================== +========================================================== +Linux Base Driver for Intel(R) Ethernet Network Connection +========================================================== Intel Gigabit Linux driver. Copyright(c) 1999 - 2013 Intel Corporation. @@ -438,10 +438,10 @@ ethtool The latest release of ethtool can be found from https://www.kernel.org/pub/software/network/ethtool/ -Enabling Wake on LAN* (WoL) ---------------------------- +Enabling Wake on LAN (WoL) +-------------------------- - WoL is configured through the ethtool* utility. + WoL is configured through the ethtool utility. WoL will be enabled on the system during the next shut down or reboot. For this driver version, in order to enable WoL, the e1000 driver must be diff --git a/Documentation/networking/device_drivers/intel/e1000e.rst b/Documentation/networking/device_drivers/intel/e1000e.rst index 01999f05509c..f49cd370e7bf 100644 --- a/Documentation/networking/device_drivers/intel/e1000e.rst +++ b/Documentation/networking/device_drivers/intel/e1000e.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: GPL-2.0+ -====================================================== -Linux* Driver for Intel(R) Ethernet Network Connection -====================================================== +===================================================== +Linux Driver for Intel(R) Ethernet Network Connection +===================================================== Intel Gigabit Linux driver. Copyright(c) 2008-2018 Intel Corporation. @@ -338,7 +338,7 @@ and higher cannot be forced. Use the autonegotiation advertising setting to manually set devices for 1 Gbps and higher. Speed, duplex, and autonegotiation advertising are configured through the -ethtool* utility. +ethtool utility. Caution: Only experienced network administrators should force speed and duplex or change autonegotiation advertising manually. The settings at the switch must @@ -351,9 +351,9 @@ will not attempt to auto-negotiate with its link partner since those adapters operate only in full duplex and only at their native speed. -Enabling Wake on LAN* (WoL) ---------------------------- -WoL is configured through the ethtool* utility. +Enabling Wake on LAN (WoL) +-------------------------- +WoL is configured through the ethtool utility. WoL will be enabled on the system during the next shut down or reboot. For this driver version, in order to enable WoL, the e1000e driver must be loaded diff --git a/Documentation/networking/device_drivers/intel/fm10k.rst b/Documentation/networking/device_drivers/intel/fm10k.rst index ac3269e34f55..4d279e64e221 100644 --- a/Documentation/networking/device_drivers/intel/fm10k.rst +++ b/Documentation/networking/device_drivers/intel/fm10k.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: GPL-2.0+ -============================================================== -Linux* Base Driver for Intel(R) Ethernet Multi-host Controller -============================================================== +============================================================= +Linux Base Driver for Intel(R) Ethernet Multi-host Controller +============================================================= August 20, 2018 Copyright(c) 2015-2018 Intel Corporation. @@ -120,8 +120,8 @@ rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r Known Issues/Troubleshooting ============================ -Enabling SR-IOV in a 64-bit Microsoft* Windows Server* 2012/R2 guest OS under Linux KVM ---------------------------------------------------------------------------------------- +Enabling SR-IOV in a 64-bit Microsoft Windows Server 2012/R2 guest OS under Linux KVM +------------------------------------------------------------------------------------- KVM Hypervisor/VMM supports direct assignment of a PCIe device to a VM. This includes traditional PCIe devices, as well as SR-IOV-capable devices based on the Intel Ethernet Controller XL710. diff --git a/Documentation/networking/device_drivers/intel/i40e.rst b/Documentation/networking/device_drivers/intel/i40e.rst index 848fd388fa6e..8a9b18573688 100644 --- a/Documentation/networking/device_drivers/intel/i40e.rst +++ b/Documentation/networking/device_drivers/intel/i40e.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: GPL-2.0+ -================================================================== -Linux* Base Driver for the Intel(R) Ethernet Controller 700 Series -================================================================== +================================================================= +Linux Base Driver for the Intel(R) Ethernet Controller 700 Series +================================================================= Intel 40 Gigabit Linux driver. Copyright(c) 1999-2018 Intel Corporation. @@ -384,7 +384,7 @@ NOTE: You cannot set the speed for devices based on the Intel(R) Ethernet Network Adapter XXV710 based devices. Speed, duplex, and autonegotiation advertising are configured through the -ethtool* utility. +ethtool utility. Caution: Only experienced network administrators should force speed and duplex or change autonegotiation advertising manually. The settings at the switch must diff --git a/Documentation/networking/device_drivers/intel/iavf.rst b/Documentation/networking/device_drivers/intel/iavf.rst index cfc08842e32c..84ac7e75f363 100644 --- a/Documentation/networking/device_drivers/intel/iavf.rst +++ b/Documentation/networking/device_drivers/intel/iavf.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: GPL-2.0+ -================================================================== -Linux* Base Driver for Intel(R) Ethernet Adaptive Virtual Function -================================================================== +================================================================= +Linux Base Driver for Intel(R) Ethernet Adaptive Virtual Function +================================================================= Intel Ethernet Adaptive Virtual Function Linux driver. Copyright(c) 2013-2018 Intel Corporation. @@ -19,7 +19,7 @@ Contents Overview ======== -This file describes the iavf Linux* Base Driver. This driver was formerly +This file describes the iavf Linux Base Driver. This driver was formerly called i40evf. The iavf driver supports the below mentioned virtual function devices and diff --git a/Documentation/networking/device_drivers/intel/ice.rst b/Documentation/networking/device_drivers/intel/ice.rst index c220aa2711c6..ee43ea57d443 100644 --- a/Documentation/networking/device_drivers/intel/ice.rst +++ b/Documentation/networking/device_drivers/intel/ice.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: GPL-2.0+ -=================================================================== -Linux* Base Driver for the Intel(R) Ethernet Connection E800 Series -=================================================================== +================================================================== +Linux Base Driver for the Intel(R) Ethernet Connection E800 Series +================================================================== Intel ice Linux driver. Copyright(c) 2018 Intel Corporation. diff --git a/Documentation/networking/device_drivers/intel/igb.rst b/Documentation/networking/device_drivers/intel/igb.rst index fc8cfaa5dcfa..87e560fe5eaa 100644 --- a/Documentation/networking/device_drivers/intel/igb.rst +++ b/Documentation/networking/device_drivers/intel/igb.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: GPL-2.0+ -=========================================================== -Linux* Base Driver for Intel(R) Ethernet Network Connection -=========================================================== +========================================================== +Linux Base Driver for Intel(R) Ethernet Network Connection +========================================================== Intel Gigabit Linux driver. Copyright(c) 1999-2018 Intel Corporation. @@ -129,9 +129,9 @@ version is required for this functionality. Download it at: https://www.kernel.org/pub/software/network/ethtool/ -Enabling Wake on LAN* (WoL) ---------------------------- -WoL is configured through the ethtool* utility. +Enabling Wake on LAN (WoL) +-------------------------- +WoL is configured through the ethtool utility. WoL will be enabled on the system during the next shut down or reboot. For this driver version, in order to enable WoL, the igb driver must be loaded diff --git a/Documentation/networking/device_drivers/intel/igbvf.rst b/Documentation/networking/device_drivers/intel/igbvf.rst index 9cddabe8108e..557fc020ef31 100644 --- a/Documentation/networking/device_drivers/intel/igbvf.rst +++ b/Documentation/networking/device_drivers/intel/igbvf.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: GPL-2.0+ -============================================================ -Linux* Base Virtual Function Driver for Intel(R) 1G Ethernet -============================================================ +=========================================================== +Linux Base Virtual Function Driver for Intel(R) 1G Ethernet +=========================================================== Intel Gigabit Virtual Function Linux driver. Copyright(c) 1999-2018 Intel Corporation. diff --git a/Documentation/networking/device_drivers/intel/ixgbe.rst b/Documentation/networking/device_drivers/intel/ixgbe.rst index c7d25483fedb..f1d5233e5e51 100644 --- a/Documentation/networking/device_drivers/intel/ixgbe.rst +++ b/Documentation/networking/device_drivers/intel/ixgbe.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: GPL-2.0+ -============================================================================= -Linux* Base Driver for the Intel(R) Ethernet 10 Gigabit PCI Express Adapters -============================================================================= +=========================================================================== +Linux Base Driver for the Intel(R) Ethernet 10 Gigabit PCI Express Adapters +=========================================================================== Intel 10 Gigabit Linux driver. Copyright(c) 1999-2018 Intel Corporation. @@ -519,8 +519,8 @@ The offload is also supported for ixgbe's VFs, but the VF must be set as Known Issues/Troubleshooting ============================ -Enabling SR-IOV in a 64-bit Microsoft* Windows Server* 2012/R2 guest OS ------------------------------------------------------------------------ +Enabling SR-IOV in a 64-bit Microsoft Windows Server 2012/R2 guest OS +--------------------------------------------------------------------- Linux KVM Hypervisor/VMM supports direct assignment of a PCIe device to a VM. This includes traditional PCIe devices, as well as SR-IOV-capable devices based on the Intel Ethernet Controller XL710. diff --git a/Documentation/networking/device_drivers/intel/ixgbevf.rst b/Documentation/networking/device_drivers/intel/ixgbevf.rst index 5d4977360157..76bbde736f21 100644 --- a/Documentation/networking/device_drivers/intel/ixgbevf.rst +++ b/Documentation/networking/device_drivers/intel/ixgbevf.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: GPL-2.0+ -============================================================= -Linux* Base Virtual Function Driver for Intel(R) 10G Ethernet -============================================================= +============================================================ +Linux Base Virtual Function Driver for Intel(R) 10G Ethernet +============================================================ Intel 10 Gigabit Virtual Function Linux driver. Copyright(c) 1999-2018 Intel Corporation. diff --git a/Documentation/networking/device_drivers/pensando/ionic.rst b/Documentation/networking/device_drivers/pensando/ionic.rst index 13935896bee6..c17d680cf334 100644 --- a/Documentation/networking/device_drivers/pensando/ionic.rst +++ b/Documentation/networking/device_drivers/pensando/ionic.rst @@ -1,8 +1,8 @@ .. SPDX-License-Identifier: GPL-2.0+ -========================================================== -Linux* Driver for the Pensando(R) Ethernet adapter family -========================================================== +======================================================== +Linux Driver for the Pensando(R) Ethernet adapter family +======================================================== Pensando Linux Ethernet driver. Copyright(c) 2019 Pensando Systems, Inc -- GitLab From 451fe015b2857de3d8027ef606284a205e177724 Mon Sep 17 00:00:00 2001 From: Igor Pylypiv Date: Thu, 3 Oct 2019 23:53:57 -0700 Subject: [PATCH 980/993] ixgbe: Remove duplicate clear_bit() call __IXGBE_RX_BUILD_SKB_ENABLED bit is already cleared. Signed-off-by: Igor Pylypiv Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 1ce2397306b9..91b3780ddb04 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -4310,7 +4310,6 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) if (test_bit(__IXGBE_RX_FCOE, &rx_ring->state)) set_bit(__IXGBE_RX_3K_BUFFER, &rx_ring->state); - clear_bit(__IXGBE_RX_BUILD_SKB_ENABLED, &rx_ring->state); if (adapter->flags2 & IXGBE_FLAG2_RX_LEGACY) continue; -- GitLab From a904a0693c189691eeee64f6c6b188bd7dc244e9 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 1 Nov 2019 10:32:19 -0700 Subject: [PATCH 981/993] inet: stop leaking jiffies on the wire Historically linux tried to stick to RFC 791, 1122, 2003 for IPv4 ID field generation. RFC 6864 made clear that no matter how hard we try, we can not ensure unicity of IP ID within maximum lifetime for all datagrams with a given source address/destination address/protocol tuple. Linux uses a per socket inet generator (inet_id), initialized at connection startup with a XOR of 'jiffies' and other fields that appear clear on the wire. Thiemo Nagel pointed that this strategy is a privacy concern as this provides 16 bits of entropy to fingerprint devices. Let's switch to a random starting point, this is just as good as far as RFC 6864 is concerned and does not leak anything critical. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet Reported-by: Thiemo Nagel Signed-off-by: David S. Miller --- drivers/crypto/chelsio/chtls/chtls_cm.c | 2 +- net/dccp/ipv4.c | 2 +- net/ipv4/datagram.c | 2 +- net/ipv4/tcp_ipv4.c | 4 ++-- net/sctp/socket.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/chelsio/chtls/chtls_cm.c b/drivers/crypto/chelsio/chtls/chtls_cm.c index 774d991d7cca..aca75237bbcf 100644 --- a/drivers/crypto/chelsio/chtls/chtls_cm.c +++ b/drivers/crypto/chelsio/chtls/chtls_cm.c @@ -1297,7 +1297,7 @@ static void make_established(struct sock *sk, u32 snd_isn, unsigned int opt) tp->write_seq = snd_isn; tp->snd_nxt = snd_isn; tp->snd_una = snd_isn; - inet_sk(sk)->inet_id = tp->write_seq ^ jiffies; + inet_sk(sk)->inet_id = prandom_u32(); assign_rxopt(sk, opt); if (tp->rcv_wnd > (RCV_BUFSIZ_M << 10)) diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index d9b4200ed12d..0d8f782c25cc 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -117,7 +117,7 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) inet->inet_daddr, inet->inet_sport, inet->inet_dport); - inet->inet_id = dp->dccps_iss ^ jiffies; + inet->inet_id = prandom_u32(); err = dccp_connect(sk); rt = NULL; diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index 9a0fe0c2fa02..4a8550c49202 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c @@ -73,7 +73,7 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len reuseport_has_conns(sk, true); sk->sk_state = TCP_ESTABLISHED; sk_set_txhash(sk); - inet->inet_id = jiffies; + inet->inet_id = prandom_u32(); sk_dst_set(sk, &rt->dst); err = 0; diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index b74192695955..67b2dc7a1727 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -303,7 +303,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) inet->inet_daddr); } - inet->inet_id = tp->write_seq ^ jiffies; + inet->inet_id = prandom_u32(); if (tcp_fastopen_defer_connect(sk, &err)) return err; @@ -1450,7 +1450,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, inet_csk(newsk)->icsk_ext_hdr_len = 0; if (inet_opt) inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen; - newinet->inet_id = newtp->write_seq ^ jiffies; + newinet->inet_id = prandom_u32(); if (!dst) { dst = inet_csk_route_child_sock(sk, newsk, req); diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ca81e06df165..ffd3262b7a41 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -9306,7 +9306,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk, newinet->inet_rcv_saddr = inet->inet_rcv_saddr; newinet->inet_dport = htons(asoc->peer.port); newinet->pmtudisc = inet->pmtudisc; - newinet->inet_id = asoc->next_tsn ^ jiffies; + newinet->inet_id = prandom_u32(); newinet->uc_ttl = inet->uc_ttl; newinet->mc_loop = 1; -- GitLab From 9cfeeb576d49a7b5e643b8066ba64a55e8417c5d Mon Sep 17 00:00:00 2001 From: Yangchun Fu Date: Fri, 1 Nov 2019 10:09:56 -0700 Subject: [PATCH 982/993] gve: Fixes DMA synchronization. Synces the DMA buffer properly in order for CPU and device to see the most up-to-data data. Signed-off-by: Yangchun Fu Reviewed-by: Catherine Sullivan Signed-off-by: David S. Miller --- drivers/net/ethernet/google/gve/gve_rx.c | 2 ++ drivers/net/ethernet/google/gve/gve_tx.c | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c index 59564ac99d2a..edec61dfc868 100644 --- a/drivers/net/ethernet/google/gve/gve_rx.c +++ b/drivers/net/ethernet/google/gve/gve_rx.c @@ -289,6 +289,8 @@ static bool gve_rx(struct gve_rx_ring *rx, struct gve_rx_desc *rx_desc, len = be16_to_cpu(rx_desc->len) - GVE_RX_PAD; page_info = &rx->data.page_info[idx]; + dma_sync_single_for_cpu(&priv->pdev->dev, rx->data.qpl->page_buses[idx], + PAGE_SIZE, DMA_FROM_DEVICE); /* gvnic can only receive into registered segments. If the buffer * can't be recycled, our only choice is to copy the data out of diff --git a/drivers/net/ethernet/google/gve/gve_tx.c b/drivers/net/ethernet/google/gve/gve_tx.c index 778b87b5a06c..0a9a7ee2a866 100644 --- a/drivers/net/ethernet/google/gve/gve_tx.c +++ b/drivers/net/ethernet/google/gve/gve_tx.c @@ -390,7 +390,21 @@ static void gve_tx_fill_seg_desc(union gve_tx_desc *seg_desc, seg_desc->seg.seg_addr = cpu_to_be64(addr); } -static int gve_tx_add_skb(struct gve_tx_ring *tx, struct sk_buff *skb) +static void gve_dma_sync_for_device(struct device *dev, dma_addr_t *page_buses, + u64 iov_offset, u64 iov_len) +{ + dma_addr_t dma; + u64 addr; + + for (addr = iov_offset; addr < iov_offset + iov_len; + addr += PAGE_SIZE) { + dma = page_buses[addr / PAGE_SIZE]; + dma_sync_single_for_device(dev, dma, PAGE_SIZE, DMA_TO_DEVICE); + } +} + +static int gve_tx_add_skb(struct gve_tx_ring *tx, struct sk_buff *skb, + struct device *dev) { int pad_bytes, hlen, hdr_nfrags, payload_nfrags, l4_hdr_offset; union gve_tx_desc *pkt_desc, *seg_desc; @@ -432,6 +446,9 @@ static int gve_tx_add_skb(struct gve_tx_ring *tx, struct sk_buff *skb) skb_copy_bits(skb, 0, tx->tx_fifo.base + info->iov[hdr_nfrags - 1].iov_offset, hlen); + gve_dma_sync_for_device(dev, tx->tx_fifo.qpl->page_buses, + info->iov[hdr_nfrags - 1].iov_offset, + info->iov[hdr_nfrags - 1].iov_len); copy_offset = hlen; for (i = payload_iov; i < payload_nfrags + payload_iov; i++) { @@ -445,6 +462,9 @@ static int gve_tx_add_skb(struct gve_tx_ring *tx, struct sk_buff *skb) skb_copy_bits(skb, copy_offset, tx->tx_fifo.base + info->iov[i].iov_offset, info->iov[i].iov_len); + gve_dma_sync_for_device(dev, tx->tx_fifo.qpl->page_buses, + info->iov[i].iov_offset, + info->iov[i].iov_len); copy_offset += info->iov[i].iov_len; } @@ -473,7 +493,7 @@ netdev_tx_t gve_tx(struct sk_buff *skb, struct net_device *dev) gve_tx_put_doorbell(priv, tx->q_resources, tx->req); return NETDEV_TX_BUSY; } - nsegs = gve_tx_add_skb(tx, skb); + nsegs = gve_tx_add_skb(tx, skb, &priv->pdev->dev); netdev_tx_sent_queue(tx->netdev_txq, skb->len); skb_tx_timestamp(skb); -- GitLab From 9d68db5092c5fac99fccfdeab3f04df0b27d1762 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 31 Oct 2019 15:42:26 -0700 Subject: [PATCH 983/993] net: phylink: Fix phylink_dbg() macro The phylink_dbg() macro does not follow dynamic debug or defined(DEBUG) and as a result, it spams the kernel log since a PR_DEBUG level is currently used. Fix it to be defined appropriately whether CONFIG_DYNAMIC_DEBUG or defined(DEBUG) are set. Fixes: 17091180b152 ("net: phylink: Add phylink_{printk, err, warn, info, dbg} macros") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/phylink.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 20e2ebe458f2..a578f7ebf715 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -87,8 +87,24 @@ struct phylink { phylink_printk(KERN_WARNING, pl, fmt, ##__VA_ARGS__) #define phylink_info(pl, fmt, ...) \ phylink_printk(KERN_INFO, pl, fmt, ##__VA_ARGS__) +#if defined(CONFIG_DYNAMIC_DEBUG) #define phylink_dbg(pl, fmt, ...) \ +do { \ + if ((pl)->config->type == PHYLINK_NETDEV) \ + netdev_dbg((pl)->netdev, fmt, ##__VA_ARGS__); \ + else if ((pl)->config->type == PHYLINK_DEV) \ + dev_dbg((pl)->dev, fmt, ##__VA_ARGS__); \ +} while (0) +#elif defined(DEBUG) +#define phylink_dbg(pl, fmt, ...) \ phylink_printk(KERN_DEBUG, pl, fmt, ##__VA_ARGS__) +#else +#define phylink_dbg(pl, fmt, ...) \ +({ \ + if (0) \ + phylink_printk(KERN_DEBUG, pl, fmt, ##__VA_ARGS__); \ +}) +#endif /** * phylink_set_port_modes() - set the port type modes in the ethtool mask -- GitLab From 5fc0f21246e50afdf318b5a3a941f7f4f57b8947 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 31 Oct 2019 15:54:05 -0700 Subject: [PATCH 984/993] net: dsa: bcm_sf2: Fix IMP setup for port different than 8 Since it became possible for the DSA core to use a CPU port different than 8, our bcm_sf2_imp_setup() function was broken because it assumes that registers are applicable to port 8. In particular, the port's MAC is going to stay disabled, so make sure we clear the RX_DIS and TX_DIS bits if we are not configured for port 8. Fixes: 9f91484f6fcc ("net: dsa: make "label" property optional for dsa2") Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/dsa/bcm_sf2.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index 26509fa37a50..d44651ad520c 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -37,22 +37,11 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) unsigned int i; u32 reg, offset; - if (priv->type == BCM7445_DEVICE_ID) - offset = CORE_STS_OVERRIDE_IMP; - else - offset = CORE_STS_OVERRIDE_IMP2; - /* Enable the port memories */ reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL); reg &= ~P_TXQ_PSM_VDD(port); core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL); - /* Enable Broadcast, Multicast, Unicast forwarding to IMP port */ - reg = core_readl(priv, CORE_IMP_CTL); - reg |= (RX_BCST_EN | RX_MCST_EN | RX_UCST_EN); - reg &= ~(RX_DIS | TX_DIS); - core_writel(priv, reg, CORE_IMP_CTL); - /* Enable forwarding */ core_writel(priv, SW_FWDG_EN, CORE_SWMODE); @@ -71,10 +60,27 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) b53_brcm_hdr_setup(ds, port); - /* Force link status for IMP port */ - reg = core_readl(priv, offset); - reg |= (MII_SW_OR | LINK_STS); - core_writel(priv, reg, offset); + if (port == 8) { + if (priv->type == BCM7445_DEVICE_ID) + offset = CORE_STS_OVERRIDE_IMP; + else + offset = CORE_STS_OVERRIDE_IMP2; + + /* Force link status for IMP port */ + reg = core_readl(priv, offset); + reg |= (MII_SW_OR | LINK_STS); + core_writel(priv, reg, offset); + + /* Enable Broadcast, Multicast, Unicast forwarding to IMP port */ + reg = core_readl(priv, CORE_IMP_CTL); + reg |= (RX_BCST_EN | RX_MCST_EN | RX_UCST_EN); + reg &= ~(RX_DIS | TX_DIS); + core_writel(priv, reg, CORE_IMP_CTL); + } else { + reg = core_readl(priv, CORE_G_PCTL_PORT(port)); + reg &= ~(RX_DIS | TX_DIS); + core_writel(priv, reg, CORE_G_PCTL_PORT(port)); + } } static void bcm_sf2_gphy_enable_set(struct dsa_switch *ds, bool enable) -- GitLab From 62bdc8fd1c21d4263ebd18bec57f82532d09249f Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Fri, 1 Nov 2019 00:10:21 +0100 Subject: [PATCH 985/993] r8169: fix wrong PHY ID issue with RTL8168dp As reported in [0] at least one RTL8168dp version has problems establishing a link. This chip version has an integrated RTL8211b PHY, however the chip seems to report a wrong PHY ID, resulting in a wrong PHY driver (for Generic Realtek PHY) being loaded. Work around this issue by adding a hook to r8168dp_2_mdio_read() for returning the correct PHY ID. [0] https://bbs.archlinux.org/viewtopic.php?id=246508 Fixes: 242cd9b5866a ("r8169: use phy_resume/phy_suspend") Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169_main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 350b0d949611..5064c292b873 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -1029,6 +1029,10 @@ static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg) { int value; + /* Work around issue with chip reporting wrong PHY ID */ + if (reg == MII_PHYSID2) + return 0xc912; + r8168dp_2_mdio_start(tp); value = r8169_mdio_read(tp, reg); -- GitLab From d64479a3e3f9924074ca7b50bd72fa5211dca9c1 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Thu, 31 Oct 2019 16:24:36 -0700 Subject: [PATCH 986/993] selftests: net: reuseport_dualstack: fix uninitalized parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test reports EINVAL for getsockopt(SOL_SOCKET, SO_DOMAIN) occasionally due to the uninitialized length parameter. Initialize it to fix this, and also use int for "test_family" to comply with the API standard. Fixes: d6a61f80b871 ("soreuseport: test mixed v4/v6 sockets") Reported-by: Maciej Żenczykowski Signed-off-by: Eric Dumazet Signed-off-by: Wei Wang Cc: Craig Gallek Signed-off-by: David S. Miller --- tools/testing/selftests/net/reuseport_dualstack.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/reuseport_dualstack.c b/tools/testing/selftests/net/reuseport_dualstack.c index fe3230c55986..fb7a59ed759e 100644 --- a/tools/testing/selftests/net/reuseport_dualstack.c +++ b/tools/testing/selftests/net/reuseport_dualstack.c @@ -129,7 +129,7 @@ static void test(int *rcv_fds, int count, int proto) { struct epoll_event ev; int epfd, i, test_fd; - uint16_t test_family; + int test_family; socklen_t len; epfd = epoll_create(1); @@ -146,6 +146,7 @@ static void test(int *rcv_fds, int count, int proto) send_from_v4(proto); test_fd = receive_once(epfd, proto); + len = sizeof(test_family); if (getsockopt(test_fd, SOL_SOCKET, SO_DOMAIN, &test_family, &len)) error(1, errno, "failed to read socket domain"); if (test_family != AF_INET) -- GitLab From 8101e069418d136b995b3da81f1af72637082fda Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 31 Oct 2019 20:06:58 -0700 Subject: [PATCH 987/993] selftests: bpf: Skip write only files in debugfs DebugFS for netdevsim now contains some "action trigger" files which are write only. Don't try to capture the contents of those. Note that we can't use os.access() because the script requires root. Fixes: 4418f862d675 ("netdevsim: implement support for devlink region and snapshots") Signed-off-by: Jakub Kicinski Signed-off-by: David S. Miller --- tools/testing/selftests/bpf/test_offload.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/testing/selftests/bpf/test_offload.py b/tools/testing/selftests/bpf/test_offload.py index 15a666329a34..1afa22c88e42 100755 --- a/tools/testing/selftests/bpf/test_offload.py +++ b/tools/testing/selftests/bpf/test_offload.py @@ -22,6 +22,7 @@ import os import pprint import random import re +import stat import string import struct import subprocess @@ -311,7 +312,11 @@ class DebugfsDir: for f in out.split(): if f == "ports": continue + p = os.path.join(path, f) + if not os.stat(p).st_mode & stat.S_IRUSR: + continue + if os.path.isfile(p): _, out = cmd('cat %s/%s' % (path, f)) dfs[f] = out.strip() -- GitLab From 41aa29a58b5f7f7be43f35372ef411f304a87a0d Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 31 Oct 2019 20:06:59 -0700 Subject: [PATCH 988/993] net: cls_bpf: fix NULL deref on offload filter removal Commit 401192113730 ("net: sched: refactor block offloads counter usage") missed the fact that either new prog or old prog may be NULL. Fixes: 401192113730 ("net: sched: refactor block offloads counter usage") Signed-off-by: Jakub Kicinski Signed-off-by: David S. Miller --- net/sched/cls_bpf.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index bf10bdaf5012..8229ed4a67be 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -162,16 +162,20 @@ static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog, cls_bpf.name = obj->bpf_name; cls_bpf.exts_integrated = obj->exts_integrated; - if (oldprog) + if (oldprog && prog) err = tc_setup_cb_replace(block, tp, TC_SETUP_CLSBPF, &cls_bpf, skip_sw, &oldprog->gen_flags, &oldprog->in_hw_count, &prog->gen_flags, &prog->in_hw_count, true); - else + else if (prog) err = tc_setup_cb_add(block, tp, TC_SETUP_CLSBPF, &cls_bpf, skip_sw, &prog->gen_flags, &prog->in_hw_count, true); + else + err = tc_setup_cb_destroy(block, tp, TC_SETUP_CLSBPF, &cls_bpf, + skip_sw, &oldprog->gen_flags, + &oldprog->in_hw_count, true); if (prog && err) { cls_bpf_offload_cmd(tp, oldprog, prog, extack); -- GitLab From aefc3e723a78c2e429a64dadd7815ef2a4aecd44 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 31 Oct 2019 20:07:00 -0700 Subject: [PATCH 989/993] net: fix installing orphaned programs When netdevice with offloaded BPF programs is destroyed the programs are orphaned and removed from the program IDA - their IDs get released (the programs may remain accessible via existing open file descriptors and pinned files). After IDs are released they are set to 0. This confuses dev_change_xdp_fd() because it compares the __dev_xdp_query() result where 0 means no program with prog->aux->id where 0 means orphaned. dev_change_xdp_fd() would have incorrectly returned success even though it had not installed the program. Since drivers already catch this case via bpf_offload_dev_match() let them handle this case. The error message drivers produce in this case ("program loaded for a different device") is in fact correct as the orphaned program must had to be loaded for a different device. Fixes: c14a9f633d9e ("net: Don't call XDP_SETUP_PROG when nothing is changed") Signed-off-by: Jakub Kicinski Signed-off-by: David S. Miller --- net/core/dev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 96afd464284a..99ac84ff398f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -8421,7 +8421,8 @@ int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack, return -EINVAL; } - if (prog->aux->id == prog_id) { + /* prog->aux->id may be 0 for orphaned device-bound progs */ + if (prog->aux->id && prog->aux->id == prog_id) { bpf_prog_put(prog); return 0; } -- GitLab From a99d8080aaf358d5d23581244e5da23b35e340b9 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 3 Nov 2019 14:07:26 -0800 Subject: [PATCH 990/993] Linux 5.4-rc6 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 79be70bf2899..b37d0e8fc61d 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc6 NAME = Kleptomaniac Octopus # *DOCUMENTATION* -- GitLab From f58546bac3c818a22a16d544e520fc526ccf3c07 Mon Sep 17 00:00:00 2001 From: Stanley Chu Date: Mon, 16 Sep 2019 23:56:49 +0800 Subject: [PATCH 991/993] FROMGIT: scsi: core: allow auto suspend override by low-level driver Rework from previous work by: Sujit Reddy Thumma Until now the scsi mid-layer forbids runtime suspend till userspace enables it. This is mainly to quarantine some disks with broken runtime power management or have high latencies executing suspend resume callbacks. If the userspace doesn't enable the runtime suspend the underlying hardware will be always on even when it is not doing any useful work and thus wasting power. Some low-level drivers for the controllers can efficiently use runtime power management to reduce power consumption and improve battery life. Allow runtime suspend parameters override within the LLD itself instead of waiting for userspace to control the power management. Link: https://lore.kernel.org/r/1568649411-5127-2-git-send-email-stanley.chu@mediatek.com Reviewed-by: Avri Altman Reviewed-by: Bart Van Assche Signed-off-by: Stanley Chu Signed-off-by: Martin K. Petersen Bug: 140620770 (cherry picked from commit c74f8056621738f5be9f5d3d7e0caa927b21aef6 https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git misc) Change-Id: Ib0b9e8bec307179187a57fe47cb747416da38db2 Signed-off-by: Todd Kjos --- drivers/scsi/scsi_sysfs.c | 3 ++- drivers/scsi/sd.c | 4 ++++ include/scsi/scsi_device.h | 3 ++- include/scsi/scsi_host.h | 3 +++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 6d7362e7367e..fb07b4456514 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1309,7 +1309,8 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) device_enable_async_suspend(&sdev->sdev_gendev); scsi_autopm_get_target(starget); pm_runtime_set_active(&sdev->sdev_gendev); - pm_runtime_forbid(&sdev->sdev_gendev); + if (!sdev->rpm_autosuspend) + pm_runtime_forbid(&sdev->sdev_gendev); pm_runtime_enable(&sdev->sdev_gendev); scsi_autopm_put_target(starget); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ebb40160539f..aab4ed891427 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3369,6 +3369,10 @@ static int sd_probe(struct device *dev) } blk_pm_runtime_init(sdp->request_queue, dev); + if (sdp->rpm_autosuspend) { + pm_runtime_set_autosuspend_delay(dev, + sdp->host->hostt->rpm_autosuspend_delay); + } device_add_disk(dev, gd, NULL); if (sdkp->capacity) sd_dif_config_host(sdkp); diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 202f4d6a4342..039e289f295e 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -199,7 +199,8 @@ struct scsi_device { unsigned broken_fua:1; /* Don't set FUA bit */ unsigned lun_in_cdb:1; /* Store LUN bits in CDB[1] */ unsigned unmap_limit_for_ws:1; /* Use the UNMAP limit for WRITE SAME */ - + unsigned rpm_autosuspend:1; /* Enable runtime autosuspend at device + * creation time */ atomic_t disk_events_disable_depth; /* disable depth for disk events */ DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 31e0d6ca1eba..2c3f0c58869b 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -486,6 +486,9 @@ struct scsi_host_template { */ unsigned int cmd_size; struct scsi_host_cmd_pool *cmd_pool; + + /* Delay for runtime autosuspend */ + int rpm_autosuspend_delay; }; /* -- GitLab From a30de0e015a2d22f6c8e633086044a16c6fd98d3 Mon Sep 17 00:00:00 2001 From: Stanley Chu Date: Mon, 16 Sep 2019 23:56:50 +0800 Subject: [PATCH 992/993] FROMGIT: scsi: ufs: override auto suspend tunables for ufs Rework from previous work by: Sujit Reddy Thumma Override auto suspend tunables for UFS device LUNs during initialization so as to efficiently manage background operations and the power consumption. Link: https://lore.kernel.org/r/1568649411-5127-3-git-send-email-stanley.chu@mediatek.com Reviewed-by: Avri Altman Reviewed-by: Bean Huo Signed-off-by: Stanley Chu Signed-off-by: Martin K. Petersen Bug: 140620770 (cherry pick from 49615ba144a0929c725d08f0d3ba8494c8b77404 https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git misc) Change-Id: I35bc8d52c73db5d9e6936c5fbfb728b5436fcf1f Signed-off-by: Todd Kjos --- drivers/scsi/ufs/ufshcd.c | 7 +++++++ drivers/scsi/ufs/ufshcd.h | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 126af87ab6d3..8083fe1645ce 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -89,6 +89,9 @@ /* Interrupt aggregation default timeout, unit: 40us */ #define INT_AGGR_DEF_TO 0x02 +/* default delay of autosuspend: 2000 ms */ +#define RPM_AUTOSUSPEND_DELAY_MS 2000 + #define ufshcd_toggle_vreg(_dev, _vreg, _on) \ ({ \ int _ret; \ @@ -4668,6 +4671,9 @@ static int ufshcd_slave_configure(struct scsi_device *sdev) ufshcd_crypto_setup_rq_keyslot_manager(hba, q); + if (ufshcd_is_rpm_autosuspend_allowed(hba)) + sdev->rpm_autosuspend = 1; + return 0; } @@ -7109,6 +7115,7 @@ static struct scsi_host_template ufshcd_driver_template = { .track_queue_depth = 1, .sdev_groups = ufshcd_driver_groups, .dma_boundary = PAGE_SIZE - 1, + .rpm_autosuspend_delay = RPM_AUTOSUSPEND_DELAY_MS, }; static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg, diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index b724a6cfe5af..10bac3241c5a 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -755,6 +755,12 @@ struct ufs_hba { * inline crypto engine, if it is present */ #define UFSHCD_CAP_CRYPTO (1 << 6) + /* + * This capability allows host controller driver to automatically + * enable runtime power management by itself instead of waiting + * for userspace to control the power management. + */ +#define UFSHCD_CAP_RPM_AUTOSUSPEND (1 << 6) struct devfreq *devfreq; struct ufs_clk_scaling clk_scaling; @@ -797,6 +803,10 @@ static inline bool ufshcd_can_autobkops_during_suspend(struct ufs_hba *hba) { return hba->caps & UFSHCD_CAP_AUTO_BKOPS_SUSPEND; } +static inline bool ufshcd_is_rpm_autosuspend_allowed(struct ufs_hba *hba) +{ + return hba->caps & UFSHCD_CAP_RPM_AUTOSUSPEND; +} static inline bool ufshcd_is_intr_aggr_allowed(struct ufs_hba *hba) { -- GitLab From aefd2d632eb0914f22fc6149f52eb0c6c148ce35 Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Wed, 30 Oct 2019 12:36:47 -0700 Subject: [PATCH 993/993] ANDROID: binder: fix sleeping from invalid function caused by RT inheritance When changing a thread's scheduling priority, binder calls sched_setscheduler_nocheck() while holding the node lock and proc inner lock. This was safe until v5.3 when a change was introduced where cpuset_read_lock() is called in this path which can sleep: commit 710da3c8ea7df ("sched/core: Prevent race condition between cpuset and __sched_setscheduler()"). Refactored binder_proc_transaction() to avoid holding a lock when calling binder_transaction_priority(). Bug: 143627611 Change-Id: I405c76b4813777905090ccc33e4f048b37700068 Fixes: e00eb41c0c7be ("ANDROID: binder: add support for RT prio inheritance.") Signed-off-by: Todd Kjos --- drivers/android/binder.c | 55 +++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 1face45e0e49..bc431dbf94f5 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2911,19 +2911,50 @@ static bool binder_proc_transaction(struct binder_transaction *t, struct binder_priority node_prio; bool oneway = !!(t->flags & TF_ONE_WAY); bool pending_async = false; + bool retry = false; BUG_ON(!node); - binder_node_lock(node); + +set_thread_prio: node_prio.prio = node->min_priority; node_prio.sched_policy = node->sched_policy; + if (thread) { + /* + * Priority must be set outside of lock, but must be + * done before enqueuing the transaction. + */ + binder_transaction_priority(thread->task, t, node_prio, + node->inherit_rt); + } + +retry_after_prio_restore: + binder_node_lock(node); if (oneway) { - BUG_ON(thread); + BUG_ON(!retry && thread); if (node->has_async_transaction) { pending_async = true; } else { node->has_async_transaction = true; } + if (thread && pending_async) { + /* + * The node state has changed since we selected + * the thread. Return the thread to the + * waiting_threads list. We have to drop + * the node lock to restore priority so we + * have to re-check the node state. + */ + binder_node_unlock(node); + binder_restore_priority(thread->task, + proc->default_priority); + binder_inner_proc_lock(proc); + list_add(&thread->waiting_thread_node, + &proc->waiting_threads); + binder_inner_proc_unlock(proc); + thread = NULL; + goto retry_after_prio_restore; + } } binder_inner_proc_lock(proc); @@ -2934,18 +2965,24 @@ static bool binder_proc_transaction(struct binder_transaction *t, return false; } - if (!thread && !pending_async) + if (!thread && !pending_async) { thread = binder_select_thread_ilocked(proc); + if (thread) { + if (oneway) + node->has_async_transaction = false; + binder_inner_proc_unlock(proc); + binder_node_unlock(node); + retry = true; + goto set_thread_prio; + } + } - if (thread) { - binder_transaction_priority(thread->task, t, node_prio, - node->inherit_rt); + if (thread) binder_enqueue_thread_work_ilocked(thread, &t->work); - } else if (!pending_async) { + else if (!pending_async) binder_enqueue_work_ilocked(&t->work, &proc->todo); - } else { + else binder_enqueue_work_ilocked(&t->work, &node->async_todo); - } if (!pending_async) binder_wakeup_thread_ilocked(proc, thread, !oneway /* sync */); -- GitLab