Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 63740
b: refs/heads/master
c: 0915c4e
h: refs/heads/master
v: v3
  • Loading branch information
Ingo Molnar committed Aug 9, 2007
1 parent 10b95d4 commit 6870b1e
Show file tree
Hide file tree
Showing 26 changed files with 162 additions and 116 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: e3bcf5e2785aa49f75f36a8d27d601891a7ff12b
refs/heads/master: 0915c4e89d311948b67cdd4c183a2efbcafcc9f9
4 changes: 1 addition & 3 deletions trunk/Documentation/lguest/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ LGUEST_GUEST_TOP := ($(CONFIG_PAGE_OFFSET) - 0x08000000)

CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -Wl,-T,lguest.lds
LDLIBS:=-lz
# Removing this works for some versions of ld.so (eg. Ubuntu Feisty) and
# not others (eg. FC7).
LDFLAGS+=-static

all: lguest.lds lguest

# The linker script on x86 is so complex the only way of creating one
Expand Down
5 changes: 0 additions & 5 deletions trunk/drivers/lguest/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,11 +453,6 @@ static void run_guest_once(struct lguest *lg, struct lguest_pages *pages)
* lguest_pages". */
copy_in_guest_info(lg, pages);

/* Set the trap number to 256 (impossible value). If we fault while
* switching to the Guest (bad segment registers or bug), this will
* cause us to abort the Guest. */
lg->regs->trapnum = 256;

/* Now: we push the "eflags" register on the stack, then do an "lcall".
* This is how we change from using the kernel code segment to using
* the dedicated lguest code segment, as well as jumping into the
Expand Down
9 changes: 3 additions & 6 deletions trunk/drivers/lguest/interrupts_and_traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,16 +195,13 @@ static int has_err(unsigned int trap)
/* deliver_trap() returns true if it could deliver the trap. */
int deliver_trap(struct lguest *lg, unsigned int num)
{
/* Trap numbers are always 8 bit, but we set an impossible trap number
* for traps inside the Switcher, so check that here. */
if (num >= ARRAY_SIZE(lg->idt))
return 0;
u32 lo = lg->idt[num].a, hi = lg->idt[num].b;

/* Early on the Guest hasn't set the IDT entries (or maybe it put a
* bogus one in): if we fail here, the Guest will be killed. */
if (!idt_present(lg->idt[num].a, lg->idt[num].b))
if (!idt_present(lo, hi))
return 0;
set_guest_interrupt(lg, lg->idt[num].a, lg->idt[num].b, has_err(num));
set_guest_interrupt(lg, lo, hi, has_err(num));
return 1;
}

Expand Down
9 changes: 3 additions & 6 deletions trunk/drivers/lguest/lguest.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,12 +323,9 @@ static void lguest_write_gdt_entry(struct desc_struct *dt,
* __thread variables). So we have a hypercall specifically for this case. */
static void lguest_load_tls(struct thread_struct *t, unsigned int cpu)
{
/* There's one problem which normal hardware doesn't have: the Host
* can't handle us removing entries we're currently using. So we clear
* the GS register here: if it's needed it'll be reloaded anyway. */
loadsegment(gs, 0);
lazy_hcall(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu, 0);
}
/*:*/

/*G:038 That's enough excitement for now, back to ploughing through each of
* the paravirt_ops (we're about 1/3 of the way through).
Expand Down Expand Up @@ -690,8 +687,7 @@ static struct clocksource lguest_clock = {
.rating = 400,
.read = lguest_clock_read,
.mask = CLOCKSOURCE_MASK(64),
.mult = 1 << 22,
.shift = 22,
.mult = 1,
};

/* The "scheduler clock" is just our real clock, adjusted to start at zero */
Expand Down Expand Up @@ -774,6 +770,7 @@ static void lguest_time_init(void)
* way, the "rating" is initialized so high that it's always chosen
* over any other clocksource. */
if (lguest_data.tsc_khz) {
lguest_clock.shift = 22;
lguest_clock.mult = clocksource_khz2mult(lguest_data.tsc_khz,
lguest_clock.shift);
lguest_clock.flags = CLOCK_SOURCE_IS_CONTINUOUS;
Expand Down
62 changes: 57 additions & 5 deletions trunk/drivers/lguest/segments.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,22 @@
* begin.
*/

/* Is the descriptor the Guest wants us to put in OK?
*
* The flag which Intel says must be zero: must be zero. The descriptor must
* be present, (this is actually checked earlier but is here for thorougness),
* and the descriptor type must be 1 (a memory segment). */
static int desc_ok(const struct desc_struct *gdt)
{
return ((gdt->b & 0x00209000) == 0x00009000);
}

/* Is the segment present? (Otherwise it can't be used by the Guest). */
static int segment_present(const struct desc_struct *gdt)
{
return gdt->b & 0x8000;
}

/* There are several entries we don't let the Guest set. The TSS entry is the
* "Task State Segment" which controls all kinds of delicate things. The
* LGUEST_CS and LGUEST_DS entries are reserved for the Switcher, and the
Expand All @@ -55,11 +71,37 @@ static int ignored_gdt(unsigned int num)
|| num == GDT_ENTRY_DOUBLEFAULT_TSS);
}

/*H:610 Once the GDT has been changed, we fix the new entries up a little. We
* don't care if they're invalid: the worst that can happen is a General
* Protection Fault in the Switcher when it restores a Guest segment register
* which tries to use that entry. Then we kill the Guest for causing such a
* mess: the message will be "unhandled trap 256". */
/* If the Guest asks us to remove an entry from the GDT, we have to be careful.
* If one of the segment registers is pointing at that entry the Switcher will
* crash when it tries to reload the segment registers for the Guest.
*
* It doesn't make much sense for the Guest to try to remove its own code, data
* or stack segments while they're in use: assume that's a Guest bug. If it's
* one of the lesser segment registers using the removed entry, we simply set
* that register to 0 (unusable). */
static void check_segment_use(struct lguest *lg, unsigned int desc)
{
/* GDT entries are 8 bytes long, so we divide to get the index and
* ignore the bottom bits. */
if (lg->regs->gs / 8 == desc)
lg->regs->gs = 0;
if (lg->regs->fs / 8 == desc)
lg->regs->fs = 0;
if (lg->regs->es / 8 == desc)
lg->regs->es = 0;
if (lg->regs->ds / 8 == desc
|| lg->regs->cs / 8 == desc
|| lg->regs->ss / 8 == desc)
kill_guest(lg, "Removed live GDT entry %u", desc);
}
/*:*/
/*M:009 We wouldn't need to check for removal of in-use segments if we handled
* faults in the Switcher. However, it's probably not a worthwhile
* optimization. :*/

/*H:610 Once the GDT has been changed, we look through the changed entries and
* see if they're OK. If not, we'll call kill_guest() and the Guest will never
* get to use the invalid entries. */
static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end)
{
unsigned int i;
Expand All @@ -70,6 +112,16 @@ static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end)
if (ignored_gdt(i))
continue;

/* We could fault in switch_to_guest if they are using
* a removed segment. */
if (!segment_present(&lg->gdt[i])) {
check_segment_use(lg, i);
continue;
}

if (!desc_ok(&lg->gdt[i]))
kill_guest(lg, "Bad GDT descriptor %i", i);

/* Segment descriptors contain a privilege level: the Guest is
* sometimes careless and leaves this as 0, even though it's
* running at privilege level 1. If so, we fix it here. */
Expand Down
15 changes: 6 additions & 9 deletions trunk/drivers/lguest/switcher.S
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
// Down here in the depths of assembler code.
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/page.h>
#include "lg.h"

// We mark the start of the code to copy
Expand Down Expand Up @@ -183,15 +182,13 @@ ENTRY(switch_to_guest)
movl $(LGUEST_DS), %eax; \
movl %eax, %ds; \
/* So where are we? Which CPU, which struct? \
* The stack is our clue: our TSS starts \
* It at the end of "struct lguest_pages". \
* Or we may have stumbled while restoring \
* Our Guest segment regs while in switch_to_guest, \
* The fault pushed atop that part-unwound stack. \
* If we round the stack down to the page start \
* We're at the start of "struct lguest_pages". */ \
* The stack is our clue: our TSS sets \
* It at the end of "struct lguest_pages" \
* And we then pushed and pushed and pushed Guest regs: \
* Now stack points atop the "struct lguest_regs". \
* Subtract that offset, and we find our struct. */ \
movl %esp, %eax; \
andl $(~(1 << PAGE_SHIFT - 1)), %eax; \
subl $LGUEST_PAGES_regs, %eax; \
/* Save our trap number: the switch will obscure it \
* (The Guest regs are not mapped here in the Host) \
* %ebx holds it safe for deliver_to_host */ \
Expand Down
4 changes: 3 additions & 1 deletion trunk/drivers/net/atl1/atl1_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1704,8 +1704,10 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
}

if (!spin_trylock_irqsave(&adapter->lock, flags)) {
local_irq_save(flags);
if (!spin_trylock(&adapter->lock)) {
/* Can't get lock - tell upper layer to requeue */
local_irq_restore(flags);
dev_printk(KERN_DEBUG, &adapter->pdev->dev, "tx locked\n");
return NETDEV_TX_LOCKED;
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/ehea/ehea.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include <asm/io.h>

#define DRV_NAME "ehea"
#define DRV_VERSION "EHEA_0073"
#define DRV_VERSION "EHEA_0072"

/* eHEA capability flags */
#define DLPAR_PORT_ADD_REM 1
Expand Down
44 changes: 27 additions & 17 deletions trunk/drivers/net/ehea/ehea_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1326,6 +1326,7 @@ static void write_swqe2_TSO(struct sk_buff *skb,
u8 *imm_data = &swqe->u.immdata_desc.immediate_data[0];
int skb_data_size = skb->len - skb->data_len;
int headersize;
u64 tmp_addr;

/* Packet is TCP with TSO enabled */
swqe->tx_control |= EHEA_SWQE_TSO;
Expand All @@ -1346,8 +1347,9 @@ static void write_swqe2_TSO(struct sk_buff *skb,
/* set sg1entry data */
sg1entry->l_key = lkey;
sg1entry->len = skb_data_size - headersize;
sg1entry->vaddr =
ehea_map_vaddr(skb->data + headersize);

tmp_addr = (u64)(skb->data + headersize);
sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
swqe->descriptors++;
}
} else
Expand All @@ -1360,6 +1362,7 @@ static void write_swqe2_nonTSO(struct sk_buff *skb,
int skb_data_size = skb->len - skb->data_len;
u8 *imm_data = &swqe->u.immdata_desc.immediate_data[0];
struct ehea_vsgentry *sg1entry = &swqe->u.immdata_desc.sg_entry;
u64 tmp_addr;

/* Packet is any nonTSO type
*
Expand All @@ -1376,8 +1379,8 @@ static void write_swqe2_nonTSO(struct sk_buff *skb,
/* copy sg1entry data */
sg1entry->l_key = lkey;
sg1entry->len = skb_data_size - SWQE2_MAX_IMM;
sg1entry->vaddr =
ehea_map_vaddr(skb->data + SWQE2_MAX_IMM);
tmp_addr = (u64)(skb->data + SWQE2_MAX_IMM);
sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
swqe->descriptors++;
}
} else {
Expand All @@ -1392,6 +1395,7 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev,
struct ehea_vsgentry *sg_list, *sg1entry, *sgentry;
skb_frag_t *frag;
int nfrags, sg1entry_contains_frag_data, i;
u64 tmp_addr;

nfrags = skb_shinfo(skb)->nr_frags;
sg1entry = &swqe->u.immdata_desc.sg_entry;
Expand All @@ -1413,9 +1417,9 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev,
/* copy sg1entry data */
sg1entry->l_key = lkey;
sg1entry->len = frag->size;
sg1entry->vaddr =
ehea_map_vaddr(page_address(frag->page)
+ frag->page_offset);
tmp_addr = (u64)(page_address(frag->page)
+ frag->page_offset);
sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
swqe->descriptors++;
sg1entry_contains_frag_data = 1;
}
Expand All @@ -1427,9 +1431,10 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev,

sgentry->l_key = lkey;
sgentry->len = frag->size;
sgentry->vaddr =
ehea_map_vaddr(page_address(frag->page)
+ frag->page_offset);

tmp_addr = (u64)(page_address(frag->page)
+ frag->page_offset);
sgentry->vaddr = ehea_map_vaddr(tmp_addr);
swqe->descriptors++;
}
}
Expand Down Expand Up @@ -2160,18 +2165,24 @@ static int ehea_clean_all_portres(struct ehea_port *port)
return ret;
}

static void ehea_remove_adapter_mr(struct ehea_adapter *adapter)
static void ehea_remove_adapter_mr (struct ehea_adapter *adapter)
{
if (adapter->active_ports)
return;
int i;

for (i=0; i < EHEA_MAX_PORTS; i++)
if (adapter->port[i])
return;

ehea_rem_mr(&adapter->mr);
}

static int ehea_add_adapter_mr(struct ehea_adapter *adapter)
static int ehea_add_adapter_mr (struct ehea_adapter *adapter)
{
if (adapter->active_ports)
return 0;
int i;

for (i=0; i < EHEA_MAX_PORTS; i++)
if (adapter->port[i])
return 0;

return ehea_reg_kernel_mr(adapter, &adapter->mr);
}
Expand Down Expand Up @@ -3088,7 +3099,6 @@ int __init ehea_module_init(void)

static void __exit ehea_module_exit(void)
{
destroy_workqueue(ehea_driver_wq);
driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
ibmebus_unregister_driver(&ehea_driver);
ehea_destroy_busmap();
Expand Down
27 changes: 12 additions & 15 deletions trunk/drivers/net/ibmveth.c
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
{
int rc, i;
struct net_device *netdev;
struct ibmveth_adapter *adapter;
struct ibmveth_adapter *adapter = NULL;

unsigned char *mac_addr_p;
unsigned int *mcastFilterSize_p;
Expand Down Expand Up @@ -997,6 +997,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
SET_MODULE_OWNER(netdev);

adapter = netdev->priv;
memset(adapter, 0, sizeof(adapter));
dev->dev.driver_data = netdev;

adapter->vdev = dev;
Expand Down Expand Up @@ -1279,28 +1280,24 @@ const char * buf, size_t count)
int i;
/* Make sure there is a buffer pool with buffers that
can hold a packet of the size of the MTU */
for (i = 0; i < IbmVethNumBufferPools; i++) {
for(i = 0; i<IbmVethNumBufferPools; i++) {
if (pool == &adapter->rx_buff_pool[i])
continue;
if (!adapter->rx_buff_pool[i].active)
continue;
if (mtu <= adapter->rx_buff_pool[i].buff_size)
break;
if (mtu < adapter->rx_buff_pool[i].buff_size) {
pool->active = 0;
h_free_logical_lan_buffer(adapter->
vdev->
unit_address,
pool->
buff_size);
}
}

if (i == IbmVethNumBufferPools) {
if (pool->active) {
ibmveth_error_printk("no active pool >= MTU\n");
return -EPERM;
}

pool->active = 0;
if (netif_running(netdev)) {
adapter->pool_config = 1;
ibmveth_close(netdev);
adapter->pool_config = 0;
if ((rc = ibmveth_open(netdev)))
return rc;
}
}
} else if (attr == &veth_num_attr) {
if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT)
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/net/ibmveth.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ static inline long h_send_logical_lan(unsigned long unit_address,
#define h_change_logical_lan_mac(ua, mac) \
plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac)

#define h_free_logical_lan_buffer(ua, bufsize) \
plpar_hcall_norets(H_FREE_LOGICAL_LAN_BUFFER, ua, bufsize)

#define IbmVethNumBufferPools 5
#define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */
#define IBMVETH_MAX_MTU 68
Expand Down
Loading

0 comments on commit 6870b1e

Please sign in to comment.