1use super::Backing;
7use super::Hcl;
8use super::HvcallRepInput;
9use super::IsolationType;
10use super::MshvHvcall;
11use super::ProcessorRunner;
12use super::hcl_get_vp_register;
13use super::hcl_set_vp_register;
14use super::ioctls::mshv_vp_registers;
15use crate::GuestVtl;
16use arrayvec::ArrayVec;
17use hvdef::HV_PARTITION_ID_SELF;
18use hvdef::HV_VP_INDEX_SELF;
19use hvdef::HvError;
20use hvdef::HvRegisterValue;
21use hvdef::HypercallCode;
22use hvdef::Vtl;
23use hvdef::hypercall::HvRegisterAssoc;
24use std::os::fd::AsRawFd;
25use thiserror::Error;
26use zerocopy::FromZeros;
27
28#[cfg(guest_arch = "x86_64")]
29type HvArchRegisterName = hvdef::HvX64RegisterName;
30
31#[cfg(guest_arch = "aarch64")]
32type HvArchRegisterName = hvdef::HvArm64RegisterName;
33
34#[derive(Error, Debug)]
35#[expect(missing_docs)]
36pub enum GetRegError {
37 #[error("failed to get VP register from ioctl")]
38 Ioctl(#[source] nix::Error),
39 #[error("failed to get VP register from hypercall")]
40 Hypercall(#[source] HvError),
41 #[error("failed to get VP register from sidecar")]
42 Sidecar(#[source] sidecar_client::SidecarError),
43}
44
45#[derive(Error, Debug)]
46#[expect(missing_docs)]
47pub enum SetRegError {
48 #[error("failed to set VP register via ioctl")]
49 Ioctl(#[source] nix::Error),
50 #[error("failed to set VP register via hypercall")]
51 Hypercall(#[source] HvError),
52 #[error("failed to set VP register via sidecar")]
53 Sidecar(#[source] sidecar_client::SidecarError),
54}
55
56impl<'a, T: Backing<'a>> ProcessorRunner<'a, T> {
57 pub fn get_vp_register(
59 &mut self,
60 vtl: GuestVtl,
61 name: HvArchRegisterName,
62 ) -> Result<HvRegisterValue, GetRegError> {
63 let mut value = [FromZeros::new_zeroed(); 1];
64 self.get_regs(vtl.into(), &[name], &mut value)?;
65 Ok(value[0])
66 }
67
68 pub fn set_vp_register(
70 &mut self,
71 vtl: GuestVtl,
72 name: HvArchRegisterName,
73 value: HvRegisterValue,
74 ) -> Result<(), SetRegError> {
75 self.set_regs(vtl.into(), [(name, value)])
76 }
77
78 pub fn get_vp_registers(
83 &mut self,
84 vtl: GuestVtl,
85 names: &[HvArchRegisterName],
86 values: &mut [HvRegisterValue],
87 ) -> Result<(), GetRegError> {
88 self.get_regs(vtl.into(), names, values)
89 }
90
91 pub fn get_vp_vtl2_register(
94 &mut self,
95 name: HvArchRegisterName,
96 ) -> Result<HvRegisterValue, GetRegError> {
97 assert!(matches!(
98 name,
99 HvArchRegisterName::VsmVpSecureConfigVtl0 | HvArchRegisterName::VsmVpSecureConfigVtl1
100 ));
101
102 let mut value = [FromZeros::new_zeroed(); 1];
105 self.get_regs(Vtl::Vtl2, &[name], &mut value)?;
106 Ok(value[0])
107 }
108
109 pub fn set_vp_registers<I>(&mut self, vtl: GuestVtl, regs: I) -> Result<(), SetRegError>
111 where
112 I: IntoIterator,
113 I::Item: Into<HvRegisterAssoc>,
114 {
115 self.set_regs(vtl.into(), regs)
116 }
117
118 fn get_regs(
121 &mut self,
122 vtl: Vtl,
123 names: &[HvArchRegisterName],
124 values: &mut [HvRegisterValue],
125 ) -> Result<(), GetRegError> {
126 assert_eq!(names.len(), values.len());
127
128 if let Some(sidecar) = &mut self.sidecar {
129 return sidecar
130 .get_vp_registers(vtl.into(), zerocopy::transmute_ref!(names), values)
131 .map_err(GetRegError::Sidecar);
132 }
133
134 const MAX_REGS_PER_HVCALL: usize = 32;
135 let mut hv_names: ArrayVec<_, MAX_REGS_PER_HVCALL> = ArrayVec::new();
136 let mut hv_values: ArrayVec<_, MAX_REGS_PER_HVCALL> = ArrayVec::new();
137
138 let do_hvcall =
139 |hv_names: &mut ArrayVec<_, _>, hv_values: &mut ArrayVec<&mut HvRegisterValue, _>| {
140 let mut values: ArrayVec<_, MAX_REGS_PER_HVCALL> = ArrayVec::from_iter(
141 std::iter::repeat_n(FromZeros::new_zeroed(), hv_names.len()),
142 );
143 self.hcl
144 .mshv_hvcall
145 .get_vp_registers_hypercall(vtl, hv_names, &mut values)
146 .map_err(GetRegError::Hypercall)?;
147
148 for (dest, value) in hv_values.iter_mut().zip(values) {
149 **dest = value;
150 }
151 hv_names.clear();
152 hv_values.clear();
153 Ok(())
154 };
155
156 for (&name, value) in names.iter().zip(values.iter_mut()) {
157 if let Ok(vtl) = vtl.try_into()
158 && let Some(v) = T::try_get_reg(self, vtl, name.into())
159 {
160 *value = v;
161 } else if self.is_kernel_managed(name) {
162 let mut reg = HvRegisterAssoc {
167 name: name.into(),
168 pad: Default::default(),
169 value: HvRegisterValue::new_zeroed(),
170 };
171 let mut mshv_vp_register_args = mshv_vp_registers {
172 count: 1,
173 regs: &mut reg,
174 };
175 unsafe {
178 hcl_get_vp_register(
179 self.hcl.mshv_vtl.file.as_raw_fd(),
180 &mut mshv_vp_register_args,
181 )
182 .map_err(GetRegError::Ioctl)?;
183 }
184 *value = reg.value;
185 } else {
186 hv_names.push(name);
187 hv_values.push(value);
188
189 if hv_names.is_full() {
190 do_hvcall(&mut hv_names, &mut hv_values)?;
191 }
192 }
193 }
194
195 if !hv_names.is_empty() {
196 do_hvcall(&mut hv_names, &mut hv_values)?;
197 }
198
199 Ok(())
200 }
201
202 fn set_regs<I>(&mut self, vtl: Vtl, regs: I) -> Result<(), SetRegError>
205 where
206 I: IntoIterator,
207 I::Item: Into<HvRegisterAssoc>,
208 {
209 self.set_regs_nongeneric(vtl, &mut regs.into_iter().map(Into::into))
210 }
211
212 fn set_regs_nongeneric(
215 &mut self,
216 vtl: Vtl,
217 regs: &mut dyn Iterator<Item = HvRegisterAssoc>,
218 ) -> Result<(), SetRegError> {
219 if let Some(sidecar) = &mut self.sidecar {
220 let regs: Vec<HvRegisterAssoc> = regs.collect();
222 return sidecar
223 .set_vp_registers(vtl.into(), ®s)
224 .map_err(SetRegError::Sidecar);
225 }
226
227 const MAX_REGS_PER_HVCALL: usize = 32;
228 let mut hv_regs: ArrayVec<_, MAX_REGS_PER_HVCALL> = ArrayVec::new();
229
230 let do_hvcall = |hv_regs: &mut ArrayVec<_, _>| {
231 self.hcl
232 .mshv_hvcall
233 .set_vp_registers_hypercall(vtl, hv_regs)
234 .map_err(SetRegError::Hypercall)?;
235 hv_regs.clear();
236 Ok(())
237 };
238
239 let vtl = vtl.try_into();
240 let mut pending_ordered_reg = false;
241 for reg in regs {
242 let in_order_update_required = T::must_flush_regs_on(self, reg.name);
243 if let Ok(vtl) = vtl
244 && !in_order_update_required
245 && T::try_set_reg(self, vtl, reg.name, reg.value)
246 {
247 } else if self.is_kernel_managed(reg.name.into()) {
248 let mshv_vp_register_args = mshv_vp_registers {
253 count: 1,
254 regs: std::ptr::from_ref(®).cast_mut(),
255 };
256 unsafe {
259 hcl_set_vp_register(self.hcl.mshv_vtl.file.as_raw_fd(), &mshv_vp_register_args)
260 .map_err(SetRegError::Ioctl)?;
261 }
262 } else {
263 hv_regs.push(reg);
264 if hv_regs.is_full() {
265 do_hvcall(&mut hv_regs)?;
266 pending_ordered_reg = false;
267 } else if in_order_update_required {
268 pending_ordered_reg = true;
269 }
270 }
271 }
272
273 if let Ok(vtl) = vtl
276 && pending_ordered_reg
277 && hv_regs.len() == 1
278 {
279 if T::try_set_reg(self, vtl, hv_regs[0].name, hv_regs[0].value) {
280 hv_regs.clear();
281 }
282 }
283
284 if !hv_regs.is_empty() {
285 do_hvcall(&mut hv_regs)?;
286 }
287
288 Ok(())
289 }
290
291 fn is_kernel_managed(&self, name: HvArchRegisterName) -> bool {
293 #[cfg(guest_arch = "x86_64")]
294 if name == HvArchRegisterName::Dr6 {
295 return self.hcl.dr6_shared();
296 }
297
298 is_vtl_shared_reg(name)
299 }
300
301 pub fn set_vp_registers_hvcall<I>(&mut self, vtl: Vtl, values: I) -> Result<(), HvError>
309 where
310 I: IntoIterator,
311 I::Item: Into<HvRegisterAssoc> + Clone,
312 {
313 let registers: Vec<HvRegisterAssoc> = values.into_iter().map(Into::into).collect();
314
315 #[cfg(guest_arch = "x86_64")]
316 let per_arch = |name| {
317 matches!(
318 name,
319 HvArchRegisterName::CrInterceptControl
320 | HvArchRegisterName::SevAvicGpa
321 | HvArchRegisterName::GuestVsmPartitionConfig
322 )
323 };
324
325 #[cfg(guest_arch = "aarch64")]
326 let per_arch = |_: HvArchRegisterName| false;
327
328 assert!(registers.iter().all(
329 |HvRegisterAssoc {
330 name,
331 pad: _,
332 value: _,
333 }| matches!(
334 (*name).into(),
335 HvArchRegisterName::PendingEvent0
336 | HvArchRegisterName::PendingEvent1
337 | HvArchRegisterName::Sipp
338 | HvArchRegisterName::Sifp
339 | HvArchRegisterName::Ghcb
340 | HvArchRegisterName::VsmPartitionConfig
341 | HvArchRegisterName::VsmVpWaitForTlbLock
342 | HvArchRegisterName::VsmVpSecureConfigVtl0
343 | HvArchRegisterName::VsmVpSecureConfigVtl1
344 ) || per_arch((*name).into())
345 ));
346 self.hcl
347 .mshv_hvcall
348 .set_vp_registers_hypercall(vtl, ®isters)
349 }
350}
351
352impl Hcl {
353 pub fn reference_time(&self) -> Result<u64, GetRegError> {
355 Ok(self
356 .get_partition_vtl2_register(HvArchRegisterName::TimeRefCount)?
357 .as_u64())
358 }
359
360 pub fn get_vsm_capabilities(&self) -> Result<hvdef::HvRegisterVsmCapabilities, GetRegError> {
362 let caps = match self.isolation {
363 IsolationType::Cca => {
365 tracing::info!(
366 "cca: get_vsm_capabilities is not implemented and returning empty set now"
367 );
368 hvdef::HvRegisterVsmCapabilities::new()
369 }
370 IsolationType::None | IsolationType::Vbs | IsolationType::Snp | IsolationType::Tdx => {
372 let caps = hvdef::HvRegisterVsmCapabilities::from(
373 self.get_partition_vtl2_register(HvArchRegisterName::VsmCapabilities)?
374 .as_u64(),
375 );
376
377 match self.isolation {
378 IsolationType::None | IsolationType::Vbs => caps,
379 IsolationType::Snp => hvdef::HvRegisterVsmCapabilities::new()
380 .with_deny_lower_vtl_startup(caps.deny_lower_vtl_startup())
381 .with_intercept_page_available(caps.intercept_page_available()),
382 IsolationType::Tdx => hvdef::HvRegisterVsmCapabilities::new()
383 .with_deny_lower_vtl_startup(caps.deny_lower_vtl_startup())
384 .with_intercept_page_available(caps.intercept_page_available())
385 .with_dr6_shared(true)
386 .with_proxy_interrupt_redirect_available(
387 caps.proxy_interrupt_redirect_available(),
388 ),
389 IsolationType::Cca => unreachable!(),
390 }
391 }
392 };
393
394 assert_eq!(caps.dr6_shared(), self.dr6_shared());
395
396 Ok(caps)
397 }
398
399 pub fn get_guest_vsm_partition_config(
401 &self,
402 ) -> Result<hvdef::HvRegisterGuestVsmPartitionConfig, GetRegError> {
403 Ok(hvdef::HvRegisterGuestVsmPartitionConfig::from(
404 self.get_partition_vtl2_register(HvArchRegisterName::GuestVsmPartitionConfig)?
405 .as_u64(),
406 ))
407 }
408
409 pub fn get_vsm_partition_status(
411 &self,
412 ) -> Result<hvdef::HvRegisterVsmPartitionStatus, GetRegError> {
413 Ok(hvdef::HvRegisterVsmPartitionStatus::from(
414 self.get_partition_vtl2_register(HvArchRegisterName::VsmPartitionStatus)?
415 .as_u64(),
416 ))
417 }
418
419 pub fn get_privileges_and_features_info(
422 &self,
423 ) -> Result<hvdef::HvPartitionPrivilege, GetRegError> {
424 #[cfg(guest_arch = "x86_64")]
425 {
426 let result = safe_intrinsics::cpuid(hvdef::HV_CPUID_FUNCTION_MS_HV_FEATURES, 0);
427 let num = result.eax as u64 | ((result.ebx as u64) << 32);
428 Ok(hvdef::HvPartitionPrivilege::from(num))
429 }
430
431 #[cfg(guest_arch = "aarch64")]
432 {
433 if self.isolation.is_hardware_isolated() {
434 return Ok(hvdef::HvPartitionPrivilege::default());
435 }
436
437 Ok(hvdef::HvPartitionPrivilege::from(
438 self.get_partition_vtl2_register(HvArchRegisterName::PrivilegesAndFeaturesInfo)?
439 .as_u64(),
440 ))
441 }
442 }
443
444 pub fn get_guest_os_id(
446 &self,
447 vtl: GuestVtl,
448 ) -> Result<hvdef::hypercall::HvGuestOsId, GetRegError> {
449 Ok(hvdef::hypercall::HvGuestOsId::from(
450 self.mshv_hvcall
451 .get_vp_register_hypercall(vtl.into(), HvArchRegisterName::GuestOsId)
452 .map_err(GetRegError::Hypercall)?
453 .as_u64(),
454 ))
455 }
456
457 pub fn set_vtl2_vsm_partition_config(
459 &self,
460 vsm_config: hvdef::HvRegisterVsmPartitionConfig,
461 ) -> Result<(), SetRegError> {
462 self.set_partition_vtl2_register(
463 HvArchRegisterName::VsmPartitionConfig,
464 HvRegisterValue::from(u64::from(vsm_config)),
465 )
466 }
467
468 pub fn set_guest_vsm_partition_config(
472 &self,
473 enable_guest_vsm: bool,
474 ) -> Result<(), SetRegError> {
475 let register_value = hvdef::HvRegisterGuestVsmPartitionConfig::new()
476 .with_maximum_vtl(if enable_guest_vsm { 1 } else { 0 })
477 .with_reserved(0);
478
479 tracing::trace!(enable_guest_vsm, "set_guest_vsm_partition_config");
480 if self.isolation.is_hardware_isolated() {
481 unimplemented!("set_guest_vsm_partition_config");
482 }
483
484 self.set_partition_vtl2_register(
485 HvArchRegisterName::GuestVsmPartitionConfig,
486 HvRegisterValue::from(u64::from(register_value)),
487 )
488 }
489
490 #[cfg(guest_arch = "x86_64")]
492 pub fn set_pm_timer_assist(&self, port: Option<u16>) -> Result<(), SetRegError> {
493 tracing::debug!(?port, "set_pm_timer_assist");
494 if self.isolation.is_hardware_isolated() {
495 if port.is_some() {
496 unimplemented!("set_pm_timer_assist");
497 }
498 }
499
500 let val = HvRegisterValue::from(u64::from(match port {
501 Some(p) => hvdef::HvPmTimerInfo::new()
502 .with_port(p)
503 .with_enabled(true)
504 .with_width_24(false),
505 None => 0.into(),
506 }));
507
508 self.set_partition_vtl2_register(HvArchRegisterName::PmTimerAssist, val)
509 }
510
511 #[cfg(guest_arch = "aarch64")]
513 pub fn set_pm_timer_assist(&self, port: Option<u16>) -> Result<(), SetRegError> {
514 tracing::debug!(?port, "set_pm_timer_assist unimplemented on aarch64");
515 Err(SetRegError::Hypercall(HvError::UnknownRegisterName))
516 }
517
518 fn get_partition_vtl2_register(
521 &self,
522 name: HvArchRegisterName,
523 ) -> Result<HvRegisterValue, GetRegError> {
524 #[cfg(guest_arch = "x86_64")]
525 let per_arch = false;
526
527 #[cfg(guest_arch = "aarch64")]
528 let per_arch = matches!(name, HvArchRegisterName::PrivilegesAndFeaturesInfo);
529
530 assert!(
531 matches!(
532 name,
533 HvArchRegisterName::GuestVsmPartitionConfig
534 | HvArchRegisterName::VsmPartitionConfig
535 | HvArchRegisterName::VsmPartitionStatus
536 | HvArchRegisterName::VsmCapabilities
537 | HvArchRegisterName::TimeRefCount
538 ) || per_arch
539 );
540 self.mshv_hvcall
541 .get_vp_register_hypercall(Vtl::Vtl2, name)
542 .map_err(GetRegError::Hypercall)
543 }
544
545 fn set_partition_vtl2_register(
548 &self,
549 name: HvArchRegisterName,
550 value: HvRegisterValue,
551 ) -> Result<(), SetRegError> {
552 #[cfg(guest_arch = "x86_64")]
553 let per_arch = matches!(name, HvArchRegisterName::PmTimerAssist);
554
555 #[cfg(guest_arch = "aarch64")]
556 let per_arch = false;
557
558 assert!(
559 matches!(
560 name,
561 HvArchRegisterName::GuestVsmPartitionConfig
562 | HvArchRegisterName::VsmPartitionConfig
563 ) || per_arch
564 );
565
566 self.mshv_hvcall
567 .set_vp_registers_hypercall(
568 Vtl::Vtl2,
569 &[HvRegisterAssoc {
570 name: name.into(),
571 pad: Default::default(),
572 value,
573 }],
574 )
575 .map_err(SetRegError::Hypercall)
576 }
577}
578
579impl MshvHvcall {
580 fn get_vp_register_hypercall(
586 &self,
587 vtl: Vtl,
588 name: HvArchRegisterName,
589 ) -> Result<HvRegisterValue, HvError> {
590 let mut value = [FromZeros::new_zeroed(); 1];
591 self.get_vp_registers_hypercall(vtl, &[name], &mut value)?;
592 Ok(value[0])
593 }
594
595 fn get_vp_registers_hypercall(
601 &self,
602 vtl: Vtl,
603 names: &[HvArchRegisterName],
604 values: &mut [HvRegisterValue],
605 ) -> Result<(), HvError> {
606 assert_eq!(names.len(), values.len());
607
608 let header = hvdef::hypercall::GetSetVpRegisters {
609 partition_id: HV_PARTITION_ID_SELF,
610 vp_index: HV_VP_INDEX_SELF,
611 target_vtl: vtl.into(),
612 rsvd: [0; 3],
613 };
614
615 let status = unsafe {
618 self.hvcall_rep(
619 HypercallCode::HvCallGetVpRegisters,
620 &header,
621 HvcallRepInput::Elements(names),
622 Some(values),
623 )
624 .expect("get_vp_registers hypercall should not fail")
625 };
626
627 status.result()?;
629 assert_eq!(status.elements_processed(), names.len());
630
631 Ok(())
632 }
633
634 fn set_vp_registers_hypercall(
640 &self,
641 vtl: Vtl,
642 registers: &[HvRegisterAssoc],
643 ) -> Result<(), HvError> {
644 let header = hvdef::hypercall::GetSetVpRegisters {
645 partition_id: HV_PARTITION_ID_SELF,
646 vp_index: HV_VP_INDEX_SELF,
647 target_vtl: vtl.into(),
648 rsvd: [0; 3],
649 };
650
651 let status = unsafe {
654 self.hvcall_rep::<hvdef::hypercall::GetSetVpRegisters, HvRegisterAssoc, u8>(
655 HypercallCode::HvCallSetVpRegisters,
656 &header,
657 HvcallRepInput::Elements(registers),
658 None,
659 )
660 .expect("set_vp_registers hypercall should not fail")
661 };
662
663 status.result()?;
665 Ok(())
666 }
667}
668
669fn is_vtl_shared_reg(reg: HvArchRegisterName) -> bool {
677 #[cfg(guest_arch = "x86_64")]
678 {
679 matches!(
680 reg,
681 HvArchRegisterName::VpIndex
682 | HvArchRegisterName::VpRuntime
683 | HvArchRegisterName::TimeRefCount
684 | HvArchRegisterName::Rax
685 | HvArchRegisterName::Rbx
686 | HvArchRegisterName::Rcx
687 | HvArchRegisterName::Rdx
688 | HvArchRegisterName::Rsi
689 | HvArchRegisterName::Rdi
690 | HvArchRegisterName::Rbp
691 | HvArchRegisterName::Cr2
692 | HvArchRegisterName::R8
693 | HvArchRegisterName::R9
694 | HvArchRegisterName::R10
695 | HvArchRegisterName::R11
696 | HvArchRegisterName::R12
697 | HvArchRegisterName::R13
698 | HvArchRegisterName::R14
699 | HvArchRegisterName::R15
700 | HvArchRegisterName::Dr0
701 | HvArchRegisterName::Dr1
702 | HvArchRegisterName::Dr2
703 | HvArchRegisterName::Dr3
704 | HvArchRegisterName::Xmm0
705 | HvArchRegisterName::Xmm1
706 | HvArchRegisterName::Xmm2
707 | HvArchRegisterName::Xmm3
708 | HvArchRegisterName::Xmm4
709 | HvArchRegisterName::Xmm5
710 | HvArchRegisterName::Xmm6
711 | HvArchRegisterName::Xmm7
712 | HvArchRegisterName::Xmm8
713 | HvArchRegisterName::Xmm9
714 | HvArchRegisterName::Xmm10
715 | HvArchRegisterName::Xmm11
716 | HvArchRegisterName::Xmm12
717 | HvArchRegisterName::Xmm13
718 | HvArchRegisterName::Xmm14
719 | HvArchRegisterName::Xmm15
720 | HvArchRegisterName::FpMmx0
721 | HvArchRegisterName::FpMmx1
722 | HvArchRegisterName::FpMmx2
723 | HvArchRegisterName::FpMmx3
724 | HvArchRegisterName::FpMmx4
725 | HvArchRegisterName::FpMmx5
726 | HvArchRegisterName::FpMmx6
727 | HvArchRegisterName::FpMmx7
728 | HvArchRegisterName::FpControlStatus
729 | HvArchRegisterName::XmmControlStatus
730 | HvArchRegisterName::Xfem
731 | HvArchRegisterName::MsrMtrrCap
732 | HvArchRegisterName::MsrMtrrDefType
733 | HvArchRegisterName::MsrMtrrPhysBase0
734 | HvArchRegisterName::MsrMtrrPhysBase1
735 | HvArchRegisterName::MsrMtrrPhysBase2
736 | HvArchRegisterName::MsrMtrrPhysBase3
737 | HvArchRegisterName::MsrMtrrPhysBase4
738 | HvArchRegisterName::MsrMtrrPhysBase5
739 | HvArchRegisterName::MsrMtrrPhysBase6
740 | HvArchRegisterName::MsrMtrrPhysBase7
741 | HvArchRegisterName::MsrMtrrPhysBase8
742 | HvArchRegisterName::MsrMtrrPhysBase9
743 | HvArchRegisterName::MsrMtrrPhysBaseA
744 | HvArchRegisterName::MsrMtrrPhysBaseB
745 | HvArchRegisterName::MsrMtrrPhysBaseC
746 | HvArchRegisterName::MsrMtrrPhysBaseD
747 | HvArchRegisterName::MsrMtrrPhysBaseE
748 | HvArchRegisterName::MsrMtrrPhysBaseF
749 | HvArchRegisterName::MsrMtrrPhysMask0
750 | HvArchRegisterName::MsrMtrrPhysMask1
751 | HvArchRegisterName::MsrMtrrPhysMask2
752 | HvArchRegisterName::MsrMtrrPhysMask3
753 | HvArchRegisterName::MsrMtrrPhysMask4
754 | HvArchRegisterName::MsrMtrrPhysMask5
755 | HvArchRegisterName::MsrMtrrPhysMask6
756 | HvArchRegisterName::MsrMtrrPhysMask7
757 | HvArchRegisterName::MsrMtrrPhysMask8
758 | HvArchRegisterName::MsrMtrrPhysMask9
759 | HvArchRegisterName::MsrMtrrPhysMaskA
760 | HvArchRegisterName::MsrMtrrPhysMaskB
761 | HvArchRegisterName::MsrMtrrPhysMaskC
762 | HvArchRegisterName::MsrMtrrPhysMaskD
763 | HvArchRegisterName::MsrMtrrPhysMaskE
764 | HvArchRegisterName::MsrMtrrPhysMaskF
765 | HvArchRegisterName::MsrMtrrFix64k00000
766 | HvArchRegisterName::MsrMtrrFix16k80000
767 | HvArchRegisterName::MsrMtrrFix16kA0000
768 | HvArchRegisterName::MsrMtrrFix4kC0000
769 | HvArchRegisterName::MsrMtrrFix4kC8000
770 | HvArchRegisterName::MsrMtrrFix4kD0000
771 | HvArchRegisterName::MsrMtrrFix4kD8000
772 | HvArchRegisterName::MsrMtrrFix4kE0000
773 | HvArchRegisterName::MsrMtrrFix4kE8000
774 | HvArchRegisterName::MsrMtrrFix4kF0000
775 | HvArchRegisterName::MsrMtrrFix4kF8000
776 )
777 }
778
779 #[cfg(guest_arch = "aarch64")]
780 {
781 matches!(
782 reg,
783 HvArchRegisterName::X0
784 | HvArchRegisterName::X1
785 | HvArchRegisterName::X2
786 | HvArchRegisterName::X3
787 | HvArchRegisterName::X4
788 | HvArchRegisterName::X5
789 | HvArchRegisterName::X6
790 | HvArchRegisterName::X7
791 | HvArchRegisterName::X8
792 | HvArchRegisterName::X9
793 | HvArchRegisterName::X10
794 | HvArchRegisterName::X11
795 | HvArchRegisterName::X12
796 | HvArchRegisterName::X13
797 | HvArchRegisterName::X14
798 | HvArchRegisterName::X15
799 | HvArchRegisterName::X16
800 | HvArchRegisterName::X17
801 | HvArchRegisterName::X19
802 | HvArchRegisterName::X20
803 | HvArchRegisterName::X21
804 | HvArchRegisterName::X22
805 | HvArchRegisterName::X23
806 | HvArchRegisterName::X24
807 | HvArchRegisterName::X25
808 | HvArchRegisterName::X26
809 | HvArchRegisterName::X27
810 | HvArchRegisterName::X28
811 | HvArchRegisterName::XFp
812 | HvArchRegisterName::XLr
813 )
814 }
815}