From 1f1ec7b955bda544c6b917d47a1d6c593adb2b67 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 4 Feb 2009 20:44:01 +0100 Subject: [PATCH] --- yaml --- r: 131391 b: refs/heads/master c: 720fd66dfad1b0286721dbb2ed4d6076c0aa953b h: refs/heads/master i: 131389: a6861cc2931e7ddf43f535f0ecae01821657b8cb 131387: 3c1b1ff305f7029c834ffa42b8f17f3c3ba8ccb7 131383: ee0ec1f3797302ed311ccbfa7b80878b10208764 131375: 68e4b104c6ae83c8194f3c3ba1e0d789127eccc5 131359: e687470a550c18234c909273aeb5c8dc2bec1ecf 131327: 4aa26504e8edc3e43db1569709aa9e090058f7ff v: v3 --- [refs] | 2 +- trunk/arch/alpha/kernel/process.c | 8 +-- trunk/arch/alpha/kernel/smp.c | 12 ++-- trunk/arch/ia64/include/asm/kvm.h | 4 -- trunk/arch/ia64/kvm/kvm-ia64.c | 4 -- trunk/arch/ia64/kvm/process.c | 17 +++-- trunk/arch/powerpc/kvm/powerpc.c | 4 -- trunk/arch/s390/kvm/kvm-s390.c | 4 -- trunk/arch/x86/include/asm/kvm.h | 7 -- .../arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 12 ++-- trunk/arch/x86/kvm/i8254.c | 2 +- trunk/arch/x86/kvm/irq.c | 7 ++ trunk/arch/x86/kvm/irq.h | 1 + trunk/arch/x86/kvm/lapic.c | 66 ++++++++++++++----- trunk/arch/x86/kvm/lapic.h | 2 + trunk/arch/x86/kvm/mmu.c | 9 +-- trunk/arch/x86/kvm/svm.c | 1 + trunk/arch/x86/kvm/vmx.c | 5 +- trunk/arch/x86/kvm/x86.c | 10 +-- trunk/drivers/mfd/htc-egpio.c | 2 +- trunk/drivers/pci/intel-iommu.c | 14 +--- trunk/drivers/usb/host/whci/asl.c | 4 +- trunk/drivers/usb/host/whci/pzl.c | 4 +- trunk/drivers/watchdog/Kconfig | 2 +- trunk/drivers/watchdog/iTCO_vendor_support.c | 32 ++------- trunk/drivers/watchdog/iTCO_wdt.c | 35 ++++++---- trunk/fs/ext4/ext4.h | 2 +- trunk/fs/ext4/inode.c | 27 ++------ trunk/fs/ext4/mballoc.c | 32 ++++----- trunk/fs/ext4/migrate.c | 8 ++- trunk/fs/ext4/super.c | 11 ++-- trunk/fs/jbd2/journal.c | 17 ++--- trunk/fs/jbd2/transaction.c | 42 ++++-------- trunk/fs/namespace.c | 6 +- trunk/fs/ocfs2/journal.h | 6 +- trunk/include/asm-frv/pgtable.h | 2 +- trunk/include/linux/jbd2.h | 3 +- trunk/include/linux/kvm.h | 10 +-- trunk/include/linux/kvm_host.h | 1 - trunk/virt/kvm/iommu.c | 6 +- trunk/virt/kvm/kvm_main.c | 43 +++--------- 41 files changed, 195 insertions(+), 291 deletions(-) diff --git a/[refs] b/[refs] index 85c070343cd1..e5e843fbb92c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 68cc8301b45dee5de275a477a60f77f5560c8ca0 +refs/heads/master: 720fd66dfad1b0286721dbb2ed4d6076c0aa953b diff --git a/trunk/arch/alpha/kernel/process.c b/trunk/arch/alpha/kernel/process.c index 8d0097f10208..f238370c907d 100644 --- a/trunk/arch/alpha/kernel/process.c +++ b/trunk/arch/alpha/kernel/process.c @@ -93,8 +93,8 @@ common_shutdown_1(void *generic_ptr) if (cpuid != boot_cpuid) { flags |= 0x00040000UL; /* "remain halted" */ *pflags = flags; - set_cpu_present(cpuid, false); - set_cpu_possible(cpuid, false); + cpu_clear(cpuid, cpu_present_map); + cpu_clear(cpuid, cpu_possible_map); halt(); } #endif @@ -120,8 +120,8 @@ common_shutdown_1(void *generic_ptr) #ifdef CONFIG_SMP /* Wait for the secondaries to halt. */ - set_cpu_present(boot_cpuid, false); - set_cpu_possible(boot_cpuid, false); + cpu_clear(boot_cpuid, cpu_present_map); + cpu_clear(boot_cpuid, cpu_possible_map); while (cpus_weight(cpu_present_map)) barrier(); #endif diff --git a/trunk/arch/alpha/kernel/smp.c b/trunk/arch/alpha/kernel/smp.c index b1fe5674c3a1..00f1dc3dfd5f 100644 --- a/trunk/arch/alpha/kernel/smp.c +++ b/trunk/arch/alpha/kernel/smp.c @@ -120,12 +120,12 @@ void __cpuinit smp_callin(void) { int cpuid = hard_smp_processor_id(); + cpumask_t mask = cpu_online_map; - if (cpu_online(cpuid)) { + if (cpu_test_and_set(cpuid, mask)) { printk("??, cpu 0x%x already present??\n", cpuid); BUG(); } - set_cpu_online(cpuid, true); /* Turn on machine checks. */ wrmces(7); @@ -436,8 +436,8 @@ setup_smp(void) ((char *)cpubase + i*hwrpb->processor_size); if ((cpu->flags & 0x1cc) == 0x1cc) { smp_num_probed++; - set_cpu_possible(i, true); - set_cpu_present(i, true); + cpu_set(i, cpu_possible_map); + cpu_set(i, cpu_present_map); cpu->pal_revision = boot_cpu_palrev; } @@ -470,8 +470,8 @@ smp_prepare_cpus(unsigned int max_cpus) /* Nothing to do on a UP box, or when told not to. */ if (smp_num_probed == 1 || max_cpus == 0) { - init_cpu_possible(cpumask_of(boot_cpuid)); - init_cpu_present(cpumask_of(boot_cpuid)); + cpu_possible_map = cpumask_of_cpu(boot_cpuid); + cpu_present_map = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP mode deactivated.\n"); return; } diff --git a/trunk/arch/ia64/include/asm/kvm.h b/trunk/arch/ia64/include/asm/kvm.h index bfa86b6af7cd..68aa6da807c1 100644 --- a/trunk/arch/ia64/include/asm/kvm.h +++ b/trunk/arch/ia64/include/asm/kvm.h @@ -25,10 +25,6 @@ #include -/* Select x86 specific features in */ -#define __KVM_HAVE_IOAPIC -#define __KVM_HAVE_DEVICE_ASSIGNMENT - /* Architectural interrupt line count. */ #define KVM_NR_INTERRUPTS 256 diff --git a/trunk/arch/ia64/kvm/kvm-ia64.c b/trunk/arch/ia64/kvm/kvm-ia64.c index 28f982045f29..4e586f6110aa 100644 --- a/trunk/arch/ia64/kvm/kvm-ia64.c +++ b/trunk/arch/ia64/kvm/kvm-ia64.c @@ -1337,10 +1337,6 @@ static void kvm_release_vm_pages(struct kvm *kvm) } } -void kvm_arch_sync_events(struct kvm *kvm) -{ -} - void kvm_arch_destroy_vm(struct kvm *kvm) { kvm_iommu_unmap_guest(kvm); diff --git a/trunk/arch/ia64/kvm/process.c b/trunk/arch/ia64/kvm/process.c index 230eae482f32..552d07724207 100644 --- a/trunk/arch/ia64/kvm/process.c +++ b/trunk/arch/ia64/kvm/process.c @@ -455,18 +455,13 @@ fpswa_ret_t vmm_fp_emulate(int fp_fault, void *bundle, unsigned long *ipsr, if (!vmm_fpswa_interface) return (fpswa_ret_t) {-1, 0, 0, 0}; - memset(&fp_state, 0, sizeof(fp_state_t)); - /* - * compute fp_state. only FP registers f6 - f11 are used by the - * vmm, so set those bits in the mask and set the low volatile - * pointer to point to these registers. + * Just let fpswa driver to use hardware fp registers. + * No fp register is valid in memory. */ - fp_state.bitmask_low64 = 0xfc0; /* bit6..bit11 */ - - fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) ®s->f6; + memset(&fp_state, 0, sizeof(fp_state_t)); - /* + /* * unsigned long (*EFI_FPSWA) ( * unsigned long trap_type, * void *Bundle, @@ -550,6 +545,10 @@ void reflect_interruption(u64 ifa, u64 isr, u64 iim, status = vmm_handle_fpu_swa(0, regs, isr); if (!status) return ; + else if (-EAGAIN == status) { + vcpu_decrement_iip(vcpu); + return ; + } break; } diff --git a/trunk/arch/powerpc/kvm/powerpc.c b/trunk/arch/powerpc/kvm/powerpc.c index 5f81256287f5..2822c8ccfaaf 100644 --- a/trunk/arch/powerpc/kvm/powerpc.c +++ b/trunk/arch/powerpc/kvm/powerpc.c @@ -125,10 +125,6 @@ static void kvmppc_free_vcpus(struct kvm *kvm) } } -void kvm_arch_sync_events(struct kvm *kvm) -{ -} - void kvm_arch_destroy_vm(struct kvm *kvm) { kvmppc_free_vcpus(kvm); diff --git a/trunk/arch/s390/kvm/kvm-s390.c b/trunk/arch/s390/kvm/kvm-s390.c index 0d33893e1e89..be8497186b96 100644 --- a/trunk/arch/s390/kvm/kvm-s390.c +++ b/trunk/arch/s390/kvm/kvm-s390.c @@ -212,10 +212,6 @@ static void kvm_free_vcpus(struct kvm *kvm) } } -void kvm_arch_sync_events(struct kvm *kvm) -{ -} - void kvm_arch_destroy_vm(struct kvm *kvm) { kvm_free_vcpus(kvm); diff --git a/trunk/arch/x86/include/asm/kvm.h b/trunk/arch/x86/include/asm/kvm.h index 886c9402ec45..d2e3bf3608af 100644 --- a/trunk/arch/x86/include/asm/kvm.h +++ b/trunk/arch/x86/include/asm/kvm.h @@ -9,13 +9,6 @@ #include #include -/* Select x86 specific features in */ -#define __KVM_HAVE_PIT -#define __KVM_HAVE_IOAPIC -#define __KVM_HAVE_DEVICE_ASSIGNMENT -#define __KVM_HAVE_MSI -#define __KVM_HAVE_USER_NMI - /* Architectural interrupt line count. */ #define KVM_NR_INTERRUPTS 256 diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 6428aa17b40e..fb039cd345d8 100644 --- a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -1157,7 +1157,8 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) data->cpu = pol->cpu; data->currpstate = HW_PSTATE_INVALID; - if (powernow_k8_cpu_init_acpi(data)) { + rc = powernow_k8_cpu_init_acpi(data); + if (rc) { /* * Use the PSB BIOS structure. This is only availabe on * an UP version, and is deprecated by AMD. @@ -1175,20 +1176,17 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) "ACPI maintainers and complain to your BIOS " "vendor.\n"); #endif - kfree(data); - return -ENODEV; + goto err_out; } if (pol->cpu != 0) { printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " "CPU other than CPU0. Complain to your BIOS " "vendor.\n"); - kfree(data); - return -ENODEV; + goto err_out; } rc = find_psb_table(data); if (rc) { - kfree(data); - return -ENODEV; + goto err_out; } /* Take a crude guess here. * That guess was in microseconds, so multiply with 1000 */ diff --git a/trunk/arch/x86/kvm/i8254.c b/trunk/arch/x86/kvm/i8254.c index 72bd275a9b5c..e665d1c623ca 100644 --- a/trunk/arch/x86/kvm/i8254.c +++ b/trunk/arch/x86/kvm/i8254.c @@ -207,7 +207,7 @@ static int __pit_timer_fn(struct kvm_kpit_state *ps) hrtimer_add_expires_ns(&pt->timer, pt->period); pt->scheduled = hrtimer_get_expires_ns(&pt->timer); if (pt->period) - ps->channels[0].count_load_time = ktime_get(); + ps->channels[0].count_load_time = hrtimer_get_expires(&pt->timer); return (pt->period == 0 ? 0 : 1); } diff --git a/trunk/arch/x86/kvm/irq.c b/trunk/arch/x86/kvm/irq.c index cf17ed52f6fb..c019b8edcdb7 100644 --- a/trunk/arch/x86/kvm/irq.c +++ b/trunk/arch/x86/kvm/irq.c @@ -87,6 +87,13 @@ void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu) } EXPORT_SYMBOL_GPL(kvm_inject_pending_timer_irqs); +void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec) +{ + kvm_apic_timer_intr_post(vcpu, vec); + /* TODO: PIT, RTC etc. */ +} +EXPORT_SYMBOL_GPL(kvm_timer_intr_post); + void __kvm_migrate_timers(struct kvm_vcpu *vcpu) { __kvm_migrate_apic_timer(vcpu); diff --git a/trunk/arch/x86/kvm/irq.h b/trunk/arch/x86/kvm/irq.h index 82579ee538d0..2bf32a03ceec 100644 --- a/trunk/arch/x86/kvm/irq.h +++ b/trunk/arch/x86/kvm/irq.h @@ -89,6 +89,7 @@ static inline int irqchip_in_kernel(struct kvm *kvm) void kvm_pic_reset(struct kvm_kpic_state *s); +void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec); void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu); void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu); void kvm_apic_nmi_wd_deliver(struct kvm_vcpu *vcpu); diff --git a/trunk/arch/x86/kvm/lapic.c b/trunk/arch/x86/kvm/lapic.c index f0b67f2cdd69..afac68c0815c 100644 --- a/trunk/arch/x86/kvm/lapic.c +++ b/trunk/arch/x86/kvm/lapic.c @@ -35,12 +35,6 @@ #include "kvm_cache_regs.h" #include "irq.h" -#ifndef CONFIG_X86_64 -#define mod_64(x, y) ((x) - (y) * div64_u64(x, y)) -#else -#define mod_64(x, y) ((x) % (y)) -#endif - #define PRId64 "d" #define PRIx64 "llx" #define PRIu64 "u" @@ -517,22 +511,52 @@ static void apic_send_ipi(struct kvm_lapic *apic) static u32 apic_get_tmcct(struct kvm_lapic *apic) { - ktime_t remaining; - s64 ns; + u64 counter_passed; + ktime_t passed, now; u32 tmcct; ASSERT(apic != NULL); + now = apic->timer.dev.base->get_time(); + tmcct = apic_get_reg(apic, APIC_TMICT); + /* if initial count is 0, current count should also be 0 */ - if (apic_get_reg(apic, APIC_TMICT) == 0) + if (tmcct == 0) return 0; - remaining = hrtimer_expires_remaining(&apic->timer.dev); - if (ktime_to_ns(remaining) < 0) - remaining = ktime_set(0, 0); - - ns = mod_64(ktime_to_ns(remaining), apic->timer.period); - tmcct = div64_u64(ns, (APIC_BUS_CYCLE_NS * apic->timer.divide_count)); + if (unlikely(ktime_to_ns(now) <= + ktime_to_ns(apic->timer.last_update))) { + /* Wrap around */ + passed = ktime_add(( { + (ktime_t) { + .tv64 = KTIME_MAX - + (apic->timer.last_update).tv64}; } + ), now); + apic_debug("time elapsed\n"); + } else + passed = ktime_sub(now, apic->timer.last_update); + + counter_passed = div64_u64(ktime_to_ns(passed), + (APIC_BUS_CYCLE_NS * apic->timer.divide_count)); + + if (counter_passed > tmcct) { + if (unlikely(!apic_lvtt_period(apic))) { + /* one-shot timers stick at 0 until reset */ + tmcct = 0; + } else { + /* + * periodic timers reset to APIC_TMICT when they + * hit 0. The while loop simulates this happening N + * times. (counter_passed %= tmcct) would also work, + * but might be slower or not work on 32-bit?? + */ + while (counter_passed > tmcct) + counter_passed -= tmcct; + tmcct -= counter_passed; + } + } else { + tmcct -= counter_passed; + } return tmcct; } @@ -629,6 +653,8 @@ static void start_apic_timer(struct kvm_lapic *apic) { ktime_t now = apic->timer.dev.base->get_time(); + apic->timer.last_update = now; + apic->timer.period = apic_get_reg(apic, APIC_TMICT) * APIC_BUS_CYCLE_NS * apic->timer.divide_count; atomic_set(&apic->timer.pending, 0); @@ -1084,6 +1110,16 @@ void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu) } } +void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec) +{ + struct kvm_lapic *apic = vcpu->arch.apic; + + if (apic && apic_lvt_vector(apic, APIC_LVTT) == vec) + apic->timer.last_update = ktime_add_ns( + apic->timer.last_update, + apic->timer.period); +} + int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu) { int vector = kvm_apic_has_interrupt(vcpu); diff --git a/trunk/arch/x86/kvm/lapic.h b/trunk/arch/x86/kvm/lapic.h index 45ab6ee71209..81858881287e 100644 --- a/trunk/arch/x86/kvm/lapic.h +++ b/trunk/arch/x86/kvm/lapic.h @@ -12,6 +12,7 @@ struct kvm_lapic { atomic_t pending; s64 period; /* unit: ns */ u32 divide_count; + ktime_t last_update; struct hrtimer dev; } timer; struct kvm_vcpu *vcpu; @@ -41,6 +42,7 @@ void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu); int kvm_lapic_enabled(struct kvm_vcpu *vcpu); int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); +void kvm_apic_timer_intr_post(struct kvm_vcpu *vcpu, int vec); void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu); diff --git a/trunk/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c index 2d4477c71473..83f11c7474a1 100644 --- a/trunk/arch/x86/kvm/mmu.c +++ b/trunk/arch/x86/kvm/mmu.c @@ -1698,13 +1698,8 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, if (largepage) spte |= PT_PAGE_SIZE_MASK; if (mt_mask) { - if (!kvm_is_mmio_pfn(pfn)) { - mt_mask = get_memory_type(vcpu, gfn) << - kvm_x86_ops->get_mt_mask_shift(); - mt_mask |= VMX_EPT_IGMT_BIT; - } else - mt_mask = MTRR_TYPE_UNCACHABLE << - kvm_x86_ops->get_mt_mask_shift(); + mt_mask = get_memory_type(vcpu, gfn) << + kvm_x86_ops->get_mt_mask_shift(); spte |= mt_mask; } diff --git a/trunk/arch/x86/kvm/svm.c b/trunk/arch/x86/kvm/svm.c index a9e769e4e251..1452851ae258 100644 --- a/trunk/arch/x86/kvm/svm.c +++ b/trunk/arch/x86/kvm/svm.c @@ -1600,6 +1600,7 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu) /* Okay, we can deliver the interrupt: grab it and update PIC state. */ intr_vector = kvm_cpu_get_interrupt(vcpu); svm_inject_irq(svm, intr_vector); + kvm_timer_intr_post(vcpu, intr_vector); out: update_cr8_intercept(vcpu); } diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index 7611af576829..6259d7467648 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -903,7 +903,6 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) data = vmcs_readl(GUEST_SYSENTER_ESP); break; default: - vmx_load_host_state(to_vmx(vcpu)); msr = find_msr_entry(to_vmx(vcpu), msr_index); if (msr) { data = msr->data; @@ -3286,6 +3285,7 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu) } if (vcpu->arch.interrupt.pending) { vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr); + kvm_timer_intr_post(vcpu, vcpu->arch.interrupt.nr); if (kvm_cpu_has_interrupt(vcpu)) enable_irq_window(vcpu); } @@ -3687,7 +3687,8 @@ static int __init vmx_init(void) if (vm_need_ept()) { bypass_guest_pf = 0; kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK | - VMX_EPT_WRITABLE_MASK); + VMX_EPT_WRITABLE_MASK | + VMX_EPT_IGMT_BIT); kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull, VMX_EPT_EXECUTABLE_MASK, VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT); diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 758b7a155ae9..cc17546a2406 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -967,6 +967,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_MMU_SHADOW_CACHE_CONTROL: case KVM_CAP_SET_TSS_ADDR: case KVM_CAP_EXT_CPUID: + case KVM_CAP_CLOCKSOURCE: case KVM_CAP_PIT: case KVM_CAP_NOP_IO_DELAY: case KVM_CAP_MP_STATE: @@ -991,9 +992,6 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_IOMMU: r = iommu_found(); break; - case KVM_CAP_CLOCKSOURCE: - r = boot_cpu_has(X86_FEATURE_CONSTANT_TSC); - break; default: r = 0; break; @@ -4129,13 +4127,9 @@ static void kvm_free_vcpus(struct kvm *kvm) } -void kvm_arch_sync_events(struct kvm *kvm) -{ - kvm_free_all_assigned_devices(kvm); -} - void kvm_arch_destroy_vm(struct kvm *kvm) { + kvm_free_all_assigned_devices(kvm); kvm_iommu_unmap_guest(kvm); kvm_free_pit(kvm); kfree(kvm->arch.vpic); diff --git a/trunk/drivers/mfd/htc-egpio.c b/trunk/drivers/mfd/htc-egpio.c index 1a4d04664d6d..194df7b8256c 100644 --- a/trunk/drivers/mfd/htc-egpio.c +++ b/trunk/drivers/mfd/htc-egpio.c @@ -307,7 +307,7 @@ static int __init egpio_probe(struct platform_device *pdev) ei->nchips = pdata->num_chips; ei->chip = kzalloc(sizeof(struct egpio_chip) * ei->nchips, GFP_KERNEL); - if (!ei) { + if (!ei->chip) { ret = -ENOMEM; goto fail; } diff --git a/trunk/drivers/pci/intel-iommu.c b/trunk/drivers/pci/intel-iommu.c index fa9e41626bfc..f4b7c79023ff 100644 --- a/trunk/drivers/pci/intel-iommu.c +++ b/trunk/drivers/pci/intel-iommu.c @@ -61,8 +61,6 @@ /* global iommu list, set NULL for ignored DMAR units */ static struct intel_iommu **g_iommus; -static int rwbf_quirk = 0; - /* * 0: Present * 1-11: Reserved @@ -787,7 +785,7 @@ static void iommu_flush_write_buffer(struct intel_iommu *iommu) u32 val; unsigned long flag; - if (!rwbf_quirk && !cap_rwbf(iommu->cap)) + if (!cap_rwbf(iommu->cap)) return; val = iommu->gcmd | DMA_GCMD_WBF; @@ -3139,13 +3137,3 @@ static struct iommu_ops intel_iommu_ops = { .unmap = intel_iommu_unmap_range, .iova_to_phys = intel_iommu_iova_to_phys, }; - -static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) -{ - /* Mobile 4 Series Chipset neglects to set RWBF capability, - but needs it */ - printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n"); - rwbf_quirk = 1; -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); diff --git a/trunk/drivers/usb/host/whci/asl.c b/trunk/drivers/usb/host/whci/asl.c index 958751ccea43..2291c5f5af51 100644 --- a/trunk/drivers/usb/host/whci/asl.c +++ b/trunk/drivers/usb/host/whci/asl.c @@ -227,13 +227,13 @@ void scan_async_work(struct work_struct *work) * Now that the ASL is updated, complete the removal of any * removed qsets. */ - spin_lock_irq(&whc->lock); + spin_lock(&whc->lock); list_for_each_entry_safe(qset, t, &whc->async_removed_list, list_node) { qset_remove_complete(whc, qset); } - spin_unlock_irq(&whc->lock); + spin_unlock(&whc->lock); } /** diff --git a/trunk/drivers/usb/host/whci/pzl.c b/trunk/drivers/usb/host/whci/pzl.c index df8b85f07092..7dc85a0bee7c 100644 --- a/trunk/drivers/usb/host/whci/pzl.c +++ b/trunk/drivers/usb/host/whci/pzl.c @@ -255,13 +255,13 @@ void scan_periodic_work(struct work_struct *work) * Now that the PZL is updated, complete the removal of any * removed qsets. */ - spin_lock_irq(&whc->lock); + spin_lock(&whc->lock); list_for_each_entry_safe(qset, t, &whc->periodic_removed_list, list_node) { qset_remove_complete(whc, qset); } - spin_unlock_irq(&whc->lock); + spin_unlock(&whc->lock); } /** diff --git a/trunk/drivers/watchdog/Kconfig b/trunk/drivers/watchdog/Kconfig index 325c10ff6a2c..09a3d5522b43 100644 --- a/trunk/drivers/watchdog/Kconfig +++ b/trunk/drivers/watchdog/Kconfig @@ -406,7 +406,7 @@ config ITCO_WDT ---help--- Hardware driver for the intel TCO timer based watchdog devices. These drivers are included in the Intel 82801 I/O Controller - Hub family (from ICH0 up to ICH10) and in the Intel 63xxESB + Hub family (from ICH0 up to ICH8) and in the Intel 6300ESB controller hub. The TCO (Total Cost of Ownership) timer is a watchdog timer diff --git a/trunk/drivers/watchdog/iTCO_vendor_support.c b/trunk/drivers/watchdog/iTCO_vendor_support.c index d8264ad0be41..2474ebca88f6 100644 --- a/trunk/drivers/watchdog/iTCO_vendor_support.c +++ b/trunk/drivers/watchdog/iTCO_vendor_support.c @@ -1,7 +1,7 @@ /* * intel TCO vendor specific watchdog driver support * - * (c) Copyright 2006-2009 Wim Van Sebroeck . + * (c) Copyright 2006-2008 Wim Van Sebroeck . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -19,7 +19,7 @@ /* Module and version information */ #define DRV_NAME "iTCO_vendor_support" -#define DRV_VERSION "1.03" +#define DRV_VERSION "1.02" #define PFX DRV_NAME ": " /* Includes */ @@ -77,26 +77,6 @@ MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (n * 20.6 seconds. */ -static void supermicro_old_pre_start(unsigned long acpibase) -{ - unsigned long val32; - - /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ - val32 = inl(SMI_EN); - val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ - outl(val32, SMI_EN); /* Needed to activate watchdog */ -} - -static void supermicro_old_pre_stop(unsigned long acpibase) -{ - unsigned long val32; - - /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ - val32 = inl(SMI_EN); - val32 |= 0x00002000; /* Turn on SMI clearing watchdog */ - outl(val32, SMI_EN); /* Needed to deactivate watchdog */ -} - static void supermicro_old_pre_keepalive(unsigned long acpibase) { /* Reload TCO Timer (done in iTCO_wdt_keepalive) + */ @@ -248,18 +228,14 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat) void iTCO_vendor_pre_start(unsigned long acpibase, unsigned int heartbeat) { - if (vendorsupport == SUPERMICRO_OLD_BOARD) - supermicro_old_pre_start(acpibase); - else if (vendorsupport == SUPERMICRO_NEW_BOARD) + if (vendorsupport == SUPERMICRO_NEW_BOARD) supermicro_new_pre_start(heartbeat); } EXPORT_SYMBOL(iTCO_vendor_pre_start); void iTCO_vendor_pre_stop(unsigned long acpibase) { - if (vendorsupport == SUPERMICRO_OLD_BOARD) - supermicro_old_pre_stop(acpibase); - else if (vendorsupport == SUPERMICRO_NEW_BOARD) + if (vendorsupport == SUPERMICRO_NEW_BOARD) supermicro_new_pre_stop(); } EXPORT_SYMBOL(iTCO_vendor_pre_stop); diff --git a/trunk/drivers/watchdog/iTCO_wdt.c b/trunk/drivers/watchdog/iTCO_wdt.c index 352334947ea3..5b395a4ddfdf 100644 --- a/trunk/drivers/watchdog/iTCO_wdt.c +++ b/trunk/drivers/watchdog/iTCO_wdt.c @@ -1,7 +1,7 @@ /* - * intel TCO Watchdog Driver (Used in i82801 and i63xxESB chipsets) + * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets) * - * (c) Copyright 2006-2009 Wim Van Sebroeck . + * (c) Copyright 2006-2008 Wim Van Sebroeck . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -63,7 +63,7 @@ /* Module and version information */ #define DRV_NAME "iTCO_wdt" -#define DRV_VERSION "1.05" +#define DRV_VERSION "1.04" #define PFX DRV_NAME ": " /* Includes */ @@ -236,16 +236,16 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); /* Address definitions for the TCO */ /* TCO base address */ -#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 +#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 /* SMI Control and Enable Register */ -#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 +#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 #define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */ #define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ -#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ -#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ -#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ -#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ +#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ +#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ +#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ +#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ #define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */ #define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */ #define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */ @@ -338,6 +338,7 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(void) static int iTCO_wdt_start(void) { unsigned int val; + unsigned long val32; spin_lock(&iTCO_wdt_private.io_lock); @@ -350,6 +351,11 @@ static int iTCO_wdt_start(void) return -EIO; } + /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ + val32 = inl(SMI_EN); + val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ + outl(val32, SMI_EN); + /* Force the timer to its reload value by writing to the TCO_RLD register */ if (iTCO_wdt_private.iTCO_version == 2) @@ -372,6 +378,7 @@ static int iTCO_wdt_start(void) static int iTCO_wdt_stop(void) { unsigned int val; + unsigned long val32; spin_lock(&iTCO_wdt_private.io_lock); @@ -383,6 +390,11 @@ static int iTCO_wdt_stop(void) outw(val, TCO1_CNT); val = inw(TCO1_CNT); + /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ + val32 = inl(SMI_EN); + val32 |= 0x00002000; + outl(val32, SMI_EN); + /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ iTCO_wdt_set_NO_REBOOT_bit(); @@ -637,7 +649,6 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, int ret; u32 base_address; unsigned long RCBA; - unsigned long val32; /* * Find the ACPI/PM base I/O address which is the base @@ -684,10 +695,6 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, ret = -EIO; goto out; } - /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ - val32 = inl(SMI_EN); - val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ - outl(val32, SMI_EN); /* The TCO I/O registers reside in a 32-byte range pointed to by the TCOBASE value */ diff --git a/trunk/fs/ext4/ext4.h b/trunk/fs/ext4/ext4.h index b0c87dce66a3..aafc9eba1c25 100644 --- a/trunk/fs/ext4/ext4.h +++ b/trunk/fs/ext4/ext4.h @@ -868,7 +868,7 @@ static inline unsigned ext4_rec_len_from_disk(__le16 dlen) { unsigned len = le16_to_cpu(dlen); - if (len == EXT4_MAX_REC_LEN || len == 0) + if (len == EXT4_MAX_REC_LEN) return 1 << 16; return len; } diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c index cbd2ca99d113..03ba20be1329 100644 --- a/trunk/fs/ext4/inode.c +++ b/trunk/fs/ext4/inode.c @@ -47,10 +47,8 @@ static inline int ext4_begin_ordered_truncate(struct inode *inode, loff_t new_size) { - return jbd2_journal_begin_ordered_truncate( - EXT4_SB(inode->i_sb)->s_journal, - &EXT4_I(inode)->jinode, - new_size); + return jbd2_journal_begin_ordered_truncate(&EXT4_I(inode)->jinode, + new_size); } static void ext4_invalidatepage(struct page *page, unsigned long offset); @@ -2439,7 +2437,6 @@ static int ext4_da_writepages(struct address_space *mapping, int no_nrwrite_index_update; int pages_written = 0; long pages_skipped; - int range_cyclic, cycled = 1, io_done = 0; int needed_blocks, ret = 0, nr_to_writebump = 0; struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); @@ -2491,15 +2488,9 @@ static int ext4_da_writepages(struct address_space *mapping, if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) range_whole = 1; - range_cyclic = wbc->range_cyclic; - if (wbc->range_cyclic) { + if (wbc->range_cyclic) index = mapping->writeback_index; - if (index) - cycled = 0; - wbc->range_start = index << PAGE_CACHE_SHIFT; - wbc->range_end = LLONG_MAX; - wbc->range_cyclic = 0; - } else + else index = wbc->range_start >> PAGE_CACHE_SHIFT; mpd.wbc = wbc; @@ -2513,7 +2504,6 @@ static int ext4_da_writepages(struct address_space *mapping, wbc->no_nrwrite_index_update = 1; pages_skipped = wbc->pages_skipped; -retry: while (!ret && wbc->nr_to_write > 0) { /* @@ -2556,7 +2546,6 @@ static int ext4_da_writepages(struct address_space *mapping, pages_written += mpd.pages_written; wbc->pages_skipped = pages_skipped; ret = 0; - io_done = 1; } else if (wbc->nr_to_write) /* * There is no more writeout needed @@ -2565,13 +2554,6 @@ static int ext4_da_writepages(struct address_space *mapping, */ break; } - if (!io_done && !cycled) { - cycled = 1; - index = 0; - wbc->range_start = index << PAGE_CACHE_SHIFT; - wbc->range_end = mapping->writeback_index - 1; - goto retry; - } if (pages_skipped != wbc->pages_skipped) printk(KERN_EMERG "This should not happen leaving %s " "with nr_to_write = %ld ret = %d\n", @@ -2579,7 +2561,6 @@ static int ext4_da_writepages(struct address_space *mapping, /* Update index */ index += pages_written; - wbc->range_cyclic = range_cyclic; if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) /* * set the writeback_index so that range_cyclic diff --git a/trunk/fs/ext4/mballoc.c b/trunk/fs/ext4/mballoc.c index 4415beeb0b62..deba54f6cbed 100644 --- a/trunk/fs/ext4/mballoc.c +++ b/trunk/fs/ext4/mballoc.c @@ -3693,8 +3693,6 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac) pa->pa_free = pa->pa_len; atomic_set(&pa->pa_count, 1); spin_lock_init(&pa->pa_lock); - INIT_LIST_HEAD(&pa->pa_inode_list); - INIT_LIST_HEAD(&pa->pa_group_list); pa->pa_deleted = 0; pa->pa_linear = 0; @@ -3757,7 +3755,6 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac) atomic_set(&pa->pa_count, 1); spin_lock_init(&pa->pa_lock); INIT_LIST_HEAD(&pa->pa_inode_list); - INIT_LIST_HEAD(&pa->pa_group_list); pa->pa_deleted = 0; pa->pa_linear = 1; @@ -4479,26 +4476,23 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac) pa->pa_free -= ac->ac_b_ex.fe_len; pa->pa_len -= ac->ac_b_ex.fe_len; spin_unlock(&pa->pa_lock); + /* + * We want to add the pa to the right bucket. + * Remove it from the list and while adding + * make sure the list to which we are adding + * doesn't grow big. + */ + if (likely(pa->pa_free)) { + spin_lock(pa->pa_obj_lock); + list_del_rcu(&pa->pa_inode_list); + spin_unlock(pa->pa_obj_lock); + ext4_mb_add_n_trim(ac); + } } + ext4_mb_put_pa(ac, ac->ac_sb, pa); } if (ac->alloc_semp) up_read(ac->alloc_semp); - if (pa) { - /* - * We want to add the pa to the right bucket. - * Remove it from the list and while adding - * make sure the list to which we are adding - * doesn't grow big. We need to release - * alloc_semp before calling ext4_mb_add_n_trim() - */ - if (pa->pa_linear && likely(pa->pa_free)) { - spin_lock(pa->pa_obj_lock); - list_del_rcu(&pa->pa_inode_list); - spin_unlock(pa->pa_obj_lock); - ext4_mb_add_n_trim(ac); - } - ext4_mb_put_pa(ac, ac->ac_sb, pa); - } if (ac->ac_bitmap_page) page_cache_release(ac->ac_bitmap_page); if (ac->ac_buddy_page) diff --git a/trunk/fs/ext4/migrate.c b/trunk/fs/ext4/migrate.c index fe64d9f79852..734abca25e35 100644 --- a/trunk/fs/ext4/migrate.c +++ b/trunk/fs/ext4/migrate.c @@ -481,7 +481,7 @@ int ext4_ext_migrate(struct inode *inode) + 1); if (IS_ERR(handle)) { retval = PTR_ERR(handle); - return retval; + goto err_out; } tmp_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode, @@ -489,7 +489,8 @@ int ext4_ext_migrate(struct inode *inode) if (IS_ERR(tmp_inode)) { retval = -ENOMEM; ext4_journal_stop(handle); - return retval; + tmp_inode = NULL; + goto err_out; } i_size_write(tmp_inode, i_size_read(inode)); /* @@ -617,7 +618,8 @@ int ext4_ext_migrate(struct inode *inode) ext4_journal_stop(handle); - iput(tmp_inode); + if (tmp_inode) + iput(tmp_inode); return retval; } diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index a5732c58f676..e5f06a5f045e 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -3046,17 +3046,14 @@ static void ext4_write_super(struct super_block *sb) static int ext4_sync_fs(struct super_block *sb, int wait) { int ret = 0; - tid_t target; trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); sb->s_dirt = 0; if (EXT4_SB(sb)->s_journal) { - if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, - &target)) { - if (wait) - jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, - target); - } + if (wait) + ret = ext4_force_commit(sb); + else + jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL); } else { ext4_commit_super(sb, EXT4_SB(sb)->s_es, wait); } diff --git a/trunk/fs/jbd2/journal.c b/trunk/fs/jbd2/journal.c index 58144102bf25..eb343008eded 100644 --- a/trunk/fs/jbd2/journal.c +++ b/trunk/fs/jbd2/journal.c @@ -450,7 +450,7 @@ int __jbd2_log_space_left(journal_t *journal) } /* - * Called under j_state_lock. Returns true if a transaction commit was started. + * Called under j_state_lock. Returns true if a transaction was started. */ int __jbd2_log_start_commit(journal_t *journal, tid_t target) { @@ -518,8 +518,7 @@ int jbd2_journal_force_commit_nested(journal_t *journal) /* * Start a commit of the current running transaction (if any). Returns true - * if a transaction is going to be committed (or is currently already - * committing), and fills its tid in at *ptid + * if a transaction was started, and fills its tid in at *ptid */ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) { @@ -529,19 +528,15 @@ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) if (journal->j_running_transaction) { tid_t tid = journal->j_running_transaction->t_tid; - __jbd2_log_start_commit(journal, tid); - /* There's a running transaction and we've just made sure - * it's commit has been scheduled. */ - if (ptid) + ret = __jbd2_log_start_commit(journal, tid); + if (ret && ptid) *ptid = tid; - ret = 1; - } else if (journal->j_committing_transaction) { + } else if (journal->j_committing_transaction && ptid) { /* * If ext3_write_super() recently started a commit, then we * have to wait for completion of that transaction */ - if (ptid) - *ptid = journal->j_committing_transaction->t_tid; + *ptid = journal->j_committing_transaction->t_tid; ret = 1; } spin_unlock(&journal->j_state_lock); diff --git a/trunk/fs/jbd2/transaction.c b/trunk/fs/jbd2/transaction.c index 28ce21d8598e..46b4e347ed7d 100644 --- a/trunk/fs/jbd2/transaction.c +++ b/trunk/fs/jbd2/transaction.c @@ -2129,46 +2129,26 @@ int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *jinode) } /* - * File truncate and transaction commit interact with each other in a - * non-trivial way. If a transaction writing data block A is - * committing, we cannot discard the data by truncate until we have - * written them. Otherwise if we crashed after the transaction with - * write has committed but before the transaction with truncate has - * committed, we could see stale data in block A. This function is a - * helper to solve this problem. It starts writeout of the truncated - * part in case it is in the committing transaction. - * - * Filesystem code must call this function when inode is journaled in - * ordered mode before truncation happens and after the inode has been - * placed on orphan list with the new inode size. The second condition - * avoids the race that someone writes new data and we start - * committing the transaction after this function has been called but - * before a transaction for truncate is started (and furthermore it - * allows us to optimize the case where the addition to orphan list - * happens in the same transaction as write --- we don't have to write - * any data in such case). + * This function must be called when inode is journaled in ordered mode + * before truncation happens. It starts writeout of truncated part in + * case it is in the committing transaction so that we stand to ordered + * mode consistency guarantees. */ -int jbd2_journal_begin_ordered_truncate(journal_t *journal, - struct jbd2_inode *jinode, +int jbd2_journal_begin_ordered_truncate(struct jbd2_inode *inode, loff_t new_size) { - transaction_t *inode_trans, *commit_trans; + journal_t *journal; + transaction_t *commit_trans; int ret = 0; - /* This is a quick check to avoid locking if not necessary */ - if (!jinode->i_transaction) + if (!inode->i_transaction && !inode->i_next_transaction) goto out; - /* Locks are here just to force reading of recent values, it is - * enough that the transaction was not committing before we started - * a transaction adding the inode to orphan list */ + journal = inode->i_transaction->t_journal; spin_lock(&journal->j_state_lock); commit_trans = journal->j_committing_transaction; spin_unlock(&journal->j_state_lock); - spin_lock(&journal->j_list_lock); - inode_trans = jinode->i_transaction; - spin_unlock(&journal->j_list_lock); - if (inode_trans == commit_trans) { - ret = filemap_fdatawrite_range(jinode->i_vfs_inode->i_mapping, + if (inode->i_transaction == commit_trans) { + ret = filemap_fdatawrite_range(inode->i_vfs_inode->i_mapping, new_size, LLONG_MAX); if (ret) jbd2_journal_abort(journal, ret); diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index 06f8e63f6cb1..228d8c4bfd18 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -614,11 +614,9 @@ static inline void __mntput(struct vfsmount *mnt) */ for_each_possible_cpu(cpu) { struct mnt_writer *cpu_writer = &per_cpu(mnt_writers, cpu); - spin_lock(&cpu_writer->lock); - if (cpu_writer->mnt != mnt) { - spin_unlock(&cpu_writer->lock); + if (cpu_writer->mnt != mnt) continue; - } + spin_lock(&cpu_writer->lock); atomic_add(cpu_writer->count, &mnt->__mnt_writers); cpu_writer->count = 0; /* diff --git a/trunk/fs/ocfs2/journal.h b/trunk/fs/ocfs2/journal.h index 172850a9a12a..3c3532e1307c 100644 --- a/trunk/fs/ocfs2/journal.h +++ b/trunk/fs/ocfs2/journal.h @@ -513,10 +513,8 @@ static inline int ocfs2_jbd2_file_inode(handle_t *handle, struct inode *inode) static inline int ocfs2_begin_ordered_truncate(struct inode *inode, loff_t new_size) { - return jbd2_journal_begin_ordered_truncate( - OCFS2_SB(inode->i_sb)->journal->j_journal, - &OCFS2_I(inode)->ip_jinode, - new_size); + return jbd2_journal_begin_ordered_truncate(&OCFS2_I(inode)->ip_jinode, + new_size); } #endif /* OCFS2_JOURNAL_H */ diff --git a/trunk/include/asm-frv/pgtable.h b/trunk/include/asm-frv/pgtable.h index e16fdb1f4f4f..83c51aba534b 100644 --- a/trunk/include/asm-frv/pgtable.h +++ b/trunk/include/asm-frv/pgtable.h @@ -478,7 +478,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define __swp_type(x) (((x).val >> 2) & 0x1f) #define __swp_offset(x) ((x).val >> 8) #define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 8) }) -#define __pte_to_swp_entry(_pte) ((swp_entry_t) { (_pte).pte }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) static inline int pte_file(pte_t pte) diff --git a/trunk/include/linux/jbd2.h b/trunk/include/linux/jbd2.h index 4d248b3f1323..b28b37eb11c6 100644 --- a/trunk/include/linux/jbd2.h +++ b/trunk/include/linux/jbd2.h @@ -1150,8 +1150,7 @@ extern int jbd2_journal_clear_err (journal_t *); extern int jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *); extern int jbd2_journal_force_commit(journal_t *); extern int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *inode); -extern int jbd2_journal_begin_ordered_truncate(journal_t *journal, - struct jbd2_inode *inode, loff_t new_size); +extern int jbd2_journal_begin_ordered_truncate(struct jbd2_inode *inode, loff_t new_size); extern void jbd2_journal_init_jbd_inode(struct jbd2_inode *jinode, struct inode *inode); extern void jbd2_journal_release_jbd_inode(journal_t *journal, struct jbd2_inode *jinode); diff --git a/trunk/include/linux/kvm.h b/trunk/include/linux/kvm.h index 0424326f1679..5715f1907601 100644 --- a/trunk/include/linux/kvm.h +++ b/trunk/include/linux/kvm.h @@ -58,10 +58,10 @@ struct kvm_irqchip { __u32 pad; union { char dummy[512]; /* reserving space */ -#ifdef __KVM_HAVE_PIT +#ifdef CONFIG_X86 struct kvm_pic_state pic; #endif -#ifdef __KVM_HAVE_IOAPIC +#if defined(CONFIG_X86) || defined(CONFIG_IA64) struct kvm_ioapic_state ioapic; #endif } chip; @@ -384,16 +384,16 @@ struct kvm_trace_rec { #define KVM_CAP_MP_STATE 14 #define KVM_CAP_COALESCED_MMIO 15 #define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ -#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT +#if defined(CONFIG_X86)||defined(CONFIG_IA64) #define KVM_CAP_DEVICE_ASSIGNMENT 17 #endif #define KVM_CAP_IOMMU 18 -#ifdef __KVM_HAVE_MSI +#if defined(CONFIG_X86) #define KVM_CAP_DEVICE_MSI 20 #endif /* Bug in KVM_SET_USER_MEMORY_REGION fixed: */ #define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21 -#ifdef __KVM_HAVE_USER_NMI +#if defined(CONFIG_X86) #define KVM_CAP_USER_NMI 22 #endif diff --git a/trunk/include/linux/kvm_host.h b/trunk/include/linux/kvm_host.h index bf6f703642fc..ec49d0be7f52 100644 --- a/trunk/include/linux/kvm_host.h +++ b/trunk/include/linux/kvm_host.h @@ -285,7 +285,6 @@ void kvm_free_physmem(struct kvm *kvm); struct kvm *kvm_arch_create_vm(void); void kvm_arch_destroy_vm(struct kvm *kvm); void kvm_free_all_assigned_devices(struct kvm *kvm); -void kvm_arch_sync_events(struct kvm *kvm); int kvm_cpu_get_interrupt(struct kvm_vcpu *v); int kvm_cpu_has_interrupt(struct kvm_vcpu *v); diff --git a/trunk/virt/kvm/iommu.c b/trunk/virt/kvm/iommu.c index 4c4037503600..e9693a29d00e 100644 --- a/trunk/virt/kvm/iommu.c +++ b/trunk/virt/kvm/iommu.c @@ -73,13 +73,14 @@ static int kvm_iommu_map_memslots(struct kvm *kvm) { int i, r = 0; + down_read(&kvm->slots_lock); for (i = 0; i < kvm->nmemslots; i++) { r = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn, kvm->memslots[i].npages); if (r) break; } - + up_read(&kvm->slots_lock); return r; } @@ -189,11 +190,12 @@ static void kvm_iommu_put_pages(struct kvm *kvm, static int kvm_iommu_unmap_memslots(struct kvm *kvm) { int i; - + down_read(&kvm->slots_lock); for (i = 0; i < kvm->nmemslots; i++) { kvm_iommu_put_pages(kvm, kvm->memslots[i].base_gfn, kvm->memslots[i].npages); } + up_read(&kvm->slots_lock); return 0; } diff --git a/trunk/virt/kvm/kvm_main.c b/trunk/virt/kvm/kvm_main.c index 29a667ce35b0..3a5a08298aab 100644 --- a/trunk/virt/kvm/kvm_main.c +++ b/trunk/virt/kvm/kvm_main.c @@ -173,6 +173,7 @@ static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work) assigned_dev->host_irq_disabled = false; } mutex_unlock(&assigned_dev->kvm->lock); + kvm_put_kvm(assigned_dev->kvm); } static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) @@ -180,6 +181,8 @@ static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) struct kvm_assigned_dev_kernel *assigned_dev = (struct kvm_assigned_dev_kernel *) dev_id; + kvm_get_kvm(assigned_dev->kvm); + schedule_work(&assigned_dev->interrupt_work); disable_irq_nosync(irq); @@ -210,7 +213,6 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian) } } -/* The function implicit hold kvm->lock mutex due to cancel_work_sync() */ static void kvm_free_assigned_irq(struct kvm *kvm, struct kvm_assigned_dev_kernel *assigned_dev) { @@ -226,24 +228,11 @@ static void kvm_free_assigned_irq(struct kvm *kvm, if (!assigned_dev->irq_requested_type) return; - /* - * In kvm_free_device_irq, cancel_work_sync return true if: - * 1. work is scheduled, and then cancelled. - * 2. work callback is executed. - * - * The first one ensured that the irq is disabled and no more events - * would happen. But for the second one, the irq may be enabled (e.g. - * for MSI). So we disable irq here to prevent further events. - * - * Notice this maybe result in nested disable if the interrupt type is - * INTx, but it's OK for we are going to free it. - * - * If this function is a part of VM destroy, please ensure that till - * now, the kvm state is still legal for probably we also have to wait - * interrupt_work done. - */ - disable_irq_nosync(assigned_dev->host_irq); - cancel_work_sync(&assigned_dev->interrupt_work); + if (cancel_work_sync(&assigned_dev->interrupt_work)) + /* We had pending work. That means we will have to take + * care of kvm_put_kvm. + */ + kvm_put_kvm(kvm); free_irq(assigned_dev->host_irq, (void *)assigned_dev); @@ -296,8 +285,8 @@ static int assigned_device_update_intx(struct kvm *kvm, if (irqchip_in_kernel(kvm)) { if (!msi2intx && - (adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI)) { - free_irq(adev->host_irq, (void *)adev); + adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI) { + free_irq(adev->host_irq, (void *)kvm); pci_disable_msi(adev->dev); } @@ -466,7 +455,6 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, struct kvm_assigned_dev_kernel *match; struct pci_dev *dev; - down_read(&kvm->slots_lock); mutex_lock(&kvm->lock); match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head, @@ -528,7 +516,6 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, out: mutex_unlock(&kvm->lock); - up_read(&kvm->slots_lock); return r; out_list_del: list_del(&match->list); @@ -540,7 +527,6 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm, out_free: kfree(match); mutex_unlock(&kvm->lock); - up_read(&kvm->slots_lock); return r; } #endif @@ -803,19 +789,11 @@ static int kvm_mmu_notifier_clear_flush_young(struct mmu_notifier *mn, return young; } -static void kvm_mmu_notifier_release(struct mmu_notifier *mn, - struct mm_struct *mm) -{ - struct kvm *kvm = mmu_notifier_to_kvm(mn); - kvm_arch_flush_shadow(kvm); -} - static const struct mmu_notifier_ops kvm_mmu_notifier_ops = { .invalidate_page = kvm_mmu_notifier_invalidate_page, .invalidate_range_start = kvm_mmu_notifier_invalidate_range_start, .invalidate_range_end = kvm_mmu_notifier_invalidate_range_end, .clear_flush_young = kvm_mmu_notifier_clear_flush_young, - .release = kvm_mmu_notifier_release, }; #endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */ @@ -905,7 +883,6 @@ static void kvm_destroy_vm(struct kvm *kvm) { struct mm_struct *mm = kvm->mm; - kvm_arch_sync_events(kvm); spin_lock(&kvm_lock); list_del(&kvm->vm_list); spin_unlock(&kvm_lock);