@@ -49,6 +49,7 @@ pub struct Aarch64VCpu {
4949 /// The MPIDR_EL1 value for the vCPU.
5050 mpidr : u64 ,
5151 pub pt_level : usize ,
52+ pub pa_bits : usize ,
5253}
5354
5455/// Configuration for creating a new `Aarch64VCpu`
@@ -61,7 +62,6 @@ pub struct Aarch64VCpuCreateConfig {
6162 pub mpidr_el1 : u64 ,
6263 /// The address of the device tree blob.
6364 pub dtb_addr : usize ,
64- pub pt_level : usize ,
6565}
6666
6767/// Configuration for setting up a new `Aarch64VCpu`
@@ -78,12 +78,16 @@ impl Aarch64VCpu {
7878 let mut ctx = TrapFrame :: default ( ) ;
7979 ctx. set_argument ( config. dtb_addr ) ;
8080
81+ let pa_bits = pa_bits ( ) ;
82+ let pt_level = max_gpt_level ( pa_bits) ;
83+
8184 Ok ( Self {
8285 ctx,
8386 host_stack_top : 0 ,
8487 guest_system_regs : GuestSystemRegisters :: default ( ) ,
8588 mpidr : config. mpidr_el1 ,
86- pt_level : config. pt_level ,
89+ pt_level,
90+ pa_bits,
8791 } )
8892 }
8993
@@ -113,18 +117,38 @@ impl Aarch64VCpu {
113117 pub fn setup_current_cpu ( & mut self , vmid : usize ) -> AxResult {
114118 // Set VMID then invalidate stage-2 TLB for this VMID to avoid stale translations.
115119 let vmid_mask: u64 = 0xffff << 48 ;
116- let val = match self . pt_level {
120+ let mut val = match self . pt_level {
117121 4 => VTCR_EL2 :: SL0 :: Granule4KBLevel0 + VTCR_EL2 :: T0SZ . val ( 64 - 48 ) ,
118122 _ => VTCR_EL2 :: SL0 :: Granule4KBLevel1 + VTCR_EL2 :: T0SZ . val ( 64 - 39 ) ,
119- } + ( VTCR_EL2 :: TG0 :: Granule4KB
123+ } ;
124+
125+ val = val
126+ + match self . pa_bits {
127+ 52 ..=64 => VTCR_EL2 :: PS :: PA_52B_4PB ,
128+ 48 ..=51 => VTCR_EL2 :: PS :: PA_48B_256TB ,
129+ 44 ..=47 => VTCR_EL2 :: PS :: PA_44B_16TB ,
130+ 42 ..=43 => VTCR_EL2 :: PS :: PA_42B_4TB ,
131+ 40 ..=41 => VTCR_EL2 :: PS :: PA_40B_1TB ,
132+ 36 ..=39 => VTCR_EL2 :: PS :: PA_36B_64GB ,
133+ _ => VTCR_EL2 :: PS :: PA_32B_4GB ,
134+ } ;
135+
136+ val = val
137+ + VTCR_EL2 :: TG0 :: Granule4KB
120138 + VTCR_EL2 :: SH0 :: Inner
121139 + VTCR_EL2 :: ORGN0 :: NormalWBRAWA
122- + VTCR_EL2 :: IRGN0 :: NormalWBRAWA ) ;
140+ + VTCR_EL2 :: IRGN0 :: NormalWBRAWA ;
141+
123142 self . guest_system_regs . vtcr_el2 = val. value ;
124143 VTCR_EL2 . set ( self . guest_system_regs . vtcr_el2 ) ;
144+ debug ! (
145+ "vCPU {:#x} set pt level: {}, pt bits: {}" ,
146+ self . mpidr, self . pt_level, self . pa_bits
147+ ) ;
125148
126149 let mut vttbr = self . guest_system_regs . vttbr_el2 ;
127150 vttbr = ( vttbr & !vmid_mask) | ( ( vmid as u64 & 0xffff ) << 48 ) ;
151+ self . guest_system_regs . vttbr_el2 = vttbr;
128152 VTTBR_EL2 . set ( vttbr) ;
129153
130154 unsafe {
0 commit comments