4 #include <machine/archtypes.h>
5 #include <minix/timers.h>
6 #include <minix/sysutil.h>
9 #include "kernel/config.h"
10 #include "kernel/const.h"
11 #include "kernel/type.h"
12 #include "kernel/proc.h"
14 EXTERN endpoint_t sef_self_endpoint
;
16 /* SEF Live update prototypes for sef_receive(). */
17 void do_sef_st_before_receive(void);
19 /*===========================================================================*
20 * do_sef_st_before_receive *
21 *===========================================================================*/
22 void do_sef_st_before_receive(void)
26 /*===========================================================================*
27 * sef_copy_state_region_ctl *
28 *===========================================================================*/
29 int sef_copy_state_region_ctl(sef_init_info_t
*info
, vir_bytes
*src_address
, vir_bytes
*dst_address
) {
30 if(info
->copy_flags
& SEF_COPY_DEST_OFFSET
) {
31 *dst_address
+= sef_llvm_get_ltckpt_offset();
33 if(info
->copy_flags
& SEF_COPY_SRC_OFFSET
) {
34 *src_address
+= sef_llvm_get_ltckpt_offset();
37 printf("sef_copy_state_region_ctl. copy_flags:\nSEF_COPY_DEST_OFFSET\t%d\nSEF_COPY_SRC_OFFSET\t%d\nSEF_COPY_NEW_TO_NEW\t%d\nSEF_COPY_OLD_TO_NEW\t%d\n", info
->copy_flags
& SEF_COPY_DEST_OFFSET
? 1 : 0,
38 info
->copy_flags
& SEF_COPY_SRC_OFFSET
? 1 : 0, info
->copy_flags
& SEF_COPY_NEW_TO_NEW
? 1 : 0, info
->copy_flags
& SEF_COPY_OLD_TO_NEW
? 1 : 0);
40 if(info
->copy_flags
& SEF_COPY_NEW_TO_NEW
)
45 /*===========================================================================*
46 * sef_copy_state_region *
47 *===========================================================================*/
48 int sef_copy_state_region(sef_init_info_t
*info
,
49 vir_bytes address
, size_t size
, vir_bytes dst_address
, int may_have_holes
)
51 vir_bytes base
, top
, target
;
52 struct vm_region_info vri
;
57 if(sef_copy_state_region_ctl(info
, &address
, &dst_address
)) {
59 printf("sef_copy_state_region: memcpy %d bytes, addr = 0x%08x -> 0x%08x...\n",
60 size
, address
, dst_address
);
62 /* memcpy region from current state */
63 memcpy((void*) dst_address
, (void *)address
, size
);
64 } else if (may_have_holes
&& sef_self_endpoint
!= VM_PROC_NR
&&
65 vm_info_region(info
->old_endpoint
, &vri
, 1, &base
) == 1) {
66 /* Perform a safe copy of a region of the old state. The section may
67 * contain holes, so ask VM for the actual regions within the data
68 * section and transfer each one separately. The alternative, just
69 * copying until a page fault happens, is not possible in the multi-
70 * component-with-VM live update case, where VM may not receive page
71 * faults during the live update window. For now, we use the region
72 * iteration approach for the data section only; other cases have not
73 * been tested, but may work as well.
76 printf("sef_copy_state_region: copying %d bytes, addr = 0x%08x -> "
77 "0x%08x, gid = %d, source = %d, with holes...\n", size
, address
,
78 dst_address
, SEF_STATE_TRANSFER_GID
, info
->old_endpoint
);
81 /* The following is somewhat of a hack: the start of the data section
82 * may in fact not be page-aligned and may be part of the last page of
83 * of the preceding (text) section. Therefore, if the first region we
84 * find starts above the known base address, blindly copy the area in
87 if (vri
.vri_addr
> address
) {
88 if ((r
= sys_safecopyfrom(info
->old_endpoint
, SEF_STATE_TRANSFER_GID
,
89 address
, dst_address
, vri
.vri_addr
- address
)) != OK
) {
91 printf("sef_copy_state_region: sys_safecopyfrom failed\n");
99 assert(vri
.vri_addr
>= address
);
100 if (vri
.vri_addr
>= top
)
102 if (vri
.vri_length
> top
- vri
.vri_addr
)
103 vri
.vri_length
= top
- vri
.vri_addr
;
104 target
= dst_address
+ (vri
.vri_addr
- address
);
105 if ((r
= sys_safecopyfrom(info
->old_endpoint
,
106 SEF_STATE_TRANSFER_GID
, vri
.vri_addr
, target
,
107 vri
.vri_length
)) != OK
) {
108 #if STATE_TRANS_DEBUG
109 printf("sef_copy_state_region: sys_safecopyfrom failed\n");
113 /* Save on a VM call if the next address is already too high. */
116 } while (vm_info_region(info
->old_endpoint
, &vri
, 1, &base
) == 1);
118 /* Perform a safe copy of a region of the old state, without taking into
119 * account any holes. This is the default for anything but the data
120 * section, with a few additioanl exceptions: VM can't query VM, so
121 * simply assume there are no holes; also, if we fail to get one region
122 * for the old process (and this is presumably possible if its heap is
123 * so small it fits in the last text page, see above), we also just
124 * blindly copy over the entire data section.
126 #if STATE_TRANS_DEBUG
127 printf("sef_copy_state_region: copying %d bytes, addr = 0x%08x -> "
128 "0x%08x, gid = %d, source = %d, without holes...\n", size
, address
,
129 dst_address
, SEF_STATE_TRANSFER_GID
, info
->old_endpoint
);
131 if ((r
= sys_safecopyfrom(info
->old_endpoint
, SEF_STATE_TRANSFER_GID
,
132 address
, dst_address
, size
)) != OK
) {
133 #if STATE_TRANS_DEBUG
134 printf("sef_copy_state_region: sys_safecopyfrom failed\n");
143 /*===========================================================================*
144 * sef_old_state_table_lookup *
145 *===========================================================================*/
146 int sef_old_state_table_lookup(sef_init_info_t
*info
, void *addr
)
148 struct priv old_priv
;
151 if ((r
= sys_getpriv(&old_priv
, info
->old_endpoint
)) != OK
) {
152 printf("ERROR. sys_getpriv() failed.\n");
156 if (sef_copy_state_region(info
, old_priv
.s_state_table
157 , sef_llvm_state_table_size(), (vir_bytes
) addr
, FALSE
/*may_have_holes*/))
159 printf("ERROR. state table transfer failed\n");
166 /*===========================================================================*
167 * sef_old_state_table_lookup_opaque *
168 *===========================================================================*/
169 int sef_old_state_table_lookup_opaque(void *info_opaque
, void *addr
)
171 assert(info_opaque
!= NULL
&& "Invalid info_opaque pointer.");
172 return sef_old_state_table_lookup((sef_init_info_t
*)(info_opaque
), addr
);
175 /*===========================================================================*
176 * sef_copy_state_region_opaque *
177 *===========================================================================*/
178 int sef_copy_state_region_opaque(void *info_opaque
, uint32_t address
,
179 size_t size
, uint32_t dst_address
)
181 assert(info_opaque
!= NULL
&& "Invalid info_opaque pointer.");
182 return sef_copy_state_region((sef_init_info_t
*)(info_opaque
),
183 (vir_bytes
) address
, size
, (vir_bytes
) dst_address
,
184 FALSE
/*may_have_holes*/);
187 /*===========================================================================*
188 * sef_st_state_transfer *
189 *===========================================================================*/
190 int sef_st_state_transfer(sef_init_info_t
*info
)
192 return sef_llvm_state_transfer(info
);