From 67de6bf1e4f869a490656448f471fdc4a0a405ad Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Thu, 29 Jun 2017 09:40:02 +0300 Subject: mei: me: enable asynchronous probing On some platforms, currently Broxton, Apollo Lake and Kaby Lake, ME FW may be busy with internal bookkeeping and answering late to the start message. As a mitigation, the driver requests for a synchronous probing to prevent stalling of the overall boot process. For example, on a Apollo Lake platform the overall boot time has reduced from ~0.9 to ~0.6 seconds on average. Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/pci-me.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/misc') diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 8621a198a2ce..8bf9a3d9792d 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -485,6 +485,7 @@ static struct pci_driver mei_me_driver = { .remove = mei_me_remove, .shutdown = mei_me_shutdown, .driver.pm = MEI_ME_PM_OPS, + .driver.probe_type = PROBE_PREFER_ASYNCHRONOUS, }; module_pci_driver(mei_me_driver); -- cgit v1.2.3 From f5ac3c49ff0b36d9b6a804b4b86efcaf27ba044b Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 14 Jun 2017 10:03:15 +0300 Subject: mei: me: use an index instead of a pointer for private data Device 'new_id' interface is useful for testing of not yet published hardware on older kernels and for internally used device ids on simulation platforms. However currently with the device configuration held in device_id driver data as a pointer to mei_cfg structure it is hard, as one need to locate the address of the correct structure. A recommended way of doing that is to use and index instead of a pointer. This patch adds a new list of configuration mei_cfg_list[] indexed via enum mei_cfg_idx. In addition it cleanups ich platform naming, renames legacy generation to ich and what was ich to ich10. Signed-off-by: Tomas Winkler Signed-off-by: Alexander Usyskin Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me.c | 45 ++++++++++++++----- drivers/misc/mei/hw-me.h | 39 +++++++++++++---- drivers/misc/mei/pci-me.c | 108 ++++++++++++++++++++++++---------------------- 3 files changed, 121 insertions(+), 71 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 71216affcab1..10dcf4ff99a5 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -1354,10 +1354,10 @@ static bool mei_me_fw_type_sps(struct pci_dev *pdev) .quirk_probe = mei_me_fw_type_sps -#define MEI_CFG_LEGACY_HFS \ +#define MEI_CFG_ICH_HFS \ .fw_status.count = 0 -#define MEI_CFG_ICH_HFS \ +#define MEI_CFG_ICH10_HFS \ .fw_status.count = 1, \ .fw_status.status[0] = PCI_CFG_HFS_1 @@ -1376,38 +1376,61 @@ static bool mei_me_fw_type_sps(struct pci_dev *pdev) .fw_status.status[5] = PCI_CFG_HFS_6 /* ICH Legacy devices */ -const struct mei_cfg mei_me_legacy_cfg = { - MEI_CFG_LEGACY_HFS, +static const struct mei_cfg mei_me_ich_cfg = { + MEI_CFG_ICH_HFS, }; /* ICH devices */ -const struct mei_cfg mei_me_ich_cfg = { - MEI_CFG_ICH_HFS, +static const struct mei_cfg mei_me_ich10_cfg = { + MEI_CFG_ICH10_HFS, }; /* PCH devices */ -const struct mei_cfg mei_me_pch_cfg = { +static const struct mei_cfg mei_me_pch_cfg = { MEI_CFG_PCH_HFS, }; - /* PCH Cougar Point and Patsburg with quirk for Node Manager exclusion */ -const struct mei_cfg mei_me_pch_cpt_pbg_cfg = { +static const struct mei_cfg mei_me_pch_cpt_pbg_cfg = { MEI_CFG_PCH_HFS, MEI_CFG_FW_NM, }; /* PCH8 Lynx Point and newer devices */ -const struct mei_cfg mei_me_pch8_cfg = { +static const struct mei_cfg mei_me_pch8_cfg = { MEI_CFG_PCH8_HFS, }; /* PCH8 Lynx Point with quirk for SPS Firmware exclusion */ -const struct mei_cfg mei_me_pch8_sps_cfg = { +static const struct mei_cfg mei_me_pch8_sps_cfg = { MEI_CFG_PCH8_HFS, MEI_CFG_FW_SPS, }; +/* + * mei_cfg_list - A list of platform platform specific configurations. + * Note: has to be synchronized with enum mei_cfg_idx. + */ +static const struct mei_cfg *const mei_cfg_list[] = { + [MEI_ME_UNDEF_CFG] = NULL, + [MEI_ME_ICH_CFG] = &mei_me_ich_cfg, + [MEI_ME_ICH10_CFG] = &mei_me_ich10_cfg, + [MEI_ME_PCH_CFG] = &mei_me_pch_cfg, + [MEI_ME_PCH_CPT_PBG_CFG] = &mei_me_pch_cpt_pbg_cfg, + [MEI_ME_PCH8_CFG] = &mei_me_pch8_cfg, + [MEI_ME_PCH8_SPS_CFG] = &mei_me_pch8_sps_cfg, +}; + +const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx) +{ + BUILD_BUG_ON(ARRAY_SIZE(mei_cfg_list) != MEI_ME_NUM_CFG); + + if (idx >= MEI_ME_NUM_CFG) + return NULL; + + return mei_cfg_list[idx]; +}; + /** * mei_me_dev_init - allocates and initializes the mei device structure * diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h index cf64847a35b9..67892533576e 100644 --- a/drivers/misc/mei/hw-me.h +++ b/drivers/misc/mei/hw-me.h @@ -41,8 +41,7 @@ struct mei_cfg { #define MEI_PCI_DEVICE(dev, cfg) \ .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, \ - .driver_data = (kernel_ulong_t)&(cfg) - + .driver_data = (kernel_ulong_t)(cfg), #define MEI_ME_RPM_TIMEOUT 500 /* ms */ @@ -63,12 +62,36 @@ struct mei_me_hw { #define to_me_hw(dev) (struct mei_me_hw *)((dev)->hw) -extern const struct mei_cfg mei_me_legacy_cfg; -extern const struct mei_cfg mei_me_ich_cfg; -extern const struct mei_cfg mei_me_pch_cfg; -extern const struct mei_cfg mei_me_pch_cpt_pbg_cfg; -extern const struct mei_cfg mei_me_pch8_cfg; -extern const struct mei_cfg mei_me_pch8_sps_cfg; +/** + * enum mei_cfg_idx - indices to platform specific configurations. + * + * Note: has to be synchronized with mei_cfg_list[] + * + * @MEI_ME_UNDEF_CFG: Lower sentinel. + * @MEI_ME_ICH_CFG: I/O Controller Hub legacy devices. + * @MEI_ME_ICH10_CFG: I/O Controller Hub platforms Gen10 + * @MEI_ME_PCH_CFG: Platform Controller Hub platforms (Up to Gen8). + * @MEI_ME_PCH_CPT_PBG_CFG:Platform Controller Hub workstations + * with quirk for Node Manager exclusion. + * @MEI_ME_PCH8_CFG: Platform Controller Hub Gen8 and newer + * client platforms. + * @MEI_ME_PCH8_SPS_CFG: Platform Controller Hub Gen8 and newer + * servers platforms with quirk for + * SPS firmware exclusion. + * @MEI_ME_NUM_CFG: Upper Sentinel. + */ +enum mei_cfg_idx { + MEI_ME_UNDEF_CFG, + MEI_ME_ICH_CFG, + MEI_ME_ICH10_CFG, + MEI_ME_PCH_CFG, + MEI_ME_PCH_CPT_PBG_CFG, + MEI_ME_PCH8_CFG, + MEI_ME_PCH8_SPS_CFG, + MEI_ME_NUM_CFG, +}; + +const struct mei_cfg *mei_me_get_cfg(kernel_ulong_t idx); struct mei_device *mei_me_dev_init(struct pci_dev *pdev, const struct mei_cfg *cfg); diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 8bf9a3d9792d..3f4e36b8892f 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -43,57 +43,58 @@ /* mei_pci_tbl - PCI Device ID Table */ static const struct pci_device_id mei_me_pci_tbl[] = { - {MEI_PCI_DEVICE(MEI_DEV_ID_82946GZ, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_82G35, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_82Q965, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_82G965, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_82GM965, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_82GME965, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82Q35, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82G33, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82Q33, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82X38, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_3200, mei_me_legacy_cfg)}, - - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_6, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_7, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_8, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_9, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_10, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_1, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_2, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_3, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_4, mei_me_legacy_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_1, mei_me_ich_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_2, mei_me_ich_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_3, mei_me_ich_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_4, mei_me_ich_cfg)}, - - {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_1, mei_me_pch_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_2, mei_me_pch_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_CPT_1, mei_me_pch_cpt_pbg_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_PBG_1, mei_me_pch_cpt_pbg_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, mei_me_pch_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, mei_me_pch_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, mei_me_pch_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, mei_me_pch8_sps_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, mei_me_pch8_sps_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, mei_me_pch8_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, mei_me_pch8_sps_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, mei_me_pch8_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP_2, mei_me_pch8_cfg)}, - - {MEI_PCI_DEVICE(MEI_DEV_ID_SPT, mei_me_pch8_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, mei_me_pch8_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, mei_me_pch8_sps_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, mei_me_pch8_sps_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_LBG, mei_me_pch8_cfg)}, - - {MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, mei_me_pch8_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, mei_me_pch8_cfg)}, - - {MEI_PCI_DEVICE(MEI_DEV_ID_KBP, mei_me_pch8_cfg)}, - {MEI_PCI_DEVICE(MEI_DEV_ID_KBP_2, mei_me_pch8_cfg)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_82946GZ, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_82G35, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_82Q965, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_82G965, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_82GM965, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_82GME965, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82Q35, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82G33, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82Q33, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_82X38, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_3200, MEI_ME_ICH_CFG)}, + + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_6, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_7, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_8, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_9, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9_10, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_1, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_2, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_3, MEI_ME_ICH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH9M_4, MEI_ME_ICH_CFG)}, + + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_1, MEI_ME_ICH10_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_2, MEI_ME_ICH10_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_3, MEI_ME_ICH10_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_4, MEI_ME_ICH10_CFG)}, + + {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_1, MEI_ME_PCH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_2, MEI_ME_PCH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_CPT_1, MEI_ME_PCH_CPT_PBG_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_PBG_1, MEI_ME_PCH_CPT_PBG_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, MEI_ME_PCH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, MEI_ME_PCH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, MEI_ME_PCH_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, MEI_ME_PCH8_SPS_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, MEI_ME_PCH8_SPS_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, MEI_ME_PCH8_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, MEI_ME_PCH8_SPS_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, MEI_ME_PCH8_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP_2, MEI_ME_PCH8_CFG)}, + + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT, MEI_ME_PCH8_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, MEI_ME_PCH8_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, MEI_ME_PCH8_SPS_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, MEI_ME_PCH8_SPS_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_LBG, MEI_ME_PCH8_CFG)}, + + {MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, MEI_ME_PCH8_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, MEI_ME_PCH8_CFG)}, + + {MEI_PCI_DEVICE(MEI_DEV_ID_KBP, MEI_ME_PCH8_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_KBP_2, MEI_ME_PCH8_CFG)}, /* required last entry */ {0, } @@ -138,12 +139,15 @@ static bool mei_me_quirk_probe(struct pci_dev *pdev, */ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - const struct mei_cfg *cfg = (struct mei_cfg *)(ent->driver_data); + const struct mei_cfg *cfg; struct mei_device *dev; struct mei_me_hw *hw; unsigned int irqflags; int err; + cfg = mei_me_get_cfg(ent->driver_data); + if (!cfg) + return -ENODEV; if (!mei_me_quirk_probe(pdev, cfg)) return -ENODEV; -- cgit v1.2.3 From 2dee584bc9e3c75afc2c85f107e516c58a8efaf3 Mon Sep 17 00:00:00 2001 From: Patrick Venture Date: Thu, 6 Jul 2017 10:03:46 -0700 Subject: drivers/misc: (aspeed-lpc-snoop): Add ast2400 to compat This driver can be used on the aspeed ast2400 with minor modifications. Tested: ast2400 on quanta-q71l Signed-off-by: Patrick Venture Signed-off-by: Greg Kroah-Hartman --- drivers/misc/aspeed-lpc-snoop.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/aspeed-lpc-snoop.c b/drivers/misc/aspeed-lpc-snoop.c index 593905565b74..cb78c98bc78d 100644 --- a/drivers/misc/aspeed-lpc-snoop.c +++ b/drivers/misc/aspeed-lpc-snoop.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,13 @@ #define HICRB_ENSNP0D BIT(14) #define HICRB_ENSNP1D BIT(15) +struct aspeed_lpc_snoop_model_data { + /* The ast2400 has bits 14 and 15 as reserved, whereas the ast2500 + * can use them. + */ + unsigned int has_hicrb_ensnp; +}; + struct aspeed_lpc_snoop { struct regmap *regmap; int irq; @@ -123,10 +131,13 @@ static int aspeed_lpc_snoop_config_irq(struct aspeed_lpc_snoop *lpc_snoop, } static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop, - int channel, u16 lpc_port) + struct device *dev, + int channel, u16 lpc_port) { int rc = 0; u32 hicr5_en, snpwadr_mask, snpwadr_shift, hicrb_en; + const struct aspeed_lpc_snoop_model_data *model_data = + of_device_get_match_data(dev); /* Create FIFO datastructure */ rc = kfifo_alloc(&lpc_snoop->snoop_fifo[channel], @@ -155,7 +166,9 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop, regmap_update_bits(lpc_snoop->regmap, HICR5, hicr5_en, hicr5_en); regmap_update_bits(lpc_snoop->regmap, SNPWADR, snpwadr_mask, lpc_port << snpwadr_shift); - regmap_update_bits(lpc_snoop->regmap, HICRB, hicrb_en, hicrb_en); + if (model_data->has_hicrb_ensnp) + regmap_update_bits(lpc_snoop->regmap, HICRB, + hicrb_en, hicrb_en); return rc; } @@ -213,14 +226,14 @@ static int aspeed_lpc_snoop_probe(struct platform_device *pdev) if (rc) return rc; - rc = aspeed_lpc_enable_snoop(lpc_snoop, 0, port); + rc = aspeed_lpc_enable_snoop(lpc_snoop, dev, 0, port); if (rc) return rc; /* Configuration of 2nd snoop channel port is optional */ if (of_property_read_u32_index(dev->of_node, "snoop-ports", 1, &port) == 0) { - rc = aspeed_lpc_enable_snoop(lpc_snoop, 1, port); + rc = aspeed_lpc_enable_snoop(lpc_snoop, dev, 1, port); if (rc) aspeed_lpc_disable_snoop(lpc_snoop, 0); } @@ -239,8 +252,19 @@ static int aspeed_lpc_snoop_remove(struct platform_device *pdev) return 0; } +static const struct aspeed_lpc_snoop_model_data ast2400_model_data = { + .has_hicrb_ensnp = 0, +}; + +static const struct aspeed_lpc_snoop_model_data ast2500_model_data = { + .has_hicrb_ensnp = 1, +}; + static const struct of_device_id aspeed_lpc_snoop_match[] = { - { .compatible = "aspeed,ast2500-lpc-snoop" }, + { .compatible = "aspeed,ast2400-lpc-snoop", + .data = &ast2400_model_data }, + { .compatible = "aspeed,ast2500-lpc-snoop", + .data = &ast2500_model_data }, { }, }; -- cgit v1.2.3 From 95925c99b9043d52db626645e6ef5ee5f62c97e4 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 24 Apr 2017 13:23:21 -0700 Subject: lkdtm: Provide more complete coverage for REFCOUNT tests The existing REFCOUNT_* LKDTM tests were designed only for testing a narrow portion of CONFIG_REFCOUNT_FULL. This moves the tests to their own file and expands their testing to poke each boundary condition. Since the protections (CONFIG_REFCOUNT_FULL and x86-fast) use different saturation values and reach-zero behavior, those have to be build-time set so the tests can actually validate things are happening at the right places. Notably, the x86-fast protection will fail REFCOUNT_INC_ZERO and REFCOUNT_ADD_ZERO since those conditions are not checked (only overflow is critical to protecting refcount_t). CONFIG_REFCOUNT_FULL will warn for each REFCOUNT_*_NEGATIVE test since it provides zero-pinning behaviors (which allows it to pass REFCOUNT_INC_ZERO and REFCOUNT_ADD_ZERO). Signed-off-by: Kees Cook --- drivers/misc/Makefile | 1 + drivers/misc/lkdtm.h | 25 ++- drivers/misc/lkdtm_bugs.c | 83 ---------- drivers/misc/lkdtm_core.c | 23 ++- drivers/misc/lkdtm_refcount.c | 356 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 393 insertions(+), 95 deletions(-) create mode 100644 drivers/misc/lkdtm_refcount.c (limited to 'drivers/misc') diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b0b766416306..d84819dc2468 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -60,6 +60,7 @@ lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o lkdtm-$(CONFIG_LKDTM) += lkdtm_heap.o lkdtm-$(CONFIG_LKDTM) += lkdtm_perms.o +lkdtm-$(CONFIG_LKDTM) += lkdtm_refcount.o lkdtm-$(CONFIG_LKDTM) += lkdtm_rodata_objcopy.o lkdtm-$(CONFIG_LKDTM) += lkdtm_usercopy.o diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h index 3b4976396ec4..04ff8b23b3b0 100644 --- a/drivers/misc/lkdtm.h +++ b/drivers/misc/lkdtm.h @@ -19,12 +19,6 @@ void lkdtm_SOFTLOCKUP(void); void lkdtm_HARDLOCKUP(void); void lkdtm_SPINLOCKUP(void); void lkdtm_HUNG_TASK(void); -void lkdtm_REFCOUNT_SATURATE_INC(void); -void lkdtm_REFCOUNT_SATURATE_ADD(void); -void lkdtm_REFCOUNT_ZERO_DEC(void); -void lkdtm_REFCOUNT_ZERO_INC(void); -void lkdtm_REFCOUNT_ZERO_SUB(void); -void lkdtm_REFCOUNT_ZERO_ADD(void); void lkdtm_CORRUPT_LIST_ADD(void); void lkdtm_CORRUPT_LIST_DEL(void); void lkdtm_CORRUPT_USER_DS(void); @@ -49,6 +43,25 @@ void lkdtm_EXEC_RODATA(void); void lkdtm_EXEC_USERSPACE(void); void lkdtm_ACCESS_USERSPACE(void); +/* lkdtm_refcount.c */ +void lkdtm_REFCOUNT_INC_OVERFLOW(void); +void lkdtm_REFCOUNT_ADD_OVERFLOW(void); +void lkdtm_REFCOUNT_INC_NOT_ZERO_OVERFLOW(void); +void lkdtm_REFCOUNT_ADD_NOT_ZERO_OVERFLOW(void); +void lkdtm_REFCOUNT_DEC_ZERO(void); +void lkdtm_REFCOUNT_DEC_NEGATIVE(void); +void lkdtm_REFCOUNT_DEC_AND_TEST_NEGATIVE(void); +void lkdtm_REFCOUNT_SUB_AND_TEST_NEGATIVE(void); +void lkdtm_REFCOUNT_INC_ZERO(void); +void lkdtm_REFCOUNT_ADD_ZERO(void); +void lkdtm_REFCOUNT_INC_SATURATED(void); +void lkdtm_REFCOUNT_DEC_SATURATED(void); +void lkdtm_REFCOUNT_ADD_SATURATED(void); +void lkdtm_REFCOUNT_INC_NOT_ZERO_SATURATED(void); +void lkdtm_REFCOUNT_ADD_NOT_ZERO_SATURATED(void); +void lkdtm_REFCOUNT_DEC_AND_TEST_SATURATED(void); +void lkdtm_REFCOUNT_SUB_AND_TEST_SATURATED(void); + /* lkdtm_rodata.c */ void lkdtm_rodata_do_nothing(void); diff --git a/drivers/misc/lkdtm_bugs.c b/drivers/misc/lkdtm_bugs.c index d9028ef50fbe..ef3d06f901fc 100644 --- a/drivers/misc/lkdtm_bugs.c +++ b/drivers/misc/lkdtm_bugs.c @@ -6,7 +6,6 @@ */ #include "lkdtm.h" #include -#include #include #include #include @@ -137,88 +136,6 @@ void lkdtm_HUNG_TASK(void) schedule(); } -void lkdtm_REFCOUNT_SATURATE_INC(void) -{ - refcount_t over = REFCOUNT_INIT(UINT_MAX - 1); - - pr_info("attempting good refcount decrement\n"); - refcount_dec(&over); - refcount_inc(&over); - - pr_info("attempting bad refcount inc overflow\n"); - refcount_inc(&over); - refcount_inc(&over); - if (refcount_read(&over) == UINT_MAX) - pr_err("Correctly stayed saturated, but no BUG?!\n"); - else - pr_err("Fail: refcount wrapped\n"); -} - -void lkdtm_REFCOUNT_SATURATE_ADD(void) -{ - refcount_t over = REFCOUNT_INIT(UINT_MAX - 1); - - pr_info("attempting good refcount decrement\n"); - refcount_dec(&over); - refcount_inc(&over); - - pr_info("attempting bad refcount add overflow\n"); - refcount_add(2, &over); - if (refcount_read(&over) == UINT_MAX) - pr_err("Correctly stayed saturated, but no BUG?!\n"); - else - pr_err("Fail: refcount wrapped\n"); -} - -void lkdtm_REFCOUNT_ZERO_DEC(void) -{ - refcount_t zero = REFCOUNT_INIT(1); - - pr_info("attempting bad refcount decrement to zero\n"); - refcount_dec(&zero); - if (refcount_read(&zero) == 0) - pr_err("Stayed at zero, but no BUG?!\n"); - else - pr_err("Fail: refcount went crazy\n"); -} - -void lkdtm_REFCOUNT_ZERO_SUB(void) -{ - refcount_t zero = REFCOUNT_INIT(1); - - pr_info("attempting bad refcount subtract past zero\n"); - if (!refcount_sub_and_test(2, &zero)) - pr_info("wrap attempt was noticed\n"); - if (refcount_read(&zero) == 1) - pr_err("Correctly stayed above 0, but no BUG?!\n"); - else - pr_err("Fail: refcount wrapped\n"); -} - -void lkdtm_REFCOUNT_ZERO_INC(void) -{ - refcount_t zero = REFCOUNT_INIT(0); - - pr_info("attempting bad refcount increment from zero\n"); - refcount_inc(&zero); - if (refcount_read(&zero) == 0) - pr_err("Stayed at zero, but no BUG?!\n"); - else - pr_err("Fail: refcount went past zero\n"); -} - -void lkdtm_REFCOUNT_ZERO_ADD(void) -{ - refcount_t zero = REFCOUNT_INIT(0); - - pr_info("attempting bad refcount addition from zero\n"); - refcount_add(2, &zero); - if (refcount_read(&zero) == 0) - pr_err("Stayed at zero, but no BUG?!\n"); - else - pr_err("Fail: refcount went past zero\n"); -} - void lkdtm_CORRUPT_LIST_ADD(void) { /* diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c index 42d2b8e31e6b..156a1a07c3db 100644 --- a/drivers/misc/lkdtm_core.c +++ b/drivers/misc/lkdtm_core.c @@ -221,12 +221,23 @@ struct crashtype crashtypes[] = { CRASHTYPE(WRITE_RO), CRASHTYPE(WRITE_RO_AFTER_INIT), CRASHTYPE(WRITE_KERN), - CRASHTYPE(REFCOUNT_SATURATE_INC), - CRASHTYPE(REFCOUNT_SATURATE_ADD), - CRASHTYPE(REFCOUNT_ZERO_DEC), - CRASHTYPE(REFCOUNT_ZERO_INC), - CRASHTYPE(REFCOUNT_ZERO_SUB), - CRASHTYPE(REFCOUNT_ZERO_ADD), + CRASHTYPE(REFCOUNT_INC_OVERFLOW), + CRASHTYPE(REFCOUNT_ADD_OVERFLOW), + CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW), + CRASHTYPE(REFCOUNT_ADD_NOT_ZERO_OVERFLOW), + CRASHTYPE(REFCOUNT_DEC_ZERO), + CRASHTYPE(REFCOUNT_DEC_NEGATIVE), + CRASHTYPE(REFCOUNT_DEC_AND_TEST_NEGATIVE), + CRASHTYPE(REFCOUNT_SUB_AND_TEST_NEGATIVE), + CRASHTYPE(REFCOUNT_INC_ZERO), + CRASHTYPE(REFCOUNT_ADD_ZERO), + CRASHTYPE(REFCOUNT_INC_SATURATED), + CRASHTYPE(REFCOUNT_DEC_SATURATED), + CRASHTYPE(REFCOUNT_ADD_SATURATED), + CRASHTYPE(REFCOUNT_INC_NOT_ZERO_SATURATED), + CRASHTYPE(REFCOUNT_ADD_NOT_ZERO_SATURATED), + CRASHTYPE(REFCOUNT_DEC_AND_TEST_SATURATED), + CRASHTYPE(REFCOUNT_SUB_AND_TEST_SATURATED), CRASHTYPE(USERCOPY_HEAP_SIZE_TO), CRASHTYPE(USERCOPY_HEAP_SIZE_FROM), CRASHTYPE(USERCOPY_HEAP_FLAG_TO), diff --git a/drivers/misc/lkdtm_refcount.c b/drivers/misc/lkdtm_refcount.c new file mode 100644 index 000000000000..313abea4bf9d --- /dev/null +++ b/drivers/misc/lkdtm_refcount.c @@ -0,0 +1,356 @@ +/* + * This is for all the tests related to refcount bugs (e.g. overflow, + * underflow, reaching zero untested, etc). + */ +#include "lkdtm.h" +#include + +#ifdef CONFIG_REFCOUNT_FULL +#define REFCOUNT_MAX (UINT_MAX - 1) +#define REFCOUNT_SATURATED UINT_MAX +#else +#define REFCOUNT_MAX INT_MAX +#define REFCOUNT_SATURATED (INT_MIN / 2) +#endif + +static void overflow_check(refcount_t *ref) +{ + switch (refcount_read(ref)) { + case REFCOUNT_SATURATED: + pr_info("Overflow detected: saturated\n"); + break; + case REFCOUNT_MAX: + pr_warn("Overflow detected: unsafely reset to max\n"); + break; + default: + pr_err("Fail: refcount wrapped to %d\n", refcount_read(ref)); + } +} + +/* + * A refcount_inc() above the maximum value of the refcount implementation, + * should at least saturate, and at most also WARN. + */ +void lkdtm_REFCOUNT_INC_OVERFLOW(void) +{ + refcount_t over = REFCOUNT_INIT(REFCOUNT_MAX - 1); + + pr_info("attempting good refcount_inc() without overflow\n"); + refcount_dec(&over); + refcount_inc(&over); + + pr_info("attempting bad refcount_inc() overflow\n"); + refcount_inc(&over); + refcount_inc(&over); + + overflow_check(&over); +} + +/* refcount_add() should behave just like refcount_inc() above. */ +void lkdtm_REFCOUNT_ADD_OVERFLOW(void) +{ + refcount_t over = REFCOUNT_INIT(REFCOUNT_MAX - 1); + + pr_info("attempting good refcount_add() without overflow\n"); + refcount_dec(&over); + refcount_dec(&over); + refcount_dec(&over); + refcount_dec(&over); + refcount_add(4, &over); + + pr_info("attempting bad refcount_add() overflow\n"); + refcount_add(4, &over); + + overflow_check(&over); +} + +/* refcount_inc_not_zero() should behave just like refcount_inc() above. */ +void lkdtm_REFCOUNT_INC_NOT_ZERO_OVERFLOW(void) +{ + refcount_t over = REFCOUNT_INIT(REFCOUNT_MAX); + + pr_info("attempting bad refcount_inc_not_zero() overflow\n"); + if (!refcount_inc_not_zero(&over)) + pr_warn("Weird: refcount_inc_not_zero() reported zero\n"); + + overflow_check(&over); +} + +/* refcount_add_not_zero() should behave just like refcount_inc() above. */ +void lkdtm_REFCOUNT_ADD_NOT_ZERO_OVERFLOW(void) +{ + refcount_t over = REFCOUNT_INIT(REFCOUNT_MAX); + + pr_info("attempting bad refcount_add_not_zero() overflow\n"); + if (!refcount_add_not_zero(6, &over)) + pr_warn("Weird: refcount_add_not_zero() reported zero\n"); + + overflow_check(&over); +} + +static void check_zero(refcount_t *ref) +{ + switch (refcount_read(ref)) { + case REFCOUNT_SATURATED: + pr_info("Zero detected: saturated\n"); + break; + case REFCOUNT_MAX: + pr_warn("Zero detected: unsafely reset to max\n"); + break; + case 0: + pr_warn("Still at zero: refcount_inc/add() must not inc-from-0\n"); + break; + default: + pr_err("Fail: refcount went crazy: %d\n", refcount_read(ref)); + } +} + +/* + * A refcount_dec(), as opposed to a refcount_dec_and_test(), when it hits + * zero it should either saturate (when inc-from-zero isn't protected) + * or stay at zero (when inc-from-zero is protected) and should WARN for both. + */ +void lkdtm_REFCOUNT_DEC_ZERO(void) +{ + refcount_t zero = REFCOUNT_INIT(2); + + pr_info("attempting good refcount_dec()\n"); + refcount_dec(&zero); + + pr_info("attempting bad refcount_dec() to zero\n"); + refcount_dec(&zero); + + check_zero(&zero); +} + +static void check_negative(refcount_t *ref, int start) +{ + /* + * CONFIG_REFCOUNT_FULL refuses to move a refcount at all on an + * over-sub, so we have to track our starting position instead of + * looking only at zero-pinning. + */ + if (refcount_read(ref) == start) { + pr_warn("Still at %d: refcount_inc/add() must not inc-from-0\n", + start); + return; + } + + switch (refcount_read(ref)) { + case REFCOUNT_SATURATED: + pr_info("Negative detected: saturated\n"); + break; + case REFCOUNT_MAX: + pr_warn("Negative detected: unsafely reset to max\n"); + break; + default: + pr_err("Fail: refcount went crazy: %d\n", refcount_read(ref)); + } +} + +/* A refcount_dec() going negative should saturate and may WARN. */ +void lkdtm_REFCOUNT_DEC_NEGATIVE(void) +{ + refcount_t neg = REFCOUNT_INIT(0); + + pr_info("attempting bad refcount_dec() below zero\n"); + refcount_dec(&neg); + + check_negative(&neg, 0); +} + +/* + * A refcount_dec_and_test() should act like refcount_dec() above when + * going negative. + */ +void lkdtm_REFCOUNT_DEC_AND_TEST_NEGATIVE(void) +{ + refcount_t neg = REFCOUNT_INIT(0); + + pr_info("attempting bad refcount_dec_and_test() below zero\n"); + if (refcount_dec_and_test(&neg)) + pr_warn("Weird: refcount_dec_and_test() reported zero\n"); + + check_negative(&neg, 0); +} + +/* + * A refcount_sub_and_test() should act like refcount_dec_and_test() + * above when going negative. + */ +void lkdtm_REFCOUNT_SUB_AND_TEST_NEGATIVE(void) +{ + refcount_t neg = REFCOUNT_INIT(3); + + pr_info("attempting bad refcount_sub_and_test() below zero\n"); + if (refcount_sub_and_test(5, &neg)) + pr_warn("Weird: refcount_sub_and_test() reported zero\n"); + + check_negative(&neg, 3); +} + +static void check_from_zero(refcount_t *ref) +{ + switch (refcount_read(ref)) { + case 0: + pr_info("Zero detected: stayed at zero\n"); + break; + case REFCOUNT_SATURATED: + pr_info("Zero detected: saturated\n"); + break; + case REFCOUNT_MAX: + pr_warn("Zero detected: unsafely reset to max\n"); + break; + default: + pr_info("Fail: zero not detected, incremeted to %d\n", + refcount_read(ref)); + } +} + +/* + * A refcount_inc() from zero should pin to zero or saturate and may WARN. + * Only CONFIG_REFCOUNT_FULL provides this protection currently. + */ +void lkdtm_REFCOUNT_INC_ZERO(void) +{ + refcount_t zero = REFCOUNT_INIT(0); + + pr_info("attempting safe refcount_inc_not_zero() from zero\n"); + if (!refcount_inc_not_zero(&zero)) { + pr_info("Good: zero detected\n"); + if (refcount_read(&zero) == 0) + pr_info("Correctly stayed at zero\n"); + else + pr_err("Fail: refcount went past zero!\n"); + } else { + pr_err("Fail: Zero not detected!?\n"); + } + + pr_info("attempting bad refcount_inc() from zero\n"); + refcount_inc(&zero); + + check_from_zero(&zero); +} + +/* + * A refcount_add() should act like refcount_inc() above when starting + * at zero. + */ +void lkdtm_REFCOUNT_ADD_ZERO(void) +{ + refcount_t zero = REFCOUNT_INIT(0); + + pr_info("attempting safe refcount_add_not_zero() from zero\n"); + if (!refcount_add_not_zero(3, &zero)) { + pr_info("Good: zero detected\n"); + if (refcount_read(&zero) == 0) + pr_info("Correctly stayed at zero\n"); + else + pr_err("Fail: refcount went past zero\n"); + } else { + pr_err("Fail: Zero not detected!?\n"); + } + + pr_info("attempting bad refcount_add() from zero\n"); + refcount_add(3, &zero); + + check_from_zero(&zero); +} + +static void check_saturated(refcount_t *ref) +{ + switch (refcount_read(ref)) { + case REFCOUNT_SATURATED: + pr_info("Saturation detected: still saturated\n"); + break; + case REFCOUNT_MAX: + pr_warn("Saturation detected: unsafely reset to max\n"); + break; + default: + pr_err("Fail: refcount went crazy: %d\n", refcount_read(ref)); + } +} + +/* + * A refcount_inc() from a saturated value should at most warn about + * being saturated already. + */ +void lkdtm_REFCOUNT_INC_SATURATED(void) +{ + refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); + + pr_info("attempting bad refcount_inc() from saturated\n"); + refcount_inc(&sat); + + check_saturated(&sat); +} + +/* Should act like refcount_inc() above from saturated. */ +void lkdtm_REFCOUNT_DEC_SATURATED(void) +{ + refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); + + pr_info("attempting bad refcount_dec() from saturated\n"); + refcount_dec(&sat); + + check_saturated(&sat); +} + +/* Should act like refcount_inc() above from saturated. */ +void lkdtm_REFCOUNT_ADD_SATURATED(void) +{ + refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); + + pr_info("attempting bad refcount_dec() from saturated\n"); + refcount_add(8, &sat); + + check_saturated(&sat); +} + +/* Should act like refcount_inc() above from saturated. */ +void lkdtm_REFCOUNT_INC_NOT_ZERO_SATURATED(void) +{ + refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); + + pr_info("attempting bad refcount_inc_not_zero() from saturated\n"); + if (!refcount_inc_not_zero(&sat)) + pr_warn("Weird: refcount_inc_not_zero() reported zero\n"); + + check_saturated(&sat); +} + +/* Should act like refcount_inc() above from saturated. */ +void lkdtm_REFCOUNT_ADD_NOT_ZERO_SATURATED(void) +{ + refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); + + pr_info("attempting bad refcount_add_not_zero() from saturated\n"); + if (!refcount_add_not_zero(7, &sat)) + pr_warn("Weird: refcount_add_not_zero() reported zero\n"); + + check_saturated(&sat); +} + +/* Should act like refcount_inc() above from saturated. */ +void lkdtm_REFCOUNT_DEC_AND_TEST_SATURATED(void) +{ + refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); + + pr_info("attempting bad refcount_dec_and_test() from saturated\n"); + if (refcount_dec_and_test(&sat)) + pr_warn("Weird: refcount_dec_and_test() reported zero\n"); + + check_saturated(&sat); +} + +/* Should act like refcount_inc() above from saturated. */ +void lkdtm_REFCOUNT_SUB_AND_TEST_SATURATED(void) +{ + refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); + + pr_info("attempting bad refcount_sub_and_test() from saturated\n"); + if (refcount_sub_and_test(8, &sat)) + pr_warn("Weird: refcount_sub_and_test() reported zero\n"); + + check_saturated(&sat); +} -- cgit v1.2.3 From c7fea48876773603721f545f8c1a2f894291ef85 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 21 Jul 2017 06:19:14 -0700 Subject: lkdtm: Provide timing tests for atomic_t vs refcount_t While not a crash test, this does provide two tight atomic_t and refcount_t loops for performance comparisons: cd /sys/kernel/debug/provoke-crash perf stat -B -- cat <(echo ATOMIC_TIMING) > DIRECT perf stat -B -- cat <(echo REFCOUNT_TIMING) > DIRECT Looking a CPU cycles is the best way to example the fast-path (rather than instruction counts, since conditional jumps will be executed but will be negligible due to branch-prediction). Signed-off-by: Kees Cook --- drivers/misc/lkdtm.h | 2 ++ drivers/misc/lkdtm_core.c | 2 ++ drivers/misc/lkdtm_refcount.c | 44 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) (limited to 'drivers/misc') diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h index 04ff8b23b3b0..063f5d651076 100644 --- a/drivers/misc/lkdtm.h +++ b/drivers/misc/lkdtm.h @@ -61,6 +61,8 @@ void lkdtm_REFCOUNT_INC_NOT_ZERO_SATURATED(void); void lkdtm_REFCOUNT_ADD_NOT_ZERO_SATURATED(void); void lkdtm_REFCOUNT_DEC_AND_TEST_SATURATED(void); void lkdtm_REFCOUNT_SUB_AND_TEST_SATURATED(void); +void lkdtm_REFCOUNT_TIMING(void); +void lkdtm_ATOMIC_TIMING(void); /* lkdtm_rodata.c */ void lkdtm_rodata_do_nothing(void); diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c index 156a1a07c3db..51decc07eeda 100644 --- a/drivers/misc/lkdtm_core.c +++ b/drivers/misc/lkdtm_core.c @@ -238,6 +238,8 @@ struct crashtype crashtypes[] = { CRASHTYPE(REFCOUNT_ADD_NOT_ZERO_SATURATED), CRASHTYPE(REFCOUNT_DEC_AND_TEST_SATURATED), CRASHTYPE(REFCOUNT_SUB_AND_TEST_SATURATED), + CRASHTYPE(REFCOUNT_TIMING), + CRASHTYPE(ATOMIC_TIMING), CRASHTYPE(USERCOPY_HEAP_SIZE_TO), CRASHTYPE(USERCOPY_HEAP_SIZE_FROM), CRASHTYPE(USERCOPY_HEAP_FLAG_TO), diff --git a/drivers/misc/lkdtm_refcount.c b/drivers/misc/lkdtm_refcount.c index 313abea4bf9d..29af0152a337 100644 --- a/drivers/misc/lkdtm_refcount.c +++ b/drivers/misc/lkdtm_refcount.c @@ -354,3 +354,47 @@ void lkdtm_REFCOUNT_SUB_AND_TEST_SATURATED(void) check_saturated(&sat); } + +/* Used to time the existing atomic_t when used for reference counting */ +void lkdtm_ATOMIC_TIMING(void) +{ + unsigned int i; + atomic_t count = ATOMIC_INIT(1); + + for (i = 0; i < INT_MAX - 1; i++) + atomic_inc(&count); + + for (i = INT_MAX; i > 0; i--) + if (atomic_dec_and_test(&count)) + break; + + if (i != 1) + pr_err("atomic timing: out of sync up/down cycle: %u\n", i - 1); + else + pr_info("atomic timing: done\n"); +} + +/* + * This can be compared to ATOMIC_TIMING when implementing fast refcount + * protections. Looking at the number of CPU cycles tells the real story + * about performance. For example: + * cd /sys/kernel/debug/provoke-crash + * perf stat -B -- cat <(echo REFCOUNT_TIMING) > DIRECT + */ +void lkdtm_REFCOUNT_TIMING(void) +{ + unsigned int i; + refcount_t count = REFCOUNT_INIT(1); + + for (i = 0; i < INT_MAX - 1; i++) + refcount_inc(&count); + + for (i = INT_MAX; i > 0; i--) + if (refcount_dec_and_test(&count)) + break; + + if (i != 1) + pr_err("refcount: out of sync up/down cycle: %u\n", i - 1); + else + pr_info("refcount timing: done\n"); +} -- cgit v1.2.3 From 7b25a85c9d9f796c5be7ad3fb8b9553d3e2ed958 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 4 Aug 2017 13:04:21 -0700 Subject: lkdtm: Test VMAP_STACK allocates leading/trailing guard pages Two new tests STACK_GUARD_PAGE_LEADING and STACK_GUARD_PAGE_TRAILING attempt to read the byte before and after, respectively, of the current stack frame, which should fault. Signed-off-by: Kees Cook --- drivers/misc/lkdtm.h | 2 ++ drivers/misc/lkdtm_bugs.c | 30 ++++++++++++++++++++++++++++++ drivers/misc/lkdtm_core.c | 2 ++ 3 files changed, 34 insertions(+) (limited to 'drivers/misc') diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h index 063f5d651076..3c8627ca5f42 100644 --- a/drivers/misc/lkdtm.h +++ b/drivers/misc/lkdtm.h @@ -22,6 +22,8 @@ void lkdtm_HUNG_TASK(void); void lkdtm_CORRUPT_LIST_ADD(void); void lkdtm_CORRUPT_LIST_DEL(void); void lkdtm_CORRUPT_USER_DS(void); +void lkdtm_STACK_GUARD_PAGE_LEADING(void); +void lkdtm_STACK_GUARD_PAGE_TRAILING(void); /* lkdtm_heap.c */ void lkdtm_OVERWRITE_ALLOCATION(void); diff --git a/drivers/misc/lkdtm_bugs.c b/drivers/misc/lkdtm_bugs.c index ef3d06f901fc..041fe6e9532a 100644 --- a/drivers/misc/lkdtm_bugs.c +++ b/drivers/misc/lkdtm_bugs.c @@ -8,6 +8,7 @@ #include #include #include +#include #include struct lkdtm_list { @@ -199,6 +200,7 @@ void lkdtm_CORRUPT_LIST_DEL(void) pr_err("list_del() corruption not detected!\n"); } +/* Test if unbalanced set_fs(KERNEL_DS)/set_fs(USER_DS) check exists. */ void lkdtm_CORRUPT_USER_DS(void) { pr_info("setting bad task size limit\n"); @@ -207,3 +209,31 @@ void lkdtm_CORRUPT_USER_DS(void) /* Make sure we do not keep running with a KERNEL_DS! */ force_sig(SIGKILL, current); } + +/* Test that VMAP_STACK is actually allocating with a leading guard page */ +void lkdtm_STACK_GUARD_PAGE_LEADING(void) +{ + const unsigned char *stack = task_stack_page(current); + const unsigned char *ptr = stack - 1; + volatile unsigned char byte; + + pr_info("attempting bad read from page below current stack\n"); + + byte = *ptr; + + pr_err("FAIL: accessed page before stack!\n"); +} + +/* Test that VMAP_STACK is actually allocating with a trailing guard page */ +void lkdtm_STACK_GUARD_PAGE_TRAILING(void) +{ + const unsigned char *stack = task_stack_page(current); + const unsigned char *ptr = stack + THREAD_SIZE; + volatile unsigned char byte; + + pr_info("attempting bad read from page above current stack\n"); + + byte = *ptr; + + pr_err("FAIL: accessed page after stack!\n"); +} diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c index 51decc07eeda..9e98d7ef5503 100644 --- a/drivers/misc/lkdtm_core.c +++ b/drivers/misc/lkdtm_core.c @@ -201,6 +201,8 @@ struct crashtype crashtypes[] = { CRASHTYPE(CORRUPT_LIST_DEL), CRASHTYPE(CORRUPT_USER_DS), CRASHTYPE(CORRUPT_STACK), + CRASHTYPE(STACK_GUARD_PAGE_LEADING), + CRASHTYPE(STACK_GUARD_PAGE_TRAILING), CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE), CRASHTYPE(OVERWRITE_ALLOCATION), CRASHTYPE(WRITE_AFTER_FREE), -- cgit v1.2.3 From 93e78c6b14c42abe4018c815aeea2aa491522fae Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 4 Aug 2017 14:34:40 -0700 Subject: lkdtm: Add -fstack-protector-strong test There wasn't an LKDTM test to distinguish between -fstack-protector and -fstack-protector-strong in use. This adds CORRUPT_STACK_STRONG to see the difference. Also adjusts the stack-clobber value to 0xff so execution won't potentially jump into userspace when the stack protector is missing. Signed-off-by: Kees Cook --- drivers/misc/lkdtm.h | 1 + drivers/misc/lkdtm_bugs.c | 21 ++++++++++++++++++--- drivers/misc/lkdtm_core.c | 1 + 3 files changed, 20 insertions(+), 3 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/lkdtm.h b/drivers/misc/lkdtm.h index 3c8627ca5f42..bfb6c45b6130 100644 --- a/drivers/misc/lkdtm.h +++ b/drivers/misc/lkdtm.h @@ -14,6 +14,7 @@ void lkdtm_EXCEPTION(void); void lkdtm_LOOP(void); void lkdtm_OVERFLOW(void); void lkdtm_CORRUPT_STACK(void); +void lkdtm_CORRUPT_STACK_STRONG(void); void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void); void lkdtm_SOFTLOCKUP(void); void lkdtm_HARDLOCKUP(void); diff --git a/drivers/misc/lkdtm_bugs.c b/drivers/misc/lkdtm_bugs.c index 041fe6e9532a..9e0b4f959987 100644 --- a/drivers/misc/lkdtm_bugs.c +++ b/drivers/misc/lkdtm_bugs.c @@ -85,16 +85,31 @@ void lkdtm_OVERFLOW(void) static noinline void __lkdtm_CORRUPT_STACK(void *stack) { - memset(stack, 'a', 64); + memset(stack, '\xff', 64); } +/* This should trip the stack canary, not corrupt the return address. */ noinline void lkdtm_CORRUPT_STACK(void) { /* Use default char array length that triggers stack protection. */ - char data[8]; + char data[8] __aligned(sizeof(void *)); + + __lkdtm_CORRUPT_STACK(&data); + + pr_info("Corrupted stack containing char array ...\n"); +} + +/* Same as above but will only get a canary with -fstack-protector-strong */ +noinline void lkdtm_CORRUPT_STACK_STRONG(void) +{ + union { + unsigned short shorts[4]; + unsigned long *ptr; + } data __aligned(sizeof(void *)); + __lkdtm_CORRUPT_STACK(&data); - pr_info("Corrupted stack with '%16s'...\n", data); + pr_info("Corrupted stack containing union ...\n"); } void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void) diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c index 9e98d7ef5503..981b3ef71e47 100644 --- a/drivers/misc/lkdtm_core.c +++ b/drivers/misc/lkdtm_core.c @@ -201,6 +201,7 @@ struct crashtype crashtypes[] = { CRASHTYPE(CORRUPT_LIST_DEL), CRASHTYPE(CORRUPT_USER_DS), CRASHTYPE(CORRUPT_STACK), + CRASHTYPE(CORRUPT_STACK_STRONG), CRASHTYPE(STACK_GUARD_PAGE_LEADING), CRASHTYPE(STACK_GUARD_PAGE_TRAILING), CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE), -- cgit v1.2.3 From b8d01b7fbaa3b9d5887ec6c6fea36fb57bbc4d6b Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Sat, 19 Aug 2017 13:52:16 +0530 Subject: mei: make device_type const Make this const as it is only stored in the type field of a device structure, which is const. Done using Coccinelle. Signed-off-by: Bhumika Goyal Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 40c79089e548..1ac10cb64d6e 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -845,7 +845,7 @@ static void mei_cl_bus_dev_release(struct device *dev) kfree(cldev); } -static struct device_type mei_cl_device_type = { +static const struct device_type mei_cl_device_type = { .release = mei_cl_bus_dev_release, }; -- cgit v1.2.3 From 54ec602370c4c818a9e9d8c4ef2a68ff8126997c Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 19 Jul 2017 23:35:28 -0300 Subject: misc: eeprom_93xx46: Simplify the usage of gpiod API Commit 3ca9b1ac28398c ("misc: eeprom_93xx46: Add support for a GPIO 'select' line.") introduced the optional usage of 'select-gpios' by using the gpiod API in a convoluted way. Rewrite the gpiod handling to make the code simpler. Signed-off-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/misc/eeprom/eeprom_93xx46.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index 94cc035aa841..38766968bfa2 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c @@ -377,8 +377,6 @@ static int eeprom_93xx46_probe_dt(struct spi_device *spi) struct device_node *np = spi->dev.of_node; struct eeprom_93xx46_platform_data *pd; u32 tmp; - int gpio; - enum of_gpio_flags of_flags; int ret; pd = devm_kzalloc(&spi->dev, sizeof(*pd), GFP_KERNEL); @@ -403,22 +401,14 @@ static int eeprom_93xx46_probe_dt(struct spi_device *spi) if (of_property_read_bool(np, "read-only")) pd->flags |= EE_READONLY; - gpio = of_get_named_gpio_flags(np, "select-gpios", 0, &of_flags); - if (gpio_is_valid(gpio)) { - unsigned long flags = - of_flags == OF_GPIO_ACTIVE_LOW ? GPIOF_ACTIVE_LOW : 0; + pd->select = devm_gpiod_get_optional(&spi->dev, "select", + GPIOD_OUT_LOW); + if (IS_ERR(pd->select)) + return PTR_ERR(pd->select); - ret = devm_gpio_request_one(&spi->dev, gpio, flags, - "eeprom_93xx46_select"); - if (ret) - return ret; - - pd->select = gpio_to_desc(gpio); - pd->prepare = select_assert; - pd->finish = select_deassert; - - gpiod_direction_output(pd->select, 0); - } + pd->prepare = select_assert; + pd->finish = select_deassert; + gpiod_direction_output(pd->select, 0); if (of_id->data) { const struct eeprom_93xx46_devtype_data *data = of_id->data; -- cgit v1.2.3 From a6dacf6ad484050a5afd0cd207dda49d7ed13689 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sun, 30 Jul 2017 10:56:37 +0530 Subject: misc: ioc4: constify pci_device_id. pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ioc4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c index 8758d033db23..ec0832278170 100644 --- a/drivers/misc/ioc4.c +++ b/drivers/misc/ioc4.c @@ -454,7 +454,7 @@ ioc4_remove(struct pci_dev *pdev) kfree(idd); } -static struct pci_device_id ioc4_id_table[] = { +static const struct pci_device_id ioc4_id_table[] = { {PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC4, PCI_ANY_ID, PCI_ANY_ID, 0x0b4000, 0xFFFFFF}, {0} -- cgit v1.2.3 From 404147ba158af1c8b14739972fa5de7558e5458c Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sun, 30 Jul 2017 10:56:36 +0530 Subject: misc: tifm: constify pci_device_id. pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. checkpatch ERROR: space prohibited before open square bracket '[' Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/misc/tifm_7xx1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c index a37a42f67088..e5f108713dd8 100644 --- a/drivers/misc/tifm_7xx1.c +++ b/drivers/misc/tifm_7xx1.c @@ -415,7 +415,7 @@ static void tifm_7xx1_remove(struct pci_dev *dev) tifm_free_adapter(fm); } -static struct pci_device_id tifm_7xx1_pci_tbl [] = { +static const struct pci_device_id tifm_7xx1_pci_tbl[] = { { PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX21_XX11_FM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* xx21 - the one I have */ { PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX12_FM, PCI_ANY_ID, -- cgit v1.2.3 From 8efa6fb50696cecacb22af2410f2db34fb37b9c3 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sun, 30 Jul 2017 10:56:35 +0530 Subject: misc: hpilo: constify pci_device_id. pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/misc/hpilo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index fea8ff40440f..097e3092c158 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -857,7 +857,7 @@ out: return error; } -static struct pci_device_id ilo_devices[] = { +static const struct pci_device_id ilo_devices[] = { { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB204) }, { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3307) }, { } -- cgit v1.2.3 From e3b9c5cea38bd3735dcc7dea571d1f57cf510ae9 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Sun, 30 Jul 2017 10:56:34 +0530 Subject: misc: pch_phub: constify pci_device_id. pci_device_id are not supposed to change at runtime. All functions working with pci_device_id provided by work with const pci_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/misc/pch_phub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index e42bdc90fa27..2ffacda884cd 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -891,7 +891,7 @@ static int pch_phub_resume(struct pci_dev *pdev) #define pch_phub_resume NULL #endif /* CONFIG_PM */ -static struct pci_device_id pch_phub_pcidev_id[] = { +static const struct pci_device_id pch_phub_pcidev_id[] = { { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB), 1, }, { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, }, { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3, }, -- cgit v1.2.3 From 57daedf812f1fe8b02fab1628b6f4e639466136c Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Wed, 2 Aug 2017 14:40:06 +0530 Subject: MISC: add const to bin_attribute structures Add const to bin_attribute structures as they are only passed to the functions sysfs_{remove/create}_bin_file. The arguments passed are of type const, so declare the structures to be const. Done using Coccinelle. @m disable optional_qualifier@ identifier s; position p; @@ static struct bin_attribute s@p={...}; @okay1@ position p; identifier m.s; @@ ( sysfs_create_bin_file(...,&s@p,...) | sysfs_remove_bin_file(...,&s@p,...) ) @bad@ position p!={m.p,okay1.p}; identifier m.s; @@ s@p @change depends on !bad disable optional_qualifier@ identifier m.s; @@ static +const struct bin_attribute s={...}; Signed-off-by: Bhumika Goyal Reviewed-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ds1682.c | 2 +- drivers/misc/eeprom/eeprom.c | 2 +- drivers/misc/eeprom/max6875.c | 2 +- drivers/misc/pch_phub.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c index 28bb495f0cf1..7231260ac287 100644 --- a/drivers/misc/ds1682.c +++ b/drivers/misc/ds1682.c @@ -173,7 +173,7 @@ static ssize_t ds1682_eeprom_write(struct file *filp, struct kobject *kobj, return count; } -static struct bin_attribute ds1682_eeprom_attr = { +static const struct bin_attribute ds1682_eeprom_attr = { .attr = { .name = "eeprom", .mode = S_IRUGO | S_IWUSR, diff --git a/drivers/misc/eeprom/eeprom.c b/drivers/misc/eeprom/eeprom.c index 2fad790db3bf..60e3d91b5e03 100644 --- a/drivers/misc/eeprom/eeprom.c +++ b/drivers/misc/eeprom/eeprom.c @@ -114,7 +114,7 @@ static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, return count; } -static struct bin_attribute eeprom_attr = { +static const struct bin_attribute eeprom_attr = { .attr = { .name = "eeprom", .mode = S_IRUGO, diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c index e4dd93b2518c..0e32709d1022 100644 --- a/drivers/misc/eeprom/max6875.c +++ b/drivers/misc/eeprom/max6875.c @@ -124,7 +124,7 @@ static ssize_t max6875_read(struct file *filp, struct kobject *kobj, return count; } -static struct bin_attribute user_eeprom_attr = { +static const struct bin_attribute user_eeprom_attr = { .attr = { .name = "eeprom", .mode = S_IRUGO, diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index 2ffacda884cd..540845651b8c 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -659,7 +659,7 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(pch_mac, S_IRUGO | S_IWUSR, show_pch_mac, store_pch_mac); -static struct bin_attribute pch_bin_attr = { +static const struct bin_attribute pch_bin_attr = { .attr = { .name = "pch_firmware", .mode = S_IRUGO | S_IWUSR, -- cgit v1.2.3 From 9045f18209b77e899f5d6ad9463f8a858f0e8535 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Fri, 4 Aug 2017 12:07:57 +0530 Subject: misc: ti-st: constify attribute_group structures. attribute_group are not supposed to change at runtime. All functions working with attribute_group provided by work with const attribute_group. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_kim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index e74413f882ab..b77aacafc3fc 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -660,7 +660,7 @@ static struct attribute *uim_attrs[] = { NULL, }; -static struct attribute_group uim_attr_grp = { +static const struct attribute_group uim_attr_grp = { .attrs = uim_attrs, }; -- cgit v1.2.3 From 27c0823fd9a3aad44f00e0e4dfa9d1b3ce3841a6 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Fri, 4 Aug 2017 12:07:56 +0530 Subject: misc: lis3lv02d: constify attribute_group structures. attribute_group are not supposed to change at runtime. All functions working with attribute_group provided by work with const attribute_group. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/misc/lis3lv02d/lis3lv02d.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index e389b0b5278d..8d53609861d8 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c @@ -856,7 +856,7 @@ static struct attribute *lis3lv02d_attributes[] = { NULL }; -static struct attribute_group lis3lv02d_attribute_group = { +static const struct attribute_group lis3lv02d_attribute_group = { .attrs = lis3lv02d_attributes }; -- cgit v1.2.3 From 64e6d2c187d8ca78629e7206e7efd67773c9a0cb Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Fri, 4 Aug 2017 12:07:55 +0530 Subject: misc: isl29020: constify attribute_group structures. attribute_group are not supposed to change at runtime. All functions working with attribute_group provided by work with const attribute_group. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/misc/isl29020.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c index 4a9c50a43afb..15d1749f5452 100644 --- a/drivers/misc/isl29020.c +++ b/drivers/misc/isl29020.c @@ -145,7 +145,7 @@ static struct attribute *mid_att_als[] = { NULL }; -static struct attribute_group m_als_gr = { +static const struct attribute_group m_als_gr = { .name = "isl29020", .attrs = mid_att_als }; -- cgit v1.2.3 From 0690ee2b01898ff2eacc8520d43a16dfc26de2ec Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Fri, 4 Aug 2017 12:07:54 +0530 Subject: misc: bh1770glc: constify attribute_group structures. attribute_group are not supposed to change at runtime. All functions working with attribute_group provided by work with const attribute_group. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/misc/bh1770glc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c index 38fcfe219d1c..9c62bf064f77 100644 --- a/drivers/misc/bh1770glc.c +++ b/drivers/misc/bh1770glc.c @@ -1175,7 +1175,7 @@ static struct attribute *sysfs_attrs[] = { NULL }; -static struct attribute_group bh1770_attribute_group = { +static const struct attribute_group bh1770_attribute_group = { .attrs = sysfs_attrs }; -- cgit v1.2.3 From 68b9e993745ffed2b39afadfe4813e104b3eba94 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Fri, 4 Aug 2017 12:07:53 +0530 Subject: misc: apds990x: constify attribute_group structures. attribute_group are not supposed to change at runtime. All functions working with attribute_group provided by work with const attribute_group. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/misc/apds990x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c index 84e5b949399e..c9f07032c2fc 100644 --- a/drivers/misc/apds990x.c +++ b/drivers/misc/apds990x.c @@ -1051,7 +1051,7 @@ static struct attribute *sysfs_attrs_ctrl[] = { NULL }; -static struct attribute_group apds990x_attribute_group[] = { +static const struct attribute_group apds990x_attribute_group[] = { {.attrs = sysfs_attrs_ctrl }, }; -- cgit v1.2.3 From 579e9a307256e550fe918485b828517ea3c5f2fb Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Fri, 4 Aug 2017 12:07:52 +0530 Subject: misc: apds9802als: constify attribute_group structures. attribute_group are not supposed to change at runtime. All functions working with attribute_group provided by work with const attribute_group. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/misc/apds9802als.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c index c6cc3dc8ae1f..05ee771793cd 100644 --- a/drivers/misc/apds9802als.c +++ b/drivers/misc/apds9802als.c @@ -197,7 +197,7 @@ static struct attribute *mid_att_als[] = { NULL }; -static struct attribute_group m_als_gr = { +static const struct attribute_group m_als_gr = { .name = "apds9802als", .attrs = mid_att_als }; -- cgit v1.2.3 From 34d0eb50bd7c0c6431a67faf2e00b1316f886d45 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 18 Jul 2017 16:43:15 -0500 Subject: misc: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring Cc: Arnd Bergmann Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/misc/eeprom/idt_89hpesx.c | 8 ++++---- drivers/misc/sram.c | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/eeprom/idt_89hpesx.c b/drivers/misc/eeprom/idt_89hpesx.c index ab0df6a17690..37312b548a03 100644 --- a/drivers/misc/eeprom/idt_89hpesx.c +++ b/drivers/misc/eeprom/idt_89hpesx.c @@ -1132,8 +1132,8 @@ static void idt_get_ofdata(struct idt_89hpesx_dev *pdev) for_each_available_child_of_node(node, child) { ee_id = idt_ee_match_id(child); if (IS_ERR_OR_NULL(ee_id)) { - dev_warn(dev, "Skip unsupported child node %s", - child->full_name); + dev_warn(dev, "Skip unsupported child node %pOF", + child); continue; } else break; @@ -1151,8 +1151,8 @@ static void idt_get_ofdata(struct idt_89hpesx_dev *pdev) /* Get custom EEPROM address from 'reg' attribute */ addr_be = of_get_property(child, "reg", &len); if (!addr_be || (len < sizeof(*addr_be))) { - dev_warn(dev, "No reg on %s, use default address %d", - child->full_name, EEPROM_DEF_ADDR); + dev_warn(dev, "No reg on %pOF, use default address %d", + child, EEPROM_DEF_ADDR); pdev->inieecmd = 0; pdev->eeaddr = EEPROM_DEF_ADDR << 1; } else { diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index d1185b78cf9a..fc0415771c00 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -196,15 +196,15 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res) ret = of_address_to_resource(child, 0, &child_res); if (ret < 0) { dev_err(sram->dev, - "could not get address for node %s\n", - child->full_name); + "could not get address for node %pOF\n", + child); goto err_chunks; } if (child_res.start < res->start || child_res.end > res->end) { dev_err(sram->dev, - "reserved block %s outside the sram area\n", - child->full_name); + "reserved block %pOF outside the sram area\n", + child); ret = -EINVAL; goto err_chunks; } @@ -230,8 +230,8 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res) ret = of_property_read_string(child, "label", &label); if (ret && ret != -EINVAL) { dev_err(sram->dev, - "%s has invalid label name\n", - child->full_name); + "%pOF has invalid label name\n", + child); goto err_chunks; } if (!label) -- cgit v1.2.3 From 07e4049ae0b2abc6b9c7226af5eb802380976bae Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Mon, 21 Aug 2017 22:13:27 +0530 Subject: misc: isl29020: constify i2c_device_id i2c_device_id are not supposed to change at runtime. All functions working with i2c_device_id provided by work with const i2c_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/misc/isl29020.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c index 15d1749f5452..e3bd3c1d2574 100644 --- a/drivers/misc/isl29020.c +++ b/drivers/misc/isl29020.c @@ -188,7 +188,7 @@ static int isl29020_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id isl29020_id[] = { +static const struct i2c_device_id isl29020_id[] = { { "isl29020", 0 }, { } }; -- cgit v1.2.3 From b8dbb5024b5e62704caac6915f0f5f33448b8b05 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Mon, 21 Aug 2017 22:13:26 +0530 Subject: misc: hmc6352: constify i2c_device_id i2c_device_id are not supposed to change at runtime. All functions working with i2c_device_id provided by work with const i2c_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/misc/hmc6352.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/hmc6352.c b/drivers/misc/hmc6352.c index 90520d76633f..eeb7eef62174 100644 --- a/drivers/misc/hmc6352.c +++ b/drivers/misc/hmc6352.c @@ -132,7 +132,7 @@ static int hmc6352_remove(struct i2c_client *client) return 0; } -static struct i2c_device_id hmc6352_id[] = { +static const struct i2c_device_id hmc6352_id[] = { { "hmc6352", 0 }, { } }; -- cgit v1.2.3 From 006dbb38d7469d7465b4ffcbf5beac961cee70df Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Mon, 21 Aug 2017 22:13:25 +0530 Subject: misc: apds9802als: constify i2c_device_id i2c_device_id are not supposed to change at runtime. All functions working with i2c_device_id provided by work with const i2c_device_id. So mark the non-const structs as const. Signed-off-by: Arvind Yadav Signed-off-by: Greg Kroah-Hartman --- drivers/misc/apds9802als.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c index 05ee771793cd..d8ac036f01ab 100644 --- a/drivers/misc/apds9802als.c +++ b/drivers/misc/apds9802als.c @@ -298,7 +298,7 @@ static UNIVERSAL_DEV_PM_OPS(apds9802als_pm_ops, apds9802als_suspend, #define APDS9802ALS_PM_OPS NULL #endif /* CONFIG_PM */ -static struct i2c_device_id apds9802als_id[] = { +static const struct i2c_device_id apds9802als_id[] = { { DRIVER_NAME, 0 }, { } }; -- cgit v1.2.3 From 234b7f8d3bf2738024b155b87303ed1218e620fa Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 17 Aug 2017 20:43:10 -0500 Subject: vmci: fix duplicated code for different branches Refactor code in order to avoid identical code for different branches. This issue was detected with the help of Coccinelle. Addresses-Coverity-ID: 1226762 Signed-off-by: Gustavo A. R. Silva Signed-off-by: Greg Kroah-Hartman --- drivers/misc/vmw_vmci/vmci_queue_pair.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c index 06c4974ee8dd..8af5c2672f71 100644 --- a/drivers/misc/vmw_vmci/vmci_queue_pair.c +++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c @@ -2235,14 +2235,8 @@ int vmci_qp_broker_detach(struct vmci_handle handle, struct vmci_ctx *context) handle.context, handle.resource, result); - if (entry->vmci_page_files) - qp_host_unregister_user_memory(entry->produce_q, - entry-> - consume_q); - else - qp_host_unregister_user_memory(entry->produce_q, - entry-> - consume_q); + qp_host_unregister_user_memory(entry->produce_q, + entry->consume_q); } -- cgit v1.2.3 From 917c8c2570e1c106ad68ee3d00eb28351b923b0a Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 18 Aug 2017 16:34:59 +0100 Subject: lkdtm: fix spelling mistake: "incremeted" -> "incremented" Trivial fix to spelling mistake in pr_info message Signed-off-by: Colin Ian King Acked-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- drivers/misc/lkdtm_refcount.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/lkdtm_refcount.c b/drivers/misc/lkdtm_refcount.c index 29af0152a337..2b99d448e7fd 100644 --- a/drivers/misc/lkdtm_refcount.c +++ b/drivers/misc/lkdtm_refcount.c @@ -202,7 +202,7 @@ static void check_from_zero(refcount_t *ref) pr_warn("Zero detected: unsafely reset to max\n"); break; default: - pr_info("Fail: zero not detected, incremeted to %d\n", + pr_info("Fail: zero not detected, incremented to %d\n", refcount_read(ref)); } } -- cgit v1.2.3 From db15d73e5f0ea8e9b2c2be31dea45205257eb5fd Mon Sep 17 00:00:00 2001 From: Huy Duong Date: Wed, 30 Aug 2017 21:53:37 +0700 Subject: eeprom: idt_89hpesx: Support both ACPI and OF probing Allow the idt_89hpesx driver to get information from child nodes from both OF and ACPI by using more generic fwnode_property_read*() functions. Below is an example of instantiating idt_89hpesx driver via ACPI Table: Device(IDT0) { Name(_HID, "PRP0001") Name(_CID, "PRP0001") Name(_CCA, ONE) Name(_STR, Unicode("IDT SW I2C Slave")) Name(_CRS, ResourceTemplate () { I2cSerialBus (0x74, ControllerInitiated, 1000, AddressingMode7Bit, "\\_SB.I2CS", 0x00, ResourceConsumer, , ) }) Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () {"compatible", "idt,89hpes32nt8ag2"}, }, }) Device (EPR0) { Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () {"compatible", "onsemi,24c64"}, Package () {"reg", 0x50}, } }) } } Signed-off-by: Huy Duong Acked-by: Serge Semin Signed-off-by: Greg Kroah-Hartman --- drivers/misc/eeprom/idt_89hpesx.c | 126 +++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 71 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/eeprom/idt_89hpesx.c b/drivers/misc/eeprom/idt_89hpesx.c index 37312b548a03..34a5a41578d7 100644 --- a/drivers/misc/eeprom/idt_89hpesx.c +++ b/drivers/misc/eeprom/idt_89hpesx.c @@ -77,7 +77,7 @@ #include #include #include -#include +#include #include #include #include @@ -1089,101 +1089,85 @@ static void idt_set_defval(struct idt_89hpesx_dev *pdev) pdev->eeaddr = 0; } -#ifdef CONFIG_OF static const struct i2c_device_id ee_ids[]; + /* * idt_ee_match_id() - check whether the node belongs to compatible EEPROMs */ -static const struct i2c_device_id *idt_ee_match_id(struct device_node *node) +static const struct i2c_device_id *idt_ee_match_id(struct fwnode_handle *fwnode) { const struct i2c_device_id *id = ee_ids; + const char *compatible, *p; char devname[I2C_NAME_SIZE]; + int ret; - /* Retrieve the device name without manufacturer name */ - if (of_modalias_node(node, devname, sizeof(devname))) + ret = fwnode_property_read_string(fwnode, "compatible", &compatible); + if (ret) return NULL; + p = strchr(compatible, ','); + strlcpy(devname, p ? p + 1 : compatible, sizeof(devname)); /* Search through the device name */ - while (id->name[0]) { - if (strcmp(devname, id->name) == 0) - return id; - id++; - } - return NULL; + while (id->name[0]) { + if (strcmp(devname, id->name) == 0) + return id; + id++; + } + return NULL; } /* - * idt_get_ofdata() - get IDT i2c-device parameters from device tree + * idt_get_fw_data() - get IDT i2c-device parameters from device tree * @pdev: Pointer to the driver data */ -static void idt_get_ofdata(struct idt_89hpesx_dev *pdev) +static void idt_get_fw_data(struct idt_89hpesx_dev *pdev) { - const struct device_node *node = pdev->client->dev.of_node; struct device *dev = &pdev->client->dev; + struct fwnode_handle *fwnode; + const struct i2c_device_id *ee_id = NULL; + u32 eeprom_addr; + int ret; - /* Read dts node parameters */ - if (node) { - const struct i2c_device_id *ee_id = NULL; - struct device_node *child; - const __be32 *addr_be; - int len; - - /* Walk through all child nodes looking for compatible one */ - for_each_available_child_of_node(node, child) { - ee_id = idt_ee_match_id(child); - if (IS_ERR_OR_NULL(ee_id)) { - dev_warn(dev, "Skip unsupported child node %pOF", - child); - continue; - } else - break; - } - - /* If there is no child EEPROM device, then set zero size */ - if (!ee_id) { - idt_set_defval(pdev); - return; - } + device_for_each_child_node(dev, fwnode) { + ee_id = idt_ee_match_id(fwnode); + if (IS_ERR_OR_NULL(ee_id)) { + dev_warn(dev, "Skip unsupported EEPROM device"); + continue; + } else + break; + } - /* Retrieve EEPROM size */ - pdev->eesize = (u32)ee_id->driver_data; - - /* Get custom EEPROM address from 'reg' attribute */ - addr_be = of_get_property(child, "reg", &len); - if (!addr_be || (len < sizeof(*addr_be))) { - dev_warn(dev, "No reg on %pOF, use default address %d", - child, EEPROM_DEF_ADDR); - pdev->inieecmd = 0; - pdev->eeaddr = EEPROM_DEF_ADDR << 1; - } else { - pdev->inieecmd = EEPROM_USA; - pdev->eeaddr = be32_to_cpup(addr_be) << 1; - } + /* If there is no fwnode EEPROM device, then set zero size */ + if (!ee_id) { + dev_warn(dev, "No fwnode, EEPROM access disabled"); + idt_set_defval(pdev); + return; + } - /* Check EEPROM 'read-only' flag */ - if (of_get_property(child, "read-only", NULL)) - pdev->eero = true; - else /* if (!of_get_property(node, "read-only", NULL)) */ - pdev->eero = false; + /* Retrieve EEPROM size */ + pdev->eesize = (u32)ee_id->driver_data; - dev_dbg(dev, "EEPROM of %u bytes found by %hhu", - pdev->eesize, pdev->eeaddr); + /* Get custom EEPROM address from 'reg' attribute */ + ret = fwnode_property_read_u32(fwnode, "reg", &eeprom_addr); + if (ret || (eeprom_addr == 0)) { + dev_warn(dev, "No EEPROM reg found, use default address 0x%x", + EEPROM_DEF_ADDR); + pdev->inieecmd = 0; + pdev->eeaddr = EEPROM_DEF_ADDR << 1; } else { - dev_warn(dev, "No dts node, EEPROM access disabled"); - idt_set_defval(pdev); + pdev->inieecmd = EEPROM_USA; + pdev->eeaddr = eeprom_addr << 1; } -} -#else -static void idt_get_ofdata(struct idt_89hpesx_dev *pdev) -{ - struct device *dev = &pdev->client->dev; - dev_warn(dev, "OF table is unsupported, EEPROM access disabled"); + /* Check EEPROM 'read-only' flag */ + if (fwnode_property_read_bool(fwnode, "read-only")) + pdev->eero = true; + else /* if (!fwnode_property_read_bool(node, "read-only")) */ + pdev->eero = false; - /* Nothing we can do, just set the default values */ - idt_set_defval(pdev); + dev_info(dev, "EEPROM of %d bytes found by 0x%x", + pdev->eesize, pdev->eeaddr); } -#endif /* CONFIG_OF */ /* * idt_create_pdev() - create and init data structure of the driver @@ -1203,8 +1187,8 @@ static struct idt_89hpesx_dev *idt_create_pdev(struct i2c_client *client) pdev->client = client; i2c_set_clientdata(client, pdev); - /* Read OF nodes information */ - idt_get_ofdata(pdev); + /* Read firmware nodes information */ + idt_get_fw_data(pdev); /* Initialize basic CSR CMD field - use full DWORD-sized r/w ops */ pdev->inicsrcmd = CSR_DWE; -- cgit v1.2.3