Pull KVM fixes from Radim Krčmář: "ARM: - PSCI selection API, a leftover from 4.16 (for stable) - Kick vcpu on active interrupt affinity change - Plug a VMID allocation race on oversubscribed systems - Silence debug messages - Update Christoffer's email address (linaro -> arm) x86: - Expose userspace-relevant bits of a newly added feature - Fix TLB flushing on VMX with VPID, but without EPT" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: x86/headers/UAPI: Move DISABLE_EXITS KVM capability bits to the UAPI kvm: apic: Flush TLB after APIC mode/address change if VPIDs are in use arm/arm64: KVM: Add PSCI version selection API KVM: arm/arm64: vgic: Kick new VCPU on interrupt migration arm64: KVM: Demote SVE and LORegion warnings to debug only MAINTAINERS: Update e-mail address for Christoffer Dall KVM: arm/arm64: Close VMID generation race
Unified · Split
| @@ -1960,6 +1960,9 @@ ARM 32-bit VFP control registers have the following id bit patterns: · 1959 unmodified lines | ||
| 1960 | 1960 | ARM 64-bit FP registers have the following id bit patterns: |
| 1961 | 1961 | 0x4030 0000 0012 0 <regno:12> |
| 1962 | 1962 | |
| 1963 | +ARM firmware pseudo-registers have the following bit pattern: | |
| 1964 | + 0x4030 0000 0014 <regno:16> | |
| 1965 | + | |
| 1963 | 1966 | |
| 1964 | 1967 | arm64 registers are mapped using the lower 32 bits. The upper 16 of |
| 1965 | 1968 | that is the register group type, or coprocessor number: |
| @@ -1976,6 +1979,9 @@ arm64 CCSIDR registers are demultiplexed by CSSELR value: · 10 unmodified lines | ||
| 1976 | 1979 | arm64 system registers have the following id bit patterns: |
| 1977 | 1980 | 0x6030 0000 0013 <op0:2> <op1:3> <crn:4> <crm:4> <op2:3> |
| 1978 | 1981 | |
| 1982 | +arm64 firmware pseudo-registers have the following bit pattern: | |
| 1983 | + 0x6030 0000 0014 <regno:16> | |
| 1984 | + | |
| 1979 | 1985 | |
| 1980 | 1986 | MIPS registers are mapped using the lower 32 bits. The upper 16 of that is |
| 1981 | 1987 | the register group type: |
| @@ -2510,7 +2516,8 @@ Possible features: · 528 unmodified lines | ||
| 2510 | 2516 | and execute guest code when KVM_RUN is called. |
| 2511 | 2517 | - KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode. |
| 2512 | 2518 | Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only). |
| 2513 | − - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 for the CPU. | |
| 2519 | + - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 (or a future revision | |
| 2520 | + backward compatible with v0.2) for the CPU. | |
| 2514 | 2521 | Depends on KVM_CAP_ARM_PSCI_0_2. |
| 2515 | 2522 | - KVM_ARM_VCPU_PMU_V3: Emulate PMUv3 for the CPU. |
| 2516 | 2523 | Depends on KVM_CAP_ARM_PMU_V3. |
| @@ -0,0 +1,30 @@ | ||
| 1 | +KVM implements the PSCI (Power State Coordination Interface) | |
| 2 | +specification in order to provide services such as CPU on/off, reset | |
| 3 | +and power-off to the guest. | |
| 4 | + | |
| 5 | +The PSCI specification is regularly updated to provide new features, | |
| 6 | +and KVM implements these updates if they make sense from a virtualization | |
| 7 | +point of view. | |
| 8 | + | |
| 9 | +This means that a guest booted on two different versions of KVM can | |
| 10 | +observe two different "firmware" revisions. This could cause issues if | |
| 11 | +a given guest is tied to a particular PSCI revision (unlikely), or if | |
| 12 | +a migration causes a different PSCI version to be exposed out of the | |
| 13 | +blue to an unsuspecting guest. | |
| 14 | + | |
| 15 | +In order to remedy this situation, KVM exposes a set of "firmware | |
| 16 | +pseudo-registers" that can be manipulated using the GET/SET_ONE_REG | |
| 17 | +interface. These registers can be saved/restored by userspace, and set | |
| 18 | +to a convenient value if required. | |
| 19 | + | |
| 20 | +The following register is defined: | |
| 21 | + | |
| 22 | +* KVM_REG_ARM_PSCI_VERSION: | |
| 23 | + | |
| 24 | + - Only valid if the vcpu has the KVM_ARM_VCPU_PSCI_0_2 feature set | |
| 25 | + (and thus has already been initialized) | |
| 26 | + - Returns the current PSCI version on GET_ONE_REG (defaulting to the | |
| 27 | + highest PSCI version implemented by KVM and compatible with v0.2) | |
| 28 | + - Allows any PSCI version implemented by KVM and compatible with | |
| 29 | + v0.2 to be set with SET_ONE_REG | |
| 30 | + - Affects the whole VM (even if the register view is per-vcpu) | |
| @@ -7744,7 +7744,7 @@ F: arch/x86/include/asm/svm.h · 7743 unmodified lines | ||
| 7744 | 7744 | F: arch/x86/kvm/svm.c |
| 7745 | 7745 | |
| 7746 | 7746 | KERNEL VIRTUAL MACHINE FOR ARM (KVM/arm) |
| 7747 | −M: Christoffer Dall <christoffer.dall@linaro.org> | |
| 7747 | +M: Christoffer Dall <christoffer.dall@arm.com> | |
| 7748 | 7748 | M: Marc Zyngier <marc.zyngier@arm.com> |
| 7749 | 7749 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 7750 | 7750 | L: kvmarm@lists.cs.columbia.edu |
| @@ -7758,7 +7758,7 @@ F: virt/kvm/arm/ · 7 unmodified lines | ||
| 7758 | 7758 | F: include/kvm/arm_* |
| 7759 | 7759 | |
| 7760 | 7760 | KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) |
| 7761 | −M: Christoffer Dall <christoffer.dall@linaro.org> | |
| 7761 | +M: Christoffer Dall <christoffer.dall@arm.com> | |
| 7762 | 7762 | M: Marc Zyngier <marc.zyngier@arm.com> |
| 7763 | 7763 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 7764 | 7764 | L: kvmarm@lists.cs.columbia.edu |
| @@ -77,6 +77,9 @@ struct kvm_arch { · 76 unmodified lines | ||
| 77 | 77 | /* Interrupt controller */ |
| 78 | 78 | struct vgic_dist vgic; |
| 79 | 79 | int max_vcpus; |
| 80 | + | |
| 81 | + /* Mandated version of PSCI */ | |
| 82 | + u32 psci_version; | |
| 80 | 83 | }; |
| 81 | 84 | |
| 82 | 85 | #define KVM_NR_MEM_OBJS 40 |
| @@ -195,6 +195,12 @@ struct kvm_arch_memory_slot { · 194 unmodified lines | ||
| 195 | 195 | #define KVM_REG_ARM_VFP_FPINST 0x1009 |
| 196 | 196 | #define KVM_REG_ARM_VFP_FPINST2 0x100A |
| 197 | 197 | |
| 198 | +/* KVM-as-firmware specific pseudo-registers */ | |
| 199 | +#define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT) | |
| 200 | +#define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM | KVM_REG_SIZE_U64 | \ | |
| 201 | + KVM_REG_ARM_FW | ((r) & 0xffff)) | |
| 202 | +#define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) | |
| 203 | + | |
| 198 | 204 | /* Device Control API: ARM VGIC */ |
| 199 | 205 | #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 |
| 200 | 206 | #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <linux/module.h> |
| 23 | 23 | #include <linux/vmalloc.h> |
| 24 | 24 | #include <linux/fs.h> |
| 25 | +#include <kvm/arm_psci.h> | |
| 25 | 26 | #include <asm/cputype.h> |
| 26 | 27 | #include <linux/uaccess.h> |
| 27 | 28 | #include <asm/kvm.h> |
| @@ -176,6 +177,7 @@ static unsigned long num_core_regs(void) · 148 unmodified lines | ||
| 176 | 177 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) |
| 177 | 178 | { |
| 178 | 179 | return num_core_regs() + kvm_arm_num_coproc_regs(vcpu) |
| 180 | + + kvm_arm_get_fw_num_regs(vcpu) | |
| 179 | 181 | + NUM_TIMER_REGS; |
| 180 | 182 | } |
| 181 | 183 | |
| @@ -196,6 +198,11 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) · 14 unmodified lines | ||
| 196 | 198 | uindices++; |
| 197 | 199 | } |
| 198 | 200 | |
| 201 | + ret = kvm_arm_copy_fw_reg_indices(vcpu, uindices); | |
| 202 | + if (ret) | |
| 203 | + return ret; | |
| 204 | + uindices += kvm_arm_get_fw_num_regs(vcpu); | |
| 205 | + | |
| 199 | 206 | ret = copy_timer_indices(vcpu, uindices); |
| 200 | 207 | if (ret) |
| 201 | 208 | return ret; |
| @@ -214,6 +221,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 12 unmodified lines | ||
| 214 | 221 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
| 215 | 222 | return get_core_reg(vcpu, reg); |
| 216 | 223 | |
| 224 | + if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW) | |
| 225 | + return kvm_arm_get_fw_reg(vcpu, reg); | |
| 226 | + | |
| 217 | 227 | if (is_timer_reg(reg->id)) |
| 218 | 228 | return get_timer_reg(vcpu, reg); |
| 219 | 229 | |
| @@ -230,6 +240,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 10 unmodified lines | ||
| 230 | 240 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
| 231 | 241 | return set_core_reg(vcpu, reg); |
| 232 | 242 | |
| 243 | + if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW) | |
| 244 | + return kvm_arm_set_fw_reg(vcpu, reg); | |
| 245 | + | |
| 233 | 246 | if (is_timer_reg(reg->id)) |
| 234 | 247 | return set_timer_reg(vcpu, reg); |
| 235 | 248 | |
| @@ -75,6 +75,9 @@ struct kvm_arch { · 74 unmodified lines | ||
| 75 | 75 | |
| 76 | 76 | /* Interrupt controller */ |
| 77 | 77 | struct vgic_dist vgic; |
| 78 | + | |
| 79 | + /* Mandated version of PSCI */ | |
| 80 | + u32 psci_version; | |
| 78 | 81 | }; |
| 79 | 82 | |
| 80 | 83 | #define KVM_NR_MEM_OBJS 40 |
| @@ -206,6 +206,12 @@ struct kvm_arch_memory_slot { · 205 unmodified lines | ||
| 206 | 206 | #define KVM_REG_ARM_TIMER_CNT ARM64_SYS_REG(3, 3, 14, 3, 2) |
| 207 | 207 | #define KVM_REG_ARM_TIMER_CVAL ARM64_SYS_REG(3, 3, 14, 0, 2) |
| 208 | 208 | |
| 209 | +/* KVM-as-firmware specific pseudo-registers */ | |
| 210 | +#define KVM_REG_ARM_FW (0x0014 << KVM_REG_ARM_COPROC_SHIFT) | |
| 211 | +#define KVM_REG_ARM_FW_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ | |
| 212 | + KVM_REG_ARM_FW | ((r) & 0xffff)) | |
| 213 | +#define KVM_REG_ARM_PSCI_VERSION KVM_REG_ARM_FW_REG(0) | |
| 214 | + | |
| 209 | 215 | /* Device Control API: ARM VGIC */ |
| 210 | 216 | #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 |
| 211 | 217 | #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/module.h> |
| 26 | 26 | #include <linux/vmalloc.h> |
| 27 | 27 | #include <linux/fs.h> |
| 28 | +#include <kvm/arm_psci.h> | |
| 28 | 29 | #include <asm/cputype.h> |
| 29 | 30 | #include <linux/uaccess.h> |
| 30 | 31 | #include <asm/kvm.h> |
| @@ -205,7 +206,7 @@ static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 174 unmodified lines | ||
| 205 | 206 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) |
| 206 | 207 | { |
| 207 | 208 | return num_core_regs() + kvm_arm_num_sys_reg_descs(vcpu) |
| 208 | − + NUM_TIMER_REGS; | |
| 209 | + + kvm_arm_get_fw_num_regs(vcpu) + NUM_TIMER_REGS; | |
| 209 | 210 | } |
| 210 | 211 | |
| 211 | 212 | /** |
| @@ -225,6 +226,11 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) · 13 unmodified lines | ||
| 225 | 226 | uindices++; |
| 226 | 227 | } |
| 227 | 228 | |
| 229 | + ret = kvm_arm_copy_fw_reg_indices(vcpu, uindices); | |
| 230 | + if (ret) | |
| 231 | + return ret; | |
| 232 | + uindices += kvm_arm_get_fw_num_regs(vcpu); | |
| 233 | + | |
| 228 | 234 | ret = copy_timer_indices(vcpu, uindices); |
| 229 | 235 | if (ret) |
| 230 | 236 | return ret; |
| @@ -243,6 +249,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 12 unmodified lines | ||
| 243 | 249 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
| 244 | 250 | return get_core_reg(vcpu, reg); |
| 245 | 251 | |
| 252 | + if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW) | |
| 253 | + return kvm_arm_get_fw_reg(vcpu, reg); | |
| 254 | + | |
| 246 | 255 | if (is_timer_reg(reg->id)) |
| 247 | 256 | return get_timer_reg(vcpu, reg); |
| 248 | 257 | |
| @@ -259,6 +268,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 10 unmodified lines | ||
| 259 | 268 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
| 260 | 269 | return set_core_reg(vcpu, reg); |
| 261 | 270 | |
| 271 | + if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW) | |
| 272 | + return kvm_arm_set_fw_reg(vcpu, reg); | |
| 273 | + | |
| 262 | 274 | if (is_timer_reg(reg->id)) |
| 263 | 275 | return set_timer_reg(vcpu, reg); |
| 264 | 276 | |
| @@ -996,14 +996,12 @@ static u64 read_id_reg(struct sys_reg_desc const *r, bool raz) · 995 unmodified lines | ||
| 996 | 996 | |
| 997 | 997 | if (id == SYS_ID_AA64PFR0_EL1) { |
| 998 | 998 | if (val & (0xfUL << ID_AA64PFR0_SVE_SHIFT)) |
| 999 | − pr_err_once("kvm [%i]: SVE unsupported for guests, suppressing\n", | |
| 1000 | − task_pid_nr(current)); | |
| 999 | + kvm_debug("SVE unsupported for guests, suppressing\n"); | |
| 1001 | 1000 | |
| 1002 | 1001 | val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT); |
| 1003 | 1002 | } else if (id == SYS_ID_AA64MMFR1_EL1) { |
| 1004 | 1003 | if (val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT)) |
| 1005 | − pr_err_once("kvm [%i]: LORegions unsupported for guests, suppressing\n", | |
| 1006 | − task_pid_nr(current)); | |
| 1004 | + kvm_debug("LORegions unsupported for guests, suppressing\n"); | |
| 1007 | 1005 | |
| 1008 | 1006 | val &= ~(0xfUL << ID_AA64MMFR1_LOR_SHIFT); |
| 1009 | 1007 | } |
| @@ -4544,12 +4544,6 @@ static void vmx_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa) · 4543 unmodified lines | ||
| 4544 | 4544 | __vmx_flush_tlb(vcpu, to_vmx(vcpu)->vpid, invalidate_gpa); |
| 4545 | 4545 | } |
| 4546 | 4546 | |
| 4547 | −static void vmx_flush_tlb_ept_only(struct kvm_vcpu *vcpu) | |
| 4548 | −{ | |
| 4549 | − if (enable_ept) | |
| 4550 | − vmx_flush_tlb(vcpu, true); | |
| 4551 | −} | |
| 4552 | − | |
| 4553 | 4547 | static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu) |
| 4554 | 4548 | { |
| 4555 | 4549 | ulong cr0_guest_owned_bits = vcpu->arch.cr0_guest_owned_bits; |
| @@ -9278,7 +9272,7 @@ static void vmx_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set) · 4722 unmodified lines | ||
| 9278 | 9272 | } else { |
| 9279 | 9273 | sec_exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE; |
| 9280 | 9274 | sec_exec_control |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; |
| 9281 | − vmx_flush_tlb_ept_only(vcpu); | |
| 9275 | + vmx_flush_tlb(vcpu, true); | |
| 9282 | 9276 | } |
| 9283 | 9277 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, sec_exec_control); |
| 9284 | 9278 | |
| @@ -9306,7 +9300,7 @@ static void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu, hpa_t hpa) · 21 unmodified lines | ||
| 9306 | 9300 | !nested_cpu_has2(get_vmcs12(&vmx->vcpu), |
| 9307 | 9301 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) { |
| 9308 | 9302 | vmcs_write64(APIC_ACCESS_ADDR, hpa); |
| 9309 | − vmx_flush_tlb_ept_only(vcpu); | |
| 9303 | + vmx_flush_tlb(vcpu, true); | |
| 9310 | 9304 | } |
| 9311 | 9305 | } |
| 9312 | 9306 | |
| @@ -11220,7 +11214,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, · 1907 unmodified lines | ||
| 11220 | 11214 | } |
| 11221 | 11215 | } else if (nested_cpu_has2(vmcs12, |
| 11222 | 11216 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) { |
| 11223 | − vmx_flush_tlb_ept_only(vcpu); | |
| 11217 | + vmx_flush_tlb(vcpu, true); | |
| 11224 | 11218 | } |
| 11225 | 11219 | |
| 11226 | 11220 | /* |
| @@ -12073,7 +12067,7 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, · 846 unmodified lines | ||
| 12073 | 12067 | } else if (!nested_cpu_has_ept(vmcs12) && |
| 12074 | 12068 | nested_cpu_has2(vmcs12, |
| 12075 | 12069 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) { |
| 12076 | − vmx_flush_tlb_ept_only(vcpu); | |
| 12070 | + vmx_flush_tlb(vcpu, true); | |
| 12077 | 12071 | } |
| 12078 | 12072 | |
| 12079 | 12073 | /* This is needed for same reason as it was needed in prepare_vmcs02 */ |
| @@ -302,13 +302,6 @@ static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec) · 301 unmodified lines | ||
| 302 | 302 | __rem; \ |
| 303 | 303 | }) |
| 304 | 304 | |
| 305 | −#define KVM_X86_DISABLE_EXITS_MWAIT (1 << 0) | |
| 306 | −#define KVM_X86_DISABLE_EXITS_HTL (1 << 1) | |
| 307 | −#define KVM_X86_DISABLE_EXITS_PAUSE (1 << 2) | |
| 308 | −#define KVM_X86_DISABLE_VALID_EXITS (KVM_X86_DISABLE_EXITS_MWAIT | \ | |
| 309 | − KVM_X86_DISABLE_EXITS_HTL | \ | |
| 310 | − KVM_X86_DISABLE_EXITS_PAUSE) | |
| 311 | − | |
| 312 | 305 | static inline bool kvm_mwait_in_guest(struct kvm *kvm) |
| 313 | 306 | { |
| 314 | 307 | return kvm->arch.mwait_in_guest; |
| @@ -37,10 +37,15 @@ static inline int kvm_psci_version(struct kvm_vcpu *vcpu, struct kvm *kvm) · 36 unmodified lines | ||
| 37 | 37 | * Our PSCI implementation stays the same across versions from |
| 38 | 38 | * v0.2 onward, only adding the few mandatory functions (such |
| 39 | 39 | * as FEATURES with 1.0) that are required by newer |
| 40 | − * revisions. It is thus safe to return the latest. | |
| 40 | + * revisions. It is thus safe to return the latest, unless | |
| 41 | + * userspace has instructed us otherwise. | |
| 41 | 42 | */ |
| 42 | − if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features)) | |
| 43 | + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features)) { | |
| 44 | + if (vcpu->kvm->arch.psci_version) | |
| 45 | + return vcpu->kvm->arch.psci_version; | |
| 46 | + | |
| 43 | 47 | return KVM_ARM_PSCI_LATEST; |
| 48 | + } | |
| 44 | 49 | |
| 45 | 50 | return KVM_ARM_PSCI_0_1; |
| 46 | 51 | } |
| @@ -48,4 +53,11 @@ static inline int kvm_psci_version(struct kvm_vcpu *vcpu, struct kvm *kvm) · 1 unmodified line | ||
| 48 | 53 | |
| 49 | 54 | int kvm_hvc_call_handler(struct kvm_vcpu *vcpu); |
| 50 | 55 | |
| 56 | +struct kvm_one_reg; | |
| 57 | + | |
| 58 | +int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu); | |
| 59 | +int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices); | |
| 60 | +int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); | |
| 61 | +int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg); | |
| 62 | + | |
| 51 | 63 | #endif /* __KVM_ARM_PSCI_H__ */ |
| @@ -676,6 +676,13 @@ struct kvm_ioeventfd { · 675 unmodified lines | ||
| 676 | 676 | __u8 pad[36]; |
| 677 | 677 | }; |
| 678 | 678 | |
| 679 | +#define KVM_X86_DISABLE_EXITS_MWAIT (1 << 0) | |
| 680 | +#define KVM_X86_DISABLE_EXITS_HTL (1 << 1) | |
| 681 | +#define KVM_X86_DISABLE_EXITS_PAUSE (1 << 2) | |
| 682 | +#define KVM_X86_DISABLE_VALID_EXITS (KVM_X86_DISABLE_EXITS_MWAIT | \ | |
| 683 | + KVM_X86_DISABLE_EXITS_HTL | \ | |
| 684 | + KVM_X86_DISABLE_EXITS_PAUSE) | |
| 685 | + | |
| 679 | 686 | /* for KVM_ENABLE_CAP */ |
| 680 | 687 | struct kvm_enable_cap { |
| 681 | 688 | /* in */ |
| @@ -63,7 +63,7 @@ static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu); · 62 unmodified lines | ||
| 63 | 63 | static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1); |
| 64 | 64 | static u32 kvm_next_vmid; |
| 65 | 65 | static unsigned int kvm_vmid_bits __read_mostly; |
| 66 | −static DEFINE_SPINLOCK(kvm_vmid_lock); | |
| 66 | +static DEFINE_RWLOCK(kvm_vmid_lock); | |
| 67 | 67 | |
| 68 | 68 | static bool vgic_present; |
| 69 | 69 | |
| @@ -473,11 +473,16 @@ static void update_vttbr(struct kvm *kvm) · 403 unmodified lines | ||
| 473 | 473 | { |
| 474 | 474 | phys_addr_t pgd_phys; |
| 475 | 475 | u64 vmid; |
| 476 | + bool new_gen; | |
| 476 | 477 | |
| 477 | − if (!need_new_vmid_gen(kvm)) | |
| 478 | + read_lock(&kvm_vmid_lock); | |
| 479 | + new_gen = need_new_vmid_gen(kvm); | |
| 480 | + read_unlock(&kvm_vmid_lock); | |
| 481 | + | |
| 482 | + if (!new_gen) | |
| 478 | 483 | return; |
| 479 | 484 | |
| 480 | − spin_lock(&kvm_vmid_lock); | |
| 485 | + write_lock(&kvm_vmid_lock); | |
| 481 | 486 | |
| 482 | 487 | /* |
| 483 | 488 | * We need to re-check the vmid_gen here to ensure that if another vcpu |
| @@ -485,7 +490,7 @@ static void update_vttbr(struct kvm *kvm) · 1 unmodified line | ||
| 485 | 490 | * use the same vmid. |
| 486 | 491 | */ |
| 487 | 492 | if (!need_new_vmid_gen(kvm)) { |
| 488 | − spin_unlock(&kvm_vmid_lock); | |
| 493 | + write_unlock(&kvm_vmid_lock); | |
| 489 | 494 | return; |
| 490 | 495 | } |
| 491 | 496 | |
| @@ -519,7 +524,7 @@ static void update_vttbr(struct kvm *kvm) · 27 unmodified lines | ||
| 519 | 524 | vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK(kvm_vmid_bits); |
| 520 | 525 | kvm->arch.vttbr = kvm_phys_to_vttbr(pgd_phys) | vmid; |
| 521 | 526 | |
| 522 | − spin_unlock(&kvm_vmid_lock); | |
| 527 | + write_unlock(&kvm_vmid_lock); | |
| 523 | 528 | } |
| 524 | 529 | |
| 525 | 530 | static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/arm-smccc.h> |
| 19 | 19 | #include <linux/preempt.h> |
| 20 | 20 | #include <linux/kvm_host.h> |
| 21 | +#include <linux/uaccess.h> | |
| 21 | 22 | #include <linux/wait.h> |
| 22 | 23 | |
| 23 | 24 | #include <asm/cputype.h> |
| @@ -427,3 +428,62 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) · 403 unmodified lines | ||
| 427 | 428 | smccc_set_retval(vcpu, val, 0, 0, 0); |
| 428 | 429 | return 1; |
| 429 | 430 | } |
| 431 | + | |
| 432 | +int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) | |
| 433 | +{ | |
| 434 | + return 1; /* PSCI version */ | |
| 435 | +} | |
| 436 | + | |
| 437 | +int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) | |
| 438 | +{ | |
| 439 | + if (put_user(KVM_REG_ARM_PSCI_VERSION, uindices)) | |
| 440 | + return -EFAULT; | |
| 441 | + | |
| 442 | + return 0; | |
| 443 | +} | |
| 444 | + | |
| 445 | +int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |
| 446 | +{ | |
| 447 | + if (reg->id == KVM_REG_ARM_PSCI_VERSION) { | |
| 448 | + void __user *uaddr = (void __user *)(long)reg->addr; | |
| 449 | + u64 val; | |
| 450 | + | |
| 451 | + val = kvm_psci_version(vcpu, vcpu->kvm); | |
| 452 | + if (copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id))) | |
| 453 | + return -EFAULT; | |
| 454 | + | |
| 455 | + return 0; | |
| 456 | + } | |
| 457 | + | |
| 458 | + return -EINVAL; | |
| 459 | +} | |
| 460 | + | |
| 461 | +int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |
| 462 | +{ | |
| 463 | + if (reg->id == KVM_REG_ARM_PSCI_VERSION) { | |
| 464 | + void __user *uaddr = (void __user *)(long)reg->addr; | |
| 465 | + bool wants_02; | |
| 466 | + u64 val; | |
| 467 | + | |
| 468 | + if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id))) | |
| 469 | + return -EFAULT; | |
| 470 | + | |
| 471 | + wants_02 = test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features); | |
| 472 | + | |
| 473 | + switch (val) { | |
| 474 | + case KVM_ARM_PSCI_0_1: | |
| 475 | + if (wants_02) | |
| 476 | + return -EINVAL; | |
| 477 | + vcpu->kvm->arch.psci_version = val; | |
| 478 | + return 0; | |
| 479 | + case KVM_ARM_PSCI_0_2: | |
| 480 | + case KVM_ARM_PSCI_1_0: | |
| 481 | + if (!wants_02) | |
| 482 | + return -EINVAL; | |
| 483 | + vcpu->kvm->arch.psci_version = val; | |
| 484 | + return 0; | |
| 485 | + } | |
| 486 | + } | |
| 487 | + | |
| 488 | + return -EINVAL; | |
| 489 | +} | |
| @@ -600,6 +600,7 @@ retry: · 599 unmodified lines | ||
| 600 | 600 | |
| 601 | 601 | list_for_each_entry_safe(irq, tmp, &vgic_cpu->ap_list_head, ap_list) { |
| 602 | 602 | struct kvm_vcpu *target_vcpu, *vcpuA, *vcpuB; |
| 603 | + bool target_vcpu_needs_kick = false; | |
| 603 | 604 | |
| 604 | 605 | spin_lock(&irq->irq_lock); |
| 605 | 606 | |
| @@ -670,11 +671,18 @@ retry: · 64 unmodified lines | ||
| 670 | 671 | list_del(&irq->ap_list); |
| 671 | 672 | irq->vcpu = target_vcpu; |
| 672 | 673 | list_add_tail(&irq->ap_list, &new_cpu->ap_list_head); |
| 674 | + target_vcpu_needs_kick = true; | |
| 673 | 675 | } |
| 674 | 676 | |
| 675 | 677 | spin_unlock(&irq->irq_lock); |
| 676 | 678 | spin_unlock(&vcpuB->arch.vgic_cpu.ap_list_lock); |
| 677 | 679 | spin_unlock_irqrestore(&vcpuA->arch.vgic_cpu.ap_list_lock, flags); |
| 680 | + | |
| 681 | + if (target_vcpu_needs_kick) { | |
| 682 | + kvm_make_request(KVM_REQ_IRQ_PENDING, target_vcpu); | |
| 683 | + kvm_vcpu_kick(target_vcpu); | |
| 684 | + } | |
| 685 | + | |
| 678 | 686 | goto retry; |
| 679 | 687 | } |
| 680 | 688 | |