@@ -460,27 +460,72 @@ static int kvm_riscv_vcpu_set_reg_core(struct kvm_vcpu *vcpu,
460460 return 0 ;
461461}
462462
463+ static int kvm_riscv_vcpu_general_get_csr (struct kvm_vcpu * vcpu ,
464+ unsigned long reg_num ,
465+ unsigned long * out_val )
466+ {
467+ struct kvm_vcpu_csr * csr = & vcpu -> arch .guest_csr ;
468+
469+ if (reg_num >= sizeof (struct kvm_riscv_csr ) / sizeof (unsigned long ))
470+ return - EINVAL ;
471+
472+ if (reg_num == KVM_REG_RISCV_CSR_REG (sip )) {
473+ kvm_riscv_vcpu_flush_interrupts (vcpu );
474+ * out_val = (csr -> hvip >> VSIP_TO_HVIP_SHIFT ) & VSIP_VALID_MASK ;
475+ } else
476+ * out_val = ((unsigned long * )csr )[reg_num ];
477+
478+ return 0 ;
479+ }
480+
481+ static inline int kvm_riscv_vcpu_general_set_csr (struct kvm_vcpu * vcpu ,
482+ unsigned long reg_num ,
483+ unsigned long reg_val )
484+ {
485+ struct kvm_vcpu_csr * csr = & vcpu -> arch .guest_csr ;
486+
487+ if (reg_num >= sizeof (struct kvm_riscv_csr ) / sizeof (unsigned long ))
488+ return - EINVAL ;
489+
490+ if (reg_num == KVM_REG_RISCV_CSR_REG (sip )) {
491+ reg_val &= VSIP_VALID_MASK ;
492+ reg_val <<= VSIP_TO_HVIP_SHIFT ;
493+ }
494+
495+ ((unsigned long * )csr )[reg_num ] = reg_val ;
496+
497+ if (reg_num == KVM_REG_RISCV_CSR_REG (sip ))
498+ WRITE_ONCE (vcpu -> arch .irqs_pending_mask , 0 );
499+
500+ return 0 ;
501+ }
502+
463503static int kvm_riscv_vcpu_get_reg_csr (struct kvm_vcpu * vcpu ,
464504 const struct kvm_one_reg * reg )
465505{
466- struct kvm_vcpu_csr * csr = & vcpu -> arch . guest_csr ;
506+ int rc ;
467507 unsigned long __user * uaddr =
468508 (unsigned long __user * )(unsigned long )reg -> addr ;
469509 unsigned long reg_num = reg -> id & ~(KVM_REG_ARCH_MASK |
470510 KVM_REG_SIZE_MASK |
471511 KVM_REG_RISCV_CSR );
472- unsigned long reg_val ;
512+ unsigned long reg_val , reg_subtype ;
473513
474514 if (KVM_REG_SIZE (reg -> id ) != sizeof (unsigned long ))
475515 return - EINVAL ;
476- if (reg_num >= sizeof (struct kvm_riscv_csr ) / sizeof (unsigned long ))
477- return - EINVAL ;
478516
479- if (reg_num == KVM_REG_RISCV_CSR_REG (sip )) {
480- kvm_riscv_vcpu_flush_interrupts (vcpu );
481- reg_val = (csr -> hvip >> VSIP_TO_HVIP_SHIFT ) & VSIP_VALID_MASK ;
482- } else
483- reg_val = ((unsigned long * )csr )[reg_num ];
517+ reg_subtype = reg_num & KVM_REG_RISCV_SUBTYPE_MASK ;
518+ reg_num &= ~KVM_REG_RISCV_SUBTYPE_MASK ;
519+ switch (reg_subtype ) {
520+ case KVM_REG_RISCV_CSR_GENERAL :
521+ rc = kvm_riscv_vcpu_general_get_csr (vcpu , reg_num , & reg_val );
522+ break ;
523+ default :
524+ rc = - EINVAL ;
525+ break ;
526+ }
527+ if (rc )
528+ return rc ;
484529
485530 if (copy_to_user (uaddr , & reg_val , KVM_REG_SIZE (reg -> id )))
486531 return - EFAULT ;
@@ -491,31 +536,32 @@ static int kvm_riscv_vcpu_get_reg_csr(struct kvm_vcpu *vcpu,
491536static int kvm_riscv_vcpu_set_reg_csr (struct kvm_vcpu * vcpu ,
492537 const struct kvm_one_reg * reg )
493538{
494- struct kvm_vcpu_csr * csr = & vcpu -> arch . guest_csr ;
539+ int rc ;
495540 unsigned long __user * uaddr =
496541 (unsigned long __user * )(unsigned long )reg -> addr ;
497542 unsigned long reg_num = reg -> id & ~(KVM_REG_ARCH_MASK |
498543 KVM_REG_SIZE_MASK |
499544 KVM_REG_RISCV_CSR );
500- unsigned long reg_val ;
545+ unsigned long reg_val , reg_subtype ;
501546
502547 if (KVM_REG_SIZE (reg -> id ) != sizeof (unsigned long ))
503548 return - EINVAL ;
504- if (reg_num >= sizeof (struct kvm_riscv_csr ) / sizeof (unsigned long ))
505- return - EINVAL ;
506549
507550 if (copy_from_user (& reg_val , uaddr , KVM_REG_SIZE (reg -> id )))
508551 return - EFAULT ;
509552
510- if (reg_num == KVM_REG_RISCV_CSR_REG (sip )) {
511- reg_val &= VSIP_VALID_MASK ;
512- reg_val <<= VSIP_TO_HVIP_SHIFT ;
553+ reg_subtype = reg_num & KVM_REG_RISCV_SUBTYPE_MASK ;
554+ reg_num &= ~KVM_REG_RISCV_SUBTYPE_MASK ;
555+ switch (reg_subtype ) {
556+ case KVM_REG_RISCV_CSR_GENERAL :
557+ rc = kvm_riscv_vcpu_general_set_csr (vcpu , reg_num , reg_val );
558+ break ;
559+ default :
560+ rc = - EINVAL ;
561+ break ;
513562 }
514-
515- ((unsigned long * )csr )[reg_num ] = reg_val ;
516-
517- if (reg_num == KVM_REG_RISCV_CSR_REG (sip ))
518- WRITE_ONCE (vcpu -> arch .irqs_pending_mask , 0 );
563+ if (rc )
564+ return rc ;
519565
520566 return 0 ;
521567}
0 commit comments