View Issue Details

IDProjectCategoryView StatusLast Update
0003253Kali LinuxGeneral Bugpublic2018-01-29 12:33
Reportersomeid Assigned Tog0tmi1k  
PrioritynormalSeverityblockReproducibilityrandom
Status closedResolutionsuspended 
Product Version2016.1 
Summary0003253: Kernel Crash on Baytrail-T
Description

Due to some SDIO/C-states-related Baytrail-T Platform weirdness, kernel crashes when system enters some deep C-state;

Steps To Reproduce

Just boot Linux and wait 1 to 5 minutes to have it crash and become uresponsive

Additional Information

Patches available @ https://github.com/hadess/rtl8723bs/tree/master/patches will solve the problem; relevant Patches for kernel >=4.4 are:

0001-PM-QoS-Add-pm_qos_cancel_request_lazy-that-doesn-t-s.patch
0001-mmc-sdhci-get-runtime-pm-when-sdio-irq-is-enabled.patch
0002-mmc-sdhci-Support-maximum-DMA-latency-request-via-PM.patch
0003-mmc-sdhci-acpi-Fix-device-hang-on-Intel-BayTrail.patch
0004b-mmc-sdhci-pci-Fix-device-hang-on-Intel-BayTrail.patch

Patches for kernel >=4.5 are available @ https://github.com/hadess/rtl8723bs/tree/master/patches_4.5

Please consider adding this patchset to the kernel; Baytrail-T devices are x86 powered, mostly passively-cooled mini-pcs, sporting an integrated battery more often than not, lightweight and extremely portable; making them perfect platforms for covert ops.

Attached Files
baytrail-t-4.4.6_consolidated_sdio-kali.patch (9,956 bytes)   
Description: <short summary of the patch>
 TODO: Put a short summary on the line above and replace this paragraph
 with a longer explanation of this change. Complete the meta-information
 with other relevant fields (see below for details). To make it easier, the
 information below has been extracted from the changelog. Adjust it or drop
 it.
 .
 linux (4.4.6-1kali1) kali-dev; urgency=medium
 .
   * Import new version from debian
   * Drop bugfix/x86/x86-efi-dont-free-reserved-regions.patch: it's in Debian
     bugfix/x86/x86-efi-fix-boot-crash-by-always-mapping-boot-servic.patch
Author: Some Id <[email protected]>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: <YYYY-MM-DD>

--- linux-4.4.6.orig/drivers/mmc/host/sdhci-acpi.c
+++ linux-4.4.6/drivers/mmc/host/sdhci-acpi.c
@@ -43,6 +43,24 @@
 
 #include "sdhci.h"
 
+#ifdef CONFIG_X86
+#include <asm/cpu_device_id.h>
+static bool sdhci_acpi_on_byt(void)
+{
+	static const struct x86_cpu_id byt[] = {
+		{ X86_VENDOR_INTEL, 6, 0x37 },
+		{}
+	};
+
+	return x86_match_cpu(byt);
+}
+#else
+static bool sdhci_acpi_on_byt(void)
+{
+	return false;
+}
+#endif
+
 enum {
 	SDHCI_ACPI_SD_CD		= BIT(0),
 	SDHCI_ACPI_RUNTIME_PM		= BIT(1),
@@ -173,6 +191,14 @@ out:
 	return ret;
 }
 
+static void sdhci_acpi_int_dma_latency(struct sdhci_host *host)
+{
+	if (sdhci_acpi_on_byt()) {
+		host->dma_latency = 20;
+		host->lat_cancel_delay = 275;
+	}
+}
+
 static int sdhci_acpi_emmc_probe_slot(struct platform_device *pdev,
 				      const char *hid, const char *uid)
 {
@@ -191,6 +217,8 @@ static int sdhci_acpi_emmc_probe_slot(st
 	    sdhci_readl(host, SDHCI_CAPABILITIES_1) == 0x00000807)
 		host->timeout_clk = 1000; /* 1000 kHz i.e. 1 MHz */
 
+	sdhci_acpi_int_dma_latency(host);
+
 	return 0;
 }
 
@@ -205,6 +233,8 @@ static int sdhci_acpi_sdio_probe_slot(st
 
 	host = c->host;
 
+	sdhci_acpi_int_dma_latency(host);
+
 	/* Platform specific code during sdio probe slot goes here */
 
 	return 0;
@@ -221,6 +251,8 @@ static int sdhci_acpi_sd_probe_slot(stru
 
 	host = c->host;
 
+	sdhci_acpi_int_dma_latency(host);
+
 	/* Platform specific code during sd probe slot goes here */
 
 	if (hid && !strcmp(hid, "80865ACA"))
--- linux-4.4.6.orig/drivers/mmc/host/sdhci-pci-core.c
+++ linux-4.4.6/drivers/mmc/host/sdhci-pci-core.c
@@ -357,6 +357,12 @@ out:
 	return ret;
 }
 
+static void byt_set_dma_latency(struct sdhci_host *host)
+{
+	host->dma_latency = 20;
+	host->lat_cancel_delay = 275;
+}
+
 static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
 {
 	slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
@@ -365,6 +371,9 @@ static int byt_emmc_probe_slot(struct sd
 				 MMC_CAP_WAIT_WHILE_BUSY;
 	slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ;
 	slot->hw_reset = sdhci_pci_int_hw_reset;
+	if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BYT_EMMC ||
+	    slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BYT_EMMC2)
+		byt_set_dma_latency(slot->host);
 	if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BSW_EMMC)
 		slot->host->timeout_clk = 1000; /* 1000 kHz i.e. 1 MHz */
 	if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_SPT_EMMC) {
@@ -379,6 +388,8 @@ static int byt_sdio_probe_slot(struct sd
 	slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
 				 MMC_CAP_BUS_WIDTH_TEST |
 				 MMC_CAP_WAIT_WHILE_BUSY;
+	if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BYT_SDIO)
+		byt_set_dma_latency(slot->host);
 	return 0;
 }
 
@@ -389,6 +400,9 @@ static int byt_sd_probe_slot(struct sdhc
 	slot->cd_con_id = NULL;
 	slot->cd_idx = 0;
 	slot->cd_override_level = true;
+	if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BYT_SD)
+		byt_set_dma_latency(slot->host);
+
 	if (slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_BXT_SD ||
 	    slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_APL_SD)
 		slot->host->mmc_host_ops.get_cd = bxt_get_cd;
--- linux-4.4.6.orig/drivers/mmc/host/sdhci.c
+++ linux-4.4.6/drivers/mmc/host/sdhci.c
@@ -725,6 +725,45 @@ static void sdhci_set_timeout(struct sdh
 	}
 }
 
+static bool sdhci_pm_qos_use_dma_latency(struct sdhci_host *host)
+{
+	return host->dma_latency != PM_QOS_DEFAULT_VALUE;
+}
+
+static void sdhci_pm_qos_set_dma_latency(struct sdhci_host *host,
+					 struct mmc_request *mrq)
+{
+	if (sdhci_pm_qos_use_dma_latency(host) && mrq->data &&
+	    (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))) {
+		pm_qos_update_request(&host->pm_qos_req, host->dma_latency);
+		host->pm_qos_set = true;
+	}
+}
+
+static void sdhci_pm_qos_unset(struct sdhci_host *host)
+{
+	unsigned int delay;
+
+	if (host->pm_qos_set) {
+		host->pm_qos_set = false;
+		delay = host->consecutive_req ? host->lat_cancel_delay : 0;
+		pm_qos_cancel_request_lazy(&host->pm_qos_req, delay);
+	}
+}
+
+static void sdhci_pm_qos_add(struct sdhci_host *host)
+{
+	if (sdhci_pm_qos_use_dma_latency(host))
+		pm_qos_add_request(&host->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
+				   PM_QOS_DEFAULT_VALUE);
+}
+
+static void sdhci_pm_qos_remove(struct sdhci_host *host)
+{
+	if (pm_qos_request_active(&host->pm_qos_req))
+		pm_qos_remove_request(&host->pm_qos_req);
+}
+
 static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
 {
 	u8 ctrl;
@@ -1366,6 +1405,8 @@ static void sdhci_request(struct mmc_hos
 
 	sdhci_runtime_pm_get(host);
 
+	sdhci_pm_qos_set_dma_latency(host, mrq);
+
 	/* Firstly check card presence */
 	present = mmc->ops->get_cd(mmc);
 
@@ -1389,6 +1430,7 @@ static void sdhci_request(struct mmc_hos
 	}
 
 	host->mrq = mrq;
+	host->consecutive_req = 0;
 
 	if (!present || host->flags & SDHCI_DEVICE_DEAD) {
 		host->mrq->cmd->error = -ENOMEDIUM;
@@ -1734,7 +1776,8 @@ static void sdhci_enable_sdio_irq(struct
 	struct sdhci_host *host = mmc_priv(mmc);
 	unsigned long flags;
 
-	sdhci_runtime_pm_get(host);
+	if (enable)
+		sdhci_runtime_pm_get(host);
 
 	spin_lock_irqsave(&host->lock, flags);
 	if (enable)
@@ -1745,7 +1788,8 @@ static void sdhci_enable_sdio_irq(struct
 	sdhci_enable_sdio_irq_nolock(host, enable);
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	sdhci_runtime_pm_put(host);
+	if (!enable)
+		sdhci_runtime_pm_put(host);
 }
 
 static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
@@ -2166,7 +2210,12 @@ static void sdhci_pre_req(struct mmc_hos
 {
 	struct sdhci_host *host = mmc_priv(mmc);
 
-	mrq->data->host_cookie = COOKIE_UNMAPPED;
+	host->consecutive_req = 1;
+
+	if (mrq->data->host_cookie) {
+		mrq->data->host_cookie = COOKIE_UNMAPPED;
+		return;
+	}
 
 	if (host->flags & SDHCI_REQ_USE_DMA)
 		sdhci_pre_dma_transfer(host, mrq->data);
@@ -2234,6 +2283,8 @@ static void sdhci_tasklet_finish(unsigne
 
 	host = (struct sdhci_host*)param;
 
+	sdhci_pm_qos_unset(host);
+
 	spin_lock_irqsave(&host->lock, flags);
 
         /*
@@ -2864,6 +2915,7 @@ struct sdhci_host *sdhci_alloc_host(stru
 
 	host = mmc_priv(mmc);
 	host->mmc = mmc;
+	host->dma_latency = PM_QOS_DEFAULT_VALUE;
 	host->mmc_host_ops = sdhci_ops;
 	mmc->ops = &host->mmc_host_ops;
 
@@ -3360,6 +3412,8 @@ int sdhci_add_host(struct sdhci_host *ho
 	 */
 	mmc->max_blk_count = (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535;
 
+	sdhci_pm_qos_add(host);
+
 	/*
 	 * Init tasklets.
 	 */
@@ -3423,6 +3477,7 @@ reset:
 #endif
 untasklet:
 	tasklet_kill(&host->finish_tasklet);
+	sdhci_pm_qos_remove(host);
 
 	return ret;
 }
@@ -3479,6 +3534,8 @@ void sdhci_remove_host(struct sdhci_host
 
 	host->adma_table = NULL;
 	host->align_buffer = NULL;
+
+	sdhci_pm_qos_remove(host);
 }
 
 EXPORT_SYMBOL_GPL(sdhci_remove_host);
--- linux-4.4.6.orig/drivers/mmc/host/sdhci.h
+++ linux-4.4.6/drivers/mmc/host/sdhci.h
@@ -19,6 +19,7 @@
 #include <linux/io.h>
 
 #include <linux/mmc/host.h>
+#include <linux/pm_qos.h>
 
 /*
  * Controller registers
@@ -428,6 +429,12 @@ struct sdhci_host {
 	struct mmc_host_ops mmc_host_ops;	/* MMC host ops */
 	u64 dma_mask;		/* custom DMA mask */
 
+	struct pm_qos_request pm_qos_req;
+	int dma_latency;
+	int lat_cancel_delay;
+	int consecutive_req;
+	bool pm_qos_set;
+
 #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
 	struct led_classdev led;	/* LED control */
 	char led_name[32];
--- linux-4.4.6.orig/include/linux/pm_qos.h
+++ linux-4.4.6/include/linux/pm_qos.h
@@ -126,6 +126,8 @@ void pm_qos_update_request(struct pm_qos
 			   s32 new_value);
 void pm_qos_update_request_timeout(struct pm_qos_request *req,
 				   s32 new_value, unsigned long timeout_us);
+void pm_qos_cancel_request_lazy(struct pm_qos_request *req,
+				unsigned int timeout_us);
 void pm_qos_remove_request(struct pm_qos_request *req);
 
 int pm_qos_request(int pm_qos_class);
--- linux-4.4.6.orig/kernel/power/qos.c
+++ linux-4.4.6/kernel/power/qos.c
@@ -517,6 +517,26 @@ void pm_qos_update_request_timeout(struc
 }
 
 /**
+ * pm_qos_cancel_request_lazy - cancels an existing qos request lazily.
+ * @req : handle to list element holding a pm_qos request to use
+ * @timeout_us: the delay before cancelling this qos request in usecs.
+ *
+ * After timeout_us, this qos request is cancelled.
+ */
+void pm_qos_cancel_request_lazy(struct pm_qos_request *req,
+				unsigned int timeout_us)
+{
+	if (!req)
+		return;
+	if (WARN(!pm_qos_request_active(req),
+		 "%s called for unknown object.", __func__))
+		return;
+
+	schedule_delayed_work(&req->work, usecs_to_jiffies(timeout_us));
+}
+EXPORT_SYMBOL_GPL(pm_qos_cancel_request_lazy);
+
+/**
  * pm_qos_remove_request - modifies an existing qos request
  * @req: handle to request list element
  *

Activities

someid

someid

2016-04-25 13:08

reporter   ~0005158

I took the liberty of refreshing the patches to cleanly apply on kali 4.4.6 kernel, and consolidating them into 1 patch, you'll find it attached.

rhertzog

rhertzog

2016-04-25 13:42

administrator   ~0005159

Why aren't those patches submitted for inclusion in the upstream kernel? We don't add random patches to our kernel. We can cherry-pick patches from newer kernels or from stable release kernels but otherwise we try to avoid merging other patches.

someid

someid

2016-04-25 18:10

reporter   ~0005160

Last edited: 2016-04-25 18:21

As it seems, these patches were slated for submission into linux-next sometime ago; I think Intel dropped linux support for BYT platform for political reasons I'm not aware of; they could possibly be included as they're needed for realtek 8723bs sdio wifi card (wich you can find on BYT devices) to work properly without crashing the whole OS.

As for being random patches, I disagree, they're written by Adrian Hunter (engineer @ Intel) and Dong Aisheng (engineer @ Freescale); they've been posted on the Linux MMC mailing list. Please see http://thread.gmane.org/gmane.linux.kernel.mmc/25081/focus=25087 and http://thread.gmane.org/gmane.linux.kernel.mmc/31583

They're actively maintained and adapted for newer kernel releases by Larry Finger; working on realtek wifi chipsets for the linux kernel and posting regularly on the linux-wireless mailing list.

This code is not (yet) mainline, but it's not random either; attribution is clear; functionality is needed for linux to support baytrail platforms; I don't know why it's still not merged though.

Maybe a baytrail flavor could be added to the kernel source package; labeled as experimental and only present in an experimental baytrail-compatible kali (minimal/netinst) iso.

Just my 2 cents.

g0tmi1k

g0tmi1k

2018-01-29 12:33

administrator   ~0008159

Due to the age of the OS (Kali Moto [v1], Kali Safi [v2], Kali Rolling 2016.x), these legacy versions are no longer supported.
We will be closing this ticket due to inactivity.

Please could you see if you are able to replicate this issue with the latest version of Kali Linux - https://www.kali.org/downloads/)?

If you are still facing the same problem, feel free to re-open the ticket. If you choose to do this, could you provide more information to the issue you are facing,and also give information about your setup?
For more information, please read: https://kali.training/topic/filing-a-good-bug-report/

Issue History

Date Modified Username Field Change
2016-04-25 12:14 someid New Issue
2016-04-25 13:08 someid Note Added: 0005158
2016-04-25 13:08 someid File Added: baytrail-t-4.4.6_consolidated_sdio-kali.patch
2016-04-25 13:42 rhertzog Note Added: 0005159
2016-04-25 18:10 someid Note Added: 0005160
2016-04-25 18:21 someid Note Edited: 0005160
2018-01-29 12:33 g0tmi1k Assigned To => g0tmi1k
2018-01-29 12:33 g0tmi1k Status new => closed
2018-01-29 12:33 g0tmi1k Resolution open => suspended
2018-01-29 12:33 g0tmi1k Note Added: 0008159