kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Avi Kivity <avi@redhat.com>
To: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>, kvm@vger.kernel.org
Subject: Re: [PATCH] KVM: x86 emulator: access GPRs on demand
Date: Wed, 08 Aug 2012 15:38:33 +0300	[thread overview]
Message-ID: <50225DC9.4030206@redhat.com> (raw)
In-Reply-To: <20120807212301.GA6689@amt.cnet>

On 08/08/2012 12:23 AM, Marcelo Tosatti wrote:
>> @@ -281,8 +294,10 @@ struct x86_emulate_ctxt {
>>  	bool rip_relative;
>>  	unsigned long _eip;
>>  	struct operand memop;
>> +	u32 regs_valid;  /* bitmaps of registers in _regs[] that can be read */
>> +	u32 regs_dirty;  /* bitmaps of registers in _regs[] that have been written */
> 
> emul_regs_dirty (to avoid with the other regs_dirty).

Well, it's in x86_emulate_ctxt, and there are other fields that can be
confused here.  I think it's okay as they're never used together.

>>  
>> @@ -4453,7 +4447,6 @@ int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip)
>>  		return EMULATE_FAIL;
>>  
>>  	ctxt->eip = ctxt->_eip;
>> -	memcpy(vcpu->arch.regs, ctxt->regs, sizeof ctxt->regs);
>>  	kvm_rip_write(vcpu, ctxt->eip);
>>  	kvm_set_rflags(vcpu, ctxt->eflags);
> 
> 
> Need to writeback here?

In emulate_in_real().  Good catch.

> 
>> @@ -4601,7 +4594,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu,
>>  	   changes registers values  during IO operation */
>>  	if (vcpu->arch.emulate_regs_need_sync_from_vcpu) {
>>  		vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
>> -		memcpy(ctxt->regs, vcpu->arch.regs, sizeof ctxt->regs);
>> +		ctxt->regs_valid = 0;
>>  	}
> 
> I think you can improve this hack now (perhaps invalidate the emulator
> cache on SET_REGS?).

This is dangerous, if someone does a GET_REGS/SET_REGS pair within an
mmio transaction.

The documentation implies it should not be done, but it doesn't say so
explicitly.  It's likely qemu allows it if the mmio transaction drops
the lock, for example.

I agree that doing it in SET_REGS is better conceptually.

> 
>>  		vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
>>  	}
>>  	regs->rax = kvm_register_read(vcpu, VCPU_REGS_RAX);
>> @@ -5724,6 +5720,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index,
>>  {
>>  	struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt;
>>  	int ret;
>> +	unsigned reg;
>>  
>>  	init_emulate_ctxt(vcpu);
>>  
>> @@ -5733,7 +5730,8 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int idt_index,
>>  	if (ret)
>>  		return EMULATE_FAIL;
>>  
>> -	memcpy(vcpu->arch.regs, ctxt->regs, sizeof ctxt->regs);
>> +	for_each_set_bit(reg, (ulong *)&ctxt->regs_dirty, 16)
>> +		kvm_register_write(vcpu, reg, ctxt->_regs[reg]);
> 
> Should update regs_avail/regs_dirty? Better to do any of that in
> emulator.c via interfaces.

emulator_task_switch() should do it, yes.

> 
>>  	kvm_rip_write(vcpu, ctxt->eip);
>>  	kvm_set_rflags(vcpu, ctxt->eflags);
>>  	kvm_make_request(KVM_REQ_EVENT, vcpu);
>> -- 
>> 1.7.11.2
> 
> Did not double check that emulator.c convertion is complete with your
> patch (which should be done).

I did s/regs/_regs/ for that.  Or did you mean something else?

Regarding emulator interfaces, perhaps we should make all entry points
regular:

  emulator_init(ctxt, ops, vcpu); // just once

  emulator_reset(ctxt)
  while ((ret = emulator_entry_point(ctxt)) == EMULATOR_NEED_DATA)
       get that data from somewhere

emulator_reset() simply resets the state machine, can be as simple as
clearing a bool flag. emulator_entry_point (can be x86_emulate_insn(),
x86_emulate_int(), x86_emulate_task_switch(), etc.) runs until one of
the callbacks tells it to stop to get more data.

(of course the while loop is actually in userspace)


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

      parent reply	other threads:[~2012-08-08 12:38 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-19 12:14 [PATCH] KVM: x86 emulator: access GPRs on demand Avi Kivity
2012-08-07 21:23 ` Marcelo Tosatti
2012-08-07 21:24   ` Marcelo Tosatti
2012-08-08 12:38   ` Avi Kivity [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=50225DC9.4030206@redhat.com \
    --to=avi@redhat.com \
    --cc=gleb@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mtosatti@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).