@@ -382,6 +382,34 @@ static int kvm_riscv_vcpu_general_set_csr(struct kvm_vcpu *vcpu,
382382 return 0 ;
383383}
384384
385+ static inline int kvm_riscv_vcpu_smstateen_set_csr (struct kvm_vcpu * vcpu ,
386+ unsigned long reg_num ,
387+ unsigned long reg_val )
388+ {
389+ struct kvm_vcpu_smstateen_csr * csr = & vcpu -> arch .smstateen_csr ;
390+
391+ if (reg_num >= sizeof (struct kvm_riscv_smstateen_csr ) /
392+ sizeof (unsigned long ))
393+ return - EINVAL ;
394+
395+ ((unsigned long * )csr )[reg_num ] = reg_val ;
396+ return 0 ;
397+ }
398+
399+ static int kvm_riscv_vcpu_smstateen_get_csr (struct kvm_vcpu * vcpu ,
400+ unsigned long reg_num ,
401+ unsigned long * out_val )
402+ {
403+ struct kvm_vcpu_smstateen_csr * csr = & vcpu -> arch .smstateen_csr ;
404+
405+ if (reg_num >= sizeof (struct kvm_riscv_smstateen_csr ) /
406+ sizeof (unsigned long ))
407+ return - EINVAL ;
408+
409+ * out_val = ((unsigned long * )csr )[reg_num ];
410+ return 0 ;
411+ }
412+
385413static int kvm_riscv_vcpu_get_reg_csr (struct kvm_vcpu * vcpu ,
386414 const struct kvm_one_reg * reg )
387415{
@@ -405,6 +433,12 @@ static int kvm_riscv_vcpu_get_reg_csr(struct kvm_vcpu *vcpu,
405433 case KVM_REG_RISCV_CSR_AIA :
406434 rc = kvm_riscv_vcpu_aia_get_csr (vcpu , reg_num , & reg_val );
407435 break ;
436+ case KVM_REG_RISCV_CSR_SMSTATEEN :
437+ rc = - EINVAL ;
438+ if (riscv_has_extension_unlikely (RISCV_ISA_EXT_SMSTATEEN ))
439+ rc = kvm_riscv_vcpu_smstateen_get_csr (vcpu , reg_num ,
440+ & reg_val );
441+ break ;
408442 default :
409443 rc = - ENOENT ;
410444 break ;
@@ -444,6 +478,12 @@ static int kvm_riscv_vcpu_set_reg_csr(struct kvm_vcpu *vcpu,
444478 case KVM_REG_RISCV_CSR_AIA :
445479 rc = kvm_riscv_vcpu_aia_set_csr (vcpu , reg_num , reg_val );
446480 break ;
481+ case KVM_REG_RISCV_CSR_SMSTATEEN :
482+ rc = - EINVAL ;
483+ if (riscv_has_extension_unlikely (RISCV_ISA_EXT_SMSTATEEN ))
484+ rc = kvm_riscv_vcpu_smstateen_set_csr (vcpu , reg_num ,
485+ reg_val );
486+ break ;
447487 default :
448488 rc = - ENOENT ;
449489 break ;
@@ -700,6 +740,8 @@ static inline unsigned long num_csr_regs(const struct kvm_vcpu *vcpu)
700740
701741 if (riscv_isa_extension_available (vcpu -> arch .isa , SSAIA ))
702742 n += sizeof (struct kvm_riscv_aia_csr ) / sizeof (unsigned long );
743+ if (riscv_isa_extension_available (vcpu -> arch .isa , SMSTATEEN ))
744+ n += sizeof (struct kvm_riscv_smstateen_csr ) / sizeof (unsigned long );
703745
704746 return n ;
705747}
@@ -708,7 +750,7 @@ static int copy_csr_reg_indices(const struct kvm_vcpu *vcpu,
708750 u64 __user * uindices )
709751{
710752 int n1 = sizeof (struct kvm_riscv_csr ) / sizeof (unsigned long );
711- int n2 = 0 ;
753+ int n2 = 0 , n3 = 0 ;
712754
713755 /* copy general csr regs */
714756 for (int i = 0 ; i < n1 ; i ++ ) {
@@ -742,7 +784,25 @@ static int copy_csr_reg_indices(const struct kvm_vcpu *vcpu,
742784 }
743785 }
744786
745- return n1 + n2 ;
787+ /* copy Smstateen csr regs */
788+ if (riscv_isa_extension_available (vcpu -> arch .isa , SMSTATEEN )) {
789+ n3 = sizeof (struct kvm_riscv_smstateen_csr ) / sizeof (unsigned long );
790+
791+ for (int i = 0 ; i < n3 ; i ++ ) {
792+ u64 size = IS_ENABLED (CONFIG_32BIT ) ?
793+ KVM_REG_SIZE_U32 : KVM_REG_SIZE_U64 ;
794+ u64 reg = KVM_REG_RISCV | size | KVM_REG_RISCV_CSR |
795+ KVM_REG_RISCV_CSR_SMSTATEEN | i ;
796+
797+ if (uindices ) {
798+ if (put_user (reg , uindices ))
799+ return - EFAULT ;
800+ uindices ++ ;
801+ }
802+ }
803+ }
804+
805+ return n1 + n2 + n3 ;
746806}
747807
748808static inline unsigned long num_timer_regs (void )
0 commit comments