ASoC: Fixes for v4.2
There are a couple of small driver specific fixes here but the overwhelming bulk of these changes are fixes to the topology ABI that has been newly introduced in v4.2. Once this makes it into a release we will have to firm this up but for now getting enhancements in before they've made it into a release is the most expedient thing. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJVxJsBAAoJECTWi3JdVIfQHUIH/2NeQyG7bL3TSIm0qK9RdmaT UrWyGm6AwhOrg9j9jnZkXag1v4Fsmo4nnslaDbmCKaWJPs7ol94NuWJK7z3He3nr 47yxl2m8OhxsS7aBDACa4gJFQce+JSjKs1ADnKR7QzY9c1/nTAWLO/LE/I5Ca18u tZg77hviip2ftfLYdNXDZvz3HzuCcRnIouc4izTs16DXwU3aYpqcctFrcqU3nNmp /+5zPwIoLA7KDwPqdYhSPNRuCnFtjVbI8hTzq+aWFlxFBZYlKmSCTSwpCN2aQDgF 1oCOP4dlv7s9Xavd2TOMJ8g3Fuyb/gjX2DhIEm7QCYxwBxdkpwm0na6gMrRJqsg= =NEOq -----END PGP SIGNATURE----- Merge tag 'asoc-fix-v4.2-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus ASoC: Fixes for v4.2 There are a couple of small driver specific fixes here but the overwhelming bulk of these changes are fixes to the topology ABI that has been newly introduced in v4.2. Once this makes it into a release we will have to firm this up but for now getting enhancements in before they've made it into a release is the most expedient thing.
This commit is contained in:
commit
6ac7ada210
|
@ -35,7 +35,7 @@ Example:
|
|||
device_type = "dma";
|
||||
reg = <0x0 0x1f270000 0x0 0x10000>,
|
||||
<0x0 0x1f200000 0x0 0x10000>,
|
||||
<0x0 0x1b008000 0x0 0x2000>,
|
||||
<0x0 0x1b000000 0x0 0x400000>,
|
||||
<0x0 0x1054a000 0x0 0x100>;
|
||||
interrupts = <0x0 0x82 0x4>,
|
||||
<0x0 0xb8 0x4>,
|
||||
|
|
|
@ -35,3 +35,6 @@ the PCIe specification.
|
|||
|
||||
NOTE: this only applies to the SMMU itself, not
|
||||
masters connected upstream of the SMMU.
|
||||
|
||||
- hisilicon,broken-prefetch-cmd
|
||||
: Avoid sending CMD_PREFETCH_* commands to the SMMU.
|
||||
|
|
|
@ -17,7 +17,6 @@ Required properties:
|
|||
"fsl,imx6sx-usdhc"
|
||||
|
||||
Optional properties:
|
||||
- fsl,cd-controller : Indicate to use controller internal card detection
|
||||
- fsl,wp-controller : Indicate to use controller internal write protection
|
||||
- fsl,delay-line : Specify the number of delay cells for override mode.
|
||||
This is used to set the clock delay for DLL(Delay Line) on override mode
|
||||
|
@ -35,7 +34,6 @@ esdhc@70004000 {
|
|||
compatible = "fsl,imx51-esdhc";
|
||||
reg = <0x70004000 0x4000>;
|
||||
interrupts = <1>;
|
||||
fsl,cd-controller;
|
||||
fsl,wp-controller;
|
||||
};
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ Binding for Qualcomm Atheros AR7xxx/AR9xxx SPI controller
|
|||
Required properties:
|
||||
- compatible: has to be "qca,<soc-type>-spi", "qca,ar7100-spi" as fallback.
|
||||
- reg: Base address and size of the controllers memory area
|
||||
- clocks: phandle to the AHB clock.
|
||||
- clocks: phandle of the AHB clock.
|
||||
- clock-names: has to be "ahb".
|
||||
- #address-cells: <1>, as required by generic SPI binding.
|
||||
- #size-cells: <0>, also as required by generic SPI binding.
|
||||
|
@ -12,9 +12,9 @@ Child nodes as per the generic SPI binding.
|
|||
|
||||
Example:
|
||||
|
||||
spi@1F000000 {
|
||||
spi@1f000000 {
|
||||
compatible = "qca,ar9132-spi", "qca,ar7100-spi";
|
||||
reg = <0x1F000000 0x10>;
|
||||
reg = <0x1f000000 0x10>;
|
||||
|
||||
clocks = <&pll 2>;
|
||||
clock-names = "ahb";
|
||||
|
|
|
@ -35,11 +35,11 @@ temp1_input Local temperature (1/1000 degree,
|
|||
temp[2-9]_input CPU temperatures (1/1000 degree,
|
||||
0.125 degree resolution)
|
||||
|
||||
fan[1-4]_mode R/W, 0/1 for manual or SmartFan mode
|
||||
pwm[1-4]_enable R/W, 1/2 for manual or SmartFan mode
|
||||
Setting SmartFan mode is supported only if it has been
|
||||
previously configured by BIOS (or configuration EEPROM)
|
||||
|
||||
fan[1-4]_pwm R/O in SmartFan mode, R/W in manual control mode
|
||||
pwm[1-4] R/O in SmartFan mode, R/W in manual control mode
|
||||
|
||||
The driver checks sensor control registers and does not export the sensors
|
||||
that are not enabled. Anyway, a sensor that is enabled may actually be not
|
||||
|
|
|
@ -199,7 +199,8 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
|
|||
buf += "#include <linux/string.h>\n"
|
||||
buf += "#include <linux/configfs.h>\n"
|
||||
buf += "#include <linux/ctype.h>\n"
|
||||
buf += "#include <asm/unaligned.h>\n\n"
|
||||
buf += "#include <asm/unaligned.h>\n"
|
||||
buf += "#include <scsi/scsi_proto.h>\n\n"
|
||||
buf += "#include <target/target_core_base.h>\n"
|
||||
buf += "#include <target/target_core_fabric.h>\n"
|
||||
buf += "#include <target/target_core_fabric_configfs.h>\n"
|
||||
|
@ -230,8 +231,14 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
|
|||
buf += " }\n"
|
||||
buf += " tpg->" + fabric_mod_port + " = " + fabric_mod_port + ";\n"
|
||||
buf += " tpg->" + fabric_mod_port + "_tpgt = tpgt;\n\n"
|
||||
buf += " ret = core_tpg_register(&" + fabric_mod_name + "_ops, wwn,\n"
|
||||
buf += " &tpg->se_tpg, SCSI_PROTOCOL_SAS);\n"
|
||||
|
||||
if proto_ident == "FC":
|
||||
buf += " ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_FCP);\n"
|
||||
elif proto_ident == "SAS":
|
||||
buf += " ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_SAS);\n"
|
||||
elif proto_ident == "iSCSI":
|
||||
buf += " ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_ISCSI);\n"
|
||||
|
||||
buf += " if (ret < 0) {\n"
|
||||
buf += " kfree(tpg);\n"
|
||||
buf += " return NULL;\n"
|
||||
|
@ -292,7 +299,7 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
|
|||
|
||||
buf += "static const struct target_core_fabric_ops " + fabric_mod_name + "_ops = {\n"
|
||||
buf += " .module = THIS_MODULE,\n"
|
||||
buf += " .name = " + fabric_mod_name + ",\n"
|
||||
buf += " .name = \"" + fabric_mod_name + "\",\n"
|
||||
buf += " .get_fabric_name = " + fabric_mod_name + "_get_fabric_name,\n"
|
||||
buf += " .tpg_get_wwn = " + fabric_mod_name + "_get_fabric_wwn,\n"
|
||||
buf += " .tpg_get_tag = " + fabric_mod_name + "_get_tag,\n"
|
||||
|
@ -322,17 +329,17 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
|
|||
buf += " .fabric_make_tpg = " + fabric_mod_name + "_make_tpg,\n"
|
||||
buf += " .fabric_drop_tpg = " + fabric_mod_name + "_drop_tpg,\n"
|
||||
buf += "\n"
|
||||
buf += " .tfc_wwn_attrs = " + fabric_mod_name + "_wwn_attrs;\n"
|
||||
buf += " .tfc_wwn_attrs = " + fabric_mod_name + "_wwn_attrs,\n"
|
||||
buf += "};\n\n"
|
||||
|
||||
buf += "static int __init " + fabric_mod_name + "_init(void)\n"
|
||||
buf += "{\n"
|
||||
buf += " return target_register_template(" + fabric_mod_name + "_ops);\n"
|
||||
buf += " return target_register_template(&" + fabric_mod_name + "_ops);\n"
|
||||
buf += "};\n\n"
|
||||
|
||||
buf += "static void __exit " + fabric_mod_name + "_exit(void)\n"
|
||||
buf += "{\n"
|
||||
buf += " target_unregister_template(" + fabric_mod_name + "_ops);\n"
|
||||
buf += " target_unregister_template(&" + fabric_mod_name + "_ops);\n"
|
||||
buf += "};\n\n"
|
||||
|
||||
buf += "MODULE_DESCRIPTION(\"" + fabric_mod_name.upper() + " series fabric driver\");\n"
|
||||
|
|
22
MAINTAINERS
22
MAINTAINERS
|
@ -5600,6 +5600,7 @@ F: kernel/irq/
|
|||
IRQCHIP DRIVERS
|
||||
M: Thomas Gleixner <tglx@linutronix.de>
|
||||
M: Jason Cooper <jason@lakedaemon.net>
|
||||
M: Marc Zyngier <marc.zyngier@arm.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
|
||||
|
@ -5608,11 +5609,14 @@ F: Documentation/devicetree/bindings/interrupt-controller/
|
|||
F: drivers/irqchip/
|
||||
|
||||
IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
|
||||
M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
M: Jiang Liu <jiang.liu@linux.intel.com>
|
||||
M: Marc Zyngier <marc.zyngier@arm.com>
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
|
||||
F: Documentation/IRQ-domain.txt
|
||||
F: include/linux/irqdomain.h
|
||||
F: kernel/irq/irqdomain.c
|
||||
F: kernel/irq/msi.c
|
||||
|
||||
ISAPNP
|
||||
M: Jaroslav Kysela <perex@perex.cz>
|
||||
|
@ -5899,7 +5903,6 @@ S: Supported
|
|||
F: Documentation/s390/kvm.txt
|
||||
F: arch/s390/include/asm/kvm*
|
||||
F: arch/s390/kvm/
|
||||
F: drivers/s390/kvm/
|
||||
|
||||
KERNEL VIRTUAL MACHINE (KVM) FOR ARM
|
||||
M: Christoffer Dall <christoffer.dall@linaro.org>
|
||||
|
@ -6839,6 +6842,12 @@ T: git git://linuxtv.org/anttip/media_tree.git
|
|||
S: Maintained
|
||||
F: drivers/media/usb/msi2500/
|
||||
|
||||
MSYSTEMS DISKONCHIP G3 MTD DRIVER
|
||||
M: Robert Jarzmik <robert.jarzmik@free.fr>
|
||||
L: linux-mtd@lists.infradead.org
|
||||
S: Maintained
|
||||
F: drivers/mtd/devices/docg3*
|
||||
|
||||
MT9M032 APTINA SENSOR DRIVER
|
||||
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
@ -10896,6 +10905,15 @@ F: drivers/block/virtio_blk.c
|
|||
F: include/linux/virtio_*.h
|
||||
F: include/uapi/linux/virtio_*.h
|
||||
|
||||
VIRTIO DRIVERS FOR S390
|
||||
M: Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
M: Cornelia Huck <cornelia.huck@de.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
L: virtualization@lists.linux-foundation.org
|
||||
L: kvm@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/s390/virtio/
|
||||
|
||||
VIRTIO GPU DRIVER
|
||||
M: David Airlie <airlied@linux.ie>
|
||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 2
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc3
|
||||
EXTRAVERSION = -rc5
|
||||
NAME = Hurr durr I'ma sheep
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -138,8 +138,8 @@
|
|||
|
||||
mipi_phy: video-phy@10020710 {
|
||||
compatible = "samsung,s5pv210-mipi-video-phy";
|
||||
reg = <0x10020710 8>;
|
||||
#phy-cells = <1>;
|
||||
syscon = <&pmu_system_controller>;
|
||||
};
|
||||
|
||||
pd_cam: cam-power-domain@10023C00 {
|
||||
|
|
|
@ -127,6 +127,10 @@
|
|||
};
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu0-supply = <&buck1_reg>;
|
||||
};
|
||||
|
||||
&fimd {
|
||||
pinctrl-0 = <&lcd_en &lcd_clk &lcd_data24 &pwm0_out>;
|
||||
pinctrl-names = "default";
|
||||
|
|
|
@ -188,6 +188,10 @@
|
|||
};
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu0-supply = <&varm_breg>;
|
||||
};
|
||||
|
||||
&dsi_0 {
|
||||
vddcore-supply = <&vusb_reg>;
|
||||
vddio-supply = <&vmipi_reg>;
|
||||
|
|
|
@ -548,6 +548,10 @@
|
|||
};
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
cpu0-supply = <&vdd_arm_reg>;
|
||||
};
|
||||
|
||||
&pinctrl_1 {
|
||||
hdmi_hpd: hdmi-hpd {
|
||||
samsung,pins = "gpx3-7";
|
||||
|
|
|
@ -40,6 +40,18 @@
|
|||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a9";
|
||||
reg = <0x900>;
|
||||
clocks = <&clock CLK_ARM_CLK>;
|
||||
clock-names = "cpu";
|
||||
clock-latency = <160000>;
|
||||
|
||||
operating-points = <
|
||||
1200000 1250000
|
||||
1000000 1150000
|
||||
800000 1075000
|
||||
500000 975000
|
||||
400000 975000
|
||||
200000 950000
|
||||
>;
|
||||
cooling-min-level = <4>;
|
||||
cooling-max-level = <2>;
|
||||
#cooling-cells = <2>; /* min followed by max */
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include "imx25.dtsi"
|
||||
|
||||
|
@ -114,8 +115,8 @@
|
|||
&esdhc1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_esdhc1>;
|
||||
cd-gpios = <&gpio2 1 0>;
|
||||
wp-gpios = <&gpio2 0 0>;
|
||||
cd-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
|
@ -286,8 +286,8 @@
|
|||
can1: can@53fe4000 {
|
||||
compatible = "fsl,imx35-flexcan", "fsl,p1010-flexcan";
|
||||
reg = <0x53fe4000 0x1000>;
|
||||
clocks = <&clks 33>;
|
||||
clock-names = "ipg";
|
||||
clocks = <&clks 33>, <&clks 33>;
|
||||
clock-names = "ipg", "per";
|
||||
interrupts = <43>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -295,8 +295,8 @@
|
|||
can2: can@53fe8000 {
|
||||
compatible = "fsl,imx35-flexcan", "fsl,p1010-flexcan";
|
||||
reg = <0x53fe8000 0x1000>;
|
||||
clocks = <&clks 34>;
|
||||
clock-names = "ipg";
|
||||
clocks = <&clks 34>, <&clks 34>;
|
||||
clock-names = "ipg", "per";
|
||||
interrupts = <44>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
&esdhc1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_esdhc1>;
|
||||
cd-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio2 29 GPIO_ACTIVE_LOW>;
|
||||
bus-width = <4>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -103,8 +103,8 @@
|
|||
&esdhc1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_esdhc1>;
|
||||
cd-gpios = <&gpio1 1 0>;
|
||||
wp-gpios = <&gpio1 9 0>;
|
||||
cd-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
|
@ -124,8 +124,8 @@
|
|||
&esdhc1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_esdhc1>;
|
||||
cd-gpios = <&gpio1 1 0>;
|
||||
wp-gpios = <&gpio1 9 0>;
|
||||
cd-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
|
@ -147,8 +147,8 @@
|
|||
&esdhc3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_esdhc3>;
|
||||
cd-gpios = <&gpio3 11 0>;
|
||||
wp-gpios = <&gpio3 12 0>;
|
||||
cd-gpios = <&gpio3 11 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio3 12 GPIO_ACTIVE_HIGH>;
|
||||
bus-width = <8>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -41,8 +41,8 @@
|
|||
&esdhc1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_esdhc1>;
|
||||
cd-gpios = <&gpio3 13 0>;
|
||||
wp-gpios = <&gpio4 11 0>;
|
||||
cd-gpios = <&gpio3 13 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio4 11 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
|
@ -41,8 +41,8 @@
|
|||
pinctrl-0 = <&pinctrl_esdhc2>,
|
||||
<&pinctrl_esdhc2_cdwp>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
wp-gpios = <&gpio1 2 0>;
|
||||
cd-gpios = <&gpio1 4 0>;
|
||||
wp-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -183,7 +183,7 @@
|
|||
};
|
||||
|
||||
&esdhc1 {
|
||||
cd-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>;
|
||||
fsl,wp-controller;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_esdhc1>;
|
||||
|
@ -191,7 +191,7 @@
|
|||
};
|
||||
|
||||
&esdhc2 {
|
||||
cd-gpios = <&gpio3 25 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
|
||||
fsl,wp-controller;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_esdhc2>;
|
||||
|
|
|
@ -119,8 +119,8 @@
|
|||
&esdhc2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_esdhc2>;
|
||||
cd-gpios = <&gpio3 25 0>;
|
||||
wp-gpios = <&gpio2 19 0>;
|
||||
cd-gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -305,8 +305,8 @@
|
|||
&usdhc2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc2>;
|
||||
cd-gpios = <&gpio1 4 0>;
|
||||
wp-gpios = <&gpio1 2 0>;
|
||||
cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -314,8 +314,8 @@
|
|||
&usdhc3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
cd-gpios = <&gpio7 0 0>;
|
||||
wp-gpios = <&gpio7 1 0>;
|
||||
cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include "imx6q.dtsi"
|
||||
|
||||
/ {
|
||||
|
@ -196,8 +197,8 @@
|
|||
};
|
||||
|
||||
&usdhc3 {
|
||||
cd-gpios = <&gpio6 11 0>;
|
||||
wp-gpios = <&gpio6 14 0>;
|
||||
cd-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio6 14 GPIO_ACTIVE_HIGH>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc3
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include "imx6q.dtsi"
|
||||
|
||||
/ {
|
||||
|
@ -161,7 +162,7 @@
|
|||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
bus-width = <4>;
|
||||
cd-gpios = <&gpio6 11 0>;
|
||||
cd-gpios = <&gpio6 11 GPIO_ACTIVE_LOW>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -251,7 +251,7 @@
|
|||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc2>;
|
||||
bus-width = <4>;
|
||||
cd-gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -260,7 +260,7 @@
|
|||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
bus-width = <4>;
|
||||
cd-gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
|
|
|
@ -173,7 +173,7 @@
|
|||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc1>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
cd-gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio4 7 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
@ -181,7 +181,7 @@
|
|||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc2>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
cd-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio4 8 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
|
@ -392,7 +392,7 @@
|
|||
&usdhc1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc1>;
|
||||
cd-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
|
||||
no-1-8-v;
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -400,7 +400,7 @@
|
|||
&usdhc2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc2>;
|
||||
cd-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
|
||||
no-1-8-v;
|
||||
status = "okay";
|
||||
|
|
|
@ -258,6 +258,6 @@
|
|||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_cubox_i_usdhc2_aux &pinctrl_cubox_i_usdhc2>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
cd-gpios = <&gpio1 4 0>;
|
||||
cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
/ {
|
||||
regulators {
|
||||
compatible = "simple-bus";
|
||||
|
@ -181,7 +183,7 @@
|
|||
&usdhc2 { /* module slot */
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc2>;
|
||||
cd-gpios = <&gpio2 2 0>;
|
||||
cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
|
@ -318,7 +318,7 @@
|
|||
&usdhc3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
cd-gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -324,7 +324,7 @@
|
|||
&usdhc3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
cd-gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -417,7 +417,7 @@
|
|||
&usdhc3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
cd-gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -299,6 +299,6 @@
|
|||
&pinctrl_hummingboard_usdhc2
|
||||
>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
cd-gpios = <&gpio1 4 0>;
|
||||
cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -453,7 +453,7 @@
|
|||
&usdhc3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
cd-gpios = <&gpio7 0 0>;
|
||||
cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -461,7 +461,7 @@
|
|||
&usdhc4 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc4>;
|
||||
cd-gpios = <&gpio2 6 0>;
|
||||
cd-gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -409,8 +409,8 @@
|
|||
&usdhc2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc2>;
|
||||
cd-gpios = <&gpio1 4 0>;
|
||||
wp-gpios = <&gpio1 2 0>;
|
||||
cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -418,7 +418,7 @@
|
|||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc3
|
||||
&pinctrl_usdhc3_cdwp>;
|
||||
cd-gpios = <&gpio1 27 0>;
|
||||
wp-gpios = <&gpio1 29 0>;
|
||||
cd-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -342,7 +342,7 @@
|
|||
pinctrl-0 = <&pinctrl_usdhc2>;
|
||||
bus-width = <4>;
|
||||
cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
@ -351,6 +351,6 @@
|
|||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
bus-width = <4>;
|
||||
cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -467,8 +467,8 @@
|
|||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
|
||||
pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
|
||||
cd-gpios = <&gpio6 15 0>;
|
||||
wp-gpios = <&gpio1 13 0>;
|
||||
cd-gpios = <&gpio6 15 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
|
@ -448,8 +448,8 @@
|
|||
&usdhc3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
cd-gpios = <&gpio7 0 0>;
|
||||
wp-gpios = <&gpio7 1 0>;
|
||||
cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -457,7 +457,7 @@
|
|||
&usdhc4 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc4>;
|
||||
cd-gpios = <&gpio2 6 0>;
|
||||
cd-gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
|
||||
vmmc-supply = <®_3p3v>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -562,8 +562,8 @@
|
|||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc2>;
|
||||
bus-width = <8>;
|
||||
cd-gpios = <&gpio2 2 0>;
|
||||
wp-gpios = <&gpio2 3 0>;
|
||||
cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
@ -571,8 +571,8 @@
|
|||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
bus-width = <8>;
|
||||
cd-gpios = <&gpio2 0 0>;
|
||||
wp-gpios = <&gpio2 1 0>;
|
||||
cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
|
@ -680,7 +680,7 @@
|
|||
pinctrl-0 = <&pinctrl_usdhc1>;
|
||||
bus-width = <4>;
|
||||
no-1-8-v;
|
||||
cd-gpios = <&gpio7 2 0>;
|
||||
cd-gpios = <&gpio7 2 GPIO_ACTIVE_LOW>;
|
||||
fsl,wp-controller;
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -690,7 +690,7 @@
|
|||
pinctrl-0 = <&pinctrl_usdhc2>;
|
||||
bus-width = <4>;
|
||||
no-1-8-v;
|
||||
cd-gpios = <&gpio7 3 0>;
|
||||
cd-gpios = <&gpio7 3 GPIO_ACTIVE_LOW>;
|
||||
fsl,wp-controller;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
/ {
|
||||
regulators {
|
||||
compatible = "simple-bus";
|
||||
|
@ -250,13 +252,13 @@
|
|||
&usdhc1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc1>;
|
||||
cd-gpios = <&gpio1 2 0>;
|
||||
cd-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&usdhc3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
cd-gpios = <&gpio3 9 0>;
|
||||
cd-gpios = <&gpio3 9 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -617,8 +617,8 @@
|
|||
pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
|
||||
pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
|
||||
bus-width = <8>;
|
||||
cd-gpios = <&gpio4 7 0>;
|
||||
wp-gpios = <&gpio4 6 0>;
|
||||
cd-gpios = <&gpio4 7 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
@ -627,8 +627,8 @@
|
|||
pinctrl-0 = <&pinctrl_usdhc2>;
|
||||
pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
|
||||
pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
|
||||
cd-gpios = <&gpio5 0 0>;
|
||||
wp-gpios = <&gpio4 29 0>;
|
||||
cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
@ -637,6 +637,6 @@
|
|||
pinctrl-0 = <&pinctrl_usdhc3>;
|
||||
pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
|
||||
pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
|
||||
cd-gpios = <&gpio3 22 0>;
|
||||
cd-gpios = <&gpio3 22 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
|
||||
pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
|
||||
bus-width = <8>;
|
||||
cd-gpios = <&gpio7 10 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio7 10 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;
|
||||
keep-power-in-suspend;
|
||||
enable-sdio-wakeup;
|
||||
|
@ -61,7 +61,7 @@
|
|||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc4>;
|
||||
bus-width = <8>;
|
||||
cd-gpios = <&gpio7 11 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio7 11 GPIO_ACTIVE_LOW>;
|
||||
no-1-8-v;
|
||||
keep-power-in-suspend;
|
||||
enable-sdio-wakup;
|
||||
|
|
|
@ -293,7 +293,7 @@
|
|||
pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
|
||||
pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
|
||||
bus-width = <8>;
|
||||
cd-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>;
|
||||
keep-power-in-suspend;
|
||||
enable-sdio-wakeup;
|
||||
|
@ -304,7 +304,7 @@
|
|||
&usdhc4 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc4>;
|
||||
cd-gpios = <&gpio6 21 GPIO_ACTIVE_HIGH>;
|
||||
cd-gpios = <&gpio6 21 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio6 20 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -234,8 +234,8 @@
|
|||
&usdhc1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_usdhc1>;
|
||||
cd-gpios = <&gpio5 0 0>;
|
||||
wp-gpios = <&gpio5 1 0>;
|
||||
cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
|
||||
enable-sdio-wakeup;
|
||||
keep-power-in-suspend;
|
||||
status = "okay";
|
||||
|
|
|
@ -13,9 +13,8 @@ clocks {
|
|||
#clock-cells = <0>;
|
||||
compatible = "ti,keystone,main-pll-clock";
|
||||
clocks = <&refclksys>;
|
||||
reg = <0x02620350 4>, <0x02310110 4>;
|
||||
reg-names = "control", "multiplier";
|
||||
fixed-postdiv = <2>;
|
||||
reg = <0x02620350 4>, <0x02310110 4>, <0x02310108 4>;
|
||||
reg-names = "control", "multiplier", "post-divider";
|
||||
};
|
||||
|
||||
papllclk: papllclk@2620358 {
|
||||
|
|
|
@ -22,9 +22,8 @@ clocks {
|
|||
#clock-cells = <0>;
|
||||
compatible = "ti,keystone,main-pll-clock";
|
||||
clocks = <&refclksys>;
|
||||
reg = <0x02620350 4>, <0x02310110 4>;
|
||||
reg-names = "control", "multiplier";
|
||||
fixed-postdiv = <2>;
|
||||
reg = <0x02620350 4>, <0x02310110 4>, <0x02310108 4>;
|
||||
reg-names = "control", "multiplier", "post-divider";
|
||||
};
|
||||
|
||||
papllclk: papllclk@2620358 {
|
||||
|
|
|
@ -22,9 +22,8 @@ clocks {
|
|||
#clock-cells = <0>;
|
||||
compatible = "ti,keystone,main-pll-clock";
|
||||
clocks = <&refclksys>;
|
||||
reg = <0x02620350 4>, <0x02310110 4>;
|
||||
reg-names = "control", "multiplier";
|
||||
fixed-postdiv = <2>;
|
||||
reg = <0x02620350 4>, <0x02310110 4>, <0x02310108 4>;
|
||||
reg-names = "control", "multiplier", "post-divider";
|
||||
};
|
||||
|
||||
papllclk: papllclk@2620358 {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
};
|
||||
|
||||
aliases {
|
||||
serial1 = &uart1;
|
||||
stmpe-i2c0 = &stmpe0;
|
||||
stmpe-i2c1 = &stmpe1;
|
||||
};
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
bootargs = "root=/dev/ram0 console=ttyAMA1,115200n8 earlyprintk";
|
||||
};
|
||||
|
||||
aliases {
|
||||
serial1 = &uart1;
|
||||
};
|
||||
|
||||
src@101e0000 {
|
||||
/* These chrystal drivers are not used on this board */
|
||||
disable-sxtalo;
|
||||
|
|
|
@ -757,6 +757,7 @@
|
|||
clock-names = "uartclk", "apb_pclk";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart0_default_mux>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart1: uart@101fb000 {
|
||||
|
|
|
@ -2373,6 +2373,9 @@ static int of_dev_hwmod_lookup(struct device_node *np,
|
|||
* registers. This address is needed early so the OCP registers that
|
||||
* are part of the device's address space can be ioremapped properly.
|
||||
*
|
||||
* If SYSC access is not needed, the registers will not be remapped
|
||||
* and non-availability of MPU access is not treated as an error.
|
||||
*
|
||||
* Returns 0 on success, -EINVAL if an invalid hwmod is passed, and
|
||||
* -ENXIO on absent or invalid register target address space.
|
||||
*/
|
||||
|
@ -2387,6 +2390,11 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
|
|||
|
||||
_save_mpu_port_index(oh);
|
||||
|
||||
/* if we don't need sysc access we don't need to ioremap */
|
||||
if (!oh->class->sysc)
|
||||
return 0;
|
||||
|
||||
/* we can't continue without MPU PORT if we need sysc access */
|
||||
if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
|
||||
return -ENXIO;
|
||||
|
||||
|
@ -2396,8 +2404,10 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data,
|
|||
oh->name);
|
||||
|
||||
/* Extract the IO space from device tree blob */
|
||||
if (!np)
|
||||
if (!np) {
|
||||
pr_err("omap_hwmod: %s: no dt node\n", oh->name);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
va_start = of_iomap(np, index + oh->mpu_rt_idx);
|
||||
} else {
|
||||
|
@ -2456,13 +2466,11 @@ static int __init _init(struct omap_hwmod *oh, void *data)
|
|||
oh->name, np->name);
|
||||
}
|
||||
|
||||
if (oh->class->sysc) {
|
||||
r = _init_mpu_rt_base(oh, NULL, index, np);
|
||||
if (r < 0) {
|
||||
WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n",
|
||||
oh->name);
|
||||
return 0;
|
||||
}
|
||||
r = _init_mpu_rt_base(oh, NULL, index, np);
|
||||
if (r < 0) {
|
||||
WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n",
|
||||
oh->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = _init_clocks(oh, NULL);
|
||||
|
|
|
@ -827,8 +827,7 @@ static struct omap_hwmod_class_sysconfig dra7xx_gpmc_sysc = {
|
|||
.syss_offs = 0x0014,
|
||||
.sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
|
||||
SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
|
||||
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
|
||||
SIDLE_SMART_WKUP),
|
||||
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
|
||||
.sysc_fields = &omap_hwmod_sysc_type1,
|
||||
};
|
||||
|
||||
|
@ -844,7 +843,7 @@ static struct omap_hwmod dra7xx_gpmc_hwmod = {
|
|||
.class = &dra7xx_gpmc_hwmod_class,
|
||||
.clkdm_name = "l3main1_clkdm",
|
||||
/* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
|
||||
.flags = HWMOD_SWSUP_SIDLE | DEBUG_OMAP_GPMC_HWMOD_FLAGS,
|
||||
.flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS,
|
||||
.main_clk = "l3_iclk_div",
|
||||
.prcm = {
|
||||
.omap4 = {
|
||||
|
|
|
@ -74,32 +74,52 @@ struct jit_ctx {
|
|||
|
||||
int bpf_jit_enable __read_mostly;
|
||||
|
||||
static u64 jit_get_skb_b(struct sk_buff *skb, unsigned offset)
|
||||
static inline int call_neg_helper(struct sk_buff *skb, int offset, void *ret,
|
||||
unsigned int size)
|
||||
{
|
||||
void *ptr = bpf_internal_load_pointer_neg_helper(skb, offset, size);
|
||||
|
||||
if (!ptr)
|
||||
return -EFAULT;
|
||||
memcpy(ret, ptr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64 jit_get_skb_b(struct sk_buff *skb, int offset)
|
||||
{
|
||||
u8 ret;
|
||||
int err;
|
||||
|
||||
err = skb_copy_bits(skb, offset, &ret, 1);
|
||||
if (offset < 0)
|
||||
err = call_neg_helper(skb, offset, &ret, 1);
|
||||
else
|
||||
err = skb_copy_bits(skb, offset, &ret, 1);
|
||||
|
||||
return (u64)err << 32 | ret;
|
||||
}
|
||||
|
||||
static u64 jit_get_skb_h(struct sk_buff *skb, unsigned offset)
|
||||
static u64 jit_get_skb_h(struct sk_buff *skb, int offset)
|
||||
{
|
||||
u16 ret;
|
||||
int err;
|
||||
|
||||
err = skb_copy_bits(skb, offset, &ret, 2);
|
||||
if (offset < 0)
|
||||
err = call_neg_helper(skb, offset, &ret, 2);
|
||||
else
|
||||
err = skb_copy_bits(skb, offset, &ret, 2);
|
||||
|
||||
return (u64)err << 32 | ntohs(ret);
|
||||
}
|
||||
|
||||
static u64 jit_get_skb_w(struct sk_buff *skb, unsigned offset)
|
||||
static u64 jit_get_skb_w(struct sk_buff *skb, int offset)
|
||||
{
|
||||
u32 ret;
|
||||
int err;
|
||||
|
||||
err = skb_copy_bits(skb, offset, &ret, 4);
|
||||
if (offset < 0)
|
||||
err = call_neg_helper(skb, offset, &ret, 4);
|
||||
else
|
||||
err = skb_copy_bits(skb, offset, &ret, 4);
|
||||
|
||||
return (u64)err << 32 | ntohl(ret);
|
||||
}
|
||||
|
@ -536,9 +556,6 @@ static int build_body(struct jit_ctx *ctx)
|
|||
case BPF_LD | BPF_B | BPF_ABS:
|
||||
load_order = 0;
|
||||
load:
|
||||
/* the interpreter will deal with the negative K */
|
||||
if ((int)k < 0)
|
||||
return -ENOTSUPP;
|
||||
emit_mov_i(r_off, k, ctx);
|
||||
load_common:
|
||||
ctx->seen |= SEEN_DATA | SEEN_CALL;
|
||||
|
@ -547,12 +564,24 @@ load_common:
|
|||
emit(ARM_SUB_I(r_scratch, r_skb_hl,
|
||||
1 << load_order), ctx);
|
||||
emit(ARM_CMP_R(r_scratch, r_off), ctx);
|
||||
condt = ARM_COND_HS;
|
||||
condt = ARM_COND_GE;
|
||||
} else {
|
||||
emit(ARM_CMP_R(r_skb_hl, r_off), ctx);
|
||||
condt = ARM_COND_HI;
|
||||
}
|
||||
|
||||
/*
|
||||
* test for negative offset, only if we are
|
||||
* currently scheduled to take the fast
|
||||
* path. this will update the flags so that
|
||||
* the slowpath instruction are ignored if the
|
||||
* offset is negative.
|
||||
*
|
||||
* for loard_order == 0 the HI condition will
|
||||
* make loads at offset 0 take the slow path too.
|
||||
*/
|
||||
_emit(condt, ARM_CMP_I(r_off, 0), ctx);
|
||||
|
||||
_emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data),
|
||||
ctx);
|
||||
|
||||
|
@ -860,9 +889,11 @@ b_epilogue:
|
|||
off = offsetof(struct sk_buff, vlan_tci);
|
||||
emit(ARM_LDRH_I(r_A, r_skb, off), ctx);
|
||||
if (code == (BPF_ANC | SKF_AD_VLAN_TAG))
|
||||
OP_IMM3(ARM_AND, r_A, r_A, VLAN_VID_MASK, ctx);
|
||||
else
|
||||
OP_IMM3(ARM_AND, r_A, r_A, VLAN_TAG_PRESENT, ctx);
|
||||
OP_IMM3(ARM_AND, r_A, r_A, ~VLAN_TAG_PRESENT, ctx);
|
||||
else {
|
||||
OP_IMM3(ARM_LSR, r_A, r_A, 12, ctx);
|
||||
OP_IMM3(ARM_AND, r_A, r_A, 0x1, ctx);
|
||||
}
|
||||
break;
|
||||
case BPF_ANC | SKF_AD_QUEUE:
|
||||
ctx->seen |= SEEN_SKB;
|
||||
|
|
|
@ -823,7 +823,7 @@
|
|||
device_type = "dma";
|
||||
reg = <0x0 0x1f270000 0x0 0x10000>,
|
||||
<0x0 0x1f200000 0x0 0x10000>,
|
||||
<0x0 0x1b008000 0x0 0x2000>,
|
||||
<0x0 0x1b000000 0x0 0x400000>,
|
||||
<0x0 0x1054a000 0x0 0x100>;
|
||||
interrupts = <0x0 0x82 0x4>,
|
||||
<0x0 0xb8 0x4>,
|
||||
|
|
|
@ -122,12 +122,12 @@ static int __init uefi_init(void)
|
|||
|
||||
/* Show what we know for posterity */
|
||||
c16 = early_memremap(efi_to_phys(efi.systab->fw_vendor),
|
||||
sizeof(vendor));
|
||||
sizeof(vendor) * sizeof(efi_char16_t));
|
||||
if (c16) {
|
||||
for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i)
|
||||
vendor[i] = c16[i];
|
||||
vendor[i] = '\0';
|
||||
early_memunmap(c16, sizeof(vendor));
|
||||
early_memunmap(c16, sizeof(vendor) * sizeof(efi_char16_t));
|
||||
}
|
||||
|
||||
pr_info("EFI v%u.%.02u by %s\n",
|
||||
|
|
|
@ -585,7 +585,8 @@ ENDPROC(el0_irq)
|
|||
*
|
||||
*/
|
||||
ENTRY(cpu_switch_to)
|
||||
add x8, x0, #THREAD_CPU_CONTEXT
|
||||
mov x10, #THREAD_CPU_CONTEXT
|
||||
add x8, x0, x10
|
||||
mov x9, sp
|
||||
stp x19, x20, [x8], #16 // store callee-saved registers
|
||||
stp x21, x22, [x8], #16
|
||||
|
@ -594,7 +595,7 @@ ENTRY(cpu_switch_to)
|
|||
stp x27, x28, [x8], #16
|
||||
stp x29, x9, [x8], #16
|
||||
str lr, [x8]
|
||||
add x8, x1, #THREAD_CPU_CONTEXT
|
||||
add x8, x1, x10
|
||||
ldp x19, x20, [x8], #16 // restore callee-saved registers
|
||||
ldp x21, x22, [x8], #16
|
||||
ldp x23, x24, [x8], #16
|
||||
|
|
|
@ -61,7 +61,7 @@ void __init init_IRQ(void)
|
|||
static bool migrate_one_irq(struct irq_desc *desc)
|
||||
{
|
||||
struct irq_data *d = irq_desc_get_irq_data(desc);
|
||||
const struct cpumask *affinity = d->affinity;
|
||||
const struct cpumask *affinity = irq_data_get_affinity_mask(d);
|
||||
struct irq_chip *c;
|
||||
bool ret = false;
|
||||
|
||||
|
@ -81,7 +81,7 @@ static bool migrate_one_irq(struct irq_desc *desc)
|
|||
if (!c->irq_set_affinity)
|
||||
pr_debug("IRQ%u: unable to set affinity\n", d->irq);
|
||||
else if (c->irq_set_affinity(d, affinity, false) == IRQ_SET_MASK_OK && ret)
|
||||
cpumask_copy(d->affinity, affinity);
|
||||
cpumask_copy(irq_data_get_affinity_mask(d), affinity);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <mach/pm.h>
|
||||
|
||||
static bool disable_cpu_idle_poll;
|
||||
|
||||
static cycle_t read_cycle_count(struct clocksource *cs)
|
||||
{
|
||||
|
@ -80,45 +81,45 @@ static int comparator_next_event(unsigned long delta,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void comparator_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *evdev)
|
||||
static int comparator_shutdown(struct clock_event_device *evdev)
|
||||
{
|
||||
switch (mode) {
|
||||
case CLOCK_EVT_MODE_ONESHOT:
|
||||
pr_debug("%s: start\n", evdev->name);
|
||||
/* FALLTHROUGH */
|
||||
case CLOCK_EVT_MODE_RESUME:
|
||||
pr_debug("%s: %s\n", __func__, evdev->name);
|
||||
sysreg_write(COMPARE, 0);
|
||||
|
||||
if (disable_cpu_idle_poll) {
|
||||
disable_cpu_idle_poll = false;
|
||||
/*
|
||||
* If we're using the COUNT and COMPARE registers we
|
||||
* need to force idle poll.
|
||||
* Only disable idle poll if we have forced that
|
||||
* in a previous call.
|
||||
*/
|
||||
cpu_idle_poll_ctrl(true);
|
||||
break;
|
||||
case CLOCK_EVT_MODE_UNUSED:
|
||||
case CLOCK_EVT_MODE_SHUTDOWN:
|
||||
sysreg_write(COMPARE, 0);
|
||||
pr_debug("%s: stop\n", evdev->name);
|
||||
if (evdev->mode == CLOCK_EVT_MODE_ONESHOT ||
|
||||
evdev->mode == CLOCK_EVT_MODE_RESUME) {
|
||||
/*
|
||||
* Only disable idle poll if we have forced that
|
||||
* in a previous call.
|
||||
*/
|
||||
cpu_idle_poll_ctrl(false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
cpu_idle_poll_ctrl(false);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int comparator_set_oneshot(struct clock_event_device *evdev)
|
||||
{
|
||||
pr_debug("%s: %s\n", __func__, evdev->name);
|
||||
|
||||
disable_cpu_idle_poll = true;
|
||||
/*
|
||||
* If we're using the COUNT and COMPARE registers we
|
||||
* need to force idle poll.
|
||||
*/
|
||||
cpu_idle_poll_ctrl(true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clock_event_device comparator = {
|
||||
.name = "avr32_comparator",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.shift = 16,
|
||||
.rating = 50,
|
||||
.set_next_event = comparator_next_event,
|
||||
.set_mode = comparator_mode,
|
||||
.name = "avr32_comparator",
|
||||
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||
.shift = 16,
|
||||
.rating = 50,
|
||||
.set_next_event = comparator_next_event,
|
||||
.set_state_shutdown = comparator_shutdown,
|
||||
.set_state_oneshot = comparator_set_oneshot,
|
||||
.tick_resume = comparator_set_oneshot,
|
||||
};
|
||||
|
||||
void read_persistent_clock(struct timespec *ts)
|
||||
|
|
|
@ -80,6 +80,9 @@ int clk_enable(struct clk *clk)
|
|||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(&clk_lock, flags);
|
||||
__clk_enable(clk);
|
||||
spin_unlock_irqrestore(&clk_lock, flags);
|
||||
|
@ -106,6 +109,9 @@ void clk_disable(struct clk *clk)
|
|||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (IS_ERR_OR_NULL(clk))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&clk_lock, flags);
|
||||
__clk_disable(clk);
|
||||
spin_unlock_irqrestore(&clk_lock, flags);
|
||||
|
@ -117,6 +123,9 @@ unsigned long clk_get_rate(struct clk *clk)
|
|||
unsigned long flags;
|
||||
unsigned long rate;
|
||||
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(&clk_lock, flags);
|
||||
rate = clk->get_rate(clk);
|
||||
spin_unlock_irqrestore(&clk_lock, flags);
|
||||
|
@ -129,6 +138,9 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
|
|||
{
|
||||
unsigned long flags, actual_rate;
|
||||
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
if (!clk->set_rate)
|
||||
return -ENOSYS;
|
||||
|
||||
|
@ -145,6 +157,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
|
|||
unsigned long flags;
|
||||
long ret;
|
||||
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
if (!clk->set_rate)
|
||||
return -ENOSYS;
|
||||
|
||||
|
@ -161,6 +176,9 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
|
|||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
if (!clk->set_parent)
|
||||
return -ENOSYS;
|
||||
|
||||
|
@ -174,7 +192,7 @@ EXPORT_SYMBOL(clk_set_parent);
|
|||
|
||||
struct clk *clk_get_parent(struct clk *clk)
|
||||
{
|
||||
return clk->parent;
|
||||
return !clk ? NULL : clk->parent;
|
||||
}
|
||||
EXPORT_SYMBOL(clk_get_parent);
|
||||
|
||||
|
|
|
@ -174,6 +174,11 @@ static inline void _writel(unsigned long l, unsigned long addr)
|
|||
#define iowrite16 writew
|
||||
#define iowrite32 writel
|
||||
|
||||
#define ioread16be(addr) be16_to_cpu(readw(addr))
|
||||
#define ioread32be(addr) be32_to_cpu(readl(addr))
|
||||
#define iowrite16be(v, addr) writew(cpu_to_be16(v), (addr))
|
||||
#define iowrite32be(v, addr) writel(cpu_to_be32(v), (addr))
|
||||
|
||||
#define mmiowb()
|
||||
|
||||
#define flush_write_buffers() do { } while (0) /* M32R_FIXME */
|
||||
|
|
|
@ -1478,7 +1478,7 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
|
|||
}
|
||||
|
||||
/* Unmask the event */
|
||||
if (eeh_enabled())
|
||||
if (ret == EEH_NEXT_ERR_NONE && eeh_enabled())
|
||||
enable_irq(eeh_event_irq);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -2220,7 +2220,7 @@ static void pnv_pci_ioda_setup_opal_tce_kill(struct pnv_phb *phb)
|
|||
|
||||
static __be64 *pnv_pci_ioda2_table_do_alloc_pages(int nid, unsigned shift,
|
||||
unsigned levels, unsigned long limit,
|
||||
unsigned long *current_offset)
|
||||
unsigned long *current_offset, unsigned long *total_allocated)
|
||||
{
|
||||
struct page *tce_mem = NULL;
|
||||
__be64 *addr, *tmp;
|
||||
|
@ -2236,6 +2236,7 @@ static __be64 *pnv_pci_ioda2_table_do_alloc_pages(int nid, unsigned shift,
|
|||
}
|
||||
addr = page_address(tce_mem);
|
||||
memset(addr, 0, allocated);
|
||||
*total_allocated += allocated;
|
||||
|
||||
--levels;
|
||||
if (!levels) {
|
||||
|
@ -2245,7 +2246,7 @@ static __be64 *pnv_pci_ioda2_table_do_alloc_pages(int nid, unsigned shift,
|
|||
|
||||
for (i = 0; i < entries; ++i) {
|
||||
tmp = pnv_pci_ioda2_table_do_alloc_pages(nid, shift,
|
||||
levels, limit, current_offset);
|
||||
levels, limit, current_offset, total_allocated);
|
||||
if (!tmp)
|
||||
break;
|
||||
|
||||
|
@ -2267,7 +2268,7 @@ static long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
|
|||
struct iommu_table *tbl)
|
||||
{
|
||||
void *addr;
|
||||
unsigned long offset = 0, level_shift;
|
||||
unsigned long offset = 0, level_shift, total_allocated = 0;
|
||||
const unsigned window_shift = ilog2(window_size);
|
||||
unsigned entries_shift = window_shift - page_shift;
|
||||
unsigned table_shift = max_t(unsigned, entries_shift + 3, PAGE_SHIFT);
|
||||
|
@ -2286,7 +2287,7 @@ static long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
|
|||
|
||||
/* Allocate TCE table */
|
||||
addr = pnv_pci_ioda2_table_do_alloc_pages(nid, level_shift,
|
||||
levels, tce_table_size, &offset);
|
||||
levels, tce_table_size, &offset, &total_allocated);
|
||||
|
||||
/* addr==NULL means that the first level allocation failed */
|
||||
if (!addr)
|
||||
|
@ -2308,7 +2309,7 @@ static long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
|
|||
page_shift);
|
||||
tbl->it_level_size = 1ULL << (level_shift - 3);
|
||||
tbl->it_indirect_levels = levels - 1;
|
||||
tbl->it_allocated_size = offset;
|
||||
tbl->it_allocated_size = total_allocated;
|
||||
|
||||
pr_devel("Created TCE table: ws=%08llx ts=%lx @%08llx\n",
|
||||
window_size, tce_table_size, bus_offset);
|
||||
|
|
|
@ -23,15 +23,15 @@
|
|||
|
||||
int main(void)
|
||||
{
|
||||
DEFINE(__THREAD_info, offsetof(struct task_struct, stack));
|
||||
DEFINE(__THREAD_ksp, offsetof(struct task_struct, thread.ksp));
|
||||
DEFINE(__THREAD_mm_segment, offsetof(struct task_struct, thread.mm_segment));
|
||||
BLANK();
|
||||
DEFINE(__TASK_thread_info, offsetof(struct task_struct, stack));
|
||||
DEFINE(__TASK_thread, offsetof(struct task_struct, thread));
|
||||
DEFINE(__TASK_pid, offsetof(struct task_struct, pid));
|
||||
BLANK();
|
||||
DEFINE(__THREAD_per_cause, offsetof(struct task_struct, thread.per_event.cause));
|
||||
DEFINE(__THREAD_per_address, offsetof(struct task_struct, thread.per_event.address));
|
||||
DEFINE(__THREAD_per_paid, offsetof(struct task_struct, thread.per_event.paid));
|
||||
DEFINE(__THREAD_ksp, offsetof(struct thread_struct, ksp));
|
||||
DEFINE(__THREAD_per_cause, offsetof(struct thread_struct, per_event.cause));
|
||||
DEFINE(__THREAD_per_address, offsetof(struct thread_struct, per_event.address));
|
||||
DEFINE(__THREAD_per_paid, offsetof(struct thread_struct, per_event.paid));
|
||||
DEFINE(__THREAD_trap_tdb, offsetof(struct thread_struct, trap_tdb));
|
||||
BLANK();
|
||||
DEFINE(__TI_task, offsetof(struct thread_info, task));
|
||||
DEFINE(__TI_flags, offsetof(struct thread_info, flags));
|
||||
|
@ -176,7 +176,6 @@ int main(void)
|
|||
DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data));
|
||||
DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap));
|
||||
DEFINE(__LC_PGM_TDB, offsetof(struct _lowcore, pgm_tdb));
|
||||
DEFINE(__THREAD_trap_tdb, offsetof(struct task_struct, thread.trap_tdb));
|
||||
DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce));
|
||||
DEFINE(__SIE_PROG0C, offsetof(struct kvm_s390_sie_block, prog0c));
|
||||
DEFINE(__SIE_PROG20, offsetof(struct kvm_s390_sie_block, prog20));
|
||||
|
|
|
@ -138,6 +138,8 @@ int init_cache_level(unsigned int cpu)
|
|||
union cache_topology ct;
|
||||
enum cache_type ctype;
|
||||
|
||||
if (!test_facility(34))
|
||||
return -EOPNOTSUPP;
|
||||
if (!this_cpu_ci)
|
||||
return -EINVAL;
|
||||
ct.raw = ecag(EXTRACT_TOPOLOGY, 0, 0);
|
||||
|
|
|
@ -178,17 +178,21 @@ _PIF_WORK = (_PIF_PER_TRAP)
|
|||
*/
|
||||
ENTRY(__switch_to)
|
||||
stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task
|
||||
stg %r15,__THREAD_ksp(%r2) # store kernel stack of prev
|
||||
lg %r4,__THREAD_info(%r2) # get thread_info of prev
|
||||
lg %r5,__THREAD_info(%r3) # get thread_info of next
|
||||
lgr %r1,%r2
|
||||
aghi %r1,__TASK_thread # thread_struct of prev task
|
||||
lg %r4,__TASK_thread_info(%r2) # get thread_info of prev
|
||||
lg %r5,__TASK_thread_info(%r3) # get thread_info of next
|
||||
stg %r15,__THREAD_ksp(%r1) # store kernel stack of prev
|
||||
lgr %r1,%r3
|
||||
aghi %r1,__TASK_thread # thread_struct of next task
|
||||
lgr %r15,%r5
|
||||
aghi %r15,STACK_INIT # end of kernel stack of next
|
||||
stg %r3,__LC_CURRENT # store task struct of next
|
||||
stg %r5,__LC_THREAD_INFO # store thread info of next
|
||||
stg %r15,__LC_KERNEL_STACK # store end of kernel stack
|
||||
lg %r15,__THREAD_ksp(%r1) # load kernel stack of next
|
||||
lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
|
||||
mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next
|
||||
lg %r15,__THREAD_ksp(%r3) # load kernel stack of next
|
||||
lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
|
||||
br %r14
|
||||
|
||||
|
@ -417,6 +421,7 @@ ENTRY(pgm_check_handler)
|
|||
LAST_BREAK %r14
|
||||
lg %r15,__LC_KERNEL_STACK
|
||||
lg %r14,__TI_task(%r12)
|
||||
aghi %r14,__TASK_thread # pointer to thread_struct
|
||||
lghi %r13,__LC_PGM_TDB
|
||||
tm __LC_PGM_ILC+2,0x02 # check for transaction abort
|
||||
jz 2f
|
||||
|
|
|
@ -259,7 +259,7 @@ void vector_exception(struct pt_regs *regs)
|
|||
}
|
||||
|
||||
/* get vector interrupt code from fpc */
|
||||
asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
|
||||
asm volatile("stfpc %0" : "=Q" (current->thread.fp_regs.fpc));
|
||||
vic = (current->thread.fp_regs.fpc & 0xf00) >> 8;
|
||||
switch (vic) {
|
||||
case 1: /* invalid vector operation */
|
||||
|
@ -297,7 +297,7 @@ void data_exception(struct pt_regs *regs)
|
|||
|
||||
location = get_trap_ip(regs);
|
||||
|
||||
asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
|
||||
asm volatile("stfpc %0" : "=Q" (current->thread.fp_regs.fpc));
|
||||
/* Check for vector register enablement */
|
||||
if (MACHINE_HAS_VX && !current->thread.vxrs &&
|
||||
(current->thread.fp_regs.fpc & FPC_DXC_MASK) == 0xfe00) {
|
||||
|
|
|
@ -448,13 +448,13 @@ static void bpf_jit_prologue(struct bpf_jit *jit)
|
|||
EMIT6_DISP_LH(0xe3000000, 0x0004, REG_SKB_DATA, REG_0,
|
||||
BPF_REG_1, offsetof(struct sk_buff, data));
|
||||
}
|
||||
/* BPF compatibility: clear A (%b7) and X (%b8) registers */
|
||||
if (REG_SEEN(BPF_REG_7))
|
||||
/* lghi %b7,0 */
|
||||
EMIT4_IMM(0xa7090000, BPF_REG_7, 0);
|
||||
if (REG_SEEN(BPF_REG_8))
|
||||
/* lghi %b8,0 */
|
||||
EMIT4_IMM(0xa7090000, BPF_REG_8, 0);
|
||||
/* BPF compatibility: clear A (%b0) and X (%b7) registers */
|
||||
if (REG_SEEN(BPF_REG_A))
|
||||
/* lghi %ba,0 */
|
||||
EMIT4_IMM(0xa7090000, BPF_REG_A, 0);
|
||||
if (REG_SEEN(BPF_REG_X))
|
||||
/* lghi %bx,0 */
|
||||
EMIT4_IMM(0xa7090000, BPF_REG_X, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1139,7 +1139,7 @@ static void __init load_hv_initrd(void)
|
|||
|
||||
void __init free_initrd_mem(unsigned long begin, unsigned long end)
|
||||
{
|
||||
free_bootmem(__pa(begin), end - begin);
|
||||
free_bootmem_late(__pa(begin), end - begin);
|
||||
}
|
||||
|
||||
static int __init setup_initrd(char *str)
|
||||
|
|
|
@ -1193,6 +1193,10 @@ static efi_status_t setup_e820(struct boot_params *params,
|
|||
unsigned int e820_type = 0;
|
||||
unsigned long m = efi->efi_memmap;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
m |= (u64)efi->efi_memmap_hi << 32;
|
||||
#endif
|
||||
|
||||
d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
|
||||
switch (d->type) {
|
||||
case EFI_RESERVED_TYPE:
|
||||
|
|
|
@ -205,7 +205,6 @@ sysexit_from_sys_call:
|
|||
movl RDX(%rsp), %edx /* arg3 */
|
||||
movl RSI(%rsp), %ecx /* arg4 */
|
||||
movl RDI(%rsp), %r8d /* arg5 */
|
||||
movl %ebp, %r9d /* arg6 */
|
||||
.endm
|
||||
|
||||
.macro auditsys_exit exit
|
||||
|
@ -236,6 +235,7 @@ sysexit_from_sys_call:
|
|||
|
||||
sysenter_auditsys:
|
||||
auditsys_entry_common
|
||||
movl %ebp, %r9d /* reload 6th syscall arg */
|
||||
jmp sysenter_dispatch
|
||||
|
||||
sysexit_audit:
|
||||
|
@ -336,7 +336,7 @@ ENTRY(entry_SYSCALL_compat)
|
|||
* 32-bit zero extended:
|
||||
*/
|
||||
ASM_STAC
|
||||
1: movl (%r8), %ebp
|
||||
1: movl (%r8), %r9d
|
||||
_ASM_EXTABLE(1b, ia32_badarg)
|
||||
ASM_CLAC
|
||||
orl $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
|
||||
|
@ -346,7 +346,7 @@ ENTRY(entry_SYSCALL_compat)
|
|||
cstar_do_call:
|
||||
/* 32-bit syscall -> 64-bit C ABI argument conversion */
|
||||
movl %edi, %r8d /* arg5 */
|
||||
movl %ebp, %r9d /* arg6 */
|
||||
/* r9 already loaded */ /* arg6 */
|
||||
xchg %ecx, %esi /* rsi:arg2, rcx:arg4 */
|
||||
movl %ebx, %edi /* arg1 */
|
||||
movl %edx, %edx /* arg3 (zero extension) */
|
||||
|
@ -358,7 +358,6 @@ cstar_dispatch:
|
|||
call *ia32_sys_call_table(, %rax, 8)
|
||||
movq %rax, RAX(%rsp)
|
||||
1:
|
||||
movl RCX(%rsp), %ebp
|
||||
DISABLE_INTERRUPTS(CLBR_NONE)
|
||||
TRACE_IRQS_OFF
|
||||
testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
|
||||
|
@ -392,7 +391,9 @@ sysretl_from_sys_call:
|
|||
|
||||
#ifdef CONFIG_AUDITSYSCALL
|
||||
cstar_auditsys:
|
||||
movl %r9d, R9(%rsp) /* register to be clobbered by call */
|
||||
auditsys_entry_common
|
||||
movl R9(%rsp), %r9d /* reload 6th syscall arg */
|
||||
jmp cstar_dispatch
|
||||
|
||||
sysretl_audit:
|
||||
|
@ -404,14 +405,16 @@ cstar_tracesys:
|
|||
testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT), ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
|
||||
jz cstar_auditsys
|
||||
#endif
|
||||
xchgl %r9d, %ebp
|
||||
SAVE_EXTRA_REGS
|
||||
xorl %eax, %eax /* Do not leak kernel information */
|
||||
movq %rax, R11(%rsp)
|
||||
movq %rax, R10(%rsp)
|
||||
movq %rax, R9(%rsp)
|
||||
movq %r9, R9(%rsp)
|
||||
movq %rax, R8(%rsp)
|
||||
movq %rsp, %rdi /* &pt_regs -> arg1 */
|
||||
call syscall_trace_enter
|
||||
movl R9(%rsp), %r9d
|
||||
|
||||
/* Reload arg registers from stack. (see sysenter_tracesys) */
|
||||
movl RCX(%rsp), %ecx
|
||||
|
@ -421,6 +424,7 @@ cstar_tracesys:
|
|||
movl %eax, %eax /* zero extension */
|
||||
|
||||
RESTORE_EXTRA_REGS
|
||||
xchgl %ebp, %r9d
|
||||
jmp cstar_do_call
|
||||
END(entry_SYSCALL_compat)
|
||||
|
||||
|
|
|
@ -280,21 +280,6 @@ static inline void clear_LDT(void)
|
|||
set_ldt(NULL, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* load one particular LDT into the current CPU
|
||||
*/
|
||||
static inline void load_LDT_nolock(mm_context_t *pc)
|
||||
{
|
||||
set_ldt(pc->ldt, pc->size);
|
||||
}
|
||||
|
||||
static inline void load_LDT(mm_context_t *pc)
|
||||
{
|
||||
preempt_disable();
|
||||
load_LDT_nolock(pc);
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static inline unsigned long get_desc_base(const struct desc_struct *desc)
|
||||
{
|
||||
return (unsigned)(desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24));
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
* we put the segment information here.
|
||||
*/
|
||||
typedef struct {
|
||||
void *ldt;
|
||||
int size;
|
||||
struct ldt_struct *ldt;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/* True if mm supports a task running in 32 bit compatibility mode. */
|
||||
|
|
|
@ -33,6 +33,50 @@ static inline void load_mm_cr4(struct mm_struct *mm)
|
|||
static inline void load_mm_cr4(struct mm_struct *mm) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ldt_structs can be allocated, used, and freed, but they are never
|
||||
* modified while live.
|
||||
*/
|
||||
struct ldt_struct {
|
||||
/*
|
||||
* Xen requires page-aligned LDTs with special permissions. This is
|
||||
* needed to prevent us from installing evil descriptors such as
|
||||
* call gates. On native, we could merge the ldt_struct and LDT
|
||||
* allocations, but it's not worth trying to optimize.
|
||||
*/
|
||||
struct desc_struct *entries;
|
||||
int size;
|
||||
};
|
||||
|
||||
static inline void load_mm_ldt(struct mm_struct *mm)
|
||||
{
|
||||
struct ldt_struct *ldt;
|
||||
|
||||
/* lockless_dereference synchronizes with smp_store_release */
|
||||
ldt = lockless_dereference(mm->context.ldt);
|
||||
|
||||
/*
|
||||
* Any change to mm->context.ldt is followed by an IPI to all
|
||||
* CPUs with the mm active. The LDT will not be freed until
|
||||
* after the IPI is handled by all such CPUs. This means that,
|
||||
* if the ldt_struct changes before we return, the values we see
|
||||
* will be safe, and the new values will be loaded before we run
|
||||
* any user code.
|
||||
*
|
||||
* NB: don't try to convert this to use RCU without extreme care.
|
||||
* We would still need IRQs off, because we don't want to change
|
||||
* the local LDT after an IPI loaded a newer value than the one
|
||||
* that we can see.
|
||||
*/
|
||||
|
||||
if (unlikely(ldt))
|
||||
set_ldt(ldt->entries, ldt->size);
|
||||
else
|
||||
clear_LDT();
|
||||
|
||||
DEBUG_LOCKS_WARN_ON(preemptible());
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for LDT copy/destruction.
|
||||
*/
|
||||
|
@ -78,12 +122,12 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
|||
* was called and then modify_ldt changed
|
||||
* prev->context.ldt but suppressed an IPI to this CPU.
|
||||
* In this case, prev->context.ldt != NULL, because we
|
||||
* never free an LDT while the mm still exists. That
|
||||
* means that next->context.ldt != prev->context.ldt,
|
||||
* because mms never share an LDT.
|
||||
* never set context.ldt to NULL while the mm still
|
||||
* exists. That means that next->context.ldt !=
|
||||
* prev->context.ldt, because mms never share an LDT.
|
||||
*/
|
||||
if (unlikely(prev->context.ldt != next->context.ldt))
|
||||
load_LDT_nolock(&next->context);
|
||||
load_mm_ldt(next);
|
||||
}
|
||||
#ifdef CONFIG_SMP
|
||||
else {
|
||||
|
@ -106,7 +150,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
|||
load_cr3(next->pgd);
|
||||
trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
|
||||
load_mm_cr4(next);
|
||||
load_LDT_nolock(&next->context);
|
||||
load_mm_ldt(next);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -354,7 +354,7 @@ struct kvm_xcrs {
|
|||
struct kvm_sync_regs {
|
||||
};
|
||||
|
||||
#define KVM_QUIRK_LINT0_REENABLED (1 << 0)
|
||||
#define KVM_QUIRK_CD_NW_CLEARED (1 << 1)
|
||||
#define KVM_X86_QUIRK_LINT0_REENABLED (1 << 0)
|
||||
#define KVM_X86_QUIRK_CD_NW_CLEARED (1 << 1)
|
||||
|
||||
#endif /* _ASM_X86_KVM_H */
|
||||
|
|
|
@ -943,7 +943,7 @@ static bool mp_check_pin_attr(int irq, struct irq_alloc_info *info)
|
|||
*/
|
||||
if (irq < nr_legacy_irqs() && data->count == 1) {
|
||||
if (info->ioapic_trigger != data->trigger)
|
||||
mp_register_handler(irq, data->trigger);
|
||||
mp_register_handler(irq, info->ioapic_trigger);
|
||||
data->entry.trigger = data->trigger = info->ioapic_trigger;
|
||||
data->entry.polarity = data->polarity = info->ioapic_polarity;
|
||||
}
|
||||
|
|
|
@ -1410,7 +1410,7 @@ void cpu_init(void)
|
|||
load_sp0(t, ¤t->thread);
|
||||
set_tss_desc(cpu, t);
|
||||
load_TR_desc();
|
||||
load_LDT(&init_mm.context);
|
||||
load_mm_ldt(&init_mm);
|
||||
|
||||
clear_all_debug_regs();
|
||||
dbg_restore_debug_regs();
|
||||
|
@ -1459,7 +1459,7 @@ void cpu_init(void)
|
|||
load_sp0(t, thread);
|
||||
set_tss_desc(cpu, t);
|
||||
load_TR_desc();
|
||||
load_LDT(&init_mm.context);
|
||||
load_mm_ldt(&init_mm);
|
||||
|
||||
t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
|
||||
|
||||
|
|
|
@ -2179,21 +2179,25 @@ static unsigned long get_segment_base(unsigned int segment)
|
|||
int idx = segment >> 3;
|
||||
|
||||
if ((segment & SEGMENT_TI_MASK) == SEGMENT_LDT) {
|
||||
struct ldt_struct *ldt;
|
||||
|
||||
if (idx > LDT_ENTRIES)
|
||||
return 0;
|
||||
|
||||
if (idx > current->active_mm->context.size)
|
||||
/* IRQs are off, so this synchronizes with smp_store_release */
|
||||
ldt = lockless_dereference(current->active_mm->context.ldt);
|
||||
if (!ldt || idx > ldt->size)
|
||||
return 0;
|
||||
|
||||
desc = current->active_mm->context.ldt;
|
||||
desc = &ldt->entries[idx];
|
||||
} else {
|
||||
if (idx > GDT_ENTRIES)
|
||||
return 0;
|
||||
|
||||
desc = raw_cpu_ptr(gdt_page.gdt);
|
||||
desc = raw_cpu_ptr(gdt_page.gdt) + idx;
|
||||
}
|
||||
|
||||
return get_desc_base(desc + idx);
|
||||
return get_desc_base(desc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
|
|
@ -951,6 +951,14 @@ static u64 intel_cqm_event_count(struct perf_event *event)
|
|||
if (!cqm_group_leader(event))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Getting up-to-date values requires an SMP IPI which is not
|
||||
* possible if we're being called in interrupt context. Return
|
||||
* the cached values instead.
|
||||
*/
|
||||
if (unlikely(in_interrupt()))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Notice that we don't perform the reading of an RMID
|
||||
* atomically, because we can't hold a spin lock across the
|
||||
|
|
|
@ -351,9 +351,15 @@ static int __init x86_noxsave_setup(char *s)
|
|||
|
||||
setup_clear_cpu_cap(X86_FEATURE_XSAVE);
|
||||
setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
|
||||
setup_clear_cpu_cap(X86_FEATURE_XSAVEC);
|
||||
setup_clear_cpu_cap(X86_FEATURE_XSAVES);
|
||||
setup_clear_cpu_cap(X86_FEATURE_AVX);
|
||||
setup_clear_cpu_cap(X86_FEATURE_AVX2);
|
||||
setup_clear_cpu_cap(X86_FEATURE_AVX512F);
|
||||
setup_clear_cpu_cap(X86_FEATURE_AVX512PF);
|
||||
setup_clear_cpu_cap(X86_FEATURE_AVX512ER);
|
||||
setup_clear_cpu_cap(X86_FEATURE_AVX512CD);
|
||||
setup_clear_cpu_cap(X86_FEATURE_MPX);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
|
@ -20,82 +21,82 @@
|
|||
#include <asm/mmu_context.h>
|
||||
#include <asm/syscalls.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* context.lock is held for us, so we don't need any locking. */
|
||||
static void flush_ldt(void *current_mm)
|
||||
{
|
||||
if (current->active_mm == current_mm)
|
||||
load_LDT(¤t->active_mm->context);
|
||||
mm_context_t *pc;
|
||||
|
||||
if (current->active_mm != current_mm)
|
||||
return;
|
||||
|
||||
pc = ¤t->active_mm->context;
|
||||
set_ldt(pc->ldt->entries, pc->ldt->size);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
|
||||
/* The caller must call finalize_ldt_struct on the result. LDT starts zeroed. */
|
||||
static struct ldt_struct *alloc_ldt_struct(int size)
|
||||
{
|
||||
void *oldldt, *newldt;
|
||||
int oldsize;
|
||||
struct ldt_struct *new_ldt;
|
||||
int alloc_size;
|
||||
|
||||
if (mincount <= pc->size)
|
||||
return 0;
|
||||
oldsize = pc->size;
|
||||
mincount = (mincount + (PAGE_SIZE / LDT_ENTRY_SIZE - 1)) &
|
||||
(~(PAGE_SIZE / LDT_ENTRY_SIZE - 1));
|
||||
if (mincount * LDT_ENTRY_SIZE > PAGE_SIZE)
|
||||
newldt = vmalloc(mincount * LDT_ENTRY_SIZE);
|
||||
if (size > LDT_ENTRIES)
|
||||
return NULL;
|
||||
|
||||
new_ldt = kmalloc(sizeof(struct ldt_struct), GFP_KERNEL);
|
||||
if (!new_ldt)
|
||||
return NULL;
|
||||
|
||||
BUILD_BUG_ON(LDT_ENTRY_SIZE != sizeof(struct desc_struct));
|
||||
alloc_size = size * LDT_ENTRY_SIZE;
|
||||
|
||||
/*
|
||||
* Xen is very picky: it requires a page-aligned LDT that has no
|
||||
* trailing nonzero bytes in any page that contains LDT descriptors.
|
||||
* Keep it simple: zero the whole allocation and never allocate less
|
||||
* than PAGE_SIZE.
|
||||
*/
|
||||
if (alloc_size > PAGE_SIZE)
|
||||
new_ldt->entries = vzalloc(alloc_size);
|
||||
else
|
||||
newldt = (void *)__get_free_page(GFP_KERNEL);
|
||||
new_ldt->entries = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
|
||||
if (!newldt)
|
||||
return -ENOMEM;
|
||||
|
||||
if (oldsize)
|
||||
memcpy(newldt, pc->ldt, oldsize * LDT_ENTRY_SIZE);
|
||||
oldldt = pc->ldt;
|
||||
memset(newldt + oldsize * LDT_ENTRY_SIZE, 0,
|
||||
(mincount - oldsize) * LDT_ENTRY_SIZE);
|
||||
|
||||
paravirt_alloc_ldt(newldt, mincount);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/* CHECKME: Do we really need this ? */
|
||||
wmb();
|
||||
#endif
|
||||
pc->ldt = newldt;
|
||||
wmb();
|
||||
pc->size = mincount;
|
||||
wmb();
|
||||
|
||||
if (reload) {
|
||||
#ifdef CONFIG_SMP
|
||||
preempt_disable();
|
||||
load_LDT(pc);
|
||||
if (!cpumask_equal(mm_cpumask(current->mm),
|
||||
cpumask_of(smp_processor_id())))
|
||||
smp_call_function(flush_ldt, current->mm, 1);
|
||||
preempt_enable();
|
||||
#else
|
||||
load_LDT(pc);
|
||||
#endif
|
||||
if (!new_ldt->entries) {
|
||||
kfree(new_ldt);
|
||||
return NULL;
|
||||
}
|
||||
if (oldsize) {
|
||||
paravirt_free_ldt(oldldt, oldsize);
|
||||
if (oldsize * LDT_ENTRY_SIZE > PAGE_SIZE)
|
||||
vfree(oldldt);
|
||||
else
|
||||
put_page(virt_to_page(oldldt));
|
||||
}
|
||||
return 0;
|
||||
|
||||
new_ldt->size = size;
|
||||
return new_ldt;
|
||||
}
|
||||
|
||||
static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
|
||||
/* After calling this, the LDT is immutable. */
|
||||
static void finalize_ldt_struct(struct ldt_struct *ldt)
|
||||
{
|
||||
int err = alloc_ldt(new, old->size, 0);
|
||||
int i;
|
||||
paravirt_alloc_ldt(ldt->entries, ldt->size);
|
||||
}
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
/* context.lock is held */
|
||||
static void install_ldt(struct mm_struct *current_mm,
|
||||
struct ldt_struct *ldt)
|
||||
{
|
||||
/* Synchronizes with lockless_dereference in load_mm_ldt. */
|
||||
smp_store_release(¤t_mm->context.ldt, ldt);
|
||||
|
||||
for (i = 0; i < old->size; i++)
|
||||
write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE);
|
||||
return 0;
|
||||
/* Activate the LDT for all CPUs using current_mm. */
|
||||
on_each_cpu_mask(mm_cpumask(current_mm), flush_ldt, current_mm, true);
|
||||
}
|
||||
|
||||
static void free_ldt_struct(struct ldt_struct *ldt)
|
||||
{
|
||||
if (likely(!ldt))
|
||||
return;
|
||||
|
||||
paravirt_free_ldt(ldt->entries, ldt->size);
|
||||
if (ldt->size * LDT_ENTRY_SIZE > PAGE_SIZE)
|
||||
vfree(ldt->entries);
|
||||
else
|
||||
kfree(ldt->entries);
|
||||
kfree(ldt);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -104,17 +105,37 @@ static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
|
|||
*/
|
||||
int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
|
||||
{
|
||||
struct ldt_struct *new_ldt;
|
||||
struct mm_struct *old_mm;
|
||||
int retval = 0;
|
||||
|
||||
mutex_init(&mm->context.lock);
|
||||
mm->context.size = 0;
|
||||
old_mm = current->mm;
|
||||
if (old_mm && old_mm->context.size > 0) {
|
||||
mutex_lock(&old_mm->context.lock);
|
||||
retval = copy_ldt(&mm->context, &old_mm->context);
|
||||
mutex_unlock(&old_mm->context.lock);
|
||||
if (!old_mm) {
|
||||
mm->context.ldt = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_lock(&old_mm->context.lock);
|
||||
if (!old_mm->context.ldt) {
|
||||
mm->context.ldt = NULL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
new_ldt = alloc_ldt_struct(old_mm->context.ldt->size);
|
||||
if (!new_ldt) {
|
||||
retval = -ENOMEM;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
memcpy(new_ldt->entries, old_mm->context.ldt->entries,
|
||||
new_ldt->size * LDT_ENTRY_SIZE);
|
||||
finalize_ldt_struct(new_ldt);
|
||||
|
||||
mm->context.ldt = new_ldt;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&old_mm->context.lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -125,53 +146,47 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
|
|||
*/
|
||||
void destroy_context(struct mm_struct *mm)
|
||||
{
|
||||
if (mm->context.size) {
|
||||
#ifdef CONFIG_X86_32
|
||||
/* CHECKME: Can this ever happen ? */
|
||||
if (mm == current->active_mm)
|
||||
clear_LDT();
|
||||
#endif
|
||||
paravirt_free_ldt(mm->context.ldt, mm->context.size);
|
||||
if (mm->context.size * LDT_ENTRY_SIZE > PAGE_SIZE)
|
||||
vfree(mm->context.ldt);
|
||||
else
|
||||
put_page(virt_to_page(mm->context.ldt));
|
||||
mm->context.size = 0;
|
||||
}
|
||||
free_ldt_struct(mm->context.ldt);
|
||||
mm->context.ldt = NULL;
|
||||
}
|
||||
|
||||
static int read_ldt(void __user *ptr, unsigned long bytecount)
|
||||
{
|
||||
int err;
|
||||
int retval;
|
||||
unsigned long size;
|
||||
struct mm_struct *mm = current->mm;
|
||||
|
||||
if (!mm->context.size)
|
||||
return 0;
|
||||
mutex_lock(&mm->context.lock);
|
||||
|
||||
if (!mm->context.ldt) {
|
||||
retval = 0;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (bytecount > LDT_ENTRY_SIZE * LDT_ENTRIES)
|
||||
bytecount = LDT_ENTRY_SIZE * LDT_ENTRIES;
|
||||
|
||||
mutex_lock(&mm->context.lock);
|
||||
size = mm->context.size * LDT_ENTRY_SIZE;
|
||||
size = mm->context.ldt->size * LDT_ENTRY_SIZE;
|
||||
if (size > bytecount)
|
||||
size = bytecount;
|
||||
|
||||
err = 0;
|
||||
if (copy_to_user(ptr, mm->context.ldt, size))
|
||||
err = -EFAULT;
|
||||
mutex_unlock(&mm->context.lock);
|
||||
if (err < 0)
|
||||
goto error_return;
|
||||
if (copy_to_user(ptr, mm->context.ldt->entries, size)) {
|
||||
retval = -EFAULT;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (size != bytecount) {
|
||||
/* zero-fill the rest */
|
||||
if (clear_user(ptr + size, bytecount - size) != 0) {
|
||||
err = -EFAULT;
|
||||
goto error_return;
|
||||
/* Zero-fill the rest and pretend we read bytecount bytes. */
|
||||
if (clear_user(ptr + size, bytecount - size)) {
|
||||
retval = -EFAULT;
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
return bytecount;
|
||||
error_return:
|
||||
return err;
|
||||
retval = bytecount;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&mm->context.lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int read_default_ldt(void __user *ptr, unsigned long bytecount)
|
||||
|
@ -195,6 +210,8 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
|
|||
struct desc_struct ldt;
|
||||
int error;
|
||||
struct user_desc ldt_info;
|
||||
int oldsize, newsize;
|
||||
struct ldt_struct *new_ldt, *old_ldt;
|
||||
|
||||
error = -EINVAL;
|
||||
if (bytecount != sizeof(ldt_info))
|
||||
|
@ -213,34 +230,39 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
|
|||
goto out;
|
||||
}
|
||||
|
||||
mutex_lock(&mm->context.lock);
|
||||
if (ldt_info.entry_number >= mm->context.size) {
|
||||
error = alloc_ldt(¤t->mm->context,
|
||||
ldt_info.entry_number + 1, 1);
|
||||
if (error < 0)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* Allow LDTs to be cleared by the user. */
|
||||
if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
|
||||
if (oldmode || LDT_empty(&ldt_info)) {
|
||||
memset(&ldt, 0, sizeof(ldt));
|
||||
goto install;
|
||||
if ((oldmode && !ldt_info.base_addr && !ldt_info.limit) ||
|
||||
LDT_empty(&ldt_info)) {
|
||||
/* The user wants to clear the entry. */
|
||||
memset(&ldt, 0, sizeof(ldt));
|
||||
} else {
|
||||
if (!IS_ENABLED(CONFIG_X86_16BIT) && !ldt_info.seg_32bit) {
|
||||
error = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fill_ldt(&ldt, &ldt_info);
|
||||
if (oldmode)
|
||||
ldt.avl = 0;
|
||||
}
|
||||
|
||||
if (!IS_ENABLED(CONFIG_X86_16BIT) && !ldt_info.seg_32bit) {
|
||||
error = -EINVAL;
|
||||
mutex_lock(&mm->context.lock);
|
||||
|
||||
old_ldt = mm->context.ldt;
|
||||
oldsize = old_ldt ? old_ldt->size : 0;
|
||||
newsize = max((int)(ldt_info.entry_number + 1), oldsize);
|
||||
|
||||
error = -ENOMEM;
|
||||
new_ldt = alloc_ldt_struct(newsize);
|
||||
if (!new_ldt)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
fill_ldt(&ldt, &ldt_info);
|
||||
if (oldmode)
|
||||
ldt.avl = 0;
|
||||
if (old_ldt)
|
||||
memcpy(new_ldt->entries, old_ldt->entries, oldsize * LDT_ENTRY_SIZE);
|
||||
new_ldt->entries[ldt_info.entry_number] = ldt;
|
||||
finalize_ldt_struct(new_ldt);
|
||||
|
||||
/* Install the new entry ... */
|
||||
install:
|
||||
write_ldt_entry(mm->context.ldt, ldt_info.entry_number, &ldt);
|
||||
install_ldt(mm, new_ldt);
|
||||
free_ldt_struct(old_ldt);
|
||||
error = 0;
|
||||
|
||||
out_unlock:
|
||||
|
|
|
@ -121,11 +121,11 @@ void __show_regs(struct pt_regs *regs, int all)
|
|||
void release_thread(struct task_struct *dead_task)
|
||||
{
|
||||
if (dead_task->mm) {
|
||||
if (dead_task->mm->context.size) {
|
||||
if (dead_task->mm->context.ldt) {
|
||||
pr_warn("WARNING: dead process %s still has LDT? <%p/%d>\n",
|
||||
dead_task->comm,
|
||||
dead_task->mm->context.ldt,
|
||||
dead_task->mm->context.size);
|
||||
dead_task->mm->context.ldt->size);
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <linux/mm.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <asm/desc.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
||||
unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs)
|
||||
{
|
||||
|
@ -30,10 +31,11 @@ unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *re
|
|||
seg &= ~7UL;
|
||||
|
||||
mutex_lock(&child->mm->context.lock);
|
||||
if (unlikely((seg >> 3) >= child->mm->context.size))
|
||||
if (unlikely(!child->mm->context.ldt ||
|
||||
(seg >> 3) >= child->mm->context.ldt->size))
|
||||
addr = -1L; /* bogus selector, access would fault */
|
||||
else {
|
||||
desc = child->mm->context.ldt + seg;
|
||||
desc = &child->mm->context.ldt->entries[seg];
|
||||
base = get_desc_base(desc);
|
||||
|
||||
/* 16-bit code segment? */
|
||||
|
|
|
@ -1595,7 +1595,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
|
|||
for (i = 0; i < APIC_LVT_NUM; i++)
|
||||
apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED);
|
||||
apic_update_lvtt(apic);
|
||||
if (!(vcpu->kvm->arch.disabled_quirks & KVM_QUIRK_LINT0_REENABLED))
|
||||
if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_LINT0_REENABLED))
|
||||
apic_set_reg(apic, APIC_LVT0,
|
||||
SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT));
|
||||
apic_manage_nmi_watchdog(apic, kvm_apic_get_reg(apic, APIC_LVT0));
|
||||
|
|
|
@ -120,6 +120,16 @@ static u8 mtrr_default_type(struct kvm_mtrr *mtrr_state)
|
|||
return mtrr_state->deftype & IA32_MTRR_DEF_TYPE_TYPE_MASK;
|
||||
}
|
||||
|
||||
static u8 mtrr_disabled_type(void)
|
||||
{
|
||||
/*
|
||||
* Intel SDM 11.11.2.2: all MTRRs are disabled when
|
||||
* IA32_MTRR_DEF_TYPE.E bit is cleared, and the UC
|
||||
* memory type is applied to all of physical memory.
|
||||
*/
|
||||
return MTRR_TYPE_UNCACHABLE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Three terms are used in the following code:
|
||||
* - segment, it indicates the address segments covered by fixed MTRRs.
|
||||
|
@ -434,6 +444,8 @@ struct mtrr_iter {
|
|||
|
||||
/* output fields. */
|
||||
int mem_type;
|
||||
/* mtrr is completely disabled? */
|
||||
bool mtrr_disabled;
|
||||
/* [start, end) is not fully covered in MTRRs? */
|
||||
bool partial_map;
|
||||
|
||||
|
@ -549,7 +561,7 @@ static void mtrr_lookup_var_next(struct mtrr_iter *iter)
|
|||
static void mtrr_lookup_start(struct mtrr_iter *iter)
|
||||
{
|
||||
if (!mtrr_is_enabled(iter->mtrr_state)) {
|
||||
iter->partial_map = true;
|
||||
iter->mtrr_disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -563,6 +575,7 @@ static void mtrr_lookup_init(struct mtrr_iter *iter,
|
|||
iter->mtrr_state = mtrr_state;
|
||||
iter->start = start;
|
||||
iter->end = end;
|
||||
iter->mtrr_disabled = false;
|
||||
iter->partial_map = false;
|
||||
iter->fixed = false;
|
||||
iter->range = NULL;
|
||||
|
@ -656,15 +669,19 @@ u8 kvm_mtrr_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn)
|
|||
return MTRR_TYPE_WRBACK;
|
||||
}
|
||||
|
||||
/* It is not covered by MTRRs. */
|
||||
if (iter.partial_map) {
|
||||
/*
|
||||
* We just check one page, partially covered by MTRRs is
|
||||
* impossible.
|
||||
*/
|
||||
WARN_ON(type != -1);
|
||||
type = mtrr_default_type(mtrr_state);
|
||||
}
|
||||
if (iter.mtrr_disabled)
|
||||
return mtrr_disabled_type();
|
||||
|
||||
/*
|
||||
* We just check one page, partially covered by MTRRs is
|
||||
* impossible.
|
||||
*/
|
||||
WARN_ON(iter.partial_map);
|
||||
|
||||
/* not contained in any MTRRs. */
|
||||
if (type == -1)
|
||||
return mtrr_default_type(mtrr_state);
|
||||
|
||||
return type;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_mtrr_get_guest_memory_type);
|
||||
|
@ -689,6 +706,9 @@ bool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (iter.mtrr_disabled)
|
||||
return true;
|
||||
|
||||
if (!iter.partial_map)
|
||||
return true;
|
||||
|
||||
|
|
|
@ -1672,7 +1672,7 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
|
|||
* does not do it - this results in some delay at
|
||||
* reboot
|
||||
*/
|
||||
if (!(vcpu->kvm->arch.disabled_quirks & KVM_QUIRK_CD_NW_CLEARED))
|
||||
if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED))
|
||||
cr0 &= ~(X86_CR0_CD | X86_CR0_NW);
|
||||
svm->vmcb->save.cr0 = cr0;
|
||||
mark_dirty(svm->vmcb, VMCB_CR);
|
||||
|
|
|
@ -8650,7 +8650,10 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
|
|||
|
||||
if (kvm_read_cr0(vcpu) & X86_CR0_CD) {
|
||||
ipat = VMX_EPT_IPAT_BIT;
|
||||
cache = MTRR_TYPE_UNCACHABLE;
|
||||
if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED))
|
||||
cache = MTRR_TYPE_WRBACK;
|
||||
else
|
||||
cache = MTRR_TYPE_UNCACHABLE;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
|
|
@ -147,6 +147,11 @@ static inline void kvm_register_writel(struct kvm_vcpu *vcpu,
|
|||
return kvm_register_write(vcpu, reg, val);
|
||||
}
|
||||
|
||||
static inline bool kvm_check_has_quirk(struct kvm *kvm, u64 quirk)
|
||||
{
|
||||
return !(kvm->arch.disabled_quirks & quirk);
|
||||
}
|
||||
|
||||
void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
|
||||
void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
|
||||
void kvm_set_pending_timer(struct kvm_vcpu *vcpu);
|
||||
|
|
|
@ -63,8 +63,6 @@ static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages,
|
|||
!PageReserved(pfn_to_page(start_pfn + i)))
|
||||
return 1;
|
||||
|
||||
WARN_ONCE(1, "ioremap on RAM pfn 0x%lx\n", start_pfn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -94,7 +92,6 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
|
|||
pgprot_t prot;
|
||||
int retval;
|
||||
void __iomem *ret_addr;
|
||||
int ram_region;
|
||||
|
||||
/* Don't allow wraparound or zero size */
|
||||
last_addr = phys_addr + size - 1;
|
||||
|
@ -117,23 +114,15 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
|
|||
/*
|
||||
* Don't allow anybody to remap normal RAM that we're using..
|
||||
*/
|
||||
/* First check if whole region can be identified as RAM or not */
|
||||
ram_region = region_is_ram(phys_addr, size);
|
||||
if (ram_region > 0) {
|
||||
WARN_ONCE(1, "ioremap on RAM at 0x%lx - 0x%lx\n",
|
||||
(unsigned long int)phys_addr,
|
||||
(unsigned long int)last_addr);
|
||||
pfn = phys_addr >> PAGE_SHIFT;
|
||||
last_pfn = last_addr >> PAGE_SHIFT;
|
||||
if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL,
|
||||
__ioremap_check_ram) == 1) {
|
||||
WARN_ONCE(1, "ioremap on RAM at %pa - %pa\n",
|
||||
&phys_addr, &last_addr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If could not be identified(-1), check page by page */
|
||||
if (ram_region < 0) {
|
||||
pfn = phys_addr >> PAGE_SHIFT;
|
||||
last_pfn = last_addr >> PAGE_SHIFT;
|
||||
if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL,
|
||||
__ioremap_check_ram) == 1)
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
* Mappings have to be page-aligned
|
||||
*/
|
||||
|
|
|
@ -126,3 +126,10 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
|
|||
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
|
||||
}
|
||||
}
|
||||
|
||||
const char *arch_vma_name(struct vm_area_struct *vma)
|
||||
{
|
||||
if (vma->vm_flags & VM_MPX)
|
||||
return "[mpx]";
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -20,20 +20,6 @@
|
|||
#define CREATE_TRACE_POINTS
|
||||
#include <asm/trace/mpx.h>
|
||||
|
||||
static const char *mpx_mapping_name(struct vm_area_struct *vma)
|
||||
{
|
||||
return "[mpx]";
|
||||
}
|
||||
|
||||
static struct vm_operations_struct mpx_vma_ops = {
|
||||
.name = mpx_mapping_name,
|
||||
};
|
||||
|
||||
static int is_mpx_vma(struct vm_area_struct *vma)
|
||||
{
|
||||
return (vma->vm_ops == &mpx_vma_ops);
|
||||
}
|
||||
|
||||
static inline unsigned long mpx_bd_size_bytes(struct mm_struct *mm)
|
||||
{
|
||||
if (is_64bit_mm(mm))
|
||||
|
@ -53,9 +39,6 @@ static inline unsigned long mpx_bt_size_bytes(struct mm_struct *mm)
|
|||
/*
|
||||
* This is really a simplified "vm_mmap". it only handles MPX
|
||||
* bounds tables (the bounds directory is user-allocated).
|
||||
*
|
||||
* Later on, we use the vma->vm_ops to uniquely identify these
|
||||
* VMAs.
|
||||
*/
|
||||
static unsigned long mpx_mmap(unsigned long len)
|
||||
{
|
||||
|
@ -101,7 +84,6 @@ static unsigned long mpx_mmap(unsigned long len)
|
|||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
vma->vm_ops = &mpx_vma_ops;
|
||||
|
||||
if (vm_flags & VM_LOCKED) {
|
||||
up_write(&mm->mmap_sem);
|
||||
|
@ -812,7 +794,7 @@ static noinline int zap_bt_entries_mapping(struct mm_struct *mm,
|
|||
* so stop immediately and return an error. This
|
||||
* probably results in a SIGSEGV.
|
||||
*/
|
||||
if (!is_mpx_vma(vma))
|
||||
if (!(vma->vm_flags & VM_MPX))
|
||||
return -EINVAL;
|
||||
|
||||
len = min(vma->vm_end, end) - addr;
|
||||
|
@ -945,9 +927,9 @@ static int try_unmap_single_bt(struct mm_struct *mm,
|
|||
* lots of tables even though we have no actual table
|
||||
* entries in use.
|
||||
*/
|
||||
while (next && is_mpx_vma(next))
|
||||
while (next && (next->vm_flags & VM_MPX))
|
||||
next = next->vm_next;
|
||||
while (prev && is_mpx_vma(prev))
|
||||
while (prev && (prev->vm_flags & VM_MPX))
|
||||
prev = prev->vm_prev;
|
||||
/*
|
||||
* We know 'start' and 'end' lie within an area controlled
|
||||
|
|
|
@ -117,7 +117,7 @@ static void flush_tlb_func(void *info)
|
|||
} else {
|
||||
unsigned long addr;
|
||||
unsigned long nr_pages =
|
||||
f->flush_end - f->flush_start / PAGE_SIZE;
|
||||
(f->flush_end - f->flush_start) / PAGE_SIZE;
|
||||
addr = f->flush_start;
|
||||
while (addr < f->flush_end) {
|
||||
__flush_tlb_single(addr);
|
||||
|
|
|
@ -269,7 +269,7 @@ static void emit_bpf_tail_call(u8 **pprog)
|
|||
EMIT4(0x48, 0x8B, 0x46, /* mov rax, qword ptr [rsi + 16] */
|
||||
offsetof(struct bpf_array, map.max_entries));
|
||||
EMIT3(0x48, 0x39, 0xD0); /* cmp rax, rdx */
|
||||
#define OFFSET1 44 /* number of bytes to jump */
|
||||
#define OFFSET1 47 /* number of bytes to jump */
|
||||
EMIT2(X86_JBE, OFFSET1); /* jbe out */
|
||||
label1 = cnt;
|
||||
|
||||
|
@ -278,15 +278,15 @@ static void emit_bpf_tail_call(u8 **pprog)
|
|||
*/
|
||||
EMIT2_off32(0x8B, 0x85, -STACKSIZE + 36); /* mov eax, dword ptr [rbp - 516] */
|
||||
EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */
|
||||
#define OFFSET2 33
|
||||
#define OFFSET2 36
|
||||
EMIT2(X86_JA, OFFSET2); /* ja out */
|
||||
label2 = cnt;
|
||||
EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */
|
||||
EMIT2_off32(0x89, 0x85, -STACKSIZE + 36); /* mov dword ptr [rbp - 516], eax */
|
||||
|
||||
/* prog = array->prog[index]; */
|
||||
EMIT4(0x48, 0x8D, 0x44, 0xD6); /* lea rax, [rsi + rdx * 8 + 0x50] */
|
||||
EMIT1(offsetof(struct bpf_array, prog));
|
||||
EMIT4_off32(0x48, 0x8D, 0x84, 0xD6, /* lea rax, [rsi + rdx * 8 + offsetof(...)] */
|
||||
offsetof(struct bpf_array, prog));
|
||||
EMIT3(0x48, 0x8B, 0x00); /* mov rax, qword ptr [rax] */
|
||||
|
||||
/* if (prog == NULL)
|
||||
|
|
|
@ -972,6 +972,11 @@ u64 efi_mem_attributes(unsigned long phys_addr)
|
|||
|
||||
static int __init arch_parse_efi_cmdline(char *str)
|
||||
{
|
||||
if (!str) {
|
||||
pr_warn("need at least one option\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (parse_option_str(str, "old_map"))
|
||||
set_bit(EFI_OLD_MEMMAP, &efi.flags);
|
||||
if (parse_option_str(str, "debug"))
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <asm/fpu/internal.h>
|
||||
#include <asm/debugreg.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
__visible unsigned long saved_context_ebx;
|
||||
|
@ -153,7 +154,7 @@ static void fix_processor_context(void)
|
|||
syscall_init(); /* This sets MSR_*STAR and related */
|
||||
#endif
|
||||
load_TR_desc(); /* This does ltr */
|
||||
load_LDT(¤t->active_mm->context); /* This does lldt */
|
||||
load_mm_ldt(current->active_mm); /* This does lldt */
|
||||
|
||||
fpu__resume_cpu();
|
||||
}
|
||||
|
|
|
@ -483,6 +483,7 @@ static void set_aliased_prot(void *v, pgprot_t prot)
|
|||
pte_t pte;
|
||||
unsigned long pfn;
|
||||
struct page *page;
|
||||
unsigned char dummy;
|
||||
|
||||
ptep = lookup_address((unsigned long)v, &level);
|
||||
BUG_ON(ptep == NULL);
|
||||
|
@ -492,6 +493,32 @@ static void set_aliased_prot(void *v, pgprot_t prot)
|
|||
|
||||
pte = pfn_pte(pfn, prot);
|
||||
|
||||
/*
|
||||
* Careful: update_va_mapping() will fail if the virtual address
|
||||
* we're poking isn't populated in the page tables. We don't
|
||||
* need to worry about the direct map (that's always in the page
|
||||
* tables), but we need to be careful about vmap space. In
|
||||
* particular, the top level page table can lazily propagate
|
||||
* entries between processes, so if we've switched mms since we
|
||||
* vmapped the target in the first place, we might not have the
|
||||
* top-level page table entry populated.
|
||||
*
|
||||
* We disable preemption because we want the same mm active when
|
||||
* we probe the target and when we issue the hypercall. We'll
|
||||
* have the same nominal mm, but if we're a kernel thread, lazy
|
||||
* mm dropping could change our pgd.
|
||||
*
|
||||
* Out of an abundance of caution, this uses __get_user() to fault
|
||||
* in the target address just in case there's some obscure case
|
||||
* in which the target address isn't readable.
|
||||
*/
|
||||
|
||||
preempt_disable();
|
||||
|
||||
pagefault_disable(); /* Avoid warnings due to being atomic. */
|
||||
__get_user(dummy, (unsigned char __user __force *)v);
|
||||
pagefault_enable();
|
||||
|
||||
if (HYPERVISOR_update_va_mapping((unsigned long)v, pte, 0))
|
||||
BUG();
|
||||
|
||||
|
@ -503,6 +530,8 @@ static void set_aliased_prot(void *v, pgprot_t prot)
|
|||
BUG();
|
||||
} else
|
||||
kmap_flush_unused();
|
||||
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
static void xen_alloc_ldt(struct desc_struct *ldt, unsigned entries)
|
||||
|
@ -510,6 +539,17 @@ static void xen_alloc_ldt(struct desc_struct *ldt, unsigned entries)
|
|||
const unsigned entries_per_page = PAGE_SIZE / LDT_ENTRY_SIZE;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* We need to mark the all aliases of the LDT pages RO. We
|
||||
* don't need to call vm_flush_aliases(), though, since that's
|
||||
* only responsible for flushing aliases out the TLBs, not the
|
||||
* page tables, and Xen will flush the TLB for us if needed.
|
||||
*
|
||||
* To avoid confusing future readers: none of this is necessary
|
||||
* to load the LDT. The hypervisor only checks this when the
|
||||
* LDT is faulted in due to subsequent descriptor access.
|
||||
*/
|
||||
|
||||
for(i = 0; i < entries; i += entries_per_page)
|
||||
set_aliased_prot(ldt + i, PAGE_KERNEL_RO);
|
||||
}
|
||||
|
|
17
block/bio.c
17
block/bio.c
|
@ -1831,8 +1831,9 @@ EXPORT_SYMBOL(bio_endio);
|
|||
* Allocates and returns a new bio which represents @sectors from the start of
|
||||
* @bio, and updates @bio to represent the remaining sectors.
|
||||
*
|
||||
* The newly allocated bio will point to @bio's bi_io_vec; it is the caller's
|
||||
* responsibility to ensure that @bio is not freed before the split.
|
||||
* Unless this is a discard request the newly allocated bio will point
|
||||
* to @bio's bi_io_vec; it is the caller's responsibility to ensure that
|
||||
* @bio is not freed before the split.
|
||||
*/
|
||||
struct bio *bio_split(struct bio *bio, int sectors,
|
||||
gfp_t gfp, struct bio_set *bs)
|
||||
|
@ -1842,7 +1843,15 @@ struct bio *bio_split(struct bio *bio, int sectors,
|
|||
BUG_ON(sectors <= 0);
|
||||
BUG_ON(sectors >= bio_sectors(bio));
|
||||
|
||||
split = bio_clone_fast(bio, gfp, bs);
|
||||
/*
|
||||
* Discards need a mutable bio_vec to accommodate the payload
|
||||
* required by the DSM TRIM and UNMAP commands.
|
||||
*/
|
||||
if (bio->bi_rw & REQ_DISCARD)
|
||||
split = bio_clone_bioset(bio, gfp, bs);
|
||||
else
|
||||
split = bio_clone_fast(bio, gfp, bs);
|
||||
|
||||
if (!split)
|
||||
return NULL;
|
||||
|
||||
|
@ -2009,6 +2018,7 @@ int bio_associate_blkcg(struct bio *bio, struct cgroup_subsys_state *blkcg_css)
|
|||
bio->bi_css = blkcg_css;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bio_associate_blkcg);
|
||||
|
||||
/**
|
||||
* bio_associate_current - associate a bio with %current
|
||||
|
@ -2039,6 +2049,7 @@ int bio_associate_current(struct bio *bio)
|
|||
bio->bi_css = task_get_css(current, blkio_cgrp_id);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bio_associate_current);
|
||||
|
||||
/**
|
||||
* bio_disassociate_task - undo bio_associate_current()
|
||||
|
|
|
@ -718,8 +718,12 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
|
|||
return -EINVAL;
|
||||
|
||||
disk = get_gendisk(MKDEV(major, minor), &part);
|
||||
if (!disk || part)
|
||||
if (!disk)
|
||||
return -EINVAL;
|
||||
if (part) {
|
||||
put_disk(disk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
spin_lock_irq(disk->queue->queue_lock);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue