Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 54060
b: refs/heads/master
c: 46fc147
h: refs/heads/master
v: v3
  • Loading branch information
Avi Kivity committed May 3, 2007
1 parent 503aafc commit d543a84
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9a2bb7f486dc639a1cf2ad803bf2227f0dc0809d
refs/heads/master: 46fc1477887c41c8e900f2c95485e222b9a54822
1 change: 1 addition & 0 deletions trunk/drivers/kvm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ struct kvm_vcpu {
int mmio_size;
unsigned char mmio_data[8];
gpa_t mmio_phys_addr;
int pio_pending;

struct {
int active;
Expand Down
48 changes: 45 additions & 3 deletions trunk/drivers/kvm/kvm_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1504,6 +1504,44 @@ void save_msrs(struct vmx_msr_entry *e, int n)
}
EXPORT_SYMBOL_GPL(save_msrs);

static void complete_pio(struct kvm_vcpu *vcpu)
{
struct kvm_io *io = &vcpu->run->io;
long delta;

kvm_arch_ops->cache_regs(vcpu);

if (!io->string) {
if (io->direction == KVM_EXIT_IO_IN)
memcpy(&vcpu->regs[VCPU_REGS_RAX], &io->value,
io->size);
} else {
delta = 1;
if (io->rep) {
delta *= io->count;
/*
* The size of the register should really depend on
* current address size.
*/
vcpu->regs[VCPU_REGS_RCX] -= delta;
}
if (io->string_down)
delta = -delta;
delta *= io->size;
if (io->direction == KVM_EXIT_IO_IN)
vcpu->regs[VCPU_REGS_RDI] += delta;
else
vcpu->regs[VCPU_REGS_RSI] += delta;
}

vcpu->pio_pending = 0;
vcpu->run->io_completed = 0;

kvm_arch_ops->decache_regs(vcpu);

kvm_arch_ops->skip_emulated_instruction(vcpu);
}

static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
int r;
Expand All @@ -1518,9 +1556,13 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
kvm_run->emulated = 0;
}

if (kvm_run->mmio_completed) {
memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
vcpu->mmio_read_completed = 1;
if (kvm_run->io_completed) {
if (vcpu->pio_pending)
complete_pio(vcpu);
else {
memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
vcpu->mmio_read_completed = 1;
}
}

vcpu->mmio_needed = 0;
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/kvm/svm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,7 @@ static int io_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
kvm_run->io.size = ((io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT);
kvm_run->io.string = (io_info & SVM_IOIO_STR_MASK) != 0;
kvm_run->io.rep = (io_info & SVM_IOIO_REP_MASK) != 0;
kvm_run->io.count = 1;

if (kvm_run->io.string) {
unsigned addr_mask;
Expand All @@ -1056,6 +1057,7 @@ static int io_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
}
} else
kvm_run->io.value = vcpu->svm->vmcb->save.rax;
vcpu->pio_pending = 1;
return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/kvm/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1459,12 +1459,14 @@ static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
= (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_DF) != 0;
kvm_run->io.rep = (exit_qualification & 32) != 0;
kvm_run->io.port = exit_qualification >> 16;
kvm_run->io.count = 1;
if (kvm_run->io.string) {
if (!get_io_count(vcpu, &kvm_run->io.count))
return 1;
kvm_run->io.address = vmcs_readl(GUEST_LINEAR_ADDRESS);
} else
kvm_run->io.value = vcpu->regs[VCPU_REGS_RAX]; /* rax */
vcpu->pio_pending = 1;
return 0;
}

Expand Down
6 changes: 3 additions & 3 deletions trunk/include/linux/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <asm/types.h>
#include <linux/ioctl.h>

#define KVM_API_VERSION 5
#define KVM_API_VERSION 6

/*
* Architectural interrupt line count, and the size of the bitmap needed
Expand Down Expand Up @@ -53,7 +53,7 @@ enum kvm_exit_reason {
struct kvm_run {
/* in */
__u32 emulated; /* skip current instruction */
__u32 mmio_completed; /* mmio request completed */
__u32 io_completed; /* mmio/pio request completed */
__u8 request_interrupt_window;
__u8 padding1[7];

Expand All @@ -80,7 +80,7 @@ struct kvm_run {
__u32 error_code;
} ex;
/* KVM_EXIT_IO */
struct {
struct kvm_io {
#define KVM_EXIT_IO_IN 0
#define KVM_EXIT_IO_OUT 1
__u8 direction;
Expand Down

0 comments on commit d543a84

Please sign in to comment.