Re: [PATCH 7/24] Understanding guest pointers to vmcs12 structures

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 06/13/2010 03:26 PM, Nadav Har'El wrote:
This patch includes a couple of utility functions for extracting pointer
operands of VMX instructions issued by L1 (a guest hypervisor), and
translating guest-given vmcs12 virtual addresses to guest-physical addresses.

+/*
+ * Decode the memory-address operand of a vmx instruction, according to the
+ * Intel spec.
+ */
+#define VMX_OPERAND_SCALING(vii)	((vii)&  3)
+#define VMX_OPERAND_ADDR_SIZE(vii)	(((vii)>>  7)&  7)
+#define VMX_OPERAND_IS_REG(vii)		((vii)&  (1u<<  10))
+#define VMX_OPERAND_SEG_REG(vii)	(((vii)>>  15)&  7)
+#define VMX_OPERAND_INDEX_REG(vii)	(((vii)>>  18)&  0xf)
+#define VMX_OPERAND_INDEX_INVALID(vii)	((vii)&  (1u<<  22))
+#define VMX_OPERAND_BASE_REG(vii)	(((vii)>>  23)&  0xf)
+#define VMX_OPERAND_BASE_INVALID(vii)	((vii)&  (1u<<  27))
+#define VMX_OPERAND_REG(vii)		(((vii)>>  3)&  0xf)
+#define VMX_OPERAND_REG2(vii)		(((vii)>>  28)&  0xf)
+static gva_t get_vmx_mem_address(struct kvm_vcpu *vcpu,
+				 unsigned long exit_qualification,
+				 u32 vmx_instruction_info)
+{
+	int  scaling = VMX_OPERAND_SCALING(vmx_instruction_info);
+	int  addr_size = VMX_OPERAND_ADDR_SIZE(vmx_instruction_info);
+	bool is_reg = VMX_OPERAND_IS_REG(vmx_instruction_info);
+	int  seg_reg = VMX_OPERAND_SEG_REG(vmx_instruction_info);
+	int  index_reg = VMX_OPERAND_SEG_REG(vmx_instruction_info);
+	bool index_is_valid = !VMX_OPERAND_INDEX_INVALID(vmx_instruction_info);
+	int  base_reg       = VMX_OPERAND_BASE_REG(vmx_instruction_info);
+	bool base_is_valid  = !VMX_OPERAND_BASE_INVALID(vmx_instruction_info);

Since those defines are used just ones, you can fold them into their uses. It doesn't add much to repeat the variable name.

+	gva_t addr;
+
+	if (is_reg) {
+		kvm_queue_exception(vcpu, UD_VECTOR);
+		return 0;
+	}
+
+	switch (addr_size) {
+	case 1: /* 32 bit. high bits are undefined according to the spec: */
+		exit_qualification&= 0xffffffff;
+		break;
+	case 2: /* 64 bit */
+		break;
+	default: /* addr_size=0 means 16 bit */
+		return 0;
+	}
+
+	/* Addr = segment_base + offset */
+	/* offfset = Base + [Index * Scale] + Displacement */
+	addr = vmx_get_segment_base(vcpu, seg_reg);
+	if (base_is_valid)
+		addr += kvm_register_read(vcpu, base_reg);
+	if (index_is_valid)
+		addr += kvm_register_read(vcpu, index_reg)<<scaling;
+	addr += exit_qualification; /* holds the displacement */

Do we need a segment limit and access rights check?

+
+	return addr;
+}
+

--
error compiling committee.c: too many arguments to function

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux