Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 68403
b: refs/heads/master
c: 97222cc
h: refs/heads/master
i:
  68401: feaa0a3
  68399: 17c10cf
v: v3
  • Loading branch information
Eddie Dong authored and Avi Kivity committed Oct 13, 2007
1 parent 736824d commit fbe8f05
Show file tree
Hide file tree
Showing 10 changed files with 1,068 additions and 34 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: 7017fc3d1a12e30ea7df4992152978a188433457
refs/heads/master: 97222cc8316328965851ed28d23f6b64b4c912d2
2 changes: 1 addition & 1 deletion trunk/drivers/kvm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Makefile for Kernel-based Virtual Machine module
#

kvm-objs := kvm_main.o mmu.o x86_emulate.o i8259.o irq.o
kvm-objs := kvm_main.o mmu.o x86_emulate.o i8259.o irq.o lapic.o
obj-$(CONFIG_KVM) += kvm.o
kvm-intel-objs = vmx.o
obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
Expand Down
53 changes: 36 additions & 17 deletions trunk/drivers/kvm/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,13 @@
*/
int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
{
struct kvm_pic *s = pic_irqchip(v->kvm);

if (s->output) /* PIC */
return 1;
/*
* TODO: APIC
*/
return 0;
struct kvm_pic *s;

if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */
s = pic_irqchip(v->kvm); /* PIC */
return s->output;
}
return 1;
}
EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt);

Expand All @@ -46,16 +45,36 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt);
*/
int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
{
struct kvm_pic *s = pic_irqchip(v->kvm);
struct kvm_pic *s;
int vector;

s->output = 0;
vector = kvm_pic_read_irq(s);
if (vector != -1)
return vector;
/*
* TODO: APIC
*/
return -1;
vector = kvm_get_apic_interrupt(v); /* APIC */
if (vector == -1) {
s = pic_irqchip(v->kvm);
s->output = 0; /* PIC */
vector = kvm_pic_read_irq(s);
}
return vector;
}
EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt);

static void vcpu_kick_intr(void *info)
{
#ifdef DEBUG
struct kvm_vcpu *vcpu = (struct kvm_vcpu *)info;
printk(KERN_DEBUG "vcpu_kick_intr %p \n", vcpu);
#endif
}

void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
{
int ipi_pcpu = vcpu->cpu;

if (vcpu->guest_mode)
smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0, 0);
}

void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
{
/* TODO: for kernel IOAPIC */
}
41 changes: 40 additions & 1 deletion trunk/drivers/kvm/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

typedef void irq_request_func(void *opaque, int level);

struct kvm_pic;
struct kvm_kpic_state {
u8 last_irr; /* edge detection */
u8 irr; /* interrupt request register */
Expand Down Expand Up @@ -61,4 +60,44 @@ int kvm_pic_read_irq(struct kvm_pic *s);
int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
int kvm_cpu_has_interrupt(struct kvm_vcpu *v);

struct kvm_lapic {
unsigned long base_address;
struct kvm_io_device dev;
struct {
atomic_t pending;
s64 period; /* unit: ns */
u32 divide_count;
ktime_t last_update;
struct hrtimer dev;
} timer;
struct kvm_vcpu *vcpu;
struct page *regs_page;
void *regs;
};

#ifdef DEBUG
#define ASSERT(x) \
do { \
if (!(x)) { \
printk(KERN_EMERG "assertion failed %s: %d: %s\n", \
__FILE__, __LINE__, #x); \
BUG(); \
} \
} while (0)
#else
#define ASSERT(x) do { } while (0)
#endif

void kvm_vcpu_kick(struct kvm_vcpu *vcpu);
int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu);
int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu);
int kvm_create_lapic(struct kvm_vcpu *vcpu);
void kvm_free_apic(struct kvm_lapic *apic);
u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu);
void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8);
void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value);
u64 kvm_get_apic_base(struct kvm_vcpu *vcpu);
void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data);
void kvm_ioapic_update_eoi(struct kvm *kvm, int vector);

#endif
3 changes: 1 addition & 2 deletions trunk/drivers/kvm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ struct kvm_vcpu {
u64 pdptrs[4]; /* pae */
u64 shadow_efer;
u64 apic_base;
struct kvm_lapic *apic; /* kernel irqchip context */
u64 ia32_misc_enable_msr;

struct kvm_mmu mmu;
Expand Down Expand Up @@ -569,8 +570,6 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr0);
void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr0);
void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr0);
unsigned long get_cr8(struct kvm_vcpu *vcpu);
u64 kvm_get_apic_base(struct kvm_vcpu *vcpu);
void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data);
void lmsw(struct kvm_vcpu *vcpu, unsigned long msw);

int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
Expand Down
52 changes: 42 additions & 10 deletions trunk/drivers/kvm/kvm_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ EXPORT_SYMBOL_GPL(kvm_vcpu_init);
void kvm_vcpu_uninit(struct kvm_vcpu *vcpu)
{
kvm_mmu_destroy(vcpu);
kvm_free_apic(vcpu->apic);
free_page((unsigned long)vcpu->pio_data);
free_page((unsigned long)vcpu->run);
}
Expand Down Expand Up @@ -598,25 +599,38 @@ void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
inject_gp(vcpu);
return;
}
vcpu->cr8 = cr8;
if (irqchip_in_kernel(vcpu->kvm))
kvm_lapic_set_tpr(vcpu, cr8);
else
vcpu->cr8 = cr8;
}
EXPORT_SYMBOL_GPL(set_cr8);

unsigned long get_cr8(struct kvm_vcpu *vcpu)
{
return vcpu->cr8;
if (irqchip_in_kernel(vcpu->kvm))
return kvm_lapic_get_cr8(vcpu);
else
return vcpu->cr8;
}
EXPORT_SYMBOL_GPL(get_cr8);

u64 kvm_get_apic_base(struct kvm_vcpu *vcpu)
{
return vcpu->apic_base;
if (irqchip_in_kernel(vcpu->kvm))
return vcpu->apic_base;
else
return vcpu->apic_base;
}
EXPORT_SYMBOL_GPL(kvm_get_apic_base);

void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data)
{
vcpu->apic_base = data;
/* TODO: reserve bits check */
if (irqchip_in_kernel(vcpu->kvm))
kvm_lapic_set_base(vcpu, data);
else
vcpu->apic_base = data;
}
EXPORT_SYMBOL_GPL(kvm_set_apic_base);

Expand Down Expand Up @@ -986,15 +1000,31 @@ static int emulator_write_std(unsigned long addr,
return X86EMUL_UNHANDLEABLE;
}

/*
* Only apic need an MMIO device hook, so shortcut now..
*/
static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu,
gpa_t addr)
{
struct kvm_io_device *dev;

if (vcpu->apic) {
dev = &vcpu->apic->dev;
if (dev->in_range(dev, addr))
return dev;
}
return NULL;
}

static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
gpa_t addr)
{
/*
* Note that its important to have this wrapper function because
* in the very near future we will be checking for MMIOs against
* the LAPIC as well as the general MMIO bus
*/
return kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr);
struct kvm_io_device *dev;

dev = vcpu_find_pervcpu_dev(vcpu, addr);
if (dev == NULL)
dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr);
return dev;
}

static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu,
Expand Down Expand Up @@ -2256,6 +2286,8 @@ static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
{
if (irq->irq < 0 || irq->irq >= 256)
return -EINVAL;
if (irqchip_in_kernel(vcpu->kvm))
return -ENXIO;
vcpu_load(vcpu);

set_bit(irq->irq, vcpu->irq_pending);
Expand Down
Loading

0 comments on commit fbe8f05

Please sign in to comment.