This commit is contained in:
emellor@leeni.uk.xensource.com committed 2006-03-23 17:37:37 +01:00
commit 22f9491cad
18 files changed
+222 -159

No files matched your search

+14 -12
View File
@@ -32,13 +32,13 @@
#endif
static int direct_remap_area_pte_fn(pte_t *pte,
struct page *pte_page,
struct page *pmd_page,
unsigned long address,
void *data)
{
mmu_update_t **v = (mmu_update_t **)data;
(*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pte_page)) <<
(*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) <<
PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
(*v)++;
@@ -67,9 +67,9 @@ static int __direct_remap_pfn_range(struct mm_struct *mm,
for (i = 0; i < size; i += PAGE_SIZE) {
if ((v - u) == (PAGE_SIZE / sizeof(mmu_update_t))) {
/* Fill in the PTE pointers. */
rc = generic_page_range(mm, start_address,
address - start_address,
direct_remap_area_pte_fn, &w);
rc = apply_to_page_range(mm, start_address,
address - start_address,
direct_remap_area_pte_fn, &w);
if (rc)
goto out;
w = u;
@@ -93,8 +93,9 @@ static int __direct_remap_pfn_range(struct mm_struct *mm,
if (v != u) {
/* get the ptep's filled in */
rc = generic_page_range(mm, start_address, address - start_address,
direct_remap_area_pte_fn, &w);
rc = apply_to_page_range(mm, start_address,
address - start_address,
direct_remap_area_pte_fn, &w);
if (rc)
goto out;
rc = -EFAULT;
@@ -142,11 +143,11 @@ int direct_kernel_remap_pfn_range(unsigned long address,
EXPORT_SYMBOL(direct_kernel_remap_pfn_range);
static int lookup_pte_fn(
pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
{
uint64_t *ptep = (uint64_t *)data;
if (ptep)
*ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pte_page)) <<
*ptep = ((uint64_t)pfn_to_mfn(page_to_pfn(pmd_page)) <<
PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
return 0;
}
@@ -155,13 +156,14 @@ int create_lookup_pte_addr(struct mm_struct *mm,
unsigned long address,
uint64_t *ptep)
{
return generic_page_range(mm, address, PAGE_SIZE, lookup_pte_fn, ptep);
return apply_to_page_range(mm, address, PAGE_SIZE,
lookup_pte_fn, ptep);
}
EXPORT_SYMBOL(create_lookup_pte_addr);
static int noop_fn(
pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
{
return 0;
}
@@ -170,7 +172,7 @@ int touch_pte_range(struct mm_struct *mm,
unsigned long address,
unsigned long size)
{
return generic_page_range(mm, address, size, noop_fn, NULL);
return apply_to_page_range(mm, address, size, noop_fn, NULL);
}
EXPORT_SYMBOL(touch_pte_range);
@@ -114,8 +114,6 @@ void smp_apic_timer_interrupt(struct pt_regs *regs)
irq_exit();
}
int __initdata unsync_tsc_on_multicluster;
/*
* This interrupt should _never_ happen with our APIC/SMP architecture
*/
@@ -517,7 +517,7 @@ void balloon_update_driver_allowance(long delta)
}
static int dealloc_pte_fn(
pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
{
unsigned long mfn = pte_mfn(*pte);
int ret;
@@ -547,8 +547,8 @@ struct page *balloon_alloc_empty_page_range(unsigned long nr_pages)
scrub_pages(vstart, 1 << order);
balloon_lock(flags);
ret = generic_page_range(
&init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL);
ret = apply_to_page_range(&init_mm, vstart,
PAGE_SIZE << order, dealloc_pte_fn, NULL);
BUG_ON(ret);
current_pages -= 1UL << order;
totalram_pages = current_pages;
+12 -10
View File
@@ -360,7 +360,7 @@ gnttab_request_free_callback(struct gnttab_free_callback *callback,
}
#ifndef __ia64__
static int map_pte_fn(pte_t *pte, struct page *pte_page,
static int map_pte_fn(pte_t *pte, struct page *pmd_page,
unsigned long addr, void *data)
{
unsigned long **frames = (unsigned long **)data;
@@ -370,7 +370,7 @@ static int map_pte_fn(pte_t *pte, struct page *pte_page,
return 0;
}
static int unmap_pte_fn(pte_t *pte, struct page *pte_page,
static int unmap_pte_fn(pte_t *pte, struct page *pmd_page,
unsigned long addr, void *data)
{
@@ -384,6 +384,7 @@ gnttab_resume(void)
{
gnttab_setup_table_t setup;
unsigned long frames[NR_GRANT_FRAMES];
int rc;
#ifndef __ia64__
void *pframes = frames;
struct vm_struct *area;
@@ -393,8 +394,8 @@ gnttab_resume(void)
setup.nr_frames = NR_GRANT_FRAMES;
setup.frame_list = frames;
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1));
BUG_ON(setup.status != 0);
rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
BUG_ON(rc || setup.status);
#ifndef __ia64__
if (shared == NULL) {
@@ -402,9 +403,10 @@ gnttab_resume(void)
BUG_ON(area == NULL);
shared = area->addr;
}
BUG_ON(generic_page_range(&init_mm, (unsigned long)shared,
PAGE_SIZE * NR_GRANT_FRAMES,
map_pte_fn, &pframes));
rc = apply_to_page_range(&init_mm, (unsigned long)shared,
PAGE_SIZE * NR_GRANT_FRAMES,
map_pte_fn, &pframes);
BUG_ON(rc);
#else
shared = __va(frames[0] << PAGE_SHIFT);
printk("grant table at %p\n", shared);
@@ -418,9 +420,9 @@ gnttab_suspend(void)
{
#ifndef __ia64__
generic_page_range(&init_mm, (unsigned long)shared,
PAGE_SIZE * NR_GRANT_FRAMES,
unmap_pte_fn, NULL);
apply_to_page_range(&init_mm, (unsigned long)shared,
PAGE_SIZE * NR_GRANT_FRAMES,
unmap_pte_fn, NULL);
#endif
return 0;
+4 -4
View File
@@ -6,9 +6,9 @@
#include <asm/uaccess.h>
#include <xen/driver_util.h>
static int f(pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
static int f(pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
{
/* generic_page_range() does all the hard work. */
/* apply_to_page_range() does all the hard work. */
return 0;
}
@@ -24,8 +24,8 @@ struct vm_struct *alloc_vm_area(unsigned long size)
* This ensures that page tables are constructed for this region
* of kernel virtual address space and mapped into init_mm.
*/
if (generic_page_range(&init_mm, (unsigned long)area->addr,
area->size, f, NULL)) {
if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
area->size, f, NULL)) {
free_vm_area(area);
return NULL;
}
+4 -4
View File
@@ -1020,10 +1020,10 @@ struct page *follow_page(struct vm_area_struct *, unsigned long address,
#define FOLL_ANON 0x08 /* give ZERO_PAGE if no pgtable */
#ifdef CONFIG_XEN
typedef int (*pte_fn_t)(pte_t *pte, struct page *pte_page, unsigned long addr,
void *data);
extern int generic_page_range(struct mm_struct *mm, unsigned long address,
unsigned long size, pte_fn_t fn, void *data);
typedef int (*pte_fn_t)(pte_t *pte, struct page *pmd_page, unsigned long addr,
void *data);
extern int apply_to_page_range(struct mm_struct *mm, unsigned long address,
unsigned long size, pte_fn_t fn, void *data);
#endif
#ifdef CONFIG_PROC_FS
+23 -19
View File
@@ -1378,36 +1378,39 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
EXPORT_SYMBOL(remap_pfn_range);
#ifdef CONFIG_XEN
static inline int generic_pte_range(struct mm_struct *mm, pmd_t *pmd,
unsigned long addr, unsigned long end,
pte_fn_t fn, void *data)
static inline int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
unsigned long addr, unsigned long end,
pte_fn_t fn, void *data)
{
pte_t *pte;
int err;
struct page *pte_page;
struct page *pmd_page;
spinlock_t *ptl;
pte = (mm == &init_mm) ?
pte_alloc_kernel(pmd, addr) :
pte_alloc_map(mm, pmd, addr);
pte_alloc_map_lock(mm, pmd, addr, &ptl);
if (!pte)
return -ENOMEM;
pte_page = pmd_page(*pmd);
BUG_ON(pmd_huge(*pmd));
pmd_page = pmd_page(*pmd);
do {
err = fn(pte, pte_page, addr, data);
err = fn(pte, pmd_page, addr, data);
if (err)
break;
} while (pte++, addr += PAGE_SIZE, addr != end);
if (mm != &init_mm)
pte_unmap(pte-1);
pte_unmap_unlock(pte-1, ptl);
return err;
}
static inline int generic_pmd_range(struct mm_struct *mm, pud_t *pud,
unsigned long addr, unsigned long end,
pte_fn_t fn, void *data)
static inline int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
unsigned long addr, unsigned long end,
pte_fn_t fn, void *data)
{
pmd_t *pmd;
unsigned long next;
@@ -1418,16 +1421,16 @@ static inline int generic_pmd_range(struct mm_struct *mm, pud_t *pud,
return -ENOMEM;
do {
next = pmd_addr_end(addr, end);
err = generic_pte_range(mm, pmd, addr, next, fn, data);
err = apply_to_pte_range(mm, pmd, addr, next, fn, data);
if (err)
break;
} while (pmd++, addr = next, addr != end);
return err;
}
static inline int generic_pud_range(struct mm_struct *mm, pgd_t *pgd,
unsigned long addr, unsigned long end,
pte_fn_t fn, void *data)
static inline int apply_to_pud_range(struct mm_struct *mm, pgd_t *pgd,
unsigned long addr, unsigned long end,
pte_fn_t fn, void *data)
{
pud_t *pud;
unsigned long next;
@@ -1438,7 +1441,7 @@ static inline int generic_pud_range(struct mm_struct *mm, pgd_t *pgd,
return -ENOMEM;
do {
next = pud_addr_end(addr, end);
err = generic_pmd_range(mm, pud, addr, next, fn, data);
err = apply_to_pmd_range(mm, pud, addr, next, fn, data);
if (err)
break;
} while (pud++, addr = next, addr != end);
@@ -1449,8 +1452,8 @@ static inline int generic_pud_range(struct mm_struct *mm, pgd_t *pgd,
* Scan a region of virtual memory, filling in page tables as necessary
* and calling a provided function on each leaf page table.
*/
int generic_page_range(struct mm_struct *mm, unsigned long addr,
unsigned long size, pte_fn_t fn, void *data)
int apply_to_page_range(struct mm_struct *mm, unsigned long addr,
unsigned long size, pte_fn_t fn, void *data)
{
pgd_t *pgd;
unsigned long next;
@@ -1461,12 +1464,13 @@ int generic_page_range(struct mm_struct *mm, unsigned long addr,
pgd = pgd_offset(mm, addr);
do {
next = pgd_addr_end(addr, end);
err = generic_pud_range(mm, pgd, addr, next, fn, data);
err = apply_to_pud_range(mm, pgd, addr, next, fn, data);
if (err)
break;
} while (pgd++, addr = next, addr != end);
return err;
}
EXPORT_SYMBOL_GPL(apply_to_page_range);
#endif
/*
+1 -2
View File
@@ -460,8 +460,7 @@ void arch_getdomaininfo_ctxt(
if ( hvm_guest(v) )
{
hvm_store_cpu_guest_regs(v, &c->user_regs);
hvm_store_cpu_guest_ctrl_regs(v, c->ctrlreg);
hvm_store_cpu_guest_regs(v, &c->user_regs, c->ctrlreg);
}
else
{
+1 -1
View File
@@ -773,7 +773,7 @@ void handle_mmio(unsigned long va, unsigned long gpa)
mmio_opp = &v->arch.hvm_vcpu.mmio_op;
regs = mmio_opp->inst_decoder_regs;
hvm_store_cpu_guest_regs(v, regs);
hvm_store_cpu_guest_regs(v, regs, NULL);
if ((inst_len = hvm_instruction_length(v)) <= 0) {
printf("handle_mmio: failed to get instruction length\n");
+29 -29
View File
@@ -201,31 +201,41 @@ int svm_initialize_guest_resources(struct vcpu *v)
}
static void svm_store_cpu_guest_regs(
struct vcpu *v, struct cpu_user_regs *regs)
struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
if ( regs != NULL )
{
#if defined (__x86_64__)
regs->rip = vmcb->rip;
regs->rsp = vmcb->rsp;
regs->rflags = vmcb->rflags;
regs->cs = vmcb->cs.sel;
regs->ds = vmcb->ds.sel;
regs->es = vmcb->es.sel;
regs->ss = vmcb->ss.sel;
regs->gs = vmcb->gs.sel;
regs->fs = vmcb->fs.sel;
regs->rip = vmcb->rip;
regs->rsp = vmcb->rsp;
regs->rflags = vmcb->rflags;
regs->cs = vmcb->cs.sel;
regs->ds = vmcb->ds.sel;
regs->es = vmcb->es.sel;
regs->ss = vmcb->ss.sel;
regs->gs = vmcb->gs.sel;
regs->fs = vmcb->fs.sel;
#elif defined (__i386__)
regs->eip = vmcb->rip;
regs->esp = vmcb->rsp;
regs->eflags = vmcb->rflags;
regs->cs = vmcb->cs.sel;
regs->ds = vmcb->ds.sel;
regs->es = vmcb->es.sel;
regs->ss = vmcb->ss.sel;
regs->gs = vmcb->gs.sel;
regs->fs = vmcb->fs.sel;
regs->eip = vmcb->rip;
regs->esp = vmcb->rsp;
regs->eflags = vmcb->rflags;
regs->cs = vmcb->cs.sel;
regs->ds = vmcb->ds.sel;
regs->es = vmcb->es.sel;
regs->ss = vmcb->ss.sel;
regs->gs = vmcb->gs.sel;
regs->fs = vmcb->fs.sel;
#endif
}
if ( crs != NULL )
{
crs[0] = vmcb->cr0;
crs[3] = vmcb->cr3;
crs[4] = vmcb->cr4;
}
}
static void svm_load_cpu_guest_regs(
@@ -372,15 +382,6 @@ static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
return 1;
}
void svm_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
crs[0] = vmcb->cr0;
crs[3] = vmcb->cr3;
crs[4] = vmcb->cr4;
}
void svm_modify_guest_state(struct vcpu *v)
{
svm_modify_vmcb(v, &v->arch.guest_context.user_regs);
@@ -448,7 +449,6 @@ int start_svm(void)
hvm_funcs.store_cpu_guest_regs = svm_store_cpu_guest_regs;
hvm_funcs.load_cpu_guest_regs = svm_load_cpu_guest_regs;
hvm_funcs.store_cpu_guest_ctrl_regs = svm_store_cpu_guest_ctrl_regs;
hvm_funcs.modify_guest_state = svm_modify_guest_state;
hvm_funcs.realmode = svm_realmode;
+71 -29
View File
@@ -398,31 +398,81 @@ void vmx_migrate_timers(struct vcpu *v)
migrate_timer(&(VLAPIC(v)->vlapic_timer), v->processor);
}
void vmx_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
struct vmx_store_cpu_guest_regs_callback_info {
struct vcpu *v;
struct cpu_user_regs *regs;
unsigned long *crs;
};
static void vmx_store_cpu_guest_regs(
struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs);
static void vmx_store_cpu_guest_regs_callback(void *data)
{
struct vmx_store_cpu_guest_regs_callback_info *info = data;
vmx_store_cpu_guest_regs(info->v, info->regs, info->crs);
}
static void vmx_store_cpu_guest_regs(
struct vcpu *v, struct cpu_user_regs *regs, unsigned long *crs)
{
if ( v != current )
{
/* Non-current VCPUs must be paused to get a register snapshot. */
ASSERT(atomic_read(&v->pausecnt) != 0);
if ( v->arch.hvm_vmx.launch_cpu != smp_processor_id() )
{
/* Get register details from remote CPU. */
struct vmx_store_cpu_guest_regs_callback_info info = {
.v = v, .regs = regs, .crs = crs };
cpumask_t cpumask = cpumask_of_cpu(v->arch.hvm_vmx.launch_cpu);
on_selected_cpus(cpumask, vmx_store_cpu_guest_regs_callback,
&info, 1, 1);
return;
}
/* Register details are on this CPU. Load the correct VMCS. */
__vmptrld(virt_to_maddr(v->arch.hvm_vmx.vmcs));
}
ASSERT(v->arch.hvm_vmx.launch_cpu == smp_processor_id());
if ( regs != NULL )
{
#if defined (__x86_64__)
__vmread(GUEST_RFLAGS, &regs->rflags);
__vmread(GUEST_SS_SELECTOR, &regs->ss);
__vmread(GUEST_CS_SELECTOR, &regs->cs);
__vmread(GUEST_DS_SELECTOR, &regs->ds);
__vmread(GUEST_ES_SELECTOR, &regs->es);
__vmread(GUEST_GS_SELECTOR, &regs->gs);
__vmread(GUEST_FS_SELECTOR, &regs->fs);
__vmread(GUEST_RIP, &regs->rip);
__vmread(GUEST_RSP, &regs->rsp);
__vmread(GUEST_RFLAGS, &regs->rflags);
__vmread(GUEST_SS_SELECTOR, &regs->ss);
__vmread(GUEST_CS_SELECTOR, &regs->cs);
__vmread(GUEST_DS_SELECTOR, &regs->ds);
__vmread(GUEST_ES_SELECTOR, &regs->es);
__vmread(GUEST_GS_SELECTOR, &regs->gs);
__vmread(GUEST_FS_SELECTOR, &regs->fs);
__vmread(GUEST_RIP, &regs->rip);
__vmread(GUEST_RSP, &regs->rsp);
#elif defined (__i386__)
__vmread(GUEST_RFLAGS, &regs->eflags);
__vmread(GUEST_SS_SELECTOR, &regs->ss);
__vmread(GUEST_CS_SELECTOR, &regs->cs);
__vmread(GUEST_DS_SELECTOR, &regs->ds);
__vmread(GUEST_ES_SELECTOR, &regs->es);
__vmread(GUEST_GS_SELECTOR, &regs->gs);
__vmread(GUEST_FS_SELECTOR, &regs->fs);
__vmread(GUEST_RIP, &regs->eip);
__vmread(GUEST_RSP, &regs->esp);
#else
#error Unsupported architecture
__vmread(GUEST_RFLAGS, &regs->eflags);
__vmread(GUEST_SS_SELECTOR, &regs->ss);
__vmread(GUEST_CS_SELECTOR, &regs->cs);
__vmread(GUEST_DS_SELECTOR, &regs->ds);
__vmread(GUEST_ES_SELECTOR, &regs->es);
__vmread(GUEST_GS_SELECTOR, &regs->gs);
__vmread(GUEST_FS_SELECTOR, &regs->fs);
__vmread(GUEST_RIP, &regs->eip);
__vmread(GUEST_RSP, &regs->esp);
#endif
}
if ( crs != NULL )
{
__vmread(CR0_READ_SHADOW, &crs[0]);
__vmread(GUEST_CR3, &crs[3]);
__vmread(CR4_READ_SHADOW, &crs[4]);
}
/* Reload current VCPU's VMCS if it was temporarily unloaded. */
if ( (v != current) && hvm_guest(current) )
__vmptrld(virt_to_maddr(current->arch.hvm_vmx.vmcs));
}
void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
@@ -456,13 +506,6 @@ void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
#endif
}
void vmx_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
{
__vmread(CR0_READ_SHADOW, &crs[0]);
__vmread(GUEST_CR3, &crs[3]);
__vmread(CR4_READ_SHADOW, &crs[4]);
}
void vmx_modify_guest_state(struct vcpu *v)
{
modify_vmcs(&v->arch.hvm_vmx, &v->arch.guest_context.user_regs);
@@ -616,7 +659,6 @@ int start_vmx(void)
hvm_funcs.store_cpu_guest_regs = vmx_store_cpu_guest_regs;
hvm_funcs.load_cpu_guest_regs = vmx_load_cpu_guest_regs;
hvm_funcs.store_cpu_guest_ctrl_regs = vmx_store_cpu_guest_ctrl_regs;
hvm_funcs.modify_guest_state = vmx_modify_guest_state;
hvm_funcs.realmode = vmx_realmode;
+1 -2
View File
@@ -27,8 +27,7 @@ void show_registers(struct cpu_user_regs *regs)
if ( hvm_guest(current) && guest_mode(regs) )
{
context = "hvm";
hvm_store_cpu_guest_regs(current, &fault_regs);
hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
hvm_store_cpu_guest_regs(current, &fault_regs, fault_crs);
}
else
{
+1 -2
View File
@@ -27,8 +27,7 @@ void show_registers(struct cpu_user_regs *regs)
if ( hvm_guest(current) && guest_mode(regs) )
{
context = "hvm";
hvm_store_cpu_guest_regs(current, &fault_regs);
hvm_store_cpu_guest_ctrl_regs(current, fault_crs);
hvm_store_cpu_guest_regs(current, &fault_regs, fault_crs);
}
else
{
+1
View File
@@ -562,6 +562,7 @@ initialise_gdb(void)
gdb_ctx->serhnd = serial_parse_handle(opt_gdb);
if ( gdb_ctx->serhnd != -1 )
printk("GDB stub initialised.\n");
serial_start_sync(gdb_ctx->serhnd);
}
/*
+5 -2
View File
@@ -121,8 +121,11 @@ static void ns16550_interrupt(
while ( !(ns_read_reg(uart, IIR) & IIR_NOINT) )
{
serial_tx_interrupt(port, regs);
serial_rx_interrupt(port, regs);
char lsr = ns_read_reg(uart, LSR);
if ( lsr & LSR_THRE )
serial_tx_interrupt(port, regs);
if ( lsr & LSR_DR )
serial_rx_interrupt(port, regs);
}
}
+43 -24
View File
@@ -7,6 +7,7 @@
*/
#include <xen/config.h>
#include <xen/delay.h>
#include <xen/init.h>
#include <xen/irq.h>
#include <xen/keyhandler.h>
@@ -15,8 +16,8 @@
#include <xen/serial.h>
static struct serial_port com[2] = {
{ .lock = SPIN_LOCK_UNLOCKED },
{ .lock = SPIN_LOCK_UNLOCKED }
{ .rx_lock = SPIN_LOCK_UNLOCKED, .tx_lock = SPIN_LOCK_UNLOCKED },
{ .rx_lock = SPIN_LOCK_UNLOCKED, .tx_lock = SPIN_LOCK_UNLOCKED }
};
void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
@@ -25,7 +26,7 @@ void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
serial_rx_fn fn = NULL;
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
spin_lock_irqsave(&port->rx_lock, flags);
if ( port->driver->getc(port, &c) )
{
@@ -39,7 +40,7 @@ void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
port->rxbuf[MASK_SERIAL_RXBUF_IDX(port->rxbufp++)] = c;
}
spin_unlock_irqrestore(&port->lock, flags);
spin_unlock_irqrestore(&port->rx_lock, flags);
if ( fn != NULL )
(*fn)(c & 0x7f, regs);
@@ -50,7 +51,19 @@ void serial_tx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
int i;
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
local_irq_save(flags);
/*
* Avoid spinning for a long time: if there is a long-term lock holder
* then we know that they'll be stuffing bytes into the transmitter which
* will therefore not be empty for long.
*/
while ( !spin_trylock(&port->tx_lock) )
{
if ( !port->driver->tx_empty(port) )
return;
cpu_relax();
}
if ( port->driver->tx_empty(port) )
{
@@ -63,7 +76,7 @@ void serial_tx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
}
}
spin_unlock_irqrestore(&port->lock, flags);
spin_unlock_irqrestore(&port->tx_lock, flags);
}
static void __serial_putc(struct serial_port *port, char c)
@@ -117,7 +130,7 @@ void serial_putc(int handle, char c)
if ( (handle == -1) || !port->driver || !port->driver->putc )
return;
spin_lock_irqsave(&port->lock, flags);
spin_lock_irqsave(&port->tx_lock, flags);
if ( (c == '\n') && (handle & SERHND_COOKED) )
__serial_putc(port, '\r');
@@ -129,7 +142,7 @@ void serial_putc(int handle, char c)
__serial_putc(port, c);
spin_unlock_irqrestore(&port->lock, flags);
spin_unlock_irqrestore(&port->tx_lock, flags);
}
void serial_puts(int handle, const char *s)
@@ -141,7 +154,7 @@ void serial_puts(int handle, const char *s)
if ( (handle == -1) || !port->driver || !port->driver->putc )
return;
spin_lock_irqsave(&port->lock, flags);
spin_lock_irqsave(&port->tx_lock, flags);
while ( (c = *s++) != '\0' )
{
@@ -156,7 +169,7 @@ void serial_puts(int handle, const char *s)
__serial_putc(port, c);
}
spin_unlock_irqrestore(&port->lock, flags);
spin_unlock_irqrestore(&port->tx_lock, flags);
}
char serial_getc(int handle)
@@ -168,27 +181,28 @@ char serial_getc(int handle)
if ( (handle == -1) || !port->driver || !port->driver->getc )
return '\0';
do {
do {
for ( ; ; )
{
spin_lock_irqsave(&port->lock, flags);
spin_lock_irqsave(&port->rx_lock, flags);
if ( port->rxbufp != port->rxbufc )
{
c = port->rxbuf[MASK_SERIAL_RXBUF_IDX(port->rxbufc++)];
spin_unlock_irqrestore(&port->lock, flags);
spin_unlock_irqrestore(&port->rx_lock, flags);
break;
}
if ( port->driver->getc(port, &c) )
{
spin_unlock_irqrestore(&port->lock, flags);
spin_unlock_irqrestore(&port->rx_lock, flags);
break;
}
spin_unlock_irqrestore(&port->lock, flags);
spin_unlock_irqrestore(&port->rx_lock, flags);
cpu_relax();
udelay(100);
}
} while ( ((handle & SERHND_LO) && (c & 0x80)) ||
((handle & SERHND_HI) && !(c & 0x80)) );
@@ -241,7 +255,7 @@ void serial_set_rx_handler(int handle, serial_rx_fn fn)
if ( handle == -1 )
return;
spin_lock_irqsave(&port->lock, flags);
spin_lock_irqsave(&port->rx_lock, flags);
if ( port->rx != NULL )
goto fail;
@@ -265,11 +279,11 @@ void serial_set_rx_handler(int handle, serial_rx_fn fn)
port->rx = fn;
}
spin_unlock_irqrestore(&port->lock, flags);
spin_unlock_irqrestore(&port->rx_lock, flags);
return;
fail:
spin_unlock_irqrestore(&port->lock, flags);
spin_unlock_irqrestore(&port->rx_lock, flags);
printk("ERROR: Conflicting receive handlers for COM%d\n",
handle & SERHND_IDX);
}
@@ -277,8 +291,13 @@ void serial_set_rx_handler(int handle, serial_rx_fn fn)
void serial_force_unlock(int handle)
{
struct serial_port *port = &com[handle & SERHND_IDX];
if ( handle != -1 )
port->lock = SPIN_LOCK_UNLOCKED;
if ( handle == -1 )
return;
port->rx_lock = SPIN_LOCK_UNLOCKED;
port->tx_lock = SPIN_LOCK_UNLOCKED;
serial_start_sync(handle);
}
@@ -290,7 +309,7 @@ void serial_start_sync(int handle)
if ( handle == -1 )
return;
spin_lock_irqsave(&port->lock, flags);
spin_lock_irqsave(&port->tx_lock, flags);
if ( port->sync++ == 0 )
{
@@ -303,7 +322,7 @@ void serial_start_sync(int handle)
}
}
spin_unlock_irqrestore(&port->lock, flags);
spin_unlock_irqrestore(&port->tx_lock, flags);
}
void serial_end_sync(int handle)
@@ -314,11 +333,11 @@ void serial_end_sync(int handle)
if ( handle == -1 )
return;
spin_lock_irqsave(&port->lock, flags);
spin_lock_irqsave(&port->tx_lock, flags);
port->sync--;
spin_unlock_irqrestore(&port->lock, flags);
spin_unlock_irqrestore(&port->tx_lock, flags);
}
int serial_tx_space(int handle)
+8 -13
View File
@@ -41,12 +41,12 @@ struct hvm_function_table {
/*
* Store and load guest state:
* 1) load/store guest register state,
* 2) store guest control register state (used for panic dumps),
* 3) modify guest state (e.g., set debug flags).
* 2) modify guest state (e.g., set debug flags).
*/
void (*store_cpu_guest_regs)(struct vcpu *v, struct cpu_user_regs *r);
void (*load_cpu_guest_regs)(struct vcpu *v, struct cpu_user_regs *r);
void (*store_cpu_guest_ctrl_regs)(struct vcpu *v, unsigned long crs[8]);
void (*store_cpu_guest_regs)(
struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs);
void (*load_cpu_guest_regs)(
struct vcpu *v, struct cpu_user_regs *r);
void (*modify_guest_state)(struct vcpu *v);
/*
@@ -93,9 +93,10 @@ hvm_relinquish_guest_resources(struct domain *d)
}
static inline void
hvm_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *r)
hvm_store_cpu_guest_regs(
struct vcpu *v, struct cpu_user_regs *r, unsigned long *crs)
{
hvm_funcs.store_cpu_guest_regs(v, r);
hvm_funcs.store_cpu_guest_regs(v, r, crs);
}
static inline void
@@ -104,12 +105,6 @@ hvm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *r)
hvm_funcs.load_cpu_guest_regs(v, r);
}
static inline void
hvm_store_cpu_guest_ctrl_regs(struct vcpu *v, unsigned long crs[8])
{
hvm_funcs.store_cpu_guest_ctrl_regs(v, crs);
}
static inline void
hvm_modify_guest_state(struct vcpu *v)
{
+1 -1
View File
@@ -42,7 +42,7 @@ struct serial_port {
char rxbuf[SERIAL_RXBUFSZ];
unsigned int rxbufp, rxbufc;
/* Serial I/O is concurrency-safe. */
spinlock_t lock;
spinlock_t rx_lock, tx_lock;
};
struct uart_driver {
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.