merge with xen-unstable.hg

This commit is contained in:
Alex Williamson committed 2007-10-01 13:59:37 -06:00
commit 3c78b60b94
11 files changed
+239 -207

No files matched your search

+28 -1
View File
@@ -55,6 +55,9 @@ from xen.util.acmpolicy import ACM_LABEL_UNLABELED_DISPLAY
import XenAPI
import inspect
from xen.xend import XendOptions
xoptions = XendOptions.instance()
# getopt.gnu_getopt is better, but only exists in Python 2.3+. Use
# getopt.getopt if gnu_getopt is not available. This will mean that options
@@ -1595,7 +1598,31 @@ def xm_sched_credit(args):
err(str(result))
def xm_info(args):
arg_check(args, "info", 0)
arg_check(args, "info", 0, 1)
try:
(options, params) = getopt.gnu_getopt(args, 'c', ['config'])
except getopt.GetoptError, opterr:
err(opterr)
usage('info')
show_xend_config = 0
for (k, v) in options:
if k in ['-c', '--config']:
show_xend_config = 1
if show_xend_config:
for name, obj in inspect.getmembers(xoptions):
if not inspect.ismethod(obj):
if name == "config":
for x in obj[1:]:
if len(x) < 2:
print "%-38s: (none)" % x[0]
else:
print "%-38s:" % x[0], x[1]
else:
print "%-38s:" % name, obj
return
if serverType == SERVER_XEN_API:
+73
View File
@@ -49,6 +49,10 @@
#include <public/version.h>
#include <public/memory.h>
/* Xen command-line option to disable hardware-assisted paging */
static int opt_hap_disabled;
invbool_param("hap", opt_hap_disabled);
int hvm_enabled __read_mostly;
unsigned int opt_hvm_debug_level __read_mostly;
@@ -74,6 +78,14 @@ void hvm_enable(struct hvm_function_table *fns)
hvm_funcs = *fns;
hvm_enabled = 1;
if ( hvm_funcs.hap_supported )
{
if ( opt_hap_disabled )
hvm_funcs.hap_supported = 0;
printk("HVM: Hardware Assisted Paging %sabled\n",
hvm_funcs.hap_supported ? "en" : "dis");
}
}
void hvm_set_guest_time(struct vcpu *v, u64 gtime)
@@ -325,6 +337,34 @@ static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
if ( hvm_load_entry(CPU, h, &ctxt) != 0 )
return -EINVAL;
/* Sanity check some control registers. */
if ( (ctxt.cr0 & HVM_CR0_GUEST_RESERVED_BITS) ||
!(ctxt.cr0 & X86_CR0_ET) ||
((ctxt.cr0 & (X86_CR0_PE|X86_CR0_PG)) == X86_CR0_PG) )
{
gdprintk(XENLOG_ERR, "HVM restore: bad CR0 0x%"PRIx64"\n",
ctxt.msr_efer);
return -EINVAL;
}
if ( ctxt.cr4 & HVM_CR4_GUEST_RESERVED_BITS )
{
gdprintk(XENLOG_ERR, "HVM restore: bad CR4 0x%"PRIx64"\n",
ctxt.msr_efer);
return -EINVAL;
}
if ( (ctxt.msr_efer & ~(EFER_LME | EFER_NX | EFER_SCE)) ||
((sizeof(long) != 8) && (ctxt.msr_efer & EFER_LME)) ||
(!cpu_has_nx && (ctxt.msr_efer & EFER_NX)) ||
(!cpu_has_syscall && (ctxt.msr_efer & EFER_SCE)) ||
((ctxt.msr_efer & (EFER_LME|EFER_LMA)) == EFER_LMA) )
{
gdprintk(XENLOG_ERR, "HVM restore: bad EFER 0x%"PRIx64"\n",
ctxt.msr_efer);
return -EINVAL;
}
/* Architecture-specific vmcs/vmcb bits */
if ( hvm_funcs.load_cpu_ctxt(v, &ctxt) < 0 )
return -EINVAL;
@@ -520,6 +560,39 @@ void hvm_triple_fault(void)
domain_shutdown(v->domain, SHUTDOWN_reboot);
}
int hvm_set_efer(uint64_t value)
{
struct vcpu *v = current;
value &= ~EFER_LMA;
if ( (value & ~(EFER_LME | EFER_NX | EFER_SCE)) ||
((sizeof(long) != 8) && (value & EFER_LME)) ||
(!cpu_has_nx && (value & EFER_NX)) ||
(!cpu_has_syscall && (value & EFER_SCE)) )
{
gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
"EFER: %"PRIx64"\n", value);
hvm_inject_exception(TRAP_gp_fault, 0, 0);
return 0;
}
if ( ((value ^ v->arch.hvm_vcpu.guest_efer) & EFER_LME) &&
hvm_paging_enabled(v) )
{
gdprintk(XENLOG_WARNING,
"Trying to change EFER.LME with paging enabled\n");
hvm_inject_exception(TRAP_gp_fault, 0, 0);
return 0;
}
value |= v->arch.hvm_vcpu.guest_efer & EFER_LMA;
v->arch.hvm_vcpu.guest_efer = value;
hvm_update_guest_efer(v);
return 1;
}
int hvm_set_cr0(unsigned long value)
{
struct vcpu *v = current;
+11 -81
View File
@@ -69,8 +69,7 @@ static void *hsa[NR_CPUS] __read_mostly;
/* vmcb used for extended host state */
static void *root_vmcb[NR_CPUS] __read_mostly;
/* hardware assisted paging bits */
extern int opt_hap_enabled;
static void svm_update_guest_efer(struct vcpu *v);
static void inline __update_guest_eip(
struct cpu_user_regs *regs, int inst_len)
@@ -106,22 +105,10 @@ static void svm_cpu_down(void)
write_efer(read_efer() & ~EFER_SVME);
}
static int svm_lme_is_set(struct vcpu *v)
{
#ifdef __x86_64__
u64 guest_efer = v->arch.hvm_vcpu.guest_efer;
return guest_efer & EFER_LME;
#else
return 0;
#endif
}
static enum handler_return long_mode_do_msr_write(struct cpu_user_regs *regs)
{
u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
u32 ecx = regs->ecx;
struct vcpu *v = current;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
HVM_DBG_LOG(DBG_LEVEL_0, "msr %x msr_content %"PRIx64,
ecx, msr_content);
@@ -129,47 +116,8 @@ static enum handler_return long_mode_do_msr_write(struct cpu_user_regs *regs)
switch ( ecx )
{
case MSR_EFER:
/* Offending reserved bit will cause #GP. */
#ifdef __x86_64__
if ( (msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE)) ||
#else
if ( (msr_content & ~(EFER_NX | EFER_SCE)) ||
#endif
(!cpu_has_nx && (msr_content & EFER_NX)) ||
(!cpu_has_syscall && (msr_content & EFER_SCE)) )
{
gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
"EFER: %"PRIx64"\n", msr_content);
goto gp_fault;
}
if ( (msr_content & EFER_LME) && !svm_lme_is_set(v) )
{
/* EFER.LME transition from 0 to 1. */
if ( hvm_paging_enabled(v) ||
!(v->arch.hvm_vcpu.guest_cr[4] & X86_CR4_PAE) )
{
gdprintk(XENLOG_WARNING, "Trying to set LME bit when "
"in paging mode or PAE bit is not set\n");
goto gp_fault;
}
}
else if ( !(msr_content & EFER_LME) && svm_lme_is_set(v) )
{
/* EFER.LME transistion from 1 to 0. */
if ( hvm_paging_enabled(v) )
{
gdprintk(XENLOG_WARNING,
"Trying to clear EFER.LME while paging enabled\n");
goto gp_fault;
}
}
v->arch.hvm_vcpu.guest_efer = msr_content;
vmcb->efer = msr_content | EFER_SVME;
if ( !hvm_paging_enabled(v) )
vmcb->efer &= ~(EFER_LME | EFER_LMA);
if ( !hvm_set_efer(msr_content) )
return HNDL_exception_raised;
break;
case MSR_K8_MC4_MISC: /* Threshold register */
@@ -185,10 +133,6 @@ static enum handler_return long_mode_do_msr_write(struct cpu_user_regs *regs)
}
return HNDL_done;
gp_fault:
svm_inject_exception(v, TRAP_gp_fault, 1, 0);
return HNDL_exception_raised;
}
@@ -452,11 +396,7 @@ static void svm_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
vmcb->cstar = data->msr_cstar;
vmcb->sfmask = data->msr_syscall_mask;
v->arch.hvm_vcpu.guest_efer = data->msr_efer;
vmcb->efer = data->msr_efer | EFER_SVME;
/* VMCB's EFER.LME isn't set unless we're actually in long mode
* (see long_mode_do_msr_write()) */
if ( !(vmcb->efer & EFER_LMA) )
vmcb->efer &= ~EFER_LME;
svm_update_guest_efer(v);
hvm_set_guest_time(v, data->tsc);
}
@@ -546,14 +486,11 @@ static void svm_update_guest_cr(struct vcpu *v, unsigned int cr)
static void svm_update_guest_efer(struct vcpu *v)
{
#ifdef __x86_64__
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
if ( v->arch.hvm_vcpu.guest_efer & EFER_LMA )
vmcb->efer |= EFER_LME | EFER_LMA;
else
vmcb->efer &= ~(EFER_LME | EFER_LMA);
#endif
vmcb->efer = (v->arch.hvm_vcpu.guest_efer | EFER_SVME) & ~EFER_LME;
if ( vmcb->efer & EFER_LMA )
vmcb->efer |= EFER_LME;
}
static void svm_flush_guest_tlbs(void)
@@ -936,18 +873,14 @@ static struct hvm_function_table svm_function_table = {
.event_pending = svm_event_pending
};
static void svm_npt_detect(void)
static int svm_npt_detect(void)
{
u32 eax, ebx, ecx, edx;
/* Check CPUID for nested paging support. */
cpuid(0x8000000A, &eax, &ebx, &ecx, &edx);
if ( !(edx & 1) && opt_hap_enabled )
{
printk("SVM: Nested paging is not supported by this CPU.\n");
opt_hap_enabled = 0;
}
return (edx & 1);
}
int start_svm(struct cpuinfo_x86 *c)
@@ -978,8 +911,6 @@ int start_svm(struct cpuinfo_x86 *c)
write_efer(read_efer() | EFER_SVME);
svm_npt_detect();
/* Initialize the HSA for this core. */
phys_hsa = (u64) virt_to_maddr(hsa[cpu]);
phys_hsa_lo = (u32) phys_hsa;
@@ -994,11 +925,10 @@ int start_svm(struct cpuinfo_x86 *c)
setup_vmcb_dump();
svm_function_table.hap_supported = svm_npt_detect();
hvm_enable(&svm_function_table);
if ( opt_hap_enabled )
printk("SVM: Nested paging enabled.\n");
return 1;
}
+10 -51
View File
@@ -199,42 +199,8 @@ static enum handler_return long_mode_do_msr_write(struct cpu_user_regs *regs)
switch ( ecx )
{
case MSR_EFER:
/* offending reserved bit will cause #GP */
if ( (msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE)) ||
(!cpu_has_nx && (msr_content & EFER_NX)) ||
(!cpu_has_syscall && (msr_content & EFER_SCE)) )
{
gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
"EFER: %"PRIx64"\n", msr_content);
goto gp_fault;
}
if ( (msr_content & EFER_LME)
&& !(v->arch.hvm_vcpu.guest_efer & EFER_LME) )
{
if ( unlikely(hvm_paging_enabled(v)) )
{
gdprintk(XENLOG_WARNING,
"Trying to set EFER.LME with paging enabled\n");
goto gp_fault;
}
}
else if ( !(msr_content & EFER_LME)
&& (v->arch.hvm_vcpu.guest_efer & EFER_LME) )
{
if ( unlikely(hvm_paging_enabled(v)) )
{
gdprintk(XENLOG_WARNING,
"Trying to clear EFER.LME with paging enabled\n");
goto gp_fault;
}
}
if ( (msr_content ^ v->arch.hvm_vcpu.guest_efer) & (EFER_NX|EFER_SCE) )
write_efer((read_efer() & ~(EFER_NX|EFER_SCE)) |
(msr_content & (EFER_NX|EFER_SCE)));
v->arch.hvm_vcpu.guest_efer = msr_content;
if ( !hvm_set_efer(msr_content) )
goto exception_raised;
break;
case MSR_FS_BASE:
@@ -285,6 +251,7 @@ static enum handler_return long_mode_do_msr_write(struct cpu_user_regs *regs)
HVM_DBG_LOG(DBG_LEVEL_0, "Not cano address of msr write %x", ecx);
gp_fault:
vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
exception_raised:
return HNDL_exception_raised;
}
@@ -380,7 +347,8 @@ static enum handler_return long_mode_do_msr_read(struct cpu_user_regs *regs)
u64 msr_content = 0;
struct vcpu *v = current;
switch ( regs->ecx ) {
switch ( regs->ecx )
{
case MSR_EFER:
msr_content = v->arch.hvm_vcpu.guest_efer;
break;
@@ -398,25 +366,12 @@ static enum handler_return long_mode_do_msr_read(struct cpu_user_regs *regs)
static enum handler_return long_mode_do_msr_write(struct cpu_user_regs *regs)
{
u64 msr_content = regs->eax | ((u64)regs->edx << 32);
struct vcpu *v = current;
switch ( regs->ecx )
{
case MSR_EFER:
/* offending reserved bit will cause #GP */
if ( (msr_content & ~EFER_NX) ||
(!cpu_has_nx && (msr_content & EFER_NX)) )
{
gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
"EFER: %"PRIx64"\n", msr_content);
vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
if ( !hvm_set_efer(msr_content) )
return HNDL_exception_raised;
}
if ( (msr_content ^ v->arch.hvm_vcpu.guest_efer) & EFER_NX )
write_efer((read_efer() & ~EFER_NX) | (msr_content & EFER_NX));
v->arch.hvm_vcpu.guest_efer = msr_content;
break;
default:
@@ -1096,6 +1051,10 @@ static void vmx_update_guest_efer(struct vcpu *v)
vmx_vmcs_exit(v);
#endif
if ( v == current )
write_efer((read_efer() & ~(EFER_NX|EFER_SCE)) |
(v->arch.hvm_vcpu.guest_efer & (EFER_NX|EFER_SCE)));
}
static void vmx_flush_guest_tlbs(void)
+97 -60
View File
@@ -134,7 +134,7 @@ static int device_context_mapped(struct iommu *iommu, u8 bus, u8 devfn)
#define level_mask(l) (((u64)(-1)) << level_to_offset_bits(l))
#define level_size(l) (1 << level_to_offset_bits(l))
#define align_to_level(addr, l) ((addr + level_size(l) - 1) & level_mask(l))
static struct dma_pte *addr_to_dma_pte(struct domain *domain, u64 addr)
static struct page_info *addr_to_dma_page(struct domain *domain, u64 addr)
{
struct hvm_iommu *hd = domain_hvm_iommu(domain);
struct acpi_drhd_unit *drhd;
@@ -144,6 +144,8 @@ static struct dma_pte *addr_to_dma_pte(struct domain *domain, u64 addr)
int level = agaw_to_level(hd->agaw);
int offset;
unsigned long flags;
struct page_info *pg = NULL;
u64 *vaddr = NULL;
drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
iommu = drhd->iommu;
@@ -153,79 +155,105 @@ static struct dma_pte *addr_to_dma_pte(struct domain *domain, u64 addr)
if ( !hd->pgd )
{
pgd = (struct dma_pte *)alloc_xenheap_page();
if ( !pgd && !hd->pgd )
if ( !pgd )
{
spin_unlock_irqrestore(&hd->mapping_lock, flags);
return NULL;
}
memset((u8*)pgd, 0, PAGE_SIZE);
if ( !hd->pgd )
hd->pgd = pgd;
else /* somebody is fast */
free_xenheap_page((void *) pgd);
memset(pgd, 0, PAGE_SIZE);
hd->pgd = pgd;
}
parent = hd->pgd;
while ( level > 0 )
while ( level > 1 )
{
u8 *tmp;
offset = address_level_offset(addr, level);
pte = &parent[offset];
if ( level == 1 )
break;
if ( dma_pte_addr(*pte) == 0 )
{
tmp = alloc_xenheap_page();
memset(tmp, 0, PAGE_SIZE);
iommu_flush_cache_page(iommu, tmp);
if ( !tmp && dma_pte_addr(*pte) == 0 )
pg = alloc_domheap_page(NULL);
vaddr = map_domain_page(mfn_x(page_to_mfn(pg)));
if ( !vaddr )
{
spin_unlock_irqrestore(&hd->mapping_lock, flags);
return NULL;
}
if ( dma_pte_addr(*pte) == 0 )
{
dma_set_pte_addr(*pte,
virt_to_maddr(tmp));
/*
* high level table always sets r/w, last level
* page table control read/write
*/
dma_set_pte_readable(*pte);
dma_set_pte_writable(*pte);
iommu_flush_cache_entry(iommu, pte);
} else /* somebody is fast */
free_xenheap_page(tmp);
memset(vaddr, 0, PAGE_SIZE);
iommu_flush_cache_page(iommu, vaddr);
dma_set_pte_addr(*pte, page_to_maddr(pg));
/*
* high level table always sets r/w, last level
* page table control read/write
*/
dma_set_pte_readable(*pte);
dma_set_pte_writable(*pte);
iommu_flush_cache_entry(iommu, pte);
}
parent = maddr_to_virt(dma_pte_addr(*pte));
else
{
pg = maddr_to_page(pte->val);
vaddr = map_domain_page(mfn_x(page_to_mfn(pg)));
if ( !vaddr )
{
spin_unlock_irqrestore(&hd->mapping_lock, flags);
return NULL;
}
}
if ( parent != hd->pgd )
unmap_domain_page(parent);
if ( level == 2 && vaddr )
{
unmap_domain_page(vaddr);
break;
}
parent = (struct dma_pte *)vaddr;
vaddr = NULL;
level--;
}
spin_unlock_irqrestore(&hd->mapping_lock, flags);
return pte;
return pg;
}
/* return address's pte at specific level */
static struct dma_pte *dma_addr_level_pte(struct domain *domain, u64 addr,
int level)
/* return address's page at specific level */
static struct page_info *dma_addr_level_page(struct domain *domain,
u64 addr, int level)
{
struct hvm_iommu *hd = domain_hvm_iommu(domain);
struct dma_pte *parent, *pte = NULL;
int total = agaw_to_level(hd->agaw);
int offset;
struct page_info *pg = NULL;
parent = hd->pgd;
while ( level <= total )
{
offset = address_level_offset(addr, total);
pte = &parent[offset];
if ( level == total )
return pte;
if ( dma_pte_addr(*pte) == 0 )
{
if ( parent != hd->pgd )
unmap_domain_page(parent);
break;
parent = maddr_to_virt(dma_pte_addr(*pte));
}
pg = maddr_to_page(pte->val);
if ( parent != hd->pgd )
unmap_domain_page(parent);
if ( level == total )
return pg;
parent = map_domain_page(mfn_x(page_to_mfn(pg)));
total--;
}
return NULL;
}
@@ -506,12 +534,16 @@ static void dma_pte_clear_one(struct domain *domain, u64 addr)
struct acpi_drhd_unit *drhd;
struct iommu *iommu;
struct dma_pte *pte = NULL;
struct page_info *pg = NULL;
drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
/* get last level pte */
pte = dma_addr_level_pte(domain, addr, 1);
pg = dma_addr_level_page(domain, addr, 1);
if ( !pg )
return;
pte = (struct dma_pte *)map_domain_page(mfn_x(page_to_mfn(pg)));
pte += address_level_offset(addr, 1);
if ( pte )
{
dma_clear_pte(*pte);
@@ -559,6 +591,7 @@ void dma_pte_free_pagetable(struct domain *domain, u64 start, u64 end)
int total = agaw_to_level(hd->agaw);
int level;
u32 tmp;
struct page_info *pg = NULL;
drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
iommu = drhd->iommu;
@@ -576,13 +609,16 @@ void dma_pte_free_pagetable(struct domain *domain, u64 start, u64 end)
while ( tmp < end )
{
pte = dma_addr_level_pte(domain, tmp, level);
if ( pte )
{
free_xenheap_page((void *) maddr_to_virt(dma_pte_addr(*pte)));
dma_clear_pte(*pte);
iommu_flush_cache_entry(iommu, pte);
}
pg = dma_addr_level_page(domain, tmp, level);
if ( !pg )
return;
pte = (struct dma_pte *)map_domain_page(mfn_x(page_to_mfn(pg)));
pte += address_level_offset(tmp, level);
dma_clear_pte(*pte);
iommu_flush_cache_entry(iommu, pte);
unmap_domain_page(pte);
free_domheap_page(pg);
tmp += level_size(level);
}
level++;
@@ -1445,6 +1481,7 @@ int iommu_map_page(struct domain *d, paddr_t gfn, paddr_t mfn)
struct acpi_drhd_unit *drhd;
struct iommu *iommu;
struct dma_pte *pte = NULL;
struct page_info *pg = NULL;
drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
iommu = drhd->iommu;
@@ -1453,12 +1490,15 @@ int iommu_map_page(struct domain *d, paddr_t gfn, paddr_t mfn)
if ( ecap_pass_thru(iommu->ecap) && (d->domain_id == 0) )
return 0;
pte = addr_to_dma_pte(d, gfn << PAGE_SHIFT_4K);
if ( !pte )
pg = addr_to_dma_page(d, gfn << PAGE_SHIFT_4K);
if ( !pg )
return -ENOMEM;
pte = (struct dma_pte *)map_domain_page(mfn_x(page_to_mfn(pg)));
pte += mfn & LEVEL_MASK;
dma_set_pte_addr(*pte, mfn << PAGE_SHIFT_4K);
dma_set_pte_prot(*pte, DMA_PTE_READ | DMA_PTE_WRITE);
iommu_flush_cache_entry(iommu, pte);
unmap_domain_page(pte);
for_each_drhd_unit ( drhd )
{
@@ -1477,7 +1517,6 @@ int iommu_unmap_page(struct domain *d, dma_addr_t gfn)
{
struct acpi_drhd_unit *drhd;
struct iommu *iommu;
struct dma_pte *pte = NULL;
drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
iommu = drhd->iommu;
@@ -1486,10 +1525,8 @@ int iommu_unmap_page(struct domain *d, dma_addr_t gfn)
if ( ecap_pass_thru(iommu->ecap) && (d->domain_id == 0) )
return 0;
/* get last level pte */
pte = dma_addr_level_pte(d, gfn << PAGE_SHIFT_4K, 1);
dma_pte_clear_one(d, gfn << PAGE_SHIFT_4K);
return 0;
}
@@ -1501,6 +1538,7 @@ int iommu_page_mapping(struct domain *domain, dma_addr_t iova,
unsigned long start_pfn, end_pfn;
struct dma_pte *pte = NULL;
int index;
struct page_info *pg = NULL;
drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
iommu = drhd->iommu;
@@ -1513,12 +1551,15 @@ int iommu_page_mapping(struct domain *domain, dma_addr_t iova,
index = 0;
while ( start_pfn < end_pfn )
{
pte = addr_to_dma_pte(domain, iova + PAGE_SIZE_4K * index);
if ( !pte )
pg = addr_to_dma_page(domain, iova + PAGE_SIZE_4K * index);
if ( !pg )
return -ENOMEM;
pte = (struct dma_pte *)map_domain_page(mfn_x(page_to_mfn(pg)));
pte += start_pfn & LEVEL_MASK;
dma_set_pte_addr(*pte, start_pfn << PAGE_SHIFT_4K);
dma_set_pte_prot(*pte, prot);
iommu_flush_cache_entry(iommu, pte);
unmap_domain_page(pte);
start_pfn++;
index++;
}
@@ -1537,12 +1578,8 @@ int iommu_page_mapping(struct domain *domain, dma_addr_t iova,
int iommu_page_unmapping(struct domain *domain, dma_addr_t addr, size_t size)
{
struct dma_pte *pte = NULL;
/* get last level pte */
pte = dma_addr_level_pte(domain, addr, 1);
dma_pte_clear_range(domain, addr, addr + size);
return 0;
}
+7 -9
View File
@@ -28,9 +28,7 @@
#include <asm/guest_access.h>
#include <xsm/xsm.h>
/* Xen command-line option to enable hardware-assisted paging */
int opt_hap_enabled;
boolean_param("hap", opt_hap_enabled);
#define hap_enabled(d) (hvm_funcs.hap_supported && is_hvm_domain(d))
/* Printouts */
#define PAGING_PRINTK(_f, _a...) \
@@ -363,14 +361,14 @@ void paging_domain_init(struct domain *d)
shadow_domain_init(d);
/* ... but we will use hardware assistance if it's available. */
if ( opt_hap_enabled && is_hvm_domain(d) )
if ( hap_enabled(d) )
hap_domain_init(d);
}
/* vcpu paging struct initialization goes here */
void paging_vcpu_init(struct vcpu *v)
{
if ( opt_hap_enabled && is_hvm_vcpu(v) )
if ( hap_enabled(v->domain) )
hap_vcpu_init(v);
else
shadow_vcpu_init(v);
@@ -434,7 +432,7 @@ int paging_domctl(struct domain *d, xen_domctl_shadow_op_t *sc,
}
/* Here, dispatch domctl to the appropriate paging code */
if ( opt_hap_enabled && is_hvm_domain(d) )
if ( hap_enabled(d) )
return hap_domctl(d, sc, u_domctl);
else
return shadow_domctl(d, sc, u_domctl);
@@ -443,7 +441,7 @@ int paging_domctl(struct domain *d, xen_domctl_shadow_op_t *sc,
/* Call when destroying a domain */
void paging_teardown(struct domain *d)
{
if ( opt_hap_enabled && is_hvm_domain(d) )
if ( hap_enabled(d) )
hap_teardown(d);
else
shadow_teardown(d);
@@ -455,7 +453,7 @@ void paging_teardown(struct domain *d)
/* Call once all of the references to the domain have gone away */
void paging_final_teardown(struct domain *d)
{
if ( opt_hap_enabled && is_hvm_domain(d) )
if ( hap_enabled(d) )
hap_final_teardown(d);
else
shadow_final_teardown(d);
@@ -465,7 +463,7 @@ void paging_final_teardown(struct domain *d)
* creation. */
int paging_enable(struct domain *d, u32 mode)
{
if ( opt_hap_enabled && is_hvm_domain(d) )
if ( hap_enabled(d) )
return hap_enable(d, mode | PG_HAP_enable);
else
return shadow_enable(d, mode | PG_SH_enable);
+3
View File
@@ -72,6 +72,9 @@ enum hvm_intack {
struct hvm_function_table {
char *name;
/* Support Hardware-Assisted Paging? */
int hap_supported;
/*
* Initialise/destroy HVM domain/vcpu resources
*/
+1
View File
@@ -234,6 +234,7 @@ int hvm_do_hypercall(struct cpu_user_regs *pregs);
void hvm_hlt(unsigned long rflags);
void hvm_triple_fault(void);
int hvm_set_efer(uint64_t value);
int hvm_set_cr0(unsigned long value);
int hvm_set_cr3(unsigned long value);
int hvm_set_cr4(unsigned long value);
+1 -1
View File
@@ -154,7 +154,7 @@ static inline int acm_array_append_tuple(struct acm_sized_buffer *buf,
/* protos */
int acm_init_domain_ssid(struct domain *, ssidref_t ssidref);
void acm_free_domain_ssid(struct acm_ssid_domain *ssid);
void acm_free_domain_ssid(struct domain *);
int acm_init_binary_policy(u32 policy_code);
int acm_set_policy(XEN_GUEST_HANDLE_64(void) buf, u32 buf_size);
int do_acm_set_policy(void *buf, u32 buf_size, int is_bootpolicy,
+2 -2
View File
@@ -258,7 +258,7 @@ static inline void acm_domain_destroy(struct domain *d)
acm_secondary_ops->domain_destroy(ssid, d);
/* free security ssid for the destroyed domain (also if null policy */
acm_domain_ssid_off_list(ssid);
acm_free_domain_ssid((struct acm_ssid_domain *)(ssid));
acm_free_domain_ssid(d);
}
}
@@ -294,7 +294,7 @@ static inline int acm_domain_create(struct domain *d, ssidref_t ssidref)
{
acm_domain_ssid_onto_list(d->ssid);
} else {
acm_free_domain_ssid(d->ssid);
acm_free_domain_ssid(d);
}
error_out:
+6 -2
View File
@@ -361,7 +361,7 @@ int acm_init_domain_ssid(struct domain *subj, ssidref_t ssidref)
{
printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n",
__func__, subj->domain_id);
acm_free_domain_ssid(ssid);
acm_free_domain_ssid(subj);
return ACM_INIT_SSID_ERROR;
}
@@ -372,8 +372,10 @@ int acm_init_domain_ssid(struct domain *subj, ssidref_t ssidref)
void
acm_free_domain_ssid(struct acm_ssid_domain *ssid)
acm_free_domain_ssid(struct domain *d)
{
struct acm_ssid_domain *ssid = d->ssid;
/* domain is already gone, just ssid is left */
if (ssid == NULL)
return;
@@ -387,6 +389,8 @@ acm_free_domain_ssid(struct acm_ssid_domain *ssid)
ssid->secondary_ssid = NULL;
xfree(ssid);
d->ssid = NULL;
printkd("%s: Freed individual domain ssid (domain=%02x).\n",
__func__, id);
}
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.