mirror of
https://github.com/torvalds/linux.git
synced 2025-10-30 16:18:41 +02:00
Merge branch 'no-rebase-mnt_ns_tree_remove'
Bring in the fix for removing a mount namespace from the mount namespace rbtree and list. Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
commit
7914f15c5e
850 changed files with 9080 additions and 4933 deletions
2
.mailmap
2
.mailmap
|
|
@ -226,6 +226,8 @@ Domen Puncer <domen@coderock.org>
|
|||
Douglas Gilbert <dougg@torque.net>
|
||||
Drew Fustini <fustini@kernel.org> <drew@pdp7.com>
|
||||
<duje@dujemihanovic.xyz> <duje.mihanovic@skole.hr>
|
||||
Easwar Hariharan <easwar.hariharan@linux.microsoft.com> <easwar.hariharan@intel.com>
|
||||
Easwar Hariharan <easwar.hariharan@linux.microsoft.com> <eahariha@linux.microsoft.com>
|
||||
Ed L. Cashin <ecashin@coraid.com>
|
||||
Elliot Berman <quic_eberman@quicinc.com> <eberman@codeaurora.org>
|
||||
Enric Balletbo i Serra <eballetbo@kernel.org> <enric.balletbo@collabora.com>
|
||||
|
|
|
|||
7
CREDITS
7
CREDITS
|
|
@ -3222,6 +3222,10 @@ D: AIC5800 IEEE 1394, RAW I/O on 1394
|
|||
D: Starter of Linux1394 effort
|
||||
S: ask per mail for current address
|
||||
|
||||
N: Boris Pismenny
|
||||
E: borisp@mellanox.com
|
||||
D: Kernel TLS implementation and offload support.
|
||||
|
||||
N: Nicolas Pitre
|
||||
E: nico@fluxnic.net
|
||||
D: StrongARM SA1100 support integrator & hacker
|
||||
|
|
@ -4168,6 +4172,9 @@ S: 1513 Brewster Dr.
|
|||
S: Carrollton, TX 75010
|
||||
S: USA
|
||||
|
||||
N: Dave Watson
|
||||
D: Kernel TLS implementation.
|
||||
|
||||
N: Tim Waugh
|
||||
E: tim@cyberelk.net
|
||||
D: Co-architect of the parallel-port sharing system
|
||||
|
|
|
|||
|
|
@ -731,7 +731,7 @@ Contact: linux-block@vger.kernel.org
|
|||
Description:
|
||||
[RW] If the device is registered for writeback throttling, then
|
||||
this file shows the target minimum read latency. If this latency
|
||||
is exceeded in a given window of time (see wb_window_usec), then
|
||||
is exceeded in a given window of time (see curr_win_nsec), then
|
||||
the writeback throttling will start scaling back writes. Writing
|
||||
a value of '0' to this file disables the feature. Writing a
|
||||
value of '-1' to this file resets the value to the default
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ zone_capacity_mb Device zone capacity (must always be equal to or lower than
|
|||
the zone size. Default: zone size.
|
||||
conv_zones Total number of conventioanl zones starting from sector 0.
|
||||
Default: 8.
|
||||
base_dir Path to the base directoy where to create the directory
|
||||
base_dir Path to the base directory where to create the directory
|
||||
containing the zone files of the device.
|
||||
Default=/var/local/zloop.
|
||||
The device directory containing the zone files is always
|
||||
|
|
|
|||
|
|
@ -435,8 +435,8 @@ both cgroups.
|
|||
Controlling Controllers
|
||||
-----------------------
|
||||
|
||||
Availablity
|
||||
~~~~~~~~~~~
|
||||
Availability
|
||||
~~~~~~~~~~~~
|
||||
|
||||
A controller is available in a cgroup when it is supported by the kernel (i.e.,
|
||||
compiled in, not disabled and not attached to a v1 hierarchy) and listed in the
|
||||
|
|
|
|||
|
|
@ -214,8 +214,8 @@ Spectre_v1 X
|
|||
Spectre_v2 X X
|
||||
Spectre_v2_user X X * (Note 1)
|
||||
SRBDS X X X X
|
||||
SRSO X X
|
||||
SSB (Note 4)
|
||||
SRSO X X X X
|
||||
SSB X
|
||||
TAA X X X X * (Note 2)
|
||||
TSA X X X X
|
||||
=============== ============== ============ ============= ============== ============ ========
|
||||
|
|
@ -229,9 +229,6 @@ Notes:
|
|||
3 -- Disables SMT if cross-thread mitigations are fully enabled, the CPU is
|
||||
vulnerable, and STIBP is not supported
|
||||
|
||||
4 -- Speculative store bypass is always enabled by default (no kernel
|
||||
mitigation applied) unless overridden with spec_store_bypass_disable option
|
||||
|
||||
When an attack-vector is disabled, all mitigations for the vulnerabilities
|
||||
listed in the above table are disabled, unless mitigation is required for a
|
||||
different enabled attack-vector or a mitigation is explicitly selected via a
|
||||
|
|
|
|||
|
|
@ -76,20 +76,21 @@ unit as preprocessor statement. The above example would then read::
|
|||
within the corresponding compilation unit before the #include for
|
||||
<linux/export.h>. Typically it's placed before the first #include statement.
|
||||
|
||||
Using the EXPORT_SYMBOL_GPL_FOR_MODULES() macro
|
||||
-----------------------------------------------
|
||||
Using the EXPORT_SYMBOL_FOR_MODULES() macro
|
||||
-------------------------------------------
|
||||
|
||||
Symbols exported using this macro are put into a module namespace. This
|
||||
namespace cannot be imported.
|
||||
namespace cannot be imported. These exports are GPL-only as they are only
|
||||
intended for in-tree modules.
|
||||
|
||||
The macro takes a comma separated list of module names, allowing only those
|
||||
modules to access this symbol. Simple tail-globs are supported.
|
||||
|
||||
For example::
|
||||
|
||||
EXPORT_SYMBOL_GPL_FOR_MODULES(preempt_notifier_inc, "kvm,kvm-*")
|
||||
EXPORT_SYMBOL_FOR_MODULES(preempt_notifier_inc, "kvm,kvm-*")
|
||||
|
||||
will limit usage of this symbol to modules whoes name matches the given
|
||||
will limit usage of this symbol to modules whose name matches the given
|
||||
patterns.
|
||||
|
||||
How to use Symbols exported in Namespaces
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ properties:
|
|||
- const: bus
|
||||
- const: core
|
||||
- const: vsync
|
||||
- const: lut
|
||||
- const: tbu
|
||||
- const: tbu_rt
|
||||
# MSM8996 has additional iommu clock
|
||||
|
|
|
|||
|
|
@ -62,11 +62,13 @@ properties:
|
|||
items:
|
||||
- description: GMAC main clock
|
||||
- description: Peripheral registers interface clock
|
||||
- description: APB glue registers interface clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: stmmaceth
|
||||
- const: pclk
|
||||
- const: apb
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
|
|
@ -88,8 +90,8 @@ examples:
|
|||
compatible = "thead,th1520-gmac", "snps,dwmac-3.70a";
|
||||
reg = <0xe7070000 0x2000>, <0xec003000 0x1000>;
|
||||
reg-names = "dwmac", "apb";
|
||||
clocks = <&clk 1>, <&clk 2>;
|
||||
clock-names = "stmmaceth", "pclk";
|
||||
clocks = <&clk 1>, <&clk 2>, <&clk 3>;
|
||||
clock-names = "stmmaceth", "pclk", "apb";
|
||||
interrupts = <66>;
|
||||
interrupt-names = "macirq";
|
||||
phy-mode = "rgmii-id";
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Infineon Buck Regulators with PMBUS interfaces
|
||||
|
||||
maintainers:
|
||||
- Not Me.
|
||||
- Guenter Roeck <linux@roeck-us.net>
|
||||
|
||||
allOf:
|
||||
- $ref: regulator.yaml#
|
||||
|
|
|
|||
|
|
@ -507,6 +507,8 @@ patternProperties:
|
|||
description: Espressif Systems Co. Ltd.
|
||||
"^est,.*":
|
||||
description: ESTeem Wireless Modems
|
||||
"^eswin,.*":
|
||||
description: Beijing ESWIN Technology Group Co. Ltd.
|
||||
"^ettus,.*":
|
||||
description: NI Ettus Research
|
||||
"^eukrea,.*":
|
||||
|
|
|
|||
|
|
@ -1420,7 +1420,7 @@ udp_hash_entries - INTEGER
|
|||
A negative value means the networking namespace does not own its
|
||||
hash buckets and shares the initial networking namespace's one.
|
||||
|
||||
udp_child_ehash_entries - INTEGER
|
||||
udp_child_hash_entries - INTEGER
|
||||
Control the number of hash buckets for UDP sockets in the child
|
||||
networking namespace, which must be set before clone() or unshare().
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ add_addr_timeout - INTEGER (seconds)
|
|||
resent to an MPTCP peer that has not acknowledged a previous
|
||||
ADD_ADDR message.
|
||||
|
||||
Do not retransmit if set to 0.
|
||||
|
||||
The default value matches TCP_RTO_MAX. This is a per-namespace
|
||||
sysctl.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,22 @@ like to know when a security bug is found so that it can be fixed and
|
|||
disclosed as quickly as possible. Please report security bugs to the
|
||||
Linux kernel security team.
|
||||
|
||||
Contact
|
||||
-------
|
||||
The security team and maintainers almost always require additional
|
||||
information beyond what was initially provided in a report and rely on
|
||||
active and efficient collaboration with the reporter to perform further
|
||||
testing (e.g., verifying versions, configuration options, mitigations, or
|
||||
patches). Before contacting the security team, the reporter must ensure
|
||||
they are available to explain their findings, engage in discussions, and
|
||||
run additional tests. Reports where the reporter does not respond promptly
|
||||
or cannot effectively discuss their findings may be abandoned if the
|
||||
communication does not quickly improve.
|
||||
|
||||
As it is with any bug, the more information provided the easier it
|
||||
will be to diagnose and fix. Please review the procedure outlined in
|
||||
'Documentation/admin-guide/reporting-issues.rst' if you are unclear about what
|
||||
information is helpful. Any exploit code is very helpful and will not
|
||||
be released without consent from the reporter unless it has already been
|
||||
made public.
|
||||
|
||||
The Linux kernel security team can be contacted by email at
|
||||
<security@kernel.org>. This is a private list of security officers
|
||||
|
|
@ -19,13 +33,6 @@ that can speed up the process considerably. It is possible that the
|
|||
security team will bring in extra help from area maintainers to
|
||||
understand and fix the security vulnerability.
|
||||
|
||||
As it is with any bug, the more information provided the easier it
|
||||
will be to diagnose and fix. Please review the procedure outlined in
|
||||
'Documentation/admin-guide/reporting-issues.rst' if you are unclear about what
|
||||
information is helpful. Any exploit code is very helpful and will not
|
||||
be released without consent from the reporter unless it has already been
|
||||
made public.
|
||||
|
||||
Please send plain text emails without attachments where possible.
|
||||
It is much harder to have a context-quoted discussion about a complex
|
||||
issue if all the details are hidden away in attachments. Think of it like a
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ Following IOMMUFD objects are exposed to userspace:
|
|||
|
||||
- IOMMUFD_OBJ_HWPT_PAGING, representing an actual hardware I/O page table
|
||||
(i.e. a single struct iommu_domain) managed by the iommu driver. "PAGING"
|
||||
primarly indicates this type of HWPT should be linked to an IOAS. It also
|
||||
primarily indicates this type of HWPT should be linked to an IOAS. It also
|
||||
indicates that it is backed by an iommu_domain with __IOMMU_DOMAIN_PAGING
|
||||
feature flag. This can be either an UNMANAGED stage-1 domain for a device
|
||||
running in the user space, or a nesting parent stage-2 domain for mappings
|
||||
|
|
@ -76,7 +76,7 @@ Following IOMMUFD objects are exposed to userspace:
|
|||
|
||||
* Security namespace for guest owned ID, e.g. guest-controlled cache tags
|
||||
* Non-device-affiliated event reporting, e.g. invalidation queue errors
|
||||
* Access to a sharable nesting parent pagetable across physical IOMMUs
|
||||
* Access to a shareable nesting parent pagetable across physical IOMMUs
|
||||
* Virtualization of various platforms IDs, e.g. RIDs and others
|
||||
* Delivery of paravirtualized invalidation
|
||||
* Direct assigned invalidation queues
|
||||
|
|
|
|||
61
MAINTAINERS
61
MAINTAINERS
|
|
@ -931,13 +931,13 @@ F: Documentation/devicetree/bindings/dma/altr,msgdma.yaml
|
|||
F: drivers/dma/altera-msgdma.c
|
||||
|
||||
ALTERA PIO DRIVER
|
||||
M: Mun Yew Tham <mun.yew.tham@intel.com>
|
||||
M: Adrian Ng <adrianhoyin.ng@altera.com>
|
||||
L: linux-gpio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/gpio/gpio-altera.c
|
||||
|
||||
ALTERA TRIPLE SPEED ETHERNET DRIVER
|
||||
M: Joyce Ooi <joyce.ooi@intel.com>
|
||||
M: Boon Khai Ng <boon.khai.ng@altera.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/altera/
|
||||
|
|
@ -4205,7 +4205,7 @@ W: http://www.baycom.org/~tom/ham/ham.html
|
|||
F: drivers/net/hamradio/baycom*
|
||||
|
||||
BCACHE (BLOCK LAYER CACHE)
|
||||
M: Coly Li <colyli@kernel.org>
|
||||
M: Coly Li <colyli@fnnas.com>
|
||||
M: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
L: linux-bcache@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
@ -4216,7 +4216,7 @@ F: drivers/md/bcache/
|
|||
BCACHEFS
|
||||
M: Kent Overstreet <kent.overstreet@linux.dev>
|
||||
L: linux-bcachefs@vger.kernel.org
|
||||
S: Supported
|
||||
S: Externally maintained
|
||||
C: irc://irc.oftc.net/bcache
|
||||
P: Documentation/filesystems/bcachefs/SubmittingPatches.rst
|
||||
T: git https://evilpiepirate.org/git/bcachefs.git
|
||||
|
|
@ -8426,6 +8426,17 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
|||
F: drivers/gpu/drm/scheduler/
|
||||
F: include/drm/gpu_scheduler.h
|
||||
|
||||
DRM GPUVM
|
||||
M: Danilo Krummrich <dakr@kernel.org>
|
||||
R: Matthew Brost <matthew.brost@intel.com>
|
||||
R: Thomas Hellström <thomas.hellstrom@linux.intel.com>
|
||||
R: Alice Ryhl <aliceryhl@google.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Supported
|
||||
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
|
||||
F: drivers/gpu/drm/drm_gpuvm.c
|
||||
F: include/drm/drm_gpuvm.h
|
||||
|
||||
DRM LOG
|
||||
M: Jocelyn Falempe <jfalempe@redhat.com>
|
||||
M: Javier Martinez Canillas <javierm@redhat.com>
|
||||
|
|
@ -10655,7 +10666,8 @@ S: Maintained
|
|||
F: block/partitions/efi.*
|
||||
|
||||
HABANALABS PCI DRIVER
|
||||
M: Yaron Avizrat <yaron.avizrat@intel.com>
|
||||
M: Koby Elbaz <koby.elbaz@intel.com>
|
||||
M: Konstantin Sinyuk <konstantin.sinyuk@intel.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Supported
|
||||
C: irc://irc.oftc.net/dri-devel
|
||||
|
|
@ -11013,7 +11025,7 @@ F: Documentation/admin-guide/perf/hns3-pmu.rst
|
|||
F: drivers/perf/hisilicon/hns3_pmu.c
|
||||
|
||||
HISILICON I2C CONTROLLER DRIVER
|
||||
M: Yicong Yang <yangyicong@hisilicon.com>
|
||||
M: Devyn Liu <liudingyuan@h-partners.com>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://www.hisilicon.com
|
||||
|
|
@ -11438,6 +11450,7 @@ F: drivers/tty/hvc/
|
|||
HUNG TASK DETECTOR
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
R: Lance Yang <lance.yang@linux.dev>
|
||||
R: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
F: include/linux/hung_task.h
|
||||
|
|
@ -12280,7 +12293,6 @@ F: include/linux/avf/virtchnl.h
|
|||
F: include/linux/net/intel/*/
|
||||
|
||||
INTEL ETHERNET PROTOCOL DRIVER FOR RDMA
|
||||
M: Mustafa Ismail <mustafa.ismail@intel.com>
|
||||
M: Tatyana Nikolova <tatyana.e.nikolova@intel.com>
|
||||
L: linux-rdma@vger.kernel.org
|
||||
S: Supported
|
||||
|
|
@ -12583,10 +12595,9 @@ S: Supported
|
|||
F: drivers/cpufreq/intel_pstate.c
|
||||
|
||||
INTEL PTP DFL ToD DRIVER
|
||||
M: Tianfei Zhang <tianfei.zhang@intel.com>
|
||||
L: linux-fpga@vger.kernel.org
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/ptp/ptp_dfl_tod.c
|
||||
|
||||
INTEL QUADRATURE ENCODER PERIPHERAL DRIVER
|
||||
|
|
@ -12724,9 +12735,8 @@ S: Maintained
|
|||
F: drivers/platform/x86/intel/wmi/thunderbolt.c
|
||||
|
||||
INTEL WWAN IOSM DRIVER
|
||||
M: M Chetan Kumar <m.chetan.kumar@intel.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/net/wwan/iosm/
|
||||
|
||||
INTEL(R) FLEXIBLE RETURN AND EVENT DELIVERY
|
||||
|
|
@ -13686,7 +13696,6 @@ F: scripts/Makefile.kmsan
|
|||
|
||||
KPROBES
|
||||
M: Naveen N Rao <naveen@kernel.org>
|
||||
M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
|
||||
M: "David S. Miller" <davem@davemloft.net>
|
||||
M: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
|
|
@ -15674,7 +15683,6 @@ MEDIATEK T7XX 5G WWAN MODEM DRIVER
|
|||
M: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
|
||||
R: Chiranjeevi Rapolu <chiranjeevi.rapolu@linux.intel.com>
|
||||
R: Liu Haijun <haijun.liu@mediatek.com>
|
||||
R: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
|
||||
R: Ricardo Martinez <ricardo.martinez@linux.intel.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
|
|
@ -16061,6 +16069,23 @@ F: mm/mempolicy.c
|
|||
F: mm/migrate.c
|
||||
F: mm/migrate_device.c
|
||||
|
||||
MEMORY MANAGEMENT - MGLRU (MULTI-GEN LRU)
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: Axel Rasmussen <axelrasmussen@google.com>
|
||||
M: Yuanchu Xie <yuanchu@google.com>
|
||||
R: Wei Xu <weixugc@google.com>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
W: http://www.linux-mm.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
|
||||
F: Documentation/admin-guide/mm/multigen_lru.rst
|
||||
F: Documentation/mm/multigen_lru.rst
|
||||
F: include/linux/mm_inline.h
|
||||
F: include/linux/mmzone.h
|
||||
F: mm/swap.c
|
||||
F: mm/vmscan.c
|
||||
F: mm/workingset.c
|
||||
|
||||
MEMORY MANAGEMENT - MISC
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
M: David Hildenbrand <david@redhat.com>
|
||||
|
|
@ -16251,8 +16276,10 @@ S: Maintained
|
|||
W: http://www.linux-mm.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
|
||||
F: rust/helpers/mm.c
|
||||
F: rust/helpers/page.c
|
||||
F: rust/kernel/mm.rs
|
||||
F: rust/kernel/mm/
|
||||
F: rust/kernel/page.rs
|
||||
|
||||
MEMORY MAPPING
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
|
|
@ -17451,6 +17478,7 @@ F: drivers/net/ethernet/neterion/
|
|||
NETFILTER
|
||||
M: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
M: Jozsef Kadlecsik <kadlec@netfilter.org>
|
||||
M: Florian Westphal <fw@strlen.de>
|
||||
L: netfilter-devel@vger.kernel.org
|
||||
L: coreteam@netfilter.org
|
||||
S: Maintained
|
||||
|
|
@ -17820,7 +17848,6 @@ F: net/ipv6/syncookies.c
|
|||
F: net/ipv6/tcp*.c
|
||||
|
||||
NETWORKING [TLS]
|
||||
M: Boris Pismenny <borisp@nvidia.com>
|
||||
M: John Fastabend <john.fastabend@gmail.com>
|
||||
M: Jakub Kicinski <kuba@kernel.org>
|
||||
L: netdev@vger.kernel.org
|
||||
|
|
@ -20850,8 +20877,8 @@ S: Maintained
|
|||
F: drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
|
||||
|
||||
QUALCOMM RMNET DRIVER
|
||||
M: Subash Abhinov Kasiviswanathan <quic_subashab@quicinc.com>
|
||||
M: Sean Tranchetti <quic_stranche@quicinc.com>
|
||||
M: Subash Abhinov Kasiviswanathan <subash.a.kasiviswanathan@oss.qualcomm.com>
|
||||
M: Sean Tranchetti <sean.tranchetti@oss.qualcomm.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/networking/device_drivers/cellular/qualcomm/rmnet.rst
|
||||
|
|
@ -22176,7 +22203,7 @@ F: arch/s390/mm
|
|||
|
||||
S390 NETWORK DRIVERS
|
||||
M: Alexandra Winter <wintera@linux.ibm.com>
|
||||
M: Thorsten Winkler <twinkler@linux.ibm.com>
|
||||
R: Aswin Karuvally <aswin@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -2,7 +2,7 @@
|
|||
VERSION = 6
|
||||
PATCHLEVEL = 17
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc1
|
||||
EXTRAVERSION = -rc4
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@
|
|||
#ifndef __ASM_STACKTRACE_H
|
||||
#define __ASM_STACKTRACE_H
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <linux/llist.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
struct stackframe {
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1160,115 +1160,8 @@ u64 kvm_vcpu_apply_reg_masks(const struct kvm_vcpu *, enum vcpu_sysreg, u64);
|
|||
__v; \
|
||||
})
|
||||
|
||||
u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg);
|
||||
void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg);
|
||||
|
||||
static inline bool __vcpu_read_sys_reg_from_cpu(int reg, u64 *val)
|
||||
{
|
||||
/*
|
||||
* *** VHE ONLY ***
|
||||
*
|
||||
* System registers listed in the switch are not saved on every
|
||||
* exit from the guest but are only saved on vcpu_put.
|
||||
*
|
||||
* SYSREGS_ON_CPU *MUST* be checked before using this helper.
|
||||
*
|
||||
* Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but
|
||||
* should never be listed below, because the guest cannot modify its
|
||||
* own MPIDR_EL1 and MPIDR_EL1 is accessed for VCPU A from VCPU B's
|
||||
* thread when emulating cross-VCPU communication.
|
||||
*/
|
||||
if (!has_vhe())
|
||||
return false;
|
||||
|
||||
switch (reg) {
|
||||
case SCTLR_EL1: *val = read_sysreg_s(SYS_SCTLR_EL12); break;
|
||||
case CPACR_EL1: *val = read_sysreg_s(SYS_CPACR_EL12); break;
|
||||
case TTBR0_EL1: *val = read_sysreg_s(SYS_TTBR0_EL12); break;
|
||||
case TTBR1_EL1: *val = read_sysreg_s(SYS_TTBR1_EL12); break;
|
||||
case TCR_EL1: *val = read_sysreg_s(SYS_TCR_EL12); break;
|
||||
case TCR2_EL1: *val = read_sysreg_s(SYS_TCR2_EL12); break;
|
||||
case PIR_EL1: *val = read_sysreg_s(SYS_PIR_EL12); break;
|
||||
case PIRE0_EL1: *val = read_sysreg_s(SYS_PIRE0_EL12); break;
|
||||
case POR_EL1: *val = read_sysreg_s(SYS_POR_EL12); break;
|
||||
case ESR_EL1: *val = read_sysreg_s(SYS_ESR_EL12); break;
|
||||
case AFSR0_EL1: *val = read_sysreg_s(SYS_AFSR0_EL12); break;
|
||||
case AFSR1_EL1: *val = read_sysreg_s(SYS_AFSR1_EL12); break;
|
||||
case FAR_EL1: *val = read_sysreg_s(SYS_FAR_EL12); break;
|
||||
case MAIR_EL1: *val = read_sysreg_s(SYS_MAIR_EL12); break;
|
||||
case VBAR_EL1: *val = read_sysreg_s(SYS_VBAR_EL12); break;
|
||||
case CONTEXTIDR_EL1: *val = read_sysreg_s(SYS_CONTEXTIDR_EL12);break;
|
||||
case TPIDR_EL0: *val = read_sysreg_s(SYS_TPIDR_EL0); break;
|
||||
case TPIDRRO_EL0: *val = read_sysreg_s(SYS_TPIDRRO_EL0); break;
|
||||
case TPIDR_EL1: *val = read_sysreg_s(SYS_TPIDR_EL1); break;
|
||||
case AMAIR_EL1: *val = read_sysreg_s(SYS_AMAIR_EL12); break;
|
||||
case CNTKCTL_EL1: *val = read_sysreg_s(SYS_CNTKCTL_EL12); break;
|
||||
case ELR_EL1: *val = read_sysreg_s(SYS_ELR_EL12); break;
|
||||
case SPSR_EL1: *val = read_sysreg_s(SYS_SPSR_EL12); break;
|
||||
case PAR_EL1: *val = read_sysreg_par(); break;
|
||||
case DACR32_EL2: *val = read_sysreg_s(SYS_DACR32_EL2); break;
|
||||
case IFSR32_EL2: *val = read_sysreg_s(SYS_IFSR32_EL2); break;
|
||||
case DBGVCR32_EL2: *val = read_sysreg_s(SYS_DBGVCR32_EL2); break;
|
||||
case ZCR_EL1: *val = read_sysreg_s(SYS_ZCR_EL12); break;
|
||||
case SCTLR2_EL1: *val = read_sysreg_s(SYS_SCTLR2_EL12); break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg)
|
||||
{
|
||||
/*
|
||||
* *** VHE ONLY ***
|
||||
*
|
||||
* System registers listed in the switch are not restored on every
|
||||
* entry to the guest but are only restored on vcpu_load.
|
||||
*
|
||||
* SYSREGS_ON_CPU *MUST* be checked before using this helper.
|
||||
*
|
||||
* Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but
|
||||
* should never be listed below, because the MPIDR should only be set
|
||||
* once, before running the VCPU, and never changed later.
|
||||
*/
|
||||
if (!has_vhe())
|
||||
return false;
|
||||
|
||||
switch (reg) {
|
||||
case SCTLR_EL1: write_sysreg_s(val, SYS_SCTLR_EL12); break;
|
||||
case CPACR_EL1: write_sysreg_s(val, SYS_CPACR_EL12); break;
|
||||
case TTBR0_EL1: write_sysreg_s(val, SYS_TTBR0_EL12); break;
|
||||
case TTBR1_EL1: write_sysreg_s(val, SYS_TTBR1_EL12); break;
|
||||
case TCR_EL1: write_sysreg_s(val, SYS_TCR_EL12); break;
|
||||
case TCR2_EL1: write_sysreg_s(val, SYS_TCR2_EL12); break;
|
||||
case PIR_EL1: write_sysreg_s(val, SYS_PIR_EL12); break;
|
||||
case PIRE0_EL1: write_sysreg_s(val, SYS_PIRE0_EL12); break;
|
||||
case POR_EL1: write_sysreg_s(val, SYS_POR_EL12); break;
|
||||
case ESR_EL1: write_sysreg_s(val, SYS_ESR_EL12); break;
|
||||
case AFSR0_EL1: write_sysreg_s(val, SYS_AFSR0_EL12); break;
|
||||
case AFSR1_EL1: write_sysreg_s(val, SYS_AFSR1_EL12); break;
|
||||
case FAR_EL1: write_sysreg_s(val, SYS_FAR_EL12); break;
|
||||
case MAIR_EL1: write_sysreg_s(val, SYS_MAIR_EL12); break;
|
||||
case VBAR_EL1: write_sysreg_s(val, SYS_VBAR_EL12); break;
|
||||
case CONTEXTIDR_EL1: write_sysreg_s(val, SYS_CONTEXTIDR_EL12);break;
|
||||
case TPIDR_EL0: write_sysreg_s(val, SYS_TPIDR_EL0); break;
|
||||
case TPIDRRO_EL0: write_sysreg_s(val, SYS_TPIDRRO_EL0); break;
|
||||
case TPIDR_EL1: write_sysreg_s(val, SYS_TPIDR_EL1); break;
|
||||
case AMAIR_EL1: write_sysreg_s(val, SYS_AMAIR_EL12); break;
|
||||
case CNTKCTL_EL1: write_sysreg_s(val, SYS_CNTKCTL_EL12); break;
|
||||
case ELR_EL1: write_sysreg_s(val, SYS_ELR_EL12); break;
|
||||
case SPSR_EL1: write_sysreg_s(val, SYS_SPSR_EL12); break;
|
||||
case PAR_EL1: write_sysreg_s(val, SYS_PAR_EL1); break;
|
||||
case DACR32_EL2: write_sysreg_s(val, SYS_DACR32_EL2); break;
|
||||
case IFSR32_EL2: write_sysreg_s(val, SYS_IFSR32_EL2); break;
|
||||
case DBGVCR32_EL2: write_sysreg_s(val, SYS_DBGVCR32_EL2); break;
|
||||
case ZCR_EL1: write_sysreg_s(val, SYS_ZCR_EL12); break;
|
||||
case SCTLR2_EL1: write_sysreg_s(val, SYS_SCTLR2_EL12); break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
u64 vcpu_read_sys_reg(const struct kvm_vcpu *, enum vcpu_sysreg);
|
||||
void vcpu_write_sys_reg(struct kvm_vcpu *, u64, enum vcpu_sysreg);
|
||||
|
||||
struct kvm_vm_stat {
|
||||
struct kvm_vm_stat_generic generic;
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu);
|
|||
int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
|
||||
phys_addr_t pa, unsigned long size, bool writable);
|
||||
|
||||
int kvm_handle_guest_sea(struct kvm_vcpu *vcpu);
|
||||
int kvm_handle_guest_abort(struct kvm_vcpu *vcpu);
|
||||
|
||||
phys_addr_t kvm_mmu_get_httbr(void);
|
||||
|
|
|
|||
|
|
@ -355,6 +355,11 @@ static inline kvm_pte_t *kvm_dereference_pteref(struct kvm_pgtable_walker *walke
|
|||
return pteref;
|
||||
}
|
||||
|
||||
static inline kvm_pte_t *kvm_dereference_pteref_raw(kvm_pteref_t pteref)
|
||||
{
|
||||
return pteref;
|
||||
}
|
||||
|
||||
static inline int kvm_pgtable_walk_begin(struct kvm_pgtable_walker *walker)
|
||||
{
|
||||
/*
|
||||
|
|
@ -384,6 +389,11 @@ static inline kvm_pte_t *kvm_dereference_pteref(struct kvm_pgtable_walker *walke
|
|||
return rcu_dereference_check(pteref, !(walker->flags & KVM_PGTABLE_WALK_SHARED));
|
||||
}
|
||||
|
||||
static inline kvm_pte_t *kvm_dereference_pteref_raw(kvm_pteref_t pteref)
|
||||
{
|
||||
return rcu_dereference_raw(pteref);
|
||||
}
|
||||
|
||||
static inline int kvm_pgtable_walk_begin(struct kvm_pgtable_walker *walker)
|
||||
{
|
||||
if (walker->flags & KVM_PGTABLE_WALK_SHARED)
|
||||
|
|
@ -551,6 +561,26 @@ static inline int kvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2
|
|||
*/
|
||||
void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt);
|
||||
|
||||
/**
|
||||
* kvm_pgtable_stage2_destroy_range() - Destroy the unlinked range of addresses.
|
||||
* @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*().
|
||||
* @addr: Intermediate physical address at which to place the mapping.
|
||||
* @size: Size of the mapping.
|
||||
*
|
||||
* The page-table is assumed to be unreachable by any hardware walkers prior
|
||||
* to freeing and therefore no TLB invalidation is performed.
|
||||
*/
|
||||
void kvm_pgtable_stage2_destroy_range(struct kvm_pgtable *pgt,
|
||||
u64 addr, u64 size);
|
||||
|
||||
/**
|
||||
* kvm_pgtable_stage2_destroy_pgd() - Destroy the PGD of guest stage-2 page-table.
|
||||
* @pgt: Page-table structure initialised by kvm_pgtable_stage2_init*().
|
||||
*
|
||||
* It is assumed that the rest of the page-table is freed before this operation.
|
||||
*/
|
||||
void kvm_pgtable_stage2_destroy_pgd(struct kvm_pgtable *pgt);
|
||||
|
||||
/**
|
||||
* kvm_pgtable_stage2_free_unlinked() - Free an unlinked stage-2 paging structure.
|
||||
* @mm_ops: Memory management callbacks.
|
||||
|
|
|
|||
|
|
@ -179,7 +179,9 @@ struct pkvm_mapping {
|
|||
|
||||
int pkvm_pgtable_stage2_init(struct kvm_pgtable *pgt, struct kvm_s2_mmu *mmu,
|
||||
struct kvm_pgtable_mm_ops *mm_ops);
|
||||
void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt);
|
||||
void pkvm_pgtable_stage2_destroy_range(struct kvm_pgtable *pgt,
|
||||
u64 addr, u64 size);
|
||||
void pkvm_pgtable_stage2_destroy_pgd(struct kvm_pgtable *pgt);
|
||||
int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size, u64 phys,
|
||||
enum kvm_pgtable_prot prot, void *mc,
|
||||
enum kvm_pgtable_walk_flags flags);
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2018 - Arm Ltd */
|
||||
|
||||
#ifndef __ARM64_KVM_RAS_H__
|
||||
#define __ARM64_KVM_RAS_H__
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/acpi.h>
|
||||
|
||||
/*
|
||||
* Was this synchronous external abort a RAS notification?
|
||||
* Returns '0' for errors handled by some RAS subsystem, or -ENOENT.
|
||||
*/
|
||||
static inline int kvm_handle_guest_sea(void)
|
||||
{
|
||||
/* apei_claim_sea(NULL) expects to mask interrupts itself */
|
||||
lockdep_assert_irqs_enabled();
|
||||
|
||||
return apei_claim_sea(NULL);
|
||||
}
|
||||
|
||||
#endif /* __ARM64_KVM_RAS_H__ */
|
||||
|
|
@ -17,6 +17,13 @@
|
|||
#include <linux/refcount.h>
|
||||
#include <asm/cpufeature.h>
|
||||
|
||||
enum pgtable_type {
|
||||
TABLE_PTE,
|
||||
TABLE_PMD,
|
||||
TABLE_PUD,
|
||||
TABLE_P4D,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
atomic64_t id;
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
|
|
|||
|
|
@ -1142,9 +1142,6 @@
|
|||
|
||||
#define ARM64_FEATURE_FIELD_BITS 4
|
||||
|
||||
/* Defined for compatibility only, do not add new users. */
|
||||
#define ARM64_FEATURE_MASK(x) (x##_MASK)
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
.macro mrs_s, rt, sreg
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@
|
|||
#include <asm/hwcap.h>
|
||||
#include <asm/insn.h>
|
||||
#include <asm/kvm_host.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/mte.h>
|
||||
#include <asm/hypervisor.h>
|
||||
|
|
@ -1945,11 +1946,11 @@ static bool has_pmuv3(const struct arm64_cpu_capabilities *entry, int scope)
|
|||
extern
|
||||
void create_kpti_ng_temp_pgd(pgd_t *pgdir, phys_addr_t phys, unsigned long virt,
|
||||
phys_addr_t size, pgprot_t prot,
|
||||
phys_addr_t (*pgtable_alloc)(int), int flags);
|
||||
phys_addr_t (*pgtable_alloc)(enum pgtable_type), int flags);
|
||||
|
||||
static phys_addr_t __initdata kpti_ng_temp_alloc;
|
||||
|
||||
static phys_addr_t __init kpti_ng_pgd_alloc(int shift)
|
||||
static phys_addr_t __init kpti_ng_pgd_alloc(enum pgtable_type type)
|
||||
{
|
||||
kpti_ng_temp_alloc -= PAGE_SIZE;
|
||||
return kpti_ng_temp_alloc;
|
||||
|
|
@ -2269,6 +2270,24 @@ static void cpu_clear_disr(const struct arm64_cpu_capabilities *__unused)
|
|||
/* Firmware may have left a deferred SError in this register. */
|
||||
write_sysreg_s(0, SYS_DISR_EL1);
|
||||
}
|
||||
static bool has_rasv1p1(const struct arm64_cpu_capabilities *__unused, int scope)
|
||||
{
|
||||
const struct arm64_cpu_capabilities rasv1p1_caps[] = {
|
||||
{
|
||||
ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, RAS, V1P1)
|
||||
},
|
||||
{
|
||||
ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, RAS, IMP)
|
||||
},
|
||||
{
|
||||
ARM64_CPUID_FIELDS(ID_AA64PFR1_EL1, RAS_frac, RASv1p1)
|
||||
},
|
||||
};
|
||||
|
||||
return (has_cpuid_feature(&rasv1p1_caps[0], scope) ||
|
||||
(has_cpuid_feature(&rasv1p1_caps[1], scope) &&
|
||||
has_cpuid_feature(&rasv1p1_caps[2], scope)));
|
||||
}
|
||||
#endif /* CONFIG_ARM64_RAS_EXTN */
|
||||
|
||||
#ifdef CONFIG_ARM64_PTR_AUTH
|
||||
|
|
@ -2687,6 +2706,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
|
|||
.cpu_enable = cpu_clear_disr,
|
||||
ARM64_CPUID_FIELDS(ID_AA64PFR0_EL1, RAS, IMP)
|
||||
},
|
||||
{
|
||||
.desc = "RASv1p1 Extension Support",
|
||||
.capability = ARM64_HAS_RASV1P1_EXTN,
|
||||
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
|
||||
.matches = has_rasv1p1,
|
||||
},
|
||||
#endif /* CONFIG_ARM64_RAS_EXTN */
|
||||
#ifdef CONFIG_ARM64_AMU_EXTN
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2408,12 +2408,12 @@ static u64 get_hyp_id_aa64pfr0_el1(void)
|
|||
*/
|
||||
u64 val = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
|
||||
|
||||
val &= ~(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2) |
|
||||
ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3));
|
||||
val &= ~(ID_AA64PFR0_EL1_CSV2 |
|
||||
ID_AA64PFR0_EL1_CSV3);
|
||||
|
||||
val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV2),
|
||||
val |= FIELD_PREP(ID_AA64PFR0_EL1_CSV2,
|
||||
arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED);
|
||||
val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_EL1_CSV3),
|
||||
val |= FIELD_PREP(ID_AA64PFR0_EL1_CSV3,
|
||||
arm64_get_meltdown_state() == SPECTRE_UNAFFECTED);
|
||||
|
||||
return val;
|
||||
|
|
|
|||
|
|
@ -1420,10 +1420,10 @@ void __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr)
|
|||
return;
|
||||
|
||||
/*
|
||||
* If we only have a single stage of translation (E2H=0 or
|
||||
* TGE=1), exit early. Same thing if {VM,DC}=={0,0}.
|
||||
* If we only have a single stage of translation (EL2&0), exit
|
||||
* early. Same thing if {VM,DC}=={0,0}.
|
||||
*/
|
||||
if (!vcpu_el2_e2h_is_set(vcpu) || vcpu_el2_tge_is_set(vcpu) ||
|
||||
if (compute_translation_regime(vcpu, op) == TR_EL20 ||
|
||||
!(vcpu_read_sys_reg(vcpu, HCR_EL2) & (HCR_VM | HCR_DC)))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -2833,7 +2833,7 @@ int kvm_inject_nested_sea(struct kvm_vcpu *vcpu, bool iabt, u64 addr)
|
|||
iabt ? ESR_ELx_EC_IABT_LOW : ESR_ELx_EC_DABT_LOW);
|
||||
esr |= ESR_ELx_FSC_EXTABT | ESR_ELx_IL;
|
||||
|
||||
vcpu_write_sys_reg(vcpu, FAR_EL2, addr);
|
||||
vcpu_write_sys_reg(vcpu, addr, FAR_EL2);
|
||||
|
||||
if (__vcpu_sys_reg(vcpu, SCTLR2_EL2) & SCTLR2_EL1_EASE)
|
||||
return kvm_inject_nested(vcpu, esr, except_type_serror);
|
||||
|
|
|
|||
|
|
@ -22,36 +22,28 @@
|
|||
|
||||
static inline u64 __vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
|
||||
{
|
||||
u64 val;
|
||||
|
||||
if (unlikely(vcpu_has_nv(vcpu)))
|
||||
if (has_vhe())
|
||||
return vcpu_read_sys_reg(vcpu, reg);
|
||||
else if (vcpu_get_flag(vcpu, SYSREGS_ON_CPU) &&
|
||||
__vcpu_read_sys_reg_from_cpu(reg, &val))
|
||||
return val;
|
||||
|
||||
return __vcpu_sys_reg(vcpu, reg);
|
||||
}
|
||||
|
||||
static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
|
||||
{
|
||||
if (unlikely(vcpu_has_nv(vcpu)))
|
||||
if (has_vhe())
|
||||
vcpu_write_sys_reg(vcpu, val, reg);
|
||||
else if (!vcpu_get_flag(vcpu, SYSREGS_ON_CPU) ||
|
||||
!__vcpu_write_sys_reg_to_cpu(val, reg))
|
||||
else
|
||||
__vcpu_assign_sys_reg(vcpu, reg, val);
|
||||
}
|
||||
|
||||
static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long target_mode,
|
||||
u64 val)
|
||||
{
|
||||
if (unlikely(vcpu_has_nv(vcpu))) {
|
||||
if (has_vhe()) {
|
||||
if (target_mode == PSR_MODE_EL1h)
|
||||
vcpu_write_sys_reg(vcpu, val, SPSR_EL1);
|
||||
else
|
||||
vcpu_write_sys_reg(vcpu, val, SPSR_EL2);
|
||||
} else if (has_vhe()) {
|
||||
write_sysreg_el1(val, SYS_SPSR);
|
||||
} else {
|
||||
__vcpu_assign_sys_reg(vcpu, SPSR_EL1, val);
|
||||
}
|
||||
|
|
@ -59,7 +51,7 @@ static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long target_mode,
|
|||
|
||||
static void __vcpu_write_spsr_abt(struct kvm_vcpu *vcpu, u64 val)
|
||||
{
|
||||
if (has_vhe())
|
||||
if (has_vhe() && vcpu_get_flag(vcpu, SYSREGS_ON_CPU))
|
||||
write_sysreg(val, spsr_abt);
|
||||
else
|
||||
vcpu->arch.ctxt.spsr_abt = val;
|
||||
|
|
@ -67,7 +59,7 @@ static void __vcpu_write_spsr_abt(struct kvm_vcpu *vcpu, u64 val)
|
|||
|
||||
static void __vcpu_write_spsr_und(struct kvm_vcpu *vcpu, u64 val)
|
||||
{
|
||||
if (has_vhe())
|
||||
if (has_vhe() && vcpu_get_flag(vcpu, SYSREGS_ON_CPU))
|
||||
write_sysreg(val, spsr_und);
|
||||
else
|
||||
vcpu->arch.ctxt.spsr_und = val;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ static inline __must_check bool nvhe_check_data_corruption(bool v)
|
|||
bool corruption = unlikely(condition); \
|
||||
if (corruption) { \
|
||||
if (IS_ENABLED(CONFIG_BUG_ON_DATA_CORRUPTION)) { \
|
||||
BUG_ON(1); \
|
||||
BUG(); \
|
||||
} else \
|
||||
WARN_ON(1); \
|
||||
} \
|
||||
|
|
|
|||
|
|
@ -253,6 +253,7 @@ static void inject_undef64(struct kvm_vcpu *vcpu)
|
|||
|
||||
*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
|
||||
*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
|
||||
__vcpu_assign_sys_reg(vcpu, read_sysreg_el1(SYS_VBAR), VBAR_EL1);
|
||||
|
||||
kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC);
|
||||
|
||||
|
|
@ -372,6 +373,9 @@ static const struct sys_reg_desc pvm_sys_reg_descs[] = {
|
|||
|
||||
/* Debug and Trace Registers are restricted. */
|
||||
|
||||
/* Group 1 ID registers */
|
||||
HOST_HANDLED(SYS_REVIDR_EL1),
|
||||
|
||||
/* AArch64 mappings of the AArch32 ID registers */
|
||||
/* CRm=1 */
|
||||
AARCH32(SYS_ID_PFR0_EL1),
|
||||
|
|
@ -460,6 +464,7 @@ static const struct sys_reg_desc pvm_sys_reg_descs[] = {
|
|||
|
||||
HOST_HANDLED(SYS_CCSIDR_EL1),
|
||||
HOST_HANDLED(SYS_CLIDR_EL1),
|
||||
HOST_HANDLED(SYS_AIDR_EL1),
|
||||
HOST_HANDLED(SYS_CSSELR_EL1),
|
||||
HOST_HANDLED(SYS_CTR_EL0),
|
||||
|
||||
|
|
|
|||
|
|
@ -1551,21 +1551,38 @@ static int stage2_free_walker(const struct kvm_pgtable_visit_ctx *ctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt)
|
||||
void kvm_pgtable_stage2_destroy_range(struct kvm_pgtable *pgt,
|
||||
u64 addr, u64 size)
|
||||
{
|
||||
size_t pgd_sz;
|
||||
struct kvm_pgtable_walker walker = {
|
||||
.cb = stage2_free_walker,
|
||||
.flags = KVM_PGTABLE_WALK_LEAF |
|
||||
KVM_PGTABLE_WALK_TABLE_POST,
|
||||
};
|
||||
|
||||
WARN_ON(kvm_pgtable_walk(pgt, 0, BIT(pgt->ia_bits), &walker));
|
||||
WARN_ON(kvm_pgtable_walk(pgt, addr, size, &walker));
|
||||
}
|
||||
|
||||
void kvm_pgtable_stage2_destroy_pgd(struct kvm_pgtable *pgt)
|
||||
{
|
||||
size_t pgd_sz;
|
||||
|
||||
pgd_sz = kvm_pgd_pages(pgt->ia_bits, pgt->start_level) * PAGE_SIZE;
|
||||
pgt->mm_ops->free_pages_exact(kvm_dereference_pteref(&walker, pgt->pgd), pgd_sz);
|
||||
|
||||
/*
|
||||
* Since the pgtable is unlinked at this point, and not shared with
|
||||
* other walkers, safely deference pgd with kvm_dereference_pteref_raw()
|
||||
*/
|
||||
pgt->mm_ops->free_pages_exact(kvm_dereference_pteref_raw(pgt->pgd), pgd_sz);
|
||||
pgt->pgd = NULL;
|
||||
}
|
||||
|
||||
void kvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt)
|
||||
{
|
||||
kvm_pgtable_stage2_destroy_range(pgt, 0, BIT(pgt->ia_bits));
|
||||
kvm_pgtable_stage2_destroy_pgd(pgt);
|
||||
}
|
||||
|
||||
void kvm_pgtable_stage2_free_unlinked(struct kvm_pgtable_mm_ops *mm_ops, void *pgtable, s8 level)
|
||||
{
|
||||
kvm_pteref_t ptep = (kvm_pteref_t)pgtable;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ static bool __is_be(struct kvm_vcpu *vcpu)
|
|||
if (vcpu_mode_is_32bit(vcpu))
|
||||
return !!(read_sysreg_el2(SYS_SPSR) & PSR_AA32_E_BIT);
|
||||
|
||||
return !!(read_sysreg(SCTLR_EL1) & SCTLR_ELx_EE);
|
||||
return !!(read_sysreg_el1(SYS_SCTLR) & SCTLR_ELx_EE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -43,8 +43,11 @@ DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
|
|||
*
|
||||
* - API/APK: they are already accounted for by vcpu_load(), and can
|
||||
* only take effect across a load/put cycle (such as ERET)
|
||||
*
|
||||
* - FIEN: no way we let a guest have access to the RAS "Common Fault
|
||||
* Injection" thing, whatever that does
|
||||
*/
|
||||
#define NV_HCR_GUEST_EXCLUDE (HCR_TGE | HCR_API | HCR_APK)
|
||||
#define NV_HCR_GUEST_EXCLUDE (HCR_TGE | HCR_API | HCR_APK | HCR_FIEN)
|
||||
|
||||
static u64 __compute_hcr(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,19 +4,20 @@
|
|||
* Author: Christoffer Dall <c.dall@virtualopensystems.com>
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/kvm_host.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/hugetlb.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include <trace/events/kvm.h>
|
||||
#include <asm/acpi.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/kvm_arm.h>
|
||||
#include <asm/kvm_mmu.h>
|
||||
#include <asm/kvm_pgtable.h>
|
||||
#include <asm/kvm_pkvm.h>
|
||||
#include <asm/kvm_ras.h>
|
||||
#include <asm/kvm_asm.h>
|
||||
#include <asm/kvm_emulate.h>
|
||||
#include <asm/virt.h>
|
||||
|
|
@ -903,6 +904,38 @@ static int kvm_init_ipa_range(struct kvm_s2_mmu *mmu, unsigned long type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume that @pgt is valid and unlinked from the KVM MMU to free the
|
||||
* page-table without taking the kvm_mmu_lock and without performing any
|
||||
* TLB invalidations.
|
||||
*
|
||||
* Also, the range of addresses can be large enough to cause need_resched
|
||||
* warnings, for instance on CONFIG_PREEMPT_NONE kernels. Hence, invoke
|
||||
* cond_resched() periodically to prevent hogging the CPU for a long time
|
||||
* and schedule something else, if required.
|
||||
*/
|
||||
static void stage2_destroy_range(struct kvm_pgtable *pgt, phys_addr_t addr,
|
||||
phys_addr_t end)
|
||||
{
|
||||
u64 next;
|
||||
|
||||
do {
|
||||
next = stage2_range_addr_end(addr, end);
|
||||
KVM_PGT_FN(kvm_pgtable_stage2_destroy_range)(pgt, addr,
|
||||
next - addr);
|
||||
if (next != end)
|
||||
cond_resched();
|
||||
} while (addr = next, addr != end);
|
||||
}
|
||||
|
||||
static void kvm_stage2_destroy(struct kvm_pgtable *pgt)
|
||||
{
|
||||
unsigned int ia_bits = VTCR_EL2_IPA(pgt->mmu->vtcr);
|
||||
|
||||
stage2_destroy_range(pgt, 0, BIT(ia_bits));
|
||||
KVM_PGT_FN(kvm_pgtable_stage2_destroy_pgd)(pgt);
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_init_stage2_mmu - Initialise a S2 MMU structure
|
||||
* @kvm: The pointer to the KVM structure
|
||||
|
|
@ -979,7 +1012,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
|
|||
return 0;
|
||||
|
||||
out_destroy_pgtable:
|
||||
KVM_PGT_FN(kvm_pgtable_stage2_destroy)(pgt);
|
||||
kvm_stage2_destroy(pgt);
|
||||
out_free_pgtable:
|
||||
kfree(pgt);
|
||||
return err;
|
||||
|
|
@ -1076,7 +1109,7 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
|
|||
write_unlock(&kvm->mmu_lock);
|
||||
|
||||
if (pgt) {
|
||||
KVM_PGT_FN(kvm_pgtable_stage2_destroy)(pgt);
|
||||
kvm_stage2_destroy(pgt);
|
||||
kfree(pgt);
|
||||
}
|
||||
}
|
||||
|
|
@ -1811,6 +1844,19 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
|
|||
read_unlock(&vcpu->kvm->mmu_lock);
|
||||
}
|
||||
|
||||
int kvm_handle_guest_sea(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
/*
|
||||
* Give APEI the opportunity to claim the abort before handling it
|
||||
* within KVM. apei_claim_sea() expects to be called with IRQs enabled.
|
||||
*/
|
||||
lockdep_assert_irqs_enabled();
|
||||
if (apei_claim_sea(NULL) == 0)
|
||||
return 1;
|
||||
|
||||
return kvm_inject_serror(vcpu);
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_handle_guest_abort - handles all 2nd stage aborts
|
||||
* @vcpu: the VCPU pointer
|
||||
|
|
@ -1834,17 +1880,8 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
|
|||
gfn_t gfn;
|
||||
int ret, idx;
|
||||
|
||||
/* Synchronous External Abort? */
|
||||
if (kvm_vcpu_abt_issea(vcpu)) {
|
||||
/*
|
||||
* For RAS the host kernel may handle this abort.
|
||||
* There is no need to pass the error into the guest.
|
||||
*/
|
||||
if (kvm_handle_guest_sea())
|
||||
return kvm_inject_serror(vcpu);
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (kvm_vcpu_abt_issea(vcpu))
|
||||
return kvm_handle_guest_sea(vcpu);
|
||||
|
||||
esr = kvm_vcpu_get_esr(vcpu);
|
||||
|
||||
|
|
|
|||
|
|
@ -1287,7 +1287,10 @@ int kvm_handle_vncr_abort(struct kvm_vcpu *vcpu)
|
|||
struct vncr_tlb *vt = vcpu->arch.vncr_tlb;
|
||||
u64 esr = kvm_vcpu_get_esr(vcpu);
|
||||
|
||||
BUG_ON(!(esr & ESR_ELx_VNCR_SHIFT));
|
||||
WARN_ON_ONCE(!(esr & ESR_ELx_VNCR));
|
||||
|
||||
if (kvm_vcpu_abt_issea(vcpu))
|
||||
return kvm_handle_guest_sea(vcpu);
|
||||
|
||||
if (esr_fsc_is_permission_fault(esr)) {
|
||||
inject_vncr_perm(vcpu);
|
||||
|
|
|
|||
|
|
@ -316,9 +316,16 @@ static int __pkvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 start, u64 e
|
|||
return 0;
|
||||
}
|
||||
|
||||
void pkvm_pgtable_stage2_destroy(struct kvm_pgtable *pgt)
|
||||
void pkvm_pgtable_stage2_destroy_range(struct kvm_pgtable *pgt,
|
||||
u64 addr, u64 size)
|
||||
{
|
||||
__pkvm_pgtable_stage2_unmap(pgt, 0, ~(0ULL));
|
||||
__pkvm_pgtable_stage2_unmap(pgt, addr, addr + size);
|
||||
}
|
||||
|
||||
void pkvm_pgtable_stage2_destroy_pgd(struct kvm_pgtable *pgt)
|
||||
{
|
||||
/* Expected to be called after all pKVM mappings have been released. */
|
||||
WARN_ON_ONCE(!RB_EMPTY_ROOT(&pgt->pkvm_mappings.rb_root));
|
||||
}
|
||||
|
||||
int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
|
||||
|
|
|
|||
|
|
@ -82,43 +82,105 @@ static bool write_to_read_only(struct kvm_vcpu *vcpu,
|
|||
"sys_reg write to read-only register");
|
||||
}
|
||||
|
||||
#define PURE_EL2_SYSREG(el2) \
|
||||
case el2: { \
|
||||
*el1r = el2; \
|
||||
return true; \
|
||||
}
|
||||
enum sr_loc_attr {
|
||||
SR_LOC_MEMORY = 0, /* Register definitely in memory */
|
||||
SR_LOC_LOADED = BIT(0), /* Register on CPU, unless it cannot */
|
||||
SR_LOC_MAPPED = BIT(1), /* Register in a different CPU register */
|
||||
SR_LOC_XLATED = BIT(2), /* Register translated to fit another reg */
|
||||
SR_LOC_SPECIAL = BIT(3), /* Demanding register, implies loaded */
|
||||
};
|
||||
|
||||
#define MAPPED_EL2_SYSREG(el2, el1, fn) \
|
||||
case el2: { \
|
||||
*xlate = fn; \
|
||||
*el1r = el1; \
|
||||
return true; \
|
||||
}
|
||||
struct sr_loc {
|
||||
enum sr_loc_attr loc;
|
||||
enum vcpu_sysreg map_reg;
|
||||
u64 (*xlate)(u64);
|
||||
};
|
||||
|
||||
static bool get_el2_to_el1_mapping(unsigned int reg,
|
||||
unsigned int *el1r, u64 (**xlate)(u64))
|
||||
static enum sr_loc_attr locate_direct_register(const struct kvm_vcpu *vcpu,
|
||||
enum vcpu_sysreg reg)
|
||||
{
|
||||
switch (reg) {
|
||||
PURE_EL2_SYSREG( VPIDR_EL2 );
|
||||
PURE_EL2_SYSREG( VMPIDR_EL2 );
|
||||
PURE_EL2_SYSREG( ACTLR_EL2 );
|
||||
PURE_EL2_SYSREG( HCR_EL2 );
|
||||
PURE_EL2_SYSREG( MDCR_EL2 );
|
||||
PURE_EL2_SYSREG( HSTR_EL2 );
|
||||
PURE_EL2_SYSREG( HACR_EL2 );
|
||||
PURE_EL2_SYSREG( VTTBR_EL2 );
|
||||
PURE_EL2_SYSREG( VTCR_EL2 );
|
||||
PURE_EL2_SYSREG( TPIDR_EL2 );
|
||||
PURE_EL2_SYSREG( HPFAR_EL2 );
|
||||
PURE_EL2_SYSREG( HCRX_EL2 );
|
||||
PURE_EL2_SYSREG( HFGRTR_EL2 );
|
||||
PURE_EL2_SYSREG( HFGWTR_EL2 );
|
||||
PURE_EL2_SYSREG( HFGITR_EL2 );
|
||||
PURE_EL2_SYSREG( HDFGRTR_EL2 );
|
||||
PURE_EL2_SYSREG( HDFGWTR_EL2 );
|
||||
PURE_EL2_SYSREG( HAFGRTR_EL2 );
|
||||
PURE_EL2_SYSREG( CNTVOFF_EL2 );
|
||||
PURE_EL2_SYSREG( CNTHCTL_EL2 );
|
||||
case SCTLR_EL1:
|
||||
case CPACR_EL1:
|
||||
case TTBR0_EL1:
|
||||
case TTBR1_EL1:
|
||||
case TCR_EL1:
|
||||
case TCR2_EL1:
|
||||
case PIR_EL1:
|
||||
case PIRE0_EL1:
|
||||
case POR_EL1:
|
||||
case ESR_EL1:
|
||||
case AFSR0_EL1:
|
||||
case AFSR1_EL1:
|
||||
case FAR_EL1:
|
||||
case MAIR_EL1:
|
||||
case VBAR_EL1:
|
||||
case CONTEXTIDR_EL1:
|
||||
case AMAIR_EL1:
|
||||
case CNTKCTL_EL1:
|
||||
case ELR_EL1:
|
||||
case SPSR_EL1:
|
||||
case ZCR_EL1:
|
||||
case SCTLR2_EL1:
|
||||
/*
|
||||
* EL1 registers which have an ELx2 mapping are loaded if
|
||||
* we're not in hypervisor context.
|
||||
*/
|
||||
return is_hyp_ctxt(vcpu) ? SR_LOC_MEMORY : SR_LOC_LOADED;
|
||||
|
||||
case TPIDR_EL0:
|
||||
case TPIDRRO_EL0:
|
||||
case TPIDR_EL1:
|
||||
case PAR_EL1:
|
||||
case DACR32_EL2:
|
||||
case IFSR32_EL2:
|
||||
case DBGVCR32_EL2:
|
||||
/* These registers are always loaded, no matter what */
|
||||
return SR_LOC_LOADED;
|
||||
|
||||
default:
|
||||
/* Non-mapped EL2 registers are by definition in memory. */
|
||||
return SR_LOC_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
static void locate_mapped_el2_register(const struct kvm_vcpu *vcpu,
|
||||
enum vcpu_sysreg reg,
|
||||
enum vcpu_sysreg map_reg,
|
||||
u64 (*xlate)(u64),
|
||||
struct sr_loc *loc)
|
||||
{
|
||||
if (!is_hyp_ctxt(vcpu)) {
|
||||
loc->loc = SR_LOC_MEMORY;
|
||||
return;
|
||||
}
|
||||
|
||||
loc->loc = SR_LOC_LOADED | SR_LOC_MAPPED;
|
||||
loc->map_reg = map_reg;
|
||||
|
||||
WARN_ON(locate_direct_register(vcpu, map_reg) != SR_LOC_MEMORY);
|
||||
|
||||
if (xlate != NULL && !vcpu_el2_e2h_is_set(vcpu)) {
|
||||
loc->loc |= SR_LOC_XLATED;
|
||||
loc->xlate = xlate;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAPPED_EL2_SYSREG(r, m, t) \
|
||||
case r: { \
|
||||
locate_mapped_el2_register(vcpu, r, m, t, loc); \
|
||||
break; \
|
||||
}
|
||||
|
||||
static void locate_register(const struct kvm_vcpu *vcpu, enum vcpu_sysreg reg,
|
||||
struct sr_loc *loc)
|
||||
{
|
||||
if (!vcpu_get_flag(vcpu, SYSREGS_ON_CPU)) {
|
||||
loc->loc = SR_LOC_MEMORY;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (reg) {
|
||||
MAPPED_EL2_SYSREG(SCTLR_EL2, SCTLR_EL1,
|
||||
translate_sctlr_el2_to_sctlr_el1 );
|
||||
MAPPED_EL2_SYSREG(CPTR_EL2, CPACR_EL1,
|
||||
|
|
@ -144,125 +206,189 @@ static bool get_el2_to_el1_mapping(unsigned int reg,
|
|||
MAPPED_EL2_SYSREG(ZCR_EL2, ZCR_EL1, NULL );
|
||||
MAPPED_EL2_SYSREG(CONTEXTIDR_EL2, CONTEXTIDR_EL1, NULL );
|
||||
MAPPED_EL2_SYSREG(SCTLR2_EL2, SCTLR2_EL1, NULL );
|
||||
case CNTHCTL_EL2:
|
||||
/* CNTHCTL_EL2 is super special, until we support NV2.1 */
|
||||
loc->loc = ((is_hyp_ctxt(vcpu) && vcpu_el2_e2h_is_set(vcpu)) ?
|
||||
SR_LOC_SPECIAL : SR_LOC_MEMORY);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
loc->loc = locate_direct_register(vcpu, reg);
|
||||
}
|
||||
}
|
||||
|
||||
u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
|
||||
static u64 read_sr_from_cpu(enum vcpu_sysreg reg)
|
||||
{
|
||||
u64 val = 0x8badf00d8badf00d;
|
||||
u64 (*xlate)(u64) = NULL;
|
||||
unsigned int el1r;
|
||||
|
||||
if (!vcpu_get_flag(vcpu, SYSREGS_ON_CPU))
|
||||
goto memory_read;
|
||||
switch (reg) {
|
||||
case SCTLR_EL1: val = read_sysreg_s(SYS_SCTLR_EL12); break;
|
||||
case CPACR_EL1: val = read_sysreg_s(SYS_CPACR_EL12); break;
|
||||
case TTBR0_EL1: val = read_sysreg_s(SYS_TTBR0_EL12); break;
|
||||
case TTBR1_EL1: val = read_sysreg_s(SYS_TTBR1_EL12); break;
|
||||
case TCR_EL1: val = read_sysreg_s(SYS_TCR_EL12); break;
|
||||
case TCR2_EL1: val = read_sysreg_s(SYS_TCR2_EL12); break;
|
||||
case PIR_EL1: val = read_sysreg_s(SYS_PIR_EL12); break;
|
||||
case PIRE0_EL1: val = read_sysreg_s(SYS_PIRE0_EL12); break;
|
||||
case POR_EL1: val = read_sysreg_s(SYS_POR_EL12); break;
|
||||
case ESR_EL1: val = read_sysreg_s(SYS_ESR_EL12); break;
|
||||
case AFSR0_EL1: val = read_sysreg_s(SYS_AFSR0_EL12); break;
|
||||
case AFSR1_EL1: val = read_sysreg_s(SYS_AFSR1_EL12); break;
|
||||
case FAR_EL1: val = read_sysreg_s(SYS_FAR_EL12); break;
|
||||
case MAIR_EL1: val = read_sysreg_s(SYS_MAIR_EL12); break;
|
||||
case VBAR_EL1: val = read_sysreg_s(SYS_VBAR_EL12); break;
|
||||
case CONTEXTIDR_EL1: val = read_sysreg_s(SYS_CONTEXTIDR_EL12);break;
|
||||
case AMAIR_EL1: val = read_sysreg_s(SYS_AMAIR_EL12); break;
|
||||
case CNTKCTL_EL1: val = read_sysreg_s(SYS_CNTKCTL_EL12); break;
|
||||
case ELR_EL1: val = read_sysreg_s(SYS_ELR_EL12); break;
|
||||
case SPSR_EL1: val = read_sysreg_s(SYS_SPSR_EL12); break;
|
||||
case ZCR_EL1: val = read_sysreg_s(SYS_ZCR_EL12); break;
|
||||
case SCTLR2_EL1: val = read_sysreg_s(SYS_SCTLR2_EL12); break;
|
||||
case TPIDR_EL0: val = read_sysreg_s(SYS_TPIDR_EL0); break;
|
||||
case TPIDRRO_EL0: val = read_sysreg_s(SYS_TPIDRRO_EL0); break;
|
||||
case TPIDR_EL1: val = read_sysreg_s(SYS_TPIDR_EL1); break;
|
||||
case PAR_EL1: val = read_sysreg_par(); break;
|
||||
case DACR32_EL2: val = read_sysreg_s(SYS_DACR32_EL2); break;
|
||||
case IFSR32_EL2: val = read_sysreg_s(SYS_IFSR32_EL2); break;
|
||||
case DBGVCR32_EL2: val = read_sysreg_s(SYS_DBGVCR32_EL2); break;
|
||||
default: WARN_ON_ONCE(1);
|
||||
}
|
||||
|
||||
if (unlikely(get_el2_to_el1_mapping(reg, &el1r, &xlate))) {
|
||||
if (!is_hyp_ctxt(vcpu))
|
||||
goto memory_read;
|
||||
return val;
|
||||
}
|
||||
|
||||
static void write_sr_to_cpu(enum vcpu_sysreg reg, u64 val)
|
||||
{
|
||||
switch (reg) {
|
||||
case SCTLR_EL1: write_sysreg_s(val, SYS_SCTLR_EL12); break;
|
||||
case CPACR_EL1: write_sysreg_s(val, SYS_CPACR_EL12); break;
|
||||
case TTBR0_EL1: write_sysreg_s(val, SYS_TTBR0_EL12); break;
|
||||
case TTBR1_EL1: write_sysreg_s(val, SYS_TTBR1_EL12); break;
|
||||
case TCR_EL1: write_sysreg_s(val, SYS_TCR_EL12); break;
|
||||
case TCR2_EL1: write_sysreg_s(val, SYS_TCR2_EL12); break;
|
||||
case PIR_EL1: write_sysreg_s(val, SYS_PIR_EL12); break;
|
||||
case PIRE0_EL1: write_sysreg_s(val, SYS_PIRE0_EL12); break;
|
||||
case POR_EL1: write_sysreg_s(val, SYS_POR_EL12); break;
|
||||
case ESR_EL1: write_sysreg_s(val, SYS_ESR_EL12); break;
|
||||
case AFSR0_EL1: write_sysreg_s(val, SYS_AFSR0_EL12); break;
|
||||
case AFSR1_EL1: write_sysreg_s(val, SYS_AFSR1_EL12); break;
|
||||
case FAR_EL1: write_sysreg_s(val, SYS_FAR_EL12); break;
|
||||
case MAIR_EL1: write_sysreg_s(val, SYS_MAIR_EL12); break;
|
||||
case VBAR_EL1: write_sysreg_s(val, SYS_VBAR_EL12); break;
|
||||
case CONTEXTIDR_EL1: write_sysreg_s(val, SYS_CONTEXTIDR_EL12);break;
|
||||
case AMAIR_EL1: write_sysreg_s(val, SYS_AMAIR_EL12); break;
|
||||
case CNTKCTL_EL1: write_sysreg_s(val, SYS_CNTKCTL_EL12); break;
|
||||
case ELR_EL1: write_sysreg_s(val, SYS_ELR_EL12); break;
|
||||
case SPSR_EL1: write_sysreg_s(val, SYS_SPSR_EL12); break;
|
||||
case ZCR_EL1: write_sysreg_s(val, SYS_ZCR_EL12); break;
|
||||
case SCTLR2_EL1: write_sysreg_s(val, SYS_SCTLR2_EL12); break;
|
||||
case TPIDR_EL0: write_sysreg_s(val, SYS_TPIDR_EL0); break;
|
||||
case TPIDRRO_EL0: write_sysreg_s(val, SYS_TPIDRRO_EL0); break;
|
||||
case TPIDR_EL1: write_sysreg_s(val, SYS_TPIDR_EL1); break;
|
||||
case PAR_EL1: write_sysreg_s(val, SYS_PAR_EL1); break;
|
||||
case DACR32_EL2: write_sysreg_s(val, SYS_DACR32_EL2); break;
|
||||
case IFSR32_EL2: write_sysreg_s(val, SYS_IFSR32_EL2); break;
|
||||
case DBGVCR32_EL2: write_sysreg_s(val, SYS_DBGVCR32_EL2); break;
|
||||
default: WARN_ON_ONCE(1);
|
||||
}
|
||||
}
|
||||
|
||||
u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, enum vcpu_sysreg reg)
|
||||
{
|
||||
struct sr_loc loc = {};
|
||||
|
||||
locate_register(vcpu, reg, &loc);
|
||||
|
||||
WARN_ON_ONCE(!has_vhe() && loc.loc != SR_LOC_MEMORY);
|
||||
|
||||
if (loc.loc & SR_LOC_SPECIAL) {
|
||||
u64 val;
|
||||
|
||||
WARN_ON_ONCE(loc.loc & ~SR_LOC_SPECIAL);
|
||||
|
||||
/*
|
||||
* CNTHCTL_EL2 requires some special treatment to
|
||||
* account for the bits that can be set via CNTKCTL_EL1.
|
||||
* CNTHCTL_EL2 requires some special treatment to account
|
||||
* for the bits that can be set via CNTKCTL_EL1 when E2H==1.
|
||||
*/
|
||||
switch (reg) {
|
||||
case CNTHCTL_EL2:
|
||||
if (vcpu_el2_e2h_is_set(vcpu)) {
|
||||
val = read_sysreg_el1(SYS_CNTKCTL);
|
||||
val &= CNTKCTL_VALID_BITS;
|
||||
val |= __vcpu_sys_reg(vcpu, reg) & ~CNTKCTL_VALID_BITS;
|
||||
return val;
|
||||
}
|
||||
break;
|
||||
val = read_sysreg_el1(SYS_CNTKCTL);
|
||||
val &= CNTKCTL_VALID_BITS;
|
||||
val |= __vcpu_sys_reg(vcpu, reg) & ~CNTKCTL_VALID_BITS;
|
||||
return val;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this register does not have an EL1 counterpart,
|
||||
* then read the stored EL2 version.
|
||||
*/
|
||||
if (reg == el1r)
|
||||
goto memory_read;
|
||||
|
||||
/*
|
||||
* If we have a non-VHE guest and that the sysreg
|
||||
* requires translation to be used at EL1, use the
|
||||
* in-memory copy instead.
|
||||
*/
|
||||
if (!vcpu_el2_e2h_is_set(vcpu) && xlate)
|
||||
goto memory_read;
|
||||
|
||||
/* Get the current version of the EL1 counterpart. */
|
||||
WARN_ON(!__vcpu_read_sys_reg_from_cpu(el1r, &val));
|
||||
if (reg >= __SANITISED_REG_START__)
|
||||
val = kvm_vcpu_apply_reg_masks(vcpu, reg, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/* EL1 register can't be on the CPU if the guest is in vEL2. */
|
||||
if (unlikely(is_hyp_ctxt(vcpu)))
|
||||
goto memory_read;
|
||||
if (loc.loc & SR_LOC_LOADED) {
|
||||
enum vcpu_sysreg map_reg = reg;
|
||||
|
||||
if (__vcpu_read_sys_reg_from_cpu(reg, &val))
|
||||
return val;
|
||||
if (loc.loc & SR_LOC_MAPPED)
|
||||
map_reg = loc.map_reg;
|
||||
|
||||
if (!(loc.loc & SR_LOC_XLATED)) {
|
||||
u64 val = read_sr_from_cpu(map_reg);
|
||||
|
||||
if (reg >= __SANITISED_REG_START__)
|
||||
val = kvm_vcpu_apply_reg_masks(vcpu, reg, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
memory_read:
|
||||
return __vcpu_sys_reg(vcpu, reg);
|
||||
}
|
||||
|
||||
void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
|
||||
void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, enum vcpu_sysreg reg)
|
||||
{
|
||||
u64 (*xlate)(u64) = NULL;
|
||||
unsigned int el1r;
|
||||
struct sr_loc loc = {};
|
||||
|
||||
if (!vcpu_get_flag(vcpu, SYSREGS_ON_CPU))
|
||||
goto memory_write;
|
||||
locate_register(vcpu, reg, &loc);
|
||||
|
||||
if (unlikely(get_el2_to_el1_mapping(reg, &el1r, &xlate))) {
|
||||
if (!is_hyp_ctxt(vcpu))
|
||||
goto memory_write;
|
||||
WARN_ON_ONCE(!has_vhe() && loc.loc != SR_LOC_MEMORY);
|
||||
|
||||
/*
|
||||
* Always store a copy of the write to memory to avoid having
|
||||
* to reverse-translate virtual EL2 system registers for a
|
||||
* non-VHE guest hypervisor.
|
||||
*/
|
||||
__vcpu_assign_sys_reg(vcpu, reg, val);
|
||||
if (loc.loc & SR_LOC_SPECIAL) {
|
||||
|
||||
WARN_ON_ONCE(loc.loc & ~SR_LOC_SPECIAL);
|
||||
|
||||
switch (reg) {
|
||||
case CNTHCTL_EL2:
|
||||
/*
|
||||
* If E2H=0, CNHTCTL_EL2 is a pure shadow register.
|
||||
* Otherwise, some of the bits are backed by
|
||||
* If E2H=1, some of the bits are backed by
|
||||
* CNTKCTL_EL1, while the rest is kept in memory.
|
||||
* Yes, this is fun stuff.
|
||||
*/
|
||||
if (vcpu_el2_e2h_is_set(vcpu))
|
||||
write_sysreg_el1(val, SYS_CNTKCTL);
|
||||
return;
|
||||
write_sysreg_el1(val, SYS_CNTKCTL);
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
|
||||
/* No EL1 counterpart? We're done here.? */
|
||||
if (reg == el1r)
|
||||
return;
|
||||
|
||||
if (!vcpu_el2_e2h_is_set(vcpu) && xlate)
|
||||
val = xlate(val);
|
||||
|
||||
/* Redirect this to the EL1 version of the register. */
|
||||
WARN_ON(!__vcpu_write_sys_reg_to_cpu(val, el1r));
|
||||
return;
|
||||
}
|
||||
|
||||
/* EL1 register can't be on the CPU if the guest is in vEL2. */
|
||||
if (unlikely(is_hyp_ctxt(vcpu)))
|
||||
goto memory_write;
|
||||
if (loc.loc & SR_LOC_LOADED) {
|
||||
enum vcpu_sysreg map_reg = reg;
|
||||
u64 xlated_val;
|
||||
|
||||
if (__vcpu_write_sys_reg_to_cpu(val, reg))
|
||||
return;
|
||||
if (reg >= __SANITISED_REG_START__)
|
||||
val = kvm_vcpu_apply_reg_masks(vcpu, reg, val);
|
||||
|
||||
if (loc.loc & SR_LOC_MAPPED)
|
||||
map_reg = loc.map_reg;
|
||||
|
||||
if (loc.loc & SR_LOC_XLATED)
|
||||
xlated_val = loc.xlate(val);
|
||||
else
|
||||
xlated_val = val;
|
||||
|
||||
write_sr_to_cpu(map_reg, xlated_val);
|
||||
|
||||
/*
|
||||
* Fall through to write the backing store anyway, which
|
||||
* allows translated registers to be directly read without a
|
||||
* reverse translation.
|
||||
*/
|
||||
}
|
||||
|
||||
memory_write:
|
||||
__vcpu_assign_sys_reg(vcpu, reg, val);
|
||||
}
|
||||
|
||||
|
|
@ -1584,6 +1710,7 @@ static u8 pmuver_to_perfmon(u8 pmuver)
|
|||
}
|
||||
|
||||
static u64 sanitise_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu, u64 val);
|
||||
static u64 sanitise_id_aa64pfr1_el1(const struct kvm_vcpu *vcpu, u64 val);
|
||||
static u64 sanitise_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val);
|
||||
|
||||
/* Read a sanitised cpufeature ID register by sys_reg_desc */
|
||||
|
|
@ -1606,19 +1733,7 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
|
|||
val = sanitise_id_aa64pfr0_el1(vcpu, val);
|
||||
break;
|
||||
case SYS_ID_AA64PFR1_EL1:
|
||||
if (!kvm_has_mte(vcpu->kvm)) {
|
||||
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE);
|
||||
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE_frac);
|
||||
}
|
||||
|
||||
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME);
|
||||
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_RNDR_trap);
|
||||
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_NMI);
|
||||
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_GCS);
|
||||
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_THE);
|
||||
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTEX);
|
||||
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_PFAR);
|
||||
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MPAM_frac);
|
||||
val = sanitise_id_aa64pfr1_el1(vcpu, val);
|
||||
break;
|
||||
case SYS_ID_AA64PFR2_EL1:
|
||||
val &= ID_AA64PFR2_EL1_FPMR |
|
||||
|
|
@ -1628,18 +1743,18 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
|
|||
break;
|
||||
case SYS_ID_AA64ISAR1_EL1:
|
||||
if (!vcpu_has_ptrauth(vcpu))
|
||||
val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_APA) |
|
||||
ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_API) |
|
||||
ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPA) |
|
||||
ARM64_FEATURE_MASK(ID_AA64ISAR1_EL1_GPI));
|
||||
val &= ~(ID_AA64ISAR1_EL1_APA |
|
||||
ID_AA64ISAR1_EL1_API |
|
||||
ID_AA64ISAR1_EL1_GPA |
|
||||
ID_AA64ISAR1_EL1_GPI);
|
||||
break;
|
||||
case SYS_ID_AA64ISAR2_EL1:
|
||||
if (!vcpu_has_ptrauth(vcpu))
|
||||
val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_APA3) |
|
||||
ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_GPA3));
|
||||
val &= ~(ID_AA64ISAR2_EL1_APA3 |
|
||||
ID_AA64ISAR2_EL1_GPA3);
|
||||
if (!cpus_have_final_cap(ARM64_HAS_WFXT) ||
|
||||
has_broken_cntvoff())
|
||||
val &= ~ARM64_FEATURE_MASK(ID_AA64ISAR2_EL1_WFxT);
|
||||
val &= ~ID_AA64ISAR2_EL1_WFxT;
|
||||
break;
|
||||
case SYS_ID_AA64ISAR3_EL1:
|
||||
val &= ID_AA64ISAR3_EL1_FPRCVT | ID_AA64ISAR3_EL1_FAMINMAX;
|
||||
|
|
@ -1655,7 +1770,7 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
|
|||
ID_AA64MMFR3_EL1_S1PIE;
|
||||
break;
|
||||
case SYS_ID_MMFR4_EL1:
|
||||
val &= ~ARM64_FEATURE_MASK(ID_MMFR4_EL1_CCIDX);
|
||||
val &= ~ID_MMFR4_EL1_CCIDX;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1836,6 +1951,31 @@ static u64 sanitise_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu, u64 val)
|
|||
return val;
|
||||
}
|
||||
|
||||
static u64 sanitise_id_aa64pfr1_el1(const struct kvm_vcpu *vcpu, u64 val)
|
||||
{
|
||||
u64 pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
|
||||
|
||||
if (!kvm_has_mte(vcpu->kvm)) {
|
||||
val &= ~ID_AA64PFR1_EL1_MTE;
|
||||
val &= ~ID_AA64PFR1_EL1_MTE_frac;
|
||||
}
|
||||
|
||||
if (!(cpus_have_final_cap(ARM64_HAS_RASV1P1_EXTN) &&
|
||||
SYS_FIELD_GET(ID_AA64PFR0_EL1, RAS, pfr0) == ID_AA64PFR0_EL1_RAS_IMP))
|
||||
val &= ~ID_AA64PFR1_EL1_RAS_frac;
|
||||
|
||||
val &= ~ID_AA64PFR1_EL1_SME;
|
||||
val &= ~ID_AA64PFR1_EL1_RNDR_trap;
|
||||
val &= ~ID_AA64PFR1_EL1_NMI;
|
||||
val &= ~ID_AA64PFR1_EL1_GCS;
|
||||
val &= ~ID_AA64PFR1_EL1_THE;
|
||||
val &= ~ID_AA64PFR1_EL1_MTEX;
|
||||
val &= ~ID_AA64PFR1_EL1_PFAR;
|
||||
val &= ~ID_AA64PFR1_EL1_MPAM_frac;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static u64 sanitise_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val)
|
||||
{
|
||||
val = ID_REG_LIMIT_FIELD_ENUM(val, ID_AA64DFR0_EL1, DebugVer, V8P8);
|
||||
|
|
@ -2697,6 +2837,18 @@ static bool access_ras(struct kvm_vcpu *vcpu,
|
|||
struct kvm *kvm = vcpu->kvm;
|
||||
|
||||
switch(reg_to_encoding(r)) {
|
||||
case SYS_ERXPFGCDN_EL1:
|
||||
case SYS_ERXPFGCTL_EL1:
|
||||
case SYS_ERXPFGF_EL1:
|
||||
case SYS_ERXMISC2_EL1:
|
||||
case SYS_ERXMISC3_EL1:
|
||||
if (!(kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, V1P1) ||
|
||||
(kvm_has_feat_enum(kvm, ID_AA64PFR0_EL1, RAS, IMP) &&
|
||||
kvm_has_feat(kvm, ID_AA64PFR1_EL1, RAS_frac, RASv1p1)))) {
|
||||
kvm_inject_undefined(vcpu);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, RAS, IMP)) {
|
||||
kvm_inject_undefined(vcpu);
|
||||
|
|
@ -2929,7 +3081,6 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
|||
~(ID_AA64PFR0_EL1_AMU |
|
||||
ID_AA64PFR0_EL1_MPAM |
|
||||
ID_AA64PFR0_EL1_SVE |
|
||||
ID_AA64PFR0_EL1_RAS |
|
||||
ID_AA64PFR0_EL1_AdvSIMD |
|
||||
ID_AA64PFR0_EL1_FP)),
|
||||
ID_FILTERED(ID_AA64PFR1_EL1, id_aa64pfr1_el1,
|
||||
|
|
@ -2943,7 +3094,6 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
|||
ID_AA64PFR1_EL1_SME |
|
||||
ID_AA64PFR1_EL1_RES0 |
|
||||
ID_AA64PFR1_EL1_MPAM_frac |
|
||||
ID_AA64PFR1_EL1_RAS_frac |
|
||||
ID_AA64PFR1_EL1_MTE)),
|
||||
ID_WRITABLE(ID_AA64PFR2_EL1,
|
||||
ID_AA64PFR2_EL1_FPMR |
|
||||
|
|
@ -3063,8 +3213,13 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
|||
{ SYS_DESC(SYS_ERXCTLR_EL1), access_ras },
|
||||
{ SYS_DESC(SYS_ERXSTATUS_EL1), access_ras },
|
||||
{ SYS_DESC(SYS_ERXADDR_EL1), access_ras },
|
||||
{ SYS_DESC(SYS_ERXPFGF_EL1), access_ras },
|
||||
{ SYS_DESC(SYS_ERXPFGCTL_EL1), access_ras },
|
||||
{ SYS_DESC(SYS_ERXPFGCDN_EL1), access_ras },
|
||||
{ SYS_DESC(SYS_ERXMISC0_EL1), access_ras },
|
||||
{ SYS_DESC(SYS_ERXMISC1_EL1), access_ras },
|
||||
{ SYS_DESC(SYS_ERXMISC2_EL1), access_ras },
|
||||
{ SYS_DESC(SYS_ERXMISC3_EL1), access_ras },
|
||||
|
||||
MTE_REG(TFSR_EL1),
|
||||
MTE_REG(TFSRE0_EL1),
|
||||
|
|
|
|||
|
|
@ -50,6 +50,14 @@ bool vgic_has_its(struct kvm *kvm)
|
|||
|
||||
bool vgic_supports_direct_msis(struct kvm *kvm)
|
||||
{
|
||||
/*
|
||||
* Deliberately conflate vLPI and vSGI support on GICv4.1 hardware,
|
||||
* indirectly allowing userspace to control whether or not vPEs are
|
||||
* allocated for the VM.
|
||||
*/
|
||||
if (system_supports_direct_sgis() && !vgic_supports_direct_sgis(kvm))
|
||||
return false;
|
||||
|
||||
return kvm_vgic_global_state.has_gicv4 && vgic_has_its(kvm);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1091,7 +1091,7 @@ int vgic_register_dist_iodev(struct kvm *kvm, gpa_t dist_base_address,
|
|||
len = vgic_v3_init_dist_iodev(io_device);
|
||||
break;
|
||||
default:
|
||||
BUG_ON(1);
|
||||
BUG();
|
||||
}
|
||||
|
||||
io_device->base_addr = dist_base_address;
|
||||
|
|
|
|||
|
|
@ -396,15 +396,7 @@ bool vgic_supports_direct_sgis(struct kvm *kvm);
|
|||
|
||||
static inline bool vgic_supports_direct_irqs(struct kvm *kvm)
|
||||
{
|
||||
/*
|
||||
* Deliberately conflate vLPI and vSGI support on GICv4.1 hardware,
|
||||
* indirectly allowing userspace to control whether or not vPEs are
|
||||
* allocated for the VM.
|
||||
*/
|
||||
if (system_supports_direct_sgis())
|
||||
return vgic_supports_direct_sgis(kvm);
|
||||
|
||||
return vgic_supports_direct_msis(kvm);
|
||||
return vgic_supports_direct_msis(kvm) || vgic_supports_direct_sgis(kvm);
|
||||
}
|
||||
|
||||
int vgic_v4_init(struct kvm *kvm);
|
||||
|
|
|
|||
|
|
@ -47,13 +47,6 @@
|
|||
#define NO_CONT_MAPPINGS BIT(1)
|
||||
#define NO_EXEC_MAPPINGS BIT(2) /* assumes FEAT_HPDS is not used */
|
||||
|
||||
enum pgtable_type {
|
||||
TABLE_PTE,
|
||||
TABLE_PMD,
|
||||
TABLE_PUD,
|
||||
TABLE_P4D,
|
||||
};
|
||||
|
||||
u64 kimage_voffset __ro_after_init;
|
||||
EXPORT_SYMBOL(kimage_voffset);
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ HAS_S1PIE
|
|||
HAS_S1POE
|
||||
HAS_SCTLR2
|
||||
HAS_RAS_EXTN
|
||||
HAS_RASV1P1_EXTN
|
||||
HAS_RNG
|
||||
HAS_SB
|
||||
HAS_STAGE2_FWB
|
||||
|
|
|
|||
|
|
@ -102,7 +102,13 @@ KBUILD_CFLAGS += $(call cc-option,-mthin-add-sub) $(call cc-option,-Wa$(comma)
|
|||
|
||||
ifdef CONFIG_OBJTOOL
|
||||
ifdef CONFIG_CC_HAS_ANNOTATE_TABLEJUMP
|
||||
# The annotate-tablejump option can not be passed to LLVM backend when LTO is enabled.
|
||||
# Ensure it is aware of linker with LTO, '--loongarch-annotate-tablejump' also needs to
|
||||
# be passed via '-mllvm' to ld.lld.
|
||||
KBUILD_CFLAGS += -mannotate-tablejump
|
||||
ifdef CONFIG_LTO_CLANG
|
||||
KBUILD_LDFLAGS += -mllvm --loongarch-annotate-tablejump
|
||||
endif
|
||||
else
|
||||
KBUILD_CFLAGS += -fno-jump-tables # keep compatibility with older compilers
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
.endm
|
||||
|
||||
.macro STACKLEAK_ERASE
|
||||
#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
|
||||
#ifdef CONFIG_KSTACK_ERASE
|
||||
bl stackleak_erase_on_task_stack
|
||||
#endif
|
||||
.endm
|
||||
|
|
|
|||
8
arch/loongarch/include/uapi/asm/setup.h
Normal file
8
arch/loongarch/include/uapi/asm/setup.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
|
||||
#ifndef _UAPI_ASM_LOONGARCH_SETUP_H
|
||||
#define _UAPI_ASM_LOONGARCH_SETUP_H
|
||||
|
||||
#define COMMAND_LINE_SIZE 4096
|
||||
|
||||
#endif /* _UAPI_ASM_LOONGARCH_SETUP_H */
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/moduleloader.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/sort.h>
|
||||
|
||||
Elf_Addr module_emit_got_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val)
|
||||
{
|
||||
|
|
@ -61,39 +62,38 @@ Elf_Addr module_emit_plt_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr v
|
|||
return (Elf_Addr)&plt[nr];
|
||||
}
|
||||
|
||||
static int is_rela_equal(const Elf_Rela *x, const Elf_Rela *y)
|
||||
#define cmp_3way(a, b) ((a) < (b) ? -1 : (a) > (b))
|
||||
|
||||
static int compare_rela(const void *x, const void *y)
|
||||
{
|
||||
return x->r_info == y->r_info && x->r_addend == y->r_addend;
|
||||
}
|
||||
int ret;
|
||||
const Elf_Rela *rela_x = x, *rela_y = y;
|
||||
|
||||
static bool duplicate_rela(const Elf_Rela *rela, int idx)
|
||||
{
|
||||
int i;
|
||||
ret = cmp_3way(rela_x->r_info, rela_y->r_info);
|
||||
if (ret == 0)
|
||||
ret = cmp_3way(rela_x->r_addend, rela_y->r_addend);
|
||||
|
||||
for (i = 0; i < idx; i++) {
|
||||
if (is_rela_equal(&rela[i], &rela[idx]))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void count_max_entries(Elf_Rela *relas, int num,
|
||||
unsigned int *plts, unsigned int *gots)
|
||||
{
|
||||
unsigned int i, type;
|
||||
unsigned int i;
|
||||
|
||||
sort(relas, num, sizeof(Elf_Rela), compare_rela, NULL);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
type = ELF_R_TYPE(relas[i].r_info);
|
||||
switch (type) {
|
||||
if (i && !compare_rela(&relas[i-1], &relas[i]))
|
||||
continue;
|
||||
|
||||
switch (ELF_R_TYPE(relas[i].r_info)) {
|
||||
case R_LARCH_SOP_PUSH_PLT_PCREL:
|
||||
case R_LARCH_B26:
|
||||
if (!duplicate_rela(relas, i))
|
||||
(*plts)++;
|
||||
(*plts)++;
|
||||
break;
|
||||
case R_LARCH_GOT_PC_HI20:
|
||||
if (!duplicate_rela(relas, i))
|
||||
(*gots)++;
|
||||
(*gots)++;
|
||||
break;
|
||||
default:
|
||||
break; /* Do nothing. */
|
||||
|
|
|
|||
|
|
@ -677,6 +677,11 @@ static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
|
|||
for (i = 1; i < 32; i++)
|
||||
err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LBT
|
||||
if (extctx->lbt.addr)
|
||||
err |= protected_save_lbt_context(extctx);
|
||||
#endif
|
||||
|
||||
if (extctx->lasx.addr)
|
||||
err |= protected_save_lasx_context(extctx);
|
||||
else if (extctx->lsx.addr)
|
||||
|
|
@ -684,11 +689,6 @@ static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
|
|||
else if (extctx->fpu.addr)
|
||||
err |= protected_save_fpu_context(extctx);
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LBT
|
||||
if (extctx->lbt.addr)
|
||||
err |= protected_save_lbt_context(extctx);
|
||||
#endif
|
||||
|
||||
/* Set the "end" magic */
|
||||
info = (struct sctx_info *)extctx->end.addr;
|
||||
err |= __put_user(0, &info->magic);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/cpuhotplug.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/init.h>
|
||||
|
|
@ -102,6 +103,23 @@ static int constant_timer_next_event(unsigned long delta, struct clock_event_dev
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int arch_timer_starting(unsigned int cpu)
|
||||
{
|
||||
set_csr_ecfg(ECFGF_TIMER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arch_timer_dying(unsigned int cpu)
|
||||
{
|
||||
constant_set_state_shutdown(this_cpu_ptr(&constant_clockevent_device));
|
||||
|
||||
/* Clear Timer Interrupt */
|
||||
write_csr_tintclear(CSR_TINTCLR_TI);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long get_loops_per_jiffy(void)
|
||||
{
|
||||
unsigned long lpj = (unsigned long)const_clock_freq;
|
||||
|
|
@ -172,6 +190,10 @@ int constant_clockevent_init(void)
|
|||
lpj_fine = get_loops_per_jiffy();
|
||||
pr_info("Constant clock event device register\n");
|
||||
|
||||
cpuhp_setup_state(CPUHP_AP_LOONGARCH_ARCH_TIMER_STARTING,
|
||||
"clockevents/loongarch/timer:starting",
|
||||
arch_timer_starting, arch_timer_dying);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,12 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
|
|||
}
|
||||
|
||||
cpu = s->sw_coremap[irq];
|
||||
vcpu = kvm_get_vcpu(s->kvm, cpu);
|
||||
vcpu = kvm_get_vcpu_by_id(s->kvm, cpu);
|
||||
if (unlikely(vcpu == NULL)) {
|
||||
kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
|
||||
return;
|
||||
}
|
||||
|
||||
if (level) {
|
||||
/* if not enable return false */
|
||||
if (!test_bit(irq, (unsigned long *)s->enable.reg_u32))
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ static void write_mailbox(struct kvm_vcpu *vcpu, int offset, uint64_t data, int
|
|||
static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data)
|
||||
{
|
||||
int i, idx, ret;
|
||||
uint32_t val = 0, mask = 0;
|
||||
uint64_t val = 0, mask = 0;
|
||||
|
||||
/*
|
||||
* Bit 27-30 is mask for byte writing.
|
||||
|
|
@ -108,7 +108,7 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data)
|
|||
if ((data >> 27) & 0xf) {
|
||||
/* Read the old val */
|
||||
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||
ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val);
|
||||
ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, 4, &val);
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||
if (unlikely(ret)) {
|
||||
kvm_err("%s: : read data from addr %llx failed\n", __func__, addr);
|
||||
|
|
@ -124,7 +124,7 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data)
|
|||
}
|
||||
val |= ((uint32_t)(data >> 32) & ~mask);
|
||||
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||
ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val);
|
||||
ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, 4, &val);
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||
if (unlikely(ret))
|
||||
kvm_err("%s: : write data to addr %llx failed\n", __func__, addr);
|
||||
|
|
@ -298,7 +298,7 @@ static int kvm_ipi_regs_access(struct kvm_device *dev,
|
|||
cpu = (attr->attr >> 16) & 0x3ff;
|
||||
addr = attr->attr & 0xff;
|
||||
|
||||
vcpu = kvm_get_vcpu(dev->kvm, cpu);
|
||||
vcpu = kvm_get_vcpu_by_id(dev->kvm, cpu);
|
||||
if (unlikely(vcpu == NULL)) {
|
||||
kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -195,6 +195,11 @@ static int kvm_pch_pic_read(struct kvm_vcpu *vcpu,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (addr & (len - 1)) {
|
||||
kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* statistics of pch pic reading */
|
||||
vcpu->stat.pch_pic_read_exits++;
|
||||
ret = loongarch_pch_pic_read(s, addr, len, val);
|
||||
|
|
@ -302,6 +307,11 @@ static int kvm_pch_pic_write(struct kvm_vcpu *vcpu,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (addr & (len - 1)) {
|
||||
kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* statistics of pch pic writing */
|
||||
vcpu->stat.pch_pic_write_exits++;
|
||||
ret = loongarch_pch_pic_write(s, addr, len, val);
|
||||
|
|
|
|||
|
|
@ -1283,9 +1283,11 @@ int kvm_own_lbt(struct kvm_vcpu *vcpu)
|
|||
return -EINVAL;
|
||||
|
||||
preempt_disable();
|
||||
set_csr_euen(CSR_EUEN_LBTEN);
|
||||
_restore_lbt(&vcpu->arch.lbt);
|
||||
vcpu->arch.aux_inuse |= KVM_LARCH_LBT;
|
||||
if (!(vcpu->arch.aux_inuse & KVM_LARCH_LBT)) {
|
||||
set_csr_euen(CSR_EUEN_LBTEN);
|
||||
_restore_lbt(&vcpu->arch.lbt);
|
||||
vcpu->arch.aux_inuse |= KVM_LARCH_LBT;
|
||||
}
|
||||
preempt_enable();
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -82,13 +82,16 @@ conf_out {
|
|||
};
|
||||
};
|
||||
|
||||
etop@e180000 {
|
||||
ethernet@e180000 {
|
||||
compatible = "lantiq,etop-xway";
|
||||
reg = <0xe180000 0x40000>;
|
||||
interrupt-parent = <&icu0>;
|
||||
interrupts = <73 78>;
|
||||
interrupt-names = "tx", "rx";
|
||||
phy-mode = "rmii";
|
||||
mac-address = [ 00 11 22 33 44 55 ];
|
||||
lantiq,rx-burst-length = <4>;
|
||||
lantiq,tx-burst-length = <4>;
|
||||
};
|
||||
|
||||
stp0: stp@e100bb0 {
|
||||
|
|
|
|||
|
|
@ -497,7 +497,7 @@ void __init ltq_soc_init(void)
|
|||
ifccr = CGU_IFCCR_VR9;
|
||||
pcicr = CGU_PCICR_VR9;
|
||||
} else {
|
||||
clkdev_add_pmu("1e180000.etop", NULL, 1, 0, PMU_PPE);
|
||||
clkdev_add_pmu("1e180000.ethernet", NULL, 1, 0, PMU_PPE);
|
||||
}
|
||||
|
||||
if (!of_machine_is_compatible("lantiq,ase"))
|
||||
|
|
@ -531,9 +531,9 @@ void __init ltq_soc_init(void)
|
|||
CLOCK_133M, CLOCK_133M);
|
||||
clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0);
|
||||
clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P);
|
||||
clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE);
|
||||
clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY);
|
||||
clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY);
|
||||
clkdev_add_pmu("1e180000.ethernet", "ppe", 1, 0, PMU_PPE);
|
||||
clkdev_add_cgu("1e180000.ethernet", "ephycgu", CGU_EPHY);
|
||||
clkdev_add_pmu("1e180000.ethernet", "ephy", 1, 0, PMU_EPHY);
|
||||
clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_ASE_SDIO);
|
||||
clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
|
||||
} else if (of_machine_is_compatible("lantiq,grx390")) {
|
||||
|
|
@ -592,7 +592,7 @@ void __init ltq_soc_init(void)
|
|||
clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM);
|
||||
clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P);
|
||||
clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM);
|
||||
clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH);
|
||||
clkdev_add_pmu("1e180000.ethernet", "switch", 1, 0, PMU_SWITCH);
|
||||
clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
|
||||
clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
|
||||
clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
|
||||
|
|
|
|||
|
|
@ -243,13 +243,13 @@ $(obj)/wrapper.a: $(obj-wlib) FORCE
|
|||
hostprogs := addnote hack-coff mktree
|
||||
|
||||
targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) zImage.lds
|
||||
extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
|
||||
always-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
|
||||
$(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds
|
||||
|
||||
dtstree := $(src)/dts
|
||||
|
||||
wrapper := $(src)/wrapper
|
||||
wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \
|
||||
wrapperbits := $(always-y) $(addprefix $(obj)/,addnote hack-coff mktree) \
|
||||
$(wrapper) FORCE
|
||||
|
||||
#############
|
||||
|
|
@ -456,7 +456,7 @@ WRAPPER_DTSDIR := /usr/lib/kernel-wrapper/dts
|
|||
WRAPPER_BINDIR := /usr/sbin
|
||||
INSTALL := install
|
||||
|
||||
extra-installed := $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(extra-y))
|
||||
extra-installed := $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(always-y))
|
||||
hostprogs-installed := $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(hostprogs))
|
||||
wrapper-installed := $(DESTDIR)$(WRAPPER_BINDIR)/wrapper
|
||||
dts-installed := $(patsubst $(dtstree)/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(dtstree)/*.dts))
|
||||
|
|
|
|||
|
|
@ -19,19 +19,19 @@
|
|||
set -e
|
||||
|
||||
# this should work for both the pSeries zImage and the iSeries vmlinux.sm
|
||||
image_name=`basename $2`
|
||||
image_name=$(basename "$2")
|
||||
|
||||
|
||||
echo "Warning: '${INSTALLKERNEL}' command not available... Copying" \
|
||||
"directly to $4/$image_name-$1" >&2
|
||||
|
||||
if [ -f $4/$image_name-$1 ]; then
|
||||
mv $4/$image_name-$1 $4/$image_name-$1.old
|
||||
if [ -f "$4"/"$image_name"-"$1" ]; then
|
||||
mv "$4"/"$image_name"-"$1" "$4"/"$image_name"-"$1".old
|
||||
fi
|
||||
|
||||
if [ -f $4/System.map-$1 ]; then
|
||||
mv $4/System.map-$1 $4/System-$1.old
|
||||
if [ -f "$4"/System.map-"$1" ]; then
|
||||
mv "$4"/System.map-"$1" "$4"/System-"$1".old
|
||||
fi
|
||||
|
||||
cat $2 > $4/$image_name-$1
|
||||
cp $3 $4/System.map-$1
|
||||
cat "$2" > "$4"/"$image_name"-"$1"
|
||||
cp "$3" "$4"/System.map-"$1"
|
||||
|
|
|
|||
|
|
@ -199,7 +199,9 @@ obj-$(CONFIG_ALTIVEC) += vector.o
|
|||
|
||||
obj-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o
|
||||
obj64-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_entry_64.o
|
||||
extra-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init_check
|
||||
ifdef KBUILD_BUILTIN
|
||||
always-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init_check
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_PPC64) += $(obj64-y)
|
||||
obj-$(CONFIG_PPC32) += $(obj32-y)
|
||||
|
|
|
|||
|
|
@ -632,19 +632,19 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
|
|||
#endif
|
||||
}
|
||||
|
||||
switch (inst_no_rt & ~KVM_MASK_RB) {
|
||||
#ifdef CONFIG_PPC_BOOK3S_32
|
||||
switch (inst_no_rt & ~KVM_MASK_RB) {
|
||||
case KVM_INST_MTSRIN:
|
||||
if (features & KVM_MAGIC_FEAT_SR) {
|
||||
u32 inst_rb = _inst & KVM_MASK_RB;
|
||||
kvm_patch_ins_mtsrin(inst, inst_rt, inst_rb);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (_inst) {
|
||||
#ifdef CONFIG_BOOKE
|
||||
switch (_inst) {
|
||||
case KVM_INST_WRTEEI_0:
|
||||
kvm_patch_ins_wrteei_0(inst);
|
||||
break;
|
||||
|
|
@ -652,8 +652,8 @@ static void __init kvm_check_ins(u32 *inst, u32 features)
|
|||
case KVM_INST_WRTEEI_1:
|
||||
kvm_patch_ins_wrtee(inst, 0, 1);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extern u32 kvm_template_start[];
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
has_renamed_memintrinsics()
|
||||
{
|
||||
grep -q "^CONFIG_KASAN=y$" ${KCONFIG_CONFIG} && \
|
||||
! grep -q "^CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX=y" ${KCONFIG_CONFIG}
|
||||
grep -q "^CONFIG_KASAN=y$" "${KCONFIG_CONFIG}" && \
|
||||
! grep -q "^CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX=y" "${KCONFIG_CONFIG}"
|
||||
}
|
||||
|
||||
if has_renamed_memintrinsics
|
||||
|
|
@ -42,15 +42,15 @@ check_section()
|
|||
{
|
||||
file=$1
|
||||
section=$2
|
||||
size=$(objdump -h -j $section $file 2>/dev/null | awk "\$2 == \"$section\" {print \$3}")
|
||||
size=$(objdump -h -j "$section" "$file" 2>/dev/null | awk "\$2 == \"$section\" {print \$3}")
|
||||
size=${size:-0}
|
||||
if [ $size -ne 0 ]; then
|
||||
if [ "$size" -ne 0 ]; then
|
||||
ERROR=1
|
||||
echo "Error: Section $section not empty in prom_init.c" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
for UNDEF in $($NM -u $OBJ | awk '{print $2}')
|
||||
for UNDEF in $($NM -u "$OBJ" | awk '{print $2}')
|
||||
do
|
||||
# On 64-bit nm gives us the function descriptors, which have
|
||||
# a leading . on the name, so strip it off here.
|
||||
|
|
@ -87,8 +87,8 @@ do
|
|||
fi
|
||||
done
|
||||
|
||||
check_section $OBJ .data
|
||||
check_section $OBJ .bss
|
||||
check_section $OBJ .init.data
|
||||
check_section "$OBJ" .data
|
||||
check_section "$OBJ" .bss
|
||||
check_section "$OBJ" .init.data
|
||||
|
||||
exit $ERROR
|
||||
|
|
|
|||
|
|
@ -141,10 +141,7 @@ void __init check_smt_enabled(void)
|
|||
smt_enabled_at_boot = 0;
|
||||
else {
|
||||
int smt;
|
||||
int rc;
|
||||
|
||||
rc = kstrtoint(smt_enabled_cmdline, 10, &smt);
|
||||
if (!rc)
|
||||
if (!kstrtoint(smt_enabled_cmdline, 10, &smt))
|
||||
smt_enabled_at_boot =
|
||||
min(threads_per_core, smt);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
|
|||
|
||||
/*
|
||||
* Common checks before entering the guest world. Call with interrupts
|
||||
* disabled.
|
||||
* enabled.
|
||||
*
|
||||
* returns:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -110,8 +110,7 @@ static int cpm_pic_probe(struct platform_device *pdev)
|
|||
|
||||
out_be32(&data->reg->cpic_cimr, 0);
|
||||
|
||||
data->host = irq_domain_create_linear(of_fwnode_handle(dev->of_node),
|
||||
64, &cpm_pic_host_ops, data);
|
||||
data->host = irq_domain_create_linear(dev_fwnode(dev), 64, &cpm_pic_host_ops, data);
|
||||
if (!data->host)
|
||||
return -ENODEV;
|
||||
|
||||
|
|
|
|||
|
|
@ -122,16 +122,11 @@ choice
|
|||
If unsure, select Generic.
|
||||
|
||||
config POWERPC64_CPU
|
||||
bool "Generic (POWER5 and PowerPC 970 and above)"
|
||||
depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN
|
||||
bool "Generic 64 bits powerpc"
|
||||
depends on PPC_BOOK3S_64
|
||||
select ARCH_HAS_FAST_MULTIPLIER if CPU_LITTLE_ENDIAN
|
||||
select PPC_64S_HASH_MMU
|
||||
|
||||
config POWERPC64_CPU
|
||||
bool "Generic (POWER8 and above)"
|
||||
depends on PPC_BOOK3S_64 && CPU_LITTLE_ENDIAN
|
||||
select ARCH_HAS_FAST_MULTIPLIER
|
||||
select PPC_64S_HASH_MMU
|
||||
select PPC_HAS_LBARX_LHARX
|
||||
select PPC_HAS_LBARX_LHARX if CPU_LITTLE_ENDIAN
|
||||
|
||||
config POWERPC_CPU
|
||||
bool "Generic 32 bits powerpc"
|
||||
|
|
|
|||
|
|
@ -412,9 +412,8 @@ static int fsl_of_msi_probe(struct platform_device *dev)
|
|||
}
|
||||
platform_set_drvdata(dev, msi);
|
||||
|
||||
msi->irqhost = irq_domain_create_linear(of_fwnode_handle(dev->dev.of_node),
|
||||
NR_MSI_IRQS_MAX, &fsl_msi_host_ops, msi);
|
||||
|
||||
msi->irqhost = irq_domain_create_linear(dev_fwnode(&dev->dev), NR_MSI_IRQS_MAX,
|
||||
&fsl_msi_host_ops, msi);
|
||||
if (msi->irqhost == NULL) {
|
||||
dev_err(&dev->dev, "No memory for MSI irqhost\n");
|
||||
err = -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -297,8 +297,9 @@ gmac1: ethernet@ffe7060000 {
|
|||
reg-names = "dwmac", "apb";
|
||||
interrupts = <67 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "macirq";
|
||||
clocks = <&clk CLK_GMAC_AXI>, <&clk CLK_GMAC1>;
|
||||
clock-names = "stmmaceth", "pclk";
|
||||
clocks = <&clk CLK_GMAC_AXI>, <&clk CLK_GMAC1>,
|
||||
<&clk CLK_PERISYS_APB4_HCLK>;
|
||||
clock-names = "stmmaceth", "pclk", "apb";
|
||||
snps,pbl = <32>;
|
||||
snps,fixed-burst;
|
||||
snps,multicast-filter-bins = <64>;
|
||||
|
|
@ -319,8 +320,9 @@ gmac0: ethernet@ffe7070000 {
|
|||
reg-names = "dwmac", "apb";
|
||||
interrupts = <66 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "macirq";
|
||||
clocks = <&clk CLK_GMAC_AXI>, <&clk CLK_GMAC0>;
|
||||
clock-names = "stmmaceth", "pclk";
|
||||
clocks = <&clk CLK_GMAC_AXI>, <&clk CLK_GMAC0>,
|
||||
<&clk CLK_PERISYS_APB4_HCLK>;
|
||||
clock-names = "stmmaceth", "pclk", "apb";
|
||||
snps,pbl = <32>;
|
||||
snps,fixed-burst;
|
||||
snps,multicast-filter-bins = <64>;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ int kvm_riscv_mmu_ioremap(struct kvm *kvm, gpa_t gpa, phys_addr_t hpa,
|
|||
unsigned long size, bool writable, bool in_atomic)
|
||||
{
|
||||
int ret = 0;
|
||||
pgprot_t prot;
|
||||
unsigned long pfn;
|
||||
phys_addr_t addr, end;
|
||||
struct kvm_mmu_memory_cache pcache = {
|
||||
|
|
@ -55,10 +56,12 @@ int kvm_riscv_mmu_ioremap(struct kvm *kvm, gpa_t gpa, phys_addr_t hpa,
|
|||
|
||||
end = (gpa + size + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
pfn = __phys_to_pfn(hpa);
|
||||
prot = pgprot_noncached(PAGE_WRITE);
|
||||
|
||||
for (addr = gpa; addr < end; addr += PAGE_SIZE) {
|
||||
map.addr = addr;
|
||||
map.pte = pfn_pte(pfn, PAGE_KERNEL_IO);
|
||||
map.pte = pfn_pte(pfn, prot);
|
||||
map.pte = pte_mkdirty(map.pte);
|
||||
map.level = 0;
|
||||
|
||||
if (!writable)
|
||||
|
|
|
|||
|
|
@ -683,7 +683,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
|
|||
}
|
||||
|
||||
/**
|
||||
* check_vcpu_requests - check and handle pending vCPU requests
|
||||
* kvm_riscv_check_vcpu_requests - check and handle pending vCPU requests
|
||||
* @vcpu: the VCPU pointer
|
||||
*
|
||||
* Return: 1 if we should enter the guest
|
||||
|
|
|
|||
|
|
@ -182,6 +182,8 @@ int kvm_riscv_vcpu_set_reg_vector(struct kvm_vcpu *vcpu,
|
|||
struct kvm_cpu_context *cntx = &vcpu->arch.guest_context;
|
||||
unsigned long reg_val;
|
||||
|
||||
if (reg_size != sizeof(reg_val))
|
||||
return -EINVAL;
|
||||
if (copy_from_user(®_val, uaddr, reg_size))
|
||||
return -EFAULT;
|
||||
if (reg_val != cntx->vector.vlenb)
|
||||
|
|
|
|||
|
|
@ -530,6 +530,9 @@ void setup_vmem(unsigned long kernel_start, unsigned long kernel_end, unsigned l
|
|||
lowcore_address + sizeof(struct lowcore),
|
||||
POPULATE_LOWCORE);
|
||||
for_each_physmem_usable_range(i, &start, &end) {
|
||||
/* Do not map lowcore with identity mapping */
|
||||
if (!start)
|
||||
start = sizeof(struct lowcore);
|
||||
pgtable_populate((unsigned long)__identity_va(start),
|
||||
(unsigned long)__identity_va(end),
|
||||
POPULATE_IDENTITY);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ CONFIG_WATCH_QUEUE=y
|
|||
CONFIG_AUDIT=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_POSIX_AUX_CLOCKS=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_BPF_JIT_ALWAYS_ON=y
|
||||
|
|
@ -19,6 +20,7 @@ CONFIG_TASK_XACCT=y
|
|||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_SCHED_PROXY_EXEC=y
|
||||
CONFIG_NUMA_BALANCING=y
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
|
|
@ -42,6 +44,7 @@ CONFIG_PROFILING=y
|
|||
CONFIG_KEXEC=y
|
||||
CONFIG_KEXEC_FILE=y
|
||||
CONFIG_KEXEC_SIG=y
|
||||
CONFIG_CRASH_DM_CRYPT=y
|
||||
CONFIG_LIVEPATCH=y
|
||||
CONFIG_MARCH_Z13=y
|
||||
CONFIG_NR_CPUS=512
|
||||
|
|
@ -105,6 +108,7 @@ CONFIG_CMA_AREAS=7
|
|||
CONFIG_MEM_SOFT_DIRTY=y
|
||||
CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
|
||||
CONFIG_IDLE_PAGE_TRACKING=y
|
||||
CONFIG_ZONE_DEVICE=y
|
||||
CONFIG_PERCPU_STATS=y
|
||||
CONFIG_GUP_TEST=y
|
||||
CONFIG_ANON_VMA_NAME=y
|
||||
|
|
@ -223,17 +227,19 @@ CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
|
|||
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
||||
CONFIG_NETFILTER_XT_TARGET_HL=m
|
||||
CONFIG_NETFILTER_XT_TARGET_HMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_NAT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NETMAP=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_REDIRECT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TEE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
@ -248,6 +254,7 @@ CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
|
|||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CPU=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DCCP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DSCP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_ESP=m
|
||||
|
|
@ -318,16 +325,8 @@ CONFIG_IP_NF_MATCH_AH=m
|
|||
CONFIG_IP_NF_MATCH_ECN=m
|
||||
CONFIG_IP_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP_NF_MATCH_TTL=m
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_IP_NF_TARGET_REJECT=m
|
||||
CONFIG_IP_NF_NAT=m
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_IP_NF_MANGLE=m
|
||||
CONFIG_IP_NF_TARGET_ECN=m
|
||||
CONFIG_IP_NF_TARGET_TTL=m
|
||||
CONFIG_IP_NF_RAW=m
|
||||
CONFIG_IP_NF_SECURITY=m
|
||||
CONFIG_IP_NF_ARPFILTER=m
|
||||
CONFIG_IP_NF_ARP_MANGLE=m
|
||||
CONFIG_NFT_FIB_IPV6=m
|
||||
CONFIG_IP6_NF_IPTABLES=m
|
||||
|
|
@ -340,15 +339,9 @@ CONFIG_IP6_NF_MATCH_IPV6HEADER=m
|
|||
CONFIG_IP6_NF_MATCH_MH=m
|
||||
CONFIG_IP6_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP6_NF_MATCH_RT=m
|
||||
CONFIG_IP6_NF_TARGET_HL=m
|
||||
CONFIG_IP6_NF_FILTER=m
|
||||
CONFIG_IP6_NF_TARGET_REJECT=m
|
||||
CONFIG_IP6_NF_MANGLE=m
|
||||
CONFIG_IP6_NF_RAW=m
|
||||
CONFIG_IP6_NF_SECURITY=m
|
||||
CONFIG_IP6_NF_NAT=m
|
||||
CONFIG_IP6_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_NF_TABLES_BRIDGE=m
|
||||
CONFIG_IP_SCTP=m
|
||||
CONFIG_RDS=m
|
||||
CONFIG_RDS_RDMA=m
|
||||
CONFIG_RDS_TCP=m
|
||||
|
|
@ -383,6 +376,7 @@ CONFIG_NET_SCH_FQ_CODEL=m
|
|||
CONFIG_NET_SCH_INGRESS=m
|
||||
CONFIG_NET_SCH_PLUG=m
|
||||
CONFIG_NET_SCH_ETS=m
|
||||
CONFIG_NET_SCH_DUALPI2=m
|
||||
CONFIG_NET_CLS_BASIC=m
|
||||
CONFIG_NET_CLS_ROUTE4=m
|
||||
CONFIG_NET_CLS_FW=m
|
||||
|
|
@ -504,6 +498,7 @@ CONFIG_DM_VDO=m
|
|||
CONFIG_NETDEVICES=y
|
||||
CONFIG_BONDING=m
|
||||
CONFIG_DUMMY=m
|
||||
CONFIG_OVPN=m
|
||||
CONFIG_EQUALIZER=m
|
||||
CONFIG_IFB=m
|
||||
CONFIG_MACVLAN=m
|
||||
|
|
@ -641,6 +636,7 @@ CONFIG_VP_VDPA=m
|
|||
CONFIG_VHOST_NET=m
|
||||
CONFIG_VHOST_VSOCK=m
|
||||
CONFIG_VHOST_VDPA=m
|
||||
CONFIG_DEV_DAX=m
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
|
|
@ -665,6 +661,7 @@ CONFIG_NILFS2_FS=m
|
|||
CONFIG_BCACHEFS_FS=y
|
||||
CONFIG_BCACHEFS_QUOTA=y
|
||||
CONFIG_BCACHEFS_POSIX_ACL=y
|
||||
CONFIG_FS_DAX=y
|
||||
CONFIG_EXPORTFS_BLOCK_OPS=y
|
||||
CONFIG_FS_ENCRYPTION=y
|
||||
CONFIG_FS_VERITY=y
|
||||
|
|
@ -755,6 +752,8 @@ CONFIG_HARDENED_USERCOPY=y
|
|||
CONFIG_BUG_ON_DATA_CORRUPTION=y
|
||||
CONFIG_CRYPTO_USER=m
|
||||
CONFIG_CRYPTO_SELFTESTS=y
|
||||
CONFIG_CRYPTO_SELFTESTS_FULL=y
|
||||
CONFIG_CRYPTO_NULL=y
|
||||
CONFIG_CRYPTO_PCRYPT=m
|
||||
CONFIG_CRYPTO_CRYPTD=m
|
||||
CONFIG_CRYPTO_BENCHMARK=m
|
||||
|
|
@ -783,7 +782,6 @@ CONFIG_CRYPTO_HCTR2=m
|
|||
CONFIG_CRYPTO_LRW=m
|
||||
CONFIG_CRYPTO_PCBC=m
|
||||
CONFIG_CRYPTO_AEGIS128=m
|
||||
CONFIG_CRYPTO_CHACHA20POLY1305=m
|
||||
CONFIG_CRYPTO_GCM=y
|
||||
CONFIG_CRYPTO_SEQIV=y
|
||||
CONFIG_CRYPTO_MD4=m
|
||||
|
|
@ -822,6 +820,7 @@ CONFIG_SYSTEM_BLACKLIST_KEYRING=y
|
|||
CONFIG_CRYPTO_KRB5=m
|
||||
CONFIG_CRYPTO_KRB5_SELFTESTS=y
|
||||
CONFIG_CORDIC=m
|
||||
CONFIG_TRACE_MMIO_ACCESS=y
|
||||
CONFIG_RANDOM32_SELFTEST=y
|
||||
CONFIG_XZ_DEC_MICROLZMA=y
|
||||
CONFIG_DMA_CMA=y
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ CONFIG_WATCH_QUEUE=y
|
|||
CONFIG_AUDIT=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_POSIX_AUX_CLOCKS=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_BPF_JIT=y
|
||||
CONFIG_BPF_JIT_ALWAYS_ON=y
|
||||
|
|
@ -17,6 +18,7 @@ CONFIG_TASK_XACCT=y
|
|||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_SCHED_PROXY_EXEC=y
|
||||
CONFIG_NUMA_BALANCING=y
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
|
|
@ -40,11 +42,12 @@ CONFIG_PROFILING=y
|
|||
CONFIG_KEXEC=y
|
||||
CONFIG_KEXEC_FILE=y
|
||||
CONFIG_KEXEC_SIG=y
|
||||
CONFIG_CRASH_DM_CRYPT=y
|
||||
CONFIG_LIVEPATCH=y
|
||||
CONFIG_MARCH_Z13=y
|
||||
CONFIG_NR_CPUS=512
|
||||
CONFIG_NUMA=y
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_HZ_1000=y
|
||||
CONFIG_CERT_STORE=y
|
||||
CONFIG_EXPOLINE=y
|
||||
CONFIG_EXPOLINE_AUTO=y
|
||||
|
|
@ -97,6 +100,7 @@ CONFIG_CMA_AREAS=7
|
|||
CONFIG_MEM_SOFT_DIRTY=y
|
||||
CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
|
||||
CONFIG_IDLE_PAGE_TRACKING=y
|
||||
CONFIG_ZONE_DEVICE=y
|
||||
CONFIG_PERCPU_STATS=y
|
||||
CONFIG_ANON_VMA_NAME=y
|
||||
CONFIG_USERFAULTFD=y
|
||||
|
|
@ -214,17 +218,19 @@ CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
|
|||
CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_CT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_DSCP=m
|
||||
CONFIG_NETFILTER_XT_TARGET_HL=m
|
||||
CONFIG_NETFILTER_XT_TARGET_HMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
|
||||
CONFIG_NETFILTER_XT_TARGET_LOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_MARK=m
|
||||
CONFIG_NETFILTER_XT_NAT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NETMAP=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFLOG=m
|
||||
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_REDIRECT=m
|
||||
CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TEE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TRACE=m
|
||||
CONFIG_NETFILTER_XT_TARGET_SECMARK=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
|
||||
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
|
||||
|
|
@ -239,6 +245,7 @@ CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
|
|||
CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_CPU=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DCCP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DSCP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_ESP=m
|
||||
|
|
@ -309,16 +316,8 @@ CONFIG_IP_NF_MATCH_AH=m
|
|||
CONFIG_IP_NF_MATCH_ECN=m
|
||||
CONFIG_IP_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP_NF_MATCH_TTL=m
|
||||
CONFIG_IP_NF_FILTER=m
|
||||
CONFIG_IP_NF_TARGET_REJECT=m
|
||||
CONFIG_IP_NF_NAT=m
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_IP_NF_MANGLE=m
|
||||
CONFIG_IP_NF_TARGET_ECN=m
|
||||
CONFIG_IP_NF_TARGET_TTL=m
|
||||
CONFIG_IP_NF_RAW=m
|
||||
CONFIG_IP_NF_SECURITY=m
|
||||
CONFIG_IP_NF_ARPFILTER=m
|
||||
CONFIG_IP_NF_ARP_MANGLE=m
|
||||
CONFIG_NFT_FIB_IPV6=m
|
||||
CONFIG_IP6_NF_IPTABLES=m
|
||||
|
|
@ -331,15 +330,9 @@ CONFIG_IP6_NF_MATCH_IPV6HEADER=m
|
|||
CONFIG_IP6_NF_MATCH_MH=m
|
||||
CONFIG_IP6_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP6_NF_MATCH_RT=m
|
||||
CONFIG_IP6_NF_TARGET_HL=m
|
||||
CONFIG_IP6_NF_FILTER=m
|
||||
CONFIG_IP6_NF_TARGET_REJECT=m
|
||||
CONFIG_IP6_NF_MANGLE=m
|
||||
CONFIG_IP6_NF_RAW=m
|
||||
CONFIG_IP6_NF_SECURITY=m
|
||||
CONFIG_IP6_NF_NAT=m
|
||||
CONFIG_IP6_NF_TARGET_MASQUERADE=m
|
||||
CONFIG_NF_TABLES_BRIDGE=m
|
||||
CONFIG_IP_SCTP=m
|
||||
CONFIG_RDS=m
|
||||
CONFIG_RDS_RDMA=m
|
||||
CONFIG_RDS_TCP=m
|
||||
|
|
@ -373,6 +366,7 @@ CONFIG_NET_SCH_FQ_CODEL=m
|
|||
CONFIG_NET_SCH_INGRESS=m
|
||||
CONFIG_NET_SCH_PLUG=m
|
||||
CONFIG_NET_SCH_ETS=m
|
||||
CONFIG_NET_SCH_DUALPI2=m
|
||||
CONFIG_NET_CLS_BASIC=m
|
||||
CONFIG_NET_CLS_ROUTE4=m
|
||||
CONFIG_NET_CLS_FW=m
|
||||
|
|
@ -494,6 +488,7 @@ CONFIG_DM_VDO=m
|
|||
CONFIG_NETDEVICES=y
|
||||
CONFIG_BONDING=m
|
||||
CONFIG_DUMMY=m
|
||||
CONFIG_OVPN=m
|
||||
CONFIG_EQUALIZER=m
|
||||
CONFIG_IFB=m
|
||||
CONFIG_MACVLAN=m
|
||||
|
|
@ -631,6 +626,7 @@ CONFIG_VP_VDPA=m
|
|||
CONFIG_VHOST_NET=m
|
||||
CONFIG_VHOST_VSOCK=m
|
||||
CONFIG_VHOST_VDPA=m
|
||||
CONFIG_DEV_DAX=m
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
|
|
@ -652,6 +648,7 @@ CONFIG_NILFS2_FS=m
|
|||
CONFIG_BCACHEFS_FS=m
|
||||
CONFIG_BCACHEFS_QUOTA=y
|
||||
CONFIG_BCACHEFS_POSIX_ACL=y
|
||||
CONFIG_FS_DAX=y
|
||||
CONFIG_EXPORTFS_BLOCK_OPS=y
|
||||
CONFIG_FS_ENCRYPTION=y
|
||||
CONFIG_FS_VERITY=y
|
||||
|
|
@ -683,7 +680,6 @@ CONFIG_TMPFS_POSIX_ACL=y
|
|||
CONFIG_TMPFS_INODE64=y
|
||||
CONFIG_TMPFS_QUOTA=y
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_CONFIGFS_FS=m
|
||||
CONFIG_ECRYPT_FS=m
|
||||
CONFIG_CRAMFS=m
|
||||
CONFIG_SQUASHFS=m
|
||||
|
|
@ -741,6 +737,7 @@ CONFIG_BUG_ON_DATA_CORRUPTION=y
|
|||
CONFIG_CRYPTO_FIPS=y
|
||||
CONFIG_CRYPTO_USER=m
|
||||
CONFIG_CRYPTO_SELFTESTS=y
|
||||
CONFIG_CRYPTO_NULL=y
|
||||
CONFIG_CRYPTO_PCRYPT=m
|
||||
CONFIG_CRYPTO_CRYPTD=m
|
||||
CONFIG_CRYPTO_BENCHMARK=m
|
||||
|
|
@ -769,7 +766,6 @@ CONFIG_CRYPTO_HCTR2=m
|
|||
CONFIG_CRYPTO_LRW=m
|
||||
CONFIG_CRYPTO_PCBC=m
|
||||
CONFIG_CRYPTO_AEGIS128=m
|
||||
CONFIG_CRYPTO_CHACHA20POLY1305=m
|
||||
CONFIG_CRYPTO_GCM=y
|
||||
CONFIG_CRYPTO_SEQIV=y
|
||||
CONFIG_CRYPTO_MD4=m
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_POSIX_AUX_CLOCKS=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
# CONFIG_CPU_ISOLATION is not set
|
||||
# CONFIG_UTS_NS is not set
|
||||
|
|
@ -11,7 +12,7 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
|||
CONFIG_KEXEC=y
|
||||
CONFIG_MARCH_Z13=y
|
||||
CONFIG_NR_CPUS=2
|
||||
CONFIG_HZ_100=y
|
||||
CONFIG_HZ_1000=y
|
||||
# CONFIG_CHSC_SCH is not set
|
||||
# CONFIG_SCM_BUS is not set
|
||||
# CONFIG_AP is not set
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
* Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||
*/
|
||||
|
||||
#include <linux/security.h>
|
||||
#include <linux/slab.h>
|
||||
#include "hypfs.h"
|
||||
|
||||
|
|
@ -66,23 +67,27 @@ static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||
long rc;
|
||||
|
||||
mutex_lock(&df->lock);
|
||||
if (df->unlocked_ioctl)
|
||||
rc = df->unlocked_ioctl(file, cmd, arg);
|
||||
else
|
||||
rc = -ENOTTY;
|
||||
rc = df->unlocked_ioctl(file, cmd, arg);
|
||||
mutex_unlock(&df->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct file_operations dbfs_ops = {
|
||||
static const struct file_operations dbfs_ops_ioctl = {
|
||||
.read = dbfs_read,
|
||||
.unlocked_ioctl = dbfs_ioctl,
|
||||
};
|
||||
|
||||
static const struct file_operations dbfs_ops = {
|
||||
.read = dbfs_read,
|
||||
};
|
||||
|
||||
void hypfs_dbfs_create_file(struct hypfs_dbfs_file *df)
|
||||
{
|
||||
df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df,
|
||||
&dbfs_ops);
|
||||
const struct file_operations *fops = &dbfs_ops;
|
||||
|
||||
if (df->unlocked_ioctl && !security_locked_down(LOCKDOWN_DEBUGFS))
|
||||
fops = &dbfs_ops_ioctl;
|
||||
df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df, fops);
|
||||
mutex_init(&df->lock);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,5 +106,18 @@ void get_cpuflags(void)
|
|||
cpuid(0x80000001, &ignored, &ignored, &cpu.flags[6],
|
||||
&cpu.flags[1]);
|
||||
}
|
||||
|
||||
if (max_amd_level >= 0x8000001f) {
|
||||
u32 ebx;
|
||||
|
||||
/*
|
||||
* The X86_FEATURE_COHERENCY_SFW_NO feature bit is in
|
||||
* the virtualization flags entry (word 8) and set by
|
||||
* scattered.c, so the bit needs to be explicitly set.
|
||||
*/
|
||||
cpuid(0x8000001f, &ignored, &ebx, &ignored, &ignored);
|
||||
if (ebx & BIT(31))
|
||||
set_bit(X86_FEATURE_COHERENCY_SFW_NO, cpu.flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -785,6 +785,7 @@ static void __head svsm_pval_4k_page(unsigned long paddr, bool validate)
|
|||
pc->entry[0].page_size = RMP_PG_SIZE_4K;
|
||||
pc->entry[0].action = validate;
|
||||
pc->entry[0].ignore_cf = 0;
|
||||
pc->entry[0].rsvd = 0;
|
||||
pc->entry[0].pfn = paddr >> PAGE_SHIFT;
|
||||
|
||||
/* Protocol 0, Call ID 1 */
|
||||
|
|
@ -810,6 +811,13 @@ static void __head pvalidate_4k_page(unsigned long vaddr, unsigned long paddr,
|
|||
if (ret)
|
||||
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE);
|
||||
}
|
||||
|
||||
/*
|
||||
* If validating memory (making it private) and affected by the
|
||||
* cache-coherency vulnerability, perform the cache eviction mitigation.
|
||||
*/
|
||||
if (validate && !has_cpuflag(X86_FEATURE_COHERENCY_SFW_NO))
|
||||
sev_evict_cache((void *)vaddr, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -227,6 +227,7 @@ static u64 svsm_build_ca_from_pfn_range(u64 pfn, u64 pfn_end, bool action,
|
|||
pe->page_size = RMP_PG_SIZE_4K;
|
||||
pe->action = action;
|
||||
pe->ignore_cf = 0;
|
||||
pe->rsvd = 0;
|
||||
pe->pfn = pfn;
|
||||
|
||||
pe++;
|
||||
|
|
@ -257,6 +258,7 @@ static int svsm_build_ca_from_psc_desc(struct snp_psc_desc *desc, unsigned int d
|
|||
pe->page_size = e->pagesize ? RMP_PG_SIZE_2M : RMP_PG_SIZE_4K;
|
||||
pe->action = e->operation == SNP_PAGE_STATE_PRIVATE;
|
||||
pe->ignore_cf = 0;
|
||||
pe->rsvd = 0;
|
||||
pe->pfn = e->gfn;
|
||||
|
||||
pe++;
|
||||
|
|
@ -358,10 +360,31 @@ static void svsm_pval_pages(struct snp_psc_desc *desc)
|
|||
|
||||
static void pvalidate_pages(struct snp_psc_desc *desc)
|
||||
{
|
||||
struct psc_entry *e;
|
||||
unsigned int i;
|
||||
|
||||
if (snp_vmpl)
|
||||
svsm_pval_pages(desc);
|
||||
else
|
||||
pval_pages(desc);
|
||||
|
||||
/*
|
||||
* If not affected by the cache-coherency vulnerability there is no need
|
||||
* to perform the cache eviction mitigation.
|
||||
*/
|
||||
if (cpu_feature_enabled(X86_FEATURE_COHERENCY_SFW_NO))
|
||||
return;
|
||||
|
||||
for (i = 0; i <= desc->hdr.end_entry; i++) {
|
||||
e = &desc->entries[i];
|
||||
|
||||
/*
|
||||
* If validating memory (making it private) perform the cache
|
||||
* eviction mitigation.
|
||||
*/
|
||||
if (e->operation == SNP_PAGE_STATE_PRIVATE)
|
||||
sev_evict_cache(pfn_to_kaddr(e->gfn), e->pagesize ? 512 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
static int vmgexit_psc(struct ghcb *ghcb, struct snp_psc_desc *desc)
|
||||
|
|
|
|||
|
|
@ -371,29 +371,30 @@ static enum es_result __vc_handle_msr_caa(struct pt_regs *regs, bool write)
|
|||
* executing with Secure TSC enabled, so special handling is required for
|
||||
* accesses of MSR_IA32_TSC and MSR_AMD64_GUEST_TSC_FREQ.
|
||||
*/
|
||||
static enum es_result __vc_handle_secure_tsc_msrs(struct pt_regs *regs, bool write)
|
||||
static enum es_result __vc_handle_secure_tsc_msrs(struct es_em_ctxt *ctxt, bool write)
|
||||
{
|
||||
struct pt_regs *regs = ctxt->regs;
|
||||
u64 tsc;
|
||||
|
||||
/*
|
||||
* GUEST_TSC_FREQ should not be intercepted when Secure TSC is enabled.
|
||||
* Terminate the SNP guest when the interception is enabled.
|
||||
* Writing to MSR_IA32_TSC can cause subsequent reads of the TSC to
|
||||
* return undefined values, and GUEST_TSC_FREQ is read-only. Generate
|
||||
* a #GP on all writes.
|
||||
*/
|
||||
if (write) {
|
||||
ctxt->fi.vector = X86_TRAP_GP;
|
||||
ctxt->fi.error_code = 0;
|
||||
return ES_EXCEPTION;
|
||||
}
|
||||
|
||||
/*
|
||||
* GUEST_TSC_FREQ read should not be intercepted when Secure TSC is
|
||||
* enabled. Terminate the guest if a read is attempted.
|
||||
*/
|
||||
if (regs->cx == MSR_AMD64_GUEST_TSC_FREQ)
|
||||
return ES_VMM_ERROR;
|
||||
|
||||
/*
|
||||
* Writes: Writing to MSR_IA32_TSC can cause subsequent reads of the TSC
|
||||
* to return undefined values, so ignore all writes.
|
||||
*
|
||||
* Reads: Reads of MSR_IA32_TSC should return the current TSC value, use
|
||||
* the value returned by rdtsc_ordered().
|
||||
*/
|
||||
if (write) {
|
||||
WARN_ONCE(1, "TSC MSR writes are verboten!\n");
|
||||
return ES_OK;
|
||||
}
|
||||
|
||||
/* Reads of MSR_IA32_TSC should return the current TSC value. */
|
||||
tsc = rdtsc_ordered();
|
||||
regs->ax = lower_32_bits(tsc);
|
||||
regs->dx = upper_32_bits(tsc);
|
||||
|
|
@ -416,7 +417,7 @@ static enum es_result vc_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
|
|||
case MSR_IA32_TSC:
|
||||
case MSR_AMD64_GUEST_TSC_FREQ:
|
||||
if (sev_status & MSR_AMD64_SNP_SECURE_TSC)
|
||||
return __vc_handle_secure_tsc_msrs(regs, write);
|
||||
return __vc_handle_secure_tsc_msrs(ctxt, write);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -218,6 +218,7 @@
|
|||
#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 1) /* "flexpriority" Intel FlexPriority */
|
||||
#define X86_FEATURE_EPT ( 8*32+ 2) /* "ept" Intel Extended Page Table */
|
||||
#define X86_FEATURE_VPID ( 8*32+ 3) /* "vpid" Intel Virtual Processor ID */
|
||||
#define X86_FEATURE_COHERENCY_SFW_NO ( 8*32+ 4) /* SNP cache coherency software work around not needed */
|
||||
|
||||
#define X86_FEATURE_VMMCALL ( 8*32+15) /* "vmmcall" Prefer VMMCALL to VMCALL */
|
||||
#define X86_FEATURE_XENPV ( 8*32+16) /* Xen paravirtual guest */
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef _ASM_X86_CPUID_H
|
||||
#define _ASM_X86_CPUID_H
|
||||
|
||||
#include <asm/cpuid/api.h>
|
||||
|
||||
#endif /* _ASM_X86_CPUID_H */
|
||||
|
|
@ -619,6 +619,24 @@ int rmp_make_shared(u64 pfn, enum pg_level level);
|
|||
void snp_leak_pages(u64 pfn, unsigned int npages);
|
||||
void kdump_sev_callback(void);
|
||||
void snp_fixup_e820_tables(void);
|
||||
|
||||
static inline void sev_evict_cache(void *va, int npages)
|
||||
{
|
||||
volatile u8 val __always_unused;
|
||||
u8 *bytes = va;
|
||||
int page_idx;
|
||||
|
||||
/*
|
||||
* For SEV guests, a read from the first/last cache-lines of a 4K page
|
||||
* using the guest key is sufficient to cause a flush of all cache-lines
|
||||
* associated with that 4K page without incurring all the overhead of a
|
||||
* full CLFLUSH sequence.
|
||||
*/
|
||||
for (page_idx = 0; page_idx < npages; page_idx++) {
|
||||
val = bytes[page_idx * PAGE_SIZE];
|
||||
val = bytes[page_idx * PAGE_SIZE + PAGE_SIZE - 1];
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline bool snp_probe_rmptable_info(void) { return false; }
|
||||
static inline int snp_rmptable_init(void) { return -ENOSYS; }
|
||||
|
|
@ -634,6 +652,7 @@ static inline int rmp_make_shared(u64 pfn, enum pg_level level) { return -ENODEV
|
|||
static inline void snp_leak_pages(u64 pfn, unsigned int npages) {}
|
||||
static inline void kdump_sev_callback(void) { }
|
||||
static inline void snp_fixup_e820_tables(void) {}
|
||||
static inline void sev_evict_cache(void *va, int npages) {}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -94,12 +94,13 @@ DECLARE_STATIC_CALL(xen_hypercall, xen_hypercall_func);
|
|||
#ifdef MODULE
|
||||
#define __ADDRESSABLE_xen_hypercall
|
||||
#else
|
||||
#define __ADDRESSABLE_xen_hypercall __ADDRESSABLE_ASM_STR(__SCK__xen_hypercall)
|
||||
#define __ADDRESSABLE_xen_hypercall \
|
||||
__stringify(.global STATIC_CALL_KEY(xen_hypercall);)
|
||||
#endif
|
||||
|
||||
#define __HYPERCALL \
|
||||
__ADDRESSABLE_xen_hypercall \
|
||||
"call __SCT__xen_hypercall"
|
||||
__stringify(call STATIC_CALL_TRAMP(xen_hypercall))
|
||||
|
||||
#define __HYPERCALL_ENTRY(x) "a" (x)
|
||||
|
||||
|
|
|
|||
|
|
@ -1326,8 +1326,8 @@ static const char * const s5_reset_reason_txt[] = {
|
|||
|
||||
static __init int print_s5_reset_status_mmio(void)
|
||||
{
|
||||
unsigned long value;
|
||||
void __iomem *addr;
|
||||
u32 value;
|
||||
int i;
|
||||
|
||||
if (!cpu_feature_enabled(X86_FEATURE_ZEN))
|
||||
|
|
@ -1340,12 +1340,16 @@ static __init int print_s5_reset_status_mmio(void)
|
|||
value = ioread32(addr);
|
||||
iounmap(addr);
|
||||
|
||||
/* Value with "all bits set" is an error response and should be ignored. */
|
||||
if (value == U32_MAX)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(s5_reset_reason_txt); i++) {
|
||||
if (!(value & BIT(i)))
|
||||
continue;
|
||||
|
||||
if (s5_reset_reason_txt[i]) {
|
||||
pr_info("x86/amd: Previous system reset reason [0x%08lx]: %s\n",
|
||||
pr_info("x86/amd: Previous system reset reason [0x%08x]: %s\n",
|
||||
value, s5_reset_reason_txt[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -386,7 +386,6 @@ static bool __init should_mitigate_vuln(unsigned int bug)
|
|||
|
||||
case X86_BUG_SPECTRE_V2:
|
||||
case X86_BUG_RETBLEED:
|
||||
case X86_BUG_SRSO:
|
||||
case X86_BUG_L1TF:
|
||||
case X86_BUG_ITS:
|
||||
return cpu_attack_vector_mitigated(CPU_MITIGATE_USER_KERNEL) ||
|
||||
|
|
@ -417,6 +416,10 @@ static bool __init should_mitigate_vuln(unsigned int bug)
|
|||
cpu_attack_vector_mitigated(CPU_MITIGATE_USER_USER) ||
|
||||
cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_GUEST) ||
|
||||
(smt_mitigations != SMT_MITIGATIONS_OFF);
|
||||
|
||||
case X86_BUG_SPEC_STORE_BYPASS:
|
||||
return cpu_attack_vector_mitigated(CPU_MITIGATE_USER_USER);
|
||||
|
||||
default:
|
||||
WARN(1, "Unknown bug %x\n", bug);
|
||||
return false;
|
||||
|
|
@ -1069,10 +1072,8 @@ static void __init gds_select_mitigation(void)
|
|||
if (gds_mitigation == GDS_MITIGATION_AUTO) {
|
||||
if (should_mitigate_vuln(X86_BUG_GDS))
|
||||
gds_mitigation = GDS_MITIGATION_FULL;
|
||||
else {
|
||||
else
|
||||
gds_mitigation = GDS_MITIGATION_OFF;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* No microcode */
|
||||
|
|
@ -2713,6 +2714,11 @@ static void __init ssb_select_mitigation(void)
|
|||
ssb_mode = SPEC_STORE_BYPASS_DISABLE;
|
||||
break;
|
||||
case SPEC_STORE_BYPASS_CMD_AUTO:
|
||||
if (should_mitigate_vuln(X86_BUG_SPEC_STORE_BYPASS))
|
||||
ssb_mode = SPEC_STORE_BYPASS_PRCTL;
|
||||
else
|
||||
ssb_mode = SPEC_STORE_BYPASS_NONE;
|
||||
break;
|
||||
case SPEC_STORE_BYPASS_CMD_PRCTL:
|
||||
ssb_mode = SPEC_STORE_BYPASS_PRCTL;
|
||||
break;
|
||||
|
|
@ -3184,8 +3190,18 @@ static void __init srso_select_mitigation(void)
|
|||
}
|
||||
|
||||
if (srso_mitigation == SRSO_MITIGATION_AUTO) {
|
||||
if (should_mitigate_vuln(X86_BUG_SRSO)) {
|
||||
/*
|
||||
* Use safe-RET if user->kernel or guest->host protection is
|
||||
* required. Otherwise the 'microcode' mitigation is sufficient
|
||||
* to protect the user->user and guest->guest vectors.
|
||||
*/
|
||||
if (cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_HOST) ||
|
||||
(cpu_attack_vector_mitigated(CPU_MITIGATE_USER_KERNEL) &&
|
||||
!boot_cpu_has(X86_FEATURE_SRSO_USER_KERNEL_NO))) {
|
||||
srso_mitigation = SRSO_MITIGATION_SAFE_RET;
|
||||
} else if (cpu_attack_vector_mitigated(CPU_MITIGATE_USER_USER) ||
|
||||
cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_GUEST)) {
|
||||
srso_mitigation = SRSO_MITIGATION_MICROCODE;
|
||||
} else {
|
||||
srso_mitigation = SRSO_MITIGATION_NONE;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <asm/spec-ctrl.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/resctrl.h>
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
|
|
@ -117,6 +118,8 @@ static void bsp_init_hygon(struct cpuinfo_x86 *c)
|
|||
x86_amd_ls_cfg_ssbd_mask = 1ULL << 10;
|
||||
}
|
||||
}
|
||||
|
||||
resctrl_cpu_detect(c);
|
||||
}
|
||||
|
||||
static void early_init_hygon(struct cpuinfo_x86 *c)
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
|
|||
if (c->x86_power & (1 << 8)) {
|
||||
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
|
||||
set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
|
||||
} else if ((c->x86_vfm >= INTEL_P4_PRESCOTT && c->x86_vfm <= INTEL_P4_WILLAMETTE) ||
|
||||
} else if ((c->x86_vfm >= INTEL_P4_PRESCOTT && c->x86_vfm <= INTEL_P4_CEDARMILL) ||
|
||||
(c->x86_vfm >= INTEL_CORE_YONAH && c->x86_vfm <= INTEL_IVYBRIDGE)) {
|
||||
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,8 +171,28 @@ static int cmp_id(const void *key, const void *elem)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static u32 cpuid_to_ucode_rev(unsigned int val)
|
||||
{
|
||||
union zen_patch_rev p = {};
|
||||
union cpuid_1_eax c;
|
||||
|
||||
c.full = val;
|
||||
|
||||
p.stepping = c.stepping;
|
||||
p.model = c.model;
|
||||
p.ext_model = c.ext_model;
|
||||
p.ext_fam = c.ext_fam;
|
||||
|
||||
return p.ucode_rev;
|
||||
}
|
||||
|
||||
static bool need_sha_check(u32 cur_rev)
|
||||
{
|
||||
if (!cur_rev) {
|
||||
cur_rev = cpuid_to_ucode_rev(bsp_cpuid_1_eax);
|
||||
pr_info_once("No current revision, generating the lowest one: 0x%x\n", cur_rev);
|
||||
}
|
||||
|
||||
switch (cur_rev >> 8) {
|
||||
case 0x80012: return cur_rev <= 0x800126f; break;
|
||||
case 0x80082: return cur_rev <= 0x800820f; break;
|
||||
|
|
@ -749,8 +769,6 @@ static struct ucode_patch *cache_find_patch(struct ucode_cpu_info *uci, u16 equi
|
|||
n.equiv_cpu = equiv_cpu;
|
||||
n.patch_id = uci->cpu_sig.rev;
|
||||
|
||||
WARN_ON_ONCE(!n.patch_id);
|
||||
|
||||
list_for_each_entry(p, µcode_cache, plist)
|
||||
if (patch_cpus_equivalent(p, &n, false))
|
||||
return p;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ static const struct cpuid_bit cpuid_bits[] = {
|
|||
{ X86_FEATURE_PROC_FEEDBACK, CPUID_EDX, 11, 0x80000007, 0 },
|
||||
{ X86_FEATURE_AMD_FAST_CPPC, CPUID_EDX, 15, 0x80000007, 0 },
|
||||
{ X86_FEATURE_MBA, CPUID_EBX, 6, 0x80000008, 0 },
|
||||
{ X86_FEATURE_COHERENCY_SFW_NO, CPUID_EBX, 31, 0x8000001f, 0 },
|
||||
{ X86_FEATURE_SMBA, CPUID_EBX, 2, 0x80000020, 0 },
|
||||
{ X86_FEATURE_BMEC, CPUID_EBX, 3, 0x80000020, 0 },
|
||||
{ X86_FEATURE_TSA_SQ_NO, CPUID_ECX, 1, 0x80000021, 0 },
|
||||
|
|
|
|||
|
|
@ -81,20 +81,25 @@ static bool parse_8000_001e(struct topo_scan *tscan, bool has_topoext)
|
|||
|
||||
cpuid_leaf(0x8000001e, &leaf);
|
||||
|
||||
tscan->c->topo.initial_apicid = leaf.ext_apic_id;
|
||||
|
||||
/*
|
||||
* If leaf 0xb is available, then the domain shifts are set
|
||||
* already and nothing to do here. Only valid for family >= 0x17.
|
||||
* If leaf 0xb/0x26 is available, then the APIC ID and the domain
|
||||
* shifts are set already.
|
||||
*/
|
||||
if (!has_topoext && tscan->c->x86 >= 0x17) {
|
||||
/*
|
||||
* Leaf 0x80000008 set the CORE domain shift already.
|
||||
* Update the SMT domain, but do not propagate it.
|
||||
*/
|
||||
unsigned int nthreads = leaf.core_nthreads + 1;
|
||||
if (!has_topoext) {
|
||||
tscan->c->topo.initial_apicid = leaf.ext_apic_id;
|
||||
|
||||
topology_update_dom(tscan, TOPO_SMT_DOMAIN, get_count_order(nthreads), nthreads);
|
||||
/*
|
||||
* Leaf 0x8000008 sets the CORE domain shift but not the
|
||||
* SMT domain shift. On CPUs with family >= 0x17, there
|
||||
* might be hyperthreads.
|
||||
*/
|
||||
if (tscan->c->x86 >= 0x17) {
|
||||
/* Update the SMT domain, but do not propagate it. */
|
||||
unsigned int nthreads = leaf.core_nthreads + 1;
|
||||
|
||||
topology_update_dom(tscan, TOPO_SMT_DOMAIN,
|
||||
get_count_order(nthreads), nthreads);
|
||||
}
|
||||
}
|
||||
|
||||
store_node(tscan, leaf.nnodes_per_socket + 1, leaf.node_id);
|
||||
|
|
|
|||
|
|
@ -1881,19 +1881,20 @@ long fpu_xstate_prctl(int option, unsigned long arg2)
|
|||
#ifdef CONFIG_PROC_PID_ARCH_STATUS
|
||||
/*
|
||||
* Report the amount of time elapsed in millisecond since last AVX512
|
||||
* use in the task.
|
||||
* use in the task. Report -1 if no AVX-512 usage.
|
||||
*/
|
||||
static void avx512_status(struct seq_file *m, struct task_struct *task)
|
||||
{
|
||||
unsigned long timestamp = READ_ONCE(x86_task_fpu(task)->avx512_timestamp);
|
||||
long delta;
|
||||
unsigned long timestamp;
|
||||
long delta = -1;
|
||||
|
||||
if (!timestamp) {
|
||||
/*
|
||||
* Report -1 if no AVX512 usage
|
||||
*/
|
||||
delta = -1;
|
||||
} else {
|
||||
/* AVX-512 usage is not tracked for kernel threads. Don't report anything. */
|
||||
if (task->flags & (PF_KTHREAD | PF_USER_WORKER))
|
||||
return;
|
||||
|
||||
timestamp = READ_ONCE(x86_task_fpu(task)->avx512_timestamp);
|
||||
|
||||
if (timestamp) {
|
||||
delta = (long)(jiffies - timestamp);
|
||||
/*
|
||||
* Cap to LONG_MAX if time difference > LONG_MAX
|
||||
|
|
|
|||
|
|
@ -810,6 +810,8 @@ static int __pv_send_ipi(unsigned long *ipi_bitmap, struct kvm_apic_map *map,
|
|||
if (min > map->max_apic_id)
|
||||
return 0;
|
||||
|
||||
min = array_index_nospec(min, map->max_apic_id + 1);
|
||||
|
||||
for_each_set_bit(i, ipi_bitmap,
|
||||
min((u32)BITS_PER_LONG, (map->max_apic_id - min + 1))) {
|
||||
if (map->phys_map[min + i]) {
|
||||
|
|
|
|||
|
|
@ -718,13 +718,6 @@ static void sev_clflush_pages(struct page *pages[], unsigned long npages)
|
|||
|
||||
static void sev_writeback_caches(struct kvm *kvm)
|
||||
{
|
||||
/*
|
||||
* Note, the caller is responsible for ensuring correctness if the mask
|
||||
* can be modified, e.g. if a CPU could be doing VMRUN.
|
||||
*/
|
||||
if (cpumask_empty(to_kvm_sev_info(kvm)->have_run_cpus))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Ensure that all dirty guest tagged cache entries are written back
|
||||
* before releasing the pages back to the system for use. CLFLUSH will
|
||||
|
|
@ -739,6 +732,9 @@ static void sev_writeback_caches(struct kvm *kvm)
|
|||
* serializing multiple calls and having responding CPUs (to the IPI)
|
||||
* mark themselves as still running if they are running (or about to
|
||||
* run) a vCPU for the VM.
|
||||
*
|
||||
* Note, the caller is responsible for ensuring correctness if the mask
|
||||
* can be modified, e.g. if a CPU could be doing VMRUN.
|
||||
*/
|
||||
wbnoinvd_on_cpus_mask(to_kvm_sev_info(kvm)->have_run_cpus);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9908,8 +9908,11 @@ static void kvm_sched_yield(struct kvm_vcpu *vcpu, unsigned long dest_id)
|
|||
rcu_read_lock();
|
||||
map = rcu_dereference(vcpu->kvm->arch.apic_map);
|
||||
|
||||
if (likely(map) && dest_id <= map->max_apic_id && map->phys_map[dest_id])
|
||||
target = map->phys_map[dest_id]->vcpu;
|
||||
if (likely(map) && dest_id <= map->max_apic_id) {
|
||||
dest_id = array_index_nospec(dest_id, map->max_apic_id + 1);
|
||||
if (map->phys_map[dest_id])
|
||||
target = map->phys_map[dest_id]->vcpu;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
|
|
|
|||
|
|
@ -5847,8 +5847,7 @@ static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
|
|||
goto out;
|
||||
}
|
||||
|
||||
bfqq = kmem_cache_alloc_node(bfq_pool,
|
||||
GFP_NOWAIT | __GFP_ZERO | __GFP_NOWARN,
|
||||
bfqq = kmem_cache_alloc_node(bfq_pool, GFP_NOWAIT | __GFP_ZERO,
|
||||
bfqd->queue->node);
|
||||
|
||||
if (bfqq) {
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg, struct gendisk *disk,
|
|||
|
||||
/* allocate */
|
||||
if (!new_blkg) {
|
||||
new_blkg = blkg_alloc(blkcg, disk, GFP_NOWAIT | __GFP_NOWARN);
|
||||
new_blkg = blkg_alloc(blkcg, disk, GFP_NOWAIT);
|
||||
if (unlikely(!new_blkg)) {
|
||||
ret = -ENOMEM;
|
||||
goto err_put_css;
|
||||
|
|
@ -1467,7 +1467,7 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css)
|
|||
|
||||
spin_lock_init(&blkcg->lock);
|
||||
refcount_set(&blkcg->online_pin, 1);
|
||||
INIT_RADIX_TREE(&blkcg->blkg_tree, GFP_NOWAIT | __GFP_NOWARN);
|
||||
INIT_RADIX_TREE(&blkcg->blkg_tree, GFP_NOWAIT);
|
||||
INIT_HLIST_HEAD(&blkcg->blkg_list);
|
||||
#ifdef CONFIG_CGROUP_WRITEBACK
|
||||
INIT_LIST_HEAD(&blkcg->cgwb_list);
|
||||
|
|
@ -1630,7 +1630,7 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)
|
|||
pd_prealloc = NULL;
|
||||
} else {
|
||||
pd = pol->pd_alloc_fn(disk, blkg->blkcg,
|
||||
GFP_NOWAIT | __GFP_NOWARN);
|
||||
GFP_NOWAIT);
|
||||
}
|
||||
|
||||
if (!pd) {
|
||||
|
|
|
|||
|
|
@ -557,7 +557,7 @@ static inline int bio_check_eod(struct bio *bio)
|
|||
sector_t maxsector = bdev_nr_sectors(bio->bi_bdev);
|
||||
unsigned int nr_sectors = bio_sectors(bio);
|
||||
|
||||
if (nr_sectors &&
|
||||
if (nr_sectors && maxsector &&
|
||||
(nr_sectors > maxsector ||
|
||||
bio->bi_iter.bi_sector > maxsector - nr_sectors)) {
|
||||
pr_info_ratelimited("%s: attempt to access beyond end of device\n"
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ static const char *const blk_queue_flag_name[] = {
|
|||
QUEUE_FLAG_NAME(SQ_SCHED),
|
||||
QUEUE_FLAG_NAME(DISABLE_WBT_DEF),
|
||||
QUEUE_FLAG_NAME(NO_ELV_SWITCH),
|
||||
QUEUE_FLAG_NAME(QOS_ENABLED),
|
||||
};
|
||||
#undef QUEUE_FLAG_NAME
|
||||
|
||||
|
|
|
|||
|
|
@ -5033,6 +5033,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
|
|||
unsigned int memflags;
|
||||
int i;
|
||||
struct xarray elv_tbl, et_tbl;
|
||||
bool queues_frozen = false;
|
||||
|
||||
lockdep_assert_held(&set->tag_list_lock);
|
||||
|
||||
|
|
@ -5056,9 +5057,6 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
|
|||
blk_mq_sysfs_unregister_hctxs(q);
|
||||
}
|
||||
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list)
|
||||
blk_mq_freeze_queue_nomemsave(q);
|
||||
|
||||
/*
|
||||
* Switch IO scheduler to 'none', cleaning up the data associated
|
||||
* with the previous scheduler. We will switch back once we are done
|
||||
|
|
@ -5068,6 +5066,9 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
|
|||
if (blk_mq_elv_switch_none(q, &elv_tbl))
|
||||
goto switch_back;
|
||||
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list)
|
||||
blk_mq_freeze_queue_nomemsave(q);
|
||||
queues_frozen = true;
|
||||
if (blk_mq_realloc_tag_set_tags(set, nr_hw_queues) < 0)
|
||||
goto switch_back;
|
||||
|
||||
|
|
@ -5091,8 +5092,12 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
|
|||
}
|
||||
switch_back:
|
||||
/* The blk_mq_elv_switch_back unfreezes queue for us. */
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list)
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list) {
|
||||
/* switch_back expects queue to be frozen */
|
||||
if (!queues_frozen)
|
||||
blk_mq_freeze_queue_nomemsave(q);
|
||||
blk_mq_elv_switch_back(q, &elv_tbl, &et_tbl);
|
||||
}
|
||||
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list) {
|
||||
blk_mq_sysfs_register_hctxs(q);
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
#include "blk-rq-qos.h"
|
||||
|
||||
__read_mostly DEFINE_STATIC_KEY_FALSE(block_rq_qos);
|
||||
|
||||
/*
|
||||
* Increment 'v', if 'v' is below 'below'. Returns true if we succeeded,
|
||||
* false if 'v' + 1 would be bigger than 'below'.
|
||||
|
|
@ -319,8 +317,8 @@ void rq_qos_exit(struct request_queue *q)
|
|||
struct rq_qos *rqos = q->rq_qos;
|
||||
q->rq_qos = rqos->next;
|
||||
rqos->ops->exit(rqos);
|
||||
static_branch_dec(&block_rq_qos);
|
||||
}
|
||||
blk_queue_flag_clear(QUEUE_FLAG_QOS_ENABLED, q);
|
||||
mutex_unlock(&q->rq_qos_mutex);
|
||||
}
|
||||
|
||||
|
|
@ -346,7 +344,7 @@ int rq_qos_add(struct rq_qos *rqos, struct gendisk *disk, enum rq_qos_id id,
|
|||
goto ebusy;
|
||||
rqos->next = q->rq_qos;
|
||||
q->rq_qos = rqos;
|
||||
static_branch_inc(&block_rq_qos);
|
||||
blk_queue_flag_set(QUEUE_FLAG_QOS_ENABLED, q);
|
||||
|
||||
blk_mq_unfreeze_queue(q, memflags);
|
||||
|
||||
|
|
@ -377,6 +375,8 @@ void rq_qos_del(struct rq_qos *rqos)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!q->rq_qos)
|
||||
blk_queue_flag_clear(QUEUE_FLAG_QOS_ENABLED, q);
|
||||
blk_mq_unfreeze_queue(q, memflags);
|
||||
|
||||
mutex_lock(&q->debugfs_mutex);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue