On Mon, Feb 3, 2014 at 4:46 PM, Anup Patel <apatel@xxxxxxx> wrote: > Hi Mark, > > On Mon, Feb 3, 2014 at 4:24 PM, Mark Rutland <mark.rutland@xxxxxxx> wrote: >> On Thu, Jan 30, 2014 at 10:41:18AM +0000, Anup Patel wrote: >>> Currently, the in-kernel PSCI emulation provides PSCI v0.1 interface to >>> VCPUs. This patch extends current in-kernel PSCI emulation to provide >>> PSCI v0.2 interface to VCPUs. >>> >>> By default, ARM/ARM64 KVM will always provide PSCI v0.1 interface for >>> keeping the ABI backward-compatible. >>> >>> To select PSCI v0.2 interface for VCPUs, the user space (i.e. QEMU or >>> KVMTOOL) will have to set KVM_ARM_VCPU_PSCI_0_2 feature when doing VCPU >>> init using KVM_ARM_VCPU_INIT ioctl. >> >> I have an issue with this. PSCI 0.2 makes all but two functions (MIGRATE >> and MIGRATE_INFO_CPU_UP) mandatory, and hence not allowed to return >> NOT_SUPPORTED. >> >> Additionally, for correct behaviour across a kexec in future, we'll >> require AFFINITY_INFO for PSCI 0.2+ systems to determint when a CPU is >> actually dead (and cannot affect the cache hierarchy). I'd very much >> like to make that a hard requirement to ensure correctness. >> >> I would very much like to see at least trivial implementations of those >> mandatory functions, so that we don't need a >> KVM_ARM_VCPU_PSCI_REALLY_0_2 or similar in future. As it stands this >> series does not implement PSCI 0.2. > > The intention behind this series was to provide a base implementation of > PSCI v0.2 which can be extended by subsequent patches that implement > other PSCI v0.2 functions. > > I already have a patch series that implement PSCI v0.2 SYSTEM_OFF and > SYSTEM_RESET based on this series. > > Regards, > Anup > >> >> Thanks, >> Mark. >> >>> >>> Signed-off-by: Anup Patel <anup.patel@xxxxxxxxxx> >>> Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@xxxxxxxxxx> >>> --- >>> arch/arm/include/asm/kvm_host.h | 2 +- >>> arch/arm/include/asm/kvm_psci.h | 4 ++ >>> arch/arm/include/uapi/asm/kvm.h | 35 ++++++++++++++- >>> arch/arm/kvm/arm.c | 1 + >>> arch/arm/kvm/psci.c | 85 +++++++++++++++++++++++++++++++------ >>> arch/arm64/include/asm/kvm_host.h | 2 +- >>> arch/arm64/include/asm/kvm_psci.h | 4 ++ >>> arch/arm64/include/uapi/asm/kvm.h | 35 ++++++++++++++- >>> 8 files changed, 152 insertions(+), 16 deletions(-) >>> >>> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h >>> index bce6d32..dc4e3ed 100644 >>> --- a/arch/arm/include/asm/kvm_host.h >>> +++ b/arch/arm/include/asm/kvm_host.h >>> @@ -36,7 +36,7 @@ >>> #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 >>> #define KVM_HAVE_ONE_REG >>> >>> -#define KVM_VCPU_MAX_FEATURES 1 >>> +#define KVM_VCPU_MAX_FEATURES 2 >>> >>> #include <kvm/arm_vgic.h> >>> >>> diff --git a/arch/arm/include/asm/kvm_psci.h b/arch/arm/include/asm/kvm_psci.h >>> index 9a83d98..4c0e3e1 100644 >>> --- a/arch/arm/include/asm/kvm_psci.h >>> +++ b/arch/arm/include/asm/kvm_psci.h >>> @@ -18,6 +18,10 @@ >>> #ifndef __ARM_KVM_PSCI_H__ >>> #define __ARM_KVM_PSCI_H__ >>> >>> +#define KVM_ARM_PSCI_0_1 1 >>> +#define KVM_ARM_PSCI_0_2 2 >>> + >>> +int kvm_psci_version(struct kvm_vcpu *vcpu); >>> bool kvm_psci_call(struct kvm_vcpu *vcpu); >>> >>> #endif /* __ARM_KVM_PSCI_H__ */ >>> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h >>> index c498b60..bf860e2 100644 >>> --- a/arch/arm/include/uapi/asm/kvm.h >>> +++ b/arch/arm/include/uapi/asm/kvm.h >>> @@ -83,6 +83,7 @@ struct kvm_regs { >>> #define KVM_VGIC_V2_CPU_SIZE 0x2000 >>> >>> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */ >>> +#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */ >>> >>> struct kvm_vcpu_init { >>> __u32 target; >>> @@ -164,7 +165,7 @@ struct kvm_arch_memory_slot { >>> /* Highest supported SPI, from VGIC_NR_IRQS */ >>> #define KVM_ARM_IRQ_GIC_MAX 127 >>> >>> -/* PSCI interface */ >>> +/* PSCI v0.1 interface */ >>> #define KVM_PSCI_FN_BASE 0x95c1ba5e >>> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n)) >>> >>> @@ -173,9 +174,41 @@ struct kvm_arch_memory_slot { >>> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2) >>> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3) >>> >>> +/* PSCI v0.2 interface */ >>> +#define KVM_PSCI_0_2_FN_BASE 0x84000000 >>> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n)) >>> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000 >>> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n)) >>> + >>> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0) >>> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1) >>> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2) >>> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3) >>> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4) >>> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5) >>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \ >>> + KVM_PSCI_0_2_FN(6) >>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \ >>> + KVM_PSCI_0_2_FN(7) >>> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8) >>> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9) >>> + >>> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1) >>> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3) >>> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4) >>> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5) >>> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \ >>> + KVM_PSCI_0_2_FN64(7) >>> + >>> +/* PSCI return values */ >>> #define KVM_PSCI_RET_SUCCESS 0 >>> #define KVM_PSCI_RET_NI ((unsigned long)-1) >>> #define KVM_PSCI_RET_INVAL ((unsigned long)-2) >>> #define KVM_PSCI_RET_DENIED ((unsigned long)-3) >>> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4) >>> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5) >>> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6) >>> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7) >>> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8) >>> >>> #endif /* __ARM_KVM_H__ */ >>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c >>> index 151eb91..e508125 100644 >>> --- a/arch/arm/kvm/arm.c >>> +++ b/arch/arm/kvm/arm.c >>> @@ -193,6 +193,7 @@ int kvm_dev_ioctl_check_extension(long ext) >>> case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: >>> case KVM_CAP_ONE_REG: >>> case KVM_CAP_ARM_PSCI: >>> + case KVM_CAP_ARM_PSCI_0_2: >>> r = 1; >>> break; >>> case KVM_CAP_COALESCED_MMIO: >>> diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c >>> index 448f60e..7fdc881 100644 >>> --- a/arch/arm/kvm/psci.c >>> +++ b/arch/arm/kvm/psci.c >>> @@ -85,17 +85,57 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu) >>> return KVM_PSCI_RET_SUCCESS; >>> } >>> >>> -/** >>> - * kvm_psci_call - handle PSCI call if r0 value is in range >>> - * @vcpu: Pointer to the VCPU struct >>> - * >>> - * Handle PSCI calls from guests through traps from HVC instructions. >>> - * The calling convention is similar to SMC calls to the secure world where >>> - * the function number is placed in r0 and this function returns true if the >>> - * function number specified in r0 is withing the PSCI range, and false >>> - * otherwise. >>> - */ >>> -bool kvm_psci_call(struct kvm_vcpu *vcpu) >>> +int kvm_psci_version(struct kvm_vcpu *vcpu) >>> +{ >>> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features)) >>> + return KVM_ARM_PSCI_0_2; >>> + >>> + return KVM_ARM_PSCI_0_1; >>> +} >>> + >>> +static bool kvm_psci_0_2_call(struct kvm_vcpu *vcpu) >>> +{ >>> + unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0); >>> + unsigned long val; >>> + >>> + switch (psci_fn) { >>> + case KVM_PSCI_0_2_FN_PSCI_VERSION: >>> + /* >>> + * Bits[31:16] = Major Version = 0 >>> + * Bits[15:0] = Minor Version = 2 >>> + */ >>> + val = 2; >>> + break; >>> + case KVM_PSCI_0_2_FN_CPU_OFF: >>> + kvm_psci_vcpu_off(vcpu); >>> + val = KVM_PSCI_RET_SUCCESS; >>> + break; >>> + case KVM_PSCI_0_2_FN_CPU_ON: >>> + case KVM_PSCI_0_2_FN64_CPU_ON: >>> + val = kvm_psci_vcpu_on(vcpu); >>> + break; >>> + case KVM_PSCI_0_2_FN_CPU_SUSPEND: >>> + case KVM_PSCI_0_2_FN_AFFINITY_INFO: >>> + case KVM_PSCI_0_2_FN_MIGRATE: >>> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE: >>> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU: >>> + case KVM_PSCI_0_2_FN_SYSTEM_OFF: >>> + case KVM_PSCI_0_2_FN_SYSTEM_RESET: >>> + case KVM_PSCI_0_2_FN64_CPU_SUSPEND: >>> + case KVM_PSCI_0_2_FN64_AFFINITY_INFO: >>> + case KVM_PSCI_0_2_FN64_MIGRATE: >>> + case KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU: >>> + val = KVM_PSCI_RET_NI; >>> + break; >>> + default: >>> + return false; >>> + } >>> + >>> + *vcpu_reg(vcpu, 0) = val; >>> + return true; >>> +} >>> + >>> +static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu) >>> { >>> unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0); >>> unsigned long val; >>> @@ -112,7 +152,6 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu) >>> case KVM_PSCI_FN_MIGRATE: >>> val = KVM_PSCI_RET_NI; >>> break; >>> - >>> default: >>> return false; >>> } >>> @@ -120,3 +159,25 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu) >>> *vcpu_reg(vcpu, 0) = val; >>> return true; >>> } >>> + >>> +/** >>> + * kvm_psci_call - handle PSCI call if r0 value is in range >>> + * @vcpu: Pointer to the VCPU struct >>> + * >>> + * Handle PSCI calls from guests through traps from HVC instructions. >>> + * The calling convention is similar to SMC calls to the secure world where >>> + * the function number is placed in r0 and this function returns true if the >>> + * function number specified in r0 is withing the PSCI range, and false >>> + * otherwise. >>> + */ >>> +bool kvm_psci_call(struct kvm_vcpu *vcpu) >>> +{ >>> + switch (kvm_psci_version(vcpu)) { >>> + case KVM_ARM_PSCI_0_2: >>> + return kvm_psci_0_2_call(vcpu); >>> + case KVM_ARM_PSCI_0_1: >>> + return kvm_psci_0_1_call(vcpu); >>> + default: >>> + return false; >>> + }; >>> +} >>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h >>> index 0a1d697..92242ce 100644 >>> --- a/arch/arm64/include/asm/kvm_host.h >>> +++ b/arch/arm64/include/asm/kvm_host.h >>> @@ -39,7 +39,7 @@ >>> #include <kvm/arm_vgic.h> >>> #include <kvm/arm_arch_timer.h> >>> >>> -#define KVM_VCPU_MAX_FEATURES 2 >>> +#define KVM_VCPU_MAX_FEATURES 3 >>> >>> struct kvm_vcpu; >>> int kvm_target_cpu(void); >>> diff --git a/arch/arm64/include/asm/kvm_psci.h b/arch/arm64/include/asm/kvm_psci.h >>> index e301a48..e25c658 100644 >>> --- a/arch/arm64/include/asm/kvm_psci.h >>> +++ b/arch/arm64/include/asm/kvm_psci.h >>> @@ -18,6 +18,10 @@ >>> #ifndef __ARM64_KVM_PSCI_H__ >>> #define __ARM64_KVM_PSCI_H__ >>> >>> +#define KVM_ARM_PSCI_0_1 1 >>> +#define KVM_ARM_PSCI_0_2 2 >>> + >>> +int kvm_psci_version(struct kvm_vcpu *vcpu); >>> bool kvm_psci_call(struct kvm_vcpu *vcpu); >>> >>> #endif /* __ARM64_KVM_PSCI_H__ */ >>> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h >>> index d9f026b..b7555d3 100644 >>> --- a/arch/arm64/include/uapi/asm/kvm.h >>> +++ b/arch/arm64/include/uapi/asm/kvm.h >>> @@ -77,6 +77,7 @@ struct kvm_regs { >>> >>> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */ >>> #define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */ >>> +#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */ >>> >>> struct kvm_vcpu_init { >>> __u32 target; >>> @@ -150,7 +151,7 @@ struct kvm_arch_memory_slot { >>> /* Highest supported SPI, from VGIC_NR_IRQS */ >>> #define KVM_ARM_IRQ_GIC_MAX 127 >>> >>> -/* PSCI interface */ >>> +/* PSCI v0.1 interface */ >>> #define KVM_PSCI_FN_BASE 0x95c1ba5e >>> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n)) >>> >>> @@ -159,10 +160,42 @@ struct kvm_arch_memory_slot { >>> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2) >>> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3) >>> >>> +/* PSCI v0.2 interface */ >>> +#define KVM_PSCI_0_2_FN_BASE 0x84000000 >>> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n)) >>> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000 >>> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n)) >>> + >>> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0) >>> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1) >>> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2) >>> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3) >>> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4) >>> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5) >>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \ >>> + KVM_PSCI_0_2_FN(6) >>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \ >>> + KVM_PSCI_0_2_FN(7) >>> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8) >>> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9) >>> + >>> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1) >>> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3) >>> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4) >>> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5) >>> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \ >>> + KVM_PSCI_0_2_FN64(7) >>> + >>> +/* PSCI return values */ >>> #define KVM_PSCI_RET_SUCCESS 0 >>> #define KVM_PSCI_RET_NI ((unsigned long)-1) >>> #define KVM_PSCI_RET_INVAL ((unsigned long)-2) >>> #define KVM_PSCI_RET_DENIED ((unsigned long)-3) >>> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4) >>> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5) >>> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6) >>> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7) >>> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8) >>> >>> #endif >>> >>> -- >>> 1.7.9.5 >>> >>> >> CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, >> is for the sole use of the intended recipient(s) and contains information >> that is confidential and proprietary to Applied Micro Circuits Corporation or its subsidiaries. >> It is to be used solely for the purpose of furthering the parties' business relationship. >> All unauthorized review, use, disclosure or distribution is prohibited. >> If you are not the intended recipient, please contact the sender by reply e-mail >> and destroy all copies of the original message. >> I accidentally used wrong email-id for my last reply. Please ignore this confidentiality notice. Sorry for the noise. Regards, Anup > _______________________________________________ > kvmarm mailing list > kvmarm@xxxxxxxxxxxxxxxxxxxxx > https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm