KVM/arm updates for Linux 5.5: - Allow non-ISV data aborts to be reported to userspace - Allow injection of data aborts from userspace - Expose stolen time to guests - GICv4 performance improvements - vgic ITS emulation fixes - Simplify FWB handling - Enable halt pool counters - Make the emulated timer PREEMPT_RT compliant
Showing the changes to include/linux (7 of 55 files). Show all
Unified · Split
| @@ -45,6 +45,7 @@ · 44 unmodified lines | |||
| 45 | #define ARM_SMCCC_OWNER_SIP 2 | 45 | #define ARM_SMCCC_OWNER_SIP 2 |
| 46 | #define ARM_SMCCC_OWNER_OEM 3 | 46 | #define ARM_SMCCC_OWNER_OEM 3 |
| 47 | #define ARM_SMCCC_OWNER_STANDARD 4 | 47 | #define ARM_SMCCC_OWNER_STANDARD 4 |
| 48 | #define ARM_SMCCC_OWNER_STANDARD_HYP 5 | ||
| 48 | #define ARM_SMCCC_OWNER_TRUSTED_APP 48 | 49 | #define ARM_SMCCC_OWNER_TRUSTED_APP 48 |
| 49 | #define ARM_SMCCC_OWNER_TRUSTED_APP_END 49 | 50 | #define ARM_SMCCC_OWNER_TRUSTED_APP_END 49 |
| 50 | #define ARM_SMCCC_OWNER_TRUSTED_OS 50 | 51 | #define ARM_SMCCC_OWNER_TRUSTED_OS 50 |
| @@ -80,6 +81,22 @@ · 29 unmodified lines | |||
| 80 | 81 | ||
| 81 | #include <linux/linkage.h> | 82 | #include <linux/linkage.h> |
| 82 | #include <linux/types.h> | 83 | #include <linux/types.h> |
| 84 | |||
| 85 | enum arm_smccc_conduit { | ||
| 86 | SMCCC_CONDUIT_NONE, | ||
| 87 | SMCCC_CONDUIT_SMC, | ||
| 88 | SMCCC_CONDUIT_HVC, | ||
| 89 | }; | ||
| 90 | |||
| 91 | /** | ||
| 92 | * arm_smccc_1_1_get_conduit() | ||
| 93 | * | ||
| 94 | * Returns the conduit to be used for SMCCCv1.1 or later. | ||
| 95 | * | ||
| 96 | * When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE. | ||
| 97 | */ | ||
| 98 | enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void); | ||
| 99 | |||
| 83 | /** | 100 | /** |
| 84 | * struct arm_smccc_res - Result from SMC/HVC call | 101 | * struct arm_smccc_res - Result from SMC/HVC call |
| 85 | * @a0-a3 result values from registers 0 to 3 | 102 | * @a0-a3 result values from registers 0 to 3 |
| @@ -302,5 +319,63 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, · 216 unmodified lines | |||
| 302 | #define SMCCC_RET_NOT_SUPPORTED -1 | 319 | #define SMCCC_RET_NOT_SUPPORTED -1 |
| 303 | #define SMCCC_RET_NOT_REQUIRED -2 | 320 | #define SMCCC_RET_NOT_REQUIRED -2 |
| 304 | 321 | ||
| 322 | /* | ||
| 323 | * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED. | ||
| 324 | * Used when the SMCCC conduit is not defined. The empty asm statement | ||
| 325 | * avoids compiler warnings about unused variables. | ||
| 326 | */ | ||
| 327 | #define __fail_smccc_1_1(...) \ | ||
| 328 | do { \ | ||
| 329 | __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \ | ||
| 330 | asm ("" __constraints(__count_args(__VA_ARGS__))); \ | ||
| 331 | if (___res) \ | ||
| 332 | ___res->a0 = SMCCC_RET_NOT_SUPPORTED; \ | ||
| 333 | } while (0) | ||
| 334 | |||
| 335 | /* | ||
| 336 | * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call | ||
| 337 | * | ||
| 338 | * This is a variadic macro taking one to eight source arguments, and | ||
| 339 | * an optional return structure. | ||
| 340 | * | ||
| 341 | * @a0-a7: arguments passed in registers 0 to 7 | ||
| 342 | * @res: result values from registers 0 to 3 | ||
| 343 | * | ||
| 344 | * This macro will make either an HVC call or an SMC call depending on the | ||
| 345 | * current SMCCC conduit. If no valid conduit is available then -1 | ||
| 346 | * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied). | ||
| 347 | * | ||
| 348 | * The return value also provides the conduit that was used. | ||
| 349 | */ | ||
| 350 | #define arm_smccc_1_1_invoke(...) ({ \ | ||
| 351 | int method = arm_smccc_1_1_get_conduit(); \ | ||
| 352 | switch (method) { \ | ||
| 353 | case SMCCC_CONDUIT_HVC: \ | ||
| 354 | arm_smccc_1_1_hvc(__VA_ARGS__); \ | ||
| 355 | break; \ | ||
| 356 | case SMCCC_CONDUIT_SMC: \ | ||
| 357 | arm_smccc_1_1_smc(__VA_ARGS__); \ | ||
| 358 | break; \ | ||
| 359 | default: \ | ||
| 360 | __fail_smccc_1_1(__VA_ARGS__); \ | ||
| 361 | method = SMCCC_CONDUIT_NONE; \ | ||
| 362 | break; \ | ||
| 363 | } \ | ||
| 364 | method; \ | ||
| 365 | }) | ||
| 366 | |||
| 367 | /* Paravirtualised time calls (defined by ARM DEN0057A) */ | ||
| 368 | #define ARM_SMCCC_HV_PV_TIME_FEATURES \ | ||
| 369 | ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ | ||
| 370 | ARM_SMCCC_SMC_64, \ | ||
| 371 | ARM_SMCCC_OWNER_STANDARD_HYP, \ | ||
| 372 | 0x20) | ||
| 373 | |||
| 374 | #define ARM_SMCCC_HV_PV_TIME_ST \ | ||
| 375 | ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ | ||
| 376 | ARM_SMCCC_SMC_64, \ | ||
| 377 | ARM_SMCCC_OWNER_STANDARD_HYP, \ | ||
| 378 | 0x21) | ||
| 379 | |||
| 305 | #endif /*__ASSEMBLY__*/ | 380 | #endif /*__ASSEMBLY__*/ |
| 306 | #endif /*__LINUX_ARM_SMCCC_H*/ | 381 | #endif /*__LINUX_ARM_SMCCC_H*/ |
| @@ -5,12 +5,6 @@ · 4 unmodified lines | |||
| 5 | 5 | ||
| 6 | #include <uapi/linux/arm_sdei.h> | 6 | #include <uapi/linux/arm_sdei.h> |
| 7 | 7 | ||
| 8 | enum sdei_conduit_types { | ||
| 9 | CONDUIT_INVALID = 0, | ||
| 10 | CONDUIT_SMC, | ||
| 11 | CONDUIT_HVC, | ||
| 12 | }; | ||
| 13 | |||
| 14 | #include <acpi/ghes.h> | 8 | #include <acpi/ghes.h> |
| 15 | 9 | ||
| 16 | #ifdef CONFIG_ARM_SDE_INTERFACE | 10 | #ifdef CONFIG_ARM_SDE_INTERFACE |
| @@ -136,6 +136,7 @@ enum cpuhp_state { · 135 unmodified lines | |||
| 136 | /* Must be the last timer callback */ | 136 | /* Must be the last timer callback */ |
| 137 | CPUHP_AP_DUMMY_TIMER_STARTING, | 137 | CPUHP_AP_DUMMY_TIMER_STARTING, |
| 138 | CPUHP_AP_ARM_XEN_STARTING, | 138 | CPUHP_AP_ARM_XEN_STARTING, |
| 139 | CPUHP_AP_ARM_KVMPV_STARTING, | ||
| 139 | CPUHP_AP_ARM_CORESIGHT_STARTING, | 140 | CPUHP_AP_ARM_CORESIGHT_STARTING, |
| 140 | CPUHP_AP_ARM64_ISNDEP_STARTING, | 141 | CPUHP_AP_ARM64_ISNDEP_STARTING, |
| 141 | CPUHP_AP_SMPCFD_DYING, | 142 | CPUHP_AP_SMPCFD_DYING, |
| @@ -32,9 +32,13 @@ struct its_vm { · 31 unmodified lines | |||
| 32 | struct its_vpe { | 32 | struct its_vpe { |
| 33 | struct page *vpt_page; | 33 | struct page *vpt_page; |
| 34 | struct its_vm *its_vm; | 34 | struct its_vm *its_vm; |
| 35 | /* per-vPE VLPI tracking */ | ||
| 36 | atomic_t vlpi_count; | ||
| 35 | /* Doorbell interrupt */ | 37 | /* Doorbell interrupt */ |
| 36 | int irq; | 38 | int irq; |
| 37 | irq_hw_number_t vpe_db_lpi; | 39 | irq_hw_number_t vpe_db_lpi; |
| 40 | /* VPE resident */ | ||
| 41 | bool resident; | ||
| 38 | /* VPE proxy mapping */ | 42 | /* VPE proxy mapping */ |
| 39 | int vpe_proxy_event; | 43 | int vpe_proxy_event; |
| 40 | /* | 44 | /* |
| @@ -741,6 +741,28 @@ int kvm_write_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, · 740 unmodified lines | |||
| 741 | unsigned long len); | 741 | unsigned long len); |
| 742 | int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc, | 742 | int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc, |
| 743 | gpa_t gpa, unsigned long len); | 743 | gpa_t gpa, unsigned long len); |
| 744 | |||
| 745 | #define __kvm_put_guest(kvm, gfn, offset, value, type) \ | ||
| 746 | ({ \ | ||
| 747 | unsigned long __addr = gfn_to_hva(kvm, gfn); \ | ||
| 748 | type __user *__uaddr = (type __user *)(__addr + offset); \ | ||
| 749 | int __ret = -EFAULT; \ | ||
| 750 | \ | ||
| 751 | if (!kvm_is_error_hva(__addr)) \ | ||
| 752 | __ret = put_user(value, __uaddr); \ | ||
| 753 | if (!__ret) \ | ||
| 754 | mark_page_dirty(kvm, gfn); \ | ||
| 755 | __ret; \ | ||
| 756 | }) | ||
| 757 | |||
| 758 | #define kvm_put_guest(kvm, gpa, value, type) \ | ||
| 759 | ({ \ | ||
| 760 | gpa_t __gpa = gpa; \ | ||
| 761 | struct kvm *__kvm = kvm; \ | ||
| 762 | __kvm_put_guest(__kvm, __gpa >> PAGE_SHIFT, \ | ||
| 763 | offset_in_page(__gpa), (value), type); \ | ||
| 764 | }) | ||
| 765 | |||
| 744 | int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len); | 766 | int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len); |
| 745 | int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len); | 767 | int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len); |
| 746 | struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn); | 768 | struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn); |
| @@ -1237,7 +1259,7 @@ extern unsigned int halt_poll_ns_grow_start; · 490 unmodified lines | |||
| 1237 | extern unsigned int halt_poll_ns_shrink; | 1259 | extern unsigned int halt_poll_ns_shrink; |
| 1238 | 1260 | ||
| 1239 | struct kvm_device { | 1261 | struct kvm_device { |
| 1240 | struct kvm_device_ops *ops; | 1262 | const struct kvm_device_ops *ops; |
| 1241 | struct kvm *kvm; | 1263 | struct kvm *kvm; |
| 1242 | void *private; | 1264 | void *private; |
| 1243 | struct list_head vm_node; | 1265 | struct list_head vm_node; |
| @@ -1290,7 +1312,7 @@ struct kvm_device_ops { · 46 unmodified lines | |||
| 1290 | void kvm_device_get(struct kvm_device *dev); | 1312 | void kvm_device_get(struct kvm_device *dev); |
| 1291 | void kvm_device_put(struct kvm_device *dev); | 1313 | void kvm_device_put(struct kvm_device *dev); |
| 1292 | struct kvm_device *kvm_device_from_filp(struct file *filp); | 1314 | struct kvm_device *kvm_device_from_filp(struct file *filp); |
| 1293 | int kvm_register_device_ops(struct kvm_device_ops *ops, u32 type); | 1315 | int kvm_register_device_ops(const struct kvm_device_ops *ops, u32 type); |
| 1294 | void kvm_unregister_device_ops(u32 type); | 1316 | void kvm_unregister_device_ops(u32 type); |
| 1295 | 1317 | ||
| 1296 | extern struct kvm_device_ops kvm_mpic_ops; | 1318 | extern struct kvm_device_ops kvm_mpic_ops; |
| @@ -35,6 +35,8 @@ typedef unsigned long gva_t; · 34 unmodified lines | |||
| 35 | typedef u64 gpa_t; | 35 | typedef u64 gpa_t; |
| 36 | typedef u64 gfn_t; | 36 | typedef u64 gfn_t; |
| 37 | 37 | ||
| 38 | #define GPA_INVALID (~(gpa_t)0) | ||
| 39 | |||
| 38 | typedef unsigned long hva_t; | 40 | typedef unsigned long hva_t; |
| 39 | typedef u64 hpa_t; | 41 | typedef u64 hpa_t; |
| 40 | typedef u64 hfn_t; | 42 | typedef u64 hfn_t; |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | #ifndef __LINUX_PSCI_H | 7 | #ifndef __LINUX_PSCI_H |
| 8 | #define __LINUX_PSCI_H | 8 | #define __LINUX_PSCI_H |
| 9 | 9 | ||
| 10 | #include <linux/arm-smccc.h> | ||
| 10 | #include <linux/init.h> | 11 | #include <linux/init.h> |
| 11 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| 12 | 13 | ||
| @@ -18,12 +19,6 @@ bool psci_tos_resident_on(int cpu); · 5 unmodified lines | |||
| 18 | int psci_cpu_suspend_enter(u32 state); | 19 | int psci_cpu_suspend_enter(u32 state); |
| 19 | bool psci_power_state_is_valid(u32 state); | 20 | bool psci_power_state_is_valid(u32 state); |
| 20 | 21 | ||
| 21 | enum psci_conduit { | ||
| 22 | PSCI_CONDUIT_NONE, | ||
| 23 | PSCI_CONDUIT_SMC, | ||
| 24 | PSCI_CONDUIT_HVC, | ||
| 25 | }; | ||
| 26 | |||
| 27 | enum smccc_version { | 22 | enum smccc_version { |
| 28 | SMCCC_VERSION_1_0, | 23 | SMCCC_VERSION_1_0, |
| 29 | SMCCC_VERSION_1_1, | 24 | SMCCC_VERSION_1_1, |
| @@ -38,7 +33,7 @@ struct psci_operations { · 8 unmodified lines | |||
| 38 | int (*affinity_info)(unsigned long target_affinity, | 33 | int (*affinity_info)(unsigned long target_affinity, |
| 39 | unsigned long lowest_affinity_level); | 34 | unsigned long lowest_affinity_level); |
| 40 | int (*migrate_info_type)(void); | 35 | int (*migrate_info_type)(void); |
| 41 | enum psci_conduit conduit; | 36 | enum arm_smccc_conduit conduit; |
| 42 | enum smccc_version smccc_version; | 37 | enum smccc_version smccc_version; |
| 43 | }; | 38 | }; |
| 44 | 39 | ||