[Lguest] [PATCH v2] lguest: Change over to using KVM hypercalls mechanism
Rusty Russell
rusty at rustcorp.com.au
Fri Oct 24 02:53:25 EST 2008
On Thursday 23 October 2008 09:32:06 Matias Zabaljauregui wrote:
> This patch allows us to use KVM hypercalls.
Thanks!
A few minor comments....
> +static void rewrite_hypercall(struct lg_cpu *cpu)
> +{
> + unsigned long physaddr = guest_pa(cpu, cpu->regs->eip);
> +
> + /* This are the opcodes we use to patch the guest.
> + * The opcode for "int $ox1f" is 0xcd 0x1f
> + * but vmcall instruction is 3 bytes long, so we complete
> + * the sequence with a NOP (0x90). */
> + u8 insn[3] = {0xcd, 0x1f, 0x90};
> +
> + lgwrite(cpu, physaddr, u8, insn[0]);
> + lgwrite(cpu, physaddr + 1, u8, insn[1]);
> + lgwrite(cpu, physaddr + 2, u8, insn[2]);
I think this is a good opportunity to use __lgwrite().
Also, above this function there should be a longer explanation, showing
your benchmarks as to why it's worth having this second hcall method.
(I know, but it's good reading for new hackers!).
> + /* The eip contains the *virtual* address of the Guest's instruction:
> + * guest_pa just subtracts the Guest's page_offset. */
> + unsigned long physaddr = guest_pa(cpu, cpu->regs->eip);
> +
> + /* This must be the Guest kernel trying to do something.
> + * The bottom two bits of the CS segment register are the privilege
> + * level. */
> + if ((cpu->regs->cs & 3) != GUEST_PL)
> + return 0;
> +
> + /* Is it a vmcall? */
> + insn[0] = lgread(cpu, physaddr, u8);
> + insn[1] = lgread(cpu, physaddr + 1, u8);
> + insn[2] = lgread(cpu, physaddr + 2, u8);
I think this can be done in one line with __lgread, as well:
__lgread(cpu, insn, guest_pa(cpu, cpu->regs->eip), sizeof(insn));
> + if (insn[0] != 0x0f || insn[1] != 0x01 || insn[2] != 0xc1)
> + return 0;
> +
> + return 1;
I've become a fan of "bool", perhaps this function should return bool, and also:
return insn[0] == 0x0f && insn[1] == 0x01 && insn[2] == 0xc1;
Thanks!
Rusty.
More information about the Lguest
mailing list