forked from Minki/linux
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
This commit is contained in:
commit
6f4c930e02
@ -85,4 +85,5 @@ examples:
|
||||
<&pd IMX_SC_R_DSP_RAM>;
|
||||
mbox-names = "txdb0", "txdb1", "rxdb0", "rxdb1";
|
||||
mboxes = <&lsio_mu13 2 0>, <&lsio_mu13 2 1>, <&lsio_mu13 3 0>, <&lsio_mu13 3 1>;
|
||||
memory-region = <&dsp_reserved>;
|
||||
};
|
||||
|
@ -43,13 +43,9 @@ properties:
|
||||
|
||||
dvdd-supply:
|
||||
description: DVdd voltage supply
|
||||
items:
|
||||
- const: dvdd
|
||||
|
||||
avdd-supply:
|
||||
description: AVdd voltage supply
|
||||
items:
|
||||
- const: avdd
|
||||
|
||||
adi,rejection-60-Hz-enable:
|
||||
description: |
|
||||
@ -99,6 +95,9 @@ required:
|
||||
examples:
|
||||
- |
|
||||
spi0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
adc@0 {
|
||||
compatible = "adi,ad7192";
|
||||
reg = <0>;
|
||||
|
@ -73,7 +73,6 @@ properties:
|
||||
- rc-genius-tvgo-a11mce
|
||||
- rc-gotview7135
|
||||
- rc-hauppauge
|
||||
- rc-hauppauge
|
||||
- rc-hisi-poplar
|
||||
- rc-hisi-tv-demo
|
||||
- rc-imon-mce
|
||||
|
@ -37,7 +37,7 @@ properties:
|
||||
- description: exclusive PHY reset line
|
||||
- description: shared reset line between the PCIe PHY and PCIe controller
|
||||
|
||||
resets-names:
|
||||
reset-names:
|
||||
items:
|
||||
- const: phy
|
||||
- const: pcie
|
||||
|
@ -954,11 +954,6 @@ When kbuild executes, the following steps are followed (roughly):
|
||||
|
||||
From commandline LDFLAGS_MODULE shall be used (see kbuild.txt).
|
||||
|
||||
KBUILD_ARFLAGS Options for $(AR) when creating archives
|
||||
|
||||
$(KBUILD_ARFLAGS) set by the top level Makefile to "D" (deterministic
|
||||
mode) if this option is supported by $(AR).
|
||||
|
||||
KBUILD_LDS
|
||||
|
||||
The linker script with full path. Assigned by the top-level Makefile.
|
||||
|
@ -498,10 +498,11 @@ build.
|
||||
will be written containing all exported symbols that were not
|
||||
defined in the kernel.
|
||||
|
||||
--- 6.3 Symbols From Another External Module
|
||||
6.3 Symbols From Another External Module
|
||||
----------------------------------------
|
||||
|
||||
Sometimes, an external module uses exported symbols from
|
||||
another external module. kbuild needs to have full knowledge of
|
||||
another external module. Kbuild needs to have full knowledge of
|
||||
all symbols to avoid spitting out warnings about undefined
|
||||
symbols. Three solutions exist for this situation.
|
||||
|
||||
@ -521,7 +522,7 @@ build.
|
||||
The top-level kbuild file would then look like::
|
||||
|
||||
#./Kbuild (or ./Makefile):
|
||||
obj-y := foo/ bar/
|
||||
obj-m := foo/ bar/
|
||||
|
||||
And executing::
|
||||
|
||||
|
@ -16,16 +16,21 @@ the kernel may be unreproducible, and how to avoid them.
|
||||
Timestamps
|
||||
----------
|
||||
|
||||
The kernel embeds a timestamp in two places:
|
||||
The kernel embeds timestamps in three places:
|
||||
|
||||
* The version string exposed by ``uname()`` and included in
|
||||
``/proc/version``
|
||||
|
||||
* File timestamps in the embedded initramfs
|
||||
|
||||
By default the timestamp is the current time. This must be overridden
|
||||
using the `KBUILD_BUILD_TIMESTAMP`_ variable. If you are building
|
||||
from a git commit, you could use its commit date.
|
||||
* If enabled via ``CONFIG_IKHEADERS``, file timestamps of kernel
|
||||
headers embedded in the kernel or respective module,
|
||||
exposed via ``/sys/kernel/kheaders.tar.xz``
|
||||
|
||||
By default the timestamp is the current time and in the case of
|
||||
``kheaders`` the various files' modification times. This must
|
||||
be overridden using the `KBUILD_BUILD_TIMESTAMP`_ variable.
|
||||
If you are building from a git commit, you could use its commit date.
|
||||
|
||||
The kernel does *not* use the ``__DATE__`` and ``__TIME__`` macros,
|
||||
and enables warnings if they are used. If you incorporate external
|
||||
|
@ -23,6 +23,7 @@ Contents:
|
||||
intel/ice
|
||||
google/gve
|
||||
mellanox/mlx5
|
||||
netronome/nfp
|
||||
pensando/ionic
|
||||
|
||||
.. only:: subproject and html
|
||||
|
@ -272,7 +272,7 @@ supported flags are:
|
||||
* MSG_DONTWAIT, i.e. non-blocking operation.
|
||||
|
||||
recvmsg(2)
|
||||
^^^^^^^^^
|
||||
^^^^^^^^^^
|
||||
|
||||
In most cases recvmsg(2) is needed if you want to extract more information than
|
||||
recvfrom(2) can provide. For example package priority and timestamp. The
|
||||
|
@ -143,6 +143,20 @@ via their employer, they cannot enter individual non-disclosure agreements
|
||||
in their role as Linux kernel developers. They will, however, agree to
|
||||
adhere to this documented process and the Memorandum of Understanding.
|
||||
|
||||
The disclosing party should provide a list of contacts for all other
|
||||
entities who have already been, or should be, informed about the issue.
|
||||
This serves several purposes:
|
||||
|
||||
- The list of disclosed entities allows communication accross the
|
||||
industry, e.g. other OS vendors, HW vendors, etc.
|
||||
|
||||
- The disclosed entities can be contacted to name experts who should
|
||||
participate in the mitigation development.
|
||||
|
||||
- If an expert which is required to handle an issue is employed by an
|
||||
listed entity or member of an listed entity, then the response teams can
|
||||
request the disclosure of that expert from that entity. This ensures
|
||||
that the expert is also part of the entity's response team.
|
||||
|
||||
Disclosure
|
||||
""""""""""
|
||||
@ -158,10 +172,7 @@ Mitigation development
|
||||
""""""""""""""""""""""
|
||||
|
||||
The initial response team sets up an encrypted mailing-list or repurposes
|
||||
an existing one if appropriate. The disclosing party should provide a list
|
||||
of contacts for all other parties who have already been, or should be,
|
||||
informed about the issue. The response team contacts these parties so they
|
||||
can name experts who should be subscribed to the mailing-list.
|
||||
an existing one if appropriate.
|
||||
|
||||
Using a mailing-list is close to the normal Linux development process and
|
||||
has been successfully used in developing mitigations for various hardware
|
||||
@ -175,9 +186,24 @@ development branch against the mainline kernel and backport branches for
|
||||
stable kernel versions as necessary.
|
||||
|
||||
The initial response team will identify further experts from the Linux
|
||||
kernel developer community as needed and inform the disclosing party about
|
||||
their participation. Bringing in experts can happen at any time of the
|
||||
development process and often needs to be handled in a timely manner.
|
||||
kernel developer community as needed. Bringing in experts can happen at any
|
||||
time of the development process and needs to be handled in a timely manner.
|
||||
|
||||
If an expert is employed by or member of an entity on the disclosure list
|
||||
provided by the disclosing party, then participation will be requested from
|
||||
the relevant entity.
|
||||
|
||||
If not, then the disclosing party will be informed about the experts
|
||||
participation. The experts are covered by the Memorandum of Understanding
|
||||
and the disclosing party is requested to acknowledge the participation. In
|
||||
case that the disclosing party has a compelling reason to object, then this
|
||||
objection has to be raised within five work days and resolved with the
|
||||
incident team immediately. If the disclosing party does not react within
|
||||
five work days this is taken as silent acknowledgement.
|
||||
|
||||
After acknowledgement or resolution of an objection the expert is disclosed
|
||||
by the incident team and brought into the development process.
|
||||
|
||||
|
||||
Coordinated release
|
||||
"""""""""""""""""""
|
||||
@ -216,7 +242,7 @@ an involved disclosed party. The current ambassadors list:
|
||||
ARM
|
||||
AMD
|
||||
IBM
|
||||
Intel
|
||||
Intel Tony Luck <tony.luck@intel.com>
|
||||
Qualcomm Trilok Soni <tsoni@codeaurora.org>
|
||||
|
||||
Microsoft Sasha Levin <sashal@kernel.org>
|
||||
|
@ -6112,7 +6112,10 @@ M: Gao Xiang <gaoxiang25@huawei.com>
|
||||
M: Chao Yu <yuchao0@huawei.com>
|
||||
L: linux-erofs@lists.ozlabs.org
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
|
||||
F: Documentation/filesystems/erofs.txt
|
||||
F: fs/erofs/
|
||||
F: include/trace/events/erofs.h
|
||||
|
||||
ERRSEQ ERROR TRACKING INFRASTRUCTURE
|
||||
M: Jeff Layton <jlayton@kernel.org>
|
||||
@ -9075,6 +9078,7 @@ F: security/keys/
|
||||
KGDB / KDB /debug_core
|
||||
M: Jason Wessel <jason.wessel@windriver.com>
|
||||
M: Daniel Thompson <daniel.thompson@linaro.org>
|
||||
R: Douglas Anderson <dianders@chromium.org>
|
||||
W: http://kgdb.wiki.kernel.org/
|
||||
L: kgdb-bugreport@lists.sourceforge.net
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/kgdb.git
|
||||
|
28
Makefile
28
Makefile
@ -1,8 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 3
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION =
|
||||
EXTRAVERSION = -rc1
|
||||
NAME = Bobtail Squid
|
||||
|
||||
# *DOCUMENTATION*
|
||||
@ -206,24 +206,8 @@ ifndef KBUILD_CHECKSRC
|
||||
KBUILD_CHECKSRC = 0
|
||||
endif
|
||||
|
||||
# Use make M=dir to specify directory of external module to build
|
||||
# Old syntax make ... SUBDIRS=$PWD is still supported
|
||||
# Setting the environment variable KBUILD_EXTMOD take precedence
|
||||
ifdef SUBDIRS
|
||||
$(warning ================= WARNING ================)
|
||||
$(warning 'SUBDIRS' will be removed after Linux 5.3)
|
||||
$(warning )
|
||||
$(warning If you are building an individual subdirectory)
|
||||
$(warning in the kernel tree, you can do like this:)
|
||||
$(warning $$ make path/to/dir/you/want/to/build/)
|
||||
$(warning (Do not forget the trailing slash))
|
||||
$(warning )
|
||||
$(warning If you are building an external module,)
|
||||
$(warning Please use 'M=' or 'KBUILD_EXTMOD' instead)
|
||||
$(warning ==========================================)
|
||||
KBUILD_EXTMOD ?= $(SUBDIRS)
|
||||
endif
|
||||
|
||||
# Use make M=dir or set the environment variable KBUILD_EXTMOD to specify the
|
||||
# directory of external module to build. Setting M= takes precedence.
|
||||
ifeq ("$(origin M)", "command line")
|
||||
KBUILD_EXTMOD := $(M)
|
||||
endif
|
||||
@ -498,7 +482,6 @@ export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN
|
||||
export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
|
||||
export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
|
||||
export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
|
||||
export KBUILD_ARFLAGS
|
||||
|
||||
# Files to ignore in find ... statements
|
||||
|
||||
@ -914,9 +897,6 @@ ifdef CONFIG_RETPOLINE
|
||||
KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
|
||||
endif
|
||||
|
||||
# use the deterministic mode of AR if available
|
||||
KBUILD_ARFLAGS := $(call ar-option,D)
|
||||
|
||||
include scripts/Makefile.kasan
|
||||
include scripts/Makefile.extrawarn
|
||||
include scripts/Makefile.ubsan
|
||||
|
@ -124,10 +124,11 @@
|
||||
};
|
||||
|
||||
lcd0: display@0 {
|
||||
compatible = "panel-dpi";
|
||||
/* This isn't the exact LCD, but the timings meet spec */
|
||||
/* To make it work, set CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=4 */
|
||||
compatible = "newhaven,nhd-4.3-480272ef-atxl";
|
||||
label = "15";
|
||||
status = "okay";
|
||||
pinctrl-names = "default";
|
||||
backlight = <&bl>;
|
||||
enable-gpios = <&gpio6 16 GPIO_ACTIVE_HIGH>; /* gpio176, lcd INI */
|
||||
vcc-supply = <&vdd_io_reg>;
|
||||
|
||||
@ -136,22 +137,6 @@
|
||||
remote-endpoint = <&dpi_out>;
|
||||
};
|
||||
};
|
||||
|
||||
panel-timing {
|
||||
clock-frequency = <9000000>;
|
||||
hactive = <480>;
|
||||
vactive = <272>;
|
||||
hfront-porch = <3>;
|
||||
hback-porch = <2>;
|
||||
hsync-len = <42>;
|
||||
vback-porch = <3>;
|
||||
vfront-porch = <4>;
|
||||
vsync-len = <11>;
|
||||
hsync-active = <0>;
|
||||
vsync-active = <0>;
|
||||
de-active = <1>;
|
||||
pixelclk-active = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
bl: backlight {
|
||||
|
@ -228,6 +228,20 @@
|
||||
>;
|
||||
};
|
||||
|
||||
i2c2_pins: pinmux_i2c2_pins {
|
||||
pinctrl-single,pins = <
|
||||
OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT | MUX_MODE0) /* i2c2_scl */
|
||||
OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT | MUX_MODE0) /* i2c2_sda */
|
||||
>;
|
||||
};
|
||||
|
||||
i2c3_pins: pinmux_i2c3_pins {
|
||||
pinctrl-single,pins = <
|
||||
OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0) /* i2c3_scl */
|
||||
OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0) /* i2c3_sda */
|
||||
>;
|
||||
};
|
||||
|
||||
tsc2004_pins: pinmux_tsc2004_pins {
|
||||
pinctrl-single,pins = <
|
||||
OMAP3_CORE1_IOPAD(0x2186, PIN_INPUT | MUX_MODE4) /* mcbsp4_dr.gpio_153 */
|
||||
@ -249,18 +263,6 @@
|
||||
OMAP3_WKUP_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE4) /* sys_boot1.gpio_3 */
|
||||
>;
|
||||
};
|
||||
i2c2_pins: pinmux_i2c2_pins {
|
||||
pinctrl-single,pins = <
|
||||
OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT | MUX_MODE0) /* i2c2_scl */
|
||||
OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT | MUX_MODE0) /* i2c2_sda */
|
||||
>;
|
||||
};
|
||||
i2c3_pins: pinmux_i2c3_pins {
|
||||
pinctrl-single,pins = <
|
||||
OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0) /* i2c3_scl */
|
||||
OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0) /* i2c3_sda */
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
&omap3_pmx_core2 {
|
||||
|
@ -108,7 +108,6 @@
|
||||
&dss {
|
||||
status = "ok";
|
||||
vdds_dsi-supply = <&vpll2>;
|
||||
vdda_video-supply = <&video_reg>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&dss_dpi_pins1>;
|
||||
port {
|
||||
@ -124,44 +123,20 @@
|
||||
display0 = &lcd0;
|
||||
};
|
||||
|
||||
video_reg: video_reg {
|
||||
lcd0: display {
|
||||
/* This isn't the exact LCD, but the timings meet spec */
|
||||
/* To make it work, set CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=4 */
|
||||
compatible = "newhaven,nhd-4.3-480272ef-atxl";
|
||||
label = "15";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&panel_pwr_pins>;
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "fixed-supply";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
gpio = <&gpio5 27 GPIO_ACTIVE_HIGH>; /* gpio155, lcd INI */
|
||||
};
|
||||
|
||||
lcd0: display {
|
||||
compatible = "panel-dpi";
|
||||
label = "15";
|
||||
status = "okay";
|
||||
/* default-on; */
|
||||
pinctrl-names = "default";
|
||||
|
||||
backlight = <&bl>;
|
||||
enable-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>;
|
||||
port {
|
||||
lcd_in: endpoint {
|
||||
remote-endpoint = <&dpi_out>;
|
||||
};
|
||||
};
|
||||
|
||||
panel-timing {
|
||||
clock-frequency = <9000000>;
|
||||
hactive = <480>;
|
||||
vactive = <272>;
|
||||
hfront-porch = <3>;
|
||||
hback-porch = <2>;
|
||||
hsync-len = <42>;
|
||||
vback-porch = <3>;
|
||||
vfront-porch = <4>;
|
||||
vsync-len = <11>;
|
||||
hsync-active = <0>;
|
||||
vsync-active = <0>;
|
||||
de-active = <1>;
|
||||
pixelclk-active = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
bl: backlight {
|
||||
|
@ -363,6 +363,7 @@ CONFIG_DRM_OMAP_PANEL_TPO_TD028TTEC1=m
|
||||
CONFIG_DRM_OMAP_PANEL_TPO_TD043MTEA1=m
|
||||
CONFIG_DRM_OMAP_PANEL_NEC_NL8048HL11=m
|
||||
CONFIG_DRM_TILCDC=m
|
||||
CONFIG_DRM_PANEL_SIMPLE=m
|
||||
CONFIG_FB=y
|
||||
CONFIG_FIRMWARE_EDID=y
|
||||
CONFIG_FB_MODE_HELPERS=y
|
||||
|
@ -1,6 +0,0 @@
|
||||
#ifndef _ASM_XEN_OPS_H
|
||||
#define _ASM_XEN_OPS_H
|
||||
|
||||
void xen_efi_runtime_setup(void);
|
||||
|
||||
#endif /* _ASM_XEN_OPS_H */
|
@ -26,7 +26,6 @@ config MACH_ASPEED_G4
|
||||
config MACH_ASPEED_G5
|
||||
bool "Aspeed SoC 5th Generation"
|
||||
depends on ARCH_MULTI_V6
|
||||
select CPU_V6
|
||||
select PINCTRL_ASPEED_G5
|
||||
select FTTMR010_TIMER
|
||||
help
|
||||
|
@ -491,11 +491,11 @@ static int ti_sysc_clkdm_init(struct device *dev,
|
||||
struct clk *fck, struct clk *ick,
|
||||
struct ti_sysc_cookie *cookie)
|
||||
{
|
||||
if (fck)
|
||||
if (!IS_ERR(fck))
|
||||
cookie->clkdm = ti_sysc_find_one_clockdomain(fck);
|
||||
if (cookie->clkdm)
|
||||
return 0;
|
||||
if (ick)
|
||||
if (!IS_ERR(ick))
|
||||
cookie->clkdm = ti_sysc_find_one_clockdomain(ick);
|
||||
if (cookie->clkdm)
|
||||
return 0;
|
||||
|
@ -1,3 +1,2 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-y := enlighten.o hypercall.o grant-table.o p2m.o mm.o
|
||||
obj-$(CONFIG_XEN_EFI) += efi.o
|
||||
|
@ -1,28 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2015, Linaro Limited, Shannon Zhao
|
||||
*/
|
||||
|
||||
#include <linux/efi.h>
|
||||
#include <xen/xen-ops.h>
|
||||
#include <asm/xen/xen-ops.h>
|
||||
|
||||
/* Set XEN EFI runtime services function pointers. Other fields of struct efi,
|
||||
* e.g. efi.systab, will be set like normal EFI.
|
||||
*/
|
||||
void __init xen_efi_runtime_setup(void)
|
||||
{
|
||||
efi.get_time = xen_efi_get_time;
|
||||
efi.set_time = xen_efi_set_time;
|
||||
efi.get_wakeup_time = xen_efi_get_wakeup_time;
|
||||
efi.set_wakeup_time = xen_efi_set_wakeup_time;
|
||||
efi.get_variable = xen_efi_get_variable;
|
||||
efi.get_next_variable = xen_efi_get_next_variable;
|
||||
efi.set_variable = xen_efi_set_variable;
|
||||
efi.query_variable_info = xen_efi_query_variable_info;
|
||||
efi.update_capsule = xen_efi_update_capsule;
|
||||
efi.query_capsule_caps = xen_efi_query_capsule_caps;
|
||||
efi.get_next_high_mono_count = xen_efi_get_next_high_mono_count;
|
||||
efi.reset_system = xen_efi_reset_system;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xen_efi_runtime_setup);
|
@ -15,7 +15,6 @@
|
||||
#include <xen/xen-ops.h>
|
||||
#include <asm/xen/hypervisor.h>
|
||||
#include <asm/xen/hypercall.h>
|
||||
#include <asm/xen/xen-ops.h>
|
||||
#include <asm/system_misc.h>
|
||||
#include <asm/efi.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -437,7 +436,7 @@ EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op);
|
||||
EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op);
|
||||
EXPORT_SYMBOL_GPL(HYPERVISOR_vcpu_op);
|
||||
EXPORT_SYMBOL_GPL(HYPERVISOR_tmem_op);
|
||||
EXPORT_SYMBOL_GPL(HYPERVISOR_platform_op);
|
||||
EXPORT_SYMBOL_GPL(HYPERVISOR_platform_op_raw);
|
||||
EXPORT_SYMBOL_GPL(HYPERVISOR_multicall);
|
||||
EXPORT_SYMBOL_GPL(HYPERVISOR_vm_assist);
|
||||
EXPORT_SYMBOL_GPL(HYPERVISOR_dm_op);
|
||||
|
@ -28,7 +28,10 @@ unsigned long xen_get_swiotlb_free_pages(unsigned int order)
|
||||
|
||||
for_each_memblock(memory, reg) {
|
||||
if (reg->base < (phys_addr_t)0xffffffff) {
|
||||
flags |= __GFP_DMA;
|
||||
if (IS_ENABLED(CONFIG_ZONE_DMA32))
|
||||
flags |= __GFP_DMA32;
|
||||
else
|
||||
flags |= __GFP_DMA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -47,30 +47,6 @@
|
||||
#define read_sysreg_el2(r) read_sysreg_elx(r, _EL2, _EL1)
|
||||
#define write_sysreg_el2(v,r) write_sysreg_elx(v, r, _EL2, _EL1)
|
||||
|
||||
/**
|
||||
* hyp_alternate_select - Generates patchable code sequences that are
|
||||
* used to switch between two implementations of a function, depending
|
||||
* on the availability of a feature.
|
||||
*
|
||||
* @fname: a symbol name that will be defined as a function returning a
|
||||
* function pointer whose type will match @orig and @alt
|
||||
* @orig: A pointer to the default function, as returned by @fname when
|
||||
* @cond doesn't hold
|
||||
* @alt: A pointer to the alternate function, as returned by @fname
|
||||
* when @cond holds
|
||||
* @cond: a CPU feature (as described in asm/cpufeature.h)
|
||||
*/
|
||||
#define hyp_alternate_select(fname, orig, alt, cond) \
|
||||
typeof(orig) * __hyp_text fname(void) \
|
||||
{ \
|
||||
typeof(alt) *val = orig; \
|
||||
asm volatile(ALTERNATIVE("nop \n", \
|
||||
"mov %0, %1 \n", \
|
||||
cond) \
|
||||
: "+r" (val) : "r" (alt)); \
|
||||
return val; \
|
||||
}
|
||||
|
||||
int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu);
|
||||
|
||||
void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
|
||||
|
@ -1,7 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _ASM_XEN_OPS_H
|
||||
#define _ASM_XEN_OPS_H
|
||||
|
||||
void xen_efi_runtime_setup(void);
|
||||
|
||||
#endif /* _ASM_XEN_OPS_H */
|
@ -229,20 +229,6 @@ static void __hyp_text __hyp_vgic_restore_state(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
}
|
||||
|
||||
static bool __hyp_text __true_value(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool __hyp_text __false_value(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static hyp_alternate_select(__check_arm_834220,
|
||||
__false_value, __true_value,
|
||||
ARM64_WORKAROUND_834220);
|
||||
|
||||
static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar)
|
||||
{
|
||||
u64 par, tmp;
|
||||
@ -298,7 +284,8 @@ static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
|
||||
* resolve the IPA using the AT instruction.
|
||||
*/
|
||||
if (!(esr & ESR_ELx_S1PTW) &&
|
||||
(__check_arm_834220()() || (esr & ESR_ELx_FSC_TYPE) == FSC_PERM)) {
|
||||
(cpus_have_const_cap(ARM64_WORKAROUND_834220) ||
|
||||
(esr & ESR_ELx_FSC_TYPE) == FSC_PERM)) {
|
||||
if (!__translate_far_to_hpfar(far, &hpfar))
|
||||
return false;
|
||||
} else {
|
||||
|
@ -67,10 +67,14 @@ static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm,
|
||||
isb();
|
||||
}
|
||||
|
||||
static hyp_alternate_select(__tlb_switch_to_guest,
|
||||
__tlb_switch_to_guest_nvhe,
|
||||
__tlb_switch_to_guest_vhe,
|
||||
ARM64_HAS_VIRT_HOST_EXTN);
|
||||
static void __hyp_text __tlb_switch_to_guest(struct kvm *kvm,
|
||||
struct tlb_inv_context *cxt)
|
||||
{
|
||||
if (has_vhe())
|
||||
__tlb_switch_to_guest_vhe(kvm, cxt);
|
||||
else
|
||||
__tlb_switch_to_guest_nvhe(kvm, cxt);
|
||||
}
|
||||
|
||||
static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm,
|
||||
struct tlb_inv_context *cxt)
|
||||
@ -98,10 +102,14 @@ static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm,
|
||||
write_sysreg(0, vttbr_el2);
|
||||
}
|
||||
|
||||
static hyp_alternate_select(__tlb_switch_to_host,
|
||||
__tlb_switch_to_host_nvhe,
|
||||
__tlb_switch_to_host_vhe,
|
||||
ARM64_HAS_VIRT_HOST_EXTN);
|
||||
static void __hyp_text __tlb_switch_to_host(struct kvm *kvm,
|
||||
struct tlb_inv_context *cxt)
|
||||
{
|
||||
if (has_vhe())
|
||||
__tlb_switch_to_host_vhe(kvm, cxt);
|
||||
else
|
||||
__tlb_switch_to_host_nvhe(kvm, cxt);
|
||||
}
|
||||
|
||||
void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
|
||||
{
|
||||
@ -111,7 +119,7 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
|
||||
|
||||
/* Switch to requested VMID */
|
||||
kvm = kern_hyp_va(kvm);
|
||||
__tlb_switch_to_guest()(kvm, &cxt);
|
||||
__tlb_switch_to_guest(kvm, &cxt);
|
||||
|
||||
/*
|
||||
* We could do so much better if we had the VA as well.
|
||||
@ -154,7 +162,7 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
|
||||
if (!has_vhe() && icache_is_vpipt())
|
||||
__flush_icache_all();
|
||||
|
||||
__tlb_switch_to_host()(kvm, &cxt);
|
||||
__tlb_switch_to_host(kvm, &cxt);
|
||||
}
|
||||
|
||||
void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
|
||||
@ -165,13 +173,13 @@ void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
|
||||
|
||||
/* Switch to requested VMID */
|
||||
kvm = kern_hyp_va(kvm);
|
||||
__tlb_switch_to_guest()(kvm, &cxt);
|
||||
__tlb_switch_to_guest(kvm, &cxt);
|
||||
|
||||
__tlbi(vmalls12e1is);
|
||||
dsb(ish);
|
||||
isb();
|
||||
|
||||
__tlb_switch_to_host()(kvm, &cxt);
|
||||
__tlb_switch_to_host(kvm, &cxt);
|
||||
}
|
||||
|
||||
void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
|
||||
@ -180,13 +188,13 @@ void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
|
||||
struct tlb_inv_context cxt;
|
||||
|
||||
/* Switch to requested VMID */
|
||||
__tlb_switch_to_guest()(kvm, &cxt);
|
||||
__tlb_switch_to_guest(kvm, &cxt);
|
||||
|
||||
__tlbi(vmalle1);
|
||||
dsb(nsh);
|
||||
isb();
|
||||
|
||||
__tlb_switch_to_host()(kvm, &cxt);
|
||||
__tlb_switch_to_host(kvm, &cxt);
|
||||
}
|
||||
|
||||
void __hyp_text __kvm_flush_vm_context(void)
|
||||
|
@ -1,4 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
xen-arm-y += $(addprefix ../../arm/xen/, enlighten.o grant-table.o p2m.o mm.o)
|
||||
obj-y := xen-arm.o hypercall.o
|
||||
obj-$(CONFIG_XEN_EFI) += $(addprefix ../../arm/xen/, efi.o)
|
||||
|
@ -5,8 +5,10 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/ptrace.h>
|
||||
|
||||
static int align_enable = 1;
|
||||
static int align_count;
|
||||
static int align_kern_enable = 1;
|
||||
static int align_usr_enable = 1;
|
||||
static int align_kern_count = 0;
|
||||
static int align_usr_count = 0;
|
||||
|
||||
static inline uint32_t get_ptreg(struct pt_regs *regs, uint32_t rx)
|
||||
{
|
||||
@ -32,9 +34,6 @@ static int ldb_asm(uint32_t addr, uint32_t *valp)
|
||||
uint32_t val;
|
||||
int err;
|
||||
|
||||
if (!access_ok((void *)addr, 1))
|
||||
return 1;
|
||||
|
||||
asm volatile (
|
||||
"movi %0, 0\n"
|
||||
"1:\n"
|
||||
@ -67,9 +66,6 @@ static int stb_asm(uint32_t addr, uint32_t val)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!access_ok((void *)addr, 1))
|
||||
return 1;
|
||||
|
||||
asm volatile (
|
||||
"movi %0, 0\n"
|
||||
"1:\n"
|
||||
@ -203,8 +199,6 @@ static int stw_c(struct pt_regs *regs, uint32_t rz, uint32_t addr)
|
||||
if (stb_asm(addr, byte3))
|
||||
return 1;
|
||||
|
||||
align_count++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -226,7 +220,14 @@ void csky_alignment(struct pt_regs *regs)
|
||||
uint32_t addr = 0;
|
||||
|
||||
if (!user_mode(regs))
|
||||
goto kernel_area;
|
||||
|
||||
if (!align_usr_enable) {
|
||||
pr_err("%s user disabled.\n", __func__);
|
||||
goto bad_area;
|
||||
}
|
||||
|
||||
align_usr_count++;
|
||||
|
||||
ret = get_user(tmp, (uint16_t *)instruction_pointer(regs));
|
||||
if (ret) {
|
||||
@ -234,6 +235,19 @@ void csky_alignment(struct pt_regs *regs)
|
||||
goto bad_area;
|
||||
}
|
||||
|
||||
goto good_area;
|
||||
|
||||
kernel_area:
|
||||
if (!align_kern_enable) {
|
||||
pr_err("%s kernel disabled.\n", __func__);
|
||||
goto bad_area;
|
||||
}
|
||||
|
||||
align_kern_count++;
|
||||
|
||||
tmp = *(uint16_t *)instruction_pointer(regs);
|
||||
|
||||
good_area:
|
||||
opcode = (uint32_t)tmp;
|
||||
|
||||
rx = opcode & 0xf;
|
||||
@ -286,18 +300,32 @@ bad_area:
|
||||
force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr);
|
||||
}
|
||||
|
||||
static struct ctl_table alignment_tbl[4] = {
|
||||
static struct ctl_table alignment_tbl[5] = {
|
||||
{
|
||||
.procname = "enable",
|
||||
.data = &align_enable,
|
||||
.maxlen = sizeof(align_enable),
|
||||
.procname = "kernel_enable",
|
||||
.data = &align_kern_enable,
|
||||
.maxlen = sizeof(align_kern_enable),
|
||||
.mode = 0666,
|
||||
.proc_handler = &proc_dointvec
|
||||
},
|
||||
{
|
||||
.procname = "count",
|
||||
.data = &align_count,
|
||||
.maxlen = sizeof(align_count),
|
||||
.procname = "user_enable",
|
||||
.data = &align_usr_enable,
|
||||
.maxlen = sizeof(align_usr_enable),
|
||||
.mode = 0666,
|
||||
.proc_handler = &proc_dointvec
|
||||
},
|
||||
{
|
||||
.procname = "kernel_count",
|
||||
.data = &align_kern_count,
|
||||
.maxlen = sizeof(align_kern_count),
|
||||
.mode = 0666,
|
||||
.proc_handler = &proc_dointvec
|
||||
},
|
||||
{
|
||||
.procname = "user_count",
|
||||
.data = &align_usr_count,
|
||||
.maxlen = sizeof(align_usr_count),
|
||||
.mode = 0666,
|
||||
.proc_handler = &proc_dointvec
|
||||
},
|
||||
|
@ -11,42 +11,66 @@
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/cachectl.h>
|
||||
|
||||
#define PG_dcache_clean PG_arch_1
|
||||
|
||||
void flush_dcache_page(struct page *page)
|
||||
{
|
||||
struct address_space *mapping = page_mapping(page);
|
||||
unsigned long addr;
|
||||
struct address_space *mapping;
|
||||
|
||||
if (mapping && !mapping_mapped(mapping)) {
|
||||
set_bit(PG_arch_1, &(page)->flags);
|
||||
if (page == ZERO_PAGE(0))
|
||||
return;
|
||||
|
||||
mapping = page_mapping_file(page);
|
||||
|
||||
if (mapping && !page_mapcount(page))
|
||||
clear_bit(PG_dcache_clean, &page->flags);
|
||||
else {
|
||||
dcache_wbinv_all();
|
||||
if (mapping)
|
||||
icache_inv_all();
|
||||
set_bit(PG_dcache_clean, &page->flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* We could delay the flush for the !page_mapping case too. But that
|
||||
* case is for exec env/arg pages and those are %99 certainly going to
|
||||
* get faulted into the tlb (and thus flushed) anyways.
|
||||
*/
|
||||
addr = (unsigned long) page_address(page);
|
||||
dcache_wb_range(addr, addr + PAGE_SIZE);
|
||||
}
|
||||
EXPORT_SYMBOL(flush_dcache_page);
|
||||
|
||||
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
|
||||
pte_t *pte)
|
||||
void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
|
||||
pte_t *ptep)
|
||||
{
|
||||
unsigned long addr;
|
||||
unsigned long pfn = pte_pfn(*ptep);
|
||||
struct page *page;
|
||||
unsigned long pfn;
|
||||
|
||||
pfn = pte_pfn(*pte);
|
||||
if (unlikely(!pfn_valid(pfn)))
|
||||
if (!pfn_valid(pfn))
|
||||
return;
|
||||
|
||||
page = pfn_to_page(pfn);
|
||||
addr = (unsigned long) page_address(page);
|
||||
if (page == ZERO_PAGE(0))
|
||||
return;
|
||||
|
||||
if (vma->vm_flags & VM_EXEC ||
|
||||
pages_do_alias(addr, address & PAGE_MASK))
|
||||
cache_wbinv_all();
|
||||
if (!test_and_set_bit(PG_dcache_clean, &page->flags))
|
||||
dcache_wbinv_all();
|
||||
|
||||
clear_bit(PG_arch_1, &(page)->flags);
|
||||
if (page_mapping_file(page)) {
|
||||
if (vma->vm_flags & VM_EXEC)
|
||||
icache_inv_all();
|
||||
}
|
||||
}
|
||||
|
||||
void flush_kernel_dcache_page(struct page *page)
|
||||
{
|
||||
struct address_space *mapping;
|
||||
|
||||
mapping = page_mapping_file(page);
|
||||
|
||||
if (!mapping || mapping_mapped(mapping))
|
||||
dcache_wbinv_all();
|
||||
}
|
||||
EXPORT_SYMBOL(flush_kernel_dcache_page);
|
||||
|
||||
void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
|
||||
unsigned long end)
|
||||
{
|
||||
dcache_wbinv_all();
|
||||
|
||||
if (vma->vm_flags & VM_EXEC)
|
||||
icache_inv_all();
|
||||
}
|
||||
|
@ -4,46 +4,63 @@
|
||||
#ifndef __ABI_CSKY_CACHEFLUSH_H
|
||||
#define __ABI_CSKY_CACHEFLUSH_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/string.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
|
||||
extern void flush_dcache_page(struct page *);
|
||||
|
||||
#define flush_cache_mm(mm) cache_wbinv_all()
|
||||
#define flush_cache_mm(mm) dcache_wbinv_all()
|
||||
#define flush_cache_page(vma, page, pfn) cache_wbinv_all()
|
||||
#define flush_cache_dup_mm(mm) cache_wbinv_all()
|
||||
|
||||
#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
|
||||
extern void flush_kernel_dcache_page(struct page *);
|
||||
|
||||
#define flush_dcache_mmap_lock(mapping) xa_lock_irq(&mapping->i_pages)
|
||||
#define flush_dcache_mmap_unlock(mapping) xa_unlock_irq(&mapping->i_pages)
|
||||
|
||||
static inline void flush_kernel_vmap_range(void *addr, int size)
|
||||
{
|
||||
dcache_wbinv_all();
|
||||
}
|
||||
static inline void invalidate_kernel_vmap_range(void *addr, int size)
|
||||
{
|
||||
dcache_wbinv_all();
|
||||
}
|
||||
|
||||
#define ARCH_HAS_FLUSH_ANON_PAGE
|
||||
static inline void flush_anon_page(struct vm_area_struct *vma,
|
||||
struct page *page, unsigned long vmaddr)
|
||||
{
|
||||
if (PageAnon(page))
|
||||
cache_wbinv_all();
|
||||
}
|
||||
|
||||
/*
|
||||
* if (current_mm != vma->mm) cache_wbinv_range(start, end) will be broken.
|
||||
* Use cache_wbinv_all() here and need to be improved in future.
|
||||
*/
|
||||
#define flush_cache_range(vma, start, end) cache_wbinv_all()
|
||||
#define flush_cache_vmap(start, end) cache_wbinv_range(start, end)
|
||||
#define flush_cache_vunmap(start, end) cache_wbinv_range(start, end)
|
||||
extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
|
||||
#define flush_cache_vmap(start, end) cache_wbinv_all()
|
||||
#define flush_cache_vunmap(start, end) cache_wbinv_all()
|
||||
|
||||
#define flush_icache_page(vma, page) cache_wbinv_all()
|
||||
#define flush_icache_page(vma, page) do {} while (0);
|
||||
#define flush_icache_range(start, end) cache_wbinv_range(start, end)
|
||||
|
||||
#define flush_icache_user_range(vma, pg, adr, len) \
|
||||
cache_wbinv_range(adr, adr + len)
|
||||
#define flush_icache_user_range(vma,page,addr,len) \
|
||||
flush_dcache_page(page)
|
||||
|
||||
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
cache_wbinv_all(); \
|
||||
memcpy(dst, src, len); \
|
||||
cache_wbinv_all(); \
|
||||
} while (0)
|
||||
|
||||
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
|
||||
do { \
|
||||
cache_wbinv_all(); \
|
||||
memcpy(dst, src, len); \
|
||||
cache_wbinv_all(); \
|
||||
} while (0)
|
||||
|
||||
#define flush_dcache_mmap_lock(mapping) do {} while (0)
|
||||
#define flush_dcache_mmap_unlock(mapping) do {} while (0)
|
||||
|
||||
#endif /* __ABI_CSKY_CACHEFLUSH_H */
|
||||
|
@ -1,13 +1,14 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
|
||||
|
||||
extern unsigned long shm_align_mask;
|
||||
#include <asm/shmparam.h>
|
||||
|
||||
extern void flush_dcache_page(struct page *page);
|
||||
|
||||
static inline unsigned long pages_do_alias(unsigned long addr1,
|
||||
unsigned long addr2)
|
||||
{
|
||||
return (addr1 ^ addr2) & shm_align_mask;
|
||||
return (addr1 ^ addr2) & (SHMLBA-1);
|
||||
}
|
||||
|
||||
static inline void clear_user_page(void *addr, unsigned long vaddr,
|
||||
|
@ -9,58 +9,63 @@
|
||||
#include <linux/random.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
unsigned long shm_align_mask = (0x4000 >> 1) - 1; /* Sane caches */
|
||||
#define COLOUR_ALIGN(addr,pgoff) \
|
||||
((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \
|
||||
(((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
|
||||
|
||||
#define COLOUR_ALIGN(addr, pgoff) \
|
||||
((((addr) + shm_align_mask) & ~shm_align_mask) + \
|
||||
(((pgoff) << PAGE_SHIFT) & shm_align_mask))
|
||||
|
||||
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
||||
/*
|
||||
* We need to ensure that shared mappings are correctly aligned to
|
||||
* avoid aliasing issues with VIPT caches. We need to ensure that
|
||||
* a specific page of an object is always mapped at a multiple of
|
||||
* SHMLBA bytes.
|
||||
*
|
||||
* We unconditionally provide this function for all cases.
|
||||
*/
|
||||
unsigned long
|
||||
arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
||||
unsigned long len, unsigned long pgoff, unsigned long flags)
|
||||
{
|
||||
struct vm_area_struct *vmm;
|
||||
int do_color_align;
|
||||
struct mm_struct *mm = current->mm;
|
||||
struct vm_area_struct *vma;
|
||||
int do_align = 0;
|
||||
struct vm_unmapped_area_info info;
|
||||
|
||||
/*
|
||||
* We only need to do colour alignment if either the I or D
|
||||
* caches alias.
|
||||
*/
|
||||
do_align = filp || (flags & MAP_SHARED);
|
||||
|
||||
/*
|
||||
* We enforce the MAP_FIXED case.
|
||||
*/
|
||||
if (flags & MAP_FIXED) {
|
||||
/*
|
||||
* We do not accept a shared mapping if it would violate
|
||||
* cache aliasing constraints.
|
||||
*/
|
||||
if ((flags & MAP_SHARED) &&
|
||||
((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
|
||||
if (flags & MAP_SHARED &&
|
||||
(addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
|
||||
return -EINVAL;
|
||||
return addr;
|
||||
}
|
||||
|
||||
if (len > TASK_SIZE)
|
||||
return -ENOMEM;
|
||||
do_color_align = 0;
|
||||
if (filp || (flags & MAP_SHARED))
|
||||
do_color_align = 1;
|
||||
|
||||
if (addr) {
|
||||
if (do_color_align)
|
||||
if (do_align)
|
||||
addr = COLOUR_ALIGN(addr, pgoff);
|
||||
else
|
||||
addr = PAGE_ALIGN(addr);
|
||||
vmm = find_vma(current->mm, addr);
|
||||
if (TASK_SIZE - len >= addr &&
|
||||
(!vmm || addr + len <= vmm->vm_start))
|
||||
return addr;
|
||||
}
|
||||
addr = TASK_UNMAPPED_BASE;
|
||||
if (do_color_align)
|
||||
addr = COLOUR_ALIGN(addr, pgoff);
|
||||
else
|
||||
addr = PAGE_ALIGN(addr);
|
||||
|
||||
for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
|
||||
/* At this point: (!vmm || addr < vmm->vm_end). */
|
||||
if (TASK_SIZE - len < addr)
|
||||
return -ENOMEM;
|
||||
if (!vmm || addr + len <= vmm->vm_start)
|
||||
vma = find_vma(mm, addr);
|
||||
if (TASK_SIZE - len >= addr &&
|
||||
(!vma || addr + len <= vm_start_gap(vma)))
|
||||
return addr;
|
||||
addr = vmm->vm_end;
|
||||
if (do_color_align)
|
||||
addr = COLOUR_ALIGN(addr, pgoff);
|
||||
}
|
||||
|
||||
info.flags = 0;
|
||||
info.length = len;
|
||||
info.low_limit = mm->mmap_base;
|
||||
info.high_limit = TASK_SIZE;
|
||||
info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
|
||||
info.align_offset = pgoff << PAGE_SHIFT;
|
||||
return vm_unmapped_area(&info);
|
||||
}
|
||||
|
@ -9,11 +9,12 @@
|
||||
#define nop() asm volatile ("nop\n":::"memory")
|
||||
|
||||
/*
|
||||
* sync: completion barrier
|
||||
* sync.s: completion barrier and shareable to other cores
|
||||
* sync.i: completion barrier with flush cpu pipeline
|
||||
* sync.is: completion barrier with flush cpu pipeline and shareable to
|
||||
* other cores
|
||||
* sync: completion barrier, all sync.xx instructions
|
||||
* guarantee the last response recieved by bus transaction
|
||||
* made by ld/st instructions before sync.s
|
||||
* sync.s: inherit from sync, but also shareable to other cores
|
||||
* sync.i: inherit from sync, but also flush cpu pipeline
|
||||
* sync.is: the same with sync.i + sync.s
|
||||
*
|
||||
* bar.brwarw: ordering barrier for all load/store instructions before it
|
||||
* bar.brwarws: ordering barrier for all load/store instructions before it
|
||||
@ -27,9 +28,7 @@
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_CACHEV2
|
||||
#define mb() asm volatile ("bar.brwarw\n":::"memory")
|
||||
#define rmb() asm volatile ("bar.brar\n":::"memory")
|
||||
#define wmb() asm volatile ("bar.bwaw\n":::"memory")
|
||||
#define mb() asm volatile ("sync.s\n":::"memory")
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define __smp_mb() asm volatile ("bar.brwarws\n":::"memory")
|
||||
|
@ -24,6 +24,7 @@ void cache_wbinv_range(unsigned long start, unsigned long end);
|
||||
void cache_wbinv_all(void);
|
||||
|
||||
void dma_wbinv_range(unsigned long start, unsigned long end);
|
||||
void dma_inv_range(unsigned long start, unsigned long end);
|
||||
void dma_wb_range(unsigned long start, unsigned long end);
|
||||
|
||||
#endif
|
||||
|
@ -4,17 +4,10 @@
|
||||
#ifndef __ASM_CSKY_IO_H
|
||||
#define __ASM_CSKY_IO_H
|
||||
|
||||
#include <abi/pgtable-bits.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
extern void __iomem *ioremap(phys_addr_t offset, size_t size);
|
||||
|
||||
extern void iounmap(void *addr);
|
||||
|
||||
extern int remap_area_pages(unsigned long address, phys_addr_t phys_addr,
|
||||
size_t size, unsigned long flags);
|
||||
|
||||
/*
|
||||
* I/O memory access primitives. Reads are ordered relative to any
|
||||
* following Normal memory access. Writes are ordered relative to any prior
|
||||
@ -40,9 +33,17 @@ extern int remap_area_pages(unsigned long address, phys_addr_t phys_addr,
|
||||
#define writel(v,c) ({ wmb(); writel_relaxed((v),(c)); mb(); })
|
||||
#endif
|
||||
|
||||
#define ioremap_nocache(phy, sz) ioremap(phy, sz)
|
||||
#define ioremap_wc ioremap_nocache
|
||||
#define ioremap_wt ioremap_nocache
|
||||
/*
|
||||
* I/O memory mapping functions.
|
||||
*/
|
||||
extern void __iomem *ioremap_cache(phys_addr_t addr, size_t size);
|
||||
extern void __iomem *__ioremap(phys_addr_t addr, size_t size, pgprot_t prot);
|
||||
extern void iounmap(void *addr);
|
||||
|
||||
#define ioremap(addr, size) __ioremap((addr), (size), pgprot_noncached(PAGE_KERNEL))
|
||||
#define ioremap_wc(addr, size) __ioremap((addr), (size), pgprot_writecombine(PAGE_KERNEL))
|
||||
#define ioremap_nocache(addr, size) ioremap((addr), (size))
|
||||
#define ioremap_cache ioremap_cache
|
||||
|
||||
#include <asm-generic/io.h>
|
||||
|
||||
|
@ -258,6 +258,16 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot)
|
||||
{
|
||||
unsigned long prot = pgprot_val(_prot);
|
||||
|
||||
prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED | _PAGE_SO;
|
||||
|
||||
return __pgprot(prot);
|
||||
}
|
||||
|
||||
#define pgprot_writecombine pgprot_writecombine
|
||||
static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
|
||||
{
|
||||
unsigned long prot = pgprot_val(_prot);
|
||||
|
||||
prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
|
||||
|
||||
return __pgprot(prot);
|
||||
|
@ -17,6 +17,12 @@
|
||||
#define PTE_INDX_SHIFT 10
|
||||
#define _PGDIR_SHIFT 22
|
||||
|
||||
.macro zero_fp
|
||||
#ifdef CONFIG_STACKTRACE
|
||||
movi r8, 0
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro tlbop_begin name, val0, val1, val2
|
||||
ENTRY(csky_\name)
|
||||
mtcr a3, ss2
|
||||
@ -96,6 +102,7 @@ ENTRY(csky_\name)
|
||||
SAVE_ALL 0
|
||||
.endm
|
||||
.macro tlbop_end is_write
|
||||
zero_fp
|
||||
RD_MEH a2
|
||||
psrset ee, ie
|
||||
mov a0, sp
|
||||
@ -120,6 +127,7 @@ tlbop_end 1
|
||||
|
||||
ENTRY(csky_systemcall)
|
||||
SAVE_ALL TRAP0_SIZE
|
||||
zero_fp
|
||||
|
||||
psrset ee, ie
|
||||
|
||||
@ -136,9 +144,9 @@ ENTRY(csky_systemcall)
|
||||
mov r9, sp
|
||||
bmaski r10, THREAD_SHIFT
|
||||
andn r9, r10
|
||||
ldw r8, (r9, TINFO_FLAGS)
|
||||
ANDI_R3 r8, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)
|
||||
cmpnei r8, 0
|
||||
ldw r12, (r9, TINFO_FLAGS)
|
||||
ANDI_R3 r12, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)
|
||||
cmpnei r12, 0
|
||||
bt csky_syscall_trace
|
||||
#if defined(__CSKYABIV2__)
|
||||
subi sp, 8
|
||||
@ -180,7 +188,7 @@ csky_syscall_trace:
|
||||
|
||||
ENTRY(ret_from_kernel_thread)
|
||||
jbsr schedule_tail
|
||||
mov a0, r8
|
||||
mov a0, r10
|
||||
jsr r9
|
||||
jbsr ret_from_exception
|
||||
|
||||
@ -189,9 +197,9 @@ ENTRY(ret_from_fork)
|
||||
mov r9, sp
|
||||
bmaski r10, THREAD_SHIFT
|
||||
andn r9, r10
|
||||
ldw r8, (r9, TINFO_FLAGS)
|
||||
ANDI_R3 r8, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)
|
||||
cmpnei r8, 0
|
||||
ldw r12, (r9, TINFO_FLAGS)
|
||||
ANDI_R3 r12, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)
|
||||
cmpnei r12, 0
|
||||
bf ret_from_exception
|
||||
mov a0, sp /* sp = pt_regs pointer */
|
||||
jbsr syscall_trace_exit
|
||||
@ -209,9 +217,9 @@ ret_from_exception:
|
||||
bmaski r10, THREAD_SHIFT
|
||||
andn r9, r10
|
||||
|
||||
ldw r8, (r9, TINFO_FLAGS)
|
||||
andi r8, (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED)
|
||||
cmpnei r8, 0
|
||||
ldw r12, (r9, TINFO_FLAGS)
|
||||
andi r12, (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED)
|
||||
cmpnei r12, 0
|
||||
bt exit_work
|
||||
1:
|
||||
RESTORE_ALL
|
||||
@ -220,11 +228,11 @@ exit_work:
|
||||
lrw syscallid, ret_from_exception
|
||||
mov lr, syscallid
|
||||
|
||||
btsti r8, TIF_NEED_RESCHED
|
||||
btsti r12, TIF_NEED_RESCHED
|
||||
bt work_resched
|
||||
|
||||
mov a0, sp
|
||||
mov a1, r8
|
||||
mov a1, r12
|
||||
jmpi do_notify_resume
|
||||
|
||||
work_resched:
|
||||
@ -232,6 +240,7 @@ work_resched:
|
||||
|
||||
ENTRY(csky_trap)
|
||||
SAVE_ALL 0
|
||||
zero_fp
|
||||
psrset ee
|
||||
mov a0, sp /* Push Stack pointer arg */
|
||||
jbsr trap_c /* Call C-level trap handler */
|
||||
@ -265,6 +274,7 @@ ENTRY(csky_get_tls)
|
||||
|
||||
ENTRY(csky_irq)
|
||||
SAVE_ALL 0
|
||||
zero_fp
|
||||
psrset ee
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
@ -276,27 +286,23 @@ ENTRY(csky_irq)
|
||||
* Get task_struct->stack.preempt_count for current,
|
||||
* and increase 1.
|
||||
*/
|
||||
ldw r8, (r9, TINFO_PREEMPT)
|
||||
addi r8, 1
|
||||
stw r8, (r9, TINFO_PREEMPT)
|
||||
ldw r12, (r9, TINFO_PREEMPT)
|
||||
addi r12, 1
|
||||
stw r12, (r9, TINFO_PREEMPT)
|
||||
#endif
|
||||
|
||||
mov a0, sp
|
||||
jbsr csky_do_IRQ
|
||||
|
||||
#ifdef CONFIG_PREEMPT
|
||||
subi r8, 1
|
||||
stw r8, (r9, TINFO_PREEMPT)
|
||||
cmpnei r8, 0
|
||||
subi r12, 1
|
||||
stw r12, (r9, TINFO_PREEMPT)
|
||||
cmpnei r12, 0
|
||||
bt 2f
|
||||
ldw r8, (r9, TINFO_FLAGS)
|
||||
btsti r8, TIF_NEED_RESCHED
|
||||
ldw r12, (r9, TINFO_FLAGS)
|
||||
btsti r12, TIF_NEED_RESCHED
|
||||
bf 2f
|
||||
1:
|
||||
jbsr preempt_schedule_irq /* irq en/disable is done inside */
|
||||
ldw r7, (r9, TINFO_FLAGS) /* get new tasks TI_FLAGS */
|
||||
btsti r7, TIF_NEED_RESCHED
|
||||
bt 1b /* go again */
|
||||
#endif
|
||||
2:
|
||||
jmpi ret_from_exception
|
||||
|
@ -1306,7 +1306,7 @@ int csky_pmu_device_probe(struct platform_device *pdev,
|
||||
&csky_pmu.count_width)) {
|
||||
csky_pmu.count_width = DEFAULT_COUNT_WIDTH;
|
||||
}
|
||||
csky_pmu.max_period = BIT(csky_pmu.count_width) - 1;
|
||||
csky_pmu.max_period = BIT_ULL(csky_pmu.count_width) - 1;
|
||||
|
||||
csky_pmu.plat_device = pdev;
|
||||
|
||||
@ -1337,7 +1337,7 @@ int csky_pmu_device_probe(struct platform_device *pdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
const static struct of_device_id csky_pmu_of_device_ids[] = {
|
||||
static const struct of_device_id csky_pmu_of_device_ids[] = {
|
||||
{.compatible = "csky,csky-pmu"},
|
||||
{},
|
||||
};
|
||||
|
@ -55,7 +55,7 @@ int copy_thread(unsigned long clone_flags,
|
||||
if (unlikely(p->flags & PF_KTHREAD)) {
|
||||
memset(childregs, 0, sizeof(struct pt_regs));
|
||||
childstack->r15 = (unsigned long) ret_from_kernel_thread;
|
||||
childstack->r8 = kthread_arg;
|
||||
childstack->r10 = kthread_arg;
|
||||
childstack->r9 = usp;
|
||||
childregs->sr = mfcr("psr");
|
||||
} else {
|
||||
|
@ -120,7 +120,12 @@ void dma_wbinv_range(unsigned long start, unsigned long end)
|
||||
cache_op_range(start, end, DATA_CACHE|CACHE_CLR|CACHE_INV, 1);
|
||||
}
|
||||
|
||||
void dma_inv_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
cache_op_range(start, end, DATA_CACHE|CACHE_CLR|CACHE_INV, 1);
|
||||
}
|
||||
|
||||
void dma_wb_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
cache_op_range(start, end, DATA_CACHE|CACHE_INV, 1);
|
||||
cache_op_range(start, end, DATA_CACHE|CACHE_CLR|CACHE_INV, 1);
|
||||
}
|
||||
|
@ -69,11 +69,20 @@ void dma_wbinv_range(unsigned long start, unsigned long end)
|
||||
sync_is();
|
||||
}
|
||||
|
||||
void dma_inv_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
unsigned long i = start & ~(L1_CACHE_BYTES - 1);
|
||||
|
||||
for (; i < end; i += L1_CACHE_BYTES)
|
||||
asm volatile("dcache.iva %0\n"::"r"(i):"memory");
|
||||
sync_is();
|
||||
}
|
||||
|
||||
void dma_wb_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
unsigned long i = start & ~(L1_CACHE_BYTES - 1);
|
||||
|
||||
for (; i < end; i += L1_CACHE_BYTES)
|
||||
asm volatile("dcache.civa %0\n"::"r"(i):"memory");
|
||||
asm volatile("dcache.cva %0\n"::"r"(i):"memory");
|
||||
sync_is();
|
||||
}
|
||||
|
@ -14,69 +14,50 @@
|
||||
#include <linux/version.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
void arch_dma_prep_coherent(struct page *page, size_t size)
|
||||
{
|
||||
if (PageHighMem(page)) {
|
||||
unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
|
||||
|
||||
do {
|
||||
void *ptr = kmap_atomic(page);
|
||||
size_t _size = (size < PAGE_SIZE) ? size : PAGE_SIZE;
|
||||
|
||||
memset(ptr, 0, _size);
|
||||
dma_wbinv_range((unsigned long)ptr,
|
||||
(unsigned long)ptr + _size);
|
||||
|
||||
kunmap_atomic(ptr);
|
||||
|
||||
page++;
|
||||
size -= PAGE_SIZE;
|
||||
count--;
|
||||
} while (count);
|
||||
} else {
|
||||
void *ptr = page_address(page);
|
||||
|
||||
memset(ptr, 0, size);
|
||||
dma_wbinv_range((unsigned long)ptr, (unsigned long)ptr + size);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cache_op(phys_addr_t paddr, size_t size,
|
||||
void (*fn)(unsigned long start, unsigned long end))
|
||||
{
|
||||
struct page *page = pfn_to_page(paddr >> PAGE_SHIFT);
|
||||
unsigned int offset = paddr & ~PAGE_MASK;
|
||||
size_t left = size;
|
||||
unsigned long start;
|
||||
struct page *page = phys_to_page(paddr);
|
||||
void *start = __va(page_to_phys(page));
|
||||
unsigned long offset = offset_in_page(paddr);
|
||||
size_t left = size;
|
||||
|
||||
do {
|
||||
size_t len = left;
|
||||
|
||||
if (offset + len > PAGE_SIZE)
|
||||
len = PAGE_SIZE - offset;
|
||||
|
||||
if (PageHighMem(page)) {
|
||||
void *addr;
|
||||
start = kmap_atomic(page);
|
||||
|
||||
if (offset + len > PAGE_SIZE) {
|
||||
if (offset >= PAGE_SIZE) {
|
||||
page += offset >> PAGE_SHIFT;
|
||||
offset &= ~PAGE_MASK;
|
||||
}
|
||||
len = PAGE_SIZE - offset;
|
||||
}
|
||||
fn((unsigned long)start + offset,
|
||||
(unsigned long)start + offset + len);
|
||||
|
||||
addr = kmap_atomic(page);
|
||||
start = (unsigned long)(addr + offset);
|
||||
fn(start, start + len);
|
||||
kunmap_atomic(addr);
|
||||
kunmap_atomic(start);
|
||||
} else {
|
||||
start = (unsigned long)phys_to_virt(paddr);
|
||||
fn(start, start + size);
|
||||
fn((unsigned long)start + offset,
|
||||
(unsigned long)start + offset + len);
|
||||
}
|
||||
offset = 0;
|
||||
|
||||
page++;
|
||||
start += PAGE_SIZE;
|
||||
left -= len;
|
||||
} while (left);
|
||||
}
|
||||
|
||||
static void dma_wbinv_set_zero_range(unsigned long start, unsigned long end)
|
||||
{
|
||||
memset((void *)start, 0, end - start);
|
||||
dma_wbinv_range(start, end);
|
||||
}
|
||||
|
||||
void arch_dma_prep_coherent(struct page *page, size_t size)
|
||||
{
|
||||
cache_op(page_to_phys(page), size, dma_wbinv_set_zero_range);
|
||||
}
|
||||
|
||||
void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
|
||||
size_t size, enum dma_data_direction dir)
|
||||
{
|
||||
@ -98,11 +79,10 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
|
||||
{
|
||||
switch (dir) {
|
||||
case DMA_TO_DEVICE:
|
||||
cache_op(paddr, size, dma_wb_range);
|
||||
break;
|
||||
return;
|
||||
case DMA_FROM_DEVICE:
|
||||
case DMA_BIDIRECTIONAL:
|
||||
cache_op(paddr, size, dma_wbinv_range);
|
||||
cache_op(paddr, size, dma_inv_range);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
@ -60,22 +60,6 @@ void __init mem_init(void)
|
||||
mem_init_print_info(NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
void free_initrd_mem(unsigned long start, unsigned long end)
|
||||
{
|
||||
if (start < end)
|
||||
pr_info("Freeing initrd memory: %ldk freed\n",
|
||||
(end - start) >> 10);
|
||||
|
||||
for (; start < end; start += PAGE_SIZE) {
|
||||
ClearPageReserved(virt_to_page(start));
|
||||
init_page_count(virt_to_page(start));
|
||||
free_page(start);
|
||||
totalram_pages_inc();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
extern char __init_begin[], __init_end[];
|
||||
|
||||
void free_initmem(void)
|
||||
|
@ -8,12 +8,12 @@
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
void __iomem *ioremap(phys_addr_t addr, size_t size)
|
||||
static void __iomem *__ioremap_caller(phys_addr_t addr, size_t size,
|
||||
pgprot_t prot, void *caller)
|
||||
{
|
||||
phys_addr_t last_addr;
|
||||
unsigned long offset, vaddr;
|
||||
struct vm_struct *area;
|
||||
pgprot_t prot;
|
||||
|
||||
last_addr = addr + size - 1;
|
||||
if (!size || last_addr < addr)
|
||||
@ -23,15 +23,12 @@ void __iomem *ioremap(phys_addr_t addr, size_t size)
|
||||
addr &= PAGE_MASK;
|
||||
size = PAGE_ALIGN(size + offset);
|
||||
|
||||
area = get_vm_area_caller(size, VM_ALLOC, __builtin_return_address(0));
|
||||
area = get_vm_area_caller(size, VM_IOREMAP, caller);
|
||||
if (!area)
|
||||
return NULL;
|
||||
|
||||
vaddr = (unsigned long)area->addr;
|
||||
|
||||
prot = __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE |
|
||||
_PAGE_GLOBAL | _CACHE_UNCACHED | _PAGE_SO);
|
||||
|
||||
if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
|
||||
free_vm_area(area);
|
||||
return NULL;
|
||||
@ -39,7 +36,20 @@ void __iomem *ioremap(phys_addr_t addr, size_t size)
|
||||
|
||||
return (void __iomem *)(vaddr + offset);
|
||||
}
|
||||
EXPORT_SYMBOL(ioremap);
|
||||
|
||||
void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot)
|
||||
{
|
||||
return __ioremap_caller(phys_addr, size, prot,
|
||||
__builtin_return_address(0));
|
||||
}
|
||||
EXPORT_SYMBOL(__ioremap);
|
||||
|
||||
void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size)
|
||||
{
|
||||
return __ioremap_caller(phys_addr, size, PAGE_KERNEL,
|
||||
__builtin_return_address(0));
|
||||
}
|
||||
EXPORT_SYMBOL(ioremap_cache);
|
||||
|
||||
void iounmap(void __iomem *addr)
|
||||
{
|
||||
@ -51,10 +61,9 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
|
||||
unsigned long size, pgprot_t vma_prot)
|
||||
{
|
||||
if (!pfn_valid(pfn)) {
|
||||
vma_prot.pgprot |= _PAGE_SO;
|
||||
return pgprot_noncached(vma_prot);
|
||||
} else if (file->f_flags & O_SYNC) {
|
||||
return pgprot_noncached(vma_prot);
|
||||
return pgprot_writecombine(vma_prot);
|
||||
}
|
||||
|
||||
return vma_prot;
|
||||
|
@ -99,7 +99,7 @@
|
||||
|
||||
miscintc: interrupt-controller@18060010 {
|
||||
compatible = "qca,ar7240-misc-intc";
|
||||
reg = <0x18060010 0x4>;
|
||||
reg = <0x18060010 0x8>;
|
||||
|
||||
interrupt-parent = <&cpuintc>;
|
||||
interrupts = <6>;
|
||||
|
@ -160,7 +160,6 @@ void __init prom_meminit(void)
|
||||
|
||||
void __init prom_free_prom_memory(void)
|
||||
{
|
||||
unsigned long addr;
|
||||
int i;
|
||||
|
||||
if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <asm/octeon/octeon-feature.h>
|
||||
|
||||
#include <asm/octeon/cvmx-ipd-defs.h>
|
||||
#include <asm/octeon/cvmx-pip-defs.h>
|
||||
|
||||
enum cvmx_ipd_mode {
|
||||
CVMX_IPD_OPC_MODE_STT = 0LL, /* All blocks DRAM, not cached in L2 */
|
||||
|
@ -52,6 +52,7 @@
|
||||
# endif
|
||||
#define __ARCH_WANT_SYS_FORK
|
||||
#define __ARCH_WANT_SYS_CLONE
|
||||
#define __ARCH_WANT_SYS_CLONE3
|
||||
|
||||
/* whitelists for checksyscalls */
|
||||
#define __IGNORE_fadvise64_64
|
||||
|
@ -24,7 +24,8 @@ static char r4kwar[] __initdata =
|
||||
static char daddiwar[] __initdata =
|
||||
"Enable CPU_DADDI_WORKAROUNDS to rectify.";
|
||||
|
||||
static inline void align_mod(const int align, const int mod)
|
||||
static __always_inline __init
|
||||
void align_mod(const int align, const int mod)
|
||||
{
|
||||
asm volatile(
|
||||
".set push\n\t"
|
||||
@ -38,8 +39,9 @@ static inline void align_mod(const int align, const int mod)
|
||||
: "n"(align), "n"(mod));
|
||||
}
|
||||
|
||||
static __always_inline void mult_sh_align_mod(long *v1, long *v2, long *w,
|
||||
const int align, const int mod)
|
||||
static __always_inline __init
|
||||
void mult_sh_align_mod(long *v1, long *v2, long *w,
|
||||
const int align, const int mod)
|
||||
{
|
||||
unsigned long flags;
|
||||
int m1, m2;
|
||||
@ -113,7 +115,7 @@ static __always_inline void mult_sh_align_mod(long *v1, long *v2, long *w,
|
||||
*w = lw;
|
||||
}
|
||||
|
||||
static inline void check_mult_sh(void)
|
||||
static __always_inline __init void check_mult_sh(void)
|
||||
{
|
||||
long v1[8], v2[8], w[8];
|
||||
int bug, fix, i;
|
||||
@ -176,7 +178,7 @@ asmlinkage void __init do_daddi_ov(struct pt_regs *regs)
|
||||
exception_exit(prev_state);
|
||||
}
|
||||
|
||||
static inline void check_daddi(void)
|
||||
static __init void check_daddi(void)
|
||||
{
|
||||
extern asmlinkage void handle_daddi_ov(void);
|
||||
unsigned long flags;
|
||||
@ -242,7 +244,7 @@ static inline void check_daddi(void)
|
||||
|
||||
int daddiu_bug = IS_ENABLED(CONFIG_CPU_MIPSR6) ? 0 : -1;
|
||||
|
||||
static inline void check_daddiu(void)
|
||||
static __init void check_daddiu(void)
|
||||
{
|
||||
long v, w, tmp;
|
||||
|
||||
|
@ -108,6 +108,9 @@ void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
|
||||
return;
|
||||
}
|
||||
|
||||
if (start < PHYS_OFFSET)
|
||||
return;
|
||||
|
||||
memblock_add(start, size);
|
||||
/* Reserve any memory except the ordinary RAM ranges. */
|
||||
switch (type) {
|
||||
@ -321,7 +324,7 @@ static void __init bootmem_init(void)
|
||||
* Reserve any memory between the start of RAM and PHYS_OFFSET
|
||||
*/
|
||||
if (ramstart > PHYS_OFFSET)
|
||||
memblock_reserve(PHYS_OFFSET, PFN_UP(ramstart) - PHYS_OFFSET);
|
||||
memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET);
|
||||
|
||||
if (PFN_UP(ramstart) > ARCH_PFN_OFFSET) {
|
||||
pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
|
||||
|
@ -80,6 +80,7 @@ SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len,
|
||||
|
||||
save_static_function(sys_fork);
|
||||
save_static_function(sys_clone);
|
||||
save_static_function(sys_clone3);
|
||||
|
||||
SYSCALL_DEFINE1(set_thread_area, unsigned long, addr)
|
||||
{
|
||||
|
@ -373,4 +373,4 @@
|
||||
432 n32 fsmount sys_fsmount
|
||||
433 n32 fspick sys_fspick
|
||||
434 n32 pidfd_open sys_pidfd_open
|
||||
# 435 reserved for clone3
|
||||
435 n32 clone3 __sys_clone3
|
||||
|
@ -349,4 +349,4 @@
|
||||
432 n64 fsmount sys_fsmount
|
||||
433 n64 fspick sys_fspick
|
||||
434 n64 pidfd_open sys_pidfd_open
|
||||
# 435 reserved for clone3
|
||||
435 n64 clone3 __sys_clone3
|
||||
|
@ -422,4 +422,4 @@
|
||||
432 o32 fsmount sys_fsmount
|
||||
433 o32 fspick sys_fspick
|
||||
434 o32 pidfd_open sys_pidfd_open
|
||||
# 435 reserved for clone3
|
||||
435 o32 clone3 __sys_clone3
|
||||
|
@ -3,6 +3,7 @@
|
||||
*/
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/bootinfo.h>
|
||||
@ -64,24 +65,22 @@ void __init prom_init_memory(void)
|
||||
node_id = loongson_memmap->map[i].node_id;
|
||||
mem_type = loongson_memmap->map[i].mem_type;
|
||||
|
||||
if (node_id == 0) {
|
||||
switch (mem_type) {
|
||||
case SYSTEM_RAM_LOW:
|
||||
add_memory_region(loongson_memmap->map[i].mem_start,
|
||||
(u64)loongson_memmap->map[i].mem_size << 20,
|
||||
BOOT_MEM_RAM);
|
||||
break;
|
||||
case SYSTEM_RAM_HIGH:
|
||||
add_memory_region(loongson_memmap->map[i].mem_start,
|
||||
(u64)loongson_memmap->map[i].mem_size << 20,
|
||||
BOOT_MEM_RAM);
|
||||
break;
|
||||
case SYSTEM_RAM_RESERVED:
|
||||
add_memory_region(loongson_memmap->map[i].mem_start,
|
||||
(u64)loongson_memmap->map[i].mem_size << 20,
|
||||
BOOT_MEM_RESERVED);
|
||||
break;
|
||||
}
|
||||
if (node_id != 0)
|
||||
continue;
|
||||
|
||||
switch (mem_type) {
|
||||
case SYSTEM_RAM_LOW:
|
||||
memblock_add(loongson_memmap->map[i].mem_start,
|
||||
(u64)loongson_memmap->map[i].mem_size << 20);
|
||||
break;
|
||||
case SYSTEM_RAM_HIGH:
|
||||
memblock_add(loongson_memmap->map[i].mem_start,
|
||||
(u64)loongson_memmap->map[i].mem_size << 20);
|
||||
break;
|
||||
case SYSTEM_RAM_RESERVED:
|
||||
memblock_reserve(loongson_memmap->map[i].mem_start,
|
||||
(u64)loongson_memmap->map[i].mem_size << 20);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ static int __init serial_init(void)
|
||||
}
|
||||
module_init(serial_init);
|
||||
|
||||
static void __init serial_exit(void)
|
||||
static void __exit serial_exit(void)
|
||||
{
|
||||
platform_device_unregister(&uart8250_device);
|
||||
}
|
||||
|
@ -142,8 +142,6 @@ static void __init szmem(unsigned int node)
|
||||
(u32)node_id, mem_type, mem_start, mem_size);
|
||||
pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n",
|
||||
start_pfn, end_pfn, num_physpages);
|
||||
add_memory_region((node_id << 44) + mem_start,
|
||||
(u64)mem_size << 20, BOOT_MEM_RAM);
|
||||
memblock_add_node(PFN_PHYS(start_pfn),
|
||||
PFN_PHYS(end_pfn - start_pfn), node);
|
||||
break;
|
||||
@ -156,16 +154,12 @@ static void __init szmem(unsigned int node)
|
||||
(u32)node_id, mem_type, mem_start, mem_size);
|
||||
pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n",
|
||||
start_pfn, end_pfn, num_physpages);
|
||||
add_memory_region((node_id << 44) + mem_start,
|
||||
(u64)mem_size << 20, BOOT_MEM_RAM);
|
||||
memblock_add_node(PFN_PHYS(start_pfn),
|
||||
PFN_PHYS(end_pfn - start_pfn), node);
|
||||
break;
|
||||
case SYSTEM_RAM_RESERVED:
|
||||
pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n",
|
||||
(u32)node_id, mem_type, mem_start, mem_size);
|
||||
add_memory_region((node_id << 44) + mem_start,
|
||||
(u64)mem_size << 20, BOOT_MEM_RESERVED);
|
||||
memblock_reserve(((node_id << 44) + mem_start),
|
||||
mem_size << 20);
|
||||
break;
|
||||
@ -191,8 +185,6 @@ static void __init node_mem_init(unsigned int node)
|
||||
NODE_DATA(node)->node_start_pfn = start_pfn;
|
||||
NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn;
|
||||
|
||||
free_bootmem_with_active_regions(node, end_pfn);
|
||||
|
||||
if (node == 0) {
|
||||
/* kernel end address */
|
||||
unsigned long kernel_end_pfn = PFN_UP(__pa_symbol(&_end));
|
||||
@ -209,8 +201,6 @@ static void __init node_mem_init(unsigned int node)
|
||||
memblock_reserve((node_addrspace_offset | 0xfe000000),
|
||||
32 << 20);
|
||||
}
|
||||
|
||||
sparse_memory_present_with_active_regions(node);
|
||||
}
|
||||
|
||||
static __init void prom_meminit(void)
|
||||
@ -227,6 +217,7 @@ static __init void prom_meminit(void)
|
||||
cpumask_clear(&__node_data[(node)]->cpumask);
|
||||
}
|
||||
}
|
||||
memblocks_present();
|
||||
max_low_pfn = PHYS_PFN(memblock_end_of_DRAM());
|
||||
|
||||
for (cpu = 0; cpu < loongson_sysconf.nr_cpus; cpu++) {
|
||||
|
@ -61,6 +61,7 @@ int init_debug = 1;
|
||||
/* memory blocks */
|
||||
struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
|
||||
|
||||
#define MAX_PROM_MEM 5
|
||||
static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
|
||||
static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
|
||||
static unsigned int nr_prom_mem __initdata;
|
||||
@ -358,7 +359,7 @@ void __init prom_meminit(void)
|
||||
p++;
|
||||
|
||||
if (type == BOOT_MEM_ROM_DATA) {
|
||||
if (nr_prom_mem >= 5) {
|
||||
if (nr_prom_mem >= MAX_PROM_MEM) {
|
||||
pr_err("Too many ROM DATA regions");
|
||||
continue;
|
||||
}
|
||||
@ -377,7 +378,6 @@ void __init prom_free_prom_memory(void)
|
||||
char *ptr;
|
||||
int len = 0;
|
||||
int i;
|
||||
unsigned long addr;
|
||||
|
||||
/*
|
||||
* preserve environment variables and command line from pmon/bbload
|
||||
|
@ -59,7 +59,7 @@ CFLAGS_REMOVE_vgettimeofday.o = -pg
|
||||
ifndef CONFIG_CPU_MIPSR6
|
||||
ifeq ($(call ld-ifversion, -lt, 225000000, y),y)
|
||||
$(warning MIPS VDSO requires binutils >= 2.25)
|
||||
obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y))
|
||||
obj-vdso-y := $(filter-out vgettimeofday.o, $(obj-vdso-y))
|
||||
ccflags-vdso += -DDISABLE_MIPS_VDSO
|
||||
endif
|
||||
endif
|
||||
|
@ -1,269 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (C) 2015 Imagination Technologies
|
||||
* Author: Alex Smith <alex.smith@imgtec.com>
|
||||
*/
|
||||
|
||||
#include "vdso.h"
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include <asm/clocksource.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/vdso.h>
|
||||
|
||||
#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
|
||||
|
||||
static __always_inline long gettimeofday_fallback(struct timeval *_tv,
|
||||
struct timezone *_tz)
|
||||
{
|
||||
register struct timezone *tz asm("a1") = _tz;
|
||||
register struct timeval *tv asm("a0") = _tv;
|
||||
register long ret asm("v0");
|
||||
register long nr asm("v0") = __NR_gettimeofday;
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (tv), "r" (tz), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static __always_inline long clock_gettime_fallback(clockid_t _clkid,
|
||||
struct timespec *_ts)
|
||||
{
|
||||
register struct timespec *ts asm("a1") = _ts;
|
||||
register clockid_t clkid asm("a0") = _clkid;
|
||||
register long ret asm("v0");
|
||||
register long nr asm("v0") = __NR_clock_gettime;
|
||||
register long error asm("a3");
|
||||
|
||||
asm volatile(
|
||||
" syscall\n"
|
||||
: "=r" (ret), "=r" (error)
|
||||
: "r" (clkid), "r" (ts), "r" (nr)
|
||||
: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
|
||||
"$14", "$15", "$24", "$25", "hi", "lo", "memory");
|
||||
|
||||
return error ? -ret : ret;
|
||||
}
|
||||
|
||||
static __always_inline int do_realtime_coarse(struct timespec *ts,
|
||||
const union mips_vdso_data *data)
|
||||
{
|
||||
u32 start_seq;
|
||||
|
||||
do {
|
||||
start_seq = vdso_data_read_begin(data);
|
||||
|
||||
ts->tv_sec = data->xtime_sec;
|
||||
ts->tv_nsec = data->xtime_nsec >> data->cs_shift;
|
||||
} while (vdso_data_read_retry(data, start_seq));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __always_inline int do_monotonic_coarse(struct timespec *ts,
|
||||
const union mips_vdso_data *data)
|
||||
{
|
||||
u32 start_seq;
|
||||
u64 to_mono_sec;
|
||||
u64 to_mono_nsec;
|
||||
|
||||
do {
|
||||
start_seq = vdso_data_read_begin(data);
|
||||
|
||||
ts->tv_sec = data->xtime_sec;
|
||||
ts->tv_nsec = data->xtime_nsec >> data->cs_shift;
|
||||
|
||||
to_mono_sec = data->wall_to_mono_sec;
|
||||
to_mono_nsec = data->wall_to_mono_nsec;
|
||||
} while (vdso_data_read_retry(data, start_seq));
|
||||
|
||||
ts->tv_sec += to_mono_sec;
|
||||
timespec_add_ns(ts, to_mono_nsec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CSRC_R4K
|
||||
|
||||
static __always_inline u64 read_r4k_count(void)
|
||||
{
|
||||
unsigned int count;
|
||||
|
||||
__asm__ __volatile__(
|
||||
" .set push\n"
|
||||
" .set mips32r2\n"
|
||||
" rdhwr %0, $2\n"
|
||||
" .set pop\n"
|
||||
: "=r" (count));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CLKSRC_MIPS_GIC
|
||||
|
||||
static __always_inline u64 read_gic_count(const union mips_vdso_data *data)
|
||||
{
|
||||
void __iomem *gic = get_gic(data);
|
||||
u32 hi, hi2, lo;
|
||||
|
||||
do {
|
||||
hi = __raw_readl(gic + sizeof(lo));
|
||||
lo = __raw_readl(gic);
|
||||
hi2 = __raw_readl(gic + sizeof(lo));
|
||||
} while (hi2 != hi);
|
||||
|
||||
return (((u64)hi) << 32) + lo;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static __always_inline u64 get_ns(const union mips_vdso_data *data)
|
||||
{
|
||||
u64 cycle_now, delta, nsec;
|
||||
|
||||
switch (data->clock_mode) {
|
||||
#ifdef CONFIG_CSRC_R4K
|
||||
case VDSO_CLOCK_R4K:
|
||||
cycle_now = read_r4k_count();
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_CLKSRC_MIPS_GIC
|
||||
case VDSO_CLOCK_GIC:
|
||||
cycle_now = read_gic_count(data);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
delta = (cycle_now - data->cs_cycle_last) & data->cs_mask;
|
||||
|
||||
nsec = (delta * data->cs_mult) + data->xtime_nsec;
|
||||
nsec >>= data->cs_shift;
|
||||
|
||||
return nsec;
|
||||
}
|
||||
|
||||
static __always_inline int do_realtime(struct timespec *ts,
|
||||
const union mips_vdso_data *data)
|
||||
{
|
||||
u32 start_seq;
|
||||
u64 ns;
|
||||
|
||||
do {
|
||||
start_seq = vdso_data_read_begin(data);
|
||||
|
||||
if (data->clock_mode == VDSO_CLOCK_NONE)
|
||||
return -ENOSYS;
|
||||
|
||||
ts->tv_sec = data->xtime_sec;
|
||||
ns = get_ns(data);
|
||||
} while (vdso_data_read_retry(data, start_seq));
|
||||
|
||||
ts->tv_nsec = 0;
|
||||
timespec_add_ns(ts, ns);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __always_inline int do_monotonic(struct timespec *ts,
|
||||
const union mips_vdso_data *data)
|
||||
{
|
||||
u32 start_seq;
|
||||
u64 ns;
|
||||
u64 to_mono_sec;
|
||||
u64 to_mono_nsec;
|
||||
|
||||
do {
|
||||
start_seq = vdso_data_read_begin(data);
|
||||
|
||||
if (data->clock_mode == VDSO_CLOCK_NONE)
|
||||
return -ENOSYS;
|
||||
|
||||
ts->tv_sec = data->xtime_sec;
|
||||
ns = get_ns(data);
|
||||
|
||||
to_mono_sec = data->wall_to_mono_sec;
|
||||
to_mono_nsec = data->wall_to_mono_nsec;
|
||||
} while (vdso_data_read_retry(data, start_seq));
|
||||
|
||||
ts->tv_sec += to_mono_sec;
|
||||
ts->tv_nsec = 0;
|
||||
timespec_add_ns(ts, ns + to_mono_nsec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
|
||||
|
||||
/*
|
||||
* This is behind the ifdef so that we don't provide the symbol when there's no
|
||||
* possibility of there being a usable clocksource, because there's nothing we
|
||||
* can do without it. When libc fails the symbol lookup it should fall back on
|
||||
* the standard syscall path.
|
||||
*/
|
||||
int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
|
||||
{
|
||||
const union mips_vdso_data *data = get_vdso_data();
|
||||
struct timespec ts;
|
||||
int ret;
|
||||
|
||||
ret = do_realtime(&ts, data);
|
||||
if (ret)
|
||||
return gettimeofday_fallback(tv, tz);
|
||||
|
||||
if (tv) {
|
||||
tv->tv_sec = ts.tv_sec;
|
||||
tv->tv_usec = ts.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
if (tz) {
|
||||
tz->tz_minuteswest = data->tz_minuteswest;
|
||||
tz->tz_dsttime = data->tz_dsttime;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MIPS_CLOCK_VSYSCALL */
|
||||
|
||||
int __vdso_clock_gettime(clockid_t clkid, struct timespec *ts)
|
||||
{
|
||||
const union mips_vdso_data *data = get_vdso_data();
|
||||
int ret = -1;
|
||||
|
||||
switch (clkid) {
|
||||
case CLOCK_REALTIME_COARSE:
|
||||
ret = do_realtime_coarse(ts, data);
|
||||
break;
|
||||
case CLOCK_MONOTONIC_COARSE:
|
||||
ret = do_monotonic_coarse(ts, data);
|
||||
break;
|
||||
case CLOCK_REALTIME:
|
||||
ret = do_realtime(ts, data);
|
||||
break;
|
||||
case CLOCK_MONOTONIC:
|
||||
ret = do_monotonic(ts, data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
ret = clock_gettime_fallback(clkid, ts);
|
||||
|
||||
return ret;
|
||||
}
|
@ -50,7 +50,7 @@ endif
|
||||
|
||||
BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -nostdinc
|
||||
|
||||
BOOTARFLAGS := -cr$(KBUILD_ARFLAGS)
|
||||
BOOTARFLAGS := -crD
|
||||
|
||||
ifdef CONFIG_CC_IS_CLANG
|
||||
BOOTCFLAGS += $(CLANG_FLAGS)
|
||||
|
@ -254,7 +254,13 @@ extern void radix__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
|
||||
extern pgtable_t radix__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
|
||||
extern pmd_t radix__pmdp_huge_get_and_clear(struct mm_struct *mm,
|
||||
unsigned long addr, pmd_t *pmdp);
|
||||
extern int radix__has_transparent_hugepage(void);
|
||||
static inline int radix__has_transparent_hugepage(void)
|
||||
{
|
||||
/* For radix 2M at PMD level means thp */
|
||||
if (mmu_psize_defs[MMU_PAGE_2M].shift == PMD_SHIFT)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern int __meminit radix__vmemmap_create_mapping(unsigned long start,
|
||||
|
@ -36,8 +36,8 @@
|
||||
#include "book3s.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
|
||||
#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
|
||||
#define VM_STAT(x, ...) offsetof(struct kvm, stat.x), KVM_STAT_VM, ## __VA_ARGS__
|
||||
#define VCPU_STAT(x, ...) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU, ## __VA_ARGS__
|
||||
|
||||
/* #define EXIT_DEBUG */
|
||||
|
||||
@ -69,8 +69,8 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
|
||||
{ "pthru_all", VCPU_STAT(pthru_all) },
|
||||
{ "pthru_host", VCPU_STAT(pthru_host) },
|
||||
{ "pthru_bad_aff", VCPU_STAT(pthru_bad_aff) },
|
||||
{ "largepages_2M", VM_STAT(num_2M_pages) },
|
||||
{ "largepages_1G", VM_STAT(num_1G_pages) },
|
||||
{ "largepages_2M", VM_STAT(num_2M_pages, .mode = 0444) },
|
||||
{ "largepages_1G", VM_STAT(num_1G_pages, .mode = 0444) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -406,6 +406,8 @@ int hash__has_transparent_hugepage(void)
|
||||
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hash__has_transparent_hugepage);
|
||||
|
||||
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
||||
|
||||
#ifdef CONFIG_STRICT_KERNEL_RWX
|
||||
|
@ -1027,13 +1027,6 @@ pmd_t radix__pmdp_huge_get_and_clear(struct mm_struct *mm,
|
||||
return old_pmd;
|
||||
}
|
||||
|
||||
int radix__has_transparent_hugepage(void)
|
||||
{
|
||||
/* For radix 2M at PMD level means thp */
|
||||
if (mmu_psize_defs[MMU_PAGE_2M].shift == PMD_SHIFT)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
||||
|
||||
void radix__ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep,
|
||||
|
@ -172,6 +172,21 @@ static __meminit void vmemmap_list_populate(unsigned long phys,
|
||||
vmemmap_list = vmem_back;
|
||||
}
|
||||
|
||||
static bool altmap_cross_boundary(struct vmem_altmap *altmap, unsigned long start,
|
||||
unsigned long page_size)
|
||||
{
|
||||
unsigned long nr_pfn = page_size / sizeof(struct page);
|
||||
unsigned long start_pfn = page_to_pfn((struct page *)start);
|
||||
|
||||
if ((start_pfn + nr_pfn) > altmap->end_pfn)
|
||||
return true;
|
||||
|
||||
if (start_pfn < altmap->base_pfn)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
|
||||
struct vmem_altmap *altmap)
|
||||
{
|
||||
@ -194,7 +209,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
|
||||
* fail due to alignment issues when using 16MB hugepages, so
|
||||
* fall back to system memory if the altmap allocation fail.
|
||||
*/
|
||||
if (altmap) {
|
||||
if (altmap && !altmap_cross_boundary(altmap, start, page_size)) {
|
||||
p = altmap_alloc_block_buf(page_size, altmap);
|
||||
if (!p)
|
||||
pr_debug("altmap block allocation failed, falling back to system memory");
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#define REG_L __REG_SEL(ld, lw)
|
||||
#define REG_S __REG_SEL(sd, sw)
|
||||
#define REG_SC __REG_SEL(sc.d, sc.w)
|
||||
#define SZREG __REG_SEL(8, 4)
|
||||
#define LGREG __REG_SEL(3, 2)
|
||||
|
||||
|
@ -98,7 +98,26 @@ _save_context:
|
||||
*/
|
||||
.macro RESTORE_ALL
|
||||
REG_L a0, PT_SSTATUS(sp)
|
||||
REG_L a2, PT_SEPC(sp)
|
||||
/*
|
||||
* The current load reservation is effectively part of the processor's
|
||||
* state, in the sense that load reservations cannot be shared between
|
||||
* different hart contexts. We can't actually save and restore a load
|
||||
* reservation, so instead here we clear any existing reservation --
|
||||
* it's always legal for implementations to clear load reservations at
|
||||
* any point (as long as the forward progress guarantee is kept, but
|
||||
* we'll ignore that here).
|
||||
*
|
||||
* Dangling load reservations can be the result of taking a trap in the
|
||||
* middle of an LR/SC sequence, but can also be the result of a taken
|
||||
* forward branch around an SC -- which is how we implement CAS. As a
|
||||
* result we need to clear reservations between the last CAS and the
|
||||
* jump back to the new context. While it is unlikely the store
|
||||
* completes, implementations are allowed to expand reservations to be
|
||||
* arbitrarily large.
|
||||
*/
|
||||
REG_L a2, PT_SEPC(sp)
|
||||
REG_SC x0, a2, PT_SEPC(sp)
|
||||
|
||||
csrw CSR_SSTATUS, a0
|
||||
csrw CSR_SEPC, a2
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/swap.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/libfdt.h>
|
||||
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/tlbflush.h>
|
||||
@ -82,6 +83,8 @@ disable:
|
||||
}
|
||||
#endif /* CONFIG_BLK_DEV_INITRD */
|
||||
|
||||
static phys_addr_t dtb_early_pa __initdata;
|
||||
|
||||
void __init setup_bootmem(void)
|
||||
{
|
||||
struct memblock_region *reg;
|
||||
@ -117,7 +120,12 @@ void __init setup_bootmem(void)
|
||||
setup_initrd();
|
||||
#endif /* CONFIG_BLK_DEV_INITRD */
|
||||
|
||||
early_init_fdt_reserve_self();
|
||||
/*
|
||||
* Avoid using early_init_fdt_reserve_self() since __pa() does
|
||||
* not work for DTB pointers that are fixmap addresses
|
||||
*/
|
||||
memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va));
|
||||
|
||||
early_init_fdt_scan_reserved_mem();
|
||||
memblock_allow_resize();
|
||||
memblock_dump_all();
|
||||
@ -393,6 +401,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
|
||||
|
||||
/* Save pointer to DTB for early FDT parsing */
|
||||
dtb_early_va = (void *)fix_to_virt(FIX_FDT) + (dtb_pa & ~PAGE_MASK);
|
||||
/* Save physical address for memblock reservation */
|
||||
dtb_early_pa = dtb_pa;
|
||||
}
|
||||
|
||||
static void __init setup_vm_final(void)
|
||||
|
@ -44,6 +44,7 @@ CONFIG_NR_CPUS=512
|
||||
CONFIG_NUMA=y
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_KEXEC_FILE=y
|
||||
CONFIG_KEXEC_SIG=y
|
||||
CONFIG_EXPOLINE=y
|
||||
CONFIG_EXPOLINE_AUTO=y
|
||||
CONFIG_CHSC_SCH=y
|
||||
@ -69,12 +70,13 @@ CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
CONFIG_MODULE_SIG=y
|
||||
CONFIG_MODULE_SIG_SHA256=y
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_BLK_DEV_INTEGRITY=y
|
||||
CONFIG_BLK_DEV_THROTTLING=y
|
||||
CONFIG_BLK_WBT=y
|
||||
CONFIG_BLK_CGROUP_IOLATENCY=y
|
||||
CONFIG_BLK_CGROUP_IOCOST=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_IBM_PARTITION=y
|
||||
CONFIG_BSD_DISKLABEL=y
|
||||
@ -370,6 +372,7 @@ CONFIG_NETLINK_DIAG=m
|
||||
CONFIG_CGROUP_NET_PRIO=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_NET_PKTGEN=m
|
||||
# CONFIG_NET_DROP_MONITOR is not set
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCI_DEBUG=y
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
@ -424,6 +427,7 @@ CONFIG_DM_CRYPT=m
|
||||
CONFIG_DM_SNAPSHOT=m
|
||||
CONFIG_DM_THIN_PROVISIONING=m
|
||||
CONFIG_DM_WRITECACHE=m
|
||||
CONFIG_DM_CLONE=m
|
||||
CONFIG_DM_MIRROR=m
|
||||
CONFIG_DM_LOG_USERSPACE=m
|
||||
CONFIG_DM_RAID=m
|
||||
@ -435,6 +439,7 @@ CONFIG_DM_DELAY=m
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_FLAKEY=m
|
||||
CONFIG_DM_VERITY=m
|
||||
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
|
||||
CONFIG_DM_SWITCH=m
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_BONDING=m
|
||||
@ -489,6 +494,7 @@ CONFIG_MLX5_CORE_EN=y
|
||||
# CONFIG_NET_VENDOR_NVIDIA is not set
|
||||
# CONFIG_NET_VENDOR_OKI is not set
|
||||
# CONFIG_NET_VENDOR_PACKET_ENGINES is not set
|
||||
# CONFIG_NET_VENDOR_PENSANDO is not set
|
||||
# CONFIG_NET_VENDOR_QLOGIC is not set
|
||||
# CONFIG_NET_VENDOR_QUALCOMM is not set
|
||||
# CONFIG_NET_VENDOR_RDC is not set
|
||||
@ -538,15 +544,16 @@ CONFIG_WATCHDOG=y
|
||||
CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
CONFIG_SOFT_WATCHDOG=m
|
||||
CONFIG_DIAG288_WATCHDOG=m
|
||||
CONFIG_DRM=y
|
||||
CONFIG_DRM_VIRTIO_GPU=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
# CONFIG_HID is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
CONFIG_INFINIBAND=m
|
||||
CONFIG_INFINIBAND_USER_ACCESS=m
|
||||
CONFIG_MLX4_INFINIBAND=m
|
||||
CONFIG_MLX5_INFINIBAND=m
|
||||
CONFIG_SYNC_FILE=y
|
||||
CONFIG_VFIO=m
|
||||
CONFIG_VFIO_PCI=m
|
||||
CONFIG_VFIO_MDEV=m
|
||||
@ -580,6 +587,8 @@ CONFIG_NILFS2_FS=m
|
||||
CONFIG_FS_DAX=y
|
||||
CONFIG_EXPORTFS_BLOCK_OPS=y
|
||||
CONFIG_FS_ENCRYPTION=y
|
||||
CONFIG_FS_VERITY=y
|
||||
CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
@ -589,6 +598,7 @@ CONFIG_QFMT_V2=m
|
||||
CONFIG_AUTOFS4_FS=m
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_CUSE=m
|
||||
CONFIG_VIRTIO_FS=m
|
||||
CONFIG_OVERLAY_FS=m
|
||||
CONFIG_FSCACHE=m
|
||||
CONFIG_CACHEFILES=m
|
||||
@ -648,12 +658,15 @@ CONFIG_FORTIFY_SOURCE=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
|
||||
CONFIG_SECURITY_SELINUX_DISABLE=y
|
||||
CONFIG_SECURITY_LOCKDOWN_LSM=y
|
||||
CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y
|
||||
CONFIG_INTEGRITY_SIGNATURE=y
|
||||
CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
|
||||
CONFIG_IMA=y
|
||||
CONFIG_IMA_DEFAULT_HASH_SHA256=y
|
||||
CONFIG_IMA_WRITE_POLICY=y
|
||||
CONFIG_IMA_APPRAISE=y
|
||||
CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor"
|
||||
CONFIG_CRYPTO_USER=m
|
||||
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
|
||||
CONFIG_CRYPTO_PCRYPT=m
|
||||
@ -664,10 +677,6 @@ CONFIG_CRYPTO_ECDH=m
|
||||
CONFIG_CRYPTO_ECRDSA=m
|
||||
CONFIG_CRYPTO_CHACHA20POLY1305=m
|
||||
CONFIG_CRYPTO_AEGIS128=m
|
||||
CONFIG_CRYPTO_AEGIS128L=m
|
||||
CONFIG_CRYPTO_AEGIS256=m
|
||||
CONFIG_CRYPTO_MORUS640=m
|
||||
CONFIG_CRYPTO_MORUS1280=m
|
||||
CONFIG_CRYPTO_CFB=m
|
||||
CONFIG_CRYPTO_LRW=m
|
||||
CONFIG_CRYPTO_PCBC=m
|
||||
@ -739,7 +748,6 @@ CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_INFO_DWARF4=y
|
||||
CONFIG_GDB_SCRIPTS=y
|
||||
CONFIG_FRAME_WARN=1024
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_HEADERS_INSTALL=y
|
||||
CONFIG_HEADERS_CHECK=y
|
||||
CONFIG_DEBUG_SECTION_MISMATCH=y
|
||||
|
@ -44,6 +44,7 @@ CONFIG_NUMA=y
|
||||
# CONFIG_NUMA_EMU is not set
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_KEXEC_FILE=y
|
||||
CONFIG_KEXEC_SIG=y
|
||||
CONFIG_EXPOLINE=y
|
||||
CONFIG_EXPOLINE_AUTO=y
|
||||
CONFIG_CHSC_SCH=y
|
||||
@ -66,11 +67,12 @@ CONFIG_MODULE_UNLOAD=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_MODULE_SRCVERSION_ALL=y
|
||||
CONFIG_MODULE_SIG=y
|
||||
CONFIG_MODULE_SIG_SHA256=y
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_BLK_DEV_THROTTLING=y
|
||||
CONFIG_BLK_WBT=y
|
||||
CONFIG_BLK_CGROUP_IOLATENCY=y
|
||||
CONFIG_BLK_CGROUP_IOCOST=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_IBM_PARTITION=y
|
||||
CONFIG_BSD_DISKLABEL=y
|
||||
@ -363,6 +365,7 @@ CONFIG_NETLINK_DIAG=m
|
||||
CONFIG_CGROUP_NET_PRIO=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_NET_PKTGEN=m
|
||||
# CONFIG_NET_DROP_MONITOR is not set
|
||||
CONFIG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_S390=y
|
||||
@ -418,6 +421,7 @@ CONFIG_DM_CRYPT=m
|
||||
CONFIG_DM_SNAPSHOT=m
|
||||
CONFIG_DM_THIN_PROVISIONING=m
|
||||
CONFIG_DM_WRITECACHE=m
|
||||
CONFIG_DM_CLONE=m
|
||||
CONFIG_DM_MIRROR=m
|
||||
CONFIG_DM_LOG_USERSPACE=m
|
||||
CONFIG_DM_RAID=m
|
||||
@ -429,6 +433,7 @@ CONFIG_DM_DELAY=m
|
||||
CONFIG_DM_UEVENT=y
|
||||
CONFIG_DM_FLAKEY=m
|
||||
CONFIG_DM_VERITY=m
|
||||
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
|
||||
CONFIG_DM_SWITCH=m
|
||||
CONFIG_DM_INTEGRITY=m
|
||||
CONFIG_NETDEVICES=y
|
||||
@ -484,6 +489,7 @@ CONFIG_MLX5_CORE_EN=y
|
||||
# CONFIG_NET_VENDOR_NVIDIA is not set
|
||||
# CONFIG_NET_VENDOR_OKI is not set
|
||||
# CONFIG_NET_VENDOR_PACKET_ENGINES is not set
|
||||
# CONFIG_NET_VENDOR_PENSANDO is not set
|
||||
# CONFIG_NET_VENDOR_QLOGIC is not set
|
||||
# CONFIG_NET_VENDOR_QUALCOMM is not set
|
||||
# CONFIG_NET_VENDOR_RDC is not set
|
||||
@ -533,16 +539,16 @@ CONFIG_WATCHDOG_CORE=y
|
||||
CONFIG_WATCHDOG_NOWAYOUT=y
|
||||
CONFIG_SOFT_WATCHDOG=m
|
||||
CONFIG_DIAG288_WATCHDOG=m
|
||||
CONFIG_DRM=y
|
||||
CONFIG_DRM_VIRTIO_GPU=y
|
||||
# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
|
||||
CONFIG_FB=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
# CONFIG_HID is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
CONFIG_INFINIBAND=m
|
||||
CONFIG_INFINIBAND_USER_ACCESS=m
|
||||
CONFIG_MLX4_INFINIBAND=m
|
||||
CONFIG_MLX5_INFINIBAND=m
|
||||
CONFIG_SYNC_FILE=y
|
||||
CONFIG_VFIO=m
|
||||
CONFIG_VFIO_PCI=m
|
||||
CONFIG_VFIO_MDEV=m
|
||||
@ -573,6 +579,8 @@ CONFIG_NILFS2_FS=m
|
||||
CONFIG_FS_DAX=y
|
||||
CONFIG_EXPORTFS_BLOCK_OPS=y
|
||||
CONFIG_FS_ENCRYPTION=y
|
||||
CONFIG_FS_VERITY=y
|
||||
CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y
|
||||
CONFIG_FANOTIFY=y
|
||||
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
|
||||
CONFIG_QUOTA_NETLINK_INTERFACE=y
|
||||
@ -581,6 +589,7 @@ CONFIG_QFMT_V2=m
|
||||
CONFIG_AUTOFS4_FS=m
|
||||
CONFIG_FUSE_FS=y
|
||||
CONFIG_CUSE=m
|
||||
CONFIG_VIRTIO_FS=m
|
||||
CONFIG_OVERLAY_FS=m
|
||||
CONFIG_FSCACHE=m
|
||||
CONFIG_CACHEFILES=m
|
||||
@ -639,12 +648,15 @@ CONFIG_SECURITY_NETWORK=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
|
||||
CONFIG_SECURITY_SELINUX_DISABLE=y
|
||||
CONFIG_SECURITY_LOCKDOWN_LSM=y
|
||||
CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y
|
||||
CONFIG_INTEGRITY_SIGNATURE=y
|
||||
CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
|
||||
CONFIG_IMA=y
|
||||
CONFIG_IMA_DEFAULT_HASH_SHA256=y
|
||||
CONFIG_IMA_WRITE_POLICY=y
|
||||
CONFIG_IMA_APPRAISE=y
|
||||
CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor"
|
||||
CONFIG_CRYPTO_FIPS=y
|
||||
CONFIG_CRYPTO_USER=m
|
||||
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
|
||||
@ -656,10 +668,6 @@ CONFIG_CRYPTO_ECDH=m
|
||||
CONFIG_CRYPTO_ECRDSA=m
|
||||
CONFIG_CRYPTO_CHACHA20POLY1305=m
|
||||
CONFIG_CRYPTO_AEGIS128=m
|
||||
CONFIG_CRYPTO_AEGIS128L=m
|
||||
CONFIG_CRYPTO_AEGIS256=m
|
||||
CONFIG_CRYPTO_MORUS640=m
|
||||
CONFIG_CRYPTO_MORUS1280=m
|
||||
CONFIG_CRYPTO_CFB=m
|
||||
CONFIG_CRYPTO_LRW=m
|
||||
CONFIG_CRYPTO_OFB=m
|
||||
@ -727,7 +735,6 @@ CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_INFO_DWARF4=y
|
||||
CONFIG_GDB_SCRIPTS=y
|
||||
CONFIG_FRAME_WARN=1024
|
||||
CONFIG_UNUSED_SYMBOLS=y
|
||||
CONFIG_DEBUG_SECTION_MISMATCH=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_MEMORY_INIT=y
|
||||
|
@ -61,7 +61,7 @@ CONFIG_RAW_DRIVER=y
|
||||
CONFIG_CONFIGFS_FS=y
|
||||
# CONFIG_MISC_FILESYSTEMS is not set
|
||||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||
# CONFIG_DIMLIB is not set
|
||||
CONFIG_LSM="yama,loadpin,safesetid,integrity"
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
|
@ -41,7 +41,7 @@ __ATOMIC_OPS(__atomic64_xor, long, "laxg")
|
||||
#undef __ATOMIC_OP
|
||||
|
||||
#define __ATOMIC_CONST_OP(op_name, op_type, op_string, op_barrier) \
|
||||
static inline void op_name(op_type val, op_type *ptr) \
|
||||
static __always_inline void op_name(op_type val, op_type *ptr) \
|
||||
{ \
|
||||
asm volatile( \
|
||||
op_string " %[ptr],%[val]\n" \
|
||||
|
@ -56,7 +56,7 @@ __bitops_byte(unsigned long nr, volatile unsigned long *ptr)
|
||||
return ((unsigned char *)ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3);
|
||||
}
|
||||
|
||||
static inline void arch_set_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
static __always_inline void arch_set_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned long *addr = __bitops_word(nr, ptr);
|
||||
unsigned long mask;
|
||||
@ -77,7 +77,7 @@ static inline void arch_set_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
__atomic64_or(mask, (long *)addr);
|
||||
}
|
||||
|
||||
static inline void arch_clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
static __always_inline void arch_clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned long *addr = __bitops_word(nr, ptr);
|
||||
unsigned long mask;
|
||||
@ -98,8 +98,8 @@ static inline void arch_clear_bit(unsigned long nr, volatile unsigned long *ptr)
|
||||
__atomic64_and(mask, (long *)addr);
|
||||
}
|
||||
|
||||
static inline void arch_change_bit(unsigned long nr,
|
||||
volatile unsigned long *ptr)
|
||||
static __always_inline void arch_change_bit(unsigned long nr,
|
||||
volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned long *addr = __bitops_word(nr, ptr);
|
||||
unsigned long mask;
|
||||
|
@ -171,7 +171,7 @@ typedef struct { unsigned char bytes[16]; } cpacf_mask_t;
|
||||
*
|
||||
* Returns 1 if @func is available for @opcode, 0 otherwise
|
||||
*/
|
||||
static inline void __cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
|
||||
static __always_inline void __cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
|
||||
{
|
||||
register unsigned long r0 asm("0") = 0; /* query function */
|
||||
register unsigned long r1 asm("1") = (unsigned long) mask;
|
||||
|
@ -28,6 +28,8 @@ asm(".include \"asm/cpu_mf-insn.h\"\n");
|
||||
CPU_MF_INT_SF_PRA|CPU_MF_INT_SF_SACA| \
|
||||
CPU_MF_INT_SF_LSDA)
|
||||
|
||||
#define CPU_MF_SF_RIBM_NOTAV 0x1 /* Sampling unavailable */
|
||||
|
||||
/* CPU measurement facility support */
|
||||
static inline int cpum_cf_avail(void)
|
||||
{
|
||||
@ -69,7 +71,8 @@ struct hws_qsi_info_block { /* Bit(s) */
|
||||
unsigned long max_sampl_rate; /* 16-23: maximum sampling interval*/
|
||||
unsigned long tear; /* 24-31: TEAR contents */
|
||||
unsigned long dear; /* 32-39: DEAR contents */
|
||||
unsigned int rsvrd0; /* 40-43: reserved */
|
||||
unsigned int rsvrd0:24; /* 40-42: reserved */
|
||||
unsigned int ribm:8; /* 43: Reserved by IBM */
|
||||
unsigned int cpu_speed; /* 44-47: CPU speed */
|
||||
unsigned long long rsvrd1; /* 48-55: reserved */
|
||||
unsigned long long rsvrd2; /* 56-63: reserved */
|
||||
@ -220,7 +223,8 @@ enum stcctm_ctr_set {
|
||||
MT_DIAG = 5,
|
||||
MT_DIAG_CLEARING = 9, /* clears loss-of-MT-ctr-data alert */
|
||||
};
|
||||
static inline int stcctm(enum stcctm_ctr_set set, u64 range, u64 *dest)
|
||||
|
||||
static __always_inline int stcctm(enum stcctm_ctr_set set, u64 range, u64 *dest)
|
||||
{
|
||||
int cc;
|
||||
|
||||
|
@ -12,8 +12,6 @@
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
|
||||
#define is_hugepage_only_range(mm, addr, len) 0
|
||||
#define hugetlb_free_pgd_range free_pgd_range
|
||||
#define hugepages_supported() (MACHINE_HAS_EDAT1)
|
||||
|
||||
@ -23,6 +21,13 @@ pte_t huge_ptep_get(pte_t *ptep);
|
||||
pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep);
|
||||
|
||||
static inline bool is_hugepage_only_range(struct mm_struct *mm,
|
||||
unsigned long addr,
|
||||
unsigned long len)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the arch doesn't supply something else, assume that hugepage
|
||||
* size aligned regions are ok without further preparation.
|
||||
|
@ -20,7 +20,7 @@
|
||||
* We use a brcl 0,2 instruction for jump labels at compile time so it
|
||||
* can be easily distinguished from a hotpatch generated instruction.
|
||||
*/
|
||||
static inline bool arch_static_branch(struct static_key *key, bool branch)
|
||||
static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
|
||||
{
|
||||
asm_volatile_goto("0: brcl 0,"__stringify(JUMP_LABEL_NOP_OFFSET)"\n"
|
||||
".pushsection __jump_table,\"aw\"\n"
|
||||
@ -34,7 +34,7 @@ label:
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool arch_static_branch_jump(struct static_key *key, bool branch)
|
||||
static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
|
||||
{
|
||||
asm_volatile_goto("0: brcl 15,%l[label]\n"
|
||||
".pushsection __jump_table,\"aw\"\n"
|
||||
|
@ -997,9 +997,9 @@ static inline pte_t pte_mkhuge(pte_t pte)
|
||||
#define IPTE_NODAT 0x400
|
||||
#define IPTE_GUEST_ASCE 0x800
|
||||
|
||||
static inline void __ptep_ipte(unsigned long address, pte_t *ptep,
|
||||
unsigned long opt, unsigned long asce,
|
||||
int local)
|
||||
static __always_inline void __ptep_ipte(unsigned long address, pte_t *ptep,
|
||||
unsigned long opt, unsigned long asce,
|
||||
int local)
|
||||
{
|
||||
unsigned long pto = (unsigned long) ptep;
|
||||
|
||||
@ -1020,8 +1020,8 @@ static inline void __ptep_ipte(unsigned long address, pte_t *ptep,
|
||||
: [r1] "a" (pto), [m4] "i" (local) : "memory");
|
||||
}
|
||||
|
||||
static inline void __ptep_ipte_range(unsigned long address, int nr,
|
||||
pte_t *ptep, int local)
|
||||
static __always_inline void __ptep_ipte_range(unsigned long address, int nr,
|
||||
pte_t *ptep, int local)
|
||||
{
|
||||
unsigned long pto = (unsigned long) ptep;
|
||||
|
||||
@ -1269,7 +1269,8 @@ static inline pte_t *pte_offset(pmd_t *pmd, unsigned long address)
|
||||
|
||||
#define pte_offset_kernel(pmd, address) pte_offset(pmd, address)
|
||||
#define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
|
||||
#define pte_unmap(pte) do { } while (0)
|
||||
|
||||
static inline void pte_unmap(pte_t *pte) { }
|
||||
|
||||
static inline bool gup_fast_permitted(unsigned long start, unsigned long end)
|
||||
{
|
||||
@ -1435,9 +1436,9 @@ static inline void __pmdp_csp(pmd_t *pmdp)
|
||||
#define IDTE_NODAT 0x1000
|
||||
#define IDTE_GUEST_ASCE 0x2000
|
||||
|
||||
static inline void __pmdp_idte(unsigned long addr, pmd_t *pmdp,
|
||||
unsigned long opt, unsigned long asce,
|
||||
int local)
|
||||
static __always_inline void __pmdp_idte(unsigned long addr, pmd_t *pmdp,
|
||||
unsigned long opt, unsigned long asce,
|
||||
int local)
|
||||
{
|
||||
unsigned long sto;
|
||||
|
||||
@ -1461,9 +1462,9 @@ static inline void __pmdp_idte(unsigned long addr, pmd_t *pmdp,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void __pudp_idte(unsigned long addr, pud_t *pudp,
|
||||
unsigned long opt, unsigned long asce,
|
||||
int local)
|
||||
static __always_inline void __pudp_idte(unsigned long addr, pud_t *pudp,
|
||||
unsigned long opt, unsigned long asce,
|
||||
int local)
|
||||
{
|
||||
unsigned long r3o;
|
||||
|
||||
|
@ -111,7 +111,7 @@ struct qib {
|
||||
/* private: */
|
||||
u8 res[88];
|
||||
/* public: */
|
||||
u8 parm[QDIO_MAX_BUFFERS_PER_Q];
|
||||
u8 parm[128];
|
||||
} __attribute__ ((packed, aligned(256)));
|
||||
|
||||
/**
|
||||
|
@ -390,7 +390,7 @@ static size_t cf_diag_getctrset(struct cf_ctrset_entry *ctrdata, int ctrset,
|
||||
|
||||
debug_sprintf_event(cf_diag_dbg, 6,
|
||||
"%s ctrset %d ctrset_size %zu cfvn %d csvn %d"
|
||||
" need %zd rc:%d\n",
|
||||
" need %zd rc %d\n",
|
||||
__func__, ctrset, ctrset_size, cpuhw->info.cfvn,
|
||||
cpuhw->info.csvn, need, rc);
|
||||
return need;
|
||||
@ -567,7 +567,7 @@ static int cf_diag_add(struct perf_event *event, int flags)
|
||||
int err = 0;
|
||||
|
||||
debug_sprintf_event(cf_diag_dbg, 5,
|
||||
"%s event %p cpu %d flags %#x cpuhw:%p\n",
|
||||
"%s event %p cpu %d flags %#x cpuhw %p\n",
|
||||
__func__, event, event->cpu, flags, cpuhw);
|
||||
|
||||
if (cpuhw->flags & PMU_F_IN_USE) {
|
||||
|
@ -803,6 +803,12 @@ static int __hw_perf_event_init(struct perf_event *event)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (si.ribm & CPU_MF_SF_RIBM_NOTAV) {
|
||||
pr_warn("CPU Measurement Facility sampling is temporarily not available\n");
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Always enable basic sampling */
|
||||
SAMPL_FLAGS(hwc) = PERF_CPUM_SF_BASIC_MODE;
|
||||
|
||||
@ -895,7 +901,7 @@ static int cpumsf_pmu_event_init(struct perf_event *event)
|
||||
|
||||
/* Check online status of the CPU to which the event is pinned */
|
||||
if (event->cpu >= 0 && !cpu_online(event->cpu))
|
||||
return -ENODEV;
|
||||
return -ENODEV;
|
||||
|
||||
/* Force reset of idle/hv excludes regardless of what the
|
||||
* user requested.
|
||||
|
@ -332,7 +332,7 @@ static inline int plo_test_bit(unsigned char nr)
|
||||
return cc == 0;
|
||||
}
|
||||
|
||||
static inline void __insn32_query(unsigned int opcode, u8 query[32])
|
||||
static __always_inline void __insn32_query(unsigned int opcode, u8 *query)
|
||||
{
|
||||
register unsigned long r0 asm("0") = 0; /* query function */
|
||||
register unsigned long r1 asm("1") = (unsigned long) query;
|
||||
@ -340,9 +340,9 @@ static inline void __insn32_query(unsigned int opcode, u8 query[32])
|
||||
asm volatile(
|
||||
/* Parameter regs are ignored */
|
||||
" .insn rrf,%[opc] << 16,2,4,6,0\n"
|
||||
: "=m" (*query)
|
||||
:
|
||||
: "d" (r0), "a" (r1), [opc] "i" (opcode)
|
||||
: "cc");
|
||||
: "cc", "memory");
|
||||
}
|
||||
|
||||
#define INSN_SORTL 0xb938
|
||||
|
@ -66,7 +66,7 @@ static inline int clp_get_ilp(unsigned long *ilp)
|
||||
/*
|
||||
* Call Logical Processor with c=0, the give constant lps and an lpcb request.
|
||||
*/
|
||||
static inline int clp_req(void *data, unsigned int lps)
|
||||
static __always_inline int clp_req(void *data, unsigned int lps)
|
||||
{
|
||||
struct { u8 _[CLP_BLK_SIZE]; } *req = data;
|
||||
u64 ignored;
|
||||
|
@ -219,13 +219,6 @@ enum {
|
||||
PFERR_WRITE_MASK | \
|
||||
PFERR_PRESENT_MASK)
|
||||
|
||||
/*
|
||||
* The mask used to denote special SPTEs, which can be either MMIO SPTEs or
|
||||
* Access Tracking SPTEs. We use bit 62 instead of bit 63 to avoid conflicting
|
||||
* with the SVE bit in EPT PTEs.
|
||||
*/
|
||||
#define SPTE_SPECIAL_MASK (1ULL << 62)
|
||||
|
||||
/* apic attention bits */
|
||||
#define KVM_APIC_CHECK_VAPIC 0
|
||||
/*
|
||||
|
@ -485,6 +485,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
|
||||
|
||||
/* cpuid 0x80000008.ebx */
|
||||
const u32 kvm_cpuid_8000_0008_ebx_x86_features =
|
||||
F(CLZERO) | F(XSAVEERPTR) |
|
||||
F(WBNOINVD) | F(AMD_IBPB) | F(AMD_IBRS) | F(AMD_SSBD) | F(VIRT_SSBD) |
|
||||
F(AMD_SSB_NO) | F(AMD_STIBP) | F(AMD_STIBP_ALWAYS_ON);
|
||||
|
||||
@ -618,16 +619,20 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
|
||||
*/
|
||||
case 0x1f:
|
||||
case 0xb: {
|
||||
int i, level_type;
|
||||
int i;
|
||||
|
||||
/* read more entries until level_type is zero */
|
||||
for (i = 1; ; ++i) {
|
||||
/*
|
||||
* We filled in entry[0] for CPUID(EAX=<function>,
|
||||
* ECX=00H) above. If its level type (ECX[15:8]) is
|
||||
* zero, then the leaf is unimplemented, and we're
|
||||
* done. Otherwise, continue to populate entries
|
||||
* until the level type (ECX[15:8]) of the previously
|
||||
* added entry is zero.
|
||||
*/
|
||||
for (i = 1; entry[i - 1].ecx & 0xff00; ++i) {
|
||||
if (*nent >= maxnent)
|
||||
goto out;
|
||||
|
||||
level_type = entry[i - 1].ecx & 0xff00;
|
||||
if (!level_type)
|
||||
break;
|
||||
do_host_cpuid(&entry[i], function, i);
|
||||
++*nent;
|
||||
}
|
||||
@ -969,53 +974,66 @@ struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
|
||||
EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry);
|
||||
|
||||
/*
|
||||
* If no match is found, check whether we exceed the vCPU's limit
|
||||
* and return the content of the highest valid _standard_ leaf instead.
|
||||
* This is to satisfy the CPUID specification.
|
||||
* If the basic or extended CPUID leaf requested is higher than the
|
||||
* maximum supported basic or extended leaf, respectively, then it is
|
||||
* out of range.
|
||||
*/
|
||||
static struct kvm_cpuid_entry2* check_cpuid_limit(struct kvm_vcpu *vcpu,
|
||||
u32 function, u32 index)
|
||||
static bool cpuid_function_in_range(struct kvm_vcpu *vcpu, u32 function)
|
||||
{
|
||||
struct kvm_cpuid_entry2 *maxlevel;
|
||||
struct kvm_cpuid_entry2 *max;
|
||||
|
||||
maxlevel = kvm_find_cpuid_entry(vcpu, function & 0x80000000, 0);
|
||||
if (!maxlevel || maxlevel->eax >= function)
|
||||
return NULL;
|
||||
if (function & 0x80000000) {
|
||||
maxlevel = kvm_find_cpuid_entry(vcpu, 0, 0);
|
||||
if (!maxlevel)
|
||||
return NULL;
|
||||
}
|
||||
return kvm_find_cpuid_entry(vcpu, maxlevel->eax, index);
|
||||
max = kvm_find_cpuid_entry(vcpu, function & 0x80000000, 0);
|
||||
return max && function <= max->eax;
|
||||
}
|
||||
|
||||
bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
|
||||
u32 *ecx, u32 *edx, bool check_limit)
|
||||
{
|
||||
u32 function = *eax, index = *ecx;
|
||||
struct kvm_cpuid_entry2 *best;
|
||||
bool entry_found = true;
|
||||
struct kvm_cpuid_entry2 *entry;
|
||||
struct kvm_cpuid_entry2 *max;
|
||||
bool found;
|
||||
|
||||
best = kvm_find_cpuid_entry(vcpu, function, index);
|
||||
|
||||
if (!best) {
|
||||
entry_found = false;
|
||||
if (!check_limit)
|
||||
goto out;
|
||||
|
||||
best = check_cpuid_limit(vcpu, function, index);
|
||||
entry = kvm_find_cpuid_entry(vcpu, function, index);
|
||||
found = entry;
|
||||
/*
|
||||
* Intel CPUID semantics treats any query for an out-of-range
|
||||
* leaf as if the highest basic leaf (i.e. CPUID.0H:EAX) were
|
||||
* requested. AMD CPUID semantics returns all zeroes for any
|
||||
* undefined leaf, whether or not the leaf is in range.
|
||||
*/
|
||||
if (!entry && check_limit && !guest_cpuid_is_amd(vcpu) &&
|
||||
!cpuid_function_in_range(vcpu, function)) {
|
||||
max = kvm_find_cpuid_entry(vcpu, 0, 0);
|
||||
if (max) {
|
||||
function = max->eax;
|
||||
entry = kvm_find_cpuid_entry(vcpu, function, index);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (best) {
|
||||
*eax = best->eax;
|
||||
*ebx = best->ebx;
|
||||
*ecx = best->ecx;
|
||||
*edx = best->edx;
|
||||
} else
|
||||
if (entry) {
|
||||
*eax = entry->eax;
|
||||
*ebx = entry->ebx;
|
||||
*ecx = entry->ecx;
|
||||
*edx = entry->edx;
|
||||
} else {
|
||||
*eax = *ebx = *ecx = *edx = 0;
|
||||
trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx, entry_found);
|
||||
return entry_found;
|
||||
/*
|
||||
* When leaf 0BH or 1FH is defined, CL is pass-through
|
||||
* and EDX is always the x2APIC ID, even for undefined
|
||||
* subleaves. Index 1 will exist iff the leaf is
|
||||
* implemented, so we pass through CL iff leaf 1
|
||||
* exists. EDX can be copied from any existing index.
|
||||
*/
|
||||
if (function == 0xb || function == 0x1f) {
|
||||
entry = kvm_find_cpuid_entry(vcpu, function, 1);
|
||||
if (entry) {
|
||||
*ecx = index & 0xff;
|
||||
*edx = entry->edx;
|
||||
}
|
||||
}
|
||||
}
|
||||
trace_kvm_cpuid(function, *eax, *ebx, *ecx, *edx, found);
|
||||
return found;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_cpuid);
|
||||
|
||||
|
@ -66,9 +66,10 @@
|
||||
#define X2APIC_BROADCAST 0xFFFFFFFFul
|
||||
|
||||
static bool lapic_timer_advance_dynamic __read_mostly;
|
||||
#define LAPIC_TIMER_ADVANCE_ADJUST_MIN 100
|
||||
#define LAPIC_TIMER_ADVANCE_ADJUST_MAX 5000
|
||||
#define LAPIC_TIMER_ADVANCE_ADJUST_INIT 1000
|
||||
#define LAPIC_TIMER_ADVANCE_ADJUST_MIN 100 /* clock cycles */
|
||||
#define LAPIC_TIMER_ADVANCE_ADJUST_MAX 10000 /* clock cycles */
|
||||
#define LAPIC_TIMER_ADVANCE_NS_INIT 1000
|
||||
#define LAPIC_TIMER_ADVANCE_NS_MAX 5000
|
||||
/* step-by-step approximation to mitigate fluctuation */
|
||||
#define LAPIC_TIMER_ADVANCE_ADJUST_STEP 8
|
||||
|
||||
@ -1504,8 +1505,8 @@ static inline void adjust_lapic_timer_advance(struct kvm_vcpu *vcpu,
|
||||
timer_advance_ns += ns/LAPIC_TIMER_ADVANCE_ADJUST_STEP;
|
||||
}
|
||||
|
||||
if (unlikely(timer_advance_ns > LAPIC_TIMER_ADVANCE_ADJUST_MAX))
|
||||
timer_advance_ns = LAPIC_TIMER_ADVANCE_ADJUST_INIT;
|
||||
if (unlikely(timer_advance_ns > LAPIC_TIMER_ADVANCE_NS_MAX))
|
||||
timer_advance_ns = LAPIC_TIMER_ADVANCE_NS_INIT;
|
||||
apic->lapic_timer.timer_advance_ns = timer_advance_ns;
|
||||
}
|
||||
|
||||
@ -2302,7 +2303,7 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu, int timer_advance_ns)
|
||||
HRTIMER_MODE_ABS_HARD);
|
||||
apic->lapic_timer.timer.function = apic_timer_fn;
|
||||
if (timer_advance_ns == -1) {
|
||||
apic->lapic_timer.timer_advance_ns = LAPIC_TIMER_ADVANCE_ADJUST_INIT;
|
||||
apic->lapic_timer.timer_advance_ns = LAPIC_TIMER_ADVANCE_NS_INIT;
|
||||
lapic_timer_advance_dynamic = true;
|
||||
} else {
|
||||
apic->lapic_timer.timer_advance_ns = timer_advance_ns;
|
||||
|
@ -83,7 +83,17 @@ module_param(dbg, bool, 0644);
|
||||
#define PTE_PREFETCH_NUM 8
|
||||
|
||||
#define PT_FIRST_AVAIL_BITS_SHIFT 10
|
||||
#define PT64_SECOND_AVAIL_BITS_SHIFT 52
|
||||
#define PT64_SECOND_AVAIL_BITS_SHIFT 54
|
||||
|
||||
/*
|
||||
* The mask used to denote special SPTEs, which can be either MMIO SPTEs or
|
||||
* Access Tracking SPTEs.
|
||||
*/
|
||||
#define SPTE_SPECIAL_MASK (3ULL << 52)
|
||||
#define SPTE_AD_ENABLED_MASK (0ULL << 52)
|
||||
#define SPTE_AD_DISABLED_MASK (1ULL << 52)
|
||||
#define SPTE_AD_WRPROT_ONLY_MASK (2ULL << 52)
|
||||
#define SPTE_MMIO_MASK (3ULL << 52)
|
||||
|
||||
#define PT64_LEVEL_BITS 9
|
||||
|
||||
@ -219,12 +229,11 @@ static u64 __read_mostly shadow_present_mask;
|
||||
static u64 __read_mostly shadow_me_mask;
|
||||
|
||||
/*
|
||||
* SPTEs used by MMUs without A/D bits are marked with shadow_acc_track_value.
|
||||
* Non-present SPTEs with shadow_acc_track_value set are in place for access
|
||||
* tracking.
|
||||
* SPTEs used by MMUs without A/D bits are marked with SPTE_AD_DISABLED_MASK;
|
||||
* shadow_acc_track_mask is the set of bits to be cleared in non-accessed
|
||||
* pages.
|
||||
*/
|
||||
static u64 __read_mostly shadow_acc_track_mask;
|
||||
static const u64 shadow_acc_track_value = SPTE_SPECIAL_MASK;
|
||||
|
||||
/*
|
||||
* The mask/shift to use for saving the original R/X bits when marking the PTE
|
||||
@ -304,7 +313,7 @@ void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask, u64 mmio_value, u64 access_mask)
|
||||
{
|
||||
BUG_ON((u64)(unsigned)access_mask != access_mask);
|
||||
BUG_ON((mmio_mask & mmio_value) != mmio_value);
|
||||
shadow_mmio_value = mmio_value | SPTE_SPECIAL_MASK;
|
||||
shadow_mmio_value = mmio_value | SPTE_MMIO_MASK;
|
||||
shadow_mmio_mask = mmio_mask | SPTE_SPECIAL_MASK;
|
||||
shadow_mmio_access_mask = access_mask;
|
||||
}
|
||||
@ -320,10 +329,27 @@ static inline bool sp_ad_disabled(struct kvm_mmu_page *sp)
|
||||
return sp->role.ad_disabled;
|
||||
}
|
||||
|
||||
static inline bool kvm_vcpu_ad_need_write_protect(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
/*
|
||||
* When using the EPT page-modification log, the GPAs in the log
|
||||
* would come from L2 rather than L1. Therefore, we need to rely
|
||||
* on write protection to record dirty pages. This also bypasses
|
||||
* PML, since writes now result in a vmexit.
|
||||
*/
|
||||
return vcpu->arch.mmu == &vcpu->arch.guest_mmu;
|
||||
}
|
||||
|
||||
static inline bool spte_ad_enabled(u64 spte)
|
||||
{
|
||||
MMU_WARN_ON(is_mmio_spte(spte));
|
||||
return !(spte & shadow_acc_track_value);
|
||||
return (spte & SPTE_SPECIAL_MASK) != SPTE_AD_DISABLED_MASK;
|
||||
}
|
||||
|
||||
static inline bool spte_ad_need_write_protect(u64 spte)
|
||||
{
|
||||
MMU_WARN_ON(is_mmio_spte(spte));
|
||||
return (spte & SPTE_SPECIAL_MASK) != SPTE_AD_ENABLED_MASK;
|
||||
}
|
||||
|
||||
static inline u64 spte_shadow_accessed_mask(u64 spte)
|
||||
@ -461,7 +487,7 @@ void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
|
||||
{
|
||||
BUG_ON(!dirty_mask != !accessed_mask);
|
||||
BUG_ON(!accessed_mask && !acc_track_mask);
|
||||
BUG_ON(acc_track_mask & shadow_acc_track_value);
|
||||
BUG_ON(acc_track_mask & SPTE_SPECIAL_MASK);
|
||||
|
||||
shadow_user_mask = user_mask;
|
||||
shadow_accessed_mask = accessed_mask;
|
||||
@ -1589,16 +1615,16 @@ static bool spte_clear_dirty(u64 *sptep)
|
||||
|
||||
rmap_printk("rmap_clear_dirty: spte %p %llx\n", sptep, *sptep);
|
||||
|
||||
MMU_WARN_ON(!spte_ad_enabled(spte));
|
||||
spte &= ~shadow_dirty_mask;
|
||||
|
||||
return mmu_spte_update(sptep, spte);
|
||||
}
|
||||
|
||||
static bool wrprot_ad_disabled_spte(u64 *sptep)
|
||||
static bool spte_wrprot_for_clear_dirty(u64 *sptep)
|
||||
{
|
||||
bool was_writable = test_and_clear_bit(PT_WRITABLE_SHIFT,
|
||||
(unsigned long *)sptep);
|
||||
if (was_writable)
|
||||
if (was_writable && !spte_ad_enabled(*sptep))
|
||||
kvm_set_pfn_dirty(spte_to_pfn(*sptep));
|
||||
|
||||
return was_writable;
|
||||
@ -1617,10 +1643,10 @@ static bool __rmap_clear_dirty(struct kvm *kvm, struct kvm_rmap_head *rmap_head)
|
||||
bool flush = false;
|
||||
|
||||
for_each_rmap_spte(rmap_head, &iter, sptep)
|
||||
if (spte_ad_enabled(*sptep))
|
||||
flush |= spte_clear_dirty(sptep);
|
||||
if (spte_ad_need_write_protect(*sptep))
|
||||
flush |= spte_wrprot_for_clear_dirty(sptep);
|
||||
else
|
||||
flush |= wrprot_ad_disabled_spte(sptep);
|
||||
flush |= spte_clear_dirty(sptep);
|
||||
|
||||
return flush;
|
||||
}
|
||||
@ -1631,6 +1657,11 @@ static bool spte_set_dirty(u64 *sptep)
|
||||
|
||||
rmap_printk("rmap_set_dirty: spte %p %llx\n", sptep, *sptep);
|
||||
|
||||
/*
|
||||
* Similar to the !kvm_x86_ops->slot_disable_log_dirty case,
|
||||
* do not bother adding back write access to pages marked
|
||||
* SPTE_AD_WRPROT_ONLY_MASK.
|
||||
*/
|
||||
spte |= shadow_dirty_mask;
|
||||
|
||||
return mmu_spte_update(sptep, spte);
|
||||
@ -2622,7 +2653,7 @@ static void link_shadow_page(struct kvm_vcpu *vcpu, u64 *sptep,
|
||||
shadow_user_mask | shadow_x_mask | shadow_me_mask;
|
||||
|
||||
if (sp_ad_disabled(sp))
|
||||
spte |= shadow_acc_track_value;
|
||||
spte |= SPTE_AD_DISABLED_MASK;
|
||||
else
|
||||
spte |= shadow_accessed_mask;
|
||||
|
||||
@ -2968,7 +2999,9 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
|
||||
|
||||
sp = page_header(__pa(sptep));
|
||||
if (sp_ad_disabled(sp))
|
||||
spte |= shadow_acc_track_value;
|
||||
spte |= SPTE_AD_DISABLED_MASK;
|
||||
else if (kvm_vcpu_ad_need_write_protect(vcpu))
|
||||
spte |= SPTE_AD_WRPROT_ONLY_MASK;
|
||||
|
||||
/*
|
||||
* For the EPT case, shadow_present_mask is 0 if hardware
|
||||
|
@ -2610,7 +2610,7 @@ static int nested_check_vm_entry_controls(struct kvm_vcpu *vcpu,
|
||||
|
||||
/* VM-entry exception error code */
|
||||
if (CC(has_error_code &&
|
||||
vmcs12->vm_entry_exception_error_code & GENMASK(31, 15)))
|
||||
vmcs12->vm_entry_exception_error_code & GENMASK(31, 16)))
|
||||
return -EINVAL;
|
||||
|
||||
/* VM-entry interruption-info field: reserved bits */
|
||||
|
@ -262,6 +262,7 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
||||
static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
|
||||
struct x86_pmu_capability x86_pmu;
|
||||
struct kvm_cpuid_entry2 *entry;
|
||||
union cpuid10_eax eax;
|
||||
union cpuid10_edx edx;
|
||||
@ -283,8 +284,10 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
|
||||
if (!pmu->version)
|
||||
return;
|
||||
|
||||
perf_get_x86_pmu_capability(&x86_pmu);
|
||||
|
||||
pmu->nr_arch_gp_counters = min_t(int, eax.split.num_counters,
|
||||
INTEL_PMC_MAX_GENERIC);
|
||||
x86_pmu.num_counters_gp);
|
||||
pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << eax.split.bit_width) - 1;
|
||||
pmu->available_event_types = ~entry->ebx &
|
||||
((1ull << eax.split.mask_length) - 1);
|
||||
@ -294,7 +297,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
|
||||
} else {
|
||||
pmu->nr_arch_fixed_counters =
|
||||
min_t(int, edx.split.num_counters_fixed,
|
||||
INTEL_PMC_MAX_FIXED);
|
||||
x86_pmu.num_counters_fixed);
|
||||
pmu->counter_bitmask[KVM_PMC_FIXED] =
|
||||
((u64)1 << edx.split.bit_width_fixed) - 1;
|
||||
}
|
||||
|
@ -209,6 +209,11 @@ static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf)
|
||||
struct page *page;
|
||||
unsigned int i;
|
||||
|
||||
if (!boot_cpu_has_bug(X86_BUG_L1TF)) {
|
||||
l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_NOT_REQUIRED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!enable_ept) {
|
||||
l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_EPT_DISABLED;
|
||||
return 0;
|
||||
@ -7995,12 +8000,10 @@ static int __init vmx_init(void)
|
||||
* contain 'auto' which will be turned into the default 'cond'
|
||||
* mitigation mode.
|
||||
*/
|
||||
if (boot_cpu_has(X86_BUG_L1TF)) {
|
||||
r = vmx_setup_l1d_flush(vmentry_l1d_flush_param);
|
||||
if (r) {
|
||||
vmx_exit();
|
||||
return r;
|
||||
}
|
||||
r = vmx_setup_l1d_flush(vmentry_l1d_flush_param);
|
||||
if (r) {
|
||||
vmx_exit();
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KEXEC_CORE
|
||||
|
@ -92,8 +92,8 @@ u64 __read_mostly efer_reserved_bits = ~((u64)(EFER_SCE | EFER_LME | EFER_LMA));
|
||||
static u64 __read_mostly efer_reserved_bits = ~((u64)EFER_SCE);
|
||||
#endif
|
||||
|
||||
#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
|
||||
#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
|
||||
#define VM_STAT(x, ...) offsetof(struct kvm, stat.x), KVM_STAT_VM, ## __VA_ARGS__
|
||||
#define VCPU_STAT(x, ...) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU, ## __VA_ARGS__
|
||||
|
||||
#define KVM_X2APIC_API_VALID_FLAGS (KVM_X2APIC_API_USE_32BIT_IDS | \
|
||||
KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK)
|
||||
@ -212,7 +212,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
|
||||
{ "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
|
||||
{ "mmu_unsync", VM_STAT(mmu_unsync) },
|
||||
{ "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
|
||||
{ "largepages", VM_STAT(lpages) },
|
||||
{ "largepages", VM_STAT(lpages, .mode = 0444) },
|
||||
{ "max_mmu_page_hash_collisions",
|
||||
VM_STAT(max_mmu_page_hash_collisions) },
|
||||
{ NULL }
|
||||
@ -885,34 +885,42 @@ int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_set_xcr);
|
||||
|
||||
static int kvm_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
|
||||
{
|
||||
if (cr4 & CR4_RESERVED_BITS)
|
||||
return -EINVAL;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_XSAVE) && (cr4 & X86_CR4_OSXSAVE))
|
||||
return -EINVAL;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_SMEP) && (cr4 & X86_CR4_SMEP))
|
||||
return -EINVAL;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_SMAP) && (cr4 & X86_CR4_SMAP))
|
||||
return -EINVAL;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_FSGSBASE) && (cr4 & X86_CR4_FSGSBASE))
|
||||
return -EINVAL;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_PKU) && (cr4 & X86_CR4_PKE))
|
||||
return -EINVAL;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_LA57) && (cr4 & X86_CR4_LA57))
|
||||
return -EINVAL;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_UMIP) && (cr4 & X86_CR4_UMIP))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
|
||||
{
|
||||
unsigned long old_cr4 = kvm_read_cr4(vcpu);
|
||||
unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE |
|
||||
X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE;
|
||||
|
||||
if (cr4 & CR4_RESERVED_BITS)
|
||||
return 1;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_XSAVE) && (cr4 & X86_CR4_OSXSAVE))
|
||||
return 1;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_SMEP) && (cr4 & X86_CR4_SMEP))
|
||||
return 1;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_SMAP) && (cr4 & X86_CR4_SMAP))
|
||||
return 1;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_FSGSBASE) && (cr4 & X86_CR4_FSGSBASE))
|
||||
return 1;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_PKU) && (cr4 & X86_CR4_PKE))
|
||||
return 1;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_LA57) && (cr4 & X86_CR4_LA57))
|
||||
return 1;
|
||||
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_UMIP) && (cr4 & X86_CR4_UMIP))
|
||||
if (kvm_valid_cr4(vcpu, cr4))
|
||||
return 1;
|
||||
|
||||
if (is_long_mode(vcpu)) {
|
||||
@ -1161,13 +1169,6 @@ static u32 msrs_to_save[] = {
|
||||
MSR_ARCH_PERFMON_PERFCTR0 + 12, MSR_ARCH_PERFMON_PERFCTR0 + 13,
|
||||
MSR_ARCH_PERFMON_PERFCTR0 + 14, MSR_ARCH_PERFMON_PERFCTR0 + 15,
|
||||
MSR_ARCH_PERFMON_PERFCTR0 + 16, MSR_ARCH_PERFMON_PERFCTR0 + 17,
|
||||
MSR_ARCH_PERFMON_PERFCTR0 + 18, MSR_ARCH_PERFMON_PERFCTR0 + 19,
|
||||
MSR_ARCH_PERFMON_PERFCTR0 + 20, MSR_ARCH_PERFMON_PERFCTR0 + 21,
|
||||
MSR_ARCH_PERFMON_PERFCTR0 + 22, MSR_ARCH_PERFMON_PERFCTR0 + 23,
|
||||
MSR_ARCH_PERFMON_PERFCTR0 + 24, MSR_ARCH_PERFMON_PERFCTR0 + 25,
|
||||
MSR_ARCH_PERFMON_PERFCTR0 + 26, MSR_ARCH_PERFMON_PERFCTR0 + 27,
|
||||
MSR_ARCH_PERFMON_PERFCTR0 + 28, MSR_ARCH_PERFMON_PERFCTR0 + 29,
|
||||
MSR_ARCH_PERFMON_PERFCTR0 + 30, MSR_ARCH_PERFMON_PERFCTR0 + 31,
|
||||
MSR_ARCH_PERFMON_EVENTSEL0, MSR_ARCH_PERFMON_EVENTSEL1,
|
||||
MSR_ARCH_PERFMON_EVENTSEL0 + 2, MSR_ARCH_PERFMON_EVENTSEL0 + 3,
|
||||
MSR_ARCH_PERFMON_EVENTSEL0 + 4, MSR_ARCH_PERFMON_EVENTSEL0 + 5,
|
||||
@ -1177,13 +1178,6 @@ static u32 msrs_to_save[] = {
|
||||
MSR_ARCH_PERFMON_EVENTSEL0 + 12, MSR_ARCH_PERFMON_EVENTSEL0 + 13,
|
||||
MSR_ARCH_PERFMON_EVENTSEL0 + 14, MSR_ARCH_PERFMON_EVENTSEL0 + 15,
|
||||
MSR_ARCH_PERFMON_EVENTSEL0 + 16, MSR_ARCH_PERFMON_EVENTSEL0 + 17,
|
||||
MSR_ARCH_PERFMON_EVENTSEL0 + 18, MSR_ARCH_PERFMON_EVENTSEL0 + 19,
|
||||
MSR_ARCH_PERFMON_EVENTSEL0 + 20, MSR_ARCH_PERFMON_EVENTSEL0 + 21,
|
||||
MSR_ARCH_PERFMON_EVENTSEL0 + 22, MSR_ARCH_PERFMON_EVENTSEL0 + 23,
|
||||
MSR_ARCH_PERFMON_EVENTSEL0 + 24, MSR_ARCH_PERFMON_EVENTSEL0 + 25,
|
||||
MSR_ARCH_PERFMON_EVENTSEL0 + 26, MSR_ARCH_PERFMON_EVENTSEL0 + 27,
|
||||
MSR_ARCH_PERFMON_EVENTSEL0 + 28, MSR_ARCH_PERFMON_EVENTSEL0 + 29,
|
||||
MSR_ARCH_PERFMON_EVENTSEL0 + 30, MSR_ARCH_PERFMON_EVENTSEL0 + 31,
|
||||
};
|
||||
|
||||
static unsigned num_msrs_to_save;
|
||||
@ -5097,13 +5091,14 @@ out:
|
||||
|
||||
static void kvm_init_msr_list(void)
|
||||
{
|
||||
struct x86_pmu_capability x86_pmu;
|
||||
u32 dummy[2];
|
||||
unsigned i, j;
|
||||
|
||||
BUILD_BUG_ON_MSG(INTEL_PMC_MAX_FIXED != 4,
|
||||
"Please update the fixed PMCs in msrs_to_save[]");
|
||||
BUILD_BUG_ON_MSG(INTEL_PMC_MAX_GENERIC != 32,
|
||||
"Please update the generic perfctr/eventsel MSRs in msrs_to_save[]");
|
||||
|
||||
perf_get_x86_pmu_capability(&x86_pmu);
|
||||
|
||||
for (i = j = 0; i < ARRAY_SIZE(msrs_to_save); i++) {
|
||||
if (rdmsr_safe(msrs_to_save[i], &dummy[0], &dummy[1]) < 0)
|
||||
@ -5145,6 +5140,15 @@ static void kvm_init_msr_list(void)
|
||||
intel_pt_validate_hw_cap(PT_CAP_num_address_ranges) * 2)
|
||||
continue;
|
||||
break;
|
||||
case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR0 + 17:
|
||||
if (msrs_to_save[i] - MSR_ARCH_PERFMON_PERFCTR0 >=
|
||||
min(INTEL_PMC_MAX_GENERIC, x86_pmu.num_counters_gp))
|
||||
continue;
|
||||
break;
|
||||
case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL0 + 17:
|
||||
if (msrs_to_save[i] - MSR_ARCH_PERFMON_EVENTSEL0 >=
|
||||
min(INTEL_PMC_MAX_GENERIC, x86_pmu.num_counters_gp))
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@ -8714,10 +8718,6 @@ EXPORT_SYMBOL_GPL(kvm_task_switch);
|
||||
|
||||
static int kvm_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
|
||||
{
|
||||
if (!guest_cpuid_has(vcpu, X86_FEATURE_XSAVE) &&
|
||||
(sregs->cr4 & X86_CR4_OSXSAVE))
|
||||
return -EINVAL;
|
||||
|
||||
if ((sregs->efer & EFER_LME) && (sregs->cr0 & X86_CR0_PG)) {
|
||||
/*
|
||||
* When EFER.LME and CR0.PG are set, the processor is in
|
||||
@ -8736,7 +8736,7 @@ static int kvm_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return kvm_valid_cr4(vcpu, sregs->cr4);
|
||||
}
|
||||
|
||||
static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
|
||||
|
@ -57,19 +57,7 @@ static efi_system_table_t __init *xen_efi_probe(void)
|
||||
return NULL;
|
||||
|
||||
/* Here we know that Xen runs on EFI platform. */
|
||||
|
||||
efi.get_time = xen_efi_get_time;
|
||||
efi.set_time = xen_efi_set_time;
|
||||
efi.get_wakeup_time = xen_efi_get_wakeup_time;
|
||||
efi.set_wakeup_time = xen_efi_set_wakeup_time;
|
||||
efi.get_variable = xen_efi_get_variable;
|
||||
efi.get_next_variable = xen_efi_get_next_variable;
|
||||
efi.set_variable = xen_efi_set_variable;
|
||||
efi.query_variable_info = xen_efi_query_variable_info;
|
||||
efi.update_capsule = xen_efi_update_capsule;
|
||||
efi.query_capsule_caps = xen_efi_query_capsule_caps;
|
||||
efi.get_next_high_mono_count = xen_efi_get_next_high_mono_count;
|
||||
efi.reset_system = xen_efi_reset_system;
|
||||
xen_efi_runtime_setup();
|
||||
|
||||
efi_systab_xen.tables = info->cfg.addr;
|
||||
efi_systab_xen.nr_tables = info->cfg.nent;
|
||||
|
@ -1992,10 +1992,14 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
|
||||
/* bypass scheduler for flush rq */
|
||||
blk_insert_flush(rq);
|
||||
blk_mq_run_hw_queue(data.hctx, true);
|
||||
} else if (plug && (q->nr_hw_queues == 1 || q->mq_ops->commit_rqs)) {
|
||||
} else if (plug && (q->nr_hw_queues == 1 || q->mq_ops->commit_rqs ||
|
||||
!blk_queue_nonrot(q))) {
|
||||
/*
|
||||
* Use plugging if we have a ->commit_rqs() hook as well, as
|
||||
* we know the driver uses bd->last in a smart fashion.
|
||||
*
|
||||
* Use normal plugging if this disk is slow HDD, as sequential
|
||||
* IO may benefit a lot from plug merging.
|
||||
*/
|
||||
unsigned int request_count = plug->rq_count;
|
||||
struct request *last = NULL;
|
||||
@ -2012,6 +2016,8 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
|
||||
}
|
||||
|
||||
blk_add_rq_to_plug(plug, rq);
|
||||
} else if (q->elevator) {
|
||||
blk_mq_sched_insert_request(rq, false, true, true);
|
||||
} else if (plug && !blk_queue_nomerges(q)) {
|
||||
/*
|
||||
* We do limited plugging. If the bio can be merged, do that.
|
||||
@ -2035,8 +2041,8 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
|
||||
blk_mq_try_issue_directly(data.hctx, same_queue_rq,
|
||||
&cookie);
|
||||
}
|
||||
} else if ((q->nr_hw_queues > 1 && is_sync) || (!q->elevator &&
|
||||
!data.hctx->dispatch_busy)) {
|
||||
} else if ((q->nr_hw_queues > 1 && is_sync) ||
|
||||
!data.hctx->dispatch_busy) {
|
||||
blk_mq_try_issue_directly(data.hctx, rq, &cookie);
|
||||
} else {
|
||||
blk_mq_sched_insert_request(rq, false, true, true);
|
||||
|
@ -129,7 +129,7 @@ static const u8 opaluid[][OPAL_UID_LENGTH] = {
|
||||
{ 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x84, 0x01 },
|
||||
|
||||
/* tables */
|
||||
[OPAL_TABLE_TABLE]
|
||||
[OPAL_TABLE_TABLE] =
|
||||
{ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01 },
|
||||
[OPAL_LOCKINGRANGE_GLOBAL] =
|
||||
{ 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x01 },
|
||||
@ -372,8 +372,8 @@ static void check_geometry(struct opal_dev *dev, const void *data)
|
||||
{
|
||||
const struct d0_geometry_features *geo = data;
|
||||
|
||||
dev->align = geo->alignment_granularity;
|
||||
dev->lowest_lba = geo->lowest_aligned_lba;
|
||||
dev->align = be64_to_cpu(geo->alignment_granularity);
|
||||
dev->lowest_lba = be64_to_cpu(geo->lowest_aligned_lba);
|
||||
}
|
||||
|
||||
static int execute_step(struct opal_dev *dev,
|
||||
|
@ -994,6 +994,16 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
|
||||
if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync)
|
||||
blk_queue_write_cache(lo->lo_queue, true, false);
|
||||
|
||||
if (io_is_direct(lo->lo_backing_file) && inode->i_sb->s_bdev) {
|
||||
/* In case of direct I/O, match underlying block size */
|
||||
unsigned short bsize = bdev_logical_block_size(
|
||||
inode->i_sb->s_bdev);
|
||||
|
||||
blk_queue_logical_block_size(lo->lo_queue, bsize);
|
||||
blk_queue_physical_block_size(lo->lo_queue, bsize);
|
||||
blk_queue_io_min(lo->lo_queue, bsize);
|
||||
}
|
||||
|
||||
loop_update_rotational(lo);
|
||||
loop_update_dio(lo);
|
||||
set_capacity(lo->lo_disk, size);
|
||||
|
@ -280,9 +280,6 @@ static int sysc_get_one_clock(struct sysc *ddata, const char *name)
|
||||
|
||||
ddata->clocks[index] = devm_clk_get(ddata->dev, name);
|
||||
if (IS_ERR(ddata->clocks[index])) {
|
||||
if (PTR_ERR(ddata->clocks[index]) == -ENOENT)
|
||||
return 0;
|
||||
|
||||
dev_err(ddata->dev, "clock get error for %s: %li\n",
|
||||
name, PTR_ERR(ddata->clocks[index]));
|
||||
|
||||
@ -357,7 +354,7 @@ static int sysc_get_clocks(struct sysc *ddata)
|
||||
continue;
|
||||
|
||||
error = sysc_get_one_clock(ddata, name);
|
||||
if (error && error != -ENOENT)
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1632,17 +1629,19 @@ static int sysc_init_module(struct sysc *ddata)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (manage_clocks) {
|
||||
sysc_clkdm_deny_idle(ddata);
|
||||
sysc_clkdm_deny_idle(ddata);
|
||||
|
||||
error = sysc_enable_opt_clocks(ddata);
|
||||
if (error)
|
||||
return error;
|
||||
/*
|
||||
* Always enable clocks. The bootloader may or may not have enabled
|
||||
* the related clocks.
|
||||
*/
|
||||
error = sysc_enable_opt_clocks(ddata);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = sysc_enable_main_clocks(ddata);
|
||||
if (error)
|
||||
goto err_opt_clocks;
|
||||
}
|
||||
error = sysc_enable_main_clocks(ddata);
|
||||
if (error)
|
||||
goto err_opt_clocks;
|
||||
|
||||
if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) {
|
||||
error = sysc_rstctrl_reset_deassert(ddata, true);
|
||||
@ -1660,7 +1659,7 @@ static int sysc_init_module(struct sysc *ddata)
|
||||
goto err_main_clocks;
|
||||
}
|
||||
|
||||
if (!ddata->legacy_mode && manage_clocks) {
|
||||
if (!ddata->legacy_mode) {
|
||||
error = sysc_enable_module(ddata->dev);
|
||||
if (error)
|
||||
goto err_main_clocks;
|
||||
@ -1677,6 +1676,7 @@ err_main_clocks:
|
||||
if (manage_clocks)
|
||||
sysc_disable_main_clocks(ddata);
|
||||
err_opt_clocks:
|
||||
/* No re-enable of clockdomain autoidle to prevent module autoidle */
|
||||
if (manage_clocks) {
|
||||
sysc_disable_opt_clocks(ddata);
|
||||
sysc_clkdm_allow_idle(ddata);
|
||||
@ -2357,6 +2357,27 @@ static void ti_sysc_idle(struct work_struct *work)
|
||||
|
||||
ddata = container_of(work, struct sysc, idle_work.work);
|
||||
|
||||
/*
|
||||
* One time decrement of clock usage counts if left on from init.
|
||||
* Note that we disable opt clocks unconditionally in this case
|
||||
* as they are enabled unconditionally during init without
|
||||
* considering sysc_opt_clks_needed() at that point.
|
||||
*/
|
||||
if (ddata->cfg.quirks & (SYSC_QUIRK_NO_IDLE |
|
||||
SYSC_QUIRK_NO_IDLE_ON_INIT)) {
|
||||
sysc_disable_main_clocks(ddata);
|
||||
sysc_disable_opt_clocks(ddata);
|
||||
sysc_clkdm_allow_idle(ddata);
|
||||
}
|
||||
|
||||
/* Keep permanent PM runtime usage count for SYSC_QUIRK_NO_IDLE */
|
||||
if (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Decrement PM runtime usage count for SYSC_QUIRK_NO_IDLE_ON_INIT
|
||||
* and SYSC_QUIRK_NO_RESET_ON_INIT
|
||||
*/
|
||||
if (pm_runtime_active(ddata->dev))
|
||||
pm_runtime_put_sync(ddata->dev);
|
||||
}
|
||||
@ -2445,7 +2466,8 @@ static int sysc_probe(struct platform_device *pdev)
|
||||
INIT_DELAYED_WORK(&ddata->idle_work, ti_sysc_idle);
|
||||
|
||||
/* At least earlycon won't survive without deferred idle */
|
||||
if (ddata->cfg.quirks & (SYSC_QUIRK_NO_IDLE_ON_INIT |
|
||||
if (ddata->cfg.quirks & (SYSC_QUIRK_NO_IDLE |
|
||||
SYSC_QUIRK_NO_IDLE_ON_INIT |
|
||||
SYSC_QUIRK_NO_RESET_ON_INIT)) {
|
||||
schedule_delayed_work(&ddata->idle_work, 3000);
|
||||
} else {
|
||||
|
@ -1732,6 +1732,56 @@ void get_random_bytes(void *buf, int nbytes)
|
||||
}
|
||||
EXPORT_SYMBOL(get_random_bytes);
|
||||
|
||||
|
||||
/*
|
||||
* Each time the timer fires, we expect that we got an unpredictable
|
||||
* jump in the cycle counter. Even if the timer is running on another
|
||||
* CPU, the timer activity will be touching the stack of the CPU that is
|
||||
* generating entropy..
|
||||
*
|
||||
* Note that we don't re-arm the timer in the timer itself - we are
|
||||
* happy to be scheduled away, since that just makes the load more
|
||||
* complex, but we do not want the timer to keep ticking unless the
|
||||
* entropy loop is running.
|
||||
*
|
||||
* So the re-arming always happens in the entropy loop itself.
|
||||
*/
|
||||
static void entropy_timer(struct timer_list *t)
|
||||
{
|
||||
credit_entropy_bits(&input_pool, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have an actual cycle counter, see if we can
|
||||
* generate enough entropy with timing noise
|
||||
*/
|
||||
static void try_to_generate_entropy(void)
|
||||
{
|
||||
struct {
|
||||
unsigned long now;
|
||||
struct timer_list timer;
|
||||
} stack;
|
||||
|
||||
stack.now = random_get_entropy();
|
||||
|
||||
/* Slow counter - or none. Don't even bother */
|
||||
if (stack.now == random_get_entropy())
|
||||
return;
|
||||
|
||||
timer_setup_on_stack(&stack.timer, entropy_timer, 0);
|
||||
while (!crng_ready()) {
|
||||
if (!timer_pending(&stack.timer))
|
||||
mod_timer(&stack.timer, jiffies+1);
|
||||
mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
|
||||
schedule();
|
||||
stack.now = random_get_entropy();
|
||||
}
|
||||
|
||||
del_timer_sync(&stack.timer);
|
||||
destroy_timer_on_stack(&stack.timer);
|
||||
mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the urandom pool to be seeded and thus guaranteed to supply
|
||||
* cryptographically secure random numbers. This applies to: the /dev/urandom
|
||||
@ -1746,7 +1796,17 @@ int wait_for_random_bytes(void)
|
||||
{
|
||||
if (likely(crng_ready()))
|
||||
return 0;
|
||||
return wait_event_interruptible(crng_init_wait, crng_ready());
|
||||
|
||||
do {
|
||||
int ret;
|
||||
ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
|
||||
if (ret)
|
||||
return ret > 0 ? 0 : ret;
|
||||
|
||||
try_to_generate_entropy();
|
||||
} while (!crng_ready());
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(wait_for_random_bytes);
|
||||
|
||||
@ -2460,4 +2520,4 @@ void add_bootloader_randomness(const void *buf, unsigned int size)
|
||||
else
|
||||
add_device_randomness(buf, size);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(add_bootloader_randomness);
|
||||
EXPORT_SYMBOL_GPL(add_bootloader_randomness);
|
||||
|
@ -25,7 +25,9 @@ static __init void timer_of_irq_exit(struct of_timer_irq *of_irq)
|
||||
|
||||
struct clock_event_device *clkevt = &to->clkevt;
|
||||
|
||||
of_irq->percpu ? free_percpu_irq(of_irq->irq, clkevt) :
|
||||
if (of_irq->percpu)
|
||||
free_percpu_irq(of_irq->irq, clkevt);
|
||||
else
|
||||
free_irq(of_irq->irq, clkevt);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user