bool XenDriver::mtrrType( unsigned long long guestAddress, uint8_t &type ) const throw() { const uint8_t MTRR_TYPE_UNCACHABLE = 0; const uint8_t MTRR_TYPE_WRTHROUGH = 4; int32_t seg, index; uint8_t overlap_mtrr = 0, overlap_mtrr_pos = 0; static bool hwMtrrInit = false; static struct hvm_hw_mtrr hwMtrr; if ( !hwMtrrInit ) { StatsCollector::instance().incStat( "partialContext" ); StatsCollector::instance().incStat( "partialMtrr" ); if ( xc_domain_hvm_getcontext_partial( xci_, domain_, HVM_SAVE_CODE( MTRR ), 0, &hwMtrr, sizeof( hwMtrr ) ) != 0 ) { if ( logHelper_ ) logHelper_->error( std::string( "xc_domain_hvm_getcontext_partial() failed: " ) + strerror( errno ) ); return false; } else hwMtrrInit = true; } uint8_t def_type = hwMtrr.msr_mtrr_def_type & 0xff; uint8_t enabled = hwMtrr.msr_mtrr_def_type >> 10; uint8_t *u8_fixed = ( uint8_t * )hwMtrr.msr_mtrr_fixed; if ( !( enabled & 0x2 ) ) { type = MTRR_TYPE_UNCACHABLE; return true; } if ( ( guestAddress < 0x100000 ) && ( enabled & 1 ) ) { /* Fixed range MTRR takes effective */ int32_t addr = ( uint32_t )guestAddress; if ( addr < 0x80000 ) { seg = ( addr >> 16 ); return u8_fixed[seg]; } else if ( addr < 0xc0000 ) {
unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom, int vcpu, unsigned long long virt) { xc_dominfo_t dominfo; uint64_t paddr, mask, pte = 0; int size, level, pt_levels = 2; void *map; if (xc_domain_getinfo(xc_handle, dom, 1, &dominfo) != 1 || dominfo.domid != dom) return 0; /* What kind of paging are we dealing with? */ if (dominfo.hvm) { struct hvm_hw_cpu ctx; if (xc_domain_hvm_getcontext_partial(xc_handle, dom, HVM_SAVE_CODE(CPU), vcpu, &ctx, sizeof ctx) != 0) return 0; if (!(ctx.cr0 & CR0_PG)) return virt >> PAGE_SHIFT; pt_levels = (ctx.msr_efer&EFER_LMA) ? 4 : (ctx.cr4&CR4_PAE) ? 3 : 2; paddr = ctx.cr3 & ((pt_levels == 3) ? ~0x1full : ~0xfffull); } else {