static void rtc_set_time(RTCState *s) { struct tm *tm = &s->current_tm; struct domain *d = vrtc_domain(s); unsigned long before, after; /* XXX s_time_t */ ASSERT(spin_is_locked(&s->lock)); before = mktime(get_year(tm->tm_year), tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); tm->tm_sec = from_bcd(s, s->hw.cmos_data[RTC_SECONDS]); tm->tm_min = from_bcd(s, s->hw.cmos_data[RTC_MINUTES]); tm->tm_hour = convert_hour(s, s->hw.cmos_data[RTC_HOURS]); tm->tm_wday = from_bcd(s, s->hw.cmos_data[RTC_DAY_OF_WEEK]); tm->tm_mday = from_bcd(s, s->hw.cmos_data[RTC_DAY_OF_MONTH]); tm->tm_mon = from_bcd(s, s->hw.cmos_data[RTC_MONTH]) - 1; tm->tm_year = from_bcd(s, s->hw.cmos_data[RTC_YEAR]) + 100; after = mktime(get_year(tm->tm_year), tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); /* We use the guest's setting of the RTC to define the local-time * offset for this domain. */ d->time_offset_seconds += (after - before); update_domain_wallclock_time(d); /* Also tell qemu-dm about it so it will be remembered for next boot. */ send_timeoffset_req(after - before); }
static int __init pvh_setup_cpus(struct domain *d, paddr_t entry, paddr_t start_info) { struct vcpu *v = d->vcpu[0]; unsigned int cpu, i; int rc; /* * This sets the vCPU state according to the state described in * docs/misc/hvmlite.markdown. */ vcpu_hvm_context_t cpu_ctx = { .mode = VCPU_HVM_MODE_32B, .cpu_regs.x86_32.ebx = start_info, .cpu_regs.x86_32.eip = entry, .cpu_regs.x86_32.cr0 = X86_CR0_PE | X86_CR0_ET, .cpu_regs.x86_32.cs_limit = ~0u, .cpu_regs.x86_32.ds_limit = ~0u, .cpu_regs.x86_32.ss_limit = ~0u, .cpu_regs.x86_32.tr_limit = 0x67, .cpu_regs.x86_32.cs_ar = 0xc9b, .cpu_regs.x86_32.ds_ar = 0xc93, .cpu_regs.x86_32.ss_ar = 0xc93, .cpu_regs.x86_32.tr_ar = 0x8b, }; cpu = v->processor; for ( i = 1; i < d->max_vcpus; i++ ) { const struct vcpu *p = dom0_setup_vcpu(d, i, cpu); if ( p ) cpu = p->processor; } rc = arch_set_info_hvm_guest(v, &cpu_ctx); if ( rc ) { printk("Unable to setup Dom0 BSP context: %d\n", rc); return rc; } rc = dom0_setup_permissions(d); if ( rc ) { panic("Unable to setup Dom0 permissions: %d\n", rc); return rc; } update_domain_wallclock_time(d); clear_bit(_VPF_down, &v->pause_flags); return 0; } static int __init acpi_count_intr_ovr(struct acpi_subtable_header *header, const unsigned long end) { acpi_intr_overrides++; return 0; }
int arch_domain_create(struct domain *d, unsigned int domcr_flags, struct xen_arch_domainconfig *config) { int rc, count = 0; BUILD_BUG_ON(GUEST_MAX_VCPUS < MAX_VIRT_CPUS); d->arch.relmem = RELMEM_not_started; /* Idle domains do not need this setup */ if ( is_idle_domain(d) ) return 0; ASSERT(config != NULL); /* p2m_init relies on some value initialized by the IOMMU subsystem */ if ( (rc = iommu_domain_init(d)) != 0 ) goto fail; if ( (rc = p2m_init(d)) != 0 ) goto fail; rc = -ENOMEM; if ( (d->shared_info = alloc_xenheap_pages(0, 0)) == NULL ) goto fail; /* Default the virtual ID to match the physical */ d->arch.vpidr = boot_cpu_data.midr.bits; clear_page(d->shared_info); share_xen_page_with_guest( virt_to_page(d->shared_info), d, XENSHARE_writable); switch ( config->gic_version ) { case XEN_DOMCTL_CONFIG_GIC_NATIVE: switch ( gic_hw_version () ) { case GIC_V2: config->gic_version = XEN_DOMCTL_CONFIG_GIC_V2; d->arch.vgic.version = GIC_V2; break; case GIC_V3: config->gic_version = XEN_DOMCTL_CONFIG_GIC_V3; d->arch.vgic.version = GIC_V3; break; default: BUG(); } break; case XEN_DOMCTL_CONFIG_GIC_V2: d->arch.vgic.version = GIC_V2; break; case XEN_DOMCTL_CONFIG_GIC_V3: d->arch.vgic.version = GIC_V3; break; default: rc = -EOPNOTSUPP; goto fail; } if ( (rc = domain_vgic_register(d, &count)) != 0 ) goto fail; if ( (rc = domain_io_init(d, count + MAX_IO_HANDLER)) != 0 ) goto fail; if ( (rc = domain_vgic_init(d, config->nr_spis)) != 0 ) goto fail; if ( (rc = domain_vtimer_init(d, config)) != 0 ) goto fail; update_domain_wallclock_time(d); /* * The hardware domain will get a PPI later in * arch/arm/domain_build.c depending on the * interrupt map of the hardware. */ if ( !is_hardware_domain(d) ) { d->arch.evtchn_irq = GUEST_EVTCHN_PPI; /* At this stage vgic_reserve_virq should never fail */ if ( !vgic_reserve_virq(d, GUEST_EVTCHN_PPI) ) BUG(); } /* * Virtual UART is only used by linux early printk and decompress code. * Only use it for the hardware domain because the linux kernel may not * support multi-platform. */ if ( is_hardware_domain(d) && (rc = domain_vuart_init(d)) ) goto fail; return 0; fail: d->is_dying = DOMDYING_dead; arch_domain_destroy(d); return rc; }