firecracker-microvm / firecracker

Secure and fast microVMs for serverless computing.
http://firecracker-microvm.io
Apache License 2.0
26.12k stars 1.81k forks source link

[Feature Request] Steal Time support in ARM #4866

Open Manciukic opened 2 weeks ago

Manciukic commented 2 weeks ago

Feature Request

PV Steal Time reporting on ARM is available in KVM since 5.10 at least but Firecracker doesn't enable it.

Describe the desired solution

We could enable the PVTIME device in Firecracker on ARM to allow for stolen time reporting.

Describe possible alternatives

Additional context

I found that this is the KVM patch that introduced it: https://lwn.net/Articles/797954/ And this is how QEMU integrated with it: https://patchew.org/QEMU/20200711101033.47371-1-drjones@redhat.com/20200711101033.47371-4-drjones@redhat.com/

It needs to be enabled via ioctl to the vcpu fd, there's an example in the kernel self tests: https://github.com/amazonlinux/linux/blob/kernel-5.10.215-203.850.amzn2/tools/testing/selftests/kvm/steal_time.c#L172

static void steal_time_init(struct kvm_vm *vm)
{
        struct kvm_device_attr dev = {
                .group = KVM_ARM_VCPU_PVTIME_CTRL,
                .attr = KVM_ARM_VCPU_PVTIME_IPA,
        };
        int i, ret;

        ret = _vcpu_ioctl(vm, 0, KVM_HAS_DEVICE_ATTR, &dev);
        if (ret != 0 && errno == ENXIO) {
                print_skip("steal-time not supported");
                exit(KSFT_SKIP);
        }

        for (i = 0; i < NR_VCPUS; ++i) {
                uint64_t st_ipa;

                vcpu_ioctl(vm, i, KVM_HAS_DEVICE_ATTR, &dev);

                dev.addr = (uint64_t)&st_ipa;

                /* ST_GPA_BASE is identity mapped */
                st_gva[i] = (void *)(ST_GPA_BASE + i * STEAL_TIME_SIZE);
                sync_global_to_guest(vm, st_gva[i]);

                st_ipa = (ulong)st_gva[i] | 1;
                ret = _vcpu_ioctl(vm, i, KVM_SET_DEVICE_ATTR, &dev);
                TEST_ASSERT(ret == -1 && errno == EINVAL, "Bad IPA didn't report EINVAL");

                st_ipa = (ulong)st_gva[i];
                vcpu_ioctl(vm, i, KVM_SET_DEVICE_ATTR, &dev);

                ret = _vcpu_ioctl(vm, i, KVM_SET_DEVICE_ATTR, &dev);
                TEST_ASSERT(ret == -1 && errno == EEXIST, "Set IPA twice without EEXIST");

        }
}

Checks

roypat commented 2 weeks ago

Describe possible alternatives

* check if `rust-vmm` has some off-the-shelf implementation we could use

we definitely have KVM_{GET,SET}_DEVICE_ATTR ioctls in kvm-ioctls :)