static int amd_vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content, uint64_t supported) { struct vcpu *v = current; struct vpmu_struct *vpmu = vcpu_vpmu(v); ASSERT(!supported); /* For all counters, enable guest only mode for HVM guest */ if ( (get_pmu_reg_type(msr) == MSR_TYPE_CTRL) && !(is_guest_mode(msr_content)) ) { set_guest_mode(msr_content); } /* check if the first counter is enabled */ if ( (get_pmu_reg_type(msr) == MSR_TYPE_CTRL) && is_pmu_enabled(msr_content) && !vpmu_is_set(vpmu, VPMU_RUNNING) ) { if ( !acquire_pmu_ownership(PMU_OWNER_HVM) ) return 1; vpmu_set(vpmu, VPMU_RUNNING); apic_write(APIC_LVTPC, PMU_APIC_VECTOR); vpmu->hw_lapic_lvtpc = PMU_APIC_VECTOR; if ( !((struct amd_vpmu_context *)vpmu->context)->msr_bitmap_set ) amd_vpmu_set_msr_bitmap(v); } /* stop saving & restore if guest stops first counter */ if ( (get_pmu_reg_type(msr) == MSR_TYPE_CTRL) && (is_pmu_enabled(msr_content) == 0) && vpmu_is_set(vpmu, VPMU_RUNNING) ) { apic_write(APIC_LVTPC, PMU_APIC_VECTOR | APIC_LVT_MASKED); vpmu->hw_lapic_lvtpc = PMU_APIC_VECTOR | APIC_LVT_MASKED; vpmu_reset(vpmu, VPMU_RUNNING); if ( ((struct amd_vpmu_context *)vpmu->context)->msr_bitmap_set ) amd_vpmu_unset_msr_bitmap(v); release_pmu_ownship(PMU_OWNER_HVM); } if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_LOADED) || vpmu_is_set(vpmu, VPMU_FROZEN) ) { context_load(v); vpmu_set(vpmu, VPMU_CONTEXT_LOADED); vpmu_reset(vpmu, VPMU_FROZEN); } /* Update vpmu context immediately */ context_update(msr, msr_content); /* Write to hw counters */ wrmsrl(msr, msr_content); return 1; }
MODULE load_session_context (void) { DESCR symbols; /* Symbol descriptor */ context_load (SCOPE_GLOBAL, msg_do-> global_size, msg_do-> global_data); context_load (SCOPE_LOCAL, msg_do-> local_size, msg_do-> local_data); /* Normally if either of these two blocks are not found, we're * starting a new session. The form symbol table is populated * with all the HTTP environment symbols passed from WTPMAN at * the start of the session. */ if (!context_get (SCOPE_GLOBAL, "_sess", &session, sizeof (session))) { memset (&session, 0, sizeof (session)); session.disable_actions = DISABLE_HIDDEN; } if (!context_getsym (SCOPE_GLOBAL, "_sym", &session.symbols)) { symbols.size = msg_do-> env_size; symbols.data = msg_do-> env_data; session.symbols = descr2symb (&symbols); } session.buffer_ = &buffer; session.program_callcode = msg_do-> call_result; session.back_used = FALSE; if (strlen (msg_do-> http_data) == 7 && streq (msg_do-> http_data, "refresh")) { session.back_used = TRUE; msg_do-> http_data [0] = '\0'; } strcpy (session.program_name, msg_do-> program); strncpy ((char *) buffer.data, msg_do-> http_data, BUFFER_MAX); buffer.data [BUFFER_MAX] = 0; sym_assume_symbol (session.symbols, "uri", msg_do-> http_uri); }
static int amd_vpmu_do_rdmsr(unsigned int msr, uint64_t *msr_content) { struct vcpu *v = current; struct vpmu_struct *vpmu = vcpu_vpmu(v); if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_LOADED) || vpmu_is_set(vpmu, VPMU_FROZEN) ) { context_load(v); vpmu_set(vpmu, VPMU_CONTEXT_LOADED); vpmu_reset(vpmu, VPMU_FROZEN); } rdmsrl(msr, *msr_content); return 1; }
static void amd_vpmu_load(struct vcpu *v) { struct vpmu_struct *vpmu = vcpu_vpmu(v); struct amd_vpmu_context *ctxt = vpmu->context; vpmu_reset(vpmu, VPMU_FROZEN); if ( vpmu_is_set(vpmu, VPMU_CONTEXT_LOADED) ) { unsigned int i; for ( i = 0; i < num_counters; i++ ) wrmsrl(ctrls[i], ctxt->ctrls[i]); return; } context_load(v); }