162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci======================
462306a36Sopenharmony_ciGeneric vcpu interface
562306a36Sopenharmony_ci======================
662306a36Sopenharmony_ci
762306a36Sopenharmony_ciThe virtual cpu "device" also accepts the ioctls KVM_SET_DEVICE_ATTR,
862306a36Sopenharmony_ciKVM_GET_DEVICE_ATTR, and KVM_HAS_DEVICE_ATTR. The interface uses the same struct
962306a36Sopenharmony_cikvm_device_attr as other devices, but targets VCPU-wide settings and controls.
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciThe groups and attributes per virtual cpu, if any, are architecture specific.
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci1. GROUP: KVM_ARM_VCPU_PMU_V3_CTRL
1462306a36Sopenharmony_ci==================================
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci:Architectures: ARM64
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci1.1. ATTRIBUTE: KVM_ARM_VCPU_PMU_V3_IRQ
1962306a36Sopenharmony_ci---------------------------------------
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci:Parameters: in kvm_device_attr.addr the address for PMU overflow interrupt is a
2262306a36Sopenharmony_ci	     pointer to an int
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciReturns:
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	 =======  ========================================================
2762306a36Sopenharmony_ci	 -EBUSY   The PMU overflow interrupt is already set
2862306a36Sopenharmony_ci	 -EFAULT  Error reading interrupt number
2962306a36Sopenharmony_ci	 -ENXIO   PMUv3 not supported or the overflow interrupt not set
3062306a36Sopenharmony_ci		  when attempting to get it
3162306a36Sopenharmony_ci	 -ENODEV  KVM_ARM_VCPU_PMU_V3 feature missing from VCPU
3262306a36Sopenharmony_ci	 -EINVAL  Invalid PMU overflow interrupt number supplied or
3362306a36Sopenharmony_ci		  trying to set the IRQ number without using an in-kernel
3462306a36Sopenharmony_ci		  irqchip.
3562306a36Sopenharmony_ci	 =======  ========================================================
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ciA value describing the PMUv3 (Performance Monitor Unit v3) overflow interrupt
3862306a36Sopenharmony_cinumber for this vcpu. This interrupt could be a PPI or SPI, but the interrupt
3962306a36Sopenharmony_citype must be same for each vcpu. As a PPI, the interrupt number is the same for
4062306a36Sopenharmony_ciall vcpus, while as an SPI it must be a separate number per vcpu.
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci1.2 ATTRIBUTE: KVM_ARM_VCPU_PMU_V3_INIT
4362306a36Sopenharmony_ci---------------------------------------
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci:Parameters: no additional parameter in kvm_device_attr.addr
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ciReturns:
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	 =======  ======================================================
5062306a36Sopenharmony_ci	 -EEXIST  Interrupt number already used
5162306a36Sopenharmony_ci	 -ENODEV  PMUv3 not supported or GIC not initialized
5262306a36Sopenharmony_ci	 -ENXIO   PMUv3 not supported, missing VCPU feature or interrupt
5362306a36Sopenharmony_ci		  number not set
5462306a36Sopenharmony_ci	 -EBUSY   PMUv3 already initialized
5562306a36Sopenharmony_ci	 =======  ======================================================
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ciRequest the initialization of the PMUv3.  If using the PMUv3 with an in-kernel
5862306a36Sopenharmony_civirtual GIC implementation, this must be done after initializing the in-kernel
5962306a36Sopenharmony_ciirqchip.
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci1.3 ATTRIBUTE: KVM_ARM_VCPU_PMU_V3_FILTER
6262306a36Sopenharmony_ci-----------------------------------------
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci:Parameters: in kvm_device_attr.addr the address for a PMU event filter is a
6562306a36Sopenharmony_ci             pointer to a struct kvm_pmu_event_filter
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci:Returns:
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	 =======  ======================================================
7062306a36Sopenharmony_ci	 -ENODEV  PMUv3 not supported or GIC not initialized
7162306a36Sopenharmony_ci	 -ENXIO   PMUv3 not properly configured or in-kernel irqchip not
7262306a36Sopenharmony_ci	 	  configured as required prior to calling this attribute
7362306a36Sopenharmony_ci	 -EBUSY   PMUv3 already initialized or a VCPU has already run
7462306a36Sopenharmony_ci	 -EINVAL  Invalid filter range
7562306a36Sopenharmony_ci	 =======  ======================================================
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ciRequest the installation of a PMU event filter described as follows::
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci    struct kvm_pmu_event_filter {
8062306a36Sopenharmony_ci	    __u16	base_event;
8162306a36Sopenharmony_ci	    __u16	nevents;
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci    #define KVM_PMU_EVENT_ALLOW	0
8462306a36Sopenharmony_ci    #define KVM_PMU_EVENT_DENY	1
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	    __u8	action;
8762306a36Sopenharmony_ci	    __u8	pad[3];
8862306a36Sopenharmony_ci    };
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ciA filter range is defined as the range [@base_event, @base_event + @nevents),
9162306a36Sopenharmony_citogether with an @action (KVM_PMU_EVENT_ALLOW or KVM_PMU_EVENT_DENY). The
9262306a36Sopenharmony_cifirst registered range defines the global policy (global ALLOW if the first
9362306a36Sopenharmony_ci@action is DENY, global DENY if the first @action is ALLOW). Multiple ranges
9462306a36Sopenharmony_cican be programmed, and must fit within the event space defined by the PMU
9562306a36Sopenharmony_ciarchitecture (10 bits on ARMv8.0, 16 bits from ARMv8.1 onwards).
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ciNote: "Cancelling" a filter by registering the opposite action for the same
9862306a36Sopenharmony_cirange doesn't change the default action. For example, installing an ALLOW
9962306a36Sopenharmony_cifilter for event range [0:10) as the first filter and then applying a DENY
10062306a36Sopenharmony_ciaction for the same range will leave the whole range as disabled.
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ciRestrictions: Event 0 (SW_INCR) is never filtered, as it doesn't count a
10362306a36Sopenharmony_cihardware event. Filtering event 0x1E (CHAIN) has no effect either, as it
10462306a36Sopenharmony_ciisn't strictly speaking an event. Filtering the cycle counter is possible
10562306a36Sopenharmony_ciusing event 0x11 (CPU_CYCLES).
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci1.4 ATTRIBUTE: KVM_ARM_VCPU_PMU_V3_SET_PMU
10862306a36Sopenharmony_ci------------------------------------------
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci:Parameters: in kvm_device_attr.addr the address to an int representing the PMU
11162306a36Sopenharmony_ci             identifier.
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci:Returns:
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	 =======  ====================================================
11662306a36Sopenharmony_ci	 -EBUSY   PMUv3 already initialized, a VCPU has already run or
11762306a36Sopenharmony_ci                  an event filter has already been set
11862306a36Sopenharmony_ci	 -EFAULT  Error accessing the PMU identifier
11962306a36Sopenharmony_ci	 -ENXIO   PMU not found
12062306a36Sopenharmony_ci	 -ENODEV  PMUv3 not supported or GIC not initialized
12162306a36Sopenharmony_ci	 -ENOMEM  Could not allocate memory
12262306a36Sopenharmony_ci	 =======  ====================================================
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ciRequest that the VCPU uses the specified hardware PMU when creating guest events
12562306a36Sopenharmony_cifor the purpose of PMU emulation. The PMU identifier can be read from the "type"
12662306a36Sopenharmony_cifile for the desired PMU instance under /sys/devices (or, equivalent,
12762306a36Sopenharmony_ci/sys/bus/even_source). This attribute is particularly useful on heterogeneous
12862306a36Sopenharmony_cisystems where there are at least two CPU PMUs on the system. The PMU that is set
12962306a36Sopenharmony_cifor one VCPU will be used by all the other VCPUs. It isn't possible to set a PMU
13062306a36Sopenharmony_ciif a PMU event filter is already present.
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ciNote that KVM will not make any attempts to run the VCPU on the physical CPUs
13362306a36Sopenharmony_ciassociated with the PMU specified by this attribute. This is entirely left to
13462306a36Sopenharmony_ciuserspace. However, attempting to run the VCPU on a physical CPU not supported
13562306a36Sopenharmony_ciby the PMU will fail and KVM_RUN will return with
13662306a36Sopenharmony_ciexit_reason = KVM_EXIT_FAIL_ENTRY and populate the fail_entry struct by setting
13762306a36Sopenharmony_cihardare_entry_failure_reason field to KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED and
13862306a36Sopenharmony_cithe cpu field to the processor id.
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci2. GROUP: KVM_ARM_VCPU_TIMER_CTRL
14162306a36Sopenharmony_ci=================================
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci:Architectures: ARM64
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci2.1. ATTRIBUTES: KVM_ARM_VCPU_TIMER_IRQ_VTIMER, KVM_ARM_VCPU_TIMER_IRQ_PTIMER
14662306a36Sopenharmony_ci-----------------------------------------------------------------------------
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci:Parameters: in kvm_device_attr.addr the address for the timer interrupt is a
14962306a36Sopenharmony_ci	     pointer to an int
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ciReturns:
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci	 =======  =================================
15462306a36Sopenharmony_ci	 -EINVAL  Invalid timer interrupt number
15562306a36Sopenharmony_ci	 -EBUSY   One or more VCPUs has already run
15662306a36Sopenharmony_ci	 =======  =================================
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ciA value describing the architected timer interrupt number when connected to an
15962306a36Sopenharmony_ciin-kernel virtual GIC.  These must be a PPI (16 <= intid < 32).  Setting the
16062306a36Sopenharmony_ciattribute overrides the default values (see below).
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci=============================  ==========================================
16362306a36Sopenharmony_ciKVM_ARM_VCPU_TIMER_IRQ_VTIMER  The EL1 virtual timer intid (default: 27)
16462306a36Sopenharmony_ciKVM_ARM_VCPU_TIMER_IRQ_PTIMER  The EL1 physical timer intid (default: 30)
16562306a36Sopenharmony_ci=============================  ==========================================
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ciSetting the same PPI for different timers will prevent the VCPUs from running.
16862306a36Sopenharmony_ciSetting the interrupt number on a VCPU configures all VCPUs created at that
16962306a36Sopenharmony_citime to use the number provided for a given timer, overwriting any previously
17062306a36Sopenharmony_ciconfigured values on other VCPUs.  Userspace should configure the interrupt
17162306a36Sopenharmony_cinumbers on at least one VCPU after creating all VCPUs and before running any
17262306a36Sopenharmony_ciVCPUs.
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci.. _kvm_arm_vcpu_pvtime_ctrl:
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci3. GROUP: KVM_ARM_VCPU_PVTIME_CTRL
17762306a36Sopenharmony_ci==================================
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci:Architectures: ARM64
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci3.1 ATTRIBUTE: KVM_ARM_VCPU_PVTIME_IPA
18262306a36Sopenharmony_ci--------------------------------------
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci:Parameters: 64-bit base address
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ciReturns:
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	 =======  ======================================
18962306a36Sopenharmony_ci	 -ENXIO   Stolen time not implemented
19062306a36Sopenharmony_ci	 -EEXIST  Base address already set for this VCPU
19162306a36Sopenharmony_ci	 -EINVAL  Base address not 64 byte aligned
19262306a36Sopenharmony_ci	 =======  ======================================
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ciSpecifies the base address of the stolen time structure for this VCPU. The
19562306a36Sopenharmony_cibase address must be 64 byte aligned and exist within a valid guest memory
19662306a36Sopenharmony_ciregion. See Documentation/virt/kvm/arm/pvtime.rst for more information
19762306a36Sopenharmony_ciincluding the layout of the stolen time structure.
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci4. GROUP: KVM_VCPU_TSC_CTRL
20062306a36Sopenharmony_ci===========================
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci:Architectures: x86
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci4.1 ATTRIBUTE: KVM_VCPU_TSC_OFFSET
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci:Parameters: 64-bit unsigned TSC offset
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ciReturns:
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci	 ======= ======================================
21162306a36Sopenharmony_ci	 -EFAULT Error reading/writing the provided
21262306a36Sopenharmony_ci		 parameter address.
21362306a36Sopenharmony_ci	 -ENXIO  Attribute not supported
21462306a36Sopenharmony_ci	 ======= ======================================
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ciSpecifies the guest's TSC offset relative to the host's TSC. The guest's
21762306a36Sopenharmony_ciTSC is then derived by the following equation:
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci  guest_tsc = host_tsc + KVM_VCPU_TSC_OFFSET
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ciThis attribute is useful to adjust the guest's TSC on live migration,
22262306a36Sopenharmony_ciso that the TSC counts the time during which the VM was paused. The
22362306a36Sopenharmony_cifollowing describes a possible algorithm to use for this purpose.
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ciFrom the source VMM process:
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci1. Invoke the KVM_GET_CLOCK ioctl to record the host TSC (tsc_src),
22862306a36Sopenharmony_ci   kvmclock nanoseconds (guest_src), and host CLOCK_REALTIME nanoseconds
22962306a36Sopenharmony_ci   (host_src).
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci2. Read the KVM_VCPU_TSC_OFFSET attribute for every vCPU to record the
23262306a36Sopenharmony_ci   guest TSC offset (ofs_src[i]).
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci3. Invoke the KVM_GET_TSC_KHZ ioctl to record the frequency of the
23562306a36Sopenharmony_ci   guest's TSC (freq).
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ciFrom the destination VMM process:
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci4. Invoke the KVM_SET_CLOCK ioctl, providing the source nanoseconds from
24062306a36Sopenharmony_ci   kvmclock (guest_src) and CLOCK_REALTIME (host_src) in their respective
24162306a36Sopenharmony_ci   fields.  Ensure that the KVM_CLOCK_REALTIME flag is set in the provided
24262306a36Sopenharmony_ci   structure.
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci   KVM will advance the VM's kvmclock to account for elapsed time since
24562306a36Sopenharmony_ci   recording the clock values.  Note that this will cause problems in
24662306a36Sopenharmony_ci   the guest (e.g., timeouts) unless CLOCK_REALTIME is synchronized
24762306a36Sopenharmony_ci   between the source and destination, and a reasonably short time passes
24862306a36Sopenharmony_ci   between the source pausing the VMs and the destination executing
24962306a36Sopenharmony_ci   steps 4-7.
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci5. Invoke the KVM_GET_CLOCK ioctl to record the host TSC (tsc_dest) and
25262306a36Sopenharmony_ci   kvmclock nanoseconds (guest_dest).
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci6. Adjust the guest TSC offsets for every vCPU to account for (1) time
25562306a36Sopenharmony_ci   elapsed since recording state and (2) difference in TSCs between the
25662306a36Sopenharmony_ci   source and destination machine:
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci   ofs_dst[i] = ofs_src[i] -
25962306a36Sopenharmony_ci     (guest_src - guest_dest) * freq +
26062306a36Sopenharmony_ci     (tsc_src - tsc_dest)
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci   ("ofs[i] + tsc - guest * freq" is the guest TSC value corresponding to
26362306a36Sopenharmony_ci   a time of 0 in kvmclock.  The above formula ensures that it is the
26462306a36Sopenharmony_ci   same on the destination as it was on the source).
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci7. Write the KVM_VCPU_TSC_OFFSET attribute for every vCPU with the
26762306a36Sopenharmony_ci   respective value derived in the previous step.
268