Skip to content

Commit 9878543

Browse files
fyin1lijinxia
authored andcommitted
DM: add system reset (with RAM content kept)
This function add high level reset_vdev function. Which is implemented to call deinit/init pairing to emulate the virtual device reset operation. This patch also add the system reset which keep the UOS RAM content functionality to DM. Signed-off-by: Yin Fengwei <fengwei.yin@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
1 parent b33012a commit 9878543

File tree

3 files changed

+96
-4
lines changed

3 files changed

+96
-4
lines changed

devicemodel/core/main.c

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,73 @@ vm_deinit_vdevs(struct vmctx *ctx)
509509
ioapic_deinit();
510510
}
511511

512+
static void
513+
vm_reset_vdevs(struct vmctx *ctx)
514+
{
515+
/*
516+
* The current virtual devices doesn't define virtual
517+
* device reset function. So we call vdev deinit/init
518+
* pairing to emulate the device reset operation.
519+
*
520+
* pci/ioapic deinit/init is needed because of dependency
521+
* of pci irq allocation/free.
522+
*
523+
* acpi build is necessary because irq for each vdev
524+
* could be assigned with different number after reset.
525+
*/
526+
atkbdc_deinit(ctx);
527+
vrtc_deinit(ctx);
528+
529+
deinit_pci(ctx);
530+
pci_irq_deinit(ctx);
531+
ioapic_deinit();
532+
533+
atkbdc_init(ctx);
534+
vrtc_init(ctx);
535+
536+
ioapic_init(ctx);
537+
pci_irq_init(ctx);
538+
init_pci(ctx);
539+
540+
if (acpi) {
541+
acpi_build(ctx, guest_ncpus);
542+
}
543+
}
544+
545+
static void
546+
vm_system_reset(struct vmctx *ctx)
547+
{
548+
int vcpu_id = 0;
549+
550+
/*
551+
* If we get system reset request, we don't want to exit the
552+
* vcpu_loop/vm_loop/mevent_loop. So we do:
553+
* 1. pause VM
554+
* 2. notify request done to reset ioreq state in vhm
555+
* 3. reset virtual devices
556+
* 4. load software for UOS
557+
* 5. hypercall reset vm
558+
* 6. reset suspend mode to VM_SUSPEND_NONE
559+
*/
560+
561+
vm_pause(ctx);
562+
for (vcpu_id = 0; vcpu_id < 4; vcpu_id++) {
563+
struct vhm_request *vhm_req;
564+
565+
vhm_req = &vhm_req_buf[vcpu_id];
566+
if (vhm_req->valid &&
567+
(vhm_req->processed == REQ_STATE_PROCESSING) &&
568+
(vhm_req->client == ctx->ioreq_client))
569+
vm_notify_request_done(ctx, vcpu_id);
570+
}
571+
572+
vm_reset_vdevs(ctx);
573+
574+
acrn_sw_load(ctx);
575+
vm_reset(ctx);
576+
vm_set_suspend_mode(VM_SUSPEND_NONE);
577+
}
578+
512579
static void
513580
vm_loop(struct vmctx *ctx)
514581
{
@@ -521,19 +588,23 @@ vm_loop(struct vmctx *ctx)
521588
assert(error == 0);
522589

523590
while (1) {
524-
int vcpu;
591+
int vcpu_id;
525592
struct vhm_request *vhm_req;
526593

527594
error = vm_attach_ioreq_client(ctx);
528595
if (error)
529596
break;
530597

531-
for (vcpu = 0; vcpu < 4; vcpu++) {
532-
vhm_req = &vhm_req_buf[vcpu];
598+
for (vcpu_id = 0; vcpu_id < 4; vcpu_id++) {
599+
vhm_req = &vhm_req_buf[vcpu_id];
533600
if (vhm_req->valid
534601
&& (vhm_req->processed == REQ_STATE_PROCESSING)
535602
&& (vhm_req->client == ctx->ioreq_client))
536-
handle_vmexit(ctx, vhm_req, vcpu);
603+
handle_vmexit(ctx, vhm_req, vcpu_id);
604+
}
605+
606+
if (VM_SUSPEND_SYSTEM_RESET == vm_get_suspend_mode()) {
607+
vm_system_reset(ctx);
537608
}
538609
}
539610
quit_vm_loop = 0;

devicemodel/hw/pci/core.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,7 @@ pci_emul_deinit(struct vmctx *ctx, struct pci_vdev_ops *ops, int bus, int slot,
827827
free(fi->fi_param);
828828

829829
if (fi->fi_devi) {
830+
pci_lintr_release(fi->fi_devi);
830831
pci_emul_free_bars(fi->fi_devi);
831832
free(fi->fi_devi);
832833
}
@@ -1621,6 +1622,25 @@ pci_lintr_request(struct pci_vdev *dev)
16211622
pci_set_cfgdata8(dev, PCIR_INTPIN, bestpin + 1);
16221623
}
16231624

1625+
void
1626+
pci_lintr_release(struct pci_vdev *dev)
1627+
{
1628+
struct businfo *bi;
1629+
struct slotinfo *si;
1630+
int pin;
1631+
1632+
bi = pci_businfo[dev->bus];
1633+
assert(bi != NULL);
1634+
1635+
si = &bi->slotinfo[dev->slot];
1636+
1637+
for (pin = 1; pin < 4; pin++) {
1638+
si->si_intpins[pin].ii_count = 0;
1639+
si->si_intpins[pin].ii_pirq_pin = 0;
1640+
si->si_intpins[pin].ii_ioapic_irq = 0;
1641+
}
1642+
}
1643+
16241644
static void
16251645
pci_lintr_route(struct pci_vdev *dev)
16261646
{

devicemodel/include/pci_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ void pci_generate_msix(struct pci_vdev *pi, int msgnum);
257257
void pci_lintr_assert(struct pci_vdev *pi);
258258
void pci_lintr_deassert(struct pci_vdev *pi);
259259
void pci_lintr_request(struct pci_vdev *pi);
260+
void pci_lintr_release(struct pci_vdev *pi);
260261
int pci_msi_enabled(struct pci_vdev *pi);
261262
int pci_msix_enabled(struct pci_vdev *pi);
262263
int pci_msix_table_bar(struct pci_vdev *pi);

0 commit comments

Comments
 (0)