aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/battery.c10
-rw-r--r--drivers/kvm/svm.c18
-rw-r--r--drivers/kvm/x86_emulate.c26
-rw-r--r--drivers/lguest/lguest_device.c3
-rw-r--r--drivers/net/virtio_net.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c2
-rw-r--r--drivers/ssb/main.c6
-rw-r--r--drivers/ssb/pcmcia.c56
-rw-r--r--drivers/virtio/virtio_ring.c10
10 files changed, 84 insertions, 52 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index c2ce0ad..192c244 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -132,7 +132,7 @@ static int acpi_battery_technology(struct acpi_battery *battery)
return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
}
-static int acpi_battery_update(struct acpi_battery *battery);
+static int acpi_battery_get_state(struct acpi_battery *battery);
static int acpi_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
@@ -140,10 +140,11 @@ static int acpi_battery_get_property(struct power_supply *psy,
{
struct acpi_battery *battery = to_acpi_battery(psy);
- if ((!acpi_battery_present(battery)) &&
- psp != POWER_SUPPLY_PROP_PRESENT)
+ if (acpi_battery_present(battery)) {
+ /* run battery update only if it is present */
+ acpi_battery_get_state(battery);
+ } else if (psp != POWER_SUPPLY_PROP_PRESENT)
return -ENODEV;
- acpi_battery_update(battery);
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
if (battery->state & 0x01)
@@ -457,6 +458,7 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
return;
device_remove_file(battery->bat.dev, &alarm_attr);
power_supply_unregister(&battery->bat);
+ battery->bat.dev = NULL;
}
static int acpi_battery_update(struct acpi_battery *battery)
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 729f1cd..7a6eead 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -494,6 +494,7 @@ static void init_vmcb(struct vmcb *vmcb)
*/
/* (1ULL << INTERCEPT_SELECTIVE_CR0) | */
(1ULL << INTERCEPT_CPUID) |
+ (1ULL << INTERCEPT_INVD) |
(1ULL << INTERCEPT_HLT) |
(1ULL << INTERCEPT_INVLPGA) |
(1ULL << INTERCEPT_IOIO_PROT) |
@@ -507,6 +508,7 @@ static void init_vmcb(struct vmcb *vmcb)
(1ULL << INTERCEPT_STGI) |
(1ULL << INTERCEPT_CLGI) |
(1ULL << INTERCEPT_SKINIT) |
+ (1ULL << INTERCEPT_WBINVD) |
(1ULL << INTERCEPT_MONITOR) |
(1ULL << INTERCEPT_MWAIT);
@@ -561,6 +563,12 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu)
struct vcpu_svm *svm = to_svm(vcpu);
init_vmcb(svm->vmcb);
+
+ if (vcpu->vcpu_id != 0) {
+ svm->vmcb->save.rip = 0;
+ svm->vmcb->save.cs.base = svm->vcpu.sipi_vector << 12;
+ svm->vmcb->save.cs.selector = svm->vcpu.sipi_vector << 8;
+ }
}
static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
@@ -1241,6 +1249,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
[SVM_EXIT_VINTR] = interrupt_window_interception,
/* [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, */
[SVM_EXIT_CPUID] = cpuid_interception,
+ [SVM_EXIT_INVD] = emulate_on_interception,
[SVM_EXIT_HLT] = halt_interception,
[SVM_EXIT_INVLPG] = emulate_on_interception,
[SVM_EXIT_INVLPGA] = invalid_op_interception,
@@ -1255,6 +1264,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
[SVM_EXIT_STGI] = invalid_op_interception,
[SVM_EXIT_CLGI] = invalid_op_interception,
[SVM_EXIT_SKINIT] = invalid_op_interception,
+ [SVM_EXIT_WBINVD] = emulate_on_interception,
[SVM_EXIT_MONITOR] = invalid_op_interception,
[SVM_EXIT_MWAIT] = invalid_op_interception,
};
@@ -1579,10 +1589,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
#endif
: "cc", "memory" );
- local_irq_disable();
-
- stgi();
-
if ((svm->vmcb->save.dr7 & 0xff))
load_db_regs(svm->host_db_regs);
@@ -1599,6 +1605,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
reload_tss(vcpu);
+ local_irq_disable();
+
+ stgi();
+
svm->next_rip = 0;
}
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index a6ace30..33b1814 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -167,7 +167,7 @@ static u8 opcode_table[256] = {
static u16 twobyte_table[256] = {
/* 0x00 - 0x0F */
0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0,
- 0, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
+ ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
/* 0x10 - 0x1F */
0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
/* 0x20 - 0x2F */
@@ -980,17 +980,6 @@ done_prefixes:
goto cannot_emulate;
dst.val = (s32) src.val;
break;
- case 0x6a: /* push imm8 */
- src.val = 0L;
- src.val = insn_fetch(s8, 1, _eip);
-push:
- dst.type = OP_MEM;
- dst.bytes = op_bytes;
- dst.val = src.val;
- register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes);
- dst.ptr = (void *) register_address(ctxt->ss_base,
- _regs[VCPU_REGS_RSP]);
- break;
case 0x80 ... 0x83: /* Grp1 */
switch (modrm_reg) {
case 0:
@@ -1243,6 +1232,17 @@ special_insn:
register_address_increment(_regs[VCPU_REGS_RSP], op_bytes);
no_wb = 1; /* Disable writeback. */
break;
+ case 0x6a: /* push imm8 */
+ src.val = 0L;
+ src.val = insn_fetch(s8, 1, _eip);
+ push:
+ dst.type = OP_MEM;
+ dst.bytes = op_bytes;
+ dst.val = src.val;
+ register_address_increment(_regs[VCPU_REGS_RSP], -op_bytes);
+ dst.ptr = (void *) register_address(ctxt->ss_base,
+ _regs[VCPU_REGS_RSP]);
+ break;
case 0x6c: /* insb */
case 0x6d: /* insw/insd */
if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
@@ -1532,6 +1532,8 @@ twobyte_special_insn:
case 0x06:
emulate_clts(ctxt->vcpu);
break;
+ case 0x08: /* invd */
+ break;
case 0x09: /* wbinvd */
break;
case 0x0d: /* GrpP (prefetch) */
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index 8904f72..66f3872 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -200,7 +200,8 @@ static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
/* Figure out how many pages the ring will take, and map that memory */
lvq->pages = lguest_map((unsigned long)lvq->config.pfn << PAGE_SHIFT,
- DIV_ROUND_UP(vring_size(lvq->config.num),
+ DIV_ROUND_UP(vring_size(lvq->config.num,
+ PAGE_SIZE),
PAGE_SIZE));
if (!lvq->pages) {
err = -ENOMEM;
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index e396c9d..a75be57 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -146,6 +146,7 @@ static void try_fill_recv(struct virtnet_info *vi)
struct scatterlist sg[1+MAX_SKB_FRAGS];
int num, err;
+ sg_init_table(sg, 1+MAX_SKB_FRAGS);
for (;;) {
skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN);
if (unlikely(!skb))
@@ -231,6 +232,8 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev)
const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
DECLARE_MAC_BUF(mac);
+ sg_init_table(sg, 1+MAX_SKB_FRAGS);
+
pr_debug("%s: xmit %p %s\n", dev->name, skb, print_mac(mac, dest));
free_old_xmit_skbs(vi);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 4f22a71..be7c9f4 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -8354,6 +8354,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
SET_IEEE80211_DEV(hw, &pdev->dev);
+ hw->rate_control_algorithm = "iwl-3945-rs";
+
IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
priv = hw->priv;
priv->hw = hw;
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index d60adcb..6757c6c 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -8955,6 +8955,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
SET_IEEE80211_DEV(hw, &pdev->dev);
+ hw->rate_control_algorithm = "iwl-4965-rs";
+
IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
priv = hw->priv;
priv->hw = hw;
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index c12a741..85a2054 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -440,6 +440,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
break;
case SSB_BUSTYPE_PCMCIA:
#ifdef CONFIG_SSB_PCMCIAHOST
+ sdev->irq = bus->host_pcmcia->irq.AssignedIRQ;
dev->parent = &bus->host_pcmcia->dev;
#endif
break;
@@ -1147,7 +1148,10 @@ static int __init ssb_modinit(void)
return err;
}
-subsys_initcall(ssb_modinit);
+/* ssb must be initialized after PCI but before the ssb drivers.
+ * That means we must use some initcall between subsys_initcall
+ * and device_initcall. */
+fs_initcall(ssb_modinit);
static void __exit ssb_modexit(void)
{
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
index b6abee8..bb44a76 100644
--- a/drivers/ssb/pcmcia.c
+++ b/drivers/ssb/pcmcia.c
@@ -63,17 +63,17 @@ int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
err = pcmcia_access_configuration_register(pdev, &reg);
if (err != CS_SUCCESS)
goto error;
- read_addr |= (reg.Value & 0xF) << 12;
+ read_addr |= ((u32)(reg.Value & 0x0F)) << 12;
reg.Offset = 0x30;
err = pcmcia_access_configuration_register(pdev, &reg);
if (err != CS_SUCCESS)
goto error;
- read_addr |= reg.Value << 16;
+ read_addr |= ((u32)reg.Value) << 16;
reg.Offset = 0x32;
err = pcmcia_access_configuration_register(pdev, &reg);
if (err != CS_SUCCESS)
goto error;
- read_addr |= reg.Value << 24;
+ read_addr |= ((u32)reg.Value) << 24;
cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE;
if (cur_core == coreidx)
@@ -152,28 +152,29 @@ error:
goto out_unlock;
}
-/* These are the main device register access functions.
- * do_select_core is inline to have the likely hotpath inline.
- * All unlikely codepaths are out-of-line. */
-static inline int do_select_core(struct ssb_bus *bus,
- struct ssb_device *dev,
- u16 *offset)
+static int select_core_and_segment(struct ssb_device *dev,
+ u16 *offset)
{
+ struct ssb_bus *bus = dev->bus;
int err;
- u8 need_seg = (*offset >= 0x800) ? 1 : 0;
+ u8 need_segment;
+
+ if (*offset >= 0x800) {
+ *offset -= 0x800;
+ need_segment = 1;
+ } else
+ need_segment = 0;
if (unlikely(dev != bus->mapped_device)) {
err = ssb_pcmcia_switch_core(bus, dev);
if (unlikely(err))
return err;
}
- if (unlikely(need_seg != bus->mapped_pcmcia_seg)) {
- err = ssb_pcmcia_switch_segment(bus, need_seg);
+ if (unlikely(need_segment != bus->mapped_pcmcia_seg)) {
+ err = ssb_pcmcia_switch_segment(bus, need_segment);
if (unlikely(err))
return err;
}
- if (need_seg == 1)
- *offset -= 0x800;
return 0;
}
@@ -181,32 +182,31 @@ static inline int do_select_core(struct ssb_bus *bus,
static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
{
struct ssb_bus *bus = dev->bus;
- u16 x;
- if (unlikely(do_select_core(bus, dev, &offset)))
+ if (unlikely(select_core_and_segment(dev, &offset)))
return 0xFFFF;
- x = readw(bus->mmio + offset);
- return x;
+ return readw(bus->mmio + offset);
}
static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
{
struct ssb_bus *bus = dev->bus;
- u32 x;
+ u32 lo, hi;
- if (unlikely(do_select_core(bus, dev, &offset)))
+ if (unlikely(select_core_and_segment(dev, &offset)))
return 0xFFFFFFFF;
- x = readl(bus->mmio + offset);
+ lo = readw(bus->mmio + offset);
+ hi = readw(bus->mmio + offset + 2);
- return x;
+ return (lo | (hi << 16));
}
static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
{
struct ssb_bus *bus = dev->bus;
- if (unlikely(do_select_core(bus, dev, &offset)))
+ if (unlikely(select_core_and_segment(dev, &offset)))
return;
writew(value, bus->mmio + offset);
}
@@ -215,12 +215,12 @@ static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value)
{
struct ssb_bus *bus = dev->bus;
- if (unlikely(do_select_core(bus, dev, &offset)))
+ if (unlikely(select_core_and_segment(dev, &offset)))
return;
- readw(bus->mmio + offset);
- writew(value >> 16, bus->mmio + offset + 2);
- readw(bus->mmio + offset);
- writew(value, bus->mmio + offset);
+ writeb((value & 0xFF000000) >> 24, bus->mmio + offset + 3);
+ writeb((value & 0x00FF0000) >> 16, bus->mmio + offset + 2);
+ writeb((value & 0x0000FF00) >> 8, bus->mmio + offset + 1);
+ writeb((value & 0x000000FF) >> 0, bus->mmio + offset + 0);
}
/* Not "static", as it's used in main.c */
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 0e4baca..1dc04b6 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -53,7 +53,7 @@ struct vring_virtqueue
unsigned int num_added;
/* Last used index we've seen. */
- unsigned int last_used_idx;
+ u16 last_used_idx;
/* How to notify other side. FIXME: commonalize hcalls! */
void (*notify)(struct virtqueue *vq);
@@ -277,11 +277,17 @@ struct virtqueue *vring_new_virtqueue(unsigned int num,
struct vring_virtqueue *vq;
unsigned int i;
+ /* We assume num is a power of 2. */
+ if (num & (num - 1)) {
+ dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num);
+ return NULL;
+ }
+
vq = kmalloc(sizeof(*vq) + sizeof(void *)*num, GFP_KERNEL);
if (!vq)
return NULL;
- vring_init(&vq->vring, num, pages);
+ vring_init(&vq->vring, num, pages, PAGE_SIZE);
vq->vq.callback = callback;
vq->vq.vdev = vdev;
vq->vq.vq_ops = &vring_vq_ops;