Commit c0000e58 authored by Shameer Kolothum's avatar Shameer Kolothum Committed by Oliver Upton
Browse files

KVM: arm64: Introduce KVM_REG_ARM_VENDOR_HYP_BMAP_2



The vendor_hyp_bmap bitmap holds the information about the Vendor Hyp
services available to the user space and can be get/set using
{G, S}ET_ONE_REG interfaces. This is done using the pseudo-firmware
bitmap register KVM_REG_ARM_VENDOR_HYP_BMAP.

At present, this bitmap is a 64 bit one and since the function numbers
for newly added DISCOVER_IPML_* hypercalls are 64-65, introduce
another pseudo-firmware bitmap register KVM_REG_ARM_VENDOR_HYP_BMAP_2.

Reviewed-by: default avatarSebastian Ott <sebott@redhat.com>
Signed-off-by: default avatarShameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Link: https://lore.kernel.org/r/20250221140229.12588-4-shameerali.kolothum.thodi@huawei.com


Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
parent 57e5cc9b
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@ The pseudo-firmware bitmap register are as follows:
      ARM DEN0057A.

* KVM_REG_ARM_VENDOR_HYP_BMAP:
    Controls the bitmap of the Vendor specific Hypervisor Service Calls.
    Controls the bitmap of the Vendor specific Hypervisor Service Calls[0-63].

  The following bits are accepted:

@@ -127,6 +127,19 @@ The pseudo-firmware bitmap register are as follows:
    Bit-1: KVM_REG_ARM_VENDOR_HYP_BIT_PTP:
      The bit represents the Precision Time Protocol KVM service.

* KVM_REG_ARM_VENDOR_HYP_BMAP_2:
    Controls the bitmap of the Vendor specific Hypervisor Service Calls[64-127].

  The following bits are accepted:

    Bit-0: KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_VER
      This represents the ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID
      function-id. This is reset to 0.

    Bit-1: KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_CPUS
      This represents the ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID
      function-id. This is reset to 0.

Errors:

    =======  =============================================================
+2 −1
Original line number Diff line number Diff line
@@ -237,7 +237,8 @@ struct kvm_arch_memory_slot {
struct kvm_smccc_features {
	unsigned long std_bmap;
	unsigned long std_hyp_bmap;
	unsigned long vendor_hyp_bmap;
	unsigned long vendor_hyp_bmap; /* Function numbers 0-63 */
	unsigned long vendor_hyp_bmap_2; /* Function numbers 64-127 */
};

typedef unsigned int pkvm_handle_t;
+12 −0
Original line number Diff line number Diff line
@@ -371,6 +371,7 @@ enum {
#endif
};

/* Vendor hyper call function numbers 0-63 */
#define KVM_REG_ARM_VENDOR_HYP_BMAP		KVM_REG_ARM_FW_FEAT_BMAP_REG(2)

enum {
@@ -381,6 +382,17 @@ enum {
#endif
};

/* Vendor hyper call function numbers 64-127 */
#define KVM_REG_ARM_VENDOR_HYP_BMAP_2		KVM_REG_ARM_FW_FEAT_BMAP_REG(3)

enum {
	KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_VER	= 0,
	KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_CPUS	= 1,
#ifdef __KERNEL__
	KVM_REG_ARM_VENDOR_HYP_BMAP_2_BIT_COUNT,
#endif
};

/* Device Control API on vm fd */
#define KVM_ARM_VM_SMCCC_CTRL		0
#define   KVM_ARM_VM_SMCCC_FILTER	0
+13 −0
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
	GENMASK(KVM_REG_ARM_STD_HYP_BMAP_BIT_COUNT - 1, 0)
#define KVM_ARM_SMCCC_VENDOR_HYP_FEATURES			\
	GENMASK(KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT - 1, 0)
#define KVM_ARM_SMCCC_VENDOR_HYP_FEATURES_2			\
	GENMASK(KVM_REG_ARM_VENDOR_HYP_BMAP_2_BIT_COUNT - 1, 0)

static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
{
@@ -360,6 +362,8 @@ int kvm_smccc_call_handler(struct kvm_vcpu *vcpu)
		break;
	case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
		val[0] = smccc_feat->vendor_hyp_bmap;
		/* Function numbers 2-63 are reserved for pKVM for now */
		val[2] = smccc_feat->vendor_hyp_bmap_2;
		break;
	case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
		kvm_ptp_get_time(vcpu, val);
@@ -387,6 +391,7 @@ static const u64 kvm_arm_fw_reg_ids[] = {
	KVM_REG_ARM_STD_BMAP,
	KVM_REG_ARM_STD_HYP_BMAP,
	KVM_REG_ARM_VENDOR_HYP_BMAP,
	KVM_REG_ARM_VENDOR_HYP_BMAP_2,
};

void kvm_arm_init_hypercalls(struct kvm *kvm)
@@ -497,6 +502,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
	case KVM_REG_ARM_VENDOR_HYP_BMAP:
		val = READ_ONCE(smccc_feat->vendor_hyp_bmap);
		break;
	case KVM_REG_ARM_VENDOR_HYP_BMAP_2:
		val = READ_ONCE(smccc_feat->vendor_hyp_bmap_2);
		break;
	default:
		return -ENOENT;
	}
@@ -527,6 +535,10 @@ static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 val)
		fw_reg_bmap = &smccc_feat->vendor_hyp_bmap;
		fw_reg_features = KVM_ARM_SMCCC_VENDOR_HYP_FEATURES;
		break;
	case KVM_REG_ARM_VENDOR_HYP_BMAP_2:
		fw_reg_bmap = &smccc_feat->vendor_hyp_bmap_2;
		fw_reg_features = KVM_ARM_SMCCC_VENDOR_HYP_FEATURES_2;
		break;
	default:
		return -ENOENT;
	}
@@ -633,6 +645,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
	case KVM_REG_ARM_STD_BMAP:
	case KVM_REG_ARM_STD_HYP_BMAP:
	case KVM_REG_ARM_VENDOR_HYP_BMAP:
	case KVM_REG_ARM_VENDOR_HYP_BMAP_2:
		return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val);
	default:
		return -ENOENT;