aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/virtual/kvm/api.txt9
-rw-r--r--Documentation/virtual/kvm/arm/psci.txt30
-rw-r--r--MAINTAINERS4
-rw-r--r--arch/arm/include/asm/kvm_host.h3
-rw-r--r--arch/arm/include/uapi/asm/kvm.h6
-rw-r--r--arch/arm/kvm/guest.c13
-rw-r--r--arch/arm64/include/asm/kvm_host.h3
-rw-r--r--arch/arm64/include/uapi/asm/kvm.h6
-rw-r--r--arch/arm64/kvm/guest.c14
-rw-r--r--arch/arm64/kvm/sys_regs.c6
-rw-r--r--arch/x86/kvm/vmx.c14
-rw-r--r--arch/x86/kvm/x86.h7
-rw-r--r--include/kvm/arm_psci.h16
-rw-r--r--include/uapi/linux/kvm.h7
-rw-r--r--virt/kvm/arm/arm.c15
-rw-r--r--virt/kvm/arm/psci.c60
-rw-r--r--virt/kvm/arm/vgic/vgic.c8
17 files changed, 189 insertions, 32 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 1c7958b57fe9..758bf403a169 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1960,6 +1960,9 @@ ARM 32-bit VFP control registers have the following id bit patterns:
1960ARM 64-bit FP registers have the following id bit patterns: 1960ARM 64-bit FP registers have the following id bit patterns:
1961 0x4030 0000 0012 0 <regno:12> 1961 0x4030 0000 0012 0 <regno:12>
1962 1962
1963ARM firmware pseudo-registers have the following bit pattern:
1964 0x4030 0000 0014 <regno:16>
1965
1963 1966
1964arm64 registers are mapped using the lower 32 bits. The upper 16 of 1967arm64 registers are mapped using the lower 32 bits. The upper 16 of
1965that is the register group type, or coprocessor number: 1968that is the register group type, or coprocessor number:
@@ -1976,6 +1979,9 @@ arm64 CCSIDR registers are demultiplexed by CSSELR value:
1976arm64 system registers have the following id bit patterns: 1979arm64 system registers have the following id bit patterns:
1977 0x6030 0000 0013 <op0:2> <op1:3> <crn:4> <crm:4> <op2:3> 1980 0x6030 0000 0013 <op0:2> <op1:3> <crn:4> <crm:4> <op2:3>
1978 1981
1982arm64 firmware pseudo-registers have the following bit pattern:
1983 0x6030 0000 0014 <regno:16>
1984
1979 1985
1980MIPS registers are mapped using the lower 32 bits. The upper 16 of that is 1986MIPS registers are mapped using the lower 32 bits. The upper 16 of that is
1981the register group type: 1987the register group type:
@@ -2510,7 +2516,8 @@ Possible features:
2510 and execute guest code when KVM_RUN is called. 2516 and execute guest code when KVM_RUN is called.
2511 - KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode. 2517 - KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode.
2512 Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only). 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 Depends on KVM_CAP_ARM_PSCI_0_2. 2521 Depends on KVM_CAP_ARM_PSCI_0_2.
2515 - KVM_ARM_VCPU_PMU_V3: Emulate PMUv3 for the CPU. 2522 - KVM_ARM_VCPU_PMU_V3: Emulate PMUv3 for the CPU.
2516 Depends on KVM_CAP_ARM_PMU_V3. 2523 Depends on KVM_CAP_ARM_PMU_V3.
diff --git a/Documentation/virtual/kvm/arm/psci.txt b/Documentation/virtual/kvm/arm/psci.txt
new file mode 100644
index 000000000000..aafdab887b04
--- /dev/null
+++ b/Documentation/virtual/kvm/arm/psci.txt
@@ -0,0 +1,30 @@
1KVM implements the PSCI (Power State Coordination Interface)
2specification in order to provide services such as CPU on/off, reset
3and power-off to the guest.
4
5The PSCI specification is regularly updated to provide new features,
6and KVM implements these updates if they make sense from a virtualization
7point of view.
8
9This means that a guest booted on two different versions of KVM can
10observe two different "firmware" revisions. This could cause issues if
11a given guest is tied to a particular PSCI revision (unlikely), or if
12a migration causes a different PSCI version to be exposed out of the
13blue to an unsuspecting guest.
14
15In order to remedy this situation, KVM exposes a set of "firmware
16pseudo-registers" that can be manipulated using the GET/SET_ONE_REG
17interface. These registers can be saved/restored by userspace, and set
18to a convenient value if required.
19
20The 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)
diff --git a/MAINTAINERS b/MAINTAINERS
index 3e41e12a88a4..db2bc3fe0ba4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7744,7 +7744,7 @@ F: arch/x86/include/asm/svm.h
7744F: arch/x86/kvm/svm.c 7744F: arch/x86/kvm/svm.c
7745 7745
7746KERNEL VIRTUAL MACHINE FOR ARM (KVM/arm) 7746KERNEL VIRTUAL MACHINE FOR ARM (KVM/arm)
7747M: Christoffer Dall <christoffer.dall@linaro.org> 7747M: Christoffer Dall <christoffer.dall@arm.com>
7748M: Marc Zyngier <marc.zyngier@arm.com> 7748M: Marc Zyngier <marc.zyngier@arm.com>
7749L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 7749L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
7750L: kvmarm@lists.cs.columbia.edu 7750L: kvmarm@lists.cs.columbia.edu
@@ -7758,7 +7758,7 @@ F: virt/kvm/arm/
7758F: include/kvm/arm_* 7758F: include/kvm/arm_*
7759 7759
7760KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) 7760KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64)
7761M: Christoffer Dall <christoffer.dall@linaro.org> 7761M: Christoffer Dall <christoffer.dall@arm.com>
7762M: Marc Zyngier <marc.zyngier@arm.com> 7762M: Marc Zyngier <marc.zyngier@arm.com>
7763L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 7763L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
7764L: kvmarm@lists.cs.columbia.edu 7764L: kvmarm@lists.cs.columbia.edu
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index c6a749568dd6..c7c28c885a19 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -77,6 +77,9 @@ struct kvm_arch {
77 /* Interrupt controller */ 77 /* Interrupt controller */
78 struct vgic_dist vgic; 78 struct vgic_dist vgic;
79 int max_vcpus; 79 int max_vcpus;
80
81 /* Mandated version of PSCI */
82 u32 psci_version;
80}; 83};
81 84
82#define KVM_NR_MEM_OBJS 40 85#define KVM_NR_MEM_OBJS 40
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index 2ba95d6fe852..caae4843cb70 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -195,6 +195,12 @@ struct kvm_arch_memory_slot {
195#define KVM_REG_ARM_VFP_FPINST 0x1009 195#define KVM_REG_ARM_VFP_FPINST 0x1009
196#define KVM_REG_ARM_VFP_FPINST2 0x100A 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/* Device Control API: ARM VGIC */ 204/* Device Control API: ARM VGIC */
199#define KVM_DEV_ARM_VGIC_GRP_ADDR 0 205#define KVM_DEV_ARM_VGIC_GRP_ADDR 0
200#define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 206#define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
index 1e0784ebbfd6..a18f33edc471 100644
--- a/arch/arm/kvm/guest.c
+++ b/arch/arm/kvm/guest.c
@@ -22,6 +22,7 @@
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/vmalloc.h> 23#include <linux/vmalloc.h>
24#include <linux/fs.h> 24#include <linux/fs.h>
25#include <kvm/arm_psci.h>
25#include <asm/cputype.h> 26#include <asm/cputype.h>
26#include <linux/uaccess.h> 27#include <linux/uaccess.h>
27#include <asm/kvm.h> 28#include <asm/kvm.h>
@@ -176,6 +177,7 @@ static unsigned long num_core_regs(void)
176unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) 177unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
177{ 178{
178 return num_core_regs() + kvm_arm_num_coproc_regs(vcpu) 179 return num_core_regs() + kvm_arm_num_coproc_regs(vcpu)
180 + kvm_arm_get_fw_num_regs(vcpu)
179 + NUM_TIMER_REGS; 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)
196 uindices++; 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 ret = copy_timer_indices(vcpu, uindices); 206 ret = copy_timer_indices(vcpu, uindices);
200 if (ret) 207 if (ret)
201 return ret; 208 return ret;
@@ -214,6 +221,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
214 if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) 221 if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
215 return get_core_reg(vcpu, reg); 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 if (is_timer_reg(reg->id)) 227 if (is_timer_reg(reg->id))
218 return get_timer_reg(vcpu, reg); 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)
230 if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) 240 if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
231 return set_core_reg(vcpu, reg); 241 return set_core_reg(vcpu, reg);
232 242
243 if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW)