Messages in this thread | | | Subject | Re: [PATCH 9/9] arm64: Retrieve stolen time as paravirtualized guest | From | Zenghui Yu <> | Date | Tue, 13 Aug 2019 14:06:56 +0800 |
| |
On 2019/8/12 18:39, Steven Price wrote: > On 09/08/2019 14:51, Zenghui Yu wrote: > [...] >> Hi Steven, >> >> Since userspace is not involved yet (right?), no one will create the >> PV_TIME device for guest (and no one will specify the IPA of the shared >> stolen time region), and I guess we will get a "not supported" error >> here. >> >> So what should we do if we want to test this series now? Any userspace >> tools? If no, do you have any plans for userspace developing? ;-) > > At the moment I have the following patch to kvmtool which creates the > PV_TIME device - this isn't in a state to go upstream, and Marc has > asked that I rework the memory allocation, so this will need to change. > > It's a little ugly as it simply reserves the first page of RAM to use > for the PV time structures.
Thanks for sharing the code. It's good enough to show what is required in user-space.
(I'm not familiar with kvmtool. I will first take some time to move the steal time part to Qemu and see what will happen.)
Thanks, zenghui
> ----8<---- > diff --git a/Makefile b/Makefile > index 3862112..a79956b 100644 > --- a/Makefile > +++ b/Makefile > @@ -158,7 +158,7 @@ endif > # ARM > OBJS_ARM_COMMON := arm/fdt.o arm/gic.o arm/gicv2m.o arm/ioport.o \ > arm/kvm.o arm/kvm-cpu.o arm/pci.o arm/timer.o \ > - arm/pmu.o > + arm/pmu.o arm/pvtime.o > HDRS_ARM_COMMON := arm/include > ifeq ($(ARCH), arm) > DEFINES += -DCONFIG_ARM > diff --git a/arm/fdt.c b/arm/fdt.c > index c80e6da..19eccbc 100644 > --- a/arm/fdt.c > +++ b/arm/fdt.c > @@ -119,6 +119,7 @@ static int setup_fdt(struct kvm *kvm) > > /* Create new tree without a reserve map */ > _FDT(fdt_create(fdt, FDT_MAX_SIZE)); > + _FDT(fdt_add_reservemap_entry(fdt, kvm->arch.memory_guest_start, 4096)); > _FDT(fdt_finish_reservemap(fdt)); > > /* Header */ > diff --git a/arm/kvm.c b/arm/kvm.c > index 1f85fc6..8bbfef1 100644 > --- a/arm/kvm.c > +++ b/arm/kvm.c > @@ -11,6 +11,8 @@ > #include <linux/kvm.h> > #include <linux/sizes.h> > > +int pvtime_create(struct kvm *kvm); > + > struct kvm_ext kvm_req_ext[] = { > { DEFINE_KVM_EXT(KVM_CAP_IRQCHIP) }, > { DEFINE_KVM_EXT(KVM_CAP_ONE_REG) }, > @@ -86,6 +88,10 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size) > /* Create the virtual GIC. */ > if (gic__create(kvm, kvm->cfg.arch.irqchip)) > die("Failed to create virtual GIC"); > + > + /* Setup PV time */ > + if (pvtime_create(kvm)) > + die("Failed to initialise PV time"); > } > > #define FDT_ALIGN SZ_2M > diff --git a/arm/pvtime.c b/arm/pvtime.c > new file mode 100644 > index 0000000..abcaab3 > --- /dev/null > +++ b/arm/pvtime.c > @@ -0,0 +1,77 @@ > +#include "kvm/kvm.h" > + > +#define KVM_DEV_TYPE_ARM_PV_TIME (KVM_DEV_TYPE_ARM_VGIC_ITS+2) > + > +/* Device Control API: PV_TIME */ > +#define KVM_DEV_ARM_PV_TIME_PADDR 0 > +#define KVM_DEV_ARM_PV_TIME_FREQUENCY 3 > + > +#define KVM_DEV_ARM_PV_TIME_ST 0 > +#define KVM_DEV_ARM_PV_TIME_LPT 1 > + > +static int pvtime_fd; > + > +int pvtime_create(struct kvm *kvm); > + > +int pvtime_create(struct kvm *kvm) > +{ > + int err; > + u64 lpt_paddr = 0x10000000; > + u64 st_paddr = lpt_paddr + 4096; > + u32 frequency = 100 * 1000 * 1000; > + > + printf("lpt_paddr=%llx\n", lpt_paddr); > + > + struct kvm_create_device pvtime_device = { > + .type = KVM_DEV_TYPE_ARM_PV_TIME, > + .flags = 0, > + }; > + > + err = ioctl(kvm->vm_fd, KVM_CREATE_DEVICE, &pvtime_device); > + if (err) { > + printf("Failed to create PV device\n"); > + return 0; > + } > + > + pvtime_fd = pvtime_device.fd; > + > + struct kvm_device_attr lpt_base = { > + .group = KVM_DEV_ARM_PV_TIME_PADDR, > + .attr = KVM_DEV_ARM_PV_TIME_LPT, > + .addr = (u64)(unsigned long)&lpt_paddr > + }; > + struct kvm_device_attr st_base = { > + .group = KVM_DEV_ARM_PV_TIME_PADDR, > + .attr = KVM_DEV_ARM_PV_TIME_ST, > + .addr = (u64)(unsigned long)&st_paddr > + }; > + > + struct kvm_device_attr lpt_freq = { > + .group = KVM_DEV_ARM_PV_TIME_FREQUENCY, > + .attr = KVM_DEV_ARM_PV_TIME_LPT, > + .addr = (u64)(unsigned long)&frequency > + }; > + > + err = ioctl(pvtime_fd, KVM_SET_DEVICE_ATTR, &lpt_base); > + if (err) { > + perror("ioctl lpt_base failed"); > + printf("Ignoring LPT...\n"); > + } > + err = ioctl(pvtime_fd, KVM_SET_DEVICE_ATTR, &st_base); > + if (err) { > + perror("ioctl st_base failed"); > + goto out_err; > + } > + err = ioctl(pvtime_fd, KVM_SET_DEVICE_ATTR, &lpt_freq); > + if (err) { > + perror("ioctl lpt_freq failed"); > + printf("Ignoring LPT...\n"); > + } > + > + printf("PV time setup\n"); > + > + return 0; > +out_err: > + close(pvtime_fd); > + return err; > +}
| |