This is the 5.10.81 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmGaP7IACgkQONu9yGCS aT7/+Q/+O42TW2iiTyR8S2EJ1i8p61mAWx7hjD6VHqi+sKyinkiWpxXL73rfu3NX 3Sk9/ChtLo6bSIktP2kvEXduLU69LsytgTsqJ1qpQmRWhK22xp91HW/A8mT7eOLp z3HcvWpDCjTQYXTtnDDxNeKEG//xssueczdwczh0B7hOyrxw7m3m80hswKxNgJpJ OEwBxfSKlgvCOqatWhmW2+YKGeETTnhJyx1et0paajLuG8JW40Q4iK/MfNnIuTYV DWvddaznY3KRHTjyMcILskVEpFq5NX3RGHvQ5qMfmlTjTobYp4miTnkD6TW4Fdo9 Q7h0NJj8hq2Ova2HoksXVgVVXw2TdkJyXdUzFHHqZtOUQeYeC2iB78y6VZQKuh9o EuIsDvEKByHc2D5lqT0MyMwe+KtWtuIJ3gIyUa08dYkn0VwKVEEVXHBJNb46EEI0 V2eaUUfIqCaYA9IaYiPINAKO9clUlxXrBiFG0yoI1mOccQ69nSAhEiX9KLqaDPA6 utQPaXWKqodR0CXP7cFkjbYQC/Gx3d2jgCZiJyrfXsoxB+lcsrHxbdIJFQL41T2G KEBe9fKQfQaYYBxhNiPt/LUoE5szwef6V3d4bSs36nDQlWBgYGhQfvuQfblXasO/ DqyG3jISEBx8ylXSijXz9rtiZMBPtWt6o2XGT7KAiRz8px2+0cM= =iupp -----END PGP SIGNATURE----- Merge 5.10.81 into android12-5.10-lts Changes in 5.10.81 fortify: Explicitly disable Clang support block: Add a helper to validate the block size loop: Use blk_validate_block_size() to validate block size bootconfig: init: Fix memblock leak in xbc_make_cmdline() net: stmmac: add clocks management for gmac driver net: stmmac: platform: fix build error with !CONFIG_PM_SLEEP net: stmmac: fix missing unlock on error in stmmac_suspend() net: stmmac: fix system hang if change mac address after interface ifdown net: stmmac: fix issue where clk is being unprepared twice net: stmmac: dwmac-rk: fix unbalanced pm_runtime_enable warnings x86/iopl: Fake iopl(3) CLI/STI usage parisc/entry: fix trace test in syscall exit path PCI/MSI: Destroy sysfs before freeing entries PCI/MSI: Deal with devices lying about their MSI mask capability PCI: Add MSI masking quirk for Nvidia ION AHCI erofs: remove the occupied parameter from z_erofs_pagevec_enqueue() erofs: fix unsafe pagevec reuse of hooked pclusters scripts/lld-version.sh: Rewrite based on upstream ld-version.sh perf/core: Avoid put_page() when GUP fails thermal: Fix NULL pointer dereferences in of_thermal_ functions selftests/x86/iopl: Adjust to the faked iopl CLI/STI usage Linux 5.10.81 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ic5ba37cba892391e62596f4c342d36a8f66e4647
This commit is contained in:
commit
94097f9434
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 80
|
||||
SUBLEVEL = 81
|
||||
EXTRAVERSION =
|
||||
NAME = Dare mighty things
|
||||
|
||||
|
@ -1849,7 +1849,7 @@ syscall_restore:
|
||||
|
||||
/* Are we being ptraced? */
|
||||
LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
|
||||
ldi _TIF_SYSCALL_TRACE_MASK,%r2
|
||||
ldi _TIF_SINGLESTEP|_TIF_BLOCKSTEP,%r2
|
||||
and,COND(=) %r19,%r2,%r0
|
||||
b,n syscall_restore_rfi
|
||||
|
||||
|
@ -21,6 +21,7 @@ int insn_get_modrm_rm_off(struct insn *insn, struct pt_regs *regs);
|
||||
int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs);
|
||||
unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx);
|
||||
int insn_get_code_seg_params(struct pt_regs *regs);
|
||||
unsigned long insn_get_effective_ip(struct pt_regs *regs);
|
||||
int insn_fetch_from_user(struct pt_regs *regs,
|
||||
unsigned char buf[MAX_INSN_SIZE]);
|
||||
int insn_fetch_from_user_inatomic(struct pt_regs *regs,
|
||||
|
@ -534,6 +534,7 @@ struct thread_struct {
|
||||
*/
|
||||
unsigned long iopl_emul;
|
||||
|
||||
unsigned int iopl_warn:1;
|
||||
unsigned int sig_on_uaccess_err:1;
|
||||
|
||||
/* Floating point and extended processor state */
|
||||
|
@ -138,6 +138,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg,
|
||||
frame->ret_addr = (unsigned long) ret_from_fork;
|
||||
p->thread.sp = (unsigned long) fork_frame;
|
||||
p->thread.io_bitmap = NULL;
|
||||
p->thread.iopl_warn = 0;
|
||||
memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
|
@ -523,6 +523,37 @@ static enum kernel_gp_hint get_kernel_gp_address(struct pt_regs *regs,
|
||||
|
||||
#define GPFSTR "general protection fault"
|
||||
|
||||
static bool fixup_iopl_exception(struct pt_regs *regs)
|
||||
{
|
||||
struct thread_struct *t = ¤t->thread;
|
||||
unsigned char byte;
|
||||
unsigned long ip;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_X86_IOPL_IOPERM) || t->iopl_emul != 3)
|
||||
return false;
|
||||
|
||||
ip = insn_get_effective_ip(regs);
|
||||
if (!ip)
|
||||
return false;
|
||||
|
||||
if (get_user(byte, (const char __user *)ip))
|
||||
return false;
|
||||
|
||||
if (byte != 0xfa && byte != 0xfb)
|
||||
return false;
|
||||
|
||||
if (!t->iopl_warn && printk_ratelimit()) {
|
||||
pr_err("%s[%d] attempts to use CLI/STI, pretending it's a NOP, ip:%lx",
|
||||
current->comm, task_pid_nr(current), ip);
|
||||
print_vma_addr(KERN_CONT " in ", ip);
|
||||
pr_cont("\n");
|
||||
t->iopl_warn = 1;
|
||||
}
|
||||
|
||||
regs->ip += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
|
||||
{
|
||||
char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR;
|
||||
@ -548,6 +579,9 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
|
||||
tsk = current;
|
||||
|
||||
if (user_mode(regs)) {
|
||||
if (fixup_iopl_exception(regs))
|
||||
goto exit;
|
||||
|
||||
tsk->thread.error_code = error_code;
|
||||
tsk->thread.trap_nr = X86_TRAP_GP;
|
||||
|
||||
|
@ -1415,7 +1415,7 @@ void __user *insn_get_addr_ref(struct insn *insn, struct pt_regs *regs)
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long insn_get_effective_ip(struct pt_regs *regs)
|
||||
unsigned long insn_get_effective_ip(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long seg_base = 0;
|
||||
|
||||
|
@ -228,19 +228,6 @@ static void __loop_update_dio(struct loop_device *lo, bool dio)
|
||||
blk_mq_unfreeze_queue(lo->lo_queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* loop_validate_block_size() - validates the passed in block size
|
||||
* @bsize: size to validate
|
||||
*/
|
||||
static int
|
||||
loop_validate_block_size(unsigned short bsize)
|
||||
{
|
||||
if (bsize < 512 || bsize > PAGE_SIZE || !is_power_of_2(bsize))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* loop_set_size() - sets device size and notifies userspace
|
||||
* @lo: struct loop_device to set the size for
|
||||
@ -1121,7 +1108,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
|
||||
}
|
||||
|
||||
if (config->block_size) {
|
||||
error = loop_validate_block_size(config->block_size);
|
||||
error = blk_validate_block_size(config->block_size);
|
||||
if (error)
|
||||
goto out_unlock;
|
||||
}
|
||||
@ -1617,7 +1604,7 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg)
|
||||
if (lo->lo_state != Lo_bound)
|
||||
return -ENXIO;
|
||||
|
||||
err = loop_validate_block_size(arg);
|
||||
err = blk_validate_block_size(arg);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include "stmmac_platform.h"
|
||||
|
||||
@ -1336,9 +1335,6 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
if (bsp_priv->integrated_phy)
|
||||
rk_gmac_integrated_phy_powerup(bsp_priv);
|
||||
|
||||
@ -1347,14 +1343,9 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
|
||||
|
||||
static void rk_gmac_powerdown(struct rk_priv_data *gmac)
|
||||
{
|
||||
struct device *dev = &gmac->pdev->dev;
|
||||
|
||||
if (gmac->integrated_phy)
|
||||
rk_gmac_integrated_phy_powerdown(gmac);
|
||||
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
|
||||
phy_power_on(gmac, false);
|
||||
gmac_clk_enable(gmac, false);
|
||||
}
|
||||
|
@ -270,6 +270,7 @@ void stmmac_disable_eee_mode(struct stmmac_priv *priv);
|
||||
bool stmmac_eee_init(struct stmmac_priv *priv);
|
||||
int stmmac_reinit_queues(struct net_device *dev, u32 rx_cnt, u32 tx_cnt);
|
||||
int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size);
|
||||
int stmmac_bus_clks_config(struct stmmac_priv *priv, bool enabled);
|
||||
|
||||
#if IS_ENABLED(CONFIG_STMMAC_SELFTESTS)
|
||||
void stmmac_selftest_run(struct net_device *dev,
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/prefetch.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
@ -113,6 +114,28 @@ static void stmmac_exit_fs(struct net_device *dev);
|
||||
|
||||
#define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
|
||||
|
||||
int stmmac_bus_clks_config(struct stmmac_priv *priv, bool enabled)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (enabled) {
|
||||
ret = clk_prepare_enable(priv->plat->stmmac_clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = clk_prepare_enable(priv->plat->pclk);
|
||||
if (ret) {
|
||||
clk_disable_unprepare(priv->plat->stmmac_clk);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
clk_disable_unprepare(priv->plat->stmmac_clk);
|
||||
clk_disable_unprepare(priv->plat->pclk);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(stmmac_bus_clks_config);
|
||||
|
||||
/**
|
||||
* stmmac_verify_args - verify the driver parameters.
|
||||
* Description: it checks the driver parameters and set a default in case of
|
||||
@ -2792,6 +2815,12 @@ static int stmmac_open(struct net_device *dev)
|
||||
u32 chan;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(priv->device);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(priv->device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (priv->hw->pcs != STMMAC_PCS_TBI &&
|
||||
priv->hw->pcs != STMMAC_PCS_RTBI &&
|
||||
priv->hw->xpcs == NULL) {
|
||||
@ -2800,7 +2829,7 @@ static int stmmac_open(struct net_device *dev)
|
||||
netdev_err(priv->dev,
|
||||
"%s: Cannot attach to PHY (error: %d)\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
goto init_phy_error;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2915,6 +2944,8 @@ static int stmmac_open(struct net_device *dev)
|
||||
free_dma_desc_resources(priv);
|
||||
dma_desc_error:
|
||||
phylink_disconnect_phy(priv->phylink);
|
||||
init_phy_error:
|
||||
pm_runtime_put(priv->device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2965,6 +2996,8 @@ static int stmmac_release(struct net_device *dev)
|
||||
|
||||
stmmac_release_ptp(priv);
|
||||
|
||||
pm_runtime_put(priv->device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4291,12 +4324,21 @@ static int stmmac_set_mac_address(struct net_device *ndev, void *addr)
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
int ret = 0;
|
||||
|
||||
ret = pm_runtime_get_sync(priv->device);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(priv->device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = eth_mac_addr(ndev, addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto set_mac_error;
|
||||
|
||||
stmmac_set_umac_addr(priv, priv->hw, ndev->dev_addr, 0);
|
||||
|
||||
set_mac_error:
|
||||
pm_runtime_put(priv->device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -4616,6 +4658,12 @@ static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vi
|
||||
bool is_double = false;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(priv->device);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(priv->device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (be16_to_cpu(proto) == ETH_P_8021AD)
|
||||
is_double = true;
|
||||
|
||||
@ -4624,10 +4672,15 @@ static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vi
|
||||
if (priv->hw->num_vlan) {
|
||||
ret = stmmac_del_hw_vlan_rx_fltr(priv, ndev, priv->hw, proto, vid);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto del_vlan_error;
|
||||
}
|
||||
|
||||
return stmmac_vlan_update(priv, is_double);
|
||||
ret = stmmac_vlan_update(priv, is_double);
|
||||
|
||||
del_vlan_error:
|
||||
pm_runtime_put(priv->device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct net_device_ops stmmac_netdev_ops = {
|
||||
@ -5066,6 +5119,10 @@ int stmmac_dvr_probe(struct device *device,
|
||||
|
||||
stmmac_check_pcs_mode(priv);
|
||||
|
||||
pm_runtime_get_noresume(device);
|
||||
pm_runtime_set_active(device);
|
||||
pm_runtime_enable(device);
|
||||
|
||||
if (priv->hw->pcs != STMMAC_PCS_TBI &&
|
||||
priv->hw->pcs != STMMAC_PCS_RTBI) {
|
||||
/* MDIO bus Registration */
|
||||
@ -5103,6 +5160,11 @@ int stmmac_dvr_probe(struct device *device,
|
||||
stmmac_init_fs(ndev);
|
||||
#endif
|
||||
|
||||
/* Let pm_runtime_put() disable the clocks.
|
||||
* If CONFIG_PM is not enabled, the clocks will stay powered.
|
||||
*/
|
||||
pm_runtime_put(device);
|
||||
|
||||
return ret;
|
||||
|
||||
error_serdes_powerup:
|
||||
@ -5152,8 +5214,8 @@ int stmmac_dvr_remove(struct device *dev)
|
||||
phylink_destroy(priv->phylink);
|
||||
if (priv->plat->stmmac_rst)
|
||||
reset_control_assert(priv->plat->stmmac_rst);
|
||||
clk_disable_unprepare(priv->plat->pclk);
|
||||
clk_disable_unprepare(priv->plat->stmmac_clk);
|
||||
pm_runtime_put(dev);
|
||||
pm_runtime_disable(dev);
|
||||
if (priv->hw->pcs != STMMAC_PCS_TBI &&
|
||||
priv->hw->pcs != STMMAC_PCS_RTBI)
|
||||
stmmac_mdio_unregister(ndev);
|
||||
@ -5176,6 +5238,7 @@ int stmmac_suspend(struct device *dev)
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
u32 chan;
|
||||
int ret;
|
||||
|
||||
if (!ndev || !netif_running(ndev))
|
||||
return 0;
|
||||
@ -5219,8 +5282,11 @@ int stmmac_suspend(struct device *dev)
|
||||
pinctrl_pm_select_sleep_state(priv->device);
|
||||
/* Disable clock in case of PWM is off */
|
||||
clk_disable_unprepare(priv->plat->clk_ptp_ref);
|
||||
clk_disable_unprepare(priv->plat->pclk);
|
||||
clk_disable_unprepare(priv->plat->stmmac_clk);
|
||||
ret = pm_runtime_force_suspend(dev);
|
||||
if (ret) {
|
||||
mutex_unlock(&priv->lock);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
@ -5286,8 +5352,9 @@ int stmmac_resume(struct device *dev)
|
||||
} else {
|
||||
pinctrl_pm_select_default_state(priv->device);
|
||||
/* enable the clk previously disabled */
|
||||
clk_prepare_enable(priv->plat->stmmac_clk);
|
||||
clk_prepare_enable(priv->plat->pclk);
|
||||
ret = pm_runtime_force_resume(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (priv->plat->clk_ptp_ref)
|
||||
clk_prepare_enable(priv->plat->clk_ptp_ref);
|
||||
/* reset the phy so that it's ready */
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/of_mdio.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/slab.h>
|
||||
@ -87,21 +88,29 @@ static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
|
||||
u32 tmp, addr, value = MII_XGMAC_BUSY;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(priv->device);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(priv->device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wait until any existing MII operation is complete */
|
||||
if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
|
||||
!(tmp & MII_XGMAC_BUSY), 100, 10000))
|
||||
return -EBUSY;
|
||||
!(tmp & MII_XGMAC_BUSY), 100, 10000)) {
|
||||
ret = -EBUSY;
|
||||
goto err_disable_clks;
|
||||
}
|
||||
|
||||
if (phyreg & MII_ADDR_C45) {
|
||||
phyreg &= ~MII_ADDR_C45;
|
||||
|
||||
ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_disable_clks;
|
||||
} else {
|
||||
ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_disable_clks;
|
||||
|
||||
value |= MII_XGMAC_SADDR;
|
||||
}
|
||||
@ -112,8 +121,10 @@ static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
|
||||
|
||||
/* Wait until any existing MII operation is complete */
|
||||
if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
|
||||
!(tmp & MII_XGMAC_BUSY), 100, 10000))
|
||||
return -EBUSY;
|
||||
!(tmp & MII_XGMAC_BUSY), 100, 10000)) {
|
||||
ret = -EBUSY;
|
||||
goto err_disable_clks;
|
||||
}
|
||||
|
||||
/* Set the MII address register to read */
|
||||
writel(addr, priv->ioaddr + mii_address);
|
||||
@ -121,11 +132,18 @@ static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
|
||||
|
||||
/* Wait until any existing MII operation is complete */
|
||||
if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
|
||||
!(tmp & MII_XGMAC_BUSY), 100, 10000))
|
||||
return -EBUSY;
|
||||
!(tmp & MII_XGMAC_BUSY), 100, 10000)) {
|
||||
ret = -EBUSY;
|
||||
goto err_disable_clks;
|
||||
}
|
||||
|
||||
/* Read the data from the MII data register */
|
||||
return readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
|
||||
ret = (int)readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
|
||||
|
||||
err_disable_clks:
|
||||
pm_runtime_put(priv->device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
|
||||
@ -138,21 +156,29 @@ static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
|
||||
u32 addr, tmp, value = MII_XGMAC_BUSY;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(priv->device);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(priv->device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wait until any existing MII operation is complete */
|
||||
if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
|
||||
!(tmp & MII_XGMAC_BUSY), 100, 10000))
|
||||
return -EBUSY;
|
||||
!(tmp & MII_XGMAC_BUSY), 100, 10000)) {
|
||||
ret = -EBUSY;
|
||||
goto err_disable_clks;
|
||||
}
|
||||
|
||||
if (phyreg & MII_ADDR_C45) {
|
||||
phyreg &= ~MII_ADDR_C45;
|
||||
|
||||
ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_disable_clks;
|
||||
} else {
|
||||
ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_disable_clks;
|
||||
|
||||
value |= MII_XGMAC_SADDR;
|
||||
}
|
||||
@ -164,16 +190,23 @@ static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
|
||||
|
||||
/* Wait until any existing MII operation is complete */
|
||||
if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
|
||||
!(tmp & MII_XGMAC_BUSY), 100, 10000))
|
||||
return -EBUSY;
|
||||
!(tmp & MII_XGMAC_BUSY), 100, 10000)) {
|
||||
ret = -EBUSY;
|
||||
goto err_disable_clks;
|
||||
}
|
||||
|
||||
/* Set the MII address register to write */
|
||||
writel(addr, priv->ioaddr + mii_address);
|
||||
writel(value, priv->ioaddr + mii_data);
|
||||
|
||||
/* Wait until any existing MII operation is complete */
|
||||
return readl_poll_timeout(priv->ioaddr + mii_data, tmp,
|
||||
!(tmp & MII_XGMAC_BUSY), 100, 10000);
|
||||
ret = readl_poll_timeout(priv->ioaddr + mii_data, tmp,
|
||||
!(tmp & MII_XGMAC_BUSY), 100, 10000);
|
||||
|
||||
err_disable_clks:
|
||||
pm_runtime_put(priv->device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -196,6 +229,12 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
|
||||
int data = 0;
|
||||
u32 v;
|
||||
|
||||
data = pm_runtime_get_sync(priv->device);
|
||||
if (data < 0) {
|
||||
pm_runtime_put_noidle(priv->device);
|
||||
return data;
|
||||
}
|
||||
|
||||
value |= (phyaddr << priv->hw->mii.addr_shift)
|
||||
& priv->hw->mii.addr_mask;
|
||||
value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
|
||||
@ -216,19 +255,26 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
|
||||
}
|
||||
|
||||
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
|
||||
100, 10000))
|
||||
return -EBUSY;
|
||||
100, 10000)) {
|
||||
data = -EBUSY;
|
||||
goto err_disable_clks;
|
||||
}
|
||||
|
||||
writel(data, priv->ioaddr + mii_data);
|
||||
writel(value, priv->ioaddr + mii_address);
|
||||
|
||||
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
|
||||
100, 10000))
|
||||
return -EBUSY;
|
||||
100, 10000)) {
|
||||
data = -EBUSY;
|
||||
goto err_disable_clks;
|
||||
}
|
||||
|
||||
/* Read the data from the MII data register */
|
||||
data = (int)readl(priv->ioaddr + mii_data) & MII_DATA_MASK;
|
||||
|
||||
err_disable_clks:
|
||||
pm_runtime_put(priv->device);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -247,10 +293,16 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
unsigned int mii_address = priv->hw->mii.addr;
|
||||
unsigned int mii_data = priv->hw->mii.data;
|
||||
int ret, data = phydata;
|
||||
u32 value = MII_BUSY;
|
||||
int data = phydata;
|
||||
u32 v;
|
||||
|
||||
ret = pm_runtime_get_sync(priv->device);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(priv->device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
value |= (phyaddr << priv->hw->mii.addr_shift)
|
||||
& priv->hw->mii.addr_mask;
|
||||
value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
|
||||
@ -275,16 +327,23 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
|
||||
|
||||
/* Wait until any existing MII operation is complete */
|
||||
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
|
||||
100, 10000))
|
||||
return -EBUSY;
|
||||
100, 10000)) {
|
||||
ret = -EBUSY;
|
||||
goto err_disable_clks;
|
||||
}
|
||||
|
||||
/* Set the MII address register to write */
|
||||
writel(data, priv->ioaddr + mii_data);
|
||||
writel(value, priv->ioaddr + mii_address);
|
||||
|
||||
/* Wait until any existing MII operation is complete */
|
||||
return readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
|
||||
100, 10000);
|
||||
ret = readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
|
||||
100, 10000);
|
||||
|
||||
err_disable_clks:
|
||||
pm_runtime_put(priv->device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -720,7 +720,6 @@ int stmmac_pltfr_remove(struct platform_device *pdev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
/**
|
||||
* stmmac_pltfr_suspend
|
||||
* @dev: device pointer
|
||||
@ -728,7 +727,7 @@ EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
|
||||
* call the main suspend function and then, if required, on some platform, it
|
||||
* can call an exit helper.
|
||||
*/
|
||||
static int stmmac_pltfr_suspend(struct device *dev)
|
||||
static int __maybe_unused stmmac_pltfr_suspend(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
@ -749,7 +748,7 @@ static int stmmac_pltfr_suspend(struct device *dev)
|
||||
* the main resume function, on some platforms, it can call own init helper
|
||||
* if required.
|
||||
*/
|
||||
static int stmmac_pltfr_resume(struct device *dev)
|
||||
static int __maybe_unused stmmac_pltfr_resume(struct device *dev)
|
||||
{
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
@ -760,10 +759,29 @@ static int stmmac_pltfr_resume(struct device *dev)
|
||||
|
||||
return stmmac_resume(dev);
|
||||
}
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops, stmmac_pltfr_suspend,
|
||||
stmmac_pltfr_resume);
|
||||
static int __maybe_unused stmmac_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
|
||||
stmmac_bus_clks_config(priv, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused stmmac_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct net_device *ndev = dev_get_drvdata(dev);
|
||||
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||
|
||||
return stmmac_bus_clks_config(priv, true);
|
||||
}
|
||||
|
||||
const struct dev_pm_ops stmmac_pltfr_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(stmmac_pltfr_suspend, stmmac_pltfr_resume)
|
||||
SET_RUNTIME_PM_OPS(stmmac_runtime_suspend, stmmac_runtime_resume, NULL)
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(stmmac_pltfr_pm_ops);
|
||||
|
||||
MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet platform support");
|
||||
|
@ -395,18 +395,6 @@ static void free_msi_irqs(struct pci_dev *dev)
|
||||
for (i = 0; i < entry->nvec_used; i++)
|
||||
BUG_ON(irq_has_action(entry->irq + i));
|
||||
|
||||
pci_msi_teardown_msi_irqs(dev);
|
||||
|
||||
list_for_each_entry_safe(entry, tmp, msi_list, list) {
|
||||
if (entry->msi_attrib.is_msix) {
|
||||
if (list_is_last(&entry->list, msi_list))
|
||||
iounmap(entry->mask_base);
|
||||
}
|
||||
|
||||
list_del(&entry->list);
|
||||
free_msi_entry(entry);
|
||||
}
|
||||
|
||||
if (dev->msi_irq_groups) {
|
||||
sysfs_remove_groups(&dev->dev.kobj, dev->msi_irq_groups);
|
||||
msi_attrs = dev->msi_irq_groups[0]->attrs;
|
||||
@ -422,6 +410,18 @@ static void free_msi_irqs(struct pci_dev *dev)
|
||||
kfree(dev->msi_irq_groups);
|
||||
dev->msi_irq_groups = NULL;
|
||||
}
|
||||
|
||||
pci_msi_teardown_msi_irqs(dev);
|
||||
|
||||
list_for_each_entry_safe(entry, tmp, msi_list, list) {
|
||||
if (entry->msi_attrib.is_msix) {
|
||||
if (list_is_last(&entry->list, msi_list))
|
||||
iounmap(entry->mask_base);
|
||||
}
|
||||
|
||||
list_del(&entry->list);
|
||||
free_msi_entry(entry);
|
||||
}
|
||||
}
|
||||
|
||||
static void pci_intx_for_msi(struct pci_dev *dev, int enable)
|
||||
@ -591,6 +591,9 @@ msi_setup_entry(struct pci_dev *dev, int nvec, struct irq_affinity *affd)
|
||||
goto out;
|
||||
|
||||
pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);
|
||||
/* Lies, damned lies, and MSIs */
|
||||
if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING)
|
||||
control |= PCI_MSI_FLAGS_MASKBIT;
|
||||
|
||||
entry->msi_attrib.is_msix = 0;
|
||||
entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT);
|
||||
|
@ -5756,3 +5756,9 @@ static void apex_pci_fixup_class(struct pci_dev *pdev)
|
||||
}
|
||||
DECLARE_PCI_FIXUP_CLASS_HEADER(0x1ac1, 0x089a,
|
||||
PCI_CLASS_NOT_DEFINED, 8, apex_pci_fixup_class);
|
||||
|
||||
static void nvidia_ion_ahci_fixup(struct pci_dev *pdev)
|
||||
{
|
||||
pdev->dev_flags |= PCI_DEV_FLAGS_HAS_MSI_MASKING;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0ab8, nvidia_ion_ahci_fixup);
|
||||
|
@ -376,11 +376,10 @@ static bool z_erofs_try_inplace_io(struct z_erofs_collector *clt,
|
||||
|
||||
/* callers must be with collection lock held */
|
||||
static int z_erofs_attach_page(struct z_erofs_collector *clt,
|
||||
struct page *page,
|
||||
enum z_erofs_page_type type)
|
||||
struct page *page, enum z_erofs_page_type type,
|
||||
bool pvec_safereuse)
|
||||
{
|
||||
int ret;
|
||||
bool occupied;
|
||||
|
||||
/* give priority for inplaceio */
|
||||
if (clt->mode >= COLLECT_PRIMARY &&
|
||||
@ -388,10 +387,9 @@ static int z_erofs_attach_page(struct z_erofs_collector *clt,
|
||||
z_erofs_try_inplace_io(clt, page))
|
||||
return 0;
|
||||
|
||||
ret = z_erofs_pagevec_enqueue(&clt->vector,
|
||||
page, type, &occupied);
|
||||
ret = z_erofs_pagevec_enqueue(&clt->vector, page, type,
|
||||
pvec_safereuse);
|
||||
clt->cl->vcnt += (unsigned int)ret;
|
||||
|
||||
return ret ? 0 : -EAGAIN;
|
||||
}
|
||||
|
||||
@ -737,15 +735,16 @@ static int z_erofs_do_read_page(struct z_erofs_decompress_frontend *fe,
|
||||
tight &= (clt->mode >= COLLECT_PRIMARY_FOLLOWED);
|
||||
|
||||
retry:
|
||||
err = z_erofs_attach_page(clt, page, page_type);
|
||||
/* should allocate an additional short-lived page for pagevec */
|
||||
err = z_erofs_attach_page(clt, page, page_type,
|
||||
clt->mode >= COLLECT_PRIMARY_FOLLOWED);
|
||||
/* should allocate an additional staging page for pagevec */
|
||||
if (err == -EAGAIN) {
|
||||
struct page *const newpage =
|
||||
alloc_page(GFP_NOFS | __GFP_NOFAIL);
|
||||
|
||||
set_page_private(newpage, Z_EROFS_SHORTLIVED_PAGE);
|
||||
err = z_erofs_attach_page(clt, newpage,
|
||||
Z_EROFS_PAGE_TYPE_EXCLUSIVE);
|
||||
Z_EROFS_PAGE_TYPE_EXCLUSIVE, true);
|
||||
if (!err)
|
||||
goto retry;
|
||||
}
|
||||
|
@ -108,12 +108,17 @@ static inline void z_erofs_pagevec_ctor_init(struct z_erofs_pagevec_ctor *ctor,
|
||||
static inline bool z_erofs_pagevec_enqueue(struct z_erofs_pagevec_ctor *ctor,
|
||||
struct page *page,
|
||||
enum z_erofs_page_type type,
|
||||
bool *occupied)
|
||||
bool pvec_safereuse)
|
||||
{
|
||||
*occupied = false;
|
||||
if (!ctor->next && type)
|
||||
if (ctor->index + 1 == ctor->nr)
|
||||
if (!ctor->next) {
|
||||
/* some pages cannot be reused as pvec safely without I/O */
|
||||
if (type == Z_EROFS_PAGE_TYPE_EXCLUSIVE && !pvec_safereuse)
|
||||
type = Z_EROFS_VLE_PAGE_TYPE_TAIL_SHARED;
|
||||
|
||||
if (type != Z_EROFS_PAGE_TYPE_EXCLUSIVE &&
|
||||
ctor->index + 1 == ctor->nr)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctor->index >= ctor->nr)
|
||||
z_erofs_pagevec_ctor_pagedown(ctor, false);
|
||||
@ -125,7 +130,6 @@ static inline bool z_erofs_pagevec_enqueue(struct z_erofs_pagevec_ctor *ctor,
|
||||
/* should remind that collector->next never equal to 1, 2 */
|
||||
if (type == (uintptr_t)ctor->next) {
|
||||
ctor->next = page;
|
||||
*occupied = true;
|
||||
}
|
||||
ctor->pages[ctor->index++] = tagptr_fold(erofs_vtptr_t, page, type);
|
||||
return true;
|
||||
|
@ -61,6 +61,14 @@ struct blk_keyslot_manager;
|
||||
*/
|
||||
#define BLKCG_MAX_POLS 5
|
||||
|
||||
static inline int blk_validate_block_size(unsigned int bsize)
|
||||
{
|
||||
if (bsize < 512 || bsize > PAGE_SIZE || !is_power_of_2(bsize))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef void (rq_end_io_fn)(struct request *, blk_status_t);
|
||||
|
||||
/*
|
||||
|
@ -228,6 +228,8 @@ enum pci_dev_flags {
|
||||
PCI_DEV_FLAGS_NO_FLR_RESET = (__force pci_dev_flags_t) (1 << 10),
|
||||
/* Don't use Relaxed Ordering for TLPs directed at this device */
|
||||
PCI_DEV_FLAGS_NO_RELAXED_ORDERING = (__force pci_dev_flags_t) (1 << 11),
|
||||
/* Device does honor MSI masking despite saying otherwise */
|
||||
PCI_DEV_FLAGS_HAS_MSI_MASKING = (__force pci_dev_flags_t) (1 << 12),
|
||||
};
|
||||
|
||||
enum pci_irq_reroute_variant {
|
||||
|
@ -382,6 +382,7 @@ static char * __init xbc_make_cmdline(const char *key)
|
||||
ret = xbc_snprint_cmdline(new_cmdline, len + 1, root);
|
||||
if (ret < 0 || ret > len) {
|
||||
pr_err("Failed to print extra kernel cmdline.\n");
|
||||
memblock_free(__pa(new_cmdline), len + 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -7037,7 +7037,6 @@ void perf_output_sample(struct perf_output_handle *handle,
|
||||
static u64 perf_virt_to_phys(u64 virt)
|
||||
{
|
||||
u64 phys_addr = 0;
|
||||
struct page *p = NULL;
|
||||
|
||||
if (!virt)
|
||||
return 0;
|
||||
@ -7056,14 +7055,15 @@ static u64 perf_virt_to_phys(u64 virt)
|
||||
* If failed, leave phys_addr as 0.
|
||||
*/
|
||||
if (current->mm != NULL) {
|
||||
struct page *p;
|
||||
|
||||
pagefault_disable();
|
||||
if (get_user_page_fast_only(virt, 0, &p))
|
||||
if (get_user_page_fast_only(virt, 0, &p)) {
|
||||
phys_addr = page_to_phys(p) + virt % PAGE_SIZE;
|
||||
put_page(p);
|
||||
}
|
||||
pagefault_enable();
|
||||
}
|
||||
|
||||
if (p)
|
||||
put_page(p);
|
||||
}
|
||||
|
||||
return phys_addr;
|
||||
|
@ -6,15 +6,32 @@
|
||||
# Print the linker version of `ld.lld' in a 5 or 6-digit form
|
||||
# such as `100001' for ld.lld 10.0.1 etc.
|
||||
|
||||
linker_string="$($* --version)"
|
||||
set -e
|
||||
|
||||
if ! ( echo $linker_string | grep -q LLD ); then
|
||||
# Convert the version string x.y.z to a canonical 5 or 6-digit form.
|
||||
get_canonical_version()
|
||||
{
|
||||
IFS=.
|
||||
set -- $1
|
||||
|
||||
# If the 2nd or 3rd field is missing, fill it with a zero.
|
||||
echo $((10000 * $1 + 100 * ${2:-0} + ${3:-0}))
|
||||
}
|
||||
|
||||
# Get the first line of the --version output.
|
||||
IFS='
|
||||
'
|
||||
set -- $(LC_ALL=C "$@" --version)
|
||||
|
||||
# Split the line on spaces.
|
||||
IFS=' '
|
||||
set -- $1
|
||||
|
||||
while [ $# -gt 1 -a "$1" != "LLD" ]; do
|
||||
shift
|
||||
done
|
||||
if [ "$1" = LLD ]; then
|
||||
echo $(get_canonical_version ${2%-*})
|
||||
else
|
||||
echo 0
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION=$(echo $linker_string | cut -d ' ' -f 2)
|
||||
MAJOR=$(echo $VERSION | cut -d . -f 1)
|
||||
MINOR=$(echo $VERSION | cut -d . -f 2)
|
||||
PATCHLEVEL=$(echo $VERSION | cut -d . -f 3)
|
||||
printf "%d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL
|
||||
|
@ -191,6 +191,9 @@ config HARDENED_USERCOPY_PAGESPAN
|
||||
config FORTIFY_SOURCE
|
||||
bool "Harden common str/mem functions against buffer overflows"
|
||||
depends on ARCH_HAS_FORTIFY_SOURCE
|
||||
# https://bugs.llvm.org/show_bug.cgi?id=50322
|
||||
# https://bugs.llvm.org/show_bug.cgi?id=41459
|
||||
depends on !CC_IS_CLANG
|
||||
help
|
||||
Detect overflows of buffers in common string and memory functions
|
||||
where the compiler can determine and validate the buffer sizes.
|
||||
|
@ -85,48 +85,88 @@ static void expect_gp_outb(unsigned short port)
|
||||
printf("[OK]\toutb to 0x%02hx failed\n", port);
|
||||
}
|
||||
|
||||
static bool try_cli(void)
|
||||
#define RET_FAULTED 0
|
||||
#define RET_FAIL 1
|
||||
#define RET_EMUL 2
|
||||
|
||||
static int try_cli(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
sethandler(SIGSEGV, sigsegv, SA_RESETHAND);
|
||||
if (sigsetjmp(jmpbuf, 1) != 0) {
|
||||
return false;
|
||||
return RET_FAULTED;
|
||||
} else {
|
||||
asm volatile ("cli");
|
||||
return true;
|
||||
asm volatile("cli; pushf; pop %[flags]"
|
||||
: [flags] "=rm" (flags));
|
||||
|
||||
/* X86_FLAGS_IF */
|
||||
if (!(flags & (1 << 9)))
|
||||
return RET_FAIL;
|
||||
else
|
||||
return RET_EMUL;
|
||||
}
|
||||
clearhandler(SIGSEGV);
|
||||
}
|
||||
|
||||
static bool try_sti(void)
|
||||
static int try_sti(bool irqs_off)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
sethandler(SIGSEGV, sigsegv, SA_RESETHAND);
|
||||
if (sigsetjmp(jmpbuf, 1) != 0) {
|
||||
return false;
|
||||
return RET_FAULTED;
|
||||
} else {
|
||||
asm volatile ("sti");
|
||||
return true;
|
||||
asm volatile("sti; pushf; pop %[flags]"
|
||||
: [flags] "=rm" (flags));
|
||||
|
||||
/* X86_FLAGS_IF */
|
||||
if (irqs_off && (flags & (1 << 9)))
|
||||
return RET_FAIL;
|
||||
else
|
||||
return RET_EMUL;
|
||||
}
|
||||
clearhandler(SIGSEGV);
|
||||
}
|
||||
|
||||
static void expect_gp_sti(void)
|
||||
static void expect_gp_sti(bool irqs_off)
|
||||
{
|
||||
if (try_sti()) {
|
||||
int ret = try_sti(irqs_off);
|
||||
|
||||
switch (ret) {
|
||||
case RET_FAULTED:
|
||||
printf("[OK]\tSTI faulted\n");
|
||||
break;
|
||||
case RET_EMUL:
|
||||
printf("[OK]\tSTI NOPped\n");
|
||||
break;
|
||||
default:
|
||||
printf("[FAIL]\tSTI worked\n");
|
||||
nerrs++;
|
||||
} else {
|
||||
printf("[OK]\tSTI faulted\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void expect_gp_cli(void)
|
||||
/*
|
||||
* Returns whether it managed to disable interrupts.
|
||||
*/
|
||||
static bool test_cli(void)
|
||||
{
|
||||
if (try_cli()) {
|
||||
int ret = try_cli();
|
||||
|
||||
switch (ret) {
|
||||
case RET_FAULTED:
|
||||
printf("[OK]\tCLI faulted\n");
|
||||
break;
|
||||
case RET_EMUL:
|
||||
printf("[OK]\tCLI NOPped\n");
|
||||
break;
|
||||
default:
|
||||
printf("[FAIL]\tCLI worked\n");
|
||||
nerrs++;
|
||||
} else {
|
||||
printf("[OK]\tCLI faulted\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
@ -152,8 +192,7 @@ int main(void)
|
||||
}
|
||||
|
||||
/* Make sure that CLI/STI are blocked even with IOPL level 3 */
|
||||
expect_gp_cli();
|
||||
expect_gp_sti();
|
||||
expect_gp_sti(test_cli());
|
||||
expect_ok_outb(0x80);
|
||||
|
||||
/* Establish an I/O bitmap to test the restore */
|
||||
@ -204,8 +243,7 @@ int main(void)
|
||||
printf("[RUN]\tparent: write to 0x80 (should fail)\n");
|
||||
|
||||
expect_gp_outb(0x80);
|
||||
expect_gp_cli();
|
||||
expect_gp_sti();
|
||||
expect_gp_sti(test_cli());
|
||||
|
||||
/* Test the capability checks. */
|
||||
printf("\tiopl(3)\n");
|
||||
|
Loading…
Reference in New Issue
Block a user