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 [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to