mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +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
	
	 Christian Brauner
						Christian Brauner