From mboxrd@z Thu Jan 1 00:00:00 1970 From: Avi Kivity Subject: Re: [PATCH 7/24] Understanding guest pointers to vmcs12 structures Date: Mon, 14 Jun 2010 11:48:17 +0300 Message-ID: <4C15ECD1.1070108@redhat.com> References: <1276431753-nyh@il.ibm.com> <201006131226.o5DCQ95O012945@rice.haifa.ibm.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: kvm@vger.kernel.org To: "Nadav Har'El" Return-path: Received: from mx1.redhat.com ([209.132.183.28]:39540 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755587Ab0FNIsV (ORCPT ); Mon, 14 Jun 2010 04:48:21 -0400 In-Reply-To: <201006131226.o5DCQ95O012945@rice.haifa.ibm.com> Sender: kvm-owner@vger.kernel.org List-ID: 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)< + 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