kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alexander Graf <graf@amazon.com>
To: Anup Patel <Anup.Patel@wdc.com>,
	Palmer Dabbelt <palmer@sifive.com>,
	"Paul Walmsley" <paul.walmsley@sifive.com>,
	Paolo Bonzini <pbonzini@redhat.com>, Radim K <rkrcmar@redhat.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Atish Patra <Atish.Patra@wdc.com>,
	Alistair Francis <Alistair.Francis@wdc.com>,
	Damien Le Moal <Damien.LeMoal@wdc.com>,
	"Christoph Hellwig" <hch@infradead.org>,
	Anup Patel <anup@brainfault.org>,
	"kvm@vger.kernel.org" <kvm@vger.kernel.org>,
	"linux-riscv@lists.infradead.org"
	<linux-riscv@lists.infradead.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v5 15/20] RISC-V: KVM: Add timer functionality
Date: Fri, 23 Aug 2019 09:52:42 +0200	[thread overview]
Message-ID: <09d74212-4fa3-d64c-5a63-d556e955b88c@amazon.com> (raw)
In-Reply-To: <20190822084131.114764-16-anup.patel@wdc.com>

On 22.08.19 10:46, Anup Patel wrote:
> From: Atish Patra <atish.patra@wdc.com>
> 
> The RISC-V hypervisor specification doesn't have any virtual timer
> feature.
> 
> Due to this, the guest VCPU timer will be programmed via SBI calls.
> The host will use a separate hrtimer event for each guest VCPU to
> provide timer functionality. We inject a virtual timer interrupt to
> the guest VCPU whenever the guest VCPU hrtimer event expires.
> 
> The following features are not supported yet and will be added in
> future:
> 1. A time offset to adjust guest time from host time
> 2. A saved next event in guest vcpu for vm migration

Implementing these 2 bits right now should be trivial. Why wait?

> 
> Signed-off-by: Atish Patra <atish.patra@wdc.com>
> Signed-off-by: Anup Patel <anup.patel@wdc.com>
> Acked-by: Paolo Bonzini <pbonzini@redhat.com>
> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   arch/riscv/include/asm/kvm_host.h       |   4 +
>   arch/riscv/include/asm/kvm_vcpu_timer.h |  32 +++++++
>   arch/riscv/kvm/Makefile                 |   2 +-
>   arch/riscv/kvm/vcpu.c                   |   6 ++
>   arch/riscv/kvm/vcpu_timer.c             | 106 ++++++++++++++++++++++++
>   drivers/clocksource/timer-riscv.c       |   8 ++
>   include/clocksource/timer-riscv.h       |  16 ++++
>   7 files changed, 173 insertions(+), 1 deletion(-)
>   create mode 100644 arch/riscv/include/asm/kvm_vcpu_timer.h
>   create mode 100644 arch/riscv/kvm/vcpu_timer.c
>   create mode 100644 include/clocksource/timer-riscv.h
> 
> diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
> index ab33e59a3d88..d2a2e45eefc0 100644
> --- a/arch/riscv/include/asm/kvm_host.h
> +++ b/arch/riscv/include/asm/kvm_host.h
> @@ -12,6 +12,7 @@
>   #include <linux/types.h>
>   #include <linux/kvm.h>
>   #include <linux/kvm_types.h>
> +#include <asm/kvm_vcpu_timer.h>
>   
>   #ifdef CONFIG_64BIT
>   #define KVM_MAX_VCPUS			(1U << 16)
> @@ -167,6 +168,9 @@ struct kvm_vcpu_arch {
>   	unsigned long irqs_pending;
>   	unsigned long irqs_pending_mask;
>   
> +	/* VCPU Timer */
> +	struct kvm_vcpu_timer timer;
> +
>   	/* MMIO instruction details */
>   	struct kvm_mmio_decode mmio_decode;
>   
> diff --git a/arch/riscv/include/asm/kvm_vcpu_timer.h b/arch/riscv/include/asm/kvm_vcpu_timer.h
> new file mode 100644
> index 000000000000..df67ea86988e
> --- /dev/null
> +++ b/arch/riscv/include/asm/kvm_vcpu_timer.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (C) 2019 Western Digital Corporation or its affiliates.
> + *
> + * Authors:
> + *	Atish Patra <atish.patra@wdc.com>
> + */
> +
> +#ifndef __KVM_VCPU_RISCV_TIMER_H
> +#define __KVM_VCPU_RISCV_TIMER_H
> +
> +#include <linux/hrtimer.h>
> +
> +#define VCPU_TIMER_PROGRAM_THRESHOLD_NS		1000
> +
> +struct kvm_vcpu_timer {
> +	bool init_done;
> +	/* Check if the timer is programmed */
> +	bool is_set;
> +	struct hrtimer hrt;
> +	/* Mult & Shift values to get nanosec from cycles */
> +	u32 mult;
> +	u32 shift;
> +};
> +
> +int kvm_riscv_vcpu_timer_init(struct kvm_vcpu *vcpu);
> +int kvm_riscv_vcpu_timer_deinit(struct kvm_vcpu *vcpu);
> +int kvm_riscv_vcpu_timer_reset(struct kvm_vcpu *vcpu);
> +int kvm_riscv_vcpu_timer_next_event(struct kvm_vcpu *vcpu,
> +				    unsigned long ncycles);

This function never gets called?

> +
> +#endif
> diff --git a/arch/riscv/kvm/Makefile b/arch/riscv/kvm/Makefile
> index c0f57f26c13d..3e0c7558320d 100644
> --- a/arch/riscv/kvm/Makefile
> +++ b/arch/riscv/kvm/Makefile
> @@ -9,6 +9,6 @@ ccflags-y := -Ivirt/kvm -Iarch/riscv/kvm
>   kvm-objs := $(common-objs-y)
>   
>   kvm-objs += main.o vm.o vmid.o tlb.o mmu.o
> -kvm-objs += vcpu.o vcpu_exit.o vcpu_switch.o
> +kvm-objs += vcpu.o vcpu_exit.o vcpu_switch.o vcpu_timer.o
>   
>   obj-$(CONFIG_KVM)	+= kvm.o
> diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
> index 6124077d154f..018fca436776 100644
> --- a/arch/riscv/kvm/vcpu.c
> +++ b/arch/riscv/kvm/vcpu.c
> @@ -54,6 +54,8 @@ static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu)
>   
>   	memcpy(cntx, reset_cntx, sizeof(*cntx));
>   
> +	kvm_riscv_vcpu_timer_reset(vcpu);
> +
>   	WRITE_ONCE(vcpu->arch.irqs_pending, 0);
>   	WRITE_ONCE(vcpu->arch.irqs_pending_mask, 0);
>   }
> @@ -108,6 +110,9 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
>   	cntx->hstatus |= HSTATUS_SP2P;
>   	cntx->hstatus |= HSTATUS_SPV;
>   
> +	/* Setup VCPU timer */
> +	kvm_riscv_vcpu_timer_init(vcpu);
> +
>   	/* Reset VCPU */
>   	kvm_riscv_reset_vcpu(vcpu);
>   
> @@ -116,6 +121,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
>   
>   void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
>   {
> +	kvm_riscv_vcpu_timer_deinit(vcpu);
>   	kvm_riscv_stage2_flush_cache(vcpu);
>   	kmem_cache_free(kvm_vcpu_cache, vcpu);
>   }
> diff --git a/arch/riscv/kvm/vcpu_timer.c b/arch/riscv/kvm/vcpu_timer.c
> new file mode 100644
> index 000000000000..a45ca06e1aa6
> --- /dev/null
> +++ b/arch/riscv/kvm/vcpu_timer.c
> @@ -0,0 +1,106 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2019 Western Digital Corporation or its affiliates.
> + *
> + * Authors:
> + *     Atish Patra <atish.patra@wdc.com>
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/err.h>
> +#include <linux/kvm_host.h>
> +#include <clocksource/timer-riscv.h>
> +#include <asm/csr.h>
> +#include <asm/kvm_vcpu_timer.h>
> +
> +static enum hrtimer_restart kvm_riscv_vcpu_hrtimer_expired(struct hrtimer *h)
> +{
> +	struct kvm_vcpu_timer *t = container_of(h, struct kvm_vcpu_timer, hrt);
> +	struct kvm_vcpu *vcpu = container_of(t, struct kvm_vcpu, arch.timer);
> +
> +	t->is_set = false;
> +	kvm_riscv_vcpu_set_interrupt(vcpu, IRQ_S_TIMER);
> +
> +	return HRTIMER_NORESTART;
> +}
> +
> +static u64 kvm_riscv_delta_cycles2ns(u64 cycles, struct kvm_vcpu_timer *t)
> +{
> +	unsigned long flags;
> +	u64 cycles_now, cycles_delta, delta_ns;
> +
> +	local_irq_save(flags);
> +	cycles_now = get_cycles64();
> +	if (cycles_now < cycles)
> +		cycles_delta = cycles - cycles_now;
> +	else
> +		cycles_delta = 0;
> +	delta_ns = (cycles_delta * t->mult) >> t->shift;
> +	local_irq_restore(flags);
> +
> +	return delta_ns;
> +}
> +
> +static int kvm_riscv_vcpu_timer_cancel(struct kvm_vcpu_timer *t)
> +{
> +	if (!t->init_done || !t->is_set)
> +		return -EINVAL;
> +
> +	hrtimer_cancel(&t->hrt);
> +	t->is_set = false;
> +
> +	return 0;
> +}
> +
> +int kvm_riscv_vcpu_timer_next_event(struct kvm_vcpu *vcpu,
> +				    unsigned long ncycles)
> +{
> +	struct kvm_vcpu_timer *t = &vcpu->arch.timer;
> +	u64 delta_ns = kvm_riscv_delta_cycles2ns(ncycles, t);

... in fact, I feel like I'm missing something obvious here. How does 
the guest trigger the timer event? What is the argument it uses for that 
and how does that play with the tbfreq in the earlier patch?


Alex


  reply	other threads:[~2019-08-23  7:53 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-22  8:42 [PATCH v5 00/20] KVM RISC-V Support Anup Patel
2019-08-22  8:42 ` [PATCH v5 01/20] KVM: RISC-V: Add KVM_REG_RISCV for ONE_REG interface Anup Patel
2019-08-22  8:42 ` [PATCH v5 02/20] RISC-V: Add bitmap reprensenting ISA features common across CPUs Anup Patel
2019-08-22  8:43 ` [PATCH v5 03/20] RISC-V: Export few kernel symbols Anup Patel
2019-08-22  8:43 ` [PATCH v5 04/20] RISC-V: Add hypervisor extension related CSR defines Anup Patel
2019-08-22  8:43 ` [PATCH v5 05/20] RISC-V: Add initial skeletal KVM support Anup Patel
2019-08-22  8:43 ` [PATCH v5 06/20] RISC-V: KVM: Implement VCPU create, init and destroy functions Anup Patel
2019-08-22  8:44 ` [PATCH v5 07/20] RISC-V: KVM: Implement VCPU interrupts and requests handling Anup Patel
2019-08-22  8:44 ` [PATCH v5 08/20] RISC-V: KVM: Implement KVM_GET_ONE_REG/KVM_SET_ONE_REG ioctls Anup Patel
2019-08-22 12:01   ` Alexander Graf
2019-08-22 14:00     ` Anup Patel
2019-08-22 14:12       ` Alexander Graf
2019-08-23 11:20         ` Anup Patel
2019-08-23 11:42           ` Graf (AWS), Alexander
2019-08-22 14:05     ` Anup Patel
2019-08-22  8:44 ` [PATCH v5 09/20] RISC-V: KVM: Implement VCPU world-switch Anup Patel
2019-08-22  8:44 ` [PATCH v5 10/20] RISC-V: KVM: Handle MMIO exits for VCPU Anup Patel
2019-08-22 12:10   ` Alexander Graf
2019-08-22 12:21     ` Andrew Jones
2019-08-22 12:27     ` Anup Patel
2019-08-22 12:14   ` Alexander Graf
2019-08-22 12:33     ` Anup Patel
2019-08-22 13:25       ` Alexander Graf
2019-08-22 13:55         ` Anup Patel
2019-08-22  8:45 ` [PATCH v5 11/20] RISC-V: KVM: Handle WFI " Anup Patel
2019-08-22 12:19   ` Alexander Graf
2019-08-22 12:50     ` Anup Patel
2019-08-22  8:45 ` [PATCH v5 12/20] RISC-V: KVM: Implement VMID allocator Anup Patel
2019-08-22  8:45 ` [PATCH v5 13/20] RISC-V: KVM: Implement stage2 page table programming Anup Patel
2019-08-22 12:28   ` Alexander Graf
2019-08-22 12:38     ` Anup Patel
2019-08-22 13:27       ` Alexander Graf
2019-08-22 13:58         ` Anup Patel
2019-08-22 14:09           ` Alexander Graf
2019-08-23 11:21             ` Anup Patel
2019-08-22  8:45 ` [PATCH v5 14/20] RISC-V: KVM: Implement MMU notifiers Anup Patel
2019-08-22  8:46 ` [PATCH v5 15/20] RISC-V: KVM: Add timer functionality Anup Patel
2019-08-23  7:52   ` Alexander Graf [this message]
2019-08-23 11:04     ` Anup Patel
2019-08-23 11:33       ` Graf (AWS), Alexander
2019-08-23 11:46         ` Anup Patel
2019-08-23 11:49           ` Alexander Graf
2019-08-23 12:11             ` Anup Patel
2019-08-23 12:25               ` Alexander Graf
2019-08-22  8:46 ` [PATCH v5 16/20] RISC-V: KVM: FP lazy save/restore Anup Patel
2019-08-22  8:46 ` [PATCH v5 17/20] RISC-V: KVM: Implement ONE REG interface for FP registers Anup Patel
2019-08-22  8:46 ` [PATCH v5 18/20] RISC-V: KVM: Add SBI v0.1 support Anup Patel
2019-08-23  8:04   ` Alexander Graf
2019-08-23 11:17     ` Anup Patel
2019-08-23 11:38       ` Graf (AWS), Alexander
2019-08-23 12:00         ` Anup Patel
2019-08-23 12:19           ` Alexander Graf
2019-08-23 12:28             ` Anup Patel
2019-08-22  8:47 ` [PATCH v5 19/20] RISC-V: Enable VIRTIO drivers in RV64 and RV32 defconfig Anup Patel
2019-08-22  8:47 ` [PATCH v5 20/20] RISC-V: KVM: Add MAINTAINERS entry Anup Patel
2019-08-23  8:08 ` [PATCH v5 00/20] KVM RISC-V Support Alexander Graf
2019-08-23 11:25   ` Anup Patel
2019-08-23 11:44     ` Graf (AWS), Alexander
2019-08-23 12:10       ` Paolo Bonzini
2019-08-23 12:19         ` Anup Patel
2019-08-23 12:28           ` Alexander Graf

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=09d74212-4fa3-d64c-5a63-d556e955b88c@amazon.com \
    --to=graf@amazon.com \
    --cc=Alistair.Francis@wdc.com \
    --cc=Anup.Patel@wdc.com \
    --cc=Atish.Patra@wdc.com \
    --cc=Damien.LeMoal@wdc.com \
    --cc=anup@brainfault.org \
    --cc=daniel.lezcano@linaro.org \
    --cc=hch@infradead.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=palmer@sifive.com \
    --cc=paul.walmsley@sifive.com \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    --cc=tglx@linutronix.de \
    /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).