bitkeeper revision 1.536 (3f9fd20aglcfc5h0kB1oldciJuy2dQ)

Many files:
  Modified blkdev and network interfaces to allow expedited flushing of pending request buffers.
This commit is contained in:
kaf24@scramble.cl.cam.ac.uk committed 2003-10-29 14:43:22 +00:00
1 parent 042e1237bd
commit 35c6e9fc2e
19 files changed
+545 -484

No files matched your search

+6 -4
View File
@@ -103,12 +103,13 @@ static inline int HYPERVISOR_set_callbacks(
return ret;
}
static inline int HYPERVISOR_net_update(void)
static inline int HYPERVISOR_net_io_op(unsigned int op, unsigned int idx)
{
int ret;
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_net_update) );
: "=a" (ret) : "0" (__HYPERVISOR_net_io_op),
"b" (op), "c" (idx) );
return ret;
}
@@ -165,12 +166,13 @@ static inline int HYPERVISOR_network_op(void *network_op)
return ret;
}
static inline int HYPERVISOR_block_io_op(void)
static inline int HYPERVISOR_block_io_op(unsigned int op)
{
int ret;
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_block_io_op) );
: "=a" (ret) : "0" (__HYPERVISOR_block_io_op),
"b" (op) );
return ret;
}
+6 -7
View File
@@ -1,9 +1,8 @@
#include <os.h>
/* Offsets in start_info structure */
#define SHARED_INFO 4
#define MOD_START 12
#define MOD_LEN 16
#define MOD_START 4
#define MOD_LEN 8
#define ENTRY(X) .globl X ; X :
@@ -31,10 +30,10 @@ _start:
/* Clear BSS first so that there are no surprises... */
2: xorl %eax,%eax
movl $__bss_start,%edi
movl $_end,%ecx
subl %edi,%ecx
rep stosb
movl $__bss_start,%edi
movl $_end,%ecx
subl %edi,%ecx
rep stosb
push %esi
call start_kernel
+4 -16
View File
@@ -230,12 +230,8 @@ static int setup_guestos(
alloc_index = tot_pages - 1;
/*
* Count bottom-level PTs, rounding up. Include one PTE for shared info. We
* therefore add 1024 because 1 is for shared_info, 1023 is to round up.
*/
num_pt_pages =
(l1_table_offset(virt_load_addr) + tot_pages + 1024) / 1024;
/* Count bottom-level PTs, rounding up. */
num_pt_pages = (l1_table_offset(virt_load_addr) + tot_pages + 1023) / 1024;
/* We must also count the page directory. */
num_pt_pages++;
@@ -250,7 +246,6 @@ static int setup_guestos(
l2tab = page_array[alloc_index] << PAGE_SHIFT;
alloc_index--;
meminfo->l2_pgt_addr = l2tab;
meminfo->virt_shinfo_addr = virt_load_addr + (tot_pages << PAGE_SHIFT);
/*
* Pin down l2tab addr as page dir page - causes hypervisor to provide
@@ -261,16 +256,12 @@ static int setup_guestos(
pgt_updates++;
num_pgt_updates++;
/*
* Initialise the page tables. The final iteration is for the shared_info
* PTE -- we break out before filling in the entry, as that is done by
* Xen during final setup.
*/
/* Initialise the page tables. */
if ( (vl2tab = map_pfn(l2tab >> PAGE_SHIFT)) == NULL )
goto error_out;
memset(vl2tab, 0, PAGE_SIZE);
vl2e = vl2tab + l2_table_offset(virt_load_addr);
for ( count = 0; count < (tot_pages + 1); count++ )
for ( count = 0; count < tot_pages; count++ )
{
if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
{
@@ -291,9 +282,6 @@ static int setup_guestos(
vl2e++;
}
/* The last PTE we consider is filled in later by Xen. */
if ( count == tot_pages ) break;
if ( count < pt_start )
{
pgt_updates->ptr = (unsigned long)vl1e;
+1 -1
View File
@@ -710,7 +710,7 @@ ENTRY(hypervisor_call_table)
.long SYMBOL_NAME(do_set_gdt)
.long SYMBOL_NAME(do_stack_switch)
.long SYMBOL_NAME(do_set_callbacks)
.long SYMBOL_NAME(do_net_update)
.long SYMBOL_NAME(do_net_io_op)
.long SYMBOL_NAME(do_fpu_taskswitch)
.long SYMBOL_NAME(do_yield)
.long SYMBOL_NAME(kill_domain)
+11 -39
View File
@@ -347,7 +347,6 @@ void release_task(struct task_struct *p)
int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo)
{
l2_pgentry_t * l2tab;
l1_pgentry_t * l1tab;
start_info_t * virt_startinfo_addr;
unsigned long virt_stack_addr;
unsigned long phys_l2tab;
@@ -374,19 +373,9 @@ int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo)
p->mm.pagetable = mk_pagetable(phys_l2tab);
unmap_domain_mem(l2tab);
/* map in the shared info structure */
phys_l2tab = pagetable_val(p->mm.pagetable);
l2tab = map_domain_mem(phys_l2tab);
l2tab += l2_table_offset(meminfo->virt_shinfo_addr);
l1tab = map_domain_mem(l2_pgentry_to_phys(*l2tab));
l1tab += l1_table_offset(meminfo->virt_shinfo_addr);
*l1tab = mk_l1_pgentry(__pa(p->shared_info) | L1_PROT);
unmap_domain_mem((void *)((unsigned long)l2tab & PAGE_MASK));
unmap_domain_mem((void *)((unsigned long)l1tab & PAGE_MASK));
/* set up the shared info structure */
update_dom_time(p->shared_info);
p->shared_info->domain_time = 0;
p->shared_info->domain_time = 0;
/* we pass start info struct to guest os as function parameter on stack */
virt_startinfo_addr = (start_info_t *)meminfo->virt_startinfo_addr;
@@ -401,7 +390,7 @@ int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo)
memset(virt_startinfo_addr, 0, sizeof(*virt_startinfo_addr));
virt_startinfo_addr->nr_pages = p->tot_pages;
virt_startinfo_addr->shared_info = (shared_info_t *)meminfo->virt_shinfo_addr;
virt_startinfo_addr->shared_info = virt_to_phys(p->shared_info);
virt_startinfo_addr->pt_base = meminfo->virt_load_addr +
((p->tot_pages - 1) << PAGE_SHIFT);
@@ -474,7 +463,7 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params,
int i, dom = p->domain;
unsigned long phys_l1tab, phys_l2tab;
unsigned long cur_address, alloc_address;
unsigned long virt_load_address, virt_stack_address, virt_shinfo_address;
unsigned long virt_load_address, virt_stack_address;
start_info_t *virt_startinfo_address;
unsigned long count;
unsigned long alloc_index;
@@ -551,16 +540,11 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params,
memset(l2tab, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE*sizeof(l2_pgentry_t));
p->mm.pagetable = mk_pagetable(phys_l2tab);
/*
* NB. The upper limit on this loop does one extra page. This is to make
* sure a pte exists when we want to map the shared_info struct.
*/
l2tab += l2_table_offset(virt_load_address);
cur_address = list_entry(p->pg_head.next, struct pfn_info, list) -
frame_table;
cur_address <<= PAGE_SHIFT;
for ( count = 0; count < p->tot_pages + 1; count++ )
for ( count = 0; count < p->tot_pages; count++ )
{
if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) )
{
@@ -574,14 +558,11 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params,
}
*l1tab++ = mk_l1_pgentry(cur_address|L1_PROT);
if ( count < p->tot_pages )
{
page = frame_table + (cur_address >> PAGE_SHIFT);
page->flags = dom | PGT_writeable_page | PG_need_flush;
page->type_count = page->tot_count = 1;
/* Set up the MPT entry. */
machine_to_phys_mapping[cur_address >> PAGE_SHIFT] = count;
}
page = frame_table + (cur_address >> PAGE_SHIFT);
page->flags = dom | PGT_writeable_page | PG_need_flush;
page->type_count = page->tot_count = 1;
/* Set up the MPT entry. */
machine_to_phys_mapping[cur_address >> PAGE_SHIFT] = count;
list_ent = frame_table[cur_address >> PAGE_SHIFT].list.next;
cur_address = list_entry(list_ent, struct pfn_info, list) -
@@ -630,17 +611,9 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params,
page->flags = dom | PGT_l2_page_table;
unmap_domain_mem(l1start);
/* Map in the the shared info structure. */
virt_shinfo_address = virt_load_address + (p->tot_pages << PAGE_SHIFT);
l2tab = l2start + l2_table_offset(virt_shinfo_address);
l1start = l1tab = map_domain_mem(l2_pgentry_to_phys(*l2tab));
l1tab += l1_table_offset(virt_shinfo_address);
*l1tab = mk_l1_pgentry(__pa(p->shared_info)|L1_PROT);
unmap_domain_mem(l1start);
/* Set up shared info area. */
update_dom_time(p->shared_info);
p->shared_info->domain_time = 0;
p->shared_info->domain_time = 0;
virt_startinfo_address = (start_info_t *)
(virt_load_address + ((alloc_index - 1) << PAGE_SHIFT));
@@ -671,8 +644,7 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params,
/* Set up start info area. */
memset(virt_startinfo_address, 0, sizeof(*virt_startinfo_address));
virt_startinfo_address->nr_pages = p->tot_pages;
virt_startinfo_address->shared_info =
(shared_info_t *)virt_shinfo_address;
virt_startinfo_address->shared_info = virt_to_phys(p->shared_info);
virt_startinfo_address->pt_base = virt_load_address +
((p->tot_pages - 1) << PAGE_SHIFT);
+3 -33
View File
@@ -159,40 +159,10 @@ net_vif_t *create_net_vif(int domain)
void destroy_net_vif(net_vif_t *vif)
{
int i;
unsigned long *pte, flags;
struct pfn_info *page;
extern long flush_bufs_for_vif(net_vif_t *vif);
struct task_struct *p = vif->domain;
/* Return any outstanding receive buffers to the guest OS. */
spin_lock_irqsave(&p->page_lock, flags);
for ( i = vif->rx_cons; i != vif->rx_prod; i = ((i+1) & (RX_RING_SIZE-1)) )
{
rx_shadow_entry_t *rx = vif->rx_shadow_ring + i;
/* Release the page-table page. */
page = frame_table + (rx->pte_ptr >> PAGE_SHIFT);
put_page_type(page);
put_page_tot(page);
/* Give the buffer page back to the domain. */
page = frame_table + rx->buf_pfn;
list_add(&page->list, &p->pg_head);
page->flags = vif->domain->domain;
/* Patch up the PTE if it hasn't changed under our feet. */
pte = map_domain_mem(rx->pte_ptr);
if ( !(*pte & _PAGE_PRESENT) )
{
*pte = (rx->buf_pfn<<PAGE_SHIFT) | (*pte & ~PAGE_MASK) |
_PAGE_RW | _PAGE_PRESENT;
page->flags |= PGT_writeable_page | PG_need_flush;
page->type_count = page->tot_count = 1;
}
unmap_domain_mem(pte);
}
spin_unlock_irqrestore(&p->page_lock, flags);
(void)flush_bufs_for_vif(vif);
UNSHARE_PFN(virt_to_page(vif->shared_rings));
kmem_cache_free(net_vif_cache, vif);
put_task_struct(p);
}
+19 -4
View File
@@ -241,11 +241,26 @@ static void end_block_io_op(struct buffer_head *bh, int uptodate)
* GUEST-OS SYSCALL -- Indicates there are requests outstanding.
*/
long do_block_io_op(void)
long do_block_io_op(unsigned int op)
{
add_to_blkdev_list_tail(current);
maybe_trigger_io_schedule();
return 0L;
long ret = 0;
switch ( op )
{
case BLKOP_PUSH_BUFFERS:
add_to_blkdev_list_tail(current);
maybe_trigger_io_schedule();
break;
case BLKOP_FLUSH_BUFFERS:
break;
default:
ret = -EINVAL;
break;
}
return ret;
}
+8
View File
@@ -8,6 +8,14 @@
#ifndef __BLOCK_H__
#define __BLOCK_H__
/*
* Command values for block_io_op()
*/
#define BLKOP_PUSH_BUFFERS 0 /* Notify Xen of new requests on the ring. */
#define BLKOP_FLUSH_BUFFERS 1 /* Flush all pending request buffers. */
/*
* Device numbers
*/
-1
View File
@@ -57,7 +57,6 @@ typedef struct domain_launch
unsigned int domain;
unsigned long l2_pgt_addr;
unsigned long virt_load_addr;
unsigned long virt_shinfo_addr;
unsigned long virt_startinfo_addr;
unsigned int num_vifs;
char cmd_line[MAX_CMD_LEN];
+37 -37
View File
@@ -19,9 +19,9 @@
* NB. The reserved range is inclusive (that is, both FIRST_RESERVED_GDT_ENTRY
* and LAST_RESERVED_GDT_ENTRY are reserved).
*/
#define NR_RESERVED_GDT_ENTRIES 40
#define FIRST_RESERVED_GDT_ENTRY 256
#define LAST_RESERVED_GDT_ENTRY \
#define NR_RESERVED_GDT_ENTRIES 40
#define FIRST_RESERVED_GDT_ENTRY 256
#define LAST_RESERVED_GDT_ENTRY \
(FIRST_RESERVED_GDT_ENTRY + NR_RESERVED_GDT_ENTRIES - 1)
/*
@@ -29,10 +29,10 @@
* are also present in the initial GDT, many OSes will be able to avoid
* installing their own GDT.
*/
#define FLAT_RING1_CS 0x0819
#define FLAT_RING1_DS 0x0821
#define FLAT_RING3_CS 0x082b
#define FLAT_RING3_DS 0x0833
#define FLAT_RING1_CS 0x0819
#define FLAT_RING1_DS 0x0821
#define FLAT_RING3_CS 0x082b
#define FLAT_RING3_DS 0x0833
/*
@@ -40,25 +40,25 @@
*/
/* EAX = vector; EBX, ECX, EDX, ESI, EDI = args 1, 2, 3, 4, 5. */
#define __HYPERVISOR_set_trap_table 0
#define __HYPERVISOR_mmu_update 1
#define __HYPERVISOR_console_write 2
#define __HYPERVISOR_set_gdt 3
#define __HYPERVISOR_set_trap_table 0
#define __HYPERVISOR_mmu_update 1
#define __HYPERVISOR_console_write 2
#define __HYPERVISOR_set_gdt 3
#define __HYPERVISOR_stack_switch 4
#define __HYPERVISOR_set_callbacks 5
#define __HYPERVISOR_net_update 6
#define __HYPERVISOR_fpu_taskswitch 7
#define __HYPERVISOR_yield 8
#define __HYPERVISOR_exit 9
#define __HYPERVISOR_dom0_op 10
#define __HYPERVISOR_network_op 11
#define __HYPERVISOR_block_io_op 12
#define __HYPERVISOR_set_debugreg 13
#define __HYPERVISOR_get_debugreg 14
#define __HYPERVISOR_update_descriptor 15
#define __HYPERVISOR_set_fast_trap 16
#define __HYPERVISOR_dom_mem_op 17
#define __HYPERVISOR_multicall 18
#define __HYPERVISOR_net_io_op 6
#define __HYPERVISOR_fpu_taskswitch 7
#define __HYPERVISOR_yield 8
#define __HYPERVISOR_exit 9
#define __HYPERVISOR_dom0_op 10
#define __HYPERVISOR_network_op 11
#define __HYPERVISOR_block_io_op 12
#define __HYPERVISOR_set_debugreg 13
#define __HYPERVISOR_get_debugreg 14
#define __HYPERVISOR_update_descriptor 15
#define __HYPERVISOR_set_fast_trap 16
#define __HYPERVISOR_dom_mem_op 17
#define __HYPERVISOR_multicall 18
#define __HYPERVISOR_kbd_op 19
#define __HYPERVISOR_update_va_mapping 20
@@ -276,19 +276,19 @@ typedef struct shared_info_st {
* NB. We expect that this struct is smaller than a page.
*/
typedef struct start_info_st {
unsigned long nr_pages; /* total pages allocated to this domain */
shared_info_t *shared_info; /* VIRTUAL address of shared info struct */
unsigned long pt_base; /* VIRTUAL address of page directory */
unsigned long mod_start; /* VIRTUAL address of pre-loaded module */
unsigned long mod_len; /* size (bytes) of pre-loaded module */
/* Machine address of net rings for each VIF. Will be page aligned. */
unsigned long net_rings[MAX_DOMAIN_VIFS];
unsigned char net_vmac[MAX_DOMAIN_VIFS][6];
/* Machine address of block-device ring. Will be page aligned. */
unsigned long blk_ring;
unsigned int dom_id;
unsigned long flags;
unsigned char cmd_line[1]; /* variable-length */
/* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME). */
unsigned long pt_base; /* VIRTUAL address of page directory. */
unsigned long mod_start; /* VIRTUAL address of pre-loaded module. */
unsigned long mod_len; /* Size (bytes) of pre-loaded module. */
/* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. */
unsigned long nr_pages; /* total pages allocated to this domain. */
unsigned long shared_info; /* MACHINE address of shared info struct.*/
unsigned int dom_id; /* Domain identifier. */
unsigned long flags; /* SIF_xxx flags. */
unsigned long net_rings[MAX_DOMAIN_VIFS]; /* MACHINE address of ring.*/
unsigned char net_vmac[MAX_DOMAIN_VIFS][6]; /* MAC address of VIF. */
unsigned long blk_ring; /* MACHINE address of blkdev ring. */
unsigned char cmd_line[1]; /* Variable-length options. */
} start_info_t;
/* These flags are passed in the 'flags' field of start_info_t. */
+8
View File
@@ -12,6 +12,14 @@
#ifndef __RING_H__
#define __RING_H__
/*
* Command values for block_io_op()
*/
#define NETOP_PUSH_BUFFERS 0 /* Notify Xen of new buffers on the rings. */
#define NETOP_FLUSH_BUFFERS 1 /* Flush all pending request buffers. */
typedef struct tx_req_entry_st
{
unsigned short id;
+202 -110
View File
@@ -1877,7 +1877,7 @@ static int get_tx_bufs(net_vif_t *vif)
tx = shared_rings->tx_ring[i].req;
target = VIF_DROP;
if ( (tx.size < PKT_PROT_LEN) || (tx.size > ETH_FRAME_LEN) )
if ( (tx.size <= PKT_PROT_LEN) || (tx.size > ETH_FRAME_LEN) )
{
DPRINTK("Bad packet size: %d\n", tx.size);
__make_tx_response(vif, tx.id, RING_STATUS_BAD_PAGE);
@@ -2019,130 +2019,222 @@ static int get_tx_bufs(net_vif_t *vif)
}
static long get_bufs_from_vif(net_vif_t *vif)
{
net_ring_t *shared_rings;
net_idx_t *shared_idxs;
unsigned int i, j;
rx_req_entry_t rx;
unsigned long pte_pfn, buf_pfn;
struct pfn_info *pte_page, *buf_page;
struct task_struct *p = vif->domain;
unsigned long *ptep;
shared_idxs = vif->shared_idxs;
shared_rings = vif->shared_rings;
/*
* PHASE 1 -- TRANSMIT RING
*/
if ( get_tx_bufs(vif) )
{
add_to_net_schedule_list_tail(vif);
maybe_schedule_tx_action();
}
/*
* PHASE 2 -- RECEIVE RING
*/
/*
* Collect up new receive buffers. We collect up to the guest OS's new
* producer index, but take care not to catch up with our own consumer
* index.
*/
j = vif->rx_prod;
for ( i = vif->rx_req_cons;
(i != shared_idxs->rx_req_prod) &&
(((vif->rx_resp_prod-i) & (RX_RING_SIZE-1)) != 1);
i = RX_RING_INC(i) )
{
rx = shared_rings->rx_ring[i].req;
pte_pfn = rx.addr >> PAGE_SHIFT;
pte_page = frame_table + pte_pfn;
spin_lock_irq(&p->page_lock);
if ( (pte_pfn >= max_page) ||
((pte_page->flags & (PG_type_mask | PG_domain_mask)) !=
(PGT_l1_page_table | p->domain)) )
{
DPRINTK("Bad page frame for ppte %d,%08lx,%08lx,%08lx\n",
p->domain, pte_pfn, max_page, pte_page->flags);
spin_unlock_irq(&p->page_lock);
make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
continue;
}
ptep = map_domain_mem(rx.addr);
if ( !(*ptep & _PAGE_PRESENT) )
{
DPRINTK("Invalid PTE passed down (not present)\n");
make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
goto rx_unmap_and_continue;
}
buf_pfn = *ptep >> PAGE_SHIFT;
buf_page = frame_table + buf_pfn;
if ( ((buf_page->flags & (PG_type_mask | PG_domain_mask)) !=
(PGT_writeable_page | p->domain)) ||
(buf_page->tot_count != 1) )
{
DPRINTK("Need a mapped-once writeable page (%ld/%ld/%08lx)\n",
buf_page->type_count, buf_page->tot_count,
buf_page->flags);
make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
goto rx_unmap_and_continue;
}
/*
* The pte they passed was good, so take it away from them. We also
* lock down the page-table page, so it doesn't go away.
*/
get_page_type(pte_page);
get_page_tot(pte_page);
*ptep &= ~_PAGE_PRESENT;
buf_page->flags = buf_page->type_count = buf_page->tot_count = 0;
list_del(&buf_page->list);
vif->rx_shadow_ring[j].id = rx.id;
vif->rx_shadow_ring[j].pte_ptr = rx.addr;
vif->rx_shadow_ring[j].buf_pfn = buf_pfn;
vif->rx_shadow_ring[j].flush_count = (unsigned short)
atomic_read(&tlb_flush_count[smp_processor_id()]);
j = RX_RING_INC(j);
rx_unmap_and_continue:
unmap_domain_mem(ptep);
spin_unlock_irq(&p->page_lock);
}
vif->rx_req_cons = i;
if ( vif->rx_prod != j )
{
smp_mb(); /* Let other CPUs see new descriptors first. */
vif->rx_prod = j;
}
return 0;
}
long flush_bufs_for_vif(net_vif_t *vif)
{
int i;
unsigned long *pte, flags;
struct pfn_info *page;
struct task_struct *p = vif->domain;
rx_shadow_entry_t *rx;
net_ring_t *shared_rings = vif->shared_rings;
net_idx_t *shared_idxs = vif->shared_idxs;
/* Return any outstanding receive buffers to the guest OS. */
spin_lock_irqsave(&p->page_lock, flags);
for ( i = vif->rx_req_cons;
(i != shared_idxs->rx_req_prod) &&
(((vif->rx_resp_prod-i) & (RX_RING_SIZE-1)) != 1);
i = RX_RING_INC(i) )
{
make_rx_response(vif, shared_rings->rx_ring[i].req.id, 0,
RING_STATUS_DROPPED, 0);
}
vif->rx_req_cons = i;
for ( i = vif->rx_cons; i != vif->rx_prod; i = RX_RING_INC(i) )
{
rx = &vif->rx_shadow_ring[i];
/* Release the page-table page. */
page = frame_table + (rx->pte_ptr >> PAGE_SHIFT);
put_page_type(page);
put_page_tot(page);
/* Give the buffer page back to the domain. */
page = frame_table + rx->buf_pfn;
list_add(&page->list, &p->pg_head);
page->flags = vif->domain->domain;
/* Patch up the PTE if it hasn't changed under our feet. */
pte = map_domain_mem(rx->pte_ptr);
if ( !(*pte & _PAGE_PRESENT) )
{
*pte = (rx->buf_pfn<<PAGE_SHIFT) | (*pte & ~PAGE_MASK) |
_PAGE_RW | _PAGE_PRESENT;
page->flags |= PGT_writeable_page | PG_need_flush;
page->type_count = page->tot_count = 1;
}
unmap_domain_mem(pte);
make_rx_response(vif, rx->id, 0, RING_STATUS_DROPPED, 0);
}
vif->rx_cons = i;
spin_unlock_irqrestore(&p->page_lock, flags);
/*
* Flush pending transmit buffers. The guest may still have to wait for
* buffers that are queued at a physical NIC.
*/
spin_lock_irqsave(&vif->tx_lock, flags);
for ( i = vif->tx_req_cons;
(i != shared_idxs->tx_req_prod) &&
(((vif->tx_resp_prod-i) & (TX_RING_SIZE-1)) != 1);
i = TX_RING_INC(i) )
{
__make_tx_response(vif, shared_rings->tx_ring[i].req.id,
RING_STATUS_DROPPED);
}
vif->tx_req_cons = i;
spin_unlock_irqrestore(&vif->tx_lock, flags);
return 0;
}
/*
* do_net_update:
* do_net_io_op:
*
* Called from guest OS to notify updates to its transmit and/or receive
* descriptor rings.
*/
long do_net_update(void)
long do_net_io_op(unsigned int op, unsigned int idx)
{
net_ring_t *shared_rings;
net_vif_t *vif;
net_idx_t *shared_idxs;
unsigned int i, j, idx;
rx_req_entry_t rx;
unsigned long pte_pfn, buf_pfn;
struct pfn_info *pte_page, *buf_page;
unsigned long *ptep;
long ret;
perfc_incr(net_hypercalls);
for ( idx = 0; idx < MAX_DOMAIN_VIFS; idx++ )
if ( (vif = current->net_vif_list[idx]) == NULL )
return -EINVAL;
switch ( op )
{
if ( (vif = current->net_vif_list[idx]) == NULL )
break;
case NETOP_PUSH_BUFFERS:
ret = get_bufs_from_vif(vif);
break;
shared_idxs = vif->shared_idxs;
shared_rings = vif->shared_rings;
/*
* PHASE 1 -- TRANSMIT RING
*/
case NETOP_FLUSH_BUFFERS:
ret = flush_bufs_for_vif(vif);
break;
if ( get_tx_bufs(vif) )
{
add_to_net_schedule_list_tail(vif);
maybe_schedule_tx_action();
}
/*
* PHASE 2 -- RECEIVE RING
*/
/*
* Collect up new receive buffers. We collect up to the guest OS's
* new producer index, but take care not to catch up with our own
* consumer index.
*/
j = vif->rx_prod;
for ( i = vif->rx_req_cons;
(i != shared_idxs->rx_req_prod) &&
(((vif->rx_resp_prod-i) & (RX_RING_SIZE-1)) != 1);
i = RX_RING_INC(i) )
{
rx = shared_rings->rx_ring[i].req;
pte_pfn = rx.addr >> PAGE_SHIFT;
pte_page = frame_table + pte_pfn;
spin_lock_irq(&current->page_lock);
if ( (pte_pfn >= max_page) ||
((pte_page->flags & (PG_type_mask | PG_domain_mask)) !=
(PGT_l1_page_table | current->domain)) )
{
DPRINTK("Bad page frame for ppte %d,%08lx,%08lx,%08lx\n",
current->domain, pte_pfn, max_page, pte_page->flags);
spin_unlock_irq(&current->page_lock);
make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
continue;
}
ptep = map_domain_mem(rx.addr);
if ( !(*ptep & _PAGE_PRESENT) )
{
DPRINTK("Invalid PTE passed down (not present)\n");
make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
goto rx_unmap_and_continue;
}
buf_pfn = *ptep >> PAGE_SHIFT;
buf_page = frame_table + buf_pfn;
if ( ((buf_page->flags & (PG_type_mask | PG_domain_mask)) !=
(PGT_writeable_page | current->domain)) ||
(buf_page->tot_count != 1) )
{
DPRINTK("Need a mapped-once writeable page (%ld/%ld/%08lx)\n",
buf_page->type_count, buf_page->tot_count, buf_page->flags);
make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
goto rx_unmap_and_continue;
}
/*
* The pte they passed was good, so take it away from them. We
* also lock down the page-table page, so it doesn't go away.
*/
get_page_type(pte_page);
get_page_tot(pte_page);
*ptep &= ~_PAGE_PRESENT;
buf_page->flags = buf_page->type_count = buf_page->tot_count = 0;
list_del(&buf_page->list);
vif->rx_shadow_ring[j].id = rx.id;
vif->rx_shadow_ring[j].pte_ptr = rx.addr;
vif->rx_shadow_ring[j].buf_pfn = buf_pfn;
vif->rx_shadow_ring[j].flush_count = (unsigned short)
atomic_read(&tlb_flush_count[smp_processor_id()]);
j = RX_RING_INC(j);
rx_unmap_and_continue:
unmap_domain_mem(ptep);
spin_unlock_irq(&current->page_lock);
}
vif->rx_req_cons = i;
if ( vif->rx_prod != j )
{
smp_mb(); /* Let other CPUs see new descriptors first. */
vif->rx_prod = j;
}
default:
ret = -EINVAL;
break;
}
return 0;
return ret;
}
@@ -40,7 +40,7 @@ static inline void signal_requests_to_xen(void)
{
DISABLE_SCATTERGATHER();
blk_ring->req_prod = req_prod;
HYPERVISOR_block_io_op();
HYPERVISOR_block_io_op(BLKOP_PUSH_BUFFERS);
}
@@ -249,7 +249,7 @@ static void network_alloc_rx_buffers(struct net_device *dev)
/* Batch Xen notifications. */
if ( np->rx_bufs_to_notify > (RX_MAX_ENTRIES/4) )
{
HYPERVISOR_net_update();
HYPERVISOR_net_io_op(NETOP_PUSH_BUFFERS, np->idx);
np->rx_bufs_to_notify = 0;
}
}
@@ -322,7 +322,7 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Only notify Xen if there are no outstanding responses. */
mb();
if ( np->net_idx->tx_resp_prod == i )
HYPERVISOR_net_update();
HYPERVISOR_net_io_op(NETOP_PUSH_BUFFERS, np->idx);
return 0;
}
@@ -9,9 +9,8 @@
#include <asm/desc.h>
/* Offsets in start_info structure */
#define SHARED_INFO 4
#define MOD_START 12
#define MOD_LEN 16
#define MOD_START 4
#define MOD_LEN 8
startup_32:
cld
@@ -35,19 +34,16 @@ startup_32:
/* Clear BSS first so that there are no surprises... */
2: xorl %eax,%eax
movl $SYMBOL_NAME(__bss_start),%edi
movl $SYMBOL_NAME(_end),%ecx
subl %edi,%ecx
rep stosb
movl $SYMBOL_NAME(__bss_start),%edi
movl $SYMBOL_NAME(_end),%ecx
subl %edi,%ecx
rep stosb
/* Copy the necessary stuff from start_info structure. */
/* We need to copy shared_info early, so that sti/cli work */
mov SHARED_INFO(%esi),%eax
mov %eax,SYMBOL_NAME(HYPERVISOR_shared_info)
mov $SYMBOL_NAME(start_info_union),%edi
mov $128,%ecx
rep movsl
jmp SYMBOL_NAME(start_kernel)
ENTRY(stack_start)
@@ -46,7 +46,11 @@
#include <asm/hypervisor.h>
#include <asm/hypervisor-ifs/dom0_ops.h>
shared_info_t *HYPERVISOR_shared_info;
/*
* Point at the empty zero page to start with. We map the real shared_info
* page as soon as fixmap is up and running.
*/
shared_info_t *HYPERVISOR_shared_info = empty_zero_page;
unsigned long *phys_to_machine_mapping;
+216 -211
View File
@@ -43,50 +43,50 @@ static unsigned long totalhigh_pages;
int do_check_pgt_cache(int low, int high)
{
int freed = 0;
if(pgtable_cache_size > high) {
do {
int freed = 0;
if(pgtable_cache_size > high) {
do {
if (!QUICKLIST_EMPTY(pgd_quicklist)) {
free_pgd_slow(get_pgd_fast());
freed++;
}
free_pgd_slow(get_pgd_fast());
freed++;
}
if (!QUICKLIST_EMPTY(pte_quicklist)) {
pte_free_slow(pte_alloc_one_fast(NULL, 0));
freed++;
}
} while(pgtable_cache_size > low);
}
return freed;
pte_free_slow(pte_alloc_one_fast(NULL, 0));
freed++;
}
} while(pgtable_cache_size > low);
}
return freed;
}
void show_mem(void)
{
int i, total = 0, reserved = 0;
int shared = 0, cached = 0;
int highmem = 0;
int i, total = 0, reserved = 0;
int shared = 0, cached = 0;
int highmem = 0;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = max_mapnr;
while (i-- > 0) {
total++;
if (PageHighMem(mem_map+i))
highmem++;
if (PageReserved(mem_map+i))
reserved++;
else if (PageSwapCache(mem_map+i))
cached++;
else if (page_count(mem_map+i))
shared += page_count(mem_map+i) - 1;
}
printk("%d pages of RAM\n", total);
printk("%d pages of HIGHMEM\n",highmem);
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
printk("%d pages swap cached\n",cached);
printk("%ld pages in page table cache\n",pgtable_cache_size);
show_buffers();
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = max_mapnr;
while (i-- > 0) {
total++;
if (PageHighMem(mem_map+i))
highmem++;
if (PageReserved(mem_map+i))
reserved++;
else if (PageSwapCache(mem_map+i))
cached++;
else if (page_count(mem_map+i))
shared += page_count(mem_map+i) - 1;
}
printk("%d pages of RAM\n", total);
printk("%d pages of HIGHMEM\n",highmem);
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
printk("%d pages swap cached\n",cached);
printk("%ld pages in page table cache\n",pgtable_cache_size);
show_buffers();
}
/* References to section boundaries */
@@ -95,118 +95,118 @@ extern char _text, _etext, _edata, __bss_start, _end;
extern char __init_begin, __init_end;
static inline void set_pte_phys (unsigned long vaddr,
unsigned long phys, pgprot_t flags)
unsigned long phys, pgprot_t flags)
{
pgprot_t prot;
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
pgprot_t prot;
pgd_t *pgd;
pmd_t *pmd;
pte_t *pte;
pgd = init_mm.pgd + __pgd_offset(vaddr);
if (pgd_none(*pgd)) {
printk("PAE BUG #00!\n");
return;
}
pmd = pmd_offset(pgd, vaddr);
if (pmd_none(*pmd)) {
printk("PAE BUG #01!\n");
return;
}
pte = pte_offset(pmd, vaddr);
pgd = init_mm.pgd + __pgd_offset(vaddr);
if (pgd_none(*pgd)) {
printk("PAE BUG #00!\n");
return;
}
pmd = pmd_offset(pgd, vaddr);
if (pmd_none(*pmd)) {
printk("PAE BUG #01!\n");
return;
}
pte = pte_offset(pmd, vaddr);
if (pte_val(*pte))
pte_ERROR(*pte);
if (pte_val(*pte))
pte_ERROR(*pte);
pgprot_val(prot) = pgprot_val(PAGE_KERNEL) | pgprot_val(flags);
pgprot_val(prot) = pgprot_val(PAGE_KERNEL) | pgprot_val(flags);
/* We queue directly, avoiding hidden phys->machine translation. */
queue_l1_entry_update(pte, phys | pgprot_val(prot));
/* We queue directly, avoiding hidden phys->machine translation. */
queue_l1_entry_update(pte, phys | pgprot_val(prot));
/*
* It's enough to flush this one mapping.
* (PGE mappings get flushed as well)
*/
__flush_tlb_one(vaddr);
/*
* It's enough to flush this one mapping.
* (PGE mappings get flushed as well)
*/
__flush_tlb_one(vaddr);
}
void __set_fixmap (enum fixed_addresses idx, unsigned long phys,
pgprot_t flags)
{
unsigned long address = __fix_to_virt(idx);
unsigned long address = __fix_to_virt(idx);
if (idx >= __end_of_fixed_addresses) {
printk("Invalid __set_fixmap\n");
return;
}
set_pte_phys(address, phys, flags);
if (idx >= __end_of_fixed_addresses) {
printk("Invalid __set_fixmap\n");
return;
}
set_pte_phys(address, phys, flags);
}
static void __init fixrange_init (unsigned long start,
unsigned long end, pgd_t *pgd_base)
{
pgd_t *pgd, *kpgd;
pmd_t *pmd, *kpmd;
pte_t *pte, *kpte;
int i, j;
unsigned long vaddr;
pgd_t *pgd, *kpgd;
pmd_t *pmd, *kpmd;
pte_t *pte, *kpte;
int i, j;
unsigned long vaddr;
vaddr = start;
i = __pgd_offset(vaddr);
j = __pmd_offset(vaddr);
pgd = pgd_base + i;
vaddr = start;
i = __pgd_offset(vaddr);
j = __pmd_offset(vaddr);
pgd = pgd_base + i;
for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
#if CONFIG_X86_PAE
if (pgd_none(*pgd)) {
pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
if (pmd != pmd_offset(pgd, 0))
printk("PAE BUG #02!\n");
}
pmd = pmd_offset(pgd, vaddr);
if (pgd_none(*pgd)) {
pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
if (pmd != pmd_offset(pgd, 0))
printk("PAE BUG #02!\n");
}
pmd = pmd_offset(pgd, vaddr);
#else
pmd = (pmd_t *)pgd;
pmd = (pmd_t *)pgd;
#endif
for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
if (pmd_none(*pmd)) {
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
clear_page(pte);
kpgd = pgd_offset_k((unsigned long)pte);
kpmd = pmd_offset(kpgd, (unsigned long)pte);
kpte = pte_offset(kpmd, (unsigned long)pte);
queue_l1_entry_update(kpte,
for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
if (pmd_none(*pmd)) {
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
clear_page(pte);
kpgd = pgd_offset_k((unsigned long)pte);
kpmd = pmd_offset(kpgd, (unsigned long)pte);
kpte = pte_offset(kpmd, (unsigned long)pte);
queue_l1_entry_update(kpte,
(*(unsigned long *)kpte)&~_PAGE_RW);
set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
}
vaddr += PMD_SIZE;
}
j = 0;
}
set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
}
vaddr += PMD_SIZE;
}
j = 0;
}
XENO_flush_page_update_queue();
XENO_flush_page_update_queue();
}
static void __init zone_sizes_init(void)
{
unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
unsigned int max_dma, high, low;
unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
unsigned int max_dma, high, low;
max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
low = max_low_pfn;
high = highend_pfn;
max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
low = max_low_pfn;
high = highend_pfn;
if (low < max_dma)
zones_size[ZONE_DMA] = low;
else {
zones_size[ZONE_DMA] = max_dma;
zones_size[ZONE_NORMAL] = low - max_dma;
if (low < max_dma)
zones_size[ZONE_DMA] = low;
else {
zones_size[ZONE_DMA] = max_dma;
zones_size[ZONE_NORMAL] = low - max_dma;
#ifdef CONFIG_HIGHMEM
zones_size[ZONE_HIGHMEM] = high - low;
zones_size[ZONE_HIGHMEM] = high - low;
#endif
}
free_area_init(zones_size);
}
free_area_init(zones_size);
}
/*
@@ -218,60 +218,65 @@ static void __init zone_sizes_init(void)
*/
void __init paging_init(void)
{
unsigned long vaddr;
unsigned long vaddr;
zone_sizes_init();
zone_sizes_init();
/*
* Fixed mappings, only the page table structure has to be created -
* mappings will be set by set_fixmap():
*/
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
fixrange_init(vaddr, HYPERVISOR_VIRT_START, init_mm.pgd);
/*
* Fixed mappings, only the page table structure has to be created -
* mappings will be set by set_fixmap():
*/
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
fixrange_init(vaddr, HYPERVISOR_VIRT_START, init_mm.pgd);
/* Cheesy: this can probably be moved to the blkdev driver. */
set_fixmap(FIX_BLKRING_BASE, start_info.blk_ring);
/* Cheesy: this can probably be moved to the blkdev driver. */
set_fixmap(FIX_BLKRING_BASE, start_info.blk_ring);
/* Switch to the real shared_info page, and clear the dummy page. */
set_fixmap(FIX_SHARED_INFO, start_info.shared_info);
HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
memset(empty_zero_page, 0, sizeof(empty_zero_page));
#ifdef CONFIG_HIGHMEM
#error
kmap_init();
kmap_init();
#endif
}
static inline int page_is_ram (unsigned long pagenr)
{
return 1;
return 1;
}
#ifdef CONFIG_HIGHMEM
void __init one_highpage_init(struct page *page, int pfn, int bad_ppro)
{
if (!page_is_ram(pfn)) {
SetPageReserved(page);
return;
}
if (!page_is_ram(pfn)) {
SetPageReserved(page);
return;
}
if (bad_ppro && page_kills_ppro(pfn)) {
SetPageReserved(page);
return;
}
if (bad_ppro && page_kills_ppro(pfn)) {
SetPageReserved(page);
return;
}
ClearPageReserved(page);
set_bit(PG_highmem, &page->flags);
atomic_set(&page->count, 1);
__free_page(page);
totalhigh_pages++;
ClearPageReserved(page);
set_bit(PG_highmem, &page->flags);
atomic_set(&page->count, 1);
__free_page(page);
totalhigh_pages++;
}
#endif /* CONFIG_HIGHMEM */
static void __init set_max_mapnr_init(void)
{
#ifdef CONFIG_HIGHMEM
highmem_start_page = mem_map + highstart_pfn;
max_mapnr = num_physpages = highend_pfn;
num_mappedpages = max_low_pfn;
highmem_start_page = mem_map + highstart_pfn;
max_mapnr = num_physpages = highend_pfn;
num_mappedpages = max_low_pfn;
#else
max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
#endif
}
@@ -279,112 +284,112 @@ static int __init free_pages_init(void)
{
#ifdef CONFIG_HIGHMEM
#error Where is this supposed to be initialised?
int bad_ppro;
int bad_ppro;
#endif
int reservedpages, pfn;
int reservedpages, pfn;
/* this will put all low memory onto the freelists */
totalram_pages += free_all_bootmem();
/* this will put all low memory onto the freelists */
totalram_pages += free_all_bootmem();
reservedpages = 0;
for (pfn = 0; pfn < max_low_pfn; pfn++) {
/*
* Only count reserved RAM pages
*/
if (page_is_ram(pfn) && PageReserved(mem_map+pfn))
reservedpages++;
}
reservedpages = 0;
for (pfn = 0; pfn < max_low_pfn; pfn++) {
/*
* Only count reserved RAM pages
*/
if (page_is_ram(pfn) && PageReserved(mem_map+pfn))
reservedpages++;
}
#ifdef CONFIG_HIGHMEM
for (pfn = highend_pfn-1; pfn >= highstart_pfn; pfn--)
one_highpage_init((struct page *) (mem_map + pfn), pfn, bad_ppro);
totalram_pages += totalhigh_pages;
for (pfn = highend_pfn-1; pfn >= highstart_pfn; pfn--)
one_highpage_init((struct page *) (mem_map + pfn), pfn, bad_ppro);
totalram_pages += totalhigh_pages;
#endif
return reservedpages;
return reservedpages;
}
void __init mem_init(void)
{
int codesize, reservedpages, datasize, initsize;
int codesize, reservedpages, datasize, initsize;
if (!mem_map)
BUG();
if (!mem_map)
BUG();
set_max_mapnr_init();
set_max_mapnr_init();
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
/* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE);
/* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE);
reservedpages = free_pages_init();
reservedpages = free_pages_init();
codesize = (unsigned long) &_etext - (unsigned long) &_text;
datasize = (unsigned long) &_edata - (unsigned long) &_etext;
initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
codesize = (unsigned long) &_etext - (unsigned long) &_text;
datasize = (unsigned long) &_edata - (unsigned long) &_etext;
initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
max_mapnr << (PAGE_SHIFT-10),
codesize >> 10,
reservedpages << (PAGE_SHIFT-10),
datasize >> 10,
initsize >> 10,
(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
);
printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
max_mapnr << (PAGE_SHIFT-10),
codesize >> 10,
reservedpages << (PAGE_SHIFT-10),
datasize >> 10,
initsize >> 10,
(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
);
boot_cpu_data.wp_works_ok = 1;
}
void free_initmem(void)
{
unsigned long addr;
unsigned long addr;
addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1);
free_page(addr);
totalram_pages++;
}
printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
set_page_count(virt_to_page(addr), 1);
free_page(addr);
totalram_pages++;
}
printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
}
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
if (start < end)
printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1);
free_page(start);
totalram_pages++;
}
if (start < end)
printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
for (; start < end; start += PAGE_SIZE) {
ClearPageReserved(virt_to_page(start));
set_page_count(virt_to_page(start), 1);
free_page(start);
totalram_pages++;
}
}
#endif
void si_meminfo(struct sysinfo *val)
{
val->totalram = totalram_pages;
val->sharedram = 0;
val->freeram = nr_free_pages();
val->bufferram = atomic_read(&buffermem_pages);
val->totalhigh = totalhigh_pages;
val->freehigh = nr_free_highpages();
val->mem_unit = PAGE_SIZE;
return;
val->totalram = totalram_pages;
val->sharedram = 0;
val->freeram = nr_free_pages();
val->bufferram = atomic_read(&buffermem_pages);
val->totalhigh = totalhigh_pages;
val->freehigh = nr_free_highpages();
val->mem_unit = PAGE_SIZE;
return;
}
#if defined(CONFIG_X86_PAE)
struct kmem_cache_s *pae_pgd_cachep;
void __init pgtable_cache_init(void)
{
/*
* PAE pgds must be 16-byte aligned:
/*
* PAE pgds must be 16-byte aligned:
*/
pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0,
SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL);
if (!pae_pgd_cachep)
panic("init_pae(): Cannot alloc pae_pgd SLAB cache");
pae_pgd_cachep = kmem_cache_create("pae_pgd", 32, 0,
SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL);
if (!pae_pgd_cachep)
panic("init_pae(): Cannot alloc pae_pgd SLAB cache");
}
#endif /* CONFIG_X86_PAE */
@@ -47,15 +47,16 @@ enum fixed_addresses {
FIX_NETRING1_BASE,
FIX_NETRING2_BASE,
FIX_NETRING3_BASE,
FIX_SHARED_INFO,
#ifdef CONFIG_VGA_CONSOLE
#define NR_FIX_BTMAPS 32 /* 128KB For the Dom0 VGA Console A0000-C0000 */
#else
#define NR_FIX_BTMAPS 1 /* have on page incase anyone wants it in future */
#define NR_FIX_BTMAPS 1 /* in case anyone wants it in future... */
#endif
FIX_BTMAP_END,
FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
/* our bt_ioremap is permenant unlike other architectures */
/* our bt_ioremap is permanent, unlike other architectures */
__end_of_permanent_fixed_addresses,
__end_of_fixed_addresses = __end_of_permanent_fixed_addresses
@@ -219,12 +219,13 @@ static inline int HYPERVISOR_set_callbacks(
return ret;
}
static inline int HYPERVISOR_net_update(void)
static inline int HYPERVISOR_net_io_op(unsigned int op, unsigned int idx)
{
int ret;
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_net_update) );
: "=a" (ret) : "0" (__HYPERVISOR_net_io_op),
"b" (op), "c" (idx) );
return ret;
}
@@ -281,12 +282,13 @@ static inline int HYPERVISOR_network_op(void *network_op)
return ret;
}
static inline int HYPERVISOR_block_io_op(void)
static inline int HYPERVISOR_block_io_op(unsigned int op)
{
int ret;
__asm__ __volatile__ (
TRAP_INSTR
: "=a" (ret) : "0" (__HYPERVISOR_block_io_op) );
: "=a" (ret) : "0" (__HYPERVISOR_block_io_op),
"b" (op) );
return ret;
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.