@@ -6,11 +6,12 @@ use displaydoc::Display;
66use kvm_bindings:: { KVM_ARM_VCPU_PVTIME_CTRL , KVM_ARM_VCPU_PVTIME_IPA } ;
77use log:: { debug, info, warn} ;
88use thiserror:: Error ;
9+ use vm_memory:: GuestAddress ;
910
1011use crate :: device_manager:: resources:: ResourceAllocator ;
1112
12- /// Size of the stolen_time struct in bytes, see 3.2.2 in DEN0057A
13- pub const STEALTIME_STRUCT_MEM_SIZE : u64 = 16 ;
13+ /// 64 bytes due to alignment requirement in 3.1 of https://www.kernel.org/doc/html/v5.8/virt/kvm/devices/vcpu.html#attribute-kvm-arm-vcpu-pvtime-ipa
14+ pub const STEALTIME_STRUCT_MEM_SIZE : u64 = 64 ;
1415
1516/// Represent PVTime device for ARM
1617#[ derive( Debug ) ]
@@ -36,27 +37,21 @@ impl PVTime {
3637 resource_allocator : & mut ResourceAllocator ,
3738 vcpu_count : u8 ,
3839 ) -> Result < Self , PVTimeError > {
39- info ! ( "Creating PVTime for {vcpu_count} vCPUs..." ) ;
40- // This returns the IPA(?) of the start of our shared memory region for all vCPUs.
41- // Q: Confirm that allocate_system_memory returns an IPA?
42- let base_addr = resource_allocator
40+
41+ // This returns the IPA of the start of our shared memory region for all vCPUs.
42+ let base_addr: GuestAddress = GuestAddress ( resource_allocator
4343 . allocate_system_memory (
4444 STEALTIME_STRUCT_MEM_SIZE * vcpu_count as u64 ,
45- 16 , // Q: We believe this to be 16, need confirmation.
45+ 64 ,
4646 vm_allocator:: AllocPolicy :: LastMatch ,
4747 )
48- . map_err ( |e| PVTimeError :: AllocationFailed ( e. to_string ( ) ) ) ?;
48+ . map_err ( |e| PVTimeError :: AllocationFailed ( e. to_string ( ) ) ) ?) ;
4949
50- debug ! (
51- "Allocated base address for PVTime stolen_time region: 0x{:x}" ,
52- base_addr
53- ) ;
5450
5551 // Now we need to store the base IPA for each vCPU's steal_time struct.
5652 let mut steal_time_regions = HashMap :: new ( ) ;
5753 for i in 0 ..vcpu_count {
58- let ipa = base_addr + ( i as u64 * STEALTIME_STRUCT_MEM_SIZE ) ;
59- debug ! ( "Assigned vCPU {} to stolen_time IPA 0x{:x}" , i, ipa) ;
54+ let ipa = base_addr. 0 + ( i as u64 * STEALTIME_STRUCT_MEM_SIZE ) ;
6055 steal_time_regions. insert ( i, ipa) ;
6156 }
6257
@@ -70,40 +65,22 @@ impl PVTime {
7065 vcpu_index : u8 ,
7166 vcpu_fd : & kvm_ioctls:: VcpuFd ,
7267 ) -> Result < ( ) , PVTimeError > {
68+
7369 // Get IPA of the steal_time region for this vCPU
7470 let ipa = self
7571 . steal_time_regions
7672 . get ( & vcpu_index)
7773 . ok_or ( PVTimeError :: InvalidVcpuIndex ( vcpu_index) ) ?;
7874
79- debug ! (
80- "Registering vCPU {} with stolen_time IPA = 0x{:x}" ,
81- vcpu_index, ipa
82- ) ;
83-
84- // IMPORTANT QUESTION: We need to confirm this is safe. We need to somehow
85- // ensure the ipa value is not dropped before we use it etc. since we
86- // are creating a raw pointer? Do we need a Box?
87- let ipa_val = * ipa;
88- let ipa_ptr = & ipa_val as * const u64 ;
89- debug ! (
90- "Registering vCPU {} with stolen_time IPA = 0x{:x} (at userspace addr 0x{:x})" ,
91- vcpu_index, ipa_val, ipa_ptr as u64
92- ) ;
93-
9475 // Use KVM syscall (kvm_set_device_attr) to register the vCPU with the steal_time region
9576 let vcpu_device_attr = kvm_bindings:: kvm_device_attr {
9677 group : KVM_ARM_VCPU_PVTIME_CTRL ,
9778 attr : KVM_ARM_VCPU_PVTIME_IPA as u64 ,
98- addr : ipa_ptr as u64 , // userspace address of attr data
79+ addr : ipa as * const u64 as u64 , // userspace address of attr data
9980 flags : 0 ,
10081 } ;
10182
10283 vcpu_fd. set_device_attr ( & vcpu_device_attr) . map_err ( |err| {
103- warn ! (
104- "Failed to set device attribute for vCPU {}: {:?}" ,
105- vcpu_index, err
106- ) ;
10784 PVTimeError :: DeviceAttribute ( err, true , KVM_ARM_VCPU_PVTIME_CTRL )
10885 } ) ?;
10986
0 commit comments