linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: marc.zyngier@arm.com (Marc Zyngier)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 4/6] arm/arm64: KVM: Clarify KVM_ARM_VCPU_INIT ABI
Date: Mon, 08 Dec 2014 11:52:17 +0000	[thread overview]
Message-ID: <548590F1.8000306@arm.com> (raw)
In-Reply-To: <1417641522-29056-5-git-send-email-christoffer.dall@linaro.org>

On 03/12/14 21:18, Christoffer Dall wrote:
> It is not clear that this ioctl can be called multiple times for a given
> vcpu.  Userspace already does this, so clarify the ABI.
> 
> Also specify that userspace is expected to always make secondary and
> subsequent calls to the ioctl with the same parameters for the VCPU as
> the initial call (which userspace also already does).
> 
> Add code to check that userspace doesn't violate that ABI in the future,
> and move the kvm_vcpu_set_target() function which is currently
> duplicated between the 32-bit and 64-bit versions in guest.c to a common
> static function in arm.c, shared between both architectures.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
> ---
>  Documentation/virtual/kvm/api.txt |  5 +++++
>  arch/arm/include/asm/kvm_host.h   |  2 --
>  arch/arm/kvm/arm.c                | 43 +++++++++++++++++++++++++++++++++++++++
>  arch/arm/kvm/guest.c              | 25 -----------------------
>  arch/arm64/include/asm/kvm_host.h |  2 --
>  arch/arm64/kvm/guest.c            | 25 -----------------------
>  6 files changed, 48 insertions(+), 54 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
> index bb82a90..81f1b97 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -2453,6 +2453,11 @@ return ENOEXEC for that vcpu.
>  Note that because some registers reflect machine topology, all vcpus
>  should be created before this ioctl is invoked.
>  
> +Userspace can call this function multiple times for a given vcpu, including
> +after the vcpu has been run. This will reset the vcpu to its initial
> +state. All calls to this function after the initial call must use the same
> +target and same set of feature flags, otherwise EINVAL will be returned.
> +
>  Possible features:
>  	- KVM_ARM_VCPU_POWER_OFF: Starts the CPU in a power-off state.
>  	  Depends on KVM_CAP_ARM_PSCI.  If not set, the CPU will be powered on
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index 53036e2..254e065 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -150,8 +150,6 @@ struct kvm_vcpu_stat {
>  	u32 halt_wakeup;
>  };
>  
> -int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
> -			const struct kvm_vcpu_init *init);
>  int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init);
>  unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
>  int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 24c9ca4..4043769 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -263,6 +263,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
>  {
>  	/* Force users to call KVM_ARM_VCPU_INIT */
>  	vcpu->arch.target = -1;
> +	bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
>  
>  	/* Set up the timer */
>  	kvm_timer_vcpu_init(vcpu);
> @@ -649,6 +650,48 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level,
>  	return -EINVAL;
>  }
>  
> +static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
> +			       const struct kvm_vcpu_init *init)
> +{
> +	unsigned int i;
> +	int phys_target = kvm_target_cpu();
> +
> +	if (init->target != phys_target)
> +		return -EINVAL;
> +
> +	/*
> +	 * Secondary and subsequent calls to KVM_ARM_VCPU_INIT must
> +	 * use the same target.
> +	 */
> +	if (vcpu->arch.target != -1 && vcpu->arch.target != init->target)
> +		return -EINVAL;
> +
> +	/* -ENOENT for unknown features, -EINVAL for invalid combinations. */
> +	for (i = 0; i < sizeof(init->features) * 8; i++) {
> +		bool set = (init->features[i / 32] & (1 << (i % 32)));
> +
> +		if (set && i >= KVM_VCPU_MAX_FEATURES)
> +			return -ENOENT;
> +
> +		/*
> +		 * Secondary and subsequent calls to KVM_ARM_VCPU_INIT must
> +		 * use the same feature set.
> +		 */
> +		if (vcpu->arch.target != -1 && i < KVM_VCPU_MAX_FEATURES &&
> +		    test_bit(i, vcpu->arch.features) != set)
> +			return -EINVAL;
> +
> +		if (set)
> +			set_bit(i, vcpu->arch.features);
> +	}
> +
> +	vcpu->arch.target = phys_target;
> +
> +	/* Now we know what it is, we can reset it. */
> +	return kvm_reset_vcpu(vcpu);
> +}
> +
> +
>  static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
>  					 struct kvm_vcpu_init *init)
>  {
> diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
> index 8c97208..384bab6 100644
> --- a/arch/arm/kvm/guest.c
> +++ b/arch/arm/kvm/guest.c
> @@ -273,31 +273,6 @@ int __attribute_const__ kvm_target_cpu(void)
>  	}
>  }
>  
> -int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
> -			const struct kvm_vcpu_init *init)
> -{
> -	unsigned int i;
> -
> -	/* We can only cope with guest==host and only on A15/A7 (for now). */
> -	if (init->target != kvm_target_cpu())
> -		return -EINVAL;
> -
> -	vcpu->arch.target = init->target;
> -	bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
> -
> -	/* -ENOENT for unknown features, -EINVAL for invalid combinations. */
> -	for (i = 0; i < sizeof(init->features) * 8; i++) {
> -		if (test_bit(i, (void *)init->features)) {
> -			if (i >= KVM_VCPU_MAX_FEATURES)
> -				return -ENOENT;
> -			set_bit(i, vcpu->arch.features);
> -		}
> -	}
> -
> -	/* Now we know what it is, we can reset it. */
> -	return kvm_reset_vcpu(vcpu);
> -}
> -
>  int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init)
>  {
>  	int target = kvm_target_cpu();
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 2012c4b..65c6152 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -165,8 +165,6 @@ struct kvm_vcpu_stat {
>  	u32 halt_wakeup;
>  };
>  
> -int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
> -			const struct kvm_vcpu_init *init);
>  int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init);
>  unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
>  int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
> diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
> index 84d5959..9535bd5 100644
> --- a/arch/arm64/kvm/guest.c
> +++ b/arch/arm64/kvm/guest.c
> @@ -296,31 +296,6 @@ int __attribute_const__ kvm_target_cpu(void)
>  	return -EINVAL;
>  }
>  
> -int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
> -			const struct kvm_vcpu_init *init)
> -{
> -	unsigned int i;
> -	int phys_target = kvm_target_cpu();
> -
> -	if (init->target != phys_target)
> -		return -EINVAL;
> -
> -	vcpu->arch.target = phys_target;
> -	bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
> -
> -	/* -ENOENT for unknown features, -EINVAL for invalid combinations. */
> -	for (i = 0; i < sizeof(init->features) * 8; i++) {
> -		if (init->features[i / 32] & (1 << (i % 32))) {
> -			if (i >= KVM_VCPU_MAX_FEATURES)
> -				return -ENOENT;
> -			set_bit(i, vcpu->arch.features);
> -		}
> -	}
> -
> -	/* Now we know what it is, we can reset it. */
> -	return kvm_reset_vcpu(vcpu);
> -}
> -
>  int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init)
>  {
>  	int target = kvm_target_cpu();
> 

Very nice cleanup.

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

  reply	other threads:[~2014-12-08 11:52 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-03 21:18 [PATCH v2 0/6] Improve PSCI system events and fix reboot bugs Christoffer Dall
2014-12-03 21:18 ` [PATCH v2 1/6] arm/arm64: KVM: Don't clear the VCPU_POWER_OFF flag Christoffer Dall
2014-12-08 11:46   ` Marc Zyngier
2014-12-03 21:18 ` [PATCH v2 2/6] arm/arm64: KVM: Correct KVM_ARM_VCPU_INIT power off option Christoffer Dall
2014-12-08 11:47   ` Marc Zyngier
2014-12-03 21:18 ` [PATCH v2 3/6] arm/arm64: KVM: Reset the HCR on each vcpu when resetting the vcpu Christoffer Dall
2014-12-08 11:49   ` Marc Zyngier
2014-12-03 21:18 ` [PATCH v2 4/6] arm/arm64: KVM: Clarify KVM_ARM_VCPU_INIT ABI Christoffer Dall
2014-12-08 11:52   ` Marc Zyngier [this message]
2014-12-03 21:18 ` [PATCH v2 5/6] arm/arm64: KVM: Turn off vcpus on PSCI shutdown/reboot Christoffer Dall
2014-12-08 12:04   ` Marc Zyngier
2014-12-08 12:58     ` Christoffer Dall
2014-12-08 13:19       ` Marc Zyngier
2014-12-12 19:42         ` Christoffer Dall
2014-12-12 19:49         ` Christoffer Dall
2014-12-12 21:04           ` Marc Zyngier
2014-12-03 21:18 ` [PATCH v2 6/6] arm/arm64: KVM: Introduce stage2_unmap_vm Christoffer Dall
2014-12-08 12:08   ` Marc Zyngier
2014-12-05 17:24 ` [PATCH v2 0/6] Improve PSCI system events and fix reboot bugs Andrew Jones
2014-12-08 11:24 ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=548590F1.8000306@arm.com \
    --to=marc.zyngier@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).