lkml.org 
[lkml]   [2006]   [Nov]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 12/38] KVM: Add idt and gdt descriptor accessors
    From
    Date
    Signed-off-by: Avi Kivity <avi@qumranet.com>

    Index: linux-2.6/drivers/kvm/kvm.h
    ===================================================================
    --- linux-2.6.orig/drivers/kvm/kvm.h
    +++ linux-2.6/drivers/kvm/kvm.h
    @@ -236,6 +236,11 @@ struct kvm_stat {
    u32 irq_exits;
    };

    +struct descriptor_table {
    + u16 limit;
    + unsigned long base;
    +} __attribute__((packed));
    +
    struct kvm_arch_ops {
    int (*cpu_has_kvm_support)(void); /* __init */
    int (*disabled_by_bios)(void); /* __init */
    @@ -253,6 +258,10 @@ struct kvm_arch_ops {
    struct kvm_segment *var, int seg);
    void (*set_segment)(struct kvm_vcpu *vcpu,
    struct kvm_segment *var, int seg);
    + void (*get_idt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt);
    + void (*set_idt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt);
    + void (*get_gdt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt);
    + void (*set_gdt)(struct kvm_vcpu *vcpu, struct descriptor_table *dt);
    };

    extern struct kvm_stat kvm_stat;
    Index: linux-2.6/drivers/kvm/kvm_main.c
    ===================================================================
    --- linux-2.6.orig/drivers/kvm/kvm_main.c
    +++ linux-2.6/drivers/kvm/kvm_main.c
    @@ -155,11 +155,6 @@ struct vmx_msr_entry *find_msr_entry(str
    }
    EXPORT_SYMBOL_GPL(find_msr_entry);

    -struct descriptor_table {
    - u16 limit;
    - unsigned long base;
    -} __attribute__((packed));
    -
    static void get_gdt(struct descriptor_table *table)
    {
    asm ("sgdt %0" : "=m"(*table));
    @@ -2827,6 +2822,7 @@ static void get_segment(struct kvm_vcpu
    static int kvm_dev_ioctl_get_sregs(struct kvm *kvm, struct kvm_sregs *sregs)
    {
    struct kvm_vcpu *vcpu;
    + struct descriptor_table dt;

    if (sregs->vcpu < 0 || sregs->vcpu >= KVM_MAX_VCPUS)
    return -EINVAL;
    @@ -2844,13 +2840,12 @@ static int kvm_dev_ioctl_get_sregs(struc
    get_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
    get_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);

    -#define get_dtable(var, table) \
    - sregs->var.limit = vmcs_read32(GUEST_##table##_LIMIT), \
    - sregs->var.base = vmcs_readl(GUEST_##table##_BASE)
    -
    - get_dtable(idt, IDTR);
    - get_dtable(gdt, GDTR);
    -#undef get_dtable
    + kvm_arch_ops->get_idt(vcpu, &dt);
    + sregs->idt.limit = dt.limit;
    + sregs->idt.base = dt.base;
    + kvm_arch_ops->get_gdt(vcpu, &dt);
    + sregs->gdt.limit = dt.limit;
    + sregs->gdt.base = dt.base;

    sregs->cr0 = vcpu->cr0;
    sregs->cr2 = vcpu->cr2;
    @@ -2879,6 +2874,7 @@ static int kvm_dev_ioctl_set_sregs(struc
    struct kvm_vcpu *vcpu;
    int mmu_reset_needed = 0;
    int i;
    + struct descriptor_table dt;

    if (sregs->vcpu < 0 || sregs->vcpu >= KVM_MAX_VCPUS)
    return -EINVAL;
    @@ -2896,13 +2892,12 @@ static int kvm_dev_ioctl_set_sregs(struc
    set_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
    set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);

    -#define set_dtable(var, table) \
    - vmcs_write32(GUEST_##table##_LIMIT, sregs->var.limit), \
    - vmcs_writel(GUEST_##table##_BASE, sregs->var.base)
    -
    - set_dtable(idt, IDTR);
    - set_dtable(gdt, GDTR);
    -#undef set_dtable
    + dt.limit = sregs->idt.limit;
    + dt.base = sregs->idt.base;
    + kvm_arch_ops->set_idt(vcpu, &dt);
    + dt.limit = sregs->gdt.limit;
    + dt.base = sregs->gdt.base;
    + kvm_arch_ops->set_gdt(vcpu, &dt);

    vcpu->cr2 = sregs->cr2;
    mmu_reset_needed |= vcpu->cr3 != sregs->cr3;
    Index: linux-2.6/drivers/kvm/vmx.c
    ===================================================================
    --- linux-2.6.orig/drivers/kvm/vmx.c
    +++ linux-2.6/drivers/kvm/vmx.c
    @@ -363,6 +363,30 @@ static void vmx_set_segment(struct kvm_v
    vmcs_write32(sf->ar_bytes, ar);
    }

    +static void vmx_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
    +{
    + dt->limit = vmcs_read32(GUEST_IDTR_LIMIT);
    + dt->base = vmcs_readl(GUEST_IDTR_BASE);
    +}
    +
    +static void vmx_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
    +{
    + vmcs_write32(GUEST_IDTR_LIMIT, dt->limit);
    + vmcs_writel(GUEST_IDTR_BASE, dt->base);
    +}
    +
    +static void vmx_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
    +{
    + dt->limit = vmcs_read32(GUEST_GDTR_LIMIT);
    + dt->base = vmcs_readl(GUEST_GDTR_BASE);
    +}
    +
    +static void vmx_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
    +{
    + vmcs_write32(GUEST_GDTR_LIMIT, dt->limit);
    + vmcs_writel(GUEST_GDTR_BASE, dt->base);
    +}
    +
    static struct kvm_arch_ops vmx_arch_ops = {
    .cpu_has_kvm_support = cpu_has_kvm_support,
    .disabled_by_bios = vmx_disabled_by_bios,
    @@ -377,6 +401,10 @@ static struct kvm_arch_ops vmx_arch_ops
    .get_segment_base = vmx_get_segment_base,
    .get_segment = vmx_get_segment,
    .set_segment = vmx_set_segment,
    + .get_idt = vmx_get_idt,
    + .set_idt = vmx_set_idt,
    + .get_gdt = vmx_get_gdt,
    + .set_gdt = vmx_set_gdt,
    };

    static int __init vmx_init(void)
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2006-11-27 13:25    [W:0.026 / U:0.500 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site